Convert most strings to fstrings for readability

Some are kept as-is because they wouldn't be more readable, or do insanity that i cannot bother deciphering right now
This commit is contained in:
Robert Maikher 2018-08-23 13:15:45 +02:00
parent 068015a972
commit d5475b834f
9 changed files with 128 additions and 118 deletions

9
db.py
View File

@ -32,7 +32,7 @@ class User(Base):
self.credit = credit
def __repr__(self):
return "<User('%s')>" % self.name
return f"<User('{self.name}')>"
def __str__(self):
return self.name
@ -63,8 +63,7 @@ class Product(Base):
self.hidden = hidden
def __repr__(self):
return "<Product('%s', '%s', '%s', '%s', '%s')>" %\
(self.name, self.bar_code, self.price, self.stock, self.hidden)
return f"<Product('{self.name}', '{self.bar_code}', '{self.price}', '{self.stock}', '{self.hidden}')>"
def __str__(self):
return self.name
@ -97,7 +96,7 @@ class PurchaseEntry(Base):
self.amount = amount
def __repr__(self):
return "<PurchaseEntry('%s', '%s')>" % (self.product.name, self.amount)
return f"<PurchaseEntry('{self.product.name}', '{self.amount}')>"
class Transaction(Base):
@ -141,7 +140,7 @@ class Purchase(Base):
pass
def __repr__(self):
return "<Purchase(%d, %d, '%s')>" % (int(self.id), self.price, self.time.strftime('%c'))
return f"<Purchase({int(self.id):d}, {self.price:d}, '{self.time.strftime('%c')}')>"
def is_complete(self):
return len(self.transactions) > 0 and len(self.entries) > 0

View File

@ -5,30 +5,30 @@ import subprocess
import os
import signal
def search_user(string, session, ignorethisflag=None):
string = string.lower()
exact_match = session.query(User).filter(or_(User.name==string, User.card==string, User.rfid==string)).first()
def search_user(str, session, ignorethisflag=None):
str = str.lower()
exact_match = session.query(User).filter(or_(User.name == str, User.card == str, User.rfid == str)).first()
if exact_match:
return exact_match
user_list = session.query(User).filter(or_(User.name.ilike('%'+string+'%'),
User.card.ilike('%'+string+'%'),
User.rfid.ilike('%'+string+'%'))).all()
user_list = session.query(User).filter(or_(User.name.ilike(f'%{str}%'),
User.card.ilike(f'%{str}%'),
User.rfid.ilike(f'%{str}%'))).all()
return user_list
def search_product(string, session, find_hidden_products=True):
def search_product(str, session, find_hidden_products=True):
if find_hidden_products:
exact_match = session.query(Product).filter(or_(Product.bar_code==string, Product.name==string)).first()
exact_match = session.query(Product).filter(or_(Product.bar_code == str, Product.name == str)).first()
else:
exact_match = session.query(Product).filter(or_(Product.bar_code==string,
and_(Product.name==string, Product.hidden == False))).first()
exact_match = session.query(Product).filter(or_(Product.bar_code == str,
and_(Product.name == str, Product.hidden == False))).first()
if exact_match:
return exact_match
if find_hidden_products:
product_list = session.query(Product).filter(or_(Product.bar_code.ilike('%'+string+'%'),
Product.name.ilike('%'+string+'%'))).all()
product_list = session.query(Product).filter(or_(Product.bar_code.ilike(f'%{str}%'),
Product.name.ilike(f'%{str}%'))).all()
else:
product_list = session.query(Product).filter(or_(Product.bar_code.ilike('%' + string + '%'),
and_(Product.name.ilike('%' + string + '%'),
product_list = session.query(Product).filter(or_(Product.bar_code.ilike(f'%{str}%'),
and_(Product.name.ilike(f'%{str}%'),
Product.hidden == False))).all()
return product_list

View File

@ -6,4 +6,4 @@ session=Session()
slabbedasker=session.query(User).filter(User.credit<0).all()
for slubbert in slabbedasker:
print("%s, %s" % (slubbert.name, slubbert.credit))
print(f"{slubbert.name}, {slubbert.credit}")

View File

@ -64,7 +64,7 @@ if __name__ == '__main__':
print('Interrupted.')
except:
print('Something went wrong.')
print('%s: %s' % (sys.exc_info()[0], sys.exc_info()[1]))
print(f'{sys.exc_info()[0]}: {sys.exc_info()[1]}')
if conf.show_tracebacks:
traceback.print_tb(sys.exc_info()[2])
else:

View File

@ -41,7 +41,7 @@ much money you're due in credits for the purchase when prompted.\n'''
(thing, amount) = line
if isinstance(thing, Product):
self.printc("%d of %s registered" % (amount, thing.name))
self.printc(f"{amount:d} of {thing.name} registered")
thing_price = self.input_int('What did you pay a piece? ', (1, 100000),
default=thing.price) * amount
self.price += thing_price
@ -65,6 +65,7 @@ much money you're due in credits for the purchase when prompted.\n'''
def complete_input(self):
return bool(self.users) and len(self.products) and self.price
# TODO: Rewrite this madness
def print_info(self):
print((6 + Product.name_length) * '-')
if self.price:
@ -72,7 +73,7 @@ much money you're due in credits for the purchase when prompted.\n'''
if self.users:
print("Users to credit:")
for user in self.users:
print(" %s" % str(user.name))
print(f" {str(user.name)}")
print("\n{{0:s}}{{1:>{0}s}}".format(Product.name_length-1).format("Product", "Amount"))
print((6 + Product.name_length) * '-')
if len(self.products):
@ -94,6 +95,7 @@ much money you're due in credits for the purchase when prompted.\n'''
print('Did you pay a different price?')
if self.confirm('>', default=False):
price = self.input_int('How much did you pay?', default=self.price)
# TODO: Loop until we get a valid answer instead of assuming default
if price > self.price:
print('Illegal action, total can not be higher than your total.')
else:
@ -109,9 +111,9 @@ much money you're due in credits for the purchase when prompted.\n'''
product.price = int(ceil(float(value) / (max(product.stock, 0) + self.products[product][0])))
product.stock = max(self.products[product][0], product.stock + self.products[product][0])
product.hidden = False
print("New stock for %s: %d" % (product.name, product.stock), \
("- New price: " + str(product.price) if old_price != product.price else ""), \
("- Removed hidden status" if old_hidden != product.hidden else ""))
print(f"New stock for {product.name}: {product.stock:d}",
f"- New price: {product.price}" if old_price != product.price else "",
"- Removed hidden status" if old_hidden != product.hidden else "")
purchase = Purchase()
for user in self.users:
@ -127,6 +129,6 @@ much money you're due in credits for the purchase when prompted.\n'''
print("Success! Transaction performed:")
# self.print_info()
for user in self.users:
print("User %s's credit is now %i" % (user.name, user.credit))
print(f"User {user.name}'s credit is now {user.credit:d}")
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not perform transaction: %s' % e)
print(f'Could not perform transaction: {e}')

View File

@ -49,7 +49,7 @@ When finished, write an empty line to confirm the purchase.\n'''
print("***********************************************************************")
print("***********************************************************************")
print("")
print("USER %s HAS LOWER CREDIT THAN %d." % (user.name, conf.low_credit_warning_limit))
print(f"USER {user.name} HAS LOWER CREDIT THAN {conf.low_credit_warning_limit:d}.")
print("THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH.")
print("CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS.")
print("")
@ -149,16 +149,16 @@ When finished, write an empty line to confirm the purchase.\n'''
try:
self.session.commit()
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store purchase: %s' % e)
print(f'Could not store purchase: {e}')
else:
print('Purchase stored.')
self.print_purchase()
for t in self.purchase.transactions:
if not t.user.is_anonymous():
print('User %s\'s credit is now %d kr' % (t.user.name, t.user.credit))
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
if t.user.credit < conf.low_credit_warning_limit:
print('USER %s HAS LOWER CREDIT THAN %d, AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.' \
% (t.user.name, conf.low_credit_warning_limit))
print(f'USER {t.user.name} HAS LOWER CREDIT THAN {conf.low_credit_warning_limit:d},',
'AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.')
return True
@ -183,15 +183,17 @@ When finished, write an empty line to confirm the purchase.\n'''
string += '(empty)'
else:
string += "\n "
string += '\n '.join(['%dx %s (%d kr)' % (e.amount, e.product.name, e.product.price) for e in entries])
string += '\n '.join([f'{e.amount:d}x {e.product.name} ({e.product.price:d} kr)' for e in entries])
if len(transactions) > 1:
string += '\n price per person: %d kr' % self.purchase.price_per_transaction()
string += f'\n price per person: {self.purchase.price_per_transaction():d} kr'
if any(t.penalty > 1 for t in transactions):
string += ' *(%d kr)' % (self.purchase.price_per_transaction() * 2)
# TODO: Use penalty multiplier instead of 2
string += f' *({self.purchase.price_per_transaction() * 2:d} kr)'
string += '\n total price: %d kr' % self.purchase.price
string += f'\n total price: {self.purchase.price:d} kr'
if any(t.penalty > 1 for t in transactions):
# TODO: Rewrite?
string += '\n *total with penalty: %d kr' % sum(
self.purchase.price_per_transaction() * t.penalty for t in transactions)

View File

@ -19,9 +19,9 @@ class AddUserMenu(Menu):
self.session.add(user)
try:
self.session.commit()
print('User %s stored' % username)
print(f'User {username} stored')
except sqlalchemy.exc.IntegrityError as e:
print('Could not store user %s: %s' % (username, e))
print(f'Could not store user {username}: {e}')
self.pause()
@ -38,27 +38,29 @@ user, then rfid (write an empty line to remove the card number or rfid).
def _execute(self):
self.print_header()
user = self.input_user('User> ')
self.printc('Editing user %s' % user.name)
card_str = '"%s"' % user.card
self.printc(f'Editing user {user.name}')
card_str = f'"{user.card}"'
if user.card is None:
card_str = 'empty'
# TODO: Inconsistent with other defaulted strings. Redo.
user.card = self.input_str('Card number (currently %s)> ' % card_str,
User.card_re, (0, 10),
empty_string_is_none=True)
if user.card:
user.card = user.card.lower()
rfid_str = '"%s"' % user.rfid
rfid_str = f'"{user.rfid}"'
if user.rfid is None:
rfid_str = 'empty'
user.rfid = self.input_str('RFID (currently %s)> ' % rfid_str,
# TODO: Inconsistent with other defaulted strings. Redo.
user.rfid = self.input_str(f'RFID (currently {rfid_str})> ',
User.rfid_re, (0, 10),
empty_string_is_none=True)
try:
self.session.commit()
print('User %s stored' % user.name)
print(f'User {user.name} stored')
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store user %s: %s' % (user.name, e))
print(f'Could not store user {user.name}: {e}')
self.pause()
@ -75,9 +77,9 @@ class AddProductMenu(Menu):
self.session.add(product)
try:
self.session.commit()
print('Product %s stored' % name)
print(f'Product {name} stored')
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store product %s: %s' % (name, e))
print(f'Could not store product {name}: {e}')
self.pause()
@ -88,9 +90,9 @@ class EditProductMenu(Menu):
def _execute(self):
self.print_header()
product = self.input_product('Product> ')
self.printc('Editing product %s' % product.name)
self.printc(f'Editing product {product.name}')
while True:
selector = Selector('Do what with %s?' % product.name,
selector = Selector(f'Do what with {product.name}?',
items=[('name', 'Edit name'),
('price', 'Edit price'),
('barcode', 'Edit barcode'),
@ -98,19 +100,19 @@ class EditProductMenu(Menu):
('store', 'Store')])
what = selector.execute()
if what == 'name':
product.name = self.input_str('Name[%s]> ' % product.name, Product.name_re, (1, product.name_length))
product.name = self.input_str(f'Name[{product.name}]> ', Product.name_re, (1, product.name_length))
elif what == 'price':
product.price = self.input_int('Price[%s]> ' % product.price, (1, 100000))
product.price = self.input_int(f'Price[{product.price}]> ', (1, 100000))
elif what == 'barcode':
product.bar_code = self.input_str('Bar code[%s]> ' % product.bar_code, Product.bar_code_re, (8, 13))
product.bar_code = self.input_str(f'Bar code[{product.bar_code}]> ', Product.bar_code_re, (8, 13))
elif what == 'hidden':
product.hidden = self.confirm('Hidden[%s]' % ("Y" if product.hidden else "N"), False)
elif what == 'store':
try:
self.session.commit()
print('Product %s stored' % product.name)
print(f'Product {product.name} stored')
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store product %s: %s' % (product.name, e))
print(f'Could not store product {product.name}: {e}')
self.pause()
return
elif what is None:
@ -128,25 +130,26 @@ class AdjustStockMenu(Menu):
self.print_header()
product = self.input_product('Product> ')
print('The stock of this product is: %d ' % product.stock)
print(f'The stock of this product is: {product.stock:d} ')
print('Write the number of products you have added to the stock')
print('Alternatively, correct the stock for any mistakes')
add_stock = self.input_int('Added stock> ', (-1000, 1000))
print('You added %d to the stock of %s' % (add_stock, product))
# TODO: Print something else when adding negative stock?
print(f'You added {add_stock:d} to the stock of {product}')
product.stock += add_stock
print('The stock is now %d' % product.stock)
print(f'The stock is now {product.stock:d}')
try:
self.session.commit()
print('Stock is now stored')
self.pause()
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store stock: %s' % e)
print(f'Could not store stock: {e}')
self.pause()
return
print('The stock is now %d' % product.stock)
print(f'The stock is now {product.stock:d}')
class CleanupStockMenu(Menu):
@ -179,7 +182,7 @@ class CleanupStockMenu(Menu):
print('New stocks are now stored.')
self.pause()
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store stock: %s' % e)
print(f'Could not store stock: {e}')
self.pause()
return

View File

@ -87,6 +87,7 @@ class Menu(object):
return i
return self.items[i]
# TODO: Allow default
def input_str(self, prompt=None, regex=None, length_range=(None, None),
empty_string_is_none=False, timeout=None):
if prompt is None:
@ -98,7 +99,7 @@ class Menu(object):
if result is None or re.match(regex + '$', result):
return result
else:
print('Value must match regular expression "%s"' % regex)
print(f'Value must match regular expression "{regex}"')
if length_range != (None, None):
while True:
result = self.input_str(prompt, empty_string_is_none=empty_string_is_none)
@ -109,11 +110,11 @@ class Menu(object):
if ((length_range[0] and length < length_range[0]) or
(length_range[1] and length > length_range[1])):
if length_range[0] and length_range[1]:
print('Value must have length in range [%d,%d]' % length_range)
print(f'Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]')
elif length_range[0]:
print('Value must have length at least %d' % length_range[0])
print(f'Value must have length at least {length_range[0]:d}')
else:
print('Value must have length at most %d' % length_range[1])
print(f'Value must have length at most {length_range[1]:d}')
else:
return result
while True:
@ -129,9 +130,9 @@ class Menu(object):
# timeout occurred, simulate empty line
result = ''
else:
result = str(input(), conf.input_encoding).strip()
result = input().strip()
else:
result = str(input(safe_str(prompt)), conf.input_encoding).strip()
result = input(safe_str(prompt)).strip()
except EOFError:
print('quit')
self.exit_menu()
@ -210,7 +211,7 @@ class Menu(object):
if prompt is None:
prompt = self.prompt
if default is not None:
prompt += ("[%s] " % default)
prompt += (f"[{default}] ")
while True:
result = self.input_str(prompt)
if result == '':
@ -223,11 +224,11 @@ class Menu(object):
if ((allowed_range[0] and value < allowed_range[0]) or
(allowed_range[1] and value > allowed_range[1])):
if allowed_range[0] and allowed_range[1]:
print('Value must be in range [%d,%d]' % allowed_range)
print(f'Value must be in range [{allowed_range[0]:d}, {allowed_range[1]:d}]')
elif allowed_range[0]:
print('Value must be at least %d' % allowed_range[0])
print(f'Value must be at least {allowed_range[0]:d}')
else:
print('Value must be at most %d' % allowed_range[1])
print(f'Value must be at most {allowed_range[1]:d}')
else:
return value
except ValueError:
@ -302,7 +303,7 @@ class Menu(object):
type_guess = guess_data_type(search_str)
if type_guess is not None and thing_for_type[type_guess] in add_non_existing:
return self.search_add(search_str)
# print 'No match found for "%s".' % search_str
# print('No match found for "%s".' % search_str)
return None
return self.search_ui2(search_str, results[selected_thing], selected_thing)
@ -321,16 +322,16 @@ class Menu(object):
def search_add(self, string):
type_guess = guess_data_type(string)
if type_guess == 'username':
print('"%s" looks like a username, but no such user exists.' % string)
if self.confirm('Create user %s?' % string):
print(f'"{string}" looks like a username, but no such user exists.')
if self.confirm(f'Create user {string}?'):
user = User(string, None)
self.session.add(user)
return user
return None
if type_guess == 'card':
selector = Selector('"%s" looks like a card number, but no user with that card number exists.' % string,
[('create', 'Create user with card number %s' % string),
('set', 'Set card number of an existing user to %s' % string)])
selector = Selector(f'"{string}" looks like a card number, but no user with that card number exists.',
[('create', f'Create user with card number {string}'),
('set', f'Set card number of an existing user to {string}')])
selection = selector.execute()
if selection == 'create':
username = self.input_str('Username for new user (should be same as PVV username)> ',
@ -342,7 +343,7 @@ class Menu(object):
user = self.input_user('User to set card number for> ')
old_card = user.card
user.card = string
print('Card number of %s set to %s (was %s)' % (user.name, string, old_card))
print(f'Card number of {user.name} set to {string} (was {old_card})')
return user
return None
if type_guess == 'bar_code':
@ -357,22 +358,19 @@ class Menu(object):
if not isinstance(result, list):
return result
if len(result) == 0:
print('No %ss matching "%s"' % (thing, search_str))
print(f'No {thing}s matching "{search_str}"')
return None
if len(result) == 1:
msg = 'One %s matching "%s": %s. Use this?' % \
(thing, search_str, str(result[0]))
msg = f'One {thing} matching "{search_str}": {str(result[0])}. Use this?'
if self.confirm(msg, default=True):
return result[0]
return None
limit = 9
if len(result) > limit:
select_header = '%d %ss matching "%s"; showing first %d' % \
(len(result), thing, search_str, limit)
select_header = f'{len(result):d} {thing}s matching "{search_str}"; showing first {limit:d}'
select_items = result[:limit]
else:
select_header = '%d %ss matching "%s"' % \
(len(result), thing, search_str)
select_header = f'{len(result):d} {thing}s matching "{search_str}"'
select_items = result
selector = Selector(select_header, items=select_items,
return_index=False)
@ -419,7 +417,8 @@ class Menu(object):
print('no help here')
else:
print('')
print('Help for %s:' % (self.header_format % self.name))
print('Help for %s:' % (self.header_format
% self.name))
print(self.help_text)
def execute(self, **kwargs):
@ -437,6 +436,7 @@ class Menu(object):
self.session = None
def _execute(self, **kwargs):
# TODO: This is a very awkward line. Is there a better way of doing this?
line_format = '%' + str(len(str(len(self.items)))) + 'd ) %s'
while True:
self.print_header()
@ -478,7 +478,7 @@ class ConfirmMenu(Menu):
def _execute(self):
options = {True: '[y]/n', False: 'y/[n]', None: 'y/n'}[self.default]
while True:
result = self.input_str('%s (%s) ' % (self.prompt, options), timeout=self.timeout)
result = self.input_str(f'{self.prompt} ({options}) ', timeout=self.timeout)
result = result.lower().strip()
if result in ['y', 'yes']:
return True
@ -507,5 +507,5 @@ class Selector(Menu):
print('\'exit\' to go out and do something else.')
else:
print('')
print('Help for selector (%s):' % self.name)
print(f'Help for selector ({self.name}):')
print(self.help_text)

View File

@ -13,30 +13,30 @@ class TransferMenu(Menu):
def _execute(self):
self.print_header()
amount = self.input_int('Transfer amount> ', (1, 100000))
self.set_context('Transfering %d kr' % amount, display=False)
self.set_context(f'Transferring {amount:d} kr', display=False)
user1 = self.input_user('From user> ')
self.add_to_context(' from ' + user1.name)
self.add_to_context(f' from {user1.name}')
user2 = self.input_user('To user> ')
self.add_to_context(' to ' + user2.name)
self.add_to_context(f' to {user2.name}')
comment = self.input_str('Comment> ')
self.add_to_context(' (comment) ' + user2.name)
self.add_to_context(f' (comment) {user2.name}')
t1 = Transaction(user1, amount,
'transfer to ' + user2.name + ' "' + comment + '"')
f'transfer to {user2.name} "{comment}"')
t2 = Transaction(user2, -amount,
'transfer from ' + user1.name + ' "' + comment + '"')
f'transfer from {user1.name} "{comment}"')
t1.perform_transaction()
t2.perform_transaction()
self.session.add(t1)
self.session.add(t2)
try:
self.session.commit()
print('Transfered %d kr from %s to %s' % (amount, user1, user2))
print('User %s\'s credit is now %d kr' % (user1, user1.credit))
print('User %s\'s credit is now %d kr' % (user2, user2.credit))
print('Comment: %s' % comment)
print(f"Transferred {amount:d} kr from {user1} to {user2}")
print(f"User {user1}'s credit is now {user1.credit:d} kr")
print(f"User {user2}'s credit is now {user2.credit:d} kr")
print(f"Comment: {comment}")
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not perform transfer: %s' % e)
print(f'Could not perform transfer: {e}')
# self.pause()
@ -47,14 +47,14 @@ class ShowUserMenu(Menu):
def _execute(self):
self.print_header()
user = self.input_user('User name, card number or RFID> ')
print('User name: %s' % user.name)
print('Card number: %s' % user.card)
print('RFID: %s' % user.rfid)
print('Credit: %s kr' % user.credit)
selector = Selector('What do you want to know about %s?' % user.name,
print(f'User name: {user.name}')
print(f'Card number: {user.card}')
print(f'RFID: {user.rfid}')
print(f'Credit: {user.credit} kr')
selector = Selector(f'What do you want to know about {user.name}?',
items=[('transactions', 'Recent transactions (List of last ' + str(
conf.user_recent_transaction_limit) + ')'),
('products', 'Which products %s has bought, and how many' % user.name),
('products', f'Which products {user.name} has bought, and how many'),
('transactions-all', 'Everything (List of all transactions)')])
what = selector.execute()
if what == 'transactions':
@ -66,21 +66,24 @@ class ShowUserMenu(Menu):
else:
print('What what?')
# TODO: This is almost identical to the print_transactions function. Reimplement using that one?
@staticmethod
def print_all_transactions(user):
num_trans = len(user.transactions)
string = '%s\'s transactions (%d):\n' % (user.name, num_trans)
string = f"{user.name}'s transactions ({num_trans:d}):\n"
for t in user.transactions[::-1]:
string += ' * %s: %s %d kr, ' % \
(t.time.strftime('%Y-%m-%d %H:%M'),
{True: 'in', False: 'out'}[t.amount < 0],
'in' if t.amount < 0 else 'out',
abs(t.amount))
if t.purchase:
# TODO: Print purchased amount, not just product names
# TODO: Print something other than "purchase" when user put products into dibbler?
string += 'purchase ('
string += ', '.join([e.product.name for e in t.purchase.entries])
string += ')'
if t.penalty > 1:
string += ' * %dx penalty applied' % t.penalty
string += f' * {t.penalty:d}x penalty applied'
else:
string += t.description
string += '\n'
@ -90,20 +93,20 @@ class ShowUserMenu(Menu):
def print_transactions(user, limit=10):
num_trans = len(user.transactions)
if num_trans <= limit:
string = '%s\'s transactions (%d):\n' % (user.name, num_trans)
string = f"{user.name}'s transactions ({num_trans:d}):\n"
else:
string = '%s\'s transactions (%d, showing only last %d):\n' % (user.name, num_trans, limit)
string = f"{user.name}'s transactions ({num_trans:d}, showing only last {limit:d}):\n"
for t in user.transactions[-1:-limit - 1:-1]:
string += ' * %s: %s %d kr, ' % \
(t.time.strftime('%Y-%m-%d %H:%M'),
{True: 'in', False: 'out'}[t.amount < 0],
'in' if t.amount < 0 else 'out',
abs(t.amount))
if t.purchase:
string += 'purchase ('
string += ', '.join([e.product.name for e in t.purchase.entries])
string += ')'
if t.penalty > 1:
string += ' * %dx penalty applied' % t.penalty
string += f' * {t.penalty:d}x penalty applied'
else:
string += t.description
string += '\n'
@ -124,7 +127,7 @@ class ShowUserMenu(Menu):
text = ''
text += 'Products purchased:\n'
for product, count in products:
text += '{0:<47} {1:>3}\n'.format(product.name, count)
text += f'{product.name:<47} {count:>3}\n'
less(text)
@ -148,16 +151,17 @@ class UserListMenu(Menu):
text += line_format % ('total credit', total_credit)
less(text)
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
# reimplements ChargeMenu
# TODO: these should be combined to one
class AdjustCreditMenu(Menu):
def __init__(self):
Menu.__init__(self, 'Adjust credit', uses_db=True)
def _execute(self):
self.print_header()
user = self.input_user('User> ')
print('User %s\'s credit is %d kr' % (user.name, user.credit))
self.set_context('Adjusting credit for user %s' % user.name, display=False)
print(f"User {user.name}'s credit is {user.credit:d} kr")
self.set_context(f'Adjusting credit for user {user.name}', display=False)
print('(Note on sign convention: Enter a positive amount here if you have')
print('added money to the PVVVV money box, a negative amount if you have')
print('taken money from it)')
@ -173,9 +177,9 @@ class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combin
self.session.add(transaction)
try:
self.session.commit()
print('User %s\'s credit is now %d kr' % (user.name, user.credit))
print(f"User {user.name}'s credit is now {user.credit:d} kr")
except sqlalchemy.exc.SQLAlchemyError as e:
print('Could not store transaction: %s' % e)
print(f'Could not store transaction: {e}')
# self.pause()