Using nested if statements within a while loop (python) - python

Here's my code:
#Greeting
print('\n---Sales Discount Calculator---\n')
#User Input
packageCount = input('Packages Purchased: ')
#To check whether packageCount is an integer or not
#loop continues until a positive integer is inputted
validInput = False
while (validInput == False):
if (packageCount.isdigit()):
packageCount = int(packageCount)
if (packageCount != 0):
validInput = True
print(packageCount)
else:
print('Invalid Input. Try again...')
packageCount = input('Packages Purchased: ')
I'm trying to see if the input from the user is a positive integer and also not a zero. I need to check if it's an integer first(the first if-statement) because you can't compare type string to numbers. If it is an integer, then I need to check if it is a zero or not(second if-statement). When the second if-statement is not present, the code checks for both a positive integer and if it's a string or not, but somehow when I include the second if statement and type in a string, it continues without printing the 'Invalid Input'(the else). *This causes issues later on.

This is because you have two seperate if-else statements. So the first checks for a digit, and sets packageCount to an int explicitly, however if this isn't hit then packageCount stays as a string and continues into the next if statement either way
if (packageCount != 0):
I believe you probably want to indent this in so your code becomes:
#Greeting
print('\n---Sales Discount Calculator---\n')
#User Input
packageCount = input('Packages Purchased: ')
#To check whether packageCount is an integer or not
#loop continues until a positive integer is inputted
validInput = False
while (validInput == False):
if (packageCount.isdigit()):
packageCount = int(packageCount)
if (packageCount != 0):
validInput = True
print(packageCount)
else:
print('Invalid Input. Try again...')
packageCount = input('Packages Purchased: ')
else:
print('Invalid Input. Try again...')
packageCount = input('Packages Purchased: ')
You will notice you now have repeated code, but I will leave that to you to remove :)
---edit---
The extra indents we have added ensures the second if-else is only called if the first is successful. The reason I've added a new else in is so that the error message and input request is maintained.
So the first if checks for an integer, if this fails (ie. the input was a string), then we hit the second else.
If this succeeds we then check if packageCount != 0 and either succeed or hit the first else in the code.

Related

Default output of input

I'm trying to make a sample code that extracts first name from a full name.
If my input is not string or simply press just enter, it will print out enter valid name.
But no matter what I type, it just prints out normal outcome.
Also if I type nothing, it just makes an error.
How can I solve this?
name = input("Enter your full name (end to stop): ")
def print_first_name():
if type(name) == str:
name.split()
first = name.split()[0]
last = name.split()[-1]
print('Your first name is: ', first)
elif name == 'end':
break
else:
print('You must enter at least your first name!')
print_first_name()
name = input("Enter your full name: ")
def print_first_name():
if len(name) > 0:
first = name.split()[0]
if first.isalpha():
print('Your first name is: ', first)
else:
print("Enter a valid name")
last = name.split()[-1]
else:
print('You must enter at least your first name!')
print_first_name()
The condition you wrote (type(name)==str) will always be true
we cant use break outside a loop. (in your case, there was no loop at all, so u cant use break)
if you enter nothing, it gives an error because the line
name.split()[0]
if name="", (which means an empty string), name.split() gives an empty list
In a empty list, there will be no element at index 0, so it gives an error.
When you say if type(name) == str:, then even when you type end as input, this condition is satisfied and the if block is executed and hence code flow never goes to the elif block.
You can put your else condition first and then the if condition:
if name == 'end':
#do whatever
elif type(name) == str:
#do whatever
else:
print('Invalid input')
Your code has a few problems, marked with comments below:
name = input("Enter your full name (end to stop): ")
# Generally you should pass a variable to a function
# or define the variable inside the function, rather
# than using a global variable (name). It's not clear
# which part of the code you want to isolate in a
# function in this example, so it's probably simplest
# not to use a function at all.
def print_first_name():
# The next test will always be True, so the else
# and elif parts will never run.
# You probably want a test for non-empty
# strings with only alphabetic characters instead
if type(name) == str:
# the next line creates a list of the parts of
# name (if possible) but doesn't store it
# anywhere, so it has no effect.
name.split()
# the next two lines will fail if name is
# an empty string
first = name.split()[0]
last = name.split()[-1]
print('Your first name is: ', first)
# the next block needs to be moved earlier to
# make sure it is tested before you try to extract
# the names
elif name == 'end':
# break cannot be used inside a function
# even if the function is called in a loop
break
else:
print('You must enter at least your first name!')
print_first_name()
Here's a version that fixes these problems:
while True:
name = input("Enter your full name (end to stop): ")
# check this first, to avoid treating as a name
if name == 'end':
break
# check whether name contains any digits or is empty
elif name.isalpha() and name != "":
name_parts = name.split()
first = name_parts[0]
last = name_parts[-1]
print('Your first name is: ', first)
else:
print('You must enter at least your first name!')
input() defaults to returning a string type. It looks like you're trying to sanitize the input by making sure the input is a string of letters, and also has a length > 0 before running.
You would probably be served by flipping out
if type(name) == str:
with something that checks both for a non-zero AND alpha only. so something like
if name.isalpha() and len(name) > 0:
{conditional code here...}
The input is always string, so you can use a array or list to store 0 -> 9 numbers (The str one). If there is a number in input, it'll print something.
You can use '' to describe that input is empty

Python While loop breakout issues

The question I have is about the flag I have here for the while loop. This works but not like I think it should. I assume I'm not understanding something so if someone is able to explain, that would be great.
From my understanding this should break out of the loop as soon as one of my conditionals is met. So if I input 'q' it should break out and stop the loop. But what happens is it keeps going through the loop and then it breaks out. so it goes through the last prompt and prints the exception.
(Python version is 3.8.5)
# Statement that tells the user what we need.
print("Enter two numbers and I will tell you the sum of the numbers.")
# Lets the user know they can press 'q' to exit the program.
print("Press 'q' at anytime to exit.")
keep_going = True
# Loop to make the program keep going until its told to stop.
while keep_going:
# Prompt for user to input first number and store it in a variable.
first_number = input("First number: ")
# Create a break when entering the first number.
if first_number == 'q':
keep_going = False
# Prompt for user to input second number and store it in a variable.
second_number = input("Second number: ")
# Create a break when entering the second number.
if second_number == 'q':
keep_going = False
# Exception for non integers being input "ValueError"
try:
# Convert input to integers and add them.
# storing the answer in a variable.
answer = int(first_number) + int(second_number)
except ValueError:
# Tell the user what they did wrong.
print("Please enter a number!")
else:
# Print the sum of the numbers
print(f"\nThe answer is: {answer}")
Using this code it breaks out right away like I expect it to.
while True:
first_number = input("First number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
if second_number == 'q':
break
I just would like to understand what the difference is and if thats how it should work. I feel like I'm missing something or misunderstanding something.
The condition of the while loop is only checked between iterations of the loop body, so if you change the condition in the middle of the loop, the current iteration will finish before the loop terminates. If you want to break a loop immediately, you need to either break (which automatically breaks the loop regardless of the condition) or continue (which jumps to the next iteration, and will therefore terminate the loop if the condition is no longer true).
Using while True: with a break when you want to stop the loop is generally much more straightforward than trying to control the loop by setting and unsetting a flag.
FWIW, rather than copying and pasting the code to input the two numbers, and have two different ways to break out of the loop, I might put that all into a function and break the loop with an Exception, like this:
print("Enter two numbers and I will tell you the sum of the numbers.")
print("Press 'q' at anytime to exit.")
def input_number(prompt: str) -> int:
"""Ask the user to input a number, re-prompting on invalid input.
Exception: raise EOFError if the user enters 'q'."""
while True:
try:
number = input(f"{prompt} number: ")
if number == 'q':
raise EOFError
return int(number)
except ValueError:
print("Please enter a number!")
while True:
try:
numbers = (input_number(n) for n in ("First", "Second"))
print(f"The answer is: {sum(numbers)}")
except EOFError:
break
This makes it easier to extend the program to handle more than two inputs; try adding a "Third" after where it says "First" and "Second"! :)
Once you run the program and type "q", Yes indeed keep_going will be set to False but it DOES NOT MEAN it will break the loop already, it will just make the keep_going be equal to False thus on the NEXT ITERATION will stop the loop. Why is that? because it would be like this while keep_going: -> while False: so since it is not True thus not executing the program anymore.
Now based on your goal as you mentioned. You can do it this way where you can add the break.
if first_number == 'q':
keep_going = False
break
# Prompt for user to input second number and store it in a variable.
second_number = input("Second number: ")
# Create a break when entering the second number.
if second_number == 'q':
keep_going = False
break
I'd also like to suggest have it this way, it's just more specific in terms of what is to happen on the code, but of course it is up to you.
first_number = input("First number: ")
# Create a break when entering the first number.
if first_number == 'q':
keep_going = False
break
# Prompt for user to input second number and store it in a variable.
# Create a break when entering the second number.
else:
second_number = input("Second number: ")
if second_number =='q':
keep_going = False
break
While loops execute until their given condition is false. A loop will only check its condition when required (program execution is moved to the top of the loop). In almost every case, this occurs when the full body of the loop has run. See here:
keep_going = True
while keep_going:
keep_going = False
# keep_going is False, but this will still print once
# because the loop has not checked its condition again.
print("Will execute once")
"Will execute once" prints a single time even after keep_going is set to False. This happens because the while loop does not re-check its condition until its entire body has run.
However, break statements are different. A break statement will cause a loop to exit immediately no matter what.
keep_going = True
while keep_going:
break # Exits the while loop immediately. The condition is not checked.
print("Will never print")
Here, nothing is printed even though keep_going is True the whole time. break made the loop exit regardless of the condition.
A continue statement will move program execution back to the start of the loop, and cause your condition to be checked again.
In this example, continue sends program execution back to the start of the loop. Since keep_going was set to False, nothing will print because the while loop will exit after realizing its condition evaluates to false.
keep_going = True
while keep_going:
keep_going = False
continue
print("Will never print")
First off, hope you have a great time learning Python!
Both ways will work and stop the loop, but there is a difference:
In the first method, you are changing the keep_going variable to false, therefore, the loop will stop when the the while loops finds out that keep_going had become False. However, the checking only happens at the end of the loop (In your case, it is after you have done your except or else part), the loop will not stop right away even when you entered q for your variable first_number.
In the second solution, you are using the break keyword in Python, to break away from the loop right away after you entered q for first_number.
Technically speaking, you will want to break if you want to break off from the loop right away when q is detected, otherwise, setting keep_going to False if you want the whole loop to be completed, but not run again for the next round.
In scenario 1 the result, even when you entered q,
Please enter a number!
Will always show, but not for scenario 2.
this is a little different approach to your script:
def main():
print("Enter two numbers and I will tell you the sum of the numbers.")
print("Press 'q' at anytime to exit.")
val = []
while True:
check_value = lambda x: 'quit' if x.lower() == 'q' or x.lower() == 'quit' else int(x)
if not val:
value = input("First number: ")
elif len(val) == 2:
answer = sum(val)
print(f"\nThe answer is: {answer}")
print('==='*15 + ' < ' + f'PROGRAM RESTARTING' + ' > ' + '==='*15)
val[:] = []
continue
else:
value = input("Second number: ")
try:
check_ = check_value(value)
val.append(check_)
except ValueError:
print("Please enter a number!")
continue
finally:
if check_ == 'quit':
print('Program is stopping....')
break
else:
pass
if __name__ == '__main__':
main()
It check at anytime the user's input, whether is a 'q' 'Q' or ('quit' or 'QUIT') or any combination or capital letter because run the check x.lower()
I suggest you to have a look at realpython.com especially the paragraph "he Python break and continue Statements."
Long story short:
Use Break to terminate the loop at any given time.
Use continue to roll back where you left and repeat the loop again (I used it in my code if the value is not a Int)
User pass to keep the loop running with no stop.

How to use and debug conditional statements in Python?

while True:
n1 = int(input("Enter first number: "))
if n1>255:
print("Invalid input. Sorry the number should be less than 255.")
continue
elif n1<255:
print("The input is valid.")
n2 = int(input("Enter second number: "))
if n2>255:
print("Invalid input. Sorry the second number should be less than 255.")
continue
elif n2<255:
print("The input is valid.")
break
Whenever I enter 'n2' higher than 255, it shows enter first number. I want it to show enter second number.
continue starts the whole while loop over: it doesn't go back to before the last if statement or anything like that. So your second continue effectively starts your program over. You need to get rid of this continue, and use some other method to redo this input.
The problem is the continue statement in the first if. continue does not mean "go on". It means, "ignore the rest of the while/for loop, and repeat from its next iteration". So, actually, the next time you are at the input prompt, are not entering n2, you are again the the same line and entering n1 again. Remove the continue statement.
Take a look at how break and continue statements work, they are pretty much the same in all languages (that I know of at least)

Why does my While loop Exit?

My comments illustrate my line of reasoning but clearly I've got something wrong. My code just jumps straight to "Your total debt is..."
# Dictionary of Bills
expenses = {'mortgage':[], 'personal':[], 'power':[], 'insurance':[], 'water':[], 'food':[], 'savings':[], 'fuel':[], 'phone':[], 'internet':[], 'credit':[], 'emergencies':[]}
totalDebt = 0
switch = "A"
while switch == switch.isalpha(): # Condition is true, switch is a letter
for each in expenses: # Iterates through each bill
debt = input("%s: "%each) # User input
if debt.isdigit(): # checks to make sure they only enter numbers
debt = int(debt) # Converts debt to its integer value
totalDebt = totalDebt + debt # adds debt to keep a running total.
else: # User entered something other than a number
print("Only enter digits!")
print("Your total Debt is: $%i" %totalDebt)
input("Press Enter to continue: ")
print("What is this fortnights Income?")
Your condition doesn't make any sense here:
while switch == switch.isalpha(): # Condition is true, switch is a letter
switch.isalpha() returns either True or False. switch itself will not be equal to either of those two values, so the whole expression is always going to be False. Remove the equality test:
while switch.isalpha(): # Condition is true, switch is a letter
Note that your code never actually changes switch, so now your loop is going to continue forever.
The While is False
>>> switch
'A'
>>> switch.isalpha()
True
>>> switch == switch.isalpha()
False
You must use switch.isalpha() allown

Program that is supposed to determine whether or not the user typed an even or odd integer?

A program that determines whether the integer the user entered is even or odd. I keep getting errors for the elif statement. What am I doing wrong?
while True:
reply=input('enter an even or odd integer:') #ASK USER TO ENTER AN EVEN OR ODD INTEGER
if reply=='stop':break #PRINTS OUT THE WORD 'STOP' IF THE USER WANTS TO EXIT THE PROGRAM
try:
num=int(reply) #USER ENTERS NUMBER
except:
print('you did not an integer integer')# IF THE USER PRINTS ANYTHING OTHER THAN AN INTEGER
else:
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
elif num%2!=0: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
Convert the elif to an if statement, there is no corresponding if block for it in your current code.
while True:
reply=input('enter an even or odd integer:') #ASK USER TO ENTER AN EVEN OR ODD INTEGER
if reply=='stop':break #PRINTS OUT THE WORD 'STOP' IF THE USER WANTS TO EXIT THE PROGRAM
try:
num=int(reply) #USER ENTERS NUMBER
except:
print('you did not an integer integer')# IF THE USER PRINTS ANYTHING OTHER THAN AN INTEGER
else:
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
if num%2!=0: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
or, convert it to an else statement and indent it with your if statement in else block of try-except:
while True:
reply=input('enter an even or odd integer:') #ASK USER TO ENTER AN EVEN OR ODD INTEGER
if reply=='stop':break #PRINTS OUT THE WORD 'STOP' IF THE USER WANTS TO EXIT THE PROGRAM
try:
num=int(reply) #USER ENTERS NUMBER
except:
print('you did not an integer integer')# IF THE USER PRINTS ANYTHING OTHER THAN AN INTEGER
else:
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
else: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
The problem is if and elif are mismatched.. You need to indent more
while True:
reply=input('enter an even or odd integer:') #ASK USER TO ENTER AN EVEN OR ODD INTEGER
if reply=='stop':break #PRINTS OUT THE WORD 'STOP' IF THE USER WANTS TO EXIT THE PROGRAM
try:
num=int(reply) #USER ENTERS NUMBER
except:
print('you did not an integer integer')# IF THE USER PRINTS ANYTHING OTHER THAN AN INTEGER
else:
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
elif num%2!=0: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
Must be of same Indent level
Order and indent matters, the correct order is if-elif-else. You can't use it like if-else-elif. If your elif statement under the else, then you have to put them at the same line.
else:
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
elif num%2!=0: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
A much nicer way to write your program would be:
while True:
reply=input('enter an even or odd integer:') #ASK USER TO ENTER AN EVEN OR ODD INTEGER
if reply=='stop':
break #TYPE OUT THE WORD 'STOP' IF THE USER WANTS TO EXIT THE PROGRAM
else:
try:
num=int(reply) #USER ENTERS NUMBER
if num%2==0:
print('you printed an even integer')#iF USER TYPES AN EVEN INTEGER, THEY PRINT OUT THIS STATEMENT
elif num%2!=0: #IF THE TYPES AN ODD INTEGER , PROGRAM IS THEN SUPPOSED TO DISPLAY THE STATEMENT BELOW
print('you printed an odd integer')
except:
print('you did not an integer integer')# IF THE USER PRINTS ANYTHING OTHER THAN AN INTEGER
Previously your conditional statements were mismatched, thus giving you an error.
You have an indentation bug. The last elif should be at the same if num%2==0 indentation level.

Categories

Resources