今日で退職しました、それと今後のブログについて
表題の通り、今勤めている会社を退職し、別の会社に転職することになりました。
こちらのブログはもともと、今の会社で最低週1でいいから投稿して欲しい指示を受けて続けていたものでした。
今後についてですが個人ブログと一本化したいなと前々から思っていたのもあり、以降はこちらで更新を続けようかなと思います。
それではこれまで見てくださった方、どうもありがとうございました。
引き続き読みたい方は個人ブログの方でよろしくお願いします。
Cacapon
Cacaponのゲームの仕組み探し① =スーパーマリオブラザーズのマリオ=
みなさん、こんにちは、仕組み大好きCacaponです。
最近NAND回路づくりを通して、自分は仕組みを考えたり仕組みを調べたりするのが好きなのがわかり、このやる気をゲームに活かしてみようと考えました。
というわけで、今回は第一弾としてほとんどの方が知っているであろう、あの方の動きを調べてみることに。
そうです、マリオです。その中でも調べたかったのは、FC版のマリオ。
FCはゲームの容量が少ない分、調べる範囲が少なくて済むし、容量不足を解決するためのいろいろなアイデアが含まれていることが多いです。*1
また、比較的原始的な部分が多いので、仕組みの理解のはじめの一歩としてはかなり良い題材かなと思います。それでは見ていきましょう。
どんな感じで調べるの?
ガッツリやる人だと、ロム吸い出してリバースエンジニアリングになるかと思いますが、今回は軽く調べただけなのとロム吸い出し機とか全く持っていないので、表面的な動きを見て推測する、という形で調べています。
また、スーパーマリオブラザーズをすぐに遊べる環境ができてなかったので、今回はスーパーマリオメーカー(3DS)で代用することにしました。
ジャンプ力の調査
マリオといえば、ジャンプ、ということでどのくらいジャンプできるのか確認しました。
調べたところ、歩いていない状態は4ブロックで、動いている場合は5ブロックになります。
私、ずっと走っていると1つ分ジャンプ力増すなぁというのは知っていたのですが、歩きでも1つ分増えるのは知りませんでした。でもよく考えたら次のようなとこのアイテムとか取ってた記憶ありますね…
I:アイテム ■:ブロック □:空き M: マリオ □I□ □■□ □□□ □□□ □□□ □M□ □■□ □□□ □□□ □□□ □□□ ■■■
移動スピード
スーパーマリオメーカーは好きな位置にブロックが置けるので、5ブロックごとにブロックをおいて、タイマーからどのくらいのスピードで移動できるのか確認してみることにしました。
F:中間用フラッグ(測定ゴール) ■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■□□□□■ □□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ M□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□F ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
こんな感じで、50m走ならぬ、50ブロック走のステージですね。
ゲームスタートから右キーを押しっぱなしにして何秒で到着するかを確認します。
その結果、歩きの場合は約5ブロック/秒、走りの場合は約10ブロック/秒になりました。
何回か測定したら、走りの場合は9秒台の時もあったので、正確な値かどうかはわかりませんが、大まかにはこのくらいの速度だと思われます。
また、走りの場合は最大速度に達するまでに助走時間がありますが、こちらについては調べきれていません。この辺りはおいおいですね。
また、左右移動の切り替えの場合、ある程度慣性が働きます。ここも歩きと走りで大きな差があるのですが、ここも調べきれておりません。
ドット絵
マリオのドット絵は何種類かありますが、地上の場合次の種類があるかと思います。 - チビ状態 - 静止状態 - 移動① - 移動② - 移動切り替え - ジャンプ - やられ - スーパーマリオ状態 - 静止状態 - 移動① - 移動② - ジャンプ - ダメージ時 - 現在のスーパーマリオ状態を縦に圧縮している
というわけでマリオを調べてみました。この後はこれを元に実際にプログラミングしてみて、マリオの動きを再現できるかとかやってみようと考えています。
その時に、実現できないところはまだ理解していないところだと思うので、その辺りも合わせて仕組みがわかると嬉しいなぁと思うCacaponでした。
それではまた来週お会いしましょう。
アプリケーションをどうやって作っていくか考えてみる。その1
私の場合は結論から言うと、実現するイメージをぼやっと作った後は、各段階のパーツを組み合わせて作っていく、という流れが今の所あっていそうです。
今日はこの考え方についてまとめていきたいと思います。
その1 作りたいもののゴールをイメージを明確にする
まずは何を作りたいかをイメージできる必要があります。
私の場合は、次のような方法でまずイメージを明確にすることが多いです。
イメージを明確にする方法① 実物でロールプレイ
以前、とあるパズルゲームを作った時は、将棋盤と麻雀牌を使って人力で動かして理解しました。 ロジック部分は人間特有の曖昧さでカバーすることで、実際にどんなゲームにしたいかを明確にすることができました。
もちろん、曖昧になっていた部分は論理的に実装する必要がある部分なので、後ほど考える必要はありますが、この時はこんな機能が必要だなぁくらいでOKです。
イメージを明確にする方法② Pythonでプロトタイプ作成
自分の中で一番コードを組みやすいのがPythonなので、Pythonでプロトタイプを組むこともあります。
この時大事なのは、あくまでプログラムの動きを把握すれば良いので、一部のデータがハリボテだったりしても問題ありません。プログラムの根幹の動きが表現できているかがわかる形でプロトタイプを作成します。
イメージを明確にする方法③ 方眼紙で設計
特にUIを表現する場合は多用しています。例えば9マスx16マスで枠を作り、その中におきたいパーツを書いていけば、スマホ向けのゲーム画面を作ることができます。
他にも、付箋と矢印を書いてアーキテクチャ図式化したりすることで、何を作れば良いかが見えたりすることもあります。
その2 必要な機能レベルでTODOリストを作成する
思いつく限りピックアップする
イメージが明確になると、必要な機能がいくつか思いつくと思います。
それらを忘れないうちにTODOリストに記載していきましょう。
この時、変に制限かけると何も書けなくなったりするので、細かい荒い、大きい小さい気にせずに思いつく限り書くようにします。
また、この一回で全部出しきれなくても大丈夫です。思いついたら都度追加しても良いですし、逆に思いついたけどいらないと思ったら思い切って捨てましょう。それはいらない機能でしょうから。
必要最低限と後に回すものを分類する
リリース時に必要なのは必要な機能が含んだリリースです。
なので、ピックアップした機能のうち、何がすぐ必要で何があとで良いかは分類しましょう。
あとで良いに分類したものはそのリリース中は考えなくても良い状態にできると良いです。思考の切り替えは無駄に繋がるので、なるべく今必要なことに集中できるようにします。
必要最低限の機能の優先順位と期限を作る
私の場合、何から手をつければいいかを悩む時間はかなりの無駄です。
なので、あらかじめ何から作っていくか優先順位はしっかりつけましょう。
アプリかなんかでTODOリストを管理する場合は、上から順番になるようにすると綺麗に手をつけられるかもしれません。
また、必ず期限は設けましょう。プレッシャーで作業効率が上がります。
正し、間に合わなくても自分を責めないようにしましょう。自分を責めるとメンタル面のダウンから来る作業効率のダウンが待っています。間に合わなかったらリスケしましょう。
その3 作成とテスト
部品を作ってテストする
私の場合、ボトムアップの方が考え方と一致しているみたいなので、原始的な機能を作成して、徐々に組み合わせて機能を実現していくという考え方で作成します。
また、それぞれ作成した部品については必ずユニットテストを行うようにしています。
ユニットテストを行うことで機能に関する安心感が得られたら、別の部品を作っていきます。
部品を組み合わせてテストする
いくつか部品作りが終わると、部品を組み合わせる段階になります。
その時も組み合わせた新しい部品でテストを行うようにします。この段階だと結合テストでしょうか?
機能が実現できているかテストする
部品を組み合わせてと組み合わせていくと、最終的に機能実現に必要な部品が出来上がります。この出来上がった部品に関してもテストしましょう。
私の中でテストすると言うのは、ちゃんと動いていくことの保証の意味合いが強いです。これを続けることで安定性のあるプログラムを作ることができると信じています。
今回は、どんなふうにプログラムを作っていくかをまとめました。参考になったらありがたいです。
それではみなさん、またお会いしましょう。
NAND論理ゲートから他の論理ゲートを作ってみる その2
前回NANDゲートから他のゲートを作りました。
今回は、XOR,マルチプレクサ、一つの入力を二つの出力どちらかに出力させるでマルチプレクサゲートを作っていきます。
なお、今回作成した論理ゲートは前回のブログで作成済みの論理ゲートから作成しております。つまり、こちらの論理ゲートもNANDゲートから作ることができる論理ゲートとなります。今回使用する論理ゲートの仕組みを知りたい方は前回のブログを参照ください。
XOR
XORはa,bの内、片方が1の場合は出力が1になる論理ゲートです。
a | b | out |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
XORの設計・実装
今まで作成した論理ゲートでXORを実現するには以下のような構成で実現できます。
真理値表で一致するか確認します。
a | b | X=NAND(a b) | Y=OR(a b) | out=AND(X Y) |
---|---|---|---|---|
0 | 0 | 1 | 0 | 0 |
0 | 1 | 1 | 1 | 1 |
1 | 0 | 1 | 1 | 1 |
1 | 1 | 0 | 1 | 0 |
一致していますので、上図の構成をもとに実装とテストをしてみます。
def Xor(a:bool,b:bool) -> bool: in1 = Nand(a,b) in2 = Or(a,b) out = And(in1,in2) return out
test_list.extend(gen_t_list(gate.Xor,gen_t_in(2),[0,1,1,0]))
tests/test_gate.py::test_gate[Xor(0, 0) = 0] PASSED tests/test_gate.py::test_gate[Xor(0, 1) = 1] PASSED tests/test_gate.py::test_gate[Xor(1, 0) = 1] PASSED tests/test_gate.py::test_gate[Xor(1, 1) = 0] PASSED
テスト確認も出来たので無事にXORゲートを作成できました。
マルチプレクサ
二つの入力と一つの選択ビットを用いてどちらかの入力を選ぶゲートのことをマルチプレクサと言います。
マルチプレクサは次のような形をとっています。
a | b | sel | out |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
真理値表をしっかり見ると、selが0の時はaの値、selが1の時はbの値が出力されていることがわかるかと思います。
マルチプレクサの設計・実装
今まで作成した論理ゲートでマルチプレクサを実現するには以下のような構成にします。
本当にこれで真理値表が同じになるか確認してみましょう。
a | b | sel | X=NOT(sel) | Y=AND(X a) | Z=AND(sel b) | out=OR(Y Z) |
---|---|---|---|---|---|---|
0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 0 | 0 | 0 |
1 | 0 | 0 | 1 | 1 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 | 0 | 1 | 1 |
1 | 0 | 1 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 0 | 0 | 1 | 1 |
最後のoutとマルチプレクサの真理値は一致しているので、この構成で作れそうですね。
それでは実装とテストを作ってみましょう。
def Mux(a:bool,b:bool,sel:bool) -> bool: in1 = Not(sel) in2 = And(a,in1) in3 = And(b,sel) out = Or(in2,in3) return out
test_list.extend(gen_t_list(gate.Mux, gen_t_in(3),[0,0,0,1,1,0,1,1]))
tests/test_gate.py::test_gate[Mux(0, 0, 0) = 0] PASSED tests/test_gate.py::test_gate[Mux(0, 0, 1) = 0] PASSED tests/test_gate.py::test_gate[Mux(0, 1, 0) = 0] PASSED tests/test_gate.py::test_gate[Mux(0, 1, 1) = 1] PASSED tests/test_gate.py::test_gate[Mux(1, 0, 0) = 1] PASSED tests/test_gate.py::test_gate[Mux(1, 0, 1) = 0] PASSED tests/test_gate.py::test_gate[Mux(1, 1, 0) = 1] PASSED tests/test_gate.py::test_gate[Mux(1, 1, 1) = 1] PASSED
マルチプレクサも大丈夫そうですね。
デマルチプレクサ
デマルチプレクサは一つの入力を二つの出力のどちらかに出力するというゲートになります。選択にはマルチプレクサと同じく選択ビットを用います。
例えば、selが0ならaの方にINの値が入りますし、1ならbの方にINが入ります。
selに選ばれなかったルートは0になります。
この挙動を心理地表で表すと以下のようになります。
in | sel | a | b |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
デマルチプレクサの設計と実装
今まで作成した論理ゲートでデマルチプレクサを実現する方法として、以下のような構成を考えました。
他のゲートと同じく真理値表で確かめてみます。
in | sel | NOT(sel) | a = AND(in NOT(sel)) | b = AND(in sel) |
---|---|---|---|---|
0 | 0 | 1 | 0 | 0 |
0 | 1 | 0 | 0 | 0 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 0 | 1 |
a,bは一致しているので、この構成で大丈夫そうです。
上の図をもとに実装とテストは下記のように作成しました。
def DMux(_in:bool,sel:bool) -> tuple[bool,bool]: nsel = Not(sel) out1 = And(_in,nsel) out2 = And(_in,sel) return (out1,out2)
test_list.extend(gen_t_list(gate.DMux,gen_t_in(2),[(0,0),(0,0),(1,0),(0,1)]))
tests/test_gate.py::test_gate[DMux(0, 0) = (0, 0)] PASSED tests/test_gate.py::test_gate[DMux(0, 1) = (0, 0)] PASSED tests/test_gate.py::test_gate[DMux(1, 0) = (1, 0)] PASSED tests/test_gate.py::test_gate[DMux(1, 1) = (0, 1)] PASSED
テストもパスしたので、デマルチプレクサも無事に作成できました。
今回のブログで、基本的に使われる論理ゲートは全て作れましたかね。
次回はこれらのゲートを組み合わせて加算器を作りたいと思います、
次回もお楽しみに、またお会いしましょう。
何かを忘れても、もう何も怖くない仕組みづくり
突然ですが、Cacaponはよく物を忘れます。
毎日行う家庭での約束事を忘れてしまったり、無くし物は頻発しますし、数ヶ月前の仕事で仕掛かり中だったものとかが覚えていないと言うのも結構あります。
これはもうCacaponの忘却能力が天才的なレベルなのでしょう。忘れることによって脳がスッキリして、新しい考え事もできるので忘却能力が高いことは良い面もあるとは考えています。
ただ、必要な時に思い出せない、何かを探す時間がロスになるのも事実。これは私にとっても嫌なことなので少なくしたいところです。
そこで、今回は「如何に忘れても問題なく仕事や生活をこなせるようにする」と言うモットーの元、いくつかアイデアを考えてみることにしました。
今回は、忘れても問題ない仕組みづくりのためのアイデアを紹介したいと思います。
- アイデア1 アラームを使う (毎日タスク向け)
- アイデア2 TODOリストを作る (長期的な単発タスク向け)
- アイデア3 住所を作る (物忘れ向け)
- アイデア4 ノートに通番と目次をつける(終わったタスク向け)
アイデア1 アラームを使う (毎日タスク向け)
今Cacaponは家族で住んでいるのですが、2つあるお釜のうち、一つの炊飯を担当しています。
これはCacapon用のご飯なのですが、何回も炊き忘れをしてしまうのですよね。よくCacaponママに怒られております。
しかし、怒られても次の日には忘れてしまうのがCacaponクオリティ、なんとか忘れても問題ないようにしたいです。
そこで、考えたのはスマホのアラームを使うこと。
スマホのアラームは名前をつけられるので、炊飯時間とか名前をつけて、特定の時間にアラームを鳴るように設定しました。
それをしておけば、その時まで忘れていてもアラームが教えてくれます。アラームを設定して以降は見事忘れないようになりました。
アイデア2 TODOリストを作る (長期的な単発タスク向け)
これは作業中のタスクが複数ある場合に有効ですね。頼まれたことはとりあえず、タイトル、タグ、期限をつけときます。
タグは自由でいいと思いますが、私の場合は頼まれた組織や人を描くようにしています。
それと、期限が近づいたら赤線アンダーバーを引いて、期限が近いと言うのがわかるようにしました。そして、完成したら、太マジックで消します。こうすることで残っているタスクが一目瞭然になりますね。
あ、ここまで書いていてなんですが、Cacaponの場合、TODOリストは方眼ルーズリーフに書いています。普段からノートを持ち歩いているので、手軽にすぐ確認できるのが気に入って使っています。
この辺りはアプリが好きな人はアプリでも良いと思います。アプリだったらアトラシアンが出しているJiraが管理しやすくていいかなって思っています。
アイデア3 住所を作る (物忘れ向け)
私の場合、物を忘れるのは、使った後に適当な場所に置くために、どこに置いたか分からなくなることが多いことがわかりました。
そこで、よく使うものについては物の住所を決めることにしました。
例えば、よく使う財布は一番上の机のエリアA、鍵はフックX番とかそんな感じに。
ものの住所を意識し始めると、忘れてもそこを見ればあるか分かりますので、どこを探せば良いか分からないから、住所にあるかをみて、無ければ探すになり、だいぶ探す手間がなくなりました。
まあ、たまに変なところに置いて探すことはあるので、要改善な点はあります。
アイデア4 ノートに通番と目次をつける(終わったタスク向け)
私の中で一番探すのが大変なのが、終わったタスクを思い出す必要がある場合。
仕事で言うなら「3ヶ月前のあの仕事の資料ってどこにある?」みたいなパターンです。
この場合は基本的に忘却の彼方にあるので、頭の中を検索するのはかなり時間がかかることが多いです。
これも暫定的な対応なのですが、タスクについてまとめた資料に番号を振ることにしました。
例えば、pythonのタスクならPY-0001 みたいな感じに。
そして目次も「PY-0001 python リファクタリング1 実践記録」みたいな形で紐付けができるようにしました。
これで、忘れても目次を見れば、どこに内容をまとめたかを確認することができます。
ちなみに本ブログの内容も[DH-0001]でまとめていたりします。DHは日常的なハック、Day Hackから取りました。*1
いかがでしたでしょうか?
色々なパターンの忘れに対して、Cacaponができるアイデアをいくつか紹介しました。
今は自分で試し中なのでこれからどうなるかは分かりませんが、いくつかは効果を実感しているところもあるので、続けていきたいなと思います。
何か聞かれた時に調べればすぐ答えられる状態ですね。その状態になるまでいろいろ試したいと思います。それではまた!
*1:英語力は無いですが、私が分かればいいかなぁと思う今日この頃
NAND論理ゲートから他の論理ゲートを作ってみる その1
最近こちらの書籍を読んでいます。
こちらの本は一言で言うと「NANDからTetrisへ」
基本的な構成要素である論理ゲートからALU,CPUと作っていき、最終的にはアプリケーションであるテトリスを0から作ってみることでコンピュータの働きを理解すると言ったテーマになっています。
私もこの本に触発されてNANDゲートを基本にして、その他の論理ゲートを作成することを試みました。今回のブログはNANDの作り方、及びNANDから基本ゲートをどのように作成したかを記録したものになります。
前提となる用語
真理値表
複数の入力に対し、出力の結果を0,1で表現した表のこと。
下記はNANDの動作を表現した例
a | b | out |
---|---|---|
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
ブール関数
ある入力に対して、0か1を返す関数のこと。
論理ゲート
ブール関数を実装するための物理デバイスのこと。
例えばNANDの論理ゲートは下記の通り。
本ブログでは物理的には作らないが、
シミュレーションとして論理ゲートに相当する関数を作成し組み合わせて他の論理ゲートを作成していく。
基本論理ゲート
論理ゲートのうち、AND,OR,NOTの論理ゲートのこと
本ブログではNANDから上記三つを作成します。
実装の流れ
NANDゲートを作る
なんでNANDゲートを基準にするのか?
NANDゲート*1には面白い性質がありまして、NANDゲートさえあれば他の論理ゲートは全て表現できると言う性質があります。
今回はその性質を利用して、まずはNANDゲートを普通に作成し、その他の論理ゲートはNAND、もしくはNANDから作成した別のゲートを組み合わせて他のゲートが作れるかを試していきます。
NANDゲートの作成
では早速NANDゲートを作成しましょう。 NANDゲートは次のような動きを行う論理ゲートになります。
a | b | out |
---|---|---|
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
これをpythonで表現すると次のようになります。
def Nand(a:bool, b:bool) -> bool: return not (a and b)
テストもしていきましょうか。
from tools import gate import pytest import itertools in2 = list(itertools.product([0,1],repeat=2)) expects = [1,1,1,0] @pytest.mark.parametrize("a,b,expect", [x + (y,) for x, y in zip(in2, expects)]) def test_nand(a,b,expect): assert gate.Nand(a,b) == expect
テストの方はやや複雑に書いていますが、行なっているのは真理値表の入力に対して、expectsで定義した入力と一致しているか順番に確認していると言った感じになります。
これの結果が下記になります。
tests/test_gate.py::test_nand[0-0-1] PASSED tests/test_gate.py::test_nand[0-1-1] PASSED tests/test_gate.py::test_nand[1-0-1] PASSED tests/test_gate.py::test_nand[1-1-0] PASSED
無事にテストが通ったのでNANDの論理ゲートは正しく動いていることがわかりました。
NOTゲートを作る
NOTゲートは一つの入力に対し、反転した値を出力する論理ゲートです。
in | out |
---|---|
0 | 1 |
1 | 0 |
NOTゲートをNANDゲートだけで考えてみる
私の場合まず図で考えてみることにしました。
図で表現すると下記の通りでNOTは表現できます。
INの値をa,b両方に入れる感じですね。
これを真理値表で表現すると次のようになります。
in | a | b | NAND(a,b) |
---|---|---|---|
0 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
inの値が反対になっているのでNOTの動きになっていますね。
この図は合っていそうです。
プログラミングで実装してみる
次にpythonで上の図と照らし合わせながら、実装してみました。
テストも併せて実装しています。
def Not(a:bool) -> bool: out = Nand(a,a) return out
# ... 省略 in1 = list(itertools.product([0,1],repeat=1)) expects = [1,0] @pytest.mark.parametrize("a,expect", [x + (y,) for x, y in zip(in1, expects)]) def test_not(a,expect): assert gate.Not(a) == expect
tests/test_gate.py::test_not[0-1] PASSED tests/test_gate.py::test_not[1-0] PASSED
無事にNANDだけでNOTも作ることができました。
他の論理ゲートも同じような流れで作成していきます。
ANDゲートを作る
ANDゲートは2つの入力を受け取り、両方の入力1なら出力を1にする論理ゲートです。
真理値表は次のようになります。
a | b | out |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
真理値表を見るとNANDと0と1がひっくり返ったものになります。
そもそもNANDがNot ANDから来ているのでこの関係性は頷けるものかと思います。
NANDからANDにするにはもう一度ひっくり返せばOKです。 つまり、出力にNOTゲートをくっ付ければ作ることができます。
なお、前述の通りNOTゲートはNANDで作ることができましたので、NANDで作られたNOTゲートを使用して実装していきます。一度できたものは有効活用していきます。
ANDゲートの実装
def And(a:bool,b:bool) -> bool: in1 = Nand(a,b) out = Not(in1) return out
expects = [0,0,0,1] @pytest.mark.parametrize("a,b,expect", [x + (y,) for x, y in zip(in2, expects)]) def test_and(a,b,expect): assert gate.And(a,b) == expect
tests/test_gate.py::test_and[0-0-0] PASSED tests/test_gate.py::test_and[0-1-0] PASSED tests/test_gate.py::test_and[1-0-0] PASSED tests/test_gate.py::test_and[1-1-1] PASSED
ORゲートを作る
ORゲートは2つの入力を受け取り、片方の入力1なら出力を1にする論理ゲートです。
真理値表は次のようになります。
a | b | out |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
NANDで構成する場合は以下のようになります。
各入力前の値をNOTゲートで反転するとORになります。
NOTは前述の通り作成済みですのでそのまま利用しましょう。
ORゲートの実装
def Or(a:bool,b:bool) -> bool: in1 = Not(a) in2 = Not(b) out = Nand(in1, in2) return out
expects = [0,1,1,1] @pytest.mark.parametrize("a,b,expect", [x + (y,) for x, y in zip(in2, expects)]) def test_or(a,b,expect): assert gate.Or(a,b) == expect
tests/test_gate.py::test_or[0-0-0] PASSED tests/test_gate.py::test_or[0-1-1] PASSED tests/test_gate.py::test_or[1-0-1] PASSED tests/test_gate.py::test_or[1-1-1] PASSED
以上から無事にNANDの作成、及び基本の論理ゲートに当たる、NOT ,AND,ORをNANDから作成することができました。
作ってみた感想ですが、基本的な構成要素から組み合わせて別の新しいものを作り出す、そして作り出したものを使いながらより複雑なものが作れるようになる、と言った感触が自分には向いているらしく、空き時間を使いながら夢中で取り掛かれました。
この後も、XORだったりマルチプレクサだったりを作ってみようかなと考えています。最終的には参考書籍のようにNANDからテトリスまで作り上げてみたいですね。
それではこの辺で、またお会いしましょう。
*1:NORゲートもですが
人が眠くなるには二つの要素で眠くなるらしい
最近こちらの本を読んでいます。
私最近まで眠くなるのって体内時計が原因だと思っていたんですけど、実はもう一つあるらしいです。
ちょっと気になったことだったのでメモしました。
眠くなる原因その1 体内時計
どの生物にも体内時計というものはあるらしく、私たちもご存知の通り体内時計があります。
この体内時計が昼に体を活発にさせ、夜に眠くなるようにコントロールしているそうです。
また体内時計を司っているのが視交叉上核(しこうさじょうかく)という部位でここに光が当たると体内時計をリセットしているそうな。
朝日光を浴びると良いと言われているのもここのあたりの話が関係ありそうですね。
眠くなる原因その2 睡眠圧
こっちは私初耳だったのですが、脳には睡眠圧というものがあるそうです。
これは睡眠圧に関係しているアデノシンという化学物質が溜まっていくとどんどん眠くなる、といった仕組みになっています。
このアデノシンは起きていると溜まり、寝るとなくなっていくというものらしいですが、この時眠りが少ないとアデノシンが十分に片付けられていない状態になり、眠気が取れない状態が続くそうです。
睡眠不足は色々とパフォーマンス低下につながるので、慢性化は避けたいですね…
また、一度の睡眠で片付けられるアデノシンの量に限りがあるので、土日の寝溜めは効果はあんまりないそうです。日常的に睡眠を十分にとる習慣を作るようにしないとなぁとCacaponは思いました。
今日はここまで。なぜ眠くなるのかというと体内時計と睡眠圧が関係していることがわかりました。
最近良い睡眠をあまり取れていない気がするので、もっと良い眠りができるようにしていきたいなぁと思うCacaponなのでした。