9 ms·
How To Write A Calculator in 70 Python Lines
- philfreo 14y agoHow to Write a Calculator in 1 Python Line print input() > 25*4-50 > 50
- edwintorok 14y agoIt accepts more than just numbers though: >>> print input() "a"+"b" ab
- BerislavLopac 14y agoThe. Best. Comment. Ever. :-)
- prezjordan 14y ago...100? Your calculator seems broken :)
- philfreo 14y agohaha thanks, fixed
- waltz 14y agoor just 'python'
- erezsh 14y agoQ. How to write code? A. I don't need to; other people will write it for me. That's fine, I guess. I prefer to understand.
- pekk 14y agoHow to get things done? Use existing tools unless they are not suitable.
- gshubert17 14y agoOr, from a bash command line, $ python -c "print input('> ')" > 2+3*5 17
- andrewcooke 14y agothis reminded me of something similar i did (i'm afraid my recursive decent parser is probably more opaque) - differentiating numerical expressions in python. http://www.acooke.org/cute/Differenti0.html http://www.acooke.org/cute/Differenti0.html
- ivan_ah 14y agoVery cool. Thanks for the cool post. I am not sure I got the difference between the LL and LR parser. Is what you have above an LR parser? Also, why did you choose to represent both + and - as "ADD" tokens (and * and / as "MUL") is this to enforce evaluation priority? It would be interesting to see if you can add or ^ as an exponent for this calculator. Maybe you intended this post strictly as as an educational post, but I think doing parsing right (and from first principles) is a really cool thing to have. Check out how khan-exercises framework uses to parse math expressions into an AST: https://github.com/Khan/khan-exercises/blob/master/utils/math-model.js https://github.com/Khan/khan-exercises/blob/master/utils/mat...
- erezsh 14y agoAn LR-parser tries to reduce the input over and over again into rules, eventually ending with the 'start' rule. So a+b+c+d becomes [add]+c+d -> [add]+d -> [add] -> [start] An LL-parser tries to expand the initial rule into a more complex rule structure, until it matches the input. So to match a+b+c+d it will do [start] -> [add] -> [add] + [num] -> [add] + [num] + [num] -> etc. What I wrote is an LL-parser, simply because it's much much simpler to write and to understand. Yes, both ADD and MUL are used for precedence. Since any list of +- or of */ will evaluate correctly if reduced from left to right, I didn't mind grouping them together and making my life easier (and shorter). It was strictly educational, and also a shtick; a short code hack. If I was to write an actual parser (and I don't think I would ever try to), it would look very different!
- piqufoh 14y agoThis article seems rather un-Zen >>> import this ... though rules are made to be broken
- erezsh 14y agoWhy is it un-zen?
- gbog 14y agoI think it is not too unzen in its aim and method but if you ask there many little tricks that I'd say are unzen. First, give all the code a pass of autopep8 comb. Second, avoid things like "lambda (op,num): (num, -num)[...], just use "x if y else z" Then you wouldn't be too far from Norvig's little educational gems.
- erezsh 14y agoI suppose I got carried away with the lambdas :) Thank you, you gave me a great compliment. Norvig's short spellchecker was very inspirational for me.
- gusgordon 14y agoI wonder if there's a way to add algebraic equation solving to this, or something like it, easily.
- lutusp 14y agoNot easily, and not in 70 lines. But there's the Python library "sympy" which can do symbolic algebraic equation solving (and many other things): from sympy import * var('x,b,c') print solve(a*x**2+b*x+c,x) Result: [(-b + (-4*a*c + b**2)**(1/2))/(2*a), -(b + (-4*a*c + b**2)**(1/2))/(2*a)]
- abecedarius 14y agoVery nicely done! I think a precedence parser could be even shorter, though I don't seem to have one handy in Python. Pratt parsing is similar, though: https://github.com/darius/sketchbook/blob/master/parsing/pratt.py https://github.com/darius/sketchbook/blob/master/parsing/pra... And here's precedence parsing in C: http://wry.me/~darius/hacks/dcalc.c http://wry.me/~darius/hacks/dcalc.c (I learned this method from Dave Gillespie, author of Gnu Calc.) Finally, using a small parsing library very similar to the scheme in this post: https://github.com/darius/peglet/blob/master/examples/infix.py https://github.com/darius/peglet/blob/master/examples/infix....
- coolSCV 14y agoThe calculator seems to miss the point of recursive descent parsing. The parser should follow naturally from the grammar. As an example, here is a 52 line python calculator: https://gist.github.com/ascv/5022712 https://gist.github.com/ascv/5022712 The idea isn't to 1-up the OP but rather to showcase the technique of recursive descent parsing. The wikipedia entry for recursive descent parsing also has a very nice example.
- erezsh 14y agoWell, to be fair, your calculator seems to miss the point of being a calculator... > 10/2*2 2.5
- coolSCV 14y agoClearly a bug. Thanks when I have more time I will fix it. I didn't give much thought to operator precedence, I assumed the user would specify it using parentheses. The idea is what is important though. Recursive descent parsing uses the functions that correspond to types in the grammar to mutually call each other thus parsing the expression recursively in a descending fashion.
- coolSCV 14y agoI decided to simply add to the description, "use parentheses to specify operator precedence."
- deleted 14y ago[deleted]
- tiziano88 14y agoFYI this http://www.imgur.com/5Ge93Xc.png http://www.imgur.com/5Ge93Xc.png is what it looks like on my Nexus 4, perhaps it's worth considering a more mobile-friendly layout ;)
- vladoh 14y agoHere is a similar calculator implemented in 58 languages including in 16 lines of Python code :) http://www.math.bas.bg/bantchev/place/rpn/rpn.impl.html http://www.math.bas.bg/bantchev/place/rpn/rpn.impl.html
- konstruktor 14y agoThis is an RPN calculator, which means you can basically execute the input using the token stream directly. TFA shows executing a context free language, which requires parsing, explaining the program being an order of magnitude larger.
- deleted 14y ago[deleted]