mirror of
https://gitlab.rlp.net/mobitar/julia_course.git
synced 2024-11-16 13:28:10 +00:00
Done structs
This commit is contained in:
parent
485aa0079c
commit
d11adbf45d
1 changed files with 188 additions and 15 deletions
203
Day_5/Day_5.jl
203
Day_5/Day_5.jl
|
@ -20,56 +20,145 @@ Julia as a functional language does not have classes like in object oriented lan
|
||||||
|
|
||||||
Using structs, you can define your own types. Structs use type composition. This means that you combine types into a new one.
|
Using structs, you can define your own types. Structs use type composition. This means that you combine types into a new one.
|
||||||
|
|
||||||
In Julia, type annotations DO NOT lead to any performance boosts. Structs build an exception! If you are writing a struct, you have to use type annotations with concrete types (not abstract)!
|
In Julia, type annotations DO NOT lead to any performance boosts. Structs build an **exception**! If you are writing a struct, you have to use type annotations with **concrete types** (not abstract)!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ╔═╡ 3e3e324d-5650-4f81-87cf-fb0f6f55d9d1
|
# ╔═╡ 3e3e324d-5650-4f81-87cf-fb0f6f55d9d1
|
||||||
|
# You should not use a struct for a 2D vector. Use Julia's vectors! This is only for demonstration.
|
||||||
struct Vec2d
|
struct Vec2d
|
||||||
x::Float64
|
x::Float64
|
||||||
y::Float64
|
y::Float64
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ 2ab6f97f-8eed-4b86-9eb6-1de88e6c846d
|
# ╔═╡ 2ab6f97f-8eed-4b86-9eb6-1de88e6c846d
|
||||||
vec_2d = Vec2d(1.0, 1.0)
|
# Define a variable with this type.
|
||||||
|
# The order of the arguments is important!
|
||||||
|
# The first argument sets the first field (here `x`).
|
||||||
|
# The second argument sets the second field and so on.
|
||||||
|
vec_2d = Vec2d(1.0, 2.0)
|
||||||
|
|
||||||
|
# ╔═╡ c9be354a-d5ef-4c94-ad2f-c2035dc9323f
|
||||||
|
# Access a field
|
||||||
|
vec_2d.x
|
||||||
|
|
||||||
|
# ╔═╡ 48d31ed6-c5b7-4510-9c49-de8a3a8a0fa7
|
||||||
|
vec_2d.y
|
||||||
|
|
||||||
# ╔═╡ 377a9100-efd8-479c-b9f6-68584c886800
|
# ╔═╡ 377a9100-efd8-479c-b9f6-68584c886800
|
||||||
|
# It is a new type
|
||||||
typeof(vec_2d)
|
typeof(vec_2d)
|
||||||
|
|
||||||
|
# ╔═╡ 9940a716-1109-46f9-a88a-29a7a996412d
|
||||||
|
md"""
|
||||||
|
## Structs with abstract types
|
||||||
|
"""
|
||||||
|
|
||||||
# ╔═╡ 0e62a7b2-0636-4018-b005-0ae674fec45e
|
# ╔═╡ 0e62a7b2-0636-4018-b005-0ae674fec45e
|
||||||
# Wow, we did reach infinity ♾️
|
# Wow, we did reach infinity ♾️
|
||||||
|
# This is because of the limits of Float64
|
||||||
Vec2d(factorial(big(1000)), 2.0)
|
Vec2d(factorial(big(1000)), 2.0)
|
||||||
|
|
||||||
|
# ╔═╡ 70bb19db-3d97-4ae1-92d8-552574aa53c3
|
||||||
|
md"""
|
||||||
|
You might think this problem can be fixed by changing the type of the fields from `Float64` to something like `Real`. This will work, but it does harm performance!
|
||||||
|
|
||||||
|
**One more important performance tip: Don't use structs with abstract field types (or no types)!**
|
||||||
|
"""
|
||||||
|
|
||||||
# ╔═╡ 6046417c-460b-4b0c-8423-4d6c4c18731f
|
# ╔═╡ 6046417c-460b-4b0c-8423-4d6c4c18731f
|
||||||
|
# Bad usage of abstract field types
|
||||||
struct BadVec2d
|
struct BadVec2d
|
||||||
x::Real
|
x::Real
|
||||||
y::Real
|
y::Real
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ 3e21d34f-3758-427f-85c0-7c457f3f0904
|
# ╔═╡ 3e21d34f-3758-427f-85c0-7c457f3f0904
|
||||||
|
# It does work, but it is bad for performance
|
||||||
bad_vec2d = BadVec2d(factorial(big(1000)), 2.0)
|
bad_vec2d = BadVec2d(factorial(big(1000)), 2.0)
|
||||||
|
|
||||||
# ╔═╡ 4a07f5e3-2413-49c4-824c-b9c844695052
|
# ╔═╡ 4a07f5e3-2413-49c4-824c-b9c844695052
|
||||||
|
# The type does not say anything about what the fields type is.
|
||||||
typeof(bad_vec2d)
|
typeof(bad_vec2d)
|
||||||
|
|
||||||
# ╔═╡ 9008b1c4-ad76-4d4f-b6c5-001a77543b97
|
# ╔═╡ 9008b1c4-ad76-4d4f-b6c5-001a77543b97
|
||||||
|
# Better for performance:
|
||||||
|
# Use this syntax to let the type be derived from an abstract type
|
||||||
struct BetterVec2d{T<:Real}
|
struct BetterVec2d{T<:Real}
|
||||||
x::T
|
x::T
|
||||||
y::T
|
y::T
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ 830dd737-4fdc-42c7-b105-d0622b055db1
|
# ╔═╡ 830dd737-4fdc-42c7-b105-d0622b055db1
|
||||||
|
# This works too and it is good for performance
|
||||||
big_vec2d = BetterVec2d(factorial(big(1000)), big(1))
|
big_vec2d = BetterVec2d(factorial(big(1000)), big(1))
|
||||||
|
|
||||||
# ╔═╡ f91b0c58-bc44-414a-b357-145d8c4339d2
|
# ╔═╡ f91b0c58-bc44-414a-b357-145d8c4339d2
|
||||||
|
# You see that a concrete type was choosen!
|
||||||
typeof(big_vec2d)
|
typeof(big_vec2d)
|
||||||
|
|
||||||
|
# ╔═╡ 169de33e-cff8-4419-be18-0f487c185ad7
|
||||||
|
# The concrete type of the fields is determined on construction
|
||||||
|
typeof(BetterVec2d(1.0, 2.0))
|
||||||
|
|
||||||
# ╔═╡ 3f1b8df9-104b-42c3-97ee-11782f9f744f
|
# ╔═╡ 3f1b8df9-104b-42c3-97ee-11782f9f744f
|
||||||
|
# This will not work. Both fields has to have the same type.
|
||||||
# BetterVec2d(1.0, 1)
|
# BetterVec2d(1.0, 1)
|
||||||
|
|
||||||
|
# ╔═╡ a053b367-f7f2-440e-b9e0-4987b491c256
|
||||||
|
struct MixedVec2d{T1<:Real, T2<:Real}
|
||||||
|
x::T1
|
||||||
|
y::T2
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ 1eab61c9-74e1-4540-9750-6ec8448e4950
|
||||||
|
# This works
|
||||||
|
mixed_vec2d = MixedVec2d(1.0, 1)
|
||||||
|
|
||||||
|
# ╔═╡ 4a24f24b-d872-4cd8-bf76-49a0496e4ea6
|
||||||
|
# Two different concrete types for the fields
|
||||||
|
typeof(mixed_vec2d)
|
||||||
|
|
||||||
|
# ╔═╡ c9f68fcf-2b20-43b1-839a-59805357c6d3
|
||||||
|
md"""
|
||||||
|
## Mutation
|
||||||
|
By default, structs are not mutable!
|
||||||
|
|
||||||
|
If you want to be mutable, you have to use the keyword `mutable`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ╔═╡ f8b27d41-448a-4329-986f-e65e0b3e77d6
|
||||||
|
# This will not work because the struct is immutable by default
|
||||||
|
# vec_2d.x = 42.0
|
||||||
|
|
||||||
|
# ╔═╡ da9e39a5-0ee3-4f6c-8cb1-abb3ebf3a01e
|
||||||
|
# Defining a mutable struct
|
||||||
|
mutable struct MutVec2d
|
||||||
|
x::Float64
|
||||||
|
y::Float64
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ d16ac12a-c772-4fee-a309-5b4a2708d08e
|
||||||
|
begin
|
||||||
|
mut_vec = MutVec2d(1.0, 2.0)
|
||||||
|
|
||||||
|
# Mutating a field
|
||||||
|
mut_vec.x = 42.0
|
||||||
|
|
||||||
|
mut_vec
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ d635a63b-44d9-4bfc-a873-ef537cdbdb09
|
||||||
|
md"""
|
||||||
|
## Structs from abstract types
|
||||||
|
To use the features of mutliple dispatch, define an abstract type and derive structs from it.
|
||||||
|
"""
|
||||||
|
|
||||||
# ╔═╡ 10c380fd-80e6-4cb7-b50e-1a7998ec00c5
|
# ╔═╡ 10c380fd-80e6-4cb7-b50e-1a7998ec00c5
|
||||||
|
# Defining an abstract type
|
||||||
abstract type Student end
|
abstract type Student end
|
||||||
|
|
||||||
# ╔═╡ 58de483d-c2b5-4252-b6da-64bd8bfac1ac
|
# ╔═╡ 58de483d-c2b5-4252-b6da-64bd8bfac1ac
|
||||||
|
# Defining a struct derived from the abstract type `Student`
|
||||||
struct MathStudent<:Student
|
struct MathStudent<:Student
|
||||||
name::String
|
name::String
|
||||||
hobby::String
|
hobby::String
|
||||||
|
@ -79,10 +168,11 @@ end
|
||||||
struct PhysicsStudent<:Student
|
struct PhysicsStudent<:Student
|
||||||
name::String
|
name::String
|
||||||
hobby::String
|
hobby::String
|
||||||
favorite_particle::String
|
favorite_particle::String # Some additional field
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ b535fd1d-695d-49fb-8a6a-2f2f0053a6f6
|
# ╔═╡ b535fd1d-695d-49fb-8a6a-2f2f0053a6f6
|
||||||
|
# Define a function that works on all students
|
||||||
function print_name(student::Student)
|
function print_name(student::Student)
|
||||||
println(student.name)
|
println(student.name)
|
||||||
|
|
||||||
|
@ -90,17 +180,19 @@ function print_name(student::Student)
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ 63f32169-b98c-4212-bbd9-4c601266f209
|
# ╔═╡ 63f32169-b98c-4212-bbd9-4c601266f209
|
||||||
|
# Define a method that works only with math students
|
||||||
function print_information(math_student::MathStudent)
|
function print_information(math_student::MathStudent)
|
||||||
println("Math student: $(math_student.name)")
|
println("Math student: $(math_student.name)")
|
||||||
println("hobby: $(math_student.hobby)")
|
println("Hobby: $(math_student.hobby)")
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# ╔═╡ cb49717b-0584-430e-a30c-c4d02cf55eb2
|
# ╔═╡ cb49717b-0584-430e-a30c-c4d02cf55eb2
|
||||||
|
# Define a method that works only with physics students
|
||||||
function print_information(physics_student::PhysicsStudent)
|
function print_information(physics_student::PhysicsStudent)
|
||||||
println("Physics student: $(physics_student.name)")
|
println("Physics student: $(physics_student.name)")
|
||||||
println("hobby: $(physics_student.hobby)")
|
println("Hobby: $(physics_student.hobby)")
|
||||||
println("Favorite particle: $(physics_student.favorite_particle)")
|
println("Favorite particle: $(physics_student.favorite_particle)")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -124,10 +216,70 @@ print_information(math_student)
|
||||||
# ╔═╡ bc8ef92b-1c68-4c9d-948a-6196dcd2b378
|
# ╔═╡ bc8ef92b-1c68-4c9d-948a-6196dcd2b378
|
||||||
print_information(physics_student)
|
print_information(physics_student)
|
||||||
|
|
||||||
# ╔═╡ d8a2ae5c-b42a-4673-9a95-24cfc69ea3e7
|
# ╔═╡ 06805ff8-f4bc-4779-baa9-2801a44407b6
|
||||||
md"""
|
md"""
|
||||||
# Writing documentation
|
## Constructors
|
||||||
|
You can either define new constructors for a struct or overwrite the default constructor.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ╔═╡ d1937187-15b0-46e7-9589-05d2349aa93a
|
||||||
|
# `begin` blocks are only needed in Pluto notebooks
|
||||||
|
begin
|
||||||
|
struct ComputerScienceStudent<:Student
|
||||||
|
name::String
|
||||||
|
hobby::String
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defining an additional constructor to the default constructor
|
||||||
|
function ComputerScienceStudent(name)
|
||||||
|
return ComputerScienceStudent(name, "Programming")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ 721e268d-b7c5-4ea8-b4d7-2bab6e2a6fb0
|
||||||
|
# Using the default constructor
|
||||||
|
ComputerScienceStudent("John", "Tennis")
|
||||||
|
|
||||||
|
# ╔═╡ 0f76bd6b-906f-49b3-8a36-9e02feb750b9
|
||||||
|
# Using the additional constructor
|
||||||
|
ComputerScienceStudent("Selina")
|
||||||
|
|
||||||
|
# ╔═╡ 513a4b3f-5b12-4d65-9321-0c883f12a1eb
|
||||||
|
mutable struct BiologyStudent<:Student
|
||||||
|
name::String
|
||||||
|
hobby::String
|
||||||
|
|
||||||
|
# Overwriting the default constructor
|
||||||
|
# You have to use the keyword `new`
|
||||||
|
function BiologyStudent(name)
|
||||||
|
return new(name, "Observing animals")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ 3063d330-c411-431e-9e7a-eb3f5cd3ee7b
|
||||||
|
# This will not work because the default constructor is overritten!
|
||||||
|
# BiologyStudent("Kate", "Swimming")
|
||||||
|
|
||||||
|
# ╔═╡ 9e621eb5-a163-4a7a-abd5-85bdf9469692
|
||||||
|
# The new default constructor
|
||||||
|
BiologyStudent("Kate")
|
||||||
|
|
||||||
|
# ╔═╡ 44511b7e-a38a-450f-9a55-b6b6a4d3edd5
|
||||||
|
# This is the default constructor now
|
||||||
|
begin
|
||||||
|
biology_student = BiologyStudent("Kate")
|
||||||
|
|
||||||
|
# The struct has to be mutable
|
||||||
|
biology_student.hobby = "Swimming"
|
||||||
|
|
||||||
|
biology_student
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╔═╡ eddfd543-091b-4a32-8124-a67687dcf457
|
||||||
|
md"""
|
||||||
|
Why would you want to overwrite the default constructor?
|
||||||
|
|
||||||
|
It is useful if you want to enforce checking fields before construction.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ╔═╡ c24c04e4-b131-11ec-2c1b-7de12fe0c324
|
# ╔═╡ c24c04e4-b131-11ec-2c1b-7de12fe0c324
|
||||||
|
@ -187,11 +339,6 @@ md"""
|
||||||
## `DifferentialEquations.jl`
|
## `DifferentialEquations.jl`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ╔═╡ b621819d-6ce3-41e1-9e61-3ad0a2c9b016
|
|
||||||
md"""
|
|
||||||
## `Intervals.jl`
|
|
||||||
"""
|
|
||||||
|
|
||||||
# ╔═╡ 0174178f-3ed9-4890-8482-714cb51a635d
|
# ╔═╡ 0174178f-3ed9-4890-8482-714cb51a635d
|
||||||
md"""
|
md"""
|
||||||
## `ProgressMeter.jl`
|
## `ProgressMeter.jl`
|
||||||
|
@ -202,6 +349,11 @@ md"""
|
||||||
## `NaturallyUnitful.jl`
|
## `NaturallyUnitful.jl`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# ╔═╡ 097b1b98-8b98-4160-bf31-d982f21ab8d6
|
||||||
|
md"""
|
||||||
|
## `Symbolics.jl`
|
||||||
|
"""
|
||||||
|
|
||||||
# ╔═╡ 2430f309-be28-4bc2-9692-92489c31f7b2
|
# ╔═╡ 2430f309-be28-4bc2-9692-92489c31f7b2
|
||||||
md"""
|
md"""
|
||||||
# Resources
|
# Resources
|
||||||
|
@ -424,18 +576,31 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ╔═╡ Cell order:
|
# ╔═╡ Cell order:
|
||||||
# ╠═c7256818-f2ab-4f8a-be6f-1d2c97dca981
|
# ╟─c7256818-f2ab-4f8a-be6f-1d2c97dca981
|
||||||
# ╠═3e3e324d-5650-4f81-87cf-fb0f6f55d9d1
|
# ╠═3e3e324d-5650-4f81-87cf-fb0f6f55d9d1
|
||||||
# ╠═2ab6f97f-8eed-4b86-9eb6-1de88e6c846d
|
# ╠═2ab6f97f-8eed-4b86-9eb6-1de88e6c846d
|
||||||
|
# ╠═c9be354a-d5ef-4c94-ad2f-c2035dc9323f
|
||||||
|
# ╠═48d31ed6-c5b7-4510-9c49-de8a3a8a0fa7
|
||||||
# ╠═377a9100-efd8-479c-b9f6-68584c886800
|
# ╠═377a9100-efd8-479c-b9f6-68584c886800
|
||||||
|
# ╟─9940a716-1109-46f9-a88a-29a7a996412d
|
||||||
# ╠═0e62a7b2-0636-4018-b005-0ae674fec45e
|
# ╠═0e62a7b2-0636-4018-b005-0ae674fec45e
|
||||||
|
# ╟─70bb19db-3d97-4ae1-92d8-552574aa53c3
|
||||||
# ╠═6046417c-460b-4b0c-8423-4d6c4c18731f
|
# ╠═6046417c-460b-4b0c-8423-4d6c4c18731f
|
||||||
# ╠═3e21d34f-3758-427f-85c0-7c457f3f0904
|
# ╠═3e21d34f-3758-427f-85c0-7c457f3f0904
|
||||||
# ╠═4a07f5e3-2413-49c4-824c-b9c844695052
|
# ╠═4a07f5e3-2413-49c4-824c-b9c844695052
|
||||||
# ╠═9008b1c4-ad76-4d4f-b6c5-001a77543b97
|
# ╠═9008b1c4-ad76-4d4f-b6c5-001a77543b97
|
||||||
# ╠═830dd737-4fdc-42c7-b105-d0622b055db1
|
# ╠═830dd737-4fdc-42c7-b105-d0622b055db1
|
||||||
# ╠═f91b0c58-bc44-414a-b357-145d8c4339d2
|
# ╠═f91b0c58-bc44-414a-b357-145d8c4339d2
|
||||||
|
# ╠═169de33e-cff8-4419-be18-0f487c185ad7
|
||||||
# ╠═3f1b8df9-104b-42c3-97ee-11782f9f744f
|
# ╠═3f1b8df9-104b-42c3-97ee-11782f9f744f
|
||||||
|
# ╠═a053b367-f7f2-440e-b9e0-4987b491c256
|
||||||
|
# ╠═1eab61c9-74e1-4540-9750-6ec8448e4950
|
||||||
|
# ╠═4a24f24b-d872-4cd8-bf76-49a0496e4ea6
|
||||||
|
# ╟─c9f68fcf-2b20-43b1-839a-59805357c6d3
|
||||||
|
# ╠═f8b27d41-448a-4329-986f-e65e0b3e77d6
|
||||||
|
# ╠═da9e39a5-0ee3-4f6c-8cb1-abb3ebf3a01e
|
||||||
|
# ╠═d16ac12a-c772-4fee-a309-5b4a2708d08e
|
||||||
|
# ╟─d635a63b-44d9-4bfc-a873-ef537cdbdb09
|
||||||
# ╠═10c380fd-80e6-4cb7-b50e-1a7998ec00c5
|
# ╠═10c380fd-80e6-4cb7-b50e-1a7998ec00c5
|
||||||
# ╠═58de483d-c2b5-4252-b6da-64bd8bfac1ac
|
# ╠═58de483d-c2b5-4252-b6da-64bd8bfac1ac
|
||||||
# ╠═4024358d-f673-45f1-a12a-00a5554622e3
|
# ╠═4024358d-f673-45f1-a12a-00a5554622e3
|
||||||
|
@ -448,7 +613,15 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
||||||
# ╠═bc43e76c-3a9b-4f3f-9f88-28f2f7f868d1
|
# ╠═bc43e76c-3a9b-4f3f-9f88-28f2f7f868d1
|
||||||
# ╠═0a2619e4-9eed-4eb3-a411-c616ee840062
|
# ╠═0a2619e4-9eed-4eb3-a411-c616ee840062
|
||||||
# ╠═bc8ef92b-1c68-4c9d-948a-6196dcd2b378
|
# ╠═bc8ef92b-1c68-4c9d-948a-6196dcd2b378
|
||||||
# ╠═d8a2ae5c-b42a-4673-9a95-24cfc69ea3e7
|
# ╟─06805ff8-f4bc-4779-baa9-2801a44407b6
|
||||||
|
# ╠═d1937187-15b0-46e7-9589-05d2349aa93a
|
||||||
|
# ╠═721e268d-b7c5-4ea8-b4d7-2bab6e2a6fb0
|
||||||
|
# ╠═0f76bd6b-906f-49b3-8a36-9e02feb750b9
|
||||||
|
# ╠═513a4b3f-5b12-4d65-9321-0c883f12a1eb
|
||||||
|
# ╠═3063d330-c411-431e-9e7a-eb3f5cd3ee7b
|
||||||
|
# ╠═9e621eb5-a163-4a7a-abd5-85bdf9469692
|
||||||
|
# ╠═44511b7e-a38a-450f-9a55-b6b6a4d3edd5
|
||||||
|
# ╟─eddfd543-091b-4a32-8124-a67687dcf457
|
||||||
# ╟─c24c04e4-b131-11ec-2c1b-7de12fe0c324
|
# ╟─c24c04e4-b131-11ec-2c1b-7de12fe0c324
|
||||||
# ╠═279d81e7-77d5-4855-bf45-a1a613265f65
|
# ╠═279d81e7-77d5-4855-bf45-a1a613265f65
|
||||||
# ╠═62e2481a-3fa1-4f2f-a7b6-7879c675701d
|
# ╠═62e2481a-3fa1-4f2f-a7b6-7879c675701d
|
||||||
|
@ -460,9 +633,9 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
||||||
# ╠═eb836cdc-de12-430c-a6f3-1524ebd28865
|
# ╠═eb836cdc-de12-430c-a6f3-1524ebd28865
|
||||||
# ╠═7e75da58-f110-41cb-ab19-79376370965f
|
# ╠═7e75da58-f110-41cb-ab19-79376370965f
|
||||||
# ╠═6b417e5d-01c2-4b06-9708-62c422a6b64b
|
# ╠═6b417e5d-01c2-4b06-9708-62c422a6b64b
|
||||||
# ╠═b621819d-6ce3-41e1-9e61-3ad0a2c9b016
|
|
||||||
# ╠═0174178f-3ed9-4890-8482-714cb51a635d
|
# ╠═0174178f-3ed9-4890-8482-714cb51a635d
|
||||||
# ╠═d29338b3-3c25-4ae4-90d0-1176538c635e
|
# ╠═d29338b3-3c25-4ae4-90d0-1176538c635e
|
||||||
|
# ╠═097b1b98-8b98-4160-bf31-d982f21ab8d6
|
||||||
# ╠═2430f309-be28-4bc2-9692-92489c31f7b2
|
# ╠═2430f309-be28-4bc2-9692-92489c31f7b2
|
||||||
# ╟─c7e76680-571e-427d-a564-8819df8b3750
|
# ╟─c7e76680-571e-427d-a564-8819df8b3750
|
||||||
# ╟─00000000-0000-0000-0000-000000000001
|
# ╟─00000000-0000-0000-0000-000000000001
|
||||||
|
|
Loading…
Reference in a new issue