update,
This commit is contained in:
1
hyhl_1022/.gitignore
vendored
Normal file
1
hyhl_1022/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
**/*.txt
|
114
hyhl_1022/1st_copy/NOTES.md
Normal file
114
hyhl_1022/1st_copy/NOTES.md
Normal file
@@ -0,0 +1,114 @@
|
||||
### objective
|
||||
|
||||
env: Windows
|
||||
deadline 23/12
|
||||
|
||||
|
||||
### CAUTION
|
||||
Do not include any code not written by you in your
|
||||
project. You are NOT allowed to import any Python libraries in your solution except the
|
||||
modules namely os (https://docs.python.org/3/library/os.html), sys
|
||||
(https://docs.python.org/3/library/sys.html) and csv (https://docs.python.org/3/library/csv.html). If
|
||||
cheating is found or the import requirement is violated, you will receive a zero mark.
|
||||
|
||||
|
||||
### Deliverable
|
||||
You have to include your student name and ID in your source code and name your project solution as
|
||||
“XXXXXXXX_project.py” (where XXXXXXXX is your 8-digit student ID). Please remember to
|
||||
upload your source code solution to Moodle by the submission deadline.
|
||||
|
||||
|
||||
### drill down
|
||||
|
||||
Functions
|
||||
Given the file of stock prices, you are asked to develop a Python program to process the data by
|
||||
designing appropriate functions. At minimum you need to implement and call the following three
|
||||
functions:
|
||||
• get_data_list(csv_file_name)
|
||||
This function has one parameter, namely csv_file_name. When the function is called, you
|
||||
need to pass along a CSV file name which is used inside the function to open and read the CSV
|
||||
file. After reading each row, it will be split into a list. The list will then be appended into a main
|
||||
list (a list of lists), namely data_list. The data_list will be returned at the end of the
|
||||
function.
|
||||
2
|
||||
• get_monthly_averages(data_list)
|
||||
This function has one parameter, namely data_list. You need to pass the data_list
|
||||
generated by the get_data_list() function as the argument to this function and then
|
||||
calculate the monthly average prices of the stock. The average monthly prices are calculated in
|
||||
the following way. Suppose the volume and adjusted closing price of a trading day are V1 and C1,
|
||||
respectively. The total sale of that day equals V1 x C1. Now, suppose the volume and adjusted
|
||||
closing price of another trading day are V2 and C2, respectively. The average of these two trading
|
||||
days is the sum of the total sales divided by the total volume:
|
||||
Average price = (V1 x C1 + V2 x C2) / (V1 + V2)
|
||||
To average a whole month, you need to add up the total sales (V1 x C1 + V2 x C2 + ... +
|
||||
Vn x Cn) for each day and divide it by the sum of all volumes (V1 + V2 + ... + Vn) where n
|
||||
is the number of trading days in the month.
|
||||
A tuple with 2 items, including the date (year and month only) and the average for that month,
|
||||
will be generated for each month. The tuple for each month will be appended to a main list,
|
||||
namely monthly_averages_list. The monthly_averages_list will be returned at
|
||||
the end of the function.
|
||||
• get_moving_averages(monthly_averages_list)
|
||||
This function has one parameter, namely monthly_averages_list. You need to pass the
|
||||
monthly_averages_list generated by get_monthly_averages() as the argument
|
||||
to this function and then calculate the 5-month exponential moving average (EMA) stock prices.
|
||||
In general, the EMA for a particular month can be calculated by the following formula:
|
||||
EMA = (Monthly average price – previous month’s EMA) x smoothing constant
|
||||
+ previous month’s EMA
|
||||
where
|
||||
smoothing constant = 2 / (number of time periods in months + 1)
|
||||
3
|
||||
For example, the following table shows the stock prices between Oct 2020 and Apr 2021:
|
||||
Month Monthly Average Price
|
||||
Oct 2020 14
|
||||
Nov 2020 13
|
||||
Dec 2020 14
|
||||
Jan 2021 12
|
||||
Feb 2021 13
|
||||
Mar 2021 12
|
||||
Apr 2021 11
|
||||
The initial 5-month EMA for Feb 2021 can be calculated by the simple average formula, as
|
||||
shown below:
|
||||
5-month EMA for Feb 2021 = (14 + 13 + 14 + 12 + 13) / 5 = 13.2
|
||||
The 5-month EMA for Mar 2021 can be calculated by the EMA formula, as shown below:
|
||||
5-month EMA for Mar 2021 = (Monthly average price – previous month’s EMA) x
|
||||
smoothing constant + previous month’s EMA
|
||||
= (12 – 13.2) x (2 / 6) + 13.2
|
||||
= 12.8
|
||||
The 5-month EMA for Apr 2021 can be calculated by the EMA formula, as shown below:
|
||||
5-month EMA for Apr 2021 = (Monthly average price – previous month’s EMA) x
|
||||
smoothing constant + previous month’s EMA
|
||||
= (11 – 12.8) x (2 / 6) + 12.8
|
||||
= 12.2
|
||||
The resulting 5-month EMA stock prices are shown below:
|
||||
Month Average Price 5-month EMA Price
|
||||
Oct 2020 14 -
|
||||
Nov 2020 13 -
|
||||
Dec 2020 14 -
|
||||
Jan 2021 12 -
|
||||
Feb 2021 13 13.2
|
||||
Mar 2021 12 12.8
|
||||
Apr 2021 11 12.2
|
||||
4
|
||||
A tuple with 2 items, including the date (year and month only) and the 5-month EMA price for
|
||||
that month, will be generated for each month except the first 4 months. Each tuple will be
|
||||
appended to a main list, namely moving_averages_list. The
|
||||
moving_averages_list will be returned at the end of the function.
|
||||
|
||||
|
||||
Program Input and Output
|
||||
At the outset, your program needs to ask the user for a CSV file name:
|
||||
Based on the entered CSV file name, a corresponding output text file (e.g. “Google_output.txt”
|
||||
for this case) will be generated. In the output file, you are eventually required to print the best month
|
||||
(with the highest EMA price) and the worst month (with the lowest EMA price) for the stock. You
|
||||
need to first print a header line for the stock, and then print a date (MM-YYYY), a comma followed by
|
||||
a moving average price (in 2 decimal places) on another line. You must follow the output format as
|
||||
shown below (please note the values are not true, which are for reference only)
|
||||
|
||||
|
||||
IV. Evaluation Criteria (40% of Overall Course Assessment)
|
||||
The project will be graded using the following criteria:
|
||||
• 15% - Correctness of program execution and output data
|
||||
• 10% - Modularization (e.g. dividing the program functionality into different functions)
|
||||
• 5% - Error handling
|
||||
• 5% - Consistent style (e.g., capitalization, indenting, etc.)
|
||||
• 5% - Appropriate comments
|
Binary file not shown.
1031
hyhl_1022/1st_copy/_ref/google.csv
Normal file
1031
hyhl_1022/1st_copy/_ref/google.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
hyhl_1022/1st_copy/_ref/steps.ods
Normal file
BIN
hyhl_1022/1st_copy/_ref/steps.ods
Normal file
Binary file not shown.
15
hyhl_1022/1st_copy/_ref/test.csv
Normal file
15
hyhl_1022/1st_copy/_ref/test.csv
Normal file
@@ -0,0 +1,15 @@
|
||||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2008-07-04,460,463.24,449.4,450.26,450.26,4848500
|
||||
2008-07-03,468.73,474.29,459.58,464.41,464.41,4314600
|
||||
2008-06-02,476.77,482.18,461.42,465.25,465.25,6111500
|
||||
2008-06-29,469.75,471.01,462.33,463.29,463.29,3848200
|
||||
2008-05-08,452.02,452.94,417.55,419.95,419.95,9017900
|
||||
2008-05-05,445.49,452.46,440.08,444.25,444.25,4534300
|
||||
2008-04-04,460,463.24,449.4,450.26,450.26,4848500
|
||||
2008-04-03,468.73,474.29,459.58,464.41,464.41,4314600
|
||||
2008-03-02,476.77,482.18,461.42,465.25,465.25,6111500
|
||||
2008-03-29,469.75,471.01,462.33,463.29,463.29,3848200
|
||||
2008-02-28,472.49,476.45,470.33,473.78,473.78,3029700
|
||||
2008-02-27,473.73,474.83,464.84,468.58,468.58,4387100
|
||||
2008-01-28,472.49,476.45,470.33,473.78,473.78,3029700
|
||||
2008-01-27,473.73,474.83,464.84,468.58,468.58,4387100
|
|
16
hyhl_1022/1st_copy/build.sh
Normal file
16
hyhl_1022/1st_copy/build.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
rm -rf _temp/*
|
||||
rm -rf delivery.zip
|
||||
|
||||
mkdir -p _temp
|
||||
|
||||
set -ex
|
||||
|
||||
cp src/main.py _temp/XXXXXXXX_project.py
|
||||
|
||||
pushd _temp
|
||||
7za a -tzip ../delivery1.zip *
|
||||
popd
|
||||
|
||||
rm -rf _temp
|
11
hyhl_1022/1st_copy/src/Pipfile
Normal file
11
hyhl_1022/1st_copy/src/Pipfile
Normal file
@@ -0,0 +1,11 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.11"
|
243
hyhl_1022/1st_copy/src/main.py
Normal file
243
hyhl_1022/1st_copy/src/main.py
Normal file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Do not include any code not written by you in your project.
|
||||
# You are NOT allowed to import any Python libraries in your solution except the modules namely
|
||||
# - os (https://docs.python.org/3/library/os.html),
|
||||
# - sys (https://docs.python.org/3/library/sys.html) and
|
||||
# - csv (https://docs.python.org/3/library/csv.html).
|
||||
#
|
||||
# If cheating is found or the import requirement is violated, you will receive a zero mark.
|
||||
|
||||
import os,sys, csv
|
||||
|
||||
# column from csv file
|
||||
# COL_DATE: the day of trading
|
||||
# COL_OPEN: the stock price at the beginning of the trading day
|
||||
# COL_HIGH: the highest price the stock achieved on the trading day
|
||||
# COL_LOW: the lowest price the stock achieved on the trading day
|
||||
# COL_CLOSE: the stock price at the end of the trading day
|
||||
# COL_ADJ_Close: the adjusted closing price of the trading day (reflecting the stock’s value after accounting for any corporate actions like dividends, stock splits and new stock offerings)
|
||||
# COL_VOLUME: the total number of shares were traded on the trading day
|
||||
COL_DATE=0
|
||||
COL_OPEN=1
|
||||
COL_HIGH=2
|
||||
COL_LOW=3
|
||||
COL_CLOSE=4
|
||||
COL_ADJ_CLOSE=5
|
||||
COL_VOLUME=6
|
||||
|
||||
# append at middle stage
|
||||
COL_TOTAL_SALE_OF_DAY=7
|
||||
COL_MONTH_ONLY=8
|
||||
COL_EMA=9
|
||||
|
||||
# monthly_averages_list
|
||||
COL_MONTHLY_AVERAGE_PRICE=1
|
||||
COL_EMA=2
|
||||
|
||||
|
||||
# get_data_list(csv_file_name)
|
||||
# This function has one parameter, namely csv_file_name.
|
||||
# When the function is called, you need to pass along a CSV file name which is used inside the function to open and read the CSV
|
||||
# file.
|
||||
# After reading each row, it will be split into a list. The list will then be appended into a main
|
||||
# list (a list of lists), namely data_list. The data_list will be returned at the end of the
|
||||
# function.
|
||||
def get_data_list(csv_file_name):
|
||||
'''read data list from csv file'''
|
||||
data_list = []
|
||||
try:
|
||||
with open(csv_file_name, newline='') as csvfile:
|
||||
temp = []
|
||||
temp = csv.reader(csvfile, delimiter=',', quotechar='"')
|
||||
data_list = list(temp)
|
||||
|
||||
return data_list
|
||||
except Exception as e:
|
||||
print('error during reading csv file ')
|
||||
print('exitting...')
|
||||
sys.exit()
|
||||
|
||||
|
||||
# get_monthly_averages(data_list)
|
||||
# This function has one parameter, namely data_list. You need to pass the data_list
|
||||
# generated by the get_data_list() function as the argument to this function and then
|
||||
# calculate the monthly average prices of the stock. The average monthly prices are calculated in
|
||||
# the following way.
|
||||
#
|
||||
# 1. Suppose the volume and adjusted closing price of a trading day are V1 and C1, respectively.
|
||||
# 2. The total sale of that day equals V1 x C1.
|
||||
# 3. Now, suppose the volume and adjusted closing price of another trading day are V2 and C2, respectively.
|
||||
# 4. The average of these two trading days is the sum of the total sales divided by the total volume:
|
||||
#
|
||||
# Average price = (V1 x C1 + V2 x C2) / (V1 + V2)
|
||||
#
|
||||
# To average a whole month, you need to
|
||||
# - add up the total sales (V1 x C1 + V2 x C2 + ... + Vn x Cn) for each day and
|
||||
# - divide it by the sum of all volumes (V1 + V2 + ... + Vn) where n is the number of trading days in the month.
|
||||
# A tuple with 2 items, including the date (year and month only) and the average for that month,
|
||||
# will be generated for each month. The tuple for each month will be appended to a main list,
|
||||
# namely monthly_averages_list. The monthly_averages_list will be returned at the end of the function.
|
||||
|
||||
def get_monthly_averages(data_list):
|
||||
'''calculate the monthly average prices of the stock'''
|
||||
|
||||
monthly_averages_list=[]
|
||||
data_list_data_only = data_list[1:]
|
||||
month_available = []
|
||||
|
||||
# data cleaning
|
||||
for i in range(len(data_list_data_only)):
|
||||
# V1 x C1, calculate the total sale, append into column
|
||||
data_list_data_only[i].append(float(data_list_data_only[i][COL_VOLUME]) * float(data_list_data_only[i][COL_ADJ_CLOSE]))
|
||||
|
||||
# mark the row by YYYY-MM for easy monthly sum calculation, COL_MONTH_ONLY
|
||||
data_list_data_only[i].append(data_list_data_only[i][COL_DATE][0:7])
|
||||
|
||||
# get the month in the list YYYY-MM
|
||||
month_available = set(list(map(lambda x: x[COL_MONTH_ONLY], data_list_data_only)))
|
||||
|
||||
# literate the whole list, calculate the total_sale and total volume
|
||||
# get the average sale by total_sale / total_volume
|
||||
for month in sorted(month_available):
|
||||
filtered_month = list(filter(lambda x: x[COL_MONTH_ONLY] == month, data_list_data_only))
|
||||
total_sale = sum(list( map(lambda x: x[COL_TOTAL_SALE_OF_DAY], filtered_month)))
|
||||
total_volume = sum(list( map(lambda x: float(x[COL_VOLUME]), filtered_month)))
|
||||
monthly_averages_list.append([month, total_sale/total_volume])
|
||||
|
||||
return list(monthly_averages_list)
|
||||
|
||||
# get_moving_averages(monthly_averages_list)
|
||||
# This function has one parameter, namely monthly_averages_list. You need to pass the
|
||||
# monthly_averages_list generated by get_monthly_averages() as the argument
|
||||
# to this function and then calculate the 5-month exponential moving average (EMA) stock prices.
|
||||
# In general, the EMA for a particular month can be calculated by the following formula:
|
||||
#
|
||||
# EMA = (Monthly average price – previous month’s EMA) x smoothing constant + previous month’s EMA
|
||||
#
|
||||
# where
|
||||
#
|
||||
# smoothing constant = 2 / (number of time periods in months + 1)
|
||||
#
|
||||
# Initial SMA = 20-period sum / 20
|
||||
# Multiplier = (2 / (Time periods + 1) ) = (2 / (20 + 1) ) = 0.0952(9.52%)
|
||||
# EMA = {Close – EMA(previous day)} x multiplier + EMA(previous day).
|
||||
def get_moving_averages(monthly_averages_list):
|
||||
'''
|
||||
get moving averages from montyly_average_list
|
||||
input:
|
||||
[ [YYYY-MM, monthly average price],
|
||||
[YYYY-MM, monthly average price],
|
||||
...]
|
||||
|
||||
output:
|
||||
[ [YYYY-MM, monthly average price, EMA],
|
||||
[YYYY-MM, monthly average price, EMA],
|
||||
...]
|
||||
'''
|
||||
|
||||
# by ref, the first 5 month EMA were given by SMA
|
||||
monthly_averages_list[0].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)
|
||||
monthly_averages_list[1].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)
|
||||
monthly_averages_list[2].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)
|
||||
monthly_averages_list[3].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)
|
||||
monthly_averages_list[4].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)
|
||||
|
||||
# smoothing constant = 2 / (number of time periods in months + 1)
|
||||
smoothing_constant = 2 / (5 + 1)
|
||||
|
||||
# main loop to calculate EMA, start from the 6th month available till the end of the list
|
||||
for i in range(5, len(monthly_averages_list)):
|
||||
previous_month_EMA = monthly_averages_list[i-1][2]
|
||||
Monthly_average_price = monthly_averages_list[i][1]
|
||||
|
||||
EMA = (Monthly_average_price - previous_month_EMA) * smoothing_constant + previous_month_EMA
|
||||
monthly_averages_list[i].append(EMA)
|
||||
|
||||
return monthly_averages_list
|
||||
|
||||
# Based on the entered CSV file name, a corresponding output text file (e.g. “Google_output.txt” for this case) will be generated.
|
||||
# In the output file, you are eventually required to print:
|
||||
# - the best month (with the highest EMA price) and
|
||||
# - the worst month (with the lowest EMA price) for the stock.
|
||||
# You need to first print a header line for the stock, and then print a date (MM-YYYY),
|
||||
# a comma followed by a moving average price (in 2 decimal places) on another line.
|
||||
def format_date_string(yyyy_mm):
|
||||
'''rearrange date string from csv file YYYY-MM => MM-YYYY'''
|
||||
[yyyy, mm] = yyyy_mm.split('-')
|
||||
return '-'.join([mm, yyyy])
|
||||
|
||||
def write_output_file(filename_to_write, monthly_averages_list_w_ema, report_name):
|
||||
'''get output string from template and write to output file
|
||||
input:
|
||||
filename_to_write: txt file name with path to be written to
|
||||
monthly_averages_list_w_ema: list provided with EMA
|
||||
report_name: report name to be written to report
|
||||
'''
|
||||
|
||||
RESULT_TEMPLATE='''
|
||||
# The best month for ^report_name^:
|
||||
# ^best_month^, ^best_EMA^
|
||||
|
||||
# The worst month for ^report_name^:
|
||||
# ^worst_month^, ^worst_EMA^
|
||||
'''.strip()
|
||||
|
||||
# get the max EMA of the list
|
||||
best_EMA = max(map(lambda x: x[2], monthly_averages_list_w_ema[5:]))
|
||||
# get the month(s) by the EMA wanted
|
||||
best_months = list(map(lambda x: format_date_string(x[0]), filter(lambda x: x[2] == best_EMA, monthly_averages_list_w_ema[5:])))
|
||||
|
||||
# get the min(worst) EMA of the list
|
||||
worst_EMA = min(map(lambda x: x[2], monthly_averages_list_w_ema[5:]))
|
||||
# get the month(s) by the EMA wanted
|
||||
worst_months = list(map(lambda x: format_date_string(x[0]), filter(lambda x: x[2] == worst_EMA, monthly_averages_list_w_ema[5:])))
|
||||
|
||||
# assemble the output string
|
||||
result_string = RESULT_TEMPLATE
|
||||
result_string = result_string\
|
||||
.replace('^best_month^', ','.join(best_months))\
|
||||
.replace('^best_EMA^', str('%.2f' % best_EMA))\
|
||||
.replace('^worst_month^', ','.join(worst_months))\
|
||||
.replace('^worst_EMA^', str('%.2f' % worst_EMA)) \
|
||||
.replace('^report_name^', report_name)
|
||||
|
||||
# write output file
|
||||
with open(filename_to_write, 'w+') as file_write:
|
||||
file_write.truncate(0)
|
||||
file_write.writelines(result_string)
|
||||
|
||||
def main():
|
||||
# Main function starts here
|
||||
|
||||
print('start')
|
||||
|
||||
# gather csv file with path from user
|
||||
input_filename = input("Please input a csv filename: ")
|
||||
|
||||
csv_filename = os.path.basename(input_filename)
|
||||
csv_path = os.path.dirname(input_filename)
|
||||
|
||||
# transform to the output file path by csv file name got
|
||||
txt_filename = csv_filename.replace('.csv','_output.txt')
|
||||
if (csv_path != ''):
|
||||
txt_filename = '/'.join([csv_path, txt_filename])
|
||||
else:
|
||||
# by default keep into current directory
|
||||
txt_filename = '/'.join(['.', txt_filename])
|
||||
|
||||
# grep the corp_name from the filename google.csv => google
|
||||
corp_name = os.path.basename(input_filename).split('.')[0]
|
||||
|
||||
# process the data_list by csv file as stateed in assignment
|
||||
print(f'processing {csv_filename}')
|
||||
csv_list=get_data_list(input_filename)
|
||||
monthly_averages_list = get_monthly_averages(csv_list)
|
||||
monthly_averages_list_w_EMA = get_moving_averages(monthly_averages_list)
|
||||
|
||||
# write output file
|
||||
write_output_file(txt_filename, monthly_averages_list_w_EMA, corp_name)
|
||||
print('wrote to {file} done'.format(file = txt_filename))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
6
hyhl_1022/1st_copy/src/test.sh
Normal file
6
hyhl_1022/1st_copy/src/test.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
|
||||
python3 ./main.py
|
112
hyhl_1022/2nd_copy/NOTES.md
Normal file
112
hyhl_1022/2nd_copy/NOTES.md
Normal file
@@ -0,0 +1,112 @@
|
||||
### objective
|
||||
|
||||
env: Windows
|
||||
deadline 23/12
|
||||
|
||||
### CAUTION
|
||||
|
||||
Do not include any code not written by you in your
|
||||
project. You are NOT allowed to import any Python libraries in your solution except the
|
||||
modules namely os (https://docs.python.org/3/library/os.html), sys
|
||||
(https://docs.python.org/3/library/sys.html) and csv (https://docs.python.org/3/library/csv.html). If
|
||||
cheating is found or the import requirement is violated, you will receive a zero mark.
|
||||
|
||||
### Deliverable
|
||||
|
||||
You have to include your student name and ID in your source code and name your project solution as
|
||||
“XXXXXXXX_project.py” (where XXXXXXXX is your 8-digit student ID). Please remember to
|
||||
upload your source code solution to Moodle by the submission deadline.
|
||||
|
||||
### drill down
|
||||
|
||||
Functions
|
||||
Given the file of stock prices, you are asked to develop a Python program to process the data by
|
||||
designing appropriate functions. At minimum you need to implement and call the following three
|
||||
functions:
|
||||
• get_data_list(csv_file_name)
|
||||
This function has one parameter, namely csv_file_name. When the function is called, you
|
||||
need to pass along a CSV file name which is used inside the function to open and read the CSV
|
||||
file. After reading each row, it will be split into a list. The list will then be appended into a main
|
||||
list (a list of lists), namely data_list. The data_list will be returned at the end of the
|
||||
function.
|
||||
2
|
||||
• get_monthly_averages(data_list)
|
||||
This function has one parameter, namely data_list. You need to pass the data_list
|
||||
generated by the get_data_list() function as the argument to this function and then
|
||||
calculate the monthly average prices of the stock. The average monthly prices are calculated in
|
||||
the following way. Suppose the volume and adjusted closing price of a trading day are V1 and C1,
|
||||
respectively. The total sale of that day equals V1 x C1. Now, suppose the volume and adjusted
|
||||
closing price of another trading day are V2 and C2, respectively. The average of these two trading
|
||||
days is the sum of the total sales divided by the total volume:
|
||||
Average price = (V1 x C1 + V2 x C2) / (V1 + V2)
|
||||
To average a whole month, you need to add up the total sales (V1 x C1 + V2 x C2 + ... +
|
||||
Vn x Cn) for each day and divide it by the sum of all volumes (V1 + V2 + ... + Vn) where n
|
||||
is the number of trading days in the month.
|
||||
A tuple with 2 items, including the date (year and month only) and the average for that month,
|
||||
will be generated for each month. The tuple for each month will be appended to a main list,
|
||||
namely monthly_averages_list. The monthly_averages_list will be returned at
|
||||
the end of the function.
|
||||
• get_moving_averages(monthly_averages_list)
|
||||
This function has one parameter, namely monthly_averages_list. You need to pass the
|
||||
monthly_averages_list generated by get_monthly_averages() as the argument
|
||||
to this function and then calculate the 5-month exponential moving average (EMA) stock prices.
|
||||
In general, the EMA for a particular month can be calculated by the following formula:
|
||||
EMA = (Monthly average price – previous month’s EMA) x smoothing constant
|
||||
|
||||
- previous month’s EMA
|
||||
where
|
||||
smoothing constant = 2 / (number of time periods in months + 1)
|
||||
3
|
||||
For example, the following table shows the stock prices between Oct 2020 and Apr 2021:
|
||||
Month Monthly Average Price
|
||||
Oct 2020 14
|
||||
Nov 2020 13
|
||||
Dec 2020 14
|
||||
Jan 2021 12
|
||||
Feb 2021 13
|
||||
Mar 2021 12
|
||||
Apr 2021 11
|
||||
The initial 5-month EMA for Feb 2021 can be calculated by the simple average formula, as
|
||||
shown below:
|
||||
5-month EMA for Feb 2021 = (14 + 13 + 14 + 12 + 13) / 5 = 13.2
|
||||
The 5-month EMA for Mar 2021 can be calculated by the EMA formula, as shown below:
|
||||
5-month EMA for Mar 2021 = (Monthly average price – previous month’s EMA) x
|
||||
smoothing constant + previous month’s EMA
|
||||
= (12 – 13.2) x (2 / 6) + 13.2
|
||||
= 12.8
|
||||
The 5-month EMA for Apr 2021 can be calculated by the EMA formula, as shown below:
|
||||
5-month EMA for Apr 2021 = (Monthly average price – previous month’s EMA) x
|
||||
smoothing constant + previous month’s EMA
|
||||
= (11 – 12.8) x (2 / 6) + 12.8
|
||||
= 12.2
|
||||
The resulting 5-month EMA stock prices are shown below:
|
||||
Month Average Price 5-month EMA Price
|
||||
Oct 2020 14 -
|
||||
Nov 2020 13 -
|
||||
Dec 2020 14 -
|
||||
Jan 2021 12 -
|
||||
Feb 2021 13 13.2
|
||||
Mar 2021 12 12.8
|
||||
Apr 2021 11 12.2
|
||||
4
|
||||
A tuple with 2 items, including the date (year and month only) and the 5-month EMA price for
|
||||
that month, will be generated for each month except the first 4 months. Each tuple will be
|
||||
appended to a main list, namely moving_averages_list. The
|
||||
moving_averages_list will be returned at the end of the function.
|
||||
|
||||
Program Input and Output
|
||||
At the outset, your program needs to ask the user for a CSV file name:
|
||||
Based on the entered CSV file name, a corresponding output text file (e.g. “Google_output.txt”
|
||||
for this case) will be generated. In the output file, you are eventually required to print the best month
|
||||
(with the highest EMA price) and the worst month (with the lowest EMA price) for the stock. You
|
||||
need to first print a header line for the stock, and then print a date (MM-YYYY), a comma followed by
|
||||
a moving average price (in 2 decimal places) on another line. You must follow the output format as
|
||||
shown below (please note the values are not true, which are for reference only)
|
||||
|
||||
IV. Evaluation Criteria (40% of Overall Course Assessment)
|
||||
The project will be graded using the following criteria:
|
||||
• 15% - Correctness of program execution and output data
|
||||
• 10% - Modularization (e.g. dividing the program functionality into different functions)
|
||||
• 5% - Error handling
|
||||
• 5% - Consistent style (e.g., capitalization, indenting, etc.)
|
||||
• 5% - Appropriate comments
|
Binary file not shown.
1031
hyhl_1022/2nd_copy/_ref/google.csv
Normal file
1031
hyhl_1022/2nd_copy/_ref/google.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
hyhl_1022/2nd_copy/_ref/steps.ods
Normal file
BIN
hyhl_1022/2nd_copy/_ref/steps.ods
Normal file
Binary file not shown.
15
hyhl_1022/2nd_copy/_ref/test.csv
Normal file
15
hyhl_1022/2nd_copy/_ref/test.csv
Normal file
@@ -0,0 +1,15 @@
|
||||
Date,Open,High,Low,Close,Adj Close,Volume
|
||||
2008-07-04,460,463.24,449.4,450.26,450.26,4848500
|
||||
2008-07-03,468.73,474.29,459.58,464.41,464.41,4314600
|
||||
2008-06-02,476.77,482.18,461.42,465.25,465.25,6111500
|
||||
2008-06-29,469.75,471.01,462.33,463.29,463.29,3848200
|
||||
2008-05-08,452.02,452.94,417.55,419.95,419.95,9017900
|
||||
2008-05-05,445.49,452.46,440.08,444.25,444.25,4534300
|
||||
2008-04-04,460,463.24,449.4,450.26,450.26,4848500
|
||||
2008-04-03,468.73,474.29,459.58,464.41,464.41,4314600
|
||||
2008-03-02,476.77,482.18,461.42,465.25,465.25,6111500
|
||||
2008-03-29,469.75,471.01,462.33,463.29,463.29,3848200
|
||||
2008-02-28,472.49,476.45,470.33,473.78,473.78,3029700
|
||||
2008-02-27,473.73,474.83,464.84,468.58,468.58,4387100
|
||||
2008-01-28,472.49,476.45,470.33,473.78,473.78,3029700
|
||||
2008-01-27,473.73,474.83,464.84,468.58,468.58,4387100
|
|
16
hyhl_1022/2nd_copy/build.sh
Normal file
16
hyhl_1022/2nd_copy/build.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
rm -rf _temp/*
|
||||
rm -rf delivery2.zip
|
||||
|
||||
mkdir -p _temp
|
||||
|
||||
set -ex
|
||||
|
||||
cp src/main.py _temp/XXXXXXXX_project.py
|
||||
|
||||
pushd _temp
|
||||
7za a -tzip ../delivery2.zip *
|
||||
popd
|
||||
|
||||
rm -rf _temp
|
11
hyhl_1022/2nd_copy/src/Pipfile
Normal file
11
hyhl_1022/2nd_copy/src/Pipfile
Normal file
@@ -0,0 +1,11 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.11"
|
262
hyhl_1022/2nd_copy/src/main.py
Normal file
262
hyhl_1022/2nd_copy/src/main.py
Normal file
@@ -0,0 +1,262 @@
|
||||
# Objective:
|
||||
# This scripts aims to analyze the historical prices of a stock
|
||||
import os
|
||||
import sys
|
||||
import csv
|
||||
|
||||
# define error constant
|
||||
CSV_FILE_NOT_FOUND='csv_file_not_found'
|
||||
|
||||
# column assignment by CSV definition
|
||||
[ C_DATE,
|
||||
C_OPEN,
|
||||
C_HIGH,
|
||||
C_LOW,
|
||||
C_CLOSE,
|
||||
C_ADJ_CLOSE,
|
||||
C_VOLUME,
|
||||
C_MONTH_AVG_PRICE,
|
||||
C_EMA
|
||||
] = list(range(0,8+1))
|
||||
|
||||
# NOTE: get_data_list(csv_file_name)
|
||||
# NOTE: This function has one parameter, namely csv_file_name.
|
||||
# NOTE: When the function is called, you need to pass along a CSV file name which is used inside the function to open and read the CSV
|
||||
# NOTE: file.
|
||||
# NOTE: After reading each row, it will be split into a list. The list will then be appended into a main
|
||||
# NOTE: list (a list of lists), namely data_list. The data_list will be returned at the end of the
|
||||
# NOTE: function.
|
||||
|
||||
# NOTE: file tested found as protected by outer try except structure
|
||||
def clean_data(data_list):
|
||||
"""clean and bloat data"""
|
||||
|
||||
out_list = []
|
||||
for data in sorted(data_list):
|
||||
out_list.append([
|
||||
data[C_DATE],
|
||||
float(data[C_OPEN]),
|
||||
float(data[C_HIGH]),
|
||||
float(data[C_LOW]),
|
||||
float(data[C_CLOSE]),
|
||||
float(data[C_ADJ_CLOSE]),
|
||||
float(data[C_VOLUME]),
|
||||
])
|
||||
return out_list
|
||||
|
||||
def get_data_list(csv_file_name):
|
||||
'''parse csv file, bloat it into list object'''
|
||||
|
||||
data_list = []
|
||||
with open(csv_file_name, newline='') as f_csv:
|
||||
data_list = list(csv.reader(f_csv, delimiter=',', quotechar='"'))
|
||||
|
||||
# NOTE: skip the very first row as that is names
|
||||
# NOTE: bloat the column accordingly
|
||||
return clean_data(data_list[1:])
|
||||
|
||||
# NOTE: get_monthly_averages(data_list)
|
||||
# NOTE: This function has one parameter, namely data_list. You need to pass the data_list
|
||||
# NOTE: generated by the get_data_list() function as the argument to this function and then
|
||||
# NOTE: calculate the monthly average prices of the stock. The average monthly prices are calculated in
|
||||
# NOTE: the following way.
|
||||
# NOTE:
|
||||
# NOTE: 1. Suppose the volume and adjusted closing price of a trading day are V1 and C1, respectively.
|
||||
# NOTE: 2. The total sale of that day equals V1 x C1.
|
||||
# NOTE: 3. Now, suppose the volume and adjusted closing price of another trading day are V2 and C2, respectively.
|
||||
# NOTE: 4. The average of these two trading days is the sum of the total sales divided by the total volume:
|
||||
# NOTE:
|
||||
# NOTE: Average price = (V1 x C1 + V2 x C2) / (V1 + V2)
|
||||
# NOTE:
|
||||
# NOTE: To average a whole month, you need to
|
||||
# NOTE: - add up the total sales (V1 x C1 + V2 x C2 + ... + Vn x Cn) for each day and
|
||||
# NOTE: - divide it by the sum of all volumes (V1 + V2 + ... + Vn) where n is the number of trading days in the month.
|
||||
# NOTE: A tuple with 2 items, including the date (year and month only) and the average for that month,
|
||||
# NOTE: will be generated for each month. The tuple for each month will be appended to a main list,
|
||||
# NOTE: namely monthly_averages_list. The monthly_averages_list will be returned at the end of the function.
|
||||
|
||||
def get_available_month(data_list):
|
||||
'''get the unique month from the list
|
||||
input:
|
||||
data_list
|
||||
'''
|
||||
return sorted(set([data[0][0:7] for data in data_list]))
|
||||
|
||||
def get_monthly_averages(data_list):
|
||||
'''get the average price by month
|
||||
input:
|
||||
data_list
|
||||
'''
|
||||
month_in_list = get_available_month(data_list)
|
||||
month_average_price = {}
|
||||
monthly_averages_list = data_list
|
||||
|
||||
# get total volume by month
|
||||
for month in month_in_list:
|
||||
filtered_month_transaction = list(filter(lambda row: row[C_DATE][0:7] == month, monthly_averages_list))
|
||||
|
||||
# NOTE: (V1 x C1 + V2 x C2 ...)
|
||||
sum_total_sale_by_month = sum(map(lambda row: row[C_VOLUME] * row[C_ADJ_CLOSE], filtered_month_transaction))
|
||||
|
||||
# NOTE: (V1 + V2 ...)
|
||||
sum_volume_by_month = sum(map(lambda t: t[C_VOLUME], filtered_month_transaction))
|
||||
|
||||
# NOTE: Average price = (V1 x C1 + V2 x C2 ...) / (V1 + V2 ... )
|
||||
month_average_price[month] = sum_total_sale_by_month/sum_volume_by_month
|
||||
|
||||
# NOTE: append to main list -> C_MONTH_AVG_PRICE
|
||||
for data in monthly_averages_list:
|
||||
data.append(month_average_price[data[C_DATE][0:7]])
|
||||
|
||||
return monthly_averages_list
|
||||
|
||||
# NOTE: get_moving_averages(monthly_averages_list)
|
||||
# NOTE: This function has one parameter, namely monthly_averages_list. You need to pass the
|
||||
# NOTE: monthly_averages_list generated by get_monthly_averages() as the argument
|
||||
# NOTE: to this function and then calculate the 5-month exponential moving average (EMA) stock prices.
|
||||
# NOTE: In general, the EMA for a particular month can be calculated by the following formula:
|
||||
# NOTE:
|
||||
# NOTE: EMA = (Monthly average price – previous month’s EMA) x smoothing constant + previous month’s EMA
|
||||
# NOTE:
|
||||
# NOTE: where
|
||||
# NOTE:
|
||||
# NOTE: smoothing constant = 2 / (number of time periods in months + 1)
|
||||
# NOTE:
|
||||
# NOTE: Initial SMA = 20-period sum / 20
|
||||
# NOTE: Multiplier = (2 / (Time periods + 1) ) = (2 / (20 + 1) ) = 0.0952(9.52%)
|
||||
# NOTE: EMA = {Close – EMA(previous day)} x multiplier + EMA(previous day).
|
||||
def get_monthly_average(data_list, month_wanted):
|
||||
'''
|
||||
get monthly average from the list
|
||||
input:
|
||||
data_list: data_list
|
||||
month_wanted: YYYY-MM
|
||||
'''
|
||||
return list(filter(lambda d: d[C_DATE][0:7] == month_wanted, data_list) )[0][C_MONTH_AVG_PRICE]
|
||||
|
||||
|
||||
def get_SMA(data_list, month_to_get_SMA):
|
||||
'''calculate SMA from the beginning(oldest) of the list
|
||||
input:
|
||||
data_list: data_list
|
||||
month_to_get_SMA : number of month to initialize the SMA (i.e. 5)
|
||||
'''
|
||||
sum_of_months = 0
|
||||
|
||||
for month in month_to_get_SMA:
|
||||
sum_of_months = sum_of_months + get_monthly_average(data_list, month)
|
||||
|
||||
return sum_of_months / len(month_to_get_SMA)
|
||||
|
||||
def get_extreme_EMA(ema_list, max_min= 'min', skip_month=0):
|
||||
'''get max/min EMA from the list
|
||||
input:
|
||||
ema_list: month list with ema
|
||||
max_min: max / min selector (default: min)
|
||||
skip_month: month to skip as initialized as SMA (i.e. the first 5 month)
|
||||
'''
|
||||
if (max_min == 'max'):
|
||||
return max(map(lambda r: r[2], ema_list[skip_month:]))
|
||||
|
||||
return min(map(lambda r: r[2], ema_list[skip_month:]))
|
||||
|
||||
def get_month_by_EMA(ema_list, ema_value):
|
||||
'''get months(value) specified by the EMA value wanted
|
||||
input:
|
||||
ema_list: month list with ema
|
||||
ema_value: ema value to select the month (i.e. max EMA)
|
||||
'''
|
||||
return list(map(lambda r: r[0], filter(lambda x: x[2] == ema_value, ema_list)))
|
||||
|
||||
def get_output_content(max_ema, min_ema, max_ema_months, min_ema_months, report_name=""):
|
||||
'''get the output content, return with a formatted string
|
||||
input:
|
||||
max_ema: max ema to report
|
||||
min_ema: min ema to report
|
||||
max_ema_months: month(s) to report with max ema
|
||||
min_ema_months: month(s) to report with min ema
|
||||
'''
|
||||
# reformat to MM-YYYY before out to file
|
||||
reformat_max_ema_months = list(map(lambda m: m.split('-')[1]+'-'+m.split('-')[0] , max_ema_months))
|
||||
reformat_min_ema_months = list(map(lambda m: m.split('-')[1]+'-'+m.split('-')[0] , min_ema_months))
|
||||
|
||||
return '''
|
||||
# The best month for {report_name}:
|
||||
# {best_ema_months}, {best_EMA}
|
||||
|
||||
# The worst month for {report_name}:
|
||||
# {worst_ema_months}, {worst_EMA}
|
||||
'''.format(
|
||||
best_ema_months=','.join(reformat_max_ema_months),
|
||||
best_EMA=round(max_ema, 2),
|
||||
worst_ema_months=','.join(reformat_min_ema_months),
|
||||
worst_EMA=round(min_ema, 2),
|
||||
report_name=report_name).strip()
|
||||
|
||||
|
||||
def get_moving_averages(monthly_averages_list):
|
||||
'''get moving averages
|
||||
input:
|
||||
monthly_averages_list
|
||||
'''
|
||||
month_available = get_available_month(monthly_averages_list)
|
||||
# NOTE: initialize first 0 to 4 SMA
|
||||
monthly_averages_list_w_EMA = [[c, get_monthly_average(monthly_averages_list, c)] for c in month_available]
|
||||
initial_SMA = sum(map(lambda x: x[1], monthly_averages_list_w_EMA[0:5]))/5
|
||||
|
||||
smoothing_constant = 2 / (5 + 1)
|
||||
|
||||
for i in range(0,len(monthly_averages_list_w_EMA)):
|
||||
if (i < 5):
|
||||
# first 5 month were given by SMA
|
||||
monthly_averages_list_w_EMA[i].append( initial_SMA)
|
||||
|
||||
else:
|
||||
month_average_this_month = monthly_averages_list_w_EMA[i][1]
|
||||
EMA_last_month = monthly_averages_list_w_EMA[i-1][2]
|
||||
EMA_this_month = (month_average_this_month - EMA_last_month) * smoothing_constant + EMA_last_month
|
||||
|
||||
monthly_averages_list_w_EMA[i].append( EMA_this_month )
|
||||
|
||||
return monthly_averages_list_w_EMA
|
||||
|
||||
# get input from user
|
||||
csv_filepath = input("Please input a csv filename: ")
|
||||
|
||||
try:
|
||||
# NOTE: get csv file from user
|
||||
csv_filename = csv_filepath
|
||||
txt_filename = csv_filename.split('.csv')[0]+'_output.txt'
|
||||
report_name = os.path.basename(csv_filename).replace('.csv','')
|
||||
|
||||
# NOTE: process file
|
||||
data_list = get_data_list(csv_filename)
|
||||
monthly_average_list = get_monthly_averages(data_list)
|
||||
ema_list = get_moving_averages(monthly_average_list)
|
||||
|
||||
# NOTE: output txt file
|
||||
max_ema = get_extreme_EMA(ema_list,'max', 5)
|
||||
min_ema = get_extreme_EMA(ema_list, 'min',5)
|
||||
best_ema_months = get_month_by_EMA(ema_list, max_ema)
|
||||
worst_ema_months = get_month_by_EMA(ema_list, min_ema)
|
||||
|
||||
output_string = get_output_content(max_ema, min_ema, best_ema_months, worst_ema_months, report_name)
|
||||
|
||||
with open(txt_filename, 'w+') as f_output:
|
||||
f_output.truncate(0)
|
||||
f_output.writelines(output_string)
|
||||
|
||||
print('output wrote '+txt_filename)
|
||||
print('done !')
|
||||
|
||||
except IsADirectoryError as e:
|
||||
# NOTE: if input is a directory, drop here
|
||||
print('sorry the path is a directory')
|
||||
|
||||
except FileNotFoundError as e:
|
||||
# NOTE: if csv file not found, drop here
|
||||
print('sorry cannot find the file wanted')
|
||||
|
||||
except Exception as e:
|
||||
# # cast outside if exception definition not found
|
||||
raise e
|
6
hyhl_1022/2nd_copy/src/test.sh
Normal file
6
hyhl_1022/2nd_copy/src/test.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
clear
|
||||
python3 ./main.py
|
7
hyhl_1022/gitUpdate.bat
Normal file
7
hyhl_1022/gitUpdate.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
git status .
|
||||
|
||||
@pause
|
||||
|
||||
git add .
|
||||
git commit -m"update hyhl_1022,"
|
||||
start git push
|
372
hyhl_1022/jupyter/jupyter-helloworld/1st_copy.ipynb
Normal file
372
hyhl_1022/jupyter/jupyter-helloworld/1st_copy.ipynb
Normal file
@@ -0,0 +1,372 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "83041d33",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%rm -rf google_output.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "9b24b4df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os,sys, csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "c2b90953",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# column from csv file\n",
|
||||
"# COL_DATE: the day of trading\n",
|
||||
"# COL_OPEN: the stock price at the beginning of the trading day\n",
|
||||
"# COL_HIGH: the highest price the stock achieved on the trading day\n",
|
||||
"# COL_LOW: the lowest price the stock achieved on the trading day\n",
|
||||
"# COL_CLOSE: the stock price at the end of the trading day\n",
|
||||
"# COL_ADJ_Close: the adjusted closing price of the trading day (reflecting the stock’s value after accounting for any corporate actions like dividends, stock splits and new stock offerings)\n",
|
||||
"# COL_VOLUME: the total number of shares were traded on the trading day\n",
|
||||
"COL_DATE=0\n",
|
||||
"COL_OPEN=1\n",
|
||||
"COL_HIGH=2\n",
|
||||
"COL_LOW=3\n",
|
||||
"COL_CLOSE=4\n",
|
||||
"COL_ADJ_CLOSE=5\n",
|
||||
"COL_VOLUME=6\n",
|
||||
"\n",
|
||||
"# append at middle stage\n",
|
||||
"COL_TOTAL_SALE_OF_DAY=7\n",
|
||||
"COL_MONTH_ONLY=8\n",
|
||||
"COL_EMA=9\n",
|
||||
"\n",
|
||||
"# monthly_averages_list\n",
|
||||
"COL_MONTHLY_AVERAGE_PRICE=1\n",
|
||||
"COL_EMA=2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "09a9417f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# get_data_list(csv_file_name)\n",
|
||||
"# This function has one parameter, namely csv_file_name. \n",
|
||||
"# When the function is called, you need to pass along a CSV file name which is used inside the function to open and read the CSV\n",
|
||||
"# file. \n",
|
||||
"# After reading each row, it will be split into a list. The list will then be appended into a main\n",
|
||||
"# list (a list of lists), namely data_list. The data_list will be returned at the end of the\n",
|
||||
"# function.\n",
|
||||
"def get_data_list(csv_file_name):\n",
|
||||
" '''read data list from csv file'''\n",
|
||||
" data_list = []\n",
|
||||
" try:\n",
|
||||
" with open(csv_file_name, newline='') as csvfile:\n",
|
||||
" temp = []\n",
|
||||
" temp = csv.reader(csvfile, delimiter=',', quotechar='\"')\n",
|
||||
" data_list = list(temp)\n",
|
||||
" \n",
|
||||
" return data_list\n",
|
||||
" except Exception as e:\n",
|
||||
" print('error during reading csv file ')\n",
|
||||
" print('exitting...')\n",
|
||||
" sys.exit()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "cd616e6e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# get_monthly_averages(data_list)\n",
|
||||
"# This function has one parameter, namely data_list. You need to pass the data_list\n",
|
||||
"# generated by the get_data_list() function as the argument to this function and then\n",
|
||||
"# calculate the monthly average prices of the stock. The average monthly prices are calculated in\n",
|
||||
"# the following way. \n",
|
||||
"# \n",
|
||||
"# 1. Suppose the volume and adjusted closing price of a trading day are V1 and C1, respectively. \n",
|
||||
"# 2. The total sale of that day equals V1 x C1. \n",
|
||||
"# 3. Now, suppose the volume and adjusted closing price of another trading day are V2 and C2, respectively. \n",
|
||||
"# 4. The average of these two trading days is the sum of the total sales divided by the total volume:\n",
|
||||
"# \n",
|
||||
"# Average price = (V1 x C1 + V2 x C2) / (V1 + V2)\n",
|
||||
"# \n",
|
||||
"# To average a whole month, you need to \n",
|
||||
"# - add up the total sales (V1 x C1 + V2 x C2 + ... + Vn x Cn) for each day and \n",
|
||||
"# - divide it by the sum of all volumes (V1 + V2 + ... + Vn) where n is the number of trading days in the month.\n",
|
||||
"# A tuple with 2 items, including the date (year and month only) and the average for that month,\n",
|
||||
"# will be generated for each month. The tuple for each month will be appended to a main list,\n",
|
||||
"# namely monthly_averages_list. The monthly_averages_list will be returned at the end of the function.\n",
|
||||
"\n",
|
||||
"def get_monthly_averages(data_list):\n",
|
||||
" '''calculate the monthly average prices of the stock'''\n",
|
||||
"\n",
|
||||
" monthly_averages_list=[]\n",
|
||||
" data_list_data_only = data_list[1:]\n",
|
||||
" month_available = []\n",
|
||||
" \n",
|
||||
" # data cleaning\n",
|
||||
" for i in range(len(data_list_data_only)):\n",
|
||||
" # V1 x C1, calculate the total sale, append into column\n",
|
||||
" data_list_data_only[i].append(float(data_list_data_only[i][COL_VOLUME]) * float(data_list_data_only[i][COL_ADJ_CLOSE]))\n",
|
||||
"\n",
|
||||
" # mark the row by YYYY-MM for easy monthly sum calculation, COL_MONTH_ONLY\n",
|
||||
" data_list_data_only[i].append(data_list_data_only[i][COL_DATE][0:7])\n",
|
||||
"\n",
|
||||
" # get the month in the list YYYY-MM\n",
|
||||
" month_available = set(list(map(lambda x: x[COL_MONTH_ONLY], data_list_data_only)))\n",
|
||||
"\n",
|
||||
" # literate the whole list, calculate the total_sale and total volume\n",
|
||||
" # get the average sale by total_sale / total_volume\n",
|
||||
" for month in sorted(month_available):\n",
|
||||
" filtered_month = list(filter(lambda x: x[COL_MONTH_ONLY] == month, data_list_data_only))\n",
|
||||
" total_sale = sum(list( map(lambda x: x[COL_TOTAL_SALE_OF_DAY], filtered_month)))\n",
|
||||
" total_volume = sum(list( map(lambda x: float(x[COL_VOLUME]), filtered_month)))\n",
|
||||
" monthly_averages_list.append([month, total_sale/total_volume])\n",
|
||||
"\n",
|
||||
" return list(monthly_averages_list)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "dfe29847",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# get_moving_averages(monthly_averages_list)\n",
|
||||
"# This function has one parameter, namely monthly_averages_list. You need to pass the\n",
|
||||
"# monthly_averages_list generated by get_monthly_averages() as the argument\n",
|
||||
"# to this function and then calculate the 5-month exponential moving average (EMA) stock prices.\n",
|
||||
"# In general, the EMA for a particular month can be calculated by the following formula:\n",
|
||||
"# \n",
|
||||
"# EMA = (Monthly average price – previous month’s EMA) x smoothing constant + previous month’s EMA\n",
|
||||
"# \n",
|
||||
"# where\n",
|
||||
"# \n",
|
||||
"# smoothing constant = 2 / (number of time periods in months + 1)\n",
|
||||
"# \n",
|
||||
"# Initial SMA = 20-period sum / 20\n",
|
||||
"# Multiplier = (2 / (Time periods + 1) ) = (2 / (20 + 1) ) = 0.0952(9.52%)\n",
|
||||
"# EMA = {Close – EMA(previous day)} x multiplier + EMA(previous day).\n",
|
||||
"def get_moving_averages(monthly_averages_list):\n",
|
||||
" '''\n",
|
||||
" get moving averages from montyly_average_list\n",
|
||||
" input:\n",
|
||||
" [ [YYYY-MM, monthly average price],\n",
|
||||
" [YYYY-MM, monthly average price],\n",
|
||||
" ...]\n",
|
||||
"\n",
|
||||
" output: \n",
|
||||
" [ [YYYY-MM, monthly average price, EMA],\n",
|
||||
" [YYYY-MM, monthly average price, EMA],\n",
|
||||
" ...]\n",
|
||||
" '''\n",
|
||||
"\n",
|
||||
" # by ref, the first 5 month EMA were given by SMA\n",
|
||||
" monthly_averages_list[0].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)\n",
|
||||
" monthly_averages_list[1].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)\n",
|
||||
" monthly_averages_list[2].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)\n",
|
||||
" monthly_averages_list[3].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)\n",
|
||||
" monthly_averages_list[4].append(sum(map(lambda x: x[1], monthly_averages_list[0:5]))/5)\n",
|
||||
"\n",
|
||||
" # smoothing constant = 2 / (number of time periods in months + 1)\n",
|
||||
" smoothing_constant = 2 / (5 + 1)\n",
|
||||
"\n",
|
||||
" # main loop to calculate EMA, start from the 6th month available till the end of the list\n",
|
||||
" for i in range(5, len(monthly_averages_list)):\n",
|
||||
" previous_month_EMA = monthly_averages_list[i-1][2]\n",
|
||||
" Monthly_average_price = monthly_averages_list[i][1]\n",
|
||||
"\n",
|
||||
" EMA = (Monthly_average_price - previous_month_EMA) * smoothing_constant + previous_month_EMA\n",
|
||||
" monthly_averages_list[i].append(EMA)\n",
|
||||
"\n",
|
||||
" return monthly_averages_list\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "c89cbae8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def format_date_string(yyyy_mm):\n",
|
||||
" '''rearrange date string from csv file YYYY-MM => MM-YYYY'''\n",
|
||||
" [yyyy, mm] = yyyy_mm.split('-')\n",
|
||||
" return '-'.join([mm, yyyy])\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "8d646beb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def write_output_file(filename_to_write, monthly_averages_list_w_ema, report_name):\n",
|
||||
" '''get output string from template and write to output file\n",
|
||||
" input:\n",
|
||||
" filename_to_write: txt file name with path to be written to\n",
|
||||
" monthly_averages_list_w_ema: list provided with EMA\n",
|
||||
" report_name: report name to be written to report\n",
|
||||
" '''\n",
|
||||
"\n",
|
||||
" RESULT_TEMPLATE='''\n",
|
||||
"# The best month for ^report_name^:\n",
|
||||
"# ^best_month^, ^best_EMA^\n",
|
||||
"\n",
|
||||
"# The worst month for ^report_name^:\n",
|
||||
"# ^worst_month^, ^worst_EMA^\n",
|
||||
" '''.strip()\n",
|
||||
"\n",
|
||||
" # get the max EMA of the list\n",
|
||||
" best_EMA = max(map(lambda x: x[2], monthly_averages_list_w_ema[5:]))\n",
|
||||
" # get the month(s) by the EMA wanted\n",
|
||||
" best_months = list(map(lambda x: format_date_string(x[0]), filter(lambda x: x[2] == best_EMA, monthly_averages_list_w_ema[5:])))\n",
|
||||
"\n",
|
||||
" # get the min(worst) EMA of the list\n",
|
||||
" worst_EMA = min(map(lambda x: x[2], monthly_averages_list_w_ema[5:]))\n",
|
||||
" # get the month(s) by the EMA wanted\n",
|
||||
" worst_months = list(map(lambda x: format_date_string(x[0]), filter(lambda x: x[2] == worst_EMA, monthly_averages_list_w_ema[5:])))\n",
|
||||
"\n",
|
||||
" # assemble the output string\n",
|
||||
" result_string = RESULT_TEMPLATE\n",
|
||||
" result_string = result_string\\\n",
|
||||
" .replace('^best_month^', ','.join(best_months))\\\n",
|
||||
" .replace('^best_EMA^', str('%.2f' % best_EMA))\\\n",
|
||||
" .replace('^worst_month^', ','.join(worst_months))\\\n",
|
||||
" .replace('^worst_EMA^', str('%.2f' % worst_EMA)) \\\n",
|
||||
" .replace('^report_name^', report_name) \n",
|
||||
"\n",
|
||||
" # write output file\n",
|
||||
" with open(filename_to_write, 'w+') as file_write:\n",
|
||||
" file_write.truncate(0)\n",
|
||||
" file_write.writelines(result_string)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "1917aaef",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def main():\n",
|
||||
" # Main function starts here\n",
|
||||
"\n",
|
||||
" print('start')\n",
|
||||
"\n",
|
||||
" # gather csv file with path from user\n",
|
||||
" input_filename = input(\"Please input a csv filename: \")\n",
|
||||
" \n",
|
||||
" csv_filename = os.path.basename(input_filename)\n",
|
||||
" csv_path = os.path.dirname(input_filename)\n",
|
||||
"\n",
|
||||
" # transform to the output file path by csv file name got\n",
|
||||
" txt_filename = csv_filename.replace('.csv','_output.txt')\n",
|
||||
" if (csv_path !=''):\n",
|
||||
" txt_filename = '/'.join([csv_path, txt_filename])\n",
|
||||
" else:\n",
|
||||
" txt_filename = '/'.join(['.', txt_filename])\n",
|
||||
" \n",
|
||||
" # grep the corp_name from the filename google.csv => google\n",
|
||||
" corp_name = os.path.basename(input_filename).split('.')[0]\n",
|
||||
"\n",
|
||||
" # process the data_list by csv file as stateed in assignment\n",
|
||||
" print(f'processing {csv_filename}')\n",
|
||||
" csv_list=get_data_list(input_filename)\n",
|
||||
" monthly_averages_list = get_monthly_averages(csv_list)\n",
|
||||
" monthly_averages_list_w_EMA = get_moving_averages(monthly_averages_list)\n",
|
||||
"\n",
|
||||
" # write output file\n",
|
||||
" write_output_file(txt_filename, monthly_averages_list_w_EMA, corp_name)\n",
|
||||
" print('wrote to {file} done'.format(file = txt_filename))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b7d3e814",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"start\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"if __name__ == \"__main__\":\n",
|
||||
" main()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "325de646",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%ls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "de467460",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%cat google_output.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "41f834e6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
21
hyhl_1022/jupyter/jupyter-helloworld/Pipfile
Normal file
21
hyhl_1022/jupyter/jupyter-helloworld/Pipfile
Normal file
@@ -0,0 +1,21 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
jupyter = "*"
|
||||
notebook = "*"
|
||||
pandas = "*"
|
||||
quandl = "*"
|
||||
seaborn = "*"
|
||||
sklearn = "*"
|
||||
scikit-learn = "*"
|
||||
pydot = "*"
|
||||
bokeh = "*"
|
||||
jupyter-bokeh = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3"
|
1403
hyhl_1022/jupyter/jupyter-helloworld/Pipfile.lock
generated
Normal file
1403
hyhl_1022/jupyter/jupyter-helloworld/Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
hyhl_1022/jupyter/jupyter-helloworld/dev.sh
Normal file
14
hyhl_1022/jupyter/jupyter-helloworld/dev.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
python -m pip install pipenv
|
||||
|
||||
pipenv sync
|
||||
|
||||
pipenv run \
|
||||
jupyter-notebook \
|
||||
--allow-root \
|
||||
--ip=0.0.0.0
|
1031
hyhl_1022/jupyter/jupyter-helloworld/google.csv
Normal file
1031
hyhl_1022/jupyter/jupyter-helloworld/google.csv
Normal file
File diff suppressed because it is too large
Load Diff
100
hyhl_1022/jupyter/jupyter-helloworld/helloworld-requests.ipynb
Normal file
100
hyhl_1022/jupyter/jupyter-helloworld/helloworld-requests.ipynb
Normal file
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "b6bf609f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Requirement already satisfied: requests in /root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.10/site-packages (2.28.1)\n",
|
||||
"Requirement already satisfied: charset-normalizer<3,>=2 in /root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.10/site-packages (from requests) (2.1.1)\n",
|
||||
"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.10/site-packages (from requests) (1.26.13)\n",
|
||||
"Requirement already satisfied: idna<4,>=2.5 in /root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.10/site-packages (from requests) (3.4)\n",
|
||||
"Requirement already satisfied: certifi>=2017.4.17 in /root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.10/site-packages (from requests) (2022.9.24)\n",
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install requests"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "9b24b4df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"r = requests.get('https://www.example.com')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "1cc7f2dc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"200"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"r.status_code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "a6bd95b7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Goog.csv\n",
|
||||
"Goog.csv\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a = input()\n",
|
||||
"print(a)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
55
hyhl_1022/jupyter/jupyter-helloworld/helloworld.ipynb
Normal file
55
hyhl_1022/jupyter/jupyter-helloworld/helloworld.ipynb
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b6bf609f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install requests"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9b24b4df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"r = requests.get('https://www.example.com')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1cc7f2dc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"r.status_code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
15
hyhl_1022/jupyter/jupyter-helloworld/init.sh
Normal file
15
hyhl_1022/jupyter/jupyter-helloworld/init.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
pipenv install jupyter
|
||||
pipenv install jupyter notebook
|
||||
|
||||
pipenv install pandas
|
||||
pipenv install quandl
|
||||
|
||||
pipenv install seaborn
|
||||
pipenv install scikit-learn
|
||||
|
||||
# jupyter-notebook
|
||||
|
27
hyhl_1022/jupyter/jupyter-helloworld/journal.md
Normal file
27
hyhl_1022/jupyter/jupyter-helloworld/journal.md
Normal file
@@ -0,0 +1,27 @@
|
||||
### to spin up dev environment
|
||||
|
||||
```
|
||||
./start_docker.sh
|
||||
|
||||
// inside docker
|
||||
|
||||
./dev.sh
|
||||
|
||||
open host browser:
|
||||
http://127.0.0.1:8888/?token=98ab80de026fe83fd8e03c8e344b31e7575ec4a084c59f21
|
||||
|
||||
```
|
||||
|
||||
### to develop
|
||||
|
||||
|
||||
start from fresh python docker image
|
||||
|
||||
```
|
||||
./start_docker.sh
|
||||
|
||||
./init.sh
|
||||
```
|
||||
|
||||
|
||||
|
17
hyhl_1022/jupyter/jupyter-helloworld/start_docker.sh
Normal file
17
hyhl_1022/jupyter/jupyter-helloworld/start_docker.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
docker run -it \
|
||||
-v $PWD:/app \
|
||||
-w /app \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v ~/.ssh/id_rsa:/home/node/.ssh/id_rsa:ro \
|
||||
-v ~/.ssh/known_host:/home/node/.ssh/known_hosts:ro \
|
||||
-p 8888:8888 \
|
||||
--rm \
|
||||
python:3.10 \
|
||||
bash
|
||||
|
||||
# -u 1000:1000 \
|
||||
# -e XDG_CACHE_HOME=/app/.cache \
|
8
hyhl_1022/meta.md
Normal file
8
hyhl_1022/meta.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
tags: [python, jupyter, INT3075]
|
||||
---
|
||||
|
||||
# hyhl_1022
|
||||
|
||||
[[1st_copy/NOTES]]
|
||||
[[2nd_copy/NOTES]]
|
BIN
hyhl_1022/notes/L10_de3593a46818cfaeab73dcada2b3b55d.pdf
Normal file
BIN
hyhl_1022/notes/L10_de3593a46818cfaeab73dcada2b3b55d.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L11_2f280c974cd98e55e99bce9c98bbfe9a.pdf
Normal file
BIN
hyhl_1022/notes/L11_2f280c974cd98e55e99bce9c98bbfe9a.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L12_2723aaec2763c65c74f58f07f7642d64.pdf
Normal file
BIN
hyhl_1022/notes/L12_2723aaec2763c65c74f58f07f7642d64.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L1_a7e95e0c362838158c2046f03f053d4e.pdf
Normal file
BIN
hyhl_1022/notes/L1_a7e95e0c362838158c2046f03f053d4e.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L2_321f978b6dc2b53b5571367ee15eaa55.pdf
Normal file
BIN
hyhl_1022/notes/L2_321f978b6dc2b53b5571367ee15eaa55.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L3_d51717b8872516d09fdb3b4bb7c838e0.pdf
Normal file
BIN
hyhl_1022/notes/L3_d51717b8872516d09fdb3b4bb7c838e0.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L4_7ceb50fbff6a5422307dd3019b8ed0f5.pdf
Normal file
BIN
hyhl_1022/notes/L4_7ceb50fbff6a5422307dd3019b8ed0f5.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L5_133c673a1e8f5762b468b6da6b955f1f.pdf
Normal file
BIN
hyhl_1022/notes/L5_133c673a1e8f5762b468b6da6b955f1f.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L6_a3eb6c2274b17ddb27e15625ce3dfae9.pdf
Normal file
BIN
hyhl_1022/notes/L6_a3eb6c2274b17ddb27e15625ce3dfae9.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L7_30fa398bf3a835b43ca63cc6e73be6f4.pdf
Normal file
BIN
hyhl_1022/notes/L7_30fa398bf3a835b43ca63cc6e73be6f4.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L8_48628cf6525035038e31c9a470438331.pdf
Normal file
BIN
hyhl_1022/notes/L8_48628cf6525035038e31c9a470438331.pdf
Normal file
Binary file not shown.
BIN
hyhl_1022/notes/L9_a2c0a3b7282f64d9a7f4bfe3d3355abe.pdf
Normal file
BIN
hyhl_1022/notes/L9_a2c0a3b7282f64d9a7f4bfe3d3355abe.pdf
Normal file
Binary file not shown.
13
hyhl_1022/package.json
Normal file
13
hyhl_1022/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "notes",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"gitUpdate": "git add . && git commit -m \"update,\" && git pull && git push"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
BIN
hyhl_1022/screen_capture/HuivQquzDj.png
(Stored with Git LFS)
Normal file
BIN
hyhl_1022/screen_capture/HuivQquzDj.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
hyhl_1022/screen_capture/Screenshot from 2022-12-19 15-19-40.png
(Stored with Git LFS)
Normal file
BIN
hyhl_1022/screen_capture/Screenshot from 2022-12-19 15-19-40.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
hyhl_1022/screen_capture/steps/google-colab-create-notebook.png
(Stored with Git LFS)
Normal file
BIN
hyhl_1022/screen_capture/steps/google-colab-create-notebook.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
hyhl_1022/screen_capture/steps/google-colab-enable-share.png
(Stored with Git LFS)
Normal file
BIN
hyhl_1022/screen_capture/steps/google-colab-enable-share.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
hyhl_1022/screen_capture/steps/wa3SkZ5QU1.png
(Stored with Git LFS)
Normal file
BIN
hyhl_1022/screen_capture/steps/wa3SkZ5QU1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
7
ifkcof/gitUpdate.bat
Normal file
7
ifkcof/gitUpdate.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
git status .
|
||||
|
||||
@pause
|
||||
|
||||
git add .
|
||||
git commit -m"update ifkcof,"
|
||||
start git push
|
9
ifkcof/meta.md
Normal file
9
ifkcof/meta.md
Normal file
@@ -0,0 +1,9 @@
|
||||
UXMPX
|
||||
|
||||
好,多謝你先
|
||||
初次見面,你介唔介意落個 HKD100 訂嘛?
|
||||
|
||||
### balance history
|
||||
|
||||
HKD300 -> quote accepted
|
||||
HKD100 deposit received
|
Binary file not shown.
265
ifkcof/task1/digest.md
Normal file
265
ifkcof/task1/digest.md
Normal file
@@ -0,0 +1,265 @@
|
||||
---
|
||||
Hong Kong Institute of Vocational Education
|
||||
ITE3919 – Programming Essentials in Python
|
||||
AY2324
|
||||
Mini Project: Investment Banking System (IBS)
|
||||
---
|
||||
|
||||
# Digest
|
||||
|
||||
## 1. Description
|
||||
|
||||
In this project, you are required to complete the following parts:
|
||||
Part 1: Pseudo code of the first function "Converting Euro or USD to HKD"
|
||||
Part 2: The coding in Python acceptable style of all 3 functions of Investment Banking System (IBS):
|
||||
|
||||
- Converting Euro or USD to HKD
|
||||
- Calculating the minimum number of coins
|
||||
- Calculating the total amount of principle and compound interest
|
||||
|
||||
Coding of system menu is provided to you in this file. You need to copy the code to the source file / online simulator:
|
||||
|
||||
[https://edube.org/sandbox](https://edube.org/sandbox)
|
||||
|
||||
Copy and paste your work into the provided MS word file `EA Project*Answer Sheet*<<Your Name>>.docx` (e.g. `EA Project_Answer Sheet_ChanTaiMan.docx`) and upload to Moodle.
|
||||
|
||||
## 2. Background
|
||||
|
||||
VTC Bank it is a local investment bank in Hong Kong. In order to attract investments from foreign cities, VTC Bank is planning to develop a program to provide the following services:
|
||||
|
||||
- Providing a currency converter;
|
||||
- Introducing the coins issued in Hong Kong; and
|
||||
- Providing compound interest calculator.
|
||||
|
||||
Assuming you are the programmer of VTC Bank, your manager asks you to develop the program.
|
||||
|
||||
## 3. IBS Structure
|
||||
|
||||
There are 3 functions of IBS:
|
||||
|
||||
- Converting Euro and US dollars to Hong Kong Dollar;
|
||||
- Calculating the minimum number of coins for corresponding amounts of dollars;
|
||||
- Calculating the total amount of principle and compound interest
|
||||
|
||||
### 3.1. Show menu
|
||||
|
||||
At the beginning, the program should show a menu. The user input a number to use a particular function. The following table shows the number and function mapping:
|
||||
|
||||
| Number | Function |
|
||||
| :----: | --------------------------------------------------------------- |
|
||||
| 1 | Converting Euro or USD to HKD |
|
||||
| 2 | Calculating the minimum number of coins |
|
||||
| 3 | Calculating the total amount of principle and compound interest |
|
||||
| 4 | Quit the system |
|
||||
|
||||
> _Assume the user will input valid number (i.e. 1, 2, 3 or 4), this part is already done for you._
|
||||
|
||||
### 3.2. Go back to menu or continue
|
||||
|
||||
After every function is finished (except quit the system), the program should show the menu again and ask user to choose a function.
|
||||
|
||||
> _\*This part is already done for you._
|
||||
|
||||
## 4. IBS Functions
|
||||
|
||||
### 4.1. Converting Euro or USD to HKD
|
||||
|
||||
When user chooses this function, user can convert Euro or USD to HKD. User inputs strings "Euro" or "USD" to choose to convert Euro to HKD or USD to HKD respectively. Then, the program asks the user to input the amount of Euro or USD. After the users input the amount, the program shows the amount of HKD.
|
||||
|
||||
> _\*Assume the user will input valid strings (i.e. "Euro" and "USD")_
|
||||
|
||||
### 4.2. Calculating the minimum number of coins
|
||||
|
||||
When user chooses this function, the program calculates the minimum number of coins for corresponding amounts of dollars. User inputs an amount, then the program shows the minimum number of 10-dollar coins, 5-dollar coins, 2-dollar coins and 1-dollar coins.
|
||||
|
||||
### 4.3. Calculating the total amount of principle and compound interest
|
||||
|
||||
When user chooses this function, the program calculates the compound interest based on the inputted principle, interest rate and number of years compounded. User inputs principle, interest rate and number of years compounded, the program shows the total amount of principle and compound interest.
|
||||
|
||||
> _You have to use while loop to finish this function. Otherwise, marks will be deducted._
|
||||
|
||||
## 5. Sample input and output
|
||||
|
||||
All user inputs are bolded and underlined.
|
||||
|
||||
### 1. When program starts, the program shows the menu (this part is already done for you)
|
||||
|
||||
```bash
|
||||
Welcome to IBS! Please choose one of the following functions
|
||||
1. Converting Euro or USD to HKD
|
||||
2. Calculating the minimum number of coins
|
||||
3. Calculating the total amount of principle and compound interest
|
||||
4. Quit
|
||||
```
|
||||
|
||||
### 2. Convert Euro or USD to HKD
|
||||
|
||||
```bash
|
||||
Welcome to IBS! Please choose one of the following functions
|
||||
|
||||
1. Converting Euro or USD to HKD
|
||||
2. Calculating the minimum number of coins
|
||||
3. Calculating the total amount of principle and compound interest
|
||||
4. Quit
|
||||
1
|
||||
Currency to be converted to HKD (Euro / USD): Euro
|
||||
Amount to be converted: 10000
|
||||
10000.0 Euro = 80200.0 HKD
|
||||
```
|
||||
|
||||
### 3. Calculate the minimum number of coins
|
||||
|
||||
```bash
|
||||
Welcome to IBS! Please choose one of the following functions
|
||||
1. Converting Euro or USD to HKD
|
||||
2. Calculating the minimum number of coins
|
||||
3. Calculating the total amount of principle and compound interest
|
||||
4. Quit
|
||||
2
|
||||
Input an amount: 28
|
||||
The minimum numbers of coins for 21 dollars are:
|
||||
10-dollar coin(s): 2
|
||||
5-dollar coin(s): 1
|
||||
2-dollar coin(s): 1
|
||||
1-dollar coin(s): 1
|
||||
```
|
||||
|
||||
> **HINTS:**
|
||||
>
|
||||
> - Use the division (/) and remainder (%) operators.
|
||||
> - The inputted amount should be an integer.
|
||||
|
||||
### 4. Calculating the total amount of principle and compound interest
|
||||
|
||||
```bash
|
||||
Welcome to IBS! Please choose one of the following functions
|
||||
|
||||
1. Converting Euro or USD to HKD
|
||||
2. Calculating the minimum number of coins
|
||||
3. Calculating the total amount of principle and compound interest
|
||||
4. Quit
|
||||
3
|
||||
Input principle: 10000
|
||||
Input interest rate: 0.05
|
||||
Input number of years compounded: 4
|
||||
The total amount of principle and compound interest: 12155.0625
|
||||
```
|
||||
|
||||
> **HINTS:**
|
||||
>
|
||||
> - The inputted number of years should be integer.
|
||||
> - Use while loop to finish this function.
|
||||
|
||||
### 5. Quit the system (this part is already done for you)
|
||||
|
||||
```bash
|
||||
Welcome to IBS! Please choose one of the following functions
|
||||
1. Converting Euro or USD to HKD
|
||||
2. Calculating the minimum number of coins
|
||||
3. Calculating the total amount of principle and compound interest
|
||||
4. Quit
|
||||
4
|
||||
Thanks for using IBS! Bye!
|
||||
```
|
||||
|
||||
## 6. Hints
|
||||
|
||||
- Use input() to get user input, for example:
|
||||
|
||||
```bash
|
||||
name = input("Enter your name:");
|
||||
# variable "name" will store the string inputted by user
|
||||
```
|
||||
|
||||
- Use int() & input() to get user input and convert the datatype from string to integer, for example:
|
||||
|
||||
```bash
|
||||
amount = int(input("Enter an integer value:"));
|
||||
# variable "amount" will store the integer inputted by user
|
||||
```
|
||||
|
||||
- Use float() & input() to get user input and convert the datatype from string to floating-point number, for example:
|
||||
|
||||
```bash
|
||||
amount = float(input("Enter an floating-point value:"));
|
||||
# variable "amount" will store the floating-point number inputted by user
|
||||
```
|
||||
|
||||
## 7. Assumption
|
||||
|
||||
- All user inputs are valid.
|
||||
- You should copy the following code to the source file / online simulator to start your work. You are required to add codes of functions 1, 2 and 3 into the program.
|
||||
|
||||
```python
|
||||
"""
|
||||
ITE3919 - Programming Essentials in Python (Mini Project)
|
||||
Student Name: <<Your Name>>
|
||||
Student No: <<Your Student No.>>
|
||||
"""
|
||||
EURO_RATE = 8.02
|
||||
USD_RATE = 7.75
|
||||
|
||||
while True:
|
||||
print("Welcome to IBS! Please choose one of the following functions")
|
||||
print("1. Converting Euro or USD to HKD")
|
||||
print("2. Calculating the minimum number of coins")
|
||||
print("3. Calculating the total amount of principle and compound interest")
|
||||
print("4. Quit")
|
||||
|
||||
command = input()
|
||||
|
||||
if command == "1":
|
||||
# add your code of Function 1 here
|
||||
|
||||
elif command == "2":
|
||||
# add your code of Function 2 here
|
||||
|
||||
elif command == "3":
|
||||
# add your code of Function 3 here
|
||||
|
||||
elif command == "4":
|
||||
print("Thanks for using IBS! Bye!")
|
||||
break
|
||||
```
|
||||
|
||||
## 8. Marking Criteria
|
||||
|
||||
| Criteria | Proportion |
|
||||
| --------------------------------------------------------------------------- | :--------: |
|
||||
| Pseudo Code of Function 1 | 10% |
|
||||
| Function 1: Converting Euro or USD to HKD | 10% |
|
||||
| Function 2: Calculating the minimum number of coins | 10% |
|
||||
| Function 3: Calculating the total amount of principle and compound interest | 5% |
|
||||
| Program Style and Design | 5% |
|
||||
|
||||
## 9. Deadline
|
||||
|
||||
The deadline of this assignment is `DD/MMM/YYYY (WWW) HH:MM` **(GMT+8) according to Hong Kong Observatory Time**.
|
||||
|
||||
## 10. Submission Guideline
|
||||
|
||||
```python
|
||||
"""
|
||||
ITE3919 - Programming Essentials in Python (Mini Project)
|
||||
Student Name:<<Your Name>>
|
||||
Student No:<<Your Student No>>
|
||||
"""
|
||||
```
|
||||
|
||||
✔️ Add the following information as comment at the beginning of your source code:
|
||||
|
||||
✔️ Copy your source code from source file / online simulator to provided word file `EA Project*Answer Sheet*<<Your Name>>.docx` (e.g. `EA Project_Answer Sheet_ChanTaiMan.docx`)
|
||||
|
||||
✔️ Submit the word file to Moodle
|
||||
|
||||
✔️ For students who doesn’t follow the file name format, **marks will be deducted**
|
||||
|
||||
## 11. Remarks
|
||||
|
||||
✔️ This assignment worth 40% of the total course masrk
|
||||
|
||||
✔️ This is an individual assignment. No collaboration work is allowed
|
||||
|
||||
✔️ Plagiarism will be **SERIOUSLY PUNISHED**. All the plagiarism assignment will **receive 0 marks**
|
||||
|
||||
✔️ Enjoy your work
|
3
ifkcof/task1/gitUpdate.bat
Normal file
3
ifkcof/task1/gitUpdate.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
git add .
|
||||
git commit -m"update ifkcof,"
|
||||
start git push
|
103
ifkcof/task1/src/main.py
Normal file
103
ifkcof/task1/src/main.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""
|
||||
ITE3919 - Programming Essentials in Python (Mini Project)
|
||||
Student Name: <<Your Name>>
|
||||
Student No: <<Your Student No.>>
|
||||
"""
|
||||
EURO_RATE = 8.02
|
||||
USD_RATE = 7.75
|
||||
|
||||
|
||||
# from docx,
|
||||
# Assumption
|
||||
# - All user inputs are valid.
|
||||
|
||||
while True:
|
||||
print("Welcome to IBS! Please choose one of the following functions")
|
||||
print("1. Converting Euro or USD to HKD")
|
||||
print("2. Calculating the minimum number of coins")
|
||||
print("3. Calculating the total amount of principle and compound interest")
|
||||
print("4. Quit")
|
||||
|
||||
command = input()
|
||||
|
||||
if command == "1":
|
||||
# add your code of Function 1 here
|
||||
# Converting Euro and US dollars to Hong Kong Dollar
|
||||
# When user chooses this function, user can convert Euro or USD to HKD.
|
||||
# User inputs strings "Euro" or "USD" to choose to convert Euro to HKD or USD to HKD respectively. Then, the program asks the user to input the amount of Euro or USD.
|
||||
# After the users input the amount, the program shows the amount of HKD.
|
||||
|
||||
# Assume the user will input valid strings (i.e. "Euro" and "USD")
|
||||
print("Currency to be converted to HKD (Euro / USD): " , end="")
|
||||
currency = input()
|
||||
|
||||
print("Amount to be converted: " , end="")
|
||||
amount = float(input())
|
||||
|
||||
# init converted amount
|
||||
converted_amount = amount
|
||||
|
||||
# from Docx, Assume the user will input valid strings (i.e. "Euro" and "USD")
|
||||
if currency == "Euro":
|
||||
converted_amount = float(amount) * EURO_RATE
|
||||
else:
|
||||
converted_amount = float(amount) * USD_RATE
|
||||
|
||||
print("{:.1f} {} = {:.1f} HKD".format(float(amount), currency, float(converted_amount)))
|
||||
|
||||
elif command == "2":
|
||||
# add your code of Function 2 here
|
||||
# Calculating the minimum number of coins for corresponding amounts of dollars
|
||||
# When user chooses this function, the program calculates the minimum number of coins for corresponding amounts of dollars.
|
||||
# User inputs an amount, then the program shows the minimum number of 10-dollar coins, 5-dollar coins, 2-dollar coins and 1-dollar coins.
|
||||
|
||||
print("Input an amount: ", end="")
|
||||
amount = int(input())
|
||||
|
||||
print("The minimum numbers of coins for {} dollars are: ".format(amount))
|
||||
|
||||
# number of coins = quotient get divided by 10
|
||||
ten_dollar_coins = amount // 10
|
||||
remaining_amount = (amount - (ten_dollar_coins * 10))
|
||||
|
||||
# number of coins = quotient get divided by 5
|
||||
five_dollar_coins = remaining_amount // 5
|
||||
remaining_amount = (remaining_amount - (five_dollar_coins * 5))
|
||||
|
||||
# number of coins = quotient get divided by 2
|
||||
two_dollar_coins = remaining_amount // 2
|
||||
remaining_amount = (remaining_amount - (two_dollar_coins * 2))
|
||||
|
||||
one_dollar_coins = remaining_amount
|
||||
|
||||
print("10-dollar coin(s): {}".format(ten_dollar_coins))
|
||||
print("5-dollar coin(s): {}".format(five_dollar_coins))
|
||||
print("2-dollar coin(s): {}".format(two_dollar_coins))
|
||||
print("1-dollar coin(s): {}".format(one_dollar_coins))
|
||||
|
||||
elif command == "3":
|
||||
# add your code of Function 3 here
|
||||
# Calculating the total amount of principle and compound interest
|
||||
|
||||
# When user chooses this function, the program calculates the compound interest based on the inputted principle, interest rate and number of years compounded.
|
||||
# User inputs principle, interest rate and number of years compounded, the program shows the total amount of principle and compound interest.
|
||||
|
||||
print("Input principle: ", end="")
|
||||
principle = float(input())
|
||||
|
||||
print("Input interest rate: ", end="")
|
||||
intrest_rate = float(input())
|
||||
|
||||
print("Input number of years compounded: ", end="")
|
||||
years = int(input())
|
||||
|
||||
# init total amount
|
||||
total_amount = principle
|
||||
for i in range(0, years):
|
||||
total_amount = total_amount + (total_amount * (intrest_rate))
|
||||
|
||||
print("The total amount of principle and compound interest: {}".format(total_amount))
|
||||
|
||||
elif command == "4":
|
||||
print("Thanks for using IBS! Bye!")
|
||||
break
|
Reference in New Issue
Block a user