Skip to content

Instantly share code, notes, and snippets.

@lucasrcezimbra
Last active June 26, 2018 12:57
Show Gist options
  • Select an option

  • Save lucasrcezimbra/7efdf62478660e4f1260db4b7d2622e3 to your computer and use it in GitHub Desktop.

Select an option

Save lucasrcezimbra/7efdf62478660e4f1260db4b7d2622e3 to your computer and use it in GitHub Desktop.
import argparse
import sys
import unittest
from collections import namedtuple
from datetime import datetime, timedelta
def ponto(args):
return _ponto(
args.entry,
working = args.working_hours,
rest_hours = args.rest_hours,
exit = args.exit,
verbose = (not args.no_verbose),
)
def _ponto(entry, working, rest_hours, format='%H:%M', exit=None, verbose=True):
entrytime = datetime.strptime(entry, format)
working_hours = _get_timedelta_from_hours(working, format)
rest_hours = _get_rest_hours_timedelta(rest_hours, format)
if exit:
worked_hours = _get_worked_hours(exit, entrytime, rest_hours, format)
msg = '{} horas trabalhadas e {} de descanso'
return _return_message(msg, [worked_hours, rest_hours], verbose)
else:
expected_exittime = entrytime + working_hours + rest_hours
msg = 'Você deve sair as {} para descansar {} e completar {} horas'
params = [
datetime.strftime(expected_exittime, format),
rest_hours,
working_hours,
]
return _return_message(msg, params, verbose)
def _return_message(msg, params, verbose):
if verbose:
return msg.format(*params)
else:
return params[0]
def _get_timedelta_from_hours(hours, format):
h = datetime.strptime(hours, format)
return timedelta(hours=h.hour, minutes=h.minute)
def _get_worked_hours(exit, entrytime, rest_hours, format):
exittime = datetime.strptime(exit, format)
return exittime - entrytime - rest_hours
def _get_rest_hours_timedelta(rest_hours, format):
if ',' in str(rest_hours):
exit, regress = rest_hours.split(',')
exittime = datetime.strptime(exit, format)
regresstime = datetime.strptime(regress, format)
return regresstime - exittime
else:
return _get_timedelta_from_hours(rest_hours, format)
class PontoTest(unittest.TestCase):
def test_ponto(self):
args = namedtuple('args', ['entry', 'working_hours', 'rest_hours', 'exit', 'no_verbose'])
args.__new__.__defaults__ = (None, '8:30', '1:00', None, None)
expected_msg = 'Você deve sair as {} para descansar {} e completar {} horas'
self.assertEqual(ponto(args('8:30')), expected_msg.format('18:00', '1:00:00', '8:30:00'))
self.assertEqual(ponto(args('9:00')), expected_msg.format('18:30', '1:00:00', '8:30:00'))
self.assertEqual(ponto(args('8:30', rest_hours='2:00')), expected_msg.format('19:00', '2:00:00', '8:30:00'))
self.assertEqual(ponto(args('8:00', working_hours='8:40')), expected_msg.format('17:40', '1:00:00', '8:40:00'))
self.assertEqual(ponto(args('8:00', working_hours='8:00', rest_hours='2:00')),
expected_msg.format('18:00', '2:00:00', '8:00:00'))
self.assertEqual(ponto(args('8:00', rest_hours='11:30,12:30')), expected_msg.format('17:30', '1:00:00', '8:30:00'))
self.assertEqual(ponto(args('8:30', exit='18:00')),
'8:30:00 horas trabalhadas e 1:00:00 de descanso')
self.assertEqual(ponto(args('8:30', rest_hours='0:00', exit='18:00')),
'9:30:00 horas trabalhadas e 0:00:00 de descanso')
self.assertEqual(ponto(args('8:30', rest_hours='0:00', exit='18:00', working_hours='10:00')),
'9:30:00 horas trabalhadas e 0:00:00 de descanso')
self.assertEqual(ponto(args('8:30', no_verbose=True)), '18:00')
def test_lunch(self):
self.assertEqual(_get_rest_hours_timedelta('11:30,12:30', '%H:%M'), timedelta(hours=1))
self.assertEqual(_get_rest_hours_timedelta('11:00,12:00', '%H:%M'), timedelta(hours=1))
self.assertEqual(_get_rest_hours_timedelta('11:00,13:00', '%H:%M'), timedelta(hours=2))
self.assertEqual(_get_rest_hours_timedelta('11:00,12:30', '%H:%M'), timedelta(hours=1.5))
def create_parser():
parser = argparse.ArgumentParser(
description='Recebe o horário de entrada e retorna o horário que deve sair '
'para completar as horas de trabalho necessárias no dia. '
'Leva em consideração o tempo de intervalo. ',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('entry',
help='Horário de entrada. Exemplo: 8:00')
parser.add_argument('-w', '--working-hours',
help='Quantidade de horas que devem ser trabalhadas. Exemplo: 8:00',
default='8:00')
parser.add_argument('-r', '--rest-hours',
help='Horas que serão usadas para descanso/almoço. '
'Aceita tempo de descanso ou horário de começo e saída separados por vírgula. '
'Exemplo: 1:00 ou 11:30,12:30',
default='1:00')
parser.add_argument('-e', '--exit',
help='Recebe o horário de saída e calcula quantas horas foram trabalhadas '
'(se receber esse paramêtro ignora o working_hours). Exemplo: 18:00',)
parser.add_argument('-n', '--no-verbose',
help='Não verboso, retorna somente o resultado.',
action='store_true')
return parser.parse_args()
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'test':
del sys.argv[1]
unittest.main()
else:
args = create_parser()
print(ponto(args))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment