OmniAICreator/Qiita-1.07M huggingface dataset:
インラインアセンブラ 小物 その2 w/Arduino @ Nucleo G070RB

# asmで1秒待つ

```cpp:main.ino
void setup() {

  Serial.begin(9600);
  while (!Serial) {}
  Serial.println("Boot NUCLEO G070");

  Serial.println("start!");

  uint32_t time0=micros();

  asm volatile(
    "LDR r0, =21333333 \r\n" // (1 + 21333333 * 3)=64,000,000 clocks.
    ".loop: \r\n"
    "SUB r0, #1 \r\n" // 1 cycle
    "BNE .loop \r\n"  // 2 cycle: if not zero, then branch
    : 
    : 
    : "r0"
  );

  uint32_t time1=micros();

  Serial.print("time0 ");
  Serial.println(time0);

  Serial.print("time1 ");
  Serial.println(time1);

  Serial.print("takes ");
  Serial.print(time1-time0);
  Serial.print("[usec] -> ");

  Serial.print((time1-time0)/1000000);
  Serial.println("[sec]");

}

void loop() {
}
```

- 動作周波数は64MHzでしたので，64,000,000クロック分待つようにしました。
- `BNE`は，フラグ Z=0 のとき2クロック使ってジャンプするようです。 (not equal zero) ついでにラベルの書き方も調べました。コロンを付けるのですね。
- PM0223では`SUBC`が`SUB と同じ演算を実行し、N、Z、C、V の各フラグも更新します。`と書いてあるのですが，コンパイルエラーとなります。なぜだろう... `SUB` を使って，フラグも更新されているようです。

実行例

```
Boot NUCLEO G070
start!
time0 119
time1 1001604
takes 1001485[usec] -> 1[sec]
```

# SysTick を読むことでクロック数を知る

```cpp:main.ino
void setup() {

  Serial.begin(9600);
  while (!Serial) {}
  Serial.println("Boot NUCLEO G070");

}

void loop() {
  uint32_t out1, out2;

  asm volatile(
    "LDR %[out1], [%[systick_val_address]] \r\n" // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "NOP \r\n"                                   // 1 cycle
    "LDR %[out2], [%[systick_val_address]] \r\n" // 1 cycle
    : [out1] "=r"(out1) , [out2] "=r"(out2)     
    : [systick_val_address] "r"((uint32_t)&SysTick->VAL)
    : 
  );

  Serial.print("out1 ");
  Serial.println(out1);

  Serial.print("out2 ");
  Serial.println(out2);

  Serial.print(out1-out2);
  Serial.println(" clocks.");

  delay(2000);
  while(1) {}
}
```

- SysTickはSTM32では重要なレジスターですね。1クロックで値が1減っていきます。それを利用して，見積もったクロック数が正しいか簡易的に調べられました。
- 上の「1秒待つ」は，これで下調べしています。
- なぜか `setup() {}` 中にSysTicｋにアクセスすると固まってしまいます... まぜ？


実行例
```
Boot NUCLEO G070
out1 57072
out2 57062
10 clocks.
```
Ubuntu20.04でLIO-SAMを実行する

# 概要
LIO-SAMは3D SLAMの一種で、Ubuntu上で動作する。Ubuntu20.04にインストールするためには少しばかり注意が必要なので注意点を示す。
# 前提条件
・**Ubuntu20.04 + ROS Noetic**
・RAM : **8GB**以上（RAM容量が少ないとcatkin_makeが失敗する）（RAM容量6GBで一敗済）
　筆者はVMware上で行ったので直接ディスクにUbuntuをインストールした場合の動作環境は不明
・ホームディレクトリ直下にワークスペースディレクトリ **catkin_ws** がある
# ROSに追加インストール
~~~
$ sudo apt-get install -y ros-noetic-navigation
$ sudo apt-get install -y ros-noetic-robot-localization
$ sudo apt-get install -y ros-noetic-robot-state-publisher
~~~
# gtsamのインストール
Georgia Tech Smoothing and Mapping libraryの略らしい
~~~
wget -O ~/Downloads/gtsam.zip https://github.com/borglab/gtsam/archive/4.0.3.zip
cd ~/Downloads/ && unzip gtsam.zip -d ~/Downloads/
cd ~/Downloads/gtsam-4.0.3/
mkdir build && cd build
cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF ..
sudo make install -j8
~~~
READMEの方法でgtsamを入れると失敗した。gtsamのバージョンは**4.0.3**にすると成功した。
makeするときにメモリが8GBないとmakeが失敗した。

# LIO-SAMのインストール
ひとまずホームディレクトリに戻る
~~~
cd
~~~
ROSワークスペースであるcatkin_wsに移動して作業を行う
~~~
$ cd ~/catkin_ws/src
/catkin_ws/src$ git clone https://github.com/TixiaoShan/LIO-SAM.git
~~~

https://github.com/TixiaoShan/LIO-SAM/tree/master

Ubuntu20.04ではこのままcatkin_makeすると失敗する。/catkin_ws/src/LIO-SAM　（cloneしたもの）の中身を修正する必要がある。

**/LIO-SAM/include/utility.h**の18行目
~~~ C++:utility.h
#include <opencv/cv.h>
~~~
を削除し、20~32行目のPCLヘッダの下に
~~~ C++:utility.h
#include <opencv2/opencv.hpp>
~~~
と書き加える。結果、utility.hの1行目から35行目までは
~~~ C++:utility.h
#pragma once
#ifndef _UTILITY_LIDAR_ODOMETRY_H_
#define _UTILITY_LIDAR_ODOMETRY_H_
#define PCL_NO_PRECOMPILE 

#include <ros/ros.h>

#include <std_msgs/Header.h>
#include <std_msgs/Float64MultiArray.h>
#include <sensor_msgs/Imu.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/NavSatFix.h>
#include <nav_msgs/Odometry.h>
#include <nav_msgs/Path.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/search/impl/search.hpp>
#include <pcl/range_image/range_image.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/icp.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/crop_box.h> 
#include <pcl_conversions/pcl_conversions.h>

#include <opencv2/opencv.hpp>

#include <tf/LinearMath/Quaternion.h>
~~~

**/LIO-SAM/CmakeLists.txt**の5行目
~~~Cmake:CmakeLists.txt
set(CMAKE_CXX_FLAGS "-std=c++14")
~~~
と書き換える必要がある。
最後に、**/catkin_ws**でcatkin_makeする。
~~~
/catkin_ws$ catkin_make
/catkin_ws$ source devel/setup.bash　
~~~
# 参考
LIO-SAMのGithub

https://github.com/TixiaoShan/LIO-SAM/tree/master

Ubuntu20.04で動作させる場合のIssue

https://github.com/TixiaoShan/LIO-SAM/issues/206
React RouterでReact.lazyした時のエラー

React Router v6 のチュートリアルを参考に実装していくと、buildした際にindex.jsのファイルサイズが大きくなります。対策のため、各コンポーネントをdynamic importにしました。
```main.jsx
import React, {lazy} from 'react'
import ReactDOM from 'react-dom/client'
import {
    createRoutesFromElements,
    createBrowserRouter,
    RouterProvider,
    Route,
} from "react-router-dom";
const Index = lazy(() => import('./routes/Index'));
const Root = lazy(() => import('./routes/Root'));
const Hoge = lazy(() => import('./routes/Hoge'));

const router = createBrowserRouter(
    createRoutesFromElements(
        <Route path="/" element={<Root />} >
            <Route>
                <Route index element={<Index />} />
                <Route path="hoge" element={<Hoge />} />
            </Route>
        </Route>
    )
);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)

```
上記のようにReact.lazyを使用したところ、画面遷移時にエラーになりました。

```
Oops!
Sorry, an unexpected error has occurred.

A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.
```

## 解決法

```修正前.jsx
<div>
  <Outlet />
</div>
```

```修正後.jsx
<Suspense fallback={<div>Loading...</div>}>
  <Outlet />
</Suspense>
```

## 参考
https://zenn.dev/monicle/articles/react-router-v6-suspense-idiom
スプレッド構文とレスト構文の違いをマリオで考えてみた

学びを備忘録としてまとめます

記念すべき第一弾は
【スプレッド構文】と【レスト構文】の違い
です。

 `...`　のやつですね。
両者の違いを”マリオ”で考えたら理解しやすかったので、書き記します🍄


## 結論：スプレッド構文とレスト構文の違い

結論として、違いはざっくり以下の感じです。

| 種類| イメージ |
|:-:|:-:|
| スプレッド構文  |  広げる |
|  レスト構文 | 集める |

スプレッド構文とレスト構文の表記 (`...`)は似ていますが、異なる目的と場面で使用されています。

## マリオのキャラクターを使って理解してみる

まず、マリオのキャラクターチームがあるとします。

```javascript:javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];
```

### スプレッド構文 (`...`)

スプレッド構文は、配列またはオブジェクトを個々の要素やプロパティに「広げる」ために使われます。

例えば、新しいキャラクターをマリオのチームに追加したい場合に、スプレッド構文を使います。

```javascript:javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];
const newCharacter = "ヨッシー";
const updatedMarioTeam = [...marioTeam, newCharacter];
//...marioTeam ＝ スプレッド構文

console.log(updatedMarioTeam);
// ["マリオ", "ルイージ", "ピーチ", "ヨッシー"]
```

マリオ・ルイージ・ピーチが、`...marioTeam`の中に収納されていて、`updatedMarioTeam`の配列の中で「広げ」られています。（解放〜〜〜〜！）

そこに`newCharacter`として、ヨッシーが追加されているということです。
（ヨッシーはゲーム内で強い味方なので、嬉しいですね↑↑）

### レスト構文 (`...`)

一方で、レスト構文は通常、関数の引数や変数の定義で使われます。

レスト構文を使うと、複数の要素を一つの配列に「集める」ことができます。

分割代入でよく使われます！

例えば、マリオのチームから最初のキャラクターだけを取り出して、残りのキャラクターを別の配列に格納できちゃいます。

```javascript:javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];
const [firstCharacter, ...remainingCharacters] = marioTeam;//分割代入
//...remainingCharacters ＝ レスト構文

console.log(firstCharacter); // "マリオ"
console.log(remainingCharacters); // ["ルイージ", "ピーチ"]
```

`firstCharacter`には配列の最初のマリオが格納されて、`...remainingCharacters`には残りのキャラクターが格納されます。

レスト構文は、分割代入をするときに、配列の残りの部分（`...remainingCharacters`）を新たな配列として取得するための構文ともいえます。

## まとめ

スプレッド構文とレスト構文は `...`　の表記で似てますが、以下のように違う役割を持っていることがわかりましたね。

| 種類| イメージ |
|:-:|:-:|
| スプレッド構文  |  広げる |
|  レスト構文 | 集める |

また理解しにくいことはマリオとか身近なものに置き換えて、楽しく学んでいきたいと思います🖐️

なにか間違っている部分などあれば、お気軽にコメントいただけると幸いです m(_ _)m
「『プログラミング＝英語』という状況は正しくない。多言語でコードを書ける世界が求められている」という言語学者さんの記事に感銘をうけた話

# はじめに
本記事は「『プログラミング＝英語』という状況は正しくない。多言語でコードを書ける世界が求められている」という言語学者さんの記事に感銘をうけたお話から、同じテーマについて考察し、「日本語トランスコンパイラ言語 Re:Mind（リマインド）」という自作トランスコンパイラ言語の企画意図を改めてまとめておきます。 

# 参考リンク

[「プログラミング＝英語」という状況は正しくない。多言語でコードを書ける世界が求められている](https://wired.jp/2019/08/04/coding-is-for-everyoneas-long-as-you-speak-english/)　wired.jp　GRETCHEN MCCULLOCH OPINION 2019.08.04

↑こちらが直接感銘を受けた記事です。記事の発信者は「インターネットは言葉をどう変えたか デジタル時代の〈言語〉地図」の著者 グレッチェン・マカロックという女性の言語学者さん。

BingのCoパイロットに記事を要約していただきました。

>プログラミング言語は英語に依存すべきではない
>
>プログラミング言語は、英語を話せない何十億という人々のために、母国語でコーディングできるようにするべきだ。
>英語以外の言語で提供されているプログラミング言語は数十個あるが、広く普及しているものは4つしかない。
>プログラミング言語の変換は容易にできるが、コミュニティの育成やリソースの提供が不十分だ。
>書くテクノロジーがラテン語に束縛されなかったのと同じように、コードを書くテクノロジーも本来、英語に束縛されるものではない。

# どこに感銘を受けたか
「プログラミング言語は語彙が限定的でしっかり定義されており、自然言語の自動機械翻訳が苦しむような多義性や文化的なニュアンスもない。100ほどのコマンドについて、何が何と対応しているのかわかれば、コードのどんな一節も自動的に翻訳することができる。」というお言葉。

ソフトウェア技術者や情報処理が専門の学者ではなく、あくまで言語学者なので多少の誤解はあるかもしれないが、形式言語としてのプログラミング言語の特徴はうまくとらえていると思う。ライブラリの語彙となるとまた数は違うとは思ったりもするけど。


## 納得したところ
「プログラミング言語には、理論上はどんな記号も使える。コンピューター上では人間が入力する『IF』も、1と0の組み合わせに変換されるのだ。IFを表すのにジャガイモの絵文字『?』が使われようと、15世紀のキリル文字のO（ꙮ）が使われようと、まったく同じように機能する。」というお言葉。まあ、これはいまのプログラミング言語が最終的にはマシン語に翻訳されることからの帰結ではありますが。ちなみにRe:Mindは「◇」です(笑)。

# 記事の結論
「書き言葉におけるラテン語の優位が終わったのと同様に、（ソフトウェア）コードを書くテクノロジーの英語の優位も終焉する可能性がある。」これは。あくまで私の意訳で、著者はそこまでは言っていないかもしれません。記事のタイトルにあるように、「多言語で書けるようにすべきだ。」という論調が妥当のよう。


# この記事の結論の妥当性はいかに
英字は文字数も少なく文字コード化が容易という点では、コンピュータの文字処理とは相性がよかったのは否めず、今後も英語英字の優位性の終焉はなかなか起きない可能性が高い。と私は考えます。

マシン語に若干の英記号を付与したアセンブリ言語が事実上存続しているのと同様に、その直上くらいに位置する相対的低水準言語のC言語が残るのと同様、C++やJava、C#、Javascriptなど半角英字を基調とした言語は標準的な言語として残り続けると思われます。（ただし、下記の母国語言語の台頭により、これらの「水準」の位置づけが相対的に変動して、かつての「高水準」言語は「中水準」言語に格付けされる可能性はあると考えます。）

# わたしの方向性
Qiitaさん上でも、新しい日本語プログラミング言語のありようとして日本語トランスコンパイラ言語の企画をご提示しようものなならば、どちらかというと否定的なコメントが多い印象です。

また、既存の英文字系プログラミング言語の文字コードのマルチバイト対応に伴い、変数名や関数名に日本字を使ってみてはという記事などに対しても、まずついてまわるのは否定的なコメントのようです。[^1]

私の感覚では、英文字系プログラミング言語を覚えられてそのまま使いたいならば、そのまま使い続けるのは技術者技能者ご本人の自由かと考えます。[^2]

21世紀に入って20年あまり、ソフトウエアやシステム開発の現場はハードウェアの開発現場（自体を支援しているのはソフトウェアではありますが）に比べると前近代的な状態は残っているようにも思えますので、生産性をあげる手段としてはあんがい母国語対応の多国語対応実装言語だったりするのかもしれません。


# おわりに
生成AIが、非エンジニアでも使えるある程度形式化されたアルゴリズム記述手順がルール化されている母国語トークンからなる言語ができれば、それらのアルゴリズム記述言語よりははるかにマシン寄りの今日の実装言語に自動変換するという未来がもうすぐのような気がします。

このような時代感の中で、ローカル言語のトランスレータってどうなの？という疑義があるのは百も承知ですが、あくまで日本語を文化ととらえる趣味ということで、温かい目で見てやってください。（いちおう多言語化も狙ってる(笑)）

https://qiita.com/mylifewithviolin/items/9d58db8a101807c19bde

# 参考リンク(原文)
https://www.wired.com/story/coding-is-for-everyoneas-long-as-you-speak-english/


[^1]: 読み返してみますと、前記事にコメントいただいた方が「じゃあ、いいよ。コメント自体しないから。」と思われてしまうような書き味にも取れますが、そういう意味ではなく、肯定的なコメントと否定的なコメントでどちらかというと後者が多かったと事実を述べているだけで、ものごとに批判的な観点の否定的なコメントは大歓迎です。お気軽にコメントお願いいたします。
[^2]: 基本的に対価を伴う実装業務の場合、多くは業務上実装言語が指定されているかと思います。既存の実装言語を否定するものではまったくないです。私も仕事で使ってますし。その上で別の言語企画もどうかな的な話です。
ransackで、パラメータに空白が含まれていても許可するよう設定する


# はじめに

Rails の gem で、ransack を使用時に、現状の仕様（v4.0.0）だと、パラメータの中に空白があったら自動的に削除されてしまいます。
それを空白があった場合でも許可するように設定する必要がありました。対処法を以下にまとめましたので、良ければご覧ください。

# 結論

`config/initializers/ransack.rb`に、`c.strip_whitespace = false`を追加すれば、空白も許可してくれるようになります。

```ruby: config/initializers/ransack.rb
Ransack.configure do |c|
  # Change whitespace stripping behaviour.
  # Default is true
  c.strip_whitespace = false ## 追加
end
```

:::note warn
ディレクトリ構成は違う可能性がありますので、ご自身の構成に合わせて修正をお願いいたします。
:::

# なぜ c.strip_whitespace = false を設定する必要があるのか

## ransack の以前の仕様

ransack のバージョンが`2.3.2`までは、パラメータの中に空白が含まれていても、空白を含む文字列として検索されていました。

```shell
[2] pry(#<Api::AbcController>)> Abc.ransack(encrypted_sanitized_tel_or_encrypted_tel_eq: Abc.encrypt(:tel, params[:abcde]))
=> Ransack::Search<class: Abc, base: Grouping <conditions: [Condition <attributes: ["encrypted_sanitized_tel", "encrypted_tel"], predicate: eq, combinator: or, values: ["abcdefg12345678==\n"]>], combinator: and>>
```

```shell
values: ["abcdefg12345678==\n"]
```

:::note warn
Controller 名やカラム名などは、適当に記載しております。ご自身の実装に合わせて考えていただけたらと思います。
:::

ただ、`2.4.0`から`2.4.2`の間は、パラメータの中に空白が含まれていたら、自動的に削除されるよう修正が入っていました。

- [ransack 2.4.0 CHANGELOG.md](https://github.com/activerecord-hackery/ransack/blob/main/CHANGELOG.md#240---2020-11-27)
- [空白が自動削除されるようになった修正 PR](https://github.com/activerecord-hackery/ransack/pull/1126)

```shell
[2] pry(#<Api::AbcController>)> Abc.ransack(encrypted_sanitized_tel_or_encrypted_tel_eq: Abc.encrypt(:tel, params[:abcde]))
=> Ransack::Search<class: Abc, base: Grouping <conditions: [Condition <attributes: ["encrypted_sanitized_tel", "encrypted_tel"], predicate: eq, combinator: or, values: ["abcdefg12345678=="]>], combinator: and>>
```

```shell
values: ["abcdefg12345678=="]
```

なので、もともと ransack のバージョンが 2.3.2 以前で、2.4.0 にバージョンアップすると、仮に実装で、空白も含めた文字列の検索処理をしているところがあると、不具合が起きると思います。（自分はこれでテストでエラーが多発しました、、、）

## 2.5.0 以降の仕様

自動で空白が削除されるようになったのはいいですが、それを回避するためのオプションが用意されていなかったため、ransack を使用している実装を大幅に変更する必要があったと思います。

そこで、`2.5.0`で空白を含んでもいいようなオプションが追加されました。それが`c.strip_whitespace = false`です。

- [ransack 2.5.0 CHANGELOG.md](https://github.com/activerecord-hackery/ransack/blob/main/CHANGELOG.md#250---2021-12-26)
- [空白も許可できるようになった修正 PR](https://github.com/activerecord-hackery/ransack/pull/1214)

この実装があったおかげで、ransack のバージョンをあげても、実装で空白も含む文字列で検索している場合は、オプションを追加すれば問題なくなりました。

これで無事解決ですね 👍

:::note alert
上記の内容は、現在（2023/07）での README には記載がありません。
GitHub で確認したい場合は、`main > Tags > v2.5.0` にすると、README で確認することができます。

https://github.com/activerecord-hackery/ransack
https://github.com/activerecord-hackery/ransack/tree/v2.5.0
:::

# まとめ

上記にも記載しましたが、現状の README に記載がなかったため、CHANGELOG を一から追ってようやく見つけることができました。CHAGELOG は、リリースされた内容が全て記載されているので、該当のバージョンの仕様を知るには、最適な資料でした。

CHANGELOG を読むのは大変だとは思いますが、何かのバージョンをあげる際には、必ず使う資料ですので、一緒に頑張っていきましょう！

最後までご視聴いただき、ありがとうございました。
この記事が、少しでも皆さんのお役に立てれたら幸いです。
ファイル管理②

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/11509319-fdfb-fb8c-1d33-ab7d5038341a.png)
１：レコードとファイル
　住所録の一人分のデータや、お店での売上１件分のデータ、倉庫の入出庫1回分のデータなど、一人分、１件分のことをレコードと言います。ファイルは、レコードをまとめて記録したものです。例えば、住所録ファイルには、複数人分の異データ、すなわち、複数のレコードが記録されています。

２：ファイル編成法
　ファイルへのレコードの格納の仕方をファイル編成法と言います。ファイル編成法は、汎用機のOSにある考え方で、私たちが普段利用しているパソコンのOSにはありません。

①順編成：基本的な構造は、先頭から順にレコードを記録する。媒体はデータ装置、ディスク装置

②直接編成：基本的な構造は、レコードのキー値を元に格納場所を決める。媒体は、ディスク装置

③索引編成：基本的な構造は、索引を用いたアクセスができる。索引域、基本域、あふれ域で構成さえっる。データは、基本域に格納する。媒体は、ディスク装置

④区分編成：基本的な構造は、プログラムライブラリを記録する。ディレクトリ域、メンバ域で構成される。媒体は、ディスク装置

　順編成ファイル
　レコードを先頭から順に記録します。隙間なく記録でき、媒体への格納効率は高くなります。また、デーブル装置に記録できることも利点です。一方で、先頭から順にしか読めないことが欠点です。途中のレコードをアクセスする場合は、録画した映像を早送りするのと同様に、目的のレコードまで読み飛ばしていく必要があり、アクセスに時間がかかります。したがって、指定したデータを素早く取り出す用途には不向きです。また、データの挿入に手間がかかることも欠点です。隙間なく記録されていますから、データを後から追加するスペースがありません。途中にデータを追加するためには、ファイル全体を最初から作り直す必要があります。

直接編成ファイル
　　社員番号や口座番号のように、データを区別するために用いる値をキー値と言います。直接編成ファイルでは、ハッシュ関数を用いてキー値のハッシュ値を計算し、ハッシュ値をデータの格納アドレスとします。指定したデータを素早く取り出せることが利点です。一方で、媒体への格納効率が低くなるのが欠点です。

索引編成ファイル
　索引域、基本域、あふれ域で構成されています。レコードは基本域に先頭から順に記録します。記録したレコードへは、索引を用いて素早くアクセスすることが可能です。
　レコードが基本域に入りきらなくなると、あふれ域に記録します。しばらく運用すると、多くのレコードがあふれ域に記録されてる状態となります。この世な状態では、アクセス速度が低下しますから、あふれ域のデータを基本域にと入り込んでファイル全体を作り直します。この作業を再編成と言います。定期的な再編成が必要です。
SharePointのURLエンコードかかったリンクを日本語に戻す（PowerShell版）

# はじめに
　SharePointやTeamsで日本語含むリンクをコピー&ペーストすると、パスにURLエンコードがかかって、長いし何のパスかわからない。リンクを日本語変換してから貼り付けたいなと思い調べてみた。

Python版はこちら

https://qiita.com/tapitapi/items/1acf508012eca079ad4a

# URLデコード
PowerShellで日本語のURLへデコードする方法。
$urlがデコードしたいURLだった場合の例。
```PowerShell
Add-Type -AssemblyName System.Web
[System.Web.HttpUtility]::UrlDecode($url)
```


# クリップボーにURL出力
クリップボードのURLをデコードし、再度クリップボードにコピーするまでの一連の処理の例。
```PowerShell
#-------------------------
#URL変換関数
#-------------------------
function URL_decode($url){
    Add-Type -AssemblyName System.Web
	return [System.Web.HttpUtility]::UrlDecode($url)
}

#クリップボードからURL取得し変換
$url=URL_decode(Get-Clipboard)

#クリップボードにコピー
Set-Clipboard $url
```
寿司ネタの関係性を可視化してみた - 多次元尺度構成法

# 多次元尺度構成法


多次元尺度構成法は、(非) 類似度を元に対象のデータ間の関係性を視覚的に分かりやすい形に変換することができる解析手法です。
ここでは寿司ネタの非類似度データが手元に有るとして、寿司ネタ同士の関係性を可視化します。
環境は MATLAB R2023a です。 



データ作成:



```matlab:Code
D = [1.6, 2.6, 3.9, 4.2, 2.5, 2.9, 4.1, 3.1, 3.9, 2.7];
DT = squareform(D); % 非類似度行列
neta = {'Tuna','Salmon','Shrimp','Salmon roe','Sea urchin'}; % 寿司ネタ
```

# 非類似度行列


寿司ネタが似ているか似ていないか (1-似ている, 5-似ていない) で点数をつけます。




こういうのを非類似度行列と言います。



```matlab:Code
disp(array2table(DT,'VariableNames',neta,'RowNames',neta)); % 非類似度行列
```


```text:Output
                  Tuna    Salmon    Shrimp    Salmon roe    Sea urchin
                  ____    ______    ______    __________    __________
    Tuna            0      1.6       2.6         3.9           4.2    
    Salmon        1.6        0       2.5         2.9           4.1    
    Shrimp        2.6      2.5         0         3.1           3.9    
    Salmon roe    3.9      2.9       3.1           0           2.7    
    Sea urchin    4.2      4.1       3.9         2.7             0    
```



マグロと鮭は比較的似ているのかなと。この様なデータをマーケッティングのアンケート等で入手できると思います。




こんな時、それぞれの寿司ネタの位置ベクトルが欲しくなります。ここで登場するのが多次元尺度構成法。




詳細は置いておいて、1つ目の戻り値が位置ベクトルを返してくれます。この位置ベクトルは元の関係性を再構築するために支配的な要素の順番に並んでいます (細かく言うと固有値問題を解いていて、固有値の大きさに対応している)。



```math
X=[x_1 ,x_1 ,\cdots ,x_n ]^{\top }
```

```matlab:Code
[X,eigvals] = cmdscale(DT) % 多次元尺度構成法 MDS
```


```text:Output
X = 5x4    
   -1.7449   -1.0391   -0.1902   -0.2083
   -1.2763    0.2307   -0.9132    0.2447
   -0.8009    0.6886    1.4895    0.0412
    1.3992    1.2282   -0.6166   -0.1657
    2.4229   -1.1085    0.2304    0.0882

eigvals = 5x1    
   13.1433
    4.3446
    3.5219
    0.1402
   -0.0000

```



負の固有値が有るとか、その辺の細かいことは置いておいて、元の関係性 (非類似度) を得られた $X$ で再現できるのかを一応、確認しておきます:



```matlab:Code
max(abs(D-pdist(X(:,1:3)))) % 部分空間における距離の最大誤差
```


```text:Output
ans = 0.0655
```



大丈夫そうですね。




今回扱っている非類似度行列が距離行列であれば (距離の公理を満たすかどうか？）、どうやら固有値は全てゼロ以上になるようなのですが、今回のデータは違ったようです。まぁ、固有値上位3つが支配的なのでそのまま分析を進めても問題有りません。


# 可視化


こんな感じになります:
(ちなみに、Salmon roe はイクラ、Sea urchin はウニです)


```matlab:Code
scatter3(X(:,1),X(:,2),X(:,3),'*');
text(X(:,1)+0.25,X(:,2),X(:,3),neta);
title("寿司ネタ同士の関係性");
```
![untitled1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473841/1513fbd6-b151-2e25-261b-e1bdde784b48.png)
そろそろIntel Mac用Homebrewを削除する

Apple SiliconのMacが十分に普及してくれたおかげで、我が家のM1 Macbookに入っているIntel Mac向けのさまざまなツールを一挙削除することができそうです。

そもそも、当初からそれほどIntel Mac向けライブラリ使わないと動かないライブラリは多くなかったのですが、いくつか常用していたツールが対応してなくて、渋々Intel Mac向けのHomebrewをインストールしていました。

あれから2年が経過して、常用していたツールが全てApple Siliconに対応していることに気付いたので、この機会にIntel Mac向けのHomebrewを削除することにしました。

やることは・・・ターミナルで以下の2行を実行するだけです。


```bash
export PATH=/usr/local/bin:${PATH}
brew uninstall $(brew list)
```

記事にするほどのことはなかったのですが、一応、記念にメモっておくことに😆
【Rails7 / 備忘録】リロードしないとJavaScriptが動かないんだけど、どした？エラー？

# 開発環境
Ruby 3.2.2
Ruby on Rails 7.0.5

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117662/bd324611-8c8b-6cdd-bea9-459cedf99db3.png)


# はじめに

最近、Rails７でチャットアプリを開発しているのですが、チャットルームにページ遷移してメッセージを投稿しようとすると、投稿できない:fearful:
しかし、ページをリロードしてからメッセージを投稿すると、投稿できる。
サーバーサイド側を確認しにいっても間違ってそうなところはないし、、、、
調べていると、メッセージ送信時にイベントが発火するようにJavaScriptを組んでいるのにそれが発火していない模様。

エラー原因がわかり、同じような現象のエラー解決の記事の通り実行するも動作せず、、、
ググっていると以下のようなJavaScriptのコードを`Turbolinks`のイベントで囲む対策法が多かったです。
```javascript:JavaScript
document.addEventListener("turbolinks:load", function() {
  // ここにページが読み込まれたときに実行するコードを書く
});
```


どうやらRails7より`Turbolinks`に代わって使用されている`Turbo Drive`が関係していることが分かったのでそれについてまとめていきます:writing_hand:

`Turbolinks`については以下の記事で簡単にまとめているのでよかったらご参照ください。

https://qiita.com/gon0821/items/8e75f8743812bd9b9994


# Turbo Driveとは
基本的な機能は`Turbolinks`と同様で、ページ全体を再読み込みするのではなく、必要な部分だけを更新することで、ページ遷移を高速化します。

Rails7では、`Turbolinks`に代わりデフォルトで`turbo-rails`というgemが用意されており、このgemによって`Turbo Drive`が使えるようになっています。
```:Gemfile（Rails7）
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails"
```

一方、Rails6までは以下のようにデフォルトで`Turbolinks`がGemfileに含まれており、`Turbokinks`によりページ遷移の高速化を行っていました。
```:Gemfile（Rails6）
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
```

# TurbolinksとTurbo Driveの違い
機能はほとんど同じですが、変更点の一つに<font color=red>**イベント名**</font>が変わったのが挙げられます。
`turbolinks:~~`であったのが`turbo:~~`に変わっています！

| Turbolinks| Turbo Drive | 内容 |
| ------- | ------- | ------- |
| turbolinks:load   | turbo:load | ページのロード後 |
| turbolinks:click | turbo:click | リンククリック時 |
| turbolinks:before-cache | turbo:before-cache | ページのキャッシュ保存前 |
| turbolinks:before-visit | turbo:before-visit | ページ訪問前 |
| turbolinks:before-render | turbo:before-render | ページのレンダリング前 |


<sub>参考：[「猫でもわかるHotwire入門 Turbo編」](https://zenn.dev/shita1112/books/cat-hotwire-turbo/viewer/event)より</sub>


# なぜ今までのエラー解決記事でエラー解決できなかったか？
- **結論**
`Turbo Drive`のイベント名でコードを書かないといけないのに、`Turbolinks`のイベント名でコードを書いていたから

- **解決法**
読み込ませたいJavaScriptのコードを以下の通り囲むことで、動作させることができました。
```JavaScript:
document.addEventListener("turbo:load", function() {
  // ページが完全に読み込まれたときに実行されるコード
});
```


# おわりに

時間はかかりましたが、バージョンの違いによって書かないといけないコードが違ってくる場合があることを学ぶことができました。
今後エラー出たときは、このような「内容自体はあっているけど、書き方の違い」も想定していきたいと思いました:wink:

# 参考文献

この記事にはお世話になりました:pray:

https://zenn.dev/shita1112/books/cat-hotwire-turbo
【PHP/Laravel】プログラミング初学者によるアプリケーション開発


概要
---
フルリモートでチーム共同開発を行いました。
今回作ったものはトークアプリです。


成果物
---

・ゲーアニ　Music Board
https://geanimusicboard.fly.dev/

・Github
https://github.com/yukihiroLaravel



担当した設計・開発
---

■posts（投稿）テーブルのマイグレーションとシーダー作成
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/posts_migration_seeder
＜設計＞
https://qiita.com/AlpacaFace/items/90211d5c2d70454c256d

■ユーザ新規登録機能
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/user_register_login
＜設計＞
https://qiita.com/AlpacaFace/items/608b1eb3a919f3d2eaed

■ユーザ編集画面・更新
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/user_edit_update
＜設計＞
https://qiita.com/AlpacaFace/items/223dac76913485359450

■投稿削除機能
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/posts_delete
＜設計＞
https://qiita.com/AlpacaFace/items/fcc4076e6789ba84541f

■ユーザ退会機能
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/user_delete
＜設計＞
https://qiita.com/AlpacaFace/items/1641a4589391bb8712fe

■フラッシュメッセージ表示機能
ユーザ退会機能、ユーザ情報更新機能
＜開発＞
https://github.com/yukihiroLaravel/joint_develop/commits/feature/fukushi/user_delete
＜設計＞
https://qiita.com/AlpacaFace/items/1641a4589391bb8712fe

■Flyデプロイ
＜実行手順整理＞
https://qiita.com/AlpacaFace/items/db0a6eaa566ffb78ad07



環境構築
---
■　DockerDesktop　ダウンロード＆インストール
＜実行手順整理＞
玉が行ったり来たりしてるだけなのになぜか円が回っているように見える現象の数理

X で見かけたこの映像。とても不思議。

https://twitter.com/TheFigen_/status/1684233373911334912?s=20

コードで再現したものが以下。コマが回っているように見える。

![vib_flat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285861/485b3844-58b8-e215-1833-7589ca93c950.gif)

一方で、色をつけてかつ軌跡がわかるようにすると、振動しているだけだとはっきりわかる。不思議。

![vib_rad.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285861/54e4884a-860e-0f7f-cd98-937258ecfa98.gif)

この小さな円に見えるものは、式にすると以下のようになる。ここで $t$ は時間を表現した実数。

$$
\left(x- \frac12 \cos t \right)^2 + \left(y + \frac12 \sin t \right)^2 = \frac14.
$$

これはすなわち $(x, y) = (\frac12 \cos t, - \frac12 \sin t)$ を中心に持つ半径 $\frac12$ の円。

これを $x$ 軸で切り取った断面の様子を見る。すなわち $y=0$ を代入する。すると、 $x$ に関する簡単な2次方程式が出てきて、その解は

$$
x = 0, \cos t
$$

である。

特に $x = \cos t$ であることから、**$x$ 軸だけに注目すると点が単振動していることがわかる。**

この推論は原点を中心とした回転の操作に対して同様に成立する。 $x$ 軸から $\theta$ だけ回転した軸上の点は以下のように表現できる:


```math
R_{\theta}
\begin{pmatrix}
\cos (t + \theta) \\
0
\end{pmatrix}
```

, ただし $R_{\theta}$ はベクトルを反時計回りに $\theta$ だけ回転させる回転行列。

実際代入してみるとわかるけれども、任意の $t$ と $\theta$ に対して、この点が上で示した小円の円周上に存在することがわかる。

上で作った gif は、 $\theta$ を 0 から $2 \pi$ の間で 8 ほどピックアップし、この式に基づいてプロットした点を $t$ を変化させながら作ったアニメーション。以下がそのコード。

```python
# %%
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation

SPLIT_NUM = 8


def rotation_matrix(theta):
    return np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])


def calculate_trajectory(t, theta):
    initial_vector = np.array([np.cos(t + theta), 0])
    rotated_vector = np.matmul(rotation_matrix(theta), initial_vector)
    return rotated_vector


fig, ax = plt.subplots(figsize=(6, 6))
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)

points = []

# Set initial values with t = 0
thetas = np.linspace(0, 2 * np.pi, SPLIT_NUM)
for i, theta in enumerate(thetas):
    (point,) = ax.plot(*calculate_trajectory(0, theta), "ro")
    points.append(point)

    # # Draw line through origin for each theta
    x_line = 1.5 * np.cos(theta)
    y_line = 1.5 * np.sin(theta)
    ax.plot([-x_line, x_line], [-y_line, y_line], color="black", lw=0.5)


ax.grid(False)
for spine in ax.spines.values():
    spine.set_visible(False)
ax.set_xticks([])
ax.set_yticks([])


def update(frame):
    t = frame / 20.0
    for i, theta in enumerate(thetas):
        color = "red" if i == 3 else "blue"
        color = "blue"
        x, y = calculate_trajectory(t, theta)
        points[i].set_data(x, y)
        points[i].set_color(color)


ani = FuncAnimation(fig, update, frames=range(1000), interval=20)
ani.save("vib_flat.gif", writer="pillow")

```

おわり。
GitHub に ssh で接続

## Key の作成

```bash:go_key_gen
ssh-keygen -t rsa -N "" -f key_example
```

実行結果
$HOME/.ssh で実行します。

```text
$ ./go_key_gen 
Generating public/private rsa key pair.
Your identification has been saved in key_example
Your public key has been saved in key_example.pub
The key fingerprint is:
SHA256:9DXUmxTGjcGxZ8XdmwFhEiE0yK6He8BVqpp/w0VxCHU uchida@example
The key's randomart image is:
+---[RSA 3072]----+
|      . += E+BB*=|
|       + .+.o.*+=|
|      . = . o..o*|
|       = = o .o= |
|    . * S +      |
|     O . .       |
|    . * .        |
|     . =         |
|      ..o        |
+----[SHA256]-----+
```

次のファイルが作成されます。

```text
key_example
key_example.pub
```

key_example.pub を GitHub にコピーペーストで登録します。


## github.com で、キーの登録

settings -> SSH and GPG keys
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6a7f2131-1567-24f5-221b-ed6d3f530776.png)

New SSH Key をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8cd746ff-a219-1008-735b-1c1b3124731d.png)

Add SSH Key をクリックして登録

## .ssh/config の作成

```text:.ssh/config
Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/key_example
```

## ssh 接続できるかの確認

```bash
ssh -T git@github.com
```

接続できる場合

```text
$ ssh -T git@github.com
Hi ekzemplaro! You've successfully authenticated, but GitHub does not provide shell access.
```

接続できない場合

```text
$ ssh -T git@github.com
git@github.com: Permission denied (publickey).
```

## クローン

```bash
git clone git@github.com:example/sample01.git
```

## 既存のリポジトリーに pull

リポジトリーが、https で pull されたか、 ssh で pull されたかを調べる

```bash
git remote -v
```

ssh で pull された場合

```text
$ git remote -v
origin	git@github.com:example/sample01.git (fetch)
origin	git@github.com:example/sample01.git (push)
```

https で pull された場合

```text
$ git remote -v
origin	https://github.com/example/sample01.git (fetch)
origin	https://github.com/example/sample01.git (push)
```

https から ssh に切り替える

```bash
git remote set-url origin git@github.com:example/sample01.git
```

pull

```bash
git pull
```
【SwiftUI】Viewの更新をプリントする

# はじめに
謎のバグに遭遇する時は意図しないタイミングでViewに更新がかかってるからかもしれません。
Viewの更新を知る方法を2つ知ったので記事にしておきます。

# 方法１
```swift
import SwiftUI

struct ContentView: View {
    @State private var count = 0
    var body: some View {
        VStack(spacing: 50) {
            let _ = print("Viewを更新しました")
            
            Text(count.description)
            
            Button {
                count += 1
            } label: {
                Text("カウントアップ")
            }
        }
    }
}
```

```
Viewを更新しました
Viewを更新しました
Viewを更新しました
Viewを更新しました
```

# 方法2
```swift
import SwiftUI

struct ContentView: View {
    @State private var count = 0
    var body: some View {
        VStack(spacing: 50) {
            let _ = Self._printChanges()
            
            Text(count.description)
            
            Button {
                count += 1
            } label: {
                Text("カウントアップ")
            }
        }
    }
}
```

```
ContentView: @self, @identity, _count changed.
ContentView: _count changed.
ContentView: _count changed.
ContentView: _count changed.
```

# おわり
`_printChanges()`のほうは詳細な情報を出力できますが、
プライベートAPIなのでAppleに提出する際は消しておいた方が良いでしょう
【FastAPI】PydanticでIPv4Addressのインポートエラーが出る理由とは？

# 概要
FastAPIで`pydantic`を使ったコードを実行したら、以下のエラーが出た。
`IPv4Address`とはなんぞや？`pydantic`と関係あるの？と思ったので調べてみました。

```
    from pydantic import BaseModel
  File "pydantic/__init__.py", line 2, in init pydantic.__init__
  File "pydantic/dataclasses.py", line 43, in init pydantic.dataclasses
    # | <blank> | No action: no method is added.          |
  File "pydantic/error_wrappers.py", line 4, in init pydantic.error_wrappers
  File "pydantic/json.py", line 5, in init pydantic.json
ImportError: cannot import name IPv4Address
```

# `ImportError`の原因
このエラーは、`ImportError`の通り、`pydantic`モジュールにおいて`IPv4Address`のインポートが失敗していることに起因しています。

通常、`IPv4Address`クラスは Python の標準モジュールである `ipaddress`モジュールに含まれています。しかし、`pydantic`モジュールが内部で`ipaddress`を使う場合、Pythonの環境によっては`ipaddress`モジュールが見つからない場合があるよう。（Python 3.3以上のバージョンを使用している場合は、通常`ipaddress`モジュールが標準で含まれているようです）

以下でインストールできます。
```
pip install ipaddress
```

## `IPv4Address`と`pydantic`の関係とは？
`IPv4Address`は、`IPv4（Internet Protocol version 4）`アドレスを表すためのクラス。
このクラスを使用すると、IPv4アドレスのパース、検証、ネットワークアドレスの取得などが容易に行えます。

公式ドキュメント：[ipaddress --- IPv4/IPv6 操作ライブラリ](https://docs.python.org/ja/3/library/ipaddress.html#ipaddress.IPv4Address)

> class ipaddress.IPv4Address(address)
IPv4 アドレスを構築する。 address が正しい IPv4 アドレスでない場合、 AddressValueError を発生させます。

なぜこれが`pydantic`と関係あるの？と思ったら、`pydantic`は、データのバリデーションに際して、データ型やフォーマットの指定ができる柔軟性を持っていて、IPv4アドレスなどの特定のデータ型をバリデーションする際にも利用されることがあるからですね。x

ということで`pydantic`は`IPv4Address`を含む様々なデータ型をサポートし、データのバリデーションを行える汎用的なデータ処理ライブラリ、ゆえに上述のインポートエラーが表示されたというわけです。

以前、`pydantic`や`BaseModel`クラスを解説する記事を書いたのでご参考までに。
[【FastAPI】Pydanticを使ってバリデーション：none is not an allowed valueエラーの解決方法](https://qiita.com/Ryo-0131/items/263915920dcddcde020f)
Rubyの将来性

# 目次
1. [Rubyとは](#Rubyとは)
1. [フレームワーク](#フレームワーク)
1. [Rubyのフレームワークの公開案件数](#Rubyのフレームワークの公開案件数)
1. [将来性](#将来性)
1. [「Rubyは将来性がない」と言われる理由](#「Rubyは将来性がない」と言われる理由)

# Rubyとは
1. [概要](#概要)

### 概要
1995年に一般公開されたオブジェクト指向スクリプト言語

https://qiita.com/Cookie_Iwate/items/44c8407e2f4a550fd313

# フレームワーク
## Ruby on Rails
「MVCアーキテクチャ」に基づいて構築されたフレームワーク
Twitter, クックパッドはRuby on Rails

#### メリット
Web開発向けのフレームワークとして設計されるため、Webアプリケーションを作るのに適している

#### デメリット
機能が多い為、実行速度が遅い
※そもそもRubyはインタープリタ方式である為、コンパイル方式の言語よりも実行速度が遅くなる

<img src="https://hataworakuni.net/wp-content/uploads/2020/03/rails.png.webp" />

## Sinatra
「簡単に記述できる」をテーマに設計されたフレームワーク

#### メリット
軽量で小規模アプリに向いている

#### デメリット
マニュアルが少ないため、学習効率が悪い可能性がある

<img src="https://www.gamehuntblog.com/wp-content/uploads/2018/07/20161121123724-1.png" width="120%"/>

## Padrino
機能が絞られたフレームワーク

#### メリット
機能が限られている為、比較的スムーズに動作する
Railsのコンポーネントを導入可能

<img src="https://testrigor.com/wp-content/uploads/2023/04/padrino_logo.png" />

# Rubyのフレームワークの公開案件数

<img src="https://cf.freelance-start.com/article/pictures/3436/Ruby_1-min.png" />

圧倒的にRuby on Rails

# 将来性
将来性は高いといわれている

#### ▼理由
1. [他言語よりもコードが短くシンプルで開発スピードが早い](#他言語よりもコードが短くシンプルで開発スピードが早い)
1. [Webアプリケーション開発において需要のある言語である](#Webアプリケーション開発において需要のある言語である)
1. [未経験者も学習しやすく教育コストが抑えられる](#未経験者も学習しやすく教育コストが抑えられる
)

## 他言語よりもコードが短くシンプルで開発スピードが早い
開発の生産性が他言語よりも高い傾向にある。
特に後述のRuby on Railsは少量のコードによりWebアプリケーションが作成可能なように作られており、スタートアップ企業などのスピード感が求められる開発において、選択されるケースが多い。

## Webアプリケーション開発において需要のある言語である
Rubyはベンチャー企業から大企業まで世界的に幅広く活用されている言語
世界のプログラミング言語検索数を示す「[TIOBE Programming Community Index (PCI)](https://news.mynavi.jp/techplus/article/20230110-2558740/)」によると、Rubyは<font color="red">**16位**</font>にランクインしている。世界規模で普及はしているとは言え、Rubyの現状としては日本の方が安定して需要のある言語と言えるだろう。

## 未経験者も学習しやすく教育コストが抑えられる
Rubyは、他言語よりもコードが短くシンプルで記載が少ないという特徴がある。
コードが短くシンプルであることは未経験者も学習がしやすいことにも繋がっている。

# 「Rubyは将来性がない」と言われる理由
1.[データサイエンスの分野においては乗り遅れている](#データサイエンスの分野においては乗り遅れている)
1.[処理速度が遅い](#処理速度が遅い)

## データサイエンスの分野においては乗り遅れている
ビッグデータやAIの活用の流れから、データサイエンスの需要が高い。
データサイエンスを支えるプログラムの構築は、現状Python・Rが主流である。一方Rubyは、データサイエンス分野のライブラリが充実しておらず、将来性については危惧されている。

## 処理速度が遅い
Rubyはインタプリタ式のプログラミング言語である為、処理速度が遅い。
【JavaScript】async/awaitとaxios、非同期通信について

# axiosとは
HTTP通信(データの更新・取得)など、HTTPリクエストのやり取りを簡単に行うことができる、JavaScriptのライブラリです。Node.jsで記述されています。APIを提供するクラウドサービスに対して、データを送受信することができます。

非同期にHTTPメソッド(GET・POST・PUT・DELETE通信など)を取り扱えます。

# 非同期処理とは

時間の掛かる処理の結果を待たずにすぐ次の処理を実行できる仕組みです。Promiseを使うと簡単に実現できます。

Promiseとは、非同期処理の状態を監視するためのオブジェクトで、非同期処理を同期処理のように扱える書き方です。

# 使う場面

JSONデータを提供しているAPIと接続して、データを取得することが多いです。

Webの場合、サーバーの中で外部にデータを提供している機能(またはそｎページ)のことをAPIとよびます。

# async/awaitとは

async/awaitを使うことによって、Promiseによる非同期処理をより簡潔に記述することができます。

Promiseのコードはthenを使ってチェーンを繋いでいくので、単調で長いコードになりやすです。

複数のPromise処理を実行する例
```js:
getDate()
.then(function(data) {

    return getYear(data)

}) .then(function(year) {

    return getSomething(year)

}) .then(function(item) {

    getAnotherThing(item)

})
```

上記のように長くなってしまいます。
そこで登場するのがasync/awaitです。

# async/awaitの使い方

## async

```
async function() { }
```

asyncを記述すると、この関数はPromiseを返すようになります。

## await

```
await Promise処理
```

awaitはPromise処理の結果が返ってくるまで一時停止する演算子です。

awaitはasyncで定義された関数の中だけでしか使えません。

# 今回書いたコード

```js:http/api.js
import axios from "axios";

const api = axios.create({
    baseURL: "http://localhost:8000/api/v1"
})


export default api
```
```vue:pages/RecipePages.vue
<script setup>
import { onMounted } from "vue";
import api from "../http/api"

onMounted(async() => {
    const { data } = await api.get('/recipes')
    console.log(data)
})
</script>
```

実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/10797b5e-6c56-6204-93f3-0427d2d8bbb7.png)

データベースに」格納されているデータを取得できました。

以下のようにしてCRUDを定義しました。

```js:httprecipe-api.js
import api from "./api";

const resource = "/recipes"

export const allRecipes = () => api.get(resource)

export const createRecipe = task => api.post(resource, recipe)

export const updateRecipe = (id, recipe) => api.put('${resource}/${id}', recipe)

export const removeRecipe = id => api.delete('${resource}/${id}')

export const completeRecipe = (id, recipe) => api.put('${resource}/${id}/complete', recipe)
```

修正を加えてコードを簡潔にします。

```vue:pages/RecipePages.vue
<script setup>
import { onMounted } from "vue";
import { allRecipes } from "../http/recipe-api"

onMounted(async() => {
    const { data } = await allRecipes()
    console.log(data)
})
</script>
```

実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/240d3884-bd52-e844-6d84-7ab6721a48eb.png)

実行結果を変えずに修正できました。
仮想マシンについて

# はじめに
私は初学者であり、一部の用語を誤って記述している可能性があります。そのような箇所があれば、本記事のコメントにてご連絡くださると幸いです。

# OS(オペレーティングシステム)
一般的なコンピュータはOSによって動作され、私たちはOSの管理によってアプリケーションを利用できます。OSの例として、Microsoftによって開発されたWindowsやApple製のmacOS、UNIXというOSとの互換性をもたせて開発されたLinuxが挙げられます。他にも、スマートフォンのOSとして、AppleによるiPhone専用OSであるiOSやGoogle社によって開発されたAndroidなどが存在します。

# 仮想マシン(Virtual Machine[VM])
仮想マシンとは、コンピュータ上で仮想的なコンピュータ環境を作り出すソフトウェアや技術のことです。

## ホストOS
基本的にコンピュータは1つのOSによって起動されます(デュアルブートやマルチブートの設定をすることでそのOSを複数にすることは可能です)。このように、物理的なコンピュータを起動するOSをホストOSといいます。

## ゲストOS
仮想マシンは、物理的なコンピュータの中で、ソフトウェアによって仮想的なコンピュータ）を作成することができます。そして、その中で別のOSやアプリケーションを動作させることができます。このOSをゲストOSといいます。つまり、仮想マシンは「ホストOS上でゲストOSを構築して制御する技術」といえます。ライセンスやハードウェアの観点で推奨されないOSが存在するため、ゲストOSの準備には注意が必要です。特に、macOSはApple社によってmacマシンのみに利用が認められており、アップルシリコンの登場によって独自的なハードウェア設計となったことから仮想マシンのゲストOSとして利用することは推奨できません。

# 仮想マシンのメリット
## 環境の分離とセキュリティ
仮想マシンは互いに独立しているため、1つのゲストOSに問題が発生しても他のゲストOSに影響を及ぼすことがありません。また、仮想マシンで検証を行うことで悪意のあるソフトウェアがホストOSに影響を及ぼすリスクを低減できます。

## テストや開発の環境
仮想マシンを使用すると、アプリケーションやシステムのテストや開発において、異なる環境を容易に構築できます。また、仮想マシンツールの機能によって仮想マシンデータをエクスポートすることで、開発チームで環境の共有が可能となります。

## バックアップと復元
仮想マシンはファイルとして保存されるため、バックアップや復元が簡単に行えます。作業内容を複製して保存することで、開発で問題点が発生した前の環境に戻ることができます。

# 代表的な仮想マシンツール
具体的な仮想マシンツールを挙げます。調査した内容をまとめたものになりますので、動作の保証はできかねます。ご了承ください。

## Windows Hyper-V
ネイティブなサポートがあり、Windowsのバージョンに対して高い互換性があります。64ビット版のWindows 10 ProとEnterprise、Educationで利用できます。

[Windows 10 の Hyper-V の概要 | Microsoft Learn](https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/about/)

## Oracle VirtualBox
オープンソースであり無料で利用ができ、豊富な機能とカスタマイズが可能です。ゲストOSはWindowsやLinux、Solaris、FreeBSDなど幅広く対応されているとのことです。複数の仮想マシンの作成やスナップショット(仮想マシンの状態の保存と復元)など、多くの機能を提供しています。処理内容によっては動作が遅いです。後述のVMware Workstation Playerに比べて、パフォーマンスがやや低くなる場合があります。また、ユーザーインターフェースがやや複雑で、初心者には少し学習コストがかかる場合があります。

[Oracle VM VirtualBox](https://www.virtualbox.org/)

## VMware Workstation Player
Oracle VirtualBoxとともに高いシェアを誇る仮想マシンツールです。高いパフォーマンスを提供し、特に3Dグラフィックスやハードウェアアクセラレーション(コンピュータの処理速度を向上させる機構)を必要とするアプリケーションの動作が得意とのことです。また、ユーザーインターフェースが直感的で使いやすいとの評判で初心者から上級者まで幅広いユーザーに適していると評判です。商用製品として提供されているため、基本機能は無料版でも利用できますが、高度な機能は有料となります。

[VMware Japan](https://www.vmware.com/jp.html)

## Parallels Desktop
macOS専用の仮想マシンツールです。シームレスなMacとWindowsの統合を提供し、高いパフォーマンスと快適な利用が可能だそうです。2週間のトライアル期間を過ぎると利用料金が発生します(2023/07/29時点)。

[Parallels](https://www.parallels.com/jp/)

## QEMU
オープンソースであり無料で利用が可能です。こちらも、クロスプラットフォームに対応しています。欠点として、ユーザーフレンドリーさに欠けており、初心者には少し扱いが難しい場合があるとのことです。また、カーネルといった低レイヤーの開発者向けの設計となっているとのことです。

[QEMU](https://www.qemu.org/)

# おわりに
ご閲覧いただきありがとうございました。現在、私は新しいパソコンで開発環境を整えるために様々なツールを導入している状況です。今後、同様の作業をする際の忘備録として記事を投稿させていただいております。拙い点や誤っている点がいくつかあるかと思いますが、コメントにてご指摘、ご教授いただけると幸いです。
AWS Public IPv4 Address有償化に向けて、全AWSアカウントの公開IP一覧を出す

2024年2月より、公開用のIPv4アドレス(elastic ip含む)が1つ約500円/月の有償化が決まりました。

# すべてのPublic IP利用を抽出
`AWS Config Advanced Query`が便利です
スコープをaws_allにして、

```sql
SELECT
  accountId,
  configuration.association.publicIp,
  configuration.interfaceType,
  availabilityZone,
  resourceId,
  tags,
  configuration
WHERE
  resourceType = 'AWS::EC2::NetworkInterface'
  AND configuration.association.publicIp > '0.0.0.0'
ORDER BY
  accountId,
  configuration.interfaceType
```




# EIPだけ抽出

公開用ipはEIPだけではないものの、EIPもそれなりの量になります。
全AWSアカウントでのEIP一覧を出すのも`AWS Config Advanced Query`が便利です
スコープをaws_allにして、

```sql
SELECT
  accountId,
  resourceName,
  awsRegion,
  resourceId,
  tags,
  relationships,
  configuration
WHERE
  resourceType='AWS::EC2::EIP'
ORDER BY
  accountId
```
resourceNameが実際のipアドレスを指します。
count(*)も可能です。

# Public IP Insights
新しくできたPublic IP InsightsはEIP以外も含まれて便利ですが、
アカウントを横断して確認することはできないようです。
(IPAMで組織横断の設定すればいけるかもしれません)
lightsailのAmazon Linux 2023にdockerとdocker composeをインストールする方法

参考サイト：https://densan-hoshigumi.com/aws/amzn2023-docker-install

```
lscpu
```
をして、Architecture: x86_64
を確認する

最新バージョン　https://github.com/docker/compose/tags

```
sudo dnf install -y docker
sudo systemctl enable --now docker
docker info

DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
sudo mkdir -p $DOCKER_CONFIG/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version
```
Markdown表示のコードスニペットのコピー機能をNuxt.jsアプリに実装してみる

[ソースコードシンタックスハイライトに対応した前回](https://qiita.com/suzuki-navi/items/2b36804e8d68d1eae156)の記事の続きで、今回はコードをクリップボードにコピーする機能を追加します。

ちょうどいいパッケージを探したのですが、見つかったパッケージは長らくメンテされてないようで、試したのですが動きませんでした。ほかに見つからなかったので、結局フルスクラッチで書きました。

HTMLの中で `$md.render(content)` と書いていたところを `renderMarkdown(content)` に置き換えて、 `renderMarkdown` を独自実装することで対応させます。

```html
<div class="markdown" v-html="renderMarkdown(content)"></div>
```

Markdownで生成したDOM要素に対して、クリックイベントなどを拾えるようにする初期設定を `renderMarkdown` の中から呼び出します。

```javascript
  methods: {
    renderMarkdown(text) {
      setTimeout(() => {
        this.initializeMarkdownDOM();
      }, 10);
      return this.$md.render(text);
    },
    initializeMarkdownDOM() {
      document.querySelectorAll('.markdown pre').forEach((preElement) => {
        if (preElement.dataset.initialized) {
          return;
        }
        preElement.dataset.initialized = "true";
        this.initializeMarkdownCodeBlock(preElement);
      });
    },
    initializeMarkdownCodeBlock(preElement) {
      const buttonAreaElem = document.createElement("div");
      buttonAreaElem.classList.add("btn-area");
      buttonAreaElem.style.display = "none";
      preElement.insertAdjacentElement("afterbegin", buttonAreaElem);

      const copyButton = document.createElement("a");
      copyButton.innerHTML = '<i aria-hidden="true" class="v-icon notranslate mdi mdi-content-copy theme--dark primary--text"></i>';
      copyButton.href = "#";
      copyButton.addEventListener("click", (event) => {
        event.preventDefault();
        const codeElem = preElement.querySelector("code");
        const text = codeElem.innerText;
        this.copyToClipboard(text);
      });
      buttonAreaElem.insertAdjacentElement("beforeend", copyButton);

      preElement.addEventListener("mouseenter", () => {
        buttonAreaElem.style.display = "block";
      });
      preElement.addEventListener("mouseleave", () => {
        buttonAreaElem.style.display = "none";
      });
    },
    copyToClipboard(text) {
      navigator.clipboard.writeText(text);
    },
  },
```

CSSには以下を加えます。これはコピーボタンを `<pre>` エリアの右上に配置するための記述です。

```css
.markdown pre {
  position: relative;
}
.markdown pre .btn-area {
  position: absolute;
  box-sizing: border-box;
  width: 100%;
  padding-right: 10px;
  text-align: right;
}
```

これで、コード上にマウスカーソルを乗せたときに右上にコピーボタンが現れ、クリックするとクリップボードにコードがコピーされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490207/38eec99c-45fa-6ec0-536e-a4e6420d5752.png)
Laravel Homesteadでnginxのaccess.logを有効にする方法

Laravel Homesteadを開発環境として使っている。

https://laravel.com/docs/10.x/homestead

Laravelが動作する仮想環境をカンタンに構築できる優れものだ。

が、デフォルトでaccess.logがoffになっていて ログの追跡ができない。

[1753][scripts]$pwd
/Users/myname/Homestead/scripts


[1753][scripts]$grep access_log * -r | grep -v location | awk {'print $1'} | tr -d : | sort | uniq
site-types/cakephp3.sh
site-types/elgg.sh
site-types/fastadmin.sh
site-types/frontcontroller.sh
site-types/laravel.sh
site-types/modx.sh
site-types/phalcon.sh
site-types/pimcore.sh
site-types/proxy.sh
site-types/silverstripe.sh
site-types/spa.sh
site-types/statamic.sh
site-types/symfony2.sh
site-types/symfony4.sh
site-types/thinkphp.sh
site-types/umi.sh
site-types/wordpress.sh
site-types/yii.sh
site-types/zf.sh
[1753][scripts]$subl `grep access_log * -r | grep -v location | a1 | sort | uniq `

Homesteadのscriptsディレクトリ以下に設定元のファイルがあるようだ。
このファイルの

access_log off;

の部分を

access_log /var/log/nginx/access.log;

に変えてしまう。

homestead up --provision

を実行して確認すると

/etc/nginx/sites-enabled

ディレクトリ以下のconfファイルの

access_log /var/log/nginx/access.log;

になっていた。
React関数命名:「on」と「handle」の理解と適切な使い方


Reactを使っていると、「on」と「handle」の接頭辞を持つ関数をよく見かけると思います。でも、これらの接頭辞がなぜよく使われ、どのように使い分けられるのか、混乱している方も多いのではないでしょうか。今回は、これらの接頭辞がどのような意味を持ち、どのように使うべきかを詳しく解説します。

## 目次

- [onとhandleの基本的な使い方](#onとhandleの基本的な使い方)
- [イベントハンドラの作成](#イベントハンドラの作成)
- [onとhandleの適切な使い方](#onとhandleの適切な使い方)

## onとhandleの基本的な使い方

まず基本から説明します。一般的に、「on」で始まる関数名は、何らかのイベントが発生したときに発火することを示しています。また、「handle」で始まる関数名は、具体的なアクションを行う関数を指します。

例えば、ReactのonClickイベントハンドラは、クリックイベントが発生したときに発火する関数です。以下の例を見てみましょう。

```jsx
<button onClick={handleClick}>Click me</button>
```

この例では、ボタンがクリックされたときに`handleClick`という関数が発火します。

## イベントハンドラの作成

それでは、「handle」で始まる関数、つまりイベントハンドラをどのように作るのか見ていきましょう。

```jsx
function ExampleComponent() {
  const handleClick = () => {
    console.log("Button clicked");
  };

  return (
    <button onClick={handleClick}>Click me</button>
  );
}
```

ここでは`handleClick`という関数を定義し、その関数をボタンのonClickイベントハンドラに指定しています。この`handleClick`関数は、ボタンがクリックされると発火します。

## onとhandleの適切な使い方

最後に、`on`と`handle`を使い分けるポイントについて説明します。

* 「on」は、特定のイベントが発生したときに何らかのアクションをトリガーするための関数に使用します。
* 「handle」は、イベントが発生したときに具体的に何をするのかを記述する関数に使用します。

具体的な例を見てみましょう。

```jsx
class ExampleComponent extends React.Component {
  handleClick = () => {
    console.log("Button clicked");
  };

  render() {
    return (
      <button onClick={this.handleClick}>Click me</button>
    );
  }
}
```

ここでは`handleClick`関数はボタンのクリックイベントに対して具体的な動作を定義します。「onClick」としてボタンに渡され、クリックイベントが発生したときに呼び出されます。

以上が、Reactの関数命名における「on」と「handle」の基本的な使い方と適切な使い分け方です。これらを適切に使い分けることで、コードの可読性を向上させ、他の開発者が理解しやすいコードを書くことができます。

それでは、Happy coding!
Azure Pipelines 内から Azure CLI でプルリクを作ってみた

例えば develop ブランチのパイプラインが全て通ったら main ブランチにプルリクを出す運用ルールだったとします。手動でプルリクを出しているくらいなら、自動化しても良いんじゃないかと思い、develop ブランチのパイプラインの一番最後に Azure CLI でプルリクを作成するタスクを組み込んでみました。

## パイプライン例

Azure CLI でプルリクを行う前提として Service Connection にサービスプリンシパルを登録済みで、そのサービスプリンシパルがプロジェクトのメンバーになっている必要があります。

```yaml:azure-pipelines.yml
trigger:
- develop

pool:
  vmImage: ubuntu-latest

steps:
- script: echo $(Build.BuildNumber)
- task: AzureCLI@2
  inputs:
    azureSubscription: 'mnrpoc'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az repos pr create \
        --organization https://dev.azure.com/mnrsdev \
        --project mnrpoc \
        --repository mnrpoc \
        --source-branch develop \
        --target-branch main \
        --title "Pipeline Completed $(Build.BuildNumber)"
```

## 実行結果のプルリク

![pipeline-completed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/4a4ec8d8-1cf0-4b71-0ca3-44311b7bac65.png)

## 参考

https://learn.microsoft.com/en-us/cli/azure/repos/pr?view=azure-cli-latest#az-repos-pr-create
デバッグモードでしか動かないプログラム。静的検査。

100万人に伝えたい！失敗を乗り超えた話を共有しよう

https://qiita.com/official-events/e9f582bec72278130942&usg=AOvVaw3jzsfZgHBQjGpWa_ucIm-H&opi=89978449


参加投稿です。技術士（情報工学）、工学博士　小川清です。


 ＜この記事は書きかけです。順次追記します。＞
 This article is not completed. I will add some words in order.
# デバッグモードでしか動かないプログラム。

計算終わるのに３年かかる。失敗から学ばない私。

https://qiita.com/kaizen_nagoya/items/42fd3cebca69525c2951

で書いた、OBJのシンタックスチェッカは、実は、デバッグモードでしか動かない。　

最初は、Small C Compilerを写経した。
次にPascalで書かれたコンパイラをC言語に移植した。　

YaccとLexで書いたコンパイラも動かしてみた。　

OBJのシンタックスチェッカを造った。　
コンパイラのデバッグモードだと動く。　
リリースモードだと暴走する。　

OBJは、LISPで書かれた言語。LISPが使えれば、シンタックスチェッカもLISPで作れたはず。

原因は推測できた。Pascalには範囲指定機能がある。C言語には範囲指定機能がなく、どこかで配列が溢れているのだろう。　

MISRA Cに取り組んだ後では、静的検査すれば分かる。　

C言語教育はCコンパイラの写経で

https://qiita.com/kaizen_nagoya/items/088a9906797559cd8b8a

写経だけでは十分ではない点が一つみつかった。MISRA Cに取り組み、すぐに解決策も見つかった。

# MISRA C
Cコンパイラを書いた経験は、Cのコーディング標準の創り方、運用の仕方、展開方法には役立った。　

そして、MISRA C用のツールで、範囲検査機能を知った。なんだ、この機能使えば、リリースモードでも動くようにできたんだ。


３つの失敗を重ねるなかで、得た経験で役立った最初の成果かもしれない。　

MISRA C まとめ #include <misra_c.h>

https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

MISRA C 2012 －組み込みプログラミングの高信頼性ガイド

https://webdesk.jsa.or.jp/books/W11M0090/index/?bunsyo_id=430006

# まとめに代えて　
コンパイラを描き始めて、プログラミング言語のそれぞれの制約にぶつかった。　

コンパイラを書いた経験にもとづき、MISRA Cに取り組んで、すぐに問題は解決した。


今まで書いてよかった技術書を紹介しよう！

https://qiita.com/kaizen_nagoya/items/d31b7c158541d345a7ef


C++/C コンパイルエラーを記録するとよい理由7つ

https://qiita.com/kaizen_nagoya/items/85c0e92b206883140e89


C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識

https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

[C][C++]の国際規格案の例題をコンパイルするときの課題７つ。

https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de


# 関連資料


夜勤明けで免許更新で眼鏡付きになった。６９歳のゴールド免許

https://qiita.com/kaizen_nagoya/items/a735e751cf398996590b

計算終わるのに３年かかる　失敗から学ばない私

https://qiita.com/kaizen_nagoya/items/42fd3cebca69525c2951

デバッグモードでしか動かないプログラム。静的検査。

https://qiita.com/kaizen_nagoya/items/02b7ee50e152475f7ff0

FAXが送れない。「Microsoft Exchange活用ガイド」技術評論社。裏話。

https://qiita.com/kaizen_nagoya/items/a129bba18cb32d68ad59

索引体系化に失敗。統計を取ろう。

https://qiita.com/kaizen_nagoya/items/57b89e7ec8ef2e1b3c83

失敗してもめげないプログラマになるには。仮説（174）


https://qiita.com/kaizen_nagoya/items/fd4515cfb6efa769661d

失敗の記録：文字列処理スクリプトの場合

https://qiita.com/kaizen_nagoya/items/dcf07a892ce32966fbb3


QC検定に落ち「たか」らかける記事。20,000人の方に読んでいただけ「たか」ら書ける記事。「たかたか」分析の勧め。

https://qiita.com/kaizen_nagoya/items/2a371ee8c8f1b78cd5bb


作業診断(process assessment)を成功させる５つの鍵。失敗する５つの罠 。仮説（50）

https://qiita.com/kaizen_nagoya/items/bcdc60db20e8d7081fab


 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong. 

# 文書履歴(document history)
ver. 0.01 初稿　　20230729

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.