はてなキーワード: Classとは
自動で安価をつけて返信するプログラムでもこんなに長く複雑になる(一部抜粋)
/**************************************
以下のCSV_DIR, FILE_PATHS, SETTINGSを書き換えてね。 <h3>o- *************************************/</h3>
//CSVファイルが置かれてるディレクトリのパス。投稿前にエラー出たら大体ここの設定ミス。 例:"C:\\Users\\sakuraimasahiro\\Documents\\iMacros\\Macros\\rentou\\";
'C:\\Users\\USER\\Desktop\\iMacros\\Macros\\rentou\\';
//ファイルのパス。CSVは絶対パスで、拡張子も必要。iimは相対パスでよく、拡張子不要。
const FILE_PATHS = {
textCsv: CSV_DIR + 'textNoAnker.csv',
//レス用投稿文が書かれたCSV。通常とレス用で分けないなら同じファイルを使えばいい。
replyTextCsv: CSV_DIR + 'textReply.csv',
};
baseWaitTime: 5,
//baseWaitTime+0~waitTimeRange(ランダム)だけ待つ
waitTimeRange: 5,
//連投しすぎだと忠告された場合に処理を一時停止させる時間(秒)
waitTimeForAvoidingPunishment: 60 * 30,
//メール
mail: 'sage',
//名前設定
name: '',
//以下、偽装ワッチョイ設定。浪人でワッチョイを非表示にしてるときだけtrueにしてね。
//妙なニックネーム(ワッチョイ、アウアウウーなど)をランダムで決めて付加するかどうか。true=付加する。false=付加しない。
//妙なニックネームの後に付く8桁の文字列をランダムで決めて付加するかどうか。
},
//アンカー無し投稿をするならtrue。しないならfalse。noAnkerPostかreplyPostのどちらかはtrueにすること(両方trueでもOK)。
//アンカー付き投稿(返信)をするならtrue。しないならfalse。もしnoAnkerPostとreplyPostの両方がtrueの場合、投稿は返信が優先され、返信対象が見つからなくなったらアンカー無し投稿をする。
//最初に取得するアンカー無し投稿文CSVファイルの行番号。もし返信用と同じCSVファイルを使うなら-1と入力。
noAnkerPostTextCsvStartRow: 1,
//最初に取得する返信用投稿文CSVファイルの行番号。もしアンカー無しと同じCSVファイルを使うなら-1と入力。
//テキストCSV/返信用テキストCSVの取得行が最終行に達したら最初の行まで戻るかどうか。true=戻る。false=マクロ終了。
//返信する場合、これより小さなレス番には返信しない。返信を投稿すると、この数値は前回の返信先のレス番に更新される。
minAnker: 895,
//返信する場合、名前に以下の文字列を含む投稿にアンカーをつけて返信する(ワッチョイやIPなど名前フィールドにあるものならなんでも可)。配列で複数指定可能。指定無しなら空配列([])。filterNamesとfilterNamesNotIncluded共に無指定ならレス番1から順に返信していく(minAnkerが設定されてればそこから順に)。以下のfilter系は全て併用可能。
//↑とは逆に、名前に以下の文字列を含まない投稿にアンカーをつけて返信する。↑と併用も可能。
//返信する場合、本文に以下の文字列を含む投稿にアンカーをつけて返信する。
filterText: ['自演かな', '自演わらわら', 'スクリプト使うの', '安価ガバ', '>>660', '自演で擁護', '最後' ,'あいうえお', 'かきくけこ', 'さしすせそ', 'なにぬねの', 'はひふへほ', 'まみむめも', 'やいゆえよ', 'やゆよ', 'らりるれろ', 'わいうえを', 'わをん', 'わいうえをん'],
},
//自分のIPアドレスの確認。VPNとかでIPを変更してマクロを動かしてるとき、突然VPNが作動しなくなってIPが元に戻ったときにマクロを止めるためのもの。
//以下の文字列が自分の現在のIPアドレスに含まれている場合、マクロを一時停止する。基本的に自分の本当のIPアドレスを入力。
},
//浪人設定。最後に動作を確認したのは5年くらい前で、今も同じように動作するかは、浪人を持ってないから確認できずわからない。
//浪人にログインしてるかどうかをチェックするかどうか。trueならする。falseならしない。trueにしていてもし浪人にログインしていないことを確認したらログインしにいく。
password: '1234',
},
};
/**************************************
設定箇所終わり。
https://info.5ch.net/index.php/%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%82%81%E3%81%AA%E3%81%84%E6%99%82%E3%81%AE%E6%97%A9%E8%A6%8B%E8%A1%A8 <h3>o- *************************************/</h3>
/**************************************
・NULL演算子(??)は使えない。論理積(&&)は使える。
・オブジェクトの分割代入はできない。
・importはできない。 <h3>o- *************************************/</h3>
/**************************************
関数 <h3>o- *************************************/</h3>
/**
* ここから始まる。
*/
checkSettings();
var _TextCsvCursors = new TextCsvCursors(
SETTINGS.postSettings.noAnkerPostTextCsvStartRow > 0
? SETTINGS.postSettings.noAnkerPostTextCsvStartRow - 1
: SETTINGS.postSettings.noAnkerPostTextCsvStartRow,
SETTINGS.postSettings.textCsvLoop,
),
SETTINGS.postSettings.replyPostTextCsvStartRow > 0
? SETTINGS.postSettings.replyPostTextCsvStartRow - 1
: SETTINGS.postSettings.replyPostTextCsvStartRow,
SETTINGS.postSettings.textCsvLoop,
),
);
var _LoopStatuses = new LoopStatuses(0, SETTINGS.postSettings.minAnker);
const _MyPosterName = new MyPosterName({
name: SETTINGS.nameSettings.name,
});
const _ThreadUrl = openPromptThreadUrl();
//ループ
while (true) {
SETTINGS.ipSettings.checkIp && checkCurrentIpNotTheIp();
//スレを開く
openUrl(_ThreadUrl.fullUrlHttps());
//浪人にログインする設定なら、浪人にログインしているかどうかを確認し、していなければログインしにいく。
if (SETTINGS.roninSettings.checkLogin) {
}
}
if (SETTINGS.postSettings.replyPost) {
const targetAnkerNumber = createPostDOMList()
.filterPostnumberHigher(_LoopStatuses.currentMinAnker())
.filterByPostername(SETTINGS.postSettings.filterNames)
.filterByPosternameNotIncluded(
SETTINGS.postSettings.filterNamesNotIncluded,
)
.filterByText(SETTINGS.postSettings.filterText)
if (targetAnkerNumber !== null) {
const r = _TextCsvCursors.takeNextRowTextAsReply(targetAnkerNumber);
messageDisplay(`返信対象有り。アンカー先: ${targetAnkerNumber}`);
return {
...r,
updatedLoopStatuses:
_LoopStatuses.updateMinAnker(targetAnkerNumber),
};
}
}
if (SETTINGS.postSettings.noAnkerPost) {
//返信対象無し、或いは返信しない設定の場合。アンカー無し投稿文を作る。
const r = _TextCsvCursors.takeNextRowTextAsNoAnker();
messageDisplay('返信対象無し。アンカー無し投稿。');
return {
...r,
updatedLoopStatuses: _LoopStatuses,
};
}
return null;
})();
if (p) {
//投稿。
nickname: SETTINGS.nameSettings.nickname,
korokoro: SETTINGS.nameSettings.korokoro,
area: SETTINGS.nameSettings.area,
}),
SETTINGS.mail,
p.text,
);
//_TextCsvCursorsと_LoopStatusesを更新。
_TextCsvCursors = p.updatedTextCsvCursors;
_LoopStatuses = p.updatedLoopStatuses.incrementPostCount();
`投稿回数: ${_LoopStatuses.currentPostCount()}`,
`minAnker: ${_LoopStatuses.currentMinAnker()}`,
`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,
`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,
]);
} else {
`返信対象が現われるのを待機中...。`,
`投稿回数: ${_LoopStatuses.currentPostCount()}`,
`minAnker: ${_LoopStatuses.currentMinAnker()}`,
`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,
`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,
]);
}
wait(SETTINGS.baseWaitTime + randomRange(0, SETTINGS.waitTimeRange));
}
}
/**
* 投稿処理と投稿結果を見てリトライしたりマクロ終了したり。
* @param {string} serverName サーバー名
* @param {MyPosterName} _MyPosterName
* @param {string} postMail メール
*/
serverName,
postMail,
_MyText,
retryTimes = 0,
) {
const r =
retryTimes === 0
? new ValuesOfPost(serverName, _MyPosterName, postMail, _MyText).post(
postTo5chTread,
)
serverName,
postMail,
_MyText,
).postSubstring(retryTimes, postTo5chTread, postConfirm);
if (r) {
back();
return;
}
wait(7);
const error = createPostErrorMessage().analyze();
messageDisplay(error.message);
if (error.order === 'KILL') {
kill();
} else if (error.order === 'SKIP') {
return;
} else if (error.order === 'TRUNCATE') {
back();
serverName,
postMail,
_MyText,
retryTimes + 1,
);
} else if (error.order === 'WAIT') {
wait(SETTINGS.waitTimeForAvoidingPunishment);
serverName,
postMail,
_MyText,
retryTimes,
);
} else if (error.order === 'LOGIN') {
serverName,
postMail,
_MyText,
retryTimes,
);
}
return;
}
/**
* 現在のIPアドレスに、SETTINGS.ipSettings.avoidTheIpの値が含まれていないことを確認する。含まれていたらマクロを一時停止。
* @returns
*/
function checkCurrentIpNotTheIp() {
openUrl('https://www.cman.jp/network/support/go_access.cgi');
const _IpAdress = createIpAdressFromCMan();
if (_IpAdress.includes(SETTINGS.ipSettings.avoidTheIp)) {
pause('現在のIPに指定した値が含まれていることを確認。');
}
return;
}
/**
* @returns
*/
if (
SETTINGS.postSettings.noAnkerPost === false &&
SETTINGS.postSettings.replyPost === false
) {
return kill('設定エラー。noAnkerPostとreplyPost両方ともfalseになってる。');
}
if (
SETTINGS.postSettings.noAnkerPostTextCsvStartRow < 0 &&
SETTINGS.postSettings.replyPostTextCsvStartRow < 0
) {
return kill(
'設定エラー。noAnkerPostTextCsvStartRowとreplyPostTextCsvStartRow両方とも-1になってる。',
);
}
if (
SETTINGS.postSettings.noAnkerPostTextCsvStartRow === 0 ||
SETTINGS.postSettings.replyPostTextCsvStartRow === 0
) {
return kill(
'設定エラー。noAnkerPostTextCsvStartRow/replyPostTextCsvStartRowの初期値は-1或いは1以上で。',
);
}
}
/**
* 入力フォームを表示して入力されたスレのURLを受け取る。
*/
function openPromptThreadUrl() {
const url = prompt('スレURLを入力');
}
/**
* 開いてるスレのレス全て読み取ってPostListインスタンスを作って返す。
* 重すぎるので使うのやめ。どうやらインスタンスの大量生成が原因な模様。
*/
const posts = window.document.getElementsByClassName('post');
return new PostList(Array.from(posts).map((e) => new Post(e)));
}
/**
* 開いてるスレのレス全て取得してPostDOMListに格納して返す。
* @returns
*/
function createPostDOMList() {
const posts = window.document.getElementsByClassName('post');
for (let index = 0; index < posts.length; index++) {
//HTMLCollectionからElementを1つずつ抽出して配列に。
arrPostDOMList.push(posts.item(index));
}
return new PostDOMList(arrPostDOMList);
}
/**
* 開いてる投稿結果画面に表示されてるエラーを読み取ってPostErrorMessageインスタンスを作って返す。
*/
function createPostErrorMessage() {
window.document
class Onanie { ... }
今やもうFANZAとなっているが、DMMの時代からライブチャットにはお世話になっている。
お気に入りパフォーマーはどんどん消えていく中、10年くらい前からノンアダ一本でやっている人もいる。
そんなFANZAライブチャットだが、マダムフロアがとてもじゃないがゲテモノ揃いだ。見るも悍ましいサムネが並んでいる。吐き気すら覚える。
フィルタは「すべての女の子」「お気に入り」「新人」「巨乳 顔出し」しかなく使い勝手がくそ悪い。
「アダルト」と「ノンアダルト」しか見たくない。マダムとかいうあんなゲテモノカテゴリを非表示にしたい。
加えてアダルト、ノンアダルトにいるゲテモノや不快なサムネの奴らを一掃したい。
意見を送ったところで実装はされないので自力で何とかしてみようと思った。
まず、昔?ニコニコ動画でマリオメーカーだかの動画を除外する拡張機能+スクリプトがあったがあれに似たものはないかと探したがなかった。
色々試したが、「はちまバスター」という拡張機能。これが素晴らしかった。
もともとはまとめサイトをぶち消すものだが、キーワードやURLで非表示にすることが可能だ。
元からこの拡張機能は渡辺直美、フワちゃんをはじめとする各種ゲテモノ、ウーマン本村、ラサール石井、立花孝志などの目に入れたくないものを排除するために入れていたのだがこれが使えた。
ライブチャットでの使い方は簡単だ。ゲテモノを右クリックしてはちまバスターに追加(URLでの追加)これだけでどんどん快適になっていく。
が、マダムは9割ゲテモノだ。追加しようにも追いつかない。溢れかえるゲテモノ。追加されるゲテモノ。
これには悩んだ。
はちまバスターで追加したものは非表示ではなく「censored」となるためこういった一覧での表示では見栄えも悪い。
キーワードで指定しようにもパフォーマーのIDはランダム。アダルトは01***とかではない。
そして次に目を付けたのが内部ソース。
パフォーマーIDに規則性はない、が表示ではアダルトやらノンアダルトでカテゴライズされているので何かしらあるはず。と覗いた。
そして発見する「listbox madam」
だが今回ははちまバスターではない。先述の通り除外したところで「censored」となる。今度は非表示にしたい。
追加は簡単だ。
##li[class="listbox madam"]
とぶち込んでやればいい。
だが気を付けてほしい。listboxとmadamの間は半角2つだ。拡張機能によっては半角2個が1個とされてしまうものもあるので注意してほしい。
これだけであのゲテモノカテゴリが非表示となるのだ。そしてアダルト、ノンアダルトのパフォーマーだけが表示されるのだ。
これで当初の目的の8割は達成できた。これだけでもかなり快適になった。
アダルトだろうとノンアダルトだろうとスマホからインしてるやつのゲテモノ率は8割くらいある。
「span class="smartphone"」があるのは見つけているがこれを含んだやつを排除すればいいはずなのだが…
あとは写真が反対になってるやつとか私が不快と思う顔をAIかなんかで自動で非表示にしてくれたら…と思う。
あ。パフォーマーが動画販売できるやつを終了させたのは英断だと思います。ほぼほぼクリーチャーだったし、ほぼ毎日出してたSMおばさんも不快だったので。
関数型プログラミングが『銀の弾丸』であるという非常識な常識2022のなにがダメなのかわからない人が多いようなので、個人攻撃をまったくせずにダメ出しする。
まず言っておくが、私はあの記事をほとんど読んでいない。しかし、簡単にダメ出しできる。
記事内を「末尾再帰」で検索してみよう。1か所もヒットしない。「末尾」でも1か所もヒットしない。そう、あの記事はめちゃくちゃ長いのに末尾再帰に触れていないのである。では「再帰」ならどうだろう。11か所ヒットした。しかし、具体的な再帰のコードはまったくない。長い記事内にあれだけ多数のコードを書いているにも関わらずである。
「末尾再帰って何?」とか「再帰ってそんな重要なの?」と思う読者も多いだろうから、末尾再帰の重要さだけ説明しよう。
あの記事は、forやwhileを使わないプログラミング手法を前提に書かれている。記事内を「制御」とかで検索すればわかる。
末尾再帰はforやwhileの代わりになるもので、そういったプログラミング手法には欠かせない。forもwhileも末尾再帰も使わないとなると、ツリー探索などのアルゴリズムを書くことが困難になる。(こういったことが苦手な私に思いつく他の方法は、setIntervalを無理やりforループの代わりにするくらい)
そもそも、ほとんどのJavaScript実行環境は、末尾再帰をサポートしていない。つまり、JavaScriptはforやwhileを使わずに込み入ったプログラムをまともに書けるような言語ではない。あの記事に書いてあるようなことをする言語ではないのである。私は別にそれでもいいのでTypeScript使いまくってるけど。classとか好きだし。
あの記事がJavaScriptを使っている理由は、JavaScriptが人気だからだろうか?もしそうだとしてもダメである。あの記事は「JavaScriptは、ほどんどの実行環境が末尾再帰をサポートしていない、このプログラミング手法に適していない言語である」といったこと自体に触れていない。人気のある言語を使いたいなら、他の末尾再帰をサポートしている人気言語を使えばいい。
ろくに読まなくても、他にもダメ出しできる。
関数型プログラミングで気になるのは、言語にもよるが実行速度やコンパイルにかかる時間である。銀の弾丸と言うからには、C言語を使うような場面でも銀の弾丸でなければならない。(Haskellの実行速度はC並に早くできるそうだが)
記事内を「パフォーマンス」で検索したところ、実行速度に関する箇所がヒットした。
記事の実行速度関連の内容を要約すると「最近はAWS・Azure・GoolgeCloudPlatformなどを使って並列計算するので、昔ながらの命令型の順次実行は不適切である」となる。私が嘘を言っていると思うなら、記事内を「パフォーマンス」とか「AWS」で検索してヒットした箇所の前後を読んで欲しい。そんなに長くはない。
【1.事実】
今日2021/10/31、Fordham Universityのサイトで卒業生リストclass of 2021 graduatesを閲覧し、新婚の夫君の名前を入力して検索した。
結果を言うと、夫君は卒業生の中に出てこない。これは誰でも確認可能なので、疑う人は試してみることを推奨する。下記のリンクから確認可能なはずである。
https://nc-vc-ceremonies.s3.amazonaws.com/s/fardham/index.html?
===
【2.推論】
悪意を排した上で、有り得そうな事を推論すれば、以下のようになる。
「7月に弁護士資格試験が行われた時には、受験の条件である卒業生の扱いであり、本人もそう思っていた。
しかし、その後、卒業生としての資格を満たしていない何らかの理由(例:単位不足など)が判明し、そのために卒業生名簿から大学側もいったん除外した。現在閲覧が可能な卒業生リストに名前が見当たらないのは、そのためである。
卒業生の条件を満たしていない情報が、弁護士資格試験の運営者へと伝えられたのは、弁護士資格試験の終了した後であった。
これならば、一応の辻褄が合う。日本でも時々、事務方のミスなどで単位不足が後から判明したという話を見聞することはある。
===
【3.展望】
次回2月に行われる弁護士資格試験に向けて、これから頑張るのであれば、まずはFordham Univ.から卒業生として承認・公表される卒業資格を取得する必要がある。
本人は、卒業生名簿に自分の名前が無いことを知っているのか否かについて。もしも知らなければ、2月に試験会場へ赴いた時、門前払いを受ける可能性が有る。普通ならば判明した時点で、大学から本人に対して「単位が不足している」とか何とか連絡しているはずである。だから、流石に本人が知らないことはないだろう。問題は、いつそれを知ったのかである。
義理の父親に「大丈夫か?」と訊ねられて「大丈夫です」と答えたと報じられたところを見ると、その時点では本人も自分は卒業していると認識していたのであろう。おそらく、不合格通知のメールが来るまで、本人も知らなかったのではないだろうか。漫画『とどろけ一番』でも、自分は小学6年生と思っていた主人公が中学受験に挑んだら、実は小学5年生だった事実が発覚して不合格になるというエピソードがあった。あれは主人公の母親のミスだった。それと似たような話であろう。
https://www.agr.nagoya-u.ac.jp/~jsbba/150/150.submission.pdf
発表番号を主
催者側で記入
します
発表者氏名(講演者には○印を付加、
https://www.fuji.ac.jp/parent1/
第一階層ページ1第一階層ページ1第一階層ページ1第一階層ページ1第一階層ページ1
横一列ボタン横一列ボタン横一列ボタン横一列ボタン横一列ボタン
https://www.jsme.or.jp/kt/tokyo/sub_template.html
見出し1
ああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ
現在表示中のページはメニューの色を濃くしています。必要に応じて、ソースの▼navigation▼の中で、li の後のclass="now"を入れる場所を変更してください。
http://www.osakac.ac.jp/labs/akutsu/h20/Mathushita/aaaa.htm
ああああああああああ。
ああああぁああああ?
ああああああああああああぁああぁああぁぁぁぁぁ!
ああああああああああああ
ああああああ
あ
装備のセットにあたま、防具、こてみたいな種類があってそれをList<List<bool>>で管理していた
この変数とは別にアイテム一覧みたいな変数もあって(String[]{初級、冒険者、炎。。。}みたいな)そこと突き合わせて使っていた
これはDB管理するときに一つのこの変数自体を一つのKeyValueで管理していたからなんだけど
最近そういうものを管理するための方法が用意されてて、〇〇セットKeyValueで{頭 = true、防具。。。}みたいなセットごとに保存するAPIがあることを知った
だからローカルのほうでもList<Bool>じゃなくてClassとか構造体に変えることも可能なんだけど、これってわかりやすさのために変えるべき?
開発終盤でショップ機能とか装備入れ替えで使ってるから結構修正いるんだが、DBから引っ張てくるときにList<bool>に変えることで対応も可能
プログラマーに憧れる皆さん!こんばんは。
「自分は文系だから」「未経験だから」と諦めていませんか?大丈夫です!プログラミングにセンスは不要です。正しい手順で学べば、文系や未経験でも、誰でも一流のプログラマとして活躍することができます。
今日は、未経験から最短でWeb系企業に就職するための勉強法をご紹介します!
もっともオススメの方法は、顕正会のセミナーに参加することです。
顕正会は、日本で最大のエンジニアのコミュニティであり、非常に良質なテキストを用いて、プログラミング初心者向けのセミナーをしていることで有名です。顕正会に入ることで、未経験からでも一流エンジニアのノウハウを学ぶことができます。
また、意外と知られていませんが、日本のエンジニアの8割は顕正会の出身です。実はあのひろゆきやビル・ゲイツも顕正会の出身です。ですので、顕正会のネットワークを介して就職先を斡旋してくれたりしますし、自分が顕正会員だと、面接時にも非常に有利になります。
顕正会のセミナーは、インターネットからも応募することができますし、秋葉原などで声をかけられることもありますので、誰でも簡単に参加できます。会員もフレンドリーな方ばかりですので、是非、お気軽に応募してみて下さい!無料体験もできますよ。
プログラミングの勉強を始める前に、まず、必要なものを準備しましょう。必ず必要なものと、できればあると良いものは以下の通りです。
可能な限りスペックの高いものを買いましょう。2021年現在であれば、CPUは18コア、36スレッド。RAMは128GBくらいはあると良いでしょう。ストレージはSSDであれば1TBもあれば十分です。
OSは、Windowsで開発するならWindowsが、Macで開発するならMacが必要です。よく分からなければMacを買っておく方が良いでしょう。基本的にMacにできてWindowsにできないことはありません。
インターネットは、この記事を見ている人は既に持っているでしょう。ただし、モバイル回線で見ている人は、自宅に有線のインターネット環境を用意した方が良いです。
顕正会に入会すれば、上記のスペックのPCを無料で貸し出ししてくれます。また、法人向けの専用線を無料で取付工事を行ってくれる上に、通信費を全て負担してくれます。
まず、他の会員と連絡を取るために、SNSのアカウントを持っていると良いでしょう。
最近は完全にPC上での学習もできますが、やはり、勉強の基本は紙のノートに直接書くことです。医学的にも、手指の動きと脳の記憶回路が関連していることは証明されており、手を動かすことで効率的にものを覚えることができます。
Kindleなどの電子書籍リーダーは持っておいた方が良いです。紙の本は時代遅れです。いやしくもITのプロを目指そうという人間が、このような最先端のデバイスを使っていないのは恥だと思うべきです。紙の本を買わないことは、環境を守ることにも繋がります。現金も持つのはやめましょう。
せっかくセミナーに参加しても、受身で聴くだけでは、プログラミングを習得することは難しいです。ここでは、自宅でどのような勉強をすればよいのか、ご紹介します。
まずは、教科書や参考書を写経することから始めましょう。教科書や参考書の本文を一字一句正確に書き写すのです。
よく、「写経は理屈を学べないからだめだ」と批判されますが、まずは正しい「型」を体に覚え込ませるのが先です。野球や水泳などでも、細かい理屈よりも先にフォームを固めるのと同じです。書き写している内に理屈は自然と身に付きます。
また、写経のメリットは「飛ばし読み」を防げるところです。一字一句正確に写経をすれば、細かい部分を「分かったつもり」になって飛ばしてしまうことを防げます。たとえば、比較演算子の等号は=ではなくて、==です。プログラミングはこういうところに注意して学ばなければいけません。
教科書のサンプルコードをノートに書き写したら、それを今度は自力でフローチャート(UML)に変換してみましょう。そうすることで、自分が本当にそのコードを理解しているのか、確かめることができます。
フローチャートやUMLが素早く正確に描けることは、プログラマーとして働く上で非常に重要なスキルです。それらはソフトウェア設計の基礎となりますし、ソースコードを読めない営業や顧客にとっては貴重な資料となるからです。プロのエンジニアは、COBOLのソースコード10万行を1週間でフローチャートにして、Excelに転載することができます。
ここで一つ注意すべきことがあります。フローチャートを描くときは、必ず専用の定規を用いて描いて下さい。フリーハンドで描いたものは業務ではフローチャートとは認められません。これはまともな企業に就職すれば研修などで必ず習うことですから、今の内に覚えておきましょう。
エンジニアを目指すのであれば、プログラミングだけではなく、Excelの使い方も学びましょう。Excelはエンジニアにとっての万能プラットフォームです。エンジニアはあらゆる作業をExcelで行います。セル結合や罫線を用いて、見栄えの良い資料を作る技術は、エンジニアにとって必須です。
プログラミング学習中であれば、たとえば以下のような題材の資料を作ってみると良いでしょう。
尤も、以上の資料は、ツールを使うことで自動で作成することもできます。たとえば、ソースコードの更新履歴はGitなどのバージョン管理システムを使うことでも管理できます。しかし、それらの資料としてのクオリティは非常に低いため、アマチュアしか使うことはありません。プロを目指す皆さんは、必ずExcelを使いこなせるようになりましょう!VBAの習得も必須です。
以上、プログラミングの勉強法について解説しました。ここからは、実際にソースコードを書くときのコツを紹介していきます。他のプログラマと差をつけることができる技術ですので、意識するようにして下さい。
理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。
また、変数の宣言と使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分もミスしにくくなります。
変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。
多くのプログラミング言語には、クラスや関数といった機能がありますが、これらは基本的にライブラリ提供者などが使う想定の機能であり、一般のプログラマが使うのは好ましくありません。したがって、クラスや関数はなるべく使わないようにして下さい。
不要な関数を作らないためのテクニックには、以下のようなものがあります。
まず、関数の引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数で複数の処理をすることができます。
function f(i) { switch(i) { case 1: // i = 1のときの処理 break; case 2: // i = 2のときの処理 break; case 3: // i = 3のときの処理 break; // ... } }
この方法は、以下に述べる「変数の寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます。
クラスに不要な関数を作らないようにするには、「継承」を用います。複数のクラスで用いる関数を定義したクラスを1つ作っておき、そのクラスを継承すれば、新しいクラスに関数を定義する必要はありません。
理想的には、プログラム内のすべての関数を同一のクラスに定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、プログラマからはこの上なく尊ばれています。
class God { f1() { // 関数1 } f2() { // 関数2 } // ... } class C1 extends God { // 何も書かなくても上の関数が使える! } class C2 extends God { // 何も書かなくても上の関数が使える! } // ...
変数は宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数の寿命が長い」と言います。
たとえば、以下のコードのaは、関数定義の外側からは参照することができません。
function f() { var a = 1; return a; }
一方、以下のコードのaは関数の内外どちらからでも参照することができます。
var a = 1; function f() { a = 2; return a; }
せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまいます。
また、変数の寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数の寿命を長くするとプログラムを変更しやすくなります。つまり、保守性が上がります。
例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイルが存在しない場合は、例外となります。
例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマは例外をきちんと処理しなければなりません。
ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。
try { // 例外が発生し得る処理 // ex. ファイルを開く } catch (e) { // 例外が発生したときに、実行する処理 }
例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラムは動作を続けます。
try { // 例外が発生し得る処理 } catch () {}
全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから、例外が発生し得るコードは、積極的に上記のtry-catch構文を用いて、例外を潰すようにしましょう。
もと増田だけど、気分まぐれに書いた駄文なので気にしないといてくれ。
それはさておき、Python が好きってことはプログラミングが好きってことで良いね?だとすると、最終的には C 言語やることになるけど、今は Python をやろう。なんと言っても、Python は C 言語できているけど、C言語は謎いので無視してオッケー!
そんでもって、Python の「公式ドキュメント」をきちんと読みこなせるようになろう。最初はから全部は必要ないけど、最終的には読みこなせるようになろう。そんでもって、プログラミングをしたいってことは「何かを作りたい」のだろ?たとえば、増田を作りたかったら Python だと Django や Flask を、人工知能を作りたかったら PyTorch を使うことになるだろうけど、その手のフレームワークの「公式ドキュメント」を読みこなせるようになろう。プログラミングスクール(やめとけよ)や本は「公式ドキュメント」を読めるようにする手段だと思ってくれ。間違っても「本に書いてあったのに、動かない!」なんて、喚かないでね。洋書も和書も「公式ドキュメント」以外のテキストは間違っていることがあるので。
次に「エラーは友達」ということ。エラーはあなたを否定したのでなく、コードを否定したのであって、エラーが出ても気にしないでください。そんでもって、エラー文を丁寧に解決していけば、すごくスキルが身につきます。
最後に、Python 言語だけじゃ解決できないプログラミングの問題は多々あります。データベースを操作するには SQL が、ウェブサイトを動かすには JavaScript が、ウェブサイトを作るには HTML/CSS が、サーバーを設置するにはシェル言語が、Python を高速化するには C言語が、必要になる場合がありますが Python を使いこなせると、おそらく習得は容易でしょう。なぜかというと「Python だとチョメチョメだったっよなー、これでいけないか?」という勘が形成されるので。
チューリング完全な言語はどれも表現力は同じだから、「この言語だから成功する」というのは無いよ。Python は interface が無くて、class が弱くて、動的型付けを用いているけど、これらがないと「制約」を課すことができないというフリーダム過ぎるから、嫌らわれることはあるけどね。制約が強い言語は、ハンターハンターふうに言うと「制約が念能力を強くする」みたいな要素はあるよ。
どうしても教育を受けたいという希望があるのなら、ハーバードの CS50 という講義が無料で見れるから、推薦したいね。あれみると、我が国は計算機科学は負けていると思った。
変数や構文などのプログラミングの基礎は覚えた人向けに、ソースコードを書くときのコツを紹介していきます。どれも今日から実践できるものばかりです。他のプログラマと差をつけることができる技術ですので、ぜひ意識するようにして下さい。良い子はまねしないで下さい。
理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。
また、変数の宣言と使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分もミスしにくくなります。
変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。
多くのプログラミング言語には、クラスや関数といった機能がありますが、これらは基本的にライブラリ提供者などが使う想定の機能であり、一般のプログラマが使うのは好ましくありません。したがって、クラスや関数はなるべく使わないようにして下さい。
不要な関数を作らないためのテクニックには、以下のようなものがあります。
まず、関数の引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数で複数の処理をすることができます。
function f(i) { switch(i) { case 1: // i = 1のときの処理 break; case 2: // i = 2のときの処理 break; case 3: // i = 3のときの処理 break; // ... } }
この方法は、以下に述べる「変数の寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます。
クラスに不要な関数を作らないようにするには、「継承」を用います。複数のクラスで用いる関数を定義したクラスを1つ作っておき、そのクラスを継承すれば、新しいクラスに関数を定義する必要はありません。
理想的には、プログラム内のすべての関数を同一のクラスに定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、その利便性からプログラマからはこの上なく尊ばれています。
class God { f1() { // 関数1 } f2() { // 関数2 } // ... } class C1 extends God { // 何も書かなくても上の関数が使える! } class C2 extends God { // 何も書かなくても上の関数が使える! } // ...
変数は宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数の寿命が長い」と言います。
たとえば、以下のコードのaは、関数定義の外側からは参照することができません。
function f() { var a = 1; return a; }
一方、以下のコードのaは関数の内外どちらからでも参照することができます。
var a = 1; function f() { a = 2; return a; }
せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまいます。
また、変数の寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数の寿命を長くするとプログラムを変更しやすくなります。つまり、保守性が上がります。
例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイルが存在しない場合は、例外となります。
例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマは例外をきちんと処理しなければなりません。
ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。
try { // 例外が発生し得る処理 // ex. ファイルを開く } catch (e) { // 例外が発生したときに、実行する処理 }
例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラムは動作を続けます。
try { // 例外が発生し得る処理 } catch () {}
全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから、例外が発生し得るコードは、積極的に上記のtry-catch構文を用いて、例外を潰すようにしましょう。