Rustでパスがフォルダがファイルかを判別する

はじめに

この記事では、「Rustでパスがフォルダがファイルかを判別する方法」について書いています。

Rustを色々勉強中ですが知らないことや学んだのに忘れてしまっていたこともまだたくさんあり、Rustの勉強も兼ねて記事を書きました。

自分に向けた備忘録でもありますが、「Rustでファイルやフォルダの扱い方を知りたい」な人の一助になれば嬉しいです。

前提(環境)

私の環境のバージョン情報は以下の通りです。

説明

早速ですが、コードを以下に記します。このコードは、実行ファイルがあるフォルダ内の全てのファイルと、それがファイルかフォルダなのかを表示(標準出力)します。

use std::path;

fn main() {
    let target_path = "./";
    let target = path::PathBuf::from(target_path);
    let files = target.read_dir().expect("このパスは存在しません");
    for dir_entry in files {
        let file_path = dir_entry.unwrap().path();

        let is_dir = file_path.is_dir();
        if is_dir {
            println!("{:?}: folder", file_path);
        } else {
            println!("{:?}: file", file_path);
        }
    }
}

このコードで重要なポイントはlet is_dir = file_path.is_dir();です。

is_dir()メソッドで、file_pathが示すパスがフォルダ(ディレクトリ)かそうでないかを判断することができます。

基本的にフォルダでない場合はファイルかと思いますが、std::pathのドキュメントを確認すると

パーミッション エラーやシンボリック リンクの破損などにより、ファイルのメタデータにアクセスできない場合はfalseを返す

とあるので、trueが返ってきたらフォルダ、falseが返ってきたら"フォルダではない"という認識の方が良いかもしれません。

コードの実行例

例えば以下の構成になっている、普通のRustプロジェクトで考えます。

sample
├ .git
│   └ ... (省略)
├ src
│   └ main.rs  <- 上のコードが記述されている
├ target
│   └ ... (省略)
├ .gitignore
├ Cargo.lock
└ Cargo.toml

この中でのポイントは.git.gitignoreです。.gitignoreはファイルなのに対して.gitはフォルダです。これらは見分けてくれるのでしょうか。

このRustプロジェクトでcargo runを実行(つまりsampleフォルダ上で上のコードを実行)した時の出力は見てみましょう。以下のようになります。

"./.git": folder
"./.gitignore": file
"./Cargo.lock": file
"./Cargo.toml": file
"./src": folder
"./target": folder

.gitfolder.gitignorefileと正しく認識されています。

おわりに

「Rustでパスがフォルダがファイルかを判別する方法」について解説しました。

Rustでツールを作りたい、作ろうとしている方の一助になれば幸いです。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

doc.rust-lang.org

MKDocsでMermaidを使う方法

はじめに

この記事では、「MKDocsでMermaidを使う方法」について書いています。

最近MKDocsを使って資料を書く機会が多いのですが、テキストで様々な図表を書くことができるMermaidをMKDocsで使いたいときはどうするのだろうと思ったのが記事を書いたきっかけでした。

自分に向けた備忘録の意味もありますが、「MKDocsでMermaidを使ってみたい」な人の一助になれば嬉しいです。

要点だけ

ymlファイルに以下の記述を足してください

site_name: My Docs

theme:
  name: 'material'

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_div_format

extra_css:
  - https://unpkg.com/mermaid@8.0.0/dist/mermaid.css

extra_javascript:
  - https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js

試してみた内容

まずは、下のymlファイルで作成した(ただテーマにmaterialを適用しただけの)MKDocsで表示を確認します。

site_name: My Docs

theme:
  name: 'material'

表示は以下の図の通りです。Flowchartの節にmermaidで記述したコードがありますが、図表化されずにコードのままになっています。

さて、次はmermaidが図表化されるよう、上のymlファイルに少し加筆してみます。ymlファイルの内容は以下の通りで、markdown_extensions:以下が追加されています。

site_name: My Docs

theme:
  name: 'material'

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_div_format

extra_css:
  - https://unpkg.com/mermaid@8.0.0/dist/mermaid.css

extra_javascript:
  - https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js

こちらのコードでMKDocsの表示を確認すると、無事にmermaidで書いた部分が図表化されています。

なお、テーマにmaterial使う場合は、extra_css:extra_javascript:を省略して以下のように書くこともできます。

materialは、ページにmermaidコードブロックが含まれている場合、JavaScript ランタイムを自動的に初期化するそうです。)

site_name: My Docs

theme:
  name: 'material'

markdown_extensions:
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format

しかし、デフォルトのテーマ(mkdocs)や'readthedocs'の場合には上手く表示されないので、色々なテーマも試すよという方はextra_css:extra_javascript:を省略せず書く方が良いかもしれません。

おわりに

「MKDocsでMermaidを使う方法」について解説しました。

テキストだけでなく図表もテキストベースで書けるとGitなどでの管理に便利ですので興味があれば是非試してみてください

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

zenn.dev

qiita.com

Rustで任意のフォルダ内の全てのファイルを表示する

はじめに

この記事では、「Rustで任意のフォルダ内の全てのファイルを表示する方法」について書いています。

Rustを色々勉強中ですが知らないことや学んだのに忘れてしまっていたこともまだたくさんあり、Rustの勉強も兼ねて記事を書きました。

自分に向けた備忘録でもありますが、「Rustでファイルやフォルダの扱い方を知りたい」な人の一助になれば嬉しいです。

前提(環境)

私の環境のバージョン情報は以下の通りです。

説明

早速ですが、コードを以下に記します。このコードは、実行ファイルがあるフォルダ内の全てのファイルを表示(標準出力)します。

use std::path;

fn main() {
    let target_path = "./";
    let target = path::PathBuf::from(target_path);
    let files = target.read_dir().expect("このパスは存在しません");
    for dir_entry in files {
        // dir_entry(Result<DirEntry, Error>型)をfile_path(PathBuf型)に変換する
        let file_path = dir_entry.unwrap().path();
        println!("{:?}", file_path);
    }
}

このコードで重要なのはread_dir()で、このメソッドを使うことで指定したフォルダの中にある全てのファイルのパスを取得します。

このread_dir()PathBuf型に対して用意されているため、フォルダパスを&str型やString型で取得している場合はPathBuf型に変換してください(上のコードではtarget_path&str型で宣言していますが、PathBufに変換したtarget変数を用意し、それにread_dir()を使用しています。)

read_dir()で取得したもの(上の例ではfiles)はイテレータになっているため、中身を取得、処理した場合はfor文などで取り出す必要があります。

コードの実行例

例えば以下の構成になっている、普通のRustプロジェクトで考えます。

sample
├ .git
│   └ ... (省略)
├ src
│   └ main.rs  <- 上のコードが記述されている
├ target
│   └ ... (省略)
├ .gitignore
├ Cargo.lock
└ Cargo.toml

このRustプロジェクトでcargo runを実行(つまりsampleフォルダ上で上のコードを実行)した時の出力は見てみましょう。以下のようになります。

"./.git"
"./.gitignore"
"./Cargo.lock"
"./Cargo.toml"
"./src"
"./target"

sampleフォルダ内にあるファイルやフォルダが全て抽出されています。

おわりに

「Rustで任意のフォルダ内の全てのファイルを表示する方法」について解説しました。

Rustでツールを作りたい、作ろうとしている方の一助になれば幸いです。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

qiita.com

Pythonのpytestで-sオプションを試してみた

はじめに

この記事では、「pytestの-sオプションの機能と試してみた結果」について書いています。

私はこれまでpytestを使ったことはほぼなく、pytestの勉強をしていますが、pytestには色々なオプションがあるので、その中の--sオプションについて、どういう機能なのか、実際に使ってみてどうなのかをまとめて記事を書きました。

自分に向けた備忘録の意味もありますが、「pytest使いたいけどよく知らない」な人の一助になれば嬉しいです。

要点だけ

  • pytest -sではテスト実行中にprint文を標準出力に出力することができます。
  • 単純に結果だけでなく途中の変数の状態などを見たい時などに役に立ちます。

前提(環境)

以下の環境で実験をしていきます。

試してみた

まず、適当なpythonファイル(名前は何でも良いですが、ここではtest_add.pyとしました)を作り、中に以下のコードを書きます。

def test_add1():
    print("in test_add_1")
    assert 3 == 1 + 2

def test_add2():
    print("in test_add_2")
    assert 4 == 1 + 3

このファイルに対してテストを実施していきます。まずはpytestです。

================================================= test session starts =================================================
platform win32 -- Python 3.9.4, pytest-7.1.3, pluggy-1.0.0
rootdir: C:\Users\xxx\sample
plugins: anyio-3.6.1
collected 2 items

test_add.py ..                                                                                                   [100%]

================================================== 2 passed in 0.04s ==================================================

print文の内容は出力されていません。では続いてpytest -s-sオプションを付けて実行してみると出力はどうなるでしょうか

================================================= test session starts =================================================
platform win32 -- Python 3.9.4, pytest-7.1.3, pluggy-1.0.0
rootdir: C:\Users\xxx\sample
plugins: anyio-3.6.1
collected 2 items

test_add.py in test_add_1
.in test_add_2
.

================================================== 2 passed in 0.03s ==================================================

7行目、test_add.pyの記述の後にprint文の内容(in test_add_1, その下の行にはin test_add_2)が追加されていることが分かります。

おわりに

「pytestの-sオプションの機能と試してみた結果」について解説しました。

この方法を知っておくと、「テストの結果と共に途中の変数の状態などを見たい」時などに役に立つかと思います。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

syachiku.net

Pythonのpytestでテストの前処理後処理を追加してみる

はじめに

この記事では、「Pythonのpytestでテストの前処理後処理を追加する方法」について書いています。

私はこれまでpytestを使ったことはほぼなく、pytestの勉強をしていますが、pytestでテストの前や後に処理を入れるにはどう書けばいいのか分からず調査したのが記事を書いたきっかけでした。

自分に向けた備忘録の意味もありますが、「pytest使いたいけどよく知らない」な人の一助になれば嬉しいです。

前提(環境)

以下の環境で実験をしていきます。

fixtureについて

pytestには、テストの実行前後で行いたい処理を記述するためにfixtureという機能があり、これを使ってテストの前処理後処理を記述していきます。fixtureはこの他にパラメータやオブジェクトをテストに渡すこともできます。

記述としては@pytest.fixtureを関数に付与し、テスト関数の引数に関数名を指定することでテスト実行前後の処理を記述する準備ができます。

具体的な例を、実際に試してみた内容を元に見ていきます。

まず、適当なpythonファイル(名前は何でも良いですが、ここではtest_add.pyとしました)を作り、中に以下のコードを書きます。

import pytest

@pytest.fixture
def alpha():
    print("--- start ---")
    
    yield
    
    print("--- end ---")

def test_add1(alpha):
    print("in test_add_1")
    assert 3 == 1 + 2

def test_add2():
    print("in test_add_2")
    assert 4 == 1 + 3

上のコードでalpha関数がテスト実行前後の処理を記述している部分になります。今回の例ではただ文字列を出力するだけです。

yieldの前がテストの前処理、後がテストの後処理です。

yieldには戻り値を指定し、テスト関数内で使うことができます。なので例えば前処理でファイルやクラスのオブジェクトを作成し、それをテスト関数に渡すこともできます。(ここでは前処理後処理を実装する方法を簡単に示すことを目的としているので何も返さないようにしています)

test_add1関数の引数にalphaを指定しているのでこれはtest_add1のテストを実行する前後でalpha関数に書かれた処理が実行されます。逆にtest_add2は引数にalphaを指定していないのでテスト前後で何か処理は行われません。

では実際に出力を見てみましょう。pytest -s -qを行うと以下のような出力結果が得られます。

--- start ---
in test_add_1
.--- end ---
in test_add_2
.
2 passed in 0.01s

上で書いたように、alpha関数の処理(print文の出力)がtest_add1関数の前後に入っており、またtest_add2関数の前後には処理が入っていないことが分かるかと思います。

おわりに

Pythonのpytestでテストの前処理後処理を追加する方法」について解説しました。

この方法を知っておくと、「テストの前後で処理を入れたい」時などに役に立つかと思います。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

note.com

MermaidでFizzBuzzのフローチャートを書いてみる

はじめに

この記事では、「MermaidでFizzBuzzフローチャートの書き方」について書いています。

Mermaidとは、フローチャートシステム開発で使われるシーケンス図、ガントチャートなどをテキストで表現することができます。

最近QiitaやGitHubなどでMermaidがサポートされるなど使える場面が増えているため、書き方を試しながら学んでみようとなったのが記事を書いたきっかけです。

その中でフローチャートの基本的な書き方を調べてみました(あまり実例に沿った書き方がWebで調べても見つからなかったので、、、)

自分に向けた備忘録でもありますが、「Mermaidで簡単なフローチャートを書いてみたい」な人の一助になれば嬉しいです。

コード

早速ですがFizzBuzzフローチャートをMermaidで書いたコードが下記です。(変数名が雑ですがご容赦ください)

```mermaid
flowchart TD
  start([start])
  start --> loop_begin[/for i in 1..100\]
  loop_begin --> c_fizzbuzz{i%15 == 0}
  c_fizzbuzz -->  |yes| fizzbuzz[[Output FizzBuzz]]
  c_fizzbuzz -->  |no| c_fizz{i%3 == 0}
  c_fizz -->  |yes| fizz[[Output Fizz]]
  c_fizz -->  |no| c_buzz{i%5 == 0}
  c_buzz -->  |yes| buzz[[Output Buzz]]
  c_buzz -->  |no| num[[Output 'i']]
  fizzbuzz --> loop_finish[\ loop end /]
  fizz --> loop_finish  %% ここはコメントです
  buzz --> loop_finish
  num --> loop_finish
  loop_finish--> EOF([end])
```

上の記述でフローチャートが描画されます。

Note

今回は描画される図を省略いたしました。

理由として、VSCodemarkdown preview enhancedでは表示されるのに何故かはてなブログでは表示されなかったためです(原因は不明。色々試したのですが上手くいかず)

申し訳ありません

FizzBuzzフローチャートをMermaidで書いて感じた注意点として

  • IDの部分は、語尾にendを使えない(予約子とかなのかもしれない)
    • ENDEndは大丈夫。またend_xxxもOK。xxx_endの形だけがNG。
  • text部分に"は使えない

おわりに

「MermaidでFizzBuzzフローチャートの書き方」について解説しました。

仕方ないとはいえ、あまりきれいなフローチャートにはなりませんでした(笑)でも簡単にフローチャートを書くという点では良いなと思いました。

ちょっとしたフローチャートをMermaidで書きたいけど書き方に困ったときに参照していただければと思います。

さいごに、記事を書く上で参考にしたサイトのリンクを以下に掲載します。合わせて読んでいただくと良いかと思います。

mermaid-js.github.io

Gitで新しくブランチを作る方法(コマンド)

はじめに

この記事では、「Gitで新しいブランチを作る方法(コマンド)」について書いています。

Gitにはたくさんのコマンドがあり、また自分は普段TortoiseGitを使っていて全然コマンドを覚えてないので、ちゃんと自分でコマンドを試しながら学んでみるべく記事にしました。

自分に向けた備忘録でもありますが、「Gitのコマンドにまだ習熟してない人」や「Gitのresetコマンドがどういうものか知りたい」な人の一助になれば嬉しいです。

要点だけ

以下の3通りある

  • git branch <ブランチ名>
  • git checkout -b <ブランチ名>(git checkout -B <ブランチ名>)
  • git switch -c <ブランチ名>

説明

branchコマンド

git branchはブランチを一覧、作成、削除などを行うことができるコマンドです。

git branchを行うと、そのリポジトリのブランチの一覧を表示(出力)することができます。

checkoutコマンド

git checkoutは作業ブランチの切り替えを行うコマンドで、基本的にはgit checkout <ブランチ名>と書いて作業ブランチを変更します。

オプションで-bを使うことで「ブランチを作成」し、「そのブランチに切り替え」を行うことができます。

以下のコマンドを同時に実行していることになるので、「新しいブランチ作ってそこで作業したい」という人には便利かもしれません

git branch <ブランチ名>
git checkout <ブランチ名>

ちなみに、既に同名のブランチがある場合はエラーになります。その場合でも-Bと大文字にすると強制的に作成することができます。

switchコマンド

switchコマンドはGit 2.23から実験的機能として実装された新しいコマンドです。

checkoutコマンドの機能が多すぎるためにその機能を分割し、代替させる目的で作られたそうです。

代替が目的ですので、checkoutコマンドの「切り替え」に関わる機能は似たような感じで使用することができます。

git switch <ブランチ名>で作業ブランチの変更ができ、またオプションで-cとつけることで「ブランチを作成」し、「そのブランチに切り替え」を行うことができます。(checkoutコマンドではオプションが-bですがswitchコマンドでは-cなので注意が必要です。)

おわりに

「Gitで新しいブランチを作る方法(コマンド)」について解説しました。

もっとGitについて勉強し、効率的に使えるようになりたいと思います。