matobaの備忘録

とあるプログラマーのブログ。ソフトウェア開発、執筆活動、ライフログ。

FreenoveのRaspberry Piスターターキットを買った話

以前から、ラズパイに興味があった。なんとなく触ってみたいなあ、というレベルの興味。

「興味がある」と言いつつ触っていない状態が続いてることを自分で認識すると、なんとなく自分にイラッとしてくる。なので、今回はとりあえず入門キットだと思われるものを購入した。触る時間作れるのかなあ、このメーカーで大丈夫かなあ、とかいろいろ思うことはあるが、ここは深く考えないことにした。

購入したものはこちら。

Freenove Raspberry Pi 4 B 3 B+ 400用の究極のスターターキット、434ページの詳細なチュートリアル、Python C Javaコード、223アイテム、57プロジェクト、無はんだブレッドボード

PythonとJavaとCのコードなので、なんとなくとっつきやすい印象があった。

そして、購入したものが届いた。

f:id:mtb_beta:20210723100527j:plain

この製品は、マニュアルがWebからダウンロードする形式になっている。

こんなふうにAmazonにリンクがついている。

f:id:mtb_beta:20210723095826p:plain

「変なファイルをばらまかれるリンクだったらどうしよう?」という防衛意識が働いて、少し抵抗があった。

実際にダウンロードすると、中にはサンプルコードやチュートリアルが入っている。

というか実際に入ってるファイルはGitHubで公開されている。

じゃあ最初からGitHubのリンク貼ってくれ....!!!と思ったりもした。

github.com

それからリポジトリの中にはPythonのサンプルコードがたくさん入っていた。

Pythonのコードをいくつかみてみたが、「読める...!!これはらわかるぞ...!!!」みたいな気持ちになった。

まだ、大量のチュートリアルがあるので、まずはざっと把握してみるところかなあ、と思いつつ楽しみにしている。

学ぶ順番を考えるのが難しいんだよなあ、と感じている話

「独学大全」という本を見つけて読んでいる。その中で「学ぶ順番を考えたり、学ぶことの優先順位づけが難しいんだよな」と感じた話を雑記的につらつらと書く。

前提として、もともと自分は独学するタイプの人なので、独学についての動機づけで困ることは少ない。

本の中では「ゲートキーパー」と呼ばれているテクニックがあった。これは、何をいつまでにどれくらいやるか、できなかった場合どうするか、という話を他の人に宣言して、独学の環境を作る話。このテクニックは、「学ぶことを少なくしたい」とか「独学で何かを学ぶのがめんどくさい」と感じている人にとって、動機付けにつながるのだと思う。

ただ、自分の場合は、「可能な限り、多くのことを学びたい」というような知識欲があって、独学自体が面倒だと思うことはないので、動機付けにはならないと思った。(他の人に言ったかどうか、に関係なく、独学自体はするので)

とは言え、学ぶことの優先順位は、「その知識があったときにど自分はどう使えるか。今、必要か。」で判断している部分が多くて、「必要になったら学ぶし、今、必要じゃないなら後で学ぶ」みたいな感じになってる。なぜかと言うと、同じことを学ぶにしても、後で学ぶ方が資料が整理されていたり、書籍の評価が見える化されていて、学びやすい傾向があると思っているから。

ただ、この優先順位で学ぶことを考えていると、「ニーズを満たすために学ぶ」みたいな性質が強くなっていくことがあって、それだけだとなんか微妙だなあと思っている。なぜ微妙かと言うと、自分の知識編成が、ニーズを中心によって構成されすぎているような気がするから。

知識を活かすためには、ニーズが必要なのだけど、「知識を学んでニーズを探す」だとその知識が求められているところにたどり着けない場合があるし、知識が風化していくこともあって、なんかそれは辛みを感じる。「ハンマーを持つ人には、すべてが釘に見える 」みたいな話が関係するけど、先に知識を学ぶと、手段と目的が反転しがち。

だから「ニーズを探して、知識を集める」の順番にした方が役に立つと思うし、有意義な感覚は得られるのだけど、これだと「自分が学びたいこと」とか「自分が伸ばしたいスキル」みたいな視点が結構無視されているような気がする。あと、ニーズについての気づきは、普段の生活環境から得ることが多いと思うので、自分が普段生活している流れに乗ってこないニーズに気づかないし、その辺に対する知識が優先度低くなりすぎる気もする。

この行動基準で進むとガラパゴス化してしまうので、なんだかなあ。と思ったりしている。

まあ、結論はないんですが。

12/12 加筆

よく考えたら「まず、身近な問題を解決するための知識を集める。その後、自分の将来の問題を解決するための知識を集める」と言う順番で学んでるので、今のまま学ぶことを進めても結局は「自分が学びたいこと、や自分が伸ばしたいスキル」と言うのは伸びているかもしれないと感じた。

そもそも「自分が学びたいこと」や「自分が伸ばしたいスキル」と言ってるのが何なのか、と言う部分が自分の中で曖昧なので、もう少しその辺を言語化したら前に進みそうだなあ。

参考図書

Rustで標準入力を受け取って、標準出力に出してみただけの話

Rustで標準入力を受け取って、標準出力に出してみただけの記録を書きます。

以下の本を読んでいたら、こんなサンプルがありました。

数当てゲームをプログラムする - The Rust Programming Language 日本語版

use std::io;


fn main() {
    println!("Guess the number.");

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess).expect("Failed to read line.");

    println!("You guess: {}", guess);
}

このページは、解説を読みながら、自分なりの理解をメモしていきます。

ライブラリを読み込む

以下の行で、標準ライブラリstdの中に存在するioライブラリを読み込む。

use std::io;

関数を定義する

関数は以下で定義できる。

fn main() {
}

mainはエントリーポイントでもある。

fnで関数を表す。上記は引数や返り値を持たないが、持つケースは追々学べるハズ。

こんな風に構造化できる。

fn hello() {
    println!("hello");
}

fn main() {
    hello();
}

変数を宣言する

以下のようにして、変数を宣言できる。

let foo = 5;

ただし、このfooはimmutableになる。つまり、変更することができない。

以下のような関数があってコンパイルするとエラーが出る。

fn define_foo() {
    let foo = 5;

    foo = foo + 1;
    println!("foo: {}", foo);
}

エラー内容

 --> src/main.rs:6:5
  |
4 |     let foo = 5;
  |         ---
  |         |
  |         first assignment to `foo`
  |         help: make this binding mutable: `mut foo`
5 |
6 |     foo = foo + 1;
  |     ^^^^^^^^^^^^^ cannot assign twice to immutable variable

可変の変数を宣言したい場合は、mutをつける。

fn define_foo() {
    let mut foo = 5;

    foo = foo + 1;
    println!("foo: {}", foo);
}

これでコンパイルが通る。Rustでは変数は標準が不変らしい。

変数が標準で不変になっていると何が嬉しいのかは今のところよくわかっていない。

変数の型を束縛する

以下の行は、guessという変数にString型のオブジェクトのnew関数を呼び出した結果で束縛している。

let mut guess = String::new();

現時点では、「束縛する」という概念が何なのかはよくわかっていない。 とりあえず、その型しかいれられないようになるのかな、くらいのイメージで進む。

なお、Stringは標準ライブラリによって提供される文字列の型らしい。 newといういわゆるスタティックメソッドを持っている。Rustでは「関連関数」と呼ぶらしい。

読み込んだライブラリの関数を呼び出す

use std::io; で読み込んだioライブラリのstdin関数を呼び出す場合、以下のようになる。

io::stdin()

なお、 use std::io で事前に読み込んでいない場合、 次のように呼び出せるらしい。

std::io::stdin()

std::io::stdin() の返り値は std::io::Stdin というオブジェクトらしい。

オブジェクトのメソッドを呼び出す。

以下のように書くと、返ってきた std::io::Stdin に対してread_lineメソッドを呼び出せるらしい。

io::stdin().read_line(&mut guess)

&mut guess は変数として参照渡ししている。らしい。

guessって変数として定義したんじゃなかったっけ?とか思うけど、メソッドや関数に参照渡しして、書き換える時は、 mut が必要なのかな。 & が参照渡しを意味している様子。

今のところよくわかってないけど、関数とかメソッド呼び出しを学ぶときにもう少し詳しく知れるのだろう。

メソッドの処理結果を解釈する

io::stdin().read_line(&mut guess) を実行すると Result 型というものが返ってくるらしい。

Result側は、OkかErrらしい。

Rustでは、エラーが発生する可能性がある行で、エラーの際の処理を書いていないとコンパイル時に警告が発生するらしい。

io::stdin().read_line(&mut guess)
warning: unused `std::result::Result` that must be used
  --> src/main.rs:19:5
   |
19 |     io::stdin().read_line(&mut guess);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_must_use)]` on by default
   = note: this `Result` may be an `Err` variant, which should be handled

エラーハンドリングするの忘れなくて良さげ。

io::stdin().read_line(&mut guess)
    .expect("Failed to read line.");

ここでは、expectを書いて、わざとクラッシュさせているらしい。そのほかのハンドリングは追々学ぶ。

標準に入力に変数を埋め込む

printデバッグするために、変数を標準出力に出したいことはある。

そのときに使えそうな例。

println!("You guess: {}", guess);

説明は省略。

所感

とりあえず、標準入力を受け取って標準出力に出すサンプルを見つつ、勉強したことを記録した。

今のところ「へー。そうなんだー」という感じ。

この記事はわざわざ公開する必要もない内容を書いている。

Notionとか非公開のところに書けばいいと言う話もあるかもしれないけど、別に隠す話でもないのと、ブログなどを介して、「なんかやってる感」を出していきたかったり、自分の中で非公開状態のところにメモするより公開状態のところにメモする方が記憶に残るので、ブログに書いてみました。

まあ、気が向いたらRustについて学び進めていきます。

Rustをインストールして、Hello Worldしただけの話

Rustを初めてみた記録を書きます。

参考資料

基本は以下のURLに従います。

The Rust Programming Language 日本語版 - The Rust Programming Language 日本語版

Rustのインストール

rustupはRustをインストール・更新するツールです。まずは、rustupをインストールします。 rustupをインストールすると、Rustに関するいろいろなツールをも一緒にインストールされます。

とりあえず、以下を実行します。macOS 10.15.7を使ってます。fishです。

$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

途中でインストール設定を聞かれたので、僕は、デフォルトでインストールしました。

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1

あと、上記のドキュメントにはありませんでしたが、rustupのインストール後、以下のようなメッセージが出ます。

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done
automatically.

「コマンドがインストールされたけど、パスは通ってないので、自分で通せ」という話ですかね。

10年くらい前の自分なら「パスって何だろう?どうやって通したらいいんだろう?」と思いながら、詰まったんだろうなあ。と思いながら、以下でコマンドがインストールされていることを確認しました。

> which rustup
[1]> ls ~/.cargo/bin
cargo*         cargo-fmt*     clippy-driver* rust-gdb*      rustc*         rustfmt*
cargo-clippy*  cargo-miri*    rls*           rust-lldb*     rustdoc*       rustup*

パスは通ってないものの、インストールはされているようです。

パスを通します。fishを使ってるので、以下のように書きます。(実際は他にもパスを書いてますが、省略)

~/.config/fish/config.fish

set PATH ~/.cargo/bin $PATH

そのあと、fishにログインし直して、パスが通っていることを確認します。

> which rustup
/Users/mtb/.cargo/bin/rustup

はい。OK。

Hello Worldしてみる

こんなコードを書き、hello.rs で保存します。拡張子は、.rsのようです。

fn main(){
    println!("Hello World!!");
}

以下のコマンドでコンパイルします。

rustc hello.rs

コンパイルしたら、 hello という実行ファイルができているので、実行すると標準出力に出ます。

> ./hello
Hello World!!

とりあえずここまでは簡単。

脱線:インストールされたツールを確認する

インストールしてHello Worldまで来たので、インストールされたツールが何なのかも確認しておきます。

と言っても、軽くhelpを読んだりリポジトリをサッと見るだけ。

  • cargo: Rust's package manager(Rustのパッケージマネージャー)
  • cargo-fmt: This utility formats all bin and lib files of the current crate using rustfmt.(rustfmtを使ってbinとlibをフォーマットするユーティリティ)
  • clippy-driver: Checks a package to catch common mistakes and improve your Rust code.(Rustコードのパッケージをチェックし、よくあるミスを発見して改善するツール)
  • rustc: (Rustのコンパイラ)
  • rust-gdb: (おそらくRustのデバッガ)
  • rustfmt: Format Rust code(Rustのフォーマッター)
  • cargo-clippy: Checks a package to catch common mistakes and improve your Rust code.(Rustコードのパッケージをチェックし、よくあるミスを発見して改善するツール)
  • cargo-miri: ???? (GitHubを見ると、Rustの実験的なインタープリタ。)
  • rls: Rust Language Server (IDEとの連携用)
  • rust-lldb: LLDB(コンパイラ基盤?)
  • rustup: The Rust toolchain installer(Rustのツールインストーラ)
  • rustdoc: Rustのドキュメント

公式のフォーマッターや静的解析ツール、Language Server、と最初から色々入ってるんだなあ、という印象を受けました。

とりあえず、cargo-fmtとrustfmt、cargo-clippyとclippy-driverの違いがよくわからないんですが、使っているととりあえずおいおいわかるんですかね。

とりあえず、終わり

これだけで、おわりかよっ!!って感じなんですが、今日は時間的にHello Worldと関連ツール調べただけで終わってしまいました。

次はもう少し、別のこともやってみたいところ。

また、気が向いたら、調べつつ、書きます。

ではでは。