What do you think is the next thing to work on?
OK, putting it all together and a bit of prettier formatting we have now:
using DataFrames
ledger=DataFrame(
date=[],
chequing=[],
expenses=[],
income=[]);
function ledgertransaction(
date,
credit_account,
credit_amount,
debit_account,
debit_amount
)
if length(date) == 0
return (false,"Error -- no date entered")
elseif !( credit_account in names(ledger) )
return (false, "Error -- credit account not found.")
elseif !( debit_account in names(ledger) )
return (false, "Error -- debit account not found")
elseif credit_amount-debit_amount != 0
return (false,"Error -- credit and debit must match." )
else
default_values=Dict("chequing"=>0,"expenses"=>0,"income"=>0)
spec = Dict(
"date" => date,
credit_account => credit_amount,
debit_account => debit_amount)
row = merge(default_values, spec)
push!(ledger,row)
return (true, "there are no errors")
end
end
ledgertransaction("Jan 1, 2000","expenses",100,"chequing",100)
You should use these code lines for the further steps.
Well done so far!
Letās take a short break here: Itās important that you understand those issues. What we have learned so far helps to create code which is easy to read. Not for others but at first for you. You need to have readable code for yourself to always see, whats going on. Doing this lets you focus on the important things in coding: the real problems.
I am not sure, if you enjoy those lessons. Of course you are always free to stop this. It only makes sense if you have some fun going through all this!
Now, we have a single one left:
If ledger
is local, that means, it is not available currently inside ledgertransaction
, so the function would produce an error. How can we overcome this?
Hmmmm, the ledger canāt be inside the function,because it would recreate the DataFrame anew, and not save the wanted information.
Iām thinking that if there was a function to create the ledger, that was called inside the transaction function, then the variable ledger would be local. Am I on the right track?
Its, again, easier.
why not doing this?
function ledgertransaction( ledger, date, credit_account, credit_amount, debit_account, debit_amount )
Where does this go? do I have to have something inside?
You provide ledger
as a parameter?
Ask, if there is something unclear!
Iām not familiar with parameters.
Thatās not a question, but anyways. functions have parameters. When you call a function you provide values to the function as parameters. See Functions Ā· The Julia Language
Well itās arguments, not parameters, sorry.
So the idea is just, that we provide ledger
as an argument to the function.
Arrays ( and DataFrames) are passed to the function as a reference. So the argument ledger
is the same as our āglobalā ledger
when we pass it as argument to the function.
Like:
julia> function test(array)
array[1]=2
end
test (generic function with 1 method)
julia> a=[1]
1-element Vector{Int64}:
1
julia> test(a)
2
julia> a
1-element Vector{Int64}:
2
Array a
is changed by the function.
If functions change their arguments the convention is to name the function with ! :
julia> function test!(array)
array[1]=2
end
Can you transfer this information into a new ledgertransaction
function?
function ledgertransaction( ledger, date, credit_account, credit_amount, debit_account, debit_amount )
ledger=DataFrame(
date=[],
#Assets
chequing=[],
#Expenses
expenses=[],
#Revenue
income=[]);
end
You donāt need any ledger1
.
Whatās your motivation for this?
I was testing things, and I forgot I did that.
function ledgertransaction!(
date,
credit_account,
credit_amount,
debit_account,
debit_amount
)
default_values=Dict("chequing"=>0,"expenses"=>0,"income"=>0)
spec = Dict(
"date" => date,
credit_account => credit_amount,
debit_account => debit_amount)
row = merge(default_values, spec)
push!(ledger,row)
end
Why did you create your own package, to manage decimals?
We are not yet at the milestone 1.
A note: A function name which ends with an ! is a convention (Style Guide Ā· The Julia Language) and denotes function, which modify one or all of their arguments.
We enforce the globale ledger to be local with:
local ledger=DataFrame(...
The complete current code is than:
using DataFrames
local ledger=DataFrame(
date=[],
chequing=[],
expenses=[],
income=[]);
function ledgertransaction(
date,
credit_account,
credit_amount,
debit_account,
debit_amount
)
if length(date) == 0
return (false,"Error -- no date entered")
elseif !( credit_account in names(ledger) )
return (false, "Error -- credit account not found.")
elseif !( debit_account in names(ledger) )
return (false, "Error -- debit account not found")
elseif credit_amount-debit_amount != 0
return (false,"Error -- credit and debit must match." )
else
default_values=Dict("chequing"=>0,"expenses"=>0,"income"=>0)
spec = Dict(
"date" => date,
credit_account => credit_amount,
debit_account => debit_amount)
row = merge(default_values, spec)
push!(ledger,row)
return (true, "there are no errors")
end
end
ledgertransaction("Jan 1, 2000","expenses",100,"chequing",100)
Now you should get an error, hopefully in Pluto too.
Your task is now to overcome this error only by changing the definition of the function ledgertransaction
. Hint: you donāt need to change the code of the function, only itās arguments (and the name by above convention).
Recommended readings are Scope of Variables Ā· The Julia Language and Functions Ā· The Julia Language .