From d160d2b8e10527464db268cd47c40371b986c01f Mon Sep 17 00:00:00 2001 From: VaclavMacha Date: Mon, 22 Mar 2021 22:31:32 +0100 Subject: [PATCH] Finished lecture_05 --- docs/src/lecture_03/functions.md | 2 +- docs/src/lecture_05/compositetypes.md | 6 +++--- docs/src/lecture_05/currencies.md | 21 ++++++++------------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/src/lecture_03/functions.md b/docs/src/lecture_03/functions.md index 47a0bb9e7..7ddd7ab5a 100644 --- a/docs/src/lecture_03/functions.md +++ b/docs/src/lecture_03/functions.md @@ -449,7 +449,7 @@ The probability density function for the Gaussian distribution equals to ```jldoctest key_args_ex; output = false function gauss(x::Real; μ::Real = 0, σ::Real = 1) - σ > 0 || error("the variance `σ^2` must be positive") + σ^2 > 0 || error("the variance `σ^2` must be positive") return exp(-1/2 * ((x - μ)/σ)^2)/(σ * sqrt(2*π)) end diff --git a/docs/src/lecture_05/compositetypes.md b/docs/src/lecture_05/compositetypes.md index ae3832138..7b4724033 100644 --- a/docs/src/lecture_05/compositetypes.md +++ b/docs/src/lecture_05/compositetypes.md @@ -6,7 +6,7 @@ Julia does not allow abstract types to be instantiated. They can only be used to All types depicted in blue are abstract types, and all green types are concrete types. For example, `Int8`, `Int16`, `Int32`, `Int64` and `Int128` are signed integer types, `UInt8`, `UInt16`, `UInt32`, `UInt64` and `UInt128` are unsigned integer types, while `Float16`, `Float32` and `Float64` are floating-point types. In many cases, the inputs must be of a specific type. An algorithm to find the greatest common denominator should work any integer types, but it should not work for any floating-point inputs. Abstract types specify these cases and provide a context into which concrete types can fit. -Abstract types are defined by `abstract type` followed by the type. It is possible to specify a type to be a subtype of another abstract type. The definition of abstract numeric types would be: +Abstract types are defined by `abstract type` followed by the type name. It is possible to specify a type to be a subtype of another abstract type. The definition of abstract numeric types would be: ```julia abstract type Number end @@ -480,8 +480,8 @@ For example, one may want to create a type with two real numbers, where the firs ```jldoctest ordered; output = false struct OrderedPair{T <: Real} - x::Real - y::Real + x::T + y::T function OrderedPair(x::Real, y::Real) x > y && error("the first argument must be less than or equal to the second one") diff --git a/docs/src/lecture_05/currencies.md b/docs/src/lecture_05/currencies.md index c2fb119e5..6640a5c94 100644 --- a/docs/src/lecture_05/currencies.md +++ b/docs/src/lecture_05/currencies.md @@ -58,9 +58,9 @@ BankAccount{Euro}("Paul", Currency[Euro(0.0)]) First, we observe that we use the `Euro` type (and not its instance) to instantiate the `BankAccount` type. The reason is the definition of the inner constructor for `BankAccount`, where the type annotation is `::Type{<:Currency}`. This is in contrast with `::Currency`. The former requires that the argument is a type, while the former needs an instance. -Second, due to the line `Currency[C(0)]` in the inner constructor, transactions are stored in a vector of type `Vector{Currency}`. The expression `C(0)` creates an instance of the currency `C` with zero value. The `Currency` type combined with the square brackets creates a vector that may contain instances of any subtypes of `Currency`. It is, therefore, possible to push a new transaction in a different currency to the `transaction` field. +Second, `BankAccount` is a parametric type, as can be seen from `BankAccount{Euro}`. In our example, this parameter plays the role of the primary account currency. -Third, `BankAccount` is a parametric type, as can be seen from `BankAccount{Euro}`. In our example, this parameter plays the role of the primary account currency. +Third, due to the line `Currency[C(0)]` in the inner constructor, transactions are stored in a vector of type `Vector{Currency}`. The expression `C(0)` creates an instance of the currency `C` with zero value. The `Currency` type combined with the square brackets creates a vector that may contain instances of any subtypes of `Currency`. It is, therefore, possible to push a new transaction in a different currency to the `transaction` field. ```jldoctest currency julia> push!(b.transaction, Dollar(2)) @@ -336,7 +336,6 @@ struct Pound <: Currency end symbol(::Type{Pound}) = "£" - rate(::Type{Euro}, ::Type{Pound}) = 1.13 # output @@ -704,7 +703,7 @@ julia> 2 .* CzechCrown.([4.5, 2.4, 16.7, 18.3]) .* 0.5 18.3 Kč ``` -Finally, we can define division. In this case, it makes sense to define the division of the instance of any `Currency` subtype by a real number. In such a case, the result is the instance of the same currency. +Finally, we can define division. In this case, it makes sense to define the division of the currency by a real number. In such a case, the result is the instance of the same currency. ```jldoctest currency; output=false Base.:/(x::T, a::Real) where {T <: Currency} = T(x.value / a) @@ -713,7 +712,7 @@ Base.:/(x::T, a::Real) where {T <: Currency} = T(x.value / a) ``` -But it also makes sense to define the division of one amount of money by another amount of money. In this case, a result is a real number representing the ratio of the given amounts of money. +But it also makes sense to define the division of one amount of money by another amount of money in different currencies. In this case, a result is a real number representing their ratio. ```jldoctest currency; output=false Base.:/(x::Currency, y::Currency) = /(promote(x, y)...) @@ -826,14 +825,7 @@ julia> sort(vals) ## Back to bank account -In the previous sections, we defined all the functions and types needed for the `BankAccount` type's proper functionality at the top of the page. We can test it by creating a new instance of this type. - -```jldoctest currency -julia> b = BankAccount("Paul", CzechCrown) -BankAccount{CzechCrown}("Paul", Currency[0.0 Kč]) -``` - -Now it is time to define some auxiliary functions. For example, we can define the `balance` function that will return the account's current balance. Since we store all transactions in a vector, the account's current balance can be simply computed as a sum of the `transaction` field. +In the previous sections, we defined all the functions and types that allow us to define the `BankAccount` type and perform basic arithmetic and other operations on currencies. We can test it by creating a new instance of this type. Now it is time to define some auxiliary functions. For example, we can define the `balance` function that will return the account's current balance. Since we store all transactions in a vector, the account's current balance can be simply computed as a sum of the `transaction` field. ```jldoctest currency; output=false balance(b::BankAccount{C}) where {C} = convert(C, sum(b.transaction)) @@ -846,6 +838,9 @@ balance (generic function with 1 method) Note that we convert the balance to the primary currency of the account. ```jldoctest currency +julia> b = BankAccount("Paul", CzechCrown) +BankAccount{CzechCrown}("Paul", Currency[0.0 Kč]) + julia> balance(b) 0.0 Kč ```