calculator.py

Tue, 12 Jan 2016 21:14:26 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Tue, 12 Jan 2016 21:14:26 +0200
changeset 165
8131cf387e3d
parent 164
e18f73e4c2e2
permissions
-rw-r--r--

Be compatible with Mercurial 2.2.2. Thanks, Debian...

124
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
1 '''
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
2 Copyright 2015 Teemu Piippo
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
3 All rights reserved.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
4
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
5 Redistribution and use in source and binary forms, with or without
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
6 modification, are permitted provided that the following conditions
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
7 are met:
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
8
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
9 1. Redistributions of source code must retain the above copyright
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
10 notice, this list of conditions and the following disclaimer.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
11 2. Redistributions in binary form must reproduce the above copyright
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
12 notice, this list of conditions and the following disclaimer in the
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
13 documentation and/or other materials provided with the distribution.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
14 3. The name of the author may not be used to endorse or promote products
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
15 derived from this software without specific prior written permission.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
16
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
27 '''
7b2cd8b1ba86 - now with extra license headers
Teemu Piippo <crimsondusk64@gmail.com>
parents: 123
diff changeset
28
146
c17b82b1f573 Mercurial handling major overhaul. Also get some stuff ready for Python 3
Teemu Piippo <tsapii@utu.fi>
parents: 137
diff changeset
29 from __future__ import print_function
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
30 import re
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
31 import cmath
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
32 import math
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
33 import random
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
34 import time
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
35 import operator
125
c44b1aa85257 - added hex support to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 124
diff changeset
36 import string
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
37 from fraction import Fraction
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
38 from copy import deepcopy
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
39 from math import pi as π
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
40
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
41 ε = 1e-10
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
42
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
43 class Operator (object):
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
44 def __init__ (self, name, symbol, operands, priority, function, assign):
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
45 self.name = name
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
46 self.symbol = symbol
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
47 self.operands = operands
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
48 self.priority = priority
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
49 self.function = function
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
50 self.assign = assign
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
51
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
52 def __repr__ (self):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
53 return '<operator %s>' % (self.name)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
54 """return ('Operator(name={name}, symbol={symbol}, operands={operands}, '
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
55 'priority={priority}, function={function})'.format(**self.__dict__))"""
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
56
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
57 class FunctionCall (object):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
58 def __init__ (self, funcname, args):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
59 assert (type(args) is list)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
60 self.funcname = funcname
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
61 self.args = args
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
62
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
63 def __repr__ (self):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
64 return '''FunctionCall(%r, %r)''' % (self.funcname, self.args)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
65
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
66 class Value (object):
137
Teemu Piippo <crimsondusk64@gmail.com>
parents: 136
diff changeset
67 def __init__ (self, value):
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
68 if isinstance (value, Fraction) and value.denominator == 1:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
69 value = value.numerator
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
70 self.value = value
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
71
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
72 def __repr__ (self):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
73 return '''Value(%r)''' % (self.value)
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
74
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
75 class Name (object):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
76 def __init__ (self, name):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
77 self.name = name
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
78
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
79 def __repr__ (self):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
80 return '''Name(%r)''' % (self.name)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
81
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
82 class AssignmentResult (object):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
83 def __init__ (self, name, value):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
84 self.name, self.value = name, value
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
85
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
86 def __repr__ (self):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
87 return '''AssignmentResult(%r, %r)''' % (self.name, self.value)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
88
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
89 def do_realf (func, *args):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
90 for x in args:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
91 if x.imag:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
92 raise ValueError ('%s called with a complex number' % func.__name__)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
93
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
94 return func (*[x.real for x in args])
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
95
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
96 def do_intf (func, *args):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
97 for x in args:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
98 if x.imag:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
99 raise ValueError ('%s called with a complex number' % func.__name__)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
100
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
101 if x.real - math.floor (x.real):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
102 raise ValueError ('%s called with a floating point number' % func.__name__)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
103
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
104 return func (*[int (x.real) for x in args])
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
105
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
106 def realf (func):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
107 return lambda *args: do_realf (func, *args)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
108
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
109 def intf (func):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
110 return lambda *args: do_intf (func, *args)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
111
134
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
112 def dice (numRolls, maxValue):
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
113 sumValue = 0
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
114
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
115 for i in range (0, numRolls):
152
1b734faab67a Port to Python 3
Teemu Piippo <crimsondusk64@gmail.com>
parents: 146
diff changeset
116 sumValue += random.randint (1, maxValue)
134
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
117
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
118 return sumValue
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
119
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
120 def scientific (mantissa, exp):
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
121 return mantissa * 10 ** exp
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
122
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
123 def cbrt (x):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
124 return x ** (1/3)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
125
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
126 def factorial (x):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
127 return math.gamma (x + 1)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
128
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
129 def is_int (x):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
130 return math.fabs (x - math.floor(x)) < ε
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
131
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
132 def div(a,b):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
133 if is_int(a) and is_int(b):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
134 return Fraction(a,b)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
135 else:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
136 return a / b
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
137
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
138 def assignment (name, value, calculator):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
139 calculator.variables[name.name] = value.value
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
140
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
141 Operators = {}
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
142 OperatorData = {
134
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
143 'not': { 'symbol': '!', 'operands': 1, 'priority': 5, 'function': lambda x: not x },
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
144 'compl': { 'symbol': '~', 'operands': 1, 'priority': 5, 'function': intf (operator.inv) },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
145 'neg': { 'symbol': '-', 'operands': 1, 'priority': 5, 'function': lambda x: -x },
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
146 'sqrt': { 'symbol': '√', 'operands': 1, 'priority': 7, 'function': cmath.sqrt },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
147 'cbrt': { 'symbol': '∛', 'operands': 1, 'priority': 7, 'function': cbrt },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
148 'fact': { 'symbol': '!', 'operands': -1, 'priority': 8, 'function': realf(factorial) },
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
149 'pow': { 'symbol': '**', 'operands': 2, 'priority': 10, 'function': lambda x, y: x ** y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
150 'mul': { 'symbol': '*', 'operands': 2, 'priority': 50, 'function': lambda x, y: x * y },
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
151 'div': { 'symbol': '/', 'operands': 2, 'priority': 50, 'function': div },
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
152 'mod': { 'symbol': '%', 'operands': 2, 'priority': 50, 'function': realf (math.fmod) },
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
153 'add': { 'symbol': '+', 'operands': 2, 'priority': 100, 'function': lambda x, y: x + y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
154 'sub': { 'symbol': '-', 'operands': 2, 'priority': 100, 'function': lambda x, y: x - y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
155 'eq': { 'symbol': '==', 'operands': 2, 'priority': 500, 'function': lambda x, y: x == y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
156 'neq': { 'symbol': '!=', 'operands': 2, 'priority': 500, 'function': lambda x, y: x != y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
157 'lt': { 'symbol': '<', 'operands': 2, 'priority': 500, 'function': lambda x, y: x < y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
158 'lteq': { 'symbol': '<=', 'operands': 2, 'priority': 500, 'function': lambda x, y: x <= y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
159 'gt': { 'symbol': '>', 'operands': 2, 'priority': 500, 'function': lambda x, y: x > y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
160 'gteq': { 'symbol': '>=', 'operands': 2, 'priority': 500, 'function': lambda x, y: x >= y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
161 'btand': { 'symbol': '&', 'operands': 2, 'priority': 600, 'function': intf (operator.and_) },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
162 'btxor': { 'symbol': '^', 'operands': 2, 'priority': 601, 'function': intf (operator.xor) },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
163 'btor': { 'symbol': '|', 'operands': 2, 'priority': 602, 'function': intf (operator.or_) },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
164 'and': { 'symbol': '&&', 'operands': 2, 'priority': 603, 'function': lambda x, y: x and y },
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
165 'or': { 'symbol': '||', 'operands': 2, 'priority': 604, 'function': lambda x, y: x or y },
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
166 'assign': { 'symbol': '=', 'operands': 2, 'priority': 999, 'function': assignment, 'assign':True },
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
167 }
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
168
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
169 def powerfunction (n):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
170 return lambda x: x**n
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
171
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
172 superscripts='⁰¹²³⁴⁵⁶⁷⁸⁹'
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
173 for i, sup in enumerate(superscripts):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
174 func = powerfunction(i)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
175 func.__name__ = 'x' + sup
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
176 OperatorData['sup' + str(i)] = { 'symbol': sup, 'operands': -1, 'priority': 3, 'function': func }
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
177
146
c17b82b1f573 Mercurial handling major overhaul. Also get some stuff ready for Python 3
Teemu Piippo <tsapii@utu.fi>
parents: 137
diff changeset
178 for name, data in OperatorData.items():
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
179 if 'assign' not in data:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
180 data['assign'] = False
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
181
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
182 Operators[name] = Operator (name=name, **data)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
183
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
184 OperatorSymbols={}
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
185 for op in Operators.values():
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
186 if op.symbol in OperatorSymbols:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
187 OperatorSymbols[op.symbol].append (op)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
188 else:
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
189 OperatorSymbols[op.symbol] = [op]
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
190
131
7349e9c6176b Added sgn(x) to .calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 130
diff changeset
191 def sgn (x):
164
e18f73e4c2e2 More Python 3 support
Teemu Piippo <crimsondusk64@gmail.com>
parents: 163
diff changeset
192 if abs(x) < 1e-10:
e18f73e4c2e2 More Python 3 support
Teemu Piippo <crimsondusk64@gmail.com>
parents: 163
diff changeset
193 return 0
e18f73e4c2e2 More Python 3 support
Teemu Piippo <crimsondusk64@gmail.com>
parents: 163
diff changeset
194 else:
e18f73e4c2e2 More Python 3 support
Teemu Piippo <crimsondusk64@gmail.com>
parents: 163
diff changeset
195 return x / abs(x)
131
7349e9c6176b Added sgn(x) to .calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 130
diff changeset
196
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
197 def integerclamp (x, bits, signed):
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
198 x = x % (2 ** bits)
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
199
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
200 if signed and x >= (2 ** (bits - 1)):
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
201 x = -(2 ** bits) + x
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
202
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
203 return x
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
204
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
205 Constants = {
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
206 'pi': π,
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
207 'e': math.,
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
208 'phi': 1.6180339887498948482,
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
209 'epsilon': ε,
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
210 }
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
211
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
212 random.seed (time.time())
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
213
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
214 Functions = {
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
215 'round': { 'function': realf (round) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
216 'floor': { 'function': realf (math.floor) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
217 'ceil': { 'function': realf (math.ceil) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
218 'factorial': { 'function': intf (math.factorial) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
219 'abs': { 'function': realf (math.fabs) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
220 'degrees': { 'function': realf (math.degrees) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
221 'radians': { 'function': realf (math.radians) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
222 'erf': { 'function': realf (math.erf) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
223 'erfc': { 'function': realf (math.erfc) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
224 'gamma': { 'function': realf (math.gamma) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
225 'lgamma': { 'function': realf (math.lgamma) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
226 'sqrt': { 'function': cmath.sqrt },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
227 'cbrt': { 'function': cbrt },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
228 'ln': { 'function': cmath.log },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
229 'log': { 'function': cmath.log10 },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
230 'sin': { 'function': cmath.sin },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
231 'sinh': { 'function': cmath.sinh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
232 'asin': { 'function': cmath.asin },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
233 'asinh': { 'function': cmath.asinh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
234 'cos': { 'function': cmath.cos },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
235 'cosh': { 'function': cmath.cosh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
236 'acos': { 'function': cmath.acos },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
237 'acosh': { 'function': cmath.acosh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
238 'tan': { 'function': cmath.tan },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
239 'tanh': { 'function': cmath.tanh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
240 'atan': { 'function': cmath.atan },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
241 'atanh': { 'function': cmath.atanh },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
242 'exp': { 'function': cmath.exp },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
243 'phase': { 'function': cmath.phase },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
244 'lg': { 'function': lambda x: cmath.log (x, 2) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
245 're': { 'function': lambda x: x.real },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
246 'im': { 'function': lambda x: x.imag },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
247 'conjugate': { 'function': lambda x: x.conjugate() },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
248 'rand': { 'function': random.random },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
249 'sgn': { 'function': realf (sgn) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
250 'byte': { 'function': intf (lambda x: integerclamp (x, bits=8, signed=False)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
251 'sbyte': { 'function': intf (lambda x: integerclamp (x, bits=8, signed=True)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
252 'word': { 'function': intf (lambda x: integerclamp (x, bits=16, signed=False)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
253 'sword': { 'function': intf (lambda x: integerclamp (x, bits=16, signed=True)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
254 'dword': { 'function': intf (lambda x: integerclamp (x, bits=32, signed=False)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
255 'sdword': { 'function': intf (lambda x: integerclamp (x, bits=32, signed=True)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
256 'qword': { 'function': intf (lambda x: integerclamp (x, bits=64, signed=False)) },
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
257 'sqword': { 'function': intf (lambda x: integerclamp (x, bits=64, signed=True)) },
162
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
258 'cdf': { 'function': realf (lambda x: (1 + math.erf (x / math.sqrt(2))) / 2) },
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
259 }
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
260
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
261 Tokens = {'(', ')'}
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
262
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
263 # Symbol table
163
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
264 class SymbolType:
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
265 constant = 0
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
266 function = 1
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
267 operator = 2
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
268 token = 3
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
269 SymbolTypes = {}
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
270 Symbols = {'ans'}
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
271 SymbolTypes['ans'] = SymbolType.constant
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
272
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
273 Aliases = {
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
274 'π': 'pi',
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
275 'ℯ': 'e',
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
276 'φ': 'phi',
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
277 'ε': 'epsilon',
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
278 '∨': '||',
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
279 '∧': '&&',
162
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
280 'Φ': 'cdf',
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
281 }
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
282
146
c17b82b1f573 Mercurial handling major overhaul. Also get some stuff ready for Python 3
Teemu Piippo <tsapii@utu.fi>
parents: 137
diff changeset
283 for name, value in Constants.items():
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
284 Symbols.add (name)
152
1b734faab67a Port to Python 3
Teemu Piippo <crimsondusk64@gmail.com>
parents: 146
diff changeset
285 SymbolTypes[name] = SymbolType.constant
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
286
146
c17b82b1f573 Mercurial handling major overhaul. Also get some stuff ready for Python 3
Teemu Piippo <tsapii@utu.fi>
parents: 137
diff changeset
287 for name, data in Functions.items():
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
288 Symbols.add (name)
152
1b734faab67a Port to Python 3
Teemu Piippo <crimsondusk64@gmail.com>
parents: 146
diff changeset
289 SymbolTypes[name] = SymbolType.function
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
290
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
291 for op in Operators.values():
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
292 if op.symbol not in Symbols:
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
293 Symbols.add (op.symbol)
152
1b734faab67a Port to Python 3
Teemu Piippo <crimsondusk64@gmail.com>
parents: 146
diff changeset
294 SymbolTypes[op.symbol] = SymbolType.operator
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
295
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
296 for name in Tokens:
152
1b734faab67a Port to Python 3
Teemu Piippo <crimsondusk64@gmail.com>
parents: 146
diff changeset
297 SymbolTypes[name] = SymbolType.token
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
298
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
299 Symbols |= Tokens
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
300 Symbols |= set(Aliases.keys())
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
301 Symbols = sorted (Symbols, key=lambda x: len (x), reverse=True)
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
302 PreferredBase = 10
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
303
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
304 def set_preferred_base(x):
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
305 global PreferredBase
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
306 PreferredBase = x
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
307
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
308 def rindex (li, value):
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
309 return (len(li) - 1) - li[::-1].index(value)
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
310
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
311 Attributes = {
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
312 'hex': lambda self: self.set_preferred_base (0x10),
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
313 'binary': lambda self: self.set_preferred_base (0b10),
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
314 'decimal': lambda self: self.set_preferred_base (10),
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
315 }
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
316
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
317 Attributes['bin'] = Attributes['binary']
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
318 Attributes['dec'] = Attributes['decimal']
162
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
319 AttributeNames = sorted ((key for key in Attributes), key=lambda x:len(x), reverse=True)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
320
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
321 def is_int (x):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
322 return math.fabs (x - math.floor(x)) < ε
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
323
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
324 identifierchars = set(string.ascii_lowercase + string.ascii_uppercase + string.digits + '_')
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
325 def is_identifier(x):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
326 return x and (x[0] not in string.digits) and (set(x) - identifierchars == set())
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
327
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
328 class Calculator (object):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
329 def __init__ (self, verbose=False):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
330 self.previous_result = None
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
331 self.preferred_base = None
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
332 self.verbose = verbose
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
333 self.variables = {}
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
334 self.namepattern = re.compile (r'^([A-Za-z_][A-Za-z0-9_]*)')
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
335
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
336 def set_preferred_base (self, x):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
337 self.preferred_base = x
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
338
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
339 def trim_spaces (self, expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
340 return re.sub ('\s+', '', expr.strip())
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
341
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
342 def parse_attributes (self, expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
343 if expr[0] != '<':
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
344 return expr
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
345
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
346 i = 1
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
347 while expr[i] != '>':
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
348 if expr[i] == '|':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
349 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
350
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
351 for name in AttributeNames:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
352 if expr[i:i + len(name)] == name:
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
353 Attributes[name] (self)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
354 i += len(name)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
355
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
356 if expr[i] == '>':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
357 break
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
358
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
359 if expr[i] != '|':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
360 raise ValueError ('malformed attributes')
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
361 break
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
362 else:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
363 raise ValueError ('bad attributes: %s' % expr[i:])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
364
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
365 return expr[i + 1:]
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
366
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
367 def parse_number (self, expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
368 """Tries to parse a number from the expression. Returns (value, length) on success."""
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
369 i = 0
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
370 value = None
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
371 base = 10
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
372
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
373 # Possibly it's hexadecimal
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
374 if expr[0:2].lower() == '0x':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
375 base = 0x10
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
376 digits = string.hexdigits
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
377 digitname = 'hexit'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
378 i = 2
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
379 elif expr[0:2].lower() == '0b':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
380 base = 0b10
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
381 digits = ['0', '1']
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
382 digitname = 'bit'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
383 i = 2
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
384
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
385 if base != 10:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
386 if not self.preferred_base:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
387 self.preferred_base = base
134
7316dc5f61ef Added scientific notation and dice expressions (cheaply as operators)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 132
diff changeset
388
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
389 # Skip leading zeroes
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
390 while i < len (expr) and expr[i] == '0':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
391 i += 1
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
392
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
393 startingIndex = i
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
394 while i < len (expr) and expr[i] in digits:
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
395 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
396
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
397 if i < len(expr) and expr[i] == '.':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
398 raise ValueError ('non-decimal floating point numbers are not supported')
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
399
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
400 if i == startingIndex:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
401 if i < len (expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
402 raise ValueError ('not a valid %s "%s" in %s' % (digitname, expr[i], expr[0:i+1]))
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
403 else:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
404 raise ValueError ('end of expression encountered while parsing '
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
405 'base-%d literal' % base)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
406
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
407 return (Value (int (expr[startingIndex:i], base)), i)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
408
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
409 if expr[0] == 'i' or expr[0] == 'ι':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
410 # Special case, we just have 'i' -- need special handling here because otherwise this would
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
411 # call float('') in the complex number routine, which throws an error.
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
412 return (Value(1j), 1)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
413
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
414 # Try parse increasingly long substrings until we are unable to create a float or complex number
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
415 # from it.
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
416 try:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
417 while i < len (expr):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
418 if expr[i] == 'i' or expr[i] == 'ι':
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
419 value = Value (float (expr[:i]) * 1j)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
420 else:
136
3812bfce21e0 Use a value class
Teemu Piippo <crimsondusk64@gmail.com>
parents: 135
diff changeset
421 value = Value (float (expr [:i + 1]))
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
422 i += 1
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
423
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
424 return (value, i)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
425 except ValueError:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
426 if i != 0:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
427 # Got a number (the error happened when we tried to parse past the number)
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
428 return (value, i)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
429 else:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
430 # The error happened on the first character. So this is not a number.
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
431 return None
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
432
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
433 def parse_symbol (self, expr):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
434 for sym in Symbols:
162
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
435 if len(sym) == 1 and ord(sym) > 256:
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
436 if expr[0] == sym:
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
437 return sym
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
438 else:
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
439 if expr[:len (sym)].lower() == sym.lower():
d24fe5e3e420 Added cdf (aka Φ(x)) to the calculator, removed unneeded list comprehensions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 161
diff changeset
440 return sym.lower()
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
441
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
442 return None
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
443
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
444 def tokenize (self, expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
445 i=0
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
446 tokens = []
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
447
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
448 while i < len(expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
449 sym = self.parse_symbol (expr[i:])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
450
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
451 if sym:
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
452 i += len(sym)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
453 if sym in Aliases:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
454 sym = Aliases[sym]
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
455
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
456 if sym == 'ans':
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
457 if self.previous_result is None:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
458 raise ValueError ('Cannot use "ans" because there is no prior result')
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
459 tokens.append (Value (self.previous_result))
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
460 else:
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
461 symtype = SymbolTypes[sym]
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
462 if symtype == SymbolType.constant:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
463 tokens.append (Value(Constants[sym]))
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
464 else:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
465 tokens.append (sym)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
466 continue
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
467
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
468 result = self.parse_number (expr[i:])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
469 if result:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
470 num, length = result
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
471 tokens.append (num)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
472 i += length
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
473 continue
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
474
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
475 match = self.namepattern.match (expr[i:])
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
476 if match:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
477 name = match.group(1)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
478 i += len(name)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
479 tokens.append (Name(name))
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
480 continue
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
481
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
482 raise ValueError ("""couldn't parse: %s""" % expr[i:])
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
483
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
484 return tokens
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
485
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
486 def process_parens (self, expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
487 """Processes parentheses of expr into sublists in-place.
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
488 [1.0, '*', '(', 3.5, '+', 1j, ')']
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
489 -> [1.0, '*', [3.5, '+', 1j]]"""
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
490 if '(' not in expr and ')' not in expr:
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
491 return
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
492
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
493 try:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
494 parenStart = rindex (expr, '(')
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
495 parenEnd = expr.index (')', parenStart)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
496 except ValueError:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
497 raise ValueError ("""mismatched parentheses in expression: %s""" % expr)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
498
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
499 subexpr = expr[parenStart + 1:parenEnd]
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
500 del expr[parenStart + 1:parenEnd + 1]
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
501 expr[parenStart] = subexpr
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
502 self.process_parens (expr)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
503
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
504 def process_functions (self, expr):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
505 """Processes functions in-place"""
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
506 i = 0
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
507 while i < len (expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
508 if type (expr[i]) is list:
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
509 self.process_functions (expr[i])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
510
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
511 if (type(expr[i]) is not str) or (expr[i] not in Functions):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
512 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
513 continue
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
514
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
515 # Ensure that arguments follow
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
516 if (i + 1 >= len (expr)) or (type (expr[i + 1]) is not list):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
517 raise ValueError ("""function %s used without arguments""" % expr[i])
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
518
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
519 args = expr[i + 1]
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
520 del expr[i + 1]
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
521 expr[i] = FunctionCall (expr[i], args)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
522 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
523
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
524 def process_variables (self, expr):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
525 for i, x in enumerate(expr):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
526 if isinstance(x, list):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
527 self.process_variables(x)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
528 elif isinstance(x, Name):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
529 try:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
530 expr[i].value = Value(self.variables[x.name])
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
531 except KeyError as e:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
532 pass
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
533
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
534 def is_operand (self, x):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
535 # Operands can be either lists (which also mean parens, thus can be single-expressions)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
536 # or complex numbers
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
537 return type(x) in [list, FunctionCall, Value, Name]
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
538
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
539 def find_fitting_operator (self, sym, numOperands):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
540 # Pass 1: exact numOperands match
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
541 foundByName = False
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
542 for op in Operators.values():
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
543 if op.symbol != sym:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
544 continue
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
545
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
546 foundByName = True
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
547 if op.operands == numOperands:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
548 return op
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
549
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
550 if foundByName:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
551 raise ValueError ('''Operator %s used incorrectly''' % sym)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
552 else:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
553 raise ValueError ('''unknown operator %s!''' % sym)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
554
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
555 def process_operators (self, expr):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
556 """Processes operators"""
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
557 i = 0
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
558
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
559 # Find all operators in this expression
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
560 while i < len (expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
561 if type (expr[i]) is list:
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
562 self.process_functions (expr[i])
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
563 self.process_operators (expr[i])
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
564
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
565 if type (expr[i]) is FunctionCall:
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
566 self.process_functions (expr[i].args)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
567 self.process_operators (expr[i].args)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
568
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
569 if (type(expr[i]) is not str) or (expr[i] not in OperatorSymbols):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
570 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
571 continue
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
572
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
573 # Test for suffix operators
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
574 if i > 0 and self.is_operand (expr[i - 1]):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
575 try:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
576 op = self.find_fitting_operator (expr[i], -1)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
577 except:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
578 pass
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
579 else:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
580 expr[i] = op
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
581 continue
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
582
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
583 args = []
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
584 argIndices = []
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
585 if i > 0 and self.is_operand (expr[i - 1]):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
586 args.append (expr[i - 1])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
587 argIndices.append (i - 1)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
588
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
589 if i + 1 < len(expr) and self.is_operand (expr[i + 1]):
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
590 args.append (expr[i + 1])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
591 argIndices.append (i + 1)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
592
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
593 # Resolve operators with the same symbol based on operand count
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
594 numOperands = 0
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
595 for arg in args:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
596 if self.is_operand (arg):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
597 numOperands += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
598
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
599 expr[i] = self.find_fitting_operator (expr[i], numOperands)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
600 i += 1
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
601
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
602 def amend_multiplication (self, expr):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
603 i = 0
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
604 while i + 1 < len(expr):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
605 if self.is_operand (expr[i]) and self.is_operand (expr[i + 1]):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
606 expr.insert(i + 1, Operators['mul'])
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
607 i += 2
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
608 else:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
609 i += 1
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
610
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
611 # Also amend multiplication in sub-expressions
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
612 for x in expr:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
613 if isinstance(x, list):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
614 self.amend_multiplication(x)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
615
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
616 def find_priority_operator (self, expr):
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
617 """Finds the operator with most priority in the expression"""
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
618 bestOp = None
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
619 bestOpIndex = -1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
620
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
621 for i in range (0, len (expr)):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
622 sym = expr[i]
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
623
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
624 if type (sym) is not Operator:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
625 continue
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
626
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
627 if not bestOp or sym.priority < bestOp.priority:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
628 bestOp = sym
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
629 bestOpIndex = i
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
630
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
631 return (bestOp, bestOpIndex)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
632
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
633 def process_values (self, values):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
634 result = []
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
635 for x in values:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
636 if isinstance (x, Name) and not hasattr (x, 'value'):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
637 raise ValueError ('%s is unknown' % (x.name))
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
638 value = x
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
639 while hasattr (value, 'value'):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
640 value = value.value
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
641 result.append (value)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
642 return result
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
643
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
644 def evaluate (self, expr, verbose=False):
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
645 printFunc = print if verbose else lambda x:None
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
646 printFunc (self.tabs + 'Preprocess: %s' % expr)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
647
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
648 # If there are sub-expressions in here, those need to be evaluated first
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
649 i = 0
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
650 while i < len (expr):
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
651 sym = expr[i]
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
652
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
653 if type (sym) is list and sym:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
654 printFunc (self.tabs + 'Evaluating sub-expression: %s' % (sym))
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
655 self.tabs += '\t'
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
656 expr[i] = self.evaluate (list (sym), verbose)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
657 self.tabs = self.tabs[:-1]
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
658 printFunc (self.tabs + '-> %s' % expr[i])
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
659
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
660 # If there are function calls, evaluate those
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
661 if type (sym) is FunctionCall:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
662 self.tabs += '\t'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
663 if sym.args:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
664 sym.args = [self.evaluate (sym.args, verbose)]
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
665 self.tabs = self.tabs[:-1]
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
666
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
667 printFunc (self.tabs + 'Evaluating function call: %s' % (sym))
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
668 expr[i] = Value (Functions[sym.funcname]['function'] (*self.process_values(sym.args)))
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
669 printFunc (self.tabs + '-> %s' % expr[i])
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
670
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
671 i += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
672
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
673 printFunc (self.tabs + 'Evaluate: %s' % expr)
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
674 runaway = 0
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
675 while True:
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
676 runaway += 1
127
66b206bd9510 Cranked up the runaway (8 was only for testing)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 126
diff changeset
677 if runaway > 1000:
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
678 raise ValueError ('infinite loop detected')
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
679
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
680 op, i = self.find_priority_operator (expr)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
681 if not op:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
682 break
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
683
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
684 if op.operands == 2:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
685 argIndices = [i - 1, i + 1]
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
686 elif op.operands == -1:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
687 argIndices = [i - 1]
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
688 else:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
689 argIndices = [i + 1]
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
690
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
691 args = [expr[x] for x in argIndices]
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
692 argIndices = sorted (argIndices, reverse=True)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
693 printFunc (self.tabs + 'Processing: (%s, %d) with args %s' % (op, i, args))
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
694 if op.assign:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
695 op.function (*args, calculator=self)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
696 expr[i] = AssignmentResult(name=args[0], value=Value(self.variables[args[0].name]))
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
697 else:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
698 expr[i] = Value (op.function (*self.process_values(args)))
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
699 printFunc (self.tabs + '-> %s' % expr[i])
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
700
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
701 for i2 in argIndices:
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
702 del expr[i2]
126
0fc519afba89 - added binary support for calc
Teemu Piippo <crimsondusk64@gmail.com>
parents: 125
diff changeset
703
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
704 if op.assign and len(expr) != 1:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
705 raise ValueError ('expression did not evaluate into an assignment: %s' % expr)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
706
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
707 printFunc (self.tabs + 'Result: %s' % expr[0])
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
708
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
709 if len(expr) != 1:
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
710 printFunc (self.tabs + 'Bad expression detected, tokens: %s' % expr)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
711 raise ValueError ('malformed expression')
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
712
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
713 return expr[0]
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
714
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
715 def repr_number (self, x):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
716 """Returns a string representation for a real number"""
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
717 base = self.preferred_base if self.preferred_base else 10
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
718 if is_int (x) and base != 10:
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
719 digits='0123456789abcdef'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
720 assert base <= len (digits), '''base %d is too large''' % base
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
721
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
722 divisor = base
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
723 rep = ''
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
724 x = int (x)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
725 runaway = 0
125
c44b1aa85257 - added hex support to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 124
diff changeset
726
135
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
727 if not x:
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
728 return '0x0'
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
729
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
730 if x < 0:
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
731 return '-' + self.repr_number (abs (x))
ad27ab7e6fb6 Added 8 integer clamping functions
Teemu Piippo <crimsondusk64@gmail.com>
parents: 134
diff changeset
732
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
733 while x > 0:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
734 runaway += 1
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
735 if runaway > 1000:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
736 raise ValueError('runaway triggered')
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
737
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
738 i = (x % divisor) / (divisor / base)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
739 x -= i * (divisor / base)
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
740 rep += digits[i]
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
741 divisor *= base
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
742
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
743 rep += 'x' if base == 16 else 'b'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
744 rep += '0'
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
745 return rep[::-1]
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
746
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
747 rep = '%.10f' % x
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
748
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
749 if '.' in rep:
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
750 while rep[-1] == '0':
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
751 rep = rep[:-1]
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
752
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
753 if rep[-1] == '.':
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
754 rep = rep[:-1]
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
755
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
756 return rep
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
757
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
758 def repr_imaginary (self, x):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
759 rep = self.repr_number (x)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
760
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
761 if rep == '1':
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
762 return 'i'
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
763 elif rep == '-1':
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
764 return '-i'
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
765 else:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
766 return rep + 'i'
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
767
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
768 def represent (self, x):
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
769 """Returns a string representation of a float or complex number"""
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
770 if isinstance (x, Value):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
771 x = x.value
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
772 if isinstance (x, Fraction):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
773 return '%s / %s' % (x.numerator, x.denominator)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
774 elif math.fabs (x.imag) > ε:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
775 if math.fabs (x.real) > ε:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
776 # Complex number
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
777 return '%s %s %s' % (self.repr_number (x.real),
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
778 '+' if x.imag >= 0 else '-',
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
779 self.repr_imaginary (math.fabs (x.imag)))
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
780 else:
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
781 # Pure imaginary number
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
782 return self.repr_imaginary (x.imag)
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
783 else:
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
784 # Real number
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
785 return self.repr_number (x.real)
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
786 elif isinstance (x, AssignmentResult):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
787 return '%s = %s' % (x.name.name, self.represent (x.value))
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
788 elif isinstance (x, Name) and hasattr(x, 'value'):
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
789 return self.represent(x.value)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
790 else:
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
791 return '<%s %s>' % (type(x).__name__, x)
123
aeb0d0788869 - added commits.db and mercurial support restructure
Teemu Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
792
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
793 def calc (self, expr, verbose=None):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
794 if verbose is None:
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
795 verbose = self.verbose
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
796 self.state = {}
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
797 self.tabs = ''
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
798 expr = self.trim_spaces (expr)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
799 expr = self.parse_attributes (expr)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
800 expr = self.tokenize (expr)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
801 self.process_parens (expr)
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
802 self.process_functions (expr)
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
803 self.process_variables (expr)
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
804 self.amend_multiplication (expr)
130
c82cef747008 - reverted previous commit (now that was a bad idea)
Teemu Piippo <crimsondusk64@gmail.com>
parents: 129
diff changeset
805 self.process_operators (expr)
161
6e7cb38f248d Calculator now supports variables
Teemu Piippo <crimsondusk64@gmail.com>
parents: 160
diff changeset
806 result = self.evaluate (expr, verbose)
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
807 self.previous_result = result
128
bd949c554dd2 Major refactor: moved calculator routines into a Calculator class.
Teemu Piippo <crimsondusk64@gmail.com>
parents: 127
diff changeset
808 return self.represent (result)
160
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
809
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
810 def __call__ (self, expr):
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
811 return self.calc (expr)
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
812
0ee4ff913747 Update to the calculator
Teemu Piippo <crimsondusk64@gmail.com>
parents: 152
diff changeset
813 calc = Calculator()
163
ed3d52b37f19 Remove use of enum in the calculator to drop minimum required version
Teemu Piippo <crimsondusk64@gmail.com>
parents: 162
diff changeset
814 dcalc = Calculator(verbose=True)

mercurial