2

私はPythonを学んでいます。奇妙な衝動から、私は10進時計を作成しようとしています。この10進時計は、1日を1日10時間、1時間100分、1分100秒に分割します。10進数の日に100,000秒あります。「古語」の時間で86,400。古風な時間の1秒ごとに、新しく改善された10進時間の約1.157秒に相当します(数学が少し正しいと仮定します)。

私が直面している問題は、時計が小数秒を正確かつ連続的に刻むために、1.157秒ごとに可能な限り正確に発火する関数が必要なことです。DeciTimeCaller無限にループする呼び出し関数があり、decimaltime.time_to_stringメソッドを呼び出します。このメソッドは、古風な時間から10進数の時間に変換し、時間を10進数の時間:分:秒で出力します。次に、呼び出し元の関数はスリープし、、、time.sleep(1.157)そしてそれをすべて実行します。

しかし、バックグラウンドプロセスが優先されるため(私は推測します)、印刷される時間はあちこちで数秒スキップします。

たとえば、約20秒からの出力は次のとおりです。

0:85:92
0:85:93
0:85:95
0:85:96
0:85:97
0:85:99
0:86:00
0:86:01
0:86:03
0:86:04
0:86:05
0:86:07
0:86:08

PythonとLinuxはリアルタイムシステムを構成していないことを認識しており、他のスレッドでいくつかの提案を試しました。たとえば、Pythonで正確な時間スリープするなど、成功しませんでした。しかし、私はこれをごまかす方法があるかもしれないと思っています。

だから問題は、この時計を時計仕掛けのように動かすことができるかということです。

私のコードは以下の通りです。注意すべき点がいくつかあります。イベントを操作しようとしていたため、スレッドモジュールをインポートしましたが、現在は使用していません。変換時の浮動小数点値の精度に問題があるのではないかと思ったので、10進モジュールを使用します。違いはないようです。また、timeitモジュールと、呼び出しの時間を計ろうとしているコメント付きのコードもあります。

import time
import datetime as dt
import decimal
import threading
import timeit

class decimaltime:
  """ Presents the time of day in Decimal Time 
      10 Hours/day
      100 minutes/hour
      100 seconds/minute
  """
  def time(self, archaic_seconds = 0):
    if archaic_seconds == 0:
      now = decimal.Decimal(dt.datetime.now().strftime('%s.%f'))
      midnight = decimal.Decimal(dt.date.today().strftime('%s.%f'))
      archaic_seconds_from_midnight = decimal.Decimal(now - midnight)
    else:
      archaic_seconds_from_midnight = decimal.Decimal(archaic_seconds)
    return archaic_seconds_from_midnight * decimal.Decimal('1.157')

  def time_to_string(self, decimal_seconds = 0):
    if decimal_seconds == 0:  
      seconds_from_midnight = self.time() 
    else:
      seconds_from_midnight =  decimal.Decimal(decimal_seconds)
    decimal_hour = seconds_from_midnight / 10000
    decimal_minute = (seconds_from_midnight % 10000) / 100
    decimal_second = seconds_from_midnight % 100
    time_string = "%(hour)01d:%(minute)02d:%(second)02d" % {"hour": decimal_hour, "minute": decimal_minute, "second": decimal_second}
    print time_string
    # return time_string

def DeciTimeCaller():
  decitime = decimaltime()
  # t = timeit.Timer(lambda: decitime.time_to_string())
  while True:
    # print t.timeit(1)
    decitime.time_to_string()
    time.sleep(1.157)

DeciTimeCaller()

アップデート:

以下のThomasの提案から、1/10秒ごとに10進時間をチェックするようにコードを変更しました。小数点以下の時間が変更された場合は、時刻を出力します。これはまさに私が探していた時計仕掛けのように機能します。

改訂されたDeciTimeCaller関数は次のとおりです。

def DeciTimeCaller():
  decitime = decimaltime()
  old_time = decitime.time_to_string()
  while True:
    new_time = decitime.time_to_string()
    if (new_time != old_time): 
      print new_time
      old_time = new_time
    time.sleep(.1667)
4

1 に答える 1

2

関数を正確な頻度で実行することは非常に困難です。

現在のシステム時刻を 10 進時刻に 30 回/秒変換する関数を作成できます。このようにして、時刻は常に正確になり、同期がずれることはありません。

于 2013-03-15T07:41:44.450 に答える