having trouble implementing the right word to a url link - python

i have a program that asks users which department they want to choose from, i made the question into a while loop that would keep asking the same question until they put a valid response in. and whenever they wanted to break the loop they would type the word "exit". once they type in a valid response it would add ask another question in another function that would ask for the class your want info on based on the department you're in, it would then lead it to a website where i can get the information i need. the issue im facing is that it doesn't take the valid response that was typed in, it would instead implement the word "exit" which was used to break out of the loop as it was the last input. i want it to take the input before that and not "EXIT"
here is the code
def get_departments():
umd_departments = requests.get("https://api.umd.io/v0/courses/departments")
umd_departments_list = umd_departments.json()
umd_departments_list2 = json.dumps(umd_departments_list, indent=1)
department_storage = [department['dept_id'] for department in umd_departments_list]#comprehensive for loop to put the department ID into a list
print(department_storage)
while True:
dept = input('what department are you in right now: ')
dept = dept.upper()
if dept == 'EXIT':
break
if dept not in department_storage:
print("not approriate response")
else:
try:
department_url = requests.get(f"https://api.umd.io/v0/courses?dept_id={dept}")
specific_major =department_url.json()
keep_keys = ["course_id"]
courses = [{k: json_dict[k] for k in keep_keys}
for json_dict in specific_major]
print(courses)
except Exception as e:
print(e)
return courses,dept
def get_classes(courses):
classes = [course['course_id'] for course in courses]
print(classes)
course_select = input('what class would you like to select').upper()
if course_select not in classes:
raise ValueError(" class does not exist")
else:
driver = webdriver.Chrome(ChromeDriverManager().install())
url = f"https://app.testudo.umd.edu/soc/202008/{dept}"
driver.get(url)
section_container = driver.find_element_by_id(f"{course_select}")
section_container.find_element_by_xpath(".//a[#class='toggle-sections-link']").click()# it would click on the show section button on the site that would reveal the sections
sleep(1)
section_info = section_container.find_element_by_xpath(".//div[#class='sections sixteen colgrid']").text
return section_info
let's say for example in the get departments function i type in INST and its considered a valid response, it would then ask for which class i want to choose from that department. it would then create a url that would get me the info i need like this:
https://app.testudo.umd.edu/soc/202008/INST
however i get this:
https://app.testudo.umd.edu/soc/202008/EXIT
the latter doesn't produce anything as it doesn't exist and it causes errors. is there a way to make it so that it doesn't make the "EXIT" input stored into a valuable and instead takes the valid response before it? greatly appreciated if anyone could help.

Looks like you just need another variable
userInput = input('what department are you in right now: ')
userInput = userInput.upper()
if userInput == 'EXIT':
break
else:
dept = userInput

Related

I am trying to update my program to have some return values to make it more testable. Why is the one named other not returned usable in main?

I receive a NameError: name 'other' is not defined. Could someone give me an example and reasoning to point me in the right direction to help me out (so i don't screw up when adding return values to the rest of my program). I thought i understood them that's why I know i need help to get a better understanding. I almost forgot to mention i am entering a number to trigger the else clause when i get the error message regarding main code.
def yes_no(y_n):
other = 'invalid response'
if y_n == 'n':
index_person(address_dict)
elif y_n == 'y':
add_person()
else:
return other
def main():
#other = 'Invalid response'
while True:
#Hmmm..would the user like to add a new person the the address book or index it?
#Loop the address program until break.
try:
user_answer = input('Would you like to add a new person to the address book? y/n \n - ')
yes_no(user_answer)
if user_answer not in ['y','n']:
print(other)

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

Concatenate random element from list with user input in Python

I'm writing a code that allows a user to enter a city they have been to. After the user inputs it, I want my code to return a randomly generated remark about the city from my list. However, whenever I run the code, it concatenates the user input with a random letter, which is not my intention of the code.
import random
message = "Type your city here: "
#Comments to concatenate with user input
comments = [f"what a lovely {}", f"I always wanted to visit {}", "I hope you enjoyed your trip to {}"]
#While loop for user input
while True:
message = input(message)
for elem in comments:
message += random.choice(elem)
if message == "quit":
break
I assume this is what your looking for?
import random
#Comments to concatenate with user input
comments = ["what a lovely ", "I always wanted to visit ", "I hope you enjoyed your trip to "]
#While loop for user input
message = None
while message != "quit":
message = input("Type your city here: ")
print(random.choice(comments)+message)
I recommend coding a function that takes the city as input then at the end returns the list. Like this
def random_quote(city):
comments = [f"what a lovely ", f"I always wanted to visit ", "I hope you
enjoyed your trip to "]
comment = random.choice(comments)
return comment + city
random.choice() accepts a list (take a look at the docs), Don't iterate over your comments variable, pass it to random.choice() and don't forget to replace {} with the city:
city = input('Please enter a city')
comment = random.choice(comments)
comment.replace('{}', city)
print(comment)
You do not need a for loop inside your while. You should always avoid while True as it is an opening for bugs. Having a break inside a loop usually marks bad programming.
You should probably read a bit about what f-string is before using it, you also don't seem to know what random.choice does since you put it into the for which gave it the messages, which it randomly took a character out of.
import random
def main():
prompt = "Type your city here: "
# Comments to concatenate with user input
comments = ["what a lovely ", "I always wanted to visit ", "I hope you enjoyed your trip to "]
usr_input = input(prompt)
# While loop for user input
while usr_input != 'quit':
message = random.choice(comments) + usr_input
usr_input = input(prompt)
if __name__ == '__main__':
main()

Having issue printing out data i want to show

i was modifying a program that i was writing to make it so that it wont continue on unless they put in a input that matches a word thats stored in a list. however after i did that, it would not let me print out the data i have, here is the code
while True:
dept = input('what department are you in right now: ')
dept = dept.upper()
if dept not in department_storage:
print("not approriate response")
continue
else:
break
if dept in department_storage:
department_url = requests.get(f"https://api.umd.io/v0/courses?dept_id={dept}")
specific_major =department_url.json()
keep_keys = ["course_id"]
courses = [{k: json_dict[k] for k in keep_keys}
for json_dict in specific_major]
#return courses,dept
print(courses)
im trying to print out the courses variable, however when i try and run the function
it doesn't show the print output, and it doesn't show any errors when i run it so im lost on what i did wrong and how to fix it . i was wondering if i could ask the kind stack overflow community for help.
You may not be getting the output for multiple reasons: -
Did you enter an input? the interpreter may be waiting for a user input which has not been entered yet.
Maybe the dept not in department_storage is breaking the loop if its true. break gets you out of the loop.
courses is a null object, probably because the result you are getting has empty objects.
You can add import pdb; pdb.set_trace(); at various points in your code and write the variable names in the debugger to see the values. That will aid you in the investigation.
As per the requirement, my suggestion is the following code: -
while True:
dept = input('what department are you in right now: (type exit to quit)')
dept = dept.upper()
if dept == 'EXIT':
break
if dept not in department_storage:
print("this department does not exist, enter correct department")
else:
try:
department_url = requests.get(f"https://api.umd.io/v0/courses?dept_id={dept}")
specific_major =department_url.json()
keep_keys = ["course_id"]
courses = [{k: json_dict[k] for k in keep_keys}
for json_dict in specific_major]
print(courses)
except Exception as e:
print(e)
The break command forces to exit the while loop and stop taking inputs.
Try:
if dept in department_storage:
...
# if dept not in department_storage
else:
...

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

Categories