aboutsummaryrefslogtreecommitdiff
path: root/utils/sort.py
diff options
context:
space:
mode:
authorAdrián Oliva <adrian.oliva@cimat.mx>2023-05-07 00:17:58 -0600
committerAdrián Oliva <adrian.oliva@cimat.mx>2023-05-07 00:17:58 -0600
commit03304074913aaf5cfc05de8ffc00f66823896e50 (patch)
treef89174ca7e4f3352315857c3e2f6962cc48e1fec /utils/sort.py
parent4875c36a055ea89118e665bdd8b3d0148b112307 (diff)
downloadLedger.py-03304074913aaf5cfc05de8ffc00f66823896e50.tar.gz
Ledger.py-03304074913aaf5cfc05de8ffc00f66823896e50.zip
First attempt at sorting.
We can only sort by date and amount right now. I don't know if there are other important ways of sorting. D:
Diffstat (limited to '')
-rw-r--r--utils/sort.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/utils/sort.py b/utils/sort.py
new file mode 100644
index 0000000..2e7f15a
--- /dev/null
+++ b/utils/sort.py
@@ -0,0 +1,118 @@
+from utils.read_file import entry
+from typing import List
+from utils.register import complete_prices
+
+
+def separate_currencies(my_entries: List[entry]):
+ """
+ Given a list of entries with just one transaction, group entries with
+ respect to their currencies symbols.
+ """
+ seen_curr = set()
+ list_curr = []
+
+ # First search for every currency we can find in `my_entries`.
+ for ent in my_entries:
+ for trans in ent.transactions:
+ wallet = trans[1]
+
+ if len(wallet.money.keys()) != 1:
+ raise Exception('Cannot compare more than one currency at a time.')
+
+ for curr in wallet.money.keys():
+ break
+
+ if curr not in seen_curr:
+ seen_curr.add(curr)
+ list_curr.append(curr)
+
+ # Now group each currency. Select a currency and append entries that have
+ # that specific currency. Then select the next seen currency and so on.
+ result = []
+ for my_currency in list_curr:
+ for ent in my_entries:
+ wallet = ent.transactions[0][1]
+
+ for curr in wallet.money.keys():
+ break
+
+ if my_currency == curr:
+ result.append(ent)
+
+ return result
+
+
+def join_concurrent_entries(my_entries: List[entry]):
+ result = []
+ for ent in my_entries:
+ if len(result) == 0:
+ result.append(ent)
+
+ elif ent.comment == result[-1].comment and ent.date == result[-1].date:
+ result[-1].transactions.append(
+ ent.transactions[0]
+ )
+
+ else:
+ result.append(ent)
+
+ return result
+
+
+def sort_by_date(my_entries: List[entry]):
+ my_entries.sort(key=lambda x: x.date)
+
+
+def sort_by_amount(my_entries: List[entry]):
+ """
+ We have to break entries by their transactions. Then we can sort the
+ entries by their amount in their unique transaction.
+ """
+
+ # Break entries for them to have only one transaction.
+ result = []
+ for ent in my_entries:
+ complete_prices(ent)
+
+ for trans in ent.transactions:
+ result.append(
+ entry(
+ date=ent.date.strftime('%Y/%m/%d'),
+ comment=ent.comment,
+ transactions=[trans]
+ )
+ )
+ # Sort each transaction given the amount value.
+ result.sort(key=lambda x: x.transactions[0][1])
+ # Separate different currencies from each other.
+ result = separate_currencies(result)
+ # Join concurrent entries if they have the same comment and date.
+ result = join_concurrent_entries(result)
+
+ # Hacky way of modifying the original `my_entries` list.
+ while my_entries:
+ my_entries.pop()
+ for item in result:
+ my_entries.append(item)
+
+ # Each transaction now has the `currencies` class format. Convert all of
+ # them into strings.
+ for ent in my_entries:
+ for trans in ent.transactions:
+ for price in trans[1]:
+ break
+
+ trans[1] = price
+
+
+def sort_entries(my_entries: List[entry], rule: str) -> None:
+ """
+ Sort the list of entries in-place. This function returns None, the list
+ given as a parameter will be modified.
+ """
+ # Sort by date.
+ if rule.lower() in ['d', 'date']:
+ sort_by_date(my_entries)
+ # Sort by amount.
+ if rule.lower() in ['a', 'amount']:
+ sort_by_amount(my_entries) \ No newline at end of file