Python infinite while loop issue - python

I am trying to make a script that asks for user input in Python, it is supposed to error with the response "Please enter first name", and then return the user back to the initial input question prompt.
This isn't working, instead after asking for both the first and last name if no name is given for both I am thrown into an infinite loop of the first error.
# User input for first name
first_name = input('Enter FIRST name here: ')
# User input for last name
last_name = input('Enter LAST name here: ')
def print_name():
# store user input in separate variable
fname = first_name
lname= last_name
while True:
# throw error if user enters no first name
if len(fname) == 0:
# error msg
print('No FIRST name entered...')
# loop back to prompt asking for first name
continue
else:
# if first name given move on to prompting for last name
# break loop
break
# loop into prompting user for last name
while True:
# throw error if user enters no last name
if len(lname) == 0:
print('No LAST name entered...')
# loop back to prompt asking for last name
continue
else:
# if last name given move on to running print command
# break loop
break
return fname, lname
print(f'your name is {fname} {lname}')
print_name()
Please can someone help me understand whats going wrong here? It should only loop back to asking for a first name (or last name) when nothing is given, other wise it should print the users name to console. both names should be given too, if first name is not given then id expect an error in the first while loop, like wise if last name is not given.
Also is there a better way to do this? using 2 while loops seems wrong?

Don't repeat yourself. If you copy and paste a section of code, stop and think. It should either be a function, or a loop.
def wait_for_input(prompt):
data = ""
while data == "":
data = input(prompt).strip()
return data
def print_name(fname, lname):
print(f'your name is {fname} {lname}')
first_name = wait_for_input('Enter FIRST name: ')
last_name = wait_for_input('Enter LAST name: ')
print_name(first_name, last_name)
Also, don't use comments to repeat what the code says.

The issue is with your infinite loops, you can simplify your function like:
def print_name():
first_name = ""
last_name = ""
# User input for first name
while first_name == "":
first_name = input('Enter FIRST name here: ')
# User input for last name
while last_name == "":
last_name = input('Enter LAST name here: ')
print(f'your name is {first_name} {last_name}')

I have the impression you are new at this:
While-loops generally look as follows:
while <condition>
...
<check_condition>
...
This means that in most cases, at every time the loop is executed, the condition is re-calculated and checked again by the while.
In your case, this would become something like:
while (len(fname) == 0)
<show_error_message>
<get fname again>
The case you have written here (while true) also exists and is used regularly, but in very different cases, like in multi-threaded event-based programs:
while true
<get_event>
This means that a part of the program (a so-called thread) is waiting for an event (like a buttonclick) to be catched and then something happens. This, however, is mostly done in multi-threaded applications, which means that the "main" program is doing something, while a subprogram is handling the events, which are coming in.

I am not fully understanding why you need so many loops. Something like this should do:
def print_name():
fname = input('Enter FIRST name here: ')
if len(fname) == 0:
raise Exception('No FIRST name entered...')
lname= input('Enter LAST name here: ')
if len(lname) == 0:
raise Exception('No LAST name entered...')
print(f"your name is {fname} {lname}")
And if all you wanted is to repeat this loop all you need to do is nest your print_name() function in a loop.
EDIT: Now that I seen other answers, I believe #Tomalak answer is better, was not getting what you really wanted.

Try this code:
def print_name():
# store user input in separate variable
first_name = input('Enter FIRST name here: ')
fname = first_name
while True:
fname = first_name
# throw error if user enters no first name
if len(fname) == 0:
# error msg
print('No FIRST name entered...')
first_name = input('Enter FIRST name here: ')
# loop back to prompt asking for first name
continue
else:
# if first name given move on to prompting for last name
# break loop
break
# loop into prompting user for last name
while True:
last_name = input('Enter LAST name here: ')
lname= last_name
# throw error if user enters no last name
if len(lname) == 0:
print('No LAST name entered...')
# loop back to prompt asking for last name
continue
else:
# if last name given move on to running print command
# break loop
break
return fname, lname
print(f'your name is {fname} {lname}')
print_name()

Related

How can I create an input that will loop and create a new list each time?

in case it isn't already obvious im new to python so if the answers could explain like im 5 years old that would be hugely appreirecated.
I'm basically trying to prove to myself that I can apply some of the basic that I have learnt into making a mini-contact book app. I don't want the data to save after the application has closed or anything like that. Just input your name, phone number and the city you live in. Once multiple names are inputted you can input a specific name to have their information printed back to you.
This is what I have so far:
Name = input("enter name here: ")
Number = input("enter phone number here: ")
City = input("enter city here: ")
User = list((Name, Number, City))
This, worked fine for the job of giving python the data. I made another input that made python print the information back to me just to make sure python was doing what I wanted it to:
print("Thank you! \nWould you like me to read your details back to you?")
bck = input("Y / N")
if bck == "Y":
print(User)
print("Thank you! Goodbye")
else:
print("Goodbye!")
The output of this, is the list that the user creates through the three inputs. Which is great! I'm happy that I have managed to make it function so far;
But I want the 'Name' input to be what names the 'User' list. This way, if I ask the user to input a name, that name will be used to find the list and print it.
How do I assign the input from Name to ALSO be what the currently named "User" list
You will need to create a variable which can store multiple contacts inside of it. Each contact will be a list (or a tuple. Here I have used a tuple, but it doesn't matter much either way).
For this you could use a list of lists, but a dictionary will be more suitable in this case.
What is a dictionary?
A dictionary is just like a list, except that you can give each of the elements a name. This name is called a "key", and it will most commonly be a string. This is perfect for this use case, as we want to be able to store the name of each contact.
Each value within the dictionary can be whatever you want - in this case, it will be storing a list/tuple containing information about a user.
To create a dictionary, you use curly brackets:
empty_dictionary = {}
dictionary_with_stuff_in_it = {
"key1": "value1",
"key2": "value2"
}
To get an item from a dictionary, you index it with square brackets, putting a key inside the square brackets:
print(dictionary_with_stuff_in_it["key1"]) # Prints "value1"
You can also set an item / add a new item to a dictionary like so:
empty_dictionary["a"] = 1
print(empty_dictionary["a"]) # Prints 1
How to use a dictionary here
At the start of the code, you should create an empty dictionary, then as input is received, you should add to the dictionary.
Here is the code I made, in which I have used a while loop to continue receiving input until the user wants to exit:
contacts = {}
msg = "Would you like to: \n - n: Enter a new contact \n - g: Get details for an existing contact \n - e: Exit \nPlease type n, g, or e: \n"
action = input(msg)
while action != "e":
if action == "n": # Enter a new contact
name = input("Enter name here: ")
number = input("Enter phone number here: ")
city = input("Enter city here: ")
contacts[name] = (number, city)
print("Contact saved! \n")
action = input(msg)
elif action == "g": # Get details for an existing contact
name = input("Enter name here: ")
try:
number, city = contacts[name] # Get that contact's information from the dictionary, and store it into the number and city variables
print("Number:", number)
print("City:", city)
print()
except KeyError: # If the contact does not exist, a KeyError will be raised
print("Could not find a contact with that name. \n")
action = input(msg)
else:
action = input("Oops, you did not enter a valid action. Please type n, g, or e: ")
#can be easier to use with a dictionary
#but its just basic
#main list storing all the contacts
Contact=[]
#takes length of contact list,'int' just change input from string to integer
contact_lenght=int(input('enter lenght for contact'))
print("enter contacts:-")
#using for loop to add contacts
for i in range(0,len(contact_lenght)):
#contact no.
print("contact",i+1)
Name=input('enter name:')
Number=input('enter number:')
City=input("enter city:")
#adding contact to contact list using .append(obj)
Contact.append((Name,Number,City))
#we can directly take input from user using input()
bck=input("Thank you! \nWould you like me to read your details back to you?[y/n]:")
#checking if user wants to read back
if bck=='y':
u=input("enter your name:")
#using for loop to read contacts
for i in range(0,len(Contact)):
#if user name is same as contact name then print contact details
if u==Contact[i][0]:
print("your number is",Contact[i][1])
print("your city is",Contact[i][2])
else:
#if user doesnt want to read back then print thank you
print("Good bye")
For this purpose you should use a dictionary.
The key of every entry should be the string 'User[0]' that corresponds to the person's name.
The contents of every entry should be the list with the information of that user.
I'll give you an example:
# first we need to create an empty dictionary
data = {}
# in your code when you want to store information into
# the dictionary you should do like this
user_name = User[0] # this is a string
data[user_name] = User # the list with the information
If you want to access the information of one person you should do like this:
# user_you_want string with user name you want the information
data[user_you_want]
Also you can remove information with this command:
del data[user_you_want_to_delete]
You can get more information on dictionaries here: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
You should start by defining a class to support name, phone and city. Once you've done that, everything else is easy.
class Data:
def __init__(self, name, city, phone):
self.name = name
self.city = city
self.phone = phone
def __eq__(self, other):
if isinstance(other, str):
return self.name == other
if isinstance(name, type(self)):
return self.name == other.name and self.city == other.city and self.phone == other.phone
return False
def __str__(self):
return f'Name={self.name}, City={self.city}, Phone={self.phone}'
DataList = []
while (name := input('Name (return to finish): ')):
city = input('City: ')
phone = input('Phone: ')
DataList.append(Data(name, city, phone))
while (name := input('Enter name to search (return to finish): ')):
try:
print(DataList[DataList.index(name)])
except ValueError:
print('Not found')

Break outside the loop

I am new to Python. I am trying to run the following code. But every time I try to run it, the IDE says that the break is outside the loop
catname = []
print("Enter the name of the cats")
name = input()
if name == '':
break
catname = catname+[name]
print("The cat Names are :")
for catname in name:
print(name)
Can you please help me?
Thanks
You use break when you want to break free from a loop, to exit the loop, to jump to the nearest code after the loop.
Your code doesn't contain a loop, so nothing to break free from, hence the error.
I think you meant exit() instead of break
You use "break" just inside the loop ("for" or "while"), you are trying use brake inside the "if"
How about this:
if name != '':
catname = catname+[name]
print("The cat Names are :")
for catname in name:
print(name)
Your break statement is not in a loop, it's just inside an if statement.
But maybe you want to do something like the following.
If you want to let the user enter an random number of names and print the names out, when the user entered nothing, you can do the following:
# Here we declare the list in which we want to save the names
catnames = []
# start endless loop
while True:
# get the input (choose the line which fits your Python version)
# comment out the other or delete it
name = input("Enter the name of a cat\n") # input is for Python 3
# name = raw_input("Enter the name of a cat\n") # raw_input is for Python 2
# break loop if name is a empty string
if name == '':
break
# append name to the list catnames
catnames.append(name)
print("The cat names are :")
# print the names
for name in catnames:
print(name)
What you are looking for is exit().
However, your code has also other problems, here is a piece of code that does what you probably want (when prompted, enter the names separated by spaces, like: Cat1 Cat2):
name = raw_input("Enter the name of the cats: ")
if len(name) == 0:
exit()
print("\nThe cat Names are:")
for c_name in name.split():
print(c_name)
If this is the entirety of your code, then it's telling you exactly what the problem is:
catname = []
print("Enter the name of the cats")
name = input()
if name == '':
break
You have a break statement in the code that's not contained inside a loop. What do you expect the code above to do?

Python - input control

I have problem with users input control in one function in Python 3.4.
def input_name (*args):
name_output = ""
name_input = input ("Give first name: ")
if name_input.isalpha() and name_input[0].isupper() == True:
name_output += name_input
return (name_output)
else:
print ("Wrong, do it again")
input_name ()
name = input_name()
print(name.lower())
I am trying to catch users wrong input - so the name must be alphabetical and first letter must be uppercase. In future code I will create users login name with lowercase letters, so I am trying to print users name with small leters for login name. And there is problem.
When I type name firs time well, it's ok
When I type first time name with 1 lowercase letter (name) and then I write it correctly (Name), it tells me Error, I don't understand why. Can you tell me, what is my mistake?
Thank you very much for showing the path.
Mirek
The error is caused by the last line. Since your input is wrong the first time, the function returns None, so name.lower() raises an exception. I wouldn't use recursion in this case.
def input_name():
while True:
name_input = input ("Give first name: ")
if name_input.isalpha() and name_input[0].isupper():
return name_input
else:
print ("Wrong, do it again")
name = input_name()
print(name.lower())
Hope it helps!

Restarting my program based on user input on Python?

I'm new to programming, fyi. I want my program to restart back to the top based on what the user inputs. It will proceed if the user inputs 2 names. If they input 1 name or more than 2 names, it should restart the program but I'm not sure of how to do this.
def main():
print("Hello, please type a name.")
first_name, last_name = str(input("")).split()
while input != first_name + last_name:
print("Please enter your first name and last name.")
main()
You should use a while loop and check the length of the split before assigning:
def main():
while True:
inp = input("Please enter your first name and last name.")
spl = inp.split()
if len(spl) == 2: # if len is 2, we have two names
first_name, last_name = spl
return first_name, last_name # return or break and then do whatever with the first and last name
Use try/except
Well, your program didn't work for me to begin with, so to parse the first and last names simply, I suggest:
f, l = [str(x) for x in raw_input("enter first and last name: ").split()]
Also your while loop will just, like, break your life if you run it without good 'ol ctrl+c on hand. So, I suggest:
def main():
print “type your first & last name”
try:
f, l = [str(x) for x in raw_input("enter first and last name: ").split()]
if f and l:
return f + ‘ ‘+ l
except:
main()
The except: main() will re-run the program for you on error.

Having trouble parsing a txt file into a list full of zip codes in my zipcode lookup program

Hello everyone thanks for looking into my problem. What I am trying to do is write a "Structured" program in python that takes txt from a file and parses it into lists. Then after closing the file, I need to reference the user input (zipcode) in those lists and then print out the city and state according to the zipcode that they entered. My instructor is having us use structure by making several functions. I know there are probably lots of more efficient ways of doing this, but I must keep the structure thats in place.
EDIT
Here is my code(Current):
#-----------------------------------------------------------------------
# VARIABLE DEFINITIONS
eof = False
zipRecord = ""
zipFile = ""
zipCode = []
city = []
state = []
parsedList = []
#-----------------------------------------------------------------------
# CONSTANT DEFINITIONS
USERPROMPT = "\nEnter a zip code to find (Press Enter key alone to stop): "
#-----------------------------------------------------------------------
# FUNCTION DEFINITIONS
def startUp():
global zipFile
print "zipcode lookup program".upper()
zipFile = open("zipcodes.txt","r")
loadList()
def loadList():
while readRecord():
pass
processRecords()
def readRecord():
global eof, zipList, zipCode, city, state, parsedList
zipRecord = zipFile.readline()
if zipRecord == "":
eof = True
else:
parsedList = zipRecord.split(",")
zipCode.append(parsedList[0])
city.append(parsedList[1])
state.append(parsedList[2])
eof = False
return not eof
def processRecords():
userInput = raw_input(USERPROMPT)
if userInput:
print userInput
print zipCode
if userInput in zipCode:
index_ = zipcode.index(userInput)
print "The city is %s and the state is %s " % \
(city[index_], state[index_])
else:
print "\nThe zip code does not exist."
else:
print "Please enter a data"
def closeUp():
zipFile.close()
#-----------------------------------------------------------------------
# PROGRAM'S MAIN LOGIC
startUp()
closeUp()
raw_input("\nRun complete. Press the Enter key to exit.")
Here is a sample from the zipcode txt file:
00501,HOLTSVILLE,NY
I am definitely stuck at this point and would appreciate your help in this matter.
EDIT
Thanks for all the help everyone. I really do appreciate it. :)
why you fill the lists zipcode, city , state like that, i mean in each user entry we get the next line from the file
i think that you should do :
def loadList():
# Fill all the list first , make the readRecord() return eof (True or False).
while readRecord():
pass
# than process data (check for zip code) this will run it only one time
# but you can put it in a loop to repeat the action.
processRecords()
about your problem :
def processRecords():
userInput = raw_input(USERPROMPT)
# Check if a user has entered a text or not
if userInput:
# check the index from zipcode
if userInput in zipcode:
# the index of the zipcode in the zipcode list is the same
# to get related cities and states.
index_ = zipcode.index(userInput)
print "The city is %s and the state is %s " % \
(city[index_], state[index_])
else:
print "\nThe zip code does not exist."
else:
print "Please enter a data"
one of the beauties of Python is that it's interactive. if you take processRecords() out of loadList(), and then at the bottom of your program put:
if __name__ == '__main__':
processRecords()
Then, from the command prompt, type "python". You'll get the Python shell prompt, ">>>". There you type:
from zipcodes import * # this assumes your program is zipcodes.py
dir() # shows you what's defined
print zipCode # shows you what's in zipCode
that ought to help debugging.
Strings don't have an append method like lists do. What I think you're trying to do is append the strings zipCode, city, and state to parsedList. This is the code you'd use to do that:
parsedList.append(zipCode)
parsedList.append(city)
parsedList.append(state)
Or, even more compactly:
parsedList = [zipCode, city, state]
Let me know if you get another error message and I can offer more suggestions.

Categories