問題としてXとYの否定論理積 X NAND Yは,NOT(X AND Y)として定義される。X OR YをNANDだけを使って表した論理式は?みたいなの出ると「……?」ってすげえ時間かかる
]]>論理和とか論理積とか
]]>/**************************************
以下のCSV_DIR, FILE_PATHS, SETTINGSを書き換えてね。
<h3>o- *************************************/</h3>//CSVファイルが置かれてるディレクトリのパス。投稿前にエラー出たら大体ここの設定ミス。 例:"C:\\Users\\sakuraimasahiro\\Documents\\iMacros\\Macros\\rentou\\";
const CSV_DIR =
'C:\\Users\\USER\\Desktop\\iMacros\\Macros\\rentou\\';
//ファイルのパス。CSVは絶対パスで、拡張子も必要。iimは相対パスでよく、拡張子不要。
const FILE_PATHS = {
//投稿文が書かれたCSVファイル名
textCsv: CSV_DIR + 'textNoAnker.csv',
//レス用投稿文が書かれたCSV。通常とレス用で分けないなら同じファイルを使えばいい。
replyTextCsv: CSV_DIR + 'textReply.csv',
};
const SETTINGS = {
//投稿後の基本待ち時間
baseWaitTime: 5,
//baseWaitTime+0~waitTimeRange(ランダム)だけ待つ
waitTimeRange: 5,
//連投しすぎだと忠告された場合に処理を一時停止させる時間(秒)
waitTimeForAvoidingPunishment: 60 * 30,
//メール
mail: 'sage',
//名前設定
nameSettings: {
//名前。名無しなら''。
name: '',
//以下、偽装ワッチョイ設定。浪人でワッチョイを非表示にしてるときだけtrueにしてね。
//妙なニックネーム(ワッチョイ、アウアウウーなど)をランダムで決めて付加するかどうか。true=付加する。false=付加しない。
nickname: false,
//妙なニックネームの後に付く8桁の文字列をランダムで決めて付加するかどうか。
korokoro: false,
//IPをランダムで決めて付加するかどうか。
ip: false,
//地域をランダムで決めて付加するかどうか。
area: false,
},
postSettings: {
//アンカー無し投稿をするならtrue。しないならfalse。noAnkerPostかreplyPostのどちらかはtrueにすること(両方trueでもOK)。
noAnkerPost: false,
//アンカー付き投稿(返信)をするならtrue。しないならfalse。もしnoAnkerPostとreplyPostの両方がtrueの場合、投稿は返信が優先され、返信対象が見つからなくなったらアンカー無し投稿をする。
replyPost: true,
//最初に取得するアンカー無し投稿文CSVファイルの行番号。もし返信用と同じCSVファイルを使うなら-1と入力。
noAnkerPostTextCsvStartRow: 1,
//最初に取得する返信用投稿文CSVファイルの行番号。もしアンカー無しと同じCSVファイルを使うなら-1と入力。
replyPostTextCsvStartRow: 1,
//テキストCSV/返信用テキストCSVの取得行が最終行に達したら最初の行まで戻るかどうか。true=戻る。false=マクロ終了。
textCsvLoop: true,
//返信する場合、これより小さなレス番には返信しない。返信を投稿すると、この数値は前回の返信先のレス番に更新される。
minAnker: 895,
//返信する場合、名前に以下の文字列を含む投稿にアンカーをつけて返信する(ワッチョイやIPなど名前フィールドにあるものならなんでも可)。配列で複数指定可能。指定無しなら空配列([])。filterNamesとfilterNamesNotIncluded共に無指定ならレス番1から順に返信していく(minAnkerが設定されてればそこから順に)。以下のfilter系は全て併用可能。
filterNames: [],
//↑とは逆に、名前に以下の文字列を含まない投稿にアンカーをつけて返信する。↑と併用も可能。
filterNamesNotIncluded: [],
//返信する場合、本文に以下の文字列を含む投稿にアンカーをつけて返信する。
filterText: ['自演かな', '自演わらわら', 'スクリプト使うの', '安価ガバ', '>>660', '自演で擁護', '最後' ,'あいうえお', 'かきくけこ', 'さしすせそ', 'なにぬねの', 'はひふへほ', 'まみむめも', 'やいゆえよ', 'やゆよ', 'らりるれろ', 'わいうえを', 'わをん', 'わいうえをん'],
},
//自分のIPアドレスの確認。VPNとかでIPを変更してマクロを動かしてるとき、突然VPNが作動しなくなってIPが元に戻ったときにマクロを止めるためのもの。
ipSettings: {
//自分の現在のIPアドレスの確認をする。
checkIp: true,
//以下の文字列が自分の現在のIPアドレスに含まれている場合、マクロを一時停止する。基本的に自分の本当のIPアドレスを入力。
avoidTheIp: '133.206.99.224',
},
//浪人設定。最後に動作を確認したのは5年くらい前で、今も同じように動作するかは、浪人を持ってないから確認できずわからない。
roninSettings: {
//浪人にログインしてるかどうかをチェックするかどうか。trueならする。falseならしない。trueにしていてもし浪人にログインしていないことを確認したらログインしにいく。
checkLogin: false,
//浪人ログイン用メールアドレス
mailAdress: 'abc@def.com',
//浪人ログイン用パスワード。
password: '1234',
},
//false: run()実行させず(デバッグ用)
run: true,
//true: 投稿処理だけしない デバッグ用
skipPost: false,
};
/**************************************
設定箇所終わり。
書き込めない時の早見表 - 5ちゃんねるwiki
<h3>o- *************************************/</h3>/**************************************
メモ
・クラスフィールドは宣言できない。
・NULL演算子(??)は使えない。論理積(&&)は使える。
・オブジェクトの分割代入はできない。
・importはできない。
<h3>o- *************************************/</h3>/**************************************
関数
<h3>o- *************************************/</h3>/**
* ここから始まる。
*/
function run() {
//設定ミスがないか調べる。
checkSettings();
var _TextCsvCursors = new TextCsvCursors(
new TextCsvCursor(
SETTINGS.postSettings.noAnkerPostTextCsvStartRow > 0
? SETTINGS.postSettings.noAnkerPostTextCsvStartRow - 1
: SETTINGS.postSettings.noAnkerPostTextCsvStartRow,
FILE_PATHS.textCsv,
SETTINGS.postSettings.textCsvLoop,
),
new TextCsvCursor(
SETTINGS.postSettings.replyPostTextCsvStartRow > 0
? SETTINGS.postSettings.replyPostTextCsvStartRow - 1
: SETTINGS.postSettings.replyPostTextCsvStartRow,
FILE_PATHS.replyTextCsv,
SETTINGS.postSettings.textCsvLoop,
),
);
var _LoopStatuses = new LoopStatuses(0, SETTINGS.postSettings.minAnker);
const _MyPosterName = new MyPosterName({
name: SETTINGS.nameSettings.name,
});
//スレURL指定
const _ThreadUrl = openPromptThreadUrl();
//ループ
while (true) {
//IPを確認する設定なら、それをする。
SETTINGS.ipSettings.checkIp && checkCurrentIpNotTheIp();
//スレを開く
openUrl(_ThreadUrl.fullUrlHttps());
//浪人にログインする設定なら、浪人にログインしているかどうかを確認し、していなければログインしにいく。
if (SETTINGS.roninSettings.checkLogin) {
if (!checkRoninLogin()) {
loginRonin();
continue;
}
}
//投稿に使うテキスト取得。
const p = (function () {
if (SETTINGS.postSettings.replyPost) {
//返信あり設定の場合。返信対象が無いか調べる。
const targetAnkerNumber = createPostDOMList()
.filterPostnumberHigher(_LoopStatuses.currentMinAnker())
.filterByPostername(SETTINGS.postSettings.filterNames)
.filterByPosternameNotIncluded(
SETTINGS.postSettings.filterNamesNotIncluded,
)
.filterByText(SETTINGS.postSettings.filterText)
.lowestPostNumber();
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) {
//投稿。
postThenCheckError(
_ThreadUrl.serverName(),
_MyPosterName.randomize({
nickname: SETTINGS.nameSettings.nickname,
korokoro: SETTINGS.nameSettings.korokoro,
ip: SETTINGS.nameSettings.ip,
area: SETTINGS.nameSettings.area,
}),
SETTINGS.mail,
p.text,
);
//_TextCsvCursorsと_LoopStatusesを更新。
_TextCsvCursors = p.updatedTextCsvCursors;
_LoopStatuses = p.updatedLoopStatuses.incrementPostCount();
messageDisplay([
`投稿回数: ${_LoopStatuses.currentPostCount()}`,
`minAnker: ${_LoopStatuses.currentMinAnker()}`,
`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,
`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,
]);
} else {
messageDisplay([
`返信対象が現われるのを待機中...。`,
`投稿回数: ${_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 メール
* @param {MyText} _MyText
* @param {number} retryTimes
* @returns {void}}
*/
function postThenCheckError(
serverName,
_MyPosterName,
postMail,
_MyText,
retryTimes = 0,
) {
const r =
retryTimes === 0
? new ValuesOfPost(serverName, _MyPosterName, postMail, _MyText).post(
postTo5chTread,
postConfirm,
)
: new ValuesOfPost(
serverName,
_MyPosterName,
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();
return postThenCheckError(
serverName,
_MyPosterName,
postMail,
_MyText,
retryTimes + 1,
);
} else if (error.order === 'WAIT') {
wait(SETTINGS.waitTimeForAvoidingPunishment);
return postThenCheckError(
serverName,
_MyPosterName,
postMail,
_MyText,
retryTimes,
);
} else if (error.order === 'LOGIN') {
//動作未確認
return postThenCheckError(
serverName,
_MyPosterName,
postMail,
_MyText,
retryTimes,
);
}
return;
}
/**
* 現在のIPアドレスに、SETTINGS.ipSettings.avoidTheIpの値が含まれていないことを確認する。含まれていたらマクロを一時停止。
* @returns
*/
function checkCurrentIpNotTheIp() {
//IP確認ページへ飛ぶ
openUrl('https://www.cman.jp/network/support/go_access.cgi');
const _IpAdress = createIpAdressFromCMan();
if (_IpAdress.includes(SETTINGS.ipSettings.avoidTheIp)) {
pause('現在のIPに指定した値が含まれていることを確認。');
//ポーズ解除したならもう一度確認しに。
checkCurrentIpNotTheIp();
}
return;
}
/**
* 設定に致命的な問題が無いか検査。
* @returns
*/
function checkSettings() {
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を受け取る。
* @returns {ThreadUrl}
*/
function openPromptThreadUrl() {
const url = prompt('スレURLを入力');
return new ThreadUrl(url);
}
/**
* 開いてるスレのレス全て読み取ってPostListインスタンスを作って返す。
* 重すぎるので使うのやめ。どうやらインスタンスの大量生成が原因な模様。
* createPostDOMListを使う。
* @returns {PostList}
*/
function createPostList() {
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');
var arrPostDOMList = [];
for (let index = 0; index < posts.length; index++) {
//HTMLCollectionからElementを1つずつ抽出して配列に。
arrPostDOMList.push(posts.item(index));
}
return new PostDOMList(arrPostDOMList);
}
/**
* 開いてる投稿結果画面に表示されてるエラーを読み取ってPostErrorMessageインスタンスを作って返す。
* @returns {PostErrorMessage}
*/
function createPostErrorMessage() {
return new PostErrorMessage(
window.document
社員は20人程度だったが、そこでは1.5流の情報系大学中退野郎で何かある前に先回りして自虐してごまかすような、プライドだけは中途半端に高くいクソ雑魚ニートもどきにも優しい会社だった。
小さい会社だからこそ、数学をかじったことがある人がほとんどおらず、論理和、論理積みたいなことをいうだけで驚かれるような会社だった。
そのおかげで運良く高い評価をもらって、またたく間に昇格していった。
また、少人数だからこそ、案件の中心ではなく、案件の周辺のゴミ拾いみたいな仕事が中心だったこともあり、隙間産業ソルジャーとしてのSIerスキルを着々と得ることができた。
最終的には自分の部下になった先輩と小競り合いをして、10年働いた会社を退職した。
退職時、年収は400万もなかった。
自分はもっと上に行ける、と社員200人程度の会社に転職した。
新しい会社では前の会社の最終役職が管理職だったため、管理職ほどではないにせよ、サブリードの立場でオファーにをもらった。
以前の会社では案件をのがしたらそのまま餓死するようなプレッシャーがあったので、仕事を全力で取りに行きつつ人を確保していこう、というやり方が正義だと思っていたのだが、どうも社内政治のようなものに巻き込まれている事に気がついた。
現場の営業との仲は良好だと思っていたが、お互いの上司が自分たちを使って代理戦争をしているような雰囲気を感じるようになった。
仕事じゃない部分に精神をすり減らされる事が多く、辟易していた頃に、自分が所属する部の部長が、パワハラやセクハラを理由に、左遷された。
部長が左遷される頃には、自分もすっかり「この会社でずっとくだらない低次元な社内政治のコマにされるのか」みたいなよくわからない諦念を覚えて、その頃たまたまオファーをもらって転職した。
退職時、年収は500万もなかった。
数年管理職を過ごしたらメーカに転職しよう、外資系に転職した。
それが間違いだった。
これまでの「案件をのがしたらそのまま餓死するようなプレッシャー」を持ったままこんな会社に入ったのは大きな間違いだった。
成長を求めてこの会社に入ったのに、常に極度のプレッシャーに苛まれ、何をしても結果が出たとは思えない日々が続いている。
5年しがみついてきたが、未だに管理職の一つ手前のランクで止まっている。入社から変わらないキャリアランク。
この5年の間に年収はほぼ倍になり、残業代を抜きにしても前職の1.5倍はもらえるようになった。
残業代を入れれば桁が変わるレベルにもなった。
それでも、どんなに残業しても仕事は減らず、常に叱責され、呆れられ、結果が出せない日々が続く。
結局は、小さい会社では昇格するスキルはあったかもしれないが、大学を中退するようなクソニートには外資系は強すぎる。
つい三日前に、40歳になった。
当初描いていた「外資系の会社で管理職になってハクをつけてからメーカに転職しよう」というプランはすでに崩れている。
先週は産業医面談を進められ仕方なく面談したのだが、その面談で急に泣き出してしまった。40の誕生日を前に泣いている自分も情けないし、それで休職を進められても結局それを黙って、仕事を続けている自分がいる。
結果が出ないのに。
多分ここからは、転げ落ちていくだけなのだと思う。
年収も、キャリアも、今がピークであり、ここからは「仕事ができない自分」を受け入れて、成果主義からはじき出されて、そうして生きていくのだと思う。
こうやって仕事ができない自分を受け入れようとすると、別に仕事で自己実現、なんて考えたこともなかったのに、ふと、自分の過去を振り返ると、結局仕事しかできていなかったのだと感じる。
そんな自分が、仕事ですら評価されなくなったら、何で評価されれば良いのだろう。何で結果を出せば良いのだろう。
だけど、もうこれ以上キャリアアップはできないし、ステップアップもできない。
すでに天井に達してしまった、という実感をいだきながら、あと何十年仕事をすれば良いのか。
今日も5時間残業しながら思うのである。
]]>これは真偽値(真=true、偽=false)同士の組み合わせを評価し、結果をtrue/falseで返すというものだ。
この演算のための演算子の代表的なものがANDとORで、それぞれ論理積と論理和という。
式aとbにtrue/falseのいずれかが定義されているとして、
a AND bだったらaとb両方がtrueのときのみ、演算結果がtrueになり、
a OR bだったらaとbいずれかがtrueであれば、演算結果がtrueになる。
ということは、
ANDの場合は左辺の式がfalseの時点で、右辺を評価するまでもなく演算結果はfalseとなり、
ORの場合は左辺の式がtrueの時点で、右辺を評価するまでもなく演算結果はtrueとなる。
これを短絡評価といい、今どきのプログラミング言語では必ずこの仕掛けが実装されていると。
この他に、XORという演算子がある。
これは排他的論理和といい、演算子の右辺と左辺の結果が違う組み合わせの場合のみtrueとなる。
つまりa=trueかつb=falseの場合か、a=falseかつb=trueの場合のみ、演算結果(a XOR b)がtrueとなる。
問題は、どういうわけかこのXORには短絡評価が存在しないのだ。
どのプログラミング言語を調べても短絡評価がないので、かなり驚いている。
一体どういうこと?
(追記)
トラバがやかましいから言っとくけど、bool型をXORで比較できる仕組みのある言語限定の話な。
]]>そもそも、暴対法なんて人権侵害法を肯定しているのはさすがに人権意識をアップデートしたほうがいい
]]>オタクの皮を被った実質ただの人間関係野郎と会った時には鼻で笑い、関わる価値のない存在だと思った。
しかしそれ以上に、アニメもラノベも漫画もたくさん消費していて、それでいて人間関係も性関係もきちんとやっていっている人間に遭遇した時には、言いようのない殺意を覚えた。
彼の話すオタクトークは分かりやすく、確かに面白かった。しかし、彼が健常者であるというだけで、それは聞くに値しないものに感じられてしまった。
彼は俺よりもオタクとして深くやっていっているのは理解できた。それなら敬意を払ってこそ然るべきだと頭では分かっていても、生理的な嫌悪が拭えなかった。
そして俺は最初に書いたように理解したのだ。
これまではオタクと会うのが楽しいと思っていたのだが、それは単にオタクと社会不適合者はかなりの程度重なり合う集合であり、
俺がそれまで関わっていたのは大部分がその論理積であったというだけなのだ。
だからオタクではあるが健常者である存在に触れると、ただただ不快なだけだったのだ。
というかそもそも俺自身は社会不適合者ではあるが、オタクではないのかもしれない。
健常者との兼業に負ける程度なのだから。
いや、もしかしたら不適合者ですらないのかもしれない。
完全な健常者では決してないにせよ、不適合というほどでもない。
何せ障害者手帳を持っているわけでもなし、少なくとも書類上ではこの上なく「まとも」な人生を歩めてしまっている。
俺が社会不適合者だというのは高度に俺の主観及び俺自身の自発的な行動に依拠しているものである。
そうだとするなら、俺が社会不適合者と関わって楽しいと思えている理由は、単に社会不適合者を見下して優越感に浸れるから、ただそれだけではないか。
健常者にも不適合者にもなりきれず、本物の不適合者を見下すことだけが生きがいで、オタクを装ってはいるがその実大して対象への愛もない、空っぽな出来損ない。
それが自分なのだとしたら。
俺のこの不快感は、自分がそのような存在であることを否応なしに気づかされてしまったから、なのだとしたら。
]]>1+0=1
0+1=1
0+0=0
1+1=1
ちゃんと和になってる。
論理積の計算では、
1*0=0
0*1=0
1*1=1
0*0=0
積っぽいじゃん。
]]>なんで論理積がANDで論理和がORなんだ、普通逆だろ?
0×1も1×0も0になるんだから掛け算で良いじゃんって言う人がいるけど、じゃあ1+1が10にならないのだめじゃん変じゃんおかしいじゃん。
もっと良い言い方無かったの?
]]>一日8時間勉強時間があるなら、だいたい一ヶ月で終わる内容。
月額1000円だけどしっかり勉強すれば一ヶ月の無料期間中に終わると思う。
もともとN高等学校のノンプログラマーの生徒をWebエンジニアとして就職させるために作られたカリキュラムで講師曰く去年はこれで二人エンジニア就職を決めたらしい。
内容も相当親切に説明していて、プログラミングで何か作るだけじゃなくて、就職に必要な環境構築やセキュリティまでみっちりやる。
で講師が書いてる入門コースで習うことがまとめ。テキスト教材もあるけど授業も1項目を2時間で説明している。授業は週2の生放送とそのアーカイブがある。
↓みたいなことが学べる
----
Webプログラミング入門コース
Web ブラウザとは (Chrome, デベロッパーコンソール, alert)
はじめてのHTML (VSCode, HTML, Emmet)
さまざまなHTMLタグ (h, p, a, img, ul, tableタグ)
HTMLで作る自己紹介ページ (HTMLタグ組み合わせ, コンテンツ埋め込み)
はじめてのJavaScript (JS, ES6, エラー)
JavaScriptでの計算 (値, 算術演算子, 変数, 代入)
JavaScriptで論理を扱う (論理値, 論理積, 論理和, 否定, 比較演算子, if)
JavaScriptのループ (ループ, for)
JavaScriptのコレクション (コレクション, 配列, 添字, undefined)
JavaScriptの関数 (関数, 関数宣言, 引数, 戻り値, 関数呼び出し, 再帰)
JavaScriptのオブジェクト (オブジェクト, モデリング, プロパティ, 要件定義)
はじめてのCSS (CSS, セレクタ, background-color, border)
CSSを使ったプログラミング (transform, id, class)
Webページの企画とデザイン (企画, 要件定義, モックアップ, 16進数カラーコード)
診断機能の開発 (const, let, JSDoc, インタフェース, 正規表現, テストコード)
診断機能の組込み (div, 無名関数, アロー関数, ガード句, truthy, falsy)
ツイート機能の開発 (リバースエンジニアリング, URI, URL, URIエンコード)
Linux開発環境構築コース
LinuxというOS (VirtualBox, Vagrant, Ubuntuのインストール, OS, CUIの大切さ)
コンピューターの構成要素 (ノイマン型コンピューター, プロセス, lshw, man, ps, dfの使い方)
ファイル操作 (pwd, ls, cd, mkdir, rm, cp, mv, find, ホストマシンとの共有ディレクトリ)
標準出力 (標準入力、標準出力、標準エラー出力、パイプ、grep)
vi (vimtutor)
シェルプログラミング (シバン, echo, read, 変数, if)
通信とネットワーク (パケット, tcpdump, IPアドレス, TCP, ルーター, ping)
サーバーとクライアント (tmux, nc, telnet)
HTTP通信 (http, https, DNS, hostsファイル, ポートフォワーディング)
通信をするボットの開発 (cron, ログ収集)
GitHubでウェブサイトの公開 (GitHub, リポジトリ, fork, commit, 情報モラル)
イシュー管理とWikiによるドキュメント作成 (Issues, Wiki)
GitとGitHubと連携 (git, ssh, clone, pull)
GitHubへのpush (init, add, status, インデックス, commit, push, tag)
Gitのブランチ (branch, checkout, merge, gh-pages)
ソーシャルコーディング (コンフリクト、プルリクエスト)
Webアプリ基礎コース
Node.js (Node.js, nodebrew, Linux, REPL, コマンドライン引数, プルリク課題)
集計処理を行うプログラム (集計, 人口動態CSV, Stream, for-of, 連想配列Map, map関数)
アルゴリズムの改善 (アルゴリズム, フィボナッチ数列, 再帰, time, プロファイル, nodegrind, O記法, メモ化)
ライブラリ (ライブラリ, パッケージマネージャー, npm)
Slackのボット開発 (slack, mention, bot)
HubotとSlackアダプタ (hubot, yo)
モジュール化された処理 CRUD, オブジェクトライフサイクル, filter)
ボットインタフェースとの連携 (モジュールのつなぎ込み, trim, join)
同期I/Oと非同期I/O (同期I/O, 非同期I/O, ブロッキング)
例外処理 (try, catch, finally, throw)
HTTPサーバー (Web, TCPとUDP, Webサーバーの仕組み, Node.jsのイベントループ, リスナー)
ログ (ログ, ログレベル)
HTTPのメソッド (メソッド, GET, POST, PUT, DELETE, CRUDとの対応)
HTMLのフォーム (フォームの仕組み, form, input)
テンプレートエンジン (テンプレートエンジン, jade)
HerokuでWebサービスを公開 (Webサービスの公開, heroku, dyno, toolbelt, login, create, logs)
認証で利用者を制限する (認証, Basic認証, Authorizationヘッダ, ステータスコード)
Cookie を使った秘密の匿名掲示板 (Cookie, Set-Cookie, expire)
UI、URI、モジュールの設計 (モジュール設計, フォームのメソッド制限, リダイレクト, 302)
フォームによる投稿機能の実装 (モジュール性, textarea, 303)
認証された投稿の一覧表示機能 (パスワードの平文管理の問題, 404, テンプレートのeach-in)
データベースへの保存機能の実装 (データベース, PostgreSQL, 主キー)
トラッキングCookieの実装 (トラッキング Cookie, IDの偽装, Cookie の削除)
削除機能の実装 (データベースを利用した削除処理, 認可, サーバーサイドでの認可)
管理者機能の実装 (Web サービスの管理責任, 管理者機能の重要性)
デザインの改善 (Bootstrap, レスポンシブデザイン, セキュリティの問題があるサイトを公開しない)
脆弱性 (脆弱性, 脆弱性で生まれる損失, 個人情報保護法, OS コマンド・インジェクション)
XSS脆弱性の対策 (XSS, 適切なエスケープ処理, リグレッション)
パスワードの脆弱性の対策(ハッシュ関数, メッセージダイジェスト, 不正アクセス禁止法, パスワードジェネレーター, 辞書攻撃)
セッション固定化攻撃脆弱性の対策 (セッション, セッション固定化攻撃, ハッシュ値による正当性チェック)
より強固なセッション管理 (推測しづらいセッション識別子, 秘密鍵)
CSRF脆弱性の対策 (CSRF, ワンタイムトークン)
安全なHerokuへの公開 (脆弱性に対する考え方, HTTPの廃止)
Webアプリ応用コース
Webフレームワーク (Express.js, フレームワーク導入, 簡単なAPI, セキュリティアップデート, Cookie パーサー, ミドルウェア, 外部認証, ロガー)
ExpressのAPI (app, Properties, Request, Response, Router)
GitHubを使った外部認証 (Passport, OAuth)
テスティングフレームワーク (Mocha, レッド, グリーン, リファクタリング)
継続的インテグレーション (CircleCI)
クライアントのフレームワーク (Webpack, Chrome 以外のブラウザでもES6)
DOM操作のフレームワーク (jQuery, jQueryアニメーション, this)
AJAX (jQuery.ajax, クロスドメイン, 同一生成元ポリシー, x-requested-by, CORS)
WebSocket (WebSocket, WebSocketの状態遷移, Socket.io)
RDBとSQL (DDL, DCL, CREATE, DROP, INSERT, DELETE, UPDATE, WHERE)
データモデリング (リレーショナルモデル, 正規化)
テーブルの結合 (外部結合, 内部結合, 片側外部結合, JOIN ON)
インデックス (インデックス, 複合インデックス, Bツリー)
集計とソート (SUM, COUNT, ORDER BY, GROUP BY)
「予定調整くん」の設計 (要件定義、用語集、データモデル、URL設計、モジュール設計、MVC)
認証とRouterモジュールの実装 (Mocha, supertest, passport-stub, モックテスト)
予定とユーザーの保存 (セキュリティ要件, UUID, 複合主キー)
予定とユーザーの一覧の表示 (非同期処理, Promise, then)
出欠とコメントの表示 (入れ子の連想配列, Promise.all, 子どもからデータを消す)
出欠とコメントの更新 (Promiseチェイン, リファクタリング)
予定の編集と削除 (要件の衝突, 関数の再利用)
デザインの改善 (this, グローバルオブジェクト)
セキュリティ対策と公開 (X-Frame-Options, Herokuの環境変数)
]]>・if else の条件分岐の考え方(条件漏れをなくすという考え方含む)
・論理和、論理積の考え方
・デザインパターンの考え方(メソッドという概念を含む)
・バグチケットの書き方
・製造プロセス全体
こんな感じだけど、実務2年くらいやらなきゃ身につかない
学校で一体何を教えるんだ?
]]>論理積の優先順位を意識してれば、自分の文章のようにはならなかったですね。
指摘ありがとうございます。
あと、自分の伝え方が悪いのがいけないんですが、
言語的な仕様の話ではなくて、増田の条件式に対しての日本語化がおかしく見えるという話です。
「かつ」とか「または」とかって、1,2,3,4と処理の順序を書いていても、
言葉にしているときには、かかる範囲があいまいに見えたから、
結果的に分かりづらくなっているということを指摘したかったのですが、
すみません、反省します。
]]>自分の知っている言語では論理積・論理和の評価優先順位は同じ物ばかり
横だけど、大多数の言語は論理積の方が優先順位高くて、例外的な言語でのみ論理和の方が高いことがあると思ってた。
]]>自分の知っている言語では論理積・論理和の評価優先順位は同じ物ばかりで、上げられている条件分に関しては
if ((param==0 && 判定(param2)) || !param3) {~}
と等価になると思われます。
そのため、仮にparamが0以外だったとしても、!param3がtrueと評価されるような値の場合は条件を満たすと思われるのですが。(実際node.jsのv5.11.0で試した所そのようになりました。)
]]>まず最初の条件をif分を一回終わらせて入れ子にするか、falseならreturn させるといい。
入れ子になってもとにかく自分が分かるようにするといいです。
一行で書くのはそのあとではどうだろう
if(param == 0 && test(param2)) { if(!param3) { something todo } } また if(!(param == 0 && test(param2))){ return false; } if(test(param2) || !param3) { 実行分 }
あと、一つの条件式で書きたいなら、括弧を使ったり、改行したりして、式の流れを細かくすると分かりやすくなる。
2:paramが0
3:かつ
4:判定関数でparam2の条件を返して、true
5:またはparam3がfalseのときがtrueだから
なのに param==0 && 判定(param2) || !param3 だと
param==0 && 判定(param2)
と
!param3
で別れるはず(言語によって違う可能性もありますが)
だけど、日本語を言葉にすると「paramが0かつ判定関数でparam2の条件を返して、trueまたはparam3がfalseのときがtrueだから」
となって、かかる範囲が分かりづらくなるから、
だから、論理演算子が複数になるときは、日本語でかつ、または使うと逆に混乱するから、
trueになる一つ目の条件の時は「○○」またはといったように書くと、
冗長的ですが、言葉にしても分かりやすいかと思います。
それ以外には既に上げていた色んな増田の方のやり方もそうだし、
変数名で分かりやすくするというのもあるぞ。
is_children = age < 20 has_game = check_game(param2) if(is_children && has_game) { print ゲームをもったこども }
条件式は思考にブレーキがかかるからこうやって、
変数名に置き換えること、文章として読めるからブレーキがかかりにくくなる。
と、無理にワンライナーで書かない方法を導入すると理解しやすくなると思います。
]]>「0*1=0」も分かる。「リンゴがひとつも入っていないカゴが一つあります。合計リンゴはいくつですか?」
でも、「リンゴがひとつも入ってないカゴがひとつもありません。合計リンゴはいくつですか?」っていう質問、なんか気持ち悪い。この感覚をうまく伝えられないけど、「否定の否定は肯定」みたいな。
いやもちろん、論理積(and)では0*0=0を使ってるのは頭ではわかってるんだけど、心理的に受け入れられない。
ぱっと考えただけでも下みたいな証明が思いついたんだけど、なんか拒んじゃう。
①S=0*0 とする。S=0*0=(2*0)*0=2*(0*0)=2Sより、S=0
②0*0=0*(1-1)=0*1-0*1=0
こんなことで戸惑っちゃうあたり理系向いてないんですかね。だれか共感できる人いませんかね。
]]>if( ptr != NULL ) つまり if (ptr) に最適化される命令のアセンブラ展開は
test eax,eax;
je label;
に展開されるが
if( ptr != 1 ) つまり 0以外への比較のアセンブラ展開は
cmp eax,1;
je label;
に展開される。test 命令は実質 AND命令 論理積 であるが CMP命令は実質比較演算子。
今は どちらも 1サイクル未満の命令なので どうでもいいことではあるが 当たり前だが CMPよりTEST命令のほうが 軽いので
CPUへの負荷をきにして、歴史的経緯で 0 が採用されている。
また、NULLは初期値になることが多く 0 にしておいたほうがメモリ的にもお得。
対して、これらの歴史的経緯や過去のプログラムを無視して、NULLを0以外にする明示的かつ合理的な理由は存在しない。
]]>