ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: не уверен, подходит ли заголовок, и это мой первый пост, поэтому я учусь, как организовать его
ИСТОРИЯ КОДА:
Я создаю фрактальное пламя (повторяющиеся изображения) с помощью Apophysis7x и открываю файл .flame (этот файл не визуализируется, он просто содержит информацию для открытия в другом редакторе) в Fractal Fr0st, где я могу, например, автоматизировать итерацию, которая будет постоянно вращаться. тем самым создавая анимацию. Fractal Fr0st использует python для такой автоматизации, однако она постоянна. Я создаю музыку и надеюсь когда-нибудь завершить мой код, чтобы чередовать вращения в зависимости от BPM моей песни. Я начал кодировать самостоятельно, чтобы создать последовательность тик-так, даже не отредактировав фактический файл Python, связанный с программой (этот код пока не совсем важен, но опубликован в конце)
ИНФОРМАЦИЯ ПО ПРОБЛЕМЕ:
Я с самого начала знаю, что Python не самый быстрый язык, но я не уверен на 100%, что мой код просто недостаточно эффективен, чтобы не отставать от того, что я пытаюсь получить на выходе. Пожалуйста, взгляните на мой код и комментарии, поскольку я пытаюсь максимально подробно объяснить, что происходит.
timer.py:
import time
#Feel free to test as you'd like
#Suppose we have a song at 140 Beat Per Minute (BPM) -> There is approximately 2.33 Beats Per Second (BPS)
#So it takes approximately 0.43 (s) per beat
#So if freq = 0.43, leng = *length of song*
#This program should alternate printing "tick" "tock" (or some action that I hope to code in the future)
#The Tick Tock output should come out every (in this case) .43 seconds
class timer(object):
"takes in a frequency and duration of loop in seconds"
def __init__(self,freq,leng):
"input a frequency and duration in seconds"
#rounded to 2 decimal places
self.freq= round (freq,2)
self.leng= round (leng,2)
def ticker (self):
"Starts the time and loop to be broken when max time is reached"
counter = 0 #recorded out of curiosity to check just how many loops were made overall
ticker = 0 #alternates the "tick" "tock"
initTime = time.time() #records the initial upon starting the loop
rnded = 0 #initial rounded time set at 0 *see the first if statement below*
while True:
stop = time.time() #The time recorded during the loop *stopwatch so-to-speak*
passed = stop - initTime #The time passed from initial launch to time during the loop
if rnded == self.leng:
"When the time that has passed reaches time limit print stats and break"
return print("Loops:".ljust(10).rjust(14) + "Initial Time:".ljust(17).rjust(21) + "Time Stopped:".ljust(17).rjust(21)+ "Passed:".ljust(11).rjust(15) + "Total Ticks:".ljust(16).rjust(20) + "\n" + (str (counter) ).ljust(10).rjust(14) +(str (initTime) ).ljust(17).rjust(21)+ (str (stop) ).ljust(17).rjust(21)+(str (rnded) ).ljust(11).rjust(15) + (str (ticker) ).ljust(11).rjust(15) )
elif round(passed,2) == rnded:
"Prevents duplicates, ie: previous stopped at .9999 (1.0) and current loop sopped at 1.001 (1.0) skip"
#If your current value happened to be rounded to the previous value don't continue
#uncomment bellow for debugging
#print ("*TEST* \t Initiated: ", initTime, "\t Time stopped: ",stop, "\nTime passed: ", rnded, "\t Tick Counter: ", ticker, "\n ---")
pass
else:
"Tick tock code"
rnded = round(passed,2) #now set current time differnce value after being checked for duplicates
if rnded % self.freq == 0 and rnded != 0:
"if the time passed mod the frequency is 0 continue to execute tick tock"
if ticker % 2 == 0:
#gives stats for debugging purposes, delete, after "tick" / "tock" if desired
#prints in the meantime in the future I would like an action to be done with music in another program as precise as possible
print ("Tick \t Initiated: ", initTime, "\t Time stopped: ",stop, "\nTime passed: ", rnded, "\t Tick Counter: ", ticker, "\n ---")
elif ticker % 2 == 1:
print ("Tock \t Initiated: ", initTime, "\t Time stopped: ",stop, "\nTime passed: ", rnded, "\t Tick Counter: ", ticker, "\n ---")
ticker +=1 #only increases if tick/tock was processed
counter += 1 #counts how many times loop was accessed, use this as you'd like
def chngFreq(self, freq):
'Changes current frequency'
self.freq = round (freq,2)
def chngLeng(self,leng):
'Changes current duration'
self.leng = round(leng,2)
Пример 1:
Вывод пропускает несколько «тиков» / «тиков» по мере того, как частота становится быстрее (я просто тестировал, например, когда частота была 0,01 (с) и общее время 4 (с), всего должно быть 399 тиков. тем не менее, он достиг только 5 тиков.Моя теория заключается в том, что, поскольку для прохождения цикла требуется время (хотя и очень небольшое время), он может пропустить тик из-за некоторой вероятности того, что до перехода к следующему тику от . От 01 до .02 до округления это могло быть галочкой, но код обрабатывался недостаточно быстро Я округлил до конца, чтобы быть как можно более точным, и сделал часть «элиф», чтобы предотвратить дублирование (см. код выше)
Вывод:
>>>s = timer(.01,4)
>>>s.ticker()
Tick Initiated: 1502409793.6775877 Time stopped: 1502409793.6937597
Time passed: 0.02 Tick Counter: 0
---
Tock Initiated: 1502409793.6775877 Time stopped: 1502409793.7562232
Time passed: 0.08 Tick Counter: 1
---
Tick Initiated: 1502409793.6775877 Time stopped: 1502409793.8409605
Time passed: 0.16 Tick Counter: 2
---
Tock Initiated: 1502409793.6775877 Time stopped: 1502409793.9940765
Time passed: 0.32 Tick Counter: 3
---
Tick Initiated: 1502409793.6775877 Time stopped: 1502409794.9579115
Time passed: 1.28 Tick Counter: 4
---
Loops: Initial Time: Time Stopped: Passed: Total Ticks:
5473896 1502409793.6775877 1502409797.680171 4.0 5
Обратите внимание, что иногда галочка засчитывается только для 2^x, например: .01, .02, .04, .08, .16, .32... < strong>Вместо: .01, .02, .03, .04, .05, .06...
Я знаю, что это не тот пример, который я привел в своем коде, но это верно всякий раз, когда я пробую более приблизительную частоту, такую как 0,23 или 0,01, но чем больше частота, независимо от точности, например: 4,29, тем больше вероятность того, что она будет точной. вернуть "галочки" 4.29, 8.58, 12.87 и т.д...
Пример 2
В следующем примере вы можете сказать, что он работает отлично, так как ему дается больше времени для обработки между тиками.
>>>s = timer(1,4)
>>>s.ticker()
Tick Initiated: 1502411198.8088021 Time stopped: 1502411199.8091898
Time passed: 1.0 Tick Counter: 0
---
Tock Initiated: 1502411198.8088021 Time stopped: 1502411200.8089292
Time passed: 2.0 Tick Counter: 1
---
Tick Initiated: 1502411198.8088021 Time stopped: 1502411201.81057
Time passed: 3.0 Tick Counter: 2
---
Tock Initiated: 1502411198.8088021 Time stopped: 1502411202.8121786
Time passed: 4.0 Tick Counter: 3
---
Loops: Initial Time: Time Stopped: Passed: Total Ticks:
5586557 1502411198.8088021 1502411202.8328226 4.0 4
Пожалуйста, дайте мне знать, если что-то в этом коде неясно, но обязательно сначала прочитайте каждый комментарий и запустите код или измените его, если это необходимо.
Как только моя предыдущая проблема будет решена, я надеюсь изменить раздел «if x.animate:» следующего кода, который используется в Fractal Fr0st.
default.py:
update_flame = False
while True:
for x in flame.xform:
if x.animate:
x.rotate(-3)
preview()
Наконец, спасибо заранее, я знаю, что это действительно долго, но я действительно пытаюсь понять, что происходит с python/как он работает, независимо от моей конечной цели.
Также, если какие-либо другие методы быстрее/эффективнее, сообщите мне. Спасибо!!!
numpy
, для эффективной работы с такими массивами. - person jasonharper   schedule 11.08.2017numpy
иscipy
, поэтому я не знаю, что взять, но затем в одном из комментариев здесь на это был дан ответ: В последний раз, когда я проверял это, метод scipy__init__
выполняетfrom numpy import *
, что означает, что он в основном влечет за собой всеnumpy
? - person BHerna   schedule 11.08.2017