Issues with KeyError: 0 - python

Im having issued where my code keeps saying KeyError: 0, I have searched all over and couldn't find a way to fix this
student_scores = {'0':65.0, '1':54.7}
average_score = 66.0
i = 0
for v in student_scores:
if student_scores[i] >= average_score:
above_avg_check = "{} {}".format(student_names[i], student_scores[i])
above_avg.append(above_avg_check)
print(above_avg_check)
i += 1
I am not sure on what to do, i is both a counter and the key of student_scores, so I can use it in a while loop.

You're checking an integer index while your 0 index is actually a string.
This code compiles for me on repl, just convert your index values to strings before trying to find them
student_scores = {'0':65.0, '1':54.7}
average_score = 66.0
i = 0
for v in student_scores:
if student_scores[str(i)] >= average_score:
above_avg_check = "{} {}".format(student_names[str(i)], student_scores[str(i)])
above_avg.append(above_avg_check)
print(above_avg_check)
i += 1

You can use the .items() method and get the scores in a much more simple way. The you can format your string based on the student and their score within your for loop.
student_scores = {'0': 65.0, '1': 54.7}
average_score = 65.0
i = 0
above_avg = []
for student, score in student_scores.items():
if score >= average_score:
above_average_check = '{}: {}'.format(student, score)
above_avg.append(above_average_check)
print(above_average_check)
i += 1
And here is your output:
0: 65.0
This will get you the output that you are looking for as you iterate through each key and its corresponding value.

Related

How do I separetly print two dictionary keys with the same value?

I want to print a message telling the user the most common personality type of an animal crossing villager using a dataset. However, the 'Lazy' and 'Normal' dictionary keys are both the most common and have the same value. I can't figure out how to make them print separately without hardcoding.
Here's my code:
totalfreq2 = {}
for p_type in personality:
if p_type in totalfreq2:
totalfreq2[p_type] +=1
else:
totalfreq2[p_type] = 1
print(totalfreq2)
maxfreq2 = max(totalfreq2.values())
print(maxfreq2)
toplst = ()
for p_type in totalfreq2:
if totalfreq2[p_type] == 63:
ww = p_type
print(ww)
print("The most common personality type for an Animal Crossing Villager is",ww,)
Here's the printed output:
{'Jock': 57, 'Cranky': 57, 'Peppy': 53, 'Big Sister': 26, 'Lazy': 63, 'Normal': 63, 'Snooty': 57, 'Smug': 37}
63
Normal
The most common personality type for an Animal Crossing Villager is Normal
How do I add 'Lazy' to this message without hardcoding?
Collect all the keys that have the max value, then use .join() to print them nicely:
# The missing data matching the OP's output.
personality = ['Jock'] * 57 + ['Cranky'] * 57 + ['Peppy'] * 53 + ['Big Sister'] * 26 + ['Lazy'] * 63 + ['Normal'] * 63 + ['Snooty'] * 57 + ['Smug'] * 37
totalfreq2 = {}
for p_type in personality:
if p_type in totalfreq2:
totalfreq2[p_type] +=1
else:
totalfreq2[p_type] = 1
maxfreq2 = max(totalfreq2.values())
# find all keys with same max value
toplist = [k for k,v in totalfreq2.items() if v == maxfreq2]
print(f"The most common personality type for an Animal Crossing Villager is: {', '.join(toplist)}")
Output:
The most common personality type for an Animal Crossing Villager is: Lazy, Normal
See also collections.Counter for a built-in way to count items and get the most common, for example:
import collections
...
totalfreq2 = collections.Counter(personality)
# Returns counts sorted highest to lowest and gets the first one.
# It returns [(key, count)] hence the subscripting to get the count.
maxfreq2 = totalfreq2.most_common(1)[0][1]
...
It looks like you had the right idea... just change toplist to an empty list and instead of assigning the value to the variable ww you can append the value to the list and then print the contents of the list once the loop has finished.
maxfreq2 = max(totalfreq2.values())
toplst = []
for p_type in totalfreq2:
if totalfreq2[p_type] == maxfreq2:
toplst.append(p_type)
print(toplst)
There are quite a few alternatives you could use as well.
list comprehension.
[print(i) for i in totalfreq2 if totalfreq2[i] == maxfreq2]
or you can use the filter function
for ptype in filter(lambda x: totalfreq2[x] == maxfreq2, totalfreq2.keys()):
print(ptype)

Dictionary task in Python: Elections

The first line gives the number of entries. Further, each entry contains the name of the candidate and the number of votes cast for him in one of the states. Summarize the results of the elections: for each candidate, determine the number of votes cast for him. Use dictionaries to complete the tasks.
Input:
Number of voting records (integer number), then pairs <> - <>
Output:
Print the solution of the problem.
Example:
Input:
5
McCain 10
McCain 5
Obama 9
Obama 8
McCain 1
Output:
McCain 16
Obama 17
My problem is at the step when I have to sum keys with same names but different values.
My code is:
cand_n = int(input())
count = 0
countd = 0
cand_list = []
cand_f = []
num = []
surname = []
edict = {}
while count < cand_n:
cand = input()
count += 1
cand_f = cand.split(' ')
cand_list.append(cand_f)
for k in cand_list:
for i in k:
if i.isdigit():
num.append(int(i))
else: surname.append(i)
while countd < cand_n:
edict[surname[countd]] = num[countd]
countd += 1
print(edict)
You can add the name and vote to the dictionary directly instead of using one more for() and while().
If the name does not exist in the dictionary, you add the name and vote. If the name exists in the dictionary, increase the vote.
cand_n = int(input())
count = 0
cand_list = []
cand_f = []
edict = {}
while count < cand_n:
cand = input()
count += 1
cand_f = cand.split(' ')
if cand_f[0] in edict:
edict[cand_f[0]] += int(cand_f[1])
else:
edict[cand_f[0]] = int(cand_f[1])
print(edict)

Appending a dictionary value to a list in python

I'm having trouble appending the student dictionary value that coincides with key 'id' to a list. Any help is much appreciated!
students = list();
students.append( {'id':12345, 'first_name':'Alice',
'last_name':'Anderson','assignments':[('assignment_1',0),('assignment_2',2),
('assignment_3',3)]})
students.append({'id':22345, 'first_name':'John',
'last_name':'Sparks','assignments':[('assignment_1',2),('assignment_2',3),
('assignment_3',4)]})
students.append({'id':32345, 'first_name':'Taylor',
'last_name':'Mason','assignments':[('assignment_1',3),('assignment_2',2),
('assignment_3',3)]})
def return_passing(students):
grade_sum = 0
counter = 0
for s in students: #loop thru students
for assignment, grade in s['assignments']:
grade_sum += grade
counter += 1
average = grade_sum / counter
lst = list()
if average >= 2.0:
lst.append((s['id']))
return lst
return_passing(students)
print(return_passing(students))
You have several issues with initializing things at the wrong place, so they get reset. Explanations for those are in the comments:
def return_passing(students):
lst = [] # initialize lst here
for s in students: #loop thru students
grade_sum = 0 # reset these for each student
counter = 0
for assignment, grade in s['assignments']:
grade_sum += grade
counter += 1
# now that we have gone throug all assignments
# compute average
average = float(grade_sum) / counter # convert to float for precision
if average >= 2.0:
lst.append(s['id'])
return lst # return only after you've gone through all students

How can I get the average of a range of inputs?

I have to create a program that shows the arithmetic mean of a list of variables. There are supposed to be 50 grades.
I'm pretty much stuck. Right now I´ve only got:
for c in range (0,50):
grade = ("What is the grade?")
Also, how could I print the count of grades that are below 50?
Any help is appreciated.
If you don't mind using numpy this is ridiculously easy:
import numpy as np
print np.mean(grades)
Or if you'd rather not import anything,
print float(sum(grades))/len(grades)
To get the number of grades below 50, assuming you have them all in a list, you could do:
grades2 = [x for x in grades if x < 50]
print len(grades2)
Assuming you have a list with all the grades.
avg = sum(gradeList)/len(gradeList)
This is actually faster than numpy.mean().
To find the number of grades less than 50 you can put it in a loop with a conditional statement.
numPoorGrades = 0
for g in grades:
if g < 50:
numPoorGrades += 1
You could also write this a little more compactly using a list comprehension.
numPoorGrades = len([g for g in grades if g < 50])
First of all, assuming grades is a list containing the grades, you would want to iterate over the grades list, and not iterate over range(0,50).
Second, in every iteration you can use a variable to count how many grades you have seen so far, and another variable that sums all the grades so far. Something like that:
num_grades = 0
sum_grades = 0
for grade in grades:
num_grades += 1 # this is the same as writing num_grades = num_grades + 1
sum_grades += sum # same as writing sum_grades = sum_grades + sum
Now all you need to do is to divide sum_grades by num_grades to get the result.
average = float(sum_grade)s / max(num_grades,1)
I used the max function that returns the maximum number between num_grades and 1 - in case the list of grades is empty, num_grades will be 0 and division by 0 is undefined.
I used float to get a fraction.
To count the number of grades lower than 50, you can add another variable num_failed and initialize him to 0 just like num_counts, add an if that check if grade is lower than 50 and if so increase num_failed by 1.
Try the following. Function isNumber tries to convert the input, which is read as a string, to a float, which I believe convers the integer range too and is the floating-point type in Python 3, which is the version I'm using. The try...except block is similar in a way to the try...catch statement found in other programming languages.
#Checks whether the value is a valid number:
def isNumber( value ):
try:
float( value )
return True
except:
return False
#Variables initialization:
numberOfGradesBelow50 = 0
sumOfAllGrades = 0
#Input:
for c in range( 0, 5 ):
currentGradeAsString = input( "What is the grade? " )
while not isNumber( currentGradeAsString ):
currentGradeAsString = input( "Invalid value. What is the grade? " )
currentGradeAsFloat = float( currentGradeAsString )
sumOfAllGrades += currentGradeAsFloat
if currentGradeAsFloat < 50.0:
numberOfGradesBelow50 += 1
#Displays results:
print( "The average is " + str( sumOfAllGrades / 5 ) + "." )
print( "You entered " + str( numberOfGradesBelow50 ) + " grades below 50." )

How to make a table with 3 data sets?

I've been going at this for a while but I'm not quite sure how to tackle it. I have three data sets- scores (A-F, counts the number of grades in each rank), count (the program prints a table of count by rank), and Percentage (dividing the count by the total in the data set to get the percentage in each rank).
The end result should look similar to this given 7 grades (integers).
(example user inputted data: [88, 76, 89, 78, 74, 87, 95])
>>> GRADE COUNT PERCENTAGE
>>> A 2 28.6%
>>> B 2 28.6%
>>> C 3 42.9%
>>> D 0 0%
>>> F 0 0%
Currently, this is my long, tedious, elementary code. I'm having a hard time with executing and making it work correctly and I probably am not making it work properly at all.
def grade_scores(scoreList):
for score in scoreList: #shows the scores in the score list, uses ddata from previous function
if score >= 91:
Ascore = 'A'
Acount +=1
sum(Ascore) / Acount len(scoreList) = Apercentage
elif score >= 81 and score <=90:
Bscore = 'B'
Bcount +=1
sum(Bscore) / Bcount len(scoreList) = Bpercentage
elif score >= 71 and score <=80:
Cscore = 'C'
Ccount +=1
sum(Cscore) / Ccount len(scoreList) = Cpercentage
elif score >= 61 and score <=70:
Dscore = 'D'
Dcount +=1
sum(Dscore) / Dcount len(scoreList) = Dpercentage
else:
Fscore = 'F'
Fcount +=1
sum(Dscore) / Dcount len(scoreList) = Dpercentage
for i in range(scoreList):
print ('Grade', '\t', 'Count', '\t', 'Percentage')
print(Ascore, end="\t", Acount, end="\t", Apercentage)
print(Bscore, end="\t", Bcount, end="\t", Bpercentage)
print(Cscore, end="\t", Ccount, end="\t", Cpercentage)
print(Dscore, end="\t", Dcount, end="\t", Dpercentage)
print(Fscore, end="\t", Fcount, end="\t", Fpercentage)
I would hope to make it more of a grid style instead but I don't think it is formatted correctly and does not seem to work properly ( I also get an error about "len" in the 6th line). I appreciate any input on this.
Not completely sure what you meant by the question, but first, the error message is most likely caused by a TypeError, because you are using the variable scoreList in the range() function (which takes in integers, and integers have no length).
Also you may want to consider to utilize lists to organize the data better.
For the grid style, you should use the .format() method to help you with printing the lines:
# Assuming you have 3 lists:
# grade = ['A','B','C','D','E']
# count = [2, 2, 3, 0, 0] Have another function capture user input
# and convert it into this list.
# percentage = [28.6, 28.6, 42.9, 0, 0] Same as above ^
print("SCORE COUNT PERCENTAGE")
for i in range(len(grade)):
print(" {} {} {} %".format(grade[i], count[i], percentage[i]))
For the elif conditionals, you would have to stick with what you already have. However, you may want to modify the variable names a bit, as a better way to do this is through lists:
for i in range(len(gradeInputList)):
if grade >= 90:
count[0] += 1 # Increase index 0 (Corresponds to value A) by 1
elif grade >= 80 and < 90:
count[1] += 1
# Omitted code here, you get the idea
# ...
else:
count[4] += 1
And at the end you could have another for loop that calculates the average:
for i in range(len(count)):
average[i] = count[i] / sum(count) * 100 # Calculates the percentage
Whew, hope this helped! :)
If you want to print something in grid format then use tabulate package. It is easy and convinient . Here is sample code :
from tabulate import tabulate
table = [["spam",42],["eggs",451],["bacon",0]]
headers = ["item", "qty"]
print tabulate(table, headers, tablefmt="grid")
This prints :
+--------+-------+
| item | qty |
+========+=======+
| spam | 42 |
+--------+-------+
| eggs | 451 |
+--------+-------+
| bacon | 0 |
+--------+-------+

Categories

Resources