# Performing calculations with updated integer

How could I improve this code to make it shorter and more functional?

#!usr/bin/python
import time
integer = 0
print("The current integer is set at " + str(integer) + ".")
print("\n")
time.sleep(2)
prompt = raw_input("Would you like to change the integer? (Y/N) ")
print("\n")
if prompt == 'y':
integer = int(raw_input("Insert the new integer here: "))
print("\n")
print("You have changed the integer to " + str(integer) + ".")
print("\n")
print("\n")
time.sleep(1)
print("1. Add / 2. Subtract / 3. Multiply / 4. Divide")
print("\n")
new_int = raw_input("What would you like to do with your new integer? (Choose a number) ")
print("\n")
if new_int == '1':
added_int = int(raw_input("What number would you like to add to your integer (" + str(integer) + ") by?"))
print("\n")
print("The sum of " + str(integer) + " + " + str(added_int) + " is " + str(outcome1))
if new_int == '2':
subtracted_int = int(raw_input("What number would you like to subtract your integer (" + str(integer) + ") by?"))
outcome2 = integer - subtracted_int
print("\n")
print("The difference of " + str(integer) + " - " + str(subtracted_int) + " is " + str(outcome2))
if new_int == '3':
multiplied_int = int(raw_input("What number would you like to multiply your integer (" + str(integer) + ") by?"))
outcome3 = integer * multiplied_int
print("\n")
print("The product of " + str(integer) + " x " + str(multiplied_int) + " is " + str(outcome3))
if new_int == '4':
divided_int = int(raw_input("What number would you like to divide your integer (" + str(integer) + ") by?"))
outcome4 = integer / divided_int
print("\n")
print("The quotient of " + str(integer) + " / " + str(divided_int) + " is " + str(outcome4))
elif prompt == "n":
print("The integer will stay the same.")
time.sleep(2)
print("Press any key to exit...")
else:
print("Invalid input.")
raw_input()

-

import time

print("\nThe sum of %s + %s is %s" % (x, added_int, outcome))
return outcome

def sub_num(x):
sub_int = int(raw_input("What number would you like to subtract to your integer (%s) by?" % x))
outcome = x - sub_int
print("\nThe subtract of %s - %s is %s" % (x, added_int, outcome))
return outcome

def mul_num(x):
mul_int = int(raw_input("What number would you like to multiply your integer (%s) by?" % x))
outcome = x * mul_int
print("\nThe multiplication of %s * %s is %s" % (x, added_int, outcome))
return outcome

def div_num(x):
div_num = int(raw_input("What number would you like to divide your integer (%s) by?" % x))
outcome = x / float(div_num)
print("\nThe divider of %s / %s is %s" % (x, added_int, outcome))
return outcome

def main():
op_map = {"1":add_num, "2":sub_num, "3":mul_num, "4":div_num}
number = 0
print("The current integer is set at %s ." % number)
while True:
prompt = raw_input("Would you like to change the number? (Y/N)").lower()
if prompt == "y":
number = int(raw_input("Insert the new integer here: "))
print("\nYou have changed the integer to %s .\n\n" % number)
time.sleep(1)
print("1. Add / 2. Subtract / 3. Multiply / 4. Divide\n")

op = raw_input("What would you like to do with your new integer? (Choose a number) \n")
if op is not None:
operation = op_map.get(op)
number = operation(number)

elif prompt == "n":
print("The integer will stay the same.")
time.sleep(2)
raw_input("Press enter key to exit...")
break
else:
print("Invalid response")

if __name__ == '__main__':
main()

-
You shouldn't define a function div_num() and then inside it use a variable also called div_num – Matt Oct 29 '12 at 12:37
@Matt eh good spot but really? function local namespace rarely matters. – Jakob Bowyer Oct 29 '12 at 20:24
It makes the code harder to understand if you use the same name for two different things like that. In general it is bad practice. – Matt Oct 29 '12 at 22:28

Here is a less verbose script that does the basic operations like you are doing. It may be a little advanced for you based on what you wrote, but I thought you might be interested in having a look.

import re

pat = re.compile(r'\s*(\-?\d+\.?\d*)\s*([+-/*])\s*(\-?\d+\.?\d*)\s*')

while True:
print 'Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:'
user_input = raw_input()
if user_input == '-1':
break

m = pat.match(user_input)
if m:
try:
result = eval(m.group())
except ZeroDivisionError:
print 'Cannot divide by zero.',
continue

print m.group(1), m.group(2), m.group(3), '=', result
else:
print 'Invalid expression.',


Sample Output from running the script:

>>>Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
-2 * 1
-2 * 1 = -2
Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
-4 / 0
Cannot divide by zero. Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
5 /2
5 / 2 = 2
Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
5/2.0
5 / 2.0 = 2.5
Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
78--2
78 - -2 = 80
Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
90+2
90 + 2 = 92
Input a basic expression (ex: 12 * 4, 3.24+3, 19/2, etc) or -1 to exit:
-1
>>>


Here's a little breakdown in case you don't understand what's going on. The script uses regular expressions, hence import re, to extract a simple equation. A simple equation meaning a number followed by an operation followed by another number.

'\s*(\-?\d+\.?\d*)\s*([+-/*])\s*(\-?\d+\.?\d*)\s*'


is the regular expression.

\s* means 0 or more spaces
\-? means there may or may not be a - (for negative numbers)
\d+ means 1 or more digits
\.? means there may or may not be a . (for decimal numbers)
\d* means 0 or more digits
[+-/*] means one of those symbols


So lets look at what is being grouped in the brackets ()

(\-?\d+\.?\d*) which means a positive or negative number that could be an integer or a decimal
([+-/*]) which picks the operation to be performed on the numbers
(\-?\d+\.?\d*) which is the same as the first


Each of these expressions in brackets are separated with a \s* and since match(string) only keeps what's in the brackets, all the spacing is ignored.

The regular expression is then compiled and you can use that pattern variable (which I called pat) to match against input (which I stored in m in the line m = pat.match(user_input)).

As I said above, match only keeps what's in the brackets, and it puts them into groups.

m.group(0) #is everything ex) 10*10.5
m.group(1) #is the first brackets contents. ex) 10
m.group(2) #is the second brackets contents. ex) *
m.group(3) #is the third brackets contents. ex) 10.5


You can see how I printed out the equation with the result using m.group(). Also, I should say that when match(input) doesn't find a match, it returns None so if m: in the code passes if a match is found and fails if one isn't.

Finally, eval() will evaluate the expression inside of it which is how we get the result.

You can also see that I used a try/except statement to catch division by zero. Oh and if you put an r in front of a string like r'hello world\n', it is a "raw string" and ignores escaped characters (ie: things like new line \n) and just stores the characters as is.

Even if this isn't exactly what you were looking for, I hope you found it interesting and perhaps learned something from it.

-

@Jackob wrote a better solution, but I can still see much duplication, here you can see a DRY version using higher order functions:

def user_interface_operation(start, operation):
b = int(raw_input("What is x in {} {} x ?".format(start, operation.__name__)))
outcome = operation(start, b)
print("The result is {}".format(outcome))
return outcome