Calculating average of specific dict key values Python 3.7.4 - python-3.x

I am trying to calculate the overall average for my grades dict. Subject level and subject code does not matter.These are my dicts and lists.
grades = {'INFO100' : 'C','INFO102' : 'B', \
'INFO125' : 'B','INFO132' : 'A', \
'INFO180' : '' ,'INFO216' : 'A', \
'INFO282' : 'C','INFO284' : '' , \
'ECON100' : 'C','ECON110' : 'C', \
'ECON218' : '' , 'GEO100' : '' , \
'GEO113' : 'D', 'GEO124' : 'D',}
subjects = ['INFO100','INFO102','INFO125',\
'INFO132','INFO180','INFO216',\
'INFO282','INFO284','ECON100',\
'ECON110','ECON218','GEO100' ,\
'GEO113' ,'GEO124']
subject_code = {'Informatics' : 'INFO',\
'Economy' : 'ECON',\
'Geografi' : 'GEO'}
This is what i have. Not sure where and how to iterate from here on.
convert_grade = {"A": 5, "B": 4, "C": 3, "D": 2, "E": 1, "F": 0}
convert_grade.update({v: k for k,v in convert_grade.items()})
grade_sum = sum(['convert_grade['something'] for 'something' in 'something if 'something' is not None])
average_grade = round(grade_sum / len(['something' for 'something' in 'something' if 'something' is not None]))
print("Average grade:", convert_grade[average_grade])
I got help constructing the way to calculate(i think at least, might be a too fancy way) but i don't really know where to iterate from there. I am fairly new to python so i am still learning how to iterate properly. Any help or guidance is more than welcome. I do not need "my" way of calculation to work, i just need help in the right direction.

grades = {'INFO100' : 'C','INFO102' : 'B',
'INFO125' : 'B','INFO132' : 'A',
'INFO180' : '' ,'INFO216' : 'A',
'INFO282' : 'C','INFO284' : '' ,
'ECON100' : 'C','ECON110' : 'C',
'ECON218' : '' , 'GEO100' : '' ,
'GEO113' : 'D', 'GEO124' : 'D',}
total = 0
count = 0
for k, v in grades.items():
if(v == "A"):
total += 5
elif(v == "B"):
total += 4
elif(v == "C"):
total += 3
elif(v == "D"):
total += 2
elif(v == "E"):
total += 1
else:
total += 0
count += 1
print(total / count)
Yields: 2.4285714285714284
Which is the average of those grades (assuming that blanks count, if you don't want them to count, we can filter them out)

I don't understand why you are adding the reverse relation to the dict with that convert_grade.update line. If you're going to need that (you don't, at least for this specific task), you should have two dictionaries. One for the letter grade -> score mapping and one for score -> letter grade. You should also rename it from convert_grade to grade_to_score or something more descriptive.
First, if '' means that you haven't taken the class yet and it shouldn't be counted as part of your average, you have to filter them out first. You were on the right track but don't check for None check for the empty string, which you do by just treating the string as a boolean, if it's an empty string it won't evaluate to true:
grades = {course: grade for course, grade in grades.items() if grade}
Then you need to convert the letter grades to a list of numbers using a dictionary, and then you can find the average of that list using either sum(x) / len(x) or statistics.mean:
from statistics import mean
grade_to_score = {"A": 5, "B": 4, "C": 3, "D": 2, "E": 1, "F": 0}
average_grade = mean(grade_to_score[grade] for grade in grades.values())
print("Average grade:", average_grade)
If a '' means that you got an F, you can skip the first step and just add an extra '': 0 part to your definition of grades_to_score.
If you want to get averages by course, just filter the dictionary right after the first step
info_grades = {course: grade for course, grade in grades.items() if course.startswith('INFO')}
and then you can pass info_grades.values() instead of grades.values() to statistics.mean() to get the average of all your Informatics courses. If you want to do every one, have a for loop over ['INFO', 'ECON', 'GEO'].

Related

How do I count the amount of 'edges' in a word in Python, using a dictionary?

For this exercise I need to count the 'number of edges' in the word 'AARDGASRESERVES' (Dutch), using a for loop and a dictionary. I already have the following code, but this doesn't give me the required output (which should be 31). I believe the middle part isn't quite right yet.
# dictionary of number of edges per letter
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
# loop over the letters in the word and count the number of edges
total_edges = 0
for key in edges:
if edges[key] == word:
total_edges += [value]
# print the total
print("Total number of edges:", total_edges)
I tried if edges[key] in word: too but that results in an error. I'm still new to Python so I might have written something that isn't even possible.
A simple way to do what you want is:
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
total_edges = sum([edges[c] for c in word])
# print the total
print("Total number of edges:", total_edges) # Output: 31
However, I advise you to carefully examine your code to understand why it doesn't work. For example here:
...
if edges[key] == word:
...
you compare if a number (value of your dict) is equal to the whole word, which is an irrational if-statement.
From what I understand about the purpose of this code. It should go about this
# dictionary of number of edges per letter
edges = {"A": 2, "R": 2, "D": 0,"G": 2,"S": 2,"R": 2,"E": 3, "V": 2}
word = "AARDGASRESERVES"
# loop over the letters in the word and count the number of edges
total_edges = 0
for key in word:
total_edges += edges[key]
# print the total
print("Total number of edges:", total_edges)
What you want to do is to get a letter from the word and get the specific element associated with that key and add it.

How do I find character frequency form text file through iteration? (python3)

I'm trying to find a way to iterate through a text file and list to find character frequency. I understand that I could use Count() for this. But Count() gives everything including spaces periods and whatnots. Also it does not show the character frequency in alphabetical order. I found a way to do it and it works but not really. I'll explain later. Also when I try to put the frequency I get a KeyError. I'll also explain.
I don't want to put my whole project on here so I'll explain some stuff first. I have a separate list called alphabet_list which includes the alphabet. There's a text file that is already read through and converted into uppercase called new_text.
Character frequency Code:
for i in range(len(alphabet_list)):
for c in new_text:
if c == alphabet_list[i]:
count += 1
else:
count = 0
print(alphbet_list[i] + " " + str(count)
i += 1
Output
A 0
A 0
.
.
.
A 1
A 0
.
.
.
B 0
.
.
.
B 1
B 2
B 0
.
.
.
Z 0
P.S the str(count) is temporarily there because I want to see how it looks like print out, I needed to store the result in dictionary
My output would be that, like I said it works but not really. It will iterate but it iterates through every letter and prints out the result already and does not iterate the whole text file and just print final result. It will add to the result if there is another letter same as before right next to each other. Ex (... bb...) it will be B 1, B 2 like shown in my output. And for some reason when I use return it doesn't work. It returns nothing and just ends the program.
Second Code with KeyError:
I skipped the problem on top because I couldn't find the answer and didn't want to waste my time but ran into another problem lol*
for i in range(len(alphabet_list)):
for c in new_text:
if c == alphabet_list[i]:
count += 1
else:
count = 0
c_freq[alphabet_list[i]] == count
print(c_freq)
i += 1
This one was pretty simple I got a KeyError: 'A'.
I tried only doing the
i = 3 #just random number to test
count = 50
c_freq[alphabet_list[i]] == count
print(c_freq)
and it works, so I'm thinking that problem is also related to the problem above(? maybe). Anyways any help would be great. Thanks!
Sorry for long question but I really needed help.
This should help you:
lst = ['A', 'Z', 'H', 'A', 'B', 'N', 'H', 'Y', '.' , ',','Z'] #Initial list. Note: The list also includes characters such as commas and full stops.
alpha_dict = {}
for ch in lst:
if ch.isalpha(): #Checks if the character is an alphabet
if ch in alpha_dict.keys():
alpha_dict[ch] += 1 #If key already exists, value is incremented by 1
else:
alpha_dict[ch] = 1 #If key does not exist, a new key is created with value 1
print(alpha_dict)
Output:
{'A': 2, 'Z': 2, 'H': 2, 'B': 1, 'N': 1, 'Y': 1}
Since you want the output to be sorted in alphabetical order, add these lines to your code:
key_list = list(alpha_dict.keys()) #Creates a list of all the keys in the dict
key_list.sort() #Sorts the list in alphabetical order
final_dict = {}
for key in key_list:
final_dict[key] = alpha_dict[key]
print(final_dict)
Output:
{'A': 2, 'B': 1, 'H': 2, 'N': 1, 'Y': 1, 'Z': 2}
Thus, here is the final code:
lst = ['A', 'Z', 'H', 'A', 'B', 'N', 'H', 'Y', '.' , ',','Z']
alpha_dict = {}
for ch in lst:
if ch.isalpha():
if ch in alpha_dict.keys():
alpha_dict[ch] += 1
else:
alpha_dict[ch] = 1
key_list = list(alpha_dict.keys())
key_list.sort()
final_dict = {}
for key in key_list:
final_dict[key] = alpha_dict[key]
print(final_dict)
Output:
{'A': 2, 'B': 1, 'H': 2, 'N': 1, 'Y': 1, 'Z': 2}

Mathematical operation on a dictionary list (Python 3.6)

I am using Python 3.6 and I have a list of dictionaries like this:
list = [{'name': 'A', 'number':'1'}, {'name': 'B', 'number':'2'}, {'name': 'C', 'number':'3'}, {'name': 'D', 'number':'4'}]
I found out how to print the list in the desired format with:
for s in list:
name = s['name']
number = s['number']
print(name + " = "+ number)
Which gives:
A = 1
B = 2
C = 3
D = 4
I would like to be able to multiply the items 'number' by 2 for example and display:
A = 2
B = 4
C = 6
D = 8
Thank you!
Are you trying to temporarily multiply the values and print them out? Which in this case, you would change your last line to
print(name + " = "+ int(number) * 2)
However, if you want to multiply the values in your dictionary directly, you would go about it as so:
for s in list:
name = s['name']
s['number'] = str(int(s['number']) * 2) # multiply value by 2
number = s['number']
print(name + " = "+ number)
Note that your problem may arise from the fact that your dictionary values are stored as strings instead of integers, which means that to perform any kind of mathematical operation on them, you must convert them to an integer and back to a string.
You're able to multiply a number by using the * symbol 2 * 2 will output 4.
Because your values are stored as Strings you'll need to convert them to Integers first. int('2') * 2 == 4.
Then to print an Integer with a string you need to convert it back to a string.
for the last line change it to
print(name + " = "+ str(int(number)*2))
You can always iterate over your list to modify the value of its nested parts, i.e.:
your_list = [{'name': 'A', 'number': '1'},
{'name': 'B', 'number': '2'},
{'name': 'C', 'number': '3'},
{'name': 'D', 'number': '4'}]
for item in your_list: # iterate over each dictionary in your_list
# since your dict contains strings we have to convert the value into a number/integer
# before multiplying it by 2
item["number"] = int(item["number"]) * 2 # turn it back to a string with str() if needed
# now, let's demonstrate that the data changed in `your_list`:
for item in your_list: # iterate over each dictionary in your_list
print("{} = {}".format(item["name"], item["number"])) # print in your desired format
# A = 2
# B = 4
# C = 6
# D = 8

Python - match dictionary value within string & print key in string order

I asked a similar question to this earlier on but Im still having a hard time figuring this out. I have the following code:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '401'}
string = '401203010'
text = ''
for i, j in d.items():
if j in string:
text += i
print(text) #prints karp
desired output: park
the output I get is karp, however I would like the output to be in order of value match in the string, Thanks!
try this maybe?
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
keylen = len(''.join(d.keys()))
while len(text) != keylen:
found_val = 0
for i, j in d.items():
jl = len(j)
if string[:jl] == j:
text += i
string = string[jl:]
found_val += 1
if found_val == 0:
break
print(text)
for the sake of clarity, this is really not an algorithm you want to use here. For example one of the downfalls is if it isn't guaranteed that a part of the string will be in the dictionary values then the loop will never end. I don't want to spend the mental resources to fix that potential pitfall because I have some reading to do but perhaps you can figure out a way around it.
edit, never mind that wasn't that difficult but you should test various edge cases.
You could first split up string into substrings of 2, and then switch the keys ad values of d in a temporary dictionary, then just add the values from that:
d = {'k' : '10', 'a' : '20', 'r' : '30', 'p' : '40'}
string = '40203010'
text = ''
split_string = [string[i:i+2] for i in range(0, len(string), 2)]
# ['40', '20', '30', '10']
new_dict = dict((y,x) for x,y in d.items())
# {'30': 'r', '10': 'k', '20': 'a', '40': 'p'}
text = "".join(new_dict[string] for string in split_string)
print(text)
# park

How to get value for each string index matching key in dictionary in Python

str = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
How can I get each letter in the string assigned to the value in the dictionary by match 'letter-key' and then summarize the values?
Thanks
s = 'strings' #Don't name a variable str, that shadows the builtin str
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = sum([newD.get(k,0) for k in s]) #assuming 0 as default for "not in dictionary"
This takes advantage of the fact that:
Strings are iterable. for i in s: print(i) would print each character, seperately.
Dictionaries have a .get(key[,default]) 1 that can take an option argument for "return this value if the key doesn't exist.
I'm using the built-in sum on a list comprehension for the sake of brevity. Brevity can both be a virtue or a vice, but, hey, one list comp is still usually pretty readable after you know what they are.
string = 'strings'
new_D = {'r': 1, 's': 1, 't': 1, 'r' : 3, 'i' : 4 }
sum_of_chars = 0
for character in string:
if character in new_D:
sum_of_chars += new_D[character]
else:
sum_of_chars += 1 # Default?
print(sum_of_chars)
btw, you should not use the name str because it shadows the builtin str and there's a mistake in your dictionary. It contains the entry r two times which doesn't make sense.

Resources