Python Calculator using Postfix ExpressionsA simple python3 calculatorCalculator parsing S-expressionsCommand line reverse polish calculatorSimple C++ calculator which follows BOMDAS rulesCalculator that parses S-expressionsCalculator using tokens of numbers and operatorsPostfix calculatorOverhauled tokenizer for markargsInfix to RPN converter using the Shunting-Yard AlgorithmSimple calculator to evaluate arithmetic expressionsPostfix calculator in Java

Can Jimmy hang on his rope?

What is this little owl-like bird?

Elf (adjective) vs. Elvish vs. Elven

How quality assurance engineers test calculations?

Is it possible to split a vertex?

OR-backed serious games

Integer Lists of Noah

Is there a nice way to implement a conditional type with default fail case?

How to drill holes in 3/8" steel plates?

How do you move up one folder in Finder?

How do native German speakers usually express skepticism (using even) about a premise?

Can I play a mimic PC?

What is the right approach to quit a job during probation period for a competing offer?

How effective would wooden scale armor be in a medieval setting?

What's it called when the bad guy gets eaten?

How are mathematicians paid to do research?

What minifigure is this?

What is the parallel of Day of the Dead with Stranger things?

What do three diagonal dots above a letter mean in the "Misal rico de Cisneros" (Spain, 1518)?

Is a request to book a business flight ticket for a graduate student an unreasonable one?

Misspelling my name on my mathematical publications

What is the minimum time required for final wash in film development?

What is /bin/red

The joke office



Python Calculator using Postfix Expressions


A simple python3 calculatorCalculator parsing S-expressionsCommand line reverse polish calculatorSimple C++ calculator which follows BOMDAS rulesCalculator that parses S-expressionsCalculator using tokens of numbers and operatorsPostfix calculatorOverhauled tokenizer for markargsInfix to RPN converter using the Shunting-Yard AlgorithmSimple calculator to evaluate arithmetic expressionsPostfix calculator in Java






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3












$begingroup$


Improved upon my previous calculator program. This program has the following features:



  1. Gives information using session prompts.


  2. Supports all common operators.


  3. Follows operator precedence.


  4. Use of identifiers is supported.


  5. Result of the previous expression can accessed by using the 'r'
    identifier.



  6. Special commands:



    1. n: Stars a new session. Deletes all previous identifiers.

    2. q: Quits the program


The code describes the features in more detail.



Issues:



  1. No useful information is given to the user if any error occurred.

Other Information:



  1. Ditched the earlier use of eval() to evaluate expressions because of security reasons.


  2. Avoids the endless function call chain used earlier that could hit the recursion limit albeit after a long while by using a loop.


My Previous calculator: A simple python3 calculator



Also uploaded the code on pastebin: https://pastebin.com/WW25hWn7



import sys
import math

usage_notes = """
1. Session prompts:
1. n: New session
2. c: Current session

2. Supported operators: +, -, *, /, ^, !

3. Precedence:
1. Parenthesization
2. Factorial
3. Exponentiation
4. Multiplication and Divison
5. Addition and Subtraction

4. Use of identifiers is supported. Use commas to separate them:
n: a=10,b=5
c: a+b
-> 15

5. Result of the previous expression can accessed by using the 'r'
identifier:
n: 2+3
-> 5
c: r+10
-> 15

6. Special commands:
1. n: Stars a new session. Deletes all previous identifiers.
2. q: Quits the program
"""

identifiers =


def start():
# Creates a prompt dictionary to differentiate sessions.
# Starts the main loop of the program.
# Takes the input from the user and calls controller().

prompts =
'n': 'n: ',
'c': 'c: ',


prompt = prompts['n']
while True:
expr = input(prompt)
if expr == 'q':
break
elif expr == 'n':
prompt = prompts['n']
identifiers.clear()
else:
res = controller(expr)

if res == 'e':
print('error: invalid expressionn')
elif res == 'i':
prompt = prompts['c']
else:
print('-> ' + identifiers['r'] + 'n')
prompt = prompts['c']


def controller(expr):
# Calls create_identifiers or passes the expr to get_postfix()
# to be converted into a postfix expression list. And, calls
# postfix_eval() for evaluation. All the Exceptions
# are terminated, so the main loop keeps running.

try:
if '=' in expr:
return create_identifiers(expr)
postfix_expr = get_postfix(expr)
return postfix_eval(postfix_expr)
except Exception:
return 'e'


def create_identifiers(expr):
# Identifiers are implemented as a global dictionary. First,
# the string is split using ',' as a delimiter. The resulting
# substring are separated using '='. First substring is assigned
# as a key with second substring as the value.

expr_list = expr.replace(' ', '').split(',')

for stmt in expr_list:
var, val = stmt.split('=')
identifiers[var] = val
return 'i'


def get_postfix(expr):
# Converts infix expressions to postfix expressions to remove ambiguity.
# Example: a+b*c -> abc*+

# Remove all the spaces in the given expression.
expr = expr.replace(' ', '')
sep_str = ''

# Insert spaces only around supported operators, so splitting
# can be done easily later.
for a_char in expr:
if a_char in '+-*/^!()':
sep_str += ' %s ' % a_char
else:
sep_str += a_char

# Use the default space as the delimiter and split the string.
token_list = sep_str.split()

# Only operators are pushed on to the op_stack, digits and identifiers
# are appended to the postfix_list.
op_stack = []
postfix_list = []

prec =
prec['!'] = 5
prec['^'] = 4
prec['/'] = 3
prec['*'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1

# The current operator's precedence in the loop is compared with the
# operators in the stack. If it's higher, it's pushed on the stack.

# If it less than or equal, the operators are popped until the
# precedence of the operator at the top is less than the
# current operators'.

# When parentheses are used, ')' forces all the operators above '('
# to be popped.

# Whenever an operator is popped it's appended to the postfix_list.
for token in token_list:
if isnum(token) or token.isalpha():
postfix_list.append(token)
elif token == '(':
op_stack.append(token)
elif token == ')':
top_token = op_stack.pop()
while top_token != '(':
postfix_list.append(top_token)
top_token = op_stack.pop()
else:
while op_stack != [] and
(prec[op_stack[-1]] >= prec[token]):
postfix_list.append(op_stack.pop())
op_stack.append(token)

while op_stack != []:
postfix_list.append(op_stack.pop())

return postfix_list


def postfix_eval(postfix_list):
# Similar stack based approach is used here for evaluation. If a
# identifier or digit is found, push it on the operand_stack. If
# an operator is found, use it on the last two operands or the last
# in case of '!', and append the result on the stack.

operand_stack = []

for val in postfix_list:
if isnum(val):
operand_stack.append(float(val))
elif val.isalpha():
val = identifiers[val]
operand_stack.append(float(val))
elif val in '+-*/^!':

if val != '!':
op2 = operand_stack.pop()
op1 = operand_stack.pop()
res = calc(op1, val, op2)
operand_stack.append(res)
else:
op = operand_stack.pop()
res = math.factorial(op)
operand_stack.append(res)

res = operand_stack[-1]
int_res = int(res)
if int_res == res:
res = int_res

identifiers['r'] = str(res)


def isnum(val):
# Used as a helper function to check if the argument is a number.
try:
float(val)
return True
except Exception:
return False


def calc(op1, op, op2):
# Performs the operation on the operands and returns the result.
if op == '+':
return op1 + op2
elif op == '-':
return op1 - op2
elif op == '*':
return op1 * op2
elif op == '/':
return op1 / op2
elif op == '^':
return op1 ** op2

if sys.argv[-1] == 'n':
print(usage_notes)

start()



Sample output:



n: 1+5
-> 6

c: r
-> 6

c: r*10+50*(3-1)-100
-> 60

c: r
-> 60

c: a=50,b=10
c: r+a+b
-> 120

c: n
n: 2^3+5!
-> 128

c: 1 +- 2
error: invalid expression

c: q



I am looking for ways to make the code more readable, minimize redundancy, improving the overall design, performance improvements, etc. Any help would be appreciated!










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Those don't look like postfix expressions to me.
    $endgroup$
    – 200_success
    6 hours ago

















3












$begingroup$


Improved upon my previous calculator program. This program has the following features:



  1. Gives information using session prompts.


  2. Supports all common operators.


  3. Follows operator precedence.


  4. Use of identifiers is supported.


  5. Result of the previous expression can accessed by using the 'r'
    identifier.



  6. Special commands:



    1. n: Stars a new session. Deletes all previous identifiers.

    2. q: Quits the program


The code describes the features in more detail.



Issues:



  1. No useful information is given to the user if any error occurred.

Other Information:



  1. Ditched the earlier use of eval() to evaluate expressions because of security reasons.


  2. Avoids the endless function call chain used earlier that could hit the recursion limit albeit after a long while by using a loop.


My Previous calculator: A simple python3 calculator



Also uploaded the code on pastebin: https://pastebin.com/WW25hWn7



import sys
import math

usage_notes = """
1. Session prompts:
1. n: New session
2. c: Current session

2. Supported operators: +, -, *, /, ^, !

3. Precedence:
1. Parenthesization
2. Factorial
3. Exponentiation
4. Multiplication and Divison
5. Addition and Subtraction

4. Use of identifiers is supported. Use commas to separate them:
n: a=10,b=5
c: a+b
-> 15

5. Result of the previous expression can accessed by using the 'r'
identifier:
n: 2+3
-> 5
c: r+10
-> 15

6. Special commands:
1. n: Stars a new session. Deletes all previous identifiers.
2. q: Quits the program
"""

identifiers =


def start():
# Creates a prompt dictionary to differentiate sessions.
# Starts the main loop of the program.
# Takes the input from the user and calls controller().

prompts =
'n': 'n: ',
'c': 'c: ',


prompt = prompts['n']
while True:
expr = input(prompt)
if expr == 'q':
break
elif expr == 'n':
prompt = prompts['n']
identifiers.clear()
else:
res = controller(expr)

if res == 'e':
print('error: invalid expressionn')
elif res == 'i':
prompt = prompts['c']
else:
print('-> ' + identifiers['r'] + 'n')
prompt = prompts['c']


def controller(expr):
# Calls create_identifiers or passes the expr to get_postfix()
# to be converted into a postfix expression list. And, calls
# postfix_eval() for evaluation. All the Exceptions
# are terminated, so the main loop keeps running.

try:
if '=' in expr:
return create_identifiers(expr)
postfix_expr = get_postfix(expr)
return postfix_eval(postfix_expr)
except Exception:
return 'e'


def create_identifiers(expr):
# Identifiers are implemented as a global dictionary. First,
# the string is split using ',' as a delimiter. The resulting
# substring are separated using '='. First substring is assigned
# as a key with second substring as the value.

expr_list = expr.replace(' ', '').split(',')

for stmt in expr_list:
var, val = stmt.split('=')
identifiers[var] = val
return 'i'


def get_postfix(expr):
# Converts infix expressions to postfix expressions to remove ambiguity.
# Example: a+b*c -> abc*+

# Remove all the spaces in the given expression.
expr = expr.replace(' ', '')
sep_str = ''

# Insert spaces only around supported operators, so splitting
# can be done easily later.
for a_char in expr:
if a_char in '+-*/^!()':
sep_str += ' %s ' % a_char
else:
sep_str += a_char

# Use the default space as the delimiter and split the string.
token_list = sep_str.split()

# Only operators are pushed on to the op_stack, digits and identifiers
# are appended to the postfix_list.
op_stack = []
postfix_list = []

prec =
prec['!'] = 5
prec['^'] = 4
prec['/'] = 3
prec['*'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1

# The current operator's precedence in the loop is compared with the
# operators in the stack. If it's higher, it's pushed on the stack.

# If it less than or equal, the operators are popped until the
# precedence of the operator at the top is less than the
# current operators'.

# When parentheses are used, ')' forces all the operators above '('
# to be popped.

# Whenever an operator is popped it's appended to the postfix_list.
for token in token_list:
if isnum(token) or token.isalpha():
postfix_list.append(token)
elif token == '(':
op_stack.append(token)
elif token == ')':
top_token = op_stack.pop()
while top_token != '(':
postfix_list.append(top_token)
top_token = op_stack.pop()
else:
while op_stack != [] and
(prec[op_stack[-1]] >= prec[token]):
postfix_list.append(op_stack.pop())
op_stack.append(token)

while op_stack != []:
postfix_list.append(op_stack.pop())

return postfix_list


def postfix_eval(postfix_list):
# Similar stack based approach is used here for evaluation. If a
# identifier or digit is found, push it on the operand_stack. If
# an operator is found, use it on the last two operands or the last
# in case of '!', and append the result on the stack.

operand_stack = []

for val in postfix_list:
if isnum(val):
operand_stack.append(float(val))
elif val.isalpha():
val = identifiers[val]
operand_stack.append(float(val))
elif val in '+-*/^!':

if val != '!':
op2 = operand_stack.pop()
op1 = operand_stack.pop()
res = calc(op1, val, op2)
operand_stack.append(res)
else:
op = operand_stack.pop()
res = math.factorial(op)
operand_stack.append(res)

res = operand_stack[-1]
int_res = int(res)
if int_res == res:
res = int_res

identifiers['r'] = str(res)


def isnum(val):
# Used as a helper function to check if the argument is a number.
try:
float(val)
return True
except Exception:
return False


def calc(op1, op, op2):
# Performs the operation on the operands and returns the result.
if op == '+':
return op1 + op2
elif op == '-':
return op1 - op2
elif op == '*':
return op1 * op2
elif op == '/':
return op1 / op2
elif op == '^':
return op1 ** op2

if sys.argv[-1] == 'n':
print(usage_notes)

start()



Sample output:



n: 1+5
-> 6

c: r
-> 6

c: r*10+50*(3-1)-100
-> 60

c: r
-> 60

c: a=50,b=10
c: r+a+b
-> 120

c: n
n: 2^3+5!
-> 128

c: 1 +- 2
error: invalid expression

c: q



I am looking for ways to make the code more readable, minimize redundancy, improving the overall design, performance improvements, etc. Any help would be appreciated!










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Those don't look like postfix expressions to me.
    $endgroup$
    – 200_success
    6 hours ago













3












3








3


1



$begingroup$


Improved upon my previous calculator program. This program has the following features:



  1. Gives information using session prompts.


  2. Supports all common operators.


  3. Follows operator precedence.


  4. Use of identifiers is supported.


  5. Result of the previous expression can accessed by using the 'r'
    identifier.



  6. Special commands:



    1. n: Stars a new session. Deletes all previous identifiers.

    2. q: Quits the program


The code describes the features in more detail.



Issues:



  1. No useful information is given to the user if any error occurred.

Other Information:



  1. Ditched the earlier use of eval() to evaluate expressions because of security reasons.


  2. Avoids the endless function call chain used earlier that could hit the recursion limit albeit after a long while by using a loop.


My Previous calculator: A simple python3 calculator



Also uploaded the code on pastebin: https://pastebin.com/WW25hWn7



import sys
import math

usage_notes = """
1. Session prompts:
1. n: New session
2. c: Current session

2. Supported operators: +, -, *, /, ^, !

3. Precedence:
1. Parenthesization
2. Factorial
3. Exponentiation
4. Multiplication and Divison
5. Addition and Subtraction

4. Use of identifiers is supported. Use commas to separate them:
n: a=10,b=5
c: a+b
-> 15

5. Result of the previous expression can accessed by using the 'r'
identifier:
n: 2+3
-> 5
c: r+10
-> 15

6. Special commands:
1. n: Stars a new session. Deletes all previous identifiers.
2. q: Quits the program
"""

identifiers =


def start():
# Creates a prompt dictionary to differentiate sessions.
# Starts the main loop of the program.
# Takes the input from the user and calls controller().

prompts =
'n': 'n: ',
'c': 'c: ',


prompt = prompts['n']
while True:
expr = input(prompt)
if expr == 'q':
break
elif expr == 'n':
prompt = prompts['n']
identifiers.clear()
else:
res = controller(expr)

if res == 'e':
print('error: invalid expressionn')
elif res == 'i':
prompt = prompts['c']
else:
print('-> ' + identifiers['r'] + 'n')
prompt = prompts['c']


def controller(expr):
# Calls create_identifiers or passes the expr to get_postfix()
# to be converted into a postfix expression list. And, calls
# postfix_eval() for evaluation. All the Exceptions
# are terminated, so the main loop keeps running.

try:
if '=' in expr:
return create_identifiers(expr)
postfix_expr = get_postfix(expr)
return postfix_eval(postfix_expr)
except Exception:
return 'e'


def create_identifiers(expr):
# Identifiers are implemented as a global dictionary. First,
# the string is split using ',' as a delimiter. The resulting
# substring are separated using '='. First substring is assigned
# as a key with second substring as the value.

expr_list = expr.replace(' ', '').split(',')

for stmt in expr_list:
var, val = stmt.split('=')
identifiers[var] = val
return 'i'


def get_postfix(expr):
# Converts infix expressions to postfix expressions to remove ambiguity.
# Example: a+b*c -> abc*+

# Remove all the spaces in the given expression.
expr = expr.replace(' ', '')
sep_str = ''

# Insert spaces only around supported operators, so splitting
# can be done easily later.
for a_char in expr:
if a_char in '+-*/^!()':
sep_str += ' %s ' % a_char
else:
sep_str += a_char

# Use the default space as the delimiter and split the string.
token_list = sep_str.split()

# Only operators are pushed on to the op_stack, digits and identifiers
# are appended to the postfix_list.
op_stack = []
postfix_list = []

prec =
prec['!'] = 5
prec['^'] = 4
prec['/'] = 3
prec['*'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1

# The current operator's precedence in the loop is compared with the
# operators in the stack. If it's higher, it's pushed on the stack.

# If it less than or equal, the operators are popped until the
# precedence of the operator at the top is less than the
# current operators'.

# When parentheses are used, ')' forces all the operators above '('
# to be popped.

# Whenever an operator is popped it's appended to the postfix_list.
for token in token_list:
if isnum(token) or token.isalpha():
postfix_list.append(token)
elif token == '(':
op_stack.append(token)
elif token == ')':
top_token = op_stack.pop()
while top_token != '(':
postfix_list.append(top_token)
top_token = op_stack.pop()
else:
while op_stack != [] and
(prec[op_stack[-1]] >= prec[token]):
postfix_list.append(op_stack.pop())
op_stack.append(token)

while op_stack != []:
postfix_list.append(op_stack.pop())

return postfix_list


def postfix_eval(postfix_list):
# Similar stack based approach is used here for evaluation. If a
# identifier or digit is found, push it on the operand_stack. If
# an operator is found, use it on the last two operands or the last
# in case of '!', and append the result on the stack.

operand_stack = []

for val in postfix_list:
if isnum(val):
operand_stack.append(float(val))
elif val.isalpha():
val = identifiers[val]
operand_stack.append(float(val))
elif val in '+-*/^!':

if val != '!':
op2 = operand_stack.pop()
op1 = operand_stack.pop()
res = calc(op1, val, op2)
operand_stack.append(res)
else:
op = operand_stack.pop()
res = math.factorial(op)
operand_stack.append(res)

res = operand_stack[-1]
int_res = int(res)
if int_res == res:
res = int_res

identifiers['r'] = str(res)


def isnum(val):
# Used as a helper function to check if the argument is a number.
try:
float(val)
return True
except Exception:
return False


def calc(op1, op, op2):
# Performs the operation on the operands and returns the result.
if op == '+':
return op1 + op2
elif op == '-':
return op1 - op2
elif op == '*':
return op1 * op2
elif op == '/':
return op1 / op2
elif op == '^':
return op1 ** op2

if sys.argv[-1] == 'n':
print(usage_notes)

start()



Sample output:



n: 1+5
-> 6

c: r
-> 6

c: r*10+50*(3-1)-100
-> 60

c: r
-> 60

c: a=50,b=10
c: r+a+b
-> 120

c: n
n: 2^3+5!
-> 128

c: 1 +- 2
error: invalid expression

c: q



I am looking for ways to make the code more readable, minimize redundancy, improving the overall design, performance improvements, etc. Any help would be appreciated!










share|improve this question











$endgroup$




Improved upon my previous calculator program. This program has the following features:



  1. Gives information using session prompts.


  2. Supports all common operators.


  3. Follows operator precedence.


  4. Use of identifiers is supported.


  5. Result of the previous expression can accessed by using the 'r'
    identifier.



  6. Special commands:



    1. n: Stars a new session. Deletes all previous identifiers.

    2. q: Quits the program


The code describes the features in more detail.



Issues:



  1. No useful information is given to the user if any error occurred.

Other Information:



  1. Ditched the earlier use of eval() to evaluate expressions because of security reasons.


  2. Avoids the endless function call chain used earlier that could hit the recursion limit albeit after a long while by using a loop.


My Previous calculator: A simple python3 calculator



Also uploaded the code on pastebin: https://pastebin.com/WW25hWn7



import sys
import math

usage_notes = """
1. Session prompts:
1. n: New session
2. c: Current session

2. Supported operators: +, -, *, /, ^, !

3. Precedence:
1. Parenthesization
2. Factorial
3. Exponentiation
4. Multiplication and Divison
5. Addition and Subtraction

4. Use of identifiers is supported. Use commas to separate them:
n: a=10,b=5
c: a+b
-> 15

5. Result of the previous expression can accessed by using the 'r'
identifier:
n: 2+3
-> 5
c: r+10
-> 15

6. Special commands:
1. n: Stars a new session. Deletes all previous identifiers.
2. q: Quits the program
"""

identifiers =


def start():
# Creates a prompt dictionary to differentiate sessions.
# Starts the main loop of the program.
# Takes the input from the user and calls controller().

prompts =
'n': 'n: ',
'c': 'c: ',


prompt = prompts['n']
while True:
expr = input(prompt)
if expr == 'q':
break
elif expr == 'n':
prompt = prompts['n']
identifiers.clear()
else:
res = controller(expr)

if res == 'e':
print('error: invalid expressionn')
elif res == 'i':
prompt = prompts['c']
else:
print('-> ' + identifiers['r'] + 'n')
prompt = prompts['c']


def controller(expr):
# Calls create_identifiers or passes the expr to get_postfix()
# to be converted into a postfix expression list. And, calls
# postfix_eval() for evaluation. All the Exceptions
# are terminated, so the main loop keeps running.

try:
if '=' in expr:
return create_identifiers(expr)
postfix_expr = get_postfix(expr)
return postfix_eval(postfix_expr)
except Exception:
return 'e'


def create_identifiers(expr):
# Identifiers are implemented as a global dictionary. First,
# the string is split using ',' as a delimiter. The resulting
# substring are separated using '='. First substring is assigned
# as a key with second substring as the value.

expr_list = expr.replace(' ', '').split(',')

for stmt in expr_list:
var, val = stmt.split('=')
identifiers[var] = val
return 'i'


def get_postfix(expr):
# Converts infix expressions to postfix expressions to remove ambiguity.
# Example: a+b*c -> abc*+

# Remove all the spaces in the given expression.
expr = expr.replace(' ', '')
sep_str = ''

# Insert spaces only around supported operators, so splitting
# can be done easily later.
for a_char in expr:
if a_char in '+-*/^!()':
sep_str += ' %s ' % a_char
else:
sep_str += a_char

# Use the default space as the delimiter and split the string.
token_list = sep_str.split()

# Only operators are pushed on to the op_stack, digits and identifiers
# are appended to the postfix_list.
op_stack = []
postfix_list = []

prec =
prec['!'] = 5
prec['^'] = 4
prec['/'] = 3
prec['*'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1

# The current operator's precedence in the loop is compared with the
# operators in the stack. If it's higher, it's pushed on the stack.

# If it less than or equal, the operators are popped until the
# precedence of the operator at the top is less than the
# current operators'.

# When parentheses are used, ')' forces all the operators above '('
# to be popped.

# Whenever an operator is popped it's appended to the postfix_list.
for token in token_list:
if isnum(token) or token.isalpha():
postfix_list.append(token)
elif token == '(':
op_stack.append(token)
elif token == ')':
top_token = op_stack.pop()
while top_token != '(':
postfix_list.append(top_token)
top_token = op_stack.pop()
else:
while op_stack != [] and
(prec[op_stack[-1]] >= prec[token]):
postfix_list.append(op_stack.pop())
op_stack.append(token)

while op_stack != []:
postfix_list.append(op_stack.pop())

return postfix_list


def postfix_eval(postfix_list):
# Similar stack based approach is used here for evaluation. If a
# identifier or digit is found, push it on the operand_stack. If
# an operator is found, use it on the last two operands or the last
# in case of '!', and append the result on the stack.

operand_stack = []

for val in postfix_list:
if isnum(val):
operand_stack.append(float(val))
elif val.isalpha():
val = identifiers[val]
operand_stack.append(float(val))
elif val in '+-*/^!':

if val != '!':
op2 = operand_stack.pop()
op1 = operand_stack.pop()
res = calc(op1, val, op2)
operand_stack.append(res)
else:
op = operand_stack.pop()
res = math.factorial(op)
operand_stack.append(res)

res = operand_stack[-1]
int_res = int(res)
if int_res == res:
res = int_res

identifiers['r'] = str(res)


def isnum(val):
# Used as a helper function to check if the argument is a number.
try:
float(val)
return True
except Exception:
return False


def calc(op1, op, op2):
# Performs the operation on the operands and returns the result.
if op == '+':
return op1 + op2
elif op == '-':
return op1 - op2
elif op == '*':
return op1 * op2
elif op == '/':
return op1 / op2
elif op == '^':
return op1 ** op2

if sys.argv[-1] == 'n':
print(usage_notes)

start()



Sample output:



n: 1+5
-> 6

c: r
-> 6

c: r*10+50*(3-1)-100
-> 60

c: r
-> 60

c: a=50,b=10
c: r+a+b
-> 120

c: n
n: 2^3+5!
-> 128

c: 1 +- 2
error: invalid expression

c: q



I am looking for ways to make the code more readable, minimize redundancy, improving the overall design, performance improvements, etc. Any help would be appreciated!







python python-3.x calculator math-expression-eval






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 6 hours ago









200_success

134k21 gold badges171 silver badges441 bronze badges




134k21 gold badges171 silver badges441 bronze badges










asked 8 hours ago









sg7610sg7610

433 bronze badges




433 bronze badges







  • 1




    $begingroup$
    Those don't look like postfix expressions to me.
    $endgroup$
    – 200_success
    6 hours ago












  • 1




    $begingroup$
    Those don't look like postfix expressions to me.
    $endgroup$
    – 200_success
    6 hours ago







1




1




$begingroup$
Those don't look like postfix expressions to me.
$endgroup$
– 200_success
6 hours ago




$begingroup$
Those don't look like postfix expressions to me.
$endgroup$
– 200_success
6 hours ago










1 Answer
1






active

oldest

votes


















2












$begingroup$

First, the most glaring thing I see is your use of catch-all exception handlers:



def controller(expr):
. . .
# . . . All the Exceptions
# are terminated, so the main loop keeps running.
. . .
except Exception:
return 'e'

. . .

res = controller(expr)

if res == 'e':
print('error: invalid expressionn')


I have to strongly caution against this practice. You're treating every exception that may possibly come up as though it's caused by a runtime error stemming from bad user input. This is a very dangerous assumption, and will bite you eventually.



In this case, why is it such a big deal? Inside the try, you're calling three different functions, and all of those functions call several other functions. Lets say in the future you decide to modify one of the many functions that are called as a result of calling controller, and lets say you accidentally introduce a bug. In a normal workflow, you'd try to run controller as a test, it would fail horribly because you wrote something incorrect somewhere, and you can use the resulting stack trace to diagnose what caused the problem.



With how you have it here, you would run it... and it would complain about an invalid expression being entered. How much information does that give you about what happened? Throwing away the clues that help you debug a problem will only make your life more difficult once you start writing larger programs and start encountering hard-to-reproduce bugs.



The better way to approach this is to specify the exact exception that you expect to catch instead of using a catch-all Exception. If you expect a ValueError to be thrown if the expression was poorly formed, catch that. That way any other exception that may be raised will still come through. A broken program crashing is a good thing. Let it fail so you can fix it.



The same problem, but to a lesser extent can be seen in isnum (which I'd rename to at least is_num):



def is_num(val):
# Used as a helper function to check if the argument is a number.
try:
float(val)
return True
except Exception:
return False


float seems to only throw two types of exceptions; and only one of them seems relevant here. Change the catch to except ValueError. This isn't a big deal right now since only the call to float is inside the try, but if you add anything later you're opening yourself up to silent failings.



In this code, catch-all exceptions won't be the end of the world. They are a bad habit to get into though, and don't encourage a safe mindset. Be aware of what exceptions the code you're using can throw and react accordingly. Catching everything is just a band-aid.



I'd also space your code out a bit. I personally like empty lines after "bodies" of code, like the bodies of a if...else, or a try...except:



def is_num(val):
try:
float(val)
return True

except Exception:
return False

def controller(expr):
try:
if '=' in expr:
return create_identifiers(expr)

postfix_expr = get_postfix(expr)
return postfix_eval(postfix_expr)

except Exception:
return 'e'


I like giving discrete parts some breathing room. I find it helps readability.




prec = 
prec['!'] = 5
prec['^'] = 4
prec['/'] = 3
prec['*'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1


This could be written as a literal, and I think it would be neater as a result:



prec = '!': 5,
'^': 4,
'/': 3,
'*': 3,
'+': 2,
'-': 2,
'(': 1



Your use of global identifiers isn't ideal. I'd prefer to pass a state around using an explicit parameter to any functions that require access to identifiers. That would make testing functions that use identifiers much easier. With how you have it now, whenever you want to test a function like postfix_eval that uses identifiers, you need to make sure to do identifiers = some_test_state before your call. If it were a parameter, its dependencies would be explicit, and it wouldn't require accessing a global mutable state.




A lot of your functions start with some comments that describe the action of the function:



def calc(op1, op, op2):
# Performs the operation on the operands and returns the result.


This is a good habit to get in. Python has a standardized convention though to handle comments intended for the end-user of the function: docstrings. Right after the function "signature", have a (triple) String literal instead of using # line comments. IDEs will grab this information and allow it to be accessed easier by callers.



def calc(op1, op, op2):
""" Performs the operation on the operands and returns the result. """





share|improve this answer











$endgroup$















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f223772%2fpython-calculator-using-postfix-expressions%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2












    $begingroup$

    First, the most glaring thing I see is your use of catch-all exception handlers:



    def controller(expr):
    . . .
    # . . . All the Exceptions
    # are terminated, so the main loop keeps running.
    . . .
    except Exception:
    return 'e'

    . . .

    res = controller(expr)

    if res == 'e':
    print('error: invalid expressionn')


    I have to strongly caution against this practice. You're treating every exception that may possibly come up as though it's caused by a runtime error stemming from bad user input. This is a very dangerous assumption, and will bite you eventually.



    In this case, why is it such a big deal? Inside the try, you're calling three different functions, and all of those functions call several other functions. Lets say in the future you decide to modify one of the many functions that are called as a result of calling controller, and lets say you accidentally introduce a bug. In a normal workflow, you'd try to run controller as a test, it would fail horribly because you wrote something incorrect somewhere, and you can use the resulting stack trace to diagnose what caused the problem.



    With how you have it here, you would run it... and it would complain about an invalid expression being entered. How much information does that give you about what happened? Throwing away the clues that help you debug a problem will only make your life more difficult once you start writing larger programs and start encountering hard-to-reproduce bugs.



    The better way to approach this is to specify the exact exception that you expect to catch instead of using a catch-all Exception. If you expect a ValueError to be thrown if the expression was poorly formed, catch that. That way any other exception that may be raised will still come through. A broken program crashing is a good thing. Let it fail so you can fix it.



    The same problem, but to a lesser extent can be seen in isnum (which I'd rename to at least is_num):



    def is_num(val):
    # Used as a helper function to check if the argument is a number.
    try:
    float(val)
    return True
    except Exception:
    return False


    float seems to only throw two types of exceptions; and only one of them seems relevant here. Change the catch to except ValueError. This isn't a big deal right now since only the call to float is inside the try, but if you add anything later you're opening yourself up to silent failings.



    In this code, catch-all exceptions won't be the end of the world. They are a bad habit to get into though, and don't encourage a safe mindset. Be aware of what exceptions the code you're using can throw and react accordingly. Catching everything is just a band-aid.



    I'd also space your code out a bit. I personally like empty lines after "bodies" of code, like the bodies of a if...else, or a try...except:



    def is_num(val):
    try:
    float(val)
    return True

    except Exception:
    return False

    def controller(expr):
    try:
    if '=' in expr:
    return create_identifiers(expr)

    postfix_expr = get_postfix(expr)
    return postfix_eval(postfix_expr)

    except Exception:
    return 'e'


    I like giving discrete parts some breathing room. I find it helps readability.




    prec = 
    prec['!'] = 5
    prec['^'] = 4
    prec['/'] = 3
    prec['*'] = 3
    prec['+'] = 2
    prec['-'] = 2
    prec['('] = 1


    This could be written as a literal, and I think it would be neater as a result:



    prec = '!': 5,
    '^': 4,
    '/': 3,
    '*': 3,
    '+': 2,
    '-': 2,
    '(': 1



    Your use of global identifiers isn't ideal. I'd prefer to pass a state around using an explicit parameter to any functions that require access to identifiers. That would make testing functions that use identifiers much easier. With how you have it now, whenever you want to test a function like postfix_eval that uses identifiers, you need to make sure to do identifiers = some_test_state before your call. If it were a parameter, its dependencies would be explicit, and it wouldn't require accessing a global mutable state.




    A lot of your functions start with some comments that describe the action of the function:



    def calc(op1, op, op2):
    # Performs the operation on the operands and returns the result.


    This is a good habit to get in. Python has a standardized convention though to handle comments intended for the end-user of the function: docstrings. Right after the function "signature", have a (triple) String literal instead of using # line comments. IDEs will grab this information and allow it to be accessed easier by callers.



    def calc(op1, op, op2):
    """ Performs the operation on the operands and returns the result. """





    share|improve this answer











    $endgroup$

















      2












      $begingroup$

      First, the most glaring thing I see is your use of catch-all exception handlers:



      def controller(expr):
      . . .
      # . . . All the Exceptions
      # are terminated, so the main loop keeps running.
      . . .
      except Exception:
      return 'e'

      . . .

      res = controller(expr)

      if res == 'e':
      print('error: invalid expressionn')


      I have to strongly caution against this practice. You're treating every exception that may possibly come up as though it's caused by a runtime error stemming from bad user input. This is a very dangerous assumption, and will bite you eventually.



      In this case, why is it such a big deal? Inside the try, you're calling three different functions, and all of those functions call several other functions. Lets say in the future you decide to modify one of the many functions that are called as a result of calling controller, and lets say you accidentally introduce a bug. In a normal workflow, you'd try to run controller as a test, it would fail horribly because you wrote something incorrect somewhere, and you can use the resulting stack trace to diagnose what caused the problem.



      With how you have it here, you would run it... and it would complain about an invalid expression being entered. How much information does that give you about what happened? Throwing away the clues that help you debug a problem will only make your life more difficult once you start writing larger programs and start encountering hard-to-reproduce bugs.



      The better way to approach this is to specify the exact exception that you expect to catch instead of using a catch-all Exception. If you expect a ValueError to be thrown if the expression was poorly formed, catch that. That way any other exception that may be raised will still come through. A broken program crashing is a good thing. Let it fail so you can fix it.



      The same problem, but to a lesser extent can be seen in isnum (which I'd rename to at least is_num):



      def is_num(val):
      # Used as a helper function to check if the argument is a number.
      try:
      float(val)
      return True
      except Exception:
      return False


      float seems to only throw two types of exceptions; and only one of them seems relevant here. Change the catch to except ValueError. This isn't a big deal right now since only the call to float is inside the try, but if you add anything later you're opening yourself up to silent failings.



      In this code, catch-all exceptions won't be the end of the world. They are a bad habit to get into though, and don't encourage a safe mindset. Be aware of what exceptions the code you're using can throw and react accordingly. Catching everything is just a band-aid.



      I'd also space your code out a bit. I personally like empty lines after "bodies" of code, like the bodies of a if...else, or a try...except:



      def is_num(val):
      try:
      float(val)
      return True

      except Exception:
      return False

      def controller(expr):
      try:
      if '=' in expr:
      return create_identifiers(expr)

      postfix_expr = get_postfix(expr)
      return postfix_eval(postfix_expr)

      except Exception:
      return 'e'


      I like giving discrete parts some breathing room. I find it helps readability.




      prec = 
      prec['!'] = 5
      prec['^'] = 4
      prec['/'] = 3
      prec['*'] = 3
      prec['+'] = 2
      prec['-'] = 2
      prec['('] = 1


      This could be written as a literal, and I think it would be neater as a result:



      prec = '!': 5,
      '^': 4,
      '/': 3,
      '*': 3,
      '+': 2,
      '-': 2,
      '(': 1



      Your use of global identifiers isn't ideal. I'd prefer to pass a state around using an explicit parameter to any functions that require access to identifiers. That would make testing functions that use identifiers much easier. With how you have it now, whenever you want to test a function like postfix_eval that uses identifiers, you need to make sure to do identifiers = some_test_state before your call. If it were a parameter, its dependencies would be explicit, and it wouldn't require accessing a global mutable state.




      A lot of your functions start with some comments that describe the action of the function:



      def calc(op1, op, op2):
      # Performs the operation on the operands and returns the result.


      This is a good habit to get in. Python has a standardized convention though to handle comments intended for the end-user of the function: docstrings. Right after the function "signature", have a (triple) String literal instead of using # line comments. IDEs will grab this information and allow it to be accessed easier by callers.



      def calc(op1, op, op2):
      """ Performs the operation on the operands and returns the result. """





      share|improve this answer











      $endgroup$















        2












        2








        2





        $begingroup$

        First, the most glaring thing I see is your use of catch-all exception handlers:



        def controller(expr):
        . . .
        # . . . All the Exceptions
        # are terminated, so the main loop keeps running.
        . . .
        except Exception:
        return 'e'

        . . .

        res = controller(expr)

        if res == 'e':
        print('error: invalid expressionn')


        I have to strongly caution against this practice. You're treating every exception that may possibly come up as though it's caused by a runtime error stemming from bad user input. This is a very dangerous assumption, and will bite you eventually.



        In this case, why is it such a big deal? Inside the try, you're calling three different functions, and all of those functions call several other functions. Lets say in the future you decide to modify one of the many functions that are called as a result of calling controller, and lets say you accidentally introduce a bug. In a normal workflow, you'd try to run controller as a test, it would fail horribly because you wrote something incorrect somewhere, and you can use the resulting stack trace to diagnose what caused the problem.



        With how you have it here, you would run it... and it would complain about an invalid expression being entered. How much information does that give you about what happened? Throwing away the clues that help you debug a problem will only make your life more difficult once you start writing larger programs and start encountering hard-to-reproduce bugs.



        The better way to approach this is to specify the exact exception that you expect to catch instead of using a catch-all Exception. If you expect a ValueError to be thrown if the expression was poorly formed, catch that. That way any other exception that may be raised will still come through. A broken program crashing is a good thing. Let it fail so you can fix it.



        The same problem, but to a lesser extent can be seen in isnum (which I'd rename to at least is_num):



        def is_num(val):
        # Used as a helper function to check if the argument is a number.
        try:
        float(val)
        return True
        except Exception:
        return False


        float seems to only throw two types of exceptions; and only one of them seems relevant here. Change the catch to except ValueError. This isn't a big deal right now since only the call to float is inside the try, but if you add anything later you're opening yourself up to silent failings.



        In this code, catch-all exceptions won't be the end of the world. They are a bad habit to get into though, and don't encourage a safe mindset. Be aware of what exceptions the code you're using can throw and react accordingly. Catching everything is just a band-aid.



        I'd also space your code out a bit. I personally like empty lines after "bodies" of code, like the bodies of a if...else, or a try...except:



        def is_num(val):
        try:
        float(val)
        return True

        except Exception:
        return False

        def controller(expr):
        try:
        if '=' in expr:
        return create_identifiers(expr)

        postfix_expr = get_postfix(expr)
        return postfix_eval(postfix_expr)

        except Exception:
        return 'e'


        I like giving discrete parts some breathing room. I find it helps readability.




        prec = 
        prec['!'] = 5
        prec['^'] = 4
        prec['/'] = 3
        prec['*'] = 3
        prec['+'] = 2
        prec['-'] = 2
        prec['('] = 1


        This could be written as a literal, and I think it would be neater as a result:



        prec = '!': 5,
        '^': 4,
        '/': 3,
        '*': 3,
        '+': 2,
        '-': 2,
        '(': 1



        Your use of global identifiers isn't ideal. I'd prefer to pass a state around using an explicit parameter to any functions that require access to identifiers. That would make testing functions that use identifiers much easier. With how you have it now, whenever you want to test a function like postfix_eval that uses identifiers, you need to make sure to do identifiers = some_test_state before your call. If it were a parameter, its dependencies would be explicit, and it wouldn't require accessing a global mutable state.




        A lot of your functions start with some comments that describe the action of the function:



        def calc(op1, op, op2):
        # Performs the operation on the operands and returns the result.


        This is a good habit to get in. Python has a standardized convention though to handle comments intended for the end-user of the function: docstrings. Right after the function "signature", have a (triple) String literal instead of using # line comments. IDEs will grab this information and allow it to be accessed easier by callers.



        def calc(op1, op, op2):
        """ Performs the operation on the operands and returns the result. """





        share|improve this answer











        $endgroup$



        First, the most glaring thing I see is your use of catch-all exception handlers:



        def controller(expr):
        . . .
        # . . . All the Exceptions
        # are terminated, so the main loop keeps running.
        . . .
        except Exception:
        return 'e'

        . . .

        res = controller(expr)

        if res == 'e':
        print('error: invalid expressionn')


        I have to strongly caution against this practice. You're treating every exception that may possibly come up as though it's caused by a runtime error stemming from bad user input. This is a very dangerous assumption, and will bite you eventually.



        In this case, why is it such a big deal? Inside the try, you're calling three different functions, and all of those functions call several other functions. Lets say in the future you decide to modify one of the many functions that are called as a result of calling controller, and lets say you accidentally introduce a bug. In a normal workflow, you'd try to run controller as a test, it would fail horribly because you wrote something incorrect somewhere, and you can use the resulting stack trace to diagnose what caused the problem.



        With how you have it here, you would run it... and it would complain about an invalid expression being entered. How much information does that give you about what happened? Throwing away the clues that help you debug a problem will only make your life more difficult once you start writing larger programs and start encountering hard-to-reproduce bugs.



        The better way to approach this is to specify the exact exception that you expect to catch instead of using a catch-all Exception. If you expect a ValueError to be thrown if the expression was poorly formed, catch that. That way any other exception that may be raised will still come through. A broken program crashing is a good thing. Let it fail so you can fix it.



        The same problem, but to a lesser extent can be seen in isnum (which I'd rename to at least is_num):



        def is_num(val):
        # Used as a helper function to check if the argument is a number.
        try:
        float(val)
        return True
        except Exception:
        return False


        float seems to only throw two types of exceptions; and only one of them seems relevant here. Change the catch to except ValueError. This isn't a big deal right now since only the call to float is inside the try, but if you add anything later you're opening yourself up to silent failings.



        In this code, catch-all exceptions won't be the end of the world. They are a bad habit to get into though, and don't encourage a safe mindset. Be aware of what exceptions the code you're using can throw and react accordingly. Catching everything is just a band-aid.



        I'd also space your code out a bit. I personally like empty lines after "bodies" of code, like the bodies of a if...else, or a try...except:



        def is_num(val):
        try:
        float(val)
        return True

        except Exception:
        return False

        def controller(expr):
        try:
        if '=' in expr:
        return create_identifiers(expr)

        postfix_expr = get_postfix(expr)
        return postfix_eval(postfix_expr)

        except Exception:
        return 'e'


        I like giving discrete parts some breathing room. I find it helps readability.




        prec = 
        prec['!'] = 5
        prec['^'] = 4
        prec['/'] = 3
        prec['*'] = 3
        prec['+'] = 2
        prec['-'] = 2
        prec['('] = 1


        This could be written as a literal, and I think it would be neater as a result:



        prec = '!': 5,
        '^': 4,
        '/': 3,
        '*': 3,
        '+': 2,
        '-': 2,
        '(': 1



        Your use of global identifiers isn't ideal. I'd prefer to pass a state around using an explicit parameter to any functions that require access to identifiers. That would make testing functions that use identifiers much easier. With how you have it now, whenever you want to test a function like postfix_eval that uses identifiers, you need to make sure to do identifiers = some_test_state before your call. If it were a parameter, its dependencies would be explicit, and it wouldn't require accessing a global mutable state.




        A lot of your functions start with some comments that describe the action of the function:



        def calc(op1, op, op2):
        # Performs the operation on the operands and returns the result.


        This is a good habit to get in. Python has a standardized convention though to handle comments intended for the end-user of the function: docstrings. Right after the function "signature", have a (triple) String literal instead of using # line comments. IDEs will grab this information and allow it to be accessed easier by callers.



        def calc(op1, op, op2):
        """ Performs the operation on the operands and returns the result. """






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 1 hour ago

























        answered 7 hours ago









        CarcigenicateCarcigenicate

        5,7521 gold badge18 silver badges39 bronze badges




        5,7521 gold badge18 silver badges39 bronze badges



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f223772%2fpython-calculator-using-postfix-expressions%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу

            Israel Cuprins Etimologie | Istorie | Geografie | Politică | Demografie | Educație | Economie | Cultură | Note explicative | Note bibliografice | Bibliografie | Legături externe | Meniu de navigaresite web oficialfacebooktweeterGoogle+Instagramcanal YouTubeInstagramtextmodificaremodificarewww.technion.ac.ilnew.huji.ac.ilwww.weizmann.ac.ilwww1.biu.ac.ilenglish.tau.ac.ilwww.haifa.ac.ilin.bgu.ac.ilwww.openu.ac.ilwww.ariel.ac.ilCIA FactbookHarta Israelului"Negotiating Jerusalem," Palestine–Israel JournalThe Schizoid Nature of Modern Hebrew: A Slavic Language in Search of a Semitic Past„Arabic in Israel: an official language and a cultural bridge”„Latest Population Statistics for Israel”„Israel Population”„Tables”„Report for Selected Countries and Subjects”Human Development Report 2016: Human Development for Everyone„Distribution of family income - Gini index”The World FactbookJerusalem Law„Israel”„Israel”„Zionist Leaders: David Ben-Gurion 1886–1973”„The status of Jerusalem”„Analysis: Kadima's big plans”„Israel's Hard-Learned Lessons”„The Legacy of Undefined Borders, Tel Aviv Notes No. 40, 5 iunie 2002”„Israel Journal: A Land Without Borders”„Population”„Israel closes decade with population of 7.5 million”Time Series-DataBank„Selected Statistics on Jerusalem Day 2007 (Hebrew)”Golan belongs to Syria, Druze protestGlobal Survey 2006: Middle East Progress Amid Global Gains in FreedomWHO: Life expectancy in Israel among highest in the worldInternational Monetary Fund, World Economic Outlook Database, April 2011: Nominal GDP list of countries. Data for the year 2010.„Israel's accession to the OECD”Popular Opinion„On the Move”Hosea 12:5„Walking the Bible Timeline”„Palestine: History”„Return to Zion”An invention called 'the Jewish people' – Haaretz – Israel NewsoriginalJewish and Non-Jewish Population of Palestine-Israel (1517–2004)ImmigrationJewishvirtuallibrary.orgChapter One: The Heralders of Zionism„The birth of modern Israel: A scrap of paper that changed history”„League of Nations: The Mandate for Palestine, 24 iulie 1922”The Population of Palestine Prior to 1948originalBackground Paper No. 47 (ST/DPI/SER.A/47)History: Foreign DominationTwo Hundred and Seventh Plenary Meeting„Israel (Labor Zionism)”Population, by Religion and Population GroupThe Suez CrisisAdolf EichmannJustice Ministry Reply to Amnesty International Report„The Interregnum”Israel Ministry of Foreign Affairs – The Palestinian National Covenant- July 1968Research on terrorism: trends, achievements & failuresThe Routledge Atlas of the Arab–Israeli conflict: The Complete History of the Struggle and the Efforts to Resolve It"George Habash, Palestinian Terrorism Tactician, Dies at 82."„1973: Arab states attack Israeli forces”Agranat Commission„Has Israel Annexed East Jerusalem?”original„After 4 Years, Intifada Still Smolders”From the End of the Cold War to 2001originalThe Oslo Accords, 1993Israel-PLO Recognition – Exchange of Letters between PM Rabin and Chairman Arafat – Sept 9- 1993Foundation for Middle East PeaceSources of Population Growth: Total Israeli Population and Settler Population, 1991–2003original„Israel marks Rabin assassination”The Wye River Memorandumoriginal„West Bank barrier route disputed, Israeli missile kills 2”"Permanent Ceasefire to Be Based on Creation Of Buffer Zone Free of Armed Personnel Other than UN, Lebanese Forces"„Hezbollah kills 8 soldiers, kidnaps two in offensive on northern border”„Olmert confirms peace talks with Syria”„Battleground Gaza: Israeli ground forces invade the strip”„IDF begins Gaza troop withdrawal, hours after ending 3-week offensive”„THE LAND: Geography and Climate”„Area of districts, sub-districts, natural regions and lakes”„Israel - Geography”„Makhteshim Country”Israel and the Palestinian Territories„Makhtesh Ramon”„The Living Dead Sea”„Temperatures reach record high in Pakistan”„Climate Extremes In Israel”Israel in figures„Deuteronom”„JNF: 240 million trees planted since 1901”„Vegetation of Israel and Neighboring Countries”Environmental Law in Israel„Executive branch”„Israel's election process explained”„The Electoral System in Israel”„Constitution for Israel”„All 120 incoming Knesset members”„Statul ISRAEL”„The Judiciary: The Court System”„Israel's high court unique in region”„Israel and the International Criminal Court: A Legal Battlefield”„Localities and population, by population group, district, sub-district and natural region”„Israel: Districts, Major Cities, Urban Localities & Metropolitan Areas”„Israel-Egypt Relations: Background & Overview of Peace Treaty”„Solana to Haaretz: New Rules of War Needed for Age of Terror”„Israel's Announcement Regarding Settlements”„United Nations Security Council Resolution 497”„Security Council resolution 478 (1980) on the status of Jerusalem”„Arabs will ask U.N. to seek razing of Israeli wall”„Olmert: Willing to trade land for peace”„Mapping Peace between Syria and Israel”„Egypt: Israel must accept the land-for-peace formula”„Israel: Age structure from 2005 to 2015”„Global, regional, and national disability-adjusted life years (DALYs) for 306 diseases and injuries and healthy life expectancy (HALE) for 188 countries, 1990–2013: quantifying the epidemiological transition”10.1016/S0140-6736(15)61340-X„World Health Statistics 2014”„Life expectancy for Israeli men world's 4th highest”„Family Structure and Well-Being Across Israel's Diverse Population”„Fertility among Jewish and Muslim Women in Israel, by Level of Religiosity, 1979-2009”„Israel leaders in birth rate, but poverty major challenge”„Ethnic Groups”„Israel's population: Over 8.5 million”„Israel - Ethnic groups”„Jews, by country of origin and age”„Minority Communities in Israel: Background & Overview”„Israel”„Language in Israel”„Selected Data from the 2011 Social Survey on Mastery of the Hebrew Language and Usage of Languages”„Religions”„5 facts about Israeli Druze, a unique religious and ethnic group”„Israël”Israel Country Study Guide„Haredi city in Negev – blessing or curse?”„New town Harish harbors hopes of being more than another Pleasantville”„List of localities, in alphabetical order”„Muncitorii români, doriți în Israel”„Prietenia româno-israeliană la nevoie se cunoaște”„The Higher Education System in Israel”„Middle East”„Academic Ranking of World Universities 2016”„Israel”„Israel”„Jewish Nobel Prize Winners”„All Nobel Prizes in Literature”„All Nobel Peace Prizes”„All Prizes in Economic Sciences”„All Nobel Prizes in Chemistry”„List of Fields Medallists”„Sakharov Prize”„Țara care și-a sfidat "destinul" și se bate umăr la umăr cu Silicon Valley”„Apple's R&D center in Israel grew to about 800 employees”„Tim Cook: Apple's Herzliya R&D center second-largest in world”„Lecții de economie de la Israel”„Land use”Israel Investment and Business GuideA Country Study: IsraelCentral Bureau of StatisticsFlorin Diaconu, „Kadima: Flexibilitate și pragmatism, dar nici un compromis în chestiuni vitale", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 71-72Florin Diaconu, „Likud: Dreapta israeliană constant opusă retrocedării teritoriilor cureite prin luptă în 1967", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 73-74MassadaIsraelul a crescut in 50 de ani cât alte state intr-un mileniuIsrael Government PortalIsraelIsraelIsraelmmmmmXX451232cb118646298(data)4027808-634110000 0004 0372 0767n7900328503691455-bb46-37e3-91d2-cb064a35ffcc1003570400564274ge1294033523775214929302638955X146498911146498911

            Smell Mother Skizze Discussion Tachometer Jar Alligator Star 끌다 자세 의문 과학적t Barbaric The round system critiques the connection. Definition: A wind instrument of music in use among the Spaniards Nasty Level 이상 분노 금년 월급 근교 Cloth Owner Permissible Shock Purring Parched Raise 오전 장면 햄 서투르다 The smash instructs the squeamish instrument. Large Nosy Nalpure Chalk Travel Crayon Bite your tongue The Hulk 신호 대사 사과하다 The work boosts the knowledgeable size. Steeplump Level Wooden Shake Teaching Jump 이제 복도 접다 공중전화 부지런하다 Rub Average Ruthless Busyglide Glost oven Didelphia Control A fly on the wall Jaws 지하철 거