Python Using a For loop inside a function

26,262

Solution 1

Here comes some tough love.

There are multiple problems here. In general you need to learn to think through your program line by line, as though you were the CPU, and figure out what you want to happen at each step. Then you need to weed out mistakes until what the actual CPU does is equal to what you want.

In the second line (the for loop), the variable "curraverage" is undefined since it doesn't get defined until a couple lines later. It's the wrong variable anyway; you want to loop over all the students so you need range(numofstudent).

In the next line, "test" is undefined. You meant "test3." If you want to learn to program you just cannot allow yourself to make these kinds of mistakes.

The variable curraverge looks like a typo, but it's actually not. Think of a better name, it's not hard.

In line 5, averagescore (which was declared as a global down below, and was a list) is now re-declared as a local and bound to a float. As such you cannot append to it in line 6. Line 5 should simply be discarded, it does nothing except create a bug.

The line grade[count] doesn't do anything. You need to call grade.append to build the list of grades. But since you haven't computed the grade yet, no such line belongs here.

Next you compare averagescore to 90 and 80 and so forth, but that's the wrong variable again. That's the list you declared below. Here you want the score for one student (which is curraverage).

Then you return from inside the loop, causing the function to exit before you have computed more than one grade. None of those returns should be in there.

I could go on. You need to be much, much more careful about what you are doing. Keep in mind that computers are profoundly stupid - they do exactly what they're told, whether that's what you want them to do or not.

Best of luck to you.

Solution 2

Here is a working example which uses some more advanced ideas:

  • we split the code into functions; each function does one specific thing. This makes the code much easier to think about, test, debug, and reuse.

  • each function has a docstring - built-in documentation about what it does and how to use it, which can be reviewed with Python's help() function, ie help(average).

  • we define a Student class which stores the name and marks for a single student. It knows how to create a student by prompting for input, and how to calculate an overall grade from the marks.

  • marks are entered using a list comprehension; something like

    result = [func(x) for x in lst]
    

    which is an easier-to-read equivalent of

    result = []
    for x in lst:
        result.append(func(x))
    

Here's the code; if you trace through it and understand it, it should help:

# assumes Python 3
def get_int(prompt):
    """
    Prompt the user to enter a number;
    return the number as an int
    """
    while True:
        try:
            return int(input(prompt))
        except ValueError:  # couldn't parse as int
            pass   # skip the error message

def average(lst):
    """
    Return the average of a list of numbers
    """
    return sum(lst) / len(lst)

def grade(mark):
    """
    Given a mark as a percentage,
    return a grade letter
    """
    if mark >= 90.:
        return "A"
    elif mark >= 80.:
        return "B"
    elif mark >= 70.:
        return "C"
    else:
        return "F"

class Student:
    @classmethod
    def from_prompt(cls):
        """
        Prompt for a student's information,
        return it as a Student object
        """
        name = input("Please enter student name: ")
        marks = [float(f) for f in input("Please enter {}'s marks: ".format(name)).split()]
        return cls(name, marks)    # implicitly calls __init__

    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def grade(self):
        """
        Return the student's overall grade
        """
        return grade(average(self.marks))

def main():
    # get student data
    num_students = get_int("How many students do you want to enter? ")
    print("")
    students = [Student.from_prompt() for _ in range(num_students)]

    # print student grades
    print("")
    for student in students:
        print("{}'s grade is {}".format(student.name, student.grade()))

if __name__=="__main__":
    # if loaded as a program, call the main function
    main()

and runs like

How many students do you want to enter? 4

Please enter student name: Anna
Please enter Anna's marks: 91.0 94.5 96.1
Please enter student name: Ben
Please enter Ben's marks: 82 86 90
Please enter student name: Charlie
Please enter Charlie's marks: 65 75 85
Please enter student name: Farquad
Please enter Farquad's marks: 10 40 55 36 51 16

Anna's grade is A
Ben's grade is B
Charlie's grade is C
Farquad's grade is F
Share:
26,262
user3598076
Author by

user3598076

Updated on June 08, 2020

Comments

  • user3598076
    user3598076 almost 4 years

    I'm a Python beginner trying write a program that will allow the user to input individuals names and test scores and I am supposed to give back a grade after finding the average so far I've been able to write the program but I am experiencing difficulties trying to debug it. my programs works fine until it starts to calculate the average, it usually displays an error message saying

    "TypeError: 'float' object is not subscriptable" 
    

    Could somebody please help me why my codes are not working? Thank you for your help in advance!

    def calcaverage(test1,test2,test3):
        for count in range(numofstudent):
            curraverage=((test1[count]+ test2[count]+ test3[count])/3)
            if curraverage>= 90:
                grade= "A"
                return grade 
            else:
                if curraverage >= 80 and curraverage < 90:
                    grade= "B"
                    return grade
                else:
                    if curraverage >= 70 and curraverage < 80:
                        grade= "C"
                        return grade
                    else:
                        if curraverage < 70:
                            grade= "F"
                            return grade
    
    numofstudent=int(input("How Many Students?: "))
    students=[]
    test1=[]
    test2=[]
    test3=[]
    averagescore=[]
    grade=[]
    for count in range(numofstudent):
        currstudent=input("Please enter name of student: ")
        students.append(currstudent)
        currstudenttest1= float(input("First test score?: "))
        currstudenttest2= float(input("Second test score?: "))
        currstudenttest3= float(input("Third test score?: "))
        test1.append(currstudenttest1)
        test2.append(currstudenttest2)
        test3.append(currstudenttest3)
    
    grade=calcaverage(test1,test2,test3)
    averagescore.append(grade)
    print([students], "your grade is " ,[grade])
    
  • user3598076
    user3598076 almost 10 years
    Thanks Paul for the advice, I didn't realize how poorly my program was written until after I posted my question. I fixed most of the issues like typos and indentations, but now that I read your comment I can see better now why my program still won't run, I appreciate your feedback thanks