2012-05-03 28 views
1

目前,我有我的Django的自定义模板过滤器是这样的:编写一个将整数分钟转换为格式为“X小时(s)Y分钟”的字符串的函数的最佳方法是什么?

from django import template 

register = template.Library() 

@register.filter 
def duration(value): 
    hours = value/60 
    minutes = value % 60 

    hours_string = str(hours) + (" hours" if hours > 1 else " hour" ) if hours else "" 
    minutes_string = str(minutes) + (" minutes" if minutes > 1 else " minute") if minutes else "" 

    return ' '.join("{hours} {minutes}".format(hours=hours_string, minutes=minutes_string).split()) 

一些可能的输出:

1 hour 25 minutes 
2 hours 
45 minutes 
3 hours 1 minute 

' '.join(....split())招是我从this solution了。我意识到我只需要在字符串的开头或结尾检查额外的字符串(因为当它是0小时或0分钟时),但它看起来有诀窍,也许比正则表达式更容易阅读人。

我也觉得我违反DRY,因为我几乎重复了两次完全相同的if-then块。我在想是这样......

for i, unit in enumerate([hours, minutes]): 
    # Do some code. 

return ' '.join("{hours} {minutes}".format(hours=value[0], minutes=value[1]).split()) 

,但我无法弄清楚如何在不另if-then块“小时(S)”或“分钟”之间进行选择。另外两条短线if-then每条线也看起来有点丑陋...

我会感谢任何建议或提示。谢谢!

+1

更糟的是,你没有I18Nize它**。 –

+0

'i18n'是我以后要看的很多东西。这是我现在应该担心的事吗?我不需要翻译网站上的每个文本吗? – hobbes3

+2

如果你现在不担心,尤其是在这个问题上,你将会陷入一个痛苦的世界。 –

回答

2
import datetime 
def pprint(val): 
    if val == 1: 
     return '1 minute' 
    x = str(datetime.timedelta(minutes=val))[:-3].split(':') 
    r = '' 
    if int(x[0]): 
     r += x[0]+' hours' if int(x[0]) > 1 else x[0]+' hour' 
    if int(x[1]): 
     r += ' %s minutes' % int(x[1]) if int(x[1]) > 1 else ' %s minute' % int(x[0]) 
    return r.strip() 

采样运行:

>>> pprint(65) 
'1 hour 5 minutes' 
>>> pprint(1) 
'1 minute' 
>>> pprint(60) 
'1 hour' 
>>> pprint(61) 
'1 hour 1 minute' 

您可以轻松地扩展为包括天为好,但既然你特别提到只有小时和分钟我调整方法。

主要的繁重工作是由datetime.timedelta完成的,其余的只是字符串解析。

1

我将此用于模块化单位转换,包括您所描述的排序。我写的工作UCI同时,和UCI给了允许在一个特定的开源许可分发:

http://stromberg.dnsalias.org/~strombrg/modunits/

您可以使用它作为一个外壳可调用的POSIX shell脚本,也可以作为一个通过导入的python模块。

我认为这是生产质量,并且确实定期将其用于生产角色(备份)。

1

这是我第一次尝试Python,所以如果这是完全错过了你的实际目标,或者是出现错误,lemme知道我会删除。

为了保持干燥,并消除“0小时”或“1分钟”的输出,只要我们接受基本单位(本例中为分钟和小时)可以是通过简单地添加's'来复数化。任何事情更加复杂,你会想要一个python忍者:

def format_output(value, unit): 
    if value == 0: 
     return "" 

    singular_output = str(value) + " " + unit 

    if value == 1: 
     return singular_output 
    elif value > 1: 
     return singular_output + "s" 

def duration(value): 
    hours = value // 60 
    minutes = value % 60 

    formatted_string = format_output(hours, "hour") + " " + format_output(minutes, "minute") 
    return formatted_string.strip() 

的一个条件上不占是,如果持续时间为0或空白,我认为应该回到“0分”,但这是一个容易修复,最好留给你的需求。

此外,我在strip()方法中添加了,否则如果两个单位中的一个出来为零,您将留下前导或尾随空格。

相关问题