From b07f87e365e0f1b36650db6f4a884df2bd0a6706 Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Thu, 10 Oct 2019 09:11:57 +0700 Subject: [PATCH 1/8] added the to postfix function --- parser.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 parser.py diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..314e7f0 --- /dev/null +++ b/parser.py @@ -0,0 +1,43 @@ +#module tokenization + +#type of token: +# Number (N) : +# Operator (O) : + - / * ^ +# Paren (P) : +def _token_type(thing): + return {'0':1, + '1':1, + '2':1, + '3':1, + '4':1, + '5':1, + '6':1, + '7':1, + '8':1, + '9':1, + '+':2, + '-':2, + '/':2, + '*':2, + '^':2, + '!':2, + '(':3, + ')':3, + }.get(thing, 4) + + +def tokenize_string(strng): + return strng.split() + +def _infix_to_postfix(tokens): + res = [] + waiting = 0 + for i in tokens: + if i.isdigit(): + res.append(i) + if waiting != 0: + res.append(waiting) + waiting = 0 + else: + waiting = i + return res From 4a930ee8905429d682eeec26a67a70dcd236d576 Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Thu, 10 Oct 2019 09:27:37 +0700 Subject: [PATCH 2/8] it has a better tokenizer now --- parser.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/parser.py b/parser.py index 314e7f0..2b07400 100644 --- a/parser.py +++ b/parser.py @@ -1,5 +1,5 @@ #module tokenization - +import re #type of token: # Number (N) : # Operator (O) : + - / * ^ @@ -26,10 +26,10 @@ def _token_type(thing): }.get(thing, 4) -def tokenize_string(strng): - return strng.split() +def tokenize(strng): + return filter(None, re.split("([+-/*\(\)])", strng.replace(" ", ""))) -def _infix_to_postfix(tokens): +def to_postfix(tokens): res = [] waiting = 0 for i in tokens: From ba74e83a7864e2c8da4f91acb86420e04e974da0 Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Thu, 10 Oct 2019 09:54:09 +0700 Subject: [PATCH 3/8] it convert the string to the reverse polish notation --- parser.py | 55 +++++++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/parser.py b/parser.py index 2b07400..444fc7f 100644 --- a/parser.py +++ b/parser.py @@ -1,43 +1,26 @@ #module tokenization import re -#type of token: -# Number (N) : -# Operator (O) : + - / * ^ -# Paren (P) : -def _token_type(thing): - return {'0':1, - '1':1, - '2':1, - '3':1, - '4':1, - '5':1, - '6':1, - '7':1, - '8':1, - '9':1, - '+':2, - '-':2, - '/':2, - '*':2, - '^':2, - '!':2, - '(':3, - ')':3, - }.get(thing, 4) - def tokenize(strng): - return filter(None, re.split("([+-/*\(\)])", strng.replace(" ", ""))) + return filter(None, re.split("([+-/*!\(\)])", strng.replace(" ", ""))) def to_postfix(tokens): - res = [] - waiting = 0 - for i in tokens: - if i.isdigit(): - res.append(i) - if waiting != 0: - res.append(waiting) - waiting = 0 + output = [] + operst = [] + for opt in tokens: + if opt.isdigit(): + output.append(opt) + elif opt == ")": + while True: + temp = operst.pop() + if temp == "(" : + break; + else: + output.append(temp) else: - waiting = i - return res + operst.append(opt) + while True : + output.append(operst.pop()) + if len(operst) == 0: + break; + return output From c15c18444826b14e3a0c17c4cd672459aab6194d Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Thu, 10 Oct 2019 10:43:22 +0700 Subject: [PATCH 4/8] the statement based equation is completed --- parser.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/parser.py b/parser.py index 444fc7f..a6317a9 100644 --- a/parser.py +++ b/parser.py @@ -1,6 +1,27 @@ #module tokenization import re +def apply(string, sarg = {}, darg = {}): + return execute(to_postfix(tokenize(string)), sarg=sarg, darg=darg) + +def execute(statement, sarg = {}, darg = {}): + stack = [] + for elem in statement : + if elem.isdigit() : + stack.append(int(elem)) + elif elem in sarg : + operand = stack.pop() + stack.append(sarg[elem](operand)) + elif elem in darg : + operandb = stack.pop() + operanda = stack.pop() + stack.append(darg[elem](operanda, operandb)) + if len(stack) == 1 : + return stack.pop() + else: + return None + + def tokenize(strng): return filter(None, re.split("([+-/*!\(\)])", strng.replace(" ", ""))) @@ -12,6 +33,8 @@ def to_postfix(tokens): output.append(opt) elif opt == ")": while True: + if len(operst) == 0 : + return [] temp = operst.pop() if temp == "(" : break; @@ -19,6 +42,9 @@ def to_postfix(tokens): output.append(temp) else: operst.append(opt) + for something in operst : + if something == "(" : + return [] while True : output.append(operst.pop()) if len(operst) == 0: From 1822664bff6ca85f4c75ed8be4590bf85def9262 Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Thu, 10 Oct 2019 22:02:40 +0700 Subject: [PATCH 5/8] resolves #10 it supports floating point statement now --- parser.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/parser.py b/parser.py index a6317a9..259a3f8 100644 --- a/parser.py +++ b/parser.py @@ -7,8 +7,8 @@ def apply(string, sarg = {}, darg = {}): def execute(statement, sarg = {}, darg = {}): stack = [] for elem in statement : - if elem.isdigit() : - stack.append(int(elem)) + if elem[0].isdigit() : + stack.append(float(elem)) elif elem in sarg : operand = stack.pop() stack.append(sarg[elem](operand)) @@ -23,13 +23,13 @@ def execute(statement, sarg = {}, darg = {}): def tokenize(strng): - return filter(None, re.split("([+-/*!\(\)])", strng.replace(" ", ""))) + return filter(None, re.split("([\+\-\/\*\!\(\)])", strng.replace(" ", ""))) def to_postfix(tokens): output = [] operst = [] for opt in tokens: - if opt.isdigit(): + if opt[0].isdigit(): output.append(opt) elif opt == ")": while True: From bf628bf35306e32903bba92aa2d79faacec337ba Mon Sep 17 00:00:00 2001 From: alyanrndh <56344623+alyanrndh@users.noreply.github.com> Date: Thu, 10 Oct 2019 22:59:50 +0700 Subject: [PATCH 6/8] update the factorial --- calc_main.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/calc_main.py b/calc_main.py index 0de8c76..b1b1682 100644 --- a/calc_main.py +++ b/calc_main.py @@ -44,6 +44,16 @@ def floor_division(): def factorial(): + num = int(input("enter a number: ")) + if num < 0: + print("Sorry, factorial does not exist for negative numbers") + elif num == 0: + print("The factorial of 0 is 1") + else: + for i in range(1,num + 1): + factorial = factorial*i + print("The factorial of",num,"is:",factorial) + return if choice==1: additon() @@ -61,4 +71,4 @@ def factorial(): factorial() else: print("wrong input") - exit(0) \ No newline at end of file + exit(0) From 0d158006e1ac8edac8f096ec17d558dd1bdb5c2d Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Sat, 12 Oct 2019 17:19:23 +0700 Subject: [PATCH 7/8] added the glue --- calc_main.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/calc_main.py b/calc_main.py index 0de8c76..7aff752 100644 --- a/calc_main.py +++ b/calc_main.py @@ -1,4 +1,5 @@ import math +import parser as pr while True: print("MENU") print("1 for addition :") @@ -8,6 +9,7 @@ print("5 for Division:") print("6 for floor division:") print("7 for factorial:") + print("8 for Statement based:") choice=int(input("enter any choice:")) def additon(): a=int(input("enter 1st no to perform addition:")) #a-first input @@ -59,6 +61,27 @@ def factorial(): floor_division() elif choice==7: factorial() + elif choice==8: + statement_wrapper() else: print("wrong input") - exit(0) \ No newline at end of file + exit(0) + +def statement_wrapper(): + soper = {'!' : factorial + } + doper = { + '+' : add + ,'-' : red + ,'*' : mul + ,'/' : div + ,'^' : power + } + states=input(">>") + result=pr.apply(states, sarg=soper, darg=doper) + if(result == None): + print("<< Undefined") + else: + print("<< ", result) + return + From e6c101a9548300b64c25e242e441bf5969d6da60 Mon Sep 17 00:00:00 2001 From: PaprikaX33 Date: Sat, 12 Oct 2019 17:36:48 +0700 Subject: [PATCH 8/8] completed the glue --- calc_main.py | 66 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 27 deletions(-) mode change 100644 => 100755 calc_main.py diff --git a/calc_main.py b/calc_main.py old mode 100644 new mode 100755 index 7aff752..5913d59 --- a/calc_main.py +++ b/calc_main.py @@ -1,5 +1,35 @@ +#!/usr/bin/env python2 import math import parser as pr + +def add(a, b): + return a + b +def red(a, b): + return a - b +def mul(a, b): + return a * b +def div(a, b): + return a / b +def power(a, b): + return a ** b + +def statement_wrapper(): + doper = { + '+' : add + ,'-' : red + ,'*' : mul + ,'/' : div + ,'^' : power + } + states=raw_input(">>") + result=pr.apply(states, darg=doper) + if(result == None): + print("<< Undefined") + else: + full = "<< ", str(result) + print(full) + return + while True: print("MENU") print("1 for addition :") @@ -14,38 +44,38 @@ def additon(): a=int(input("enter 1st no to perform addition:")) #a-first input b=int(input("enter 2nd no to perform addition:")) #b-second input - c=a+b + c=add(a, b) print("sum is:",c) return def subtract(): a = int(input("enter 1st no to perform subtraction:")) b = int(input("enter 2nd no to perform subtraction:")) - c = a - b + c = red(a, b) print("subtraction is:", c) return def multiplication(): a = int(input("enter 1st no to perform multipication:")) b = int(input("enter 2nd no to perform multiplication:")) - c = a*b + c = mul(a, b) print("multiplication is:", c) return def power(): a = int(input("enter base :")) b = int(input("enter power :")) - c = a**b + c = pow(a, b) print("division is:", c) return def divide(): a = int(input("enter 1st no to perform division:")) b = int(input("enter 2nd no to perform division:")) - c = a/b + c = div(a, b) print("division is:", c) return - def floor_division(): - - - def factorial(): + #def floor_division(): + # + # + #def factorial(): if choice==1: additon() @@ -67,21 +97,3 @@ def factorial(): print("wrong input") exit(0) -def statement_wrapper(): - soper = {'!' : factorial - } - doper = { - '+' : add - ,'-' : red - ,'*' : mul - ,'/' : div - ,'^' : power - } - states=input(">>") - result=pr.apply(states, sarg=soper, darg=doper) - if(result == None): - print("<< Undefined") - else: - print("<< ", result) - return -