OmniAICreator/Qiita-1.07M huggingface dataset:
SpringBoot+Kotlinでログを出力する方法

# はじめに

SpringBootでログを出そうとしたときに結構時間がかかってしまったのでまとめます
実際やり方がわかれば簡単でしたが、ここまで時間がかかったのはなぜなのでしょうか

# やり方

まずは`build.gradle.kt`に以下を追加します

```kotlin:build.gradle.kt
	implementation("org.springframework.boot:spring-boot-starter-aop")
```

`application.properties`に以下を追加

```application.properties
logging.level.root=INFO
```

そして、ログを出したい箇所に以下を追加します

```kotlin
import org.slf4j.LoggerFactory

private val logger = LoggerFactory.getLogger(ToDoController::class.java)

logger.info("ここにログで表示する文章を書く")
```

# おわりに

SpringBootでLoggerFactoryをインポートしたかったのですが、何故か`slf4j`が見つからず、`spring-boot-starter-aop`を入れることでログを表示できるようになりました

# 参考

https://www.amazon.co.jp/Kotlin-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA-%E7%AB%B9%E7%AB%AF-%E5%B0%9A%E4%BA%BA/dp/4297118599/ref=sr_1_3?keywords=kotlin&qid=1673674698&sprefix=kotl%2Caps%2C165&sr=8-3
jetson nanoにjupyterlabをインストールした時のメモ

メモをローカルに保存していましたが、メモがローカル家出したので
こちらへメモを残しておこうと思います。

# jetson nanoのイメージ情報
```
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```

# pyenvのダウンロード、pythonインストール

## pyenv事前準備
```
sudo apt install -y \
build-essential \
libffi-dev \
libssl-dev \
zlib1g-dev \
liblzma-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
libopencv-dev \
tk-dev \
git
```

## pyenvのダウンロード
```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

## 動作確認したバージョンにpyenvを変更
```
cd ~/.pyenv
git checkout v2.0.3
```

## 環境変数の更新
```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
source ~/.bashrc
```

## pythonインストール
```
apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils
pyenv install --list
pyenv install 3.9.6
pyenv global 3.9.6
```

# jupyterlabのインストール、外部ＰＣ接続ありで起動
```
pip install jupyterlab
jupyter lab --ip=0.0.0.0 --no-browser
```

以下のログがでるのでブラウザからアクセス
http://`ＰＣ名`:`ポート番号`/lab?token=`トークン番号`
Twitter botの作成方法

## 初めに
　botと言えばTwitterのbotを表現する事が多いかと思います。この記事では、Twitterのbot作成方法を紹介します。ただし、対象者は非エンジニアです。
　エンジニアの方が参考になる情報は、何もありません。TwitterのBotを作成したいが、作り方がわからない人向けです。


## 対象者
- プログラムに詳しくない人
- 非エンジニア
- 拘りが無く動けばいい人

　そもそも論ですが、10年経過すればそれはもうひと昔です。IT業界も大きく様変わりしました。20年前はサーバーを構築できるエンジニアは、非常にもてはやされていましたが、今現在では、何の価値もありません。
　なぜなら、ブラウザでアクセスして数回クリックするだけで　数百万もするサーバーを１時間単位で利用できる世の中になったからです。
　
　そして、そんな手段でサーバー構築が可能な人は星の数ほどいます。

　プログラムも一緒で、
> 10年前はC#が・・・

とか

> JAVAが・・・

と、もてはやされていたと思いますが、現在はPHPやpython等が幅を利かせています。

この記事ではTwitterのBOT作成方法を紹介しますが、GASを使ったり、サーバーレスで作ったりと高尚な説明はありません。APIキーの申請が・・・　等も悩む必要はありません。

利用者として
> ある物を利用する

たったこれだけの `選択肢` を自ら選ぶ力が大事な時代になっています。※AWS／Azureの発展が良い例です。

## Twitter bot 作成 の ohbottw を使う
Twitterのbot作成方法を説明します。
以下システムにログオンします。
https://tw.ohbot.win/

たったのこれだけです。

これだけで、説明を終わらせると不親切ですので解説を織り交ぜます。

###### ログイン
普段利用しているTwitterのアカウントにパソコンでアクセスした後、
ohbottw URLにアクセスし、右上のログインフォームで簡単な計算を行い、ログイン処理を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/11bef81f-a5e7-22d4-b6a6-1f755b8ac110.png)

計算が正しければ、Twitterの認証画面に飛びますのでアプリに　`アクセス許可` を与えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/8a904bdb-efb4-f993-a439-08eec43f0998.png)

初回のみ利用規約の同意がありますので、同意して先に進みます。
あとは、つぶやき間隔の設定を行い、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/82d613cb-8b99-3bdd-2019-352815695524.png)

つぶやきたい言葉を登録して終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/f7d53f18-8fb8-6bac-9416-6adca18d9013.png)

たったのこれだけで、自動でつぶやくTwitterのbotが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/42a93b4d-e807-7bcf-afcf-6b6f3567f3a0.png)


ここまでの流れで出てこなかったものは以下です。
- 何のプログラム言語を使うか
- どのようなインフラを利用するのか
- APIキーの取得

特に最後のAPIキーの取得等は、非エンジニアの方が嫌がる内容なのではないでしょうか。
無事に取得できたとしても、それらはプログラムに埋め込まなければなりません。
ある程度テンプレートが準備されていても、
>APIキーを指定して・・・・

と言った行為は、非エンジニアにとって、非常に頭を悩ませる行為になると思います。
AWSやAzureの発展は、既に出来上がった機能をパーツとして組み立てるその簡易性です。
※それを採用した会社が多かったという理由も大きいですが・・

Twitterのbot作成も、無理して0から作成するのではなく、ある物を利用するという選択肢を活用してみましょう。

## こういったつぶやきができます。

### スケジュールのツイート
予定を登録して、定期的につぶやく。
出勤・出店予定など
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/8e3821d2-b90b-f4b8-7520-3174b7776d5f.png)

### RSSを用いたblogのツイート
blog等、rssを備えている、例えばwordpressやlivedoorBlogの内容を定期的につぶやく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/935dab52-3b79-f00c-d9f0-28d1b132e696.png)



### Youtubeの動画ツイート
自身が投稿したyoutubeの動画
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111570/790b09a7-ad6d-a695-8639-90d4fa70fbd9.png)
※さる有名な方の動画をお借りしました・・


### その他
そのほか、占いbotやAIを用いた自動返信botなど、様々な機能を有したbotを作成する事が可能です。
これってAWSやAzure等のクラウドサービスを利用する事と同じだと思いませんか？
インフラエンジニアもプログラマも一人で全部できる事に越したことはありませんが、無理して疲弊するよりも、ある物をただ利用するという着想も時には必要な時があります。

https://tw.ohbot.win/
Drupalの操作ログってどこに保存されているのかという話

主には自分の備忘用に。バージョンはDrupal8です。

とある日、Drupalの操作ログってどこかで取れるのか？という質問をもらう。

ワイ「そういえば全然知らんな…」
ワイ「調べてみるか」

# 数分後

ワイ「なるほど、そもそもファイルに保存されるログとDBに保存されるログがあるんか」
ワイ「操作ログは・・・DBの方っぽいな」
ワイ「テーブル名は、`watchdog`テーブルか」
ワイ「画面的には、`ホーム > 管理 > レポート > 最近のログメッセージ`に出力されるみたいやな」
ワイ「ほーん、`新規ユーザ作成`、`コンテンツ追加`、`ユーザログイン`辺りの情報が出るんか」
ワイ「サンキュー、いろんなサイト達^^」

# おわりに
ただ単に書くよりも短文で物語風にした方が自分的には頭に入りやすいので、この形にしました。
基本この形式でいいかな…
Googleプロジェクト管理：OKRを使用してプロジェクトの進捗を評価する

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# Objectives and Key Results (OKRs)

[以前OKRは、目標と評価指標を組み合わせて、測定可能な結果を決定することを学びました][ref1]。OKRを設定することは、プロジェクトチームが共通の成功基準を定義し、伝達し、測定するのに役立つテクニックである。

[ref1]: https://qiita.com/mapami/items/75bb720d9c4a9846b6fb

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/72bf4894-7628-bbf3-76a5-3d1e3b79c767.png" width="600">

# OKRを追跡する

定期的なチェックインを行い、チームと積極的に進捗を確認することで、目標が達成されていることを確認し、問題があればできるだけ早く解決することができます。

プロジェクトのOKRを作成したら、それをチームに伝え、全員がどのように集中し、努力を傾けるべきかを知ることが重要です。OKRは、プロジェクトチームが目標を守り、目標を下回っているものを監視し、プロジェクトの目標達成に向けて継続的なモチベーションを高めるのに役立つのです。

重要な成果には必ずオーナーを決め、誰が何に責任を持つのか、全員がわかるようにします。こうすることで、責任の所在が明確になり、説明責任も高まります。

# OKRをスコアリングする

OKRを測定することは、進捗状況を把握し、共有するための重要な要素です。プロジェクトの状況を把握する近道は、OKRをスコアやグレードで評価することです。

点数や評点は、プロジェクトの成功を完全に評価するものではありませんが、目標達成にどれだけ近づいたかを判断するのに役立つツールです。そして、プロジェクト全体の更新の一環として、OKRのスコアをプロジェクトのステークホルダーやチームメンバーと共有することができます。

OKRは、さまざまな方法でスコアリングすることができます。

- 目標の達成率、特定のマイルストーンの達成度、または1～10までのスケールに基づいてスコアリングすることができます。
- 「トラフィックライト」という採点方法を使うこともできます。赤は何も進展がなかったこと、黄色はある程度進展があったこと、緑は目的を達成したことを意味します。
- 最もシンプルな採点方法は、「YES/NO」方式で、「YES」は目的を達成したこと、「NO」は達成できなかったことを意味します。
- より高度なスコアリング・アプローチは、キーとなる結果をスケールで評価することです。この方法では、「6つの新機能を立ち上げる」というキー・リザルトがあったとして、3つの新機能しか立ち上げられなかった場合、OKRは0.5と評価されるかもしれません。一般的に、KRが目的達成に役立った場合はOKRは高得点になり、役立たなかった場合はOKRは低得点になるはずです。

# GoogleでのOKRのスコアリング

Googleでは、OKRは通常0.0から1.0までのスケールで評価され、1.0は目的が完全に達成されたことを意味する。個々のキー・リザルトが評定され、その評定が平均化されて、そのOKRのスコアが決定される。

Googleの0.0～1.0スケールでは、野心的なOKRを設定し、すべてのOKRの平均が少なくとも ***<font color="MediumBlue">0.6～0.7</font>*** を達成することを目指すことが期待されます。達成率で評価されるOKRの場合、スイートスポットは60～70％の範囲です。これより低い得点は、チームが本来達成できるはずのものを達成できていないことを意味する場合があります。これより高い得点は、意欲的な目標が十分に高く設定されていないことを意味します。

<img src="
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/bf5b321a-a061-71ff-ce37-bdcaf591dfda.png" width="650">

# チェックポイントをスケジュールする

プロジェクトのOKRの状況を、定期的にチームやシニア・マネージャーに伝えることが重要です。たとえば、OKRの進捗について毎月チェックインすることで、個人とチームの両方が自分の位置を把握することができます。通常、四半期末には、各OKRを採点し、チームが目標達成にどれだけ貢献したかを評価します。
MATLABからマウスを操作する

## １．はじめに
だいぶ前に、EXCEL VBAを用いてマウスを動かす記事を見かけました。「数分間に一度、マウスをちょっとだけ動かす」というものですが、何に使うのでしょうか（と書いてみた）。
本記事では、MATLABを用いてマウスを操作する方法についてまとめました。

## ２．MATLABからマウスの操作はできない
いきなり書いてしまいましたが、MATLABからマウスを操作することはできないようです。
それどころか、特殊な条件（Figureの上）でなければ、マウスの位置情報も得ることはできないということで。
ですので、ここではJavaのお世話になり、この問題を解決することにします。

## ３．マウスをちょっとだけ動かす方法
JavaにはRobotクラスというものがあって、これを使ってマウスを動かします。
スクリプトは以下のようになります。

```matlab
% 関係するJavaのクラスをインポートする
import java.awt.Robot;
import java.awt.MouseInfo;
import java.awt.event.*;

robot = Robot();% Robotクラスのインスタンス

pause(5);% 単なる時間かせぎ

a = MouseInfo.getPointerInfo();
b = a.getLocation();% マウス位置を得る
x =  b.getX();%　マウスのX座標を取得
y =  b.getY();%　マウスのY座標を取得

for t=1:10
    robot.mouseMove(x+100,y);%　マウス移動
    pause(0.1);
    robot.mouseMove(x,y);%　マウスを戻す
    pause(1);
end
```
マウス移動はスクリーン座標をもとに指定するので、「現在位置からどれだけ動かす」というようにするため、マウスの現在座標を取得し、それに移動量を加えて制御します。
マウスの位置を動かすのはmouseMoveというメソッドを使っています。

## ４．マウスで描画する
マウスの位置を動かすmouseMove、マウスのボタンを押すmousePress、マウスのボタンを離すmouseRelease を組み合わせると描画ができます。Paintアプリの上で描画するスクリプトの例を示します。

```matlab
% 関係するJavaのクラスをインポートする
import java.awt.Robot;
import java.awt.MouseInfo;
import java.awt.event.*;

robot = Robot();% Robotクラスのインスタンス

pause(5);%単なる時間かせぎ

% 描画する四角形の座標
x=[100 200 200 100 100];
y=[300 300 200 200 300];

% 始点にマウスを移動
robot.mouseMove(x(1),y(1));

% マウスの左ボタンを押す
robot.mousePress(InputEvent.BUTTON1_MASK);

for t=2:5
    pause(1);
    % マウスを動かす
    robot.mouseMove(x(t),y(t));
end

% マウスの左ボタンを離す
robot.mouseRelease(InputEvent.BUTTON1_MASK);
```
これで、下記のように四角形が描画できます。

![MouseDraw.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/51b8941a-e7fe-ae61-97cd-460aed4d655c.gif)


## ５．マウスのスクロール
マウスをホイールでスクロールさせるメソッドmouseWheel も使えます。スクリプトの例を示します。

```matlab
% 関係するJavaのクラスをインポートする
import java.awt.Robot;
import java.awt.MouseInfo;
import java.awt.event.*;

robot = Robot();% Robotクラスのインスタンス

pause(5);% 単なる時間かせぎ

%ペイントのウインドウ上にマウスを移動する
robot.mouseMove(100,100);

for t=1:3
    % スクロール（プラスがロールアップ）
    robot.mouseWheel(1);
    pause(0.5);
end

for t=1:3
    % スクロール（ロールダウン）
    robot.mouseWheel(-1);
    pause(0.5);
end
```

これでスクロールができるようになります。

![MouseScrool.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434947/de46c8ec-c9af-9bb5-6c53-8151279bcc1b.gif)


## ６．マウスじゃなくて、キーボードを制御する方法
キーボードを操作する方法については、@HppyCtrlEngnrng さんの記事『[MATLABによるChromeの恐竜のアレ](https://qiita.com/HppyCtrlEngnrng/items/b66503df98792c469c3b)』をご参照ください。

以上です。
Pythonで日本地図を表示し、マーキングする方法【Folium】

<iframe width="560" height="315" src="https://www.youtube.com/embed/eFnB0QFAwRk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

### ライブラリをインストール
```
pip install folium
```
### 地図を表示
folium.Map()を使って地図のインスタンスを作成します。引数に地図の中心の位置(latitude, longitude)を指定します。日本の中心位置は、緯度35度、経度139度です。
```python
import folium
m = folium.Map(location=[35, 139], zoom_start=5)
m
```
![](https://storage.googleapis.com/zenn-user-upload/7b03f87d36d1-20230114.png)

### マーキングする
地図にマーカーを追加します。 add_child()メソッドを使って、Markerクラスのインスタンスを地図に追加します。
```python
folium.Marker(location=[35,139],popup='Tokyo').add_to(m)
m
```
![](https://storage.googleapis.com/zenn-user-upload/43fbf51ec48c-20230114.png)

### サークルマーカーを描く
地図にサークルマーカーを追加します。 add_child()メソッドを使って、CircleMarkerクラスのインスタンスを地図に追加します。
```python
folium.CircleMarker(
    location=[34.6937, 135.5022],
    radius=10,
    color='#ff0000',
    fill_color='#0000ff'
).add_to(m)
m
```
![](https://storage.googleapis.com/zenn-user-upload/31af49f2f4c1-20230114.png)

### 画像保存
地図をhtmlファイルとして保存する場合は、save()メソッドを使用します。
```
m.save('map.html')
```
【base shellscript】競技プログラミングでの値取得 01

# 入力値
#### ・パターン１（文字列）

##### 入力
入力例1
abcdefg

```shell
#!/bin/bash

# 取得方法（read 変数）で取得できる。
read s
# 出力
echo $s
```

##### 出力結果
abcdefg

#### ・パターン２（数値）※パターン１と同じ

#### ・パターン３（数値）※文字列も恐らく同じ

##### 入力
入力例1
A B

```shell
#!/bin/bash

# 取得方法（read 変数）で取得できる。
read y z
# 出力
echo $y
echo $z
```
##### 出力結果
AB

#### ・パターン４（数値 N + N行）N行を配列で受け取る

##### 入力
入力例1
4
200
500
555
124

```shell
#!/bin/bash

# 頭の 4 を取得
read N
# 配列で受け取り
A=(`tr ' ' '\n'`)

# 配列要素　全出力
# echo ${A[@]}
```
##### 出力結果
200
500
555
124

### あとがき
・追記していければと思います。何かの役に立てれば幸いです。ごっつあんです！
flutter_hooksで配列に値を加えて変更を画面に反映する方法

# この記事を書こうと思ったわけ
```sample.dart
final list = useState(<int>[]);
// ... 省略
onPressed: () => list.value.add(0);
```
と記述しても変更が反映されませんでした。
# 結論

```sample.dart
final list = useState(<int>[]);
// ... 省略
onPressed: () =>list.value = List.from(list.value)..add(0);
```

成功しました
基本情報処理（学習用）＊

●ネットワーク・・LANとWANの区分がある
LAN（local）・・小さいレベルのネットワーク
WAN・・大きいレベルのネットワーク

●LANの接続方式
１　スター型・・ハブを中心として放射状に各コンピュータを接続
２　バス型・・一本の期間となるケーブルに各コンピュータを接続
３　リング型・・リング上に各コンピュータを接続・トークンリングが代表的（トークンパッシング方式が一般的）

●LANの規格はイーサネットが最も普及している・・アクセス制御でCSMA/CD方式を用いる（一本のケーブルで複数のコンピューターで共有）

・ユニキャスト・・メインコンピューターからネットワークに接続している一人に情報送る
・マルチキャスト・・複数人
・ブロードキャスト・・全員
・エニーキャスト・・誰でもいいから一人にとって欲しい状況に使う

・パケット・・送受信のために分割されたデータ。細かく分けることで、ネットワークを複数のコンピュータで同時に使えるようになる
　　　　　　　　　　　　　　　　分けないと回線が混み合ってしまい使えなくなる

・パケット交換方式・情報をいくつかのブロックに分割し、各ブロックに制御情報を付加して送信する方式

・CSMA／CD方式・・一本のケーブルで複数のコンピュータで通信ができる。基本的にケーブル空いてる時にパケットを送るが、
もし複数のパケットが流れ衝突した場合、再送処理を行う
・トークンパッシング方式・トークンに情報をつけて（トークンに対してパケットをつける）ネットワーク内で情報を回す
フリートークン・・平常時に流れているトークン
ビジートークン・・データのくっついたトークン

●クライアントサーバーシステム・・分散処理と集中処理のいいとことをとったシステム。集中的に管理した方がいい資源を提供するサーバと必要に応じてリクエストを投げるクライアントというに種類のコンピュータで処理を行う。

●プロトコル・・約束事。共通の言語、ルール＝TCP／IP（現在のデファクトスタンダード）

・OSI基本参照モデル・・インターネットにおける通信モデルのスタンダード。ケーブルのつなぎ方からサービスまでレイヤーごとに規格を定めている。７層に分かれている。＊どの相が何をしているのか覚えておく必要がある
現在は「TCP/IP」というプロトコルが使われている。

・TCP/IP・・通信データをパケットに分けて通信路へ流す
・ネットワークの伝送速度・・伝送速度＝データ量/回線速度
・Openflow・・SDNを実現するための技術。


●アドレスにはMACアドレスとIPアドレスの二つに大別される
MACアドレス・・製造される時に一意のアドレスがつけられる。しかし階層性がないのでインターネットを作り出せない、データリンク層が対象。形式が統一されていない。目的は同一データリンク内での識別
ex)日本で作られたということはわかるが、日本のどのネットワークにつながっているかなどわからない
この時に使うのがIPアドレス
IPアドレス・・階層性がある。一つの端末に対して複数設定できる。ネットワーク層が対象。形式も統一されている。ルーティングに用いる

・NAT,IPマスカレード・・プライベートIPアドレスをグローバルIPアドレスを変換する技術

・DHCP・・IPアドレスを自動で振り分けるプロトコル

・DNS・・ドメインとIPを関連づけて管理する

●
ConoHaでWireGuard中継サーバーをつくる

# ConoHaでWireGuard中継サーバーを作った話

もう何番煎じかわかりませんが、備忘録として…

## 構成

PC -- 中継サーバー(ConoHa) -- 踏み台(RasPi) -- 目的のサーバー

- PCはWindows
- 中継サーバーはConoHa VPS上のUbuntu 22.04
- RasPiを踏み台にして目的のサーバーにアクセスしたい
- PCからは透過的に目的のサーバーのIPアドレスを指定してアクセスする
- VPSは管理用に必要最低限のアクセスのみ許可するよう基盤側のセキュリティグループを設定する

## 手順

- 前準備
    - ConoHaのIPv6を有効にする(必要に応じて)
    - ConoHaのセキュリティグループを設定してSSH接続可能なIPアドレスを制限する
- Wireguardをインストールして設定する
    - サーバー(ConoHa)
    - クライアント(PC)
    - 踏み台(RasPi)
- ConoHaのセキュリティグループにWireguardの待ち受けポートを追加する
    - API経由でカスタマイズする(ConoHa Netが便利)
- Wireguardで末端同士が通信できるようにする
  - sysctl.confを修正してフォワードを有効にしないとクライアント間の通信ができない
  - さらにufwでrouteを追加し、TCP/UDPのフォワードを許可する
      - sudo ufw route allow in on wg0 out on wg0
      - iptablesのFORWARDの追加に相当
      - ICMPはデフォルトで許可されているのでpingは通る(これではまった)
- 踏み台の向こう側のネットワークと通信できるようにRasPiにルーティング設定をする
    - iptabelsにNATとフォワードの許可設定をする
    - FORWARDに追加する許可エントリは-iと-oの両方が必要
- RasPiの電源を引っこ抜いても壊れないようにシステムをRAMディスク化する
    - raspi-config nonint enable_overlayfs
    - *ubuntuの場合*
        - overlayrootをインストール
        - /etc/overlayroot.local.confを作成し、overlayroot="tmpfs"を記述
- なにかあったときにSDカードを再作成できるようにイメージを作成する
    - **上記手順を行う前に**、初回起動時にパーティションを拡張しないようにbootフォルダ内の起動時のコマンドを変更しておく 
    - https://qiita.com/yamato225/items/e42e7e395a99d9dabcbd


## 参照URL

全体像

https://qiita.com/ryosuk/items/906c0a68dfcefa4457ec

IPv6設定
20230316追記
Ubuntu22.04で改めて実行したところ、
下記サイトのRAを有効にする方法ではIPv6アドレスが割り当てられませんでした。
手動でnetplanにアドレスを書いてあげる必要がありました。
https://world.203.jp/blog/post/1175 (RAで対応。20230316現在IPアドレス設定できず)
↓

https://zenn.dev/book000/articles/conohavps-cloudflare-ipv6#vps-%E3%81%AB-ipv6-%E3%81%AE%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%8B

セキュリティグループの設定用ツール

https://developers.gmo.jp/10042/

https://github.com/hironobu-s/conoha-net


ルーティング

https://blog.n-z.jp/blog/2020-04-29-wireguard-route-to-private-net.html

https://qiita.com/onodes/items/6c62bd3f1a4d2350f8e8

https://zenn.dev/hiroe_orz17/scraps/37c543e8cfda99


Overlayfs

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0568

https://qiita.com/ma2shita/items/45818f0872472ecacac1


カスタムイメージ化

https://qiita.com/yamato225/items/e42e7e395a99d9dabcbd
【Docker】Pythonで特定のコンテナを起動(run)する方法

## 前置き
Python上で作成済みのコンテナを起動したい時の方法について、ざっくり説明していきます！

## 方法
Pythonではライブラリを用いて、作成済みのコンテナを起動することができます。

まず、ライブラリをインストールしておきましょう

```:cmd
>>pip install docker
```
　
次にコンテナの名前を調べましょう
下記の様に入力すると起動中のコンテナの情報を得られます。
今回必要なのは最後の「NAMES」です。下記の場合は「piyopiyo」ですね。

※出力情報は適当に入力してあります
```:cmd
>>docker ps
CONTAINER ID   IMAGE     COMMAND    CREATED      STATUS    PORTS    NAMES
test12312dfs   hoge/tmp  "bin/sh…"  2 hours ago  up 1 sec  12323    piyopiyo
```


確認を終えたら、次は例です!
「docker_container_name」に入力した名前のコンテナを起動できます。
```Python:example.py
import docker
import sys

docker_container_name = "ここに起動させたいコンテナ名"

client = docker.from_env()
# 起動済みコンテナたちを取得
Started = client.containers.list()
# 起動させたいコンテナが起動しているか確認
for container in Started:
    if container.name == docker_container_name:
        print("起動済み")
        # プログラム終了
        sys.exit()

# 起動していない場合
client.containers.get(docker_container_name).start()
```

## まとめ
他の記事では、コンテナを作り直すものばかりだったので今回記事にしてみました。
どなたかの役に立てば幸いです！
間違い等ありましたらコメントいただけますと幸いです。
【emacsユーザー向け】macのiTerm2上で⌘ + wでウインドウを閉じないようにする方法

全国のemacsユーザーの皆さん、macでemacs使っていますか？

ターミナルでemacsを使用する場合も多いと思うんですが、`⌘ (Command)`キーをMetaキーをしているときに、`⌘` + `w` でウインドウが閉じてしまい、困ったとはないでしょうか？

私もずっと困っていたんですが、iTerm2での設定方法がわかったので、共有します。

1. メニューから`Settings`を選ぶ。
1. `Keys`を選択し、`Key Bindings`が表示された状態にする。
1. `+`ボタンを押し、出た画面の`Key Shortcut`で`⌘` + `w`を押す。
1. `Action`を`Send Escape Sequence`を選択する。
1. `Esc+`のフィールドに`w`と入力する。
1. `OK`ボタンを押す。

以上です！
IsarではEmbbed Objectの名前をカスタマイズできない

# はじめに

[Isar](https://pub.dev/packages/isar)はflutterのデータベースパッケージのひとつです。
[Hive](https://pub.dev/packages/hive)の後継にあたり、処理速度の速さや豊富なAPIに強みがあります。

# Emmbed Objectとは

Isarコレクションは、bool,String等の基本的な型のほかに、ネストされたオブジェクトをフィールドに持つことができます。
例えば以下のようなものです。

```dart
@collection
class Email {
  Id? id;

  String? title;

  Recepient? recipient;
}

@embedded
class Recepient {
  String? name;

  String? address;
}
```

# Nameアノテーションとは

Isarコレクションは、Nameアノテーションを用いてコレクション・フィールドの名前を設定することができます。
例えば以下のようなものです。
```dart
@collection
@Name("SpecialEmail")
class Email {
  Id? id;

  String? title;
}
```

# Emmbed ObjectにNameアノテーションは使えない

さて、Emmbed ObjectにNameアノテーションをつけるとどうなるでしょうか？
コード生成には成功しますが、新規のIsarインスタンスを作成した際に、以下のようなエラーが発生します。

> IsarError: SchemaError: Target collection does not exist.

このメッセージからはEmmbed Objectが理由でエラーが発生していること読み取れないため、注意が必要です。

# 参考
https://github.com/isar/isar/discussions/763
エンジニアは伝えるのが下手な人が多いよね、という話。

まあ本当はエンジニアに限った話でもないのだけど、非エンジニアと語彙が違い過ぎるせいで余計に強調されてそう思われてるし、そう思わせてしまう。

# リアルワールドには通信プロトコルは実在しない
我々の世界にはありますよね、通信のプロトコルが。
これを守ればちゃんと情報が伝わりますという決まりが。

これ、コンピューターの外のリアルワールドには存在しないですよね?


# お前だけのネイティヴコードは、そいつだけのネイティヴコードしかしらない誰かに伝わらない
リアルワールドの人間は、全員別のネイティヴコードで動いています。
似たようなアーキテクチャの人はいても完全に同じ命令セットの人は誰一人いない。

それなのに、エンジニアという生き物は本人のネイティヴコードでの最小限だけを伝えて、それでちゃんと相手に伝えた気になってます。
そんな事は思っていないという感情的反論はあるでしょうが、実際には『これで理解しないのはお前がいけない』と言っている状態と同じです。

# じゃあどうするのか?
ここが本題です。じゃあどうするのか?

スタート地点としては『お前だけのネイティヴコードでの最小限は相手には多分伝わらない』を認識していろいろやる事だと思います。
その具体的な形の一例として実社会で見られる例としては、自分が伝える側なら
『いま私がお伝えした事を、あなたの言葉で説明してみて頂けますか?』
のような確認をする事だし、自分が受け取る側なら『今のお話は、これこれこういう事で宜しかったでしょうか?』と自分の解釈を確認してみる事だったりする。

『宜しかったでしょうか』はバイト君敬語っぽいが、この文脈なら正しく遜ってるというか、違うかもしれないので違うなら指摘して下さいという意味で間違っていない感じがする。

あとこの応酬をチャットやメールで記録に残すと、これはあの不毛且つどこでも起こる「言った言わない論争」にも役に立つ。
口頭ベースで物事を済ませたい人種は多いようだが、この部分はテキストベースが明確に口頭ベースより優れている部分だと個人的には思っている。
Mac Safariのパスワードでinput(type="password" style="text-align: center;")のカーソル位置がずれた時の対処方法

# はじめに
`style="text-align: center;"`のinputを複数並べた際、MacのSafariでtype="password"のinputだけカーソルが少し左にずれていることに気づきました。
※ChromeやiOSでは起きませんでした。

修正方法を調べたので、備忘録として残します。


パスワードのボタン自体を非表示にする方法と、スタイルを調整する方法の2種類を試しました。


## 対処方法１：パスワードのボタン自体を非表示にする
- ボタンを非表示、ポインターイベントなどを無効化します。
```scss
  .input::-webkit-credentials-auto-fill-button {
    visibility: hidden;
    display: none !important;
    pointer-events: none; 
    position: absolute; // フォーカス時、キーアイコン要素分中央からずれるため指定しています。
    right: 0;
  }

```

## 対処方法２：カーソルの位置がずれないようにスタイルを調整する
- positionを指定して、ボタンの位置を調整します。
```scss
 /* inputを囲むdiv要素に指定 */
  .input-outer-wrapper {
    position: relative;
  }

  .input::-webkit-credentials-auto-fill-button {
    position: absolute;
    right: 0;
  }
```

### サンプル
<p class="codepen" data-height="500" data-default-tab="css,result" data-slug-hash="jOpwrdm" data-user="h-matcha" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/h-matcha/pen/jOpwrdm">
  input-hidden-autofill-btn-sample</a> by h-matcha (<a href="https://codepen.io/h-matcha">@h-matcha</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


### さいごに
果たしてこれが正解なのかは分かりません。
もっとスマートで良い方法があれば、コメントなどご教示いただけるとうれしいです。
作業ログをマインドマップからマークダウンに移行した

## 作業ログとは
作業内容を随時書き残して、出来上がったログのこと。
![スクリーンショット 2023-01-14 11.10.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/2211dd70-7a57-b741-74e6-d68cf261540b.png)


### メリット
- 記憶しなくていいので、頭の負荷が減る
    - 記録にも残るので、後で見返せる
- ログに起こす際に言語化するので、思考が明確になる

### デメリット
- 短期的には作業時間が増える
    - 記憶不要、言語化による損益分岐点を超えると時間を回収できると思う
- 人によっては、めんどくさくてやってられない人もいるかも

## マインドマップで取る作業ログ

- 直感的に操作できる
- グラフィカルで構造を把握しやすい
- 自分の場合は、mindnodeというアプリを使っていた
- タスク管理もできるので、すべての作業をマインドマップ起点で行っていた

## マインドマップ作業ログの課題

- ノードの移動はカーソルキーを使うことになる
- 距離のあるノードを移動しようとすると、マウスを使うことになる
- 記号が一部変になる
    - ```'```→```‘```
- ファイル構成が独特
    - googleドライブにアップすると、ファイルが壊れたりした
    - CUIから操作しづらかった

## マークダウンで取る作業ログ
![スクリーンショット 2023-01-14 11.10.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/194eabc4-f45a-67c1-3fb2-d2de8a8f28fa.png)
- VImで操作できるので、キーボードで完結する
    - マインドマップのように、ノート間の移動コストが低いので、より思考と記録が一体化する
- ファイル構成がシンプル
    - 移植しやすい
    - CUIからも操作しやすい

## おわりに

タスク管理用のチェックボックス（- [ ]）運用、 インデントをどこまで整理しながら作業するかなど、また微調整が必要な部分もありますが、今のところいい感じです。
paiza.ioでelixir その167

# 概要
paiza.ioでelixirやってみた。
データ永続化どうすんの。

# 参考にしたページ

https://qiita.com/t-yamanashi/items/5a4e260a2a089f7d451d


# サンプルコード

```


x = %{first: 1, last: 10, step: 2}
y = :erlang.term_to_binary(x)
File.write("data.txt", y)

{_, z} = File.read("data.txt")
w = :erlang.binary_to_term(z)
IO.inspect w



```

# 実行結果

```
%{first: 1, last: 10, step: 2}
```

# 成果物

https://paiza.io/projects/rwBkdtyhd_S5b0JvimOeeg


以上。
aptとyumの違い

## 背景

`telnet` コマンドを実行する際`command not found: telnet`と怒られました。

`telnet`をインストールするために`yum`が必要だと思い、`yum install`を実行したら`yum: command not found`と怒られました。

`yumの`変わりに`apt`をインストールするため、`sudo apt update`&`sudo apt install telnet`でインストールできましたが、**「yum？apt？なんだっけ？」** となったので備忘録として投稿します。

## どちらにも共通しているもの

どちらもLinuxでソフトウェアの導入、管理、削除に用いられるパッケージ管理システム。

ファイルダウンロード、ソースコードのコンパイル、実行可能ファイルの作成、配置を全て行ってくれる。

コマンドを実行した際、気を利かせて依存関係を確認し、必要なものを一緒にインストールしてくれる。

違いは、ディストリビュージョンやコマンドの使い方。

## apt

`**Debian`系ディストリビューションで使われるパッケージ管理システム。**

元々Debian系では`dpkg`というパッケージ管理システムがありましたが、依存関係を解消し、より使いやすくするためにaptが登場しました。

コマンドは`apt`

参考：[aptコマンドチートシート](https://qiita.com/SUZUKI_Masaya/items/1fd9489e631c78e5b007)
参考：[重要なのに忘れがちなapt関係のコマンドのメモ](https://qiita.com/karaage0703/items/f01db1cf49b151022b7c)

## yum

**パッケージ管理に`RPM（Red Hat Package Manager）`を採用しているLinux ディストリビューションで使われるパッケージ管理システム。**

ちょっとややこしいように聞こえますが、つまり、元々あったパッケージ管理システムである`RPM`をより使いやすくしたのが`yum`です（私はそう理解しています）。

RPMコマンドでパッケージをインストールすることはできますが、依存関係を解消することはできないため（厳密にはRPMも依存関係を解消する仕組みは存在しますが）、yumを使うことで依存関係を解消します。

コマンドは`yum`

参考：[yumコマンド一覧](https://atmarkit.itmedia.co.jp/ait/articles/1608/29/news019.html)

自身の環境がDebian系か、Redhat系かによって、使うプログラムが異なります。
Error message "error:0308010C:digital envelope routines::unsupported" の解決方法

```
$ bundle exec bin/webpack-dev-server
```
上記のコマンドを実行時に
Error message "error:0308010C:digital envelope routines::unsupported"エラーが表示

# 解決方法
```
$ export NODE_OPTIONS=--openssl-legacy-provider
```

上記のコマンドで解決
Outlookで曜日の背景色を変えて見やすくする

Outlookで曜日の背景色を変えて見やすくする

Outlook使ってますか？
お仕事の友としてOutlookを使っている方も多いと思うのですが、Outlookのカレンダーって土日に色がついてないので見づらいと思っている方も多いんじゃないでしょうか？

そこでOutlookのカレンダーを見やすくするための、土日に色を付ける方法を教えちゃいます。

画面の説明ではOutlook2013を使ってますが、Outlook2019などでも使えますよ。

★まず、どんな風になるか？

フツーのOutlookのカレンダー画面
![Clipboard11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/4d13d760-0e13-d256-31a4-ed6babef965b.jpeg)
土日に色が付いてないのでぱっと見何曜日なのかわかりにくい。


今回紹介の方法を使うと…
土日に色が付いて周単位の予定がわかりやすくなります。
![20230114101109.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/8a18001d-cae9-fbb4-20b1-4921e8082ac2.jpeg)
こんな感じにできます。


【やり方】
土曜日に色を付ける例として紹介します。
まず、Outlookのカレンダー画面を表示します。
そこで適当に土曜日のマスを選んで、右クリック。
定期的な予定を選択します。
![20230114100814.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/00154b15-c110-c45b-3e57-bb0523e5fc25.jpeg)


そして、開始時間を0:00、期間を１日、パターンの設定を「週」、間隔を「土曜日にチェック」して「ok」で登録します。
![20230114100829.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/0acae0f4-8bcf-3dfc-21f9-47f95b019692.jpeg)


そこで新しく作った予定に「タグ」を設定します。
![20230114100845.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/7ad27406-e15e-faca-4ad9-c971eee48df5.jpeg)


このとき、新しいタグの作成で
名前「土曜」、色「青色」というのを作っておきます。
![Clipboard04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/0c397b9d-8819-aa0c-2d33-0b08af8bda1f.jpeg)


そして、新しく作った「土曜」のタグを選択します。
![20230114100846.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/03796dd7-ab13-8095-1de1-34c0fb45c89e.jpeg)


ここで、定期的な予定を保存して閉じます。
![20230114100914.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/bfed59a1-c883-6b96-1377-318dcbfef194.jpeg)


そうすると
Outlookのカレンダー画面で土曜日に青色の予定が入ったと思います。
![20230114100915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/871c2c84-a10f-761c-6d79-9f169e5ae34b.jpeg)



そしたら、どれでもいいので土曜日の予定を選んで
「定期的な予定」タブから、「公開方法」の「取込中」を選びます。
たしか、Outlook2019だと文言が変わってたはず…
![20230114101009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/63595bd1-c933-075d-55f0-000c5f657306.jpeg)


すると、カレンダーの土曜の背景にタブで設定した色の背景が付きます。
これで土曜に色が付きます。
![20230114101011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/7113cbf3-23ca-1e0a-4edc-3518ac09c125.jpeg)



同じ手順で、日曜にも色を付けることが可能です。
![20230114101109.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215704/efba683d-06a0-4971-e3c7-7267770fdb33.jpeg)



これでOutlookのカレンダーが見やすくなりますね！
AWS DataSyncとAzure File Sync 比較 ～Azure File Sync動作確認編～

AWS DataSync(以下、DataSync)と Azure File Sync(以下、File Sync)シリーズの7本目の記事です。
1本目は記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～共通点と相違点～](https://qiita.com/hidekko/items/9610ef551999f6ea1f37)
2本目は記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～前提条件定義編～](https://qiita.com/hidekko/items/45eab57f6c6088eb1607)
3本目は記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～AWS DataSync構築事前準備編～](https://qiita.com/hidekko/items/8e7a3fb6494462926597)
4本目の記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～AWS DataSync構築編～](https://qiita.com/hidekko/items/3c042c3ef159bd8e28fd)
5本目の記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～AWS DataSync動作確認編～](https://qiita.com/hidekko/items/8132d024fc81c7d8ab10)
6本目の記事はこちら
[AWS DataSyncとAzure File Sync 比較 ～Azure File Sync構築編～](https://qiita.com/hidekko/items/05cfe4240b33022611a5)

本記事ではFile Syncの動作確認を行います。

# 動作確認
動作確認を行いますが、その前に念のためDataSyncとFile Syncの動作確認環境の違いを構成図にします。
後程DataSyncの動作確認の記事にも構成図を掲載します。

## 構成図
以下の構成で動作確認を行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/0321ac24-6fde-4b03-5a4e-39d40ecf37af.png)
<font color="Blue">青線で同期</font>を行い、<font color="Red">権限確認に必要な新ファイルサーバーへの同期処理は赤線</font>で行っています。
Azure Filesを既存のファイルサーバーにストレージアカウントのアクセスキーでマウントすることもできるのですが、アクセスキーでのマウントはNTFSアクセス権が効かなくなってしまいますのでもう1台ファイルサーバーを立ててそこにAzure File Syncで接続して確認します。
今回は検証なのでオンプレのKVM上にVMを立てて検証していますが、AzureとVPNを張っていればAzure上にVMを立ててもいいです。
というかAzure上にVM立ててるとAzureへのファイルサーバーのLift＆Shiftが完全な形で検証できますね。
この動作確認の構成を応用すると、オンプレミスのファイルサーバーのリプレースや、多拠点間でのデータ同期とアクセス速度向上を行うキャッシュサーバーの構成が構築できます。

## 同期実行
File SyncはDataSyncと違って同期グループ設定後に即時同期かつ常時同期なので、わざわざ同期を実行するという操作は不要です。

## 同期データ確認
同期実行の操作が不要なのでデータ確認からです。
[前回の記事](https://qiita.com/hidekko/items/05cfe4240b33022611a5)の通りに同期グループにサーバエンドポイントとして新しいファイルサーバーを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/6f38f015-1fa2-60a6-f5d9-4fb6a34e3e56.png)
何もないディレクトリに対して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/e00b3706-543b-f5b4-6ca5-19081f594417.png)
無事データ同期が行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/3ccddfbe-6840-b983-64de-7076564bbd13.png)

## NTFSアクセス権確認
A事業部に所属するdomain.user01でアクセスすると無事データを開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/a00b8dca-0543-e29e-cf0b-0f214143ae68.png)
B事業部に所属するdomain.user11でアクセスすると、事業部フォルダすら開けません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/b5479853-f0fe-20fa-4915-150609b38265.png)

<font color="Red">**Microsoftさん、完璧ですね！**</font>
NTFSアクセス権とかActive DirectoryとかはMicrosoftさんのお家芸なんで当たり前と言えば当たり前かもしれませんが、それでも思い通りに動作すると嬉しいですね。

今回はここまで。
Supabaseに作った郵便番号テーブルを参照する（Vue、Nuxt）

下記の記事では、Supabaseに作成したデータベースに日本郵政のホームページから郵便番号データをダウンロードして、登録するところまで行いました。

https://qiita.com/adchan/items/7b11091de8612dfb623b

Web画面からそれを使うアプリケーションを作成してみます。

## アプリケーションの雛形

アプリケーションの雛形は、Supabaseのチュートリアルにある、Nuxt3のものを使っています。
下記のページの内容を一通り実施します。

https://supabase.com/docs/guides/getting-started/tutorials/with-nuxt-3

## 郵便番号テーブル定義

RSLをONにして、SELECTは誰でもできるようにしています。

```sql

CREATE TABLE IF NOT EXISTS postcode(
  id serial  primary key,
  postcode varchar(8),
  ken varchar(6),
  address1 varchar(50),
  address2 varchar(50),
  updated_at timestamp with time zone not null default now()
);

create index on postcode (postcode);

alter table postcode
  enable row level security;

create policy "Users can select postcode." on postcode
  for select using (true);
```

## 郵便番号テーブルへのデータ登録

下記の記事です
https://qiita.com/adchan/items/7b11091de8612dfb623b


## Webアプリケーションの実装

```vue
<script setup>
const supabase = useSupabaseClient()
const postcode = ref('')
const address = ref('')

async function searchAddress() {
    const { data, error } = await supabase
        .from('postcode')
        .select(`ken, address1, address2`)
        .eq('postcode', postcode.value)
        .single()
    if (error) {
        alert("住所情報が取得できません")
        return
    }
    if (data) {
        address.value = `${data.ken}${data.address1}${data.address2}`
    }
}

</script>
<template>
        <div>
            <label for="postcode">PostCode</label>
            <input id="postcode" type="text" v-model="postcode" />
            <button @click="searchAddress" :disabled="postcode === ''">住所変換</button>
        </div>
        <div>
            <label for="address">住所</label>
            <input id="address" type="text" v-model="address" />
        </div>
</template>
```
実践で使うには、２つ以上の住所が返ってくるケースなど考える必要があります。

APIの実装の手間が無く、非常に短時間に実装できました。
RDBをやっていた人にとっては、FirebaseのFirestoreよりは、とっつきやすいと思います。

## SupabaseClientでSELECT時のエラーコードについて

SELECT時にデータが無い時は、下記のようなJSONが返ってきます。
code?って思ったのですが、下記ページのpostgrestのコードのようです。

```JSON
{
code: "PGRST116",
details: "Results contain 0 rows, application/vnd.pgrst.object+json requires 1 row",
hint: null,
message: "JSON object requested, multiple (or no) rows returned"
}
```

https://postgrest.org/en/stable/errors.html#group-1-api-request
privateメソッドとは何か、どういう時に使うのか

## Privateメソッドとは何か
クラス外からは呼び出せず、クラス内でのみ使えるメソッドのこと。
（インスタンスを作ってprivateメソッドを直接呼び出すということができない）

```HogeHoge.rb
# encoding: UTF-8

class HogeHoge
  def hoge_method
    p("ほげほげ")
  end

  def call_private_hoge_method
    p("プライベートな情報を取得する前の事前作業")
    p(".........")    
    private_hoge_method
  end


  private
  def private_hoge_method
    p("プライベートな情報を取得！")
  end
end


hogehoge = HogeHoge.new
hogehoge.hoge_method
hogehoge.call_private_hoge_method
hogehoge.private_hoge_method  # 直接呼び出すとエラーになる

```

```
ruby hogehoge.rb

"ほげほげ"
"プライベートな情報を取得する前の事前作業"
"........."
"プライベートな情報を取得！"
Traceback (most recent call last):
hoge.rb:25:in `<main>': private method `private_hoge_method' called for #<HogeHoge:0x00007fadd6900688> (NoMethodError)
```

## privateメソッドはどういう時に使うのか？
適切な順番で呼び出す必要があるメソッドだったり、
外から呼び出されると内部状態に問題が生じる場合に設定する時にprivateメソッドを使う。
下記の記事がとても参考になった。

http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000129.html

## 余談
Railsでprivateメソッドを定義する時は、
モデルではvalidateとかコールバック関数、
コントローラーではストロングパラメータを使う時
定義している印象がある。

## 参考文献：
https://media.wemotion.co.jp/class-diary/%E3%80%90%E4%BB%8A%E6%97%A5%E3%81%AEqa%E3%80%91private%E3%81%AE%E7%94%A8%E9%80%94%E3%83%BB%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%80%90%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E8%A3%85%E9%A3%BE/
ローカル環境でmysqlが立ち上がらないの解決例

## 何があった？

下記のコマンドを打つと、下記のようなエラーが出た。
```:コマンド
sudo mysql.server start 
```

```:エラー文
The server quit without updating PID file (/usr/local/var/mysql/DESKTOP-5FH95RJ.pid).
```


## 解決した方法

自動立ち上げ設定で先に動いていたSQLightを下記コマンドで終了し、
```:コマンド
# SQLightに接続
sqlight3 file_name

ーーー接続後ーーー
>.quite
```

通常通り`sudo mysql.server start`を実行することで立ち上がった



## 原因
確信はないがSQLightとMySQLでPIDがバッティングしていたと思われる。
とりあえずSQLightとMySQLは相性悪そうだと思った。

※ただしmysql立ち上げた後ならsqlightを立ち上げても相互干渉はなさそうなのは確認できた。

MySQLのバージョンは 8.0
SQLite versionは 3.28.0
サンタさんにもらったmac mini late 2012 にUbuntu 22.04 を入れて普段使いPCにセットアップする

Qiita初投稿です！

昨年末、サンタさんから[mac mini late 2012](https://support.apple.com/kb/sp659?locale=ja_JP)をもらいました。

![321640195_1211561373126230_5302878109587516325_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989162/2905e692-80cc-f966-c829-988e3c635975.png)

もともとLinuxとか入れて遊べる端末を探す旅に出ていて
過去に[MacBook Air (11-inch, Mid 2012)](https://support.apple.com/kb/sp650?locale=ja_JP)を買って[Cloudready(現：ChromeOS Flex)](https://chromeenterprise.google/os/chromeosflex/#intro-text)を入れて遊んでいたりしたのですが
プライベートで使ってるノートPCがWindows 11に対応しておらず、今回は遊べる＆乗り換えられる端末ということで購入に至りました。

スペックはこんな感じ。

・CPU：2.5GHzデュアルコアIntel Core i5
・メモリ：16GB
・ストレージ：SSD256GB

じゃーん！
![320044593_859893065234595_4540320345606462794_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989162/b483f93f-5476-77c2-abdf-efbdb840ec2d.jpeg)

じゃーん！！
![325162658_678770537316885_4109053969941563129_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989162/59fd7a75-4ce8-a364-7dba-0fb910cc7e69.jpeg)

じゃーん！！！
![323714678_1336114037243300_708573123629272160_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989162/ec9b15dd-b9a5-cea2-5c37-dd9aa17e73a4.jpeg)

細かいキズありですが、やはり造形美が素晴らしい。

もともとWindowsの住人でmacの知識は皆無なのですが
中古macの中では抜群の[カスタマイズ性](https://monolog-saizo.com/gadget_home-electronics/mac-mini-2012-01/#%E3%81%A9%E3%81%86%E3%81%97%E3%81%A6%E4%BB%8A%E6%9B%B4Mac_mini_2012%E3%81%AA%E3%81%AE%E3%81%8B:~:text=%E5%AE%9F%E3%81%AF%E3%81%93%E3%81%AE3%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A7%E4%B8%80%E7%95%AA%E9%AB%98%E6%80%A7%E8%83%BD%E3%81%AA%E3%81%AE%E3%81%AF2012%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AA%E3%82%93%E3%81%A7%E3%81%99%E3%80%82)らしいです。

前の持ち主がメモリもSSDも換装してくれたみたいで、macOS Catalinaもサクサクでした。

が、OSのサポートが切れているので流石にこのまま使い続けるのは難しい。。
ということで次回以降、Ubuntuをインストールしていきます。

他にもこのあたりの設定について触れようかと思います。
・Microsoft edge のインストール
・Caps lock → Ctrl に切り替え
・Magic Trackpad の初期設定＆ジェスチャー登録

次回もお楽しみに！
[Git] 現在のbranchの最新のコミットを１コマンドでpullする

# 結論

```shell
git rev-parse --abbrev-ref HEAD | git pull origin
```

# bash_profile

エイリアスに登録 

```shell .bash_profile
alias gploh="git rev-parse --abbrev-ref HEAD | git pull origin"
```

これで、gploh で current branchの最新コミットをpull できるようになりました。
gploh は g (git) + pl (pull) + o (origin) + h (HEAD) のつもりです。
再実行のやり方とGotoとエラー処理

仕事で開発やっていて、phpの仕様について誤解していたので反省がてら。

とりあえずコード。
下は、try内容がエラーになった時、３回は再実行し
それ以降は対応できなかったとアラートを出して終了するという処理だ。

```test.php
//変数宣言と初期化
$i = 0;
repeat:
try {
    //try内の内容
    echo (12/0);

} catch ( Exception $e ) {
    //エラーしたら行われる処理
    //４回以下なら上に戻る
    if ($i <= 2){
        $i++;
        print($i.'回目の再実行をします');
        goto repeat;                
    } else {
        print('３回再実行をしましたが、対応できませんでした');
        exit;
    }
} finally {
        //エラーしてもしなくても実行される処理のはず
        //エラー処理の場合は、exitされるはずなので、ここは正常処理で考えてた
        print('正常終了しました');
}
```
この結果、どうなったか。

```
1回めの再実行をします
正常終了しました
```
となった。
さてなぜこうなったのか？

ちなみに私はマクロ屋出身で、VBAが得意。
VBAだと、こういうgotoの使い方は問題ない。（書き方は大いに問題あるが）

しかし、phpは、ダメである。　
下記を読んでみると
https://www.php.net/manual/ja/control-structures.goto.php

> 関数やメソッドの外に飛び出したり 関数やメソッドの中に突入したりすることはできない

とある。　
try構文は関数だっただろうか。。。
しかし上のページを読んでも、gotoが飛び先より前にあるものはない。
ということは、おそらく、後ろしか飛べないのだろう、と推測した。
もし、前には飛べない旨の説明が書かれている箇所があったら教えてほしい。

さて、これを直してみた。
再実行処理をfor文で構成したものだ。
機能は先ほどと同じ。

```test.php
for ($i=1; $i<４; $i++){
    try {
        //try内の内容
        echo (12/0);  
    } catch ( Exception $e ) {
        //エラーしたら行われる処理
        //次が3回以下なら再実行
        if ($i + 1 <= 3){
            $i++;
            print($i.'回目の再実行をします');
            continue;                
        } else {
            print('３回再実行をしましたが、対応できませんでした');
            exit;
        }
    } finally {
            //エラーしてもしなくても実行される処理のはず
            //エラー処理の場合は、exitされるはずなので、ここは正常処理で考えてた
            print('正常終了しました');
    }
}
```
結果は。

```
1回めの再実行をします
正常終了しました
```
ええええええ。
continueがあるのに。。。
continueって普通にループの最後までスキップするんじゃなかったんか？
finallyに飛んでしまってるやん。。。

という。

で、よく考えたら、正常処理は、普通にtry内に書けばfinallyがいらないやん、
と考え直して、
こう書けば、continueもいらない。

```test.php
for ($i=1; $i<４; $i++){
    try {
        //try内の内容
        print(12/0); 
        print('正常終了しました');
    } catch ( Exception $e ) {
        //エラーしたら行われる処理
        //次が3回以下なら再実行
        if ($i + 1 <= 3){
            $i++;
            print($i.'回目の再実行をします');              
        } else {
            print('３回再実行をしましたが、対応できませんでした');
            exit;
        }
    }
}
```
finallyの内容をtry内に書いた。
そしたら、
```
1回目の再実行をします
2回目の再実行をします
3回目の再実行をします
３回再実行をしましたが、対応できませんでした
```
とイメージ通りのものが出力された。

ちなみに、print内を正しい割算にすれば、正しく正常終了しました、とだけでる。



gotoはまあわかるとしても、
continueからのこの不思議な処理は一体なんなのだろうか。。。

とりあえず解決できたので、まとめとしてカキコ。
Googleプロジェクト管理：成功基準

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# 成功基準を定義する

- プロジェクトが成功したかどうかを知るにはどうしたらいいのでしょうか？
- 実際にランディングできたかどうかは、どうすればわかるのでしょうか？

プロジェクト開始時には、目標や成果物を測定可能な形で定義しました。同様に、成功基準を定義し、それが達成されたかどうかを測定する必要があります。

***<font color="MediumVioletRed">『成功基準は、プロジェクトが全体として成功したかどうかを示すもの』</font>***

成功基準は、
- ゴールや成果物の具体的な内容で、やろうとしたことが達成できたかどうかがわかります。
- ステークホルダーや顧客に引き渡された後のプロジェクトの判断基準となるものです。
- 成功基準を定義することで、単にユーザーに何かを提供するだけでなく、チームが何を達成しようとしているのかが明確になります。

# 成功基準の決め方

成功基準の決め方に決まったプロセスはありませんが、いくつかのポイントに分けて考えてみます。

プロジェクトのゴールと成果物を確認し、スコープを見直し、プロジェクトの測定可能な側面を特定します。これらは、予算やスケジュールの詳細とともに、目標や成果物で使用されたメトリクスのいずれかとなる。

もう一つ必要なことは、ステークホルダーからプロジェクトの要件と期待値を明確にすることです。これは重要です。そこで、以下のような質問をすることになります。

- プロジェクトが成功したかどうか、最終的に判断するのは誰なのか？
- 成功の判断基準は何か？
- このプロジェクトの成功は、何を基準にしているのか？

:::note info
製品によっては、複数の測定基準を使用することが合理的な場合もあります。選択する測定基準は、プロジェクトの目標にできるだけ近いものであるべきです。
:::

# 指標の種類

#### ハピネスメトリクス
ユーザーの態度や満足度、あるいは使いやすさの実感を測るものです。

> 例）ローンチから3ヶ月以内に、85%の顧客満足度を達成する

#### アドプション（採用）

顧客が製品やサービスを問題なく使用し、採用することを指します。アドプションメトリクスには、新製品をユーザーのグループに投入し、そのうちの多くのユーザーが使用または採用することが含まれます。

> 例）ローンチから3ヶ月以内に、５０人のお客様が新サービスに最初にサインアップしている

#### エンゲージメント

顧客とのインタラクションや参加が長期的にどの程度の頻度で、あるいは有意義なものであるかを示すものである。 エンゲージメントの指標には、デザイン機能の日々の使用量の増加や、注文や顧客とのインタラクションの増加が含まれるかもしれません。

> 例）毎月１００人の顧客が新サービスの投稿に対して、フィードバックを共有している

# 指標の追跡

測定する指標を定義したら、その指標をどのように追跡するかを考えてください。どのようなツールを使えば、計画通りに進んでいるかどうかを確認するために必要なデータを収集できるかを検討します。

- 収益のようなビジネス指標を測定する場合は、スプレッドシートやダッシュボードで追跡し、ギャップやトレンドを簡単に発見できるようにします。
- 顧客満足度を測定するのであれば、定期的なメール調査に参加するよう顧客にインセンティブを与える方法を考え、参加した際の反応を測定するシステムを構築します。
- プロジェクト管理ツールを活用して、タスクが何パーセント完了しているか、プロジェクトが計画通りのスケジュールで進行しているかなど、効率性の指標を確認します。

プロジェクトや製品が進行している間に、チーム内で成功を測定するのは賢い方法です。例えば、
- 月に1回プロジェクトレビューを実施する。
- チームメンバーに特定の期限までにタスクチェックリストを完成させる。
- ユーザーや顧客とライブフィードバックセッションを行う。

:::note info
成功を測定する方法はさまざまです。重要なのは、あなたの成功基準に最も適した方法を選ぶことです。
:::

リストの各成功基準と一緒に、

- 成功をどのように測定するか？
- どのくらいの頻度で測定するか？
- 誰が測定するのか？

も記載しておくとよいでしょう。

成功基準をステークホルダーと共有し、プロジェクトの成功がどのように決定されるかに同意するかどうかを尋ねます。また、適切なステークホルダーに成功基準への署名をもらうのも良いアイデアです。こうすることで、誰がどのタスクに責任を持つのかが明確になり、成功への道筋がどのようなものかを全員が徹底的に理解することができます

:::note info
成功基準をステークホルダーと共有し、プロジェクトの成功がどのように決定されるかに同意するかどうかを尋ねます。また、適切なステークホルダーに成功基準への署名をもらうのも良いアイデアです。
:::

# 品質に関する測定基準

プロジェクトの最終成果物であるプロダクトには、その成功を定義する属性がある。製品の成功に必要な属性には、

- 機能の完成度
- 機能の品質
- 単価使い勝手

などがあります。

製品がどの程度完成しているかは、製品の成功に寄与する。成功への道筋をつけるために、製品要件のリストを作成し、見落としがないようにすることができます。

製品の成功を測定するために、これらの指標をチェックリストに含めることを検討してください。

- 製品の優先要件を実装したかどうかを追跡する。
- 製品の技術的な問題や欠陥の数を追跡し、評価する。
- プロジェクト終了時に納品またはリリースした機能の割合を測定する。


# さいごに

成功基準を正しく定義することで、チーム内の連携が強化され、成功への道筋がより明確になるはずです。また、成功基準を明確にすることで、どの取り組みがユーザーにとって最もインパクトがあるのか、優先順位をつけることができます。

プロジェクトの成功を定義することは、複雑ではありますが、プロジェクトマネジメントの重要な部分です。このプロセスは、何度も練習することで、計画段階やプロジェクト全体を通してより自然に身につくようになります。
【マークダウン】折りたたみの実装方法（detailsタグ）

# はじめに
プログラミング学習中の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。

GitHubにてマークダウン形式で学習の記録をしているのですが、
マークダウン形式ファイルでの折りたたみ（トグル）の記述方法の共有です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/e6bb1b7a-8490-5013-62e2-2b85ce13ffb7.png)

# 結論
`details`タグを使用すると可能です！

```md
<details>
<summary>折りたたみタイトル</summary>
中身です。
中身です。  
中身です。  
</details>
```

:::note info
行末に半角スペースを2つ入れると改行できます。
:::

# おわりに
お読みいただきありがとうございました。
どなたかの参考になれば嬉しいです。
↓に載せております参考ページがマークダウンについて分かりやすくて勉強になりました！
一緒に頑張っていきましょう〜😄

# 参考
https://www.wakuwakubank.com/posts/861-git-markdown/#index_id12
エレキ素人が何か考える（その17）：1bit DRAM

# Arduinoから擬似「1 bit DRAM」を制御
擬似的な「1 bit DRAM」をマイコン（Arduino）から制御する。

## DRAMの原理
1. [DRAMとは？DRAMの構造・動作原理を図解で説明](https://elite-lane.com/dram/)
1. [コンピュータの基礎(2)-メモリ-   Memory](http://www.crl.nitech.ac.jp/~ida/education/MaterialsDesign/01_02/2.pdf)
1. [半導体メモリ  ー　DRAM](https://www.s-graphics.co.jp/nanoelectronics/kaitai/memory/2.htm)

上記URLなどに適切な説明が見つかる。MOSFETやトランジスタとコンデンサを利用し、電化の有無で、'1'を'0'を記憶するものである。最後のサイトの図を使って説明。

### Write
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3fbc6f64-9555-e778-5a88-4af4ac4292b3.png)
"W"ラインをHighにして、"B"ラインをHighまたはLowにして、コンデンサに'1'または'0'の状態をつくる。

### Read
![ramread.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e2979303-1699-dfc8-d1de-82ddb07b3335.gif)
"W"ラインをHighにして、"B"ラインの状態を読み込み、Highであれば'1'、Lowであれば'0'と判断する。ただし、'1'の場合、放電されてしまうため、再度、"B"ラインをHighにして、コンデンサに'1'の状態をつくることが必要である。

## 実回路
接続は下記のとおり。
|MOSFET|接続先|
|---|---|
|Gate|Arduino Pin 2|
|Drain|Arduino Pin 4|
|Source|Capcitor & GND|

![Sch_回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9d397040-69b7-07ed-c0b3-52dc4dd81d80.png)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/bb1b93f4-8e39-706b-f24f-ff2c6bd1230b.png", width=70%>

## ソースコード
```c++
#define G_PIN 2
#define D_PIN 4

void setup() {
  Serial.begin(9600);
  pinMode(G_PIN, OUTPUT);
}

void write_data(uint8_t data) {
  digitalWrite(G_PIN, HIGH);
  pinMode(D_PIN, OUTPUT);
  Serial.print("Write data: ");
  Serial.println(data);
  digitalWrite(D_PIN, (data? HIGH:LOW));
  delay(1);
  digitalWrite(G_PIN, LOW);
}

void read_data() {
  digitalWrite(G_PIN, HIGH);
  pinMode(D_PIN, INPUT);
  uint8_t data = digitalRead(D_PIN);
  Serial.print("Read data: ");
  Serial.println(data);
  if (data) {                   // ①
    pinMode(D_PIN, OUTPUT);     // ①
    digitalWrite(D_PIN, HIGH);  // ①
  }                             // ①
  delay(1);
  digitalWrite(G_PIN, LOW);
}

// 0: 0-Write 1: 1-Write Others: Read
void loop() {
  if (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    uint8_t val = input.toInt();
    if (val < 2) {
      write_data(val);
    } else {
      read_data();
    }
  }
}
```
アルゴリズム的には下記となる。
|シリアル入力|0|1|それ以外|
|---|---|---|---|
|Action|'0'書き込み|'1'書き込み|読み込み|

※ エラー入力は未考慮

## 実験
'0'を書き込んだあとの読み取りは'0'、'1'を書き込んだあとの読み取りは'1'となり、期待どおりの動作をしている。
![通常動作.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3e0e6d90-f018-ca6c-eb43-42f54ab5140a.png)
また、上記コードの①の部分をコメント化（読み込み後の書き込みなし）すると、下記のように、'1'の書き込み後、すぐに読み出せば'1'となるが、その後は'0'となる（期待どおり）。
![書き込みなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2fa50823-535d-1647-591d-5314be613636.png)

## 終わりに
本当にこれで正しいのか自信はないが、DRAM制御の基本的な考え方はある程度理解したつもりである。
wslでelixir その18

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
パッケージマネージャ?、mix deps.get使ってみた。
jsonパーサー、jason使ってみた。

# mix deps.get

mix.exsいじる。

```
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
		{:jason, "~> 1.2"}
    ]
  end
```
実行

```
$ mix deps.get
Resolving Hex dependencies...
Resolution completed in 0.532s
New:
  jason 1.4.0
* Getting jason (Hex package)

```

# jasonを実行

```
$ iex -S mix
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

==> jason
Compiling 10 files (.ex)
Generated jason app
==> hello
Generated hello app
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> %{"first" => 1, "last" => 10, "step" => 2}
%{"first" => 1, "last" => 10, "step" => 2}
iex(2)> |> Jason.encode!
"{\"first\":1,\"last\":10,\"step\":2}"
iex(3)> |> Jason.decode!(keys: :atoms)
%{first: 1, last: 10, step: 2}
iex(4)> %{first: 1, last: 10, step: 2}
%{first: 1, last: 10, step: 2}
iex(5)> |> Jason.encode!
"{\"first\":1,\"last\":10,\"step\":2}"
iex(6)> |> Jason.decode!
%{"first" => 1, "last" => 10, "step" => 2}
iex(7)>
```


以上。
API通信とAPI通信による非同期処理時のクロージャの利用してそれらの挙動を確認する

## はじめに
①URLSessionのdataTask(with: complitionHandler)を使ったAPI通信と②API通信による非同期処理時のクロージャの利用してそれらの挙動を確認する。また、使用するAPIは郵便番号検索APIである。7桁の郵便番号を入力すると住所の情報が返ってくる。


## 詳細
- API通信とAPI通信による非同期処理時のクロージャの利用に関してそれらの挙動を確認する
- 要は、API通信をしてそれをクロージャで受け取った非同期処理をする
- 今回、API通信を行うにあたってURLSessionのdataTask(with: complitionHandler)を使う
```swift:Swift
//print関数で[番号]を出力している箇所があるが、
//非同期処理で行なっているので必ずしも順番で処理が走るわけではないことに注意

// URLSession.shared.dataTaskを使ってサーバーと通信するメソッド
// closure: @escaping( (String) -> Void ) は非同期処理時に利用するクロージャーのこと
func api(zipCode: String, closure: @escaping( (String) -> Void ) ) {
    print("[1] api関数の処理を開始")
    
    //住所検索のAPI
    let url = URL(string: "https://zipcloud.ibsnet.co.jp/api/search?zipcode=\(zipCode)")!
    let request = URLRequest(url: url)
    
    // URLSession.shared.dataTaskメソッドがcompletionHandlerという名前のクロージャをパラメータに持っている
    // 次に定義するのは、それに渡すclosure
    // api通信が終わればこのclosureに代入され、実行される
    let dataTaskCompletionClosure = { (data: Data?, response: URLResponse?, error: Error?) in
        print("[2] dataTaskCompletionClosureに代入し、処理を開始")
        
        guard let data = data else {
            closure("通信失敗")
            return
        }
        let jsonStr = String(data: data, encoding: .utf8)!
        print("[3] api関数実行時に渡しているclosure定数に代入され、実行する")
        closure(jsonStr)
    }
    
    print("[4] api通信するためのメソッドdataTaskにdataTaskCompletionClosureを代入")
    let task = URLSession.shared.dataTask(with: request, completionHandler: dataTaskCompletionClosure)

    print("[5] resumeメソッドを実行すると通信が始まる")
    task.resume()
    
    print("[6] 通信が終わるのを待たずにメソッドを抜ける")
}

// api関数の実行時に渡す定数
let zipcode = "1006117"

//このclosureはapi関数のレスポンスを受け取る
//関数の中でAPI通信でdataを取得している
let inputClosure = { response in
    print("[7] inputClosure定数に代入され、処理を開始")
    print(response)
}

print("[8] api関数の実行前に行う処理")
api(zipCode: zipcode, closure: inputClosure)

print("[9] api関数の実行後に行う処理")

//出力
//{
//    "message": null,
//    "results": [
//        {
//            "address1": "東京都",
//            "address2": "千代田区",
//            "address3": "永田町山王パークタワー　１７階",
//            "kana1": "ﾄｳｷｮｳﾄ",
//            "kana2": "ﾁﾖﾀﾞｸ",
//            "kana3": "ﾅｶﾞﾀﾁｮｳｻﾝﾉｳﾊﾟｰｸﾀﾜｰ17ｶｲ",
//            "prefcode": "13",
//            "zipcode": "1006117"
//        }
//    ],
//    "status": 200
//}
```

## おわりに
不備がありましたらぜひコメント欄にてご指摘ください。

## 参考記事
- [iOSエンジニアを目指すプログラミング初心者のほとんどが躓くクロージャを徹底的に細かく分解して解説していく　(練習問題あり、回答のみ有料)](https://note.com/sakiyamak/n/nf40752b88f98)

- [崎山圭さんのnoteです](https://note.com/sakiyamak/n/nf40752b88f98)
- [郵便番号検索API(今回使用したAPI)](https://zipcloud.ibsnet.co.jp/doc/api)

- [[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)　](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-Swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E7%9B%B4%E6%84%9F%E7%9A%84%E3%81%AA%E6%96%87%E6%B3%95%E3%81%A8%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E5%85%BC%E3%81%AD%E5%82%99%E3%81%88%E3%81%9F%E8%A8%80%E8%AA%9E-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4297112132)
↑引用元
石川 洋資 (著), 西山 勇世 (著)
発行者：片岡 巌
出版社：技術評論社
印刷/製本：日経印刷株式会社

## 開発環境
- Xcode-13.4.1
- Swift version 5.7
学習記録　elixir

ElixirスキルシートのEnum.reduceについて学習メモ



>reduce(enumerable, fun)

>Invokes fun for each element in the enumerable with the accumulator.

DeepLで翻訳をするとこんな答えが返ってきた
アキュムレータの意味が良くわかっていないので後日調査予定

>列挙可能な各要素に対して、アキュムレータを用いたfunを起動します。

https://hexdocs.pm/elixir/1.12/Enum.html