Use a String For a Variable name and convert Dictionaries to DataFrames

Here’s a way to do it for what I understood of the task:

using DataFrames

# Initialize accounts data frame with one row
accounts = DataFrame(
    Chequing_debit=[100], Chequing_credit=[0],
    Wages_debit=[0], Wages_credit=[100],
    Sales_debit=[0], Sales_credit=[0],
    Rent_debit=[0], Rent_credit=[0],
    Personal_debit=[0], Personal_credit=[0],
    Inputs_debit=[0], Inputs_credit=[0],
    Ducks_debit=[0], Ducks_credit=[0],
)

# Initialize journal with 4 rows
journal = DataFrame(Date=["Jan 1, 2000" for _ in 1:4],
                    Debited_account=["Chequing", "", "", ""],
                    Credited_account=["", "Personal", "Inputs", "Ducks"],
                    Debit=[100, 0, 0, 0],
                    Credit=[0, 10, 20, 70],
)

The initial data frames look like this:

accounts:

 Row │ Chequing_debit  Chequing_credit  Wages_debit  Wages_credit  Sales_debit  Sales_credit  Rent_debit  Rent_credit  Personal_debit  Personal_credit  Inpu ⋯
     │ Int64           Int64            Int64        Int64         Int64        Int64         Int64       Int64        Int64           Int64            Int6 ⋯
─────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │            100                0            0           100            0             0           0            0               0                0       ⋯

journal:

 Row │ Date         Debited_account  Credited_account  Debit  Credit 
     │ String       String           String            Int64  Int64  
─────┼───────────────────────────────────────────────────────────────
   1 │ Jan 1, 2000  Chequing                             100       0
   2 │ Jan 1, 2000                   Personal              0      10
   3 │ Jan 1, 2000                   Inputs                0      20
   4 │ Jan 1, 2000                   Ducks                 0      70

Now a function to add a transaction:

function transaction!(date, debit_account, debit_amount, credit_account, credit_amount)
    if debit_amount != credit_amount
        error("Debit ($debit_amount) and credit ($credit_amount) must match")
    end

    # Prepare row as named tuple, starting with zero values overwritten by values for the specified accounts
    new_row = (; (Symbol.(names(accounts)) .=> 0)...,
                 Symbol(debit_account, "_debit") => debit_amount,
                 Symbol(credit_account, "_credit") => credit_amount)
    push!(accounts, new_row)

    push!(journal, (; Date=date, Debited_account=debit_account, Credited_account=credit_account,
                      Debit=debit_amount, Credit=credit_amount))
end

Test the function:

julia> transaction!("Jan 1, 2019", "Wages", 1000, "Chequing", 1000)
5×5 DataFrame
 Row │ Date         Debited_account  Credited_account  Debit  Credit 
     │ String       String           String            Int64  Int64  
─────┼───────────────────────────────────────────────────────────────
   1 │ Jan 1, 2000  Chequing                             100       0
   2 │ Jan 1, 2000                   Personal              0      10
   3 │ Jan 1, 2000                   Inputs                0      20
   4 │ Jan 1, 2000                   Ducks                 0      70
   5 │ Jan 1, 2019  Wages            Chequing           1000    1000

Note: this is all with integers… maybe you want to create the data frames with another number type.

4 Likes