Home > Enterprise >  While iterating through my dictionary it's not picking up my keys even though I'm inputtin
While iterating through my dictionary it's not picking up my keys even though I'm inputtin

Time:05-17

Calculator that takes 3 user inputs: operation signs and numbers 1-5 spelled out. Then it converts them to numbers and symbols. Users can input them in any order. The problem is in my for loops in functions i(1-3) the only input that works is one any other doesn't convert to a number or symbol.

dictt = {
    'one': 1,
    'two': 2,
    'three': 3,
    'four': 4,
    'five': 5,
    'add': r" ",
    'subtract': r"-",
    'multiply': r"*",
    'divide': r"/"
}
def i1():
    i1 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
    num1=0
    for k,v in dictt.items():
        if i1 == k:
            num1 = dictt[k]
        return num1

def i2():
    i2 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
    num2=0
    for k,v in dictt.items():
        if i2 == k:
            num2 = dictt[k]
        return num2

def i3():
    i3 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
    num3=0
    for k,v in dictt.items():
        if i3 == k:
            num3 = dictt[k]
        return num3

def main():
    x=i1()
    y=i2()
    z=i3()
    listo=[x,y,z]
    listn=[]
    for i in listo:
        if i == int:
            listn.append(i)
            listo.remove(i)
        else:
            pass
    if len(listn) == 2:
        if listo[0] == "add":
            result=listn[0] listn[1]
            return f"{listn[0]}   {listn[1]} = {result}"
        elif listo[0] == "subtract":
            result = listn[0] - listn[1]
            return f"{listn[0]} - {listn[1]} = {result}"
        elif listo[0] == "multiply":
            result=listn[0] * listn[1]
            return f"{listn[0]} * {listn[1]} = {result}"
        elif listo[0] == "divide":
            result=listn[0] / listn[1]
            return f"{listn[0]} / {listn[1]} = {result}"
    elif len(listn) < 2:
        return "not enough numbers"
    elif len(listo) != 1:
        return "just one operator"

CodePudding user response:

Your iteration is broken because you return too early, but you don't need to iterate through a dictionary to look up an item in it in the first place. Instead of:

def i1():
    i1 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
    num1=0
    for k,v in dictt.items():
        if i1 == k:
            num1 = dictt[k]
        return num1

do:

def i1():
    i1 = input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': ")
    return dictt.get(i1, 0)

You also don't need i2 and i3, because all of these functions do exactly the same thing, just with different names. Instead of:

    x=i1()
    y=i2()
    z=i3()
    listo=[x,y,z]

you could just do:

    listo = [i1(), i1(), i1()]

or:

    listo = [i1() for _ in range(3)]

I might suggest simplifying the overall code by putting all the inputs in a list, sorting them into numbers and functions, and then applying them, rather than having a bunch of if statements:

ops = {
    'one': 1,
    'two': 2,
    'three': 3,
    'four': 4,
    'five': 5,
    'add': (" ", int.__add__),
    'subtract': ("-", int.__sub__),
    'multiply': ("*", int.__mul__),
    'divide': ("/", int.__truediv__),
}


def get_op():
    while True:
        try:
            return ops[input(
                "Please input 'add', 'subtract', 'multiply', 'divide', "
                "'one', 'two', 'three' , 'four', or 'five': "
            )]
        except KeyError:
            print("Not a valid input.")


def main():
    while True:
        ops = [get_op() for _ in range(3)]
        nums = [n for n in ops if isinstance(n, int)]
        f = [f for f in ops if isinstance(f, tuple)]
        if len(f) == 1 and len(nums) == 2:
            break
        else:
            print("Must enter exactly two numbers and one operation.")
    symbol, func = f.pop()
    expr = f" {symbol} ".join(str(n) for n in nums)
    return f"{expr} = {func(*nums)}" 

if __name__ == '__main__':
    print(main())

CodePudding user response:

I think you make your codes a little bit complicated, which will be difficult to maintain, this can be simple if using operator

    from operator import add, sub, mul, truediv
    from typing import Callable
    
    dictt = {
        'one': 1,
        'two': 2,
        'three': 3,
        'four': 4,
        'five': 5,
        'add': add,
        'subtract': sub,
        'multiply': mul,
        'divide': truediv,
    }
    
    
    def main():
        input_msg = "Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "
    
        v1 = dictt.get(input(input_msg).strip())
        v2 = dictt.get(input(input_msg).strip())
        v3 = dictt.get(input(input_msg).strip())
    
        if isinstance(v2, Callable) and v1 and not isinstance(v1, Callable) and v3 and not isinstance(v3, Callable)::
            return v2(v1, v3)
        else:
            return 'Invalid input'
    
    
    if __name__ == '__main__':
        res = main()
        print(res)
  • Related