I have code that will take a legend of grades, and number of grades and then return values for it. I have everything right except for the semester average. Here's the formula to finding semester average:
homework average * 0.2 + quiz average * 0.2 + project average * 0.6.
My code works well with homework averages, quiz averages, and project averages but not with semester average.
Here's what I have written:
def get_header():
gb_data = open('gb_data.txt','r')
header = gb_data.readline()
return header.strip()
def get_content():
gb_data = open('gb_data.txt','r')
content = gb_data.readlines()
del content[0]
return content
hw_pos = []
project_pos = []
quiz_pos = []
header_list = get_header()
header_list = header_list.split(", ")
header_list_index = enumerate(header_list)
for index, target in header_list_index:
if target == "hw":
hw_pos.append(index)
elif target == "quiz":
quiz_pos.append(index)
elif target == "project":
project_pos.append(index)
content_list = get_content()
avg_dict = {}
for element in content_list:
element = element.strip().split(", ")
name = element[0] + ', ' + element[1]
hw_avg = sum([int(element[i]) for i in hw_pos]) / len(hw_pos)
quiz_avg = sum([int(element[i]) for i in quiz_pos]) / len(quiz_pos)
project_avg = sum([int(element[i]) for i in project_pos]) / len(project_pos)
sem_avg = hw_avg * 0.2 + quiz_avg * 0.2 + project_avg * 0.6
avg_dict.update({name:(hw_avg, quiz_avg, project_avg, sem_avg)})
f = open('avg.txt', 'w')
for name, avg in avg_dict.items():
dataline = name + ": hw avg = " + str(round(avg[0], 2)) + ", quiz avg = " + str(round(avg[2], 2)) + ", proj avg = " + str(round(avg[1], 2)) + ", sem avg = " + str(round(avg[2], 2)) + "\n"
f.write(dataline)
f.close()
Here's an example of an input I put in:
last, first, hw, hw, project, quiz, hw, hw, hw, quiz, hw, hw, project
Cat, Figaro, 57, 58, 71, 93, 56, 86, 90, 99, 55, 99, 88
The top line is the legend so ignore that, my code handles that
Here's what should be given back:
Cat, Figaro: hw avg = 71.57, quiz avg = 96.0, proj avg = 79.5, sem avg = 81.21
Here's what I actually get back:
Cat, Figaro: hw avg = 71.57, quiz avg = 96.0, proj avg = 79.5, sem avg = 96.0
I want to make them match EXACTLY, down to every character. I just need to know how to round it correctly. This is NOT homework and is just a project to understand files better, I'm very close!! My name is Scarlett btw please help!!!
You have a typo this line:
dataline = name + ": hw avg = " + str(round(avg[0], 2)) + ", quiz avg = " + str(round(avg[2], 2)) + ", proj avg = " + str(round(avg[1], 2)) + ", sem avg = " + str(round(avg[2], 2)) + "\n"
It should be
dataline = name + ": hw avg = " + str(round(avg[0], 2)) + ", quiz avg = " + str(round(avg[1], 2)) + ", proj avg = " + str(round(avg[2], 2)) + ", sem avg = " + str(round(avg[3], 2)) + "\n"
instead. The calculation is fine, just the output was messed up (You printed 0, 2, 1, 2 instead of 0, 1, 2, 3). To prevent mistakes like this in the future, maybe take a look at Pandas with its column names? Pandas is probably an overkill in this case, but a very powerful tool for table-based calculations.
This should work:
from statistics import mean
legend = ['last', 'first', 'hw', 'hw', 'project', 'quiz', 'hw', 'hw', 'hw', 'quiz', 'hw', 'hw', 'project']
grades = ['Cat', 'Figaro', 57, 58, 71, 93, 56, 86, 90, 99, 55, 99, 88]
hw_avg = mean([g for l, g in zip(legend, grades) if l == 'hw'])
quiz_avg = mean([g for l, g in zip(legend, grades) if l == 'quiz'])
project_avg = mean([g for l, g in zip(legend, grades) if l == 'project'])
sem_avg = hw_avg * 0.2 + quiz_avg * 0.2 + project_avg * 0.6
print(f'{grades[0]}, {grades[1]}: hw avg = {hw_avg:.2f}, quiz avg = {quiz_avg:.2f}, project avg = {project_avg:.2f}, sem avg = {sem_avg:.2f}')
It gives me the following:
Cat, Figaro: hw avg = 71.57, quiz avg = 96.00, project avg = 79.50, sem avg = 81.21
Note that I'm just using statistics.mean as it makes the code cleaner. But you could do the same with a method like yours.
Related
I am trying to store the values obtained from excel sheet cells to a list. The code provided basically collects data from different continuous rows and columns and creates a string of those values. I could work upt o storing the string value but I don't really know how to store the strings in a list, Can anyone help me with this?
for i in range(NR):
print("This TC checks the output for")
for j in range(NC):
inputVariable = str(ws[get_column_letter(ColumnStart+j) + str(rowStart-1)].value)
c = str((ws.cell(row = (rowStart + i),column = (ColumnStart +j)).value))
if (ws.cell(row = (rowStart + i),column = (ColumnStart+j)).value) == (ws.cell(row = (MaxValRow),column = (ColumnStart+j)).value):
b = '(maximum)'
elif (ws.cell(row = (rowStart + i),column = (ColumnStart+j)).value) == (ws.cell(row = (MinValRow),column = (ColumnStart+j)).value):
b = '(minimum)'
else:
b ='(intermediate)'
Commentstr = str(j+1) + '. The value of input ' + inputVariable + ' =' + " " + c + b
# need to create a list here to store the commentstr for each iteration
NR = no. of rows, NC = no. of columns
my_list=[]
for i in range(NR):
x=0
print("This TC checks the output for")
for j in range(NC):
inputVariable = str(ws[get_column_letter(ColumnStart+j) + str(rowStart-1)].value)
c = str((ws.cell(row = (rowStart + i),column = (ColumnStart +j)).value))
if (ws.cell(row = (rowStart + i),column = (ColumnStart+j)).value) == (ws.cell(row = (MaxValRow),column = (ColumnStart+j)).value):
b = '(maximum)'
elif (ws.cell(row = (rowStart + i),column = (ColumnStart+j)).value) == (ws.cell(row = (MinValRow),column = (ColumnStart+j)).value):
b = '(minimum)'
else:
b ='(intermediate)'
Commentstr = str(j+1) + '. The value of input ' + inputVariable + ' =' + " " + c + b
my_list[x]=Commentstr
x+=1
I want to write code that will take a file of grades and return an average of it all, so homework average, project average, quiz average, and semester average. In the file it would have a column at the start which would be the "legend" to the code. Here's an example of what the grade file would look like:
last, first, hw, hw, project, quiz, hw, hw, hw, quiz, hw, hw, project
#It won't also be in this order, that's what makes this hard!
Cat, Figaro, 57, 58, 71, 93, 56, 86, 90, 99, 55, 99, 88
#Not a real name lol, there would also be A LOT more names and grades
I can't figure out how to make it iterate through the legend column and the grades column to correctly grade the file. Here's the formula for grading:
semester average = homework average * 0.2 + quiz average * 0.2 + project average * 0.6.
Here's what I have so far. I'm terrible with files so I only know how to call a column.
def start():
gb_data = open('gb_data.txt','r')
header = gb_data.readline()
print(header.strip())
the strip() at the end would get rid of the \n that happens when you change lines. This prints the first column of the file but I want to iterate through it and identify the legend, not just print it. Here's what the return file would look like:
Cat, Figaro: hw avg = 71.57, quiz avg = 96.0, proj avg = 79.5, sem avg = 81.21
Please help! This is NOT homework and is simply a project to understand files better, my name is Scarlett btw.
ginkul's answer couldn't cover to handle multiple row of values
so I try to write code more generally like below:
def get_header():
gb_data = open('gb_data.txt','r')
header = gb_data.readline()
return header.strip()
def get_content():
gb_data = open('gb_data.txt','r')
content = gb_data.readlines()
del content[0]
return content
hw_pos = []
project_pos = []
quiz_pos = []
header_list = get_header()
header_list = header_list.split(", ")
header_list_index = enumerate(header_list)
for index, target in header_list_index:
if target == "hw":
hw_pos.append(index)
elif target == "quiz":
quiz_pos.append(index)
elif target == "project":
project_pos.append(index)
content_list = get_content()
avg_dict = {}
for element in content_list:
element = element.strip().split(", ")
name = element[0] + ', ' + element[1]
hw_avg = sum([int(element[i]) for i in hw_pos]) / len(hw_pos)
project_avg = sum([int(element[i]) for i in project_pos]) / len(project_pos)
quiz_avg = sum([int(element[i]) for i in quiz_pos]) / len(quiz_pos)
avg_dict.update({name:(hw_avg, project_avg, quiz_avg)})
for name, avg in avg_dict.items():
print(name, "hw avg : ", round(avg[0], 2), "project avg : ", round(avg[1], 2), "quiz avg : ", round(avg[2], 2))
save your all output to another text file
for name, avg in avg_dict.items():
with open("avg.txt", "a") as f:
dataline = name + " hw avg : " + str(round(avg[0], 2)) + \
" project avg : " + str(round(avg[1], 2)) + " quiz avg : " + str(round(avg[2], 2)) + "\n"
f.write(dataline)
You probably want to have a look at pandas. It's best to give your columns unique column names, though.
import pandas as pd
def get_avg(row):
hw_avg = (row['hw_1'] + row['hw_1'] + row['hw_1']) / 3
# fill in as needed
quiz_avg = ...
proj_avg = ...
return hw_avg * 0.2 + quiz_avg * 0.2 + proj_avg * 0.6
# read your data
df = pd.read_csv('your-file.csv')
# 'apply' a function to each row (axis=1) in a dataframe,
# add all results to a new column called 'semester_avg'
df['semester_avg'] = df.apply(get_avg, axis=1)
EDIT This code is incorrect for multiple rows
You could try the following code:
def start():
with open('gb_data_.txt', 'r') as f:
keys = f.readline().strip().split(',')
values = f.readline().strip().split(',')
last = values[0]
first = values[1]
hw = [int(v) for k, v in zip(keys, values) where 'hw' in k]
hw_avr = sum(hw) / len(hw)
project = [int(v) for k, v in zip(keys, values) where 'project' in k]
project_avr = sum(project) / len(project)
quiz = [int(v) for k, v in zip(keys, values) where 'quiz' in k]
quiz_avr = sum(quiz) / len(quiz)
sem_avr = hw_avr * 0.2 + quiz_avr * 0.2 + project_avr * 0.2
def SetHP(self, hpPercentage, curHP, maxHP):
if not self.hpGauge.IsShow():
self.SetSize(200 + 7*self.nameLength, 70)
self.hpGauge.Show()
self.UpdatePosition()
self.hpGauge.SetPercentage(hpPercentage, 100)
strCurHP = str(curHP)
strMaxHP = str(maxHP)
self.broadCastHP.SetText(strCurHP + " / " + strMaxHP)
Example output is: 8993 / 18782
I see some questions like that, but all of them was about "float".
I want to make these integers like that:
8,9K / 18,7K
What is the "proper" way to do that?
Try this function:
def HPformat(str):
if len(str)==5:
newstr=str[0]+str[1] + ','+ str[2] + 'K'
return newstr
elif len(str)==4:
newstr=str[0]+','+ str[1] + 'K'
return newstr
And replace your final line of code with the function:
def SetHP(self, hpPercentage, curHP, maxHP):
if not self.hpGauge.IsShow():
self.SetSize(200 + 7*self.nameLength, 70)
self.hpGauge.Show()
self.UpdatePosition()
self.hpGauge.SetPercentage(hpPercentage, 100)
strCurHP = str(curHP)
strMaxHP = str(maxHP)
self.broadCastHP.SetText(HPformat(strCurHP) + " / " + HPformat(strMaxHP))
Also, if you don't want to add a new function you could just do:
def SetHP(self, hpPercentage, curHP, maxHP):
if not self.hpGauge.IsShow():
self.SetSize(200 + 7*self.nameLength, 70)
self.hpGauge.Show()
self.UpdatePosition()
self.hpGauge.SetPercentage(hpPercentage, 100)
strCurHP = str(curHP)
strMaxHP = str(maxHP)
newCurHP = strCurHP[0] + ',' + strCurHP [1] + 'K'
newMaxHP = strMaxHP[0] + strMaxHP[1] + ',' + strMaxHP[2] + 'K'
self.broadCastHP.SetText(newCurHP + " / " + newMaxHP)
I wrote a python script trying to solve the 'calculate 24' problem, which originated from a game, drawing 4 cards from a deck of cards and try to get the value 24 using +,-, *, and /.
The code is working, only that it have many duplications, for example, I input 2, 3, 4, 5 to get the value of 24, it will find and print that 2*(3 + 4 + 5) is 24, but it will also print 2*(5 + 4 + 3), 2*(5 + 3 + 4), etc., while it will find 4*(3 + 5 - 2), it will also print 4*(5 + 3 - 2). Could anyone please give me some hints on how to remove duplicated answers?
The code is as follows:
def calc(oprands, result) :
ret=[]
if len(oprands)==1 :
if oprands[0]!=result :
return ret
else :
ret.append(str(oprands[0]))
return ret
for idx, x in enumerate(oprands) :
if x in oprands[0:idx] :
continue
remaining=oprands[0:idx]+oprands[idx+1:]
temp = calc(remaining, result-x) # try addition
for s in temp :
ret.append(str(x) + ' + ' + s)
if(result%x == 0) : # try multiplication
temp = calc(remaining, result/x)
for s in temp :
ret.append(str(x) + ' * (' + s + ')')
temp = calc(remaining, result+x) # try subtraction
for s in temp :
ret.append(s + ' - ' + str(x))
temp = calc(remaining, x-result)
for s in temp :
ret.append(str(x) + ' - (' + s + ')')
temp = calc(remaining, result*x) # try division
for s in temp :
ret.append('(' + s + ') / ' + str(x))
if result!=0 and x%result==0 and x/result!=0 :
temp = calc(remaining, x/result)
for s in temp :
ret.append(str(x) + ' / ' + '(' +s +')')
return ret
if __name__ == '__main__' :
nums = raw_input("Please input numbers seperated by space: ")
rslt = int(raw_input("Please input result: "))
oprds = map(int, nums.split(' '))
rr = calc(oprds, rslt)
for s in rr :
print s
print 'calculate {0} from {1}, there are altogether {2} solutions.'.format(rslt, oprds, len(rr))
Calculate 24 is an interesting and challenging game. As other users pointed out in the comments, it's difficult to create a solution that doesn't present any flaw.
You could study the Rosetta Code (spoiler alert) implementation and compare it to your solution.
I am currently doing a python exercise for my University studies. I am very stuck at this task:
The taylor polynomial of degree N for the exponential function e^x is given by:
N
p(x) = Sigma x^k/k!
k = 0
Make a program that (i) imports class Polynomial (found under), (ii) reads x and a series of N values from the command line, (iii) creates a Polynomial instance representing the Taylor polynomial, and (iv) prints the values of p(x) for the given N values as well as the exact value e^x. Try the program out with x = 0.5, 3, 10 and N = 2, 5, 10, 15, 25.
Polynomial.py
import numpy
class Polynomial:
def __init__(self, coefficients):
self.coeff = coefficients
def __call__(self, x):
"""Evaluate the polynomial."""
s = 0
for i in range(len(self.coeff)):
s += self.coeff[i]*x**i
return s
def __add__(self, other):
# Start with the longest list and add in the other
if len(self.coeff) > len(other.coeff):
result_coeff = self.coeff[:] # copy!
for i in range(len(other.coeff)):
result_coeff[i] += other.coeff[i]
else:
result_coeff = other.coeff[:] # copy!
for i in range(len(self.coeff)):
result_coeff[i] += self.coeff[i]
return Polynomial(result_coeff)
def __mul__(self, other):
c = self.coeff
d = other.coeff
M = len(c) - 1
N = len(d) - 1
result_coeff = numpy.zeros(M+N+1)
for i in range(0, M+1):
for j in range(0, N+1):
result_coeff[i+j] += c[i]*d[j]
return Polynomial(result_coeff)
def differentiate(self):
"""Differentiate this polynomial in-place."""
for i in range(1, len(self.coeff)):
self.coeff[i-1] = i*self.coeff[i]
del self.coeff[-1]
def derivative(self):
"""Copy this polynomial and return its derivative."""
dpdx = Polynomial(self.coeff[:]) # make a copy
dpdx.differentiate()
return dpdx
def __str__(self):
s = ''
for i in range(0, len(self.coeff)):
if self.coeff[i] != 0:
s += ' + %g*x^%d' % (self.coeff[i], i)
# Fix layout
s = s.replace('+ -', '- ')
s = s.replace('x^0', '1')
s = s.replace(' 1*', ' ')
s = s.replace('x^1 ', 'x ')
#s = s.replace('x^1', 'x') # will replace x^100 by x^00
if s[0:3] == ' + ': # remove initial +
s = s[3:]
if s[0:3] == ' - ': # fix spaces for initial -
s = '-' + s[3:]
return s
def simplestr(self):
s = ''
for i in range(0, len(self.coeff)):
s += ' + %g*x^%d' % (self.coeff[i], i)
return s
def _test():
p1 = Polynomial([1, -1])
p2 = Polynomial([0, 1, 0, 0, -6, -1])
p3 = p1 + p2
print p1, ' + ', p2, ' = ', p3
p4 = p1*p2
print p1, ' * ', p2, ' = ', p4
print 'p2(3) =', p2(3)
p5 = p2.derivative()
print 'd/dx', p2, ' = ', p5
print 'd/dx', p2,
p2.differentiate()
print ' = ', p5
p4 = p2.derivative()
print 'd/dx', p2, ' = ', p4
if __name__ == '__main__':
_test()
Now I'm really stuck at this, and I would love to get an explaination! I am supposed to write my code in a separate file. I'm thinking about making an instance of the Polynomial class, and sending in the list in argv[2:], but that doesn't seem to be working. Do I have to make a def to calculate the taylor polynomial for the different values of N before sending it in to the Polynomial class?
Any help is great, thanks in advance :)
Not quite finished, but this answers your main question I believe. Put class Polynomial in poly.p and import it.
from poly import Polynomial as p
from math import exp,factorial
def get_input(n):
''' get n numbers from stdin '''
entered = list()
for i in range(n):
print 'input number '
entered.append(raw_input())
return entered
def some_input():
return [[2,3,4],[4,3,2]]
get input from cmd line
n = 3
a = get_input(n)
b = get_input(n)
#a,b = some_input()
ap = p(a)
bp = p(b)
print 'entered : ',a,b
c = ap+bp
print 'a + b = ',c
print exp(3)
x = ap
print x
sum = p([0])
for k in range(1,5):
el = x
for j in range(1,k):
el el * x
print 'el: ',el
if el!=None and sum!=None:
sum = sum + el
print 'sum ',sum
output
entered : [2, 3, 4] [4, 3, 2]
a + b = 6*1 + 6*x + 6*x^2
20.0855369232
2*1 + 3*x + 4*x^2
sum 2*1 + 3*x + 4*x^2
el: 4*1 + 12*x + 25*x^2 + 24*x^3 + 16*x^4
sum 6*1 + 15*x + 29*x^2 + 24*x^3 + 16*x^4
el: 4*1 + 12*x + 25*x^2 + 24*x^3 + 16*x^4
el: 8*1 + 36*x + 102*x^2 + 171*x^3 + 204*x^4 + 144*x^5 + 64*x^6
sum 14*1 + 51*x + 131*x^2 + 195*x^3 + 220*x^4 + 144*x^5 + 64*x^6
el: 4*1 + 12*x + 25*x^2 + 24*x^3 + 16*x^4
el: 8*1 + 36*x + 102*x^2 + 171*x^3 + 204*x^4 + 144*x^5 + 64*x^6
el: 16*1 + 96*x + 344*x^2 + 792*x^3 + 1329*x^4 + 1584*x^5 + 1376*x^6 + 768*x^7 + 256*x^8
sum 30*1 + 147*x + 475*x^2 + 987*x^3 + 1549*x^4 + 1728*x^5 + 1440*x^6 + 768*x^7 + 256*x^8
I solved the task in the following way, though im not sure if it answers question (iv).
The output just compares the exact value of e**x to the calculated value from module Polynomial.
from math import factorial, exp
from Polynomial import *
from sys import *
#Reads x and N from the command line on the form [filename.py, x-value, N-value]
x = eval(argv[1])
N = eval(argv[2])
#Creating list of coefficients on the form [1 / i!]
list_coeff = [1./factorial(i) for i in range(N)]
print list_coeff
#Creating an instance of class Polynomial
p1 = Polynomial(list_coeff)
print 'Calculated value of e**%f = %f ' %(x, p1.__call__(x))
print 'Exact value of e**%f = %f'% (x, exp(x))
"""Test Execution
Terminal > python Polynomial_exp.py 0.5 5
[1.0, 1.0, 0.5, 0.16666666666666666, 0.041666666666666664]
Calculated value of e**0.500000 = 1.648438
Exact value of e**0.500000 = 1.648721
"""