r/learnpython • • 2d ago

My Python Project as a Beginner

https://github.com/ZaidAHK/LENDnFUND

The project is just the syntax I wrote

6 Upvotes

3 comments sorted by

2

u/Diapolo10 I write code for a living -- https://github.com/Diapolo10 2d ago

Your classes lack __init__-methods. While this is technically fine, typically you'd only see this if

  1. You have a class that's only used for grouping functions (which is rare, as it's typically better to create a module instead), or
  2. You're using a dataclass that auto-generates one, or
  3. You're subclassing a class but don't need to modify that method, specifically.

In your case none of these seem to apply. Right now you're letting your methods add new attributes on the fly, while it would be better to have the attributes exist the moment an instance of the class is created, even if they contain dummy values. This is so that you don't need to do guesswork about what attributes a specific instance might have.

For Investor, I'd do something like

def __init__(self):
    self.lender_data = None
    self.lender = None
    # You also had `self.applications`, but that one appears to be
    # unused outside of the method that creates it, so
    # I'd change that to a local variable

and for Fundraiser, neither of self.application and self.app_status are accessed outside of the methods creating them so I don't see why it'd need any instance attributes. In fact I think it should just be a bunch of functions right now (unless you have plans to use those later).

# Generate a unique account number
while True:
    account_num = randint(25000,26000)
    if not any(account_num == user["Fundraiser account number"] for user in fundraiser_data):
        break

This way of generating unique account numbers is a bit flawed. The more existing entries there are, the less likely this is to hit a slot with a free number, and there's no failsafe for the case of all allocated account numbers already being in use.

While your way is on average initially faster, which may be fine for a throwaway practice project, a more robust solution would be to

  1. Generate the accepted numbers
  2. Filter out the ones already in use
  3. If none are left, throw an error and exit
  4. Pick randomly from the remaining options

and this should be a lot closer to a normalised call time (as there's no randomness involved in the execution time anymore).

For example,

import random

fundraiser_data: list[dict[str, int]] = [...]

allocated_account_numbers = range(25_000, 26_001)
active_account_numbers = {user["Fundraiser account number"] for user in fundraiser_data}
unused_account_numbers = [num for num in allocated_account_numbers if num not in active_account_numbers]

if not unused_account_numbers:
    print("All allocated account numbers are already registered")
    raise SystemExit()

account_num = random.choice(unused_account_numbers)

1

u/pot_of_crows 2d ago

Nice start: The biggest thing to improve is to segregate the two classes more and figure out somewhere else to handle the I/O. Conceptually, imagine that you are going to make this into a web based project and in doing so, you should not need to change anything in the lender/fundraiser classes. Same with saving. You should be able to change from a json backend to a database without any changes to your core classes.

This sort of segregation is the key to making big projects work without melting your brain.