4
\$\begingroup\$

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?"))
 outcome1 = integer + added_int
 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()
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Oct 27, 2012 at 18:12
\$\endgroup\$

3 Answers 3

2
\$\begingroup\$

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.

answered Nov 10, 2012 at 3:17
\$\endgroup\$
1
\$\begingroup\$

How about something like this?

import time
def add_num(x):
 added_int = int(raw_input("What number would you like to add to your integer (%s) by?" % x))
 outcome = x + added_int
 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()
answered Oct 27, 2012 at 18:48
\$\endgroup\$
3
  • \$\begingroup\$ You shouldn't define a function div_num() and then inside it use a variable also called div_num \$\endgroup\$ Commented Oct 29, 2012 at 12:37
  • \$\begingroup\$ @Matt eh good spot but really? function local namespace rarely matters. \$\endgroup\$ Commented Oct 29, 2012 at 20:24
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Commented Oct 29, 2012 at 22:28
1
\$\begingroup\$

@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
add_num = lambda start: user_interface_operation(start, op.add)
sub_num = lambda start: user_interface_operation(start, op.sub)
mul_num = lambda start: user_interface_operation(start, op.mul)
div_num = lambda start: user_interface_operation(start, op.div)
answered Apr 24, 2015 at 13:06
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.