0

Where in the world did I go wrong? This looks like it would work to me. There is an unused variable; Do I need to import math? There is an error picture in at the bottom of this thread.

import sys

def menu(retries=4):
    menu = ['+ [1]', '- [2]', '/ [3]', '* [4]', 'Exit [0]']
    print(menu)
    x = input("Choose and option 0-4: ")[:1]
    if x == '1':
        add()
    elif x == '2':
        sub()
    elif x == '3':
        div()
    elif x == '4':
        mult()
    elif x == '0':
        print("Terminating")
        xterm()
    else:
        print("Issue")

def xterm():
    sys.exit()
def add():
    a=input("Number 1: ")
    b=input("Number 2: ")
    print(a+b)
def sub():
    a=input("Number 1: ")
    b=input("Number 2: ")
    print(a-b)
def div():
    a=input("Number 1: ")
    b=input("Number 2: ")
    print(a/b)
def mult():
    a=input("Number 1: ")
    b=input("Number 2: ")
    print(a*b)

menu()

Error: https://i.stack.imgur.com/svlKG.png

Girin
  • 11
  • I am thinking I need to convert the inputs, a and b, to floats? – Girin Feb 08 '15 at 10:57
  • 1
    Yes, you need to convert the inputs from string to float (or maybe int), because you want to perform arithmetic on them. And in future, please paste error messages as text, not as images. – PM 2Ring Feb 08 '15 at 10:59
  • Thank you to everyone who had replied. Right after posting someone said "cant subtract strings from strings". I then used y=float(a) and so on. I learn best by trial and error, sticks in my head. I am forever grateful for your replies. Appreciate it! – Girin Feb 08 '15 at 13:22

2 Answers2

4

In Python, you can add strings but cannot subtract them. input() gives you a string. "hello "+"world" will result in "hello world", but "hello "-"world" will give you an error. You can also multiply string, but only by a number (an integer) like this: "a"*3=="aaa".

Here you want inputed data be a number. Use int() or float() then.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
1

input is a string, you need to cast each one before you try to do addition etc.. :

 a = int(input("Number 1: "))
 b = int(input("Number 2: "))

If you are worried about the user entering extra whitespace when comparing the first user input use str.strip:

x = input("Choose and option 0-4: ").strip()

If you use x = input("Choose and option 0-4: ")[:1] and the user enters a space followed by a 1 " 1" you will get an empty string as the value where strip will just remove the whitespace.

You only need cast in the functions you are doing math operations. It is fine to just compare x to "1" etc..

You can use a while loop to verify the initial user input:

def menu():
    menu = ['+ [1]', '- [2]', '/ [3]', '* [4]', 'Exit [0]']
    print(menu)
    while True:
        x = input("Choose and option 0-4: ")[:1]
        if x == '1':
            add()
        elif x == '2':
            sub()
        elif x == '3':
            div()
        elif x == '4':
            mult()
        elif x == '0':
            print("Terminating")
            return
        else:
            print("Invalid choice")


def add():
    a = int(input("Number 1: "))
    b = int(input("Number 2: "))
    print(a  +b)

def sub():
    a = int(input("Number 1: "))
    b = int(input("Number 2: "))
    print(a  -b)

def div():
    a = int(input("Number 1: "))
    b = int(input("Number 2: "))
    print(a / b)

def mult():
    a = int(input("Number 1: "))
    b = int(input("Number 2: "))
    print(a * b)

But using a dict the operator module and one helper function would be much better:

 from operator import add, truediv, sub, mul

def get_nums():
    while True:
        try:
            a = float(input("Number 1: "))
            b = float(input("Number 2: "))
            return  a,b
        except ValueError:
            print("Not a valid number")


def menu():
    menu = ['+ [1]', '- [2]', '/ [3]', '* [4]', 'Exit [0]']
    print(menu)
    ops = {"1":add,"2":sub,"3":truediv,"4":mul}
    while True:
        x = input("Choose and option 0-4: ")
        if x == '0':
            print("Terminating")
            return
        if x in ops:
            a,b = get_nums()
            print(ops[x](a,b))
        else:
            print("Invalid choice")
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • @PM2Ring, the OP is comparing `"1"` etc,, to the first input where they won't need to cast. `"1" != " 1 "` – Padraic Cunningham Feb 08 '15 at 11:12
  • @PM2Ring, don't worry about it – Padraic Cunningham Feb 08 '15 at 11:21
  • I tried using if x = 1 but it wouldn't allow it. I know == is comparing. Now I used [:1] at the end because to my knowledge it only allows one input... Oddly I never even tried adding more. I figured it would prevent any overflow crashing. I have much to learn. I don't want to be able to get 1 by doing 3-2 and then have it execute 1. I want to force only one byte input. Ill test that now, the [:1]. I could always do a if len(x) I suppose. – Girin Feb 08 '15 at 13:25
  • yes only takes the first input but who is to say that is the correct input? really you should use a while loop. I will add an example – Padraic Cunningham Feb 08 '15 at 13:27