364 Views
April 19, 21
スライド概要
サークルでProcessingを使ったプログラミング基礎講習会を行った時の資料です。
公立はこだて未来大学複雑系学部3年
1 18時15分開始 お待ちくだせぇ
プログラミング基礎講習 第二回 at FUN AI 2020/5/18
本日の予定 18:15 〜 講習会開始 〜20:00 終わり 面倒なのでPDF作ってないです。テヘペロ。 各位休憩を適宜とって下さい。
予定変更 来週は私のブロック崩しコードを リファクタリングします! リファクタリングとは プログラムの外部から見た動作を変えずにソースコードの内部構造を整理すること
用意して欲しいもの ・Processing サンプルコードを手元に持ってきて遊んでみてね。
本日のテーマ「可読性」 ・可読性とは ・命名規則 ・変数のスコープ ・コメントアウト ・関数 ・制御フロー ・関数の副作用
1 可読性
可読性とは > コードの読みやすさ・わかりやすさの指標
可読性とは > なにが目的でどんな工程を踏んでいるのか > どの変数が何の役割をしているのか
なんで気にするの? ・チーム開発する際に余計なコストがかからずに済む ・あとから改修がしやすくなる
1 変数とのお付き合い
変数と和解せよ > 変数と雑な付き合いするとあとで辛い思いしますよ。
2 サンプルコード
3 命名規則
命名規則とは > 変数に名前をつける時に守るお約束ごと
キャメルとスネーク >単語の先頭を大文字にする(StateTitle, UpWord) >単語の間にアンダーバーを入れる (left_word)
統一感のある命名 > rectX,rectYなど、同じ処理に使用するなら名前を似せ る
大文字と小文字で変数を分けない > rectXとRectXを別変数として扱う > XrectとrectXとか順番で区別もよくない
上書きしない > もうすでに役目のあるお名前は使わない
システム変数 > もうすでに役目がある変数たち。 > 上書き可能(するな) 例)mouseX, width
予約語 > もうすでに役目があり、上書きが不可 例)int, float
関数の名前を使わない > もうすでに役目のある関数の名前も使わない 例)rect,random,circle
シンタックスハイライト > コードが見やすくなるように色がついている > 色がついたらすでに役割があるので使わない!
・濃い青:void関数 ・緑:void ・ピンク:システム変数 ・薄い青:組み込み関数
変数名の変えかた >
変数楽に変えられるよ >
便利サイト 日本語入力すると良い感じに英語にして返してくれる! codic : https://codic.jp/
修正前 修正後
変数名綺麗にしたコードだが… →変数が多い…💦
4 変数の削除
検討するポイント > 特に処理を行わないで値を渡していないか? > 定数ではないか?
・backColorは必要? ・rectConstantは必要? ・Low,Highは必要? ・directionChangeは必要?
用法の確認 >
確認できること ・どこで宣言したのか ・何に使ってるか ・何を代入されてるか VSCodeではcommand+Fで検索できる ので、それで見ると
・変数名をわかりやすくした ・不要な一時変数を削除 →だいぶ見やすくなった!🤗
1 変数のスコープ
スコープとは >変数のスコープは変数が使える有効範囲のこと >宣言する場所でスコープが変わる
スコープとは >有効範囲を狭めることを「スコープを狭める」と言う
例)正しいスコープ >>> marumarumarumarumarumaru… と出力される
例) スコープを間違えると… >>> エラー:maruがいません
イメージ >{}で囲まれた範囲=有効範囲
用語解説 ・グローバル変数:完全にお外で宣言 ・ローカル変数:中で宣言
なんで気にしなきゃダメなの? > どこで変数の上書きがされてるか把握しづらい > 変数が変更されればされるほど中身を追いにくい
なんで気にしなきゃダメなの? > 変数名の競合を防ぐ。全部一意の名前にするのきつい べ。
なんで気にしなきゃダメなの? > データを扱う際はメモリ消費が気になる gc.collect()!!!!!!!!
注意ポイント > draw()は何度も回ってるので、宣言で初期化されて困る ものは影響が出ない場所で宣言する!
・verX,verY,rectX,rectYは中身が 動いてほしいのでスコープ小さくできな い。 ・backcolorは定数として扱っている のでスコープを狭めていい
1 インデント
インデントとは void draw(){ aaaif(maru){ aaaaaprint(“まる!”); aaa} } {}は同じインデントに揃える!
便利コマンド紹介 ● ctrl + R : 実行 ● ctrl + T : 自動フォーマット ● ctrl + S : 保存
Pythonではインデント命 > スコープについて、Pythonではインデントで判断される > Processingは{}があるとはいえ気にしよう
7 コメントアウト
コメントアウトとは Processingでは// Pythonだと#
使い道 ・処理の解説 ・開発のメモ(//あとで修正しよう)
一連の処理へのコメントアウト /*---------Mecabの準備----------*/ t = MeCab.Tagger('/usr/local/lib/mecab/dic/mecab-ipadic-neologd') t.parse('')
一連の処理へのコメントアウト #Mecab t = MeCab.Tagger('/usr/local/lib/mecab/dic/mecab-ipadic-neologd') t.parse('')
1行に対してコメントアウト twitter = OAuth1Session(CK, CS, AT, ATS) # 認証処理 url = "https://api.twitter.com/1.1/statuses/home_timeline.json" タイムライン取得エンドポイント #
7 関数
関数とは 一連の処理をまとめて定義すること。
int a=0; void draw(){ //...long process a++; } aを+1し続ける処理を 関数にしよう
int a=0; void draw(){ //... returnがある関数は a = add(a) 値を返すよ } 例)random,mouseX int addition(int x){ return x+1; }
int a=0; void draw(){ //... addition(a); } (これはうまく動かんです) void addition(int x){ x=x+1; } void の関数は上から下に 流れるだけだよ。 例)void mousePressed()
関数の引数 void add(int x)とかint add(int x)の int xを関数の引数という。 rect(10,10,10,10)の”10”も関数の引数です。
何が嬉しい? 繰り返しが防げる →書く手間が省ける →使わないと変更点が出ると全部書き直さなきゃいけない 場合がある(addが+1ではなく+2にしたいなど)
何が嬉しい? 関数名をつけることで何の処理かわかりやすくなる →コードをべたに書くよりもわかりやすくなる
7 制御フロー
制御フローとは > 実行される順序のこと > 条件やループなどに出会わない限り、コードは最初の行 から順に最後の行まで順番に実行する。
制御フロー できるだけ「自然」にする。
自然?? フローチャートを思い出そう。
int sum=0; int n=1; while(n<=10){ sum = sum + n; n++; } print(sum);
int sum=0; sumを定義 int n=1; while(n<=10){ sum = sum + n; sumに1~10まで足す n++; } print(sum); sumを出力
int sum=0; int n=0; while(n<=10){ sum = sum + n; if(n==10){ print(sum); } n++; }
int sum=0; int n=0; sumを定義 while(n<=10){ sum = sum + n; if(n==10){ sumに1~10まで足す print(sum); } n++; } sumを出力
気付きにくい。 > 具体的に考えれば考えるほど上記のようなことが起きや すい > 定期的に自分がそもそも何を書きたかったのかを思い出 そう
if文 if (a == b) { // Case One ... } else { // Case Two ... }
if文 if (a != b) { // Case Two ... } else { // Case One ... }
つまり > 否定的ではなく肯定的ケースに対処する
ついでに > より注目させたい処理を先に書く →判別させたいことは何か、何の処理をさせたいのか →エラー処理なら否定で入った方が良い
ネスト とは > 入れ子構造のこと if(){ if(){ if(){ } } } //...
ネストが深すぎると… > あとから読んだときになにが起きたらどこに入りどこで 抜け出すのか追いにくい →「自然」じゃない
if(hoge!=0){ //超長い }else{ return hoge; } API使ってる人とかこうなって ませんか。私はなりました。
if(hoge==0){ return hoge; } //長い処理 さっさとreturnさせる。
if(hoge!=0){ //... if(hoge>5){ //hoge操作 if(hoge>100){ //hogeを操作 hoge=fuga; } //hoge操作 } } hogeの操作のみの場所があるなら
piyo=hoge_calculation(hoge) int hoge_calculation(int piyo){ //ここに一連の処理を書き return piyo; } まとめてしまった方が良い。
なにが嬉しい > 「これどんな条件分岐だっけ?」を防げる > あとで書き足しやすい&修正しやすい
7 関数の副作用
副作用のない関数とは > いついかなる時、場所でも同じ引数なら同じ振る舞いを する関数
副作用のある関数とは > 副作用のない関数以外の関数全て
副作用とみなされる行為 ・グローバル変数を読む、あるいは書く ・標準入力または標準出力を使う ・副作用のある関数を呼ぶ
なぜ副作用がいけない? > 単体テストができないから。 →関数外に依存要素があるから単体でテストが行えない
なぜ副作用がいけない? > リファクタリングするときに範囲を定めにくい →他のところも改修しなきゃいけなくなる
出力予想できますか?
nestMaru:0 marumaru:2 nestMaru:2 marumaru:2
同じ関数を呼んだのに出力 が違う →副作用がある
8 次回予告
お品書き(予定) ● 実演 私が去年作ったブロック崩しをリファクタリング しながら学んだ内容の復習します。
おわり。 感想くれ。 98