My program is not recognizing its using a negative number - python-3.x

I just started programming for school and this assignment requires me to enter a number and then use it to count from 0 up to the number, then choose a math operation, and then use that math operation.
The problem occurs when I enter a negative number, it gives me the correct message "Too small - Try again: " . but once I enter a positive number it still assigns my original negative number to the program.
Here is my noobie code:
num1 = int(input("\nEnter a number 1 or greater:\t"))
counting = num1 + 1
def count():
print("Counting from 0 to", num1,":")
for i in range(0,counting):
print(i, end = ' ')
math_op()
def reset():
num1 = int(input("Too small - Try again: "))
if num1 <= 0:
reset()
else:
count()
def math_op():
ops = input("\n\nChoose math operation (+, -, *)")
if ops in ('+'):
print("Table for",num1,"using +:")
for i in range(1,11):
print(num1 ,'+', i ,'=', num1 + i)
if ops in ('-'):
print("Table for",num1,"using -:")
for i in range(1,11):
print(num1 ,'-', i ,'=', num1 - i)
if ops in ('*'):
print("Table for",num1,"using *:")
for i in range(1,11):
print(num1 ,'*', i ,'=', num1 * i)
if num1 <= 0:
reset()
else:
count()

Yes, you're missing a while loop:
num1 = -1
while num1 < 1:
num1 = int(input("\nEnter a number 1 or greater:\t"))
# remaining code after here

you never set the number to count when the correction is positive:
def reset():
num1 = int(input("Too small - Try again: "))
if num1 <= 0:
reset()
else:
counting = num1 + 1
count()

Related

Problem with a simple calculator program where an error always seems to occur when entering the number zero

I'm new to the stack overflow website, python, and programming as a whole. So pardon me if the title or body of this question isn't apt.
I'm trying to create a simple calculator program in python, which performs only four operations, namely, addition, subtraction (difference), multiplication and division.
Here's my code:
print("Welcome to the calculator \n")
num1 = int(input("Enter the first number \n"))
num2 = int(input("Enter the second number \n"))
operation = (input("""Enter the symbol of the operation to be performed. Your choices are:
+
- (Difference)
*
/
\n """))
add = num1+num2
sub1 = num1-num2
sub2 = num2 - num1
product = num1*num2
quotient = num1 / num2
if operation == "-" :
if num1 > num2:
print(sub1)
else:
print(sub2)
elif operation == "+" :
print(add)
elif operation == "*" :
print(product)
elif operation == "/" :
if num2 == 0:
print("Sorry, can't divide a number by zero")
else:
print(quotient)
else:
print("Please enter a valid operator from among the ones provided above")
Everything runs fine, except, when I enter zero as num2, and no matter what operator I select, the output
is this:
Traceback (most recent call last):
File "test4.py.txt", line 19, in <module>
quotient = num1 / num2
ZeroDivisionError: division by zero
Help would be greatly appreciated.Thanks!
Find the quotient inside the if condition, not before checking num==0, otherwise the division by zero is already done, causing the error.:
elif operation == "/" :
if num2 == 0:
print("Sorry, can't divide a number by zero")
else:
quotient = num1 / num2
print(quotient)
quotient = num1 / num2
That's the line that is giving you the error. You should be checking if num2 is zero before calculating num1 / num2. You can do it as follows and your program would work fine.
quotient
if num2 == 0:
quotient = None
else :
quotient = num1 / num2
Else you could just declare quotient and calculate the quotient when user inputs the operator. If user enters /, then you can check if num2==0 and if it is you can give error message.
Working code -
print("Welcome to the calculator \n")
num1 = int(input("Enter the first number \n"))
num2 = int(input("Enter the second number \n"))
operation = (input("""Enter the symbol of the operation to be performed. Your choices are:
+
- (Difference)
*
/
\n """))
add = num1+num2
sub1 = num1-num2
sub2 = num2 - num1
product = num1*num2
quotient = None # Don't divide by num2 here or you will get error of divisionbyzero
if operation == "-" :
if num1 > num2:
print(sub1)
else:
print(sub2)
elif operation == "+" :
print(add)
elif operation == "*" :
print(product)
elif operation == "/" :
if num2 == 0:
print("Sorry, can't divide a number by zero")
else:
quotient = num1 / num2
print(quotient)
else:
print("Please enter a valid operator from among the ones provided above")
Since you are new, I will explain this in more detail so you actually know what you are doing wrong
Pay attention to these lines
add = num1+num2
sub1 = num1-num2
sub2 = num2 - num1
product = num1*num2
quotient = num1 / num2
When you do this it is actually performing the calculation and assigning it to the respective value (i.e. quotient = num1 / num2 will actually do the calculation and store the result in the quotient variable). So, you are doing every calculation every time regardless of your choice of operator. It would be better to assign the values only if that operator has been chosen like below.
print("Welcome to the calculator \n")
num1 = int(input("Enter the first number \n"))
num2 = int(input("Enter the second number \n"))
operation = (input("""Enter the symbol of the operation to be performed. Your choices are:
+
- (Difference)
*
/
\n """))
if operation == "-" :
sub1 = num1-num2
sub2 = num2 - num1
if num1 > num2:
print(sub1)
else:
print(sub2)
elif operation == "+" :
add = num1+num2
print(add)
elif operation == "*" :
product = num1*num2
print(product)
elif operation == "/" :
if num2 == 0:
print("Sorry, can't divide a number by zero")
else:
quotient = num1 / num2
print(quotient)
else:
print("Please enter a valid operator from among the ones provided above")
This part is just a suggestion. You could also make your Difference operation easier by using the following.
if operation == "-" :
sub1 = num1-num2
print(abs(sub1))
abs gets the absolute value, basically removes the negative.
You should calculate the results only after checking the operators (thus avoiding any errors caused by trying to divide by zero), this way you will also avoid unnecessary calculations:
elif operation == "/" :
if num2 == 0:
print("Sorry, can't divide a number by zero")
else:
quotient = num1 / num2
print(quotient)

Using generated variable whose value was assigned in one function in another function

New python amateur, and first time posting a question so excuse me if the structure of the question is not standard
Full code, if you understand what i am trying to achieve skip the intro, and skip the first four functions anyway (provided them if you want to execute the full code on your side):
import os, random
modes = ['Addition', 'Subtraction', 'Multiplication', 'Division']
global very_beginning, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds, Round, correct, total_time
def mode_addition():
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " + ", num2)
return num1 + num2
def mode_subtraction():
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
while num1 <= num2:
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " - ", num2)
return num1 - num2
def mode_multiplication():
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " X ", num2)
return num1 * num2
def mode_division():
num2, num3 = random.randrange(1, 10), random.randrange(1, 10)
num1 = num2 * num3
print(num1, " ÷ ", num2)
return num3
def mode_var_names(mode):
return "mode_" + mode.lower() + "()", "c_" + mode.lower()[0:3], mode.lower()[0:3] + "_rounds"
def mental_math():
print("Mental math game: ")
global Round, correct, total_time, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds
Round, total_time = 1, 0
correct, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds = int(), int(), int(), int(), int(), int(), int(), int(), int()
while Round <= 20:
print('Round ' + str(Round), end=":\n\n")
roundmode = random.choice(modes)
mode_info = mode_var_names(roundmode)
print("This round will be about:", roundmode)
correct_answer = eval(mode_info[0])
exec(mode_info[2] + " += 1")
print("The answer is: ", end='')
roundanswer = int(input())
if roundanswer == correct_answer:
print("The answer {} is correct.".format(roundanswer))
correct += 1
exec(mode_info[1] + " += 1")
else:
print("The answer {} is incorrect. The answer should be: {}".format(roundanswer, correct_answer))
print("You got {} out of {} questions correct".format(correct, Round))
user = input("Press enter to continue, or type 'stop' to end this quiz\n")
if user == 'stop' or Round == 20:
result_page()
break
Round += 1
def result_page():
mark = round(correct / Round * 100)
os.system('cls')
print("Mental math game")
print('FIN\n\n')
print("You solved {} questions".format(Round))
print("You got {}% of the questions correct.".format(mark))
print("If you want detailed results type 'details'")
print("If you want to continue, type 'again', else just close this windows or press Enter")
user = input()
if user == "details":
for i in modes:
print("In", i, "You got ", eval(mode_var_names(i)[1]), "correct answers out of ",
eval(mode_var_names(i)[2]))
mental_math()
Intro:
I am putting together a mental math game as coding practice. It randomly chooses the mode from a list of strings: ['Addition', 'Subtraction', 'Multiplication' and 'Division'],uses its name to call the corresponding function which creates the question (for example if it chose Addition it would call a function called mode_addition)and keeps track of the number of correct answers of each mode out of the total of each mode as variables generated on the spot with a predetermined template (for example if it chose addition it would create 2 variables called c_add (stores correct answer) and add_rounds (stores total rounds/questions involving addition) as follows:
modes = ['Addition', 'Subtraction', 'Multiplication', 'Division']
def mode_var_names(mode):
return "mode_" + mode.lower() + "()", "c_" + mode.lower()[0:3], mode.lower()[0:3] + "_rounds"
roundmode = random.choice(modes)
mode_info = mode_var_names(roundmode)
the return keyword returns a string containing the variable name which
is then incremented through exec function
ex: exec(mode_info[1] + " += 1") increments the c_add if mode is
addition
I broke up the app into 2 main functions, the main one called mental_math (which contains the above code and generates the variables) and another one called results_page (which is called once I type in 'stop' at the interpreter or solve 20 questions) to show the percentage and how many questions of each mode have i got correctly.
Now the problem:
I am trying to get the variables generated at the mental_math to print their values at the results_page through the following code :
for i in modes:
print("In", i, "You got ", eval(mode_var_names(i)[1]), "correct answers out of ",
eval(mode_var_names(i)[2]))
And both the correct and the total of all the round return 0:
In Addition You got 0 correct answers out of 0
In Subtraction You got 0 correct answers out of 0
In Multiplication You got 0 correct answers out of 0
In Division You got 0 correct answers out of 0
, while the percentage "mark = round(correct / Round * 100)" is correct. When i copy the print loop back to the mental_math i get the correct numbers ( but still i want to know why the original state doesn't work)
What i tried so far
the global keyword thrown around is a failed attempt to get the results_page to get the modes' variables (but do the job for Round and correct variables), and i can't pass the eval() code used to generate the variables' names directly to global , i thought of using return method but don't know how to use it in this context (and would rather just make the generated variables accessible)
I also tried grouping them together as a class hoping all variables would be accessible to other functions or an instance but failed because i am just starting to learn OOP
Update & Solution:
There are (at least) 2 fixes, the answer Jason Nick Porter, and adding the 2 functions to the same class
Note: I ended up editing this a lot, so it gets increasingly correct as you go along :)
I would start by ditching the globals at the top. Global variables are a fickle mistress, one that I try to avoid at all costs. This would be a great place to use an array in your mental_math() fcn. Inside the function where you currently have:
global Round, correct, total_time, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds
Round, total_time = 1, 0
correct, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds = int(), int(), int(), int(), int(), int(), int(), int(), int()
I would just put:
level, total_time = [1,0] # I put level instead of Round, since round is a keyword and could be confusing
correct = [0,0,0,0] # the index here corresponds to the mode
asked = [0,0,0,0] # numpy.zeros would be an even more robust way to do this
So that each variable exists within the function, and then at the end of mental_math() have something like this:
if user == 'stop' or level == 20:
stats = [level, correct, total_time ] # and all the rest...
result_page(stats)
break
Then all the stats you have are passed to the results_page(). Now you'll want to make the modes into tuples instead of strings at the top of your program. Tuples are basically the best, because you can link together different types of variables, like so:
modes = [('Addition' , 3 , 7), # These numbers correspond to where the correct
('Subtraction' , 4 , 8), # and total numbers will be located in the stats
('Multiplication' , 5 , 9), # array.
('Division' , 6 , 10)] # The spacing just makes it easier to see
Now you'll have to adjust results_page() to receive the array. Then instead of each variable name, you can access all the values by their index. Like so:
def result_page(stats):
mark = round(correct / stats[0] * 100)
os.system('cls')
print("Mental math game")
print('FIN\n\n')
print("You solved {} questions".format(stats[0]))
print("You got {}% of the questions correct.".format(mark))
print("If you want detailed results type 'details'")
user = input("If you want to continue, type 'again', else just close this window or press Enter")
# Fun-fact: If you pass a string to input() it prints it as a prompt
if user == "details":
for i in modes:
print("In", i[0], " you got ", stats[i[1]], " correct answers out of ",
stats[i[2]])
Then you don't even need mode_var_names().
EDIT:
Ok I didn't realize some of the problems with my code, so some of the above is not great. I'm leaving it there in case it's helpful though.
The code below is updated and should let you add as many modes as you want. The problem was that I didn't look closely at mental_math(), so I didn't realize it was still calling mode_var_names(). Now instead of executing a function with a variable string, it just passes an int to a single function, and uses the same int to decide which numbers to update in the "correct" and "asked" arrays.
import os
import random
import numpy as np
modes = [('Addition' , 3 , 7), # These numbers correspond to where the correct
('Subtraction' , 4 , 8), # and total numbers will be located in the stats
('Multiplication' , 5 , 9), # array.
('Division' , 6 , 10)] # The spacing just makes it easier to see
def process(mode):
# if you have more modes you want to add, just add more elif statements
if mode == 0:
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " + ", num2)
return num1 + num2
elif mode == 1:
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
while num1 <= num2:
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " - ", num2)
return num1 - num2
elif mode == 2:
num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
print(num1, " X ", num2)
return num1 * num2
elif mode == 3:
num2, num3 = random.randrange(1, 10), random.randrange(1, 10)
num1 = num2 * num3
print(num1, " ÷ ", num2)
return num3
def mental_math():
print("Mental math game: ")
level, total_time = 0,0 # I put level instead of level, since level is a keyword and could be confusing
correct = np.zeros(len(modes)) # the index here corresponds to the mode
asked = np.zeros(len(modes))
while level <= 20:
level += 1
print('Round ' + str(level), end=":\n\n")
m = random.choice(range(len(modes)))
print("This level will be about:", modes[m][0])
correct_answer = process(m)
asked[m] += 1
levelanswer = int(input("The answer is: "))
if levelanswer == correct_answer:
print("The answer {} is correct.".format(levelanswer))
correct[m] += 1
else:
print("The answer {} is incorrect. The answer should be: {}".format(levelanswer, correct_answer))
print("You got {} out of {} questions correct".format(sum(correct), level))
user = input("Press enter to continue, or type 'stop' to end this quiz\n")
if user == 'stop' or level == 20:
stats = np.hstack((level,sum(correct),total_time,correct,asked))
result_page(stats)
break
def result_page(stats):
mark = round(stats[1] / stats[0] * 100)
os.system('cls')
print("Mental math game")
print('FIN\n\n')
print("You solved {} questions".format(stats[0]))
print("You got {}% of the questions correct.".format(mark))
print("If you want detailed results type 'details'")
user = input("If you want to continue, type 'again', else just close this window or press Enter\n")
if user == "details":
for i in modes:
print("In", i[0], " you got ", stats[i[1]], " correct answers out of ",
stats[i[2]])
mental_math()

Python multiplication function not working

I am a beginner to python wanted to make a simple calculator app which takes multiple inputs for the case of operators 'Add' and 'Multiply'. I was having a problem with the operator 'Multiply where wrong outputs are being diplayed. So can any one help me with the syntax. I would also be thankful if you help me improve the other parts of the code.
print("Type Add to add the numbers")
print("Type Subtract to subtract the numbers")
print("Type Multiply to multiply the numbers")
print("Type Divide to divide the numbers")
Operator = input()
if Operator == "Add":
print("Type the number of numbers you want to add" )
Num_Numbers = range(0,int(input()))
Total = 0
for Count in Num_Numbers:
print("Type Num"+str(Count+1))
Count = int(input())
Total = Total + Count
print(Total)
elif Operator == "Subtract":
print("Type the first number")
Num1 = float(input())
print("Type the second number")
Num2 = float(input())
print(Num1 - Num2)
elif Operator == "Multiply":
print("Type the number of numbers you want to multiply" )
Num_Numbers = range(0,int(input()))
Total = 0
Counter = 0
for Count in Num_Numbers:
print("Type Num"+str(Count+1))
count = int(input())
if Counter != 0:
Counter = Counter + 1
while Total == 0:
Total = Total + count
print("Code implemented")
else:
continue
Total = Total * count
print(Total)
elif Operator == "Divide":
try:
print("Type the first number")
Num1 = float(input())
print("Type the second number")
Num2 = float(input())
print(Num1 / Num2)
except ZeroDivisionError:
print("Division by zero not possible")
else:
print("Operator Unidentified!")
elif Operator == "Multiply":
print("Type the number of numbers you want to multiply" )
Num_Numbers = range(0,int(input()))
Total = 1.0
for Count in Num_Numbers:
print("Type Num"+str(Count+1))
count = float(input()) #chances are the number can be float
Total = Total * count
print(Total)
Just simplified your code!
You put the start Total as 0. 0 multiplied by anything is 0, so you should start at 1:
Total = 1
It's more math than programming.
You also need to remove the strange lines (what are they for?!) shown below:
Counter = 0
#some needed lines
if Counter != 0:
Counter = Counter + 1
while Total == 0:
Total = Total + count
print("Code implemented")
else:
continue
Note for the future that:
var=var+1
Is quicker written as:
var+=1
And the same for other operators, and:
else:
continue
Is obsolete, you don't need a else statement for every if.

Novice Coder with issue properly looping

So I'm a novice coder having never coded before and am teaching myself Python on the guidance of my CS instructor. I'm walking myself through "Automating the Boring Stuff with Python" and I'm having issues with the Collatz sequence portion at the end of Chapter 3. I've got the sequence down but I'm having issues properly looping the code in order to get the result I want which is looping the sequence until the answer is == to integer 1. This is what I have and I would love some feedback and assistance.
def collatz(number): #defines the collatz sequence
if number%2 == 0:
num1 = number//2
else:
num1 = 3 * (number + 1)
return num1
print("Let's try the collatz sequence. Enter a number")
num = int(input())
num3 = collatz(num)
while num3 != 1: #loops collatz sequence until it equals 1
num2 = collatz(num3)
if num2 == 1:
break
else:
num3 = collatz(num2)
print("ta da!")
You need this code:
def collatz(number):
if number % 2 == 0:
num1 = number//2
else: num1 = 3 * number + 1 # Do not use brackets!!! Or you will have infinite loop
return num1
print("Let's try the collatz sequence. Enter a number")
num = int(input())
while num != 1:
num = collatz(num)
print(num)
if num == 1: break
print("ta da!"); input()

When comparing 2 variables output always the same

this is my code for a quiz with ten question.the problem is that whenever I write the answer (the answer gets printed before asking the question) it always say incorrect. please take into consideration that I am very bad at the language and don't correct what doesn't need to be fixed. Thankyou.
from random import randint
name = input("what is your name?")
score = 0
qn = 0
def q():
global qn
global name
global score
qn += 1
if qn < 11:
num1 = randint(1,12)
s = randint(1,3)
num2 = randint(1,12)
if s == 1:
symbal = '+'
answer = num1 + num2
elif s == 2:
symbal = '-'
answer = num1 - num2
elif s == 3:
symbal = '*'
answer = num1 * num2
print(answer)
print(num1 ,symbal ,num2)
sanswer = input("= ?")
if answer == sanswer:
score += 1
print("correct!!!")
else:
print("incorrect")
q()
else:
global name
print("""welldone""")
print(name)
q()
from random import randint
name = input("what is your name?")
score = 0
qn = 0
def q():
global qn
global name
global score
qn += 1
if qn < 11:
num1 = randint(1,12)
s = randint(1,3)
num2 = randint(1,12)
if s == 1:
symbal = '+'
answer = num1 + num2
elif s == 2:
symbal = '-'
answer = num1 - num2
elif s == 3:
symbal = '*'
answer = num1 * num2
print(num1 ,symbal ,num2)
sanswer = int(input("= ?"))
print(answer)
if answer == sanswer:
score += 1
print("correct!!!")
else:
print("incorrect")
q()
else:
global name
print("""welldone""")
print(name)
q()
2 mistake you have:
first: you shouldn't put print(answer) before input
second: you should sanswer = int(input("= ?")) use int() because what you take with input is string
and a simple suggestion try not to use global when coding.

Resources