{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a554392b",
   "metadata": {},
   "source": [
    "# Lesson 7 Exercise\n",
    "\n",
    "This lesson is divided into two main sections.\n",
    "\n",
    "In the first part, you'll choose the most suitable type of graph for a variety of weather-related datasets and use the Matplotlib functions and methods you learned in order to construct informative visualizations.\n",
    "\n",
    "In the second (optional) part, you'll read the Matplotlib documentation to learn how to create a specialized type of graph that we didn't cover in the lesson. The goal is to practice reading and applying knowledge from the documentation, which is a useful skill not just in the context of Matpotlib, but any time you're working with a new library or tool (which is pretty much always)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "859f293c",
   "metadata": {},
   "source": [
    "# Part 0: Setup and necessary Python modules"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "597cca7b",
   "metadata": {},
   "source": [
    "Please be sure to use the Python virtual environment you've set up for this course. Pandas, Numpy, Seaborn, and Matplotlib should already be installed if you followed the tutorials.\n",
    "\n",
    "You will also need a new package. We will use **Meteostat**, a publicly available weather data API for Python. This will be used to fetch weather data for our visualizations, but you will not need to work with it directly. Should you be interested in learning more about it, you can find the documentation here:  \n",
    "[https://dev.meteostat.net/python/](https://dev.meteostat.net/python/)\n",
    "\n",
    "You can install Meteostat using pip by running the code block below (it will also attempt to install the other packages if you don't have them already):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0fd0141f",
   "metadata": {
    "vscode": {
     "languageId": "shellscript"
    }
   },
   "outputs": [],
   "source": [
    "!pip install pandas numpy seaborn matplotlib meteostat"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45829df5",
   "metadata": {},
   "source": [
    "If that code block didn't work, just run the following command in your terminal:\n",
    "```\n",
    "pip install numpy pandas seaborn matplotlib meteostat\n",
    "```\n",
    "\n",
    "Next, import the necessary Python modules by running the following code block:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abc7ef47",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "from datetime import datetime\n",
    "from meteostat import Hourly as H\n",
    "from meteostat import Daily as D"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69c885fa",
   "metadata": {},
   "source": [
    "# Part 1: Creating appropriate visualizations for weather data\n",
    "\n",
    "During the lesson, you learned how to create four different types of graphs using Matplotlib:\n",
    "- Line graphs\n",
    "- Scatter plots\n",
    "- Bar graphs\n",
    "- Histograms\n",
    "\n",
    "This section will provide three datasets, and it will be your job to choose the most appropriate type of graph for each dataset and create it using Matplotlib (no graph type will be used twice). Later, you can use the solution sheet to compare your generated graphs with the provided solutions.\n",
    "\n",
    "Of course, there is a lot of flexibility in how you can create graphs in Matplotlib, so it is natural that your graphs won't looks *exacctly* like the solutions, but as long as you're in the same ballpark, you're doing just fine!\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a95fd9bc",
   "metadata": {},
   "source": [
    "## Graph 1\n",
    "\n",
    "**Run**: The code block below will fetch the data which will be used for this first graphing exercise. `df1_munich` contains weather data for Munich, Germany and `df1_muc` contains weather data for Munich Airport, which is located a bit outside of the city.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31d9d01b",
   "metadata": {},
   "outputs": [],
   "source": [
    "start = datetime(2025, 12, 1, 0, 0)\n",
    "end = datetime(2025, 12, 22, 23, 59)\n",
    "df1_munich = H('10865', start, end).fetch()\n",
    "df1_muc = H('10866', start, end).fetch()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbada023",
   "metadata": {},
   "source": [
    "**Task:** Use the code block below to figure out the datatype of `df1_muc` and `df1_munich` and familiarize yourself with the format of data queried from the Meteostat weather API."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b81bdf21",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dae19bdf",
   "metadata": {},
   "source": [
    "Now that you understand the data format, please note that you will need to only use a subset of the data for this exercise.\n",
    "\n",
    "In this exercise, we will not use all of the data contained in `df1_munich` and `df1_muc` for our graph. Instead, we'll only use the `\"temp\"` data from each structure.\n",
    "\n",
    "**Question:** Based on the type of data we will use for the graph, which type of graph from the four we learned would be the most appropriate to visualize it? Come up with your own answer, then run the block below to compare it with the solution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f87e7a95",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ANSWER BLOCK - Run this block to reveal the correct answer\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"eg2!jt!b!Qboebt!EbubGsbnf!pg!xfbuifs!bu!ipvsmz!joufswbmt-!boe!xf(sf!pomz!vtjoh!uif!#ufnq#!dpmvno/!B!mjof!qmpu!xjui!uxp!mjoft!)pof!gps!Nvojdi-!pof!gps!NVD!Bjsqpsu*!nblft!uif!nptu!tfotf!gps!uijt!ufnqpsbm!ebub/\\x0b\\x0b.!Tdbuufs!qmpu;!Hppe!gps!dpnqbsjoh!uxp!wbsjbcmft-!cvu!xifo!pof!wbsjbcmf!jt!ujnf-!b!mjof!qmpu!jt!npsf!bqqspqsjbuf/\\x0b.!Cbs!hsbqi;!Hppe!gps!ebub!tpsufe!joup!b!tnbmm!ovncfs!pg!ejtdsfuf-!vtvbmmz!opo.ovnfsjdbm!dbufhpsjft-!cvu!ipvsmz!ebub!sfqsftfout!tobqtiput!pg!ujnf-!xijdi!jt!ovnfsjdbm!boe!dpoujovpvt!)opu!ejtdsfuf*\\x0b.!Ijtuphsbn;!Uijt!jt!gps!tipxjoh!uif!gsfrvfodjft!pg!wbmvft!pg!tpnf!dpoujovpvt!wbsjbcmf-!xijdi!xpvme!jowpmwf!ejtdbsejoh!uif!ujnf!ebub!pg!uijt!ebubtfu-!tipxjoh!pomz!uif!gsfrvfodjft!pg!ufnqfsbuvsft\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99bc0eb5",
   "metadata": {},
   "source": [
    "Now you know the most suitable type of graph for this dataset. Before creating the actual graph, it would be nice to do a little bit of preprocessing. Namely, it would be convenient (though not strictly necessary) if all of the data were in the same DataFrame.\n",
    "\n",
    "In this part, you'll create a new DataFrame called `df1` which contains the temperature data from both `df1_munich` and `df1_muc`.\n",
    "\n",
    "Since you will end up with two columns named \"temp\", you can use `df1.columns = ['temp_munich', 'temp_muc']` to rename them accordingly (this was not covered in the Pandas lesson, hence why it's provided here).\n",
    "\n",
    "\n",
    "**Task:** Preprocess the data by creating a single `df1` variable containing the temp data from both `df1_munich` and `df1_muc`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "16a2aff3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Uifsf!bsf!uisff!tufqt!gps!uijt!qsfqspdfttjoh!ubtl;\\x0b2/!Vtf!uif!epvcmf.trvbsf!csbdlfu!opubujpo!up!hfu!pomz!uif!#ufnq#!dpmvno!gspn!fbdi!EbubGsbnf\\x0b3/!Dpodbufobuf!uif!uxp!EbubGsbnft!vtjoh!qe/dpodbu-!vtjoh!byjt>2!up!tubdl!ipsj{poubmmz!jotufbe!pg!wfsujdbmmz\\x0b4/!Sfobnf!uif!dpmvnot!tp!uifz!dbo!cf!joefyfe!qspqfsmz!)ibwjoh!uxp!dpmvnot!obnfe!#ufnq#!xpvme!mfbe!up!qspcmfnt!xifo!uszjoh!up!bddftt!uif!ebub!jo!uif!EbubGsbnf*\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f2b4518",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1034748",
   "metadata": {},
   "source": [
    "Excellent, with the data in a more convenient format, you can now create the visualization for this data.\n",
    "\n",
    "**Task:** Based on the most appropriate graph type identified earlier, create a visualization for the temperature data from Munich and Munich Airport contained in `df1` using Matplotlib."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a22baad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Zpv!tipvme!cf!hfofsbujoh!b!mjof!qmpu!gps!uijt!fyfsdjtf-!xijdi!sfrvjsft!zpv!up!vtf!uif!by/qmpu)*!gvodujpo!boe!qbtt!joup!ju-!bu!b!njojnvn-!b!dpmvno!pg!ebub!gspn!eg2!boe!b!mbcfm!)wjb!uif!(mbcfm(!lfzxpse!bshvnfou*/\\x0b\\x0bGvsuifsnpsf-!up!nblf!zpvs!hsbqi!dpnqmfuf-!zpv!tipvme!vtf!uif!gpmmpxjoh!gvodujpot;\\x0b.!by/mfhfoe)*\\x0b.!by/tfu`ujumf)*\\x0b.!by/tfu`ymbcfm)*\\x0b.!by/tfu`zmbcfm)*\\x0b\\x0bBoe!pg!dpvstf-!epo(u!gphfu!up!dbmm!qmu/tipx)*\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82ffa6eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "903087be",
   "metadata": {},
   "source": [
    "Great. Your graph should have a title, labels for the axes, and a legend indicating which line corresponds to which dataset. It should also contain two lines, one for each location (Munich and Munich Airport).\n",
    "\n",
    "Your graph might have an x-axis that's unreadable because the labels are overlapping. If so, try adjusting the figure size to something like (10, 5) or (12, 6) to give the labels more space. You can do this by adding `figsize=(10, 5)` as an argument to the `plt.figure()` function.\n",
    "\n",
    "**Check your work:** Once you're satisfied with your graph, go ahead and compare it with the solution provided in the solution sheet."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "414b5952",
   "metadata": {},
   "source": [
    "## Graph 2\n",
    "\n",
    "Great work on the first graph. For the next two graphs, there will be fewer, less verbose instructions. \n",
    "\n",
    "You will be given a dataset, told which parts of the dataset to use (e.g. which columns), and asked to choose the most appropriate graph type and create it using Matplotlib. \n",
    "\n",
    "The data preprocessing will be up to you from hereon out -- for example, you may choose to create a new DataFrame containing only the relevant columns, or you may choose to work with the original DataFrame directly.\n",
    "\n",
    "**Run**: The code block below will fetch the data which will be used for this second exercise. The various `df2_...` variables contain weather data for different cities in Germany. The data follows the same structure and spans the same time period as the data from the first exercise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f40231c",
   "metadata": {},
   "outputs": [],
   "source": [
    "start = datetime(2025, 12, 1, 0, 0)\n",
    "end = datetime(2025, 12, 22, 23, 59)\n",
    "\n",
    "df2_frankfurt = H('D1424', start, end).fetch()\n",
    "df2_munich = H('10865', start, end).fetch()\n",
    "df2_berlin = H('10389', start, end).fetch()\n",
    "df2_hamburg = H('D1981', start, end).fetch()\n",
    "df2_hanover = H('D2011', start, end).fetch()\n",
    "df2_cologne = H('D2968', start, end).fetch()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72a9d853",
   "metadata": {},
   "source": [
    "**Note:** For my German-speaking friends, I am using the English city names, so watch out for `cologne` (Köln) and `hanover` (with one N)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e15634e",
   "metadata": {},
   "source": [
    "In this exercise, we will use the best graph type to visualize the average temperature in each of the cities in the month of December.\n",
    "\n",
    "**Question:** Which type of graph would be most suitable for visualizing the average temperature in each city in December?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96ed61e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ANSWER BLOCK - Run this block to reveal the correct answer\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"B!cbs!hsbqi!jt!uif!cftu/\\x0b\\x0b.!Djujft!bsf!ejtdsfuf!dbufhpsjft\\x0b.!Uifsf!jt!op!pcwjpvt!psefsjoh!pg!djujft!)opo.psejobm!ebub*\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3865bed",
   "metadata": {},
   "source": [
    "**Task:** Bearing the most suitable type of graph in mind, create a visualization of the average temperature in each of the cities in December using Matplotlib. Do any data preprocessing you think is necessary. Make sure to include a title and labels for the axes in your graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f888acc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Vtf!by/cbs)*!boe!qbtt!joup!ju!b!mjtu!pg!uif!djuz!obnft!boe!b!qbsbmmfm!mjtu!pg!uif!bwfsbhf!ufnqfsbuvsf!jo!fbdi!djuz/\\x0bUp!hfu!uif!bwfsbhf!ufnqfsbuvsft-!oq/nfbo)*!jt!pg!vtf/\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "686b85fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1588b68",
   "metadata": {},
   "source": [
    "Excellent work. Once you're satisfied with your graph, compare it with the solution provided in the solution sheet."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45c4921b",
   "metadata": {},
   "source": [
    "## Dataset 3\n",
    "\n",
    "Excellent work so far. Let's move on to the third dataset.\n",
    "\n",
    "**Run**: The code block below will fetch the data which will be used for this second exercise. `df3` contains Munich city weather data, but it is not identical to the data used in the first exercise, so you will need to familiarize yourself with it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "057c1afe",
   "metadata": {},
   "outputs": [],
   "source": [
    "start = datetime(2025, 1, 1, 0, 0)\n",
    "end = datetime(2025, 12, 22, 23, 59)\n",
    "df3: pd.DataFrame = D('10865', start, end).fetch()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "735c633b",
   "metadata": {},
   "source": [
    "**Question:** Familiarize yourself with the dataset using the code block below. What is different about this compared to the data from the first exercise? Run the answer block to compare your observations with the solution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21c0b0e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "176b6b04",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ANSWER BLOCK - Run this block to reveal the correct answer\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Uif!EbubGsbnf!eg4!jt!ejggfsfou!gspn!uif!ebub!jo!uif!gjstu!fyfsdjtf!cfdbvtf!ju!dpoubjot!ebub!sfdpsefe!pwfs!b!ejggfsfou!ujnftqbo!boe!gsfrvfodz;\\x0b.!Ujnftqbo;!xipmf!pg!3136!vq!up!Efdfncfs!33\\x0b.!Gsfrvfodz;!Pof!ebubqpjou!qfs!ebz\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a636460",
   "metadata": {},
   "source": [
    "**Question:** We will use the dataset to show the correlation between temperature and pressure. What would be the most suitable graph type?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e052bd4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ANSWER BLOCK - Run this block to reveal the correct answer\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"B!tdbuufs!qmpu!jt!uif!cftu/\\x0b\\x0b.!Tdbuufs!qmput!bsf!jefbm!gps!dpnqbsjoh!uxp!wbsjbcmft\\x0b.!Ufnqfsbuvsf!boe!qsfttvsf!bsf!opu!ujnf!ebub-!svmjoh!pvu!b!mjof!qmpu\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73e9cf37",
   "metadata": {},
   "source": [
    "**Task:** Using `df3`, create a the most suitable visualization for analyzing the correlation between temperature and pressure in Munich. Use the `\"pres\"` (pressure) and `\"tavg\"` (average temperature) columns from both datasets to do so."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e12883a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Vtf!by/tdbuufs)*!boe!qbtt!joup!ju!uif!dpmvnot!eg4\\\\#qsft#^!boe!eg4\\\\#ubwh#^\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b380c343",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6588a73d",
   "metadata": {},
   "source": [
    "**Task:** To top it all off, add a line of best fit to your graph to better illustrate the correlation between temperature and pressure.\n",
    "\n",
    "Do this in the code block above so that you do not have to copy the entire graphing code again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a1391e8f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Uifsf!bsf!b!gfx!tufqt!uibu!hp!joup!uijt;\\x0b\\x0b2/!Vtf!oq/qpmzgju)eg4\\\\#qsft#^-!eg4\\\\#ubwh#^-!2*!up!hfu!uif!tmpqf!boe!joufsdfqu!pg!uif!mjof/\\x0b3/!Dsfbuf!b!mjtu!)f/h/!Z`mjof*!cz!fwbmvbujoh!uif!z.wbmvf!pg!uibu!mjof!gps!fbdi!y.wbmvf!)wbmvf!jo!eg4\\\\#qsft#^*\\x0b!!!)Uibu!jt!nptu!fbtjmz!pof!vtjoh!uif!fmfnfou.xjtf!bsjuinfujd!fyqfsttjpo;!tmpqf!+!eg4\\\\#qsft#^!,!joufsdfqu*\\x0b4/!Gjobmmz-!qmpu!uif!mjof!vtjoh!by/qmpu)*/\\x0b\\x0bMppl!bu!uif!vtf!pg!oq/qpmzgju)*!jo!uif!mfttpo!8!opufcppl!gps!npsf!hvjebodf/\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5451db1d",
   "metadata": {},
   "source": [
    "Great job! Once you're satisfied with your graph, compare it with the solution provided in the solution sheet.\n",
    "\n",
    "This also concludes the first part of this exercise sheet. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2e7d9c0",
   "metadata": {},
   "source": [
    "# Part 2 (optional): Creating specialized graphs using the Matplotlib documentation\n",
    "\n",
    "**Please note that this section is more challenging and is meant as an optional exercise.**\n",
    "\n",
    "In this bonus section, you may choose to go beyond what we covered in the lesson and create a specialized type of graph using the Matplotlib documentation.\n",
    "\n",
    "This type of visualization will actually become helpful in the lesson 8 exercise sheet, so if you choose to do this part, you may find that it helps you later on.\n",
    "\n",
    "**Run:** Fetch the dataset to be used for this part by running the code block below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de917e9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "df4: pd.DataFrame = sns.load_dataset(\"flights\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80bbc1af",
   "metadata": {},
   "source": [
    "This dataset contains information about the number of passengers flying on commercial flights per month from 1949 to 1960.\n",
    "\n",
    "**Task:** Familiarize yourself with the dataset structure using the code block below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92677efa",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "373320db",
   "metadata": {},
   "source": [
    "In this exercise, you will create a heatmap, which shows data in a matrix format using colors and which can be useful for visualizing a variety of data types. In this particular instance, it will be helpful for observing seasonal patterns in air travel over the years. The heatmap will show years as rows and months as columns, allowing you to easily see how flight passenger numbers vary within the months of a year or across years during one particular month.\n",
    "\n",
    "This exercise is meant as a practice in reading and applying knowledge from the Matplotlib documentation, so you will need to refer to it in order to complete this task. You can find the documentation here:  \n",
    "[https://matplotlib.org/stable](https://matplotlib.org/stable)\n",
    "\n",
    "**Task:** Find the matplotlib documenation page for creating an \"Annotated Heatmap.\" Read the page to familiarize yourself with the data type and structure expected by this type of graph. Based on what you've learned, how would you need to preprocess the `df4` dataset in order to create the heatmap?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ad0d435",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ANSWER BLOCK - Run this block to reveal the correct answer\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Uif!boopubufe!ifbunbq!vtft!uif!by/jntipx)*!nfuipe-!xijdi!fyqfdut!ebub!up!cf!jo!b!nbusjy!gpsnbu/\\x0bJo!ufsnt!pg!ebub!qspdfttjoh-!zpv!offe!up!gjhvsf!pvu!ipx!up!uvso!uif!ebub!jo!uif!eg5!EbubGsbnf!joup!b!uxp.ejnfotjpobm!Ovnqz!bssbz!xifsf!spxt!bsf!zfbst!boe!dpmvnot!bsf!npouit/\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ff3f1aa",
   "metadata": {},
   "source": [
    "Now that you understand the structure of the data required to create it, you're ready to write the code to create your visualization of flight passenger numbers over the years 1949 to 1960.\n",
    "\n",
    "**Task:** Preprocess the `df4` dataset as necessary for later use in creating the heatmap."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b5fdaa9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# HINT BLOCK - Run this to show a hint if you're struggling with this part of the exercise sheet\n",
    "print(\"\".join(chr(ord(c) - 1) for c in \"Zpv!offe!up!dsfbuf!b!uxp.ejnfotjpobm!Ovnqz!bssbz!jo!xijdi!spxt!bsf!zfbst!boe!dpmvnot!bsf!npouit/\\x0bUif!tjnqmftu!xbz!jt!up!dsfbuf!bo!bssbz!pg!{fspt!vtjoh!oq/{fspt))23-!23*-!euzqf>jou*!boe!vtjoh!b!oftufe!gps!mppq!up!gjmm!jo!bss\\\\spx-!dpm^!gps!fbdi!spx!boe!dpmvno!dpncjobujpo/\\x0bUp!gjmm!jo!bss\\\\spx-!dpm^-!zpv!offe!up!gjmufs!eg5!epxo!up!b!tjohmf!spx!)tqfdjgjd!zfbs!boe!npoui*!boe!uifo!bddftt!uif!wbmvf!pg!uif!#qbttfohfst#!dpmvno!bu!uibu!qptjujpo/\\x0b\\x0bOpuf!uibu!zpv!nbz!offe!up!vtf!nbudi`eg\\\\#qbttfohfst#^/wbmvft\\\\1^!up!dpssfdumz!sfusjfwf!uif!wbmvf-!xifsf!nbudi`eg!jt!b!EbubGsbnf!dpoubjojoh!b!tjohmf!spx!nbudijoh!tpnf!tqfdjgjfe!zfbs!boe!npoui\\x0b\\x0bBmtp!opuf!uibu!uif!npouit!ibwf!obnft!boe!opu!ovncfst!jo!uif!psjhjobm!ebubtfu-!tp!zpv!offe!b!mjtu!pg!Npoui!obnft!uibu!zpv!dbo!vtf!up!hfu!uif!obnf!pg!fbdi!npoui!xijmf!jufsbujoh!uispvhi!uifn\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6662fa48",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "01b8c082",
   "metadata": {},
   "source": [
    "With the correctly-formatted data in hand, the only thing left to do is create the visualization using the Matplotlib documentation as a guide.\n",
    "\n",
    "**Task:** Using the Matplotlib documentation as a guide, create the heatmap visualization for the preprocessed `df4` dataset showing flight passenger numbers from 1949 to 1960."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20363ef8",
   "metadata": {},
   "outputs": [],
   "source": [
    "#TODO task"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6de97f09",
   "metadata": {},
   "source": [
    "Excellent work! Once you're satisfied with your graph, compare it with the solution provided in the solution sheet.\n",
    "\n",
    "At this point, you have completed all parts of the exercise sheet. I hope you found it both challenging and enjoyable.\n",
    "\n",
    "If you have any feedback, send it to:\n",
    "[py.ldv@xcit.tum.de](mailto:py.ldv@xcit.tum.de)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "adlr",
   "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.11.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
