Skip to content

Instantly share code, notes, and snippets.

@ricardosiri68
Last active March 22, 2016 05:45
Show Gist options
  • Save ricardosiri68/050b44da24e48d8fe400 to your computer and use it in GitHub Desktop.
Save ricardosiri68/050b44da24e48d8fe400 to your computer and use it in GitHub Desktop.

Como se usa

En linux

./main.py <yyyy-mm>

ej (recuperando los registro de marzo del 2016):

./main.py 2016-03

En windows (tambien en linux)

python main.py <yyyy-mm>

ej (recuperando los registro de marzo del 2016):

python main.py 2016-03

salida o resultado

  ID |                          NOMBRE COMPLETO |  C. HORAS |       MONTO | SUELDO
----------------------------------------------------------------------------------
0001 |                           Carlyn Yeldell |       001 | $ 10.000,00 | $ 10.000,00
0002 |                            Darci Simkins |       001 | $ 10.000,00 | $ 10.000,00
0003 |                             Alison Penna |       001 | $ 10.000,00 | $ 10.000,00
0004 |                          Tammi Mcfarland |       102 | $ 00.050,00 | $ 05.100,00
0005 |                           Johnna Arehart |       122 | $ 00.086,00 | $ 10.492,00
0006 |                             Anitra Saleh |       116 | $ 00.050,00 | $ 05.800,00
0007 |                             Daine Boutte |       121 | $ 00.070,00 | $ 08.470,00
0008 |                            Judie Dejonge |       106 | $ 00.075,00 | $ 07.950,00
0009 |                               Pierre Apo |       000 | $ 00.000,00 | $ 00.000,00
0010 |                              Beau Nunley |       000 | $ 00.000,00 | $ 00.000,00
[
{"id": 1, "first_name": "Carlyn", "last_name": "Yeldell", "age": 22, "salary_type": "m", "amount": 10000},
{"id": 2, "first_name": "Darci", "last_name": "Simkins", "age": 21, "salary_type": "m", "amount": 10000},
{"id": 3, "first_name": "Alison", "last_name": "Penna", "age": 20, "salary_type": "m", "amount": 10000},
{"id": 4, "first_name": "Tammi", "last_name": "Mcfarland", "age": 23, "salary_type": "h", "amount": 50},
{"id": 5, "first_name": "Johnna", "last_name": "Arehart", "age": 40, "salary_type": "h", "amount": 86},
{"id": 6, "first_name": "Anitra", "last_name": "Saleh", "age": 50, "salary_type": "h", "amount": 50},
{"id": 7, "first_name": "Daine", "last_name": "Boutte", "age": 19, "salary_type": "h", "amount": 70},
{"id": 8, "first_name": "Judie", "last_name": "Dejonge", "age": 50, "salary_type": "h", "amount": 75},
{"id": 9, "first_name": "Pierre", "last_name": "Apo", "age": 22, "salary_type": "v"},
{"id": 10, "first_name": "Beau", "last_name": "Nunley", "age": 30, "salary_type": "v"}
]
year_month week_num employee_id cant_hours
2016-03 1 4 21
2016-03 2 4 36
2016-03 3 4 20
2016-03 4 4 25
2016-03 1 5 30
2016-03 2 5 36
2016-03 3 5 17
2016-03 4 5 39
2016-03 1 6 19
2016-03 2 6 20
2016-03 3 6 40
2016-03 4 6 37
2016-03 1 7 40
2016-03 2 7 23
2016-03 3 7 36
2016-03 4 7 22
2016-03 1 8 37
2016-03 2 8 23
2016-03 3 8 33
2016-03 4 8 13
2016-02 1 4 21
2016-02 2 4 36
2016-02 3 4 20
2016-02 4 4 25
2016-02 1 5 30
2016-02 2 5 36
2016-02 3 5 17
#!/usr/bin/env python
import sys
import locale
from object_collections import Employees
locale.setlocale(locale.LC_ALL, 'es_AR')
if __name__ == '__main__': # espero que no cuenten esto como un if :$
header = "%04s | %40s | %9s | %11s | %s" % ('ID', 'NOMBRE COMPLETO',
'C. HORAS', 'MONTO', 'SUELDO')
print(header)
print("-" * len(header))
for e in Employees.liquidate_salaries(sys.argv[1]):
row = "%(id)04d | %(fullname)40s | %(cant_hours)03d | $ "
row += "%(amount)s | $ %(salary_collect)s"
print(row % {
'id': e.id,
'fullname': e.fullname,
'cant_hours': e.cant_hours,
'amount': locale.format('%08.2f', e.amount, grouping=True),
'salary_collect': locale.format('%08.2f', e.salary_collect,
grouping=True)
})
class Employee(object):
'''modelo de datos del empleado'''
def __init__(self, item, collection):
self.__id = item['id']
self.__first_name = item['first_name']
self.__last_name = item['last_name']
self.__age = item['age']
self.__salary_type = item['salary_type']
self.__amount = item.get('amount', 0)
self.__collection = collection
def fix(self):
'''multiplo de hs de un empleado con sueldo mensual fijo'''
return 1
def voluntary(self):
'''multiplo de js de un empleado voluntario (sin sueldo)'''
return 0
def week_hours(self):
'''recupera las hs trabajadas cada semana del mes y la suma'''
return sum(record.hours for record in
self.collection.week_hours.get_by_employee(self.id))
# este diccionario mapea los metodos que recuperarn el modo de operar el
# monto que se le asigna a un empleado
SALARY_OPTION = {
'm': fix,
'v': voluntary,
'h': week_hours
}
@property
def collection(self):
'''instancia de la collection Employees que lista esta instancia del
modelo'''
return self.__collection
@property
def cant_hours(self):
'''recupera la contidad de hs trabajadas por un empleado, si es
voluntario son 0 hs y si cobra sueldo fijo es 1 finalmente en ultimo
caso devuelvela suma semanal de su jornadas'''
return self.SALARY_OPTION[self.salary_type](self)
@property
def salary_collect(self):
'''importe del sueldo a cobrar del empleado'''
return self.cant_hours * self.amount
@property
def id(self):
'''numero identificador del empleado o legajo'''
return self.__id
@property
def fist_name(self):
'''nombre'''
return self.__first_name
@property
def last_name(self):
'''apellido'''
return self.__last_name
@property
def fullname(self):
'''nombre compledo'''
return "%s %s" % (self.fist_name, self.last_name)
@property
def age(self):
'''edad'''
return self.__age
@property
def salary_type(self):
'''tipo del suelo: m (fijo mensual), h (suma de horas semanales),
v (voluntario)'''
return self.__salary_type
@property
def amount(self):
'''monto unitario del sueldo ya sea por hora o mensual'''
return self.__amount
class WeekHour(object):
'''modelo de datos de un registro de las horas hechas en una semana'''
def __init__(self, item):
self.__year_month = item['year_month']
self.__week_num = int(item['week_num'])
self.__employee_id = int(item['employee_id'])
self.__cant_hours = int(item['cant_hours'])
@property
def year_month(self):
'''formato yyyy-mm del anio al que pertenece esta suma semanal de
horas'''
return self.__year_month
@property
def week_num(self):
'''numero de la semana a la que pertenece'''
return self.__week_num
@property
def employee(self):
'''numero id del empleado al que pertenece el registro horario
semanal'''
return self.__employee_id
@property
def hours(self):
'''cantidad de horas detalladas'''
return self.__cant_hours
import json
import csv
from models import Employee, WeekHour
class Collection(object):
'''clase base de una colleccion de modelos de datos'''
def __len__(self):
return len(self.items)
def __iter__(self):
for item in self.items:
yield item
def __getitem__(self, key):
return self.items[key]
class JsonCollection(Collection):
'''colleccion que recupera los datos y genera los modelos desde una entrada
JSON'''
json_name = None
def __init__(self):
with open(self.json_name, 'r') as json_file:
self.items = [self.model_class(item, self) for item in
json.load(json_file)]
class CSVCollection(Collection):
'''colleccion que recupera los datos y genera los modelos desde una entrada
CSV'''
csv_name = None
def __init__(self):
with open(self.csv_name, 'r') as csv_file:
self.items = [self.model_class(item) for item in
csv.DictReader(csv_file)]
class Employees(JsonCollection):
'''colleccion de instancias de models.Employee'''
json_name = 'empleados.json'
model_class = Employee
def get_by_pk(self, pk):
'''recupera el empleado segun su clave id (pk)'''
return list(filter(lambda x: x.id == pk, self))[0]
@classmethod
def liquidate_salaries(cls, year_month):
'''asigna a la clase una instancia de liquidacion de horas semanales de
un mes determinado en year_month (yyyy-mm)'''
cls.week_hours = WeekHours(year_month)
return cls()
class WeekHours(CSVCollection):
'''coleccion de instancias de models.WeekHour'''
csv_name = 'horas_semanales.csv'
model_class = WeekHour
def __init__(self, year_month):
'''luego de recuperar TODOS los registros filtra aquellos que pertenecen
al mes y anio (year_month - yyyy-mm)'''
super().__init__()
self.items = list(filter(lambda x: x.year_month == year_month,
self.items))
def get_by_employee(self, pk):
'''filtra todos los registros de liquidacion semanal de segun la id de
un empleado (pk)'''
return list(filter(lambda x: x.employee == pk, self))
#!/usr/bin/env python
import unittest
from object_collections import Employees, WeekHours
from models import Employee
class TestEmployees(unittest.TestCase):
def test_index(self):
'''obtener todos los empleados sin liquidar su sueldo'''
employees = Employees()
self.assertEqual(len(employees), 10)
def test_by_id(self):
'''obtener un empleado segun su id'''
employee = Employees().get_by_pk(4)
self.assertIsInstance(employee, Employee)
self.assertEqual(employee.fist_name, "Tammi")
def test_liquidate(self):
'''obtener empleados liquidando el mes de marzo'''
employees = Employees.liquidate_salaries("2016-03")
self.assertEqual(len(employees), 10)
def test_liquidate_employee_hour(self):
'''empleado por suma semanal de horas'''
employees = Employees.liquidate_salaries("2016-03")
employee = employees.get_by_pk(4)
self.assertEqual(employee.salary_collect, 5100)
def test_liquidate_employee_month(self):
'''empleado con sueldo fijo por mes'''
employees = Employees.liquidate_salaries("2016-03")
employee = employees.get_by_pk(1)
self.assertEqual(employee.salary_collect, 10000)
def test_liquidate_employee_voluntary(self):
'''empleado voluntario (sin sueldo)'''
employees = Employees.liquidate_salaries("2016-03")
employee = employees.get_by_pk(9)
self.assertEqual(employee.salary_collect, 0)
class TestWeekHours(unittest.TestCase):
week_hours = WeekHours("2016-03")
def test_index(self):
'''obtener los registros de horas trabajadas del mes de marzo del
2016'''
self.assertEqual(len(self.week_hours), 20)
def test_by_employee(self):
'''obtener todas los registros de un empleado segun su id'''
hours = self.week_hours.get_by_employee(4)
self.assertEqual(len(hours), 4)
if __name__ == '__main__': # espero que no cuenten esto como un if :$
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment