-1
from statistics import stdev

data = [line.rstrip('\n').split(',') for line in open('C:/Users/User/Downloads/documents-export-2016-05-04/Data.csv')]
dates = list(open('C:/Users/User/Downloads/documents-export-2016-05-04/Dates.csv').read().split('\n'))
stock_values = [int(x) for x in open('C:/Users/User/Downloads/documents-export-2016-05-04/stock_value.csv').read().split(',')]
companies = open('C:/Users/User/Downloads/documents-export-2016-05-04/companies.csv').read().split(',')
prices = dict(zip(companies, stock_values))

PRICE = 0
old_volatility = 0
new_volatility = 0

def get_change(values, invested):
    sum_product = ([x * y for x, y in zip(values, invested)])
    return(sum(sum_product) / sum(invested))


def get_volatility(invested):
    changes = {}
    for i, j in enumerate(list(reversed(dates))):
        changes[j] = get_change(list(map(float, data[i])), invested.values())
    vals = changes.values()
    volatility = stdev(vals)
    return volatility


def tuner(invested, company):
    global PRICE
    global old_volatility

    temp_invested = invested.copy()
    temp_invested[company] += 1
    new_volatility = get_volatility(temp_invested)
    new_price = PRICE + prices[company]
    if new_volatility - old_volatility < -0.01 and new_price <= BUDGET:
        old_volatility = new_volatility
        PRICE = new_price
        tuner(temp_invested, company)
    else:
        return invested


if __name__ == "__main__":
    BUDGET = int(input())

    invested = {}
    for company in companies: invested[company] = 0
    invested['A'] = 1
    old_volatility = get_volatility(invested)

    for company in companies:
        if PRICE < BUDGET:
            invested = tuner(invested, company)
        else:
            break
    print("Price = ", PRICE)
    print("Volatility = ", old_volatility)

For some reason in the above code, after 3 iterations of the for loop "for company in companies", I get an error that says "'NoneType' object has no attribute 'copy'", referring to the dictionary 'invested'. I don't understand why after a few iterations, the dictionary would suddenly be treated as NoneType. The original data are just being read in as lists of strings so they don't really matter. Any help is appreciated. Thanks.

ENPM
  • 167
  • 2
  • 9

1 Answers1

4

One of your branches in your tuner function doesn't return anything, so invested gets set to None when that branch is taken.

Cubic
  • 14,902
  • 5
  • 47
  • 92
  • But that other branch of `tuner` recursively calls itself and I know from the data that the `else` branch has to be taken eventually, so it will return `invested` as it should. Besides, the few iterations that do works actually take the former branch. – ENPM May 05 '16 at 11:42
  • 1
    @ENPM It recursively calls itself but it doesn't return the value it gets from that recursive call. – Cubic May 05 '16 at 11:43