mirror of
https://gitlab.rlp.net/mobitar/julia_course.git
synced 2024-09-14 12:47:20 +00:00
1646 lines
47 KiB
Julia
1646 lines
47 KiB
Julia
### A Pluto.jl notebook ###
|
||
# v0.19.42
|
||
|
||
using Markdown
|
||
using InteractiveUtils
|
||
|
||
# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
|
||
macro bind(def, element)
|
||
quote
|
||
local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
|
||
local el = $(esc(element))
|
||
global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
|
||
el
|
||
end
|
||
end
|
||
|
||
# ╔═╡ 56ca47c1-6e4d-48a2-9f55-ca89362c7d3f
|
||
# Import packages and export their (public) functions
|
||
using Measurements, Unitful
|
||
|
||
# ╔═╡ 1f347724-1db2-48f0-87df-4e63ad6e8820
|
||
# Importing a builtin library that provides more functions for linear algebra.
|
||
# The keyword `using` imports the package and exports (public) functions automatically.
|
||
using LinearAlgebra
|
||
|
||
# ╔═╡ d1a4ef8b-8e7d-4d34-80d8-cee195e237ae
|
||
# Oh, no, you found my secret! 😱
|
||
# Don't change this hidden cell!
|
||
begin
|
||
using PlutoUI
|
||
|
||
TableOfContents()
|
||
end
|
||
|
||
# ╔═╡ 2c5e32f4-1d7d-4494-b025-a90d17919756
|
||
md"""
|
||
# Introduction
|
||
"""
|
||
|
||
# ╔═╡ 21590bf1-1e1c-46b4-a2b6-7eb915e121ab
|
||
md"""
|
||
## Why Julia?
|
||
- ⚡ Need for speed
|
||
- Dynamic and interactive, yet **fast**!
|
||
- JIT: Just in time compiler
|
||
- Solution to the "2 language problem"
|
||
- 🔬 Focus on scientific and numerical programming
|
||
- Arrays (vectors, matrices, tensors) out of the box
|
||
- Awesome packages!
|
||
- 📃 Easy syntax
|
||
- 🧐 Readable code
|
||
- 🧩 Modern package manager with environments out of the box
|
||
- 🔀 Parallelism and distributed computation
|
||
- 💻 "Julia is written in Julia"
|
||
- `@` Metaprogramming (macros)
|
||
- 🔓 Free open source software
|
||
- 😉 Unicode support
|
||
"""
|
||
|
||
# ╔═╡ d04af0fd-5ced-4f4f-b157-dd170e2ef8c8
|
||
md"""
|
||
## Pluto notebooks
|
||
- ⌨️ Press **`F1`** to see the full list of **shortcuts**.
|
||
- ▶️ Most important shortcut: `Shift` + `Enter` to run a cell.
|
||
- 📚️ Take a look at the **live docs** to the right.
|
||
"""
|
||
|
||
# ╔═╡ 938adcfe-8d1b-4c77-8d82-c48415f5673e
|
||
md"""
|
||
## Calculation
|
||
|
||
You can use Julia as a calculator 🧮
|
||
"""
|
||
|
||
# ╔═╡ 73190799-fd03-4cc4-9b4e-c523bc310468
|
||
1 + 1
|
||
|
||
# ╔═╡ 4c242a67-6445-48e7-a6c3-418a489b89ba
|
||
3 - 1
|
||
|
||
# ╔═╡ fe70db85-6e68-48ee-9b9a-7072e2dd7fe3
|
||
2 * 2
|
||
|
||
# ╔═╡ a73c132f-fd81-49ae-afc8-29e08a9042c8
|
||
3^4
|
||
|
||
# ╔═╡ 7671c5cb-9265-479d-b782-195bad6b7ba7
|
||
# ⚠️ Different from Python! This gives a helpful error:
|
||
# 3 ** 4
|
||
|
||
# ╔═╡ 3f2c4ab8-4ba4-44d5-99d4-9d941e4df99e
|
||
5 / 2
|
||
|
||
# ╔═╡ 02282f61-e1ca-483d-b6de-feeccedd7bc0
|
||
# Remainder of division
|
||
5 % 2
|
||
|
||
# ╔═╡ e4237ccd-b042-408b-8177-4c0d31a28caa
|
||
# Quotient of division
|
||
5 ÷ 2
|
||
|
||
# ╔═╡ 0dc9bbb4-fdde-4006-b04d-4509f7d041a7
|
||
3^2 * 2 - 8
|
||
|
||
# ╔═╡ 9c837673-79dd-4a6f-a11d-6f0f2c001587
|
||
3^2 * (2 - 8)
|
||
|
||
# ╔═╡ 0b6c6d50-e24c-43c7-8f04-4a53a3309bbf
|
||
md"""
|
||
Compare the results of the last two cells.
|
||
|
||
The followed operation priority is the same as in math (multiplication before addition/subtraction and so on). Use brackets to make sure that you get the result you want!
|
||
"""
|
||
|
||
# ╔═╡ d1bf37f9-5135-48b8-8f9b-84ddd4a86157
|
||
md"""
|
||
## Variables
|
||
|
||
Variables store data 📦️
|
||
"""
|
||
|
||
# ╔═╡ 8d005ddd-0308-4a06-8bae-251387facf6f
|
||
# Assignment
|
||
a = 2
|
||
|
||
# ╔═╡ b7d27cd4-a655-492e-b2b3-cdc745b2c2da
|
||
b = 3
|
||
|
||
# ╔═╡ 141950e5-e9f8-414b-b08d-86777428cbec
|
||
# Change a or b above and see what happens 🪄
|
||
a * b
|
||
|
||
# ╔═╡ 2e7f29ce-3afa-4c12-838d-8051c0567e20
|
||
# You can also store the result of a computation
|
||
c = a + b
|
||
|
||
# ╔═╡ 4936c9fc-43da-4b8b-84ce-11e739802e07
|
||
# You can also use variables with long names, but make sure to connect the words with an underscore (_)
|
||
variable_with_a_long_name = 42
|
||
|
||
# ╔═╡ 5e7f8a5e-9354-442b-aa13-7b9b3de536b1
|
||
md"""
|
||
There is a useful syntax to update the value of a variable using an operator acting on the variable itself.
|
||
"""
|
||
|
||
# ╔═╡ cf08cc65-7a9e-490d-b7e6-eecf6a1d9977
|
||
md"""
|
||
From now on, blocks will be used sometimes when manipulating a variable to prevent dependency on execution order in the notebooks.
|
||
|
||
A block starts with `begin` and ends with `end`. Code in the block should be indented.
|
||
|
||
The output of a cell with a block is the output of the last line of this block.
|
||
"""
|
||
|
||
# ╔═╡ 4774fa16-a6f6-48ae-b9b6-8a279118c99a
|
||
begin
|
||
incr_var = 1
|
||
incr_var += 1
|
||
# Equivalent to the following:
|
||
# incr_var = incr_var + 1
|
||
|
||
incr_var
|
||
end
|
||
|
||
# ╔═╡ 30000e9f-ec3d-416a-b402-010da80cd9ea
|
||
md"""
|
||
This syntax can also be used for all other operators (`*`, `/`, `^`, etc.)
|
||
"""
|
||
|
||
# ╔═╡ 72daf832-dba6-49ad-8d5a-f2c3aecdb630
|
||
# Example with one more operator
|
||
begin
|
||
doppel_var = 5
|
||
doppel_var *= 2
|
||
doppel_var
|
||
end
|
||
|
||
# ╔═╡ 2121b949-06e7-4079-a25a-d0518ee2ba50
|
||
md"""
|
||
## Types
|
||
|
||
These are the most important primitive types:
|
||
- `Bool`
|
||
- `Char`
|
||
- `Float64`
|
||
- `Int64`
|
||
|
||
Most other types (like `String`) are composed.
|
||
|
||
*Spoiler: You can compose your own types! More about this later* 😉
|
||
"""
|
||
|
||
# ╔═╡ 534f3b32-1fc9-4eed-887a-2cac66c2bdb4
|
||
# Bool has only two possible values: `true` or `false`.
|
||
bo1 = true
|
||
|
||
# ╔═╡ 3894b6b5-1952-409a-9966-502c277e26c3
|
||
bo2 = false
|
||
|
||
# ╔═╡ f20de3db-f270-4c43-aab7-692c313b5fa9
|
||
# Char
|
||
# Single quotes!
|
||
ch = 'c'
|
||
|
||
# ╔═╡ c72f187f-9626-45d9-870a-267c8530202c
|
||
# String, not a char!
|
||
# Double quotes!
|
||
st1 = "c"
|
||
|
||
# ╔═╡ e4295349-fc5c-48cb-975e-803e44d1a06e
|
||
# Shows the type of a variable
|
||
typeof(ch)
|
||
|
||
# ╔═╡ 7287122b-e5ea-4f69-963b-023483914992
|
||
typeof(st1)
|
||
|
||
# ╔═╡ 8b6609b0-5d6d-4c7d-a144-deaff79f93e9
|
||
# A string is a chain of characters
|
||
hello = "Hello world!"
|
||
|
||
# ╔═╡ 196682db-f5e1-4c07-9d35-644da3eecdd6
|
||
md"""
|
||
Pluto notebooks automatically print the output of a cell.
|
||
|
||
When using scripts instead of notebooks, `println` is needed to print to the console / terminal.
|
||
"""
|
||
|
||
# ╔═╡ 10fdb32f-b66f-4c4e-abd9-e856549941b8
|
||
# Print to the console
|
||
# ln stands for new line which is printed at the end of the output
|
||
println(hello)
|
||
|
||
# ╔═╡ 00ba151b-a741-448d-b8bf-775217250915
|
||
# Float
|
||
fl = 42.0
|
||
|
||
# ╔═╡ 204cf77f-bf37-4110-9c9f-1f9236301ba9
|
||
# Float64 is the default
|
||
typeof(fl)
|
||
|
||
# ╔═╡ 750bba32-e695-48f1-af70-70c94d13366b
|
||
# Integer
|
||
meaning_of_life = 42
|
||
|
||
# ╔═╡ 0b663bcb-4ff4-4597-b28b-b58c9cbfa181
|
||
# Int64 is the default
|
||
typeof(meaning_of_life)
|
||
|
||
# ╔═╡ 5e45b854-c173-452b-b62b-54037a3780fd
|
||
md"""
|
||
## String operations
|
||
"""
|
||
|
||
# ╔═╡ 0596fe87-4201-476e-8e11-618c621c5474
|
||
# Concatenation
|
||
# ⚠️ Not +
|
||
"Hello " * "world!"
|
||
|
||
# ╔═╡ 28063282-5c60-4ffb-a715-9b1e88498df9
|
||
new_to_julia = "Hi, I am new to Julia!"
|
||
|
||
# ╔═╡ da5fb1f9-2a2d-4148-8ba5-8c4a529829e9
|
||
# check if a string is part of another one
|
||
# ⚠️ Not in
|
||
contains(new_to_julia, "Hi")
|
||
|
||
# ╔═╡ 943da836-384d-4774-aaf4-54c27feb53d8
|
||
# Split on occurrences of the provided delimiter (comma here)
|
||
split(new_to_julia, ",")
|
||
|
||
# ╔═╡ a96f3ae9-12df-4df8-85da-09b9b1e47de1
|
||
# Join a list of strings with a provided delimiter and last delimiter
|
||
# Some of the used arguments are optional, see the docs 📚️
|
||
# Lists are actually called vectors in Julia. More about this later!
|
||
join(["Apple", "Banana", "Orange", "Lemon"], ", ", " and ")
|
||
|
||
# ╔═╡ 8d106ad2-5f92-4138-bfff-56ee21e098fa
|
||
# Multi line strings with three double quotes
|
||
multi_line_string = """Line 1
|
||
Line 2
|
||
Line 3"""
|
||
|
||
# ╔═╡ f8bc4051-93c6-4376-abaa-7b4cb4b8f607
|
||
# To see the new lines (\n)
|
||
println(multi_line_string)
|
||
|
||
# ╔═╡ b25dc5f2-e186-4da1-b045-47b22c93799b
|
||
md"""
|
||
## String formatting
|
||
"""
|
||
|
||
# ╔═╡ e0d7fbc8-39fc-4b70-9b92-0c19fffb0c05
|
||
a
|
||
|
||
# ╔═╡ 398648e8-358e-4289-ae95-957e77d0c46f
|
||
b
|
||
|
||
# ╔═╡ 28fa32e7-4e50-4890-a765-5cfb1d3f791b
|
||
a_mult_b = a * b
|
||
|
||
# ╔═╡ d2607457-1794-4a0f-af41-cb80aadb598f
|
||
# Use $ followed by the name of a variable to insert the variable into a string
|
||
"The result of $a * $b is $a_mult_b"
|
||
|
||
# ╔═╡ 23dbbe13-d997-4f9f-a300-7cb78c4fb8ee
|
||
# Use brackets after $ to insert a result of computation instead of a variable
|
||
"The result of $a * $b is $(a * b)"
|
||
|
||
# ╔═╡ e767971a-7e1d-4a78-88d7-03e4ae4d51db
|
||
# Using the macro @show, helpful for usage in scripts
|
||
@show a * b
|
||
|
||
# ╔═╡ 1e7b103c-6cc9-4586-820b-9ec836b997da
|
||
md"""
|
||
### Why even string formatting?
|
||
|
||
The following is an example of a possible calculation in a physical context.
|
||
"""
|
||
|
||
# ╔═╡ 7ade3f89-4838-4a8b-815c-4e2d6ccd7fea
|
||
# Voltage
|
||
U1 = 12.0 # V
|
||
|
||
# ╔═╡ 35675b9b-a28a-427f-9da4-e6c756d2276a
|
||
# Voltage uncertainty
|
||
dU1 = 0.1 # V
|
||
|
||
# ╔═╡ 66d39465-8244-483f-9a82-8d17b95cf41d
|
||
# Current
|
||
I1 = 0.30 # mA
|
||
|
||
# ╔═╡ 879c5330-781f-44c2-b072-1ee0f9bd971d
|
||
# Current uncertainty
|
||
dI1 = 0.01 # mA
|
||
|
||
# ╔═╡ df5914e3-b250-4824-80a5-cac5d0bed084
|
||
# Resistance
|
||
R1 = U1 / I1 # kΩ
|
||
|
||
# ╔═╡ 099ac8f8-8c5c-410b-a11f-c98bc68230b2
|
||
# Resistance uncertainty calculated with the Gaussian propagation of uncertainty.
|
||
dR1 = R1 * ((dU1 / U1)^2 + (dI1 / I1)^2)^0.5 # kΩ
|
||
|
||
# ╔═╡ cd46845b-4980-465c-a64f-3a8bcb66f53e
|
||
# You can get the ± symbol by typing \pm and then pressing tab.
|
||
println("""U: $U1 ± $dU1 V
|
||
I: $I1 ± $dI1 mA
|
||
R: $R1 ± $(round(dR1; digits=2)) kΩ""") # We will get to rounding later
|
||
|
||
# ╔═╡ a0bd2da0-344d-470c-918e-e8760fc77355
|
||
md"""
|
||
Nice, we were able to generate a nice output 🤩
|
||
|
||
But wait, Julia can automatically handle physical units and propagation of uncertainty for us! 🙀
|
||
"""
|
||
|
||
# ╔═╡ a2c4c4d9-4f06-41d4-baeb-b5f9f3b5b7c3
|
||
md"""
|
||
## Measurements and units
|
||
"""
|
||
|
||
# ╔═╡ f4122e58-a30c-45a4-8ede-492ddb8deba4
|
||
U2 = (12.0 ± 0.1)u"V"
|
||
|
||
# ╔═╡ 949e7fb8-8eff-49ea-8e76-0306857b05b9
|
||
I2 = (0.30 ± 0.01)u"mA"
|
||
|
||
# ╔═╡ 26869678-32f0-46e8-8cb2-d45b84441f03
|
||
R2 = U2 / I2
|
||
|
||
# ╔═╡ 0121add2-b42b-4dcd-8912-f8420a8b4c72
|
||
R2_converted = uconvert(u"kΩ", R2)
|
||
|
||
# ╔═╡ 9df364d6-0f43-4fe3-8a10-4bf0dc79e04d
|
||
md"""
|
||
Magic 🪄
|
||
"""
|
||
|
||
# ╔═╡ b8d7bd0b-a0ea-499f-9e61-3875535887e9
|
||
md"""
|
||
## Functions
|
||
|
||
In the last example, we did calculate the resistance. The resistance is a function of two variables: `I` and `U`.
|
||
|
||
In physics or mathematics, you would write this function this way:
|
||
|
||
$R(U, I) = U / I$
|
||
|
||
Guess what: In Julia, you can just write the same thing and you get a function!
|
||
"""
|
||
|
||
# ╔═╡ 13dd1d3c-dec8-4871-8ffa-b3db1bdd2847
|
||
# Function definition
|
||
R(U, I) = U / I
|
||
|
||
# ╔═╡ 0078ea9a-9c94-4703-a878-3cdd2e11d625
|
||
md"""
|
||
Now, you can call the function with some arguments.
|
||
"""
|
||
|
||
# ╔═╡ 38d3105f-427b-427b-bf7b-8aa76dfb3bef
|
||
R(12.0, 0.30)
|
||
|
||
# ╔═╡ 41b17c21-5b57-4912-88ee-e33215c1e0c8
|
||
# You can also pass units and uncertainties, Julia will just handle them.
|
||
# You can store the result in a new variable.
|
||
R3 = R((12.0 ± 0.1)u"V", (0.30 ± 0.01)u"mA")
|
||
|
||
# ╔═╡ b6dcaf22-c075-442e-b0d0-e48eae2350ac
|
||
# Now convert the result
|
||
uconvert(u"kΩ", R3)
|
||
|
||
# ╔═╡ 7f01c4a5-0e56-43aa-8d14-5fecfa04b370
|
||
md"""
|
||
OK, I guess you are asking what the benefit is. Why functions? You can just write `U / I`, right? 🤔
|
||
|
||
It was just a demonstration! Functions are more useful when you have a long calculation.
|
||
|
||
Lets write a function that does more than one thing. We want to calculate and show the results in a nice way.
|
||
|
||
Function with more than one line start with the keyword `function` and end with `end`. After `function` the name of the function and the arguments follow.
|
||
|
||
Everything inbetween should be indented (with tab). The result has to be returned with `return`.
|
||
"""
|
||
|
||
# ╔═╡ 105362be-572c-4a4d-9163-15ed8b4f1fbf
|
||
function calc_and_print_R(U, I)
|
||
@show U
|
||
@show I
|
||
|
||
R = U / I
|
||
R = uconvert(u"kΩ", R)
|
||
@show R
|
||
|
||
return R
|
||
end
|
||
|
||
# ╔═╡ 18c2ffb9-a895-491b-96ee-a0b5c68da180
|
||
# Test the function
|
||
calc_and_print_R(U2, I2)
|
||
|
||
# ╔═╡ 62cdf927-4e2b-40bb-be2d-eb32e0789548
|
||
md"""
|
||
Now, every time you want to calculate a resistance, you just use this function and it calculates and outputs for you 😃
|
||
"""
|
||
|
||
# ╔═╡ 9847a224-701a-489a-b125-95158aa805d4
|
||
# Take a look at this function doing some random calculation
|
||
function complex_function(a, b, c, d)
|
||
result = a + b
|
||
result = result * c
|
||
result = result / d
|
||
return result
|
||
end
|
||
|
||
# ╔═╡ 21163504-972d-4362-8c57-dbd708b2fa04
|
||
complex_function(1, 2, 3, 4)
|
||
|
||
# ╔═╡ 9ef91243-04fc-44f2-ae69-76f372364f21
|
||
# Try to access the variable `result`
|
||
# result
|
||
|
||
# ╔═╡ 3df766f0-38cb-4cdf-a68f-a4771c78fe31
|
||
md"""
|
||
Why can't we access the variable that we did define and use in the function? 😢
|
||
|
||
It is because of the concept of *scopes*. The variable result is only defined inside the function and it is only accessible inside of this function (in the scope of the function), not outside it!
|
||
|
||
`result` is called an *internal* variable. When you define a variable outside a function, it is called a *global* variable and is accessible everywhere.
|
||
"""
|
||
|
||
# ╔═╡ a6d882a0-c80e-4acf-b05b-c0ae120d698d
|
||
md"""
|
||
We will get back to data analysis. But first, we have to dive a bit deeper into the language 🤿
|
||
"""
|
||
|
||
# ╔═╡ 944e2d37-8280-47b8-b874-97221955d048
|
||
md"""
|
||
## Type hierarchy
|
||
|
||
Julia does have abstract types which are helpful for multiple dispatch.
|
||
|
||
More about multiple dispatch later 😉
|
||
"""
|
||
|
||
# ╔═╡ 23d4ac67-05ec-4b3d-8368-86256076be62
|
||
# The type hierarchy of Int64
|
||
supertypes(Int64)
|
||
|
||
# ╔═╡ e8d7de2f-7c7e-47cb-9364-27d583652167
|
||
md"""
|
||
All types showed in the output of the above cell except `Int64` are abstract.
|
||
|
||
This means that you can not have a variable with an abstract type.
|
||
|
||
You can only derive from an abstract type, but more about this when discussing structs and multiple dispatch 😉
|
||
|
||
`Any` is the abstract type of everything.
|
||
"""
|
||
|
||
# ╔═╡ 866edf5e-a76c-448d-98e8-925eaed5eba5
|
||
# A number can either be real or complex
|
||
subtypes(Number)
|
||
|
||
# ╔═╡ a8ea4ac1-7f62-4485-a8c5-8ccf00c45720
|
||
# There are some types of real numbers.
|
||
subtypes(Real)
|
||
|
||
# ╔═╡ 786a96be-16cd-4f1b-9b5f-138e232d3183
|
||
# Integers can have a sign or no sign (only positive).
|
||
# A Bool is also treated as an integer with the value 0 or 1.
|
||
subtypes(Integer)
|
||
|
||
# ╔═╡ dd8dad86-6bc2-4489-8469-7eac80fc41bb
|
||
# Integers can have different number of bits.
|
||
subtypes(Signed)
|
||
|
||
# ╔═╡ fac04aa7-28e9-4f93-9312-a8f8f93c0877
|
||
# Minimum and maximum value of a type
|
||
typemin(Int8), typemax(Int8)
|
||
|
||
# ╔═╡ 86bc0ff0-b6bf-4700-a741-36323be58391
|
||
typemin(Int128), typemax(Int128)
|
||
|
||
# ╔═╡ ef35a3a7-c1df-4952-aa41-1ed22d7f3981
|
||
# BigInt does not have a minimum or maximum!
|
||
BigInt(10)^1000 + 1
|
||
|
||
# ╔═╡ c336d5f6-80ee-4994-a55f-2d6b3aa3d559
|
||
# Hierarchy of Float64
|
||
supertypes(Float64)
|
||
|
||
# ╔═╡ 608d4433-6e68-4f95-8581-437234b58e87
|
||
md"""
|
||
## Conversion
|
||
|
||
You can convert some types to others if it is possible.
|
||
"""
|
||
|
||
# ╔═╡ beadbfd3-0015-449a-b6e7-b5182b396c1d
|
||
# Converting a float to an integer
|
||
convert(Int64, 3.0)
|
||
|
||
# ╔═╡ 552fafa4-fad5-4efe-895f-255b3ec5c858
|
||
# Complex is a composed type for complex numbers
|
||
convert(Complex, 3.0)
|
||
|
||
# ╔═╡ d11fde7f-3238-4013-bd2d-546aab0d9f9c
|
||
# This does not work! See rounding below.
|
||
# convert(Int64, 3.2)
|
||
|
||
# ╔═╡ 036a2c43-dbc9-487c-96aa-94324eeb4a52
|
||
md"""
|
||
## Rounding
|
||
"""
|
||
|
||
# ╔═╡ 1e954726-254e-41bb-a62f-17bdc9884bee
|
||
# We have to tell Julia explicitly what to do when converting a float with non zero digits after the decimal point.
|
||
round(Int64, 3.2)
|
||
|
||
# ╔═╡ d74f6c46-f5a8-4720-bcaf-936f1508efda
|
||
# The default is rounding to 0 digits after the decimal points, but keeping the float type.
|
||
round(π)
|
||
|
||
# ╔═╡ 3e5daca6-5aa8-42bf-988b-c09fb17388df
|
||
# ; marks the start of keyword arguments. More about it later!
|
||
round(π; digits=2)
|
||
|
||
# ╔═╡ 7ff20c67-58d5-4095-bb8e-7ab7522791c7
|
||
# You can provide a rounding mode, see the docs!
|
||
round(π, RoundUp)
|
||
|
||
# ╔═╡ 3102810f-3467-4ed8-86c0-16e9177fa69d
|
||
md"""
|
||
## `for` loop
|
||
|
||
You might be asking your self, why even bother learning a programming language when you can just use a calculator 🤨
|
||
|
||
One very important aspect of computers is their ability to do a computation for many times, without getting tired or missing a step 😴
|
||
|
||
To use this ability, programming languages provide `for` and `while` loops.
|
||
|
||
In a `for` loop, Julia iterates over every element of a given collection and does a specific computation with this element.
|
||
|
||
Lets see some examples!
|
||
"""
|
||
|
||
# ╔═╡ c1c705d2-7e46-4811-9fb1-6b88b5a4140e
|
||
# This for loop iterates over the numbers 1, 2, 3 and 4 and prints them.
|
||
for i in 1:4
|
||
println(i)
|
||
end
|
||
|
||
# ╔═╡ ddd3c019-6e70-4714-88fe-07d7a006ebc6
|
||
# This loop iterates over some strings and prints a welcoming message.
|
||
for name in ["Alice", "Bob", "everyone"]
|
||
println("Hello $name, welcome to this Julia course!")
|
||
end
|
||
|
||
# ╔═╡ 05db4e85-857d-4056-a576-5de992eabf29
|
||
md"""
|
||
Now, let's make our function for calculating and printing resistance more useful!
|
||
|
||
We want to iterate over some measured values of voltage and current.
|
||
|
||
To do so, we pair each element of one vector (list of measurements) with the corresponding element of the second vector.
|
||
|
||
*Vectors will be explained later. Until then, it is enough to understand a vector as an ordered list of elements.*
|
||
|
||
Lets take a look!
|
||
"""
|
||
|
||
# ╔═╡ 85c3c314-0f66-41be-8398-a5f9149ddfbd
|
||
# Vector of measured voltage values to different resistances
|
||
# The point is important, it will be explained later!
|
||
measured_U = [12.0, 15.0, 16.0, 12.5, 23.2, 22.6] .* u"V" .± 0.1u"V"
|
||
|
||
# ╔═╡ 566553a0-0202-4b59-b3ef-6954bf946b79
|
||
# Vector of measured current values to the different resistances
|
||
measured_I = [0.30, 0.25, 0.13, 0.22, 0.15, 0.75] .* u"mA" .± 0.05u"mA"
|
||
|
||
# ╔═╡ b70a48ca-362c-40d6-b703-2553a0b01275
|
||
for (u, i) in zip(measured_U, measured_I)
|
||
calc_and_print_R(u, i)
|
||
println("---") # Separate output
|
||
end
|
||
|
||
# ╔═╡ c0b32101-5863-4c22-8ee5-8e29abe0da39
|
||
md"""
|
||
Now imagine that you have not only 6 measurements, but 1000 or more. How much time would you need with the calculator? ⏳️
|
||
|
||
Later, we will learn how to plot and further analyze calculated values!
|
||
"""
|
||
|
||
# ╔═╡ 00456b15-5d1c-4c74-a875-31ff9c8e1789
|
||
md"""
|
||
## `while` loop
|
||
|
||
A `while` loop is similar to a `for` loop. The loop does the same computation with different values over and over. Instead of going through elements of a vector, a `while` loop checks a condition and runs the computation until the condition is `false`.
|
||
|
||
Lets see the following example!
|
||
"""
|
||
|
||
# ╔═╡ 91c4c623-5680-4b35-a694-2bd2612def94
|
||
begin
|
||
value = 5
|
||
while value > 0
|
||
value -= 1
|
||
println(value)
|
||
end
|
||
end
|
||
|
||
# ╔═╡ 4a00035f-a1d1-409f-b73b-07f9073dc9d5
|
||
md"""
|
||
## Boolean operators
|
||
|
||
Boolean operators are especially needed to check conditions, for `while`, `if` or `elseif`.
|
||
"""
|
||
|
||
# ╔═╡ d4ebb324-fa31-4058-9da1-35e07a971106
|
||
# Boolean AND
|
||
true && false
|
||
|
||
# ╔═╡ f8259580-5a29-4a13-811f-c91d6811a291
|
||
# Boolean OR
|
||
true || false
|
||
|
||
# ╔═╡ f813afd8-2e1b-43f7-beeb-ac9bd15fbeb6
|
||
# Boolean NOT
|
||
!false
|
||
|
||
# ╔═╡ 7ab3a69d-ac31-49cf-8d34-3a427b02ed06
|
||
md"""
|
||
⚠️ Don't try to use `and`, `or` or `not` if you are coming from Python!
|
||
"""
|
||
|
||
# ╔═╡ 2a85d95b-51d2-4ea0-a2a2-43307a725f2a
|
||
md"""
|
||
## `if`, `elseif`, `else`
|
||
"""
|
||
|
||
# ╔═╡ eef07cd2-0a83-491f-a3ff-c51400aadebb
|
||
md"""
|
||
`if` checks for a condition and runs the code indented under it if the condition is `true`.
|
||
"""
|
||
|
||
# ╔═╡ 9a78bf14-7fb4-448a-a8dd-69e244a0a297
|
||
@bind test_value Slider(1:4)
|
||
|
||
# ╔═╡ a5a71d00-bf30-4c07-bcd8-2bf99698522e
|
||
test_value
|
||
|
||
# ╔═╡ 5281ef32-5de6-4488-8430-e5652cbf8299
|
||
if test_value == 1
|
||
println("The value is 1")
|
||
end
|
||
|
||
# ╔═╡ 9107a95e-6ef5-465f-bd28-9a774f99f4ab
|
||
md"""
|
||
`else` runs a piece of code indented under it if the condition of `if` is `false`.
|
||
"""
|
||
|
||
# ╔═╡ eec41279-e038-4415-81b3-ad5d4c396011
|
||
# change the value of the variable `test_value` and see how the input changes
|
||
if test_value == 1
|
||
println("The value is 1")
|
||
else
|
||
println("The value is not 1")
|
||
end
|
||
|
||
# ╔═╡ 544368b2-3e39-41e7-97ea-e2bbf44a7749
|
||
md"""
|
||
`elseif` checks for further conditions if the conditions before it were `false`. If the condition is `true`, then the code indented under it is executed and `else` is ignored. Otherwise, the next `elseif` is checked or `else` is executed if no `elseif` is left.
|
||
|
||
Sounds complicated. It is best explained with an example.
|
||
"""
|
||
|
||
# ╔═╡ d2333817-e941-429b-b8e3-2ff07669096b
|
||
# change the value of the variable `test_value` and see how the input changes
|
||
if test_value == 1
|
||
println("The value is 1")
|
||
elseif test_value == 2
|
||
println("The value is 2")
|
||
elseif test_value == 3
|
||
println("The value is 3")
|
||
else
|
||
println("The value is not 1, 2 or 3")
|
||
end
|
||
|
||
# ╔═╡ be0ff87b-229a-433e-a49e-2f1ced5bb9aa
|
||
# You can combine conditions
|
||
if (test_value == 1) || (test_value == 2)
|
||
println("Value is 1 or 2")
|
||
end
|
||
|
||
# ╔═╡ 54d654cd-110f-4b1f-9578-109a80db4574
|
||
@bind second_test_value Slider(1:2)
|
||
|
||
# ╔═╡ 96803a1e-0779-4eab-b120-b5569a44ac7b
|
||
second_test_value
|
||
|
||
# ╔═╡ 5ab233d2-f360-4362-b1f8-3f3ae2a4fee1
|
||
# change the value of the variable `second_test_value` and see how the input changes
|
||
if (test_value == 1) && (second_test_value == 1)
|
||
println("Both values are 1")
|
||
end
|
||
|
||
# ╔═╡ 0d100501-de84-4a5c-beb7-8ff9e83c473d
|
||
# change the value of the variable `test_value` and see how the input changes
|
||
if !(test_value == 1)
|
||
println("Value is not 1")
|
||
end
|
||
|
||
# ╔═╡ 9e3f698d-e57b-46c2-98e0-157fa7b06ae6
|
||
md"""
|
||
# Arrays
|
||
An array is a **mutable ordered** collection of elements of the same type.
|
||
|
||
Arrays can have different dimensions.
|
||
|
||
An array with (`n × 1`) dimensions is called a vector, like in mathematics.
|
||
|
||
An array with (`n × n`) dimensions is called a matrix, also like in mathematics.
|
||
|
||
But arrays can also have other dimensions (`n₁ × n₂ × n₃ × ...`) with `nᵢ` as natural numbers.
|
||
"""
|
||
|
||
# ╔═╡ d1680205-a8eb-4ef6-ae4f-059e7a30f5c1
|
||
md"""
|
||
## Vectors
|
||
"""
|
||
|
||
# ╔═╡ b54ace0e-8947-46a3-842a-05b5cbfc4e87
|
||
first_vector = [2, 4, 6, 8, 10]
|
||
|
||
# ╔═╡ 0d5bfd45-79da-435b-9a98-8ed996bbc7b4
|
||
# Show the dimensions of an array
|
||
size(first_vector)
|
||
|
||
# ╔═╡ 8c47710f-1ed2-40fd-9290-374b498380e3
|
||
first_vector[1]
|
||
|
||
# ╔═╡ a03b46cc-1b26-44c2-b83d-884e3dbbe4fa
|
||
md"""
|
||
Yes, it is not the second element of the vector! 😯
|
||
|
||
In Julia, indexing starts with 1️⃣
|
||
"""
|
||
|
||
# ╔═╡ 68658408-188e-43f7-ad74-251172dec0a8
|
||
# ⚠️ This results in an error!
|
||
# first_vector[0]
|
||
|
||
# ╔═╡ 7c00f22c-860f-4bb1-b4b4-74c5c3c70f45
|
||
# Last element
|
||
first_vector[end]
|
||
|
||
# ╔═╡ 45b64c7a-850b-402c-b7ce-2a0bf6d77060
|
||
# ⚠️ No negative indexing!
|
||
# first_vector[-1]
|
||
|
||
# ╔═╡ d1ed1515-cd59-4e10-a15c-b64325bc44c2
|
||
# Instead, this can be used
|
||
first_vector[end-1]
|
||
|
||
# ╔═╡ 6c80e009-30de-4232-9a1b-ac954242a5a6
|
||
md"""
|
||
## Slicing
|
||
"""
|
||
|
||
# ╔═╡ b1426df5-a083-4977-a72c-81e03fd7719d
|
||
# Syntax: start_index:end_index
|
||
first_vector[2:4]
|
||
|
||
# ╔═╡ 5b16ca43-1f56-4934-a420-5ffa5ed437ec
|
||
# start_index:step:end_index
|
||
first_vector[1:2:end]
|
||
|
||
# ╔═╡ 628852dc-16e5-4a03-93a9-be209b1e8fb4
|
||
# Vector of indices
|
||
first_vector[[1, end, 2]]
|
||
|
||
# ╔═╡ 3ea54f0d-2aa5-47a3-bbc3-92023a56b834
|
||
md"""
|
||
## Mutation
|
||
"""
|
||
|
||
# ╔═╡ e9e117af-1194-4d64-94a8-3e9fd51498aa
|
||
# Setting the first element to 3
|
||
begin
|
||
second_vector = [1, 2, 3]
|
||
second_vector[1] = 42
|
||
second_vector
|
||
end
|
||
|
||
# ╔═╡ 1fd6fdd3-82a0-480e-9db6-e657536da63f
|
||
# Add elements to a vector
|
||
begin
|
||
growing_vector = []
|
||
push!(growing_vector, 42)
|
||
push!(growing_vector, 33)
|
||
growing_vector
|
||
end
|
||
|
||
# ╔═╡ ace6fd59-ccb8-4318-85ce-966b04c4ce53
|
||
# Append elements of one vector to another one
|
||
begin
|
||
growing_vector2 = [1, 2]
|
||
vector_to_append = [22, 33, 44]
|
||
append!(growing_vector2, vector_to_append)
|
||
growing_vector2
|
||
end
|
||
|
||
# ╔═╡ b7bb3e82-a2ee-4356-8c7b-0db664adcbe0
|
||
# Remove elements
|
||
begin
|
||
shrinking_vector = [-1, -2, -2, 55, 123, 44, 52, 98, -3, -112]
|
||
@show shrinking_vector
|
||
|
||
# Remove the last element
|
||
pop!(shrinking_vector)
|
||
@show shrinking_vector
|
||
|
||
# Remove the first element
|
||
popfirst!(shrinking_vector)
|
||
@show shrinking_vector
|
||
|
||
# Remove at a given index
|
||
popat!(shrinking_vector, 3)
|
||
@show shrinking_vector
|
||
end
|
||
|
||
# ╔═╡ 027313d6-c247-43e9-872b-c3f0fe71b733
|
||
third_vector = [1, 2, 3]
|
||
|
||
# ╔═╡ e77e7ceb-31e3-4231-9923-f62b1382a2d1
|
||
# ⚠️ This does not work!
|
||
# third_vector[2] = 42.1
|
||
|
||
# ╔═╡ 65d3ddc2-36ed-4126-9211-e838ffc0d859
|
||
# This is because the type of the array is Int64, a Float64 can not be inserted! All elements of an array have to have the same type!
|
||
typeof(third_vector)
|
||
|
||
# ╔═╡ 641e8c05-3e80-47e5-be77-91090a5f799a
|
||
# You can mix types during initialization of an array
|
||
begin
|
||
mixed_vector = ["hi", 2.1, 55.7]
|
||
mixed_vector[2] = 1 + 2im
|
||
mixed_vector
|
||
end
|
||
|
||
# ╔═╡ 2b9a5867-ca82-4a27-a700-bd0bd6c89bbe
|
||
# But then, the type of the array is Any
|
||
typeof(mixed_vector)
|
||
|
||
# ╔═╡ 87b43f26-7437-4ee9-9b83-5b21e86dd0c9
|
||
md"""
|
||
⚠️ Try to avoid using mixed arrays (type `Any`)!
|
||
|
||
It hurts the performance! 🐢
|
||
|
||
This is because the array can contain anything and the compiler can not optimize for specific types.
|
||
"""
|
||
|
||
# ╔═╡ 22f5ebc1-fd5c-4ee7-b169-8144fbd9b570
|
||
# ⚠️ This does not work! Run it and see the helpful error message
|
||
# first_vector[1:2] = 5
|
||
|
||
# ╔═╡ 7479c420-2e04-4fe7-823c-3fde9efb54ca
|
||
# Instead use this to change many slices in the original vector
|
||
first_vector[1:2] .= 5
|
||
|
||
# ╔═╡ 4cd82256-be63-4db1-b2af-82a1358f4881
|
||
# Compare the output of the cell above with this. What is the difference?
|
||
typeof(first_vector[1:2])
|
||
|
||
# ╔═╡ 605ee405-ec83-4064-adc8-861d95513e5e
|
||
md"""
|
||
## Views
|
||
Views are not a copy of an array, but a *reference* to a part of it. It is best explained by an example:
|
||
"""
|
||
|
||
# ╔═╡ 22a7baee-6533-43f7-8503-e5d5537a8c78
|
||
# Don't panic!
|
||
# You don't have to understand everything in this "long" piece of code.
|
||
# It is only meant for concept explanation.
|
||
# The output is important!
|
||
begin
|
||
v = [3, 6, 9, 12]
|
||
@show v
|
||
|
||
# Copy
|
||
@show copy_of_v = v[1:3]
|
||
|
||
# View
|
||
@show view_of_v = view(v, 1:3)
|
||
|
||
println() # Generate a new empty line
|
||
|
||
new_value = 100
|
||
v[1] = new_value
|
||
println("Changed first element of v to $new_value")
|
||
|
||
@show v
|
||
@show copy_of_v
|
||
@show view_of_v
|
||
|
||
println()
|
||
|
||
new_value = 42
|
||
copy_of_v[2] = new_value
|
||
println("Changed second element of copy_of_v to $new_value")
|
||
|
||
@show v
|
||
@show copy_of_v
|
||
@show view_of_v
|
||
|
||
println()
|
||
|
||
new_value = 55
|
||
view_of_v[3] = new_value
|
||
println("Changed third element of view_of_v to $new_value")
|
||
|
||
@show v
|
||
@show copy_of_v
|
||
@show view_of_v
|
||
end
|
||
|
||
# ╔═╡ 90b0fb2f-eb2d-4d06-96da-a4605ce61c41
|
||
md"""
|
||
Using views is important for performance. Copying or initializing an array is expensive!
|
||
|
||
This is because a free place in the memory has to be found and assigned to the new array. This process is called *memory allocation*. More about allocations and performance improvements in the days 😉
|
||
"""
|
||
|
||
# ╔═╡ 786682f6-692d-488d-8dab-231b0111d07f
|
||
md"""
|
||
## Vector operations
|
||
"""
|
||
|
||
# ╔═╡ 16a9cb53-2812-4ed3-afe4-96c0b116ad9a
|
||
v1 = [1, 2, 3]
|
||
|
||
# ╔═╡ dfd91d6b-65a5-454b-a0f9-6ed267def022
|
||
v2 = [0, 5, 10]
|
||
|
||
# ╔═╡ e68c54d8-3fb8-4aae-a334-665fdb8db1f0
|
||
v1 + v2
|
||
|
||
# ╔═╡ 8d74d994-3d4e-40ba-97cb-6dac1003fb8f
|
||
# Now we have access to the function `dot` (and many others)
|
||
# Dot product
|
||
dot(v1, v2)
|
||
|
||
# ╔═╡ af87251f-a37c-4088-8f4d-3803778bd97e
|
||
# Cross product
|
||
cross(v1, v2)
|
||
|
||
# ╔═╡ 2ac5d431-1a4d-4db2-8954-97e011cd2175
|
||
md"""
|
||
## Matrices
|
||
"""
|
||
|
||
# ╔═╡ d30b3a5f-e14c-45ea-89a4-cf710733a2ee
|
||
# Readable method to define a matrix
|
||
first_matrix = [
|
||
1 2
|
||
3 4
|
||
]
|
||
|
||
# ╔═╡ 6bb730e4-b5aa-4e7b-9ccd-9298db061e7f
|
||
# Easier to write method
|
||
second_matrix = [1 2; 3 4]
|
||
|
||
# ╔═╡ 2ef34862-0578-41fe-adad-0e894c287dd5
|
||
third_matrix = [
|
||
1 2 3
|
||
4 5 6
|
||
]
|
||
|
||
# ╔═╡ 09f2d0f9-cd0e-45e4-a159-cb360292dac1
|
||
# Dimensions: n × m
|
||
size(third_matrix)
|
||
|
||
# ╔═╡ 6f6a875e-fe60-47ba-8837-60edef1b20e0
|
||
# Determinant, from LinearAlgebra
|
||
det(first_matrix)
|
||
|
||
# ╔═╡ e99a89ab-af3a-42f5-b1c1-22e13a761eeb
|
||
# Inverse matrix, from LinearAlgebra
|
||
inv_first_matrix = inv(first_matrix)
|
||
|
||
# ╔═╡ f45b7774-df6f-4019-9217-e88d99babdb3
|
||
# Matrix multiplication
|
||
inv_first_matrix * first_matrix
|
||
|
||
# ╔═╡ db1b6e53-3116-48df-b098-1c3045be0dad
|
||
# Calculate eigenvalues and vectors, from LinearAlgebra
|
||
vals, vecs = eigen(first_matrix)
|
||
|
||
# ╔═╡ cd5abd71-1bf8-484f-a46a-99cc8b994b91
|
||
# Eigenvalues
|
||
vals
|
||
|
||
# ╔═╡ 7cef46dc-803a-4a7a-9663-148b6de4a267
|
||
# First eigenvector
|
||
vecs[:, 1]
|
||
|
||
# ╔═╡ 70710989-9139-4970-a7b0-5702571e59a4
|
||
# Second eigenvector
|
||
vecs[:, 2]
|
||
|
||
# ╔═╡ 873be989-d587-4d9f-ad5d-5632ae24b0bf
|
||
# Transpose a matrix
|
||
first_matrix'
|
||
|
||
# ╔═╡ a9f39e34-4c2c-48f2-9353-babe1bc3cd05
|
||
md"""
|
||
## More dimensions
|
||
|
||
One of the best ways to initialize arrays is to use `zeros`, `ones` or `fill` providing the dimensions.
|
||
|
||
After initialization, you can populate the array (inplace).
|
||
"""
|
||
|
||
# ╔═╡ 83eca43d-2280-40f1-bf2a-016a843362a3
|
||
# Tensor with the following dimensions: 3 × 3 × 3
|
||
begin
|
||
first_tensor = zeros(3, 3, 3)
|
||
first_tensor[1, 1, 1] = 1.0
|
||
first_tensor[2, :, :] .= 4.0 # The dot is important! (Remember views)
|
||
first_tensor
|
||
end
|
||
|
||
# ╔═╡ f4c48701-d90e-48d6-bf9d-539c7fb7c7a5
|
||
ones(3, 2)
|
||
|
||
# ╔═╡ 875cb2c2-e78d-41e3-808b-c6948f215b76
|
||
# Fill with a value other than 0 or 1
|
||
fill(42, (2, 2, 3))
|
||
|
||
# ╔═╡ 91cc92b5-0be7-4ddf-91d1-bf56506e899c
|
||
md"""
|
||
## Range
|
||
|
||
While using `for` loops, we used a syntax like the following:
|
||
|
||
for i in 1:4
|
||
|
||
The `1:4` is a range. You can think of it as a vector that does not store all values in memory, but only the start, end and step values.
|
||
|
||
To see what a range contains, you can convert it to a vector by *collecting* its elements using `collect`.
|
||
"""
|
||
|
||
# ╔═╡ c24f0bf2-0054-49f2-bffc-8b3e3ff6409b
|
||
# Does not show the elements explicitly
|
||
1:4
|
||
|
||
# ╔═╡ 800d4999-d7d7-4818-95e7-d93027f23c53
|
||
collect(1:4)
|
||
|
||
# ╔═╡ a790ba58-c369-49eb-8f00-fdb73bcaab6c
|
||
# Using a step different from 1
|
||
collect(1:2:10)
|
||
|
||
# ╔═╡ 28c9ef22-25b9-4640-bdd1-1b8dc7b33090
|
||
# Ranges of floats are also possible
|
||
collect(0.0:0.4:2.0)
|
||
|
||
# ╔═╡ 1c4c05d7-455f-4a47-88aa-cf84a323a663
|
||
# You can generate a range by providing the number of elements you want between start and end. The step is then calculated automatically.
|
||
# This will be helpful for plotting later
|
||
r = range(0.0, 2.0; length=5)
|
||
|
||
# ╔═╡ e8c26d42-f841-4966-8d9e-3f11e9334551
|
||
collect(r)
|
||
|
||
# ╔═╡ 00000000-0000-0000-0000-000000000001
|
||
PLUTO_PROJECT_TOML_CONTENTS = """
|
||
[deps]
|
||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||
Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
|
||
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
|
||
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||
|
||
[compat]
|
||
Measurements = "~2.11.0"
|
||
PlutoUI = "~0.7.59"
|
||
Unitful = "~1.19.1"
|
||
"""
|
||
|
||
# ╔═╡ 00000000-0000-0000-0000-000000000002
|
||
PLUTO_MANIFEST_TOML_CONTENTS = """
|
||
# This file is machine-generated - editing it directly is not advised
|
||
|
||
julia_version = "1.10.3"
|
||
manifest_format = "2.0"
|
||
project_hash = "022676ff05294a4cf046ceb66a716a28bdcf6c6a"
|
||
|
||
[[deps.AbstractPlutoDingetjes]]
|
||
deps = ["Pkg"]
|
||
git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a"
|
||
uuid = "6e696c72-6542-2067-7265-42206c756150"
|
||
version = "1.3.2"
|
||
|
||
[[deps.ArgTools]]
|
||
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
||
version = "1.1.1"
|
||
|
||
[[deps.Artifacts]]
|
||
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
||
|
||
[[deps.Base64]]
|
||
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||
|
||
[[deps.Calculus]]
|
||
deps = ["LinearAlgebra"]
|
||
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
|
||
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
|
||
version = "0.5.1"
|
||
|
||
[[deps.ColorTypes]]
|
||
deps = ["FixedPointNumbers", "Random"]
|
||
git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d"
|
||
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
|
||
version = "0.11.5"
|
||
|
||
[[deps.CompilerSupportLibraries_jll]]
|
||
deps = ["Artifacts", "Libdl"]
|
||
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
||
version = "1.1.1+0"
|
||
|
||
[[deps.Dates]]
|
||
deps = ["Printf"]
|
||
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||
|
||
[[deps.Downloads]]
|
||
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
|
||
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
|
||
version = "1.6.0"
|
||
|
||
[[deps.FileWatching]]
|
||
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
||
|
||
[[deps.FixedPointNumbers]]
|
||
deps = ["Statistics"]
|
||
git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172"
|
||
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
|
||
version = "0.8.5"
|
||
|
||
[[deps.Hyperscript]]
|
||
deps = ["Test"]
|
||
git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4"
|
||
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
|
||
version = "0.0.5"
|
||
|
||
[[deps.HypertextLiteral]]
|
||
deps = ["Tricks"]
|
||
git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653"
|
||
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
|
||
version = "0.9.5"
|
||
|
||
[[deps.IOCapture]]
|
||
deps = ["Logging", "Random"]
|
||
git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c"
|
||
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
|
||
version = "0.2.4"
|
||
|
||
[[deps.InteractiveUtils]]
|
||
deps = ["Markdown"]
|
||
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
||
|
||
[[deps.JSON]]
|
||
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
|
||
git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
|
||
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||
version = "0.21.4"
|
||
|
||
[[deps.LibCURL]]
|
||
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
||
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
|
||
version = "0.6.4"
|
||
|
||
[[deps.LibCURL_jll]]
|
||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
|
||
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
|
||
version = "8.4.0+0"
|
||
|
||
[[deps.LibGit2]]
|
||
deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
|
||
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||
|
||
[[deps.LibGit2_jll]]
|
||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
|
||
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
||
version = "1.6.4+0"
|
||
|
||
[[deps.LibSSH2_jll]]
|
||
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
|
||
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
||
version = "1.11.0+1"
|
||
|
||
[[deps.Libdl]]
|
||
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
||
|
||
[[deps.LinearAlgebra]]
|
||
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
||
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||
|
||
[[deps.Logging]]
|
||
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||
|
||
[[deps.MIMEs]]
|
||
git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb"
|
||
uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65"
|
||
version = "0.1.4"
|
||
|
||
[[deps.Markdown]]
|
||
deps = ["Base64"]
|
||
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
||
|
||
[[deps.MbedTLS_jll]]
|
||
deps = ["Artifacts", "Libdl"]
|
||
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
||
version = "2.28.2+1"
|
||
|
||
[[deps.Measurements]]
|
||
deps = ["Calculus", "LinearAlgebra", "Printf", "Requires"]
|
||
git-tree-sha1 = "bdcde8ec04ca84aef5b124a17684bf3b302de00e"
|
||
uuid = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
|
||
version = "2.11.0"
|
||
|
||
[deps.Measurements.extensions]
|
||
MeasurementsBaseTypeExt = "BaseType"
|
||
MeasurementsJunoExt = "Juno"
|
||
MeasurementsRecipesBaseExt = "RecipesBase"
|
||
MeasurementsSpecialFunctionsExt = "SpecialFunctions"
|
||
MeasurementsUnitfulExt = "Unitful"
|
||
|
||
[deps.Measurements.weakdeps]
|
||
BaseType = "7fbed51b-1ef5-4d67-9085-a4a9b26f478c"
|
||
Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d"
|
||
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
|
||
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
|
||
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||
|
||
[[deps.Mmap]]
|
||
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
|
||
|
||
[[deps.MozillaCACerts_jll]]
|
||
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
|
||
version = "2023.1.10"
|
||
|
||
[[deps.NetworkOptions]]
|
||
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
||
version = "1.2.0"
|
||
|
||
[[deps.OpenBLAS_jll]]
|
||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
||
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
||
version = "0.3.23+4"
|
||
|
||
[[deps.Parsers]]
|
||
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
||
git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821"
|
||
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
||
version = "2.8.1"
|
||
|
||
[[deps.Pkg]]
|
||
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
|
||
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||
version = "1.10.0"
|
||
|
||
[[deps.PlutoUI]]
|
||
deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"]
|
||
git-tree-sha1 = "ab55ee1510ad2af0ff674dbcced5e94921f867a9"
|
||
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
|
||
version = "0.7.59"
|
||
|
||
[[deps.PrecompileTools]]
|
||
deps = ["Preferences"]
|
||
git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
|
||
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
|
||
version = "1.2.1"
|
||
|
||
[[deps.Preferences]]
|
||
deps = ["TOML"]
|
||
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
|
||
uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
||
version = "1.4.3"
|
||
|
||
[[deps.Printf]]
|
||
deps = ["Unicode"]
|
||
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||
|
||
[[deps.REPL]]
|
||
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
|
||
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||
|
||
[[deps.Random]]
|
||
deps = ["SHA"]
|
||
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||
|
||
[[deps.Reexport]]
|
||
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
||
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
||
version = "1.2.2"
|
||
|
||
[[deps.Requires]]
|
||
deps = ["UUIDs"]
|
||
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
|
||
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
|
||
version = "1.3.0"
|
||
|
||
[[deps.SHA]]
|
||
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
||
version = "0.7.0"
|
||
|
||
[[deps.Serialization]]
|
||
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||
|
||
[[deps.Sockets]]
|
||
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
||
|
||
[[deps.SparseArrays]]
|
||
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
||
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||
version = "1.10.0"
|
||
|
||
[[deps.Statistics]]
|
||
deps = ["LinearAlgebra", "SparseArrays"]
|
||
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||
version = "1.10.0"
|
||
|
||
[[deps.SuiteSparse_jll]]
|
||
deps = ["Artifacts", "Libdl", "libblastrampoline_jll"]
|
||
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
||
version = "7.2.1+1"
|
||
|
||
[[deps.TOML]]
|
||
deps = ["Dates"]
|
||
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
||
version = "1.0.3"
|
||
|
||
[[deps.Tar]]
|
||
deps = ["ArgTools", "SHA"]
|
||
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
|
||
version = "1.10.0"
|
||
|
||
[[deps.Test]]
|
||
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
|
||
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||
|
||
[[deps.Tricks]]
|
||
git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f"
|
||
uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775"
|
||
version = "0.1.8"
|
||
|
||
[[deps.URIs]]
|
||
git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b"
|
||
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
|
||
version = "1.5.1"
|
||
|
||
[[deps.UUIDs]]
|
||
deps = ["Random", "SHA"]
|
||
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||
|
||
[[deps.Unicode]]
|
||
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
||
|
||
[[deps.Unitful]]
|
||
deps = ["Dates", "LinearAlgebra", "Random"]
|
||
git-tree-sha1 = "352edac1ad17e018186881b051960bfca78a075a"
|
||
uuid = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||
version = "1.19.1"
|
||
|
||
[deps.Unitful.extensions]
|
||
ConstructionBaseUnitfulExt = "ConstructionBase"
|
||
InverseFunctionsUnitfulExt = "InverseFunctions"
|
||
|
||
[deps.Unitful.weakdeps]
|
||
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
|
||
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
||
|
||
[[deps.Zlib_jll]]
|
||
deps = ["Libdl"]
|
||
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
||
version = "1.2.13+1"
|
||
|
||
[[deps.libblastrampoline_jll]]
|
||
deps = ["Artifacts", "Libdl"]
|
||
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
|
||
version = "5.8.0+1"
|
||
|
||
[[deps.nghttp2_jll]]
|
||
deps = ["Artifacts", "Libdl"]
|
||
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
|
||
version = "1.52.0+1"
|
||
|
||
[[deps.p7zip_jll]]
|
||
deps = ["Artifacts", "Libdl"]
|
||
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
||
version = "17.4.0+2"
|
||
"""
|
||
|
||
# ╔═╡ Cell order:
|
||
# ╟─2c5e32f4-1d7d-4494-b025-a90d17919756
|
||
# ╟─21590bf1-1e1c-46b4-a2b6-7eb915e121ab
|
||
# ╟─d04af0fd-5ced-4f4f-b157-dd170e2ef8c8
|
||
# ╟─938adcfe-8d1b-4c77-8d82-c48415f5673e
|
||
# ╠═73190799-fd03-4cc4-9b4e-c523bc310468
|
||
# ╠═4c242a67-6445-48e7-a6c3-418a489b89ba
|
||
# ╠═fe70db85-6e68-48ee-9b9a-7072e2dd7fe3
|
||
# ╠═a73c132f-fd81-49ae-afc8-29e08a9042c8
|
||
# ╠═7671c5cb-9265-479d-b782-195bad6b7ba7
|
||
# ╠═3f2c4ab8-4ba4-44d5-99d4-9d941e4df99e
|
||
# ╠═02282f61-e1ca-483d-b6de-feeccedd7bc0
|
||
# ╠═e4237ccd-b042-408b-8177-4c0d31a28caa
|
||
# ╠═0dc9bbb4-fdde-4006-b04d-4509f7d041a7
|
||
# ╠═9c837673-79dd-4a6f-a11d-6f0f2c001587
|
||
# ╟─0b6c6d50-e24c-43c7-8f04-4a53a3309bbf
|
||
# ╟─d1bf37f9-5135-48b8-8f9b-84ddd4a86157
|
||
# ╠═8d005ddd-0308-4a06-8bae-251387facf6f
|
||
# ╠═b7d27cd4-a655-492e-b2b3-cdc745b2c2da
|
||
# ╠═141950e5-e9f8-414b-b08d-86777428cbec
|
||
# ╠═2e7f29ce-3afa-4c12-838d-8051c0567e20
|
||
# ╠═4936c9fc-43da-4b8b-84ce-11e739802e07
|
||
# ╟─5e7f8a5e-9354-442b-aa13-7b9b3de536b1
|
||
# ╟─cf08cc65-7a9e-490d-b7e6-eecf6a1d9977
|
||
# ╠═4774fa16-a6f6-48ae-b9b6-8a279118c99a
|
||
# ╟─30000e9f-ec3d-416a-b402-010da80cd9ea
|
||
# ╠═72daf832-dba6-49ad-8d5a-f2c3aecdb630
|
||
# ╟─2121b949-06e7-4079-a25a-d0518ee2ba50
|
||
# ╠═534f3b32-1fc9-4eed-887a-2cac66c2bdb4
|
||
# ╠═3894b6b5-1952-409a-9966-502c277e26c3
|
||
# ╠═f20de3db-f270-4c43-aab7-692c313b5fa9
|
||
# ╠═c72f187f-9626-45d9-870a-267c8530202c
|
||
# ╠═e4295349-fc5c-48cb-975e-803e44d1a06e
|
||
# ╠═7287122b-e5ea-4f69-963b-023483914992
|
||
# ╠═8b6609b0-5d6d-4c7d-a144-deaff79f93e9
|
||
# ╟─196682db-f5e1-4c07-9d35-644da3eecdd6
|
||
# ╠═10fdb32f-b66f-4c4e-abd9-e856549941b8
|
||
# ╠═00ba151b-a741-448d-b8bf-775217250915
|
||
# ╠═204cf77f-bf37-4110-9c9f-1f9236301ba9
|
||
# ╠═750bba32-e695-48f1-af70-70c94d13366b
|
||
# ╠═0b663bcb-4ff4-4597-b28b-b58c9cbfa181
|
||
# ╟─5e45b854-c173-452b-b62b-54037a3780fd
|
||
# ╠═0596fe87-4201-476e-8e11-618c621c5474
|
||
# ╠═28063282-5c60-4ffb-a715-9b1e88498df9
|
||
# ╠═da5fb1f9-2a2d-4148-8ba5-8c4a529829e9
|
||
# ╠═943da836-384d-4774-aaf4-54c27feb53d8
|
||
# ╠═a96f3ae9-12df-4df8-85da-09b9b1e47de1
|
||
# ╠═8d106ad2-5f92-4138-bfff-56ee21e098fa
|
||
# ╠═f8bc4051-93c6-4376-abaa-7b4cb4b8f607
|
||
# ╟─b25dc5f2-e186-4da1-b045-47b22c93799b
|
||
# ╠═e0d7fbc8-39fc-4b70-9b92-0c19fffb0c05
|
||
# ╠═398648e8-358e-4289-ae95-957e77d0c46f
|
||
# ╠═28fa32e7-4e50-4890-a765-5cfb1d3f791b
|
||
# ╠═d2607457-1794-4a0f-af41-cb80aadb598f
|
||
# ╠═23dbbe13-d997-4f9f-a300-7cb78c4fb8ee
|
||
# ╠═e767971a-7e1d-4a78-88d7-03e4ae4d51db
|
||
# ╟─1e7b103c-6cc9-4586-820b-9ec836b997da
|
||
# ╠═7ade3f89-4838-4a8b-815c-4e2d6ccd7fea
|
||
# ╠═35675b9b-a28a-427f-9da4-e6c756d2276a
|
||
# ╠═66d39465-8244-483f-9a82-8d17b95cf41d
|
||
# ╠═879c5330-781f-44c2-b072-1ee0f9bd971d
|
||
# ╠═df5914e3-b250-4824-80a5-cac5d0bed084
|
||
# ╠═099ac8f8-8c5c-410b-a11f-c98bc68230b2
|
||
# ╠═cd46845b-4980-465c-a64f-3a8bcb66f53e
|
||
# ╟─a0bd2da0-344d-470c-918e-e8760fc77355
|
||
# ╟─a2c4c4d9-4f06-41d4-baeb-b5f9f3b5b7c3
|
||
# ╠═56ca47c1-6e4d-48a2-9f55-ca89362c7d3f
|
||
# ╠═f4122e58-a30c-45a4-8ede-492ddb8deba4
|
||
# ╠═949e7fb8-8eff-49ea-8e76-0306857b05b9
|
||
# ╠═26869678-32f0-46e8-8cb2-d45b84441f03
|
||
# ╠═0121add2-b42b-4dcd-8912-f8420a8b4c72
|
||
# ╟─9df364d6-0f43-4fe3-8a10-4bf0dc79e04d
|
||
# ╟─b8d7bd0b-a0ea-499f-9e61-3875535887e9
|
||
# ╠═13dd1d3c-dec8-4871-8ffa-b3db1bdd2847
|
||
# ╟─0078ea9a-9c94-4703-a878-3cdd2e11d625
|
||
# ╠═38d3105f-427b-427b-bf7b-8aa76dfb3bef
|
||
# ╠═41b17c21-5b57-4912-88ee-e33215c1e0c8
|
||
# ╠═b6dcaf22-c075-442e-b0d0-e48eae2350ac
|
||
# ╟─7f01c4a5-0e56-43aa-8d14-5fecfa04b370
|
||
# ╠═105362be-572c-4a4d-9163-15ed8b4f1fbf
|
||
# ╠═18c2ffb9-a895-491b-96ee-a0b5c68da180
|
||
# ╟─62cdf927-4e2b-40bb-be2d-eb32e0789548
|
||
# ╠═9847a224-701a-489a-b125-95158aa805d4
|
||
# ╠═21163504-972d-4362-8c57-dbd708b2fa04
|
||
# ╠═9ef91243-04fc-44f2-ae69-76f372364f21
|
||
# ╟─3df766f0-38cb-4cdf-a68f-a4771c78fe31
|
||
# ╟─a6d882a0-c80e-4acf-b05b-c0ae120d698d
|
||
# ╟─944e2d37-8280-47b8-b874-97221955d048
|
||
# ╠═23d4ac67-05ec-4b3d-8368-86256076be62
|
||
# ╟─e8d7de2f-7c7e-47cb-9364-27d583652167
|
||
# ╠═866edf5e-a76c-448d-98e8-925eaed5eba5
|
||
# ╠═a8ea4ac1-7f62-4485-a8c5-8ccf00c45720
|
||
# ╠═786a96be-16cd-4f1b-9b5f-138e232d3183
|
||
# ╠═dd8dad86-6bc2-4489-8469-7eac80fc41bb
|
||
# ╠═fac04aa7-28e9-4f93-9312-a8f8f93c0877
|
||
# ╠═86bc0ff0-b6bf-4700-a741-36323be58391
|
||
# ╠═ef35a3a7-c1df-4952-aa41-1ed22d7f3981
|
||
# ╠═c336d5f6-80ee-4994-a55f-2d6b3aa3d559
|
||
# ╟─608d4433-6e68-4f95-8581-437234b58e87
|
||
# ╠═beadbfd3-0015-449a-b6e7-b5182b396c1d
|
||
# ╠═552fafa4-fad5-4efe-895f-255b3ec5c858
|
||
# ╠═d11fde7f-3238-4013-bd2d-546aab0d9f9c
|
||
# ╟─036a2c43-dbc9-487c-96aa-94324eeb4a52
|
||
# ╠═1e954726-254e-41bb-a62f-17bdc9884bee
|
||
# ╠═d74f6c46-f5a8-4720-bcaf-936f1508efda
|
||
# ╠═3e5daca6-5aa8-42bf-988b-c09fb17388df
|
||
# ╠═7ff20c67-58d5-4095-bb8e-7ab7522791c7
|
||
# ╟─3102810f-3467-4ed8-86c0-16e9177fa69d
|
||
# ╠═c1c705d2-7e46-4811-9fb1-6b88b5a4140e
|
||
# ╠═ddd3c019-6e70-4714-88fe-07d7a006ebc6
|
||
# ╟─05db4e85-857d-4056-a576-5de992eabf29
|
||
# ╠═85c3c314-0f66-41be-8398-a5f9149ddfbd
|
||
# ╠═566553a0-0202-4b59-b3ef-6954bf946b79
|
||
# ╠═b70a48ca-362c-40d6-b703-2553a0b01275
|
||
# ╟─c0b32101-5863-4c22-8ee5-8e29abe0da39
|
||
# ╟─00456b15-5d1c-4c74-a875-31ff9c8e1789
|
||
# ╠═91c4c623-5680-4b35-a694-2bd2612def94
|
||
# ╟─4a00035f-a1d1-409f-b73b-07f9073dc9d5
|
||
# ╠═d4ebb324-fa31-4058-9da1-35e07a971106
|
||
# ╠═f8259580-5a29-4a13-811f-c91d6811a291
|
||
# ╠═f813afd8-2e1b-43f7-beeb-ac9bd15fbeb6
|
||
# ╟─7ab3a69d-ac31-49cf-8d34-3a427b02ed06
|
||
# ╟─2a85d95b-51d2-4ea0-a2a2-43307a725f2a
|
||
# ╟─eef07cd2-0a83-491f-a3ff-c51400aadebb
|
||
# ╠═a5a71d00-bf30-4c07-bcd8-2bf99698522e
|
||
# ╟─9a78bf14-7fb4-448a-a8dd-69e244a0a297
|
||
# ╠═5281ef32-5de6-4488-8430-e5652cbf8299
|
||
# ╟─9107a95e-6ef5-465f-bd28-9a774f99f4ab
|
||
# ╠═eec41279-e038-4415-81b3-ad5d4c396011
|
||
# ╟─544368b2-3e39-41e7-97ea-e2bbf44a7749
|
||
# ╠═d2333817-e941-429b-b8e3-2ff07669096b
|
||
# ╠═be0ff87b-229a-433e-a49e-2f1ced5bb9aa
|
||
# ╠═96803a1e-0779-4eab-b120-b5569a44ac7b
|
||
# ╟─54d654cd-110f-4b1f-9578-109a80db4574
|
||
# ╠═5ab233d2-f360-4362-b1f8-3f3ae2a4fee1
|
||
# ╠═0d100501-de84-4a5c-beb7-8ff9e83c473d
|
||
# ╟─9e3f698d-e57b-46c2-98e0-157fa7b06ae6
|
||
# ╟─d1680205-a8eb-4ef6-ae4f-059e7a30f5c1
|
||
# ╠═b54ace0e-8947-46a3-842a-05b5cbfc4e87
|
||
# ╠═0d5bfd45-79da-435b-9a98-8ed996bbc7b4
|
||
# ╠═8c47710f-1ed2-40fd-9290-374b498380e3
|
||
# ╟─a03b46cc-1b26-44c2-b83d-884e3dbbe4fa
|
||
# ╠═68658408-188e-43f7-ad74-251172dec0a8
|
||
# ╠═7c00f22c-860f-4bb1-b4b4-74c5c3c70f45
|
||
# ╠═45b64c7a-850b-402c-b7ce-2a0bf6d77060
|
||
# ╠═d1ed1515-cd59-4e10-a15c-b64325bc44c2
|
||
# ╟─6c80e009-30de-4232-9a1b-ac954242a5a6
|
||
# ╠═b1426df5-a083-4977-a72c-81e03fd7719d
|
||
# ╠═5b16ca43-1f56-4934-a420-5ffa5ed437ec
|
||
# ╠═628852dc-16e5-4a03-93a9-be209b1e8fb4
|
||
# ╟─3ea54f0d-2aa5-47a3-bbc3-92023a56b834
|
||
# ╠═e9e117af-1194-4d64-94a8-3e9fd51498aa
|
||
# ╠═1fd6fdd3-82a0-480e-9db6-e657536da63f
|
||
# ╠═ace6fd59-ccb8-4318-85ce-966b04c4ce53
|
||
# ╠═b7bb3e82-a2ee-4356-8c7b-0db664adcbe0
|
||
# ╠═027313d6-c247-43e9-872b-c3f0fe71b733
|
||
# ╠═e77e7ceb-31e3-4231-9923-f62b1382a2d1
|
||
# ╠═65d3ddc2-36ed-4126-9211-e838ffc0d859
|
||
# ╠═641e8c05-3e80-47e5-be77-91090a5f799a
|
||
# ╠═2b9a5867-ca82-4a27-a700-bd0bd6c89bbe
|
||
# ╟─87b43f26-7437-4ee9-9b83-5b21e86dd0c9
|
||
# ╠═22f5ebc1-fd5c-4ee7-b169-8144fbd9b570
|
||
# ╠═7479c420-2e04-4fe7-823c-3fde9efb54ca
|
||
# ╠═4cd82256-be63-4db1-b2af-82a1358f4881
|
||
# ╟─605ee405-ec83-4064-adc8-861d95513e5e
|
||
# ╠═22a7baee-6533-43f7-8503-e5d5537a8c78
|
||
# ╟─90b0fb2f-eb2d-4d06-96da-a4605ce61c41
|
||
# ╟─786682f6-692d-488d-8dab-231b0111d07f
|
||
# ╠═16a9cb53-2812-4ed3-afe4-96c0b116ad9a
|
||
# ╠═dfd91d6b-65a5-454b-a0f9-6ed267def022
|
||
# ╠═e68c54d8-3fb8-4aae-a334-665fdb8db1f0
|
||
# ╠═1f347724-1db2-48f0-87df-4e63ad6e8820
|
||
# ╠═8d74d994-3d4e-40ba-97cb-6dac1003fb8f
|
||
# ╠═af87251f-a37c-4088-8f4d-3803778bd97e
|
||
# ╟─2ac5d431-1a4d-4db2-8954-97e011cd2175
|
||
# ╠═d30b3a5f-e14c-45ea-89a4-cf710733a2ee
|
||
# ╠═6bb730e4-b5aa-4e7b-9ccd-9298db061e7f
|
||
# ╠═2ef34862-0578-41fe-adad-0e894c287dd5
|
||
# ╠═09f2d0f9-cd0e-45e4-a159-cb360292dac1
|
||
# ╠═6f6a875e-fe60-47ba-8837-60edef1b20e0
|
||
# ╠═e99a89ab-af3a-42f5-b1c1-22e13a761eeb
|
||
# ╠═f45b7774-df6f-4019-9217-e88d99babdb3
|
||
# ╠═db1b6e53-3116-48df-b098-1c3045be0dad
|
||
# ╠═cd5abd71-1bf8-484f-a46a-99cc8b994b91
|
||
# ╠═7cef46dc-803a-4a7a-9663-148b6de4a267
|
||
# ╠═70710989-9139-4970-a7b0-5702571e59a4
|
||
# ╠═873be989-d587-4d9f-ad5d-5632ae24b0bf
|
||
# ╟─a9f39e34-4c2c-48f2-9353-babe1bc3cd05
|
||
# ╠═83eca43d-2280-40f1-bf2a-016a843362a3
|
||
# ╠═f4c48701-d90e-48d6-bf9d-539c7fb7c7a5
|
||
# ╠═875cb2c2-e78d-41e3-808b-c6948f215b76
|
||
# ╟─91cc92b5-0be7-4ddf-91d1-bf56506e899c
|
||
# ╠═c24f0bf2-0054-49f2-bffc-8b3e3ff6409b
|
||
# ╠═800d4999-d7d7-4818-95e7-d93027f23c53
|
||
# ╠═a790ba58-c369-49eb-8f00-fdb73bcaab6c
|
||
# ╠═28c9ef22-25b9-4640-bdd1-1b8dc7b33090
|
||
# ╠═1c4c05d7-455f-4a47-88aa-cf84a323a663
|
||
# ╠═e8c26d42-f841-4966-8d9e-3f11e9334551
|
||
# ╟─d1a4ef8b-8e7d-4d34-80d8-cee195e237ae
|
||
# ╟─00000000-0000-0000-0000-000000000001
|
||
# ╟─00000000-0000-0000-0000-000000000002
|