There are various posts related to infinite loops on here but none reflect my particular predicament (they deal with Java or they do not match my code format etc). The code I have used is actually source code or 'answer code' to an exercise aimed at new students such as myself and it only supplies the 'correct code without correct format' which for an independent student can complicate things but also provide a more productive challenge.
The code makes solid use of 'functions' and 'calling functions from within other functions' which leaves very little 'global code' as a result, this may make things slightly more complicated but hopefully experienced programmers won't be phased by this.
I think the loop is either an issue with my 'while loop code indentation' or the 'while loop condition/counter code itself'. The loop code takes and uses data from other parts of the program code and shouldn't be completely ruled out but realistically I suspect the problem is one of the two former possible issues of either indentation or internal loop code itself, I have already tried multiple variations of 'indentation layout' as well as making quick fixes (misstyped syntax etc).
The code in question can be found towards the end of the program code (there is only one 'while loop' in the program code) it is in the 'menu options' section of code under '# Loop through quotes selecting those referencing the appropriate month and store the data in the summary dictionary'.
I have included two separate code windows, one highlighting the suspected 'problem code' and the the other with 'full program code'. Any help in any aspect will be appreciated.
Code segment most likely to hold error
def monthlyReport():
file = open(QUOTES_TO_DATE_FILE, 'r')
text = file.read()
file.close()
quotes = text.split()
month = input('Enter month: ')
summary = {'Lawn':{'Quantity' : 0.0, 'Value' : 0.0}, 'Patio' :{'Quantity' : 0.0, 'Value' : 0.0}, 'Water Feature' :{'Quantity' : 0.0, 'Value' : 0.0}}
# Loop through quotes selecting those referencing the appropriate month and
#store the data in summary dictionary
index = 0
while True:
if quotes[index] == month:
inputQuotesFromFile2(quotes[index+1])
summary['Lawn']['Quantity'] = summary['Lawn']['Quantity'] + quote['Lawn']['Width'] * quote['Lawn']['Length']
summary['Lawn']['Value'] = summary['Lawn']['Value'] + quote ['Lawn']['Cost']
summary['Patio']['Quantity'] = summary['Patio']['Quantity'] + quote['Patio']['Width'] * quote['Patio']['Length']
summary['Patio']['Value'] = summary['Patio']['Value'] + quote['Patio']['Cost']
summary['Water Feature']['Quantity'] = summary['Water Feature']['Quantity'] + quote['Water Feature']['Quantity']
summary['Water Feature']['Value'] = summary['Water Feature']['Value'] + quote['Water Feature']['Cost']
index = index + 2
if (index >= len(quotes)):
break
totalValue = summary['Lawn']['Value'] + summary['Patio']['Value'] + summary['Water Feature']['Value']
outputSummaryDictionary(summary, month, totalValue)
Full program code
# `Dictionary containing time values (mins) per square metre/ per feature
##lawn:20 patio:20 water feature:60
TIME = {'Lawn': 20, 'Patio': 20, 'Water Feature': 60}
# Constant for labour cost
##16.49
LABOUR_COST = 16.49
# Variable for filename of list of quotes made to date
##quotesToDateFile
QUOTES_TO_DATE_FILE = 'quotesToDateFile.txt'
# 'Global variables'
# A dictionary that stores quote data temporarily, contains sub dicts for each
#material type including keys for length, width, cost, time/quantity,cost, time
quote = {'Lawn':{'Length': 0 , 'Width': 0 , 'Cost': 0.0 , 'Time': 0.0},
'Patio':{'Length': 0 , 'Width': 0, 'Cost': 0.0 , 'Time': 0.0 },
'Water Feature':{'Quantity': 0 , 'Cost': 0.0 , 'Time': 0.0}}
# A dictionary storing material costs of individual items (can be updated)
materialCost = {'Lawn': 15.5, 'Patio': 20.99, 'Water Feature': 150}
# 'Input'
# Function to input material info defined by a length
##create function with named parameter for 'item'
def inputItemDimensions(item):
s = 'Enter length of ' + item + ':'
length = int(input('Enter length of material: '))
s = 'Enter width of ' + item + ':'
width = int(input('Enter width of material: '))
return length, width
# Function to input material info defined by quantity
##create function with named parameter 'item
def inputItemQuantity(item):
s = 'Enter quantity of ' + item + ':'
quantity = int(input('Enter quantity of items: '))
return quantity
# Function for input of area and quantity
def itemInput():
global quote
quote['Lawn']['Length'], quote['Lawn']['Width'] = inputItemDimensions('lawn')
quote['Patio']['Length'], quote['Patio']['Width'] = inputItemDimensions('concrete patio')
quote['Water Feature']['Quantity'] = inputItemQuantity('water feature')
# 'Cost calculation'
# Function to calculate, output to screen, return the material cost and time
#to install a landscape item installed by length and width
def costCalculation1(num, item, length, width, cost, time):
print('[{0}]'.format(num))
print('Length and width of the {0} = {1} x {2}m'.format(item, length, width))
area = length * width
print('Total area of {0} = {1:.2f}m^2'.format(item, area))
print('Cost of {0} per m^2 = £{1:.2f}'.format(item, cost))
totalCost = area * cost
print('Total cost of {0} = £{1}\n'.format(item, totalCost))
totalTime = area * time
return totalCost, totalTime
# Function to calculate, output to screen and return the material cost and time
#to install a landscape item installed by quantity
def costCalculation2(num, item, quantity, cost, time):
print('[{0}]'.format(num))
print('Quantity of {0} = {1} items'.format(item, quantity))
print('Cost of one {0} = £{1:.2f}'.format(item, cost))
totalCost = quantity * cost
print("Total cost of {0} {1} = £{2}\n".format(quantity, item, totalCost))
totalTime = quantity * time
return totalCost, totalTime
# Function to calculate individual costs of items
def calculateItemCosts():
global quote
quote['Lawn']['Cost'], quote['Lawn']['Time'] = costCalculation1('1', 'lawn', quote['Lawn']['Length'], quote['Lawn']['Width'], materialCost['Lawn'], TIME['Lawn'])
quote['Patio']['Cost'], quote['Patio']['Time'] = costCalculation1('2', 'patio', quote['Patio']['Length'], quote['Patio']['Width'], materialCost['Patio'], TIME['Patio'])
quote['Water Feature']['Cost'], quote['Water Feature']['Time'] = costCalculation2('3', 'water features', quote['Water Feature']['Quantity'], materialCost['Water Feature'], TIME['Water Feature'])
# Function to calculate workimg costs and output them
def workingCost():
print('Working costs:')
totalTime = (quote['Lawn']['Time'] + quote['Patio']['Time'] + quote['Water Feature']['Time']) / 60
labourCost = totalTime * LABOUR_COST
print('Total time to complete work = {0} mins'.format(totalTime))
print('Cost of work per hour = £{0}'.format(LABOUR_COST))
print('Total cost of work = £{0}\n'.format(labourCost))
# Calculate total fee payable by customer, output to screen and file
materialCost = quote['Lawn']['Cost'] + quote['Patio']['Cost'] + quote['Water Feature']['Cost']
totalCost = materialCost + labourCost
print('Total cost to pay = £{0}\n'.format(totalCost))
# 'Output functions'
# Output details concerning item
def outputItems():
outputItems1('1', 'Lawn', quote['Lawn'])
outputItems1('2', 'Patio', quote['Patio'])
outputItems2('3', 'Water Feature', quote['Water Feature'])
# Output dimensions and cost for certain item
def outputItems1(num, item, itemDict):
print('[{0}]'.format(num))
print('Length of width of {0} = {1}m x {2}m'.format(item, itemDict['Length'], itemDict['Width']))
print('Total cost of {0} = £{1}'.format(item, itemDict['Cost']))
print('Time to install {0} = {1}mins\n'.format(item, itemDict['Time'] / 60))
# Output quantity and cost for item
def outputItems2(num, item, itemDict):
print('[{0}]'.format(num))
print('Quantity of {0} = {1} items'.format(item, itemDict['Quantity']))
print('Cost of one {0} = £{1:.2f}'.format(item, itemDict['Cost']))
print('Time to install {0} = {1:.2f} hours\n'.format(item, itemDict['Time'] / 60))
# Output material cost dictionary
def outputMaterialCostDictionary():
for key, value in materialCost.items():
print('{0} = {1}'.format(key, value))
print('\n')
# Output summary dictionary
def outputSummaryDictionary(summaryD, month, totalV):
outputSummaryItem1(['Month', month, '', '', ''])
outputSummaryItem1(['Total', '', 'Total', 'Total', 'Total'])
outputSummaryItem1(['Working', 'Item', 'Square metre', 'Number', 'Monthly'])
outputSummaryItem1(['Costs', '', 'Purchased', 'Purchased', 'Value'])
outputSummaryItem2('Lawn', summaryD['Lawn'])
outputSummaryItem2('Patio', summaryD['Patio'])
outputSummaryItem3('Water Feature', summaryD['Water Feature'])
outputSummaryItem4(totalV)
# Output summary dictionary item ver 1
def outputSummaryItem1(sList):
print('|{0:^13}|{1:^13}|{2:^13}|{3:^13}|{4:^13}|'.format(sList[0], sList[1], sList[2], sList[3], sList[4]))
# Output summary dictionary item ver 2
def outputSummaryItem2(name, item):
print('|{0:^13}|{1:^13}|{2:13.2f}|{3:^13}|{4:13.2f}|'.format('', name, item['Quantity'], '', item['Value']))
# Output summary dictionary item ver 3
def outputSummaryItem3(name, item):
print('|{0:^13}|{1:^13}|{2:^13}|{3:13.0f}|{4:13.2f}|'.format('', name, '', item['Quantity'], item['Value']))
# Output summary dictionary item ver 4
def outputSummaryItem4(totalValue):
print('|{0:^13}|{1:^13}|{2:^13}|{3:^13}|{4:13.2f}|'.format('Total', '', '', '', totalValue))
# 'File handling'
# Function to output file
def outputToFile():
filename = input('Enter file name: ')
file = open(filename, 'w')
month = input('Enter month:' )
print('Filename = {0}....Month = {1}\n'.format(filename, month))
file.write('{0}\n'.format(month))
s = '{0} {1} {2} {3}\n'.format(quote['Lawn']['Length'], quote['Lawn']['Width'], quote['Lawn']['Cost'], quote['Lawn']['Time'])
file.write(s)
s = '{0} {1} {2} {3}\n'.format(quote['Patio']['Length'], quote['Patio']['Width'], quote['Patio']['Cost'], quote['Patio']['Time'])
file.write(s)
s = '{0} {1} {2}\n'.format(quote['Water Feature']['Quantity'], quote['Water Feature']['Cost'], quote['Water Feature']['Time'])
file.write(s)
file.close()
# Update quotes to date file
file = open(QUOTES_TO_DATE_FILE, 'a')
s = '{0} {1}\n'.format(month, filename)
file.write(s)
file.close()
# Function to input quote from file where file name is not known
def inputQuoteFromFile1():
filename = input('Enter name for input file: ')
inputQuoteFromFile2(filename)
# Function to input quote from file when file IS known
def inputQuoteFromFile2(filename):
file = open(filename, 'r')
text = file.read()
list1 = text.split()
file.close()
# Process the data (ignore first item which is the month)
##declare 'quote' dict as global (this might mean this code is within function)
global quote
subDictionary = {'Length' : float(list1[1]), 'Width' : float(list1[2]), 'Cost' : float(list1[3]), 'Time' : float(list1[4])}
quote['Lawn'] = subDictionary
subDictionary = {'Length' : float(list1[5]), 'Width' : float(list1[6]), 'Cost' : float(list1[7]), 'Time' : float(list1[8])}
quote['Patio'] = subDictionary
subDictionary = {'Quantity' : float(list1[9]), 'Cost' : float(list1[10]), 'Time' : float(list1[11])}
quote['Water Feature'] = subDictionary
file.close()
# 'Menu options'
# Function to allow preperation of a new quote
def prepareANewQuote():
itemInput()
calculateItemCosts()
workingCost()
outputToFile()
# Function to load new material costs
def loadNewMaterialCosts():
filename = input('Enter filename: ')
file = open(filename, 'r')
text = file.read()
file.close()
newMaterialCosts = text.split()
# Assign costs to material cost dictionary
index = 0
for key in materialCost.keys():
materialCost['Key'] = float(newMaterialCosts['index'])
index = index + 1
# Output new material costs # NOTE MAY NEED TO BE INDENTED FURTHER
outputMaterialCostDictionary()
# Function to view and load existing quote
def viewExistingQuote():
inputQuoteFromFile1()
outputItems()
workingCost()
# Function to generate monthly report summary
def monthlyReport():
file = open(QUOTES_TO_DATE_FILE, 'r')
text = file.read()
file.close()
quotes = text.split()
month = input('Enter month: ')
summary = {'Lawn':{'Quantity' : 0.0, 'Value' : 0.0}, 'Patio' :{'Quantity' : 0.0, 'Value' : 0.0}, 'Water Feature' :{'Quantity' : 0.0, 'Value' : 0.0}}
# Loop through quotes selecting those referencing the appropriate month and
#store the data in summary dictionary
index = 0
while True:
if quotes[index] == month:
inputQuotesFromFile2(quotes[index+1])
summary['Lawn']['Quantity'] = summary['Lawn']['Quantity'] + quote['Lawn']['Width'] * quote['Lawn']['Length']
summary['Lawn']['Value'] = summary['Lawn']['Value'] + quote ['Lawn']['Cost']
summary['Patio']['Quantity'] = summary['Patio']['Quantity'] + quote['Patio']['Width'] * quote['Patio']['Length']
summary['Patio']['Value'] = summary['Patio']['Value'] + quote['Patio']['Cost']
summary['Water Feature']['Quantity'] = summary['Water Feature']['Quantity'] + quote['Water Feature']['Quantity']
summary['Water Feature']['Value'] = summary['Water Feature']['Value'] + quote['Water Feature']['Cost']
index = index + 2
if (index >= len(quotes)):
break
totalValue = summary['Lawn']['Value'] + summary['Patio']['Value'] + summary['Water Feature']['Value']
outputSummaryDictionary(summary, month, totalValue)
# 'Main' (initialisation)
# Top level function
def start():
while True :
print('Select one of following options')
print('(1) Prepare new quote')
print('(2) Load new cost data')
print('(3) Load and view existing quote')
print('(4) Generate monthly report summary')
print('(5) Exit')
selection = int(input())
if selection == 1:
prepareANewQuote()
elif selection == 2:
loadNewMaterialCosts()
elif selection == 3:
viewExistingQuote()
elif selection == 4:
monthlyReport()
elif selection == 5:
quit()
else:
print('Error unrecognised command')
# Start
start()
index never gets modified if quotes[index] does not equal month, so the code will keep checking the same value over and over again and never proceed.
You should unindent that assignment of index by one level. But really this is not an appropriate use of a while loop; you should use for to iterate over quotes:
for quote in quotes:
(Also note there are two while loops in this code; and actually far too much use of global.)
Related
I've written a python program that takes some inputs and turns them into a matplotlib graph. Specifically, it displays wealth distributions by percentile for a country of the user's choosing. However, these inputs are currently given by changing variables in the program.
I want to put this code on a website, allowing users to choose any country and see the wealth distribution for that country, as well as how they compare. Essentially, I am trying to recreate this: https://wid.world/income-comparator/
The code in python is all done but I am struggling to incorporate it into an HTML file. I was trying to use pyscript but it currently loads forever and displays nothing. Would rather not rewrite it in javascript (mainly because I don't know js). My thoughts are that it has something to do with the code importing csv files from my device?
import csv
from typing import List
import matplotlib.pyplot as plt
import collections
import math
from forex_python.converter import CurrencyRates
# ---------------- #
# whether or not the graph includes the top 1 percent in the graph (makes the rest of the graph visible!)
one_percent = False # True or False
# pick which country(ies) you want to view
country = 'China' # String
# what currency should the graph use
currency_used = 'Canada' # String
# if you want to compare an income
compare_income = True # True or False
# what income do you want to compare
income = 100000 # Int
# ---------------- #
codes = {}
# get dictionary of monetary country codes
monetary_codes = {}
with open('codes-all.csv') as csv_file:
list = csv.reader(csv_file, delimiter=',')
for row in list:
if row[5] == "":
monetary_codes[row[0]] = (row[2], row[1])
# get dictionary of country names and codes for WID
with open('WID_countries.csv') as csv_file:
WID_codes = csv.reader(csv_file, delimiter=',')
next(WID_codes)
for row in WID_codes:
if len(row[0]) == 2:
if row[2] != "":
monetary_code = monetary_codes[row[1].upper()][0]
currency_name = monetary_codes[row[1].upper()][1]
codes[row[1].upper()] = (row[0], monetary_code, currency_name)
elif row[2] == "":
codes[row[1].upper()] = (row[0], 'USD', 'United States Dollar')
elif row[0][0] == 'U' and row[0][1] == 'S':
codes[row[1].upper()] = (row[0], 'USD', 'United States Dollar')
# converts user input to upper case
country = country.upper()
currency_used = currency_used.upper()
# gets conversion rate
c = CurrencyRates()
conversion_rate = c.get_rate(codes[country][1], codes[currency_used][1])
# convert money into correct currency
def convert_money(conversion_rate, value):
return float(value) * conversion_rate
# get and clean data
def get_data(country):
aptinc = {}
# cleaning the data
with open(f'country_data/WID_data_{codes[country][0]}.csv') as csv_file:
data = csv.reader(csv_file, delimiter=';')
for row in data:
# I only care about the year 2021 and the variable 'aptinc'
if 'aptinc992' in row[1] and row[3] == '2021':
# translates percentile string into a numerical value
index = 0
for i in row[2]:
# index 0 is always 'p', so we get rid of that
if index == 0:
row[2] = row[2][1:]
# each string has a p in the middle of the numbers we care about. I also only
# care about the rows which measure a single percentile
# (upper bound - lower bound <= 1)
elif i == 'p':
lb = float(row[2][:index - 1])
ub = float(row[2][index:])
# if the top one percent is being filtered out adds another requirement
if not one_percent:
if ub - lb <= 1 and ub <= 99:
row[2] = ub
else:
row[2] = 0
else:
if ub - lb <= 1:
row[2] = ub
else: row[2] = 0
index += 1
# adds wanted, cleaned data to a dictionary. Also converts all values to one currency
if row[2] != 0:
aptinc[row[2]] = convert_money(conversion_rate, row[4])
return aptinc
# find the closest percentile to an income
def closest_percentile(income, data):
closest = math.inf
percentile = float()
for i in data:
difference = income - data[i]
if abs(difference) < closest:
closest = difference
percentile = i
return percentile
# ---------------- #
unsorted_data = {}
percentiles = []
average_income = []
# gets data for the country
data = get_data(country)
for i in data:
unsorted_data[i] = data[i]
# sorts the data
sorted = collections.OrderedDict(sorted(unsorted_data.items()))
for i in sorted:
percentiles.append(i)
average_income.append(data[i])
# makes countries pretty for printing
country = country.lower()
country = country.capitalize()
# calculates where the income places against incomes from country(ies)
blurb = ""
if compare_income:
percentile = closest_percentile(income, sorted)
blurb = f"You are richer than {round(percentile)} percent of {country}'s population"
# plot this data!
plt.plot(percentiles,average_income)
plt.title(f'{country} Average Annual Income by Percentile')
plt.xlabel(f'Percentile\n{blurb}')
plt.ylabel(f'Average Annual Income of {country}({codes[currency_used][1]})')
plt.axvline(x = 99, color = 'r', label = '99th percentile', linestyle=':')
if compare_income:
plt.axvline(x = percentile, color = 'g', label = f'{income} {codes[currency_used][2]}')
plt.legend(bbox_to_anchor = (0, 1), loc = 'upper left')
plt.show()
product_dict = {"Jeans": 150, "Jacket": 300, "Perfume": 50, "Wallet": 125, "Glasses": 100}
#product dictonary with prices
order_history = {'Andrew':[{'Jeans':2, 'Wallet': 4}, {'Perfume':2}], 'Max':[{'Jacket': 3}]}
c_name = input('customer name: ')
print('The following is order history of, c_name')
key = order_history['c_name']
for i in range(len(key)):
print('purchase', i+1, key[i])
I am creating a retail check out program, I have a predefined products stored in a dictionary along with prices that I use in other part of program, I wanted to print the output in a more presentable like this:
This is the order history of Andrew.
Jeans Wallet Perfume Jacket
Purchase 1: 2 4
Purchase 2: 2
This is more of a console display issue rather than a python issue.
You could potentially use a library for this, such as Textualize/rich. I don't want to give you the full answer, just lead you in the right direction as it appears you are learning:
from rich.console import Console
from rich.table import Table
console = Console()
table = Table(show_header=True, header_style="bold magenta")
table.add_column("Jeans", style="dim", width=12)
table.add_column("Jacket")
table.add_column("Perfume", justify="right")
table.add_column("Wallet", justify="right")
#add more columns as necessary
#iterate over your order history to add rows
table.add_row(
)
console.print(table)
In my opinion, creating a table in the console would look best.
Use a nested loop to print the quantity of each item, by looping over the keys of product_dict. Use end='' to print all the quantities on the same line, and use fixed-width fields in the formatting string to make everything line up.
product_dict = {"Jeans": 150, "Jacket": 300, "Perfume": 50, "Wallet": 125, "Glasses": 100}
#product dictonary with prices
order_history = {'Andrew':[{'Jeans':2, 'Wallet': 4}, {'Perfume':2}], 'Max':[{'Jacket': 3}]}
c_name = 'Andrew'
print(f'The following is order history of {c_name}')
print(' ' * 12, end='')
for product in product_dict:
print(f'{product:10}', end='')
print()
key = order_history[c_name]
for i, items in enumerate(key, 1):
print(f'Purchase {i}: ', end='')
for product in product_dict:
if product in items:
print(f'{items[product]:<10}', end='')
else:
print(' ' * 10, end='')
print()
If you want to accommodate additions to your dictionary with arbitrary length product names:
product_dict = {"Jeans": 150, "Jacket": 300, "Perfume": 50, "Wallet": 125, "Glasses": 100}
skus = list(product_dict)
width = 0
for sku in skus:
l = len(sku)
if l > width:
width = l
width = width + 2
pl = len('Purchase XX')
h = ' '.center(pl + 1,' ')
for sku in skus:
h = h + sku.center(width,' ')
#product dictonary with prices
order_history = {'Andrew':[{'Jeans':2, 'Wallet': 4}, {'Perfume':2}], 'Max':[{'Jacket': 3}]}
c_name = input('customer name: ')
print('The following is order history of', c_name)
print(h)
key = order_history[c_name]
for i in range(len(key)):
s = ''
for sku in skus:
if sku in list(key[i]):
s = s + str(key[i][sku]).center(width,' ')
else:
s = s + ' '.center(width,' ')
print('Purchase ' + str(i + 1).rjust(2,' ') + ' ' + s)
You'll get something like this:
The following is order history of Andrew
Jeans Jacket Perfume Wallet Glasses
Purchase 1 2 4
Purchase 2 2
I’m not so sure how to do the last part which is the dictionary part and ticker part, and also
On
“”file = open("/home/ubuntu/environment/hw5/" + tickers + “.txt”)””"
This line keep showing
TypeError: must be str, not list
Any suggestion on how to fix those or make the code works ?
Here’s my code
import json
def meanReversionStrategy(prices):
total_profit = 0
first_buy = None
buy = 0
for i in range(len(prices)):
if i >= 5:
current_price = prices[i]
moving_average = (prices[i-1] + prices[i-2] + prices[i-3] + prices[i-4] +prices[i-5]) / 5
if current_price < moving_average * 0.95 and buy == 0:
buy = current_price
print("buy at: ",round (current_price,2))
if first_buy is None:
first_buy = buy
elif current_price > moving_average * 1.05 and buy != 0:
print("sell at: ", round(current_price,2))
print("trade profit: ", round(current_price - buy,2))
total_profit = current_price - buy
buy = 0
final_profit_percentage = ( total_profit / first_buy ) * 100
print("First buy: " , round(first_buy,2))
print("Total profit: " , round(total_profit, 2))
print("Percentage return: ", round(final_profit_percentage, 2),"%")
def simpleMovingAverageStrategy(prices):
i = 0
buy = 0
total_profit = 0
first_buy = 0
for p in prices:
if i >= 5:
moving_average = (prices[i-1] + prices[i-2] + prices[i-3] + prices[i-4] +
prices[i-5]) / 5
#simple moving average logic, not mean
if p > moving_average and buy == 0: #buy
print("buying at: ", p)
buy = p
if first_buy == 0:
first_buy = p
elif p < moving_average and buy != 0: #sell
print("selling at: ", p)
print("trade profit: ", p - buy)
total_profit += p - buy
buy = 0
i += 1
final_percentage = (total_profit / first_buy) * 100
print("first buy: ", first_buy)
print("total profit: ", total_profit)
print("final percentage: ", final_percentage, "%")
return total_profit, final_percentage
tickers = ["AAPL1" , "ADBE" , "BA", "CMCSA", "CSCO", "CVS", "GOOG", "TLSYY","TM"]
file = open("/home/ubuntu/environment/hw5/" + tickers + ".txt")
lines = file.readlines()
# print(lines)
prices = []
for line in lines:
prices.append(float(line))
profit, returns = simpleMovingAverageStrategy(prices)
results = {}
results["AAPL1_profit"] =profit
results["AAPL1_returns"] = returns
json.dump(results, open("/home/ubuntu/environment/hw5/results.json", "w") )
Coding Requirements
-Create a function called meanReversionStrategy which takes a list called “prices” as an argument. The function runs a mean reversion strategy, and outputs to the console the buys and sells of the strategy (like you did in HW4). The function returns the profit and final returns percentage.
-Create a function called simpleMovingAverageStrategy which takes a list called “prices” as an argument. The function runs a Simple Moving Average strategy, and outputs to the console the buys and sells of the strategy. The function returns the profit and final returns percentage.
-Create a function called saveResults which takes a dictionary as an argument. Save the dictionary to a json file called “results.json”.
loop through the list of tickers
for ticker in tickers:
-load prices from a file <ticker>.txt, and store them in the results dictionary with the
key “<ticker>_prices”
-call meanReversionStrategy(prices) and store the profit and returns in the results
dictionary with the keys “<ticker>_mr_profit” and “<ticker>_mr_returns”
-call simpleMovingAverageStrategy(prices) and store the profit and returns in the
results dictionary with the keys “<ticker>_sma_profit” and “<ticker>_sma_profit”
with the keys “ticker_mr_profit” and “ticker_mr_returns”
call saveResults(results) and save the results dictionary to a file called results.json
Welcome!
As this is a homework question, I will not solve it for You, but here is my advice for You:
tickers is an array and as your homework description states, You must 'loop through the list of tickers' and open each of them. So how do You loop over tickers?
And reflect about the error. What do You think should be the result of "/home/ubuntu/environment/hw5/" + tickers + ".txt"?
class CovidRecord:
def __init__(self, pruid, prname, prnameFR, date, update, numcomf, numprob, numdeaths, numtotal):
self.pruid = pruid
self.prname = prname
self.prnameFR = prnameFR
self.date = date
self.update = update
self.numconf = numcomf
self.numprob = numprob
self.numdeaths = numdeaths
self.numtotal = numtotal
def __str__(self):
return self.pruid + self.prname + self.prnameFR + self.date + self.update + self.numconf + self.numprob + self.numdeaths + self.numtotal`
def write_to_dataframe(self):
dataframe = pd.read_csv(r'C:\Users\jakev\Downloads\covid19-download.csv')
dataframetop = dataframe.head(6)
print('Please insert information to add')
pruid = input('Province ID: ')
prname = input('Province name: ')
prnameFR = input('Province name in French: ')
date = input('Date: ')
update = input('When was it updated: ')
numcomf = input('Confirmed cases: ')
numprob = input('Probable cases: ')
numdeaths = input('Number of deaths ')
numtotal = input('Total number')
newrecord = CovidRecord(pruid, prname, prnameFR, date, update, numcomf, numprob, numdeaths, numtotal)
dfobj = pd.DataFrame(newrecord, columns = ['prvid', 'prname', 'prnameFR', 'date', 'update', 'numcomf', 'numprob'
, 'numdeaths', 'numtotal', 'newrecord'], index=['1'])
newdataframe = dataframetop.append(dfobj, ignore_index = True)
print(newdataframe)
CovidRecord is a record object I've created to load additional records into a dataframe. When I input the responses to the inputs in the terminal, it prints out a giant String with each of my responses under every single column instead of separating them into their individual rightful columns. How can I make it so that when I enter the "prvname" it puts my answer only under province name and so on? Below is an example of the output I get.
pruid prname prnameFR date
0 35.0 Ontario Ontario 2020-01-31
1 59.0 British Columbia Colombie-Britannique 2020-01-31
6 NaN 23OntarioOntario2021-02-182021-02-182334278 23OntarioOntario2021-02-182021-02-182334278 23OntarioOntario2021-02-182021-02-182334278
the bottom record being the one I attempted to insert. It taking all my answers to each input, putting them into 1 String and then putting that one giant string into each column.
What am I missing?
Thanks.
str returning one giant string
You are putting them together yourself with following line:
return self.pruid + self.prname + self.prnameFR + self.date + self.update + self.numconf + self.numprob + self.numdeaths + self.numtotal
import xlrd
import numpy
fileWorkspace = 'C://Users/jod/Desktop/'
wb1 = xlrd.open_workbook(fileWorkspace + 'assign2.xls')
sh1 = wb1.sheet_by_index(0)
time,amount,category = [],[],[]
for a in range(2,sh1.nrows):
time.append(int(sh1.cell(a,0).value)) # Pulling time from excel (column A)
amount.append(float(sh1.cell(a,1).value)) # Pulling amount from excel (column B)
category.append(str(sh1.cell(a,2).value)) # Pulling category from excel (column C)
#print(time)
#print(amount)
#print(category)
print('\n')
p_p2 = str(sh1.cell(0,1))
p_p1 = p_p2.replace("text:'","")
pp = p_p1.replace("'","")
print(pp) # Printing the type of pay period (Row 1, col B)
c_p2 = str(sh1.cell(1,1))
c_p1 = c_p2.replace("text:'","")
cp = c_p1.replace("'","")
print(cp) # Printing the type of compound period (Row 2, col B)
netflow = 0
outflow = 0
inflow = 0
flow = 0
cat = ["Sales", "Salvage", "Subsidy", "Redeemable", "Utility", "Labor",
"Testing", "Marketing", "Materials", "Logistics"]
if pp == "Years" and cp == "Years": # if pay period and compound period are both in years
IRR = numpy.irr(amount) * 100 # Calculates the internal rate of return (IRR)
print ("IRR:", round(IRR, 2), '%', '\n') # prints (IRR)
for i in time: # for every value in time array
if cat[5] in category: # if "Labor" for cat array is in category array or not
# calculates the present values using all the amount values (col B) instead of
# just using the ones that has "Labor" category label beside them
# Need to make every other value 0, such as beside "Redeemable" and "Salvage"
flow = amount[i] / numpy.power((1 + (IRR/100)), time[i])
if flow>0:
inflow = inflow + flow
if flow<0:
outflow = outflow + flow
print ('Present Value (P) is:', round(flow,0), '\n')
netflow = outflow + inflow
print("In year 0 or current year")
print("-------")
print ('Outflow is: ', round(outflow,0))
print ('Inflow is: ', round(inflow,0))
print ('Netflow is: ', round(netflow,0), '\n')
outflow2 = (round(outflow,0))*(1+(IRR/100))**(9)
inflow2 = (round(inflow,0))*(1+(IRR/100))**(9)
netflow2 = outflow2 + inflow2
print("In year 9")
print("-------")
print ('Outflow is: ', round(outflow2,0))
print ('Inflow is: ', round(inflow2,0))
print ('Netflow is: ', round(netflow2,0), '\n')
I have commented important lines of code for clarification.
Here is the original question:
illustrate the breakdown of major project revenues and expenses by category as a percentage of that project’s future value in year 9. The illustration must also clearly indicate the total future value of the project in year 9 as well as the IRR.
There will be a total of 10 revenue and cost categories that a project may be composed of. The categories are: Sales, salvage, subsidy, redeemable, utility, labor, testing, marketing, materials and logistics. All revenues and expenses will fall in one of these ten categories. The project pay period and compound period will be identified at the top of the Excel sheet. Pay period and compound period may be designated as any of the following: years, quarters, months.
I am getting confused because I am not able to pull the only values from beside the "Labor", "Redeemable", or "Salvage". I just don't know where I am making a mistake, or there is something that is incomplete. Below is the excel file image:
Excel File Image 2
Excel File Image 3
After revising, all cashflows are discounted at the irr. What is done is the following:
i) determineAdjustments takes the pay period (column A) and adjusts if for the year ended (if it is a monthly amount it puts it in the proper year ended) and if its monthly puts in in the month ended (no adjustment necessary). This will divide the pay period by 12 if yearly cash flows are needed (yearly compounding)
ii) IRR is calculated, and the compounding period is used to adjust the monthly IRR for monthly pay periods
iii) all expenses are discounted at the IRR and input into a list for cat_contributions['category_name'] = [discounted period 1, discounted period 2 ... ]
iv) Then the net inflows and outflows are sums of these.
I can't type up data in the spreadsheets from the images as that would take a while, but maybe tinker with this and see if you can get it to work.
from __future__ import division
import xlrd
import numpy
import os
import math
def main(xls = 'xls_name.xlsx', sh = 0):
#save script in same folder as the xls file
os.chdir( os.getcwd() )
wb = xlrd.open_workbook(xls)
sh = wb.sheet_by_index(0)
pay_period = sh.cell_value(0,1)
compounding_period = sh.cell_value(1,1)
compounding_factor, pay_factor = determineAdjustments(
pay_period, compounding_period)
number_of_periods = max( sh.col_values(0, start_rowx = 2) )
flow_per_period = [ 0*i for i in range( int( math.ceil( number_of_periods/pay_factor ) ) + 1 ) ]#list of length number of pay_periods
for r in range(2,sh.nrows):
pay_period = int( math.ceil( sh.cell_value(r,0) / pay_factor ) )
flow_per_period[pay_period] += sh.cell_value(r,1) #unadjusted cash flows
irr = calculateIRR(flow_per_period, compounding_factor)
cat_contributions = sortExpenditures(sh, irr, pay_factor)
total_cat_contributions, netflow, total_outflow, total_inflow = calculateFlows(cat_contributions)
printStats(cat_contributions, irr, compounding_factor, pay_factor,
total_cat_contributions, netflow, total_outflow, total_inflow)
return
def determineAdjustments(pay_period, compounding_period):
if compounding_period == 'years':
compounding_factor = 1
if pay_period == 'months':
pay_factor = 12
if pay_period == 'years':
pay_factor = 1
#assume no days pay periods
if compounding_period == 'months':
compounding_factor = 12
#assume no yearly payouts and that the
#all payments are in months
pay_factor = 1
return compounding_factor, pay_factor
def calculateIRR(cashflow, compounding_factor):
irr = numpy.irr(cashflow)
irr_comp = (1 + irr)**compounding_factor - 1
#seems like in first example it uses rounded irr, can do something like:
#irr_comp = round(irr_comp,4)
return irr_comp
def sortExpenditures(sh, irr, pay_factor):
#percentages and discounting occurs at the IRR caculated in the main
#function
cat = ["Sales", "Salvage", "Subsidy", "Redeemable", "Utility", "Labor",
"Testing", "Marketing", "Materials", "Logistics"]
#python dictionary to sort contributions into categories
cat_contributions = {}
for c in cat:
cat_contributions[c] = []
# create list of contributions of each list item to FV in a dictionary
for r in range(2,sh.nrows):
try:
#discounted cash flow of each expenditure
#using formula FV = expenditure/(1+i)^n
cat_contributions[sh.cell_value(r,2)].append(
sh.cell_value(r,1) / ( (1 + irr) ** (sh.cell_value(r,0)/pay_factor) )
)
except KeyError:
print "No category for type: " + sh.cell_value(r,2) +'\n'
return cat_contributions
def calculateFlows(cat_contributions):
total_outflow = 0
total_inflow = 0
total_cat_contributions = {}
for cat in cat_contributions:
total_cat_contributions[cat] = sum( cat_contributions[cat] )
if total_cat_contributions[cat] < 0:
total_outflow += total_cat_contributions[cat]
else:
total_inflow += total_cat_contributions[cat]
netflow = total_inflow + total_outflow
return total_cat_contributions, netflow, total_outflow, total_inflow
def printStats(cat_contributions, irr, compounding_factor, pay_period,
total_cat_contributions, netflow, total_outflow, total_inflow):
print "IRR: "+str(irr*100) +' %'
if compounding_factor == 1: print "Compounding: Yearly"
if compounding_factor == 12: print "Compounding: Monthly"
if pay_period == 1: "Cashflows: Year Ended"
if pay_period == 12: "Cashflows: Month Ended"
print "Future Value (Net Adjusted Cashflow): " +str(netflow)
print "Adjusted Inflows: " + str(total_inflow)
print "Adjusted Outflows: " + str(total_outflow) +'\n'
for cat in total_cat_contributions:
if total_cat_contributions[cat] != 0:
print '-----------------------------------------------------'
print cat + '\n'
print "Total Contribution to FV " + str( total_cat_contributions[cat] )
if total_cat_contributions[cat] < 0:
print "Contribution to Expenses: " + str ( abs(100 * total_cat_contributions[cat]/total_outflow) )
else:
print "Contribution to Revenues: " + str ( abs(100 * total_cat_contributions[cat]/total_inflow) ) +'\n'
main(xls='Book1.xlsx')