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 分の場合) で余分な文字列を確認するだけでよいことはわかっていますが、それはうまくいくようで、一部の人にとっては正規表現よりも読みやすいかもしれません。人。

また、ほぼ同じif-thenブロックを 2 回繰り返しているため、DRY に違反していると感じています。みたいなことを考えていた...

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-then1行に2つの略記も少し醜く見えます...

提案やヒントをいただければ幸いです。ありがとう!

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

これは Python での私の最初の試みであるため、これが実際の目標を完全に逃している場合、またはエラーが発生している場合は、お知らせください。削除します。

物事をDRYに保ち、「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() 

上記で考慮されていない 1 つの条件は、duration が 0 または空白の場合です。これは「0 分」を返すはずですが、これは簡単な修正であり、ニーズに任せるのが最善です。

また、strip()メソッドに追加しました。そうしないと、2 つの単位のいずれかがゼロになると、先頭または末尾にスペースが残ります。

于 2012-05-03T06:31:03.570 に答える
1

これは、あなたが説明した並べ替えを含め、モジュラー単位の変換に使用します。UCI で働いていたときに書いたもので、UCI は特定のオープンソース ライセンスの下で配布する許可を与えました。

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

POSIX シェル スクリプトのシェル呼び出し可能として使用することも、インポートを介して Python モジュールとして使用することもできます。

私はそれを製品品質と考えており、実際に製品の役割 (バックアップ) で定期的に使用しています。

于 2012-05-03T05:20:32.230 に答える