Restarting my program based on user input on Python? - 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.

Related

Python infinite while loop issue

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()

Another question: Phone dictionary problem 'while-loop' using Error

Simply question making phone dictionary
What I want to do is putting person's name and number and finding them in dictionary!
Examples what I want to do
Enter command (a, f, d, or q).: a
Enter new name................: Perry
Enter new phone number........: 229-449-9683
Enter command (a, f, d, or q).: f
Enter name to look up...:
I would like to find full name and number when I type
Phone dictionary code what I wrote so far:
phone_dict = {}
command = input('Enter command (a, f, d, or q).: ')
newname = input('Enter new name................: ')
newphone = input('Enter new phone number........: ')
while True:
if command == 'a':
newname
newphone
phone_dict[newname] = newphone
print(phone_dict)
# In here, 'while-loop' does not work.
In there, if I enter 'a' command, and type the name
The dictionary is supposed to be { Perry: 229-449-9683}
Thanks, The question might be little confused, but if you can help this out, I am very happy!
To find the result from the dictionary, you can loop through the items and check if the key contains the string you want to find. If you want to get all values which satisfy your query, you can create another list or dictionary and store the items you find:
phone_dict = {
"Han Perry": "1234",
"Harry Gildong": "2345",
"Hanny Test": "123",
}
find_str = "Han"
result = {}
for key, value in phone_dict.items():
# Converting it to lower makes it case insensitive
if find_str.lower().strip() in key.lower():
result[key] = value
print(result)
# {'Han Perry': '1234', 'Hanny Test': '123'}
Take note that this will run through all of the values of the dictionary: O(n)
To find the number using the first o last name of the person you could do:
a = 'Add a new phone number'
d = 'Delete a phone number'
f = 'Find a phone number'
q = 'Quit'
phone_dict = {}
while True:
# Gets the user command every loop
command = input('Enter command (a, f, d, or q).: ')
# Add a new registry to the directory
if command == 'a':
newname = input('Enter new name................: ')
newphone = input('Enter new phone number........: ')
phone_dict[newname] = newphone
print(phone_dict)
# Find a registry on the directory
elif command == "f"
query = input("Enter name to look up...: ")
match = None
for key in phone_dict.keys():
if query.strip() in key:
match = phone_dict[key]
break
if match is None:
print(f"The name {query} could not be found on the directory")
else:
print(f"The phone number of {query} is {match}")
elif command == "d":
# Delete registry
elif command == "q":
# Quits program
else:
print(f"The command {command} was not found, please try again!")
In this case, I am using query.strip() to remove any extra start/end spaces that could cause to not find the person.

List of objects only saving the last object in Python program

So I have an otherwise easy homework assignment that wants me to input my grades for subjects, etc. The amount of input varies with the number of subjects the user wants to enter. The input works fine, but when I print out the saved values only the ones most recently entered are saved. Here is my code for input:
def gpa_input(classList):
print("please enter how many classes you have")
while True:
try:
numOfClasses = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
for i in range (numOfClasses):
classList.append(subject)
print("enter name of " + str(i+1) + "th subject:")
classList[i].name = input()
print("enter num of credits for " + str(i+1) + "th subject:")
while True:
try:
classList[i].credits = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
print("enter grade for " + str(i+1) + "th subject:")
while True:
try:
classList[i].gradePercentage = int(input())
except ValueError:
print("please enter a valid number")
continue
else:
break
A subject is a class containing a string value and 2 int values, defined as following:
class subject:
def __init__(name, credits, gradePercentage):
self.name = name
self.credits = credits
self.gradePercentage = gradePercentage
And here is the code that prints out all of this:
def main():
gpa_input(classList)
for i in range (len(classList)):
print(classList[i].name)
print(classList[i].credits)
print(classList[i].gradePercentage)
What is the problem with my code? Am I iterating through something the wrong way, or is there something not getting properly assigned/saved?
You've got into the very common "trap".
The problem is in how you initialize your subject class.
Here you just append a class to the list:
classList.append(subject)
The situation here is the following:
Once you called subject without braces you will have a new object.
But when you call it on the second time - python will not initialize the new object for you and just return the object created on the first step.
So all you need is to properly initialize all subject objects.
Two ways:
1) Remove args from subject definition and make default values are none + add braces to the classList.append(subject)
2) Collect all values in your for loop into variables and at the end of the function initialize you subject class with proper args.

How to write to a text file using iteration?

My code does not write to a file, what am I doing wrong? I am trying to program to continue to ask for products until the user does not enter a product code. I want all products to be saved in the file.
store_file = open("Database.txt", "w")
NewProduct = ""
while NewProduct != False:
contine = input("Press 1 to enter a new product press 2 to leave: ")
if contine == "1":
print("Enter your product information")
information = []
product = input("What's the product code: ")
information.append(product)
description = input("Give a description of the product: ")
information.append(description)
price = input("Enter price of product: ")
information.append(price)
information = str(information)
clean = information.replace("]","").replace("[","").replace(",","").replace("'","")
store_file.write(clean)
elif contine == "2":
NewProduct = False
else:
print("Your input is invalid")
store_file.close
I got the program working with the following adjustments. See comments for explanations:
store_file = open("Database.txt", "w")
NewProduct = ""
while NewProduct != False:
continue = raw_input("Press 1 to enter a new product press 2 to leave: ")
#Changed to raw_input because input was reading in an integer for 1 rather than a
#string like you have set up. This could be specific to my IDE
if continue == "1":
print("Enter your product information")
information = []
product = raw_input("What's the product code: ")
information.append(product)
description = raw_input("Give a description of the product: ")
information.append(description)
price = raw_input("Enter price of product: ")
information.append(price)
information = str(information)
clean = information.replace("]","").replace("[","").replace(",","").replace("'","")
store_file.write(clean + "\n")
#Added a line break at the end of each file write
elif contine == "2":
NewProduct = False
else:
print("Your input is invalid")
store_file.close() #Added parentheses to call the close function
I'm assuming the problem here is that you're using Python 2, and input isn't doing what you think it does. In Python 2, input evals the input as if it were Python source code, so if someone enters 2, it's going to return the int value 2, not "2". In Python 2, you want to use raw_input, always (eval-ing random user input not being secure/reliable).
Also, while on CPython (the reference interpreter) files tend to naturally close themselves when they go out of scope, you made an effort to close, but forgot to actually call the close method; store_file.close looks up the method without calling it, store_file.close() would actually close it. Of course, explicit close is usually the wrong approach; you should use a with statement to avoid the possibility of forgetting to close (or of an exception skipping the close). You can replace:
store_file = open("Database.txt", "w")
...
store_file.close()
with:
with open("Database.txt", "w") as store_file:
... do all your work that writes to the file indented within the with block ...
... When you dedent from the with block, the file is guaranteed to be closed ...
There are other issues though. What you're doing with:
information = str(information)
information = information.replace("]","").replace("[","").replace(",","").replace("'","")
is terrible. I'm 99% sure what you really wanted was to just join the inputs with spaces. If you switch all your input calls to raw_input (only on Python 2, on Python 3, input is like raw_input on Python 2), then your list is a list of str, and you can just join them together instead of trying to stringify the list itself, then remove all the list-y bits. You can replace both lines above with just:
information = ' '.join(information)

Grouping string input by count

I'm trying to do a question out of my book and it asks:
Implement function names that takes no input and repeatedly asks the
user to enter a student's first name. When the user enters a blank
string, the function should print for every name, the number of
students with that name.
Example usage:
Usage:
names()
Enter next name: Valerie
Enter next name: Bob
Enter next name: Valerie
Enter next name: John
Enter next name: Amelia
Enter next name: Bob
Enter next name:
There is 1 student named Amelia
There are 2 students named Bob
There is 1 student named John
There are 2 students named Valerie
So far I have this code:
def names():
names = []
namecount = {a:name.count(a) for a in names}
while input != (''):
name = input('Enter next name: ')
names = name
if input == ('')
for x in names.split():
print ('There is', x ,'named', names[x])
I'm really lost here and any input would help out tons. Also if possible please explain how to fix my code
There are a lot of issues with namings in your function, you are using such variables like 'names' that is used for function name as well as 'input' that is a python function name for reading user input - so you have to avoid using this. Also you defining a namecount variable as a dict and trying to initialize it before fill. So try to check solution below:
def myFunc():
names = []
name = ''
while True: #bad stuff you can think on your own condition
name = raw_input('press space(or Q) to exit or enter next name: ')
if name.strip() in ('', 'q', 'Q'):
for x in set(names):
print '{0} is mentioned {1} times'.format(x, names.count(x))
break
else:
names.append(name)
myFunc()
OR:
from collections import defaultdict
def myFunc():
names = defaultdict(int)
name = ''
while True: #bad stuff you can think on your own condition
name = raw_input('press space(or Q) to exit or enter next name: ')
if name.strip() in ('', 'q', 'Q'):
for x in set(names):
print '{0} is mentioned {1} times'.format(x, names[x])
break
else:
names[name] += 1
I rewrote your function for you:
def names():
names = {} # Creates an empty dictionary called names
name = 'cabbage' # Creates a variable, name, so when we do our while loop,
# it won't immediately break
# It can be anything really. I just like to use cabbage
while name != '': # While name is not an empty string
name = input('Enter a name! ') # We get an input
if name in names: # Checks to see if the name is already in the dictionary
names[name] += 1 # Adds one to the value
else: # Otherwise
names[name] = 1 # We add a new key/value to the dictionary
del names[''] # Deleted the key '' from the dictionary
for i in names: # For every key in the dictionary
if names[i] > 1: # Checks to see if the value is greater for 1. Just for the grammar :D
print("There are", names[i], "students named", i) # Prints your expected output
else: # This runs if the value is 1
print("There is", names[i], "student named", i) # Prints your expected output
When doing names():
Enter a name! bob
Enter a name! bill
Enter a name! ben
Enter a name! bob
Enter a name! bill
Enter a name! bob
Enter a name!
There are 3 students named bob
There are 2 students named bill
There is 1 student named ben
Let's analyse your code:
def names():
names = []
namecount = {a:name.count(a) for a in names}
while input != (''):
name = input('Enter next name: ')
names = name
if input == ('')
for x in names.split():
print ('There is', x ,'named', names[x])
There seem to be a few problems, let's list them
The while loop's conditional
What you want to do check if input from user is '' (nothing)..
input is a built-in function for getting input from user, so it never will be ('').
The names = name statement
What you want to do is add name to the list names.
Here you are changing names to a string, which isn't what you want.
The if's conditional
same as 1.
The for loop
let's ignore.. just not valid.. here..
We fix these problems as follows(solution has same numbering as problem above that it solves)
Change the conditional to something like name != ''.
Also, before the loop begins, you need to get input once for this to work, which in this case has a bonus, the first input can have a different prompt.
Use names.append(name) to add name to names.
Same as 1.
Just look at the for loop below...
Try this
def names():
names = []
name = input('Enter a name: ').strip() # get first name
while name != '':
names.append(name)
name = raw_input('Enter next name: ').strip() # get next name
for n in set(names): # in a set, no values are repeated
print '%s is mentioned %s times' % (n, names.count(n)) # print output
def names():
counters = {}
while True:
name = input('Enter next name:')
if name == ' ':
break
if name in counters:
counters[name] += 1
else:
counters[name] = 1
for name in counters:
if counters[name] == 1:
print('There is {} student named {}'.format(counters[name],name))
else:
print('There are {} student named {}'.format(counters[name],name))
names()

Categories