uaveiro-leci/1ano/fp/avaliacao/apx2/shop.py

125 lines
5.5 KiB
Python

# Pode correr o programa sem argumentos:
# python3 shop
# ou passando outros ficheiros de produtos como argumento:
# python3 shop produtos1.txt ...
def loadDataBase(fname, produtos):
"""Lê dados do ficheiro fname e atualiza/acrescenta a informação num
dicionário de produtos com o formato {código: (nome, secção, preço, iva), ...}.
"""
with open(fname, 'r') as f: # Abre o ficheiro em modo de leitura
productsFileContent = f.read() # Cria uma string com o conteudo do ficheiro
for product in productsFileContent.split('\n')[1:]: # Divide a string 'productsFileContent' numa lista com cada produto
productComponents = product.split(';') # Divide as componentes do produto (código, nome, secção, preço, iva)
if len(productComponents) != 5:
continue
produtos.update({productComponents[0]: ( # Atualiza a entrada de uma determinada chave (código)
productComponents[1], # Nome
productComponents[2], # Secção
float(productComponents[3]), # Preço
float(productComponents[4].strip('%')) / 100 # IVA
)})
def registaCompra(produtos):
"""Lê códigos de produtos (ou códigos e quantidades),
mostra nome, quantidade e preço final de cada um,
e devolve dicionário com {codigo: quantidade, ...}
"""
compra = {"totals": [0, 0, 0]} # Inicia o dicionário da compra com os totais da mesma: [total bruto, total iva, total liquido]
userInput = input('Code? ')
while userInput != "":
try:
code, amount = userInput.split(' ') # Divide o input do utilizador no código e na quantia
except ValueError:
code, amount = userInput, 1 # No caso de não ser introduzida quantia, então ela fica 1
# Caso a segunda parcela da entrada não seja um número, é pedido ao utilizador para introduzir o código de novo
try:
amount = int(amount)
except ValueError:
userInput = input('Code? ')
continue
if code in produtos:
if code not in compra: # Se o produto ainda não estiver na lista é adicionado à mesma
compra[code] = 0
compra[code] += amount # Adiciona ao dicionário da compra a quantidade comprada do produto
noIvaPrice = produtos[code][2] * amount # Obtém o preço (sem iva) do determinado produto
compra["totals"][0] += noIvaPrice # Adiciona o preço sem iva ao total bruto
compra["totals"][1] += noIvaPrice * produtos[code][3] # Adiciona o valor do iva ao total iva
print(f"{produtos[code][0]} {amount} {noIvaPrice * (1+produtos[code][3]):.2f}")
userInput = input('Code? ')
compra["totals"][2] += compra["totals"][0] + compra["totals"][1] # Calcula o total liquido da compra
return compra # Devolve a lista
def fatura(produtos, compra):
"""Imprime a fatura de uma dada compra."""
# Obtém a lista de secções presentes na compra (por ordem alfabética)
sections = sorted(list({section for section in [product[1] for code, product in produtos.items() if code in compra]}))
# Itera as secções para apresentar os produtos ordenados por secção
for section in sections:
print(section) # Mostra a secção
# Obtém a lista de codigos usados na compra presentes na secção atual
sectionProductsCodes = sorted([code for code in produtos if produtos[code][1] == section and code in compra])
# Itera os códigos para apresentar as informações de cada produto
for code in sectionProductsCodes:
print(f"{compra[code]:>4} {produtos[code][0]:<31}({int(produtos[code][3]*100):>2}%){round(compra[code]*produtos[code][2]*(1+produtos[code][3]), 2):>11}")
# Apresenta os totais da compra
print(f"""{'Total Bruto:':>41}{round(compra["totals"][0], 2):>11}
{'Total IVA:':>41}{round(compra["totals"][1], 2):>11}
{'Total Liquido:':>41}{round(compra["totals"][2], 2):>11}""")
def main(args):
# produtos guarda a informação da base de dados numa forma conveniente.
produtos = {'p1': ('Ketchup.', 'Mercearia Salgado', 1.59, 0.23)}
# Carregar base de dados principal
loadDataBase("produtos.txt", produtos)
# Juntar bases de dados opcionais (Não altere)
for arg in args:
loadDataBase(arg, produtos)
# Use este código para mostrar o menu e ler a opção repetidamente
MENU = "(C)ompra (F)atura (S)air ? "
compras = {}
repetir = True
while repetir:
# Utilizador introduz a opção com uma letra minúscula ou maiúscula
op = input(MENU).upper()
# Processar opção
if op == "C":
# Esta opção regista os produtos de uma compra
compras[len(compras)+1] = registaCompra(produtos)
elif op == "F":
# Esta opção apresenta a fatura de uma compra
try:
numCompra = int(input("Numero compra? "))
fatura(produtos, compras[numCompra])
except:
continue
elif op == "S":
repetir = False
print("Obrigado!")
# Não altere este código / Do not change this code
import sys
if __name__ == "__main__":
main(sys.argv[1:])