Skip to content

Instantly share code, notes, and snippets.

@ricardosiri68
Created May 11, 2016 06:36
Show Gist options
  • Save ricardosiri68/006997ea326dc3ad48e1b3d45a34af5b to your computer and use it in GitHub Desktop.
Save ricardosiri68/006997ea326dc3ad48e1b3d45a34af5b to your computer and use it in GitHub Desktop.
id name
0 Pedro
1 Juan
2 Diego
3 Luisa
4 Marta
import services
import sys
import os
clients_service = services.ClientsService()
products_service = services.ProductsService()
bills_service = services.BillsService()
sellings_service = services.SellingsService()
def clear_screen():
'''limpiar lo que hay en la pantalla'''
os.system('cls' if os.name == 'nt' else 'clear')
def get_object_loop(func):
'''este decorador mantiene espera la entrada del usuario'''
def wrapper():
while True:
try:
return func(int(input('> ')))
except IndexError:
print('La id ingresada no se encuentra en el servicio')
except ValueError:
print('La id debe ser un numero entero')
return wrapper
def show_clients():
'''muestra la lista de clientes'''
for client in clients_service:
print('{client.id:04d} | {client.name}'.format(client=client))
def show_clients_totals():
'''muestra la suma total de lo vendido a cada cliente'''
for client, cant, total in sellings_service.clients_totals():
print('{client.id:04d} | {client.name:^30} | {cant:4d} |'
' $ {total:8.2f}'.format(client=client, cant=cant, total=total))
def show_products_counts():
'''muestra la cantidad vendida de cada producto'''
for product, count in sellings_service.products_counts():
print('{product.id:04d} | {product.name:^30} | {count}'
.format(product=product, count=count))
def show_products():
'''muestra la lista de productos'''
for product in products_service:
print('{product.id:04d} | {product.name:<30} | $ {product.price:8.2f}'
.format(product=product))
def show_bills():
'''muestra todas las boletas de venta'''
for bill in bills_service:
print('{bill.id:04d} | $ {bill.total:8.2f}'.format(bill=bill))
def show_bell_sellings(bill):
'''muestra todos los articulos de una venta'''
print('boleta ID: %s ' % bill.id)
show_sellings(bill.sellings)
print('total $ %8.2f' % bill.total)
def show_sellings(sellings=sellings_service):
for sell in sellings:
print('{sell.bill_id:04d} | {sell.client.name:<15} | {sell.cant:4.1f} |'
' {sell.product.name:^25} | $ {sell.product.price:8.2f} |'
' $ {sell.amount:8.2f}'.format(sell=sell))
def show_bill():
'''muestra muestra el detalle de una boleta segun si id'''
print('ingrese el numero de boleta')
bill = get_bill()
show_bell_sellings(bill)
@get_object_loop
def get_bill(bill_id):
'''obtiene un boleta segun su id'''
return bills_service[bill_id]
@get_object_loop
def get_client(client_id):
'''obtiene un cliente según su id'''
return clients_service[int(client_id)]
@get_object_loop
def get_product(product_id):
'''obtiene un producto según su id'''
return products_service[int(product_id)]
def get_cant():
'''recupera la cantidad de un productos de un reglon de venta'''
while True:
try:
return float(input('> '))
except ValueError:
print('la cantidad ingresada debe ser un numero')
def make_newsale():
'''lleva cabo una nueva venta'''
# a) Determinar el nuevo numero de boleta, basado en lista de ventas.
# b) muestra el listado de usuarios, el vendedor ingresa el numero de
# cliente
# c) muestra el listado de productos, el vendedor ingresa el numero de
# producto
# d) pide la cantidad de items para ese producto.
# e) pregunta si hay q ingresar mas productos
# f) si no hay q ingresar mas productos, se presenta un resumen de la
# boleta, indicando los productos vendidos, su cantidad, precio unitario y
# precio por item.
# g) Finalmente, se presenta el total a pagar.
# h) Estos datos deben quedar almacendos en la lista ventas, de manera de
# poder ver reportes de ventas posteriores
new_bill = bills_service.create()
show_clients()
client = get_client()
if not client:
return
while True:
show_products()
product = get_product()
if not product:
return
print('ingrese la cantidad a despachar')
cant = get_cant()
sellings_service.create(new_bill, client, cant, product)
if input('añadir nuevo') == 's':
clear_screen()
else:
break
show_bell_sellings(new_bill)
def show_mainmenu():
'''muestra el menu principal de la aplicacion'''
clear_screen()
print('ingrese opcion:\n'
'1 realizar nueva venta\n'
'2 listar productos y precios\n'
'3 listar clientes\n'
'4 listar ventas\n'
'5 ver boleta N°\n'
'6 listar suma de ventas por cliente\n'
'7 listar cantidad vendida por producto\n'
'8 listar boletas\n'
'm mostras este menu\n'
's salir')
def main():
'''metodo principal donde se encuentra el map de las acciones del usario y
el mainloop de ejecucion'''
main_actions = {
'1': make_newsale,
'2': show_products,
'3': show_clients,
'4': show_sellings,
'5': show_bill,
'6': show_clients_totals,
'7': show_products_counts,
'8': show_bills,
'm': show_mainmenu,
's': sys.exit
}
show_mainmenu()
while True:
option = input('> ')
if option not in main_actions:
print('La opcion ingresada no es valida, intente nuevamente')
else:
main_actions[option]() # llamamos a la accion principal
if __name__ == "__main__":
main()
id name price
0 Coca cola 700
1 Ramitas bolsa 300
2 Helado litro 1200
3 Hielo bolsa 500
4 Pisco 750cc 1300
bill_id client_id cant product_id
1 4 4 1
1 4 4 3
1 4 2 4
2 3 5 3
2 3 5 0
3 2 1 2
3 2 2 1
3 2 2 3
3 2 3 0
4 0 4 1
5 4 1 2
5 4 5 1
6 2 2 4
6 2 5 3
7 4 4 2
7 4 3 1
7 4 2 0
7 4 1 3
8 2 5 4
8 2 1 3
9 0 3 2
10 2 5 1
10 2 3 3
10 2 4 4
11 0 4 3
11 0 5 0
12 1 1 0
12 1 3 1
12 1 4 2
13 4 4 1
14 3 3 2
14 3 5 0
14 3 3 4
from collections import namedtuple
import csv
Client = namedtuple('Cliente', 'id name')
Product = namedtuple('Product', 'id name price')
SellTuple = namedtuple('Sell', 'bill_id client cant product')
BillTuple = namedtuple('Bill', 'id sellings')
ClientTotal = namedtuple('ClientSellingsTotal', 'client cant total')
ProductCount = namedtuple('ProductCount', 'product count')
class Bill(BillTuple):
@property
def total(self):
'''el total vendido de una boleta'''
return sum(sell.amount for sell in self.sellings)
class Sell(SellTuple):
@property
def amount(self):
'''el importe de de una venta'''
return self.cant * self.product.price
def get_csv_data(filename):
with open(filename) as csv_file:
reader = csv.DictReader(csv_file)
for item in reader:
yield tuple(item[fieldname] if fieldname != 'id' and
not fieldname.endswith('_id') else int(item[fieldname])
for fieldname in reader.fieldnames)
class Service:
def __len__(self):
return len(self.items)
def __iter__(self):
for item in self.items:
yield item
def __getitem__(self, index):
'''obtiene un item segun su id'''
for item in self.items:
if item.id == index:
return item
raise IndexError('no hay un item con esa id en %s' % self.__class__)
class ClientsService(Service):
'''servicio de clientes'''
def __init__(self):
self.items = [Client(*item) for item in get_csv_data('clients.csv')]
class ProductsService(Service):
'''servicio de productos'''
def __init__(self):
self.items = [Product(p_id, name, float(price))
for p_id, name, price in get_csv_data('products.csv')]
class BillsService(Service):
'''servicio de boletas'''
def __init__(self):
sellings = SellingsService()
bills_items = {}
for sell in sellings:
bills_items[sell.bill_id] = bills_items.get(sell.bill_id, []) + \
[sell]
self.items = [Bill(bill_id, itemsellings)
for bill_id, itemsellings in bills_items.items()]
def create(self):
'''crea una boleta nueva y la añade a la lista'''
new_bill = Bill(max(item.id for item in self.items) + 1, [])
self.items.append(new_bill)
return new_bill
class SellingsService:
'''servicio de ventas'''
def __init__(self):
clients = ClientsService()
products = ProductsService()
sellings_csv = get_csv_data('sellings.csv')
self.items = [Sell(bill_id, clients[client_id], float(cant),
products[product_id])
for bill_id, client_id, cant, product_id in sellings_csv]
def __len__(self):
return len(self.items)
def __iter__(self):
for sell in self.items:
yield sell
def create(self, bill, client, cant, product):
'''crea una nueva tupla de venta y la añade a la lista del servicio'''
sell = Sell(bill.id, client, cant, product)
self.items.append(sell)
bill.sellings.append(sell)
return sell
def clients_totals(self):
'''genera las tuplas de ClienteTotal de cada cliente'''
clients_totals = {}
for sell in self:
if sell.client in clients_totals:
client_total = clients_totals[sell.client]
clients_totals[sell.client] = ClientTotal(client_total.client,
client_total.cant + 1, client_total.total + sell.amount)
else:
clients_totals[sell.client] = ClientTotal(sell.client, 1,
sell.amount)
return clients_totals.values()
def products_counts(self):
'''devuelve la cantidad'''
products_counts = {}
for sell in self:
products_counts[sell.product] = products_counts\
.get(sell.product, 0) + sell.cant
for product, count in products_counts.items():
yield ProductCount(product, count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment