OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript 日付をYYYYMMDD, YYYY/MM/DD など区切り文字指定してフォーマットする関数

# 状況によって区切り文字を変えたい
JavaScriptで日付をフォーマットする際に
- YYYYMMDD (区切り文字なし)
- YYYY<font color="Red">/</font>MM<font color="Red">/</font>DD (スラッシュ区切り)
- YYYY<font color="Red">-</font>MM<font color="Red">-</font>DD (ハイフン区切り)
- YYYY<font color="Red">.</font>MM<font color="Red">.</font>DD (ドット区切り)

など状況に応じて区切り文字を変えたいときがあります。
そこで区切り文字を可変で指定できるフォーマット関数を作成しました。

こちらの記事を参考にさせていただいております。
月、日のゼロ埋め(1 → 01) なども解説頂いております。
[日付をYYYY-MM-DDの書式で返す関数 (JavaScript)](https://qiita.com/toshimin/items/5f13c3b4c28825219231)


# 日付フォーマットする際に区切り文字を指定できる関数

以下のような、`dateオブジェクト`と`区切り文字`を引数で渡す関数になっています。
区切り文字の引数`sep`はデフォルトで`""(空文字)`にしているので
指定しないと、`YYYYMMDD`形式(空文字区切り)で返ってきます。

```javascript:日付フォーマット関数 区切り文字指定可
function formatDate(date, sep="") {
  const yyyy = date.getFullYear();
  const mm = ('00' + (date.getMonth()+1)).slice(-2);
  const dd = ('00' + date.getDate()).slice(-2);

  return `${yyyy}${sep}${mm}${sep}${dd}`;
}
```

以下のように関数を呼び出します。
```javascript:日付フォーマット関数呼び出し方
const dateTime = new Date();
const date = new Date(dateTime.getFullYear(), dateTime.getMonth(), dateTime.getDate());

// 区切り文字なし
const dateStr = formatDate(date);
console.log(dateStr);
// 20220914

// ハイフン区切り
const dateStrHyphen = formatDate(date, "-");
console.log(dateStrHyphen);
// 2022-09-14

// スラッシュ区切り
const dateStrSlash = formatDate(date, "/");
console.log(dateStrSlash);
// 2022/09/14
```
# アロー関数で1行で書く
```javascript:アロー関数版
const formatDate = (date, sep="") => date.getFullYear() + sep + ('00' + (date.getMonth()+1)).slice(-2) + sep +('00' + date.getDate()).slice(-2);
```


アロー関数でも従来の関数の使い方と一緒です。
```javascript
const formatDate = (date, sep="") => date.getFullYear() + sep + ('00' + (date.getMonth()+1)).slice(-2) + sep +('00' + date.getDate()).slice(-2);

const dateTime = new Date();
const date = new Date(dateTime.getFullYear(), dateTime.getMonth(), dateTime.getDate());

// 区切り文字なし
const dateStr = formatDate(date);
console.log(dateStr);
// 20220914

// ハイフン区切り
const dateStrHyphen = formatDate(date, "-");
console.log(dateStrHyphen);
// 2022-09-14

// スラッシュ区切り
const dateStrSlash = formatDate(date, "/");
console.log(dateStrSlash);
// 2022/09/14
```
each_with_indexメソッドを使ってみた備忘録

今日も学んだことを忘れない為にメモします

### each_with_indexメソッドとは？
each_with_indexは、Rubyに標準で組み込まれている要素の繰り返し処理であるeachメソッドに、その要素が何番目に処理されたのかも表すことが出来る機能がついたメソッド。
これを使えば任意の数字が配列の中の何番目に格納されているかを確認できるプログラムを実装できる。

例えば下記のようにランダムな数字が入った配列があるとする。
```
[3, 5, 9 ,12, 15, 21, 29, 35, 42, 51, 62, 78, 81, 87, 92, 93]
```
この中から任意の数字を探して何番目に含まれているかいない確認した場合は下記のように記述する。
```
def search(target_num, input)

  input.each_with_index do |num, index|
    if num == target_num
      puts "#{index + 1}番目にあります"
      return
    end
  end
  puts "その数字は含まれていません"
end

input = [3, 5, 9 ,12, 15, 21, 29, 35, 42, 51, 62, 78, 81, 87, 92, 93]
search(10, input)
```

配列を変数inputに代入して確認したい数字とinputという変数を実引数としてセットしてsearchメソッドを呼び出す。
そして、呼び出されたsearchメソッドでは、実引数でセットした値を仮引数target_numとinputとして受け取る。

searchメソッド内ではinput.each_with_indexでinputに格納されている要素を1つひとつnumとして取り出すと同時に、要素毎に割り当てられている添字をindexとして取得する。

次に、if文でnum == target_numという条件式を設定
numとtarget_numが等しければ、numがinputの中の何番目に含まれているかが出力される。
添字は０から始まるので#{index + 1}と記述して、「0番目」が出力されないようにする。

numとtarget_numが等くなければ、「その数は含まれていません」と出力される。

今回、配列には10は含まれていないので「その数は含まれていません」と出力される。
```:結果
その数は含まれていません
```

*下記のようにreturnではなくelseで記述すると配列の要素の数、処理が行われる
```
def search(target_num, input)

  input.each_with_index do |num, index|
    if num == target_num
      puts "#{index + 1}番目にあります"
    else
      puts "その数は含まれていません"
    end
  end
end

input = [3, 5, 9 ,12, 15, 21, 29, 35, 42, 51, 62, 78, 81, 87, 92, 93]
search(92, input)
```
```:結果
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
その数は含まれていません
```

以上がeach_with_indexメソッドを使ってみた備忘録になります。
returnってどこで使うんだろうと思ってましたがこういう場面で使うんだってreturnの使いどころも学べました。
MFAについて考えてみる

## MFAを知っていますか？

MFAとは、Multi-Factor-Authenticationの略で、2つ以上の認証要素の提供を求める認証方式のことです。
認証要素ってどんなものがあるのでしょうか。
認証要素の種類は大きく**3種類**です。

**1\.バイオメトリクスによる認証**
　⇒指紋認証や静脈認証、虹彩認証等が該当します。

**2\.所有物による認証**
　⇒印鑑証明やICカードによる認証、ディジタル証明書等が該当します。

**3\.記憶や秘密による認証**
　⇒パスワードや暗証番号、生年月日等が該当します。

これらの認証要素から2つ以上の提供を利用して認証を行うのがMFA、つまり**多要素認証**でしたね。

## AWSでのMFAデバイスを利用している気になった話

AWSにもMFAを利用する機能がありますよね。
先日、rootアカウントに紐づけているMFAデバイスを複数台用意するという記事をみかけました。
実際にはどういった運用がベストプラクティスになるのだろうかと迷ってしまいましたので、ご紹介します。

## 問題となるやり口
AWSでは、仮想MFAデバイスというMFA認証を実施するための機能を用いることができます。
その機能を利用するのですが、やり口は以下の通り。

1．MFAを利用する際に発行するQRコードをスクショしておく。
2．スクショしたQRコードを複数のデバイスで読み取り、仮想MFAデバイスとして機能させる。

## 初めの感想
驚いてしまいましたね。。。
本来、rootアカウントは利用せずAMIを利用する。そして、アカウントとデバイスは1:1にする。
これが原則だと考えます。
しかし、AWS上では実際に上記の手順で複数のデバイスを用意することができてしまう。
しかも、この手口はだいぶ前から公開されている手口のようです。
セキュリティと運用性はトレードオフだとはよく言ったもんですが、こんな実態があるとは。。。

## みなさん、、、
巷の皆様は、どういったMFAの管理方法を実施しているのでしょうか？？？
とても気になるところです。
自分もまだまだ調べてみます。

ということで以上となります。長々とすみませんでした笑
queryStringのクエリにランダムな英数字を入れるとごく稀にINFになる

https://qiita.com/ast_and_kaya/items/c3bc931bca2b725bd1eb

↑の関連

## 前提
LivewireのComponentでは`$queryString`という変数をオーバーライドすることでURLにクエリを付与したり書き換えたり出来ます。
https://laravel-livewire.com/docs/2.x/query-string

例えば、web.phpで↓のようにコンポーネントへのルーティングを行い、
```php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', \App\Http\Livewire\Item::class );
```

それからComponentで`$qs`を`$queryString`へ追加してから

```php
<?php

namespace App\Http\Livewire;

class Item extends \Livewire\Component
{
    public string $qs = ''; // URLのクエリ名

    protected $queryString = ['qs']; // 対象の変数名を文字列で設定

    public function mount()
    {
        var_dump( $this->qs ); // 出力
    }
}
```

`http://localhost/?qs=123456`とかにアクセスすると
```
string(6) "123456"
```
クエリ`qs`に渡した値をプロパティ`$qs`に代入してくれます。

## 注意点

普通に使っていれば割と便利なこの機能ですが、残念ながら
`http://localhost/?qs=123e456`
とかやってしまうと`123e456`が指数表記と解釈されてしまうため、上記のクエリでは↓の出力結果になってしまいます。
```
string(3) "INF"
```
ちなみに`http://localhost/?qs=10e2`とかだと↓
```
string(4) "1000"
```
うーん、なんとも気味の悪い挙動

回避策としては「**`http://localhost/?qs="123e456"`でアクセスする**」とか「**そもそもそんな短いランダム文字列を使わない**」とかが有効です。

これが原因の不具合にぶつかったときも「テストデータだしランダムなコードも6文字ぐらいで良いか」的な感じのノリだったので、今後は気を付けたい。

## おまけ
Q. なんでこんなことが起こるのか？

A. なんかLivewireが受け取った値をjson_decodeに通してるから（↓の41行目）

https://github.com/livewire/livewire/blob/master/src/Features/SupportBrowserHistory.php#L41

多分バグですねこれ
カスタムフックのテスト(Jest)でRecoilでステートが更新されているかチェックする

# はじめに

Recoilを導入してテストをする際にステートが更新されていることをどうしてもテストしたかったのですが、なかなか解決方法が見つからなかったのでまとめます

# 問題

Reactのカスタムフックでログイン認証(Axios)を実装しました
そこでは、Axiosの結果に応じて、`Recoil`の`isLogin`をtrue/falseに切り替えるという処理を行いました

Jestを書く際に、Recoilのステートが変わることをテストしようとしましたが、公式をみてもやり方がよくわからず困りました

# 解決方法

`testing-library/react-hook`を利用して以下のように書けました

```test.tsx

  const {result} = renderHook(
    () => {
      const [isLogin, setIsLogin] = useRecoilState(isLoginState)
      const { login } = useAuth()
      return {
        isLogin,
        setIsLogin,
        login,
      }
    },
    {
      wrapper: RecoilRoot
    }
  )

(関数を呼び出す処理は省略)

expect(result.current.state).toBe(true)

```

# おわりに

テストとして行うことが多そうなのですが、なかなかやり方がみつかりませんでした

# 参考
https://github.com/testing-library/react-hooks-testing-library/issues/746
Dockerでmmposeの環境構築

# はじめに
mmposeやらなくちゃいけなくなったけど、自分の環境を汚したくない！

そんなあなたにDocker

ということで以下の環境でDockerでのmmpose環境構築を行った

| 機種 | MacBook Air (Retina, 13-inch, 2019) |
|:-:|:-:|
| プロセッサ | 1.6 GHz デュアルコアIntel Core i5 |
| メモリ | 8 GB 2133 MHz LPDDR3 |
| GPU | Intel UHD Graphics 617 1536 MB |
| OS | Monterey ver12.4 |
| 開発環境 | vscode |
| 使用ツール | Docker |

# 構築
### 事前準備
1) docker desktopのインストール
https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/
公式を参考にどうぞ

2) vscodeのインストール
https://qiita.com/watamura/items/51c70fbb848e5f956fd6
他の方のqiitaを参考にどうぞ

### Githubからmmposeのソースコードをダウンロード

1) 下のリンクにアクセス
https://github.com/open-mmlab/mmpose

2) CodeからDownload ZIPをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525698/9e688ae3-a26e-41e0-475c-da9fc51f9a55.png)

3) ダウンロードしたzipファイルを解凍
解凍したファイルは自分の好きなところに移動しておいてください

4) ターミナルを開き、mmposeのディレクトリに移動
このとき、mmposeのフォルダをターミナルにドラッグ&ドロップするとパス名が自動入力されるので便利

5) 以下のコマンドをうつ
```docker build -t mmpose docker/```
dockerのイメージがこれで作成される(docker desktopのイメージでmmposeができていることが確認できる)

6) マウント用のディレクトリを用意する
自分で用意した画像や動画などを随時追加したいので、外部のディレクトリを用意しておく
今回はmmpose直下にdataディレクトリを用意した(mmpose/data)

7) 以下のコマンドをうつ
```docker run --name mmpose -it -v [マウントするディレクトリ(絶対パス)]:/mmpose/data mmpose```
これでdataディレクトリがマウントされたdockerコンテナが作成される（仮想環境の作成完了）

8) vscodeで作成したdockerコンテナを開く
vscodeの拡張機能で"Remote-Containers"をインストール
左側のアイコンにRemote Explorerというパソコンのディスプレイのようなものが増えると思う
それを押すとcontainerの部分にmmposeという名前のコンテナがあるので右側にあるプラスブラウザアイコンのようなものを押すと先ほど作成した仮想環境に入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525698/0685e9b7-46a1-cdc5-e1dd-77c514a081f9.png)

9) mmposeの動作確認
mmpose/demo/top_down_img_demo.pyを実行してみる
vscodeでのターミナルの開き方はmacだとcontrol+shift+^
以下のコマンドをターミナルでうつ
```
python demo/top_down_img_demo.py \
    configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
    --img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
    --out-img-root vis_results \
    --device=cpu
```
結果がmmpose/vis_resultsに結果が保存されていたらok
既存Anaconda環境にStable Diffusion導入

# 1. はじめに
* 本稿作成時に50以上の記事がありましたので、反響が高いモデルだと思います。
    * また、世の中ではAIで絵を描いた（DLとAIはホントは違う）と話題になったアレです。
    * 昨年の業務で門前払い食らったhuggingfaceでGPT-2のリベンジのチャンス(個人的に）
    * 基本的には公式の手順を守るのが環境を汚さなくてよいです。

**公式 Github**

https://github.com/CompVis/stable-diffusion

# 2. 前提
* 昨年度のGPT-2（おもにRinna）で頑張ばった環境あり。
    * OmniverseもPytorchベースでした。
    * ・・・ということでわざわざcondaで仮想環境作らなくてもと思ってしまいました。
    
* なお、GPT2のりんなですが、Bingサイトでチャットボットとしても活躍。
    * Edge使用でBing上で検索すると表示されますね。
* その他、日本語を用いた言語処理に活躍されています。

> 2021年当方のGPT2（withりんな)活用状況
>> Wikipedia2021年日本語コーパス利用
>>PC Watch 20年分データ使用
>>自社FAQサイトのデータをスクレイピングで抽出
> 合わせて5GB程度のデータですがRTX3090でギンギンに回して2.8エポック5営業日回しました。

:::note warn
残念
素のデータ及び、3エポック以上ではメモリオーバーでやら、エラー中断しました・・・
:::

* 会話レベルはりんなと遜色ない出来までいけたと思います。
    * 業務上は無かったことになっちゃいましたが・・・(汗）
    
***

https://rinna.co.jp/


:::note info
インフォメーション
なお、さらなる高度な自然言語処理にはGPT3でしょう（有償ですが…）
:::

https://openai.com/api/

# 3. Stable Diffusion v1ここだけやりました(インストール)

1. 既存condaのactivate
2. 公式Githubより、必要と思われる箇所のみインストール

```言語:Ubuntu

pip install transformers==4.19.2 diffusers invisible-watermark
pip install -e .

```

:::note warn
注意
よほどのことがなければ、公式の手順に沿った方が操作が楽です。

:::

# 4. txt2imgを試してみる。
* コマンドのフレーズの中に標示したいシーンを記述
    * 英語が一番しっくりくる画像を出してくれますが、日本語もOKです。
  
```言語:Stable-diffusionフォルダ上

python scripts/txt2img.py --prompt "a photograph of an astronaut riding a horse" --plms 

```

* 公式のシュールな画像が見る事ができます。

***
* 私は海外でも有名なあの方を入力してみました。

```言語:Stable-diffusionフォルダ上

python scripts/txt2img.py --prompt "(有名人の名前)" --plms 

```
![grid-0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/2f29bee0-9fba-a4ee-220a-15903d361e76.png)


* 日本語でも入力できますが、自社の様子など惨憺たる結果が出てがっくりしました。
* huggingfaceらしいなぁって感じがとてもします。

***

# 5. img2imgをためしてみる。

* 世にいうAIが絵画コンクールで賞を取ってしまったのはこっちのコマンドでしょうかね？
    * こちらは元ある画像→＜キーワード＞⇒画像の相関の強さ（0～1.0）でできます。
    * オプションもあるので、それを組み合わせるといいでしょう。
    
**サンプル**
* 当社が誇る作家が作成した有名人をこれまた世界的に有名な漫画・アニメに掛け合わせた結果です。
![grid-0046mn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/1c24e7df-3bd9-4108-e6cc-25a6ca8cc530.png)

:::note info
インフォメーション
オリジナルはホントに萌え～です
:::

* 公式では風景がをこんなコマンドラインで入力しています。

```言語:Stable-diffusionフォルダ上
python scripts/img2img.py --prompt "A fantasy landscape, trending on artstation" --init-img <path-to-img.jpg> --strength 0.8

```


# 6. HW要求は厳しい

* 公式でも10GB以上のVRAMが最低ラインと言っていました。
    * 実際、500ピクセル越えの画像はPythonに16GB取られて足りないだの怒られました。
    * ピクセル数が足りても”PyTorch runtime error : invalid argument 0: Sizes of tensors must match except in dimension 1”が出ると画像の縦横比率が合わない事があります。
    * これだけ値を入れたいのに突っ込めないと怒られています。
    
https://stackoverflow.com/questions/54417736/pytorch-runtime-error-invalid-argument-0-sizes-of-tensors-must-match-except-i

:::note info
妄想
GPT3使わせてくれないかな・・・Tesla使いたいなぁ…3090じゃ足りない！
:::

## 追記2(2022/9/25追加)

:::note info
インフォメーション
* VRAM10GB 以上が最低ラインと公式Gitでもありましたが、12GBのRTX3060ではメモリ不足を起こしてしまいました。
* 公式サンプルでtxt2img.pyを動かす際に出力する画像サンプルを減らして"--n_sample 1"など製品に応じて調整が必要でした。
* 出力数やサイズ調整はimg2img.pyでも必要になります。
* 速度よりも出力を重視したフォーク版を使ってみましたが、こちらの方が倍以上の速さです(画像半分になったけど・・・）
:::
[CUDA] 速いカーネルを書くために

## メモリの階層構造
グローバルメモリ >> コンスタントメモリ > シェアードメモリ >> レジスタ

## スレッド間のデータ共有手段
グローバルメモリ経由 >> シェアードメモリ経由 > ワープシャッフル命令(同一ワープ内のみ)

## グローバルメモリのアクセスパターン
ストライドアクセスは避ける。目指せコアレスアクセス、アラインアクセス
ランダムアクセスはストライドアクセスよりよっぽどまし。
ロード、ストア命令回数が少なくなればなるほどいい

## シェアードメモリのアクセスパターン
ハードウェアによって違うが、２次元的にアクセスしていて、取り出し口は一次元的なので、バンクコンフリクトしないようにワープ内でコアレスアクセスするのがいい。
ストライドアクセスするときは、パディングを入れて、無理やりバンクコンフリクトを回避するのも一つの手。
最悪３２倍の命令が必要になる場合もありうる(ストライドアクセス)

## レジスタの使用量
レジスタはすべてのスレッドで分けて使う。なので、使用レジスタ数が少なくても十分早ければ別ストリームによる並列化もできて最高。遅ければ一スレッドあたりの仕事を増やして、使用レジスタ数を増やしてやるのも吉。

## シェアードメモリの量とL1キャッシュの量はトレードオフ
シェアードメモリを使うなら徹底的に使え

## nvprofとかを使って律速の確認や、各メトリクスを確かめろ
バンクコンフリクトの回数とか、いろんなメトリクスを調べられる。

## 上の指針は目安であって、確かめろ！
計測しながらやれ！

## 計算アルゴリズムは何よりも大事
計算方法のレベルでは最適化が簡単にはできないがオーダーレベルで良くなるのでやれ！
上の指針は定数倍しかよくならない。

## 以上を忘れないこと。
ボットハーダー とは

## 勉強前イメージ

なんだっけ・・・悪いやつの中心核とかだったっけ？

## 調査

### ボットハーダー とは

[ボットネット](https://qiita.com/miyuki_samitani/items/99446bd186dbe571a1b2) を統制してサイバー攻撃などを行うクラッカーのことを指します。
元々は羊飼いみたいな意味で、多数のボットネットを操ることから名付けられました。

しかしボットネットを特定したからと言っても元々のボットハーダーを特定することは難しいです。
理由といては、乗っ取ったコンピュータの通信記録はもちろん改ざんしたり削除を行いどこから通信されているかわからない状態にします。
またボットハーダーから直接コンピュータに接続せずに他の乗っ取ったコンピュータを経由して通信するなど
発信元を徹底的に隠して行うためです。

また、ボットハーダーは直接ボットネットに指令を行うのではなく [C&Cサーバ](https://qiita.com/miyuki_samitani/items/76df7e5db1589d4ba447) を仲介して指令を行います。
イメージとしては以下になります。

![12022-09-14 # ボットハーダー とは.drawio - diagrams.net - Go.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/fcf9ad85-d76d-b7ec-5aa0-4959afbf7c17.png)

## 勉強後イメージ

ボットハーダーとボットネットの間にC&Cサーバがいるのか・・・
ココがわからんかった。

## 参考

- [ボットネット 【botnet】 ゾンビクラスタ / zombie cluster](https://e-words.jp/w/%E3%83%9C%E3%83%83%E3%83%88%E3%83%8D%E3%83%83%E3%83%88.html)
- [マルウェアのボットの仕組みを解説！](https://itmanabi.com/malware-bot/)
【C】初めてのC言語（19. 文字列とバッファオーバーフロー）

# はじめに

* これまでの学習に続いて、今回は文字列の基本的な操作について学んだ結果をまとめてみました。
  * [【C】初めてのC言語（1. Hello world）](https://qiita.com/nkojima/items/518c1a4ec06861d74b3c)
  * [【C】初めてのC言語（2. 四則演算とフォーマット指定子）](https://qiita.com/nkojima/items/36ea93b7296ce9e8a55b)
  * [【C】初めてのC言語（3. ポインタ）](https://qiita.com/nkojima/items/825bb9f931016faccd68)
  * [【C】初めてのC言語（4. 構造体）](https://qiita.com/nkojima/items/40a1101f2f6f5800bc2d)
  * [【C】初めてのC言語（5. 関数）](https://qiita.com/nkojima/items/1fa3317c04f25fe24276)
  * [【C】初めてのC言語（6. 配列）](https://qiita.com/nkojima/items/eda3ff6675b47e7ab5f0)
  * [【C】初めてのC言語（7. for文）](https://qiita.com/nkojima/items/a5659098f7e5275a96ec)
  * [【C】初めてのC言語（8. 2次元配列）](https://qiita.com/nkojima/items/f5eb25a4f8d1725faa89)
  * [【C】初めてのC言語（9. 関数のプロトタイプ宣言）](https://qiita.com/nkojima/items/57318d74bdfa670bf72e)
  * [【C】初めてのC言語（10. 構造体配列）](https://qiita.com/nkojima/items/75530a3ca63924a14397)
  * [【C】初めてのC言語（11. ヘッダファイル）](https://qiita.com/nkojima/items/a10cd943ed66e0cea7fd)
  * [【C】初めてのC言語（12. 3つのからくり構文＋ポインタ演算）](https://qiita.com/nkojima/items/83cb40ec01cd6a6e6a87)
  * [【C】初めてのC言語（13. メモリを扱う標準関数）](https://qiita.com/nkojima/items/13c8d942f282beb3c212)
  * [【C】初めてのC言語（14. ヒープの利用）](https://qiita.com/nkojima/items/837557cc86ce9697611a)
  * [【C】初めてのC言語（15. sizeofの注意点）](https://qiita.com/nkojima/items/6c9a3ba04c6348219578)
  * [【C】初めてのC言語（16. 文字列の基本）](https://qiita.com/nkojima/items/d87ce0cb15dd1a26f21a)
  * [【C】初めてのC言語（17. 文字列リテラル）](https://qiita.com/nkojima/items/527ef37d84cf9b201dc5)
  * [【C】初めてのC言語（18. 文字列の受け渡し）](https://qiita.com/nkojima/items/a07ac9a9bb3b41296f1e)


# 学習環境

* 今回は[paiza.io](https://paiza.io/ja/projects/new)のC言語のエディタを使いました。

# 終端文字とバッファオーバーフロー（オーバーラン）

* 以下のように終端文字「\0」を上書きしてしまうと、`printf`関数は「\0」が現れるまで探し続けることになります。
* そのため、配列として確保していない領域（※100バイト目以降）にもアクセスしようとして、バッファオーバーフローを引き起こしてしまう可能性があります。
  * paiza.ioの環境ではバッファオーバーフローは発生しませんでしたが...

```c:Main.c
#include <stdio.h>
int main(void){
    char str[100] = "Hello";
    str[5] = '!';  // 終端文字「\0」が失われてしまう！
    
    printf("%s\n", str);
    return 0;
}
```

# バッファオーバーフローを起こす例

* 以下のコードでは256バイトのバッファ`buff`を用意して、`gets`関数で標準入力を受け取って`buff`に読み込みます。
  * `gets`関数は、読み込んだ文字列の末尾に終端文字「\0」を加えます。
* この時、`gets`関数は読み込むバイト数に制限が無いため、256バイトを読み込んでも終端文字が現れないとバッファオーバーフローが発生します。
  * このような事故を防ぐため、現在では標準入力を受け取る場合は`fgets`関数を利用します。
* また、paiza.io上で以下のコードを実行すると、`warning: the 'gets' function is dangerous and should not be used.`というwarningが発生しますが、これは2011年に改訂されたC11規格以降の標準Cライブラリにおいて`gets`関数が廃止されたことが原因です。
  * @SaitoAtsushi さん、コメント欄にてご指摘および丁寧な解説を頂き、ありがとうございました。


```c:Main.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    char buff[256];
    gets(buff);  // 256バイトを超えても終端文字が現れないとバッファオーバーフローが発生する！
    
    printf("入力値：%s\n", buff);
    return 0;
}
```


# 参考URL

* [スッキリわかるC言語入門 第2版](https://www.amazon.co.jp/dp/4295012785/)
  * p.413～p.416
* [バッファオーバーラン - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%83%95%E3%82%A1%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%83%B3)
  * 「C言語特有の例」を参照。
* [gets - Wikipedia](https://ja.wikipedia.org/wiki/Gets)
【VBA】VBEのシンタックスハイライトは何色にするのがいいんだろう

VBEのシンタックスハイライトを背景黒に合わせて変更したい。
でもせっかくなら流行りに合わせたい、ということでいくつかサイトで調べてみました。

|サイト（外部リンク）|背景色|標準コード|コメント|キーワード|識別子|
|-|:-:|:-:|:-:|:-:|:-:|
|初期設定|自動（白色）|自動（黒色）|緑色 |青色 |自動（黒色）|
|[Qiita（@yukgaejangbowser）](https://qiita.com/yukgaejangbowser/items/0685400d2359bbe98a44)|黒色 |黄色 |灰色 |水色 |白色 |
|[Qiita（@nobunobunobupepe）](https://qiita.com/nobunobunobupepe/items/9621de8be21ad3ccfb07)|黒色 |緑色 |灰色 |青色 |白色 |
|[Qiita（@YuichiTanaka007）](https://qiita.com/YuichiTanaka007/items/1159318131550126d040)|黒色 |白色 |濃いグレー |黄色 |黄緑色|
|[Qiita（@msht0511）](https://qiita.com/msht0511/items/8b8928dd6cfa0278ba2a)|黒色 |黄色 |緑色 |水色 |白色 | 
|[Learning Note](https://konifug.hatenablog.com/entry/2017/05/16/004611)|黒色 |黄色 |濃いグレー |水色 |白色 |
|[いつも隣にITのお仕事](https://tonari-it.com/excel-vba-vbe-syntax-highlight/)|黒色 |黄色 |濃いグレー|水色 |白色 |
|[和風スパゲティのレシピ](https://www.limecode.jp/entry/vbe/syntax-highlight)|黒色 |黄色 |黄緑色 |水色  |白色 |
|[SAMURAI ENGINEER Blog](https://www.sejuku.net/blog/111660)|黒色 |黄色 |濃い緑色 |水色 |白色 |

初期設定だと同じ色にされてる標準コードと識別子ですが、**標準コードは黄**、**識別子は白**と分けてる方が多いです。
標準コード（コードにベタ書きの値）が見分けやすくなるのは大きなメリットだと思うので、特に初期設定で困ってない人もここだけは変えといたほうがいいでしょう。

コメントは初期設定だと緑色ですが、灰色に変更してる方が多いですね。緑色系のままの方もいるのでここは好みで分かれそうです。
キーワードは初期設定の流れのまま青色系にしてる方が多いようです。

## 参考：シンタックスハイライトの変更方法
個人的に以下のブログが一番わかりやすかったのでご参照ください。

https://www.limecode.jp/entry/vbe/syntax-highlight
Docker 版 Redmine の主副サーバ運用(Mac)


リモートワーク全盛の今日このごろ。

私的事情で環境が変わったこともあり、MacBook(自宅就業時には持ち帰り。以降、副サーバ)の中に Docker で redmine を入れて、自分の進捗管理やその他の資料保存をしていたが、上司同僚にもイントラで公開する必要が出てきた。と言うことで、私の自宅就業時に、上司同僚が閲覧出来ない状態は都合が悪い。

そこで、デスクトップ端末(Mac mini: 以降、主サーバ)の方にも redmine を立てて同期させ、そちら側を閲覧してもらう事に。


|サーバ|IP|目的|
|:-:|:-:|:--|
|主|XXX.XXX.XXX.XXX|閲覧のみ|
|副|YYY.YYY.YYY.YYY|編集及びリモートワーク時の閲覧用|


**背景**

- 主副双方とも M1 チップの mac。
- この redmine については、ユーザが自分のみのため、主サーバの方の権限変更などは考慮していない。
<br>



----

## 0. 主副サーバ双方の Docker のインストール

***先人達の情報と大差ない*** ので要点のみ。
 

brew で docker のアプリ, docker-compose をインストールした。設定に顕著な変更は加えていない。
FILE SHARING に、以下のディレクトリを登録している。

```
/opt/docker/redmine/plugins
/opt/docker/redmine/themes
/opt/docker/redmine/files
/opt/docker/redmine/db
```

<br>


## 1. 副サーバの Docker 版 redmine の構築状況

***先人達の情報と大差ない*** ので要点のみ。

[参考URL](https://qiita.com/TakSus/items/1f8bf5eab24548a7ed28) の他、色々と情報がある。

私の場合は、


```
/opt/docker/redmine
+-- docker-compose.yml
+-- plugins/
+-- themes/
+-- files/
+-- db/
(etc...)
```

な状態で `docker-compose up -d` している。プラグインやテーマを複数個入れているが、本稿では触れない。

一応 docker-compose.yml のみ記載する。

<details>
<summary>docker-compose.yml</summary>


```yaml:docker-compose.yml
version: '3.8'
services:
  redmine:
    container_name: redmine
    image: redmine
    restart: always
    ports:
      - 3000:3000
    volumes:
      - ./plugins:/usr/src/redmine/plugins
      - ./themes:/usr/src/redmine/public/themes
      - ./plugins:/usr/src/redmine/files
    environment:
      REDMINE_DB_MYSQL: redmine-db
      REDMINE_DB_PASSWORD: redmine
  redmine-db:
    image: mariadb
    container_name: redmine-db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: redmine
      MYSQL_DATABASE: redmine
    volumes:
      - ./db:/var/lib/mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
```

</details>

<br>

## 2. 副サーバから主サーバへの移植

***<font color=red>初回のみ。</font>***

### @副サーバ

**イメージの tar 玉化**

```
% pwd
/opt/docker/redmine
# 動いていたら止める。
% docker-compose stop   
# イメージの tar 玉作成。ひとつにまとめている。
% docker save -o redmine.tar redmine mariadb
%
```

[^1]

[^1]: image の名前は、`docker images` で確認可能。つか docker-compose.yml に明記してある。

<br>

### @主サーバ

**tar 玉他、データコピー**

```
% rsync -av bunzaemon@YYY.YYY.YYY.YYY:/opt/docker/redmine/ /opt/docker/redmine
%
```

`bunzaemon@YYY.YYY.YYY.YYY` はもちろん副サーバのもの。

<br>

**イメージの読み込み**

```
% cd /opt/docker/redmine
% docker load < redmine.tar
%
```

**起動**

```
% docker-compose up -d --build
%
```


<font color=red>--build を付けないと、素のイメージを呼び、添付ファイル等が上手く表示されない状態となる。</font>

<br>

他のマシンから `http://XXX.XXX.XXX.XXX:3000`(主サーバ) にアクセスして表示されたら成功。

<br>


## 3. 次回以降の同期

後は、副サーバに更新が入ったタイミングで、主サーバの方で 

### @主サーバ

```
% pwd
/opt/docker/redmine
# docker-compose の停止
% docker-compose stop 
# データの同期
% rsync -av bunzaemon@XXX.XXX.XXX.XXX:/opt/docker/redmine/ /opt/docker/redmine
# 起動
% docker-compose up -d --build
%
```

すればいい。

もちろん、自力で同期スクリプトを作成して定時実行するのもアリ。

<br>
Homebrew 版 GitBucket の移植(Mac)


リモートワーク全盛の今日このごろ。

私的事情で環境が変わったこともあり、MacBook(自宅就業時には持ち帰り。以降、BU サーバ)の中に homebrew で gitbucket を入れて、ソースコード管理をしていたが、上司同僚にもイントラで公開する必要が出てきた。と言うことで、私の自宅就業時に、上司同僚が閲覧出来ない状態は都合が悪い。

そこで、

1. デスクトップ端末(Mac mini: 以降、主サーバ)の方に移植
2. 主サーバのイントラ公開

を行なう。

|サーバ|IP|目的|
|:-:|:-:|:--|
|主|XXX.XXX.XXX.XXX|閲覧編集(他者は閲覧のみ)|
|BU|127.0.0.1|リモートワーク時閲覧用|


**背景**

- デフォルトでの `brew services start gitbucket` による起動では、
	- 起動した PC にて、`http://127.0.0.1:8080` でしかアクセス出来ない。
	- レポジトリ等のデータは、 ~/.gitbucket 配下に保存される。
- 面倒なので、現状の最小限の修正で、移植及びイントラ公開がしたい。
- 主副双方とも M1 チップの mac。
- この gitbucket については、ユーザが自分のみのため、主サーバの方の権限変更などは考慮していない。


<br>

## 1. BU サーバの Homebrew 版 GitBucket の状況

readme に従い、

```
# インストール
% brew install gitbucket
# サービスの起動
% brew services start gitbucket
%
```

し、`http://127.0.0.1:8080` にアクセスしてデータを蓄積更新していた。

<br>

## 2. BU サーバから主サーバへの移植

### @BUサーバ

サービス停止

```
% brew services stop gitbucket
%
```

<br>

### @主サーバ

**gitbucket インストールと、起動確認**

```
% brew install gitbucket
# サービスの起動
% brew services start gitbucket
# 主サーバに GUI で入り
# http://127.0.0.1:8080
# にアクセス。確認が取れたらストップ
% brew services stop gitbucket
%
```

<br>

**homebrew.mxcl.gitbucket.plistの修正**

.plist 内部の --host オプションの引数をデフォルトの 127.0.0.1 から、主サーバの IP(XXX.XXX.XXX) ヘ変更する。

```
# /PATH/TO は、homebrew のデータがある場所。私の場合は、/opt。
# 4.37.2 は数値違いの可能性有り。
% cd /PATH/TO/homebrew/Cellar/gitbucket/4.37.2
% cp homebrew.mxcl.gitbucket.plist homebrew.mxcl.gitbucket.plist.bak
# homebrew.mxcl.gitbucket.plistの修正
% vi homebrew.mxcl.gitbucket.plist
% diff homebrew.mxcl.gitbucket.plist homebrew.mxcl.gitbucket.plist.bak
13c13
<    <string>--host=XXX.XXX.XXX.XXX</string>
---
>    <string>--host=127.0.0.1</string>
```

<font color=red>~/Library/LaunchAgents/homebrew.mxcl.gitbucket.plist は、`brew services start gitbucket` 実行時に上書きされる。</font>
本稿では、`brew services` を利用予定のため修正対象とはならない。


<br>

**~/.gitbucket/ の移植と修正**

gitbucket.conf の `base_url=http\://127.0.0.1\:8080` を
`base_url=http\://XXX.XXX.XXX.XXX\:8080` へ編集する。

```
% cd 
% mv .gitbucket .gitbucket.bak
% rsync -av bunzaemon@YYY.YYY.YYY.YYY:.gitbucket .
% cd .gitbucket
% vi gitbucket.conf
# バックアップ取り忘れのため diff は無し。
%
```

<br>

**起動**

```
% brew services start gitbucket
%
```


<br>

他のマシンから、`http://XXX.XXX.XXX.XXX:8080`(主サーバ) にアクセスして乱れ無く表示されたら成功。

後は、普通に運用すれば良い。


<br>

## BU サーバへのバックアップ


### @BU サーバ


```
% brew services stop gitbucket
% cd 
% rsync -av bunzaemon@XXX.XXX.XXX.XXX:.gitbucket/ .gitbucket
% cd .gitbucket
# gitbucket.conf の `base_url=http\://XXX.XXX.XXX.XXX\:8080` を
# `base_url=http\://127.0.0.1\:8080` へ編集する。
% vi gitbucket.conf
% brew services start gitbucket
%
```

<br>

基本的には、自宅就業時のデータの `push` は翌日以降に出社した時に、主サーバへ行なう方針で。

<br>
有料のEIPが削除できないので原因を特定してみた

先日、AWSで基本的なネットワークを構築していました。数日放置していると料金もバカにならないため一つひとつの設定項目を削除していました。

そうすると、、あれ・・EIPが解放できない・・！？
![スクリーンショット 2022-09-14 20.05.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/83656eaf-eb1f-1603-0a38-710ad4b5cf79.png)

手順としてはEIPを解放して削除することができるのですが、、これはどうなっているのだろう・・

調べてみるとAWSサポートに問い合わせしなければならない、アカウントロックされているなどのことが書かれていました。

このほかにもVPCを削除しようとすると「VPC内にインスタンスがあるので削除できません」のエラーが出ました。

たしかに。まだインスタンスを終了していないかった。インスタンスを終了してまた試すと今度は、、「ネットワークインターフェースがあるので削除できません」となるエラーが、、、

ネットワークを削除しようとするとまた新たなエラーが。。。なんだかよくわからなくなりました。

調べてみると[EC2ダッシュボード]-[ネットワークインターフェースの概要] -［説明］にあるAWSのサービスに紐づいていて、こいつを削除しないとできないんだとか。

![スクリーンショット 2022-09-14 20.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/89cb7c9f-2728-d33b-d69f-2b6148033106.png)

つまり今回の場合はNATゲートウェイ。というわけでNATゲートウェイが邪魔だということでNATゲートウェイを削除します。


![スクリーンショット 2022-09-14 20.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/0f07d79b-0b0a-a9c6-b662-3e6cd4d381e8.png)

そうするとネットワークインターフェースを削除できるようになったので、、、削除のボタンを押します。

![スクリーンショット 2022-09-13 23.40.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/c8db04e2-3cfa-a567-74b4-c63b94647bb1.png)

はい！これで削除しました！

![スクリーンショット 2022-09-14 20.40.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/8e9ab1ce-beff-5593-c52f-f6c1146c22d2.png)

そうするとElasti IPアドレスの解放が表示されるように！

あぁ〜よかった、これで余計に課金せずに済む！

よく調べてみるとVPCやネットワークインターフェース、NATゲートウェイなどは互いに依存関係にあり、元となるサービスを終了させないと削除できないんだとか。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/troubleshoot-dependency-error-delete-vpc/

たしかに、私、SESのエンジニアなんですけど、貸し出しているPCを返すときは中身を初期化してから返却しますよね。それが今回はEC2とNATゲートウェイ、ネットワークインターフェースだったということでした。

## 今回参考にした記事
【Amazon VPC を削除しようとしましたが、依存関係によるエラーが発生しました。Amazon VPC を削除するにはどうすればよいですか?】
https://aws.amazon.com/jp/premiumsupport/knowledge-center/troubleshoot-dependency-error-delete-vpc/


【AWS VPC で ネットワークインターフェイス をデタッチまたは削除する方法】
https://cloud5.jp/elastic-network-interface/

ほかにもこんな記事を書いています！ぜひ興味があれば読んでいってください！

https://qiita.com/mmurm/items/1d42ab3d47dd85e4efbd

https://qiita.com/mmurm/items/de7b641e376685fad71e

https://qiita.com/mmurm/items/2437bf57ed4516f80dfa
ubuntu 20.04 VNC Server のインストール

# インストール

- server install
```
sudo apt install tigervnc-standalone-server -y
```

- 設定ファイルを

`xstartup`という名前のファイルを`~/.vnc`内に作成

```
#!/bin/bash

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
vncconfig -iconic &
dbus-launch --exit-with-session gnome-session &
```
実行権限付与
```
sudo chmod +x ~/.vnc/xstartup
```

# 自動起動設定

- serviceファイル作成

`/etc/systemd/system/vncserver@.service`というファイルを作成`hoshina`の部分を自分のユーザー名に変更する

```bash:/etc/systemd/system/vncserver@.service
[Unit]
Description=Start TightVNC server at startup
After=syslog.target network.target

[Service]
Type=forking
User=hoshina
Group=hoshina
WorkingDirectory=/home/hoshina

PIDFile=/home/hoshina/.vnc/%H:%i.pid
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 -localhost :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target
```

- serviceの起動

```
sudo systemctl daemon-reload
sudo systemctl enable vncserver@1.service
sudo systemctl start vncserver@1
```

# 確認

```
vncserver -list
```

以下のように出力されればOK(※PROCESS IDのあとに、英語でなんか書かれていたらvnc serverの起動失敗してい)

```
TigerVNC server sessions:

X DISPLAY #	RFB PORT #	PROCESS ID
:1		5901		907
```



# 参考

- vncserverの自動起動方法
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-20-04-ja

# おまけ

## vncクライアントのインストール

- vncのクライアント取得

```
wget https://downloads.realvnc.com/download/file/viewer.files/VNC-Viewer-6.22.515-Linux-x64.deb
sudo dpkg -i VNC-Viewer-6.22.515-Linux-x64.deb
```

- 実行

```
vncviewer
```

## vnc server手動実行

```
vncserver --local no :1
```
プログラミングでよく使う比較的間違えやすそうな英単語集

# 記事の目的

どうもー、[N予備校](https://www.nnn.ed.nico/)でプログラミングをせっせせっせと勉強中のふーちんです！
前置きは短くしたいので早速本題に入るのですが、プログラミングでは、変数やIDは基本半角英数字ですよね。
そういう場合名前を英語にしなければいけません。
ローマ字も一つの手ですが、僕は「どうせなら英語派」です。
それで、プログラミングでよく使う比較的間違えやすそうな英単語を表にしてみました。
「そんなん間違えへんやろ」っていう単語もあるかもしれませんが、まあまあ。
今後も単語を追加していく予定です。

# 単語集

| 日本語 | 正解 | 間違い | ひとこと |
|:-:|:-:|:-:|:-:|
| 作成 | create | criate | スペルは「クレアテ」！ |
| 削除 | delete | delate | ↑と語尾を同じにしてしまいそう |
| ドキュメント | document | docment | 「u」あるんですね～ |
| 公衆 | public | publik | 「c」なんですね～ |
| ライセンス | license | lisence | `c`と`s`、どっちが先かは<br>アルファベット順と覚えておこう |
| データ | data | deta | スペルは「デタ」ではなく「ダタ」 |
| インポート | import | inport | 「ポ」は口を閉じてから発音なので<br>「ン」の後にくる場合は「m」になる |
| レスポンス | response | responce | 「s」なんですね～ |
| リリース | release | releese | 「ea」で「イー」って読むのかな |
| デフォルト | default | defalt | でふぁうると |
| 成功 | success | sucsess | s→cc→ss |
| 背景 | background | backgraund | スペルは「グロウンド」！ |
| ランダム | random | randam | スペルは「ランダｍ」ではなく「ランドｍ」 |

まだこんだけしかありませんが、今後も増やしていく予定です～～

# 最後に

### 参考にしたページ
- https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923

### 感想
僕自身英語はそんなに話せませんが、プログラミング初心者である限り、こういうことを知っておこうと思いました。
これからもプログラミング頑張ります！
ありがとうございました～！
Windows11での簡単な環境構築

# はじめに

Windows11を買ってからの簡単な環境構築例の記事です。
パッケージマネージャーにはwingetを使用しています。

# 前提

インストールに使用するツールについて紹介します。

## Terminal

Windows11で登場したターミナル。Windows11では標準で存在すると思いますので、これを使用して環境構築していきます。
Windows11以外では標準で存在しませんが、PowerShellやコマンドプロンプトなどで代用できますし、別途インストールできます。
スタートメニューを右クリックして、「Terminal」をクリックすると起動することができます。

## winget

この記事で使うWindows11で標準で存在するパッケージマネージャー。
最近登場したMicrosoft公式のWindows用パッケージマネージャーでこれからメジャーになっていくと思われるので採用します。
こちらもWindows11以外では標準で存在しませんので入っていない場合は別途インストールしてください。

wingetがあるかを確認するには、以下のようなコマンドをTerminalで入力してバージョンが出てくればOKです。
```powershell:PowerShell
winget --version
```

# インストールするソフト

ここでは、Google Chrome、PowerShellの最新バージョン、Visual Studio Codeのインストール例を紹介していきます。

## Google Chrome

まず買ってから、Microsoft Edgeを開いてGoogle Chromeをインストール、でもいいですが、先ほど述べたwingetでインストールすることができます。
スタートメニューを右クリックして、「Terminal」を開いて以下のようなコードを入力しましょう。

```powershell:PowerShell
winget install -e --id Google.Chrome 
```

※ eオプションはexactの省略で、入力したキーワードに完全一致するパッケージを指定するオプションです。主にidと併用します。

## PowerShellの最新バージョン

標準で入っているPowerShellは古いバージョンなので、最新バージョンをインストールしておきましょう。

```powershell:PowerShell
winget install -e --id Microsoft.PowerShell
```

先ほどと同様これでインストール自体はOKなのですが、TerminalでインストールしたPowerShellを使用するには、既定のプロファイルを変更する必要があります。

Terminalの下の画像の赤枠のボタンから設定を開き、
![s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359398/70f5e663-33fc-bd6b-6772-81fec70ca11f.png)


下の画像のように既定のプロファイルをWindows PowerShellからPowerShellに変更して保存しておいてください。
![s2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359398/997dc6f3-f966-62c3-3485-143eab88a79a.png)

## Visual Studio Code

こちらはGoogle Chromeと同様の手順でOKなのですが、フォルダやファイルを右クリックして「Codeで開く」を利用したい場合オプションを加える必要があります。

```powershell:PowerShell
winget install vscode --override "/silent /mergetasks=""addcontextmenufiles,addcontextmenufolders"""
```

ちなみに、Windows11は右クリックメニューが変わって「その他のオプションを表示」を押さないと「Codeで開く」は出てきません。レジストリを編集するなどして昔の仕様に戻してもいいですが、**Shiftを押しながら右クリック**しても一発で「Codeで開く」は出せるので、ぜひご活用ください。

# まとめ

Windows11での簡単な環境構築例をまとめてみました。他にもいろいろなソフトを入れたいという方は、基本的にはGoogle Chromeのようなやり方でOKなので調べてみてください。

### 参考文献

- winget.run
  <https://winget.run/>
- Windows 10搭載PCを買ったら最初にやっておきたいこと【開発者編】
  <https://news.mynavi.jp/techplus/article/20210622-1904714/2>
- Windows: winget: wingetでオプション付きで、アプリをインストールする
  <https://zenn.dev/atsushifx/articles/winget-install_deep>
- winget で vscode をインストールする - proudust.github.io
  <https://proudust.github.io/20200726-winget-install-vscode/>
Ansible Tips: shellモジュールの途中経過ログをansible-playbookのログと一緒にリアルタイムで表示する例

https://qiita.com/hiroyuki_onodera/items/2fa11aeb3598284dbe54
の続き

あまり綺麗なやり方ではないが、一応できるということで、備忘として残す。

# 目標: ansible-playbookのログとshellモジュールのstdout, stderrを同じ画面に表示したい。

# 方法: tail -fをバックグラウンドで実行したターミナルでansible-playbookを実行

## タスクの例

```yaml:tasks
  - name: terraform apply --auto-approve
    shell:
      executable: /bin/bash
      cmd: |
        exec &> >(tee -a "/tmp/ansible_shell.log") 
        set -x
        cd terraform
        terraform apply --auto-approve
```
## 実行例 (対象がローカルノード)

- tail -fをバックグラウンドで実行し、ログファイルを実行ターミナルにもリアルタイムに出力させておく
- その後、ansible-playbookを行うと、ansible-playbookのログとshellモジュールのstdout, stderrが同じ実行ターミナルに表示される事になる


```
$ touch /tmp/ansible_shell.log

$ tail -f /tmp/ansible_shell.log &
[1] 87649

$ ansible-playbook -i localhost, -c local site.yml
...

TASK [terraform apply --auto-approve] ******************************************
+ cd terraform
+ terraform apply --auto-approve
Acquiring state lock. This may take a few moments...
ibm_pi_volume.ds_volume_share2: Refreshing state... [id=976c66a7-d403-4432-8ddb-f876cce6db0d/b7308887-0380-4f2d-a4e2-5ab8d6bada6a]
data.ibm_pi_network.power_networks_private: Reading...
...

Apply complete! Resources: 18 added, 0 changed, 0 destroyed.

changed: [localhost]

...
```

バックグラウンドtailを停止するには

```
% jobs
[1]  + running    tail -f /tmp/ansible_shell.log
$ kill %1
[1]  + terminated  tail -f /tmp/ansible_shell.log  
$       
```

まあ、普通は別ターミナルで見ると思いますが。。


## リモートノードの場合

- sshでtail -fを行なっておく

```
$ ssh remote_node "touch /tmp/ansible_shell.log; tail -f /tmp/ansible_shell.log" & 
[1] 89800
[1]  + suspended (tty input)  ssh remote_node "touch /tmp/ansible_shell.log; tail -f /tmp/ansible_shell.log"
$ ansible-playbook -i remote_node, site.yml 
...
```
扇形(circular sector)の面積「2022年 早稲田本庄高等学院 数学[2]」をsympyでやってみた。 

オリジナル:ますいしい様

https://ameblo.jp/mathisii/entry-12734081753.html

# sympyで(ますいしい様の手順で)
勉強中

# sympyで(大学受験流?)
放物線とPointで,13行でした。
```python
from sympy import *
x,y=symbols("x,y",real=True,postive=True)
O=Point(0,0)
F=x**2
C1=Circle(x**2 + y**2 - sqrt(2)    **2)
C2=Circle(x**2 + y**2 - (2*sqrt(3))**2)
Ax=solve(Eq(F,solve(C1.equation(x, y),y)[1]),x)[1]
Bx=solve(Eq(F,solve(C2.equation(x, y),y)[1]),x)[1]
A=Point(Ax,F.subs({x:Ax}))
B=Point(Bx,F.subs({x:Bx}))
E=C2.intersection(Line(O,A))[0]
D=Point(C2.radius,0)
I=Triangle(O,B,D).incenter
print("#問1",Bx,",",F.subs({x:Bx}))
print("#問2",O.distance(E)**2*Line(O,E).angle_between(Line(O,B))*Rational(1,2))
print("#問3",O.distance(I)-C1.radius)
#問1 sqrt(3) , 3
#問2 pi/2
#問3 2 - sqrt(2)
```


# 参考

https://ja.wikipedia.org/wiki/%E6%89%87%E5%BD%A2

https://en.wikipedia.org/wiki/Circular_sector
自然に見える画像の枠線を求めて

## この記事の概要

サムネイル画像やユーザーアイコンなど、どんな画像が適用されるか分からない要素ってありますよね。
そんな要素に対して、視認性を確保するためにborderをひいてあるのによく遭遇します。

そのborderが時折ちらついて見えるのが嫌だったので、改善策を考えてみました。

## 完成物＆通常のborderとの比較

全体像はこちらです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/9d52eff2-668d-f477-7f3d-f137007d184e.png)

差がわかりやすそうな部分をクローズアップしました。
左の画像の草、真ん中の画像の右端にあるペンケース（？）、右の画像の机や天井など「borderの方が明るい箇所」が悪目立ちしているというか、ノイズに見えて気になります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/116d04f9-5655-fabd-e26a-5695f6f22928.png)

修正版がこちらです。
左の画像の空や右の画像の窓など、白く飛んでいる場所にだけborderが見え、それ以外の箇所は元の画像を活かしています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/24a0c18c-d0d2-15a1-4aaf-418bf9d0ee16.png)

[CodePenはこちら。](https://codepen.io/xrxoxcxox/pen/poVEdXE)

## 仕組み

```html
<div class="adjusted-border"> <!-- 1 -->
  <img alt="" src="画像のパス">
</div>
```

```css
.adjusted-border {
  position: relative;
}

.adjusted-border::before {
  position: absolute;
  content: "";
  inset: 0; /* 2 */
  box-shadow: 0 0 0 2px rgb(220 220 220) inset; /* 3 */
  mix-blend-mode: darken; /* 4 */
}
```

1. 擬似要素を使う都合上、`img`単体では実現できないため`div`で包む
1. `div`の擬似要素を中身の要素と同じサイズに指定
1. `box-shadow`の`inset`を使い、`div`の領域の内側に線っぽく描画
1. `mix-blend-mode: darken;`で、線の方が暗いときだけ描画されるように変更

若干行数が多いものの、簡単にできました。

また、`mix-blend-mode: lighten;`にすれば、ダークモード用の描画（画像よりも明るい箇所だけ薄い白の線を引く）も実現できます。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox
【Laravel】脱MVCでアーキテクチャ的な事を試みる

## 行き着いた背景

Laravel、MVCだけの取り決めだと、書く人によってFatControllerになってたりFatModelになったりする。
これってどうにかならないの？と思い、Repositoryパターンもどきを実践してみた。

## やった事
大まかな役割を持たせた層を用意し、開発ルールを設けた。

### 層
以下の階層に分ける
- LivewireComponent/Controller 
- Service
- Repository
- Model


### 参照関係

```mermaid
flowchart TD;
LivewireComponent/Controller --> Service --> Repository --> Model

Service --> r2[Repository] --> m2[Model]

```


## LivewireComponent/Controller 

- ビジネスロジックは書かない
- アクセス可能な他の層はServiceのみ※Modelオブジェクトの定義は良い
- 単純にデータが欲しいだけの時も必ずServiceを仲介する


## Service
- ビジネスロジックは全てここに書く
- DB操作ロジックは書かない
- アクセス可能な層はRepository層のみ
- 極力他のServiceを呼び出さないようにする※共通処理はTraitにまとめれそうならまとめる

## Repository
- DB操作のロジックは全てここに書く
- 関連が強いModelの処理を集約させる
    - Userモデル、UserImageモデル、UserPostモデルなどUserに紐づく情報は全てUserRepositoryに集約させる

## Model
- リレーションの定義や、属性の定義のみ書く

## 課題
- Serviceクラスの切り分けが少し悩む
- 現状Serviceクラスに全てのロジックを入れている為、単純な処理置き場になっている
- ServiceからServiceへのアクセスをルールとして許している場合、改修する時に考えるべき影響範囲が増える
    - もう一つ層を挟むにしても、自分が取り扱うプロジェクト的にはオーバースペックな気もする

## 取り入れた感想
- どの層に何を書くかが明確になった為、切り分けがしやすくなった
- ルールを設けたので書く人によってのムラが少なくなった
- まだ開発途中だが、処理が色んな所にとっちらかないので改修などがしやすい。
- MVCのみで開発してきた人でもとっつきやすいので、脱MVCの第一歩に良さそう。


## 参考記事

https://deha.co.jp/magazine/introducing-laravel-repository/

https://qiita.com/mikesorae/items/ff8192fb9cf106262dbf

https://kaki-note-02.netlify.app/2020/11/22/
S3バケットポリシーをTerraformで書く方法まとめ

最近terraformを書いてインフラを構築する機会がありました。S3におけるバケットポリシーの書き方をまとめます。

## 前提
以下の二つです。
(1)ロードバランサーのログをS3に保存する。

(2)投稿した画像を加工するために、外部サーバーへ画像(そのURL)を渡します。その際外部の特定のサーバーがS3アクセスできるようにしなければなりません。

S3はアクセスコントロールのために３つの方法があります。
・ACL(アクセスコントロールリスト)
・バケットポリシー
・IAMポリシー
(1)に関して、はIAMユーザレベルの制御なので、バケットポリシーかIAMポリシーを使用します(今回は、書きやすそうなバケットポリシー)
(2)に関して、外部のサーバからのアクセスのため、ACLを利用します。
参考: (https://qiita.com/ryo0301/items/791c0a666feeea0a704c)


## TFのコード

(1)ロードバランサーのログに関して、
```
data "aws_iam_policy_document" "alb_log" {
  statement {
    effect    = "Allow"
    actions   = ["s3:PutObject"]
    resources = ["arn:aws:s3:::${aws_s3_bucket.alb_log.id}/*"]

    principals {
      type = "AWS"
      # Principalには、東京リージョン（ap-northeast-1）を指すElastic Load Balancing アカウント ID（582318560864）を記載する
      identifiers = ["582318560864"]
    }
  }
}

resource "aws_s3_bucket" "alb_log" {
  bucket = "${var.service}-${var.environment}-alb-log"
  lifecycle_rule {
    enabled = true

    // logの保存期間は180日
    expiration {
      days = "180"
    }
  }
}

resource "aws_s3_bucket_policy" "alb_log" {
  bucket = aws_s3_bucket.alb_log.id
  policy = data.aws_iam_policy_document.alb_log.json
}
```

のようにかけます。


真ん中のaws_s3_bucketにより、alb_logという名前のバケットを生成します。
ログの保存期間は、180日にするため、lifecyecleを有効(enabled = true)にし、
expirationにdays=180を指定します。


また、一番上のaws_iam_policy_documentを書くことで、alb_logという名の、ポリシードキュメントを定義できます(これは任意です)。

statement内部に設定を書いていきます。
effectには、AllowかDenyが入ります(デフォは、Allow)、今回は許可するためAllow。
actionsには、上で許可(拒否)した、アクションを入れます。今回は、ログを入れるためs3:PutObject。
resourcesには、どのS3に対して、許可したかを指定します。今回は、上で作成したalb_log以下に保存するため、arn:aws:s3:::${aws_s3_bucket.alb_log.id}/*

その下のprincipals引数には、ステートメントが適用されるユーザーを定義します(適用しない場合は、not_principals)。
typeには、AWS。ELBを設定しているリージョンのID(東京の場合は、582318560864).
(ちなみに、リージョンとIDの対応表はhttps://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html)

最後に、aws_s3_bucket_policyから、S3にドキュメントをデータソースをJSON文字列にして、アタッチします。

(2)二つ目の外部サーバーからのアクセスに関して、
```
resource "aws_s3_bucket" "private-files" {
  bucket = "${var.service}-${var.environment}-private-files"
}

resource "aws_s3_bucket_acl" "private-files" {
  bucket = aws_s3_bucket.private-files.id
  acl    = "private"
}
```
のように書きます。
アクセス制御はacl(デフォルトはprivate)を利用し、
private(所有者に FULL_CONTROL が付与される)を指定。
(その他参考https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/acl-overview.html#canned-acl)

その後アタッチして終了。



## 参考文献
aws_iam_policy_documentの書き方に関して
・https://zenn.dev/junkin_au/scraps/43af950cadf396
・https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration

IAMロールのprincipalに関して
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_principal.html

S3の設定に関して
https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html

S3のアクセス制御に関して、https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_access_point
サイトに表示するアニメーションをLottieで作る（Lottie編）

前回の記事で、AfterEffectsを使ったアニメーションを作成したのでサイトにアニメーションを実装する手順を説明します。

https://qiita.com/haruyoshi_o/items/b548c1191acafdf9de22

## 【流れ】
1）拡張機能「Bodymovin」をダウンロード、インストール
2）After Effectsで組み込みたいアニメーションを作成（前回の記事）
3）作成したアニメーションをBodymovinを使って書き出し
4）作成したJSONファイルをプレビュー確認
5）Webサイトに実装

### 1）拡張機能「Bodymovin」をダウンロード、インストール
プラグインをインストールするために最初に[ZXP Installer](https://zxpinstaller.com/)をダウンロードしてください。
次にlottieを使うためのプラグイン「[bodymovin.zxp](https://github.com/airbnb/lottie-web/blob/master/build/extension/bodymovin.zxp)」をダウンロードして[ZXP Installer](https://zxpinstaller.com/)へドラッグ＆ドロップします。
そして、メインメニューより「編集」>「環境設定」>「スクリプトとエクスプレッション」より「スクリプトによるファイルへの書き込みとネットワークへのアクセスを許可」にチェックを入れてください。こうすることでファイル出力が可能になります。
![スクリプトによるファイルへの書き込みとネットワークへのアクセスを許可.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1555848/3a383c99-3b69-eb09-1dd6-e79b1cbf39d2.jpeg)

### 2）After Effectsで組み込みたいアニメーションを作成（前回の記事）
「サイトに表示するアニメーションをLottieで作る（After Effects編）」という記事を書いたので参照ください。

https://qiita.com/haruyoshi_o/items/b548c1191acafdf9de22

### 3）作成したアニメーションをBodymovinを使って書き出し
メインメニューの「ウィンドウ」>「エクステンション」>「Bodymovin」をクリックすると、以下のウィンドウが開きます。
![書き出し.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1555848/0c7eb748-e58b-474d-1dd9-6e7b24af999c.jpeg)

書きだすコンポジションを選択して保存先を選択したら、Renderをクリックすると書き出しが実行されます。

### 4）保存したJSONファイルをプレビューで確認します。
JSONを書きだしたら下記のサイトにアクセスし、JSONファイルをドラッグ＆ドロップで追加するとアニメーションが確認できます。

https://lottiefiles.com/preview

![preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1555848/504a68b7-b466-b7ec-e7d7-c7c1204c3595.png)

### 5）サイトへの実装
サイトに実装する方法は2通りあります。
A）コードを自動生成して貼り付ける方法
B）JavaScriptを使用する方法

#### A）コードを自動生成し、貼り付ける方法
ページ右にあるアイコンのうちHandoff & EmbedをクリックしてEnable Asset LinkをオンにするとEmbedという欄にscriptタグから始まる埋め込み用コードが表示されます。
![embed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1555848/60ef9c7a-7b2a-0706-5c3b-1f73921351ab.jpeg)
これをコピーしてページに貼りけることでアニメーションが表示されます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="RwyrKMN" data-user="lvn_HO" 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/lvn_HO/pen/RwyrKMN">
  Untitled</a> by haruyosih (<a href="https://codepen.io/lvn_HO">@lvn_HO</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### B）JavaScriptを使用する方法
①アニメーションのJSONデータを用意します。
[GitHub](https://github.com/airbnb/lottie-web)からダウンロードするか[CDN](https://cdnjs.com/libraries/bodymovin)経由で読み込みます。
②アニメーションをサイトに組み込むためのプラグイン（lottie.min.js）を読み込みます。
③アニメーションを表示させるための箱を用意します。今回は
```
<div id="test"></div>
```
④以下のJavaScriptの設定を行います。
```
<script>
var animation = lottie.loadAnimation({
  container: document.getElementById("test"), //③で作ったIDを指定
  renderer: "svg", // svg・canvas・htmlの3種類から機能に応じて指定(省略可、デフォルトはsvg)
  loop: false, // ループの有無を指定(省略可、デフォルトはtrue)
  autoplay: true, // 自動再生の有無を指定(省略可、デフォルトはtrue)
  path: "animation01.json" //使用するJSONファイルがある実際のディレクトリ名・ファイル名を入れる
});
</script>
```
あとはサーバにアップすれば完了です。
【MYSQL】--initialize specified but the data directory has files in it. Aborting.エラーについて【Docker】

先日ポートフォリオアプリを作成中にMYSQLが立ち上がらずexited(1)になってしまったので、備忘録。

とりあえず原因を探るため

```
docker-compose logs
```
でログを読むと、、、
```
error --initialize specified but the data directory has files in it. Aborting.
error he designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.

```
との事。

色々とググって分からないなりに解釈して見た結果、データディレクトリ内の/var/lib/mysql/が邪魔だぞと
言っていそうなので/var/lib/mysql/のファイルを削除。

それでもエラーが治らないので、databaseフォルダ内の中身を全て削除で無事起動することができました！

自分の環境はNext.js×Rails×Dockerだったので、Railsの方が次はエラーになり、
db:migrateやdb:createを使ってdbを新しく作り直し無事apiサーバーとMYSQL両方とも立ち上げることに成功しました！！
【AZ-900 Microsoft Azure Fundamentals】合格体験記

## はじめに
2022年8月に、Microsoft Azure Fundamentals(AZ-900) 試験を受験しました。
AZ-900という試験に合格すると、Azure Fundamentalsに認定されます。Azureにはいくつか試験がありまして、これが一番初級の試験です。

Azureの案件に入ることが決まり、なにもわからなかったので受験しました。（AWSもGCPもほぼ未経験）そういうレベルの人の勉強方法とのことを念頭に参考にして頂けると良いかと思います。

Azure試験の中では一番簡単なレベルではあるものの、広く浅くAzureサービスについて問われる形になっているので、クラウド自体が初心者の場合はそれなりに勉強しておく必要があります。

## この記事の対象者
・Azure初心者

## 筆者のレベル
AWSの学習をしていた時期があるので、クラウドの基礎的なところは理解しています。
実務でのクラウド使用経験はほとんどなく、Azureに関しては全くの初心者です。

## 試験の概要
試験の概要を記載します。

【試験】AZ-900：Microsoft Azure Fundamentals
【試験会場】テストセンター、自宅または職場のオンライン
【受験手数料】￥13,200（税込）
【合否発表】メールで即時
【試験時間】60分
【試験形式】CBT（コンピュータを使用した試験）、選択式
【問題数】30～40問
【合格点】700点／1000点

## 試験結果
無事に合格しました。
805点/1000点と余裕を持って合格できたと思います。

## 勉強内容
【2022年版】AZ-900 Microsoft Azure Fundamentals模擬問題集（7回分430問）

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

教科書などは使用せず、いきなりUdemyの問題集で演習を行いました。
本番の試験とほぼ同じ内容となっていて、上記の問題集を正答率9割にできたら問題なく合格できると思います。


## 所感
試験の合格難易度はAWS認定クラウドプラクティショナーよりは簡単だと思います。クラウド初心者でも1週間程度で合格できます。

## 最後に
以上、Azure Fundamentals合格体験記でした。
この記事がお役に立てれば幸いです。
laravel9.x inertia vue3.2でsetup+lang="ts"での対応

laravel + inertia + vue3.2で
vueファイル内のスクリプトタグを`<script setup lang="ts">`とすると
laravel-echoをimportしているファイルで
Module cannot などエラーが出るため対応。
予め、`resources/js/@types`フォルダを作っておく。

#### tsconfig.jsonの設定
色々変えたのでどこが肝かわからないので一通り設定を記載する。
```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "baseUrl": "./",
     "typeRoots": [
        "./resources/js/@types"
    ],
    "types": [
      "node"
    ],       
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": false,
    "skipLibCheck": true
  },
  "include": [
    "./resources/js/**/*"
  ]
}
```

window.Pusherとwindow.Echoを別のtsファイルでも使えるようにするため
`resources/js/@types`フォルダにファイル`global.d.ts`を作成する。

```typescript:resources/js/@types/global.d.ts
interface Window {
  Echo: any;
  Pusher: any;
}
declare var window: Window;
```
これでとりあえずビルドも通ってlarave-echoのbroadcastの通知も来る。
他にいい方法がありそうだが。
【SQLite】DBを使った簡単なパスワード認証

## DBを使ったパスワード認証の方法を確認する

### 実行結果
```bash
$ python ./db.py

Please input user ID: mash
Please input user Password: xxxxx
-----------------------------------
Success! You are loged in as "MASH" 

```
+ 上記のように __ユーザID__ と __パスワード__ の入力を求められる

### 実行環境

+ __macOSX Monterey__
+ __Python 3.10.6__

### Pythonコード

```db.py
import hashlib
import sqlite3


# digest
def get_digest(password):
    pwd = bytes(password, 'utf-8')
    digest = hashlib.sha256(pwd).hexdigest()
    return digest


# DB connection
def get_id_pwd():
    ''' Connect to db and get id & pwd '''

    sqlite_path = 'user_db.sqlite'
    connection = sqlite3.connect(sqlite_path)
    cursor = connection.cursor()
    cursor.execute('select name, password from users')
    id_pwd_hash = dict(cursor.fetchall())
    connection.close()
    return id_pwd_hash


# Login check
def login_check():
    if user_id in id_pwd_hash.keys():
        if password == id_pwd_hash[user_id]:
            print('-' * 35)
            print(f'Success! You are loged in as "{ user_id.upper() }" \n')
    else:
        print('-' * 35)
        print('You are not permitted to login \n')


# Login input
user_id = input('Please input user ID: ')
pwd = input('Please input user Password: ')


# Execution
password = get_digest(pwd)
id_pwd_hash = get_id_pwd()
login_check()

```

### Database (user_db.sqlite)

![スクリーンショット 2022-09-14 15.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/28113185-7830-2385-8067-e128f6089e9d.png)


::: note info
__ポイント__

+ get_digest()関数で、引数としてターミナルで入力パスワードをハッシュ化する
+ SQLiteのDBに接続しIDとパスワードを取り出し、辞書（id_pwd_hash）の形にして返す
+ ハッシュ化されたパスワードをDBの値と照合する（DBのパスワードはハッシュ化された状態で保存されている前提）
+ ほぼこのまま、Flaskに実装可能
:::
Laravel CSVダウンロード

共通関数にでもしておき引数渡してダウンロード

```php
$csv = [
            ['id','user'],
            [1,'a'],
            [2,'b']
        ];

$file_name = 'CSV' . date('YmdHis');
$response = Csv::csv_download($csv, $file_name);
return $response;
```


```php
<?php

namespace App\Library;

use Illuminate\Support\Facades\Facade;
use Symfony\Component\HttpFoundation\StreamedResponse;

class Csv extends Facade
{
    public static function csv_download($data, $fileName)
    {
        $response = new StreamedResponse(function () use ($data) {
            $stream = fopen('php://output', 'w');

            //　文字化け回避
            stream_filter_prepend($stream, 'convert.iconv.utf-8/cp932//TRANSLIT');

            // データからcsv生成
            foreach ($data as $key => $value) {
                fputcsv($stream, $value);
            }
            fclose($stream);
        });

        $response->headers->set('Content-Type', 'application/octet-stream');
        $response->headers->set('Content-Disposition', 'attachment; filename="' . $fileName . '.csv"');

        return $response;
    }
}

```