2016-10-03 2 views
3

Я даже не уверен, как задать этот вопрос; Я занимаюсь программированием около месяца, и прогресс, который я сделал в этой программе, по-прежнему немного выше моей головы, поэтому я сожалею, если вопрос немного непонятен. Я беру класс программирования, но, насколько мне известно, эта программа предназначена только для моей собственной функциональности и наслаждения музыкой.Как делать вычисления в списках с * args в Python 3.5.1

Я пытаюсь написать функцию, которая принимает музыкальные ноты, представленные целыми числами, и выплескивает определенную компоновку и преобразование этих чисел. В частности, я пытаюсь преобразовать их в нечто из теории музыкальных множеств, называемой «простой формой».

Я написал функцию, которая успешно делает это для набора из трех шагов, но я хотел бы расширить его, чтобы у меня могло быть любое количество аргументов для функции.

Вот код для первой функции

def prime_form (pitch1, pitch2, pitch3, tones_in_octave = 12): 
    """ 
    (int, int, int, int) -> (str) 

    finds the prime form of any 3 note pitch set in any equal temperament, 
    one octave span of frequency classes (default is 12 tones). 

    >>> prime_form (9, 1, 5) 
    (0 4 8) 
    this is the prime form! 
    >>> prime_form (11, 1, 0) 
    (0 1 2) 
    this is the prime form! 
    >>> prime_form (1, 3, 4) 
    (0 1 3) 
    this is the prime form! 
    """ 
    pitches = [pitch1 %tones_in_octave, pitch2 %tones_in_octave, pitch3 %tones_in_octave] 
    spitches = sorted(pitches) 
    intervals = [(spitches[1] - spitches[0]) %tones_in_octave, (spitches[2] - spitches[1]) %tones_in_octave, (spitches [0] - spitches[2]) %tones_in_octave] 
    sintervals = sorted(intervals) 
    prime_form = [0, sintervals[0], sintervals[0]+sintervals[1]] 
    print('({} {} {})\nthis is the prime form!'.format(prime_form[0], prime_form[1], prime_form[2]))   

я узнал немного о * аргументах, и это то, что я закончил с после некоторой помощи от программистов гораздо умнее, чем я.

def prime_form (*pitches, tones_in_octave = 12): 
    tones_in_octave=int(tones_in_octave) 
    spitches = list(set(sorted([pitch %tones_in_octave for pitch in list(pitches)]))) 
    print(spitches) 

Параллельное последнюю программу, это делает то, что мне нужно это делать до сих пор до той части, где я начинаю определение «интервалов», но я не знаю, как идти об этом. Наверное, я мог бы написать много утверждений if, но теоретически, если бы я хотел сделать его функциональным для tones_in_octave = 12, тогда мне пришлось бы написать много сообщений if и elif, и даже тогда, если бы я хотел пройти мимо этого (есть даже установленная музыкальная система, которая использует 43 тонов в октаве, хотя эта конкретная система не выиграет от этой функции), мне пришлось бы написать кучу их вручную, и даже тогда моя функция перестанет работать в точке I решите остановиться.

В этом случае то, что я хотел бы, чтобы написать буквально в коде будет

sintervals = sorted([(spitches[1] - spitches[0]) %tones_in_octave, (spitches[2] - spitches[1]) %tones_in_octave, …, (spitches[n-1] - spitches[n-2]) %tones_in_octave, (spitches[0] - spitches[-1]) %tones_in_octave]) 

Где п число элементов в списке spitches (который отличается от элементов в * смол, поскольку определяется способ spitches удаляет избыточные значения)

Вопрос 1. Как определить переменную как этот список в python?

После этого, добавив интервалы, как это дает PRIME образуют

prime_from = [0, sintervals[0], sintervals[0] + sintervals[1], sintervals[0] + sintervals[1] + sintervals [2], ..., sintervals[0] + sintervals[1] + ... + sintervals[n-2]] 

Где п число элементов в sintervals (а также количество элементов в этом списке)

Вопрос 2. Как сделать Я добавляю такие числа в зависимости от количества элементов в моем списке из Вопроса 1?

Edit:

Вот объяснение того, что в конечном счете пытается осуществить, извините, если это не ярчайший (это может быть даже утончаются неправильно aahahaha позволяет надеяться не).

--- ПРЕДПОСЫЛКИ: Пек и октав ---

В наиболее широко используется система музыки, конкретные частоты воздушных колебаний называют «смолы»; Частота основного тона вычисляется путем

(ссылка) * 2^(расстояние от ссылки смол/смол в октаву)

Термин «октава» является (^ х 2): 1 Частота отношения где х - целое число, а x = «количество октав»; эта связь важна, потому что мы, люди, воспринимаем частоты колебаний воздуха, связанных октавами/это отношение, более или менее одинаковыми. Частота, наиболее часто используемая для эталонного тона в этой системе музыки, составляет «A 440», что означает «A4» - это частота 440 Гц. 4 в «A4» - это номер регистра, для которого «октавный регистр» находится в записке. Регистры октавы делятся на высоту C, поэтому A4 является «выше» или «с более высокой частотой, чем« C4 (которая имеет частоту (440)^- 9/12 = ~ 261,6 Гц). A0 = 27,5 Гц, А1 = 55 Гц, А2 = 110 Гц и т. Д. (Вы можете сказать, что система алфавитной записи, которую мы все еще использовали, была задумана до измерения частоты колебаний воздуха)

--- Фон: Теория музыки ---

В теории музыки, Теория множеств - один из хорошо установленных инструментов, используемых для подхода к теории музыки. Теория музыкальных наборов абстрагирует шаг как целые числа. Он также обычно игнорирует октавные регистры, обрабатывая A4, полностью равный A2, A3, A6 и т. Д. В вышеупомянутой самой популярной системе музыки в октаве есть 12 тонов, поэтому способ ссылки на этапы в теории множеств изменяется от (C , C#, D, D #, E, F, F #, G, G #, A, A #, B) до (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) соответственно ; чтобы все были на одной странице, есть имя, когда октавные регистры рассматриваются как нерелевантная информация для поля, называемого «класс основного тона». С классами тангажа все математические вычисления выполняются в моде 12, как циферблат, так как в октаве 12 тонов.

Также в теории множеств есть полезный способ перечислить набор шаговых классов («класс основного тона»), называемый «простой формой». Прайм-формы, также называемые заданными классами, рассматриваются как наиболее сжатый и абстрактный способ представления наборов классов тона.

--- То, что я пытаюсь выполнить ---

Я хочу написать код, который съедает наборы классов тангажа и выплевывает набор классов/премьер-форму. В качестве примечания, первичная форма должна начинаться с нуля, если она удовлетворяет другим требованиям (крайняя левая часть с учетом инверсии множества) и не начинается на 0, а затем будет перенесена на 0 Ex. [1,2,4] является самой лево-компактной компоновкой с учетом ее инверсии [1,3,4], но не начинается с нуля, поэтому множество транспонируется на (-1) до (0 1 3), которое является его премьер от. У человека, пытаясь выяснить основную форму обычно занимает несколько шагов, чтобы прибыть в ответе:

  1. Удалить лишние Смолы классов - если вы получаете смолы, такие как (1, 13, 0, 2, 0), удалить 13, потому что он является избыточным с 1 (13% 12 = 1) и удаляет второе 0.

  2. Упорядочить классы основного тона в пределах одного октавного диапазона - (не обязательно октавный регистр, октавный регистр понимается всегда на основе шаг C и октавный диапазон относятся к диапазону любых двух нот с соотношением частот 2: 1, а не только к двум Cs на октаву друг от друга.). В качестве примера мы бы упорядочили (10, 9, 0, 11) как (0, 9, 10, 11) (начиная с нуля/в пределах октавного регистра) или [9,10,11,0] (Нормальная форма/leftmost-compact) или несколько других способов, которые, вероятно, не так полезны.

  3. Найти интервалы - интервал в этом случае является абсолютным значением разности смежных классов основного тона в одной октаве: 9-10 или 10-9 = 1, 10-11 = 1, 0-11 = 1 (0 должно быть на мгновение задумано как 12, это случай, когда числа охватывают точку петли для «циферблата» мод 12 и прикручивают математику) и 0-9 (0 хорош как 0 здесь так как он не пересекает точку цикла, если 0 считается равным 12, вы получаете неверный интервал) = 9. В этот момент разность первого и последнего интервалов в этом случае 9 также рассматривается в случае существует набор, подобный [3,4,7,9,0] или [1,2,4,5,7,8,10,11], где есть связь между интервалами. Таким образом, вы не можете игнорировать последний интервал.

  4. Отрегулируйте интервалы в соответствии с инверсиями и самой левой-компактностью - вот почему мы нашли интервалы; интервалы абстрагируют фактический шаг, поэтому нам не нужно переносить его на 0 (поскольку требование простой формы состоит в том, что список начинается с 0), и поэтому мы можем перечислить наши интервалы в самом левом компактном режиме между «нормальным »и« перевернутый »список интервалов (по часовой стрелке и против часовой стрелки на поверхности часов) для вычисления первичной формы. Способ, которым человек будет это делать, - начать с точки в списке интервалов и переименовать его влево или вправо с этой точки, сохраняя интервалы в том же порядке, что и те, которые они соответствуют, и петля, когда это необходимо.

    1. Выбрать правильный список интервалов и рассчитать простой вид - (0,9,10,11) Список интервалов времени (9,1,1,1), что мы сделать здесь выбрать самую левую компактную версию, которая игнорирует 9, так как она является наименее компактной, а затем использовать интервалы, чтобы построить основную форму, которая (0 1 2 3)

для (9,11,1,2,4,6,8), список интервалов равен (2,2,1,2,2,2,1,1). самый левый компакт (1, 2, 2, 1, 2, 2, 2), поэтому основной формой является (0 1 3 5 6 8 10).

Однако на этом последнем этапе есть некоторые разногласия, разногласия между алгоритмами Рана и Форте. Это связано с тем, что критерии, которые я излагал, приводят к двум ответам в пяти конкретных случаях, потому что в этих случаях вопрос «что является самым компактным?» требует большего определения. Честно говоря, я не имею в виду, если изменить tones_in_octave на что-то, кроме 12, каким-то образом измените эти исключения на критерии, которые я представил или нет. Я также не знаю, как объяснить различия между двумя алгоритмами в терминах интервалов, поскольку алгоритмы определяются на основе определенных интервалов основного тона от 0, которые вызывают несогласие между тем, что является самым левым компактным, а не фактическим порядком интервалов. Думаю, я должен поработать над этим, если я хочу закончить эту программу.

Python, похоже, хорошо следит за этими шагами от того, что я показал Stack Overflow и других источников (кроме, может быть, сортировки интервальных списков), это просто вопрос, как его обобщить настолько, чтобы функция работает для потенциально бесконечного количества аргументов. Благодаря Моисею Коледою, который делает большую часть тяжелого подъема, обобщая функцию для работы с * args, кажется, есть только одна проблема, которая не была решена, которая сортирует список интервалов по способу, показанному выше на шаге 4. (остальные шаги работают очень хорошо, версия Коледоя 3-го шага дала неверные интервалы, но, применяя mod 12 к ответу, он придумывал иногда исправления, что для случаев, когда шаг 4 срабатывает правильно (И НЕКОТОРЫЕ ВРЕМЯ ВИНТЫ ЭТОГО UP).

Вот код с ошибочным шагом 4, напечатайте сообщения, чтобы уведомить о том, что только что определено, и дополнительный шаг в конце, что SOMETIMES исправляет случаи, когда шаг 3 не работает должным образом, я полагаю , математика по «точке петли»/«clockface», а в других случаях испортить ее, когда это было правильно с кодом Коледоя.

def prime_form (*pitches, tones_in_octave = 12): 
    tones_in_octave=int(tones_in_octave) 
    spitches = list(set(sorted([pitch %tones_in_octave for pitch in list(pitches)]))) 
    print('{}\nthis is the sorted list of pitches \n'.format(spitches)) 

    lth = len(spitches) 
    print('{}\nthis is the length of spitches \n'.format(lth)) 

    intervals = [(spitches[0 if (i+1) >= lth else (i+1)]-x) % tones_in_octave for i, x in enumerate(spitches)]  
    print('{}\nthis is the interval list \n'.format(intervals)) 

    sintervals = sorted(intervals) 
    print('{}\nthis is the sorted interval list \n'.format(sintervals)) 

    p_form = [sum(sintervals[:i]) for i in range(len(intervals))] 
    print('{}\nthis may be the prime form, but maybe not \n'.format(p_form)) 

    true_p_form = list({i % tones_in_octave for i in p_form}) 
    print('({})\nthis is the prime form! (apparently it might not be)'.format(' '.join(map(str, true_p_form)) 

и вот несколько примеров, чтобы попытаться

>>> prime_form(9, 3, 0) 
(0 3 6) 
this is the prime form! 

>>> prime_form(1, 11, 9, 4, 2, 6, 8) 
(0 1 3 5 6 8 10) 
this is the prime form! 

>>> prime_form(10, 9, 0, 11) 
(0 1 2 3) 
this is the prime form! 

А вот калькулятор, который уже делает большинство из этого и более (за исключением изменения количества тонов в октаве) http://composertools.com/Tools/PCSets/setfinder.html

У него даже есть объяснение разницы между алгоритмами Рана и Форте.

ответ

0

следующее довольно много делает то, что вы хотите.

  • Хитрая часть является вычисление интервалов, было сделано с помощью enumerate вычесть текущий элемент из пункта на следующий индекс и вычитая последний элемент из первого.

  • Кумулятивы взяты суммирование кусочки вычисленного sintervals. Индекс остановки каждого среза увеличивается на 1, чем предыдущий:

  • последняя частью является частью форматирования, который использует .join для присоединиться элементов списка, которые затем отформатированы.


def prime_form(*pitches, tones_in_octave=12): 
    # pitches = set(pitches) 
    spitches = sorted([p % tones_in_octave for p in pitches]) 
    lth = len(spitches) 

    # Question 1 
    intervals = [(spitches[0 if (i+1) >= lth else (i+1)]-x) % tones_in_octave for i, x in enumerate(spitches)]  
    sintervals = sorted(intervals) 

    # Question 2 
    p_form = [sum(sintervals[:i]) for i in range(len(intervals))] 

    print('({})\nthis is the prime form!'.format(' '.join(map(str, p_form)))) 

Тесты:

>>> prime_form(9, 1, 5) 
(0 4 8) 
this is the prime form! 

>>> prime_form(11, 1, 0) 
(0 1 2) 
this is the prime form! 

>>> prime_form(1, 3, 4) 
(0 1 3) 
this is the prime form! 
+2

было бы неплохо, если бы downvoter мог оставить комментарий –

+0

кстати спасибо тонну! (Я все еще пытаюсь понять все это, это потрясающе) Были проблемы с кодом, потому что я глупый и не могу объяснить эту тему достаточно хорошо. Также я должен был предоставить тесты. проблема 1. Когда генерируется список интервалов, иногда он дает слишком большие интервалы, как в случае с параметром prime_form (9,0,3). [9,6,9] вместо [3,6,3], потому что sorted() не обрабатывает 0 так же, как мне бы хотелось. Когда он сортирует и генерирует «p_form»,% tones_in_octave может быть применен к списку, чтобы получить основную форму, поэтому не стоит беспокоиться об этом. –

+0

Ok @JamesWilkinson Glad Я мог бы помочь. Вы уже нашли способ решить эту проблему? И если ответ помог, вы можете подумать о принятии :) –

Смежные вопросы