{
"cells": [
{
"cell_type": "markdown",
"id": "2a21efb9",
"metadata": {
"execution": {}
},
"source": [
"
"
]
},
{
"cell_type": "markdown",
"id": "e79e6195",
"metadata": {
"execution": {}
},
"source": [
"# Tutorial 3: Content Enhancements\n",
"\n",
"**Week 1, Day 1: Instructions**\n",
"\n",
"**By Neuromatch**\n",
"\n",
"__Content creators:__ Viviana Greco\n",
"\n",
"__Content reviewers:__ Konstantine Tsafatinos\n",
"\n",
"__Production editors:__ Konstantine Tsafatinos\n",
"\n",
"
\n",
"\n",
"Acknowledgments: [Ella Batty, Spiros Chavlis and neuromatch]"
]
},
{
"cell_type": "markdown",
"id": "2e1685a5",
"metadata": {
"execution": {}
},
"source": [
"___\n",
"\n",
"# Tutorial Objectives\n",
"\n",
"*Estimated timing of tutorial: [15 mins]*\n",
"\n",
"In this tutorial, we'll dive into enhancing your content by integrating various media and interactive elements.\n",
"\n",
"By the end of this tutorial, you will:\n",
"\n",
"- learn how to add Airtable links\n",
"- learn how to embed videos \n",
"- learn how to integrate Kaggle/Collab Buttons\n",
"- learn how to upload data to OSF and access it from Jupyter Books"
]
},
{
"cell_type": "markdown",
"id": "6e6328a8",
"metadata": {
"execution": {}
},
"source": [
"---\n",
"\n",
"# Section 1: How to add Airtable links\n",
" "
]
},
{
"cell_type": "markdown",
"id": "29492952",
"metadata": {
"execution": {}
},
"source": [
"Airtable links should be added at the end of the OUTRO page of each tutorial."
]
},
{
"cell_type": "markdown",
"id": "599e8aa1",
"metadata": {
"execution": {}
},
"source": [
"Steps:"
]
},
{
"cell_type": "markdown",
"id": "d99d752c",
"metadata": {
"execution": {}
},
"source": [
"1. Request the Airtable Link\n",
"2. Add Image button\n",
"3. Embed and test the button"
]
},
{
"cell_type": "markdown",
"id": "60cc05b6",
"metadata": {
"execution": {}
},
"source": [
"**Request the Airtable Link**\n",
"\n",
"\n",
"Reach Out to Neuromatch Staff: Request the specific Airtable link for the day. You will receive a link that resembles:\n",
"https://portal.neuromatchacademy.org/api/redirect/to/48f385bc-3cd4-4516-96bb-46bdbdccbe9a"
]
},
{
"cell_type": "markdown",
"id": "a1e320ad",
"metadata": {
"execution": {}
},
"source": [
"**Add the Image Button**\n",
"\n",
"The button image is stored in the \"static\" folder within \"tutorials\" and is named \"button.png\". You can access it on GitHub using this URL:\n",
"\n",
"https://github.com/neuromatch/course-content-template/blob/main/tutorials/static/button.png?raw=1\n",
"\n",
"**Note:** Please refrain from altering this image."
]
},
{
"cell_type": "markdown",
"id": "e3643ebf",
"metadata": {
"execution": {}
},
"source": [
"**Embed the image button into your markdown cells**\n",
"\n",
"Insert the following HTML code to add the image button:\n",
"\n",
"```\n",
"\n",
"
\n",
"\n",
"```\n",
"\n",
"Replace YOUR_AIRTABLE_LINK_HERE with the link provided by Neuromatch staff.\n",
"\n",
"Ex:\n",
"\n",
"```\n",
"\n",
"
\n",
"\n",
"```\n",
"\n",
"After embedding the button click on it to ensure it redirects correctly to the Airtable survey."
]
},
{
"cell_type": "markdown",
"id": "7c033e9a",
"metadata": {
"execution": {}
},
"source": [
"---\n",
"\n",
"# Section 2: How to embed videos\n",
" "
]
},
{
"cell_type": "markdown",
"id": "c2b8ab03",
"metadata": {
"execution": {}
},
"source": [
"When adding videos to your content, please follow the guidelines outlined below:"
]
},
{
"cell_type": "markdown",
"id": "4e21b25d",
"metadata": {
"execution": {}
},
"source": [
"1. Utilize the Provided Code: Use the code template provided below. A few important notes about the code:\n",
"\n",
"- **PlayVideo Class & display_videos Function:** Avoid making modifications to the PlayVideo class or the display_videos function. \n",
"
\n",
"2. Update the **video_ids** List: Your main focus should be on modifying the video_ids list. Here, you specify the video platform and the corresponding video ID:\n",
"\n",
"- **Youtube** Videos: Adopt the format ('Youtube', '\\'). The \\ can be found in the video's Youtube URL. For example, in the URL https://www.youtube.com/watch?v=KUdKlJxtjQw, the video ID is KUdKlJxtjQw.
\n",
"\n",
"\n",
"- **Bilibili** Videos: Use the format ('Bilibili', '\\'). The \\ represents Bilibili's unique ID for that video.
\n",
"\n",
"- **OSF** Videos: The format is ('Osf', '\\').
\n",
"\n",
"3. Run the Code: After updating the video_ids list, execute the entire code block to display the videos within your notebook.
\n",
"\n",
"\n",
"4. Instructions on how to upload video to these platform can be found [here](https://neuromatch.slite.com/app/channels/g2mc8TY_Sk-ush)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5467f4b0",
"metadata": {
"cellView": "form",
"execution": {},
"tags": [
"remove-input"
]
},
"outputs": [],
"source": [
"# @markdown\n",
"\n",
"from ipywidgets import widgets\n",
"from IPython.display import YouTubeVideo\n",
"from IPython.display import IFrame\n",
"from IPython.display import display\n",
"\n",
"\n",
"class PlayVideo(IFrame):\n",
" def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n",
" self.id = id\n",
" if source == 'Bilibili':\n",
" src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'\n",
" elif source == 'Osf':\n",
" src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'\n",
" super(PlayVideo, self).__init__(src, width, height, **kwargs)\n",
"\n",
"\n",
"def display_videos(video_ids, W=400, H=300, fs=1):\n",
" tab_contents = []\n",
" for i, video_id in enumerate(video_ids):\n",
" out = widgets.Output()\n",
" with out:\n",
" if video_ids[i][0] == 'Youtube':\n",
" video = YouTubeVideo(id=video_ids[i][1], width=W,\n",
" height=H, fs=fs, rel=0)\n",
" print(f'Video available at https://youtube.com/watch?v={video.id}')\n",
" else:\n",
" video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,\n",
" height=H, fs=fs, autoplay=False)\n",
" if video_ids[i][0] == 'Bilibili':\n",
" print(f'Video available at https://www.bilibili.com/video/{video.id}')\n",
" elif video_ids[i][0] == 'Osf':\n",
" print(f'Video available at https://osf.io/{video.id}')\n",
" display(video)\n",
" tab_contents.append(out)\n",
" return tab_contents\n",
"\n",
"\n",
"video_ids = [('Youtube', ''), ('Bilibili', ''), ('Osf', '')]\n",
"tab_contents = display_videos(video_ids, W=730, H=410)\n",
"tabs = widgets.Tab()\n",
"tabs.children = tab_contents\n",
"for i in range(len(tab_contents)):\n",
" tabs.set_title(i, video_ids[i][0])\n",
"display(tabs)"
]
},
{
"cell_type": "markdown",
"id": "fb863895",
"metadata": {
"execution": {}
},
"source": [
"## Section 2.1: Tag at the top of the video code cell \n",
"\n",
"In the W#D#_Intro.ipynb and W#D#_Outro.ipynb, use **# @markdown** at the top of the video code cell. \n",
"\n",
"In the W#D#_Tutorial# use **# @title Video \\: Title of the video**"
]
},
{
"cell_type": "markdown",
"id": "5f427f95",
"metadata": {
"execution": {}
},
"source": [
"## Section 2.2: Add video links in the material.yml file\n",
"\n",
"When you add or modify videos in the Jupyter Notebook, it's also essential to keep the materials.yml file up-to-date. Here's how to do it: Remember that the main structure for this File has been already explaineed in W1D1_Tutorial2, Section 4. \n",
"\n",
"```\n",
"- day: W1D1\n",
" category: Course Content Template Instructions \n",
" \n",
" # Replace with the Youtube video link from W#D#_Intro.ipynb. Example:\n",
" intro: https://www.youtube.com/watch?v=KxldhMR5PxA \n",
" \n",
" # Replace with the Bilibili video link from W#D#_Intro.ipynb. Example:\n",
" intro_bilibili: https://www.bilibili.com/video/BV1HT4y1E7U4/\n",
" \n",
" name: Instructions \n",
" \n",
" # Replace with the Youtube video link from W#D#_Outro.ipynb. Example:\n",
" outro: https://www.youtube.com/watch?v=KZQXfQL1SH4\n",
" \n",
" # Replace with the Bilibili video link from W#D#_Outro.ipynb. Example:\n",
" outro_bilibili: https://www.bilibili.com/video/BV1vv411i7SG/\n",
" \n",
" # Replace with the Youtube playlist link. Example:\n",
" playlist: https://www.youtube.com/playlist?list=PLkBQOLLbi18ObAiSOZ42YBwOQIKNvspeI\n",
"``` "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0b259bd",
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"## Section 2.3: Video embedding example\n",
"\n",
"# @markdown\n",
"from ipywidgets import widgets\n",
"from IPython.display import YouTubeVideo\n",
"from IPython.display import IFrame\n",
"from IPython.display import display\n",
"\n",
"\n",
"class PlayVideo(IFrame):\n",
" def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n",
" self.id = id\n",
" if source == 'Bilibili':\n",
" src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'\n",
" elif source == 'Osf':\n",
" src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'\n",
" super(PlayVideo, self).__init__(src, width, height, **kwargs)\n",
"\n",
"\n",
"def display_videos(video_ids, W=400, H=300, fs=1):\n",
" tab_contents = []\n",
" for i, video_id in enumerate(video_ids):\n",
" out = widgets.Output()\n",
" with out:\n",
" if video_ids[i][0] == 'Youtube':\n",
" video = YouTubeVideo(id=video_ids[i][1], width=W,\n",
" height=H, fs=fs, rel=0)\n",
" print(f'Video available at https://youtube.com/watch?v={video.id}')\n",
" else:\n",
" video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,\n",
" height=H, fs=fs, autoplay=False)\n",
" if video_ids[i][0] == 'Bilibili':\n",
" print(f'Video available at https://www.bilibili.com/video/{video.id}')\n",
" elif video_ids[i][0] == 'Osf':\n",
" print(f'Video available at https://osf.io/{video.id}')\n",
" display(video)\n",
" tab_contents.append(out)\n",
" return tab_contents\n",
"\n",
"\n",
"video_ids = [('Youtube', 'W5o_HTsef0I'), ('Bilibili', 'BV1ho4y1C7Eo')]\n",
"tab_contents = display_videos(video_ids, W=730, H=410)\n",
"tabs = widgets.Tab()\n",
"tabs.children = tab_contents\n",
"for i in range(len(tab_contents)):\n",
" tabs.set_title(i, video_ids[i][0])\n",
"display(tabs)"
]
},
{
"cell_type": "markdown",
"id": "65ad3198",
"metadata": {
"execution": {}
},
"source": [
"---\n",
"\n",
"# Section 3: Add and test buttons for Kaggle/Colab"
]
},
{
"cell_type": "markdown",
"id": "485fa49c",
"metadata": {
"execution": {}
},
"source": [
"**COLAB** \n",
"\n",
"\n",
"STEP 1: The URL structure for Google Colab links that point to GitHub repositories is:\n",
"https://colab.research.google.com/github/[USERNAME]/[REPOSITORY]/blob/[BRANCH]/[PATH_TO_NOTEBOOK].ipynb\n",
"\n",
"Replace:\n",
"- [USERNAME] with the GitHub organization name ⟶ ask Konstantine if in the future this will be Neuromatch or Neuromatch Academy.\n",
"- [REPOSITORY] with the name of the GitHub repository.\n",
"- [BRANCH] with the name of the branch - usually this will be `main`\n",
"- [PATH_TO_NOTEBOOK].ipynb with the relative path to the notebook in the repository.\n",
"\n",
"\n",
"STEP 2: Embed the Button in Jupyter Book\n",
"Use the following HTML to add the Google Colab button:\n",
"```\n",
"
\n",
"```\n",
"\n",
"Replace YOUR_GENERATED_LINK_HERE with the link you generated in step 1.\n",
"\n",
"For example: \n",
"```
\n",
"```\n",
"\n",
"**KAGGLE**\n",
"\n",
"\n",
"STEP 1: The URL structure to open notebooks in Kaggle from a GitHub repository is:\n",
"https://kaggle.com/kernels/welcome?src=https://raw.githubusercontent.com/[USERNAME]/[REPOSITORY]/[BRANCH]/[PATH_TO_NOTEBOOK].ipynb\n",
"\n",
"Replace:\n",
"- [USERNAME] with the GitHub organization name.\n",
"- [REPOSITORY] with the name of the GitHub repository.\n",
"- [BRANCH] with the name of the branch - - usually this will be `main`\n",
"- [PATH_TO_NOTEBOOK].ipynb with the relative path to the notebook in your repository.\n",
"\n",
"\n",
"STEP 2: Embed the Button in Jupyter Book\n",
"\n",
"Use the following HTML to add the Kaggle button:\n",
"```\n",
"
\n",
"```\n",
"\n",
"Replace YOUR_GENERATED_LINK_HERE with the link you generated in step 1.\n",
"\n",
"For example: \n",
"```\n",
"
\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "3d9cdb65",
"metadata": {
"execution": {}
},
"source": [
"Test the Button for both Colab and Kaggle:\n",
"\n",
"- After embedding the button in your Jupyter book and publishing the changes:\n",
"- Click on the \"Open In Colab\" button or \"Open In Kaggle\" button.\n",
"\n",
"This should open a new tab, and the notebook should be loaded into Google Colab / Kaggle directly from the GitHub repository."
]
},
{
"cell_type": "markdown",
"id": "79f6b6aa",
"metadata": {
"execution": {}
},
"source": [
"---\n",
"\n",
"# Section 4: Uploade data to OSF and access it from Jupyter "
]
},
{
"cell_type": "markdown",
"id": "3e9dfd65",
"metadata": {
"execution": {}
},
"source": [
"**Uploading Data to OSF:**\n",
"\n",
"1. Navigate to the OSF Neuromatch Academy page. If you already have an account, log in using your credentials. If not, create a new account.\n",
"\n",
"2. Upload Data: Choose or create the appropriate project/folder in which you want to upload the data. Click on Files, then Upload (+) to add your data files.\n",
"\n",
"3. Grab the Link ID: Once the data or file is uploaded, each file or folder will have a unique link ID. This ID can be found in the URL of the uploaded file. Example URL: https://osf.io/6dxwe/ - Here, 6dxwe is the unique link ID."
]
},
{
"cell_type": "markdown",
"id": "40a9b5a1",
"metadata": {
"execution": {}
},
"source": [
"When uploading materials to OSF, please maintain the following structure:\n",
"\n",
"**For New Courses:** Use the structure adopted by the \"Climatematch\" course as a template (e.g., Climatematch/2023/Projects)\n",
"\n",
"**For Existing Courses:** If you're adding materials to a course that already has content on OSF, follow the established structure. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n"
]
},
{
"cell_type": "markdown",
"id": "42416117",
"metadata": {
"execution": {},
"tags": [
"remove-input"
]
},
"source": [
"# @markdown\n",
"from IPython.display import IFrame\n",
"from ipywidgets import widgets\n",
"out = widgets.Output()\n",
"with out:\n",
" print(f\"If you want to download the slides: https://osf.io/download//\")\n",
" display(IFrame(src=f\"https://mfr.ca-1.osf.io/render?url=https://osf.io//?direct%26mode=render%26action=download%26mode=render\", width=730, height=410))\n",
"display(out)"
]
},
{
"cell_type": "markdown",
"id": "37ce90ee",
"metadata": {
"execution": {}
},
"source": [
"To check storage limits imposed by OSF please visit the (website) [https://help.osf.io/article/386-project-storage#:~:text=OSF%20will%20limit%20the%20capacity,for%20storage%20management%20wherever%20possible.] \n",
"\n",
"Here's what you need to know about storage Limits:\n",
"\n",
"- Private Projects: Limited to 5 GB using OSF Storage.\n",
"- Public Projects: Can utilize up to 50 GB with OSF Storage."
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"include_colab_link": true,
"name": "W1D1_Tutorial3",
"toc_visible": true
},
"kernel": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 5
}