Skip to content

Commit

Permalink
Finished lecture_05
Browse files Browse the repository at this point in the history
  • Loading branch information
VaclavMacha committed Mar 22, 2021
1 parent 49fe3d1 commit d160d2b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 17 deletions.
2 changes: 1 addition & 1 deletion docs/src/lecture_03/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions docs/src/lecture_05/compositetypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down
21 changes: 8 additions & 13 deletions docs/src/lecture_05/currencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -336,7 +336,6 @@ struct Pound <: Currency
end
symbol(::Type{Pound}) = "£"
rate(::Type{Euro}, ::Type{Pound}) = 1.13
# output
Expand Down Expand Up @@ -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)
Expand All @@ -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)...)
Expand Down Expand Up @@ -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))
Expand All @@ -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č
```
Expand Down

0 comments on commit d160d2b

Please sign in to comment.