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()
\$\endgroup\$

3 Answers 3

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()
\$\endgroup\$
3
  • \$\begingroup\$ You shouldn't define a function div_num() and then inside it use a variable also called div_num \$\endgroup\$
    – Matt
    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\$
    – Matt
    Commented Oct 29, 2012 at 22:28
1
\$\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.

\$\endgroup\$
0
\$\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)
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.