質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

解決済

classのself.の要否がわからずエラーになる

lteru
lteru

総合スコア6

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2回答

0リアクション

0クリップ

678閲覧

投稿2021/10/25 14:07

編集2021/10/26 01:13

前提・実現したいこと

PCのキープレスに応じて異なる音が出力されるアプリを作っています。
アプリをclassで定義しようとしたところ、initの要否が一部分からず詰まっています。
プログラミング初心者のため初歩的な質問かと存じますが、教えていただけると幸いです。

発生している問題・エラーメッセージ

name 'sin_t' is not defined

該当のソースコード

Python

# ライブラリのインポート import numpy as np # sin波 import pyaudio # メモリ上の音楽を再生 from pygame.locals import * # キープレス import matplotlib.pyplot as plt import pygame import sys # クラスの定義 class Sinwave_synth: def __init__(self, gain=0.25, rate=44100, chunk_size=1024): self.gain = gain # "A" self.rate = rate # サンプリング周波数"fs":44100 self.chunk_size = chunk_size # 音源から1回読み込むときのデータサイズ。1024(=2の10乗) とする場合が多い self.p = pyaudio.PyAudio() # pyaudioの開始 self.start_up() # 初期値 # 初期値 def start_up(self): global duration # 初期値のためにglobal変数が必要 duration = DURATION['L4'] # sin波の作成 def create_sinwave(self, duration, freq): self.duration = duration self.freq = freq # 指定周波数のsin波を指定秒数生成 t = np.arange(0, duration * self.rate) / self.rate sin_t = np.sin(2 * np.pi * freq * t) envRange = np.ones(int(duration * self.rate)) # 1字配列 # グラフのプロット fig = plt.figure() fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 fig_envRange.plot(t, envRange) fig_wave.plot(sin_t[:500]) plt.show # ストリームに渡して再生 def play(self): self.stream = self.p.open(format=pyaudio.paFloat32, channels=1, rate=self.rate, frames_per_buffer=self.chunk_size, output=True) self.stream.write(sin_t.astype(np.float32).tobytes()) self.stream.close() # パラメータ bpm = 120 DURATION = { 'L1': (60 / bpm * 4), # 全音符 'L2': (60 / bpm * 4) / 2, # 二分音符 'L4': (60 / bpm * 4) / 4, # 四分音符 'L8': (60 / bpm * 4) / 8, # 八分音符 } FREQ_SCALE = { # 周波数f0のスケール 'ド/C4': 261.626, 'レ/D4': 293.665, 'ミ/E4': 329.628, } # 実装 Sinwave = Sinwave_synth() # 画面作成 pygame.init() # Pygameを初期化 screen = pygame.display.set_mode((400, 330)) # 画面を作成 pygame.display.set_caption("keyboard event") # タイトルを作成 # キープレスに応じて音を変える while True: screen.fill((0, 0, 0)) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYDOWN: # キーを押したとき # ESCキーならスクリプトを終了 if event.key == K_ESCAPE: pygame.quit() sys.exit() # キーに応じて周波数変化 if event.key == K_a: freq = FREQ_SCALE['ド/C4'] elif event.key == K_s: freq = FREQ_SCALE['レ/D4'] elif event.key == K_d: freq = FREQ_SCALE['ミ/E4'] else: continue # sin波の作成 および 音声出力 print("押されたキー = " + pygame.key.name(event.key)) Sinwave.create_sinwave(duration, freq) Sinwave.play() pygame.display.update()

試したこと

上記のclass Sinwave_synthをSinwave = Sinwave_synth()で実装したあと、create_sinwave()メソッドとplay()の順に実行しているはずが、creat_sinwave()メソッドで定義しているsint_tがplay()メソッド実行時にNameErrorになります。

<エラーあり>

Python

# クラスの定義 class Sinwave_synth: # sin波の作成 def create_sinwave(self, duration, freq): self.duration = duration self.freq = freq # 指定周波数のsin波を指定秒数生成 t = np.arange(0, duration * self.rate) / self.rate sin_t = np.sin(2 * np.pi * freq * t) envRange = np.ones(int(duration * self.rate)) # 1字配列 # グラフのプロット fig = plt.figure() fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 fig_envRange.plot(t, envRange) fig_wave.plot(sin_t[:500]) plt.show # ストリームに渡して再生 def play(self): self.stream = self.p.open(format=pyaudio.paFloat32, channels=1, rate=self.rate, frames_per_buffer=self.chunk_size, output=True) self.stream.write(sin_t.astype(np.float32).tobytes()) self.stream.close()

一方、create_sinwave()内のtやsin_tに"self."をつけるとエラーが無くなりました。ここで、sin_tはcreate_sinwave()のアトリビュートではない認識なのですが、なぜ"self."が必要なのでしょうか?

この"self."が必要な場合とそうでない場合がよくわかりません。グローバル変数を用いるようになると更にわからなくなります。

<エラーなし>

Python

# sin波の作成 def create_sinwave(self, duration, freq): self.duration = duration self.freq = freq # 指定周波数のsin波を指定秒数生成 self.t = np.arange(0, duration * self.rate) / self.rate self.sin_t = np.sin(2 * np.pi * freq * self.t) self.envRange = np.ones(int(duration * self.rate)) # 1字配列 # グラフのプロット fig = plt.figure() fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 fig_envRange.plot(self.t, self.envRange) fig_wave.plot(self.sin_t[:500]) plt.show # ストリームに渡して再生 def play(self): self.stream = self.p.open(format=pyaudio.paFloat32, channels=1, rate=self.rate, frames_per_buffer=self.chunk_size, output=True) self.stream.write(self.sin_t.astype(np.float32).tobytes()) self.stream.close()

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。