Skip to content

Commit 6469349

Browse files
committed
Update documentation
1 parent 8084e82 commit 6469349

9 files changed

Lines changed: 685 additions & 271 deletions

File tree

_sources/docs/answer.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Task Answers (Python Coding Warm-Up)
2+
3+
(Last updated: Jan 26, 2026)
4+
5+
## Tasks
6+
7+
```{eval-rst}
8+
.. literalinclude:: util/answer.py
9+
:language: python
10+
```

_sources/docs/python-warm-up-notebook.ipynb

Lines changed: 60 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"id": "a771b7f3-dc1c-406b-93a0-d75984a23cf1",
1616
"metadata": {},
1717
"source": [
18-
"(Last updated: Jan 30, 2024)[^credit]\n",
18+
"(Last updated: Jan 26, 2026)[^credit]\n",
1919
"\n",
2020
"[^credit]: Credit: this teaching material is created by [Yen-Chia Hsu](https://github.com/yenchiah).\n",
2121
"\n",
@@ -30,157 +30,76 @@
3030
"outputs": [],
3131
"source": [
3232
"import pandas as pd\n",
33-
"import numpy as np"
33+
"import numpy as np\n",
34+
"\n",
35+
"# Import the answers for the tasks\n",
36+
"from util.answer import (\n",
37+
" check_answer_df,\n",
38+
" answer_resample_df,\n",
39+
" answer_merge_df,\n",
40+
" answer_aggregate_df,\n",
41+
" answer_transform_df,\n",
42+
" answer_transform_text_df\n",
43+
")"
44+
]
45+
},
46+
{
47+
"cell_type": "code",
48+
"execution_count": 2,
49+
"id": "db186ced-e386-4001-bbaf-97e066c83caf",
50+
"metadata": {},
51+
"outputs": [
52+
{
53+
"data": {
54+
"text/html": [
55+
"\n",
56+
" <style>\n",
57+
" .dataframe * {font-size: 1em !important;}\n",
58+
" </style>\n",
59+
" "
60+
],
61+
"text/plain": [
62+
"<IPython.core.display.HTML object>"
63+
]
64+
},
65+
"execution_count": 2,
66+
"metadata": {},
67+
"output_type": "execute_result"
68+
}
69+
],
70+
"source": [
71+
"from IPython.core.display import HTML\n",
72+
"\n",
73+
"def set_global_df_style():\n",
74+
" styles = \"\"\"\n",
75+
" <style>\n",
76+
" .dataframe * {font-size: 1em !important;}\n",
77+
" </style>\n",
78+
" \"\"\"\n",
79+
" return HTML(styles)\n",
80+
"\n",
81+
"# Call this function in a notebook cell to apply the style globally\n",
82+
"set_global_df_style()"
3483
]
3584
},
3685
{
3786
"cell_type": "markdown",
38-
"id": "7116cc3a-4b67-49b8-a318-57ff5c76c854",
87+
"id": "aca45d18-b23d-43a6-be46-9cfe0ea0a792",
3988
"metadata": {},
4089
"source": [
41-
"**Do not check the answers in the next cell before practicing the tasks.**"
90+
"<a name=\"answer\"></a>"
4291
]
4392
},
4493
{
45-
"cell_type": "code",
46-
"execution_count": 2,
47-
"id": "b0cffe15-9b31-4655-b408-80393bf18b3d",
48-
"metadata": {
49-
"jupyter": {
50-
"source_hidden": true
51-
},
52-
"tags": [
53-
"hide-cell"
54-
]
55-
},
56-
"outputs": [],
94+
"cell_type": "markdown",
95+
"id": "7116cc3a-4b67-49b8-a318-57ff5c76c854",
96+
"metadata": {},
5797
"source": [
58-
"def check_answer_df(df_result, df_answer, n=1):\n",
59-
" \"\"\"\n",
60-
" This function checks if two output dataframes are the same.\n",
61-
" \"\"\"\n",
62-
" try:\n",
63-
" assert df_answer.equals(df_result)\n",
64-
" print(\"Test case %d passed.\" % n)\n",
65-
" except:\n",
66-
" print(\"Test case %d failed.\" % n)\n",
67-
" print(\"\")\n",
68-
" print(\"Your output is:\")\n",
69-
" print(df_result)\n",
70-
" print(\"\")\n",
71-
" print(\"Expected output is:\")\n",
72-
" print(df_answer)\n",
73-
"\n",
74-
"\n",
75-
"def answer_resample_df(df):\n",
76-
" \"\"\"\n",
77-
" This function is the answer for task 1.\n",
78-
" \"\"\"\n",
79-
" # Copy to avoid modifying the original dataframe.\n",
80-
" df = df.copy(deep=True)\n",
81-
"\n",
82-
" # Convert the timestamp to datetime.\n",
83-
" df.index = pd.to_datetime(df.index, unit=\"s\", utc=True)\n",
84-
"\n",
85-
" # Resample the timestamps by hour and take the average value.\n",
86-
" # Because we want data from the past, so label need to be \"right\".\n",
87-
" df = df.resample(\"60Min\", label=\"right\").mean()\n",
88-
" return df\n",
89-
"\n",
90-
"\n",
91-
"def answer_merge_df(df1, df2):\n",
92-
" \"\"\"\n",
93-
" This function is the answer for task 2.\n",
94-
" \"\"\"\n",
95-
" # Copy to avoid modifying the original dataframe.\n",
96-
" df1 = df1.copy(deep=True)\n",
97-
" df2 = df2.copy(deep=True)\n",
98-
"\n",
99-
" # Make sure that the index has the same name.\n",
100-
" df2.index.name = df1.index.name\n",
101-
"\n",
102-
" # Merge the two data frames based on the index name.\n",
103-
" # We need to use outer merging since we want to preserve data from both data frames.\n",
104-
" df = pd.merge_ordered(df1, df2, on=df1.index.name, how=\"outer\", fill_method=None)\n",
105-
"\n",
106-
" # Move the datetime column to index\n",
107-
" df = df.set_index(df1.index.name)\n",
108-
" return df\n",
109-
"\n",
110-
"\n",
111-
"def answer_aggregate_df(df):\n",
112-
" \"\"\"\n",
113-
" This function is the answer for task 3.\n",
114-
" \"\"\"\n",
115-
" # Copy to avoid modifying the original dataframe.\n",
116-
" df = df.copy(deep=True)\n",
117-
"\n",
118-
" # Filter the data\n",
119-
" df = df[(df[\"v1\"]>0)&(df[\"group\"]!=\"15227\")]\n",
120-
"\n",
121-
" # Aggregate data for each group\n",
122-
" all_groups = []\n",
123-
" for g, df_g in df.groupby(\"group\"):\n",
124-
" # Select only the variable v1.\n",
125-
" df_g = df_g[\"v1\"]\n",
126-
" # Resample data using your code (or the answer) for task 1\n",
127-
" df_g = answer_resample_df(df_g)\n",
128-
" # Set the dataframe's name to the group value\n",
129-
" df_g.name = g\n",
130-
" # Save the group in an array\n",
131-
" all_groups.append(df_g)\n",
132-
"\n",
133-
" # Merge all groups using your code (or the answer) for task 2\n",
134-
" df = all_groups.pop(0)\n",
135-
" while len(all_groups) != 0:\n",
136-
" df = answer_merge_df(df, all_groups.pop(0))\n",
137-
"\n",
138-
" # Fill in the missing data with value -1\n",
139-
" df = df.fillna(0)\n",
140-
" return df\n",
141-
"\n",
142-
"\n",
143-
"def answer_transform_df(df):\n",
144-
" \"\"\"\n",
145-
" This function is the answer for task 4.\n",
146-
" \"\"\"\n",
147-
" # Copy to avoid modifying the original dataframe.\n",
148-
" df = df.copy(deep=True)\n",
149-
"\n",
150-
" # Define the function to process wind speed\n",
151-
" def process_wind_mph(x):\n",
152-
" if pd.isna(x):\n",
153-
" return None\n",
154-
" else:\n",
155-
" return x<5\n",
156-
"\n",
157-
" # Add the transformed columns.\n",
158-
" df[\"wind_deg_sine\"] = np.sin(np.deg2rad(df[\"wind_deg\"]))\n",
159-
" df[\"wind_deg_cosine\"] = np.cos(np.deg2rad(df[\"wind_deg\"]))\n",
160-
" df[\"is_calm_wind\"] = df[\"wind_mph\"].apply(process_wind_mph)\n",
161-
"\n",
162-
" # Delete the original columns.\n",
163-
" df = df.drop([\"wind_deg\"], axis=1)\n",
164-
" df = df.drop([\"wind_mph\"], axis=1)\n",
165-
" return df\n",
166-
"\n",
167-
"\n",
168-
"def answer_transform_text_df(df):\n",
169-
" \"\"\"\n",
170-
" This function is the answer for task 5.\n",
171-
" \"\"\"\n",
172-
" # Copy to avoid modifying the original dataframe.\n",
173-
" df = df.copy(deep=True)\n",
174-
"\n",
175-
" # Process the required columns.\n",
176-
" df[\"CV\"] = df[\"venue\"].str.contains(\"BMVC|WACV|ICCV|CVPR\")\n",
177-
" df[\"ML\"] = df[\"venue\"].str.contains(\"NeurIPS|ICLR\")\n",
178-
" df[\"MM\"] = df[\"venue\"].str.contains(\"MM\")\n",
179-
" df[\"year\"] = df[\"venue\"].str.extract(r'([0-9]{4})')\n",
98+
"## Task Answers\n",
18099
"\n",
181-
" # Delete the venue columns\n",
182-
" df = df.drop([\"venue\"], axis=1)\n",
183-
" return df"
100+
"Click on one of the following links to check answers for the assignments in this tutorial. **Do not check the answers before practicing the tasks.**\n",
101+
"- [Click this for task answers if you open this notebook on your local machine](util/answer.py)\n",
102+
"- {any}`Click this for task answers if you view this notebook on a web browser <./answer>`"
184103
]
185104
},
186105
{

0 commit comments

Comments
 (0)