A record of hell lessons imposed on beginner Python students

**【Character】 M: (= Mentor = Kyoto eagle) Can you see it from Tokyo? Q: (= Tokyo student = graduate of a Python beginner's course) **

print("Looked")

Looked

M: Python has a lot of lesson videos and reference books, but if you stumble a little, you can't move on (there is), so it's good to use them, but I wonder if you should use this place together.

**Narration: This is a record of the hellish one-on-one lessons of Python programming conducted using the sharing capabilities of Google colaboratory. The purpose is basically to learn programming, but as a material, a deep poop about musical scales and chords is developed. ** **

M: Example: Can you draw a graph of y = sin (x) (0 ≤ x ≤ 4π)?

It's a non-essential task, so I'll break it up. (As one method)

import numpy as np
#numpy is a numerical library that is a little smarter than math, and can also be used for matrix operations.
#Since numpy is a long name, we will use np for ease of use.
import matplotlib.pyplot as plt
#Since ita is not included in colab from the beginning, I use a graphic library called matplotlib.

x = np.arange(0, 4 * np.pi, 0.1)  #From 0 to 4π 0.Get 1-step data (like an array).
y = np.sin(x)
plt.plot(x, y)

output_7_1.png

# Q:
print(x)
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.   1.1  1.2  1.3
  1.4  1.5  1.6  1.7  1.8  1.9  2.   2.1  2.2  2.3  2.4  2.5  2.6  2.7
  2.8  2.9  3.   3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9  4.   4.1
  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.   5.1  5.2  5.3  5.4  5.5
  5.6  5.7  5.8  5.9  6.   6.1  6.2  6.3  6.4  6.5  6.6  6.7  6.8  6.9
  7.   7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9  8.   8.1  8.2  8.3
  8.4  8.5  8.6  8.7  8.8  8.9  9.   9.1  9.2  9.3  9.4  9.5  9.6  9.7
  9.8  9.9 10.  10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 11.  11.1
 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 12.  12.1 12.2 12.3 12.4 12.5]
Q: ↑ Why is the graph connected smoothly even though x is discrete in this graph?

M: [Answer 0001] => Good! matplotlib.pyplot.plot () isn't really a smooth graph, It seems to be a method of connecting coordinates and coordinates with line segments, that is, drawing a "line graph". If you increase the tick of x (such as 1), it looks like this. ↓

 x = np.arange(0, 4 * np.pi, 1)
 y = np.sin(x)
 print(x)
 plt.plot(x, y)

kakukaku.png Q: I see.

M: [Issue 0001] Graph of the above sin function Let's fix it and halve the cycle. (Do not change the domain)

# Q:[Answer 0001]
x = np.arange(0, 4 * np.pi, 0.1)
y = np.sin(2 * x)
plt.plot(x, y)

output_11_1.png

M: [Problem 0002] Let's add the data with half the period and amplitude to the original graph of Task 0001.

# Q:[Answer 0002](Whatisdataaddition?Ithinkit'sasuperposition)
x = np.arange(0, 4 * np.pi, 0.1) 
y1 = np.sin(x)
y2 = 0.5 * (np.sin(2 * x))

y = y1 + y2
plt.plot(x, y)

output_15_1.png

M: [Problem 0003] In the original graph of Task 0001, Multiple periods and amplitudes set to 1 / i Let's add the data series. However, i is an integer from 2 to 9. Once you've done that, try setting i up to 99.

# M:[Answer 0003] ①
#Suddenly hint
import numpy as np
import matplotlib.pyplot as plt 
x = np.arange(0, 4 * np.pi, 0.1) 
y = np.zeros(len(x)) 
#y is an all-zero sequence of the same length as x
#len stands for length
print(y) 
#Now let y have 9 series
#You shouldn't add them in order.
#(There are several methods)

for i in range(1,10):
  y_temp = (np.sin(i * x)) / i
  y += y_temp


plt.plot(x, y)
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0.]
![output_18_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216556/a4797ca9-5a0f-e2c9-9bdb-2487cfec49b9.png)

output_17_2.png

# Q:[Answer 0003] ②
y2 = np.zeros(len(x)) #= Line added later
for i in range(1,100):
  y_temp = (np.sin(i * x)) / i
  y2 += y_temp

plt.plot(x, y2)

output_18_1.png

M: Hmm, wonderful! Oh wait a minute! ② is regrettable! If you do not initialize y with zero before the loop, the result of ① will be inherited! Because the amplitude is too big! By the way, isn't it possible to do without using y_temp? So let's fix only ②.

And if you can do that [Problem 0004] In Task 0003②, let's try i with only odd numbers! Q: Really, ② Corrected! You can certainly do it without using y_temp! I wonder if it leads to the story of Fourier transform. I've done it in physics or math!

# Q:[Answer 0004]
y_0004 = np.zeros(len(x))
for i in range(1,100, 2):
  y_0004 += (np.sin(i * x)) / i

plt.plot(x, y_0004)

output_21_1.png

M: It leads to physics, mathematics, and music. If the root note is do, the 2nd overtone is an octave above the do, the 3rd overtone is the above so, the 4th overtone is the 2 octave above the do, and the 5th overtone is the above mi, that is, the constituent notes of the C major chord. (However, values other than do are approximate values) Also, if you play harmonics at the 12th fret position on your guitar, you will get 2 harmonics, and if you are at the 7th fret, you will get 3rd overtones, and if you are at the 5th fret, you will get 4th overtones. (Is the entertainer doing something on the 7th fret?) Actually, the sound of the guitar is close to the sawtooth wave (problem 0003), so when you play an open string normally, it sounds with overtones that are an integral multiple. The sawtooth wave is close to the overtone composition of many musical instruments such as violins and trumpets, in addition to guitars. On the other hand, a square wave (problem 0004), that is, a waveform with many odd harmonics, becomes a woodwind instrument such as a recorder, flute, or oboe. Waveforms with odd harmonics include not only square waves but also triangular waves. https://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E6%B3%A2_(%E6%B3%A2%E5%BD%A2)
In general, a waveform with only odd harmonics has a symmetrical half cycle.

M: [Issue 0005] Assuming that the x-coordinate of the guitar nut is 0 and the x-coordinate of the bridge is 1, the x-coordinate of each fret is

And so on. (... Is it true?)

The following program was intended to plot the position from the guitar nut to the 12th fret (y coordinate fixed at 0). The a and x are calculated incorrectly, and the frets are evenly spaced.

① Can you fix the fret position like the real thing?

(2) Should the harmonics playing method used near the 7th fret be slightly shifted to the nut side or the bridge side?

# M:
import numpy as np
import matplotlib.pyplot as plt
 
a = 1 / 12
n = 13
x = [1 - a * i for i in range(n)] 
y = [0] * n 
print(x)
plt.plot(x, y, "o")
[1.0, 0.9166666666666666, 0.8333333333333334, 0.75, 0.6666666666666667, 0.5833333333333334, 0.5, 0.41666666666666674, 0.33333333333333337, 0.25, 0.16666666666666674, 0.08333333333333337, 0.0]

output_24_2.png

# Q:
import numpy as np
import matplotlib.pyplot as plt
 
a = (1/2)**(1 / 12)
n = 13
x = [1 - a ** i for i in range(n)] 
y = [0] * n 
print(x)
plt.plot(x, y, "o")
[0.0, 0.05612568731830647, 0.10910128185966061, 0.1591035847462854, 0.2062994740159002, 0.25084646156165913, 0.2928932188134523, 0.3325800729149827, 0.3700394750525633, 0.40539644249863926, 0.43876897584531327, 0.4702684528203521, 0.4999999999999998]

output_25_2.png s: The 3rd overtone is x = 0.333 ... On the other hand, the position of the 7th fret is x = 0.3325 ... Therefore, it should be slightly shifted to the bridge side. M: Very well done! So why isn't the 7th fret exactly 1/3 the length of a string?

The answer is, "There is no reason to do that."

The 7th fret position 1- (1/2) ** (7/12) is probably an irrational number (that is, not 1/3), isn't it?

Probably not proof that it will be 1/3.

Historically, was it the time of Mr. Bach? In order to freely transpose the music, it was necessary to design the frequency of the scale as a geometric progression.

That is, the ratio of adjacent frequencies is made constant. Do: Do # = Do #: Les = Les: Les # = ・ ・ ・ Then, when I happened to divide one octave into 12 geometric progressions (this is called equal temperament), I noticed that there were some pleasant pitches.

For example, Domiso feels good (in harmony) when played together. Upon closer inspection, the frequency ratio of Domiso was "roughly" 4: 5: 6.

On the other hand, there is also a scale design that forces the domiso to have a tight ratio (that is, a rational number) such as 4: 5: 6, which is called "just intonation". (The roots are Mr. Pythagoras.) However, in just intonation, it is rarely used because it is necessary to retune (or add a capo).

M: [Problem 0006] Let's implement a function sin_wave that generates arbitrary sine wave data by giving each of frequency, amplitude, number of seconds, and minimum data interval. (The function here is not a mathematical function that finds y from x.)

# M:
import numpy as np
import matplotlib.pyplot as plt

def sin_wave(frequency, amplitude, duration, tick):
    # sine_wave:A function that generates arbitrary sine wave data
    #   frequency:frequency(Hz),  
    #   amplitude:amplitude(V,That is, the bolt), 
    #   duration :Number of seconds of data, 
    #   tick     :Minimum data interval(Seconds), 

    #Implement here.
    # s:
    x = np.arange(0, duration, tick)
    y = amplitude * (np.sin(2 * np.pi * x * frequency))

    return x, y

x, y = sin_wave(frequency=10, amplitude=3, duration=2, tick=0.01)
plt.plot(x, y)

output_29_1.png

M: Issue 0006 = Mostly Good!

In general, calculations that result in constants should be taken out of the loop. For example, if you want to use 2 * np.pi * x [i] * frequency in a for loop that turns i

npf = 2 * np.pi *  frequency
for i in range(0,duration,tick):
    y[i] = amplitude * (np.sin(npf * x[i]))

It will be faster if you do.

However, if you use numpy's vector operation instead of for like this time, the speed may not change much if the implementation of numpy is smart.

M: [Problem 0007] Using the sin_wave function, graphs of the three constituent notes of the basic form of the major chord of A and a total of four series in which they are superimposed are shown in different colors (the color parameter of the plot is set to "r" respectively. Let's make it "," g "," b "," k ") and draw it on one coordinate system.

However, the time is 0.02 seconds, the minimum data interval is 1 / 10,000 second, the fundamental frequency of A is 220Hz, and the amplitude of the constituent sounds is 1V.

Q: I did it by intuition </ font>

# Q:
x, y1 = sin_wave(frequency=220, amplitude=1, duration=0.02, tick=0.0001)
plt.plot(x, y1, color="r")
x, y2 = sin_wave(frequency=220*2**(1/3), amplitude=1, duration=0.02, tick=0.0001)
plt.plot(x, y2, color="g")
x, y3 = sin_wave(frequency=220*2**(7/12), amplitude=1, duration=0.02, tick=0.0001)
plt.plot(x, y3, color="b")

plt.plot(x, y1+y2+y3, color="k")

output_34_1.png

M: I see, it's an ant. ・ ・ Is it equal temperament? (That's right w) I didn't realize that (2 \ * \ * (1/12)) \ * \ * 4 became 2 \ * \ * (1/3) ... (humanities explosion) The following example solution is for when you need to save memory. For reference, lightly.

# M:Answer example
plt.figure(figsize=(40, 10), dpi=72)
root = 2 ** (1 / 12)
for i, s in enumerate([[0, "r"], [4, "g"], [7, "b"]]):
    x, y = sin_wave(220 * (root ** s[0]), 1, 0.05, 0.0001)
    plt.plot(x, y, color=s[1], lw=2)
    y_sum = y if i == 0 else y_sum + y
plt.plot(x, y_sum, color="k", lw=5)
plt.plot([0, 0.05], [0, 0], color="k")

output_36_1.png

M: [Issue 0008] By the way, Exercise 0007 was equal temperament, but what if it is just intonation? Since it's a big deal, why not try it based on the above answer example? Also, try drawing the x-axis (line of y = 0).

# Q:
plt.figure(figsize=(40, 10), dpi=72)
for i, s in enumerate([[1, "r"], [1.25, "g"], [1.5, "b"]]):
    x, y = sin_wave(220 * (s[0]), 1, 0.05, 0.0001)
    plt.plot(x, y, color=s[1], lw=2)
    y_sum = y if i == 0 else y_sum + y
plt.plot(x, y_sum, color="k", lw=5)
#y = [0] * len(x)
#plt.plot(x, y, color="k")
plt.plot([0, 0.05], [0, 0], color="k")

output_38_1.png

M: I changed the display size of the above two graphs. (It may be easier to understand if you look at it on a PC)

In the just intonation below, you can see that there are two points where each series crosses at exactly y = 0.

Also, although it's the x-axis, I only draw one line, so I used only two coordinates to save memory. (I wish there was a method to draw the x-axis in the first place, but I haven't confirmed it yet)

So, I think that it is not important to make a zero cross, but that the synthesized waveform repeats the same pattern in a short cycle.

When I extended the time to 0.05 seconds, the latter just intonation repeats exactly the same pattern, while the former equal temperament. The pattern seems to change gradually.

(The same waveform repeats when the time reaches the least common multiple of the cycle.)

Well, the long-awaited topic of octave. Why did you decide to design a scale with an octave interval and a geometric progression of frequencies between them? To put it the other way around, for example, shouldn't we divide the scale into seven scales in units of two octaves? Furthermore, shouldn't we make a scale with "arithmetic progression" of frequencies between 1Hz and 1KHz, for example? It has a relationship between timbre and pitch. As seen in sawtooth waves, musical tones other than sine waves (sounds with pitches) usually contain "overtones" that are integral multiples of the fundamental tone, which form the "timbre". The lowest pitch of this overtone is usually twice the frequency, that is, one octave higher. So, in Task 0002, the "timbre" was adjusted by synthesizing the fundamental tone and the sine wave one octave higher. If you increase the ratio of this higher note further, it will gradually approach the note one octave higher. In other words, instead of gradually increasing the frequency, such as from do to re, by changing the ratio of overtones, the sound becomes one octave higher before you know it. In other words, a sound with an octave difference can be said to be a sound with a different timbre (same original pitch). For example, in karaoke, a female voice and a male voice duet with the same melody with different octaves can be said to be singing with the same pitch, although the tones are different. In this way, sounds with different octaves are "originally the same pitch", so the concept of one octave cannot be excluded from the design of the scale. Is it an explanation? (Well, how should I explain the odd harmonics of a square wave? Well, the pitch of "so" for "do" cannot be removed ...)

** Once completed **

Recommended Posts

A record of hell lessons imposed on beginner Python students
A record of patching a python package
A memo of a tutorial on running python on heroku
A well-prepared record of data analysis in Python
A memorandum of stumbling on my personal HEROKU & Python (Flask)
Handling of python on mac
[Python] Visualize overseas Japanese soccer players on a map as of 2021.1.1
AtCoder Beginner Contest 169 A Explanation of Problem "Multiplication 1" (Python3, C ++, Java)
AtCoder Beginner Contest 176 A Explanation of problem "Takoyaki" (Python3, C ++, Java)
[Windows] A story of a beginner who stumbles on Anaconda's PATH setting.
I did a lot of research on how Python is executed
Get the number of readers of a treatise on Mendeley in Python
Building a Python environment on Mac
A good description of Python decorators
[Python] A memorandum of beautiful soup4
Create a Python environment on Mac (2017/4)
A brief summary of Python collections
Create a python environment on centos
Environment construction of python3.8 on mac
Build a python3 environment on CentOS7
Record of Python introduction for newcomers
A story of a deep learning beginner trying to classify guitars on CNN
Run a batch of Python 2.7 with nohup on Amazon Linux AMI on EC2
A beginner of machine learning tried to predict Arima Kinen with python
Build a python environment on MacOS (Catallina)
Display a list of alphabets in Python 3
Make a relation diagram of Python module
Map rent information on a map with python
Connect a lot of Python or and and
Creating a python virtual environment on Windows
[python] Get a list of instance variables
[python] [meta] Is the type of python a type?
A little more detail on python comprehensions
Pandas of the beginner, by the beginner, for the beginner [Python]
Study on Tokyo Rent Using Python (3-1 of 3)
Run Python code on A2019 Community Edition
Build a Python + OpenCV environment on Cloud9
The story of blackjack A processing (python)
[Python] Japanese localization of matplotlib on Ubuntu
[Python] A progress bar on the terminal
[Python] Get a list of folders only
A memorandum of python string deletion process
A record of the time it took to deploy mysql on Cloud9 + Rails
Separately install a version of Python that is not pre-installed on your Mac
I made a script to record the active window using win32gui of Python
[Python] Plot data by prefecture on a map (number of cars owned nationwide)