--------------------------------------------------------------------------------
/website/content/02-introduction-to-python/200-conclusion/00-wrapping-up.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Wrapping Up"
3 | date: 2019-02-10T18:39:32-08:00
4 | draft: false
5 | ---
6 |
7 | Today you've gotten a whirlwind tour of the Python programming language.
8 |
9 | During Day 2, we're going to put our knowledge to work writing real programs.
10 |
11 | ## Source Control
12 |
13 | I highly recommend that you use source control while working on your Python projects. GitHub is a popular and free option.
14 |
15 | Source control lets you track changes to your project. You can use that to your advantage to commit early and often and track changes to your project.
16 |
17 | If you're not familiar with how to use git or GitHub, you can watch my [Git In-depth Frontend Masters class](https://frontendmasters.com/courses/git-in-depth/). For Python projects, make sure that you use the correct `.gitignore` file. GitHub provides a [free template that you can use](https://github.com/github/gitignore/blob/master/Python.gitignore).
18 |
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/layouts/partials/search.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ $assetBusting := not .Site.Params.disableAssetsBusting }}
7 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/10-introduction/00-getting-ready.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Getting Ready"
3 | date = 2019-03-03T11:56:24-08:00
4 | weight = 1
5 | draft = false
6 | +++
7 |
8 | ### Get Ready For Day 2 - Navigate To Your Project
9 |
10 | Building on the project structure from Day 1, enter your `~/pyworkshop` directory, and start your already existing virtual environment.
11 |
12 | Windows:
13 |
14 | ```powershell
15 | > cd $home
16 | > cd pyworkshop
17 | > env\scripts\activate
18 | ```
19 |
20 | Mac:
21 |
22 | ```bash
23 | $ cd ~/pyworkshop
24 | $ source env/bin/activate
25 | ```
26 |
27 | ### Open VS Code
28 |
29 | If VS Code isn't already open, type the following in the same PowerShell or Terminal window where you activated your virtual environment.
30 |
31 | ```text
32 | $ code .
33 | ```
34 |
35 | ### Start The REPL
36 |
37 | Open the Command Palette in VS Code, and type: "Python: Start REPL"
38 |
39 | {{% notice tip %}}
40 | Remember, open the VS Code command palette (cmd + shift + P on Mac, ctrl + shift + P on Windows) and
41 | {{% /notice %}}
42 |
--------------------------------------------------------------------------------
/pyworkshop/2_intermediate_python/chapter8/test.py:
--------------------------------------------------------------------------------
1 | import repos.api
2 | import repos.exceptions
3 |
4 | import unittest
5 |
6 | class TestCreateQuery(unittest.TestCase):
7 |
8 | def test_create_query(self):
9 | test_languages = ["Python", "Ruby", "Java"]
10 | test_min_stars = 10000
11 |
12 | expected = "language:Python language:Ruby language:Java stars:>10000"
13 | result = repos.api.create_query(test_languages, test_min_stars)
14 |
15 | self.assertEqual(result, expected, "Unexpected result from create_query")
16 |
17 |
18 | class TestGitHubApiException(unittest.TestCase):
19 |
20 | def test_exception_403(self):
21 | status_code = 403
22 | exception = repos.exceptions.GitHubApiException(status_code)
23 | self.assertTrue("Rate limit" in str(exception), "'Rate limit' not found")
24 |
25 | def test_exception_500(self):
26 | status_code = 500
27 | exception = repos.exceptions.GitHubApiException(status_code)
28 | self.assertTrue(str(status_code) in str(exception))
29 |
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
33 |
--------------------------------------------------------------------------------
/website/static/code/day_two_final_exercise/test.py:
--------------------------------------------------------------------------------
1 | import repos.api
2 | import repos.exceptions
3 |
4 | import unittest
5 |
6 | class TestCreateQuery(unittest.TestCase):
7 |
8 | def test_create_query(self):
9 | test_languages = ["Python", "Ruby", "Java"]
10 | test_min_stars = 10000
11 |
12 | expected = "language:Python language:Ruby language:Java stars:>10000"
13 | result = repos.api.create_query(test_languages, test_min_stars)
14 |
15 | self.assertEqual(result, expected, "Unexpected result from create_query")
16 |
17 |
18 | class TestGitHubApiException(unittest.TestCase):
19 |
20 | def test_exception_403(self):
21 | status_code = 403
22 | exception = repos.exceptions.GitHubApiException(status_code)
23 | self.assertTrue("Rate limit" in str(exception), "'Rate limit' not found")
24 |
25 | def test_exception_500(self):
26 | status_code = 500
27 | exception = repos.exceptions.GitHubApiException(status_code)
28 | self.assertTrue(str(status_code) in str(exception))
29 |
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2018 GitHub, Inc. and contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/static/css/auto-complete.css:
--------------------------------------------------------------------------------
1 | .autocomplete-suggestions {
2 | text-align: left;
3 | cursor: default;
4 | border: 1px solid #ccc;
5 | border-top: 0;
6 | background: #fff;
7 | box-shadow: -1px 1px 3px rgba(0,0,0,.1);
8 |
9 | /* core styles should not be changed */
10 | position: absolute;
11 | display: none;
12 | z-index: 9999;
13 | max-height: 254px;
14 | overflow: hidden;
15 | overflow-y: auto;
16 | box-sizing: border-box;
17 |
18 | }
19 | .autocomplete-suggestion {
20 | position: relative;
21 | cursor: pointer;
22 | padding: 7px;
23 | line-height: 23px;
24 | white-space: nowrap;
25 | overflow: hidden;
26 | text-overflow: ellipsis;
27 | color: #333;
28 | }
29 |
30 | .autocomplete-suggestion b {
31 | font-weight: normal;
32 | color: #1f8dd6;
33 | }
34 |
35 | .autocomplete-suggestion.selected {
36 | background: #333;
37 | color: #fff;
38 | }
39 |
40 | .autocomplete-suggestion:hover {
41 | background: #444;
42 | color: #fff;
43 | }
44 |
45 | .autocomplete-suggestion > .context {
46 | font-size: 12px;
47 | }
48 |
--------------------------------------------------------------------------------
/pyworkshop/2_intermediate_python/chapter3/exercise_part3.py:
--------------------------------------------------------------------------------
1 | class Vehicle:
2 |
3 | def __init__(self, make, model, fuel="gas"):
4 | self.make = make
5 | self.model = model
6 | self.fuel = fuel
7 |
8 |
9 | class Car(Vehicle):
10 |
11 | number_of_wheels = 4
12 |
13 |
14 | class Truck(Vehicle):
15 |
16 | number_of_wheels = 6
17 |
18 | def __init__(self, make, model, fuel="diesel"):
19 | super().__init__(make, model, fuel)
20 |
21 |
22 | daily_driver = Car("Subaru", "Crosstrek")
23 | print(f"I drive a {daily_driver.make} {daily_driver.model}. "
24 | f"It uses {daily_driver.fuel} and has {daily_driver.number_of_wheels} wheels.")
25 |
26 | truck = Truck("Ford", "F350")
27 | print(f"I also have a {truck.make} {truck.model}. "
28 | f"It uses {truck.fuel} and has {truck.number_of_wheels} wheels.")
29 |
30 | print(
31 | f"My daily driver is a {type(daily_driver)} and my truck is a {type(truck)}")
32 |
33 | print(f"Is my daily driver a car? {isinstance(daily_driver, Car)}")
34 | print(f"Is my truck a Vehicle? {isinstance(truck, Vehicle)}")
35 | print(f"Is my truck a Car? {isinstance(truck, Car)}")
36 |
37 | print(f"Is a Truck a subclass of Vehicle? {issubclass(Truck, Vehicle)}")
38 |
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/layouts/shortcodes/attachments.html:
--------------------------------------------------------------------------------
1 |
2 |
6 | {{if eq .Page.File.BaseFileName "index"}}
7 | {{$.Scratch.Add "filesName" "files"}}
8 | {{else}}
9 | {{$.Scratch.Add "filesName" (printf "%s.files" .Page.File.BaseFileName)}}
10 | {{end}}
11 |
33 | {{.Inner}}
34 |
35 |
36 |
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Grav
4 | Copyright (c) 2016 MATHIEU CORNIC
5 | Copyright (c) 2017 Valere JEANTET
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | this software and associated documentation files (the "Software"), to deal in
9 | the Software without restriction, including without limitation the rights to
10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 | the Software, and to permit persons to whom the Software is furnished to do so,
12 | subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/pyworkshop/2_intermediate_python/chapter8/repos/api.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from repos.exceptions import GitHubApiException
4 | from repos.models import GitHubRepo
5 |
6 |
7 | GITHUB_API_URL = "https://api.github.com/search/repositories"
8 |
9 |
10 | def create_query(languages, min_stars):
11 | """
12 | Create the query string for the GitHub search API,
13 | based on the minimum amount of stars for a project, and
14 | the provided programming languages.
15 | """
16 | # Notice we are calling .strip() on each language,
17 | # to clear it of leading and trailing whitespace
18 | query = " ".join(f"language:{language.strip()}" for language in languages)
19 | query = query + f" stars:>{min_stars}"
20 | return query
21 |
22 |
23 | def repos_with_most_stars(languages, min_stars=40000, sort="stars", order="desc"):
24 | query = create_query(languages, min_stars)
25 | parameters = {"q": query, "sort": sort, "order": order}
26 | print(parameters)
27 | response = requests.get(GITHUB_API_URL, params=parameters)
28 |
29 | if response.status_code != 200:
30 | raise GitHubApiException(response.status_code)
31 |
32 | response_json = response.json()
33 | items = response_json["items"]
34 | return [GitHubRepo(item["name"], item["language"], item["stargazers_count"]) for item in items]
35 |
--------------------------------------------------------------------------------
/website/static/code/day_two_final_exercise/repos/api.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from repos.exceptions import GitHubApiException
4 | from repos.models import GitHubRepo
5 |
6 |
7 | GITHUB_API_URL = "https://api.github.com/search/repositories"
8 |
9 |
10 | def create_query(languages, min_stars):
11 | """
12 | Create the query string for the GitHub search API,
13 | based on the minimum amount of stars for a project, and
14 | the provided programming languages.
15 | """
16 | # Notice we are calling .strip() on each language,
17 | # to clear it of leading and trailing whitespace
18 | query = " ".join(f"language:{language.strip()}" for language in languages)
19 | query = query + f" stars:>{min_stars}"
20 | return query
21 |
22 |
23 | def repos_with_most_stars(languages, min_stars=40000, sort="stars", order="desc"):
24 | query = create_query(languages, min_stars)
25 | parameters = {"q": query, "sort": sort, "order": order}
26 | print(parameters)
27 | response = requests.get(GITHUB_API_URL, params=parameters)
28 |
29 | if response.status_code != 200:
30 | raise GitHubApiException(response.status_code)
31 |
32 | response_json = response.json()
33 | items = response_json["items"]
34 | return [GitHubRepo(item["name"], item["language"], item["stargazers_count"]) for item in items]
35 |
--------------------------------------------------------------------------------
/website/content/02-introduction-to-python/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | pre: "Day 1. "
3 | title: "Intro to Python"
4 | date: 2019-01-24T08:21:04-08:00
5 | draft: false
6 | chapter: true
7 | weight: 2
8 | ---
9 |
10 | ### Day 1
11 |
12 | # An Introduction to Python
13 |
14 | Let's talk about the anatomy of a Python program, along with Python best practices like naming and commenting.
15 |
16 | Today you'll be learning all the foundational basics of Python. How to work with different data types, the Python control structures, best practices, and lastly an exercise in interacting with APIs.
17 |
18 | # Day 1 Overview
19 |
20 | By coding along with me in this workshop, you'll:
21 |
22 | * You’ll learn about the origins of Python, and how it can help you solve complex problems quickly.
23 | * Learn about the different data types Python has to offer, including tips on when and how to use each one.
24 | * Understand the control flow of Python programs - loops, boolean statements, if statements, and return statements.
25 | * Make your code more concise by writing reusable functions.
26 | * Learn to use Python packages from the standard library, as well as how to find and install external libraries.
27 | * Learn how to work with files on your filesystem by reading and writing to them.
28 | * Write programs that interact with APIs by sending requests and receiving responses.
--------------------------------------------------------------------------------
/pyworkshop/2_intermediate_python/chapter8/app.py:
--------------------------------------------------------------------------------
1 | """
2 | A Simple Flask Web Application interface
3 | For viewing popular GitHub Repos sorted by stars using the
4 | GitHub Search API.
5 |
6 | To run:
7 | (env) $ python -m pip install -r requirements.txt
8 | (env) $ export FLASK_ENV=development; python3 -m flask run
9 | """
10 | from flask import Flask, render_template, request
11 |
12 | from repos.api import repos_with_most_stars
13 | from repos.exceptions import GitHubApiException
14 |
15 | app = Flask(__name__)
16 |
17 | available_languages = ["Python", "JavaScript", "Ruby", "Java"]
18 |
19 |
20 | @app.route('/', methods=['POST', 'GET'])
21 | def index():
22 | if request.method == 'GET':
23 | # Use the list of all languages
24 | selected_languages = available_languages
25 | elif request.method == 'POST':
26 | # Use the languages we selected in the request form
27 | selected_languages = request.form.getlist("languages")
28 |
29 | results = repos_with_most_stars(selected_languages)
30 |
31 | return render_template(
32 | 'index.html',
33 | selected_languages=selected_languages,
34 | available_languages=available_languages,
35 | results=results)
36 |
37 |
38 | @app.errorhandler(GitHubApiException)
39 | def handle_api_error(error):
40 | return render_template('error.html', message=error)
41 |
--------------------------------------------------------------------------------
/website/static/code/day_two_final_exercise/app.py:
--------------------------------------------------------------------------------
1 | """
2 | A Simple Flask Web Application interface
3 | For viewing popular GitHub Repos sorted by stars using the
4 | GitHub Search API.
5 |
6 | To run:
7 | (env) $ python -m pip install -r requirements.txt
8 | (env) $ export FLASK_ENV=development; python3 -m flask run
9 | """
10 | from flask import Flask, render_template, request
11 |
12 | from repos.api import repos_with_most_stars
13 | from repos.exceptions import GitHubApiException
14 |
15 | app = Flask(__name__)
16 |
17 | available_languages = ["Python", "JavaScript", "Ruby", "Java"]
18 |
19 |
20 | @app.route('/', methods=['POST', 'GET'])
21 | def index():
22 | if request.method == 'GET':
23 | # Use the list of all languages
24 | selected_languages = available_languages
25 | elif request.method == 'POST':
26 | # Use the languages we selected in the request form
27 | selected_languages = request.form.getlist("languages")
28 |
29 | results = repos_with_most_stars(selected_languages)
30 |
31 | return render_template(
32 | 'index.html',
33 | selected_languages=selected_languages,
34 | available_languages=available_languages,
35 | results=results)
36 |
37 |
38 | @app.errorhandler(GitHubApiException)
39 | def handle_api_error(error):
40 | return render_template('error.html', message=error)
41 |
--------------------------------------------------------------------------------
/website/content/02-introduction-to-python/110-control-statements-looping/30-while-loops.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "while loops"
3 | date: 2019-02-10T18:22:01-08:00
4 | draft: false
5 | weight: 30
6 | ---
7 |
8 | `while` loops are a special type of loop in Python. Instead of running just once when a condition is met, like an `if` statement, they run **forever** until a condition is *no longer* met.
9 |
10 | `while` loops usually need to be accompanied by an always changing sentinel value.
11 |
12 | ```python
13 | >>> counter = 0
14 | >>> max = 4
15 | >>>
16 | >>> while counter < max:
17 | ... print(f"The count is: {counter}")
18 | ... counter = counter + 1
19 | ...
20 | The count is: 0
21 | The count is: 1
22 | The count is: 2
23 | The count is: 3
24 | ```
25 |
26 | {{% notice warning %}}
27 | Our loop will run forever if we forget to *update* the sentinel value. **Press Ctrl-C to exit the infinite loop.**
28 | {{% /notice %}}
29 |
30 |
31 | ```python
32 | # Warning: don't copy and paste this example.
33 |
34 | >>> counter = 0
35 | >>> max = 4
36 |
37 | >>> while counter < max:
38 | ... print(f"The count is: {counter}")
39 | ...
40 | # What happens if we don't update counter?
41 | The count is: 0
42 | The count is: 0
43 | The count is: 0
44 | The count is: 0
45 | # An infinite loop repeated until we hit Ctrl-C
46 | The count ^CTraceback (most recent call last):
47 | File "", line 2, in
48 | KeyboardInterrupt
49 | ```
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/_index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Intermediate Python"
3 | date = 2019-03-03T11:55:16-08:00
4 | weight = 3
5 | chapter = true
6 | draft = false
7 | pre = "Day 2. "
8 | +++
9 |
10 | ### Day 2
11 |
12 | # Intermediate Python
13 |
14 | During day two, we'll start getting more comfortable with some of the more advanced aspects of Python, like classes, list comprehensions, and the standard library. At the end of the day, you'll know enough to build a small interactive API using the Flask web framework.
15 |
16 | {{% notice tip %}}
17 | To fully participate in todays class, you must have VS Code set up locally, along with Python version >= 3.7. You must be familiar with all the concepts from Day 1, including running Python programs, simple and complex types, boolean logic, control statements, and looping. If you're not sure, start with [Day 1](../02-introduction-to-python).
18 | {{% /notice %}}
19 |
20 | # Day 2 Overview
21 |
22 | By coding along with me in this workshop, you'll:
23 |
24 | - Use object-oriented programming to organize your code.
25 | - Diagnose problems in your Python programs by understanding Exceptions.
26 | - Work with new features in Python3 that make Python easier than ever, such as f-strings.
27 | - Learn about generators, a Python feature that allows you to loop over large data sets in a memory efficient way.
28 | - Learn how to build interactive APIs and websites efficiently using the Flask web framework.
--------------------------------------------------------------------------------
/website/static/code/day_one_min.py:
--------------------------------------------------------------------------------
1 | """
2 | A small Python program that uses the GitHub search API to list
3 | the top projects by language, based on stars.
4 | """
5 |
6 | import requests
7 |
8 | GITHUB_API_URL = "https://api.github.com/search/repositories"
9 |
10 |
11 | def create_query(languages, min_stars=50000):
12 | query = f"stars:>{min_stars} "
13 |
14 | for language in languages:
15 | query += f"language:{language} "
16 |
17 | # a sample query looks like: "stars:>50 language:python language:javascript"
18 | return query
19 |
20 |
21 | def repos_with_most_stars(languages, sort="stars", order="desc"):
22 | query = create_query(languages)
23 | params = {"q": query, "sort": sort, "order": order}
24 |
25 | response = requests.get(GITHUB_API_URL, params=params)
26 |
27 | print(response.url)
28 | status_code = response.status_code
29 |
30 | if status_code != 200:
31 | raise RuntimeError(f"An error occurred. HTTP Code: {status_code}.")
32 | else:
33 | response_json = response.json()
34 | return response_json["items"]
35 |
36 |
37 | if __name__ == "__main__":
38 | languages = ["python", "javascript", "ruby"]
39 | results = repos_with_most_stars(languages)
40 |
41 | for result in results:
42 | language = result["language"]
43 | stars = result["stargazers_count"]
44 | name = result["name"]
45 |
46 | print(f"-> {name} is a {language} repo with {stars} stars.")
47 |
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/static/css/featherlight.min.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Featherlight - ultra slim jQuery lightbox
3 | * Version 1.2.3 - http://noelboss.github.io/featherlight/
4 | *
5 | * Copyright 2015, Noël Raoul Bossart (http://www.noelboss.com)
6 | * MIT Licensed.
7 | **/
8 | @media all{.featherlight{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:2147483647;text-align:center;white-space:nowrap;cursor:pointer;background:#333;background:rgba(0,0,0,0)}.featherlight:last-of-type{background:rgba(0,0,0,.8)}.featherlight:before{content:'';display:inline-block;height:100%;vertical-align:middle;margin-right:-.25em}.featherlight .featherlight-content{position:relative;text-align:left;vertical-align:middle;display:inline-block;overflow:auto;padding:25px 25px 0;border-bottom:25px solid transparent;min-width:30%;margin-left:5%;margin-right:5%;max-height:95%;background:#fff;cursor:auto;white-space:normal}.featherlight .featherlight-inner{display:block}.featherlight .featherlight-close-icon{position:absolute;z-index:9999;top:0;right:0;line-height:25px;width:25px;cursor:pointer;text-align:center;font:Arial,sans-serif;background:#fff;background:rgba(255,255,255,.3);color:#000}.featherlight .featherlight-image{width:100%}.featherlight-iframe .featherlight-content{border-bottom:0;padding:0}.featherlight iframe{border:0}}@media only screen and (max-width:1024px){.featherlight .featherlight-content{margin-left:10px;margin-right:10px;max-height:98%;padding:10px 10px 0;border-bottom:10px solid transparent}}
--------------------------------------------------------------------------------
/website/themes/nnja-theme-learn/layouts/index.html:
--------------------------------------------------------------------------------
1 | {{ partial "header.html" . }}
2 |
3 | navigation
4 |
5 |
6 | {{if .Site.Home.Content }}
7 | {{.Site.Home.Content}}
8 | {{else}}
9 | {{if eq .Site.Language.Lang "fr"}}
10 |
Personaliser la page d'accueil
11 |
12 | Le site fonctionne. Ne pas oublier de personaliser cette page avec votre propre contenu. 3 manières de faire :
13 |
14 |
15 |
1. Créer un fichier _index.md dans le dossier content et le remplir de Markdown
16 |
2. Créer un fichier index.html dans le dossier static et le remplir de code HTML
17 |
3. Configurer le serveur http pour rediriger automatiquement la homepage vers la page de votre choix dans le site
18 |
19 | {{else}}
20 |
Customize your own home page
21 |
22 | The site is working. Don't forget to customize this homepage with your own. You typically have 3 choices :
23 |
24 |
25 |
1. Create an _index.md document in content folder and fill it with Markdown content
26 |
2. Create an index.html file in the static folder and fill the file with HTML content
27 |
3. Configure your server to automatically redirect home page to one your documentation page
28 |
29 | {{end}}
30 | {{ end }}
31 | {{ partial "footer.html" . }}
32 |
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/20-advanced-looping/70-zip.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "The zip function"
3 | date: 2019-03-03T18:03:03-08:00
4 | draft: false
5 | weight: 7
6 | ---
7 |
8 | It's often necessary to iterate over multiple lists simultaneously. Suppose we're keeping score of a game and we have two lists, one for names and one for scores:
9 |
10 | ```python
11 | >>> names = ["Bob", "Alice", "Eve"]
12 | >>> scores = [42, 97, 68]
13 | ```
14 |
15 | The `zip` function takes any number of iterable arguments and steps through
16 | all of them at the same time until the end of the *shortest* iterable has been reached:
17 |
18 | ```python
19 | >>> for name, score in zip(names, scores):
20 | >>> print(f"{name} had a score of {score}.")
21 | ...
22 | Bob had a score of 42.
23 | Alice had a score of 97.
24 | Eve had a score of 68.
25 | ```
26 |
27 | What will the above loop print after removing the last element from `scores`?
28 |
29 | ```python
30 | >>> scores.pop(-1)
31 | 68
32 | >>> for name, score in zip(names, scores):
33 | >>> print(f"{name} had a score of {score}.")
34 | ...
35 | Bob had a score of 42.
36 | Alice had a score of 97.
37 | ```
38 |
39 | The loop terminates even though there are more values in `names`. Here, Eve isn't included because `scores` only has two elements.
40 |
41 | We can also use `zip()` to quickly and easily create a `dict` from two lists. For example:
42 |
43 | ```python
44 | >>> scores = [42, 97, 68]
45 | >>> score_dict = dict(zip(names, scores))
46 | >>> print(score_dict)
47 | {'Bob': 42, 'Alice': 97, 'Eve': 68}
48 | ```
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/50-libraries-modules/50-pypi.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "PyPI"
3 | date: 2019-03-10T19:17:03-07:00
4 | draft: false
5 | weight: 5
6 | ---
7 |
8 | PyPI (the Python Package Index) is an awesome service that helps you find and install software developed and shared by the Python community. Almost every user-contributed Python package has been published to PyPI. You can browse the site at [pypi.org](https://pypi.org/) but most of the time you will probably interact with it through Python's `pip` tool.
9 |
10 | ### Basic Usage
11 |
12 | You can use the `pip` tool to install the latest version of a module and its dependencies from the Python Packaging Index:
13 |
14 | ```bash
15 | (env) $ python -m pip install SomePackage
16 | ```
17 |
18 |
19 | ### Know your Packages
20 |
21 | There are a lot of packages on PyPI, and they're not always up-to-date. Sometimes it helps to look at a package before installing it. Simply search for a package name on PyPI.org - for example, here's the page for the [redis package](https://PyPI.org/project/redis/). If you follow the Homepage link, you'll be taken to the project's [GitHub page](https://github.com/andymccurdy/redis-py), where you can see that the latest commit was very recently. So you know this package is actively maintained, and will probably work in your up-to-date version of Python.
22 |
23 | {{% notice warning %}}
24 | When you're first starting out, it's a good idea to copy the `pip install` text from the website, otherwise bad actors could take advantage of your typos.
25 | {{% /notice %}}
26 |
27 |
28 | We'll practice installing a package in the exercise for this chapter.
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/70-tests/30-assertions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Assertions"
3 | date: 2019-03-10T19:30:41-07:00
4 | draft: false
5 | weight: 3
6 | ---
7 |
8 | Python comes with a handy-dandy `assert` keyword that you can use for simple sanity checks. An assertion is simply a boolean expression that checks if its conditions return true or not. If the assertion is true, the program continues. If it's false, it throws an `AssertionError`, and your program will stop. Assertions are also a great debugging tool, as they can stop your program in exactly the spot where an error has occurred. This is great for rooting out unreliable data or faulty assumptions.
9 |
10 | To make an assertion, just use the `assert` keyword followed by a condition that should be `True`:
11 |
12 | ```python
13 | >>> input_value = 25
14 | >>> assert input_value > 0
15 | ```
16 |
17 | If our assertion fails, however:
18 |
19 | ```python
20 | >>> input_value = 25
21 | >>> assert input_value > 100
22 | Traceback (most recent call last):
23 | File "", line 1, in
24 | AssertionError
25 | ```
26 |
27 | ### `assert` Is For Sanity Checks, Not For Production!
28 |
29 | Assertions are great for simple self-checks and sanity tests. You shouldn't, however, use assertions for failure cases that can occur because of bad user input or operating system/environment failures, such as a file not being found. These situations are much better suited to an exception or an error message.
30 |
31 | {{% notice warning %}}
32 | Assertions can be disabled at run time, by starting the program with `python -O`, so you shouldn't rely on assertions to run in production code. Don't use them for validation!
33 | {{% /notice %}}
34 |
--------------------------------------------------------------------------------
/website/config.toml:
--------------------------------------------------------------------------------
1 | baseURL = "/"
2 | languageCode = "en-US"
3 | defaultContentLanguage = "en"
4 |
5 | title = "Nina Zakharenko - Introduction and Intermediate Python"
6 | theme = "nnja-theme-learn"
7 | themesdir = "themes"
8 | metaDataFormat = "yaml"
9 | defaultContentLanguageInSubdir= true
10 | ignoreFiles = [ "\\.pyc$", "__pycache__"]
11 | publishDir = "docs"
12 | googleAnalytics = "UA-138644383-1"
13 |
14 | [params]
15 | # Change default color scheme with a variant one. Can be "red", "blue", "green".
16 | themeVariant = "blue"
17 | editURL = "https://github.com/nnja/python/edit/master/website/content/"
18 | defaultSocialImage = "images/twittercard.png"
19 | description = "Free Learn Python Course by Nina Zakharenko - An intensive two day introduction and intermediate course on Python. Video course published on Frontend Masters."
20 | author = "Nina Zakharenko"
21 | showVisitedLinks = true
22 | disableBreadcrumb = false
23 | disableNextPrev = false
24 | disableInlineCopyToClipBoard = true
25 | twitter = "nnja"
26 |
27 |
28 | # For search functionality
29 | [outputs]
30 | home = [ "HTML", "RSS", "JSON"]
31 |
32 | [Languages]
33 | [Languages.en]
34 | title = "Learn Python by Nina Zakharenko"
35 | weight = 1
36 | languageName = "English"
37 |
38 | [[Languages.en.menu.shortcuts]]
39 | name = " Github repo"
40 | identifier = "ds"
41 | url = "https://git.io/python3"
42 | weight = 10
43 |
44 | [[Languages.en.menu.shortcuts]]
45 | name = " Follow Nina on Twitter"
46 | url = "https://twitter.com/nnja"
47 | weight = 20
48 |
49 | [[Languages.en.menu.shortcuts]]
50 | name = " Credits"
51 | url = "/credits"
52 | weight = 30
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/40-exceptions/50-exception-hierarchy.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Exception Hierarchy"
3 | date: 2019-03-10T19:15:44-07:00
4 | draft: true
5 | weight: 5
6 | ---
7 |
8 | Python has many useful built-in exceptions that you'll probably encounter in your travels. Some of the more common ones that you'll run into are listed in the [All About Exceptions](../10-all-about-exceptions) section. You can find a more detailed list of built-in exceptions in the [Python documentation](https://docs.python.org/3/library/exceptions.html).
9 |
10 | An important thing to know is that exceptions, like everything else in Python, are just objects. They follow an inheritance hierarchy, just like classes do. For example, the `ZeroDivisionError` is a subclass of `ArithmeticError`, which is a subclass of `Exception`, itself a subclass of `BaseException`.
11 |
12 | ```python
13 | >>> issubclass(ZeroDivisionError, ArithmeticError)
14 | True
15 | >>> issubclass(ArithmeticError, Exception)
16 | True
17 | >>> issubclass(Exception, BaseException)
18 | True
19 |
20 | # Thus,
21 | >>> issubclass(ZeroDivisionError, BaseException)
22 | True
23 | ```
24 |
25 | So, if you wanted to catch a divide-by-zero error, you could use `except ZeroDivisionError`. But you could also use `except ArithmeticError`, which would catch not only `ZeroDivisionEror`, but also `OverflowError` and `FloatingPointError`. You could use `except Exception`, but this is not a good idea, as it will catch almost *every* type of error, even ones you weren't expecting. We'll discuss this a bit later.
26 |
27 | A full chart of the hierarchy for built-in exceptions can be found at the bottom of the [Python documentation](https://docs.python.org/3/library/exceptions.html#exception-hierarchy).
--------------------------------------------------------------------------------
/website/content/03-intermediate-python/30-oop-classes-inheritance/10-concept.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Concept"
3 | date: 2019-03-10T19:29:28-07:00
4 | draft: false
5 | weight: 1
6 | ---
7 |
8 | Object-oriented Programming (OOP) is a language model (or *paradigm*) in which properties or behaviors are organized into "objects". Some languages encourage a more procedural style, like if you were writing a recipe - some popular examples are COBOL and BASIC. Languages that adopt an Object-oriented style organize things into objects, and provide methods for objects to communicate with one another.
9 |
10 | ### What is an object?
11 |
12 | An object can be a function, a variable, a property, a class... everything in Python is an object. You can think of an object as a generic container - a `list` object might contain a sequence of `int` objects, along with some function objects. The `int` objects contain integer numbers. The function objects contain code that can be executed on the `list` object or maybe on the items in the `list`.
13 |
14 |
15 | ### Python and OOP
16 |
17 | Python buys heavily into the OOP model - you'll find that everything in Python is an object of some kind, and almost everything has attributes and methods.
18 |
19 | This doesn't mean you *have* to use OOP in your programs - Python works perfectly well as a procedural or "script" language, where one command is executed after another, like a recipe. But getting familiar with OOP will not only help you read other Python code, but it will help you learn to encapsulate your code into objects for better organization and readability, as well as increase efficiency by making your code easily reusable. Objects are center-stage in Python, representing not only the data, but the overall structure of your programs as well.
--------------------------------------------------------------------------------
/website/content/02-introduction-to-python/190-APIs/00-what-is-an-API.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "What Is an API?"
3 | date: 2019-03-16T21:38:31-07:00
4 | draft: false
5 | weight: 1
6 | ---
7 |
8 | Per the dictionary, an API is:
9 |
10 | > a set of functions and procedures allowing the creation of applications that access the features or data of an operating system, application, or other service.
11 |
12 | An API is a standardized way of accessing information across the web, between clients and servers. These days most APIs are *RESTful*. That means they follow a common set of paradigms and practices.
13 |
14 | There are many types of APIs, but these days they're commonly known to refer to *web* APIs.
15 |
16 | #### Authentication
17 |
18 | Some, but not all APIs require you to authenticate. Methods of authentication are out of the scope of this class, but you'll be happy to know that there are plenty of free APIs available that require no authentication at all.
19 |
20 | #### Rate Limiting
21 |
22 | Some APIs allow unauthenticated requests, but they're usually *rate limited*. Rate limiting means prevent the same client (usually by IP address) from making too many requests at once and overloading the server. *The GitHub API allows 50 unauthenticated requests per hour per IP, or 10 unauthenticated requests to their Search API.*
23 |
24 | Note: After the class, you can find a detailed list of APIs in this [public-apis repo](https://github.com/toddmotto/public-apis).
25 |
26 | #### Free APIs
27 |
28 | {{% notice note %}}
29 | Free APIs are... free. That means that they may go down if their owner decides to drop their upkeep. If the API used in these examples doesn't work in the future, try a different one listed in the `public-apis` repo linked to above.
30 | {{% /notice %}}
31 |
32 |
--------------------------------------------------------------------------------
/website/content/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Learn Python
3 | weight: 1
4 | chapter: true
5 | ---
6 |
7 | # Learn Python
8 |
9 | Welcome to Introduction and Intermediate Python, recorded for Frontend Masters.
10 |
11 | Created by Nina Zakharenko. @nnja.
12 |
13 | Watch the accompanying screencast via subscription on [FrontendMasters.com](https://frontendmasters.com/teachers/nina-zakharenko/).
14 |
15 | {{< figure src="/images/fem.png" title="Watch the course" link="https://frontendmasters.com/courses/python/">}}
16 |
17 | Stay up to date with me on LinkedIn, or to contact me directly, please send me an email at learnpython@nnja.io.
18 |
19 | You can find the content and exercises on the Github repo.
20 |
21 |
22 | The course content is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
23 |
24 | I'd like to encourage learning individuals to learn Python from the course material for free, but if you'd like to use the material for your own workshop or for commercial use, please consider supporting my work and [watch the screencast](https://frontendmasters.com/teachers/nina-zakharenko/) instead.
--------------------------------------------------------------------------------
/website/content/02-introduction-to-python/175-running-code/65-libraries.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "Working with Libraries"
3 | date = 2019-01-25T15:06:06-06:00
4 | weight = 65
5 | draft = false
6 | +++
7 |
8 | Working with external libraries in Python makes use of the `import` keyword. While this can go anywhere in your file, it's almost always best to import libraries at the top of each file where they're used. For example, in the last section, we were able to call upon the built-in `json` library by calling `import json` at the top of our code.
9 |
10 | Importing modules with the `import` keyword is usually the best method, because it preserves the module's namespace. However, you can also use the `from import