{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Sydney Stock Exchange – view trading on a particular day\n", "\n", "Select a date to view details of that day's trading (if any). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This notebook is designed to run in Voila as an app (with the code hidden).\n", "# To launch this notebook in Voila, just select 'View > Open with Voila in New Browser Tab'\n", "# Your browser might ask for permission to open the new tab as a popup." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import datetime\n", "import os\n", "from collections import Counter\n", "from urllib.parse import parse_qs, quote_plus\n", "\n", "import arrow\n", "import ipywidgets as widgets\n", "import pandas as pd\n", "from IPython.display import HTML, Image, display\n", "\n", "from page_data_master import pages_per_vol\n", "\n", "SESSIONS = {\"M\": \"Morning\", \"N\": \"Noon\", \"A\": \"Afternoon\", \"U\": \"Unknown\"}\n", "\n", "CLOUDSTOR_URL = \"https://cloudstor.aarnet.edu.au/plus/s/i02k4gxeEpMAUkm\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_pages(vol_num, page_num):\n", " for key, pages in pages_per_vol.items():\n", " vols = key.split(\"_\")\n", " vols = [int(y) for y in vols]\n", " if len(vols) == 2:\n", " vols = list(range(vols[0], vols[1] + 1))\n", " if vol_num in vols:\n", " for p_key, p_pages in pages.items():\n", " p_range = p_key.split(\"_\")\n", " if p_range[1] == \"*\":\n", " if page_num >= int(p_range[0]):\n", " return p_pages\n", " else:\n", " if page_num >= int(p_range[0]) and page_num <= int(p_range[1]):\n", " return p_pages" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get the list of dates\n", "df_dates = pd.read_csv(\"complete_date_list.csv\", parse_dates=[\"date\"])\n", "# Get the list of pages\n", "df_pages = pd.read_csv(\"complete_page_list.csv\", parse_dates=[\"date\"])\n", "# Merge dates and pages on the date field\n", "df = pd.merge(df_dates, df_pages, how=\"left\", on=\"date\").sort_values(\n", " by=[\"date\", \"page_num\"]\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def highlight_missing(row):\n", " \"\"\"\n", " Highlight missing pages.\n", " \"\"\"\n", " if row[\"pages expected\"] == row[\"pages found\"]:\n", " return [\"\", \"\"]\n", " else:\n", " return [\"\", \"background-color: yellow\"]\n", "\n", "\n", "def find_pages():\n", " results.clear_output()\n", " date = arrow.get(date_picker.value)\n", " with results:\n", " display(HTML(f'

{date.format(\"D MMMM YYYY\")}

'))\n", " rows = df.loc[df[\"date\"] == pd.Timestamp(date_picker.value)]\n", " first_page = rows.iloc[0][\"page_num\"]\n", " vol_num = rows.iloc[0][\"vol_num\"]\n", " num_pages = rows.iloc[0][\"pages\"]\n", " if date.weekday() < 6 and pd.notnull(vol_num):\n", "\n", " # Get the expected number of pages\n", " expected = get_pages(int(vol_num), int(first_page))\n", " if date.weekday() < 5:\n", " expected_pages = expected[\"weekday\"]\n", " elif date.weekday() == 5:\n", " expected_pages = expected[\"saturday\"]\n", " expected_num_pages = expected_pages[0]\n", " display(\n", " HTML(\n", " f\"

Number of pages: {expected_num_pages} expected / {int(num_pages)} found

\"\n", " )\n", " )\n", "\n", " # Display a breakdown of the number of pages per session\n", " expected_sessions = dict(Counter(expected_pages[1]))\n", " actual_sessions = rows[\"session\"].value_counts().to_dict()\n", " sessions = []\n", " for session, number in expected_sessions.items():\n", " try:\n", " sessions.append(\n", " {\n", " \"session\": SESSIONS[session],\n", " \"pages expected\": number,\n", " \"pages found\": actual_sessions[session],\n", " }\n", " )\n", " except KeyError:\n", " sessions.append(\n", " {\n", " \"session\": SESSIONS[session],\n", " \"pages expected\": number,\n", " \"pages found\": 0,\n", " }\n", " )\n", " display(\n", " pd.DataFrame(sessions)\n", " .set_index(keys=\"session\")\n", " .style.apply(highlight_missing, axis=1)\n", " )\n", "\n", " # Show page images\n", " for row in rows.itertuples():\n", " if pd.isnull(row.vol_title):\n", " print(row.reason)\n", " else:\n", " image_url = f\"{CLOUDSTOR_URL}/download?path={quote_plus(row.vol_title)}&files=N193-{int(row.vol_num):03}_{int(row.page_num):04}.jpg\"\n", " display(\n", " HTML(\n", " f'

{SESSIONS[row.session]}

{row.vol_title}, page {int(row.page_num)} – Download image

'\n", " )\n", " )\n", " display(Image(url=image_url))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def start(b):\n", " find_pages()\n", "\n", "\n", "date_picker = widgets.DatePicker(\n", " description=\"Pick a Date\", disabled=False, value=datetime.date(1901, 1, 1)\n", ")\n", "\n", "# with results:\n", "# print(os.environ.get('QUERY_STRING', ''))\n", "query_string = os.environ.get(\"QUERY_STRING\", \"\")\n", "parameters = parse_qs(query_string)\n", "date = parameters.get(\"date\")\n", "\n", "find = widgets.Button(\n", " description=\"Find pages\",\n", " disabled=False,\n", " button_style=\"primary\", # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip=\"Click me\",\n", " icon=\"search\",\n", ")\n", "\n", "find.on_click(start)\n", "results = widgets.Output()\n", "display(widgets.VBox([widgets.HBox([date_picker, find]), results]))\n", "# display(widgets.HBox([date_picker, find]))\n", "# display(results)\n", "\n", "\n", "if date:\n", " date_picker.value = arrow.get(date[0]).date()\n", " find_pages()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "Created by [Tim Sherratt](https://timsherratt.org) for the [GLAM Workbench](https://glam-workbench.github.io/)." ] } ], "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.8.12" }, "voila": { "template": "material" } }, "nbformat": 4, "nbformat_minor": 4 }