lists of list and random choice - python

The question I need help with is:
Write a program that stores the names of ten countries in column1 and their capitals in column2. The program should then pick a random country and ask the user for the capital.
Display an appropriate message to the user to show whether they are right or wrong.
So far I have
column1 = []
column2 = []
listoflist = [(column1)(column2)]
maxlength = 10
while len (column1) < maxlength:
country = input("please enter a country: ")
capital = input("please enter the capital of the country entered: ")
column1.append(country)
column2.append(capital)
for item in done:
print (item[0],item[1])
if anyone can help please.

I believe your list of list setup is a little off for what you intend. Try something like this:
from random import shuffle
data = []
maxlength = 10
while len (data) < maxlength:
country = input("please enter a country: ")
capital = input("please enter the capital of the country entered: ")
# for this scenario, probably better to keep rows together instead of columns.
data.append((country, capital)) # using a tuple here. It's like an array, but immutable.
# this will make them come out in a random order!
shuffle(data)
for i in range(maxlength):
country = data[i][0]
capital = data[i][1]
print("Capital for the country {0}?".format(country))
user_said_capital_was = input("What do you think?")
if user_said_capital_was == capital:
print("Correct!")
else:
print("Incorrect!")

You should write this as:
listoflist = [column1, column2]
In your code you're not correctly defining the list of lists and that leads to an error.

import random
dict1 ={"Turkey":"Istanbul","Canada":"Ottawa","China":"Beijing"}
list1=[key for key in dict1.keys()]
try:
q=random.choice(list1)
except:
print ("We are out of countries, sorry!")
while True:
user=input("What is the capital city of {} ?: ".format(q))
if user == dict1[q]:
print ("Correct")
list1.remove(q) #removing first choice so same country never asking again
try:
q=random.choice(list1)
except:
print ("We are out of countries,sorry!")
break
else:
print ("Not correct")
Using dict and key-value system and list comprehension.

A list of lists can work, but a dictionary with key, value pairs works great for this.
In keeping with your original theme of user input, the logic works out well and you can use the random.choice function to pick your country while keeping track.
import random
data = {}
maxlength = 10
for _ in range(maxlength):
country = input("please enter a country: ")
capital = input("please enter the capital of the country entered: ")
# using a dict, keeps things simple
data[country] = capital
countries = list(data.keys())
picked = []
while len(picked) < maxlength:
country = random.choice(countries)
if country in picked:
continue
print("Capital for the country {0}?".format(country))
user_said_capital_was = input("What do you think? ")
if user_said_capital_was == data[country]:
print("Correct!")
picked.append(country)
else:
print("Incorrect!")

Related

Does anyone have advice for how to use inputs to determine placement into list?

I am writing code to identify if plants are safe or unsafe. In my code, after a user enters their plant, I want to have the user answer questions about the plant. Once they are done answering questions, they can enter another plant and repeat this process.
My goal is to have each question assigned a value; so, if the user answers "no" to all the questions, the plant is the safest, if the user answers "no" to half of them, it is half as safe. I would append plants with four or more "yeses" to safe and the other plants to "unsafe". Then, I want to define two more functions that print the safest and least safe plants using the amount of yes and nos.
Thank you to everyone who commented! I now have so many different ways I could code this. I'm very grateful for all the help!! The new edits reflect the new names of the list.
def plantidentifier():
print(("Enter plant or XXX to quit "))
plant = input().upper()
print("Is a mushroom")
print("Does your plant have thorns?")
print("Is your plant yellow or white?")
print ("Are there shiny leaves?")
print("Is your plant umbrella shaped?")
Good.append(plant)
Bad.append(plant)
return Good, Bad
Good = []
Bad = []
print("Welcome to plant identifier!")
print("Please cafeully consider your plants")
print("Enter the name of your first plant and start answering questions. When done entering plants, enter XXX")
plantidentifier()
To go with my comment, here is a simple outline of what you might want to do in this situation. Notice that if you want the results for individual questions this will not work,
from distutils.util import strtobool
class Plant:
max_danger_rating = 1 # The number of questions asked
def __init__(self):
self.danger_rating = 0 # how many questions have been answered yes
is_dangerous = input("Is this plant dangerous?")
if strtobool(is_dangerous): #here is_dangerous can be "yes", "y", "t", ...
self.danger_rating += 1
plants = [] # create your plants and add them to this list
dangerous_plants = [plant for plant in plants if plant.danger_rating > Plant.max_danger_rating / 2]
safe_plants = [plant for plant in plants if plant.danger_rating <= Plant.max_danger_rating / 2]
dangerous_plants.sort(key = lambda plant: plant.danger_rating)
You'll notice especially at the end that we can use the danger_rating as a key to sort by, which makes your work a lot easier.
See the comments for explanation on what I did here. This is not a great code, but hopefully it does what you want.
def plantidentifier():
print(("Enter plant or XXX to quit "))
plant = input().upper()
while plant != "XXX":
if plant == "" or plant ==" ":
print("no plant entered")
else:
# Get answers from user and make them lowercase
q1 = input("Is your a plant a mushroom\n").lower()
q2 = input("Does your plant have shiny leaves or thorns?\n").lower()
q3 = input("Is your plant yellow or white?\n").lower()
q4 = input("Is your plant umbrella shaped?\n").lower()
# put answers in a list, to operate on all of them
answers = [q1, q2, q3, q4]
positive_answers = 0 # this will count how many "yeses" we got
negative_answers = 0 # this will count how many "no" we got
for answer in positive_answers:
if answer == "yes":
positive_answers += 1
elif answer == "no":
negative_answers += 1
# we need to use str function, because you can't add number to string (ie. "a" + 4).
# You need to convert 4 => "4"
print("The plant is " + str(positive_answers/negative_answers) + " safe")
if positive_answers == SOME_NUMBER:
SafePlants.append(plant)
else:
UnsafePlants.append(plant)
# there is no "return" here, because you use global variables (SafePlants, UnsafePlants)
SafePlants = []
UnsafePlants = []
print("Welcome to plant identifier!")
print("Please cafeully consider your plants")
print("Enter the name of your first plant and start answering questions. When done entering plants, enter XXX")
plantidentifier()
Here's one possible solution:
import sys
# Request input and check if it equals XXX
def input_cx(msg):
x = input(msg)
if x.upper() == "XXX":
sys.exit()
return x
def plantidentifier():
while True:
plant = input_cx("Enter plant or XXX to quit ")
if plant.strip() == "":
print("no plant entered")
else:
inputs = []
yes_inputs = 0
inputs.append(input_cx("Is your a plant a mushroom"))
inputs.append(input_cx("Does your plant have shiny leaves or thorns?"))
inputs.append(input_cx("Is your plant yellow or white?"))
inputs.append(input_cx("Is your plant umbrella shaped?"))
for i in inputs:
if i == "yes":
yes_inputs += 1
if yes_inputs >= 4:
UnsafePlants.append(plant)
else:
SafePlants.append(plant)
SafePlants = []
UnsafePlants = []
print("Welcome to plant identifier!")
print("Please cafeully consider your plants")
print("Enter the name of your first plant and start answering questions. When done entering plants, enter XXX")
plantidentifier()
This first defines input_cx as a function that takes a string parameter. It will run the input function with msg and return the input, unless it equals "XXX", in which case it will exit the program.
In the plantidentifier function, it runs a while True loop. Each iteration, it first uses input_cx to define the plant name. If it is not an empty value (ignoring whitespace), it will define inputs and yes_inputs as an empty list and 0 respectively. It then asks the user the 4 questions and appends each of them to inputs. It will then iterate over each value of inputs and, for each "yes" input, will add 1 to yes_inputs. If the value of yes_inputs comes out to be 4 or greater, the plant is appended to UnsafePlants; otherwise, it is appended to SafePlants.
You can
capture the answers in a list
sum the scores ('no' has a score of 1)
store the plant-score pair in a dictionary
add to SafePlants if score is >= 4
return SafePlants, UnsafePlants, and plant_score dictionary
you can print the plant-score pairs sorted by score
def func():
# a dictionary to store the plant, score pair
p_score = {}
print(("Enter name or XXX to quit "))
name = input().upper()
while name != "XXX":
if name == "" or name ==" ":
print("no name entered")
else:
# put responses in a list
response = [
input("Is your a name a mushroom"),
input("Does your name have shiny?"),
input("Is your name yellow or white?"),
input("Is your name umbrella?")
]
# calculate the score, 'no' has score of 1, this sums the score of the questions
score = sum([x=='no' for x in response])
# store plant and score in the dictionary
p_score[name]=score
# add plant to good if it has score of 4 or more
if score >=4:
good.append(name)
else:
bad.append(name)
print(("Enter name or XXX to quit "))
name = input().upper()
return bad, good, p_score
good = []
bad = []
print("Welcome to name identifier!")
print("Please carefully consider your names")
print("Enter the name of your first plant and start answering questions. When done entering plants, enter XXX")
bad, good, p_score=func()
# print plants with scores from unsafest to safest
print(sorted(p_score.items(), key=lambda x: x[1]))
Instead of printing, you can do this:
results_list.append(True if input("Does your plant have this quality?").upper() == "TRUE" else False)
This uses Python's ternary operator, which is useful to know about.
As Galunid suggested, you can also do this:
results_list.append(input("Does your plant have this quality?").upper() == "TRUE")
since this will add a boolean.
Both check case-insensitively whether the input is "TRUE" (obviously in your case, you may want to check more than just that) and adds True to results_list if so and False if not. If you want to check more than just "TRUE" I suggest assigning the input to a variable like so: var = input("Foo").
Then, you can just check the count of True in results_list to determine whether the plant is safe!
Below is the working version, with a typo fixed and the results printed:
def plantidentifier():
print(("Enter plant or XXX to quit "))
plant = input().upper()
while plant != "XXX":
if plant == "" or plant ==" ":
print("no plant entered")
else:
results_list = []
results_list.append(input("Is your a plant a mushroom").upper() == "TRUE")
results_list.append(input("Does your plant have shiny leaves or thorns?").upper() == "TRUE")
results_list.append(input("Is your plant yellow or white?").upper() == "TRUE")
results_list.append(input("Is your plant umbrella shaped?").upper() == "TRUE")
if results_list.count(True) > 2:
Good.append(plant)
else:
Bad.append(plant)
return Bad, Good
Good = []
Bad = []
print("Welcome to plant identifier!")
print("Please carefully consider your plants")
print("Enter the name of your first plant and start answering questions. When done entering plants, enter XXX")
print(plantidentifier())

Python - searching for letters in a list of words

I am absolutely new to programming atm. I have searched the forums but none of the results were applicable to my case (unless I am mistaken, but trust me the first thing I did was to google). Please help me if you have time.
Write a python program that prompts the user to enter a list of first names and stores them in a list. The program should display how many times the letter 'a' appears within the list.
Now I thought I have got the PERFECT code. But everytime the program only counts the number of "a"s in the first word on the list!?
terminate = False
position = 0
name_list = [ ]
while not terminate:
name = str(input('Please enter name: '))
name_list.append(name)
response = input('Add more names? y/n: ')
if response == 'n':
terminate = True
print(name_list)
for t in name_list:
tally = name_list[position].count('a')
position = position + 1
print("The numer of 'a' is: ", tally)
If anyone has time to help I would appreciate it.
A couple of points:
you meant to use tally as an accumulator but are actually not adding to it.
You don't need the position indexer, for t in name_list already iterates over all names in the list, at each iteration of the for loop t is a name from name_list.
fix the inner loop
terminate = False
# position = 0 <-- this is not needed anywhere
name_list = [ ]
while not terminate:
name = str(input('Please enter name: '))
name_list.append(name)
response = input('Add more names? y/n: ')
if response == 'n':
terminate = True
print(name_list)
tally = 0 # initialise tally
for t in name_list:
tally += t.count('a') # increment tally
print("The numer of 'a' is: ", tally)
Your code is not fully understandable to me. Probably, because some stuff is missing. So, I am assuming, you already have the list of names. In the code you presented, you are overwriting tally each time you count the number of a in a name in the list. Besides other possible bugs in your code (maybe when creating the list of names - I'd use a while-loop for this), you should write
tally += name_list[position].count('a')
which equals
tally = tally + name_list[position].count('a')
instead of your
tally = name_list[position].count('a')
terminate = False
position = 0
name_list = [ ]
tally = 0
while not terminate:
name = str(input('Please enter name: '))
name_list.append(name)
response = input('Add more names? y/n: ')
if response == 'n':
terminate = True
print(name_list)
for t in name_list:
#tally = name_list[position].count('a')
tally += name_list[position].count('a')
position = position + 1
print("The numer of 'a' is: ", tally)
initilize tally=0 and insted of "tally = name_list[position].count('a')" use "tally += name_list[position].count('a')" if you have to count "a" in entire list you have to update the tally value
I would suggest you get rid of the for loop, and position counter. If you want the total of all 'a', you have to sum tally for all the names :
terminate = False
name_list = []
total = 0
while "Adding more names":
name = str(input('Please enter name: '))
name_list.append(name)
tally = name.count('a')
total += tally
print("The numer of 'a' in current name is: ", tally)
if input('Add more names? y/n: ') == 'n':
break
print(name_list)
print("The numer of 'a' is: ", total)

Search through an array with another array

I'm pulling in a text file as a multidimensional array and giving the user a choice to pick one of the items and it is stored in another array. I'm trying to figure out how to find the index of the first array with the elements in the second.
Code:
with open("books.txt") as b:
books = b.readlines()[7:]
books = [x.strip() for x in books]
books = [x.split(",") for x in books]
def welcome():
print("Welcome to the Bookstore")
global name
name = input("What is your name? ")
print("Our current list of books are: ")
inventory()
def choice():
select = input("Which books would you like? (ID):\n")
global chosen
chosen = []
flag = "y"
while flag == "y":
chosen.append(select)
flag = input("Would you like to add more books to your cart? (y/n): ")
print(chosen)
for chosen in books:
books.index(chosen[0])
def inventory():
length = len(books)
for i in range(length):
print(books[i][0], books[i][1].strip(), ("$" + books[i][2]).replace(" ", ""))
choice()
def receipt():
print("Thank you", name)
welcome()
Text File:
To add books to your store please have a new book on each line,
and use the format ItemNumber,BookName,BookPrice an example would be as follows:
B142, Prelude to Programing, 5.25
Please start entering books under the heading Books Available.
Thank You
Books Available:
B12, Prelude to Programing, 5.25
B13, Lazy Python, 10.25
B14, Coding for Dummys, 19.25
I have tried
for chosen in books:
books.index(chosen[0])
If i select B12, I want the result to be 0 0 for the index numbers.
Issues:
You are overwriting chosen in the line for chosen in books:.
Loop prompting for more books just appends last selected book id when y is entered for more.
The word select colors in my editor as a module select exists. You may want to change the name.
Replace choice() with this change.
def choice():
global chosen
chosen = []
while True:
select = input("Which books would you like? (ID):\n")
chosen.append(select)
flag = input("Would you like to add more books to your cart? (y/n): ")
if flag != 'y':
break
print(chosen)
index = []
for item in chosen:
for idx, book in enumerate(books):
if item == book[0]:
index.append([idx, 0])
print('index:', index)
The index list contains i.e. [[2, 0], ...]
The 2 being the index to find the book in books.
The 0 being the index of the book id.
If the result not exactly what you want, you can make the any changes needed.
Storing the book ID means searching later. You could store the index of the book instead.
i.e.
def choice():
global chosen
chosen = []
while True:
select = input("Which books would you like? (ID):\n")
# Get the index of the selected book in books.
for idx, book in enumerate(books):
if select == book[0]:
chosen.append(idx)
break
flag = input("Would you like to add more books to your cart? (y/n): ")
if flag != 'y':
break
print(chosen)
# [[0, 0], ...]
result = [[idx, 0] for idx in chosen]
print(result)
This function is storing the index of the book chosen rather than the ID of the book ID as it is more convenient to use the index later as the use of list comprehension shows at the end.

Python Lists: .lower() attribute error

I am trying to create a program on python to do with manipulating lists/arrays. I am having trouble with an error:
lowercase = names.lower
AttributeError: 'list' object has no attribute 'lower'
I really need some help to fix this!
names = [] #Declares an array
print("Type menu(), to begin")
def menu():
print("----------------------------MENU-----------------------------")
print("Type: main() for core functions")
print("Type: delete() to delete a name")
print("Type: save() to save the code")
print("Type: load() to load the saved array")
print("Type: lower() to make all items in the list lower case")
print("-------------------------------------------------------------")
def main():
times = int(input("How many names do you want in the array? ")) #Asks the user how many names they want in the array
for i in range(times):
names.append(input("Enter a name ")) #Creates a for loop that runs for the amount of times the user requested, it asks the user to enter the names
choice = input("Would you like the array printed backwards? ") #asks the user whether they want the array backwards
if choice == "Yes":
names.reverse() #If the user says yes, the array is reversed then printed backwards
print(names)
else:
print(names) #Otherwise, the array is printed normally
number = int(input("Which item would you like to print out? "))
number = number - 1
print(names[number])
start = int(input("What is the first position of the range of items to print out? "))
start = start - 1
end = int(input("What is the last position of the range of items to print out? "))
print(names[start:end])
def delete():
takeAway = input("Which name would you like to remove? ")
names.remove(takeAway)
print(names)
def save():
saving1 = open("Save.txt", 'w')
ifsave = input("Would you like to save the array? ")
if ifsave == "Yes":
for name in names:
saving1.write("%s\n" % name)
saving1.close
else:
menu()
def load():
loadquestion = input("Would you like to load a list of names? ")
if loadquestion == "Yes":
saving1 = open('Save.txt', 'r')
print(saving1.read())
saving1.close()
else:
menu()
def lower():
lowerq = input("Would you like to make the array lowercase? ")
if lowerq == "Yes":
lowercase = names.lower
print(lowercase)
else:
menu()
The variable names is a list. You can't use the .lower() method on a list.
pp_ provided the solution:
lowercase = [x.lower() for x in names]
While not exactly equivalent to the previous example, this may read better to you and has, effectively, the same result:
lowercase=[]
for name in names:
lowercase.append(name.lower())
Alternate solution that may fit your needs:
print (str(names).lower())
Like the error message says, you can't use .lower() on lists, only on strings. That means you'll have to iterate over the list and use .lower() on every list item:
lowercase = [x.lower() for x in names]

Python assignment for a phonebook

This weeks lab is based on the example on pages 53,54 of the wikibook "Non-Programmers Tutorial For Python" by Josh Cogliati (2005), (see http://en.wikibooks.org/wiki/Non-Programmer%27s_Tutorial_for_Python_3/Dictionaries).
In his example, Cogliati has options for printing, adding, removing, and looking up a phone number. Change the code so that, instead of the value in the dictionary being a simple phone number, it is now a list with three values:
phone number
e-mail
address web page
The key should still be simply the persons name. Adapt the menu used in the example accordingly, for example the '2. Add a Phone Number' should now read '2. Add an entry' and if selected should ask the user for the 4 items of information (name, phone, email, web). Aditionally:
Add an option (e.g. number 6 in the menu) to 'Change/Edit an existing entry'.
Add options to:
Print just a list of the phone numbers
Print just a list of the e-mail addresses
Print just a list of the web addresses
Print all of the above together
This is the assignment we were given, I understand what's given in the link and have added a bit to it, unsure as to how to go about adding in the calling upon of the email and webpage information once stored
Although I agree with the comment under your answer, I will still try my best to give you some guidance.
Original Code:
def print_menu():
print('1. Print Phone Numbers')
print('2. Add a Phone Number')
print('3. Remove a Phone Number')
print('4. Lookup a Phone Number')
print('5. Quit')
print()
numbers = {}
menu_choice = 0
print_menu()
while menu_choice != 5:
menu_choice = int(input("Type in a number (1-5): "))
if menu_choice == 1:
print("Telephone Numbers:")
for x in numbers.keys():
print("Name: ", x, "\tNumber:", numbers[x])
print()
elif menu_choice == 2:
print("Add Name and Number")
name = input("Name: ")
phone = input("Number: ")
numbers[name] = phone
elif menu_choice == 3:
print("Remove Name and Number")
name = input("Name: ")
if name in numbers:
del numbers[name]
else:
print(name, "was not found")
elif menu_choice == 4:
print("Lookup Number")
name = input("Name: ")
if name in numbers:
print("The number is", numbers[name])
else:
print(name, "was not found")
elif menu_choice != 5:
print_menu()
Notice that numbers is equal to {} - this signifies that it is a "Dictionary", which stores key/value pairs. To add to a dictionary (or "dict"), you can modify it manually as such: numbers = {'David': 18003574689}. So, in order to access David's phone number, you would type in numbers['David'].
Another way to add to it is by instantiating it (which is already done for you via numbers = {}), and then adding information into to it via the shortcut formula dictname['key'] = value. So in this case, the shorthand can be numbers['Laura'] = 9173162546.
Now, to add a list into the mix, you could use [] (which is a list in python), but you would probably be better suited nesting another dict into the current one. For example, instead of numbers = {'David': 18003574689}, you can now have numbers = {'David': {'phone number': 18003574689, 'e-mail': 'david2015#gmail.com', 'address web page': 'http://dave.com'}, 'Laura': [...etc...]}.
To access these new nested dicts, what you can do is the shorthand numbers['David']['phone number'], which will return his #. You can then do this exact shortcode 2 more times numbers['David']['e-mail'] & numbers['David']['address web page']. These three will access the associated data.
Since I believe this is the toughest part for a newcomer, I'll stop here since the rest should be easy. All you have to do is create new inputs in the correct if conditions. Assign the captured input data into proper variables via the = assignment operator (ex. email = input('Email: ')), and then use the rest of the info logically. I hope this helps.

Categories