Dictionary not updating if key and value are not unique - python

Im new to python and Im creating this gambling game where a user will have the choice to bet on symbols that will be generated (eventually- haven't gotten there yet). Im creating a dictionary to hold my data for how much the user is betting (the value) and the number corresponding to the symbol they are betting on (the key). Each player has the option to place more than 1 bet per turn. I am running into a problem where if two different players input the same bet&symbol combination (for example $10 on 1 (Crown)) then the dictionary wont update to contain 2 separate entries of 1:10, it will only have one entry of 1:10. This is what Im working with right now
def getPlayers():
print("Hello and Welcome to the Crown and Anchor Game")
num = int(input('Please enter the number of people playing today: ')) # takes the number of people who are playing from the user
scoreInit = [] # creating an empty list for the players inital score of 10
for i in range(num): # for loop to append the inital score of 10 to the empty list scoerInit for the amount of players input
scoreInit += i * [10]
return scoreInit # returns the list of inital scores for the amount of players playing
def collectBets(balance):
bets = {}
index = 0
for i in balance:
index += 1
print('Player %d, what would you like to do this round?' % (index))
print('1: Bet on a symbol')
print('2: Skip this round')
userOpt = int(input('Please enter 1 or 2 depending on your choice: ')) # assigning what the user inputs as the variable 'usesrOpt'
if userOpt == 1: # if user decides to bet:
betTimes = int(input('How many times would you like to bet this round?: '))
for a in range(betTimes):
betAmount = int(input('Enter the amount you would like to bet this round: $1, $2, $5, or $10: '))
symbol = int(input('Enter the number corresponding to the symbol you would like to bet on\n' # asking user what symbol they want to bet on - assigning it to a variable
'1: Crown\n'
'2: Anchor\n'
'3: Heart\n'
'4: Diamond\n'
'5: Club\n'
'6: Spade\n'
))
bets.update({symbol:betAmount})
print(bets)
def main():
balance1 = getPlayers()
collectBets(balance1)
main()
Any help would be much appreciated! Thank you!

It is best to think of a Python Dictionary as "an un ordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary)." https://docs.python.org/3/tutorial/datastructures.html
With that being said, whenever user A chooses 10, and then user B chooses 10; user A choice is literally being overwritten by user B's choice. A single dictionary can only hold 10 once as a key. In order to resolve your solution you'll have to use some other data structures. The key within a dictionary should be unique.
A solution to your problem could be to use different levels of dictionaries. You could have a dictionary of player names that holds a dictionary of their value, and their symbol. However, your player names would have to be unique, otherwise you would run into the same issue.

Related

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: How to ask the user for the index of a list

-------Answered, turns out I was doing the right thing, but had a different error that made me think it was the wrong thing to do------------------
Alright, so I know this is super simple but I am really confused as to how to take a user input as a number and use that number to index from a list with that number.
So what I am trying to do is this:
Enter your choice: (User enters a 1)
You choose 1.
Which sentence? (User enters a 0 or whatever number they want within the bounds of how many sentences they enter)
I then just want to use their inputted number and index that from the list.
So if they entered these two sentences for their list:
good
bad
Then when they ask which sentence, and say 1, I want to index sentenceList[1] and print it back to them.
But this needs to be scale-able to any number, so sentenceList[variable],
but I do not know how to properly do this.
Thanks, I know this might be confusing.
#declare variable
TOTAL_SENTENCES = 5
def main():
#print greeting
print ('This program will demonstrate lists')
#establish array sentences
sentenceList = list()
#prompt user for how many sentences to store (assume integer, but if
negative, set to 5)
TOTAL_SENTENCES = int(input('How many sentences? '))
if TOTAL_SENTENCES < 0:
TOTAL_SENTENCES = 5
else:
pass
#store in a list in all lower case letters (assume no period at the end)
while len(sentenceList) < TOTAL_SENTENCES:
userSentence = input('Enter a sentence: ')
sentenceList.append(userSentence.lower())
#print 5 options for the user to choose from (looping this for the total
number of sentences)
for i in range(TOTAL_SENTENCES):
print ('Enter 1 to see a sentence\n' 'Enter 2 to see the whole list\n'
'Enter 3 to change a sentence\n' 'Enter 4 to switch words\n'
'Enter 5 to count letters')
#prompt user for their choice
userChoice = int(input('Enter your choice: '))
#print their choice back to them
print ('You selected choice' ,userChoice)
#prompt for which sentence
#CHOICE-1 (pull from the list and print the sentence)
Now, in the last line of your code, if you want to pull up a sentence from the list sentenceList, you can just write:
print(sentenceList[userChoice-1])
Note that I wrote userChoice-1. This is because people usually are going to number the sentences from 1 to N. But Python's internal list numbering is from 0 to N-1.
I hope this answers your question!

Auto append list items in dictionary with default values python

I am trying to create an attendance logger where I create a dictionary which I fill with student names. The names will be lists where I append their class attendance data (whether they attended class or not). The code I have so far is displayed below`
#! /bin/python3
#add student to dict
def add_student(_dict):
student=input('Add student :')
_dict[student]=[]
return _dict
#collect outcomes
def collector(student,_dict, outcome):
_dict[student].append(outcome)
return _dict
#counts target
def count(_dict,target):
for i in _dict:
# records total attendance names
attendance_stat = len(_dict[i])
# records total instances absent
freq_of_absence=_dict[i].count(target)
# records percentage of absence
perc_absence = float((freq_of_absence/attendance_stat)*100)
print(i,'DAYS ABSENT =',freq_of_absence)
print('TOTAL DAYS: ', i, attendance_stat)
print('PERCENTAGE OF ABSENCE:', i, str(round(perc_absence, 2))+'%')
#main function
def main():
#date=input('DATE: ')
outcomes=['Y','N']
student_names = {}
try:
totalstudents = int(input('NO. OF STUDENTS: '))
except ValueError:
print('input an integer')
totalstudents = int(input('NO. OF STUDENTS: '))
while len(student_names) < totalstudents:
add_student(student_names)
print(student_names)
i = 0
while i < totalstudents:
i = i + 1
target='Y'
student=str(input('student :'))
outcome=str(input('outcome :'))
collector(student,student_names,outcome)
count(student_names,target)
if __name__=='__main__':
main()
`
The code works well so far but the problem is when the number of students is too large, time taken to input is extensive cutting in on class time. Since the number of absentees is usually less than those present, is it possible to select from the dictionary students absent which will append the value Y for each selected absent, while appending N to the remaining lists in dictionary.
This isn't exactly what you're asking for, but I think it will help. Instead of asking the user to input a name each time for the second part, why not just print the name yourself, and only ask for the outcome? Your last while loop would then become a for loop instead, like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
collector(student_name, student_names, outcome)
You could also add some logic to check if outcome is an empty string, and if so, set it to 'N'. This would just allow you to hit enter for most of the names, and only have to type in 'Y' for the certain ones that are absent. That would look like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
if outcome = "":
outcome = "N"
collector(student_name, student_names, outcome)

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

Assigning variables from inputs in FOR loop in python

For my university python course I have an assignment which asks:
Create a change-counting game that gets the user to enter the number of coins
necessary to make exactly two dollars. Design an algorithm, express it in
pseudocode, and then use it to implement a Python program that prompts the user
to enter a number of 5c coins, 10c coins, 20c coins, 50c coins, $1 coins and
$2 coins. If the total value of those coins entered is equal to two dollars,
then the program should congratulate the user for winning the game. Otherwise
the program should display a message advising that the total was NOT exactly
two dollars, and showing how much the value was above or below two dollars.
I understand how to implement the program but im having trouble trying to apply a variable to the user inputs without repetition.
I would like to use a FOR loop like so:
def main():
for coin in ['5c','10c','20c','50c','$1','$2']:
int(input("Enter the number of " + coin + " coins you wish use: "))
#Call the main function
main()
But how do I assign a new variable to each user input every time it loops?
def main():
coins = {}
for kind in ['5c','10c','20c','50c','$1','$2']:
coins[kind] = int(raw_input("Enter the number of " + kind \
+ " coins you wish use: ").strip() or 0)
The best would be a list or a dictionary.
inputFor= {}
for coin in ['5c','10c','20c','50c','$1','$2']:
inputFor[coin]= int(input("Enter the number of " + coin + " coins you wish use: "))
In the previous case, a dictionary. Then you can retrieve the user answers in the following way:
... inputFor['5c'] ...
... inputFor['10c'] ...
... inputFor['20c'] ...
... inputFor['50c'] ...
... inputFor['$1'] ...
... inputFor['$2'] ...
The dots represent the context in which you want to use the answers (formulas, display, etc).

Categories

Resources