Great Deal! Get Instant $10 FREE in Account on First Order + 10% Cashback on Every Order Order Now

Can you do the first two parts according to instructions?

2 answer below »
Can you do the first two parts according to instructions?
Answered 40 days After Jan 13, 2021

Solution

Swapnil answered on Feb 22 2021
161 Votes
74525/python/.githu
classroom/autograding.json
{
"tests": [
{
"name": "test_partthree",
"setup": "sudo -H pip3 install pytest numpy",
"run": "pytest test_ps5.py::test_partthree",
"input": "",
"output": "",
"comparison": "included",
"timeout": 5,
"points": 25
},
{
"name": "test_partone",
"setup": "sudo -H pip3 install pytest numpy",
"run": "pytest test_ps5.py::test_partone",
"input": "",
"output": "",
"comparison": "included",
"timeout": 2,
"points": 20
},
{
"name": "test_parttwob",
"setup": "sudo -H pip3 install pytest numpy",
"run": "pytest test_ps5.py::test_parttwob",
"input": "",
"output": "",
"comparison": "included",
"timeout": 5,
"points": 25
},
{
"name": "test_parttwoa",
"setup": "sudo -H pip3 install pytest numpy",
"run": "pytest test_ps5.py::test_parttwoa",
"input": "",
"output": "",
"comparison": "included",
"timeout": 5,
"points": 20
}
]
}
74525/python/.githu
workflows/classroom.yml
name: GitHub Classroom Workflow
on: [push]
jobs:
build:
name: Autograding
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: education/autograding@v1
74525/python/.replit
language = "python3"
74525/python/__pycache__/cu
.cpython-37.pyc
74525/python/__pycache__/cu
_parser.cpython-37.pyc
74525/python/__pycache__/triggers.cpython-37.pyc
74525/python/cu
.py
import numpy as np
class Cu
ency:
def __init__(self, code, total_days):
self.code = code
self.BUY = np.zeros(total_days)
self.SELL = np.zeros(total_days)
def get_data_fragment(self, idx_1, idx_2, param):
data = self.__getattribute__(param)
return data[idx_1:idx_2]
def calc_change(self, idx_1, idx_2, prop):
"""
:param idx_1: first date index
:param idx_2: second date index
:param prop: property to be measured
:return:
"""
try:
value = 100*(idx_2 - idx_1)/idx_1
except ZeroDivisionE
or:
value=0
return value
def calc_mean(self,idx_1, idx_2, prop):
"""
Calculates mean of a property given date indices
:param idx_1: first date index
:param idx_2: second date index
:param prop: property to be measured
:return:
"""
value = np.mean(c.get_data_fragment(idx_1, idx_2, prop))
return value
def calc_volatility(self, idx_1, idx_2,prop):
value = np.var(c.get_data_fragment(idx_1, idx_2, prop))
return value
def calc_max(self, idx_1, idx_2, prop):
"""
Desc
:param idx_1: first date index
:param idx_2: second date index
:param prop: property to be measured
:return: float
"""
value = np.max(c.get_data_fragment(idx_1, idx_2, prop))
return value
def calc_min(self, idx_1, idx_2, prop):
"""
Desc
:param idx_1: first date index
:param idx_2: second date index
:param prop: property to be measured
:return: float
"""
value = np.min(c.get_data_fragment(idx_1, idx_2, prop))
return value
if __name__ == "__main__":
# DON'T MODIFY THIS!
total_days = 10
c = Cu
ency("EUR", total_days)
np.random.seed(42)
c.BUY = 5.0*np.ones(total_days) + np.random.rand(total_days)
c.SELL = c.BUY + 0.1
print("Change: ", c.calc_change(0, 7, "BUY"))
print("Vol: ", c.calc_volatility(2, 9, "SELL"))
print("Max: ",c.calc_max(4, 9, "SELL"))
print("Mean: ",c.calc_mean(4, 9, "SELL"))
print("Min: ",c.calc_min(0, 3, "BUY"))
74525/python/cu
_database.py
from cu
import Cu
ency
import datetime
from cu
_parser import get_data
from triggers import LowTrigger,HighTrigger,AndTrigger,OrTrigger,NotTrigge
import numpy as np
class Cu
encyDatabase:

def __init__(self, start_date, end_date):
self.start_date = self.conv2date(start_date)
self.end_date = self.conv2date(end_date)
self.market_open = np.zeros(self.date_cnt)
self.cu
ency_list = ['USD', 'AUD', 'DKK', 'EUR', 'GBP', 'CHF', 'SEK', 'CAD', 'KWD',
'NOK', 'SAR', 'JPY', 'BGN', 'RON', 'RUB', 'IRR', 'CNY', 'PKR']
self.trigger_list = []
self.analysis_list = []
self.comp_trigger_list = []
self.comp_analysis_list = []

self.db = {}
for cu
in self.cu
ency_list:
self.db[cu
] = Cu
ency(total_days=self.date_cnt, code=cu
)
# Get data from TCMB
for i in range(self.date_cnt):
date = self.start_date + datetime.timedelta(days=i)
data_dict = get_data(date)
# Check the dictionary is emtpy
if bool(data_dict):
db[cu
]= data_dict[i]
# Market is open. TODO
self.market_open[i] = 1
return db[cu
]
else:
db[cu
] = date_dict[i-1]

# Market is closed. TODO
print("Database init completed.")
print(f"Database interval: {self.start_date} - {self.end_date}")
print(f"Fetched {self.date_cnt} days. Market is open {np.sum(self.market_open)} days.")
print(f"There are {len(self.cu
ency_list)} cu
encies.")
print("---")
@property
def date_cnt(self,start_date,end_date):
if start_date == end_date:
val = 1
else:
val = (end_date-start_date).days

return val
def conv2date(self, date):
date = datetime(date)
return date
def idx2date(self, idx):
date = datetime()
return date
def date2idx(self, target_date):
idx = DatetimeIndex(target_date)
assert idx >= 0, f'Date is out of range!'
assert self.date_cnt >= idx, "Date is out of range!"
return idx
def set_triggers(self, trigger_list_path):
with open(trigger_list_path, "r") as f:
for line in f:
# Read the line, parse as a list
arg = line.rstrip().split()
# Extract list
trig_cls = arg[0] # Trigger class
if trig_cls == "LOW":
date_start_str = arg[4]
date_end_str = arg[5]
date_start_idx = self.date2idx(date_start_str.split('/'))
date_end_idx = self.date2idx(date_end_str.split('/'))
trigger = LowTrigger(func = arg[1], prop = arg[2], threshold = float(arg[3]),
date_start_idx=date_start_idx, date_end_idx=date_end_idx,
date_start_str = date_start_str, date_end_str = date_end_str)
elif trig_cls == "HIGH":
date_start_str = arg[4]
date_end_str = arg[5]
date_start_idx = self.date2idx(date_start_str.split('/'))
date_end_idx = self.date2idx(date_end_str.split('/'))
trigger = HighTrigger(func = arg[1], prop = arg[2], threshold = float(arg[3]),
date_start_idx=date_start_idx, date_end_idx=date_end_idx,
date_start_str = date_start_str, date_end_str = date_end_str)
elif trig_cls == "NOT":
trig_idx = int(arg[1])
trigger = NotTrigger(self.trigger_list[trig_idx])
elif trig_cls == "AND":
trig_idx_1 = int(arg[1])
trig_idx_2 = int(arg[2])
trigger = AndTrigger(self.trigger_list[trig_idx_1], self.trigger_list[trig_idx_2])
elif trig_cls == "OR":
trig_idx_1 = int(arg[1])
trig_idx_2 = int(arg[2])
trigger = OrTrigger(self.trigger_list[trig_idx_1], self.trigger_list[trig_idx_2])
print(f'Initialized trigger: {trigger}')
self.trigger_list.append(trigger)
print("Initializing triggers complete!")
print("---")
def run_triggers(self):
"""
Runs triggers on a specific date interval.
If start date is not set, it scans from the first day.
If end date is not set, it scans to the end.
If nothing has been set, it scans entire dataset.
:param start_date: tuple ()
:param end_date: tuple ()
:return:
"""
for trig in self.trigger_list:
print(f'Evaluating trigger: {trig}')
analysis = []
for cu
_code in self.cu
ency_list:
cu
= self.db[cu
_code]
result = trig.evaluate(cu
)
if result:
analysis.append(cu
.code)
self.analysis_list.append(analysis)
print("Running triggers complete!")
def analyze(self, trigger_list_path = False, debug = False):
self.set_triggers(trigger_list_path=trigger_list_path)
self.run_triggers()
print(f'============Writing Report============')
for idx, list in enumerate(self.analysis_list):
if list:
print(f"{idx + 1} - {self.trigger_list[idx]} is fired for: {list}")
elif not list and debug:
print(f"{idx + 1} - {self.trigger_list[idx]} is not fired!")
print(f'==========End of the Report==========')
74525/python/cu
_parser.py
import xml.etree.ElementTree as ET
import urlli
from urllib.request import urlopen
import datetime
def get_data(date):
"""
:param date: datetime object
:return: data dictionary of cu
ency values.
"""
# Prepare the URL
url = 'https:
www.tcmb.gov.t
kurla
'+ datetime.datetime.strftime(date,"%Y%m")+'/'+ datetime.datetime.strftime(date,"%d%m%Y")+'.xml'
# Container for the date
data_dict = {}
try:
tree = ET.parse(urlopen(url))
root = tree.getroot()
for cu
ency in root.findall('Cu
ency'):
code = cu
ency.get('Cu
encyCode')
# Skip it since this is not a cu
ency.
if code == "XDR":
continue
unit=cu
ency.find('Unit').text
buying=cu
ency.find('ForexBuying').text
selling=cu
ency.find('ForexSelling').text
# Prepare a dictionary to store parsed information.
cur_dict = {'buying': buying, 'selling': selling}
# Save the cu
ency dictionary to data dictionary.
data_dict[code] = cur_dict
except urllib.e
or.HTTPE
or as e
:
if e
.code == 404:
'whatever'
else:
raise
return data_dict
if __name__ == "__main__":
date = datetime.datetime(2020, 9, 14)
cur_dict = get_data(date)
print(cur_dict)
date = datetime.datetime(2020, 1, 1)
cur_dict = get_data(date)
74525/python/Instructions.md
# TCMB Cu
ency Database
# Deadline: 17/01/2021 - 11:00pm
Required reading: Section 4.5 & 4.6 from your textbook.
## Part 0: Overview
In this assignment, you will implement a small cu
ency database for the Central Bank of Turkey (TCMB), which holds TRY (Turkish Lira) foreign exchange rates
for a short interval. In this database, you will implement alarm mechanisms to alert the cu
ency analysts if a specific threshold is violated,
for example, when EUR/TRY is lower than 5.2.
You will complete your implementation in three parts.
In the first part, you will code a parser, text-processor for a webpage in XML format.This parser is going to fetch the data stored
in the [Central Bank of Turkey webpage](https:
www.tcmb.gov.t
kurla
201806/29062018.xml).This link returns daily cu
ency rates based on URL.
The first segment of the link is the year-month format (2018 and 06).
The second segment of the link is in the day-month-year format.
You will extract foreign exchange (forex) buying and selling data from this tabular data with the code inside "cu
_parser.py".
In the second part, you will implement a cu
ency class (in cu
ency.py) that holds this parsed exchange data. Each cu
ency will be an instance of this class,
and you will keep this data in an indexed format. Then, you will aggregate these instances inside a master-class, called `Cu
encyDatabase`.
This class will implement the high-level operations such as indexing, running triggers, writing reports, etc.
In the final part, you will implement the alarm mechanism for this database, namely, triggers. You will process trigger definitions from the "triggers.txt"
file provided. In each line of this file, there is a trigger configuration. You will iterate over the database and trigger an alarm if a specific
threshold is violated.
We provide you a skeleton code to complete all of these parts in multiple files.
## Part I: (Text Processing) Building the Parse
1. In the "cu
_parser.py" file, we have a `get_data` function, which expects a `datetime` object, parses an XML file, and
returns a dictionary of cu
ency values.
The following definitions and sources may be useful for you in this part:
* To work with dates as objects, you will need a module called `datetime`. This class date contains the year, month, day, hour, minute, second,
and microsecond,
and implements powerful functions. For more information, please check the [Python documentation for the `datetime` module]
(https:
docs.python.org/3/li
ary/datetime.html).
* Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a human-readable and machine-readable format.
TCMB stores money data on the web in this format.
First, construct the URL as a string. For example, for June 29th of 2019, the url should be as follows:
https:
www.tcmb.gov.t
kurla
201806/29062018.xml
For the date-related part, you need to use the class properties of the `datetime` such as `month`.
**Hint**: Check the `strftime` method, which returns a custom string representing the date.
2. The page is in a both human-readable and machine-readable format. We can see the source of the page by typing into a
owser
view-source:https:
www.tcmb.gov.t
kurla
201806/29062018.xml
or
y going to the website
https:
www.tcmb.gov.t
kurla
201806/29062018.xml
and doing right-click and then choosing the "view source".
This way, we can see the data stored on this webpage. This page structure is called an *element-tree*. A tree is a data structure with a root value and subtrees
of children with a parent node. The root-node of this XML is:
```
Tarih_Date Tarih="29.06.2018" Date="06/29/2018" Bulten_No="2018/125"
...
Tarih_Date
```
and one of the children subtrees is a cu
ency tree, which holds daily exchange rate information:
```
Cu
ency CrossOrder="0" Kod="USD" Cu
encyCode="USD"
            1
Unit
            ABD DOLARI
Isim
            encyName>US DOLLAR
Cu
encyName
            4.5607
ForexBuying
            4.5690
ForexSelling
            4.5575
BanknoteBuying
            4.5758
BanknoteSelling
                                
Cu
ency
```
All subtrees -except one which you should not wo
y about- are in the same format. All we need to do is to iterate over each subtree and extract information
for cu
ency exchange. From each subtree, we need to extract the attribute `Cu
encyCode` and the information stored in the leaves including `Unit`, `ForexBuying`,
and `ForexSelling`. `ForexBuying` and `ForexSelling` define the conversion rates used for money trading as explained next with an example.
For example, for the `Cu
encyCode` USD, if the `ForexSelling` is equal to 4.5690, this means by selling 1 USD, the bank will receive 4.5690 TRY in return.
Similarly, if the `ForexBuying` is equal to 4.5607, this means in order to buy 1 USD, the bank needs to spend 4.5607 TRY. `Unit` is used to scale down values
into readable ranges for some cu
encies. The value is typically 1, then we do not need to do anything but if it is greater than 1, for example 100 for some
cu
encies, then we need to multiply both `ForexSelling` and `ForexBuying` by the `Unit`.
Please follow the instructions to extract this information as follows:
To extract the value of an attribute like `CrossOrder` or `Cu
encyCode`, you can use `get` function of the tree object. For example, `cu
ency.get('CrossOrder')`
eturns "0". We do not need to know its implementation in order to use this function. This is called *abstraction*.
To extract the information stored inside the leaves, you can call the `find` function of the tree object. This returns an XML-Unit object instance, which has a
class property called `text` that is a string. Here, you are accessing a property of a class instance. For example, `cu
ency.find('Cu
encyName').text` returns
a string "US DOLLAR". You need to cast it appropriately if you are processing numeric data.
To complete this section, please fill in the TODO part 2 in "cu
_parser.py".
3. (Exception handling) As you might imagine, not all pages are available all the time, for example when the exchange market is closed. Use exception handling
to catch these cases, and show a meaningful message, e.g. with the URL or date in consideration as shown in the example below.
You can test your implementation by running "cu
_parser.py". We provide a small script as a tester. If you get the same output with the following,
you are good to go!
```
{'USD': {'buying': 7.4689, 'selling': 7.4823}, 'AUD': {'buying': 5.4207, 'selling': 5.4561}, 'DKK': {'buying': 1.1887, 'selling': 1.1946},
'EUR': {'buying': 8.858, 'selling': 8.8739}, 'GBP': {'buying': 9.5837, 'selling': 9.6336}, 'CHF': {'buying': 8.2078, 'selling': 8.2605},
'SEK': {'buying': 0.84827, 'selling': 0.85705}, 'CAD': {'buying': 5.6628, 'selling': 5.6883}, 'KWD': {'buying': 24.29, 'selling': 24.6079},
'NOK': {'buying': 0.82709, 'selling': 0.83265}, 'SAR': {'buying': 1.9912, 'selling': 1.9948}, 'JPY': {'buying': 702.9200000000001, 'selling': 707.58},
'BGN': {'buying': 4.5035, 'selling': 4.5624}, 'RON': {'buying': 1.8134, 'selling': 1.8372}, 'RUB': {'buying': 0.09894, 'selling': 0.10023},
'IRR': {'buying': 1.7680000000000002, 'selling': 1.791}, 'CNY': {'buying': 1.0882, 'selling': 1.1024}, 'PKR': {'buying': 0.0447, 'selling': 0.04528},
'QAR': {'buying': 2.0392, 'selling': 2.0659}}
HTTP E
or 404: Not Found - https:
www.tcmb.gov.t
kurla
202001/01012020.xml
```
## Part IIa: (OOP) Cu
ency Class
We will start by implementing a `Cu
ency` class for our database. This class will hold our cu
ency exchange data and also provide some analysis functions
such as calculating the mean, the minimum, the maximum, the change rate, and the volatility over a given interval. We will use `NumPy`,
which is a fundamental package for scientific computing in Python.
You can construct a `Cu
ency` object with two parameters only: `code` and `total_days`. `code` stands for `Cu
encyCode` in your parsed XML file,
a short notation for cu
encies (e.g., EUR, USD, JPY). `total_days` stands for the number of days that our cu
ency data is fetched. For example,
`Cu
ency("EUR", 10)` creates a cu
ency object for Euro for 10 days data. Initially, your data is set to 0; that's what `np.zeros(total_days)` does.
You will implement five numeric calculation functions: `mean`, `min`, `max`, `volatility`, and `change`. Each of them expects two indices; start date index,
end date index, and a property to measure (`BUY` or `SELL`). For your convenience, we provide `get_data_fragment` function to extract cu
ency data over an
interval for you.
* Mean is computed by averaging all of the values inside a data...
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here