適当なメモ
Rust ファイル参照して開くときどうやって参照したら良いのか指定方法.
cargo new my_cargo
で作ったプロジェクト
my_cargo
├── Cargo.lock
├── Cargo.toml
└── src
├── iris.csv
└── main.rs
main.rs
から iris.csv
を読み込みたい場合どうすんの ?
my_cargo
からのパスで指定.
プロジェクトのホームディレクトリfn main() {
let my_path = "src/iris.csv";
let file = File::open(&my_path).expect("Cannot open file.");
}
main.rs
からの相対パスだと思って let my_path = "./iris.csv";
だと思っていたら違った.
YOLOX の訓練のときに要求するディレクトリ構造がわかりづらい
公式レポのREADME.md に明示的に書いてないんで、初見でやろうとすると絶対つまづく。
一応 ここ
に記載されているけども.. それにしてももう少しわかりやすく書いてくれないかなあ。
.
├── datasets # my_custom_exp.py に記載した Exp classで指定する.
│ ├── annotations # この名前の通りでないとだめ.
│ │ ├── instances_train2017.json # my_custom_exp.py に記載した Exp classで指定する.
│ │ └── instances_val2017.json # my_custom_exp.py に記載した Exp classで指定する.
│ ├── train2017 # この名前の通りでないとだめ.
│ │ ├── train_image1.jpg
│ │ └── train_image2.jpg
│ └── val2017 # この名前の通りでないとだめ.
│ ├── val_image1.jpg
│ └── val_image2.jpg
├── my_custom_exp.py
└── train.py # 訓練ファイル 公式レポをそのまま自分の作業ディレクトリにコピー
ラズパイ新しくインストールし直して接続 有線LAN ケーブルを使って, 他のMac などPCからssh 接続しようとする場合エラー出るのでそのときの解決方法
ssh pi@raspberrypi.local
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The ECDSA host key for raspberrypi.local has changed,
and the key for the corresponding IP address XXXXXXXXXXXXXXXXX
is unknown. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Please contact your system administrator.
Add correct host key in /Users/XXXXXX/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/XXXXXX/.ssh/known_hosts:10
ECDSA host key for raspberrypi.local has changed and you have requested strict checking.
Host key verification failed.
ssh-keygen -R raspberrypi.local
参考URL
Rust で Quicksortを実装してみる.
Test
#[cfg(test)]
mod tests {
use crate::quick_sort;
#[test]
fn test_quick_sort_when_some_i32_elements_exist_in_input() {
// Given input v
let v = vec![3, 1, 5, 4, 6, 2];
// When calling quick_sort
let result = quick_sort(v);
// Then the numbers should be nicely sorted !!
assert_eq!(vec![1, 2, 3, 4, 5, 6], result);
}
#[test]
fn test_quick_sort_when_single_i32_element_exists_in_input() {
// Given input v
let v = vec![1];
// When calling quick_sort
let result = quick_sort(v);
// Then the number should be returned the same as the input.
assert_eq!(vec![1], result);
}
#[test]
fn test_quick_sort_when_vacant_vector_given_as_input() {
// Given vacant vector as input,
let v = vec![];
// When calling quick_sort
let result = quick_sort(v);
// Then the number should be returned as vec![] as Vec<i32>.
assert_eq!(Vec::<i32>::new(), result);
}
}
実装
fn quick_sort(v: Vec<i32>) -> Vec<i32> {
println!("quick_sort called here {:?}", v);
let res: Option<(&i32, &[i32])> = (&v).split_first();
if v.len() == 0 {
return v;
}
if v.len() == 1 {
return v;
}
let (pivot, rest_v) = res.unwrap();
let left = rest_v.iter()
.filter(|item| item < &pivot)
.collect::<Vec<&i32>>();
let right = rest_v.iter()
.filter(|item| item >= &pivot)
.collect::<Vec<&i32>>();
println!("Recursive call 'left' from here");
let left = quick_sort(left.iter()
.map(|x| **x)
.collect::<Vec<i32>>());
println!("Recursive call 'right' from here");
let right = quick_sort(right.iter()
.map(|x| **x)
.collect::<Vec<i32>>());
println!("Recursive call end");
println!("left: {:?}, center: {:?} right: {:?}", &left, vec![&pivot], &right);
let sorted = [left, vec![*pivot], right].concat().iter()
.map(|x| *x)
.collect::<Vec<i32>>();
println!("Concat result: {:?}", &sorted);
return sorted
}
コメント
- Iteratorまわりの振る舞いが難しい. Vec<i32>.iter()で取り出される要素が参照になったり, 再帰呼び出しを行うために, 参照外しを行ったり, 自分がやっている型変換が正しいのか? もし正しくても, もっとまともなやり方あるんじゃあねえか?と思考の迷子になりがち, Rustが難しいと言われる理由はこういうところにあるのだろなと.
fn main() {
let v = vec![3, 5, 6, 2, 4, 1];
assert_eq!(vec![1, 2, 3, 4, 5, 6], quick_sort(v));
}
- 再帰呼び出しの振る舞いがつかみづらい.
- 呼び出し順は left を再帰で呼び出しまくって, その後で rightを呼び出しまくって,concatで結合.
quick_sort called here [3, 5, 6, 2, 4, 1]
# --- まずは split_firstを使って 最初の3 (pivot) と残り (rest)に分けて,
# --- 3より小さいものを left = [1, 2], 大きいものを right = [5, 6, 4]として
# --- left をまたquick_sortに入れて呼び出し.
Recursive call 'left' from here
quick_sort called here [2, 1]
Recursive call 'left' from here
quick_sort called here [1]
# --- 要素の数 1になったので 最初の left の再帰呼び出し終了.
# --- ここからは pivot=3と[2, 1]の配列に対する右側配列だから空.
Recursive call 'right' from here
quick_sort called here []
Recursive call end
left: [1], center: [2] right: []
Concat result: [1, 2]
# ---これでようやくpivot=3と[2, 1]に対する処理が終了.
# ---最初の[3, 5, 6, 2, 4, 1]に対する pivot=3, right=[5, 4, 6]の入力がここからスタート.
Recursive call 'right' from here
quick_sort called here [5, 6, 4]
Recursive call 'left' from here
quick_sort called here [4]
Recursive call 'right' from here
quick_sort called here [6]
Recursive call end
left: [4], center: [5] right: [6]
Concat result: [4, 5, 6]
Recursive call end
# ----pivot=3と[5, 6, 4]に対する処理が終了.
left: [1, 2], center: [3] right: [4, 5, 6]
Concat result: [1, 2, 3, 4, 5, 6]
std::str::FromStr
と filter_mapの合わせ技が超強力!!
Rust の
FromStr
について
こんな使い方ができる.
use std::str::FromStr;
#[test]
fn test_f64_from_str() {
let n = f64::from_str("2").unwrap();
assert_eq!(n, 2f64);
}
#[test]
#[should_panic(expected = "kind: Invalid")]
fn test_文字列はParseFloatError() {
let s = f64::from_str("a"); // ParseFloatError
s.unwrap();
}
#[test]
#[should_panic(expected = "kind: Invalid")]
fn test_f64_from_str_with_space() {
f64::from_str("2 ").unwrap();
// ParseFloatError {kind: Invalid}
}
#[test]
fn test_f64_from_str_containing_space_require_trim() {
let actual = f64::from_str(" 2 ".trim()).unwrap();
assert_eq!(actual, 2f64);
}
#[test]
fn test_f64_from_str_dot_exists_before_int_can_convert_to_f64() {
let actual = f64::from_str(".2").unwrap();
assert_eq!(actual, 0.2f64);
}
filter_map
について
15.3 イテレータアダプタ 330ページより
use std::str::FromStr;
#[test]
fn test_filter_from_str_with_filer_map() {
let text = "1\nfrond .25 289\n3.1415 estuary\n";
let numbers = text.split_whitespace()
.filter_map(|w| f64::from_str(w) // std::str::FromStr
// filter_mapは Someの中身を取り出し Noneの値をDropする
.ok()) // .okによりErr の場合はNoneを返す
.collect::<Vec<f64>>();
assert_eq!(numbers, [1f64, 0.25, 289f64, 3.1415f64]);
}
Rustのテスト書いているときにResult型の返すErrorを特定したいとなったが...
この記事を見るにかなり大変 💦
結局むりやり unwrapでパニックをおこしてエラーメッセージを補足するようなやり方が手軽そうではある.
なんかいい方法ないのかな?
#[test]
#[should_panic(expected="kind: InvalidDigit")]
fn test_zero_division() {
let number_str = "10 ";
number_str.parse::<i32>() // Result<i32, ParseIntError>
.unwrap(); // ParseIntError({ kind: InvalidDigit })
}
pub(crate)
の意味
pub(crate)はRustのアクセス修飾子で、その要素は同じcrate(ライブラリやモジュールの集合)内からのみアクセス可能です。つまり、他のcrateからはアクセスできないが、同じcrate内からはアクセスできるという意味です。このように、crate内部のアクセス制限を設定することで、crateのインターフェイスを隠蔽し、実装の詳細を隠すことができます。
上記の例で言うと、 Config struct は、外部のモジュールからはアクセスできないが、同じcrate内部ではアクセスできる、という意味になる。
Github actions設定して
clippyが通らない件
I took a Clippy error that said "Resource not accessible by integration". If you get this error, you need to change "Workflow permissions" into "Read and write permissions" instead of "Read repository contents permission". It's in the "Actions" section under the repository settings.
上記の通りに repositoryのSettings-> Actionsでやってみる
通った!!