OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】Tkinterで多言語翻訳アプリを作ってみた（Part 1）

# はじめに
以前から翻訳アプリを作りたくてウェブで調べていたら、googletransという便利なライブラリーがあったので作成してみました。
```md
環境
・Python3.10 64bit
・Windows11
```
# ライブラリーのインストール

# １．speech_recognitionのインストール

```md
%pip install SpeechRecognition
```
# 2．googletransのインストール

```md
%pip install googletrans
```
googletransについては、インストールの過程で苦戦しました。
Youtubeでソリューションがのっていたので、以下の動画を参考にしました。

https://www.youtube.com/watch?v=eMZEXTpIF4U

# googletransの言語リスト

googletransの提供している言語リストは、こちらのURLを参考にしてください。

https://cloud.google.com/translate/docs/languages?hl=ja

今回使用した言語は以下の2つです。
| 言語 | ISO-639－1コード                 |
| :------: | :--------------------------- |
| 日本語 | ja |
| スペイン語 |  es   

                                 













```python
import speech_recognition as sr
import googletrans
import gtts
import playsound
import tkinter

Bob = googletrans.Translator()

''' 入力する言語(日本語はja-JP)と出力する言語の指定。'''
input_lang = 'ja-JP'
output_lang = 'es'

'''翻訳ボタンの関数'''
def click_btn():
    text = text_a.get('1.0', 'end - 1c')
    translated = Bob.translate(text, dest = output_lang)
    text_b.delete('1.0', tkinter.END)
    text_b.insert(tkinter.END, translated.text)
    audio = gtts.gTTS(translated.text, lang = output_lang)
    audio.save('romantic.mp3')
    playsound.playsound('romantic.mp3')
'''消去ボタンの関数'''
def del_btn():
    text_b.delete('1.0', 'end -1c')

root = tkinter.Tk()
root.geometry('1000x1000')
root.title('多言語翻訳アプリ')
btn = tkinter.Button(text = 'Translation', font = ('Courier', 30), command = click_btn)
btn.place(x = 180, y = 700)
btn_d = tkinter.Button(text = 'DELETE', font = ('Courier', 30), command = del_btn)
btn_d.place(x = 550, y = 700)
text_a = tkinter.Text(width = 50, height = 10, font = ('Courier', 16), bg = 'lightyellow')
text_a.place(x = 150, y = 6)
text_b = tkinter.Text(width = 50, height = 10, font = ('Courier', 16))
text_b.place(x = 150, y = 400)

root.mainloop()
```
![gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2035661/844922c2-d987-eba2-dda9-d9a47cf411e5.gif)

翻訳した内容しか出てきてませんが、スペイン語も話します。
Chapter6　Eloquentの基本（6-1）

# ORMとは？

PHPとデータベースのレコードは基本的な仕組みが異なるので、
データベースのレコードをPHPの変数に入れるとなると、
「とりあえず、レコードは全部連想配列にまとめてしまえ」となるのはやむを得ない。

そこで、PHPのオブジェクトとデータベースの間の、
橋渡しをしてくれる仕組みが *「ORM」* と呼ばれる機能です。

*「ORM」* ＝　Object Relational Mapping

# Eloquentとモデル

Laravelには「Eloquent（エロクアント）」というORMが用意されています。

「モデル」のクラスを定義し、これを利用してデータベース操作を行えるように
設計されています。

モデルは、「テーブルの内容を定義したクラス」です。

# モデルを作成する

モデル作成するphp arisanコマンドを使用する。

```
 % php artisan make:model Person
```

＜注意事項＞

＊Laravelでは、「テーブル名は複数形、モデルは単数形」という命名規則がある。


# PersonController.phpを作成する

コントローラを作成するphp artisanコマンドを使用する。

```
 % php artisan make:controller PersonController
```

# ルート情報に記述する

```web.php
Route::get('person','App\Http\Controllers\PersonController@index');
```

# Personモデルで全レコードを得る

```sample.php
$items = Person::all();
```

上記の記述で、全レコードを取得することができます。
取得されたレコードは、「Illuminate\Database\Eloquent」名前空間の
Collectionクラスのインスタンスとして得られます。

# Personクラスにメソッドを追加する

DBクラスと決定的に違うのは、
「コレクションにまとめられているのは、配列ではなく、モデルクラスのインスタンスである」という点です。

1つ1つのレコードは全てPersonクラスのインスタンスとしてまとめられています。

## Personクラスの拡張

```person/index.php
@extends('layouts.helloapp')

@section('title','Person.index')

@section('menubar')
    @parent
    インデックスページ
@endsection

@section('content')

    <table>
        <tr><th>Name</th></tr>

        @foreach($items as $item)
            <tr>
                <td>{{$item->getData()}}</td>
            </tr>
        @endforeach

    </table>

@endsection

@section('footer')
    copyright 2020 tuyano.
@endsection
```

# IDによる検索

```
$変数 = モデルクラス :: find( 変数 );
```

findは、そのようにモデルクラスの静的メソッドとして呼び出します。
引数には検索するID番号を指定します。

＜注意点＞
Eloquentでは、
「デーブルのプライマリキーはidという整数値のフィールドである」という前提でfindは実行します。

## 検索用のテンプレートページを作る

```find.php
@extends('layouts.helloapp')

@section('title','Person.find')

@section('menubar')
    @parent
    検索ページ
@endsection

@section('content')

    <form action="/person/find" method="post">
        @csrf
        <input type="text" name="input" value="{{$input}}">
        <input type="submit" value="find">
    </form>
    @if (isset($item))
        <table>
            <tr><th>Data</th></tr>
            <tr>
                <td>{{$item->getData()}}</td>
            </tr>
        </table>
    @endif

@endsection

@section('footer')
    copyright 2020 tuyano.
@endsection
```

 ## PersonController.phpの修正

```PersonController.php
class PersonController extends Controller
{
    public function index(Request $request)
    {
        $items = Person::all();

        return view('person.index', ['items' => $items]);
    }

    public function find(Request $request)
    {

        return view('person.find', ['input' => '']);
    }

    public function search(Request $request)
    {
        $item = Person::find($request->input);
        $param = ['input' => $request->input, 'item' => $item];

        return view('person.find', $param);
    }
}
```

## ルート情報の追加

```web.php
Route::get('person/find','App\Http\Controllers\PersonController@find');
Route::post('person/find','App\Http\Controllers\PersonController@search');
```

findは、/findにGETアクセスした時の処理、
searchは、POST送信された時の処理です。

```sample.php
$item = Person::find($request->input);
```

上記の記述で、$itemには、検索されたPersonインスタンスが代入されます。
プログラマーこそ、フェルミ推定で論理思考力を鍛えよう！

## はじめに


:::note warn
下記の点、ご了承ください。
- 本記事はあくまで、「プログラマーが論理思考力を鍛えるため」にフェルミ推定を用いています。
- 企画職やコンサルの人が使えるレベルの精度になっていません。
- 本記事内で用いた統計情報は年度がバラバラです。あくまで例として捉えてください。
- 実例のロジックはガバガバかもしれませんが、これもあくまで思考の例ということで。
:::

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- 「フェルミ推定って、企画職とかコンサルの人が使うやつでしょ？」と拒絶しているプログラマー

## 結論
フェルミ推定はプログラマーが論理思考力を鍛えるのに最適！

## フェルミ推定とは
フェルミ推定とは<font color="Blue">「未知の数値を、分かっている数値をもとに見積もること」</font>
実際に調査するにはコスト・時間がかかりすぎたり、物理的に調査不可能なものを推定する手法です。

企画職やコンサルではよく使われる手法ですが、プログラマーでは敬遠される傾向がある気がします。
しかし、元々製造業の企画職を経験したことがある身としては、**フェルミ推定はプログラマーにこそ役立つ**と考えています。

## フェルミ推定はプログラマーの役に立つ？
フェルミ推定は<font color="Red">「やってみないと分からないよね」</font>ではなく、<font color="Blue">「分からないなりに事前に考えて、見積もっておこう」</font>というと時に役に立ちます。

具体的には、下記のような場面で役に立つでしょう。

:::note
フェルミ推定が役立つ場面
- 設計
- 見積書作成
- スケジュール管理
:::

正直、実装に関しては「ローカル環境でやってみればいいじゃん」って話なので、推定とか要らない場合が多いです。
しかし、上記のような場面だと、多少は未来予測をして見積もらなきゃいけないですよね。
そんな時にコーディングと一緒で「やらなきゃ分からないでしょー」というわけにはいかないので、フェルミ推定をうまく使いましょう！

## フェルミ推定の手順

### STEP1:課題を把握する
まずは何を算出しなければいけないのかを明確にします。
ぼんやりしている場合は具体的なイメージが掴める状態まで、細分化しましょう。

### STEP2:ロジックを組み立てる
まずは目的の数字をロジックツリーを用いて細分化していきましょう。
ロジックツリーについてはこちらをご参照ください。

https://qiita.com/YutaManaka/items/59e549073f7bff792d48

ロジックツリーを書く際にMECE(ダブりなく、抜け漏れなく)を意識しましょう。
全ての要素が統計で調べられそうなレベルになれば、この作業は終わりです。

### STEP3:必要な情報を集める
あとは統計情報を集めるだけ。
人数、比率、台数、などなど...とにかく集めましょう。

### STEP4:計算してみる
あとは計算式に代入するだけ！

### STEP5:常識的な範囲か、確認する
もちろん、答えのない問いに答えるのがフェルミ推定ですが、あまりにも的外れではないか、は確認した方が良いです。
別の統計情報と比較して、遜色なければ問題ないですが、あまりにも桁が違いすぎる場合はロジックに破綻がないか、確認しましょう。


## フェルミ推定を実際に使ってみる
「東京で使用されているMacの台数は？」というお題でフェルミ推定してみましょう。

まずは、ロジックツリーを用いて、MECEなロジックを組み立てましょう。

![フェルミ推定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2157342/3d816db4-62d0-d002-7b92-efd1748306df.png)
こんな感じ。
それぞれのロジックを見てみましょう。

:::note
東京で使用されるMacの数=(プライベート使用台数)+(仕事利用台数)
:::
プライベートor業務使用でMECEになっています。
プライベートと仕事で別々に使用していてもOKですね。

:::note
プライベート使用=(世帯数)×(世帯あたりのPC台数)×(Macのシェア)
つまり
700万世帯×1.3台/世帯×8% = 72.8万台
:::
PCを個人で持てる年齢を15才以上と仮定し、統計情報から人口を調べました。
また、PCの普及率を掛ければ、使用PC数がわかります。
使用PC数にMacのシェアをかければ、Macの使用数が算出できます。

:::note
仕事利用=(労働者人口)×(ホワイトカラー比率)×(Macシェア)
つまり
800万人×55%×8% = 35.2万台
:::

労働者数を統計情報から人口を調べました。
また、ホワイトカラー(PC使う)とブルーカラー(PC使わない)と仮定しました。(異論はあるでしょうが、あくまで思考の例です)
労働人口にホワイトカラー比率を掛ければ、使用PC数がわかります。
使用PC数にMacのシェアをかければ、Macの使用数が算出できます。

:::note
つまり、東京で使用されるMacの数は
72.8万台 + 35.2万台 = 108万台
:::

ちなみに、2020年のMacの出荷台数が93万台なので、なんかそれっぽい数字にはなってる気がしますね。
ただし、ここで大事ないのは<font color="Red">「それっぽい数字になったか」</font>よりも<font color="Blue">「ロジックツリーがMECEに書けたか」と「使用する項目と掛け算のロジックに破綻がないか」</font>ですね。

## おわりに
フェルミ推定についてまとめました。
企画職やコンサルのためのフレームワークと思われがちですが、論理的思考力が必要なプログラマーにこそ、必要なものだと思いますので、是非マスターしてみてはいかがでしょうか？

## 参考記事
[【フェルミ推定】4ステップの基本解法はこれでマスターしよう！](https://factlogic.jp/best_strategy_of_felmi_estimation/)
【2022年版】Node.js, React, Webpack 環境構築

Reactの環境構築記事は沢山存在しているが、数年前の記事そのままでやっても、どこかしらでエラーがでてしまい上手くいかなかったりする。
自分用に最新版を作ってみた。
参考記事(2018年)：https://qiita.com/olt/items/11eb99a8961007ceb52f

ファイル構成は以下の通り
```
react_app/
  ├ package.json
  ├ webpack.config.js
  ├ index.html
  ├ App.js
```
## アプリケーションディレクトリの作成
`react_app`という名前のディレクトリ上で作業を行う
```terminal
mkdir react_app
```
`react_app`へ移動する
```terminal
cd react_app
```
## package.jsonを作成

`npm init -y`で、多くの項目がデフォルト値に設定された状態のpackage.jsonが作成できる。

package.jsonファイルを作成
```json:package.json
{
  "name": "react_app",
  "version": "1.0.0",
  "description": "",
  "main": "App.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "html-webpack-plugin": "^5.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  },
  "babel": {
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
    ]
  }
}

```

`package.json`ファイルで`dependency`と`devDependency`内に書いたパッケージを`npm install`コマンドでまとめてインストールする。
```terminal:terminal
npm install
```

## webpackの作成
`webpack.config.js`ファイルを作成する
```js:webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');

module.exports = {
  mode: 'development',
  entry: path.resolve(__dirname, 'App.js'),
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js'
  },
  devServer: {
    port: 3000,
    static: {
        directory: path.resolve(__dirname, "./dist"),
    }
  },
  resolve: {
    modules: [path.resolve(__dirname, "src"), "node_modules"],
    extensions: ['.js', '.jsx']
  },
  module: {
    rules: [
        {
         test: /\.js$/,
         exclude: /node_modules/,
         use: {
             loader: 'babel-loader'
         }
       }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({template: './index.html'})
  ]
};
```
`webpack-dev-server`のバージョンによってdevServerの部分の書き方が違ってくるので注意。（実際v3以前ではcontentBaseが使えるのに対して最新版のv4では使えない）

## index.html, App.jsの作成
```html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <div id="root"></div>
</body>
</html>
```

```js:App.js
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);
```

## アプリケーションのビルド
```terminal
npm run build
```

成功すれば、`webpack 5.73.0 compiled successfully in 1298 ms`というメッセージが表示され、distフォルダに`index.html`と`bundle.js`が作成されている。

## アプリケーションの実行
```terminal
npm start
```
`webpack 5.73.0 compiled successfully in 1565 ms`というメッセージが表示されていたら成功。
`http://localhost:3000/`にアクセスして`Hello, world!`と表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675371/e6cb49a8-0cd7-0f49-2ace-999b726d2019.png)
[Ruby] include, prepend, extend の違い

個人的に忘れがちなものなので、自分用でメモしておきます。

間違いがありましたら、ぜひご指摘お願いします！

# 用途による分け方
|用途|キーワード|個人的な<br>使用頻度|
|-|-|-|
| あるモジュールのインスタンスメソッドが欲しい<br>かつ、**今のクラスやモジュールの定義を優先したい** | [Module#include](https://docs.ruby-lang.org/ja/latest/method/Module/i/include.html) |高|
| あるモジュールのインスタンスメソッドが欲しい<br>かつ、**今のクラスやモジュールのインスタンスメソッド定義より優先したい** | [Module#prepend](https://docs.ruby-lang.org/ja/latest/method/Module/i/prepend.html) |底|
| あるモジュールのインスタンスメソッドが欲しい<br>かつ、**特異メソッドとして欲しい** | [Object#extend](https://docs.ruby-lang.org/ja/latest/method/Object/i/extend.html) |底|

## メソッド呼び出しの順番
### Module#include
- 今のクラスやモジュールが一番優先して呼び出される
- 遅くincludeされるほど、呼び出す時の優先度が上がる
```ruby
module Three; end
module Two; end

class One
  include Three
  include Two
end

p One.ancestors

#=> [One, Two, Three, Object, PP::ObjectMixin, Kernel, BasicObject]
```

### Module#prepend
- 今のクラスやモジュールより優先して呼び出される
- 遅くprependされるほど、呼び出す時の優先度が上がる
```ruby
module Three; end
module Two; end

class One
  prepend Three
  prepend Two
end

p One.ancestors

#=> [Two, Three, One, Object, PP::ObjectMixin, Kernel, BasicObject]
```

### Object#extend
- あるモジュールのインスタンスメソッド特異メソッドとして読み込まれる
- 遅くextendされるほど、呼び出す時の優先度が上がる

#### クラスの特異メソッドとして読み込む
```ruby
module Three
  def print_three; end
end

module Two
  def print_two; end
end

class One
  extend Three
  extend Two
end

p One.ancestors
#=> [One, Object, PP::ObjectMixin, Kernel, BasicObject]

One.singleton_methods
#=> [:print_two, :print_three]
```

#### インスタンスの特異メソッドとして読み込む
```ruby
module Three
  def print_three; end
end

module Two
  def print_two; end
end

class One
  extend Three
  extend Two
end

obj = Object.new
obj.extend Three, Two

obj.singleton_methods
#=> [:print_two, :print_three]
```

## 用語
- 特異メソッド: 
あるオブジェクトに特化したメソッドのこと。特異メソッドを確認するためにはオブジェクト#singleton_methodsを呼び出すとおっけー
mergeコミットを取り消す(git revertする)

mergeされたコミットを取り消す(git revertする)

基本的には`git revert`するだけではあるが、mergeされたコミットのrevertは`-m`オプションによりmergeされた側かmergeした側かを指定する必要がある。

通常のrevertコマンド

```
$ git revert { mergeコミットのcommit id }
```

mergeされたコミットのrevertコマンド

> https://qiita.com/t-vinn/items/537c2236e56ef389133b
> そこで、 -m オプションが必要になります。
-m は mainline の略で、2つの履歴のどちらをmainlineとして残したいかを 1 か 2 で指定します。
1 がマージされた側のブランチ（今回でいうとabcブランチ）、2がマージした側のブランチ（今回でいうとmasterブランチ）を指します。
今回のようにmergeコミットをrevertしたい場合は、1を指定すればOKです。


```
$ git revert -m 1 { mergeコミットのcommit id }
```

# 参考
https://qiita.com/t-vinn/items/537c2236e56ef389133b
PDF-LIBでフォントをサブセット化

# PDF-LIB

PDFを生成するAPIを開発することになり、今回はPDF-LIBを使ってみることにしました。

https://pdf-lib.js.org/

# 発生した問題

今回はテンプレートとして用意されているPDFに対して文字や線を配置していくような処理で、2日ほどの作業でAPIが動作しました。デプロイして動作確認をしていると、PDFのファイルサイズが極端に大きくなっていることに気づきました。テンプレートのPDFは300KB程度なのに対して、出力されたPDFは14MBになっていました。

# フォントのサブセット化

PDF-LIBではデフォルトでフォントがサブセット化されずに埋め込まれていて、サブセット化するには明示的に指定する必要がありました。以下のエントリーでは`たぬき油性マジック`を埋め込んだPDFが5.3MBになっていて、それをサブセット化したら7KBになったようです。

https://symfoware.blog.fc2.com/blog-entry-2597.html

私は`NotoSansMonoCJKjp-Regular.otf`を利用していて、それがそのままPDFに埋め込まれてしまったようです。以下のようなコードでフォントの埋め込みのサブセット化を有効にします。

```typescript
const font = await pdfDoc.embedFont(fontBytes, { subset: true });
```

# サブセット化の失敗

サブセット化を有効にしたのですが、今度はPDFにフォントが埋め込まれずに文字が出力されなくなってしまいました。以下のエントリーではこの問題についてまとめられていました。

https://crocro.com/news/20220517231535.html

# 解決方法

fontkitを修正してフォントのサブセット化を実現する方法もあるようですが、`たぬき油性マジック`ではフォントのサブセット化ができていたことから、サブセット化がうまくいくフォントを調べて利用するという解決方法もあるかと思いました。

こういう時はIPAフォントかなと思い、`IPAexゴシック(Ver.004.01)`をダウンロードしました。

https://moji.or.jp/ipafont/

IPAexゴシックではフォントのサブセット化がうまくいき、PDFのファイルサイズを小さくすることができました。

# その他に利用可能だったフォント

私の場合、これまで`NotoSansMonoCJKjp-Regular.otf`を利用してきました。IPAexゴシックだとフォントの感じが少し違っていたため、PDF-LIBでサブセット化が有効になる他のフォントをさがしました。

https://qiita.com/hamaguchitm/items/546d40b7777bd9242e78

源真ゴシックに等幅フォントがあり、PDF-LIBでサブセット化も大丈夫だったので、これを利用することにしました。

http://jikasei.me/font/genshin/
Reactのエラー回避まとめ

# 1.`JSX expressions must have one parent element.ts`
```React
const App = () => {
  return (
      <h1>React</h1>
      <h1>エラーが出る</h1>
  );
};
```
JSXの要素は一つのタグで囲まなければいけない。ただエラー回避したいだけならこれでOK
```React
const App = () => {
  return (
    <>
      <h1>React</h1>
      <h1>エラー回避</h1>
    </>
  );
};
```

# 2.`'msg' is declared but its value is never read.`
```React
const msg = () => {
  return <p>エラー出る</p>;
};
```
ユーザー定義のコンポーネントは大文字で始める
```React
const Msg = () => {
  return <p>エラー回避</p>;
};
```
タイピング早くするにはこれをやれ！！

今回は、技術ではなくタイピングについてです。

以前、僕は死ぬほどタイピングができませんでした。

ましてやブラインドタッチなんてできるわけないと思っていました。

しかし、以下の三つのサイトを駆使して、できるようになりました！！！

私の場合ですと

0ヶ月目・・・寿司打で初級ですら得をできない

1ヶ月目・・・ブラインドタッチがゆっくりできるようになる

2ヶ月目・・・ある程度の速さでブラインドタッチができるようになる

3ヶ月目・・・寿司打で１００００円で得をできるようになる

＊あくまで参考です。

辛抱強くやることでしかタイピングは上手くならないなと感じた。。。。

- 指の配置など基礎から学べる
https://www.typingclub.com/sportal/program-3.game

- 上記をやりつつ毎日コツコツ寿司打と腕試しを行う
    - e-typing 腕試し　https://www.e-typing.ne.jp/roma/check/
    - 寿司打　http://typingx0.net/sushida/play.html

### タイピングが速くなるかは努力次第です！！！
EDR とは


## 勉強前イメージ

なにかでセキュリティのソフトとは聞いたけど・・・
ええやつなんかな？

## 調査

### EDR とは

Endpoint Detection and Response の略でパソコンなどで不審な挙動を検知して対応を支援するソフトウェアの総称です。
比較的新しい定義で常に監視して検出した際は管理者へ報告が行きます。

従来のアンチウイルスソフトやウイルス対策ソフトを Endpoint Protection Platform の略でEPPと言われています。
EPPはパターンマッチングなどでウイルスの侵入を防ぎます。
しかし既知のウイルスは防げても未知のものは防げません。
そこで侵入されてからでもマルウェアの挙動をしているものを振る舞い検知などで発見し、対処をおこなうのがEDRになります。
発見し連絡するだけでなく管理者への連絡し早く対処できるように支援するのがEDRになります。

もちろん、EPPも必要で
侵入される前の発見 → EPP
侵入されてからの発見 → EDR
といった役割もあり、多重でセキュリティ対策を行うことが必要です。

### EDRの機能

EDRは基本的に操作ログ監視になります。
パソコン(デバイス)をagentで、管理サーバを通信を行ってデータを取得します。
そのログからマルウェア特有の動作(情報の持ち立ちや攻撃の横展開)も検出可能で
マルウェア自身の足跡削除にも素早く対応することが出来ます。

## 勉強後イメージ

イメージ的にはEPPはfirewall、EDRはIDSって感じかな？
中に入られてからもデータが取られる前に停止しないといけない

## 参考

- [EDRとは｜機能や効果、従来のウイルス対策ソフト（EPP）との違い](https://www.ntt.com/business/lp/edr.html)
- [EPP・EDRとは？エンドポイント対策の必要性や仕組みについて解説](https://www.nttpc.co.jp/column/security/epp-edr.html)
【Swift】rethrows とは何か、どのような時に指定するべきか

## `rethrows` とは何か

`rethrows` は関数の修飾子の一つです（`throws` と同様です）。
`rethrows` が指定された関数（ここでは便宜上、親関数と呼ぶことにします）は
引数として関数（同じく、子関数とします）を取ります。

子関数として渡された関数に `throws` が指定されていた場合、
子関数がエラーをスローすると親関数はそのエラーをそのままスローします。
当然、親関数の呼び出し元には `try` が必要です。

しかし子関数として渡された関数に `throws` が指定されていなかった場合、
親関数がエラーをスローすることはありません。
この場合、**親関数の呼び出し元には `try` は不要です。**

**親関数の呼び出し元で子関数として渡した関数に `throws` が指定されていたかどうかによって、
親関数の呼び出し元に `try` が必要かどうかが変わる**のです。
これが `rethows` と `throws` の違いです。

```Swift
// 親関数の例
func parent(_ child: () throws -> Void) rethrows {
    try child()
}
// throws が指定された子関数の例として使う関数
func childThrows() throws { }
// throws が指定されていない子関数の例として使う関数
func childDoesNotThrow() { }

try parent(childThrows)
// ^ 子関数に throws が指定されているため、親関数の呼び出しに try が必要。
parent(childDoesNotThrow)
// ^ 子関数に throws が指定されていないため、親関数の呼び出しに try が不要。
```

子関数がクロージャで、`throws` の有無が明示されていない場合は、
暗黙的に `throws` が指定されていると見なされるかどうかで決まります。

```Swift
// 親関数の例
func parent(_ child: () throws -> Void) rethrows {
    try child()
}

try parent { throw NSError() }
// ^ 子関数に throws が指定されていると見なされるため、親関数の呼び出しに try が必要。
parent { }
// ^ 子関数に throws が指定されていないと見なされるため、親関数の呼び出しに try が不要。
```


## どのような時に `rethrows` を指定するべきか

親関数に `rethrows` を指定するべきなのは、次の全てを満たす場合です。

- (1) 関数を引数に取る関数である。
- (2) 親関数がスローするエラーは、子関数がスローしたエラーだけである。
- (3) 子関数が、  
  `throws` が指定されている関数の場合もあれば、  
  `throws` が指定されていない関数の場合もある。

(1)と(2)は、親関数に `rethrows` を指定するための必要条件です。

(3)は必要条件ではありませんが、
子関数が常に `throws` が指定された関数なのであれば `rethrows` でなく `throws` でよいですし、
子関数が常に `throws` が指定されていない関数なのであれば `rethrows` も `throws` も不要です。

(1)(2)(3)を全て満たす場合に、`rethrows` ではなく `throws` を指定することもできますが、
それだと子関数が`throws` が指定されていない関数だった場合に、親関数がエラーをスローすることがなくなるにも関わらず、
親関数の呼び出し元に `try` が必要となってしまいます。


## `rethrows` を指定した関数を定義する

親関数は次のように定義します。

- `throws` 指定子を書くのと同じ場所に `rethrows` 指定子を書く。
```Swift
func myFunc(arg: () throws -> String) rethrows -> String {
                                   // ^^^^^^^^ throws を書くのと同じ場所に書く。
    try arg()
}
```
- 子関数には（実際にはエラーをスローしない関数が渡されるかもしれないが）`throws` 指定子を付ける。
```Swift
func myFunc(arg: () throws -> Void) rethrows {
                 // ^^^^^^ throws を指定する。
    try arg()
}
```


## あとがき

`rethrows` については、Swift 公式の [LANGUAGE GUIDE](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html) にも書かれていないし、日本語のわかりやすい記事も見当たらなかったため、この記事を書きました。
誤りなどがございましたらご指摘いただけると幸いです。


／以上
make(Integromat)からWikipediaの情報を取得するメモ(MediaWiki操作API)

## はじめに

MediaWiki 操作 API を叩いて、Wikipedia の情報を Google スプレッドシートに出力するメモ記事です。

## ドキュメント

- [API:メイン ページ - MediaWiki](https://www.mediawiki.org/wiki/API:Main_page/ja#MediaWiki%E6%93%8D%E4%BD%9CAPI%E3%81%AE%E4%BD%BF%E3%81%84%E9%81%93)

## リクエストのサンプル

なんでもいいのですが、エマ・ワトソンを検索しておきます。

`https://ja.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=エマ・ワトソン`

## シナリオ全体

<a href="https://gyazo.com/5f20f552e6890951f2d73f236625f188"><img src="https://i.gyazo.com/5f20f552e6890951f2d73f236625f188.png" alt="Image from Gyazo" width="700"/></a>

## モジュールの設定

### HTTPモジュール

`https://ja.wikipedia.org/w/api.php?format=json&action=query&list=search&srsearch=エマ・ワトソン`

`URL`、`Method`、`Query String`の設定をします。

<a href="https://gyazo.com/88a140e1df28a6bbc6ba4cac3bea376f"><img src="https://i.gyazo.com/88a140e1df28a6bbc6ba4cac3bea376f.png" alt="Image from Gyazo" width="810"/></a>

### JSONモジュール

<a href="https://gyazo.com/8decd35d76a3b33b25944a05c815f71f"><img src="https://i.gyazo.com/8decd35d76a3b33b25944a05c815f71f.png" alt="Image from Gyazo" width="763"/></a>

### Iteratorモジュール

<a href="https://gyazo.com/7f778b89ef4ba31a977517838f6fe485"><img src="https://i.gyazo.com/7f778b89ef4ba31a977517838f6fe485.png" alt="Image from Gyazo" width="762"/></a>

### Google Sheetsモジュール

<a href="https://gyazo.com/47d8507144bce824239c179a901f5f03"><img src="https://i.gyazo.com/47d8507144bce824239c179a901f5f03.png" alt="Image from Gyazo" width="739"/></a>

## 実行結果

[![Image from Gyazo](https://i.gyazo.com/4312b64c50b62cbffb7259f18875ab8f.png)](https://gyazo.com/4312b64c50b62cbffb7259f18875ab8f)
【更新中】テザリングがすぐ切れてしまう事象について

社会人2桁目になると新人のOJTの指導をする機会があった時に、気にしたことなかったことを聞かれたので、久しぶりに手を動かしてみた。

# Wifiがすぐ切れてしまうんですが何でですか？？

．．．そんなに早く切れてしまうのかい。
気になる程度にならなかったけど、わからん！

ということで、調べてみた。

iPhoneのテザリングには以下のような仕様が存在していることを初めてしった。

> 1.　テザリング接続数がゼロで、スリープ（画面OFF）して1分45秒経った場合
> 2.  テザリング接続数がゼロで、「設定」→「インターネット共有」画面以外に移って1分45秒経った場合

ここからすると、スリープモードを解除して、インターネット共有から画面を動かさなければよいのか。

．．．現実的には難しいな。

Bluetooth テザリングなるものだと、切れないという情報もあるが、Bluetooth は仕事だしつかえない。

そもそもPCを使っているのに、ネットワークが切れるって違和感はあったんだけど、通信が発生していないと、この仕様に引っかかって、切れちゃってた？？

う～ん…引き続き継続して、トライ＆エラーでやってみるかな。
vCenter 7.0.3 install

windows統合認証が非推奨で、LDAP推奨となって、インストール手間取ったのでまとめ。

今回の構成
 - 
#バージョン
　ESXi：6.7.0 Update 3
　vCenter：7.0.3
　AD/DNS：Win server 2019(同一サーバー)

#ドメイン
　vSpehere　システムドメイン：vsphere.local
　LDAPドメイン：home.lab

設定内容
 - 
#AD設定
/DNS
①ADDS インストール
　home.labドメインとして構築
②Active Directory証明書サービス
　役割サービスにて「証明機関」のみをインストール
　インストール後に以下を選択してセットアップ
　　エンタープライズCA
　　⇒ルートCA
　　⇒新しい秘密キー
　　⇒RSA#Microsoft Software Key Strong Provider、 キー長2048、SHA256
　　⇒残りはデフォルトのまま
　セットアップ完了後にサーバー再起動実施
③DNS インストール
　vCenter名を名前解決できるよう、vsphere.localドメインを作成し、
　「vcenter.vsphere.local」を登録
④vCenterデプロイ
　ISOをマウントして、以下でデプロイ
　FQDN：xxxx.vsphere.local
　SSOドメイン：vsphere.local
⑤証明書作成
　デプロイ完了後にvCenterへsshログイン
　　#shell
　　#openssl s_client -connect AD.home.lab:636 -showcerts
　表示された、BEGIN行からEND行を「sa.cer」として保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255858/917b45e3-3dc8-a69b-cb86-483f9cae90af.png)

⑥LDAP設定
　vSphere ClientにてvCenterへログイン
　管理⇒Single Sign-on⇒設定⇒IDソース⇒追加　を選択
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255858/d69026ba-7bed-c9a5-624c-48b761eb2967.png)

　IDソースタイプ：LDAPを介したAD
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255858/e1379a2c-b538-3f92-741d-cbc76e84bdb7.png)

無事追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255858/f5474d31-896f-641d-3eb1-6bb0ed6277f7.png)


参照
 -
KB2041378
https://kb.vmware.com/s/article/2041378?lang=en_us

LDAP構成
https://hidemium.hatenablog.com/entry/2022/01/29/080105

AD over LDAPS en Vmware Vcenter 7.0
https://www.youtube.com/watch?v=eKW1Nh7S0Es
サイバーセキュリティお嬢様「CIAってなんですの？」

# ある日
お嬢様「来年からわたくしも華のJKですわ」
お嬢様「さっそく高校の入学願書を取り寄せてみましたの」
お嬢様「あら...！この『最羽（さいば）女学院』の制服、とっても素敵ですわね」

お嬢様「どうやら **『サイバーセキュリティ』** について学ぶ学校のようですわ」
お嬢様「**サイバーセキュリティってなんだかよく分かりませんけど**、響きが格好良くてよ！」

お嬢様「今からわたくしも **『サイバーセキュリティお嬢様』** を名乗ることにいたしますわ」

じいや「**お嬢様！**」

サイバーセキュリティお嬢様（以下CSお嬢様）「じいや一体何事ですの」

じいや「じいやはお嬢様の進路選択が雑すぎて呆れておりますのじゃ」

CSお嬢様「でも、こんなにリボンとフリルがふんだんにあしらわれていて素敵な制服の学校は他になくってよ」
CSお嬢様「じいや、わたくしどうしても最羽女学院へ行きたいですわ！」

じいや「よろしい、ではサイバーセキュリティの基本についてお教えしましょうぞ」

CSお嬢様「なんでもかかってこいですわ！」

# サイバーセキュリティとは
じいや「まずサイバーセキュリティの定義から話しますぞ」
じいや「情報セキュリティとか、サイバーセキュリティとか呼ばれておりますが」
じいや「この２つの言葉の意味には微妙に違いがあるのです」

じいや「単に**情報資産を守るための仕組みを指すのが情報セキュリティ**であるのに対し」
じいや「**情報空間（サイバースペース）の安全を確保するのがサイバーセキュリティ**なんですぞ」
じいや「情報空間はインターネットと読み換えると分かりやすいですな」

CSお嬢様「**なんだかよく分かりませんけど完全に理解しましたわ**」

# CIAとは
じいや「ところでお嬢様はCIAをご存知ですかな？」

CSお嬢様「**あのハリウッド映画やドラマで見るCIAですわね！** 知ってますわ！」

じいや「**違いますぞ**」

CSお嬢様「じゃあなんですの」

じいや「情報セキュリティの3要素となる、」


じいや「機密性（**C**onfidentiality）」
じいや「完全性（**I**ntegrity）」
じいや「可用性（**A**vailability）」


じいや「の頭文字を取ったものなんですぞ」
じいや「ちなみにお嬢様のおっしゃられたCIAは**C**entral **I**ntelligence **A**gency、米国中央情報局の略称ですぞ」

## 機密性
CSお嬢様「機密性ってなんですの？」

じいや「お嬢様でも分かるように説明すると」
じいや「アクセスを許可されている人にだけその情報を見れることですぞ」

CSお嬢様「わたくしの日記帳は誰にも見られたくないのと一緒ですわね」

## 完全性
CSお嬢様「じゃあ完全性ってなんですの？」

じいや「情報が改ざんされない状態、つまりデータが常に正しい状態であることですな」
じいや「分かりやすい例で言うと」
じいや「お嬢様の成績データが勝手に書き換えられる、と完全性が脅かされた状態になるわけです」

CSお嬢様「これ以上内申が下がるのは嫌ですわー！！」

## 可用性
CSお嬢様「最後の、可用性ってなんですの？」

じいや「いつでもその情報にアクセスできることですぞ」

CSお嬢様「じいやが指パッチンでいつでも来てくれるのと一緒ですわね」

# おわりに
じいや「どうでしたかな」

CSお嬢様「とっても分かりやすかったわ、ありがとうじいや」

じいや「お礼には及びませんぞ」
じいや「お嬢様、これからも少しずつサイバーセキュリティの知識をつけて」
じいや「**真のサイバーセキュリティお嬢様**になるのです」

CSお嬢様「**おーっほっほ！真のサイバーセキュリティお嬢様を目指しますわ！**」

# 参考文献
サイバーセキュリティ入門 第２版
この一冊で全部わかる セキュリティの基本

# 次回以降
[サイバーセキュリティお嬢様「しんせいせい...ってなんですの？」](https://qiita.com/choco_py3/items/0d05409534f267e40001)
[サイバーセキュリティお嬢様「き...脆弱性ってなんですの？」](https://qiita.com/choco_py3/items/15479e37b011c34abf36)
[サイバーセキュリティお嬢様「マルウェア...？スキーウェアのお仲間ですの？」](https://qiita.com/choco_py3/items/00af04f6906de4135b48)
[サイバーセキュリティお嬢様「クラッカー？何それ食べられますの？」](https://qiita.com/choco_py3/items/40fe5a27af3722daa654)
[サイバーセキュリティお嬢様「ハクティビストってなんですの？」](https://qiita.com/choco_py3/items/262df8fc893cf7fd303f)
[サイバーセキュリティお嬢様「F5攻撃（アタック）ってなんですの？」](https://qiita.com/choco_py3/items/f0164dedc7e4b761b25d)
[サイバーセキュリティお嬢様「SQLいんじぇくしょん...ってなんですの？」](https://qiita.com/choco_py3/items/4a597f25f0c3dbbea437)
[サイバーセキュリティお嬢様「クロスサイトスクリプティング？...美味しそうですわぁ！」](https://qiita.com/choco_py3/items/f3bb70ecf819bb55ad80)

# 宣伝
[技術書典13](https://techbookfest.org/event/tbf13)にサークル参加予定です。
良かったら[Twitter](https://twitter.com/choco_py3)フォローしてください！
C#のサマリコメントをドキュメント化できる「DocFX」使ってみた

## 0. はじめに
CShaperな人達にとっては、
**オリジナルドキュメント作るの面倒くさいので、C#のサマリコメントをドキュメント化したい！**
っていうときが3年～5年に1回くらいあるかと思います。
そんなときに便利な「DocFX」というのがあるので使ってみました。

## 1. 環境構築
### 1-1. DocFXのダウンロード
https://github.com/dotnet/docfx/releases

上記のGitHubサイトからDocFXのzipファイルをダウンロードし、任意のフォルダに解凍します。
その後、環境変数にパスを追加しましょう。

### 1-2. DocFXの初期設定

以下のコマンドを実行し、DocFXの初期フォルダ・ファイルを作成します。
```powershell
> docfx.exe init -q -o DocFXTest
```

## 2. ドキュメント生成の準備
### 2-1. 生成対象ファイルを用意

ドキュメント生成したいクラス、及びプロジェクトを用意します。
今回は以下を使用します。

https://github.com/i-tanaka730/SvnLib/tree/main/SvnLib

### 2-2. 生成対象ファイルを指定のフォルダに配置

[**1-2. DocFXの初期設定**](https://qiita.com/i-tanaka730/items/0c2a1b9d33e0103c7327#1-2-docfx%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A)で生成された`DocFXTest\src`フォルダ配下に、ドキュメント生成したいクラス、及びプロジェクトを配置します。
今回の場合は以下のようになります。

```
DocFXTest
　┗　src
　　┗　SvnLib.csproj
　　┗　SvnService.cs
```

## 3. ドキュメントを生成

以下のコマンドを実行します。
```powershell
DocFXTest> docfx.exe metadata
DocFXTest> docfx.exe build
```
すると、`DocFXTest/_site`フォルダが生成され、これらがドキュメントになります。
(フォルダの中にはhtmlファイルやcssファイルがあります。)
なお、`DocFXTest`フォルダ配下の`docfx.json`・`index.md`・`toc.yml`あたりを変更してビルドすることで、ドキュメントのデザインや構成を変更することができます。
が、詳細は割愛します。~~というか自分が分かっていなi~~

## 4. localhostで確認
以下のコマンドで、localhostを立ち上げて確認することができます。
```
\DocFXTest> docfx.exe serve
```
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/62a77d47-fbfb-c946-9abc-2addae41ed13.png)

## 5. おわりに
- サマリコメントをさくっとドキュメント化したい場合はなかなか便利ですね😇
- デザインをテンプレート化してしまえばその後も楽ちん😇
【PHP初級㉕】論理演算子5

［問題］　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)
整数値を入力させ、その値が-10未満ならrange 1、-10以上0未満であればrange 2、0以上であればrange 3、と表示するプログラムを作成しなさい。



# コード
```php
$a = intval(fgets(STDIN));
if($a < -10){
    echo 'range 1';
}else if($a >= -10 && $a < 0){
    echo 'range 2';
}else{
    echo 'range 3';
}   
```



↓「0」と入力



# 結果
```
range 3
```
東急電鉄URBAN HACKSを解いてみた（東急96駅の最長駅名しりとり）

# はじめに
東急線に乗っていた時にURBAN HACKSという広告を目にしました。
広告には、**東急電鉄全96駅の駅名でしりとりを行った際に最長となる組み合わせを算出せよ**という問題が書かれていました。
サマーウォーズのケンジ君のように、こういう問題は解いてみたくなります。
よろしくお願いしまぁーす！

# 結論
東急電鉄96駅の最長駅名しりとり結果は **25** と分かりました。
（合ってるか知りたい…）
```:結果
[1]すずかけだい  -> [2]いちがお  -> [3]おやまだい  -> [4]いしかわだい  -> [5]いけがみ  -> 
[6]みょうれんじ  -> [7]じゆうがおか  -> [8]かじがや  -> [9]やました  -> [10]たな  -> 
[11]ながつた  -> [12]たまがわ  -> [13]わかばやし  -> [14]しぶや  -> [15]やぐちのわたし -> 
[16]しもしんめい  -> [17]いけじりおおはし  -> [18]しょういんじんじゃまえ  -> [19]えばらまち  -> [20]ちどりちょう  -> 
[21]うのき  -> [22]きたせんぞく  -> [23]くほんぶつ  -> [24]つなしま  -> [25]まつばら
```

# 内容
事前にpipでnumpyと、線形計画法のソルバーライブラリであるPulPをインストールしてください。

```terminal:terminal
$ pip install numpy
$ pip install pulp
```

以下コードを実行することで結果が得られます。コードは参考記事を全面的に写させていただきました。
```python:python
from pulp import * # pip install pulp
import numpy as np

kw = "あおばだい,あざみの,いけがみ,いけじりおおはし,いしかわだい,いちがお,うのき,えだ,えばらなかのぶ,えばらまち,"  \
     "おおいまち,おおおかやま,おおくらやま,おおさきひろこうじ,おくさわ,おやまだい,おんだ,おんたけさん," \
     "がくげいだいがく,かじがや,かまた,かみのげ,かみまち,きくな,きたせんぞく,くがはら,くほんぶつ,ごたんだ," \
     "こどものくに,こまざわだいがく,さぎぬま,さくらしんまち,さんげんちゃや,しぶや,しもしんめい,しもたかいど," \
     "しもまるこ,じゆうがおか,しょういんじんじゃまえ,しんまるこ,すずかけだい,せたがや,せんぞく,せんぞくいけ," \
     "だいかんやま,たかつ,たな,たまがわ,たまぷらーざ,たんまち,ちどりちょう,ちゅうおうりんかん,つきみの,つくしの," \
     "つなしま,でんえんちょうふ,とごしぎんざ,とごしこうえん,とどろき,とりつだいがく,ながつた,なかのぶ,ながはら," \
     "なかめぐろ,にしこやま,にしたいしどう,ぬまべ,はくらく,はすぬま,はたのだい,ひがしはくらく,ひよし,ふじがおか," \
     "ふたこしんち,ふたこたまがわ,ふどうまえ,まつばら,みぞのくち,みどりがおか,みなみまちだぐらんべりーぱーく," \
     "みやざきだい,みやのさか,みやまえだいら,みょうれんじ,むさしこすぎ,むさしこやま,むさしにった,めぐろ," \
     "もとすみよし,やぐちのわたし,やました,ゆうてんじ,ゆきがやおおつか,ようが,よこはま,わかばやし".split(',')

print(len)
n, r = len(kw), range(len(kw))
m = LpProblem(sense=LpMaximize) # 数理モデル
x = [[0 if kw[i][-1] != kw[j][0] else LpVariable('x%d_%d'%(i,j), cat=LpBinary)
      for j in r] for i in r] # kw_i から kw_j に繋げるかどうか (1)
y = [LpVariable('y%d'%i, lowBound=0) for i in r] # kw_iが先頭かどうか (2)
z = [LpVariable('z%d'%i, lowBound=0) for i in r] # kw_iの順番 (3)
m += lpSum(x[i][j] for i in r for j in r) # なるべく繋げる (0)
for i in r:
    cou = lpSum(x[i][j] for j in r) # kw_i から出る数
    cin = lpSum(x[j][i] for j in r) # kw_i へ入る数
    m += cou <= 1 # kw_i から出る数は1以下 (4)
    m += cin <= 1 # kw_i へ入る数は1以下 (5)
    m += cou <= cin + y[i] # yに関する制約 (6)
    for j in r:
        m += z[i] <= z[j]-1+(n+1)*(1-x[i][j]) # zに関する制約 (7)
m += lpSum(y) == 1 # 先頭は1つだけ (8)
m.solve() # 求解
print(int(value(m.objective)) + 1) # 最長しりとり数
rr = range(1,n+1)
vx = np.vectorize(value)(x).astype(int)
i, s = 0, int(np.vectorize(value)(y)@rr)
while s:
    if i:
        print(' -> ', end='')
    i += 1
    print('[%d]%s'%(i,kw[s-1]), end=' ')
    s = vx[s-1]@rr
```

# 感想
* 線形計画法も最大マッチング問題の何たるかも分かってないのにそれっぽいことができるPythonしゅごい…。
* アルゴリズムがわかっていないので検算ができません。目下勉強中。

# 参考
https://qiita.com/SaitoTsutomu/items/ba2dedb5795cae36f8a1
VSCodeでのスニペットの書き方


## きっかけ
Next.jsで毎回SSRとかコンポート書くのめんどくさくないですか...？拡張機能見つかんなかったから、スニペット作るかぁって感じです。

## やり方
二種類ある。
- VSCode全体
- プロジェクト単位。`.vscode`ディレクトリに`*.code-snippets`ファイルをおくことで可能

今回はVSCode全体でやります。

### 1. `.code-snippets`snipetsファイルを作成する
`ctrl + shift + P` で検索窓をだして、
「ユーザースニペットの作成」＞「新しいグローバルスニペットの作成」

### 2. 書き方

```json
  "new getServerSideProps": {
    "scope": "javascriptreact,typescriptreact",
    "prefix": "SSR",
    "body": [
      "export async function getServerSideProps() {",
        "const res = await fetch(`https://.../data`)",
        "const data = await res.json()",

        "return { props: { data } }",
      "}"
    ],
    "description": "Template of new SSR"
  }
```
- `scope` : どの拡張子のファイルで使うか設定。以下の公式サイトから言語を選ぶ。

https://code.visualstudio.com/docs/languages/identifiers

- `prefix` : 呼び出し方
- `body` : 挿入される文字列。配列にすると複数行を入力できる。
- `description`: 説明文。



## 参考

https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets

https://zenn.dev/hotsukai/articles/69fc0e93436814

(青い記事入れてすみませんqiitaさん)
半透明のパーティクルを不透明にする方法

#　比較

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/4fa87311-a37c-2d84-6482-6f813f1f9052.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/f5a7feb6-ac5c-5f4f-f9dc-280be1984d4e.png)

##### 背景

VR環境だと、半透明のパーティクルがマジで見づらい！

##### やること

♡と☆のパーティクルについて、両方ともカラーのalpha値が1なのですが、ハートが半透明で星が不透明になっていると思います。

今回はこれのやり方の解説です。

##### 1. テクスチャの編集

元のテクスチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/be7a8d9d-c962-cc86-ddce-d1cec0eea92d.png)

編集後のテクスチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/7e2357f5-050f-dc80-990e-1cd2558f4018.png)

元のテクスチャは背景が黒なのですが、これを画像編集して、背景を透明にします。

##### 2. マテリアルの編集

Shaderを変更します

Shader > Legacy Shaders > Particles >　Additive　

がデフォルトの設定になっているので、これを

Shader > Legacy Shaders > Particles > Alpha Blende

に変更します。以上！
flutter3で追加されたenumの書き方を使用します


enumの内部でpropertyやmethodなど、一つのファイルで管理できるのが非常に良くてもう当たり前になっている

```dart
enum HogeType {
  hoge('ほげ', list: ['ほげ', 'hoge']),
  fuga('ふが', list: ['ふが', 'huga']),
  piyo('ぴよ', list: ['ぴよ']),
  foo('ふー', list: ['foo']),
  bar('ばー'),
  none('');

  const HogeType(this.type, {this.list = const []});
  final String type;
  final List<String> list;

  static HogeType fromIndex(int from) {
    if (0 <= from && from < HogeType.values.length) return HogeType.values[from];
    return HogeType.none;
  }

  static HogeType fromName(String? from) {
    return HogeType.values.firstWhere(
      (value) => value.name == from,
      orElse: () => HogeType.none,
    );
  }
}

void hg() {
  print(HogeType.fromName('hoge'));
  //HogeType.hoge
  print(HogeType.fromName('aa'));
  //HogeType.none

  print(HogeType.fromIndex(1));
  //HogeType.fuga
  print(HogeType.fromIndex(3));
  //HogeType.foo
}
```

テストコードも書きました
```dart
import 'package:flutter_test/flutter_test.dart';

import 'package:saiteki/enum/hoge_type.dart';

void main() {
  group('hogeをまとめた$HogeType >', () {
    group('$intを入力した際に$HogeTypeを出力するMethod: fromIndex(${HogeType.fromIndex}) >', () {
      test('(int 0)を入力した際に\${HogeType.hoge}を出力する', () {
        expect(HogeType.fromIndex(0), HogeType.hoge);
      });
      test('(int 5)を入力した際に\${HogeType.none}を出力する', () {
        expect(HogeType.fromIndex(5), HogeType.none);
      });
      test('下限の境界値の一つ外側の値(int -1)を入力した際に\${HogeType.none}を出力する', () {
        expect(HogeType.fromIndex(-1), HogeType.none);
      });
      test('上限の境界値の一つ外側の値(int 6)を入力した際に\${HogeType.none}を出力する', () {
        expect(HogeType.fromIndex(6), HogeType.none);
      });
    });
  });

  group('$Stringを入力した際に$HogeTypeを出力するMethod: fromName(${HogeType.fromName}) >', () {
    test('(String hoge)を入力した際に\${HogeType.hoge}を出力する', () {
      expect(HogeType.fromName('hoge'), HogeType.hoge);
    });
    test('(String none)を入力した際に\${HogeType.none}を出力する', () {
      expect(HogeType.fromName('none'), HogeType.none);
    });
    test('対応外文字列の(String hogehoge)を入力した際に\${HogeType.none}を出力する', () {
      expect(HogeType.fromName('hogehoge'), HogeType.none);
    });
    test('文字列ではない(String? null)を入力した際に\${HogeType.none}を出力する', () {
      expect(HogeType.fromName(null), HogeType.none);
    });
  });
}
```

おわり
【#21 エンジニア転職学習】DB入門

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

本日よりDBの入門をざっくり学習していきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日の学習内容は「そもそもデータベースとは」というところになります。

* Git stash
* **DB・SQLとは　←Topics!!**

# DB・SQLとは
データベースとは、下記4つの機能を持っている。
1. 検索と更新（登録・修正・削除）
1. 同時実行制御
1. 耐障害性
1. セキュリティ

「リレーショナルデータベース」と「NoSQL」が良く使用されている。
* リレーショナルDB：**二次元表を使ってデータ管理**。**SQL文を使って操作**する
* NoSQL：リレーショナルDBにある**機能の一部を捨てて、パフォーマンスを上げた**DB。


使用している教材はこちら↓


https://www.amazon.co.jp/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E5%AD%A6%E3%81%B9%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B00TTRZFDC/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1657112653&sr=8-1


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
音ゲーつくったった！

# 概要

女の子をハイタッチして、リズムを刻む音ゲーです！

# 何でしょう？

T大学制作展 2022 Extra (7月開催の方) Emulsion の出展作品です。

https://www.iiiexhibition.com/

# デモ映像

https://youtu.be/qcqKm2OGZ_8

https://youtu.be/maGBm-ND3pg

つくりかたは、過去記事を参考に！

[Noesis](http://noe-sis.jp/)みてねー！
[safari][Javascript]safariでwindow.print()を2回実行すると空白で印刷されてしまう

# 初めに
Window.print()を使用して印刷を行なった際、safariにて印刷が空白表示となり、また苦しんだので、
その解決策を記載します。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [現象](#現象)
1. [対策](#対策)
1. [試したけど現象が解決しなかった方法](#試したけど現象が解決しなかった方法)
1. [参考文献](#参考文献)

<a id="#Chapter1"></a>
# 現象
safariにてwindow.print()を2回実行すると、
「このWebページがプリントを求めています。このWebページをプリントしますか?」とダイアログが表示される。
OKを押下すると空白のページが複数枚印刷される。

初回印刷
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727564/ecba5659-c258-d2f8-5956-2a69aa506574.png)

ダイアログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727564/007363c2-9d4a-45c6-3154-2ef07232fc06.png)

二回目の印刷
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727564/6ea98400-0cd7-772e-fc23-4bfef5298412.png)


<a id="#Chapter2"></a>
# 対策
印刷レイアウトを別タグ/別ウィンドウで表示し、そこで印刷を行う。

```html:index.html
<html>
<head>
    <meta charset="UTF-8">
    <!-- !-- for DataTables --> -->
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.24/datatables.min.css" />
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>
<body>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"
        integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

        <h1>テストです</h1>
        <button type="button" onclick="printPage()">Print</button>
    <script src="main.js"></script>
</body>
</html>
```

```javascript:main.js
function printPage ()
{
    var printPage = window.open(window.location);
    printPage.onload = function()
    {
        printPage.addEventListener('afterprint', (event) => 
        {
            setTimeout(() => { printPage.close()},1000);
         
        });
        printPage.print();    
    };
}
```



<a id="#Chapter３"></a>
# 試したけど現象が解決しなかった方法
・印刷のたびに画面の更新を行う。
　→window.reloadでは解決しない、ブラウザの更新ボタン、F5キー押下であれば解決する。
・キャッシュクリア
・windowオブジェクトのインスタンスを取得し、初期状態を維持。印刷のたびに初期状態をコピーする。
　→windowオブジェクトから実体を取得できなかった。参照先が同じになってしまうため解決せず。
・windowオブジェクトのプロパティを初期化し、印刷を1回目として実行する。
　→windowオブジェクトのプロパティはほとんどが読み取り専用のため初期化できず。

色々試しましたが、safariの機能による問題と考えています。
そのため、windowオブジェクトの書き換えでは解決しないと推測しています。

ナイスな解決方法をご存知でしたら教えてほしいです。

<a id="#reference"></a>
# 参考文献
- [手がかり記憶B](https://www.shiga-med.ac.jp/hqbioph/iBaad/patternB/)
- [MDN Window](https://developer.mozilla.org/ja/docs/Web/API/Window)
Xcodeでfontawesomeを使う方法

こんにちわ。

今回は、Xcodeでfontawesomeのアイコンを使う方法を紹介します！

# 手順
1.fontawesomeをダウンロード
2.fontawesomeのフォントをxcodeのプロジェクトに入れる
3.表示する

それでは一個ずつ紹介します！

## fontawesomeをダウンロード

まず、Fontawesomeのサイトへ行って、ダウンロードを行います。
[fontawesomeリンク](https://fontawesome.com/)

今回はDesktop用をダウンロードしてください。

## Xcodeのプロジェクトにフォントを入れる

次に、ダウンロードしたfontawesomeフォルダの中にあるotfフォルダーをxcodeのプロジェクト内に入れます。

![スクリーンショット 2022-07-06 21.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2354244/d8e9e0d4-13dc-9991-379c-629a6f2789f8.png)

## 実際にアイコンを使う

![スクリーンショット 2022-07-06 21.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2354244/962b8929-1b59-6dc2-7ae1-505b312d0c92.png)

1.Labelを用意する
2.Fontawesomeのアイコンをコピー
3.Textにコピーしたものをペースト(?になってる所)
4.Fontの種類を[Font Awesome]に設定する

これで表示されると思います！
AzureでのSSO設定アプリにグループが割り当てられない

# １．現象

- AzureでSSO対応アプリを登録。
- アプリ用に新規でセキュリティグループを作成。
- SSO対応アプリの管理画面で、上記のグループを割り当てようとする。
- 上記のグループが選択肢に表示されない。

# ２．原因と対応

- グループ作成時に、所有者を設定していないとグループの割当ができない。
- 再度、グループ作成時に所有者を割り当てて作成。
- これで問題なく対応。
ハンドトラッキングできれいに女の子を動かしてみよう！(アバター編)

## デモ動画

### 大きい女の子と鏡に映った自分のアバターのデモ

https://youtu.be/NKznhSmi49o

### 左の一夜さんが同じ動きで、右の一夜さんが鏡の動きをするデモ

https://youtu.be/sZ9vm-F2QoQ

## 目次

1. ダミーの設定をしよう！
1. ダミーの回転と位置をスクリプトで動かそう！
1. VRIKの設定をしよう！

[次回](https://qiita.com/KayaTakashiro/items/6d5f025c4818597d5157)はこれ

VRIKを使います。

## 1. ダミーの設定をしよう

TrackingSpace中の LeftHandAnchor と RightHandAnchor　と CenterEyeAnchor　を使っただけでは、VRIKがきれいに動きません。

そのため、LeftHandAnchorのダミーとRightHandAnchorのダミーとCenterEyeAnchorを用意して、それを制御することで、アバターをきれいに動かします。


まず、TrackingSpaceの下に、写真のように CenterEyeAnchorDummy, RightHandAnchorDummy, LeftHandAnchorDummyを用意します。(空のオブジェクト)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/cf94b651-5bf4-ed29-ed7e-04ea38170846.png)

## 2.ダミーの回転と位置をスクリプトで動かそう！

次に、AnchorTracer.csを用意して、TrackingSpaceにアタッチします。

```AnchorTracer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnchorTracer : MonoBehaviour
{
    [SerializeField] Transform LeftHandAnchor;

    [SerializeField] Transform RightHandAnchor;

    [SerializeField] Transform LeftHandAnchorDummy;

    [SerializeField] Transform RightHandAnchorDummy;

    [SerializeField] Transform CenterEyeAnchor;

    [SerializeField] Transform CenterEyeAnchorDummy;

    [SerializeField] bool isFirstView;

    // Update is called once per frame
    void Update()
    {
        LeftHandAnchorDummy.position = LeftHandAnchor.position;
        RightHandAnchorDummy.position = RightHandAnchor.position;
        if(!isFirstView){
            CenterEyeAnchorDummy.position = CenterEyeAnchor.position;
        }else{
            var centerEyePosition = CenterEyeAnchor.position;
            CenterEyeAnchorDummy.position = new Vector3(centerEyePosition.x, centerEyePosition.y + 0.05f, centerEyePosition.z + 0.15f);
        }


        LeftHandAnchorDummy.localRotation = Quaternion.Euler(new Vector3(-LeftHandAnchor.eulerAngles.x, LeftHandAnchor.eulerAngles.y, -LeftHandAnchor.eulerAngles.z));
        RightHandAnchorDummy.localRotation = Quaternion.Euler(new Vector3(-RightHandAnchor.eulerAngles.x, RightHandAnchor.eulerAngles.y, -RightHandAnchor.eulerAngles.z));
        CenterEyeAnchorDummy.localRotation = Quaternion.Euler(new Vector3(-CenterEyeAnchor.eulerAngles.x, CenterEyeAnchor.eulerAngles.y, -CenterEyeAnchor.eulerAngles.z));
    }

}

```
Is First View が一人称視点専用の位置です。(エージェントを動かすときは必ずOFFにしてください)

最後にLeftHandAnchorDummy, RightHandAnchorDummy, CenterEyeAnchorDummy2w22を落とし込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/4593bcdc-edd2-f4a8-0fcd-8506494a828d.png)

### VRIKの設定です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/d5f3632d-a799-9a00-7d89-dca24973bd47.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/3e865b12-ffbd-6a3f-515d-376974809c08.png)

これできれいに自分のアバターが動くようになります！

[Noesis](http://noe-sis.jp/)みてねー！
SQL超初心者がDB・SQLについて調べてみました

# はじめに
新人エンジニアのしゅんやです！
今回は私が勉強しているDB・SQLについて記事を書いていきます。

# この記事の対象者

- SQLを学びたい方
- 初級エンジニア
- IT企業に就職する学生

# 筆者のレベル
- 新人エンジニア
- SQLの開発経験なし
- Oracle master silver SQLの資格取得に向けて学習中

# DB(データベース)とは
データベースとは、決まった形式で整理されたデータの集まりのことをいい、大量にあるデータベースを検索しやすくしたもので、一般的にコンピュータ上で整理されたデータ群を指します。
特定のルールによって規則正しく整理されたデータの集まりを意味しており、膨大な量のデータを業務で有効活用出来るように複数人で共有し、検索する機能がついています。

データベースが利用されているわかりやすい例として、電話帳や辞書などの大量の情報を扱いやすく整理されているものをいいます。

# データベースの種類
データベースの種類は代表的なもので４種類あります。
#### 階層型データベース
階層型データベースとは、ツリーのようにデータを関連付けて保存するタイプです。上層から下層に分岐していく1対多の形でデータが整理されています。

メリットは、上層から特定のデータに至るまでのルートは一つのみのため、データの検索が早いという特徴が有りますが、逆にデメリットは、状況次第では一つのデータを複数個所に登録する必要が生じてしまいデータが冗長となってしまったり、データの追加や削除を行うと各子ノードへのアクセスルートが都度変わってしまい、柔軟なデータ管理がしにくいのがデメリットです。

#### ネットワーク型データベース
ネットワーク型データベースとは、関連性のあるデータを互いに紐づけて保存するタイプのデータベースです。
メリットは、多対多の関係性が成り立つと同時に、階層型データベースでは発生する可能性があった情報の重複登録を防ぐことができます。デメリットは、データ構造に依存してしまうという点があげられます。

#### リレーショナル型データベース
リレーショナルデータベースは、階層型データベースとネットワーク型データベースのデメリットを解消するために開発されました。

行と列によって構成された「表形式のテーブル」と呼ばれるデータの集合を、互いに関連付けて関係モデルを使用したデータベースのことです。そのことから日本語では「関係データベース」とも言います。Excelを創造してもらえるとよいかもしれません。

#### NoSQL型データベース
NoSQL系データベースとは、おおまかに「リレーショナル型データベース以外」のデータベースを指します。

NoSQL系データベースは関係データベースほど排他制御が厳格ででないがゆえに、関係データベースのようにはデータの独立性・一貫性が保証されないことがデメリットです。
その代わりに並列処理がしやすく、スケールアウトが容易というメリットがあります。そのため独立性・一貫性よりも大量のデータを高速で処理することを優先したいシステムに向いています。

# データベースとスプレッドシートの違い
リレーショナルデータベースはスプレッドシートやExcelに似た形をしています。
似てはいますが、どこが違うのか説明していきたいと思います。

- 想定されるアクセス数
- 想定されるデータ量
- 整合性を保つための機能

データベースと異なり、スプレットシートは操作する人数が増えてきたり、過剰に複雑なデータ操作を大量に実行してしまうと正常に動く事が難しくなります。

しかし、データベースは整理された大規模なデータの集合を保持するように設計されているので、スプレッドシートよりもより大人数が同時に複雑で過剰な操作を迅速かつ安全に利用することが可能になっています。ここがデータベースとスプレッドシートの違いになります。

# 最後に
今回は、データベースとはどんなものなのか紹介してきましたが、今後はSQLの書き方など色々紹介していきます。
記事を読んでDB・SQLについて興味を持っていただけたら幸いです。
基本情報（RAIDはハードディスクの合体技）

RAIDって必殺技の名前かと思っていたらRedundant Arrays of Inexpensive Disksの略のようです。
Redundantが冗長でArraysは配列でInexpensiveは安価なDisksはディスク。

複数のハードディスクを組み合わせて、ハードディスクの速度や信頼性を向上させます。
RAIDはRAID0からRAID6までの7種類に分かれており、実用に応じて種類を選択するようです。

RAIDの中で一般的に使用するのが、高速化を実現するRAID0と信頼性を高めるRAID1、そしてRAID５のようです。

## RAID0(ストライピング）
![220px-RAID_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542637/23c4ab95-e68b-e566-c7a5-e9ca7be9be60.png)
１つのデータを２台以上のディスクに分散させて書き込むのがRAID0です。
複数のディスクに分散させて書くので高速化できますが、１台でも故障すると全ファイルが失われてしまうため信頼度が低いです。

## RAID1(ミラーリング)
![220px-RAID_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542637/1bfa1682-e707-439a-e408-d35dba2913f2.png)
２台以上のディスクに対して常に同じデータを書き込みます。
複数のディスクに同じデータを書くので常時バックアップがある状態です。使えるディスク領域が半分以下になりますが
いずれか１台が交渉してもそのまま使えるので信頼性は高いです。

## RAID5
![220px-RAID_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542637/e53bc3d6-19d5-50b2-4710-684773149c58.png)
３台以上のディスクを使って、データと同時にパリティと呼ばれる誤り訂正符号も分散させて書き込みます。
複数のディスクに分散させてデータを書くとともにパリティ情報を別のディスクに保存するので、いずれが１台が故障しても
他のディスクにあるパリティ情報を使ってデータを復元できます。

[RAID（出典）](https://ja.wikipedia.org/wiki/RAID#:~:text=RAID%EF%BC%88Redundant%20Arrays%20of%20Inexpensive,%E6%80%A7%E3%82%92%E5%90%91%E4%B8%8A%E3%81%95%E3%81%9B%E3%82%8B%E6%8A%80%E8%A1%93%E3%80%82)

## まとめ
HDDは奥が深い
Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement.（メモ）

### エラー内容
下記のエラーは、別コンポーネントをレンダリングしたい時、他の値を返す可能性のある条件の後にhooksを使用すると発生します
```
Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
```
≈

### エラーが発生する例
```
import React, { useState } from 'react'

export default function App() {
  const [loading, setLoading] = useState()

  // 👇エラー発生原因
  if (loading) {
    <p>Loading...</p>
  }
  const [count, setCount] = useState(0)

  return (
    <div>
      <span>{count}</span>
      <button onClick={(e) => setCount(count => count + 1)}>ボタン</button>
    </div>
  )
}

```

### 正常なコード
useStateの下に置く。
コンポーネントがレンダリングされるたびにReactフックが同じ順序で呼び出されるようにする必要があるため、これによりエラーが解決されます。ループ、条件、またはネストされた関数内でフックを使用できない。
```
import React, { useState } from 'react'

export default function App() {
  const [loading, setLoading] = useState()
  const [count, setCount] = useState(0)

  // 👇
  if (loading) {
    <p>Loading...</p>
  }

  return (
    <div>
      <span>{count}</span>
      <button onClick={(e) => setCount(count => count + 1)}>ボタン</button>
    </div>
  )
}

```

参照
[Rules of Hooks](https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level)
json の値を環境変数に設定する話 

# Overview

たとえば環境変数を json から読み込みたいとき。

# お困り事例

たとえばこんな json を

```json:env.json
{
  "DB_HOST": "mysql.example.com",
  "DB_NAME": "sampledb",
  "DB_PASSWORD": "password",
  "DB_USER": "user",
  "VAR1": "val1",
  "VAR2": "val2",
  "VAR3": "val3"
}
```

環境変数にしたい時ってあるじゃないですか。

```bash:bash
$ echo $DB_HOST
mysql.example.com

$ echo $DB_NAME
sampledb
```

## 解

こんな感じで変換すると

```js:to-env.jq
{DB_HOST, DB_NAME, DB_PASSWORD, DB_USER}
| to_entries[]
| [.key, .value]
| join("=")
```

こうなるので、

```
$ jq -r -f to-env.jq env.json
DB_HOST=mysql.example.com
DB_NAME=sampledb
DB_PASSWORD=password
DB_USER=user
```

これを `export` の引数に渡してやると、いい感じになる。

```bash:bash
$ export $(jq -r -f to-env.jq <env.json)

$ env | grep -e DB_HOST -e DB_NAME -e DB_USER -e DB_PASSWORD
DB_PASSWORD=password
DB_USER=user
DB_HOST=mysql.example.com
DB_NAME=sampledb

$ echo $DB_HOST
mysql.example.com
```

### 駄目な例：その１

なお、シェル変数にしようと思って `export`　をつけないと、思惑通りにいかず、エラーになるので注意。

```bassh:bash
$ $(jq -r -f to-env.jq <env.json)
-bash: DB_HOST=mysql.example.com: コマンドが見つかりません
```

### 駄目な例：その２

あと、値にホワイトスペースが入ってると駄目なので、

```bash:bash
$ jq -r -f to-env.jq env.json
DB_NAME="sample    db"

$ export $(jq -r -f to-env.jq env.json)
-bash: export: `db'': 有効な識別子ではありません
```

素直に一度ファイルに落とすなどして対応するとよいと思う。

```bash:bash
$ jq -r -f to-env.jq env.json >.env

$ . .env && echo "$DB_NAME"
sample    db
```

## ワンライナー

`&&` で繋げば1行でもいける。

```bash:bash
$ export $(jq -r -f to-env.jq <env.json) && echo $DB_HOST
mysql.example.com
```

`Dockerfile` とか `Makefile` とか、どうしても1行に詰め込まないとならないときに。

## 応用：ファイルに埋め込む

`envsubst` と合わせると

```cnf.tpl
[client]
host=${DB_HOST}
port=3306
user=${DB_USER}
password=${DB_PASSWORD}

[mysql]
database=${DB_NAME}
```

簡易テンプレートエンジンみたいなことができちゃったり。

```bash:bash
$ export $(jq -r -f to-env.jq env.json) && envsubst <cnf.tpl
[client]
host=mysql.example.com
port=3306
user=user
password=password

[mysql]
database=sampledb
```

っていう話。