Problems with random "Lists" - python

I want to create a game where a person is drawn out randomly.
Can some1 check the code if everything is setup correctly.
I have tested the code numerous times and its ok in my eyes.
But when I send the code to a review, to an online class I only get 50% score.
import random
# 🚨 Don't change the code below πŸ‘‡
test_seed = int(input("Create a seed number: "))
random.seed(test_seed)
# Split string method
names_string = input("Give me everybody's names, separated by a comma. ")
names = names_string.split(", ")
# 🚨 Don't change the code above πŸ‘†
#Write your code below this line πŸ‘‡
print(names)
names_count = len(names)
random_name_number = random.randint(0, names_count)
print(f"{names[random_name_number]} is going to buy the meal today!")

The problem here is almost certainly with randint. Unlike most Python conventions, the parameters to randint are inclusive. That means, if you supply (0,10), you are going to get numbers from 0 to 10. In your case, if they supply 10 names, using index 10 is going to cause an exception.
You want random.randrange, not random.randint. randrange(0,10) will supply numbers from 0 to 9.

Related

How do I add numbers I've iterated into a list to a string?

I've got a tiny project I'm working on: I'm trying to make a "grading" program that lets you enter the number of exams, the scores for each exam, and then prints the results.
What I'm looking to do:
Enter the number of tests:
use that number with the string "Exam #: " to number each test.
I've gotten as far as sticking the input from "Enter the number of tests:" into a list..(looks like [0,1,2,3,4.. etc] now I'm trying to combine each of those list numbers with the above string and nothing I'm trying is working.. suggestions?
This is what I came up with, and its output:
test1 = int(input('How many tests are there? '))
test2 = []
for number in range(test1):
test2.append(number)
for number2 in test2:
print('Exam #:' + str(number2))
(inputting "5" here)
Exam #:0
Exam #:1
Exam #:2
Exam #:3
Exam #:4
exactly what I needed!
Try something link this
num_exams = int(input('Enter the number of exams: '))
exam_scores = [int(input(f'Enter score for exam #{n+1}: ')) for n in range(num_exams)]
print(f'Average score: {sum(exam_scores) / num_exams:0.2f}')
Seems like you'd want to collect inputs for the number of tests and then all the test scores. Then to print the test scores you could do something like
for test in range(numTests):
print('Exam #' + (test+1) + ': ' + testScores[test])
The (test+1) is so that you could have the same variable manage the test number as well as the index in the test array. For example, it could print
Exam #1: 82
Exam #2: 93
Exam #3: 87
Not sure if this is needed for your program, but you can iterate through all your values in a list with a for loop. This allows you you to access each value and perform some set of commands on that value. So in this example, we will access each value and then print it. Print can take multiple arguments. It will print out each argument with a space in between.
for examNumber in myList:
print ('Exam', examNumber)

How to match input with elements in list/dictionary in Python3

I'm very new at coding, and I'm trying to create a shop list with items and prices on it.
That is, once typed in all the items, the function should calculate the sum and stop the moment you exceed the budget.
So I wrote something like:
def shoplist():
list={"apple":30, "orange":20, "milk":60......}
buy=str(input("What do you want to purchase?")
If buy in list:
While sum<=budget:
sum=sum+??
shoplist ()
I really don't know how to match the input of an item with the price in the list...
My first thought is to use 'if', but it's kinda impractical when you have more than 10 items on the list and random inputs.
I'm in desperate need of help....So any suggestions would be nice!! (or if you have a better solution and think me writing it this way is complete garbage... PLEASE let me know what those better solutions are😭😭😭
The code you post will not run in python. list is a builtin and should not be used for a variable name, and is doubly confusing since it refers to a dict object here. input() already returns a str so the cast has no effect. if and while should be lowercase, and there is no indentation, so we have no way of knowing the limits of those statements.
There are so many things wrong, take a look at this:
def shoplist(budget):
prices = {"apple":30, "orange":20, "milk":60}
# Initialise sum
sum = 0
while sum <= budget:
buy = input("What do you want to purchase?")
# Break out of the loop if the user hts <RETURN>
if not buy: break
if buy in prices:
sum += prices[buy] # This gets the price
else:
print("Invalid item", buy)
shoplist(142)
So what have I changed? The budget has to come from somewhere, so I pass it in as a parameter (142, I made that up). I initialise the sum to zero, and I moved the while loop to the outside.
Notice as well lots of whitespace - it makes the code easier to read and has no effect on performance.
Lots of improvements to make. The user should be shown a list of possible items and prices and also how much budget there is left for each purchase. Note as well that it is possible to go over budget since we might only have 30 in the budget but we can still buy milk (which is 60) - we need another check (if statement) in there!
I'll leave the improvements to you. Have fun!
Take a look at this as an example:
# this is a dictionary not a list
# be careful not using python reserved names as variable names
groceries = {
"apple":30,
"orange":20,
"milk":60
}
expenses = 0
budget = 100
cart = []
# while statements, as well as if statements are in lower letter
while expenses < budget:
# input always returns str, no need to cast
user_input = input("What do you want to purchase?")
if user_input not in groceries.keys():
print(f'{user_input} is not available!')
continue
if groceries[user_input] > budget - expenses:
print('You do not have enough budget to buy this')
user_input = input("Are you done shopping?Type 'y' if you are.")
if user_input == 'y':
break
continue
cart.append(user_input)
# this is how you add a number to anotherone
expenses += groceries[user_input]
print("Shopping cart full. You bought {} items and have {} left in your budget.".format(len(cart), budget-expenses))
I've made some changes to your code to make it work, with explanation including using comments indicated by the # symbol.
The two most important things are that all parentheses need to be closed:
fun((x, y) # broken
fun((x, y)) # not broken
and keywords in Python are all lowercase:
if, while, for, not # will work
If, While, For, Not # won't work
You might be confused by True and False, which probably should be lowercase. They've been that way so long that it's too late to change them now.
budget = 100 # You need to initialize variables before using them.
def shoplist():
prices = { # I re-named the price list from list to prices
'apple' : 30, # because list is a reserved keyword. You should only
'orange' : 20, # use the list keyword to initialize list objects.
'milk' : 60, # This type of object is called a dictionary.
} # The dots .... would have caused an error.
# In most programming languages, you need to close all braces ().
# I've renamed buy to item to make it clearer what that variable represents.
item = input('What do you want to purchase? ')
# Also, you don't need to cast the value of input to str;
# it's already a str.
if item in prices:
# If you need an int, you do have to cast from string to int.
count = int(input('How many? '))
cost = count*prices[item] # Access dictionary items using [].
if cost > budget:
print('You can\'t afford that many!')
else:
# You can put data into strings using the % symbol like so:
print('That\'ll be %i.' % cost) # Here %i indicates an int.
else:
print('We don\'t have %s in stock.' % item) # Here %s means str.
shoplist()
A lot of beginners post broken code on StackOverflow without saying that they're getting errors or what those errors are. It's always helpful to post the error messages. Let me know if you have more questions.

Python - Creating a league table, that displays the lines separately and a function to extract certain lines

I am trying to write three funcitons that, create a league table(I used 3 teams to make it easier to test but in practice there will be 16), calculate the points of those teams (3 points for a win, 1 point for a draw and 0 for a loss) and a function that, given the name of a team will return all its information. The saveInfo function works and the createLeague function works however it only returns the first line not the subsequent 2, also the getTeam function returns (none).
def saveInfo():
myFile=open("league.txt","w")
for i in range(3):
team=input("Enter name of team: ")
matchesPlayed=input("Enter number of matches played: ")
matchesWon=int(input("Enter number of matches won: "))
matchesDrawn=int(input("Enter number of matches drawn: "))
matchesLost=int(input("Enter number of matches lost: "))
return team,"",matchesPlayed,"",matchesWon,"",matchesDrawn,"",matchesLost
myFile.close()
def createLeague():
myFile=open("league.txt","r")
points=0
for info in myFile:
for i in range(3):
info=info.rstrip("/n")
team_info=info.split()
team_info[2]=int(team_info[2])
team_info[3]=int(team_info[3])
points=(team_info[2]*3)+(team_info[3]*1)
team_info.append(points)
return team_info
myFile.close()
def getTeam():
name="Enter name of team"
myFile=open("league.txt","r")
team_info=""
for line in myFile:
info=info.rstrip("/n")
team_info=info.split()
if team_info[0]==name:
print(team_info)
myFile.close()
saveInfo()
team_info=createLeague
print(createLeague()) # only displays first line not the other 2
That's accurate per your code. create_league enters the loop, processes the first item, and then returns that team's info without going back to the top of the loop. You told it to return as soon as it gets to that point. You need to allow it to finish the loop, writing and collecting things in whatever form you're using.
Similarly, getTeam doesn't return anything: there's no return statement at all. That's why the return value is None.
I can't show you how to fix this, since you haven't specified the functionality in your posting, but that's where you're going wrong. It looks as if you may be confusing yourself between the information you write to a file, compared to what you return in communicating between the function and the calling routine.
There are mistakes to your code
You put return on the loop, that's why it only loop once, then get out of the loop
You did not write anything to file
Probably you mean something like this
def save_info():
with open("league.txt","w") as myFile:
for i in range(3):
team=input("Enter name of team: ")
matchesPlayed=input("Enter number of matches played: ")
matchesWon=int(input("Enter number of matches won: "))
matchesDrawn=int(input("Enter number of matches drawn: "))
matchesLost=int(input("Enter number of matches lost: "))
myFile.write("{0},{1},{2},{3},{4}\n".format(team,matchesPlayed,matchesWon,matchesDrawn,matchesLost))
def create_league():
with open("league.txt","r") as myFile:
contents = myFile.readlines()
for content in contents:
content.rstrip('\n')
team_info=content.split(",")
team_info[2]=int(team_info[2])
team_info[3]=int(team_info[3])
points=(team_info[2]*3)+(team_info[3]*1)
print(points)
save_info()
create_league()
same applies to get_team method, and you should use snake case instead of camel case for python method

Making a statistics program

I am trying to write a Python program that computes and prints the following :
the average score from a list of scores
the highest score from a list of scores
the name of the student who got the highest score.
The program starts by asking the user to enter the number of cases. For EACH case, the program should ask the user to enter the number of students. For each student the program asks the user to enter the student's name and marks. For EACH case the program reports the average marks, the highest marks and the name of the student who got the highest marks.
Also
If there are more than one person with the highest score in a CASE, the program should report the first occurrence only.
The average score and the highest score should have exactly 2 decimal places.
The output should be as in the sample program output.
What I have been trying so far is the following:
grade=[]
name_list=[]
cases=int(input('Enter number of cases: '))
for case in range(1,cases+1):
print('case',case)
number=int(input('Enter number of students: '))
for number in range (1,number+1):
name=str(input('Enter name of student: '))
name_list.append(name)
mark=float(input('Enter mark of student:'))
grade.append(mark)
highest= max (grade)
average=(sum(grade)/number)
high_name=grade.index(max(grade))
print('average',average)
print('Highest',highest)
print (high_name)
This is what i have deciphered so far. my biggest problem now is getting the name of the individual with the high score. Any thoughts and feedback is much appreciated. As with respect to the answer posted below, i am afraid the only thing i do not understand is the dictionary function but otherwise the rest does make sense to me.
This resembles an assignment, it is too specific on details.
Anyways, the official docs are a great place to get started learning Python.
They are quite legible and there's a whole bunch of helpful information, e.g.
range(start, end): If the start argument is omitted, it defaults to0
The section about lists should give you a head start.
numcases = int(input("How many cases are there? "))
cases = list()
for _ in range(numcases):
# the _ is used to signify we don't care about the number we're on
# and range(3) == [0,1,2] so we'll get the same number of items we put in
case = dict() # instantiate a dict
for _ in range(int(input("How many students in this case? "))):
# same as we did before, but skipping one step
name = input("Student name: ")
score = input("Student score: ")
case[name] = score # tie the score to the name
# at this point in execution, all data for this case should be
# saved as keys in the dictionary `case`, so...
cases.append(case) # we tack that into our list of cases!
# once we get here, we've done that for EVERY case, so now `cases` is
# a list of every case we have.
for case in cases:
max_score = 0
max_score_student = None # we WILL need this later
total_score = 0 # we don't actually need this, but it's easier to explain
num_entries = 0 # we don't actually need this, but it's easier to explain
for student in case:
score = case[student]
if score > max_score:
max_score = score
max_score_student = student
total_score += score
num_entries += 1
# again, we don't need these, but it helps to demonstrate!!
# when we leave this for loop, we'll know the max score and its student
# we'll also have the total saved in `total_score` and the length in `num_entries`
# so now we need to do.....
average = total_score/max_entries
# then to print we use string formatting
print("The highest score was {max_score} recorded by {max_score_student}".format(
max_score=max_score, max_score_student=max_score_student))
print("The average score is: {average}".format(average=average))

Infinite loop in simulation

I'm starting out in python.. The details I have written in the below.. It goes to an infinite loop and give me an error when I try to call the function inside itself.. Is this kind of recursion not allowed ?
Posting code below.. Thanks for all your help :)
The program assumes that we have 100 passengers boarding a plane. Assuming if the first one has lost his boarding pass, he finds a random seat and sits there. Then the other incoming passengers sit in their places if unoccupied or some other random seat if occupied.
The final aim is to find the probability with which the last passenger will not sit in his/her own seat. I haven't added the loop part yet which
would make it a proper simulation. The question above is actually a puzzle in probability. I am trying to verify the answer as I don't really follow the reasoning.
import random
from numpy import zeros
rand = zeros((100,3))
# The rows are : Passenger number , The seat he is occupying and if his designated seat is occupied. I am assuming that the passengers have seats which are same as the order in which they enter. so the 1st passenger enter has a designated seat number 1, 2nd to enter has no. 2 etc.
def cio(r): # Says if the seat is occupied ( 1 if occupied, 0 if not)
if rand[r][2]==1:
return 1
if rand[r][2]==0:
return 0
def assign(ini,mov): # The first is passenger no. and the second is the final seat he gets. So I keep on chaning the mov variable if the seat that he randomly picked was occupied too.
if cio(rand[mov][2])== 0 :
rand[mov][2] = 1
rand[mov][1] = ini
elif cio(rand[mov][2])== 1 :
mov2 = random.randint(0,99)
# print(mov2) Was used to debug.. didn't really help
assign(ini,mov2) # I get the error pointing to this line :(
# Defining the first passenger's stats.
rand[0][0] = 1
rand[0][1] = random.randint(1,100)
m = rand[0][1]
rand[m][2]= 1
for x in range(99):
rand[x+1][0] = x + 2
for x in range(99):
assign(x+1,x+1)
if rand[99][0]==rand[99][1] :
print(1);
else :
print(0);
Please tell me if y'all get the same error.. ALso tell me if I am breaking any rules coz thisi sthe first question I'm posting.. Sorry if it seems too long.
This is how it should've been...
The code does work fine in this case with the following mods :
def assign(ini,mov):
if cio(mov)== 0 : """Changed here"""
rand[mov][2] = 1
rand[mov][1] = ini
elif cio(mov)== 1 : """And here"""
mov2 = random.randint(0,99)
assign(ini,mov2)
I am using Python 2.6.6 on Windows 7, using a software from Enthought Academic Version of Python.
http://www.enthought.com/products/getepd.php
Also the answer to this puzzle is 0.5 which is actually what I am getting(almost) by running it 10000 times.
I didn't see it here but it had to be available online..
http://www.brightbubble.net/2010/07/10/100-passengers-and-plane-seats/
Recursion, while allowed, isn't your best first choice for this.
Python enforces an upper bound on recursive functions. It appears that your loop exceeds the upper bound.
You really want some kind of while loop in assign.
def assign(ini,mov):
"""The first is passenger no. and the second is the final seat he gets. So I keep on chaning the mov variable if the seat that he randomly picked was occupied too.
"""
while cio(rand[mov][2])== 1:
mov = random.randint(0,99)
assert cio(rand[mov][2])== 0
rand[mov][2] = 1
rand[mov][1] = ini
This may be more what you're trying to do.
Note the change to your comments. Triple-quoted string just after the def.
you may be able to find the exact solution using dynamic programming
http://en.wikipedia.org/wiki/Dynamic_programming
For this you will need to add memoization to your recursive function:
What is memoization and how can I use it in Python?
If you just want to estimate the probability using simulation with random numbers then I suggest you break out of your recursive function after a certain depth when the probability is getting really small because this will only change some of the smaller decimal places (most likely.. you may want to plot the change in result as you change the depth).
to measure the depth you could add an integer to your parameters:
f(depth):
if depth>10:
return something
else: f(depth+1)
the maximum recursion depth allowed by default is 1000 although you can change this you will just run out of memory before you get your answer

Categories

Resources