snipt

Ctrl+h for KB shortcuts

Python

math_solver.py

#!/usr/bin/python

# globals
verbose = False # set to True if you want debug info printed
max_iter = 1000 # this stops infinate loops incase the code does not allow for some input

def solve(problem_str):
    """
    This task was to create a program that can process simple maths equations 
    without the use of any external libraries, lambdas, eval() etc. See Stack 
    Overflow question here for more details:
    http://stackoverflow.com/questions/21573436/solving-math-in-python-without-any-built-in-eval-functions-or-external-libraries/21580431#21580431
    """
    
    def multiply(arg_list):
        x = 1
        for i in arg_list:
            x *= i
        return x

    def find_innermost(x_str):
        a, b, c = [-1], [0], 0
        while True:
            start = a[-1]+1 # get position just after last opening bracket as start
            a.append(x_str.find('(', start)) # find next (
            b.append(x_str.find(',', start)) # find next ,
            c = x_str.find(')', start)       # find next )
            # if closing bracket is first or no more opening brackets left
            if (a[-1] > c) or (a[-1] == -1): 
                 # add to this to allow for more than 2 args by getting last comma before )?
                if (b[-2] > a[-3]) and (b[-2] < a[-2]): 
                    # if there is a comma between opening brackets 2 & 3 steps ago
                    return x_str[b[-2]+1:c+1] 
                else:
                    return x_str[a[-3]+1:c+1] 
            if len(a) > max_iter:
                raise Exception("Stuck in find_innermost loop")

    def do_sum(x_str):
        # get function arguements as integers from command string
        args = [int(x) for x in x_str[x_str.find('(')+1:x_str.find(')')].split(',')]
        task = x_str[:3].lower() # get function to be performed from command string
        if task == 'add':
            return sum(args)
        elif task == 'sub':
            return args[0] - sum(args[1:])
        elif task == 'abs':
            if len(args) > 1:
                raise Exception("Only one arguement can be supplied for abs() function")
            return abs(args.pop())
        elif task == 'mul':
            return multiply(args)
        else:
            print x_str + ': Task not recognised, please modify program or input'
            raise Exception("Invalid input")
    
    # solve function starts here...
    i = 0
    while True:
        i += 1
        if verbose: print 'debug: problem_str:', problem_str
        # find innermost nested problem if >1 opening bracket...
        if problem_str.count('(') > 1:
            x_str = find_innermost(problem_str)
        else:
            x_str = problem_str
        if verbose: print '.'*6, 'x_str:\t', x_str
        # process individual problem extracted from string...
        x = do_sum(x_str)
        if verbose: print '.'*6, 'x:\t', x, '\n'
        # replace individual problem with solution in full problem string...
        problem_str = problem_str.replace(x_str, str(x))
        # return result if no problems remaining in string...
        if problem_str.count('(') == 0:
            return int(problem_str)
        if i >= max_iter:
            raise Exception("Stuck in main loop")
        

# test solve function...
p1 = 'abs(add(add(9465,38),multiply(add(63303,146),46)))'
p2 = 'abs(add(multiply(95,multiply(-1,multiply(13,18875))),multiply(-1,add(18293,26))))'
p3 = 'abs(add(subtract(add(add(151,26875),122),254),subtract(237,multiply(-1,56497))))'
r1, r2, r3 = solve(p1), solve(p2), solve(p3)
print 'p1 evaluates to:', r1
print 'p2 evaluates to:', r2
print 'p3 evaluates to:', r3

Description

Answer to stack overflow question here: http://stackoverflow.com/questions/21573436/solving-math-in-python-without-any-built-in-eval-functions-or-external-libraries/21580431#21580431
https://snipt.net/embed/f8bfb2f852c46b3d2cdc095c19e83bf3/
/raw/f8bfb2f852c46b3d2cdc095c19e83bf3/
f8bfb2f852c46b3d2cdc095c19e83bf3
python
Python
87
2019-08-24T04:43:06
True
False
False
/api/public/snipt/111349/
math_solverpy
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><a href="#L-1"> 1</a> <a href="#L-2"> 2</a> <a href="#L-3"> 3</a> <a href="#L-4"> 4</a> <a href="#L-5"> 5</a> <a href="#L-6"> 6</a> <a href="#L-7"> 7</a> <a href="#L-8"> 8</a> <a href="#L-9"> 9</a> <a href="#L-10">10</a> <a href="#L-11">11</a> <a href="#L-12">12</a> <a href="#L-13">13</a> <a href="#L-14">14</a> <a href="#L-15">15</a> <a href="#L-16">16</a> <a href="#L-17">17</a> <a href="#L-18">18</a> <a href="#L-19">19</a> <a href="#L-20">20</a> <a href="#L-21">21</a> <a href="#L-22">22</a> <a href="#L-23">23</a> <a href="#L-24">24</a> <a href="#L-25">25</a> <a href="#L-26">26</a> <a href="#L-27">27</a> <a href="#L-28">28</a> <a href="#L-29">29</a> <a href="#L-30">30</a> <a href="#L-31">31</a> <a href="#L-32">32</a> <a href="#L-33">33</a> <a href="#L-34">34</a> <a href="#L-35">35</a> <a href="#L-36">36</a> <a href="#L-37">37</a> <a href="#L-38">38</a> <a href="#L-39">39</a> <a href="#L-40">40</a> <a href="#L-41">41</a> <a href="#L-42">42</a> <a href="#L-43">43</a> <a href="#L-44">44</a> <a href="#L-45">45</a> <a href="#L-46">46</a> <a href="#L-47">47</a> <a href="#L-48">48</a> <a href="#L-49">49</a> <a href="#L-50">50</a> <a href="#L-51">51</a> <a href="#L-52">52</a> <a href="#L-53">53</a> <a href="#L-54">54</a> <a href="#L-55">55</a> <a href="#L-56">56</a> <a href="#L-57">57</a> <a href="#L-58">58</a> <a href="#L-59">59</a> <a href="#L-60">60</a> <a href="#L-61">61</a> <a href="#L-62">62</a> <a href="#L-63">63</a> <a href="#L-64">64</a> <a href="#L-65">65</a> <a href="#L-66">66</a> <a href="#L-67">67</a> <a href="#L-68">68</a> <a href="#L-69">69</a> <a href="#L-70">70</a> <a href="#L-71">71</a> <a href="#L-72">72</a> <a href="#L-73">73</a> <a href="#L-74">74</a> <a href="#L-75">75</a> <a href="#L-76">76</a> <a href="#L-77">77</a> <a href="#L-78">78</a> <a href="#L-79">79</a> <a href="#L-80">80</a> <a href="#L-81">81</a> <a href="#L-82">82</a> <a href="#L-83">83</a> <a href="#L-84">84</a> <a href="#L-85">85</a> <a href="#L-86">86</a> <a href="#L-87">87</a></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span id="L-1"><a name="L-1"></a><span class="ch">#!/usr/bin/python</span> </span><span id="L-2"><a name="L-2"></a> </span><span id="L-3"><a name="L-3"></a><span class="c1"># globals</span> </span><span id="L-4"><a name="L-4"></a><span class="n">verbose</span> <span class="o">=</span> <span class="bp">False</span> <span class="c1"># set to True if you want debug info printed</span> </span><span id="L-5"><a name="L-5"></a><span class="n">max_iter</span> <span class="o">=</span> <span class="mi">1000</span> <span class="c1"># this stops infinate loops incase the code does not allow for some input</span> </span><span id="L-6"><a name="L-6"></a> </span><span id="L-7"><a name="L-7"></a><span class="k">def</span> <span class="nf">solve</span><span class="p">(</span><span class="n">problem_str</span><span class="p">):</span> </span><span id="L-8"><a name="L-8"></a> <span class="sd">&quot;&quot;&quot;</span> </span><span id="L-9"><a name="L-9"></a><span class="sd"> This task was to create a program that can process simple maths equations </span> </span><span id="L-10"><a name="L-10"></a><span class="sd"> without the use of any external libraries, lambdas, eval() etc. See Stack </span> </span><span id="L-11"><a name="L-11"></a><span class="sd"> Overflow question here for more details:</span> </span><span id="L-12"><a name="L-12"></a><span class="sd"> http://stackoverflow.com/questions/21573436/solving-math-in-python-without-any-built-in-eval-functions-or-external-libraries/21580431#21580431</span> </span><span id="L-13"><a name="L-13"></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-14"><a name="L-14"></a> </span><span id="L-15"><a name="L-15"></a> <span class="k">def</span> <span class="nf">multiply</span><span class="p">(</span><span class="n">arg_list</span><span class="p">):</span> </span><span id="L-16"><a name="L-16"></a> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> </span><span id="L-17"><a name="L-17"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">arg_list</span><span class="p">:</span> </span><span id="L-18"><a name="L-18"></a> <span class="n">x</span> <span class="o">*=</span> <span class="n">i</span> </span><span id="L-19"><a name="L-19"></a> <span class="k">return</span> <span class="n">x</span> </span><span id="L-20"><a name="L-20"></a> </span><span id="L-21"><a name="L-21"></a> <span class="k">def</span> <span class="nf">find_innermost</span><span class="p">(</span><span class="n">x_str</span><span class="p">):</span> </span><span id="L-22"><a name="L-22"></a> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">0</span> </span><span id="L-23"><a name="L-23"></a> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> </span><span id="L-24"><a name="L-24"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="mi">1</span> <span class="c1"># get position just after last opening bracket as start</span> </span><span id="L-25"><a name="L-25"></a> <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x_str</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="n">start</span><span class="p">))</span> <span class="c1"># find next (</span> </span><span id="L-26"><a name="L-26"></a> <span class="n">b</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x_str</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="n">start</span><span class="p">))</span> <span class="c1"># find next ,</span> </span><span id="L-27"><a name="L-27"></a> <span class="n">c</span> <span class="o">=</span> <span class="n">x_str</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="n">start</span><span class="p">)</span> <span class="c1"># find next )</span> </span><span id="L-28"><a name="L-28"></a> <span class="c1"># if closing bracket is first or no more opening brackets left</span> </span><span id="L-29"><a name="L-29"></a> <span class="k">if</span> <span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">c</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span> </span><span id="L-30"><a name="L-30"></a> <span class="c1"># add to this to allow for more than 2 args by getting last comma before )?</span> </span><span id="L-31"><a name="L-31"></a> <span class="k">if</span> <span class="p">(</span><span class="n">b</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">])</span> <span class="ow">and</span> <span class="p">(</span><span class="n">b</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]):</span> </span><span id="L-32"><a name="L-32"></a> <span class="c1"># if there is a comma between opening brackets 2 &amp; 3 steps ago</span> </span><span id="L-33"><a name="L-33"></a> <span class="k">return</span> <span class="n">x_str</span><span class="p">[</span><span class="n">b</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> </span><span id="L-34"><a name="L-34"></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-35"><a name="L-35"></a> <span class="k">return</span> <span class="n">x_str</span><span class="p">[</span><span class="n">a</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span><span class="n">c</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> </span><span id="L-36"><a name="L-36"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">max_iter</span><span class="p">:</span> </span><span id="L-37"><a name="L-37"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Stuck in find_innermost loop&quot;</span><span class="p">)</span> </span><span id="L-38"><a name="L-38"></a> </span><span id="L-39"><a name="L-39"></a> <span class="k">def</span> <span class="nf">do_sum</span><span class="p">(</span><span class="n">x_str</span><span class="p">):</span> </span><span id="L-40"><a name="L-40"></a> <span class="c1"># get function arguements as integers from command string</span> </span><span id="L-41"><a name="L-41"></a> <span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">x_str</span><span class="p">[</span><span class="n">x_str</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;(&#39;</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span><span class="n">x_str</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;)&#39;</span><span class="p">)]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)]</span> </span><span id="L-42"><a name="L-42"></a> <span class="n">task</span> <span class="o">=</span> <span class="n">x_str</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="c1"># get function to be performed from command string</span> </span><span id="L-43"><a name="L-43"></a> <span class="k">if</span> <span class="n">task</span> <span class="o">==</span> <span class="s1">&#39;add&#39;</span><span class="p">:</span> </span><span id="L-44"><a name="L-44"></a> <span class="k">return</span> <span class="nb">sum</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> </span><span id="L-45"><a name="L-45"></a> <span class="k">elif</span> <span class="n">task</span> <span class="o">==</span> <span class="s1">&#39;sub&#39;</span><span class="p">:</span> </span><span id="L-46"><a name="L-46"></a> <span class="k">return</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="nb">sum</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> </span><span id="L-47"><a name="L-47"></a> <span class="k">elif</span> <span class="n">task</span> <span class="o">==</span> <span class="s1">&#39;abs&#39;</span><span class="p">:</span> </span><span id="L-48"><a name="L-48"></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span> </span><span id="L-49"><a name="L-49"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Only one arguement can be supplied for abs() function&quot;</span><span class="p">)</span> </span><span id="L-50"><a name="L-50"></a> <span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span> </span><span id="L-51"><a name="L-51"></a> <span class="k">elif</span> <span class="n">task</span> <span class="o">==</span> <span class="s1">&#39;mul&#39;</span><span class="p">:</span> </span><span id="L-52"><a name="L-52"></a> <span class="k">return</span> <span class="n">multiply</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> </span><span id="L-53"><a name="L-53"></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-54"><a name="L-54"></a> <span class="k">print</span> <span class="n">x_str</span> <span class="o">+</span> <span class="s1">&#39;: Task not recognised, please modify program or input&#39;</span> </span><span id="L-55"><a name="L-55"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Invalid input&quot;</span><span class="p">)</span> </span><span id="L-56"><a name="L-56"></a> </span><span id="L-57"><a name="L-57"></a> <span class="c1"># solve function starts here...</span> </span><span id="L-58"><a name="L-58"></a> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> </span><span id="L-59"><a name="L-59"></a> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> </span><span id="L-60"><a name="L-60"></a> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span> </span><span id="L-61"><a name="L-61"></a> <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span> <span class="k">print</span> <span class="s1">&#39;debug: problem_str:&#39;</span><span class="p">,</span> <span class="n">problem_str</span> </span><span id="L-62"><a name="L-62"></a> <span class="c1"># find innermost nested problem if &gt;1 opening bracket...</span> </span><span id="L-63"><a name="L-63"></a> <span class="k">if</span> <span class="n">problem_str</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s1">&#39;(&#39;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span> </span><span id="L-64"><a name="L-64"></a> <span class="n">x_str</span> <span class="o">=</span> <span class="n">find_innermost</span><span class="p">(</span><span class="n">problem_str</span><span class="p">)</span> </span><span id="L-65"><a name="L-65"></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-66"><a name="L-66"></a> <span class="n">x_str</span> <span class="o">=</span> <span class="n">problem_str</span> </span><span id="L-67"><a name="L-67"></a> <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span> <span class="k">print</span> <span class="s1">&#39;.&#39;</span><span class="o">*</span><span class="mi">6</span><span class="p">,</span> <span class="s1">&#39;x_str:</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">x_str</span> </span><span id="L-68"><a name="L-68"></a> <span class="c1"># process individual problem extracted from string...</span> </span><span id="L-69"><a name="L-69"></a> <span class="n">x</span> <span class="o">=</span> <span class="n">do_sum</span><span class="p">(</span><span class="n">x_str</span><span class="p">)</span> </span><span id="L-70"><a name="L-70"></a> <span class="k">if</span> <span class="n">verbose</span><span class="p">:</span> <span class="k">print</span> <span class="s1">&#39;.&#39;</span><span class="o">*</span><span class="mi">6</span><span class="p">,</span> <span class="s1">&#39;x:</span><span class="se">\t</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span> </span><span id="L-71"><a name="L-71"></a> <span class="c1"># replace individual problem with solution in full problem string...</span> </span><span id="L-72"><a name="L-72"></a> <span class="n">problem_str</span> <span class="o">=</span> <span class="n">problem_str</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">x_str</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">))</span> </span><span id="L-73"><a name="L-73"></a> <span class="c1"># return result if no problems remaining in string...</span> </span><span id="L-74"><a name="L-74"></a> <span class="k">if</span> <span class="n">problem_str</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s1">&#39;(&#39;</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> </span><span id="L-75"><a name="L-75"></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">problem_str</span><span class="p">)</span> </span><span id="L-76"><a name="L-76"></a> <span class="k">if</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="n">max_iter</span><span class="p">:</span> </span><span id="L-77"><a name="L-77"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Stuck in main loop&quot;</span><span class="p">)</span> </span><span id="L-78"><a name="L-78"></a> </span><span id="L-79"><a name="L-79"></a> </span><span id="L-80"><a name="L-80"></a><span class="c1"># test solve function...</span> </span><span id="L-81"><a name="L-81"></a><span class="n">p1</span> <span class="o">=</span> <span class="s1">&#39;abs(add(add(9465,38),multiply(add(63303,146),46)))&#39;</span> </span><span id="L-82"><a name="L-82"></a><span class="n">p2</span> <span class="o">=</span> <span class="s1">&#39;abs(add(multiply(95,multiply(-1,multiply(13,18875))),multiply(-1,add(18293,26))))&#39;</span> </span><span id="L-83"><a name="L-83"></a><span class="n">p3</span> <span class="o">=</span> <span class="s1">&#39;abs(add(subtract(add(add(151,26875),122),254),subtract(237,multiply(-1,56497))))&#39;</span> </span><span id="L-84"><a name="L-84"></a><span class="n">r1</span><span class="p">,</span> <span class="n">r2</span><span class="p">,</span> <span class="n">r3</span> <span class="o">=</span> <span class="n">solve</span><span class="p">(</span><span class="n">p1</span><span class="p">),</span> <span class="n">solve</span><span class="p">(</span><span class="n">p2</span><span class="p">),</span> <span class="n">solve</span><span class="p">(</span><span class="n">p3</span><span class="p">)</span> </span><span id="L-85"><a name="L-85"></a><span class="k">print</span> <span class="s1">&#39;p1 evaluates to:&#39;</span><span class="p">,</span> <span class="n">r1</span> </span><span id="L-86"><a name="L-86"></a><span class="k">print</span> <span class="s1">&#39;p2 evaluates to:&#39;</span><span class="p">,</span> <span class="n">r2</span> </span><span id="L-87"><a name="L-87"></a><span class="k">print</span> <span class="s1">&#39;p3 evaluates to:&#39;</span><span class="p">,</span> <span class="n">r3</span> </span></pre></div> </td></tr></table>
maths, parser, python