pythonjython

Why Do I Get List Indices Error When Changing How My Functions Are Called


This method is grabbing data from an API, and using a library I partially wrote called CAP. It takes three parameters the first two of which are dates, the third being an empty list to return data to.

    def getData(startDate, endDate, dataList):
        apiData = CAP.apiGet(9,startDate,endDate)
        
        for data in apiData:
            customer = CAP.dive(data, ['customer'])
            sName = CAP.dive(data, ['sName'])
            date = system.date.parse(CAP.dive(data, ['date']).replace('T', ' '))
            pounds = CAP.dive(data, ['lbs'])
                
            dataList.append([customer, sName, date, pounds])
        dataList.sort(key=lambda x: x[2])
        return dataList       

This method is used to create USABLE data by removing outliers that don't quite meet the conditions specified by a dictionary that is set outside of the program and pulled in through the CAP library. rowsData is dataList from the previous method, and tempRow is another empty list which now that I think about it I don't need because I can modify rowsData in place.

    def createData(rowsData, tempRow):
        weekAmount, total = 0, 0
        for idx, row in enumerate(rowsData):
            try:
                pounds, customer, product = row[3], row[0], row[1]
                rowDay, nextRowDay = row[2], rowsData[idx+1][2]
            except IndexError:
                tempRow.append(weekAmount)
            if customer == data['Customer'] and product == data['Product'] or product == 'All Products':
                weekAmount += pounds
                total += pounds
            if rowDay == nextRowDay:
                continue
            if STD.isoWeek(rowDay) < STD.isoWeek(nextRowDay):
                tempRow.append(weekAmount)
                weekAmount = 0        
        return [tempRow, total]

After all is said and done this is the method that actually puts everything together.

    def setupData():
        dt = system.date
        sumColumns, sumRows = [['WeekNumber'], ['lbs2020'], ['lbs2021'], ['lbs2022'], ['lbs2023'], ['Average']], []
        totalColumns, totalRows = [['total2020'], ['total2021'], ['total2022'], ['total2023']], []
        years = (dt.getYear(dt.now()) - 2020)
        
        yearData = []
        for year in range(years+1):
            year += 2020
            if year != 2023:
                startDate, endDate = STD.isoW01(year), STD.isoW01(year + 1)
            else:
                startDate, endDate = STD.isoW01(year), system.date.now()
            yearData.append(createData(getData(startDate, endDate, []), [])) 


        totalRows.append([yearData[0][1], yearData[1][1], yearData[2][1], yearData[3][1]])
        for i in range(53):
            if i < len(yearData[3]):
                count = sum(1 for year in yearData if year[0][i] > 0)
                sumRows.append([i+1, yearData[0][0][i], yearData[1][0][i], yearData[2][0][i], yearData[3][0][i], count])
            elif i < 52:
                count = sum(1 for year in yearData[:3] if year[0][i] > 0)
                sumRows.append([i+1, yearData[0][0][i], yearData[1][0][i], yearData[2][0][i], 0, count])
        sumRows.append([53, yearData[0][0][52], 0, 0, 0, 1])            
        data['Sums'] = system.dataset.toDataSet(sumColumns, sumRows)
        data['Total'] = system.dataset.toDataSet(totalColumns, totalRows)
    setupData()

This line works perfectly fine.

mtdData = structureData(getData(start, end, []), [])

However, when I switch it up like this

data = getData(start, end, [])
mtdData = structureData(data, [])

It doesn't seem to work and wants to give me a finalizeDataTypeError: list indices must be integers The block of code referencing mtdData is as such

data["Total"] = system.dataset.toDataSet([["mtdTotal"]], [[mtdData[1]]])

Does anyone know why you can do it the first way but not the second as it throws an error?

I've already tried printing out mtdData after switching the statements when I do

print(mtdData)

For both I get
([[Date_Here, Some_Data]], Some_Data)

I am trying to reference the first index of the tuple and because both the ways of structuring mtdData print the same thing out I am at a loss as to why it wouldn't work especially when the first index will always be the same.


Solution

  • If we compare:

    Code A:

    mtdData = structureData(getData(start, end, []), [])
    

    with Code B:

    data = getData(start, end, [])
    mtdData = structureData(data, [])
    

    Both of them set mtdData to the same thing. But the difference between them is that code B has the side effect of setting the value of data, while code A does not.

    So if your overall program works correctly with code A but not with code B, it's very likely that the variable data is relied on elsewhere in your program, and so the side-effect of code B is causing your problem.

    (If you're doing this inside a function, and data is a global variable, then its global value won't change, but all subsequent code within the function itself will use your new locally assigned value of data.)

    If you prefer to use two lines (like Code B), you can - just make sure to choose a variable name that isn't used elsewhere. Something like:

    temp_data = getData(start, end, [])
    mtdData = structureData(temp_data, [])