user3605899
user3605899

Reputation: 11

need help converting integers to string in a list

I'm writing a program for my intro programming class and I need to make a calculator that prints out the results like a history. I'm doing it in a way that the first number, the arithmetic operation and second number are separate objects in a list but I need to combine them into a complete object in a list. I've tried several ways to do this but each time it will either crash or not work exactly how it should.

history = []
first_number = int(input("please input your first number"))
second_number = int(input("please input your second number"))
operator = input("ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? ").lower()

def add():
    return(first_number + second_number)

def problemAdd(): 
    return(first_number, "+", second_number)

while operator != "stop":
    if operator == "add":
        print("the problem was:", first_number, "+", second_number, "=", add())
        history.append (problem())
        print(history)
        first_number = int(input("please input your first number"))
        second_number = int(input("please input your second number"))
        operator = input("ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? ").lower()

Now this part of the code I hope it's enough to spot a problem. And this is what it outputs:

please input your first number2
please input your second number2
would you like to ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? add
the problem was: 2 + 2 = 4
[(2, '+', 2)]
please input your first number1
please input your second number2
would you like to ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? add
the problem was: 1 + 2 = 3
[(2, '+', 2), (1, '+', 2)]
please input your first number

I ran through it twice to show how each individual problem is displayed.

Upvotes: 1

Views: 60

Answers (1)

Adam Smith
Adam Smith

Reputation: 54213

# lst = [(2, '+', 2)]
for tpl in lst:
   operation = " ".join(map(str,tpl))
   # map(str, tpl) returns an object where every element in tpl is mapped
   # using the str function. str(object) returns the value of object as a
   # string.

   result = eval(operation)
   # eval IS A BAD IDEA, BUT SIMPLE TO IMPLEMENT

   print("{} = {}".format(operation, result))

It's a little unclear if this is what you're trying to do. I'm not sure where the [ ..., "3 - 2 = 1"] part from your question comes in. Maybe this will help, though?

If you only ever have two operands and one operator (e.g. everything is of the form a ? b where ? is an operator, then this is much safer:

def do_operation(operation):
    import operator
    operand_1, operator, operand_2 = operation
    try:
        f = {"+": operator.add, "-": operator.sub,
             "/": operator.truediv, "*": operator.mul,
             "//": operator.floordiv, "%": operator.mod}[operator]
    except KeyError:
        raise ValueError("Invalid operator")
    return f(operand_1, operand_2)

for tpl in lst:
    operation = " ".join(map(str,tpl))
    result = do_operation(tpl)
    print("{} = {}".format(operation, result))

Directly responding to your question:

history = []

first_number = int(input("please input your first number"))    
second_number = int(input("please input your second number"))
# what do you do if the user doesn't enter a number? Your program crashes

operator = input("ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? ").lower()
op_mapping = {"add":"+", "subtract":"-", "divide":"/", "multiply":"*"}

if operator in op_mapping: # this will exclude 'choose' and 'stop'
    operator = op_mapping[operator]
elif operator == 'choose': # handle it
elif operator == 'stop': # handle it, these are up to you
else: # invalid input, handle it.

# NEW
operation = (first_number, operator, second_number)
# this makes it easier to refer to all three at once.

def calculate(operation):
    """Calculates the result based on which operator is used"""
    import operator
    operand_1, operator, operand_2 = operation
    try:
        f = {"+": operator.add, "-": operator.sub,
             "/": operator.truediv, "*": operator.mul,
             "//": operator.floordiv, "%": operator.mod}[operator]
    except KeyError:
        raise ValueError("Invalid operator")
    return f(operand_1, operand_2)

## while operator != "stop": # you're gonna handle this above

## if operator == "add": # we modified it so our mapping handles all if cases
##     print("the problem was:", first_number, "+", second_number, "=", add())  
##     history.append (problem())  
##     print(history)  
##     first_number = int(input("please input your first number"))    
##     second_number = int(input("please input your second number"))  
##     operator = input("ADD, SUBTRACT, DIVIDE, MULTIPLY, CHOOSE again or STOP? ").lower()

human_readable = " ".join(map(str,operation))
history.append(human_readable)
print("{} = {}".format(human_readable, calculate(operation))
print(history)

# LOOP AS NEEDED, IMPLEMENTED BY YOU.

Mind you if I were to do a complete rewrite it would probably look like:

def get_input():
    """Get user input for the calculation"""
    inputprompt = """Return the result of a calculation, based on user input.
Your input must be of the form X ? Y where X, Y are any number and ? is one of:
+, -, /, //, *, %
Please include spaces between operand and operator, or STOP to stop.

>> """
    return input(inputprompt)

def calculate(operation):
    """Calculates the result based on which operator is used"""
    import operator
    operand_1, operator, operand_2 = operation
    try:
        operand_1, operand_2 = float(operand_1), float(operand_2)
    except ValueError:
        raise ValueError("Invalid operand")
    try:
        f = {"+": operator.add, "-": operator.sub,
             "/": operator.truediv, "*": operator.mul,
             "//": operator.floordiv, "%": operator.mod}[operator]
    except KeyError:
        raise ValueError("Invalid operator")
    return f(operand_1, operand_2)

def main():
    from collections import deque
    history = deque()
    # a deque is a list that allows easy popping and appending from left OR right
    MAX_HISTORY_LENGTH = 10
    while True
        print("CALCULATOR:\n\n")
        readable = get_input()
        if "stop" in readable.lower():
            break
        operation = readable.split()
        history.append(readable)
        if len(history) > MAX_HISTORY_LENGTH:
            history.popleft()
        print("{} = {}".format(readable, calculate(operation))
        input(" ( press ENTER to continue ) ")

main()
# we love functional programming!

Upvotes: 2

Related Questions