我使用 beancount 记账流程中的有一步是这样的,将每张信用卡的账单日添加到滴答清单中,每月重复。
每当到达账单日时,提醒我在 beancount 文件中添加一条对应帐目的 balance 断言语句,由于大部分信用卡
的出账是有滞后的,所以该balance断言通常需要同时加上!
标记,便于后续账单出来后修改。
这个过程是比较机械的,所以我想到了使用 chatGPT 来自动化这个过程,这样我只需要在出账后手动更新自动添加
的断言语句,将金额修改为正确的还款金额,同时去除!
标记。最终的脚本如下。
import datetime
def add_balance_statement(ledger_path, account, date, balance, currency):
with open(ledger_path, 'a') as file:
file.write(f"{date} balance {account} {balance} {currency}\n")
def auto_add_balance_statements(ledger_path, credit_cards):
today = datetime.date.today()
for card in credit_cards:
bill_date = card['bill_date']
accounts = card['accounts']
balance = card['balance']
currency = card['currency']
if today.day == bill_date:
for account in accounts:
add_balance_statement(ledger_path, account, today, balance, currency)
print(f"Balance statement added for {account} on {today}.")
# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"
# Specify your credit card details (bill date, accounts, balance, and currency)
credit_cards = [
{
'bill_date': 1, # Example: 1st of the month
'accounts': [
{'account': 'Assets:CreditCards:Card1:Account1', 'currency': 'USD'}, # Example: Account1 for Card1 with USD currency
{'account': 'Assets:CreditCards:Card1:Account2', 'currency': 'EUR'}, # Example: Account2 for Card1 with EUR currency
],
'balance': 1000.00, # Example: Current balance for Card1
'currency': 'USD' # Example: Currency for Card1
},
{
'bill_date': 15, # Example: 15th of the month
'accounts': [
{'account': 'Assets:CreditCards:Card2:Account1', 'currency': 'USD'}, # Example: Account1 for Card2 with USD currency
{'account': 'Assets:CreditCards:Card2:Account2', 'currency': 'GBP'}, # Example: Account2 for Card2 with GBP currency
],
'balance': 2000.00, # Example: Current balance for Card2
'currency': 'USD' # Example: Currency for Card2
},
# Add more credit card details as needed
]
# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)
对于有兴趣的读者,可以看我和 chatgpt 的几轮对话。
Q: Write a python script, it check today’s date, if it match a specific day in a month, writing some content to a file, whois path is <path>
.
A: Certainly! Here’s a Python script that checks if today’s date matches a specific day in a month and writes some content to a file:
import datetime
def write_content_to_file(path, content):
with open(path, 'a') as file:
file.write(content + '\n')
def check_and_write_content(path, day, month, content):
today = datetime.date.today()
if today.day == day and today.month == month:
write_content_to_file(path, content)
print("Content written to the file.")
else:
print("Today's date does not match the specified day.")
# Specify the path, day, month, and content
file_path = "<path>"
day = 15
month = 7
content = "This is the content to be written."
# Call the function to check and write content
check_and_write_content(file_path, day, month, content)
In the script above, you need to replace "<path>"
with the actual path to the file where you want to write the content. Also, specify the day
, month
, and content
variables according to your requirements.
The script checks if today’s date matches the specified day and month. If it does, it calls the write_content_to_file
function to append the content to the file. If the date doesn’t match, it prints a message indicating that today’s date doesn’t match the specified day.
Q:I have many credit cards, each card have different bill date. I want a python script can auto add a balance statement to my beancount ledger. please help me writing this script. A:Certainly! Here’s a Python script that can help you automatically add a balance statement to your Beancount ledger based on the bill dates of your credit cards:
import datetime
def add_balance_statement(ledger_path, account, date, balance):
with open(ledger_path, 'a') as file:
file.write(f"{date} balance {account} {balance}\n")
def auto_add_balance_statements(ledger_path, credit_cards):
today = datetime.date.today()
for card in credit_cards:
bill_date = card['bill_date']
account = card['account']
balance = card['balance']
if today.day == bill_date:
add_balance_statement(ledger_path, account, today, balance)
print(f"Balance statement added for {account} on {today}.")
# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"
# Specify your credit card details (bill date, account, and balance)
credit_cards = [
{
'bill_date': 1, # Example: 1st of the month
'account': 'Assets:CreditCards:Card1', # Example: Account for Card1
'balance': 1000.00 # Example: Current balance for Card1
},
{
'bill_date': 15, # Example: 15th of the month
'account': 'Assets:CreditCards:Card2', # Example: Account for Card2
'balance': 2000.00 # Example: Current balance for Card2
},
# Add more credit card details as needed
]
# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)
In the script above, you need to replace "<ledger_path>"
with the actual path to your Beancount ledger file. Also, specify the bill_date
, account
, and balance
for each of your credit cards in the credit_cards
list.
The script checks if today’s date matches the bill date for each credit card. If it does, it calls the add_balance_statement
function to add a balance statement to the ledger file. The balance statement includes the account, date, and balance for the credit card. If the date doesn’t match the bill date for a particular credit card, it moves on to the next card.
Q:one bill_date can have multiple accounts, refine your code. A:Certainly! Here’s an updated version of the script that allows multiple accounts for a single bill date:
import datetime
def add_balance_statement(ledger_path, account, date, balance):
with open(ledger_path, 'a') as file:
file.write(f"{date} balance {account} {balance}\n")
def auto_add_balance_statements(ledger_path, credit_cards):
today = datetime.date.today()
for card in credit_cards:
bill_date = card['bill_date']
accounts = card['accounts']
balance = card['balance']
if today.day == bill_date:
for account in accounts:
add_balance_statement(ledger_path, account, today, balance)
print(f"Balance statement added for {account} on {today}.")
# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"
# Specify your credit card details (bill date, accounts, and balance)
credit_cards = [
{
'bill_date': 1, # Example: 1st of the month
'accounts': [
'Assets:CreditCards:Card1:Account1', # Example: Account1 for Card1
'Assets:CreditCards:Card1:Account2', # Example: Account2 for Card1
],
'balance': 1000.00 # Example: Current balance for Card1
},
{
'bill_date': 15, # Example: 15th of the month
'accounts': [
'Assets:CreditCards:Card2:Account1', # Example: Account1 for Card2
'Assets:CreditCards:Card2:Account2', # Example: Account2 for Card2
],
'balance': 2000.00 # Example: Current balance for Card2
},
# Add more credit card details as needed
]
# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)
In this updated version, each credit card in the credit_cards
list has a bill_date
, accounts
, and balance
. The accounts
field is a list of all the accounts associated with that credit card. The script iterates through each credit card and its associated accounts. If today’s date matches the bill date, it adds a balance statement for each account with the specified balance.
Please replace "<ledger_path>"
with the actual path to your Beancount ledger file. Also, update the credit card details in the credit_cards
list according to your specific accounts and balances.
Q:different accounts can have different currency, please add currency info to account. A:Certainly! Here’s an updated version of the script that includes currency information for each account:
import datetime
def add_balance_statement(ledger_path, account, date, balance, currency):
with open(ledger_path, 'a') as file:
file.write(f"{date} balance {account} {balance} {currency}\n")
def auto_add_balance_statements(ledger_path, credit_cards):
today = datetime.date.today()
for card in credit_cards:
bill_date = card['bill_date']
accounts = card['accounts']
balance = card['balance']
currency = card['currency']
if today.day == bill_date:
for account in accounts:
add_balance_statement(ledger_path, account, today, balance, currency)
print(f"Balance statement added for {account} on {today}.")
# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"
# Specify your credit card details (bill date, accounts, balance, and currency)
credit_cards = [
{
'bill_date': 1, # Example: 1st of the month
'accounts': [
{'account': 'Assets:CreditCards:Card1:Account1', 'currency': 'USD'}, # Example: Account1 for Card1 with USD currency
{'account': 'Assets:CreditCards:Card1:Account2', 'currency': 'EUR'}, # Example: Account2 for Card1 with EUR currency
],
'balance': 1000.00, # Example: Current balance for Card1
'currency': 'USD' # Example: Currency for Card1
},
{
'bill_date': 15, # Example: 15th of the month
'accounts': [
{'account': 'Assets:CreditCards:Card2:Account1', 'currency': 'USD'}, # Example: Account1 for Card2 with USD currency
{'account': 'Assets:CreditCards:Card2:Account2', 'currency': 'GBP'}, # Example: Account2 for Card2 with GBP currency
],
'balance': 2000.00, # Example: Current balance for Card2
'currency': 'USD' # Example: Currency for Card2
},
# Add more credit card details as needed
]
# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)
In this updated version, each account in the accounts
list of each credit card includes both the account
name and the currency
. The add_balance_statement
function is modified to include the currency
parameter when writing the balance statement to the ledger.
Please replace "<ledger_path>"
with the actual path to your Beancount ledger file. Also, update the credit card details in the credit_cards
list according to your specific accounts, balances, and currencies.