[Python-es] Opinión sobre función para obtener una duración (de tiempo)
Dani
dani en damufo.eu
Mar Mar 16 12:44:31 EDT 2021
Hola: 🙂
Estoy intentando de validar una duración (tiempo) introducido en una
caja de texto.
Lo que trato de validar es una duración no una hora.
Las duraciones tienen una precisión de centésimas de segundo por lo que
la función devuelve las centésimas de la duración.
El caso es que creo que me he complicado algo y seguro que se puede
hacer mejor.
Es por aprender, porque la función tal como está me funciona (o eso creo).
Para la validación se tienen en cuenta dos formas de introducir las
duraciones, una con puntuación y otra sin.
Para la separación de decimales se puede introducir tanto coma como punto.
El tiempo mínimo son 10,00 (10 s).
El tiempo máximo son 23:59:59
Con «tiempo» me estoy refiriendo a duraciones.
Mis dudas preguntas son:
Creéis que son demasiado laxos los formatos a introducir?
Por ejemplo, no tengo claro si esto
'1:6.44'
sería mejor NO validarlo?
O las introducciones que acaban en «:» como por ejemplo:
:16:
16:
las cuales actualmente tienen resultados válidos.
Saludos y gracias por la atención.
duraciones.py
# -*- coding: utf-8 -*-
values = (
':34', # error
'000044', # error
'000000', # error
'106.44', # error
'106.4', # error
'1:06.44', # 1:06,44
'1:6.44', # 1:06,44
'1:6.4', # 1:06,40
'16.44', # 16,44
'16:44', # 16,44
'16.4', # 16,40
'16.', # 16,00
':16: ', # 16,00
'16: ', # 16:00.00
'.16: ', # error por inferior a 10,00
'34.15', # 34,15
'3415', # 34,15
'1:30:44', # 1:30:44,00
'13044', # 1:30,44
'1:60.44', # error
'A1b:6.44', # error
'00:00.44', # error por ser inferior a 10,00
'00:10.4', # 10,44
'59:00.44', # 59:00,44
'0:59:00.44', # 59:00,44
'23:59:59.99', # 23:59:59,99
'10.00', # 10,00
'12:34:15', # 12:34:15,00
'123415', # 12:34,15
'2:01:23.56', # 2:01:23,56
'2012356', # 2:01:23,56
'23:01:23.56', # 23:01:23,56
'23:01:23:56', # esto pasa a 23:01:23:56.00 por lo que da error al
pasar el valor máximo 23:59:59.99
'25:01:23.56', # error, el valor máximo es 23:59:59,99
'25012356', # error, el valor máximo es 23:59:59,99
)
def validate(value):
'''
value is a duration string
return hundredths integer
'''
hundredths = 0
tempo_formatado = ''
value = value.strip()
error = ''
partes = []
if value.isdigit(): # valida introducción de marca sólo con números
digits = value
len_digits = len(digits)
if len_digits == 4:
partes = [digits[-2:], digits[-4:-2]]
elif len_digits in (5, 6):
partes = [digits[-2:], digits[-4:-2], digits[-6:-4]]
elif len_digits in (7, 8):
partes = [digits[-2:], digits[-4:-2], digits[-6:-4],
digits[-8:-6]]
else:
partes = []
error = 'Exceeded the maximum number of digits.'
else: # valida introducción de marca con puntuación
# busca a última puntuación e separa
for pos in range((len(value)-1), -1, -1):
if value[pos] in ('.',','):
partes = value.split(value[pos])
# repair void
for x, i in enumerate(partes):
if not i:
partes[x] = '00'
if len(partes) > 2:
error = 'value mal formed'
partes = []
else:
partes = partes[0].split(":") + [partes[1], ]
break
elif value[pos] == ':':
partes = value.split(":")
# repair void
for x, i in enumerate(partes):
if not i:
partes[x] = '00'
partes.append('00')
break
if len(partes) in (2, 3, 4):
partes = partes[::-1] # reverse
for x, i in enumerate(partes):
if i.isdigit():
if len(i) == 1:
if x == 0:
partes[x] = '%s0' % i
else:
partes[x] = '0%s' % i
else:
partes = []
error = 'ilegal characters'
break
else:
error = 'value mal formed'
partes = []
while len(partes) > 1 and int(partes[-1]) == 0:
partes.pop()
if len(partes) in (2, 3, 4):
# check partes ranges
for x, i in enumerate(partes):
if x == 0:
if int(i) > 99:
error = 'value out range'
break
else:
hundredths += int(i)
elif x == 1:
if int(i) > 59:
error = 'value out range'
hundredths = 0
break
else:
hundredths += int(i) * 100
elif x == 2:
if int(i) > 59:
error = 'value out range'
hundredths = 0
break
else:
hundredths += int(i) * 6000
elif x == 3:
if int(i) > 23:
error = 'value out range'
hundredths = 0
break
else:
hundredths += int(i) * 360000
if hundredths:
tempo_formatado = partes[::-1]
tempo_formatado[0] = str(int(tempo_formatado[0])) # quita
o cero incial
tempo_formatado = ':'.join(tempo_formatado)
tempo_formatado = tempo_formatado[::-1].replace(':', ',',
1)[::-1]
print('{} -> {} -> {} {}'.format(value, tempo_formatado,
hundredths, error))
return hundredths
for value in values:
validate(value)
--
Dani
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <https://mail.python.org/pipermail/python-es/attachments/20210316/7184bbb2/attachment.html>
Más información sobre la lista de distribución Python-es