Thank you
knackwurstbagel for your help and guidance so far.
The latest iteration of my script can be found at the bottom of this post. When I import it, instantiate, and perform a few deposits in my REPL, here is the output:
$ bpython
bpython version 0.22.1 on top of Python 3.10.2 /usr/bin/python
>>> import script
>>> BA = script.Account('Winston', 'Smith')
The date and time: 2022-03-14 13:18:01 MDT-0600
The date and time condensed: 20220314131801
>>> print(BA.deposit(100))
D-1400-20220314131801-1
None
>>> print(BA.deposit(100))
D-1400-20220314131801-2
None
>>> print(BA.deposit(100))
D-1400-20220314131801-3
None
>>> print(BA.deposit(100))
D-1400-20220314131801-4
None
Next in my REPL I enter your recommended two functions:
>>> def is_dunder(property):
... return True if property[:2] == '__' else False
...
...
>>> def print_properties(obj):
... [print(prop) for prop in dir(obj) if not is_dunder(prop)]
...
...
>>> print_properties(BA)
account_num
balance
deposit
first_name
full_name
interest
last_name
pay_interest
transaction_id
tzone
withdraw
So far, so good. That makes sense. Your
print_properties()
function behaves as you describe. All the class properties that are not dunders are printed out in a list that you have achieved with list comprehension.
What comes next kind of throws me off:
>>> is_dunder(BA)
Traceback (most recent call last):
File "<input>", line 1, in <module>
is_dunder(BA)
File "<input>", line 2, in is_dunder
return True if property[:2] == '__' else False
TypeError: 'Account' object is not subscriptable
>>> is_dunder(last_name)
Traceback (most recent call last):
File "<input>", line 1, in <module>
is_dunder(last_name)
NameError: name 'last_name' is not defined
>>> is_dunder(self.last_name)
Traceback (most recent call last):
File "<input>", line 1, in <module>
is_dunder(self.last_name)
NameError: name 'self' is not defined
>>>
When calling
is_dunder()
on various properties and objects, the Python REPL just says: “object not subscriptable” or “is not defined”. Is this expected?
By the way, if I am not mistaken, I believe
property
is a reserved keyword in Python so this partially threw me off in the beginning, but now that the
print_properties()
function works, I think I understand.
Here is my script:
from datetime import datetime
from pytz import timezone
class TimeZone:
def __init__(self, locality='US/Mountain'):
self.tz = datetime.now(timezone(locality))
self.readable_format = '%Y-%m-%d %H:%M:%S %Z%z'
print(f'The date and time: {self.tz.strftime(self.readable_format)}')
self.transaction_time_id_format = '%Y%m%d%H%M%S'
print(f'The date and time condensed: {self.tz.strftime(self.transaction_time_id_format)}')
def condensed(self):
return f'{self.tz.strftime(self.transaction_time_id_format)}'
class Account:
interest = 0.005 # Percent
def __init__(self, first_name, last_name, account_num=1400, starting_balance=0.00):
self.first_name = first_name
self.last_name = last_name
self.full_name = f'{first_name} {last_name}'
self.account_num = account_num
self.balance = starting_balance
self.transaction_id = 0
self.tzone = TimeZone()
def deposit(self, amount):
self.balance += amount
self.transaction_id += 1
print(f'D-{self.account_num}-{self.tzone.condensed()}-{self.transaction_id}')
def withdraw(self, amount):
if amount > self.balance:
self.transaction_id += 1
print(f'X-{self.account_num}-{self.tzone.condensed()}-{self.transaction_id}')
raise ValueError('Transaction declined. Insufficient funds. Please deposit some more $$$ first.')
self.balance -= amount
self.transaction_id += 1
print(f'W-{self.account_num}-{self.tzone.condensed()}-{self.transaction_id}')
def pay_interest(self):
monthly_rate = self.interest/12
monthly_sum = monthly_rate * self.balance
self.transaction_id += 1
print(f'I-{self.account_num}-{self.tzone.condensed()}-{self.transaction_id}')
return monthly_sum + self.balance
def __repr__(self):
"""Return a string that represents the account."""
return f"{self.__class__.__name__}({self.last_name}, {self.first_name}, balance={self.balance})"