1+ <script setup>
2+ import { ref , onMounted , onUnmounted } from ' vue' ;
3+ import { useRouter } from ' vue-router' ;
4+ import Title from ' ../components/Title.vue' ;
5+ import Header from ' ../components/Header.vue' ;
6+ import SubHeader from ' ../components/SubHeader.vue' ;
7+ import Paragraph from ' ../components/Paragraph.vue' ;
8+ import PyScript from ' ../components/PyScript.vue' ;
9+ import Code from ' ../components/Code.vue' ;
10+ import Hint from ' ../components/Hint.vue' ;
11+ import ProgressFooter from ' ../components/ProgressFooter.vue' ;
12+
13+ const router = useRouter ()
14+ const completion = ref (0 );
15+
16+ const navigate = (index ) => {
17+ router .push ({
18+ name: ' lecture' ,
19+ params: {
20+ number: index
21+ }
22+ })
23+ }
24+
25+ const updateScrollCompletion = () => {
26+ const currentProgress = window .scrollY ;
27+ const scrollHeight = document .body .scrollHeight - window .innerHeight ;
28+ if (scrollHeight) {
29+ completion .value = Math .round ((currentProgress / scrollHeight) * 100 );
30+ if (completion .value > 100 ) {
31+ completion .value = 100 ;
32+ }
33+ }
34+ };
35+
36+ onMounted (() => {
37+ window .addEventListener (" scroll" , updateScrollCompletion);
38+ });
39+
40+ onUnmounted (() => {
41+ window .removeEventListener (" scroll" , updateScrollCompletion);
42+ });
43+ </script >
44+
45+ <template >
46+ <Title >演習問題 解答・解説</Title >
47+
48+ <div class =" container w-3/6 mx-auto mb-10 text-start" >
49+ <div class =" flex-col mx-auto mb-12 border rounded-lg border-green-600 p-3.5" >
50+ <span class =" text-2xl ml-2" >目次</span ><br >
51+ <ul class =" ml-5 mt-3" >
52+ <li ><a href =" #1" class =" hover:underline hover:text-2xl hover:text-green-600 decoration-green-600" >第1講 Python: データ型、変数、演算子</a ></li >
53+ <li ><a href =" #2" class =" hover:underline hover:text-2xl hover:text-green-600 decoration-green-600" >第2講 Python: if文、for文、while文</a ></li >
54+ <li ><a href =" #3" class =" hover:underline hover:text-2xl hover:text-green-600 decoration-green-600" >第3講 Python: 配列、辞書</a ></li >
55+ <li ><a href =" #4" class =" hover:underline hover:text-2xl hover:text-green-600 decoration-green-600" >第4講 Python: 関数、ライブラリ</a ></li >
56+ </ul >
57+ </div >
58+ <Header id =" 1" >第1講 Python: データ型、変数、演算子</Header >
59+ <Paragraph >
60+ <div class =" -my-3 underline text-blue-500 hover:text-blue-300" @click =" navigate(1)" >第1講 Python: データ型、変数、演算子のページへ</div >
61+ </Paragraph >
62+ <Paragraph >
63+ <SubHeader class =" mb-3" >[<span class =" text-green-600 font-bold" >Easy</span >] 入力される名前を、"Your name is XXX."のように出力するプログラムを書け。</SubHeader >
64+ <Hint level =" 1_easy" ><span class =" text-yellow-400" >input()</span >関数を使うと、入力された文字列を取得できる。</Hint >
65+
66+ <PyScript >
67+ name = input()
68+
69+ print(f"Your name is {name}.")
70+ </PyScript >
71+
72+ 別解として、print("Your name is " + name)とすることもできるが、文字列のフォーマット(<span class =" text-yellow-400" >format</span >)を行った方が可読性が高い(と思う)。
73+ </Paragraph >
74+
75+ <Paragraph >
76+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] 入力される2数(num1, num2)の平均を求めるプログラムを書け。</SubHeader >
77+ <Hint level =" 1_med1" >input()関数から返されるデータは、<span class =" text-yellow-400" >str</span >型であることに注意しよう。</Hint >
78+
79+ <PyScript >
80+ num1 = input()
81+ num2 = input()
82+
83+ print(f"The average is {(float(num1) + float(num2)) / 2}")
84+ </PyScript >
85+
86+ input()関数の戻り値は必ずstr型であるので、演算をする前にint型やfloat型などの演算可能な型にキャストしておくこと。
87+ </Paragraph >
88+
89+ <Paragraph >
90+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] 次のプログラムの誤りを指摘し、修正せよ。</SubHeader >
91+ <Hint level =" 1_med2" >プログラムは、括弧の内側から順に評価される。</Hint >
92+
93+ <PyScript >
94+ a = input() # aに任意の数を代入
95+ b = input() # bに任意の数を代入
96+ # print(float(a + b)) # aとbの和を出力
97+
98+ # 正しいプログラム
99+ print(float(a) + float(b))
100+ </PyScript >
101+
102+ 前問と同様。上のコードではstr型を加えてしまっているので、先にfloat型へキャストすること。
103+ </Paragraph >
104+
105+ <Paragraph >
106+ <SubHeader class =" mb-3" >[<span class =" text-red-500 font-bold" >Hard</span >] 1番目の整数(num1)から2番目の整数(num2)を引いた結果を出力するプログラムを書け。ただし、算術演算子のうち使えるのは + のみとする。</SubHeader >
107+ <Hint level =" 1_hard" ><span class =" text-yellow-400" >ビット演算</span >について調べてみよう。</Hint >
108+
109+ <PyScript >
110+ num1: int = 10
111+ num2: int = 8
112+
113+ answer = num1 + (~num2 + 1)
114+ print(f"The answer is {answer}")
115+ </PyScript >
116+
117+ ビット演算子のうちのビット反転(~)を利用して、2の補数表現を作ること。
118+ さらに詳しく知りたい場合は、ビット演算の仕組みをインターネットで検索してみよう。
119+ </Paragraph >
120+
121+ <Header id =" 2" >第2講 Python: if文、for文、while文</Header >
122+ <Paragraph >
123+ <div class =" -my-3 underline text-blue-500 hover:text-blue-300" @click =" navigate(2)" >第2講 Python: if文、for文、while文のページへ</div >
124+ </Paragraph >
125+ <Paragraph >
126+ <SubHeader class =" mb-3" >[<span class =" text-green-600 font-bold" >Easy</span >] 1以上x未満の範囲に含まれる奇数の総和を求めるプログラムを書け。</SubHeader >
127+ <Hint level =" 2_easy1" ><span class =" text-yellow-400" >range()</span >関数を使うと、list型(厳密にはrange型)の数列を取得できる。</Hint >
128+
129+ <PyScript >
130+ x: int = 100
131+
132+ answer = 0
133+ for i in range(1, x):
134+ if i % 2 == 1:
135+ answer += i
136+
137+ print(f"The sum is {answer}")
138+ </PyScript >
139+
140+ 1以上x未満の範囲にある整数は、range(1, x)とすることで得られる。
141+ あとは、奇数の条件分岐を忘れないようにすること。
142+ 上の例では、mod(2)が1に等しいことから奇数を判定している。
143+ </Paragraph >
144+
145+ <Paragraph >
146+ <SubHeader class =" mb-3" >[<span class =" text-green-600 font-bold" >Easy</span >] 次のプログラムのエラーの原因を特定し、修正せよ。</SubHeader >
147+ <Hint level =" 2_easy2" >宣言されていない変数は呼び出せない。</Hint >
148+
149+ <PyScript >
150+ sum = 0
151+
152+ # 追加したコード
153+ flag = True
154+
155+ while (flag):
156+ sum += 1
157+ if (sum > 5):
158+ flag = False
159+ print('Correct!')
160+ </PyScript >
161+
162+ 定義されていない変数flagがいきなり呼び出されていたことでエラーが発生していた。
163+ したがって、flagを呼び出しより先に宣言してやれば良い。
164+ (題意が不明瞭だったかもしれませんね。すみません。)
165+ </Paragraph >
166+
167+ <Paragraph >
168+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] 入力された自然数に対して、適切な序数を出力するプログラムを書け。例えば、1が入力された時に"1st"を返すこと。</SubHeader >
169+ <Hint level =" 2_med" >1の位の数に応じて条件分岐させること。ただし、例外がいくつか存在するので注意せよ。</Hint >
170+
171+ <PyScript >
172+ num = int(input())
173+
174+ if (num % 100 // 10) == 1: # (mod(100)した結果を10で割った商の整数部) == 1
175+ print(str(num) + 'th')
176+ elif (num % 10) == 1:
177+ print(str(num) + 'st')
178+ elif (num % 10) == 2:
179+ print(str(num) + 'nd')
180+ elif (num % 10) == 3:
181+ print(str(num) + 'rd')
182+ else:
183+ print(str(num) + 'th')
184+ </PyScript >
185+
186+ ここでのポイントは、10の位が1の時(12, 113など)は、序数詞が必ず"th"となることである。
187+ したがって、それを優先的に判定することが必要となる。
188+ </Paragraph >
189+
190+ <Paragraph >
191+ <SubHeader class =" mb-3" >[<span class =" text-red-500 font-bold" >Hard</span >] 任意の実数x(rad)に対して、sin(x)の値を出力するプログラムを書け。ただし、必要な計算精度は10桁程度とし、以下のpiの値を利用しても良いものとする。</SubHeader >
192+ <Hint level =" 2_hard" >関数の周期性を利用することで効率的なコードが書ける。</Hint >
193+
194+ <PyScript >
195+ pi: float = 3.14159265359
196+ x: float = pi / 2
197+
198+ # sin(x)を 0 <= x <= pi/2 の範囲で表現する
199+ if (pi / 2 < x and x <= pi):
200+ x = pi - x
201+ elif (pi < x < 2 * pi):
202+ x = x - pi
203+ elif (x >= 2 * pi):
204+ x = x % 2 * pi
205+
206+ # Maclaurin展開の実装部
207+ sum = 0
208+ for i in range(10):
209+ # 階乗(factorial)を計算するためのfor文
210+ fact = 1
211+ for j in range(1, 2*i+1 +1):
212+ fact *= j
213+ sum += ((-1)**i) * (x**(2*i+1)) / fact
214+
215+ print(f'sin({x}) = {sum}')
216+ </PyScript >
217+
218+ Maclaurin展開を実装すれば良い。
219+ 注意すべき点としては、xの値が原点から離れるほど精度が低下するため、xをなるべく原点に近い点に置き直すことが必要となる。
220+ </Paragraph >
221+
222+ <Header id =" 3" >第3講 Python: 配列、辞書</Header >
223+ <Paragraph >
224+ <div class =" -my-3 underline text-blue-500 hover:text-blue-300" @click =" navigate(3)" >第3講 Python: 配列、辞書のページへ</div >
225+ </Paragraph >
226+ <Paragraph >
227+ <SubHeader class =" mb-3" >[<span class =" text-green-600 font-bold" >Easy</span >] 次のデータを正規化せよ。</SubHeader >
228+ <Hint level =" 3_easy" >グレイスケール(8bit)ですね。</Hint >
229+
230+ <PyScript >
231+ data = [
232+ [133, 254, 0, 233, 45],
233+ [230, 43, 198, 172, 85],
234+ [ 75, 189, 34, 210, 222],
235+ [ 43, 240, 65, 184, 202],
236+ [139, 14, 78, 255, 164]
237+ ]
238+
239+ # データの値を一つずつ確認して、最小値と最大値を求める
240+ min = data[0][0]
241+ max = data[0][0]
242+ for i in range(len(data)):
243+ for j in range(len(data[i])):
244+ if data[i][j] > max:
245+ max = data[i][j]
246+ elif data[i][j] < min:
247+ min = data[i][j]
248+
249+ # データを正規化する
250+ normalized_data = []
251+ for i in range(len(data)):
252+ array = []
253+ for j in range(len(data[i])):
254+ array.append((data[i][j] - min) / (max - min))
255+ normalized_data.append(array)
256+
257+ # 結果を表示
258+ print('[')
259+ for array in normalized_data:
260+ print(f"{array},")
261+ print(']')
262+ </PyScript >
263+
264+ データの最小値と最大値を求めるためにfor文を実装し、さらにデータを正規化するためにもう一度for文を使用する。
265+ グレイスケールの値は必ず[0, 255]の範囲に存在することが分かっているので、このことを利用してもよい。
266+ </Paragraph >
267+
268+ <Paragraph >
269+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] 次のデータを昇順(ascending order)に並べ替えよ。ただし、バブルソートを使うこと。</SubHeader >
270+ <Hint level =" 3_med1" >各データが泡のように浮かび上がってきます。</Hint >
271+
272+ <PyScript >
273+ data = [5, 9, 3, 6, 2, 1, 4, 7, 8, 0]
274+
275+ # bubble sort
276+ for i in range(len(data) - 1):
277+ for j in range(len(data) - i - 1):
278+ if data[j] > data[j+1]:
279+ data[j], data[j+1] = data[j+1], data[j]
280+ # 上の1行の代わりに、下の3行を使うこともできる
281+ # data[j] = tmp
282+ # data[j] = data[j+1]
283+ # data[j+1] = tmp
284+ print(data)
285+
286+ print(data)
287+ </PyScript >
288+
289+ 隣り合うデータをそれぞれ比較し、より大きい値が常に右側に来るように入れ替え続けると、最も大きい値が配列の右端に来る。これを繰り返すこと。
290+ </Paragraph >
291+
292+ <Paragraph >
293+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] 行列Aと行列Bの積を求めよ。</SubHeader >
294+ <Hint level =" 3_med2" >定義通りに計算しよう。(※手計算しないでね)</Hint >
295+
296+ <PyScript >
297+ A = [
298+ [1, 2, 3],
299+ [4, 5, 6],
300+ [7, 8, 9],
301+ ]
302+ B = [
303+ [-1, 0, 1],
304+ [ 0, 1, -1],
305+ [ 1, -1, -1]
306+ ]
307+
308+ # 行列の積が定義されるかを確認
309+ if len(A[0]) != len(B):
310+ print("Matrix A can't be multiplied by matrix B.")
311+ else:
312+ C = [[0] * len(B[0]) for _ in range(len(A))]
313+
314+ # 計算部
315+ for i in range(len(A)):
316+ for j in range(len(B[0])):
317+ for k in range(len(B)):
318+ C[i][j] += A[i][k] * B[k][j]
319+
320+ # 結果を表示
321+ print('[')
322+ for array in C:
323+ print(f"{array},")
324+ print(']')
325+ </PyScript >
326+
327+ 定義通りにfor文を実装するだけだが、これがなかなかややこしいのである。
328+ </Paragraph >
329+
330+ <Paragraph >
331+ <SubHeader class =" mb-3" >[<span class =" text-yellow-400 font-bold" >Medium</span >] データAとデータBの相関係数を求めよ。</SubHeader >
332+ <Hint level =" 3_med3" >平方根は、<span class =" text-yellow-400" >math.sqrt()</span >関数で計算できる。</Hint >
333+
334+ <PyScript >
335+ import math
336+
337+ data_A = [ 0, 3, 5, 9, -2, 1, 2, -4, 7, 8]
338+ data_B = [ 3, 12, 6, 5, 4, -2, 3, -1, 9, 7]
339+
340+ # 平均値を計算
341+ avr_A = 0
342+ avr_B = 0
343+ for i in range(len(data_A)):
344+ avr_A += data_A[i] / len(data_A)
345+ avr_B += data_B[i] / len(data_B)
346+
347+ # 相関係数を計算
348+ cov_AB = 0
349+ sd_A = 0
350+ sd_B = 0
351+ for i in range(len(data_A)):
352+ dev_A = data_A[i] - avr_A
353+ dev_B = data_B[i] - avr_B
354+
355+ cov_AB += dev_A * dev_B
356+ sd_A += dev_A ** 2
357+ sd_B += dev_B ** 2
358+ cor_AB = cov_AB / math.sqrt(sd_A * sd_B)
359+
360+ print(cor_AB)
361+ </PyScript >
362+
363+ こちらも定義式に当てはめて実装すれば良いのだが、for文がいくつも出てくるので、落ち着いてやらなければ混乱してしまう。
364+ もし解けた場合は、二つのデータ(AとB)をベクトルとして見た場合のcos類似度(cosine similarity)も計算してみると良い。
365+ そうすると、内積と相関係数が深い関係にあることに気づくはずである。
366+ </Paragraph >
367+
368+ <Header id =" 4" >第4講 Python: 関数、ライブラリ</Header >
369+ <Paragraph >
370+ <div class =" -my-3 underline text-blue-500 hover:text-blue-300" @click =" navigate(4)" >第4講 Python: 関数、ライブラリ</div >
371+ </Paragraph >
372+ <Paragraph >
373+ まだできてないよ。
374+ </Paragraph >
375+
376+ <ProgressFooter :progress =" completion" class =" mt-16" />
377+ <div class =" text-center my-5" >
378+ <a href =" #" class =" p-2 rounded-md bg-green-700 hover:bg-green-600" >ページ上部へ!</a >
379+ </div >
380+ </div >
381+ </template >
382+
383+ <style scoped>
384+ </style >
0 commit comments