diff --git a/.gitignore b/.gitignore index bc4b8ed..70fd339 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ venv/ -site/ \ No newline at end of file +site/ +videos/ \ No newline at end of file diff --git a/README.md b/README.md index 4a8501c..2a9a177 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ```bash ffmpeg -i in.mov -filter:v "setpts=0.5*PTS" out.gif +ffmpeg -i in.mkv out.mov ``` ```bash diff --git a/converter.py b/converter.py new file mode 100644 index 0000000..c9cec2a --- /dev/null +++ b/converter.py @@ -0,0 +1,22 @@ +import subprocess +import os +import time + +done_files = [] + +while True: + # get a list of all .mov or .gif files + movs = list(filter(lambda item: item.endswith(".mov"), os.listdir())) + print(f"Found {len(movs)} .mov files.") + gifs = list(filter(lambda item: item.endswith(".gif"), os.listdir())) + print(f"Found {len(gifs)} .gif files.") + + # find files that are not already gifs and aren't default + not_done = list(filter(lambda mov: mov.replace(".mov",".gif") not in gifs and not mov.startswith("Screen Recording"), movs)) + print(f"Found {len(not_done)} to convert.") + + for mov in not_done: + print(f"converting {mov}. Ctrl + C to stop...") + subprocess.run(['/usr/local/bin/ffmpeg', '-i', mov, '-filter:v', 'setpts=0.5*PTS', mov.replace(".mov",".gif")], capture_output=True) + + time.sleep(1) \ No newline at end of file diff --git a/docs/day2.md b/docs/day2.md new file mode 100644 index 0000000..c5b27f1 --- /dev/null +++ b/docs/day2.md @@ -0,0 +1,242 @@ +# Day 2 + +## Back to the basics: and, or, not, if + +Before we do anything more interesting we're going to have to cover our logical basics. In Python these are `not`, `and`, `or`, and `if`. + +1. Stop your server with ++ctrl++ + C +2. Type `python` in the terminal to open your python interpretor + + ![python_prompt](img/day1/python_prompt.gif) + + +### not + +1. Type `x = True` and press enter. +2. Type `x` and press enter to see that x is true. +3. Type `not x` and press enter. `not` inverts the value of `x`. So if `x` is True, `not x` is False. +4. Type `not not x` and press enter. `not not x` inverts `not x`. You can chain `not` as many times as you want. +5. Let's imagine we're building a weather app and we want to know if it's raining. Type `is_raining = True` and press enter. +6. Type `print(f"should I wear a raincoat? {is_raining}")` and press enter. +7. Today it's not raining. We could create a variable called `is_not_raining` but we could also just `not`. Type `print(f"should I wear a raincoat? {not is_raining}")` +8. Type `not 'hello'` and press enter. This might seem strange but Python interprets a string as `True`. `not 'hello'` will return `False`. +9. Type `not ''` and press enter. An empty string in Python is False. `not ''` returns `True`. + +### and + +1. In your terminal type `x = True` and press enter. +2. Type `x` and press enter to see that x is True. +3. Type `y = True` and press enter. +4. Type `y` and press enter to see that y is True. +5. Type `y and x` and press enter. `y` is true *and* `x` is true, so `y` and `x` is true. +6. We're building our weather app to be more useful. We want to tell people if it's rainy and windy. Type `rainy = True` and press enter. +7. Type `windy = True` and press enter. +8. Type `rainy and windy` and press enter. We get True because it's rainy and windy. +9. Today it's not windy. Type `rainy and not windy` and press enter. We get False because it isn't rainy *and* windy. +10. Tomorrow it won't be windy and it also won't be rainy. Type `not rainy and not windy` and press enter. We get False because neither weather conditions are met. + +### or + +1. In your terminal type `x = True` and press enter. +2. Type `x` and press enter to see that x is True. +3. Type `y = False` and press enter. +4. Type `y` and press enter to see that y is False. +5. Type `y or x` and press enter. `x` is True so asking if x or y is true will result in `True`. +6. Our weather app has millions of downloads. Our data suggests people don't like when it's cold or raining. Let's tell them when it's cold or raining. +7. Type `cold = True` and press enter. +8. Type `raining = True` and press enter. +9. Type `cold or raining` and press enter. We get `True`, it is cold and it is raining. +10. Today it isn't cold but it is raining. Type `not cold or raining`. We get `True`, it is still raining outside. +11. Tomorrow it won't be cold and it won't be raining. Type `not cold or not raining`. We get `False` because neither of our disliked weather conditions are met. + +### if + +1. In your terminal type `x = True` and press enter. +2. Type `x` and press enter to see that x is True. +3. Type `y = False` and press enter. +4. Type `y` and press enter to see that y is False. +5. Type `if x:` and press enter. You'll see a `...`. Python is waiting for another input. +6. Type ++tab++ `print('x is true!')` and press enter. You should see another `...`. +7. Press enter again. 'x is true!' will print to the terminal. + + ![if_interpreter](img/day2/if_interpreter.gif) + +8. Type `if y:` and press enter. Now type ++tab++ `print('y is true!')` and press enter twice. You won't see anything print. + + ![y_is_false](img/day2/y_is_false.gif) + +9. Type `if not y:` and press enter. Now type ++tab++ `print('y is false!')` and press enter twice. You'll see 'y is false!') printed. +10. Now that our weather app is sentient let's give it some decision making capability. +11. Type `raining = True` and press enter. +12. Type `if raining:` and press enter. +13. Type ++tab++ `print('You should wear a rain jacket')` and press enter twice. Your weather app can now tell you to wear a jacket if it's raining outside. + + ![rain_jacket](img/day2/rain_jacket.gif) + +14. Type `exit()` to exit + +## Building a Terrible Weather App + +1. Create a new file called `weather_app.py` by clicking the "add file" icon in the top left of VSCode. + + ![create_file](img/day2/create_file.gif) + +2. We're going to create an app where the user has to guess the weather. We're going to need the python random module to generate random weather conditions. +3. Add the following to the top of the page: + + ```python + import random + ``` + + ![import random](img/day2/import_random.png) + + This tells python we intend to use the `random` package + +4. We'll generate 4 weather conditions. Add the following after `import random` + + ```python + warm = random.choice([True, False]) + cold = not warm + raining = random.choice([True, False]) + snowing = not raining + ``` + + ![conditions](img/day2/conditions.png) + + random.choice([True, False]) selects either True or False randomly. + +5. Let's print our weather conditions in a cryptic way. Add the following below our variables: + + ```python + if warm or cold: + print("It's warm or cold.") + + if raining or warm: + print("It's raining or warm.") + + if raining or snowing: + print("It's raining or snowing.") + + if cold or snowing: + print("It's cold or snowing.") + ``` + + ![if_prints](img/day2/if_prints.png) + + This will print weather conditions in pairs to make it more challenging for our users to guess the weather. + +6. Now let's get our user input. Since we have 4 possible weather conditions we'll need 4 "guessing modules". Let's build the first one: + + ```python + warm_guess = input("Is it warm? (y/n) ") + if warm_guess == 'y' and warm: + print('Correct!') + elif warm_guess == 'n' and not warm: + print('Correct!') + else: + print('Wrong!') + ``` + + ![warm_module](img/day2/warm_module.png) + + We ask the user if it's warm. If they say 'y' and it is warm we tell them they got it right! If they guess wrong we tell them they are wrong. + +7. We'll just repeat the guess module 3 more times for cold, raining, and snowing. + + ```python + cold_guess = input("Is it cold? (y/n) ") + if cold_guess == 'y' and cold: + print('Correct!') + elif cold_guess == 'n' and not cold: + print('Correct!') + else: + print('Wrong!') + + raining_guess = input("Is it raining? (y/n) ") + if raining_guess == 'y' and raining: + print('Correct!') + elif raining_guess == 'n' and not raining: + print('Correct!') + else: + print('Wrong!') + + snowing_guess = input("Is it snowing? (y/n) ") + if snowing_guess == 'y' and snowing: + print('Correct!') + elif snowing_guess == 'n' and not snowing: + print('Correct!') + else: + print('Wrong!') + ``` + + ![modules](img/day2/modules.png) + +8. Save with ++ctrl++ + S and run your weather app by typing `python weather_app.py`. Try to guess the weather. + + ![run_app](img/day2/run_app.gif) + +## Pulling it all together with some Django + +1. Let's make a weather app! Open "views.py" by clicking on it. + + ![open_views](img/day2/open_views.gif) + +2. At the top of views.py add the following: + + ```python + import random + ``` + + ![django_random](img/day2/django_random.gif) + +3. Now under all of our existing code in views.py add the following: + + ```python + def weather(request): + warm = random.choice([True, False]) + cold = not warm + raining = random.choice([True, False]) + snowing = not raining + + if warm: + temperature_report = "It's warm out! Don't wear a jacket." + else: + temperature_report = "It's cold out! Wear a jacket." + + if raining: + precipitation_report = "It's raining! Bring an umbrella." + else: + precipitation_report = "It's snowing! Bring your skis." + + return render( + request, + "mysite/index.html", + {"data": temperature_report + " " + precipitation_report} + ) + ``` + + ![add_weather](img/day2/add_weather.gif) + + This creates a new "view" in our django app. + +4. Open mysite/urls.py by clicking on it. + + ![open_urls](img/day2/open_urls.gif) + +5. Under `path('', views.index),` add: + + ```python + path('weather/', views.weather), + ``` + + ![add_weather_path](img/day2/add_weather_path.gif) + +6. Run your server with `python manage.py runserver` (if it isn't already running) + + ![python_manage_run](img/day2/python_manage_run.gif) + +7. Navigate to + + ![navigate_to_weather](img/day2/navigate_to_weather.gif) + +Congratulations! You've added a new page to your app! diff --git a/docs/img/day2/add_weather.gif b/docs/img/day2/add_weather.gif new file mode 100644 index 0000000..1618105 Binary files /dev/null and b/docs/img/day2/add_weather.gif differ diff --git a/docs/img/day2/add_weather_path.gif b/docs/img/day2/add_weather_path.gif new file mode 100644 index 0000000..9a8fd9c Binary files /dev/null and b/docs/img/day2/add_weather_path.gif differ diff --git a/docs/img/day2/conditions.png b/docs/img/day2/conditions.png new file mode 100644 index 0000000..79a76be Binary files /dev/null and b/docs/img/day2/conditions.png differ diff --git a/docs/img/day2/create_file.gif b/docs/img/day2/create_file.gif new file mode 100644 index 0000000..a6b47a2 Binary files /dev/null and b/docs/img/day2/create_file.gif differ diff --git a/docs/img/day2/django_random.gif b/docs/img/day2/django_random.gif new file mode 100644 index 0000000..833de5b Binary files /dev/null and b/docs/img/day2/django_random.gif differ diff --git a/docs/img/day2/if_interpreter.gif b/docs/img/day2/if_interpreter.gif new file mode 100644 index 0000000..77effd8 Binary files /dev/null and b/docs/img/day2/if_interpreter.gif differ diff --git a/docs/img/day2/if_prints.png b/docs/img/day2/if_prints.png new file mode 100644 index 0000000..08771ad Binary files /dev/null and b/docs/img/day2/if_prints.png differ diff --git a/docs/img/day2/import_random.png b/docs/img/day2/import_random.png new file mode 100644 index 0000000..f0ab718 Binary files /dev/null and b/docs/img/day2/import_random.png differ diff --git a/docs/img/day2/modules.png b/docs/img/day2/modules.png new file mode 100644 index 0000000..38f10f3 Binary files /dev/null and b/docs/img/day2/modules.png differ diff --git a/docs/img/day2/navigate_to_weather.gif b/docs/img/day2/navigate_to_weather.gif new file mode 100644 index 0000000..7c9bbfa Binary files /dev/null and b/docs/img/day2/navigate_to_weather.gif differ diff --git a/docs/img/day2/open_urls.gif b/docs/img/day2/open_urls.gif new file mode 100644 index 0000000..ec53125 Binary files /dev/null and b/docs/img/day2/open_urls.gif differ diff --git a/docs/img/day2/open_views.gif b/docs/img/day2/open_views.gif new file mode 100644 index 0000000..539cbee Binary files /dev/null and b/docs/img/day2/open_views.gif differ diff --git a/docs/img/day2/python_manage_run.gif b/docs/img/day2/python_manage_run.gif new file mode 100644 index 0000000..ac57d0e Binary files /dev/null and b/docs/img/day2/python_manage_run.gif differ diff --git a/docs/img/day2/rain_jacket.gif b/docs/img/day2/rain_jacket.gif new file mode 100644 index 0000000..e540f91 Binary files /dev/null and b/docs/img/day2/rain_jacket.gif differ diff --git a/docs/img/day2/run_app.gif b/docs/img/day2/run_app.gif new file mode 100644 index 0000000..79868a9 Binary files /dev/null and b/docs/img/day2/run_app.gif differ diff --git a/docs/img/day2/warm_module.png b/docs/img/day2/warm_module.png new file mode 100644 index 0000000..c60b271 Binary files /dev/null and b/docs/img/day2/warm_module.png differ diff --git a/docs/img/day2/y_is_false.gif b/docs/img/day2/y_is_false.gif new file mode 100644 index 0000000..6dcafb3 Binary files /dev/null and b/docs/img/day2/y_is_false.gif differ diff --git a/ffmpeg.yaml b/ffmpeg.yaml new file mode 100644 index 0000000..f33e276 --- /dev/null +++ b/ffmpeg.yaml @@ -0,0 +1,58 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ffmpeg +spec: + selector: + matchLabels: + app: ffmpeg + template: + metadata: + labels: + app: ffmpeg + spec: + containers: + - image: debian:latest + name: ffmpeg + command: + - sleep + - infinity + volumeMounts: + - mountPath: /in + name: in + - mountPath: /out + name: out + resources: + limits: + memory: "16Gi" + cpu: "16" + requests: + memory: "1Mi" + cpu: "1m" + restartPolicy: Always + volumes: + - name: out + persistentVolumeClaim: + claimName: ffmpeg +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ffmpeg-in +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 32Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ffmpeg-out +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 32Gi \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 330e512..420c2b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,7 @@ nav: - Home: index.md - Day 0: day0.md - Day 1: day1.md + - Day 2: day2.md theme: name: material markdown_extensions: diff --git a/my_program.py b/my_program.py new file mode 100644 index 0000000..b1e6a87 --- /dev/null +++ b/my_program.py @@ -0,0 +1,16 @@ +def print_hello(): + print('hello, world!') + +def print_goodbye(): + print('goodbye!') + +def middle_stuff(): + x = 1 + y = 2 + print(x + y) + my_name = "Reese" + print(my_name) + +print_hello() +middle_stuff() +print_goodbye() \ No newline at end of file diff --git a/weather_app.py b/weather_app.py new file mode 100644 index 0000000..4da594d --- /dev/null +++ b/weather_app.py @@ -0,0 +1,51 @@ +import random + + +warm = random.choice([True, False]) +cold = not warm +raining = random.choice([True, False]) +snowing = not raining + +if warm or cold: + print("It's warm or snowing.") + +if raining or warm: + print("It's raining or warm.") + +if raining or snowing: + print("It's raining or cold.") + +if cold or snowing: + print("It's cold or snowing.") + +warm_guess = input("Is it warm? (y/n) ") +if warm_guess == 'y' and warm: + print('Correct!') +elif warm_guess == 'n' and not warm: + print('Correct!') +else: + print('Wrong!') + +cold_guess = input("Is it cold? (y/n) ") +if cold_guess == 'y' and cold: + print('Correct!') +elif cold_guess == 'n' and not cold: + print('Correct!') +else: + print('Wrong!') + +raining_guess = input("Is it raining? (y/n) ") +if raining_guess == 'y' and raining: + print('Correct!') +elif raining_guess == 'n' and not raining: + print('Correct!') +else: + print('Wrong!') + +snowing_guess = input("Is it snowing? (y/n) ") +if snowing_guess == 'y' and snowing: + print('Correct!') +elif snowing_guess == 'n' and not snowing: + print('Correct!') +else: + print('Wrong!')