LazerSharks
LazerSharks

Reputation: 3155

items not appending to list, or list returning as empty in python?

In my code, the item percentgrade is not appending to the list lnpercentgrade in each iteration of a for loop, but I'm not sure why. When I try to sum the items in lnpercentgrade (at the end of the code), I am returned 0 because lnpercentgrade is empy. I have lnpercentgrades declared as a global variable outside of the maininput() function, because otherwise at the bottom of the code when I try to sum(lnpercentgrades), I am returned "lnpercentgrades not defined".

I'm guessing lnpercentgrades is not being modified somehow inside the maininput() function, even though I am sure I typed it correctly before the .append function.

What I am really trying to do is match the sum(lnpercentgrades) with 100, but when I enter 5 items all with value of 20, the sum is 0 instead of 100.

The important lines are marked with arrows <<<<<<<<<<<<<<<<<<<<<

lnpercentgrades = []   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
def maininput():
    numtests = int(input("Enter # of tests:"))
    numassign = int(input("Enter # of assignments:"))
    numquizzes = int(input("Enter # of quizzes:"))
    numlabs = int(input("Enter # of labs:"))

    l = [numtests, numassign, numquizzes, numlabs]
    ln = ["test", "assignments", "quizzes", "labs"]
    lnpercentgrades = [] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    testwavg = None
    numassignwavg = None
    numquizzeswavg = None
    numlabswavg = None
    numfinalwavg = None

    lnwavg = [testwavg, numassignwavg, numquizzeswavg, numlabswavg]
    print(l[0])
    print("Is there a separately weighted final?")
    yn = int(input("Enter 1 for yes. 2 for no:"))
    while (yn > 2 or yn < 1):
        yn = int(input("Enter 1 for yes. 2 for no, please:"))

    n = 4 
    if yn == 1:
        final = 1
        l.append(final)
        ln.append("final")
        lnwavg.append(numfinalwavg)
        n = 5


    for i in range (n):
        if l[i] > 0:
            print("Enter % of total grade of",ln[i],":") 
            percentgrade = float(input("")) 
            print("you inputed:", percentgrade)
            lnpercentgrades.append(percentgrade) <<<<<<<<<<<<<<<<<<<<<<
            percentgrade = percentgrade*.01 


            varscoreslist = []
            for x in range(l[i]):
                print("Enter score of", ln[i], x+1,"as a fraction:")
                from fractions import Fraction
                inputfrac = input("")
                varscore = float(sum(Fraction(s) for s in inputfrac.split())) 
                #the above converts fractional inputs to decimals
                varscoreslist.append(varscore)

            if ln[i] == "labs":
                score = sum(varscoreslist)
            else:
                sumscores = sum(varscoreslist)
                score = sumscores/l[i]

            lnwavg[i] = score*percentgrade

maininput()
print(lnpercentgrades)
print("sum of percent of grades", sum(lnpercentgrades)) <<<<<<<<<<<<<<<

if float(sum(lnpercentgrades)) != 100:  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    print("Sorry, the grade percent of each item enter did not sum to 100:")
    print("Program will rerun.")
    input("")
    maininput()

coursegrade = sum(lnwavg)
print("Your course grade is:", coursegrade)

input("")

Upvotes: 3

Views: 9687

Answers (1)

RocketDonkey
RocketDonkey

Reputation: 37249

At first glance, it looks like you may have a scoping issue. You are modifying the list inside of the function, but keep in mind that is a local copy of the list. Despite the fact you are declaring it in the outer scope, you are not prefacing it with global, which means it instead creates a function-local copy, does its business and then exits, not affecting the 'main' list at all.

I would suggest modifying your function to return the lists you want so that you can use them as you'd expect. Here is a basic example:

def MyFunc():
    l1 = ['my', 'first', 'list']
    l2 = ['another', 'list']
    return l1, l2

main_list, second_list = MyFunc()

print(main_list)
print(second_list)

Which will output:

['my', 'first', 'list']
['another', 'list']

If you really want to keep the variable in the outer scope, you would have to preface it with global inside of your function (I would probably go with the first method though):

main_list = []
second_list = []

def MyFunc():
    global main_list
    global second_list
    main_list = ['more', 'good', 'stuff']
    second_list = ['another', 'list']


MyFunc()

print(main_list) # ['more', 'good', 'stuff']
print(second_list) # ['another', 'list']

Upvotes: 8

Related Questions