1

我目前有我的 Django 自定义模板过滤器,如下所示:

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())诀窍是我从这个解决方案中得到的东西。我意识到我只需要在字符串的开头或结尾检查额外的字符串(当它是 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块的情况下在“小时”或“分钟”之间进行选择。另外每行的两个速记if-then也看起来有点难看......

我将不胜感激任何建议或提示。谢谢!

4

3 回答 3

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,其余的只是字符串解析。

于 2012-05-03T07:25:55.107 回答
1

我将其用于模块化单位转换,包括您描述的那种。我在为 UCI 工作时编写了它,UCI 允许在特定的开源许可证下分发它:

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

您可以将其用作 POSIX shell 脚本的可调用 shell,也可以通过导入将其用作 python 模块。

我认为它具有生产质量,并且确实定期在生产角色(备份)中使用它。

于 2012-05-03T05:20:32.230 回答
1

这是我第一次尝试 Python,所以如果这完全没有达到您的实际目标或出现错误,请让我知道,我会删除。

为了保持干燥,并消除“0小时”或“1分钟”的输出,这应该有效,只要我们接受基本单位(在本例中为分钟和小时)可以通过简单地添加复数的前提一个's'。任何更复杂的东西,你会想要一个 python ninja:

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()方法中添加了,否则如果两个单位之一归零,您将留下前导或尾随空格。

于 2012-05-03T06:31:03.570 回答