def find_gpa(sem=1):
sub = int(input("Enter the no of subjects: "))
credits = []
grade = []
temp = []
for i in range(0,sub):
a=i+1
x = int(input("Enter the credits for subject {}".format(a)))
credits.append(x)
grade = input("Enter the Grade for subject {}".format(a))
y = gpa_convert(grade)
print(type(y))
grade.append(y)
temp.append(x*y)
gpa = sum(temp)/sum(credits)
tup = (gpa,sum(credits))
print ("The Gpa of semester {} is: {}".format(sem,gpa))
return tup
def gpa_convert(z):
if z.lower() == 'o':
return 10
elif z.lower() == 'a+':
return 9
elif z.lower() == 'a':
return 8
elif z.lower() == 'b+':
return 7
elif z.lower() == 'b':
return 6
else :
return 0
AttributeError:
'str' object has no attribute 'append'
I'm trying to append an integer in grade but its showing string
can you help me in rectifying the error?
You start with
grade = []
but in your loop you have :
grade = input("Enter the Grade for subject {}".format(a))
your list doesn't exist anymore, grade is now an int
int don't have append method, so this doesn't work :
grade.append(y)
Solution :
replace grade = [] by grades = [] and then use plural where a list is expected
def find_gpa(sem=1):
sub = int(input("Enter the no of subjects: "))
credits = []
grades = []
temp = []
for i in range(0,sub):
a=i+1
x = int(input("Enter the credits for subject {}".format(a)))
credits.append(x)
grade = input("Enter the Grade for subject {}".format(a))
y = gpa_convert(grade)
print(type(y))
grades.append(y)
temp.append(x*y)
gpa = sum(temp)/sum(credits)
tup = (gpa,sum(credits))
print ("The Gpa of semester {} is: {}".format(sem,gpa))
return tup
Please note however that you declare a list in the scope of the function, but never use it or return it ! This code can be simplified a lot
Related
I have a problem adding scores to an object with a for loop.
what I'm trying to achieve is this:
enter test num: 1
enter test score: 58
enter test num: 2
etc...
and then print out the three test numbers and the average, but I can't seem to get it to set the test num nor the score.
this is the error I get after tring to add test 1 and test 1 score:
Traceback (most recent call last):
File "d:\pyproj\Lecture 5\Main.py", line 27, in <module>
studentArray()
File "d:\pyproj\Lecture 5\Main.py", line 25, in studentArray s = student.setTestScore(test,score)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: student.setTestScore() missing 1 required positional argument: 'result'
Main.py
from student import student
def studentArray():
classSize = int(input("how big is the class? "))
classList = []
num=0
while not(num == classSize):
firstName = input("\nWhat's the students first name? ");
lastName = input("\nWhat's the students last name? ");
homeAddress = input("\nWhat's the students home address? ");
schoolAddress = input("\nWhat's the students school address? ");
courseName = input("\nWhat course is the students taking? ");
courseCode = input("\nWhat's the course code? ");
classList.append(student(firstName,lastName,homeAddress,schoolAddress,courseName,courseCode));
num+=1
for s in classList:
for i in range(len(classList)):
test = int(input("enter test number: "))
score = int(input("enter test score: "))
s.setTestScore(test,score)
print("\n",s)
studentArray()
studentclass.py:
from Course import Course
class student:
def __init__(self,first, last, home, school,courseName,courseCode):
self.firstName = first
self.lastName = last
self.homeAddress = home
self.schoolAddress = school
self.courseName = courseName
self.courseCode = courseCode
Course(courseName,courseCode)
self.testResults = []
def setTestScore(self,test,result):
if test < 1 | result < 0 | test > 100:
print("Error: Wrong test results.")
else:
self.testResults.append(result)
def average(self):
average = 0;
total = 0;
for result in self.testResults:
total += result
average = total / 3.0;
return average;
def __str__(self):
testAString = ""
for testResult in self.testResults:
testAString += str(testResult) + " "
result = "Student name:\n"+self.firstName + " " + self.lastName+"\n";
result += "Course name:\n"+self.courseName+"\n";
result += "Course Code: "+ self.courseCode+"\n";
result += "Test results:\n"+testAString+"\n";
result += "Average:\n", str(self.average()), "\n";
result += "Home Address:\n"+self.homeAddress+"\n";
result += "School Address:\n"+ self.schoolAddress;
return result;
Courseclass.py:
class Course:
def __init__(self,course,code):
self.course = course
self.code = code
def setCourseName(self,name):
self.course = name
def setCourseCode(self, code):
self.course = code
Issue is you are trying to run setTestScore function without instantiating the class. Either make it a staticmethod or call it from an object
for s in classList:
for i in range(len(classList)):
test = int(input("enter test number: "))
score = int(input("enter test score: "))
s.setTestScore(test,score)
print("\n"+s)
PS: Line
classList = [classSize]
creates a new list and adds classSize to the list as the first element. I assume you want to create a list with size of classSize. You do not need to specify length when creating lists in python.
Also,
testResults = []
this initalization is outside of init, which makes testResults a class variable, means it will be shared within all classes. I would advise you to move it inside init function
Editing upon your edit, you are trying to concat string with a tuple
result += "Average:\n", str(self.average()), "\n";
What you should do is:
result += "Average:\n" + str(self.average()) + "\n";
In python you don't need to end lines with ;
also you need to create an instance of the class and on that instance you can use the class methods
look in the code I added comments on every change
Main.py
from student import student
def studentArray():
classSize = int(input("how big is the class? "))
classList = []
num = 0
while num != classSize:
firstName = input("\nWhat's the students first name? ")
lastName = input("\nWhat's the students last name? ")
homeAddress = input("\nWhat's the students home address? ")
schoolAddress = input("\nWhat's the students school address? ")
courseName = input("\nWhat course is the students taking? ")
courseCode = input("\nWhat's the course code? ")
new_student = student(firstName, lastName, homeAddress, schoolAddress, courseName, courseCode)
classList.append(new_student)
number_of_test = int(input("\nHow many tests did the student had? "))
for i in range(number_of_test):
test = int(input("enter test number: "))
score = int(input("enter test score: "))
new_student.setTestScore(test, score)
num += 1
for s in classList:
print("\n" + str(s))
studentArray()
studentclass.py
from Course import Course
class student:
def __init__(self, first, last, home, school, courseName, courseCode):
self.firstName = first
self.lastName = last
self.homeAddress = home
self.schoolAddress = school
self.courseName = courseName
self.courseCode = courseCode
self.testResults = []
Course(courseName, courseCode)
def setTestScore(self, test, result):
if test < 0 or result < 0 or result > 100:
print("Error: Wrong test results.")
else:
self.testResults.append(result) # append to the list
def average(self):
average = 0
total = 0
for result in self.testResults:
total += result
average = total / 3.0
return str(average) # str the average
def __str__(self):
testAString = ""
for testResult in self.testResults:
testAString += str(testResult) + " " # str the testResult
result = "Student name:\n" + self.firstName + " " + self.lastName + "\n"
result += "Course name:\n" + self.courseName + "\n"
result += "Course Code: " + self.courseCode + "\n"
result += "Test results:\n" + testAString + "\n"
result += "Average:\n" + self.average() + "\n"
result += "Home Address:\n" + self.homeAddress + "\n"
result += "School Address:\n" + self.schoolAddress
return result
There are several issues with your code, most of them involve try to concatenate strings and non string types, as well as a few type errors along the way. You are also using the bitwise | instead of or which are not the same thing.
Starting with your student class:
use the actual or keyword instead of using bitwise |, it may be providing accurate results for some answers but it is not operating in the way you think it is.
in your __str__ method there are a few instances where you are trying to contatenate a string and an int.
in your setTestScores function you want to append the result to the testResults list.
Here is an example fix for those problems:
class student:
testResults = []
def __init__(self,first, last, home, school,courseName,courseCode):
self.firstName = first
self.lastName = last
self.homeAddress = home
self.schoolAddress = school
self.courseName = courseName
self.courseCode = courseCode
Course(courseName,courseCode)
def setTestScore(self,test,result):
if test < 1 or result < 0 or test > 100:
print("Error: Wrong test results.")
else:
self.testResults.append(result)
def average(self):
average = 0
total = 0
for result in self.testResults:
total += result
average = total / 3.0
return average
def __str__(self):
testAString = ""
for testResult in self.testResults:
testAString += str(testResult) + " "
result = "Student name:\n"+self.firstName + " " + self.lastName+"\n"
result += "Course name:\n"+self.courseName+"\n"
result += "Course Code: "+ self.courseCode+"\n"
result += "Test results:\n"+testAString+"\n"
result += "Average:\n" + str(self.average()) +"\n"
result += "Home Address:\n"+self.homeAddress+"\n"
result += "School Address:\n"+ self.schoolAddress
return result
Next you have the studentArray function.
you don't need to specify the size of the classList since lists can be dynamically appended to.
you need to convert your instance to a string before concatenating it with the new line character.
Here is an example fix for that.
def studentArray():
classSize = int(input("how big is the class? "))
classList = []
num=0
while not(num == classSize):
firstName = input("\nWhat's the students first name? ")
lastName = input("\nWhat's the students last name? ")
homeAddress = input("\nWhat's the students home address? ")
schoolAddress = input("\nWhat's the students school address? ")
courseName = input("\nWhat course is the students taking? ")
courseCode = input("\nWhat's the course code? ")
s = student(firstName,lastName,homeAddress,schoolAddress,courseName,courseCode)
classList.append(s)
num+=1
for s in classList:
for i in range(len(classList)):
test = int(input("enter test number: "))
score = int(input("enter test score: "))
s.setTestScore(test,score)
print("\n"+str(s))
Making these adjustments this was the output of your code.
how big is the class? 1
What's the students first name? a
What's the students last name? b
What's the students home address? 10
What's the students school address? 12
What course is the students taking? art
What's the course code? 1
enter test number: 1
enter test score: 88
Student name:
a b
Course name:
art
Course Code: 1
Test results:
88
Average:
29.333333333333332
Home Address:
10
School Address:
12
finally if you want to add more test scores you need add another question that asks how many tests were taken in the class and then iterate based on the response.
num_tests = int(input('how many tests'))
for s in classList:
for i in range(num_tests):
test = int(input("enter test number: "))
score = int(input("enter test score: "))
s.setTestScore(test,score)
Hello I am trying to run a program that will return back students grades and their average. ALSO I KNOW I AM A BASIC BRAINLESS FIRST YEAR PROGRAMMER. I WILL PROBABLY BE HORRIBLE AT PROBABLY. HOWEVER PLEASE HELP THE BEST YOU CAN IT WOULD BE GREATLY APPRECIATED.
THANK YOU.
The error says to be in line 49.
saying that"
line 49, in <module>
while ids > STOP:
TypeErrorL unorderable types: str() > int()
XXXX
def assigngrades(scores):
avg = sum(scores)/len(scores)
print(avg)
for val in scores:
if val > avg + 10:
grade = 'A'
elif val > avg + 5:
grade = 'B'
elif val > avg -5:
grade = 'C'
elif val > avg - 10:
grade = 'D'
else:
grade = 'F'
grades.append(grade)
print("in assigngrades, grades: ",grades)
return grades
def printsummary(grades, ave):
print('ID Score Average Grade')
print('===========================================')
print( )
for val in range(len(ids)):
print('val', val)
print(ids,' ',scores, ' ', grades)
return
#main
ids = []
scores = []
grades = []
STOP = 0
ids = input("Enter an ID:")
while ids > STOP:
ids.append(ids)
score = eval(input("Enter a score:"))
scores.append(score)
id = (input("Enter an ID number, 0 to STOP:"))
grades = assigngrades(scores)
print("after while loop")
print("Ids:", ids, "Scores:", scores, "Grades:", grades)
printsummary(grades, avg)
Nonetheless, I am confused on what is the issue.I appreciate your time and help looking at this. Thank you so so so much. Yes I know I am stupid.
The input() function returns a string, so you should convert it to an integer with int() so you can compare its value with another integer. You should also name the variable that stores the user input something other than ids since you already define it as a list:
ids = []
scores = []
grades = []
STOP = 0
id = int(input("Enter an ID:"))
while id > STOP:
ids.append(id)
score = eval(input("Enter a score:"))
scores.append(score)
grades = assigngrades(scores)
print("after while loop")
print("Ids:", ids, "Scores:", scores, "Grades:", grades)
printsummary(grades, avg)
In the following code I'm showing a function that lets you add students to a dictionary (book) with rut being the key, the issue I have is that I'm trying to make a function that can search by department and then print all students of that are part of that department, basically I'm asking how do you search a dictionary with 1 key that is associated to a lot of values and you want to search for a particular value and then print all keys that have it along with their info?
book = {}
def add(rut, name, age, department):
student = {}
student['rut'] = rut
student['name'] = name
student['age'] = age
student['department'] = department
book[rut] = student
def printall():
for rut in book:
student = book[rut]
print(student['rut'], student['name'], student['age'], student['department'])
def main():
count = 0
x = 0
y = int(input("How many students will you add?: "))
while count < y:
print('Input data of the student: ', count+1)
rut = input("rut: ")
name = input("name: ")
age = int(input("age: "))
print("Department 1: RH, 2: Logistic, 3: Cleaners, 4: TI ")
department = ''
while x == 0:
num_dept = int(input("department number: "))
if num_dept == 1:
department = "RH"
x = 1
elif num_dept == 2:
department = "Logistic"
x = 1
elif num_dept == 3:
department = "Mathematics"
x = 1
elif num_dept == 4:
department = "TI"
x = 1
else:
print('Error')
x = 0
add(rut, name, age, department)
count = count + 1
printall()
main()
You can use a list comprehension.
students = [student for student in book.values()
if student["department"] == desired_department]
This will give you a list, which you can then print out if you so choose.
this is a GPA calculator code in my textbook. I'd like to ask about a few this I don't understand here.
# Semester GPA Calculation
def convertGrade(grade):
if grade == 'A+':
return 4
if grade == 'A':
return 3.7
if grade == 'A-':
return 3.3
if grade == 'B+':
return 3.0
if grade == 'B':
return 2.7
if grade == 'B-':
return 2.3
if grade == 'C+':
return 2.0
if grade == 'C':
return 1.7
if grade == 'C-':
return 1.3
if grade == 'D+':
return 1.0
if grade == 'D':
return 0.7
if grade == 'D-':
return 0.3
else:
return 0
def getGrades():
semester_info = []
more_grades = True
empty_str = ''
while more_grades:
course_grade = input('Enter grade (hit Enter if done): ')
while course_grade not in ['A+', 'A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-', 'E+', 'E', 'E-', 'F', empty_str]:
course_grade = input('Enter letter grade you received: ')
if course_grade == empty_str:
more_grades = False
else:
num_credits = int(input('Enter number of credits: '))
semester_info.append([num_credits, course_grade])
return semester_info
def calculateGPA(sem_grades_info, cumm_gpa_info):
sem_quality_pts = 0
sem_credits = 0
current_cumm_gpa, total_credits = cumm_gpa_info
for k in range(len(sem_grades_info)):
num_credits, letter_grade = sem_grades_info[k]
sem_quality_pts = sem_quality_pts + \
num_credits * convertGrade(letter_grade)
sem_credits = sem_credits + num_credits
sem_gpa = sem_quality_pts / sem_credits
new_cumm_gpa = (current_cumm_gpa * total_credits + sem_gpa * \
sem_credits) / (total_credits + sem_credits)
return (sem_gpa, new_cumm_gpa)
# ---- main
# program greeting
print('This program calculates new semester and cumulative GPAs\n')
# get current GPA info
total_credits = int(input('Enter total number of earned credits: '))
cumm_gpa = float(input('Enter your current cummulative GPA: '))
cumm_gpa_info = (cumm_gpa, total_credits)
# get current semester grade info
print()
semester_grades = getGrades()
# calculate semester gpa and new cumulative gpa
semester_gpa, cumm_gpa = calculateGPA(semester_grades, cumm_gpa_info)
#display semester gpa and new cummulative gpa
print('\nYour semester GPA is', format(semester_gpa, '.2f'))
print('Your new cummulative GPA is', format(cumm_gpa, '.2f'))
What does current_cumm_gpa, total_credits = cumm_gpa_info mean below? Does it create a new array? I tried simpler but it doesn't work.
def calculateGPA(sem_grades_info, cumm_gpa_info):
sem_quality_pts = 0
sem_credits = 0
current_cumm_gpa, total_credits = cumm_gpa_info
From this line:
cumm_gpa_info = (cumm_gpa, total_credits)
We can see that cumm_gpa_info is a tuple of two values. Then current_cumm_gpa, total_credits = cumm_gpa_info unpacks the values in the tuple to two variables, the first to current_cumm_gpa and the second to total_credits. It's a simpler way of doing:
current_cumm_gpa = cumm_gpa_info[0]
total_credits = cumm_gpa_info[1]
From the docs:
This is called, appropriately enough, sequence unpacking and works for
any sequence on the right-hand side. Sequence unpacking requires that
there are as many variables on the left side of the equals sign as
there are elements in the sequence. Note that multiple assignment is
really just a combination of tuple packing and sequence unpacking.
Tracing your program we see the following :
>>> total_credits = int(input('Enter total number of earned credits: '))
#3.2
>>> cumm_gpa = float(input('Enter your current cummulative GPA: '))
#4.6
>>> cumm_gpa_info = (cumm_gpa, total_credits)
>>> cumm_gpa_info
(3.2 , 4.6)
>>> type(cumm_gpa_info)
Tuple
So we see that cumm_gpa_info is a Tuple. Now this is passed to the function.
>>> ... = calculateGPA(semester_grades, cumm_gpa_info)
#inside function
>>> current_cumm_gpa, total_credits = cumm_gpa_info
#current_cumm_gpa, total_credits = (3.2 , 4.6)
>>> current_cumm_gpa
3.2
>>> total_credits
4.6
So as we can see, the values were unpacked from the tuple and assigned to current_cumm_gpa & total_credits respectively.
It is similar to doing :
>>> current_cumm_gpa = cumm_gpa_info[0]
>>> total_credits = cumm_gpa_info[1]
Note : sorry if its not exactly how it would look on a console. Can't get to my PC, writing it out on my mobile right now. So have put it approximately how it would look.
Hi having trouble trying to fix an error that occurs when I put just a '#' or rogue value in case someone doesn't want to add any data. I don't know how to fix it and I'm hoping to just end the code just like I would with data.
#Gets Data Input
def getData():
fullList = []
inputText = checkInput("Enter the students first name, last name, first mark, and second mark (# to exit): ")
while inputText != "#":
nameList = []
nameList2 = []
nameList = inputText.split()
nameList2.extend((nameList[0],nameList[1]))
nameList2.append((float(nameList[2]) + float(nameList [3]))/2)
fullList.append(nameList2)
inputText = checkInput("Enter the students first name, last name, first mark, and second mark (# to exit): ")
print("\n")
return fullList
#Calculates Group Average
def calc1(fullList):
total = 0
for x in fullList:
total = total + x[2]
groupAverage = total/(len(fullList))
return(groupAverage)
#Finds Highest Average
def calc2(fullList):
HighestAverage = 0
nameHighAverage = ""
for x in fullList:
if x[2] > HighestAverage:
HighestAverage = x[2]
nameHighAverage = x[0] + " " + x[1]
return (HighestAverage, nameHighAverage)
#Returns Marks above average
def results1(groupAverage,r1FullList):
r1FullList.sort()
print("List of students with their final mark above the group average")
print("--------------------------------------------------------------")
print("{:<20} {:<12}".format("Name","Mark"))
for x in r1FullList:
if x[2] > groupAverage:
name = x[0] + " " + x[1]
print("{:<20} {:<12.2f}".format(name,x[2]))
def calc3(x):
if x[2] >= 80:
return 'A'
elif x[2] >= 65:
return 'B'
elif x[2] >= 50:
return 'C'
elif x[2] < 50:
return 'D'
else:
return 'ERROR'
def results2(fullList):
print("List of Studens with their Final Marks and Grades")
print("-------------------------------------------------")
print("{:<20} {:<12} {:<12}".format("Name","Mark","Grade"))
for x in fullList:
grade = calc3(x)
name = x[0] + " " + x[1]
print("{:<20} {:<12.2f} {:<12}".format(name,x[2],grade))
#Checks for boundary and invalid data
def checkInput(question):
while True:
textInput = input(question)
if textInput == "#":
return textInput
splitList = textInput.split()
if len(splitList) !=4:
print("Invalid Format, Please Try Again")
continue
try:
a = float(splitList[2])
a = float(splitList[3])
if float(splitList[2]) < 0 or float(splitList[2]) > 100:
print("Invalid Format, Please Try Again")
continue
if float(splitList[3]) < 0 or float(splitList[3]) > 100:
print("Invalid Format, Please Try Again")
continue
return(textInput)
except ValueError:
print("Invalid Input, Please Try Again")
continue
#Main Program
#Input Data
fullList = getData()
#Process Data
groupAverage = calc1(fullList)
HighestAverage, nameHighAverage = calc2(fullList)
#Display Results
print("The group average was %.2f" % groupAverage)
print("The student with the highest mark was: %s %0.2f" %(nameHighAverage,HighestAverage))
results1(groupAverage,fullList)
print("\n")
results2(fullList)
Your program works OK for me, unless you enter a # as the first entry, in which case fullList is [] and has length 0. Hence, DivisionByZero at this line: groupAverage = total/(len(fullList)).
You could modify your code to check for this and exit:
import sys
fullList = getData()
if not fullList:
print('No Data!')
sys.exit()