尝试从二维列表(从 .txt 文件读取)中查找平均变化率时结果不正确

Incorrect results when trying to find average rate of change from a 2-dimensional list (read from a .txt file)

我创建了一个程序来读取由价格列表组成的 .txt 文件。该程序将创建一个二维列表来存储周数、价格和与前一周相比的变化。用户将输入所需的开始周和结束周。

如果用户将 'start week' 输入为“1”,将 'end week' 输入为“6”: 平均变化应该是“-0.30” 最高变化应该是 'week 4',变化为“2.80” 最低的变化应该是 'week 5',变化为 '-4.93'

然而,我的数字完全错了。

这是我的代码:

# get two dimensional list
priceList = []

#open the file
priceFile = open ('MicrosoftPrices.txt', 'r')

#create variable for start year
week = 1
price = float (priceFile.readline())

#special case for week 1

#initialize loop counter
i = 0

while price != '':
    priceList.append ([0,0,0])

    priceList [i][0] = week
    priceList [i][1] = float (price)

    if week == 1:
        priceList [i][2] = 0
    else:
        priceList[i][2] = ((priceList[i][1] - priceList[i-1][1])/priceList[i-1][1])

    #read the next line
    price = priceFile.readline()

    #add to the counter
    i += 1

    #go to next week
    week = week + 1

#initialize start and end weeks
startWeek = 0
endWeek = 0

#define start week validation
def FirstValidation (startWeek):

    startWeek = -1

    while startWeek == -1:
        startWeek = input ('What week would you like to start with?')

        try:
            if startWeek == '':
                startWeek = 1
                break

            startWeek = int (startWeek)

        except Exception:
            print ('Year must be a valid integer between 1 and 52')

        else:
            if startWeek >= 1 and startWeek <= 52:
                break
            else:
                startWeek = -1
                print ('ERROR: Week must be a valid integer between 1 and 52! Please try again.')

    return startWeek

#define end week validation
def LastValidation (endWeek):
    endWeek = -1

    while endWeek == -1:
        endWeek = input ('What week would you like to end with?')

        try:
            if endWeek == '':
                endWeek = 52
                break

            endWeek = int (endWeek)

        except Exception:
            print ('Year must be a valid integer between 1 and 52')
        else:
            if endWeek >= startWeek and endWeek <= 52:
                break
            else:
                endWeek = -1
                print ('ERROR: Week must be a valid integer between 1 and 52! Please try again.')

    return endWeek

def main ():

    #call week validations
    startWeekVal = FirstValidation ('Start Week')
    endWeekVal = LastValidation ('End Week')


    #initialize min and max
    maxChange = 0
    minChange = 100
    maxIndex = 0
    minIndex = 0
    total = 0
    count = 0

    for j in range (startWeekVal, endWeekVal +1):
        if priceList [j][2] > maxChange:
            maxChange = priceList [j][2]
            maxIndex = j
        if priceList [j][2] < minChange:
            minChange = priceList [j][2]
            minIndex = j

        #calc average
        total += priceList [j][2]
        count += 1

        #compute average
        average = total / count

    print ('Start Week:', startWeekVal)
    print ('End Week:', endWeekVal)
    print ('The average change is ', average)
    print ('The week with the highest change is week' , priceList [maxIndex][0], 'with $', format (maxChange, '.2f'))
    print ('The week with the lowest change is week' , priceList [minIndex][0], 'with $', format (minChange, '.2f'))

    #close the file
    priceFile.close()

#call main
main ()

作为参考,这里是 .txt 文件:

52.33
50.99
52.29
55.09
50.16
50.50
51.82
51.30
52.03
53.07
53.49
54.21
55.57
54.42
55.65
51.78
49.87
50.39
51.08
50.62
52.32
51.79
51.48
50.13
49.83
51.16
52.30
53.70
56.57
56.68
57.96
57.94
57.62
58.03
57.67
56.21
57.25
57.43
57.60
57.80
57.42
59.66
59.87
58.71
59.02
60.35
60.53
59.25
61.97
62.30
63.24
62.14

我认为这段代码应该可以满足您的要求:

# get two dimensional list
priceList = []

#open the file
priceFile = open ('MicrosoftPrices.txt', 'r')

#create variable for start year
week = 1
price = float (priceFile.readline())

#special case for week 1

#initialize loop counter
i = 0

while price != '':
    priceList.append ([0,0,0])

    priceList [i][0] = week
    priceList [i][1] = float (price)

    if week == 1:
        priceList [i][2] = 0
    else:
        priceList[i][2] = (priceList[i][1] - priceList[i-1][1])

    #read the next line
    price = priceFile.readline()

    #add to the counter
    i += 1

    #go to next week
    week = week + 1

#initialize start and end weeks
startWeek = 0
endWeek = 0

#define start week validation
def FirstValidation (startWeek):

    startWeek = -1

    while startWeek == -1:
        startWeek = input ('What week would you like to start with?')

        try:
            if startWeek == '':
                startWeek = 1
                break

            startWeek = int (startWeek)

        except Exception:
            print ('Year must be a valid integer between 1 and 52')

        else:
            if startWeek >= 1 and startWeek <= 52:
                break
            else:
                startWeek = -1
                print ('ERROR: Week must be a valid integer between 1 and 52! Please try again.')

    return startWeek

#define end week validation
def LastValidation (endWeek):
    endWeek = -1

    while endWeek == -1:
        endWeek = input ('What week would you like to end with?')

        try:
            if endWeek == '':
                endWeek = 52
                break

            endWeek = int (endWeek)

        except Exception:
            print ('Year must be a valid integer between 1 and 52')
        else:
            if endWeek >= startWeek and endWeek <= 52:
                break
            else:
                endWeek = -1
                print ('ERROR: Week must be a valid integer between 1 and 52! Please try again.')

    return endWeek

def main ():

    #call week validations
    startWeekVal = FirstValidation ('Start Week')
    endWeekVal = LastValidation ('End Week')


    #initialize min and max
    maxChange = 0
    minChange = 100
    maxIndex = 0
    minIndex = 0
    total = 0
    count = 0

    print priceList

    for j in range (startWeekVal-1, endWeekVal):
        if priceList [j][2] > maxChange:
            maxChange = priceList [j][2]
            maxIndex = j
        if priceList [j][2] < minChange:
            minChange = priceList [j][2]
            minIndex = j

        #calc average
        total += priceList [j][2]
        count += 1

        #compute average

    average = total / count

    print ('Start Week:', startWeekVal)
    print ('End Week:', endWeekVal)
    print ('The average change is ', average)
    print ('The week with the highest change is week' , priceList [maxIndex][0], 'with $', format (maxChange, '.2f'))
    print ('The week with the lowest change is week' , priceList [minIndex][0], 'with $', format (minChange, '.2f'))

    #close the file
    priceFile.close()

#call main
main ()

有几个问题,您迭代的范围向上移动了一个。这意味着,如果您尝试让开始周为 1,结束周为 2,那么实际上应该是 2 和 3。然后,您试图跟踪每个子数组的第三个条目中的变化百分比,然后再次对它们进行平均。相反,跟踪第三个条目中的幅度变化,然后在最后取平均值。

我会推荐这样的东西

def stats(y, start, stop):
    maximum = max(y[start, stop])
    minimum = min(y[start, stop])
    average = sum(y[start, stop])/len(y[start, stop])
    return maximum, minimum, average

with open('prices.txt') as f:
    l = list(map(float, f.readlines()))

x = l[0]
y = []
for i in l:
    y.append(i-x)
    x=i

#We now have two lists.  l[i] has the price at week i, and 
    #y[i] has the change in price from week i-1

start_week = int(input("Start Week: ")) -1
end_week = int(input("End Week: "))

maximum, minimum, average = stats(y, start_week, end_week)

print("Maximum {}".format(maximum))
print("Minimum {}".format(minimum))
print("Average {}".format(average))