Nurturing Session

Problem: Combined Daily Time Series

%load_problem combined-daily-time-series
Problem: Combined Daily Time Series

Write a function combined_daily_time_series that combines stock data from www.alphavantage.co. for given list of symbols and returns a dataframe. The dataframe should have these numeric columns, open, high, low, close, volume, symbol. Here are some hints. Have a look at these functions and methods pd.concat, DataFrame.rename, pd.to_numeric

Also write a function get_total_volume which takes dataframe generated by above function and returns a series that symbols as row labels and total volume for that symbol as a value.

>>> df = combined_daily_time_series(["AAPL","IBM"])
>>> df
open  high low close volume symbol
2022-08-25 20:00:00 170.290 170.3500 170.2000 170.2000 11160 AAPL
2022-08-25 20:15:00 170.290 170.3500 170.2000 170.2000 11160 AAPL
2022-08-25 20:30:00 170.290 170.3500 170.2000 170.2000 11160 AAPL
.
.
2022-08-25 20:00:00 170.290 170.3500 170.2000 170.2000 11160 IBM
2022-08-25 20:15:00 170.290 170.3500 170.2000 170.2000 11160 IBM

200 rows × 6 columns

>>> get_total_volume(df)
symbol
AAPL    77772389
IBM      7689538
Name: volume, dtype: int64

You can verify your solution using:

%verify_problem combined-daily-time-series

# your code here


import pandas as pd
d1 = pd.DataFrame({"a":[1, 2, 3, 4, 5],
              "b":["h","e","l","l","o"]})
d1
a b
0 1 h
1 2 e
2 3 l
3 4 l
4 5 o
d1['symbol'] = 'APPL' # you will add for column for symbol
d1
a b symbol
0 1 h APPL
1 2 e APPL
2 3 l APPL
3 4 l APPL
4 5 o APPL
d1.rename(columns={"a":"high", "b":"low"}) # you will rename the column using this
high low symbol
0 1 h APPL
1 2 e APPL
2 3 l APPL
3 4 l APPL
4 5 o APPL
d2 = pd.DataFrame({"a":["1", "2", "3", "4", "5"],
              "b":["h","e","l","l","o"]})
d2
a b
0 1 h
1 2 e
2 3 l
3 4 l
4 5 o
d2.a + 2
TypeError: can only concatenate str (not "int") to str
d2.info() # this is how you see what are types of columns from dataframe
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   a       5 non-null      object
 1   b       5 non-null      object
dtypes: object(2)
memory usage: 208.0+ bytes
d2['a'] = pd.to_numeric(d2['a'])
d2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   a       5 non-null      int64 
 1   b       5 non-null      object
dtypes: int64(1), object(1)
memory usage: 208.0+ bytes
  • combined-daily-time-series
   dfs = []
   for symbol in symbols:
       data = fetch_from_internet(symbol)
       data = curate_data() # will change types of columns. change names of columns
       data['symbol'] = symbol
       dfs.appned(data)

    return pd.concat(dfs)
wallet = pd.read_csv("wallet.csv")
wallet
Unnamed: 0 date category description debit
0 0 2021-03-07 14:53:28.377359 Music Amazon 421.207327
1 1 2020-10-08 09:53:28.377359 Food Swiggy 328.440080
2 2 2021-02-23 09:53:28.377359 Books Amazon 244.679437
3 3 2020-11-01 14:53:28.377359 Utility Phone 222.756318
4 4 2021-06-05 13:53:28.377359 Books Flipcart 494.128492
... ... ... ... ... ...
95 95 2021-07-19 13:53:28.377359 Utility Phone 388.671213
96 96 2021-01-12 19:53:28.377359 Books Flipcart 467.554562
97 97 2021-03-25 11:53:28.377359 Utility Phone 320.789434
98 98 2021-05-13 15:53:28.377359 Travel Taxi 442.096469
99 99 2020-10-11 16:53:28.377359 Food Hotel 100.455501

100 rows × 5 columns

wallet.groupby("description")['debit'].sum() # change column names to what is appropriate for above problem
description
Amazon           2504.690567
Amazon Kindle    1389.052376
Auto             2210.428935
Electricity      2885.064355
Flipcart         2503.255216
Hotel            2752.174732
Metro            1216.463665
Netflix          1546.567562
Phone            4677.202878
Swiggy           1936.495366
Taxi             2626.039276
Zomato           3592.519075
spotify          1219.636541
Name: debit, dtype: float64
  • the site allows only 25 calls per day!
  • get your data in one variable after you download it from internet!
  • then till you fix your solution don’t fetch the data again and again …make use of variable

Problem: Client for Free Dictionary API

%load_problem dict-client
Problem: Client for Free Dictionary API

Write a program dict.py to find the meaning of a word using the Free Dictionary API.

Expected Usage

The program should take one word as argument and display the phonetics and meaning of that word using the Free Dictionary API.

$ python dict.py obscure
onscure /əbˈskjɔː(ɹ)/

VERB

To render obscure; to darken; to make dim; to keep in the dark; to hide; to make less visible, intelligible, legible, glorious, beautiful, or illustrious.

To hide, put out of sight etc.

To conceal oneself; to hide.

ADJECTIVE

Dark, faint or indistinct.

Hidden, out of sight or inconspicuous.

As you can see, The first line in the word and its phonetic. For each part of speech, the part of speech is shown in uppercase, followed by each of the meaning provided in the response. There will be exactly one new line after each meaning and part-of-speech line.

You can verify your solution using:

%verify_problem dict-client

%%file dict.py
# your code here


def get_word_data(word):
    #make use of requests and string fromating to fetch data
    url = f"https://api.dictionaryapi.dev/api/v2/entries/en/{word}"
    # request.get(url).json()
    return [
    {
      "word": "hello",
      "phonetic": "həˈləʊ",
      "phonetics": [
        {
          "text": "həˈləʊ",
          "audio": "//ssl.gstatic.com/dictionary/static/sounds/20200429/hello--_gb_1.mp3"
        },
        {
          "text": "hɛˈləʊ"
        }
      ],
      "origin": "early 19th century: variant of earlier hollo ; related to holla.",
      "meanings": [
        {
          "partOfSpeech": "exclamation",
          "definitions": [
            {
              "definition": "used as a greeting or to begin a phone conversation.",
              "example": "hello there, Katie!",
              "synonyms": [],
              "antonyms": []
            }
          ]
        },
        {
          "partOfSpeech": "noun",
          "definitions": [
            {
              "definition": "an utterance of ‘hello’; a greeting.",
              "example": "she was getting polite nods and hellos from people",
              "synonyms": [],
              "antonyms": []
            }
          ]
        },
        {
          "partOfSpeech": "verb",
          "definitions": [
            {
              "definition": "say or shout ‘hello’.",
              "example": "I pressed the phone button and helloed",
              "synonyms": [],
              "antonyms": []
            }
          ]
        }
      ]
    }
  ]
get_word_data("hello")
[{'word': 'hello',
  'phonetic': 'həˈləʊ',
  'phonetics': [{'text': 'həˈləʊ',
    'audio': '//ssl.gstatic.com/dictionary/static/sounds/20200429/hello--_gb_1.mp3'},
   {'text': 'hɛˈləʊ'}],
  'origin': 'early 19th century: variant of earlier hollo ; related to holla.',
  'meanings': [{'partOfSpeech': 'exclamation',
    'definitions': [{'definition': 'used as a greeting or to begin a phone conversation.',
      'example': 'hello there, Katie!',
      'synonyms': [],
      'antonyms': []}]},
   {'partOfSpeech': 'noun',
    'definitions': [{'definition': 'an utterance of ‘hello’; a greeting.',
      'example': 'she was getting polite nods and hellos from people',
      'synonyms': [],
      'antonyms': []}]},
   {'partOfSpeech': 'verb',
    'definitions': [{'definition': 'say or shout ‘hello’.',
      'example': 'I pressed the phone button and helloed',
      'synonyms': [],
      'antonyms': []}]}]}]
data =  get_word_data("hello") 
type(data)
list
len(data)
1
data[0]['phonetic']
'həˈləʊ'
def prety_print(word, data):
    d = data[0]
    print(f"{word} {d['phonetic']}")
prety_print("hello", data)
hello həˈləʊ

Problem: Frankfurter Exchange Rates

%load_problem frankfurter
Problem: Frankfurter Exchange Rates

Write a program frankfurter.py to list the historical currency rate of a currency against a base currency using Frankfurter Exchange Rate API.

The program should take the following command-line arguments.

  --currency CURRENCY target currency, default INR
  --base BASE  base currency, default USD
  --date DATE  First date to consider, default yesterday
  --days DAYS  number of days to display

The program should display the curreny rate between the base currency and the target currency for n days starting from yesterday. Optionally, the start date could be provided as a command-line argument.

Please note that there convertion data is not available on weekends. So the number of rows of data shown may be less than n.

The Output Format

The output needs to be properly tabulated. Please use Python library tabulate for doing this.

Please refer to Printing Tables with Tabulate in the Python Cookbook to learn how to the the tabulate library.

Usage

$ python frankfurter.py
Date          USD    INR
----------  -----  -----
2023-10-18      1  83.25
2023-10-17      1  83.22
2023-10-16      1  83.25
2023-10-13      1  83.27
2023-10-12      1  83.24
2023-10-11      1  83.18
2023-10-10      1  83.24
2023-10-09      1  83.3
$ python frankfurter.py --days 2
Date          USD    INR
----------  -----  -----
2023-10-18      1  83.25
2023-10-17      1  83.22
$ python frankfurter.py --base GBP
Date          GBP     INR
----------  -----  ------
2023-10-18      1  101.55
2023-10-17      1  101.31
2023-10-16      1  101.37
2023-10-13      1  101.41
2023-10-12      1  102.47
2023-10-11      1  102.24
2023-10-10      1  101.96
2023-10-09      1  101.39
$ python frankfurter.py --base GBP --currency USD
Date          GBP     USD
----------  -----  ------
2023-10-18      1  1.2198
2023-10-17      1  1.2173
2023-10-16      1  1.2176
2023-10-13      1  1.2178
2023-10-12      1  1.231
2023-10-11      1  1.2292
2023-10-10      1  1.2249
2023-10-09      1  1.2172
$ python frankfurter.py --date 2023-01-31
Date          USD    INR
----------  -----  -----
2023-01-31      1  81.82
2023-01-30      1  81.53
2023-01-27      1  81.61
2023-01-26      1  81.53
2023-01-25      1  81.57
2023-01-24      1  81.62
2023-01-23      1  81.36

Hints

You can verify your solution using:

%verify_problem frankfurter

%%file frankfurter.py
# your code here


def get_exchange_data(start, end):
    url = f"https://api.frankfurter.app/{start}..{end}"
    params = {"base":"USD", "to":"INR"} # here base and to is hardcoded but you can take it as argumet
    r = requests.get(url, params=params)
    return r.json()
d = get_exchange_data("2024-01-01", "2024-01-31")
d
{'amount': 1.0,
 'base': 'USD',
 'start_date': '2024-01-02',
 'end_date': '2024-01-31',
 'rates': {'2024-01-02': {'INR': 83.32},
  '2024-01-03': {'INR': 83.3},
  '2024-01-04': {'INR': 83.24},
  '2024-01-05': {'INR': 83.15},
  '2024-01-08': {'INR': 83.11},
  '2024-01-09': {'INR': 83.11},
  '2024-01-10': {'INR': 83.03},
  '2024-01-11': {'INR': 83.02},
  '2024-01-12': {'INR': 82.93},
  '2024-01-15': {'INR': 82.87},
  '2024-01-16': {'INR': 83.09},
  '2024-01-17': {'INR': 83.14},
  '2024-01-18': {'INR': 83.15},
  '2024-01-19': {'INR': 83.08},
  '2024-01-22': {'INR': 83.13},
  '2024-01-23': {'INR': 83.12},
  '2024-01-24': {'INR': 83.11},
  '2024-01-25': {'INR': 83.13},
  '2024-01-26': {'INR': 83.13},
  '2024-01-29': {'INR': 83.16},
  '2024-01-30': {'INR': 83.13},
  '2024-01-31': {'INR': 83.05}}}
import tabulate
records = [
    ["IBM", 123, 124, 5.0],
    ["APPL", 225, 226.5, 4.0] 
]
print(tabulate.tabulate(records))
----  ---  -----  -
IBM   123  124    5
APPL  225  226.5  4
----  ---  -----  -
print(tabulate.tabulate(records, headers=['symbol','price','high','gain']))
symbol      price    high    gain
--------  -------  ------  ------
IBM           123   124         5
APPL          225   226.5       4
currency_data = [[date, 1.0, value["INR"]] for date, value in d['rates'].items()]
currency_data
[['2024-01-02', 1.0, 83.32],
 ['2024-01-03', 1.0, 83.3],
 ['2024-01-04', 1.0, 83.24],
 ['2024-01-05', 1.0, 83.15],
 ['2024-01-08', 1.0, 83.11],
 ['2024-01-09', 1.0, 83.11],
 ['2024-01-10', 1.0, 83.03],
 ['2024-01-11', 1.0, 83.02],
 ['2024-01-12', 1.0, 82.93],
 ['2024-01-15', 1.0, 82.87],
 ['2024-01-16', 1.0, 83.09],
 ['2024-01-17', 1.0, 83.14],
 ['2024-01-18', 1.0, 83.15],
 ['2024-01-19', 1.0, 83.08],
 ['2024-01-22', 1.0, 83.13],
 ['2024-01-23', 1.0, 83.12],
 ['2024-01-24', 1.0, 83.11],
 ['2024-01-25', 1.0, 83.13],
 ['2024-01-26', 1.0, 83.13],
 ['2024-01-29', 1.0, 83.16],
 ['2024-01-30', 1.0, 83.13],
 ['2024-01-31', 1.0, 83.05]]
print(tabulate.tabulate(currency_data, headers=['Date', 'USD', 'INR']))
Date          USD    INR
----------  -----  -----
2024-01-02      1  83.32
2024-01-03      1  83.3
2024-01-04      1  83.24
2024-01-05      1  83.15
2024-01-08      1  83.11
2024-01-09      1  83.11
2024-01-10      1  83.03
2024-01-11      1  83.02
2024-01-12      1  82.93
2024-01-15      1  82.87
2024-01-16      1  83.09
2024-01-17      1  83.14
2024-01-18      1  83.15
2024-01-19      1  83.08
2024-01-22      1  83.13
2024-01-23      1  83.12
2024-01-24      1  83.11
2024-01-25      1  83.13
2024-01-26      1  83.13
2024-01-29      1  83.16
2024-01-30      1  83.13
2024-01-31      1  83.05
%%file frankfurter.py
import typer
import datetime

def print_currency_data(currency="INR", 
                        base="USD", 
                        date=str(datetime.date.today() - datetime.timedelta(days=1)) , 
                        days=10):
    # fetch data
    # print
    pass


typer.run(print_currency_data)
Overwriting frankfurter.py
!python frankfurter.py --help
Usage: frankfurter.py [OPTIONS]

Options:
  --currency TEXT  [default: INR]
  --base TEXT      [default: USD]
  --date TEXT      [default: 2024-03-26]
  --days TEXT      [default: 10]
  --help           Show this message and exit.
import datetime
yest = datetime.date.today() - datetime.timedelta(days=1)
yest
datetime.date(2024, 3, 26)
str(yest)
'2024-03-26'
  • given a date in text how to convert it into date?
datetime.date.fromisoformat('2024-03-26')
datetime.date(2024, 3, 26)