Im new to coding in python, and is trying to make this work.
if input from user is "name age" it works just fine. But I want it to work if user inputs either (name+age) or (name+lastname+age). If I input 3 values I get ValueError: too many values to unpack (expected 2)
and if add name, lastname, age, =map(str, sys.stdin.readline().split()) to the code. I get a not enough values error when user input name+lastname+age
Hopefully someone can help me :)
name, age, =map(str, sys.stdin.readline().split())
age = int(age)
if "Paul" in (name):
result1 = (age*2)
print("Answer is", + result1)
Here's a possibility - read the input line without the map, parse it, and then differentiate the input based on the number of elements in the resulting list,
import sys
entry = sys.stdin.readline()
entry = entry.strip().split()
if len(entry) == 2:
# Name + age
name = entry[0]
age = int(entry[1])
print(name, age)
elif len(entry) == 3:
# Name + last name + age
name = entry[0]
last_name = entry[1]
age = int(entry[2])
print(name, last_name, age)
else:
raise ValueError('Wrong input arguments')
if "Paul" in (name):
result1 = (age*2)
print("Answer is", + result1)
If the input is nothing of the expected, this code raises an exception. You can instead keep prompting the user until they enter the right values. If you decide to keep the exception approach, consider using a more informative exception message.
Instead of trying to unpack the result of split() into two variables, you can use join() combined with list slicing to join everything but the last value into one (the name):
user = input().split()
age = int(user[-1])
name = ' '.join(user[:-1])
if "Paul" in name:
print(f"Answer is {age*2}")
This works regardless of how many "words" are in the name:
Paul McCartney 42
Answer is 84
Pauline 42
Answer is 84
Paul W. S. Anderson 42
Answer is 84
You can't split something into a dynamic number of variables this way.
Instead you need to capture the input and then work out how many fields were passed in. Something like:
user = map(str, sys.stdin.readline().split())
lastname = ''
name = user[0]
age = user[1]
if len(user) == 3:
lastname = user[1]
age = user[2]
Related
I am a beginner programmer (or so I think) at this programming stuff so my knowledge of terminology usage is rather subpar. So with that said. I'm doin this in Python, (yea yea, it should be easy cause it's Python but it's not easy for me). I want to know, is there an easier way to return a string that is legitimately a string and not represented as an integer when using the input function? Cause when I ask the user to type their name and they type a number instead (for whatever reason...must be lupus), the numeric input is still accepted as an string value.
I want to accept string (actual words) and not numeric(integer or float), so when a numeric value is entered, it'll print a message asking to try again, then return the user to the input function to enter the correct value (simple stuff, right???). I had also added entry for age, height(haven't done anything for these two yet) and gender (gender options are just male and female).
As for the gender portion, I created a function to enter either male or female and associated both gender by returning the value of their respective gender sign. Excuse my grammar. Anyhoo, penny for your thoughts? P.S. May be a lot of unnecessary clutter in my code so excuse the hot mess. I am welcome to criticism.
the code goes as follows:
i = 'Name'
j = 'Age'
k = 'Height'
l = 'Sex'
def anno_name(input_str: str ) -> str:
if input_str.isalpha():
return
#print(input_str)
else:
print("Entry invalid. Name can neither be numeric nor left empty. Please try again.\n")
return anno_name(input("Enter your name: "))
aname = input(f'{i}\nEnter your name: \n')
anno_name(aname)
print(input(f'\n{j}\nEnter age: \n'))
print(input(f'\n{k}\nEnter height: \n'))
def sym_g():
gen = input(f'\n{l}\nEnter sex: \n')
if gen == 'female':
return 'female \f'
elif gen == 'male':
return ('male \v')
else:
if gen != 'female' or 'male':
print("Entry invalid. Please try again.\n")
return sym_g()#('Invalid value. Please try again...')
sym_gen = sym_g()
print(sym_gen)
Output
With what you are trying to do, you will have to evaluate every input which I it's a good thing to create functions for each and every input and return the input if it pass the evaluation. That will give you the flexibility to handle every error individually.
Example:
def anno_name(input_str: str ) -> str:
if input_str.replace(" ", "").isalpha():
return " ".join(input_str.split(" ")).title()
else:
print("Entry invalid. Name can neither be numeric nor left empty. Please try again.\n")
return anno_name(input("Enter your name: "))
def get_age(input_age: int ) -> int:
try:
input_age = int(input_age)
except ValueError:
pass
if type(input_age) is int:
return input_age
else:
print("Entry invalid. Accepts only integers. Please try again.\n")
return get_age(input("Enter Age: "))
def get_height(input_height: float ) -> float:
try:
input_height = float(input_height)
except ValueError:
pass
if type(input_height) is float:
return input_height
else:
print("Entry invalid. Accepts either integers or float. Please try again.\n")
return get_height(input("Enter height: "))
def get_sex(input_sex: str ) -> str:
input_sex = input_sex.lower()
if input_sex == "male" or input_sex == "female":
return input_sex.title()
else:
print("Entry invalid. Enter (male) or (female).\n")
return get_sex(input("Enter sex: "))
def get_personal_details() -> None:
name = anno_name(input("Name\nEnter your name: "))
print(name, "\n")
age = get_age(input("\vAge\nEnter Age: "))
print(age, "\n")
height = get_height(input("\vHeight\nEnter Height: "))
print(height, "\n")
sex = get_sex(input("\vSex\nEnter Sex: "))
print(sex, "\n")
print("\vPersonal Details:")
print(f"Name: {name}\nAge: {age}\nHeight: {height}\nSex: {sex}")
get_personal_details()
output:
Name
Enter your name: james kookoo
James Kookoo
Age
Enter Age: 67
67
Height
Enter Height: 6732
6732.0
Sex
Enter Sex: male
Male
Personal Details:
Name: James Kookoo
Age: 67
Height: 6732.0
Sex: Male
What kind of signs are you referring to? Some signs might not show when you use them, depending on your python version. You can use something like ♂ and ♀ and you can also use lambda if you wish to. The choice is yours.
I will suggest you concatenate using f-string. Something like:
def get_sex(input_sex):
input_sex = input_sex.lower()
user_gender = lambda x : f"{input_sex.title()} ♂" if (x == "male") else f"{input_sex.title()} ♀"
if input_sex == "male" or input_sex == "female":
return user_gender(input_sex)
else:
print("Entry invalid. Enter (male) or (female).\n")
return get_sex(input("Enter sex: "))
output:
Sex
Enter Sex: female
Female ♀
Ok, that looks like about it. This does work. But I was wondering is there a way to return the gender sign along side the gender itself where they are concatenated. In my original code I had associated the gender with the sign. Your code is clean and very efficient. I just having a some challenges and want to seek some pointers. So what I did was changed a few things in the gender function.
def get_sex(input_sex):
input_sex = input_sex.lower()
if input_sex == "male":
return input_sex.title() + (' \v')
elif input_sex == "female":
return input_sex.title() + (' \f')
else:
print("Entry invalid. Enter (male) or (female).\n")
return get_sex(input("Enter sex: "))'
That way I keep the the gender concatenated with the respective gender sign (escape sequences). My change may be not as clean as what was corrected to be. I am open to anymore ideas to make it least wordy. Perhaps using a lambda. Which I do not have the slightest of clues to squeeze all of this block into one or two or three lines of code.
I have this function, which is part of a larger code I am working on for a class, so I am not looking for all the answers, just a little help with this part because I really don't know how to proceed. I have a function that asks for multiple inputs. firstname, lastname, bus row, and bus seat. these are then split and printed into a text file that I will do some other things with that i have not included the code for because I am still working on it.
the first two entries need to be strings(first and last name), and the second two need to be numbers ( at least for now) the first number needs to be 1-4(row), and the second needs to be 1-15(seat), because that is all the seats available. I want an error to come back if anything else is entered in the following code.
def purchase():
while True:
try:
firstname, lastname, bus_row, bus_seat = input(
'Enter name first and last name and bus row and seat:').split()
print("Name: {} {}\nrow {} seat {}".format(firstname, lastname, bus_row, bus_seat))
with open('bookings.txt', 'a') as bookings:
bookings.write('\n' + firstname + " " + lastname + " " + bus_row + " " + bus_seat)
break
except ValueError:
print('Invalid entry')
return
purchase()
This should work. You don't need to raise anything because you are already in a try/except. Simply you assert there are exactly 4 inputs and they are 2 strings and 2 integers. if they are not the program runs into an error and prints 'Invalid Entry'
def purchase():
while True:
try:
variables = input('Enter name first name, last name, bus row and bus seat:').split()
assert len(variables) == 4
firstname, lastname, bus_row, bus_seat = variables
for i in firstname:
assert not i.isdigit()
for i in lastname:
assert not i.isdigit()
bus_row = int(bus_row)
bus_seat = int(bus_seat)
assert 0 < bus_row < 5 and 0 < bus_seat < 16
print("Name: {} {}\nrow {} seat {}".format(firstname, lastname, bus_row, bus_seat))
with open('bookings.txt', 'a') as bookings:
bookings.write('\n' + firstname + " " + lastname + " " + str(bus_row) + " " + str(bus_seat))
break
except:
print('Invalid entry')
purchase()
Hope I helped
You will need to include something like this in your code:
try:
bus_row = int(bus_row)
bus_seat = int(bus_seat)
if not 1 <= bus_row <= 4:
raise ValueError("A bus row should be a whole number between 1 and 4")
if not 1 <= bus_seat <= 15:
raise ValueError("A bus seat should be a whole number between 1 and 15")
except ValueError as e:
# handle the exception
Don't assign firstname, lastname, etc. until you know they entered exactly four things. If they entered more or fewer, the assignment will fail.
# keep prompting until they enter correct input
while True:
answers = input('Enter name and ...').split()
if len(answers) != 4:
print('You did not enter the correct number of answers')
continue
firstname, lastname, bus_row, bus_seat = answers
if not firstname.isalpha():
print('First name must be only letters')
continue
# do the same for last name ...
if not bus_row.isdigit():
print('Bus row must be a number')
# do the same for bus seat ...
# if we make it all the way here, the input must be correct, so break the loop
break
This is part of my homework and the reason why I found posted this was because I was confused about what I'm doing wrong.
school = [['Abby Li'],
['Ella Wang', 'Danielle Han','Katherine Zhang', 'Morgan Liu'],
['Josh Li']
]
def searchStudent(school1, lastname1):
firstname = "Not"
lastname = "Found"
for grade in school1:
for student in grade:
name = student.split();
if name[1] == lastname1:
firstname = name[0]
lastname = name[1]
return firstname, lastname
while (True):
search = input("Please enter last name to search:")
if (search == "exit"):
break
foundFirst, foundLast = searchStudent(school, search)
print("found student: ", foundFirst, foundLast)
print("")
So this is my code, but whenever I enter "Li" as the last name, only Josh shows up and Abby doesn't. Can someone help me fix it? Thank you so much!
Also, here's the link for it if it doesn't show up above: code
Your indentation makes your if statement out of the for loop
Also if you want to print all the matches you need to store all of them, so you'll need something like list!
school = [['Abby Li'],
['Ella Wang', 'Danielle Han','Katherine Zhang', 'Morgan Liu'],
['Josh Li']
]
def searchStudent(school1, lastname1):
firstname = "Not"
lastname = "Found"
result = []
for grade in school1:
for student in grade:
name = student.split();
if name[1] == lastname1:
firstname = name[0]
lastname = name[1]
result.append([firstname, lastname])
return result
while (True):
search = input("Please enter last name to search:")
if (search == "exit"):
break
result = searchStudent(school, search)
for name in result: print("found student: ", name[0], name[1])
print("")
Please enter last name to search:Li
found student: Abby Li
found student: Josh Li
Please enter last name to search:exit
You have an indentation error:
for grade in school1:
for student in grade:
name = student.split();
if name[1] == lastname1:
firstname = name[0]
lastname = name[1]
Note that the if statement is outside the loop, after the loop.
Therefore, the only name it will check is that last one in the entire school list. To check all names, you have to indent it to the same level as that inner split command.
Also note that your return statement will return only that last name found. If you want to return more, you need to upgrade your logic.
You need to make a list of found students say:
found_students = []
and then append found names to it and then return that list
as of now 'Abby Li' is being overwritten by 'Josh Li'
So I just started learning a few basics with Python. Since I am a pretty practical person, I enjoy doing it with the book "Automate the boring stuff with Python".
No there is a chapter introducing lists in python and their advantages.
To be practical one should write a code which asks the user to enter cat names, which then will be added to the list. If no cat name is added anymore, all the cat names should be displayed.
Until now, fair enough. So I thought I should give it a try and go a small step further and extend the functionality by adding the ages of the cats. The desired result would be that the user is asked for the name input, then the age input, the name input again and the age input again and so on. If the user doesn´t put in a name again, it should list the cats with the respective ages.
I created a second list and also the second input and everything kinda works but I just dont know how to combine the both lists or rather the values.
It just gives me the two names first and then the two ages.
Is anyone happy to help me with this beginner problem?
Thanks in advance
catNames = []
catAges = []
while True:
print("Enter the name of Cat " + str(len(catNames) + 1) + "(Or enter
nothing to stop.)")
name = input()
while name !="":
print("Enter the age of cat ")
age = input()
break
if name == "":
print("The cat names and ages are: ")
for name in catNames:
print(" " + name)
for age in catAges:
print(" " + age)
break
catNames = catNames + [name]
catAges = catAges + [age]
I think you're looking for zip:
catNames = ['Fluffy', 'Whiskers', 'Bob']
catAges = [5, 18, 2]
catZip = zip(catNames, catAges)
print(list(catZip))
Out:
[('Fluffy', 5), ('Whiskers', 18), ('Bob', 2)]
In general you would use dictionaries for this kind of task.
But if you were to use lists for your problem, it could be implemented like this:
catNames = []
catAges = []
while True:
print("Enter the name of Cat " + str(len(catNames) + 1) + "(Or enter nothing to stop.)")
name = input()
while name !="":
print("Enter the age of cat ")
age = input()
break
if name == "":
print("The cat names and ages are: ")
for i in range(len(catNames)):
print("Cat number",i, "has the name", catNames[i], "and is", catAges[i], "years old")
break
catNames = catNames + [name]
catAges = catAges + [age]
If I can understand correctly you want it to print the age and the name together?
Well if thats so you can do it like this:
catNames = []
catAges = []
while True:
name = input("Enter the name of Cat {} (Or enter nothing to stop): ".format(str(len(catNames) + 1)))
while name != "":
age = input("Enter the age of {}: ".format(name)) # Takes inputted name and adds it to the print function.
catNames.append(name) # Adds the newest name the end of the catNames list.
catAges.append(age) # Adds the newest age the end of the catNames list.
break
if name == "":
print("\nThe cat names and ages are: ")
for n in range(len(catNames)):
print("\nName: {}\nAge: {}".format(catNames[n], catAges[n]))
break
Resulting output:
Enter the name of Cat 1 (Or enter nothing to stop): Cat1
Enter the age of Cat1: 5
Enter the name of Cat 2 (Or enter nothing to stop): Cat2
Enter the age of Cat2: 7
Enter the name of Cat 3 (Or enter nothing to stop): # I hit enter here so it skips.
The cat names and ages are:
Name: Cat1
Age: 5
Name: Cat2
Age: 7
If you have any issues with what I did, please just ask.
age = 3
name = age
if age = "Bob"
print(name is: age)
I have to find the errors in this such as "if age = should be if age ==" and finish the code to accomplish the task.
For the errors I have located the following "if age = should be if age == and I also believe that name = age doesn't make sense as it should be name = Bob as well as (name is: age) should be (name is: "Bob").
Please let me know if I correct in my findings of these mistakes and let me know what else I am missing.
Lastly the code I am using to finish accomplish it is as follows
name = input("Enter name:")
age = float(input("Enter age:"))
if age == 3:
print(name is "Bob")
This however just gives me a false statement if I enter 3 for the name, please help me
You're doing fine, except that I expect the last line should read
print ("name is:", name)
The original checks to see whether the name is "Bob", printing either True or False.
print ("name is: ", name) is the correct syntax