$ pip install python-dotenv
.env
PSQL_PASSWORD=hoge
import os
from dotenv import load_dotenv
load_dotenv('../.env')
PSQL_PASSWORD = os.getenv('PSQL_PASSWORD')
print(PSQL_PASSWORD)
$ python3 migration.py
hoge
随机应变 ABCD: Always Be Coding and … : хороший
$ pip install python-dotenv
.env
PSQL_PASSWORD=hoge
import os
from dotenv import load_dotenv
load_dotenv('../.env')
PSQL_PASSWORD = os.getenv('PSQL_PASSWORD')
print(PSQL_PASSWORD)
$ python3 migration.py
hoge
$ tree
.
├── config
│ ├── hoge.dat
│ └── secret.pem
├── index.html
├── log
│ └── log.txt
├── src
│ └── main.rs
└── target
.gitignore
target/ congif/ target/ log/*.txt .env
git push

これだと、logやconfigの空フォルダが生成できない。
.gitkeepをフォルダの中に置いて、以下のように書く
!config/ config/* !config/.gitkeep !log/ log/*.txt !log/.gitkeep target/ .env
すると、logやconfigは空フォルダができるが、中のファイル群は更新されない。


OK!
async fn handle_index()-> Response {
let mut name_list: Vec<Name> = Vec::new();
let name1 = Name { family: "tanaka".to_string(), first: "taro".to_string(), age: 12};
let name2 = Name { family: "yamada".to_string(), first: "koji".to_string(), age: 13};
let name3 = Name { family: "okamoto".to_string(), first: "ai".to_string(), age: 14};
name_list.push(name1);
name_list.push(name2);
name_list.push(name3);
let name_list_serialized = serde_json::json!(&name_list);
let mut post_url = format!("http://192.168.33.10:3000/fetch");
let client = reqwest::Client::new();
let resp = client.post(post_url)
.header(reqwest::header::CONTENT_TYPE, "application/json")
.json(&name_list_serialized)
.send()
.await
.unwrap();
// println!("{:?}", resp);
"All good".into_response()
}
async fn handle_fetch(extract::Json(names): extract::Json<Vec<Name>>)-> Response {
println!("get names: {:?}", names);
let file_path = format!("./data/names.txt");
if !Path::new(&file_path.clone()).exists() {
let mut file = File::create(file_path.clone()).unwrap();
for name in names {
let serialized: Vec<u8> = serde_json::to_vec(&name).unwrap();
file.write_all(&serialized).expect("write failed");
file.write_all(b"\n").expect("write failed");
}
println!("done");
} else {
println!("file exist");
}
"All good".into_response()
}
names.txt
{“family”:”tanaka”,”first”:”taro”,”age”:12}
{“family”:”yamada”,”first”:”koji”,”age”:13}
{“family”:”okamoto”,”first”:”ai”,”age”:14}
うん、期待通りです。
[i32; 10]からStringへの変換
let mut bf = BloomFilter { filter: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]};
bf.set_v("hello world".to_string());
println!("{:?}", bf.filter);
let mut bloom_str = String::new();
for i in bf.filter {
bloom_str = format!("{}{}", bloom_str, i);
}
println!("{}", bloom_str);
String(chars)から[i32; n]への変換
let str = "2201211222".to_string();
let mut filter:[i32;10] = [0,0,0,0,0,0,0,0,0,0];
for (i,c) in str.chars().enumerate() {
filter[i] = (c.to_string()).parse::<i32>().unwrap();
}
println!("{:?}", filter);
[2, 2, 0, 1, 2, 1, 1, 2, 2, 2]
websocketで、send_textはあるけど、send_binary, sendしかなく、配列の送り方が不明なので、[i32; n]を文字列に変換して、受け取った側で、[i32; n]に戻すという処理にしている。
うーん、 なんか
websocketで通信して、connection errorや、通信内容の処理でのエラーハンドリング
以下のように書くと、接続先のURLにミスがあった場合もerrorを返してくれる。
#[tokio::main]
async fn main() {
let url = format!("wss://echo.websocket.org/");
// let url = format!("wss://echo.aaaaaaa.org/");
let res = web_socket(url).await;
match res {
Ok(_) => {
println!("wsに成功しました!");
}
Err(error) => {
println!("wsに失敗");
println!("{}", error);
}
}
}
async fn web_socket(url: String) -> Result<(), Box<dyn std::error::Error>> {
let mut ws = WebSocket::connect(&url).await?;
ws.send_text("foo".to_string()).await?;
ws.receive().await?;
if let Frame::Text { payload: received_msg, .. } = ws.receive().await? {
println!("{}", received_msg);
if received_msg != "hoge" {
let error = "メッセージの照合に失敗しました。".to_string();
return Err(error.into());
}
}
ws.close(None).await?;
Ok(())
}
– connectionエラー
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.17s
Running `target/debug/app`
wsに失敗
could not parse into SocketAddrs
– ソケット通信での内容でのエラーを明示的にエラーとして知らせる
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.81s
Running `target/debug/app`
foo
wsに失敗
メッセージの照合に失敗しました。
– 成功時
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.58s
Running `target/debug/app`
foo
wsに成功しました!
以下のような書き方はできない。
let mut ws = WebSocket::connect(&url).await?;
match ws {
Ok(_) => {
println!("wsに成功しました!");
}
Err(error) => {
println!("wsに失敗");
println!("{}", error);
}
}
なるほど、これは面白い。
error_for_status() で、エラーレスポンスの場合を取得できる。
https://docs.rs/reqwest/latest/reqwest/struct.Response.html
200の場合は通過する。
pub async fn handle_health() -> Response {
(StatusCode::OK, format!("I'm ACTIVE")).into_response()
// (StatusCode::BAD_REQUEST, format!("Something wrong happened")).into_response()
}
async fn handle_post_test()-> Response {
let res = reqwest::get("http://192.168.33.10:3000/health").await;
match res.unwrap().error_for_status() {
Ok(_res) => {
println!("health check is OK");
},
Err(_err) => {
println!("got bad request response. something wrong");
}
}
//
}
なるほど〜
レスポンスで、statusコードをStatusCode::OKと返却しない場合でも、.error_for_status()は通過する。
// OK
(StatusCode::OK, format!(“I’m ACTIVE”)).into_response()
// OK
“All good”.into_response()
// Err
(StatusCode::BAD_REQUEST, format!(“Something wrong happened”)).into_response()
4回くじを引くという条件から、nパターンの4回分を全通り試して、一致する組み合わせを探している。
全通りを探す場合、ループの中でループをするという書き方が多い。
static MAX_N: usize = 50;
fn main() {
let mut n: i32;
let mut m: i32;
let mut k: Vec<i32> = Vec::new();
println!("紙の枚数 n を入力してください。");
let mut line = String::new();
std::io::stdin().read_line(&mut line).ok();
let n = line.trim().parse::<i32>().unwrap();
println!("期待する数字の和 m を入力してください。");
let mut line = String::new();
std::io::stdin().read_line(&mut line).ok();
let m = line.trim().parse::<i32>().unwrap();
println!("紙に書かれている数字をそれぞれ入力してください。");
for i in 0..n {
println!("{}番目の数字:", i + 1);
let mut line = String::new();
std::io::stdin().read_line(&mut line).ok();
let n = line.trim().parse::<i32>().unwrap();
k.push(n);
}
let mut flg = false;
for a in 0..n {
for b in 0..n {
for c in 0..n {
for d in 0..n {
if k[a as usize] + k[b as usize] + k + k[d as usize] == m {
flg = true;
println!("発見! 組み合わせは{},{},{},{}", k[a as usize], k[b as usize], k, k[d as usize]);
}
}
}
}
}
if !flg {
println!("そのような組み合わせはありません。");
}
}
紙の枚数 n を入力してください。
3
期待する数字の和 m を入力してください。
10
紙に書かれている数字をそれぞれ入力してください。
1番目の数字:
3
2番目の数字:
3
3番目の数字:
2
発見! 組み合わせは3,3,2,2
発見! 組み合わせは3,3,2,2
発見! 組み合わせは3,2,3,2
発見! 組み合わせは3,2,3,2
発見! 組み合わせは3,2,2,3
発見! 組み合わせは3,2,2,3
発見! 組み合わせは3,3,2,2
発見! 組み合わせは3,3,2,2
発見! 組み合わせは3,2,3,2
発見! 組み合わせは3,2,3,2
発見! 組み合わせは3,2,2,3
発見! 組み合わせは3,2,2,3
発見! 組み合わせは2,3,3,2
発見! 組み合わせは2,3,3,2
発見! 組み合わせは2,3,2,3
発見! 組み合わせは2,3,2,3
発見! 組み合わせは2,3,3,2
発見! 組み合わせは2,3,3,2
発見! 組み合わせは2,3,2,3
発見! 組み合わせは2,3,2,3
発見! 組み合わせは2,2,3,3
発見! 組み合わせは2,2,3,3
発見! 組み合わせは2,2,3,3
発見! 組み合わせは2,2,3,3
import { RepositoryFactoryHttp, Account } from "symbol-sdk";
import { firstValueFrom } from 'rxjs';
const example = async (): Promise<void> => {
const nodeUrl = "http://sym-test-01.opening-line.jp:3000";
const respositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const networkType = await firstValueFrom(respositoryFactory.getNetworkType());
const alice = Account.generateNewAccount(networkType!);
console.log(alice);
console.log(alice.address);
console.log(alice.privateKey);
console.log(alice.publicKey);
};
example().then();
$ npm i -D tsx
$ npx tsx sample.ts
Account {
address: Address {
address: ‘TDKBPLRUAJLQLW7GTWIBXR5C35OLDTPOYPTGCQA’,
networkType: 152
},
keyPair: {
privateKey: Uint8Array(32) [
154, 6, 107, 15, 31, 11, 53, 21,
239, 158, 217, 230, 149, 43, 210, 175,
9, 46, 66, 202, 37, 169, 113, 38,
220, 27, 134, 214, 214, 187, 146, 181
],
publicKey: Uint8Array(32) [
30, 210, 66, 23, 95, 217, 178, 237,
101, 141, 64, 213, 241, 27, 146, 146,
169, 63, 253, 50, 218, 183, 250, 51,
52, 42, 249, 118, 210, 118, 62, 229
]
}
}
Address {
address: ‘TDKBPLRUAJLQLW7GTWIBXR5C35OLDTPOYPTGCQA’,
networkType: 152
}
9A066B0F1F0B3515EF9ED9E6952BD2AF092E42CA25A97126DC1B86D6D6BB92B5
1ED242175FD9B2ED658D40D5F11B9292A93FFD32DAB7FA33342AF976D2763EE5
どちらかというと、最初はフォーマットを覚えるのに時間がかかりそうやな…
普通のvectorから1つだけ削除
let target = 2;
let mut vec = vec![1, 2, 3, 4, 5];
if let Some(remove_index) = vec.iter().position(|x| *x == target){
vec.remove(remove_index);
}
println!("{:?}", vec);
[1, 3, 4, 5]
vectorから複数削除する
let targets = [2, 4];
let mut vec = vec![1, 2, 3, 4, 5];
for target in targets {
if let Some(remove_index) = vec.iter().position(|x| *x == target){
vec.remove(remove_index);
}
}
println!("{:?}", vec);
[1, 3, 5]
vectorの中身が構造体の時
=> 基本同じ処理
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct Person {
last: String,
first: String,
age: i32
}
//
let mut vec: Vec<Person> = Vec::new();
let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
vec.push(person1.clone());
vec.push(person2.clone());
vec.push(person3.clone());
vec.push(person4.clone());
vec.push(person5.clone());
let mut engineers:Vec<Person> = Vec::new();
engineers.push(person1);
engineers.push(person2);
for engineer in engineers {
if let Some(remove_index) = vec.iter().position(|x| *x == engineer){
vec.remove(remove_index);
}
}
println!("{:?}", vec);
[Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]
### mutexのvectorの場合
=> うまくいかない
static VECT: Lazy<Mutex<Vec<Person>>> = Lazy::new(|| Mutex::new(vec![]));
#[tokio::main]
async fn main() {
let mut vec: Vec<Person> = Vec::new();
let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
VECT.lock().unwrap().push(person1.clone());
VECT.lock().unwrap().push(person2.clone());
VECT.lock().unwrap().push(person3.clone());
VECT.lock().unwrap().push(person4.clone());
VECT.lock().unwrap().push(person5.clone());
let mut engineers:Vec<Person> = Vec::new();
engineers.push(person1);
engineers.push(person2);
for engineer in engineers {
if let Some(remove_index) = VECT.lock().unwrap().iter().position(|x| *x == engineer){
VECT.lock().unwrap().remove(remove_index);
}
}
println!("{:?}", VECT.lock().unwrap());
}
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.94s
Running `target/debug/app`
処理が止まったままになる…
ちょっとコードが冗長になるが、別の関数に切り出して、削除後のデータを再度空にしたmutexに入れるという処理を行うと上手くいく。
#[tokio::main]
async fn main() {
// mutex vectorの準備
let mut vec: Vec<Person> = Vec::new();
let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
VECT.lock().unwrap().push(person1.clone());
VECT.lock().unwrap().push(person2.clone());
VECT.lock().unwrap().push(person3.clone());
VECT.lock().unwrap().push(person4.clone());
VECT.lock().unwrap().push(person5.clone());
println!("{:?}", VECT.lock().unwrap());
// mutex vectorから削除したい値
let mut engineers:Vec<Person> = Vec::new();
engineers.push(person1);
engineers.push(person2);
let objs = processing_mutex_vector(engineers).await;
// 一度全て削除し、残したいデータを挿入する
VECT.lock().unwrap().clear();
for obj in objs {
VECT.lock().unwrap().push(obj);
}
println!("{:?}", VECT.lock().unwrap());
}
async fn processing_mutex_vector(engineers:Vec<Person>) -> Vec<Person> {
let mut binding = VECT.lock().unwrap();
let objs = binding.deref_mut();
for engineer in engineers {
if let Some(remove_index) = objs.iter().position(|x| *x == engineer){
objs.remove(remove_index);
}
}
return objs.to_vec();
}
[Person { last: “yamada”, first: “taro”, age: 20 }, Person { last: “yoshida”, first: “akira”, age: 15 }, Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]
[Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]
hex::encodeした値をhex::decodeした場合、元のStringを .to_owned().into_bytes() としないといけない。
pub static TEST_STRING : &'static str = "hogehoge";
#[tokio::main]
async fn main() {
let hex_string = hex::encode(TEST_STRING);
println!("{}", hex_string);
let hex_string_decode = hex::decode(hex_string).unwrap();
assert_eq!(TEST_STRING.to_owned().into_bytes(), hex_string_decode);
}
assert_eq!(TEST_STRING, hex_string_decode); ではないので、注意が必要。