Last active
June 26, 2018 12:57
-
-
Save lucasrcezimbra/7efdf62478660e4f1260db4b7d2622e3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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