How to fix printing of score values? - python

This program should display:
Here are your grades
Math score is 100
Science score is 90
Reading score is 70
Average grade score is 86.66
However with the code I have, it is displaying this:
Here are your grades:
Math score is 100.0
Sciencee score is 95.0
Reading score is 86.66666666666667
The average score is 86.66666666666667
So basically the average is correct but now the scores are not.
gradesFile = open("grades.txt","r")
#Establishes the variables
total = 0
numberOfLines = 0
lines = 0
print('Here are your grades:','\n')
# Creates a loop that will print out each score, until there aren't anymore
# scores to read. For example:
#Math score is 100
#Science score is 90
#and so on.
for line in gradesFile:
numberOfLines += 1
lines = line.strip()
total += float(gradesFile.readline())
score = total / numberOfLines
print(lines + ' score is', score)
gradesFile.close
average = float(total) / (numberOfLines)
print('The average score is', average)
The grades.txt file looks like this:
Math
100.0
Science
90.0
Reading
70.0

Your score is essentially a rolling average. There's no need for that, just print it directly:
for line in gradesFile:
numberOfLines += 1
lines = line.strip()
score = float(gradesFile.readline())
total += score
print(lines + ' score is', score)

Related

Ignoring a specific letter grade when calculating average student grade

I'm trying to calculate the average of the numeric grade for students who take [0]=14224. But how do I tell my program to ignore any grades with a 'W'?
import sys
import csv
def findnumericgrade(grade):
if grade == 'A':
return 4.0
elif grade == 'B':
return 3.0
else:
return 2.0
def loaddata(filename, course):
count = 0
total = 0.0
with open(filename, 'r') as f:
lines = csv.reader(f)
next(lines)
for row in lines:
if course in row[0]:
get_grade = findnumericgrade(row[3])
total += float(get_grade)
count += 1
avg = total / count
print(f"The {course} average is: {round(avg, 2)}")
loaddata('studentdata.csv', sys.argv[1])
#example of studentdata.csv:
There are certainly a number of ways. The easiest approach is probably just to check for the 'W' string and continue to the next row.
One approach to doing this is to use the continue control to move on to the next iteration in the loop.
def loaddata(filename, course):
count = 0
total = 0.0
with open(filename, 'r') as f:
lines = csv.reader(f)
next(lines)
for row in lines:
if row[3] == 'W':
continue # Go to next iteration in loop
if course in row[0]:
get_grade = findnumericgrade(row[3])
total += float(get_grade)
count += 1
avg = total / count
print(f"The {course} average is: {round(avg, 2)}")
You can also do this by making your if statement the and boolean operation to also ensure that Course_Grade is not 'W'.
def loaddata(filename, course):
count = 0
total = 0.0
with open(filename, 'r') as f:
lines = csv.reader(f)
next(lines)
for row in lines:
if course in row[0] and row[3] != 'W':
get_grade = findnumericgrade(row[3])
total += float(get_grade)
count += 1
avg = total / count
print(f"The {course} average is: {round(avg, 2)}")
The above solutions are probably most practical, since this looks like some sort of utility script, but depending on how large you expect your dataset to be, you could use something like pandas. Then you'd have access to all of the data manipulation and analysis tools it offers.
import sys
import pandas as pd
def find_numeric_grade(grade):
if grade == 'A':
return 4.0
elif grade == 'B':
return 3.0
else:
return 2.0
df = pd.read_csv('studentdata.csv')
section_number = int(sys.argv[1])
print(df[(section_number == df['Section_Number']) & (df['Course_Grade'] != 'W')]
['Course_Grade'].apply(find_numeric_grade).mean())
*Solutions tested with the following data in studentdata.csv
Section_Number,Prof_ID,Student_ID,Course_Grade,Student_Name,Course_ID
14224,5,109,B,John Smith,IT1130
14224,5,110,B,Jennifer Johnson,IT1130
14224,5,111,W,Kristen Hawkins,IT1130
14224,5,112,A,Tom Brady,IT1130
14224,5,113,C,Cam Newton,IT1130
14224,5,114,C,Tim Tebow,IT1130
14225,5,115,A,Peyton Manning,IT1130
14225,5,116,B,Maria Sharapova,IT1130
14225,5,117,W,Brian McCoy,IT1130
if course in row[0]:
if row[3]!='W':
get_grade = findnumericgrade(row[3])
total += float(get_grade)
count += 1
avg = total / count

calculate avg from an input that is a string

I have a string that looks like the following
s = """nate : 9.5 ,8 ,5 ,8.7
moe : 7 ,6.8 , - ,1
sam : 6 ,4 , ,7.6
cat : 8 ,8.6 ,6 ,2"""
for the dash (- ) it should just be removed completely for ex: 6.8, - , 1 should become 6.8,1
for the blank parts, it should have 0 instead for ex 4, , 7.6 should become 4, 0 , 7.6
after that is all done I want to calculate the average of each person and display it as a dictionary
this what I have come up with and I couldn't manage to go any further
def avg(s):
s = s.replace(" - ,", ""). replace(", ,", ", 0 ,")
s= s.strip().splitlines()
students={}
for i in s:
s = i.strip().split(":")
students[s[0]]= s[1].strip().split(",")
Loop through the scores, skipping -, replacing empty strings with 0, and converting the rest to floats. Then calculate the average by dividing by the length, and store that in the students dictionary.
It's easier to replace individual list elements than replacing in the original lines, since your spacing is inconsistent.
def avg(s):
s= s.strip().splitlines()
students={}
for i in s:
s = i.split(":")
student = s[0].strip()
scores = [x.strip() for x in s[1].split(",")]
scores = [float(score) if score else 0 for score in scores if score != "-"]
students[student] = sum(scores) / len(scores) if scores else 0
# split s into lines and iterate over each line
for line in s.splitlines():
# init num_scores and total to zero for this student
num_scores = 0
total = 0.0
# get the name and the scores
name, scores = line.split(" : ")
# split scores on commas and iterate over each score
for score in scores.split(","):
# remove whitespace
score = score.strip()
# if we have something and it's not a dash
if score and score != "-":
num_scores += 1
total += float(score)
# print this student's name and average
print(f"{name}: average score {total/num_scores}")

Finding two specific substrings and adding them to a counter, then printing out the counter

I have an infile that contains fake coronavirus results (sex, age, height, weight, test results, zipcode)
I am trying to retrieve the amount of positive female and male cases and output it to a printline.
I am new to programming and i've tried for so long to get it to work but no luck, this is my current code
sample infile
M 87 66 133 - 33634
M 17 77 119 - 33625
M 63 57 230 - 33603
F 55 50 249 - 33646
M 45 51 204 - 33675
males = 0
females = 0
positivem = 0
positivef = 0
with open("/Users/newuser/Desktop/hw1data.txt", 'r') as f:
for line in f.readlines():
words = line.lower().split()
for word in words:
if (word == "m"):
males += 1
elif (word == 'f'):
females += 1
else:
males = males
females = females
for word in words:
if ((word == 'm') and (word == '+')):
positivem += 1
elif ((word == 'f') and (word == '+')):
positivef += 1
else:
positivem = positivem
positivef = positivef
print("{0} males have been tested and {1} females have been tested.".format(males,females))
print("Of those {0} males, {1} have tested positive.".format(males, positivem))
print("Of those {0} females, {1} have tested positive.".format(females, positive
I have modified your code a bit. You need to learn the basics of if...else statements.
Since the data occurs at a specific index in the list "words", you can directly use the indices to fetch them, you do not need to loop through the entire list.
Let me know if this code has any errors.
males = females = positivef = positivem = 0
with open("/Users/newuser/Desktop/hw1data.txt", 'r') as f:
for line in f.readlines():
words = line.lower().split()
if words[0]=='M':
males+=1
if words[4]=='+':
positivem+=1
else:
females+=1
if words[4]=='+':
positivef+=1
print("{0} males have been tested and {1} females have been tested.".format(males,females))
print("Of those {0} males, {1} have tested positive.".format(males, positivem))
print("Of those {0} females, {1} have tested positive.".format(females, positivef))

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

python 3.x overwrite previous terminal line

I wrote a simple program to calculate average outcome of a dice throw (pretty pointless, but you have to start somewhere ;P):
import random, time
from random import randrange
count = 0
total = 0
one_count = 0
for x in range(10000000):
random = randrange(1,7)
count = count + 1
total = total + random
average = total / count
percentage = one_count / count * 100
if random == 1:
one_count = one_count + 1
print("the percentage of ones occurring is", percentage, "and the average outcome is", average)
# time.sleep(1)
To clean it up I want the output to overwrite the previous line. I tried everything I could find, but the only thing I managed to to is to print to the same line without erasing the previous content by changing the last line to:
print("the percentage of ones occuring is", percentage, "and the average outcome is", average, "/// ", end="")
which outputs:
the percentage of ones occuring is 0.0 and the average outcome is 4.0 /// the percentage of ones occuring is 0.0 and the average outcome is 4.5 /// the percentage of ones occuring is 0.0 and the average outcome is 3.6666666666666665 ///
Any ideas?
Add a \r at the end. That way, the next line you write will start at the beginning of the previous line. And then flush output so it shows immediately.
Note: If the next line is shorter, the remaining characters will still be there.
use end='\r:
for x in range(100000):
rnd = randrange(1,7) # don't use random
count += 1
total = total + rnd
average = total / count
percentage = one_count / count * 100
if rnd == 1:
one_count += 1
print("the percentage of ones occurring is {} and the average outcome is {}".format(percentage,average),end='\r')
time.sleep(.1)
On another note using total = total + random is not a good idea, you are importing the random module and using random as a variable name.

Categories

Resources