C# Calculator with base methods.

Hi, everyone!

In my latest project I have to wrote calculator for models with another logic than basic arithmetic operations. It doesn’t matter for my latest words, just see results.

For implementing we have to create parser of expressions. All mathemactic experssions we can illustrate as tree with tokens(nodes) and part of token node value(generic class).

Token Types:

  1. Operand.
  2. Operator.
  3. Precedence( ‘)’, ‘(’ ).
using System;

namespace Voodoo.Expressions
{
    /// 
    /// Class implements container for storing intermediate values of parsed line.
    /// Save tokens for expression parser class.
    /// 
    /// 
    public struct Token<T>
    {
        /// 
        /// Field contains available operands in the expression draft line.
        /// 
        public static readonly String Operands = "+-*/()";

        public T Operand { get; set; }
        public char Operator { get; set; }
        public int Precedence { get; set; }

        public override string ToString()
        {
            return Operator != 0 ? Operator.ToString() : Operand.ToString();
        }
    }
}

Node value we will transfer using generic T param.

namespace Voodoo.Expressions
{
    /// 
    /// Class implements container for storing intermediate values in the expression
    /// parser class.
    /// 
    /// The type of the variable.
    /// The type of the number.
    public class Node<T1, T2>
    {
        public Node()
        {
        }

        public Node(T1 variable, T2 number)
        {
            Variable = variable;
            Number = number;
        }

        public T1 Variable { get; set; }

        public T2 Number { get; set; }
    }
}

Now I show abstract class for parsing expression and making expression tree. In our class we can see abstracts method for add, sub, mul, div operations that’s you can simply override with your implementation.

using System;
using System.Collections.Generic;

namespace Voodoo.Expressions
{
    /// <summary>
    /// Base class implements method for parsing draft line of expression.
    /// </summary>
    /// <typeparam name="T">The type of the 1.</typeparam>
    public abstract class ExpressionParserBase<T, T2>
    {
        private readonly Dictionary<String, T2> m_variables = new Dictionary<String, T2>();

        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionParserBase<T>"/> class.
        /// </summary>
        /// <param name="expression">The expression.</param>
        protected ExpressionParserBase(String expression)
        {
            Expression = expression;
        }

        /// <summary>
        /// Gets or sets the variables.
        /// </summary>
        /// <value>The variables.</value>
        public Dictionary<String, T2> Variables
        {
            get { return m_variables; }
        }

        /// <summary>
        /// Gets or sets the expression.
        /// </summary>
        /// <value>The expression.</value>
        public String Expression { get; private set; }

        /// <summary>
        /// Gets or sets the tokens.
        /// </summary>
        /// <value>The tokens.</value>
        public List<Token<T>> Tokens { get; private set; }

        /// <summary>
        /// Convert string to T.
        /// </summary>
        /// <param name="variable">The variable.</param>
        /// <returns></returns>
        protected abstract T ConvertStringToT(String variable);

        /// <summary>
        /// Adds the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected abstract T Add(Stack<T> stack, T v1, T v2);

        /// <summary>
        /// Subs the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected abstract T Sub(Stack<T> stack, T v1, T v2);

        /// <summary>
        /// Divs the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected abstract T Div(Stack<T> stack, T v1, T v2);

        /// <summary>
        /// Muls the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected abstract T Mul(Stack<T> stack, T v1, T v2);

        /// <summary>
        /// Tokenizes the specified line.
        /// </summary>
        /// <param name="line">The line.</param>
        /// <returns></returns>
        private List<Token<T>> Tokenize(IEnumerable<char> line)
        {
            var tokens = new List<Token<T>>();
            String variable = String.Empty;
            foreach (char arg in line)
            {
                var token = new Token<T>();
                if (Token<T>.Operands.Contains(arg.ToString()) &&
                    !String.IsNullOrEmpty(variable))
                {
                    token.Operand = ConvertStringToT(variable);
                    variable = String.Empty;
                    token.Precedence = 0;
                    tokens.Add(token);
                }
                switch (arg)
                {
                    case '+':
                    case '-':
                        token.Operator = arg;
                        token.Precedence = 2;
                        tokens.Add(token);
                        break;
                    case '*':
                    case '/':
                        token.Operator = arg;
                        token.Precedence = 1;
                        tokens.Add(token);
                        break;
                    case '(':
                        token.Operator = arg;
                        token.Precedence = -1;
                        tokens.Add(token);
                        break;
                    case ')':
                        token.Operator = arg;
                        token.Precedence = 3;
                        tokens.Add(token);
                        break;
                    default:
                        variable += arg;
                        break;
                }
            }

            if (!String.IsNullOrEmpty(variable))
            {
                var token = new Token<T> {Operand = ConvertStringToT(variable), Precedence = 0};
                tokens.Add(token);
            }

            return tokens;
        }

        /// <summary>
        /// Posts the fix.
        /// </summary>
        /// <param name="tokens">The tokens.</param>
        private void PostFix(List<Token<T>> tokens)
        {
            for (int i = 0; i < tokens.Count - 1; i++)
            {
                if (tokens[i].Precedence > tokens[i + 1].Precedence)
                {
                    int j = i;
                    int scopes = 0;
                    while (j < tokens.Count - 1 && (scopes > 0 ||
                                                    tokens[j].Precedence > tokens[j + 1].Precedence))
                    {
                        Token<T> tmp = tokens[j];
                        tokens[j] = tokens[j + 1];
                        tokens[j + 1] = tmp;
                        scopes += ((tokens[j].Operator == '(') ? 1 : 0)
                                  - ((tokens[j].Operator == ')') ? 1 : 0);
                        j++;
                    }
                    i--;
                }
            }
        }

        /// <summary>
        /// Gets the result of execution.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        protected abstract T2 GetResult(T value);

        /// <summary>
        /// Calculate expression.
        /// </summary>
        /// <returns></returns>
        public virtual T2 Execute()
        {
            Tokens = Tokenize(Expression);
            PostFix(Tokens);

            var stack = new Stack<T>();
            foreach (var token in Tokens)
            {
                switch (token.Operator)
                {
                    case '+':
                        Add(stack, stack.Pop(), stack.Pop());
                        break;
                    case '-':
                        Sub(stack, stack.Pop(), stack.Pop());
                        break;
                    case '*':
                        Mul(stack, stack.Pop(), stack.Pop());
                        break;
                    case '/':
                        Div(stack, stack.Pop(), stack.Pop());
                        break;
                    case '(':
                    case ')':
                        break;
                    default:
                        stack.Push(token.Operand);
                        break;
                }
            }
            return GetResult(stack.Pop());
        }
    }

And using base model of expression parser we can implement our arithmetic operations calculator. See example:

using System;
using System.Collections.Generic;

namespace Voodoo.Expressions
{
    /// <summary>
    /// Class implements basic expression evaluator.
    /// </summary>
    public class Calculator : ExpressionParserBase<float, float>
    {
        public Calculator(String expression)
            : base(expression)
        {
        }

        /// <summary>
        /// Adds the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected override float Add(Stack<float> stack, float v1, float v2)
        {
            float value = v1 + v2;
            stack.Push(value);
            return value;
        }

        /// <summary>
        /// Subs the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected override float Sub(Stack<float> stack, float v1, float v2)
        {
            float value = v2 - v1;
            stack.Push(value);
            return value;
        }

        /// <summary>
        /// Divs the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected override float Div(Stack<float> stack, float v1, float v2)
        {
            float value = v2/v1;
            stack.Push(value);
            return value;
        }

        /// <summary>
        /// Muls the specified stack.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="v1">The v1.</param>
        /// <param name="v2">The v2.</param>
        /// <returns></returns>
        protected override float Mul(Stack<float> stack, float v1, float v2)
        {
            float value = v2 - v1;
            stack.Push(value);
            return value;
        }

        /// <summary>
        /// Gets the result.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        protected override float GetResult(float value)
        {
            return value;
        }

        /// <summary>
        /// Converts the string to T.
        /// </summary>
        /// <param name="variable">The variable.</param>
        /// <returns></returns>
        protected override float ConvertStringToT(string variable)
        {
            float result = 0;
            if (!float.TryParse(variable, out result))
            {
                throw new ArgumentException("Unknown token: " + variable);
            }
            return result;
        }
    }
}

Thanks for reading!!!

1 note

Using jQuery Ajax in SharePoint Portal Customization

In one day I received task for customize standard SharePoint Survey Library for showing in the main page with graphics using fusioncharts and ajax requests. This graphics showed in the main page of web application. And now I wanna to share my experience in this development.

The first stuff what do you wanna to make, you have to decide what certain javascript library(or nothing)you will try to use and how survey in SharePoint works.

Standard SharePoint Survey Library it works very simple. When you are creating one question, you are automatically creating new field with name of title question, for example: Question: “How are you?”, you will see in the Library Settings new field with name “How_are_you”, it’s just sample, try to create it and you will see the same stuffs.

If you wanna to answer to one of the questions, you can create in the list one item and set field with answer. That’s all.

// This is example of handler for submiting new answer.
public class SubmitAnswerHandler : IHttpHandler
{
    #region IHttpHandler Members

    public void ProcessRequest(HttpContext context)
    {
        String title = context.Request.Params["name"];
        String listName = context.Request.Params["listname"];

        SPWeb web = SPContext.GetContext(context).Web;
        SPList list = web.Lists[listName];
        SPField field = SurveyUtility.GetLatestQuestionField(list);
        SPListItem item = list.Items.Add();
        item[field.Id] = title;
        item.Update();
    }

    public bool IsReusable
    {
        get { return true; }
    }

    #endregion
}

Then I choose jQuery as a primary javascript framework for implemeting me new showing survey.

In the bottom you see example of code that’s you have to add to the survey control. This control can be part of custom web part what you will decide to develop.

$(document).ready(function () {
    $('#<%= _surveyContainer.ClientID %>').survey({
        submit_link: '/_layouts/SubmitAnswerHandler.ashx',
        graphic_link: '<%= ChartPageLink %>',
        listname: '<%= ListTitle %>'
    });
});

; (function ($) {
    $.fn.survey = function (options) {
        var $graphic_link = options['graphic_link'];
        var $listname = options['listname'];
        var $submit_link = options['submit_link'];

        return this.each(function () {
            var $container = $(this);
            var $vote_container = $($container.find(".vote_panel"));
            var $results_container = $($container.find(".results_panel"));
            var $vote_button = $($container.find(".vote_button"));
            var $results_button = $($container.find(".results_button"));
            var $loading_container = $($container.find(".loading_container"));

            $vote_button.click(function (e) {
                if ($vote_container.is(':visible')) {
                    var selected = 0;
                    var $checked = $container.find("input[@class='radio_button']:checked");
                    if ($checked.length != 0) {
                        var title = $checked.parent().find('input[type="hidden"]').val();
                        $.ajax({
                            type: 'POST',
                            data: 'name=' + title + '&listname=' + $listname,
                            url: $submit_link,
                            success: function (data) {
                                show_results();
                                hide_buttons();
                            }
                        });
                    }
                } else {
                    $results_container.fadeOut("fast", function () {
                        $vote_container.fadeIn("fast");
                    });
                }
                e.preventDefault();
                return false;
            });

            $results_button.click(function (e) {
                show_results();
                e.preventDefault();
                return false;
            });

            function hide_buttons() {
                $vote_button.hide();
                $results_button.hide();
            }

            function show_results() {
                $.ajax({
                    type: 'GET',
                    url: $graphic_link,
                    success: function (data) {
                        $loading_container.hide();
                        $results_container.html(data);
                    }
                });
                $vote_container.fadeOut("fast", function () {
                    $results_container.fadeIn("fast");
                });
            };
        });
    };
})(jQuery);
0 notes

Creeping line - my first jQuery plugin.


In my last project I had to write very simple web part control for SharePoint. It was creeping line. You have some div elements that have to go to top with animation smoothly and with some mouse events.

For your review, please, check it code:

// jquery.creeping.js
;(function($) {

    var ver = "0.01";
    var author = "oivoodoo";

    function debug(s) {
        if ($.fn.cycle.debug)
            log(s);
    }

    function log() {
        if (window.console && window.console.log)
            window.console.log('[creeping] ' + Array.prototype.join.call(arguments, ' '));
    };

    $.fn.creeping = function(options, arg2) {
        var o = { s: this.selector, c: this.context };

        if (this.length === 0 && options != 'stop') {
            if (!$.isReady && o.s) {
                log('DOM not ready, queuing creeping line');
                $(function() {
                    $(o.s, o.c).creeping(options, arg2);
                });
                return this;
            }
            log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
            return this;
        }

        return this.each(function() {
            var $cont = $(this);
            var $height = $cont.height();
            var $iteration = 0;
            $cont.parent().css('display', 'block').css('height', options.height).css('overflow', 'hidden').css('position', 'relative');
            $cont.css('position', 'relative');

            var maxSize = $cont.children().length * ($height - options.height);

            $cont.mouseover(function() {
                $cont.clearQueue().stop().delay(1500);
            });
            $cont.mouseout(function() {
                start_animation();
            });
            function start_animation() {
                $cont.animate({ top: '-' + maxSize +'px' }, 60000, 'linear', function() {
                    $cont.animate({ top: (options.height - 100) + 'px' }, 4000, 'linear', function() {
                        start_animation();
                    });
                }).delay(options.delay);
            };

            start_animation();
        });
    };
})(jQuery);
1 note

Convert HTML to HAML snippet.

Not for along time ago I’ve started to use haml syntax for quickly writing html code for rails applications. But in one day I received for applying any changes existence rails 2.3.5 application written using the standard html.erb templates for views.
I start to search how to change current html.erb to haml code and I found!!!

$> find . -name '*erb' | \
xargs ruby -e 'ARGV.each { |i| puts "html2haml -r #{i} #{i.sub(/erb$/,"haml")}"}' | \
bash

This is great script I’ve found in the next following link -> great snippet

0 notes