OmniAICreator/Qiita-1.07M huggingface dataset:
[TypeScript] 配列のUnion (e.g.  A[ ] | B[ ] ) を型として持つ値がどちらの配列なのかを判定する方法

# この記事でできるようになること
以下の引数arrのように`２つの異なる型の配列をUnion型として持つ値`をどちらの型の配列かを判定し、その結果をもとに条件分岐し型ごとに処理を分けることができる

```typescript
type Hoge = {
  type:'A',
  id:number,
  name:string;
}

type Fuga = {
  type:'B',
  id:number
}

const sample = (arr:Hoge[]|Fuga[])=>{
  ????

  if(????){
    console.log(arr[0].type) // => A
  }else{
    console.log(arr[0].type) // => B
  }
}
```

# 方法

## 結論
`user-defined typeguard`を用いて次のような判定用の関数を作成すれば良い

```typescript
const isHogeArr = (item:any): item is Hoge[] => item[0].type === 'A';
```

```typescript
type Hoge = {
  type:'A',
  id:number,
  name:string;
}

type Fuga = {
  type:'B',
  id:number
}

const sample = (arr:Hoge[]|Fuga[])=>{
  const isHogeArr = (item:Hoge[]|Fuga[]): item is Hoge[] => item[0].type === 'A';

  if(isHogeArr(arr)){
    // arr はHoge[]と判定される
    console.log(arr[0].type) // => 'A'
    console.log(arr[0].name) // => errorなし
  }else{ 
    // arr はFuga[]と判定される
    console.log(arr[0].type) // => 'B'
    console.log(arr[0].name) // => error Fugaにはnameプロパティは存在しないため
  }
}
```

## 説明

### そもそも`user-defined type guard`って？
関数の戻り値の型に `引数 is 型`としてTypeScriptに型を教えてあげる機能。
TypeScriptは関数の戻り値がtrueなら`引数の型は上記で指定した型`と認識し、 falseなら`指定した型ではない`と認識する

### 今回の使い方
今回はsample関数の引数として渡されたarrがHogeの配列なのか、Fugaの配列なのかを判定したい。そこで`引数 is Hoge[]`となる判定関数を作る。
この際戻り値を決める条件式に関しては、
arrがHoge[]の時だけtrueにしたいので、HogeとFugaで共通して持つが値は異なるtypeプロパティを配列の先頭の要素から取得して評価する。
Hogeの時は,`type==='A'`なので戻り値はtrueになる。従ってTypeScriptはisHogeArrの戻り値(引数)の型はHoge[]であると判断する。

```typescript
const isHogeArr = (item:Hoge[]|Fuga[]): item is Hoge[] => item[0].type === 'A';
```

### その他の使い道
自分が`user-defined type guard`を最初に知ったのは、型が`(string | undefined)[]`な配列からundefinedを取り除く処理の書き方を学んだ時だった。

例えば、以下のような処理をした時は、resultの結果は`(string | undefined)[]`になる。

```typescript
const arr = ['A','B','C']
const result = ['A','B'].map(item => arr.find( i => i ===item))

```
ここからundefinedを取り除こうとfilterメソッドを使ってもundefinedを取り除くことはできない

```typescript
const result2 = result.filter(item => item !== undefined)
// => (string | undefined)[]
```

`user-defined type guard`を使うとこれを解決できる
次のような判定関数をかくと、result3はstring[]になる

```typescript
const isNotUndefined = (item:string|undefined):item is string => { return item!==undefined}

const result3 = result.filter(isNotUndefined)
// => string[]
```


# 参考
- [Cannot type hint an arguments as two different Array shapes](https://github.com/microsoft/TypeScript/issues/11076#issuecomment-250362001)
- [Typescript: Check "typeof" against custom type](https://stackoverflow.com/questions/51528780/typescript-check-typeof-against-custom-type/51529486)
LASP: The type or namespace name 'Span<>' could not be found 

LASPをUnity 2021.1.17f1で使っていると，`ReadOnlySpan<>`　と `Span<>` が見つからないと怒られました．

![83685623-d8fdf200-a5e0-11ea-970b-8cf9dd3aa252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1771055/b0e4dce7-b848-3a10-94be-649e64aa57b6.png) 


[LASPのissue](https://github.com/keijiro/Lasp/issues/28)と[KlakNDIのissue](https://github.com/keijiro/KlakNDI/issues/72)の両方を参考にしながら，この問題を解決しました．

`Project Settings -> Player -> Other Settings -> Configuration` の項目に `Api Compatibility Level`があるので，`.NET 4.x`にし，Scripting Define Symbolsに`NET_STANDARD_2_0`をいれてApplyをすれば終わりです！

![NET_STANDARD_2_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1771055/47646d22-79af-acb2-2e12-c82a6c72b4a3.png)
別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません。と出た時の対処法

ファイルやフォルダを削除・移動しようとした際に『別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません。』というメッセージが出た時の対処法です。

![msgBox](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/83a67f9a-0f51-5ba8-26da-c43d954cb0c6.jpeg)

# 開いているアプリケーションが何かを調べる方法

1. 検索ボックスに「resmon」と入力し、リソースモニターを起動する
	![resmon](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/74f8486e-95e2-31de-16c9-e7f9807affd5.jpeg)

2. 「CPU」タブを開く
	![CPU](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/ae090cf0-b23b-9cc0-2535-0cfe0393e3f4.jpeg)

3. 「関連付けられたハンドル」の「ハンドルの検索」に削除・移動できないファイル名もしくはフォルダ名を入力して検索する
	![search](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/2ddcb85a-e1e9-2c70-bbed-c1553ecd4eb9.jpeg)

4. 検索結果に表示されたアプリケーションを終了する
	![handle](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/13f2fee1-0662-a9cf-c3e7-513b90039c80.jpeg)

これで削除・移動できるようになるはずです。
アプリケーションを終了しても削除・移動できない場合は、PCを再起動してください。
AdvancedHMIでPCをHMI化 (modbus RTU)

##はじめに
日本語情報が少なかったので、設定等忘れないように覚書
PCから簡単にPLCの内部情報が引っ張れたらいいなと思い使ってみた。

##AdvancedHMIとは
ソフトウェアHMI（ヒューマンマシンインターフェース）
メーカー製タッチパネルディスプレイと同じことを、Windows,LinuxPCで実現できる。
ドングル等は不要

##環境
・PLC : KV-N24AT（内臓シリアルポート）
・PC : Windows10
　- Microsoft Visual Studio Community 2022 (64 ビット)
　- advancedHMI　v3.99x 

##手順
PLC側とPC側の通信設定を合わせたら準備OK
好きなプロトコルを選んでボタン類を置いて、アドレス指定すれば完了。

###通信プロトコル設定
今回はPLC内臓のシリアルポートとmodbusRTUで通信としている。
他通信方式でもやることは同じ。

####PLC側
- KV-STUDIOのユニットエディタから内臓シリアルの設定を変更。
- Modbusスレーブモードに設定　＋　ボーレート等はPC側と合わせる。

####PC側
- AdvancedHMIのソリューションを開き。
- ツールボックスからAdvancedHMIDriversのModbusRTUCom.vbを選択。
- 画面上にドラック&ドロップで設置。
- 配置されたModbusRTUComを選択する。
- プロパティ内のCommunication_Settingsの設定をPLCの設定を合わせる。

###デザイン

- ボタン類を配置して、プロパティを設定する。
- アドレスは+1すること。（仕様？）

アドレス仕様はよく理解していないが、+1する必要がある。
R000だったら、00001
R100だったら、00017

ボタンはPLCAddressClickにアドレスを記載
ランプはPLCAddressValueだったはず。

他、DMを読みたい場合はファンクションコードを指定する必要がある。
ファンクションコードを指定方法は下記
3:00001

##さいごに
メーカー製HMI（タッチパネルディスプレイ）は高額なのでフリーのHMIを使ってみたが、
仕事では使わないかな。というところ…

デザインが好みではないので…
Laravelプロジェクトをcloneしてきたらやること

Laravelのプロジェクト作成後にやる設定もろもろ忘れることが多いのでメモ。


### ライブラリのインストール

```php
composer install
```

### .envの作成・編集

デフォルトだと.envファイルが存在しないので、.env.exampleからコピーする
```php
cp .env.example .env
```
.envの編集

```
vi .env
```
僕はvim使うことが多いので今回はvimで編集。
DBの設定周りの設定をします。

### アプリケーションキーを設定

```php
php artisan key:generate
```
### パーミッション変更

```
chmod -R 777 storage
chmod -R 777 bootstrap/cache
```

## 必要であれば
### マイグレーション実行

```php
php artisan migrate
```
### シーダーの実行

```php
php artisan db:seed
```

### storageにシンボリックリンクを張る
storage配下扱うときは必ず
```
php artisan storage:link
```
Vue.jsでchart.jsを使用する

# 概要
Vue.jsでchart.jsを使用してグラフを描画する。
備忘録として記載します。

# 環境
* @vue/cli 4.5.15
* vue@2.6.14 (vuetify使用のため、2を使用する)
* chart.js@2.9.4
* vue-chartjs@3.5.1
* vuetify@2.6.3
* vuetify-loader@1.7.3

chart.jsについては、versionが3.0.0以上だと以下のエラーが出てしまうようです。
`TypeError: chart_js__WEBPACK_IMPORTED_MODULE_0__.default is not a constructor`


# chart.js 関係のインストール
```
npm install vue-chartjs
npm install chart.js@2.9.4
```

# ファイル構成
ファイル構成は以下になる。
`vue create`と`vue add vuetify`で生成する。
```
src
├── App.vue
├── components
│   └── chart
│       ├── bar_chart_box.js
│       └── barChartCard.vue
├── main.js
├── plugins
│   └── vuetify.js
├── router
│   └── index.js
└── views
    └── Home.vue
```



今回は棒グラフを作成する
bar_chart_box.jsがベースで、各vueファイルで読み込み
```javascript:bar_chart_box.js
import { Bar } from "vue-chartjs";

export default {
  extends: Bar,
  props: ["chartData", "options"],
  mounted() {
    this.renderChart(this.chartData, this.options)
  }
}
```

```vue:barChartCard.vue
<template>
  <v-card outlined elevation="2">
    <v-card-title>
      <v-icon>mdi-image</v-icon>
      履歴
    </v-card-title>
    <v-card-subtitle>ユーザー履歴</v-card-subtitle>
    <v-card-text>
      <Chart :chartData="chartItems" :options="chartOptions"/>
    </v-card-text>
  </v-card>
</template>
 
<script>
  import Chart from './bar_chart_box.js'

  export default {
    components: {
      Chart
    },
    data() {
      return {
        chartItems: {
          labels: ["ユーザー1", "ユーザー2", "ユーザー3", "ユーザー4", "ユーザー5"],
          datasets: [{
            label: "アクセス数",
            data: [12, 23, 4, 16, 28],
            backgroundColor: 'skyblue'
          }]
        },
        chartOptions: {
          maintainAspectRatio: false,
          scales: {
            // X-Axis
            xAxes: [{
              display: true,
              // グリッドの非表示
              gridLines: {
                display:false
              }
            }],
            // Y-Axis
            yAxes: [{
              display: true,
              position: 'left',
              ticks: {
                beginAtZero: true,
                maxTicksLimit: 10,
              },
            }]
          },
        }
      }
    }
  }
</script>
```

```vue:Home.vue
<template>
  <div>
    <v-row>
      <v-col>
        <barChartCard />
      </v-col>
    </v-row>
  </div>
</template>

<script>
  import barChartCard from "../components/chart/barChartCard.vue";

  export default {
    name: 'Home',
    components: {
      barChartCard
    }
  }
</script>
```


`npm run serve`で以下のように表示されました
![スクリーンショット 2022-02-12 0.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449831/2ffc689f-ee89-e28f-f10f-eea5739c645d.png)
OOUIについてメモ

# OOUI
OOUIとはオブジェクト指向UI(Object Oriented User Interface)を意味する。一言で言えばオブジェクトを起点に作られたUIのことである。
対になるものとしてタスク指向UIがある。これはタスクを起点に作られたUIのことである。

# 例
ECサイトを例に挙げてそれぞれのUIについて説明する。
## オブジェクト指向UI
　商品の一覧画面ではオブジェクト、すなわち商品を起点としてUIが構成されている。商品を選択すれば

- カゴに入れる
- 購入する
- 口コミを見る
- 説明を見る

など様々なアクション(タスク)ができることを直感的に想像させる。
　逆にこれをタスク指向UIで構成しようとすると、タスクを起点にUIが構成されているので、購入するまでの流れは以下のような流れになる。

- 「説明を見る」(タスク)を選択する→説明を見たい商品(オブジェクト)を選択する
- 「口コミを見る」(タスク)を選択する→口コミを見たい商品(オブジェクト)を選択する
- 「カゴに入れる」(タスク)を選択する→カゴに入れたい商品(オブジェクト)を選択する
- 「購入する」(タスク)→購入したい商品(オブジェクト)を選択する

オブジェクトごとのタスクが複数あったり複雑であればタスク指向よりもオブジェクト指向でUIを構成したほうが直感的でありわかりやすい。

## タスク指向UI
　検索するための画面ではアクション、タスクを起点としてUIが構成されている。例えば

- 値段で絞って検索する
- ジャンルで絞って検索する
- 評価で絞って検索する

などが選択できるようになっている。何を軸に検索したいかという行動が定まっていない場合にタスク指向UIが有効である。

# 参考
https://nijibox.jp/blog/ooui/#OOUI
https://www.concentinc.jp/design_research/2021/07/ooui/
https://sevendex.com/post/3676/
shellscript上で、数値のリスト(LIST=(0 5 2 3 6 3 2 9 19 1 11))から最大の値を線形探索する

shellscript上で、数値のリスト(LIST=(0 5 2 3 6 3 2 9 19 1 11))から最大の値を線形探索する

```shell:test.sh
#!/bin/bash                                                                                                                                                                                          

function testfunc(){

    # exec loop                                                                                                                                                                                      
    local LOOP_MAX=10
    local SCORE_MAX=-10000000000
    local SCORE_MAX_INDEX=1
    LIST=(0 5 2 3 6 3 2 9 19 1 11)

    for N in `seq 0 ${LOOP_MAX}`; do
    # check max score                                                                                                                                                                                
        echo ${LIST[${N}]}
        if [ ${LIST[${N}]} -ge ${SCORE_MAX} ];then
            SCORE_MAX=${LIST[${N}]}
            SCORE_MAX_INDEX=${N}
        fi
    done

    echo "SCORE_MAX=${SCORE_MAX}"
    echo "SCORE_MAX_INDEX=${SCORE_MAX_INDEX}"
}
testfunc
```

実行

```
$ bash test.sh
0
5
2
3
6
3
2
9
19
1
11
SCORE_MAX=19
SCORE_MAX_INDEX=8
```

以上です。
もうページの一番下までスクロールして「次へ」ボタンを押すのはしんどいので、Gesturefyを導入した

## なぜGesturefy？
私の場合やりたいのは無限スクロール化ではなくスムーズなページ送り、つまりスクロールする手間の省略なので、まず無限スクロール系のアドオンは除外した
正直マウスジェスチャー以外の方法でやりたかったが、適任となるものが見つからなかったのでこちらにした（Firefox向けのみで探したので、Chrome向けだともしかしたらあるのかもしれない）

（[NextPrev Page](https://addons.mozilla.org/ja/firefox/addon/nextprev-page/)というのもあったが、こちらはGesturefyと違いショートカットキーを設定することはできるものの、正規表現などの文字列マッチで増減させる数字を指定できないためurlエンコードなどで誤動作してしまうことがあった）
## 手法
URL内に`page=2`及び`page/2`というような文字列があった場合、その中の数字を増減させる
## やりかた
1. [Gesturefy](https://addons.mozilla.org/ja/firefox/addon/gesturefy/)を入れます
2. Gesturefyの設定画面を開きます
3. 新しいジェスチャーを適当に作成し、コマンドに「URLの数値を増やす」を選択します（中盤辺りにあります）
4. 「マッチパターンの指定」で`((?<=page=)|(?<=page\/))\d+`を指定します[^1]
5. 保存を選択し、もう片方の方のジェスチャーも同じように作成します

以上です

あとはお好みでGesturefy自体の設定をいじるなどしてください
手法はなんにせよ、ちまちま一番下までスクロールしてページ送りボタンを押すコストは人によっては馬鹿にならないと思うので簡略化できるといいですね

私の場合サクサクページ送り出来て大分便利になりました

追記：vimiumの`[[`と`]]`でも似たようなことができるようなので、適宜使い分けるといいと思います（現在だと私は主にそちらを使っています）  
Gesturefyのはurlをいじる方式で、vimiumのやつはリンクテキストから判別してそこをたどるものっぽいので、両方使えたほうが便利そうではあります  


[^1]: ちなみに`?<=`の意味はよくわかってないんですが、なんか動くのでオーケーです（なぜかこれがないと動かないのでwikiから丸パクリした）。~~正規表現のテスターにかけてもエラーになるし独自の判断用フラグっぽい？~~ →肯定的先読みってやつらしい、完全に理解。[記事に書いた](https://qiita.com/ewre/items/22636b6d9444550fa0b0)
複数あるjsonファイルを１つのjsonファイルにしたい

以下のようなjsonが複数あり、順番に生成される状況であったとする。 
この状況下で以下を行いたい

- `index`を取得する
- `index`以外を抜き出す
- `json`ファイルを新しく作る
- `index`をキーにして１つのjsonファイルにする。（`test1.json`,`test2.json`...`testn.json` --> `test.json`）

`json`ファイル

```json:test1.json
{
  "test": {
    "index":1
    "testtest": [
      123,
      456
    ]
  }
}
```

```json:test2.json
{
  "test": {
    "index":2
    "testtest": [
      789,
      012
    ]
  }
}
```

- `index`を取得する

```
$ jq .test.index test1.json
1
```

- `index`以外を抜き出す

```
$ jq 'del(.test.index)' test1.json
{
  "test": {
    "testtest": [
      123,
      456
    ]
  }
}
```

- `json`ファイルを新しく作る

```
$ echo {} | jq . > file.json
$ jq . file.json 
{}
```

- `index`をキーにして１つのjsonファイルにする。（`test1.json`,`test2.json`...`testn.json` --> `test.json`）

```shell:do.sh
OUTPUTJSON="output.json"
echo {} | jq . > ${OUTPUTJSON}
# loop N
LOOP_MAX=2
for N in `seq 1 ${LOOP_MAX}`; do
    # get index
    INDEX=`jq .test.index test${N}.json`
    # get json without index
    TESTJSON_WITHOUT_INDEX=`jq 'del(.test.index)' test${N}.json`
    # update ${OUTPUTJSON}
    jq ".index${N} = ${TESTJSON_WITHOUT_INDEX}" ${OUTPUTJSON} > tmp && mv tmp ${OUTPUTJSON}
done
jq . ${OUTPUTJSON}
```

```bash
$ bash do.sh
{
  "index1": {
    "test": {
      "testtest": [
        123,
        456
      ]
    }
  },
  "index2": {
    "test": {
      "testtest": [
        789,
        12
      ]
    }
  }
}
```

キーの概念と微妙に異なる部分があるかもしれないが、やりたい事はできている。

# 参考

[jq コマンドで新規JSONファイルを生成するには](https://qiita.com/Morichan/items/3ae173db33e66cb2c9a0)
[jq で複数の JSON ファイルを結合して書き出す](https://webgroove.work/jq-cat-json/)
[jqコマンド(jsonデータの加工, 整形)の使い方](https://www.wakuwakubank.com/posts/676-linux-jq/)
【Docker】Dockerに関する用語について

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## Dockerについて

### Dockerとは
Dockerとは、コンテナ型仮想環境を作成、実行、管理するためのプラットフォームです。
Dockerのソフトウェアを使用して素早くコンテナを起動し、さまざまなアプリケーションを実行することができます。
また、異なる環境で容易に同じ仮想環境を再現することができ、開発チームのメンバー間で同じ環境を用意する際に重宝されます。
Docker自体はGo言語で書かれています。

### Dockerを学習していると出てくる用語について
#### Dockerイメージ
Dockerコンテナを作成するための雛形です。
Dockerイメージは、アプリケーション、ライブラリ、設定ファイルなどのアプリケーション実行に必要なものが一式まとめられたものです。
完成したアプリケーションをDockerイメージとして保存し、別のサーバーに持っていくことで同じ環境を別のサーバー上で再現することができます。

#### Dockerコンテナ
Dockerイメージを元に作成されるコンテナ型仮想環境のことです。
イメージからコンテナを作成することで、何度でも簡単に同じ環境を作成することができます。
また、コンテナを起動することで、予めイメージにセットアップしたアプリケーションの機能を提供することができます。


#### Docker Hub
Dockerイメージを保存するための機能などを提供しているサービスです。
Docker Hubから公開されているイメージをダウンロードすることで様々なコンテナを起動することができます。

#### nginx・Apache
Webサーバーのソフトウェアです。

#### MySQL・Postgrespl
データベースサーバーのソフトウェアです。

#### Ubuntu
Linux OSのディストリビューションの一つです。

#### Redis
Key-Value型でデータを保存するキーバリューストアと呼ばれるデータベースシステムの一種です。
メモリ上にデータを保持して高速に動作します。
アプリケーションのデータのキャッシュや、セッション情報の保存によく使用されます。

#### Node.js
Javascriptの実行環境で、サーバー上でJavascriptのプログラムを実行することができます。
VSCodeにFlaskを導入する方法ー補足ー

以前の記事 [VSCodeにFlaskを導入](https://qiita.com/Euphysics/items/db0d17dbd5416c480456) では、
>
+ 手順３
hogehoge.py ファイルを作り保存する。
>
ここでは以下のモノを試した。
>
```python:hogehoge.py
from flask import Flask
app = Flask(__name__)
>
@app.route("/") #当然ここでの app は2行目の app を受けて。2行目が hoge = Flask... であれば @hoge.route(...) とする。
def hello_world():
    return"<p>Hello, World!</p>"
```

と minimal な構成を行っていた。
以下では、@app.route("/") 以降について補足しておく。
以前の hogehoge.py に代わり、次のモノを用意する。

```python:hogehoge2.py
from flask import Flask,render_template
app = Flask(__name__)

@app.route("/")
def hello_world():
    return"<p>Hello, World!</p>"

@app.route("/about")
def about():
    return"<h1>About:</h1>"

@app.route("/hello/<hoge>")
def hello(hoge):
    return f"<h1>Hello {hoge}</h1>"
    #Python3.6以降に導入されたもの
    #f文字列という。Pythonで文字列の中に変数を組み込む場合に用いる。
    #他にもr文字列なども存在する。
    #変数は{}で囲う。

@app.route("/addition/<int:num>_<int:num2>")
def add(num,num2):
    return f"{num}+{num2}={num+num2}"
    #このように変数の型（コンバーター）を指定することも可能
    #リクエストを処理する際に文字列として受け取った値の処理が簡単に
    #string / int / float / path / uuid がある
    #コンバーターを使うことで、例外処理を自前で実装する必要がないのは便利かも

@app.route("/hello2/<hoge2>")
def hello2(hoge2):
    return render_template("hello.html",whom=hoge2)
    #変数whomはhello.htmlファイル内で用いられている変数
```
1行目に`,render_template`を加えた。
これは`@app.route("/hello2/<hoge2>")`で必要となるためである。
5行目以降に同じようなものをいくつか加えていることが分かる。

+ `@app.route("/about")`について

flask run で実行して表示された URL を開くとこれまで通り Hello, World! と表示されている（以下同じ）
開いた URL（=BaseURLとする） の後に BaseURL/about と記述すると about 関数が実行される（以下同様）。

+ `@app.route("/hello/<hoge>")`について

BaseURL/*** と記述する際の *** に変数を設定することもできる。
hello 関数の中身、return f"..." とあるが、これはf文字列と呼ばれるもの。
Pythonで文字列の中に変数を組み込む場合に用いる（Python3.6以降に導入）。

+ `@app.route("/addition/<int:num>_<int:num2>")`について

変数の型を指定することもできる。
変数の型として string / int / float / path / uuid がある。
予め変数の型をこちらで定義しておくことで、他の型は受け付けなくなるので処理が簡単になることがある。

+ `@app.route("/hello2/<hoge2>")`について

Jinja2テンプレートエンジンを用いて、html ファイルを別に用意しておき、そこに変数を代入することができる。
この hogehoge2.py 内では hoge2 という変数に文字列などが入力される。
そして render_template 関数の引数を見ると、hoge2 の中身を whom という変数に代入してある。
**この whom は hello.html ファイル内で用いられている変数名と一致させてある。**

---

以下、この hello.html ファイルの配置と中身について

+ 手順１ templates フォルダの作成

Flaskでは、テンプレートをtemplatesフォルダから検索する。
Flask アプリがモジュール（単一ファイル）で構成されている場合には、
templates フォルダはモジュールと同じレベルに配置。
Flask アプリがパッケージとして構成されているのであれば、パッケージ内に配置。

+ 手順２ hello.html ファイルの作成

templates フォルダ内にhello.html ファイルを作成する。
ここでは次のようなものを作った。

```html:hello.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
    <h1>Using Jinja2 Template engine</h1>
    <h2>Hello {{whom}}</h2> 
    <!-- ２重中括弧の部分がJinja2構文 -->
</body>
</html>
```

このとき、hogehoge2.py を実行し、 BaseURL/hello2/Taro と入力すれば、次のように表示される。
![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526409/7a0b2f95-6fdf-b8cd-c130-509f947aa140.jpeg)

次回は VSCode で作る仮想環境について。
Flask-loginでタイムアウト設定(記録)

FlaskにてFlask-loginを使用してsessionのタイムアウト設定を行いました。
パスワードのハッシュ化、セッションのタイムアウト後にログイン画面に推移します。

###app.py
```python
#import
from flask import Flask, session, app
from flask import render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin, LoginManager, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash

#app
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SECRET_KEY'] = os.rundum
app.config['PERMANENT_SESSION_LIFETIME'] = timedalta(minutes=10)#session time（10分）
db.SQLAlchemy(app)

#flask-login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' #redirect login

#user table
class User(UserMixin,db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    authority = db.Column(db.String(15), nullable=False)
    password = db.Column(db.String(15), nullable=False)

#login_manager
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

#signup
@app.route("/signup", methods=['GET','POST'])
@login_required
def signup():
    if request.method == 'POST':
        authority = request.form.get('authority')
        password = request.form.get('password')
        if authority == '':
            err_msg = "権限を入力してください"
            return render_template('auth/signup.html', err_msg = err_msg)
        elif password == '':
            err_msg = "パスワードを入力してください"
            return render_template('auth/signup.html', err_msg = err_msg)
        else:
            user = User(authority = authority, password = generate_password_hash(password, method='sha256')) #password hash
            db.session.add(user)
            db.session.commit()
            return render_template('auth/signup.html', authority = authority, password = password)
    else:
        return render_template('auth/signup.html')

#login
@app.route("/login",methods=['GET','POST'])
def login():
    session.permanent = True #make session permanent
    if request.method == 'POST':
        password = request.form.get('password')
        user1 = User.query.filter_by(authority = "host").one_or_name()
        user2 = User.query.filter_by(authority = "common").one_or_name()
        if check_password_hash(user1.password, password):
            login_user(user = user1)
            next = request.args.get('next')
            return redirect(next or url_for('search'))
        elif check_password_hash(user2.password, password):
            login_user(user = user2)
            next = request.args.get('next')
            return redirect(next or url_for('search'))
        else:
            err_msg = "パスワードがなし又は違います。"
            return render_template('auth/login.html', err_msg = err_msg)
    else:
        return render_template('auth/login.html')

```
SPA とは

## 勉強前イメージ

SPIみたいだね。全然SPAはピンとこない

## 調査

### SPA とは

Single Page Application の略で直訳すると単一ページのアプリケーションとなります。
これはwebページの構成の一つで、
ブラウザでページの遷移が発生せずアプリケーションが呼ばれて表示が変化する というものになります。
javascriptで動的に変化を加えながら画面描写を行っています。

### SPA のメリデメ

#### メリット

- 動作の向上

↑でも書いたとおり、ブラウザでのページ遷移が発生しないので
アクションに必要なデータだけをサーバに要求して
サーバとの通信量を抑えることができ、
webアプリケーションの動作を向上できます。

- 高度な技術を使える

ブラウザとの挙動に縛られることがないので
幅広いUIを実装できます。

#### デメリット

- 実装コストがかかる

元々ブラウザに処理をお願いしていた部分も実装する必要があるため
実装コストがブラウザに処理をお願いするよりかかってしまいます。

- 初期のローディングに時間がかかる

サーバとの遷移時のデータのやり取りは減るのでページの遷移が早くなりますが、
アプリケーションを動かすためのjavascriptのコードが追加されるので
最初のローディングに時間がかかってしまいます。

### SPAの例

google mapやメッセンジャーがSPAを実装して作られています。
googlemapであれば、画面遷移せずとも
場所を検索 → 確認 までを行うことができます。

## 勉強後イメージ

あれSPAっていうんだ・・・知らなかった。。
おしゃれなサイトにはよくあるイメージ

## 参考

- [シングルページアプリケーション（SPA）の導入メリット＆デメリット](https://www.oro.com/ja/technology/001/#:~:text=SPA%E3%81%A8%E3%81%AF%E3%80%8CSingle%20Page,%E8%A1%8C%E3%81%86Web%20%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%20%E3%81%AE%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3&text=SPA%E3%81%A7%E3%81%AF%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E3%82%88%E3%82%8B%E3%83%9A%E3%83%BC%E3%82%B8,%E5%BE%97%E3%82%89%E3%82%8C%E3%82%8B%E4%BD%93%E9%A8%93%E3%81%AE%E3%81%93%E3%81%A8%E3%80%82)
- [SPA（Single Page Application）の意味を徹底解説します！](https://www.profuture.co.jp/mk/column/28468)
SQL Serverでレコード件数を調べる方法

テーブルのレコード件数を調べる方法としてまず思いつくのがcount関数ですが、件数が膨大なテーブルに対して実行した場合、結果が返ってくるまでに時間がかかります。

```sql
SELECT
	count(*) as [行数]
FROM
	[テーブル名]
```

![count](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/38bd6523-f713-3e88-6094-21571998814b.jpeg)

count以外でレコード数を取得する方法について調べてみました。

# sp_spaceused

システム ストアド プロシージャのsp_spaceusedを使ってレコード数を取得できます。

[sp_spaceused (Transact-SQL) - SQL Server | Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-spaceused-transact-sql?view=sql-server-ver15)

```sql
EXEC sp_spaceused [テーブル名]
```

![sp_spaceused](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/074b0995-aaa5-1f14-c5d9-4d9c7a2301c3.jpeg)

# sys.partitions

システム カタログ ビューを使用して、データベース内の全テーブルの行の概数を取得できます。

[sys. partitions (Transact-sql SQL) - SQL Server | Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-catalog-views/sys-partitions-transact-sql?view=sql-server-ver15)

```sql
SELECT
	 obj.name as [テーブル名]
	,sum(par.rows) as [行の概数]
FROM
	sys.objects as obj
INNER JOIN
	sys.partitions as par
	ON obj.object_id = par.object_id
WHERE
	obj.type = 'U'
	and par.index_id < 2
GROUP BY
	obj.name
ORDER BY
	obj.name
```

![rows](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/436205ec-c832-5f40-82e0-ab96e7f4e66f.jpeg)

テーブルがパーティション分割されている場合、パーティションごとの行の概数も取得できます。

```sql
SELECT
	 obj.name as [テーブル名]
	,par.partition_number as [パーティション番号]
	,par.rows as [行の概数]
FROM
	sys.objects as obj
INNER JOIN
	sys.partitions as par
	ON obj.object_id = par.object_id
WHERE
	obj.type = 'U'
	and par.index_id < 2
ORDER BY
	 obj.name
	,par.partition_number
```

![partitions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/9ae4621c-ced3-a351-4589-79330b6c9502.jpeg)

# sys.sysindexes

sys.sysindexesを使用して行数を取得もできますが、sys.sysindexesは将来サポートされなくなるようです。

[sys.sysindexes (Transact-SQL) - SQL Server | Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-compatibility-views/sys-sysindexes-transact-sql?view=sql-server-ver15)

> この機能は、Microsoft SQL Server の将来のバージョンで削除されます。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください

```sql
SELECT
	 obj.name as [テーブル名]
	,ind.rows as [行数]
FROM
	sys.objects as obj
INNER JOIN
	sys.sysindexes as ind
	ON obj.object_id = ind.id
WHERE
	obj.type = 'U'
	and ind.indid < 2
ORDER BY
	obj.name
```

![sysindexes](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230850/aec611b1-cc1c-74e3-90af-d0e5d7df02dc.jpeg)
自作ライブラリをComposerでインストールできるようにしよう！

# はじめに
今回カレンダーライブラリを作成してみました。

https://github.com/tyatyamaruko/Calendar

仕事でカレンダーを表示するような事例が多々あるのでこの際ライブラリ作ってcomposerでインストールできるようにしてしまおうと思いったったのがきっかけです。

さて、ライブラリの中身については省略してどうやって

```
composer require hogehoge/fugafuga
```

できるようにするのかみていきましょう。

# composer.json
作ったライブラリ（composer requireできるようにしたいやつ）のルートディレクトリにcomposer.jsonを作成しましょう。
作成できたら書き込んでいきましょう。

```json:composer.json
{
  "name": "hogehoge/fugafuga",
  "description": "hogehoge~~~~~~",
  "version": 1.0,
  "type": "library",
  "authors": [
    {
      "name": "hogehoge";
      "email": hogehoge@example.com
    }
  ],
  "autoload": {
    "psr-0": {
      "FugaFuga\\": "src/"
    }
  },
  "license": "MIT"
}
```

こんな感じでかけたら以下のコマンドを打ちましょう

```bash
composer validate
```
composer.jsonのバリデーションしてくれます。

ここまでできたらリポジトリにプッシュしましょう。

# LICENSEファイルの作成

githubでリポジトリを作成する際に作れるそうなんですが、忘れてた場合について書いておきます。

- Add file -> Create new file　を押す
- ファイル名を入力するところで　LICENSE または　LICENSE.mdと入力する
- すると Choose a license template　というものがあるのでクリックしてください
- composer.jsonで指定したlicenseと同じものを選択する

こんな感じでできます。

詳しくは[こちら](https://docs.github.com/ja/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository)を参照してください。

# packaist
[packagist](https://packagist.org/)でアカウントを作成してください。
作成したらメニューバーからSubmitを押してください。
Repository URLとなっているところにgithubのリポジトリのURLを入力し、checkを押してください。
続けてSubmitを押してください。

問題なければこれでcomposerでインストールできるようになってます。

# さいごに
なかなかしんどいですが、これで自分のライブラリを誰でも使えるんだ〜へえ〜って感じですね。

# 参照
http://vdeep.net/composer-packagist
ほぼ知られていないが有用なWindows用ソフト

面倒なので文字ベタ打ち生地失礼します。

世の中ググってわからないことはない...いや実際はそんなにうまくいかないことも多い。「こんなソフト無いかな？」と思って検索した場合、多くの場合はきちんと探せるのですが、ほんの一部例外もあり、ひどい場合ソフトのジャンルをググっても全然出てこないで、目的とは被らない内容を何か検索している際に偶然発見することもあるくらいです。
以下は、私が知っている、検索では発見困難なツールです。

EXEのbit数判別ツール
APEC
http://yamori-jp.blogspot.com/2011/03/windows-64-bit-exe-dll.html
この手のソフト、32bitだっけ64bitだっけ？とか64bit用のソフトだけど一部が32bitだということがわかってはいるけどどれが32bitなのかわからないとかいうときに便利です。
...とはいいつつ、ごく普通のWindowsユーザーはそんな悩むケースはなく、また自らツール作っているガチの方たちはVisualStudioなど使うと思うので、この手が必要な方はかなり少ないとは思いますが...
おそらく知名度からいえばExeDetectではないかと思いますが、こちらは現在は配布されていません。お勧めはapec。exeだけでなくdllファイルについても判別できます。なお、ARMはunknownになります。

Excelのインクリメンタルサーチ
ExAddin
https://www.vector.co.jp/soft/win95/business/se401446.html
文字を打ち込むごとにリアルタイムで検索を行ってくれる、インクリメンタルサーチ。Excelで使う方法はないかと検索すると、なんかそれらしき記事は出てくるものの...この検索ではなかなか出てこないツールのExAddinが一番だと思います。実は窓の杜で2006年に記事にされている。以下一部引用
－－－－－－－－－－－
「ExAddin」は、「MS Excel」でのXLSファイル編集時に便利な多数の機能を追加するアドイン。追加される機能は、セル内の文字列を任意のテキストエディターで編集できる機能や、任意のシートを一括で非表示にできる機能、文字列検索で一致したセルを一括選択状態にできる機能など、計10種類。 
－－－－－－－－－－－
この説明文の通り、インクリメンタルサーチは数ある機能の一つ。この機能を、Ctrl+Fに割り当てる(標準で設定できる)といいかもしれない(本来の検索はリボンからor置換を出してタブ切り替え)

フォルダ内フィルタリングツール
StExBar
https://sourceforge.net/projects/stefanstools/files/StExBar/
ファイルを探そうとして、フォルダ内に大量のファイルがあり、その中だけで探したい時はないだろうか？そんな時に便利なのが、フォルダ内をフィルタリングするツール。このたぐい、どんな検索キーワードを使えばいいかがわかりにくいのもあり、知名度が低いかもしれない。
この手のツール、XP時代はHandySelectorというのがありました。いや、現在でもダウンロードできます。ただ、エクスプローラと密接にかかわることからVista以降は動きません。そこで10でも64bitでも動く代替ツールが必要、ということでした。

WindowsPE作成ツール
WinPtchX
WinPEを作成するツールの一つ。知名度がないわけではないが、一つだけほぼ知られていないことを書いておく。Windows11に該当するWindowsPEも作成できるということ。なお、Windows11 WindowsPEとか検索しても出てきません。
コピペで即動くKafka速習

### JDKインストール
```
apt-get install java-1.8.0-openjdk-devel
```
### Kafka Brokerインストール
```
wget http://ftp.tsukuba.wide.ad.jp/software/apache/kafka/2.8.1/kafka_2.12-2.8.1.tgz
tar -xvf kafka_2.12-2.8.1.tgz
mv kafka_2.12-2.8.1 /usr/local/
cd /usr/local/kafka_2.12-2.8.1
```
### Zookeeper起動
```
./bin/zookeeper-server-start.sh -daemon ./config/zookeeper.properties
```
### Broker起動
```
./kafka-server-start.sh ../config/server.properties
```
### Topic作成
```
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
./kafka-topics.sh --list --zookeeper localhost:2181
test
```
### Topicにメッセージ生成
```
./kafka-console-producer.sh --broker-list localhost:9092 --topic test
>Hellow World!
>How has COVID-19 affected your country?
```
### Topicからメッセージ取得
```
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
Hellow World!
How has COVID-19 affected your country?
```
Kafka OpenShift

--- 
#コピペで即動くKafka速習
---
### JDKインストール
```
apt-get install java-1.8.0-openjdk-devel
```
### Kafka Brokerインストール
```
wget http://ftp.tsukuba.wide.ad.jp/software/apache/kafka/2.8.1/kafka_2.12-2.8.1.tgz
tar -xvf kafka_2.12-2.8.1.tgz
mv kafka_2.12-2.8.1 /usr/local/
cd /usr/local/kafka_2.12-2.8.1
```
### Zookeeper起動
```
./bin/zookeeper-server-start.sh -daemon ./config/zookeeper.properties
```
### Broker起動
```
./kafka-server-start.sh ../config/server.properties
```
### Topic作成
```
./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
./kafka-topics.sh --list --zookeeper localhost:2181
test
```
### Topicにメッセージ生成
```
./kafka-console-producer.sh --broker-list localhost:9092 --topic test
>Hellow World!
>How has COVID-19 affected your country?
```
### Topicからメッセージ取得
```
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
Hellow World!
How has COVID-19 affected your country?
```
migrationファイルのnull:falseとは

## はじめに
Qiitaへの初投稿になります。
学習していて気になったので調べてみました。
# 意味
migrationファイルのnull:falseとは指定したカラムがデータベースに空の状態で保存されることを防ぐものです。

```ruby
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.string :name,    null: false
      t.text :text,      null: false
      t.timestamps
    end
  end
end
```

上記の場合nameカラム、textカラムを空で保存できない設定になります。
# presence: true
似ているものでmodelにバリデーションとして記述するpresence: trueがあります。
意味は指定したカラムが空の状態で保存されることを防ぐ。

```ruby
class Post < ApplicationRecord
  validates :name, presence: true
  validates :text, presence: true
end
```

こちらの記述もnameカラム、textカラムを空で保存できない設定です。
似ているというか意味は同じですね。

# なぜ似たようなものがあるのか？

presence: trueはRailsアプリでの設定で、これだけの設定だとデータベースへSQLで直接空のデータを保存できてしまいます。

* migrationファイルはデータベースに対する設定
* モデルのバリデーションはRailsに対する設定

**null: false 、 presence: true　両方設定した方が安全**

# おわりに
調べてみるとなるほどなと思いました。プログラミング学習をしていると横文字が多くて訳が分からなくなります。疑問を感じたら、その都度調べていく事が大事だと感じました。
そしてその調べた先にも横文字があるという・・・・・・。
# 参考

https://qiita.com/baby-0105/items/59a2a6946cbe8f53240e

https://mikannoishiii.hatenablog.com/entry/what-is-null-false
スマホで電話番号入力の際に数字のキーボードを出す（jQuery）

WordPressのプラグイン「MW WP Form」で、電話番号入力の際にスマホで数字キーボードを出したい！
そう思ったときによくあるのは、functions.phpに下記を追加するというもの

```php:functions.php
function my_do_shortcode_tag(   ) {
	if ( $tag == 'mwform_text' && $attr['name'] == 'hoge' ) {
		$output = rtrim( substr( $output , 0 , -3 ) ) . ' inputmode="tel" />' . "\n";
	}
	return $output;
}
add_filter( 'do_shortcode_tag', 'my_do_shortcode_tag', 10, 4 );
```

うまくいった！と思ったのですが…
バリデーションで入力エラーが出た後にもう一度入力しようとすると、数字のキーボードが出なくなりました…

type属性をtelにしたらなんか入力項目が分割されてしまうし…
なにか方法がないかな〜と調べてたところ、どうやら ``inputmode="tel"`` だと数字のキーボードがでるということがわかった（いまさら…）

ならば発想を変えてjQueryとかで属性入れられないかなと思ったらできました。

```html
<input type="text" class="tel">
```

```javascript
$('.tel').on('focus', function () {
  $(this).attr("inputmode", "tel");
});
```
これで入力エラー後でもちゃんと数字キーボードがでました！
たぶんこれで支障はないと思いますが…
なにか支障がありそうであれば教えて下さい〜:bow:
現場 Rails の gem install mailcatcher でハマったところを brew install mailcatcher で解決した件

# 目次
- [対象となる読者](#対象となる読者)
- [筆者の解決方法](#筆者の解決方法)
- [mailcathcer 導入手順](#mailcathcer-導入手順)
- [参考文献](#参考文献)

# 対象となる読者
- 本記事は「[現場で使える Ruby on Rails 5 速習実践ガイド](https://book.mynavi.jp/ec/products/detail/id=93905)」通称「現場Rails」で<br>
メール送信処理の動作確認を行うためテキスト通り「$ gem install mailcatcher」を<br>
実行したらエラーが出て沼った人に向けて書きました。
- ~~意地でも mailcatcher を使いたい人。~~
- 動作環境
 - macOS Monterey version 12.2
 - MacBook Air(M1, 2020)
 - コマンドはVSCodeのターミナルで実行しています。

**<font color="Red">勿論、本記事が絶対の正解ではないので、その辺りは予めご了承ください！**</font>

# 筆者の解決方法
結論から言うと、gemではなく、brew経由でインストールしました。
brewでインストールするに至った経緯としては、mailcathcerの開発者が
Gemfileにmailcatcherを入れないでくださいと[README.md](https://github.com/sj26/mailcatcher)に記載されていたので、
「それじゃあgemにこだわらなくてもいいのでは？」と思い、
試しに brew install したら上手くいったと言う話です。簡単ですね。:wink:

# mailcathcer 導入手順
先ず、brew で mailcathcer をインストールします。

```
brew install mailcatcher
```

次いで、mailcatcherがインストールされたことを確認します。
下記コマンドの実行結果に「mailcatcher」が含まれていればOKです！

```
brew list
```

development環境でmailcatcherのSMTPサーバーを利用することを明示します。[^1]

```config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings   = { address: '127.0.0.1', port: 1025 }
```

早速、mailcatcherを使ってみます！[^2]

```
mailcatcher
```

:tada::tada::tada:以上で導入手順の説明はお終いです！
後は引き続き現場Railsに沿って進めて頂ければと思います。
ここまでお付き合いくださり、有難う御座いました！:clap:

# 参考文献
- [GitHub MailCatcher README](https://github.com/sj26/mailcatcher#readme)
- [Homebrew Formulae mailcatcher](https://formulae.brew.sh/formula/mailcatcher)
- [brew と gem の違いとは？](https://mune-blog.com/homebrew-rbenv-gem/)
- [現場で使える Ruby on Rails 5 速習実践ガイド](https://book.mynavi.jp/ec/products/detail/id=93905)

[^1]: コードの挿入箇所の説明は現場Railsに譲ります。
[^2]: 余談ですが、筆者の環境では実行時に「warning: constant ::Fixnum is deprecated(定数名Fixnum非推奨警告)」が出ますが無視して進めました。
【Swift】UIButtonのsetTitle(_:for:)で文字サイズやフォントまで変わってしまう

#開発環境
Xcode 13.1

#はじめに
題の通り、UIButtonに対してsetTitle(_:for:)を利用すると、StoryboardでUIButtonに設定したものが全てリセットされてしまいました。
![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1285063/f6fb8335-4968-eebd-249a-f54678f79237.gif)


#解決法
![スクリーンショット 2022-02-11 16.14.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1285063/1a4eb96d-83fa-6590-12b7-7fedd8109f89.png)

「Attributes inspector」にある「Style」がデフォルトでは「Plain」になっているのですが、ここを「default」に変更した上でsetTitle(_:for:)を利用するとフォントやサイズが保たれたままタイトルを変更することが出来ます。
useCallbackとuseMemoized(Flutter Hooks)

フックに慣れていないので、サクッと勉強第２弾です。
#useCallback
関数インスタンス(値が入った関数)をキャッシュ(再利用の為に保存)。初回の呼び出しで渡された関数をそのまま返して、再レンダリングされた時も初回のレンダリング同様の関数オブジェクトを再利用できます。useMemoizedのシンタックスシュガー(構文を別の記法で記述)であり、関数コンポーネント内で値の再計算を抑制する効果を持っています。

```dart
final cachedFunction = useCallback(() {
  print('doSomething');
}, [key]);
```

```dart
T useCallback<T extends Function>(
  T callback,
  List<Object?> keys,
) {
  return useMemoized(() => callback, keys);
}
```

#useMemoized
複雑なオブジェクトのインスタンスをキャッシュ。変化する値を固定させたり、膨大な計算を軽減させる為に使用。useCallback同様、最初の呼び出しで関数を返したら、その結果を保存してHookWidgetのビルド(再構築)時に保存していたインスタンスを返します。下記の場合、オプション引数(第２引数)のkeysが変更された場合は、valueBuilderがサイド呼ばれ新しいインスタンスが作られます。

```dart
final cachedFunction = useMemoized(() => () {
  print('doSomething');
}, [key]);
```

```dart
T useMemoized<T>(
  T Function() valueBuilder, [
  List<Object?> keys = const <Object>[],
]) {
  return use(
    _MemoizedHook(
      valueBuilder,
      keys: keys,
    ),
  );
}
```

##状態に応じて値を使う時にはuseCallbackやuseMemoizedは便利ですね。
markdownをwordに変換するのにPandocが便利だった

## Pandocとは？

The universal markup converter

> [https://pandoc.org/](https://pandoc.org/)
> [https://github.com/jgm/pandoc](https://github.com/jgm/pandoc)
> The universal markup converter
> Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library. It can convert from

## インストール

以下を参考にしてインストールする

> [https://github.com/jgm/pandoc/blob/master/INSTALL.md](https://github.com/jgm/pandoc/blob/master/INSTALL.md)

Macの場合

> ```
brew install pandoc
```

## 変換する

```md:README.md
# Test!

This is a test of *pandoc*.

- list one
- list two
```

### コマンド実行してHTMLに変換する

```
pandoc README.md -f markdown -t html -s -o test1.html
```

変換した`test1.html`

![スクリーンショット 2022-02-11 22.22.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/f98446ef-9ad3-d602-204b-a0c37d34fa1f.png)

### コマンド実行してWordに変換する

```
pandoc README.md -f markdown -t docx -s -o test1.docx
```

変換した`test1.docx`

![スクリーンショット 2022-02-11 22.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/88740f8f-18f3-1cec-0d3e-f02f8e3ebd13.png)

すごい！`これはmarkdown`でドキュメント作成したくなる。

# 参考

[https://pandoc.org/](https://pandoc.org/)
[https://github.com/jgm/pandoc](https://github.com/jgm/pandoc)
[https://github.com/jgm/pandoc/blob/master/INSTALL.md](https://github.com/jgm/pandoc/blob/master/INSTALL.md)
VSCodeでC言語の赤い下線（エラーの波線）を表示させる

Visual Studio Code (以下 VSCode) で C言語のプログラムを作成中、シンタックスエラー（構文エラー）を赤い波線で表示してくれるオプションが外れてしまったので、その復帰方法等についてのメモです。
![エラーの波線を無効にする](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/992e1cc7-432a-9385-e0cb-8ca0d25e0e3a.png)
ちなみにエラーの際、 `電球マーククリック` または `⌘ (command) + . (ピリオド)` (Show Code Actions のショートカット) で表示された、**「エラーの波線を無効にする」** を誤ってクリックしてしまったことが今回の発端でした。


## C/C++ Extension を入れる
そもそもの話として、構文チェックをしてくれる機能拡張が入っていなければエラー表示もしてくれません。
自分は一番メジャーそうな Microsoft の C/C++ 機能拡張 (C/C++ for Visual Studio Code) を元々インストールしています。
まだの人は是非。
![C/C++ for Visual Studio Code Extension (screen image)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/42ec45a5-9ecd-7c28-5c28-029c3f5390f5.png "C/C++ for Visual Studio Code")

## 赤い波線を表示させる（または非表示にする）
`Code (メインメニュー) > Preferences > Settings`
または
`ショートカットで ⌘ (command) + , (カンマ)`
で Settings の画面を開きます。
![設定画面の開き方スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/65ddbbba-b972-bc61-6285-2e24d673f5a4.png "設定画面の開き方")

検索欄に `Intellisense` 、それでも数が多い場合は `Intellisense Error` や `Error Squiggles` など入力すれば設定項目が絞り込まれます。
**C_CPP: Error Squiggles** が探していた項目です。左上の `User/Workspace` のタブは必要に応じて切り替えてください。
![Intellisense error setting](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/62346d3e-0066-1e17-5799-c19367ca10d0.png)

C_CPP: Error Squiggles が **Disabled** になっています。
Squiggles は "波線" という意味ですので、エラーの波線が無効になっている、ということですね。
エラーの波線を非表示にしたい人は、こちらを Disabled の状態にしてください。

エラーの波線を表示させたい人は、こちらのプルダウンからデフォルトの `EnabledIfIncludesResolve`、または `Enabled` を選択すれば設定完了です。
![スクリーンショット 2022-02-11 21.25.24のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/431db49e-4e43-7b20-ecb0-0a55c050a418.png)



#### 参考URL
[c++ : VSコードで赤い線/エラービューアをオンにする方法
](https://www.fixes.pub/program/816541.html)
【Unity】GameObjectのAudio Sourceに設定したBGMを、別のGameObjectに切り替える方法

例えば、すでにBGM1というGameObjectのAudio Sourceに設定したBGMを再生している状態で、
BGM2という別のGameObjectの同じように設定したBGMを再生したい場合です。

原始的ですが、

```C#
GameObject.Find("BGM1").GetComponent<AudioSource>().Stop();
GameObject.Find("BGM2").GetComponent<AudioSource>().Play();
```
PlayとStopを切り替えることで可能となります。

GameObject.Findはヒエラルキーの全走査するので、Updateなどでは避けたほうが良いです。
SerializeFieldで定義しておくのが良いかもしれないです。
標高タイルを作る rio-rgbify を Docker で動かす

![social preview image](https://repository-images.githubusercontent.com/458115975/a60adc7f-c03c-4e91-b00e-9fe57d770b8c)

標高タイルを作るツールである [rio-rgbify](https://github.com/mapbox/rio-rgbify) を Docker で動かす [unvt/rgbify](https://github.com/unvt/rgbify) を作りました。

https://github.com/unvt/rgbify

# 成果
成果となる Dockerfile の内容は、次のとおりとなりました。

```Dockerfile
FROM osgeo/gdal:ubuntu-small-3.4.0
RUN apt update \
&& apt upgrade -y \
&& apt install -y \
gdal-bin \
git \
libgdal-dev \
libproj-dev \
python3-numpy \
python3-pip \
python3-rasterio \
rasterio \
sqlite3 \
&& git clone https://github.com/mapbox/rio-rgbify.git \
&& cd rio-rgbify \
&& pip install -e '.[test]' \
&& cd .. \
```

## 留意した点
- pip に上がっている rio-rgbify は実は古く、どうも 2018 年頃から更新されていないようです。この間、GDALのアップグレードなどがありましたので、`pip install rio-rgbify`の方法ではうまくいきませんでした。
- rasterio 本体や、ライブラリ類は apt でインストールし、rio-rgbify は git clone したものから導入する、という方法で、最新版をインストールすることで、動作するプログラムを得ることができました。

## 思わぬ収穫
上記のアプローチは、 Raspberry Pi OS の上でも有効であり、Raspberry Pi OS ネイティブで動くプログラムを得ることができました。なお、`sudo pip install -e '.[test]'` と、sudo する必要があるところがポイントかもしれません。

## 感想
ベクトルタイルではなく画像タイルなので仕方がないとは思いますが、処理は思ったよりも重い印象があります。これから、このツールを少し試してみたいと思います。
Railsで作った日本、台湾華語対応のブログ構成

# なぜまとめるのか
Railsオンリーでつくったブログ([日台one!](https://nittai-one.com)というブログ名)のフロントをこれからNext.jsに置き換えようと考えています。
そのため、現状の仕様が置き換わってしまう前に現状の姿形を記録に残したいと思いました。

[github リポジトリ](https://github.com/atamakonkurii/blog_JT)

ちなみに、僕は日本人、彼女が台湾人でブログの記事作成は二人でやってます。
お互いの母国語で記事を書いて、記事を投稿した瞬間にAmazon translateで翻訳し、DBに保存する仕様です。

# 技術スタック

|  カテゴリ  |  要素  |
| ---- | ---- |
|  言語/フレームワーク  |  Ruby / Rails / tailwind css |
|  ミドルウェア  |  MySQL |
| クラウドサービス | AWS EC2 / CloudFront / AmazonTranslate|

未経験入社した段階ではRails歴1週間にも関わらず、Railsのバックエンドエンジニアとして採用されたので、自学のためにRailsでブログを作りました。
Railsなのにtailwind cssを採用した理由は、綺麗なUIのテンプレが揃っていたのでそのままデザインに使えそう！と思ったからです。
インフラは勉強も兼ねてAWSを使いました。ドメイン代とRoute53(月額0.5$)以外は無料枠で済んでます。

# ブログの画面構成

コントローラーは記事とユーザーのしかないのでその二つのカテゴリに分けてまとめます。
他にある画面はユーザーのログイン画面くらいです。
ユーザーの認証にはdeviceを使っています。

### 記事

|    |  画面| 説明 | 
| ---- | ---- | ---- | 
|  一覧  |  ![nittai-one_com_zh-TW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/8c956a68-fc12-3844-c57f-52667b40bbd8.png) |* サムネイル、タイトル、記事の冒頭、場所、タグ、記事作成者をカードで表示<br> * ヘッダーに言語切り替えボタン<br> * フッターに利用規約、問い合わせ、各種SNSへのリンク| 
|  詳細  |  ![nittai-one.com_articles_72_locale=zh-TW (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/e950d3cb-6f8f-b85e-b3b6-fa4fdcd4cb45.png)  |* サムネイル、タイトル、場所、タグ、作成者、本文<br> * 記事作成者の各種SNS<br> *おすすめ記事(ランダムで3つ表示してるだけ)|
|  新規作成/編集　| ![日台友好___日台one_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/e69605e3-2bb0-9bfc-ce07-e16ba0c3d6c9.png)  |*サムネイル、国、都道府県、タグ、タイトル、本文<br> * マークダウン記法<br> *本文はドラッグアンドドロップで画像アップロード|


### ユーザー
ユーザーの新規作成画面はあえて作っていません。
コンソールからユーザーデータは作成しています。

|    |  画面| 説明 | 
| ---- | ---- | ---- | 
|  詳細  |  ![nittai-one.com_users_1_locale=zh-TW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/c31144fc-6594-5b57-806f-3d557c557d1f.png)  |* ユーザーの各種SNS<br> * ユーザーの記事投稿数<br> *ユーザーが投稿した記事|
|  編集  |  ![日台友好___日台one_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/1d36484d-7719-43bf-1395-f4ef99d8b3d1.png)  |* 画像、表示名、自己紹介、記事を書く言語(翻訳言語を決めるため)<br> * ユーザーの各種SNS|


# まとめ
Railsオンリーのブログの構成についてまとめました。
フロントをNext.jsに置き換えていくために、Railsのapiの開発も必要になってきます。
一部の画面はerbで一部の画面はNext.jsの画面のように段階的に変えていくことは可能なのか気になっているので、調べてみたいと思います。

# おまけ
PageSpeed Insightsの情報を載せておきます。
Next.jsに置き換えたときに良くなるといいなと思っています。

## 一覧ページ

|  スマホ  |  PC  |
| ---- | ---- |
|  ![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/5ab86c67-f594-9fa3-2aaf-7c1e9825face.png)  |  ![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/32875afd-f561-986a-96dd-4c14e0f9ef0d.png) |


## 詳細ページ
|  スマホ  |  PC  |
| ---- | ---- |
|  ![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/442ee8b3-0468-5c08-ede6-e1e78505e0c0.png) |  ![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/b940349e-2e17-d611-71d8-bf50a7a440b6.png) |
Ubuntu Server 20.04.3 LTS 構築#13 セキュリティ設定6(rootkit対策)

実施日:2022/02/11

<<今回の内容>>
rkhunterの導入から設定まで

今回はrootkit対策をします。

rkhunterを導入します。

```
sudo apt install rkhunter
```
導入したバージョンは1.4.6
どうやら、データベースのアップデートもあるようなので、アップデートします。

```
sudo rkhunter --update
```
エラー文が表示されました。

:::note warn
Invaild WEB_CMD configuration option: Relative pathname:"/bin/false"
:::

どうやらrkhunterを導入して、はいrootkit対策が出来るようにされていないようです。

/etc/rkhunter.confの中にあるエラー箇所を修正する必要があるようなので、修正をします。
その前にバックアップを取ります。設定ファイルを変更する前にバックアップを取る習慣を付けようと思います。
バックアップ名はrkhunter-default.confにしておきます。

```
cp /etc/rkhunter.conf /etc/rkhunter-default.conf
```

バックアップも取りましたので、rkhunter.confファイルのエラー該当箇所を修正します。

修正箇所

:::note
\#WEB_CMD=curl⇒WEB_CMD="curl"
UPDATE_MIRRORS=0⇒#UPDATE_MIRRORS=0
       新たに追加⇒UPDATE_MIRRORS=1
MIRRORS_MODE=1⇒#UPDATE_MIRRORS=1
       新たに追加⇒MIRRORS_MODE=0
PKGMGR=NONE⇒PKGMGR=DPKG
上記を修正し、下記のコマンドを実行しました。
sudo rkhunter --update
sudo rkhunter --propud
:::
ご参考にさせて頂いたサイト様では""又はcurlのどちらかにしていました。

どちらが正解なのかは判りません。curlはURLで示されるネットワーク上の場所でのデータ送受信が可能なオープンソースソフトウェアである。
調べてみると、curlはそういう役割を持っているそうです。
今回は"curl"で設定してみました。

問題なく、アップデートも出来ました。

ウイルス対策同様に定期的に侵入されていないか確認が必要です。

:::note
/etc/default/rkhunter
このファイル内で定期的に確認出来るように設定が出来ます。
CRON_DAILY_RUN="true"
CRON_DB_UPDATE="true"
APT_AUTOGEN="true"
:::

参考にさせて頂きましたサイト様
[@hogehuga様](https://qiita.com/hogehuga/items/b4c9ceb20940bf3e317a)
[鳥さんでは足りないつぶやき様](http://harukarium.sblo.jp/article/184880130.html)
VSCodeでのFlaskアプリのデバッグ～忘備録～

前回の [Flask 導入](https://qiita.com/Euphysics/items/db0d17dbd5416c480456) の続き。
VSCode での Flask アプリのデバッグを行う。

+ 手順１
実行とデバッグをクリックして、launch.json ファイルを作成。

このとき、Debug Configuration として Flask を選択。
そして、application へのパスを入力（ここでは前回のファイルを踏襲し hogehoge.py）.

+ 手順２
すると次のようにlaunch.json ファイルが作られる。

```json:launch.json
{
    // 省略
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "hogehoge.py",
                "FLASK_ENV": "development"
            },
            "args": [
                "run",
                "--no-debugger"
            ],
            "jinja": true
        }
    ]
}
```

+ 手順３
hogehoge.py ファイルに戻り適当にブレークポイントを作ってやるなど、デバッグができる。

次回は、前回の [Flask 導入](https://qiita.com/Euphysics/items/db0d17dbd5416c480456) の補足 [Flaskー補足ー](https://qiita.com/Euphysics/items/45044dac795b6d0f80e4)。
Kaggleのhouse pricesをlightGBMで解く

さて、[前回の記事](https://qiita.com/tatessy/items/75020b60633a11a6fd29)で、house pricesの課題について結果を出すところまではできました。
今回は、性能を上げるために前回とは異なる機械学習モデルのlightGBMで実装してみたいと思います。


### lightGBMとは
lightGBMとは、[公式ドキュメント](https://lightgbm.readthedocs.io/en/latest/)にもあるように、

:::note info
ツリーベースの学習アルゴリズムを用いた勾配ブースティングのフレームワーク
:::
のことです。

ちょっと何言っているかわからないのですが、
https://qiita.com/kuroitu/items/57425380546f7b9ed91c
こちらの記事の方が非常によくまとめてくださっていますので、引用しておきます。

### 実装
https://colab.research.google.com/drive/1nbjf8ZBfRkxWyMyHLYucq8ULB3-x8moY
実装の概要はこちらのgoogle colabに記載しております。

結果は0.2ぐらいでまだベスト更新できていないので、データの選別の仕方等を見直そうと思います。
Windows10 HomeにDocker Desktopを入れる時にハマったこと

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

Windows10 HomeエディションにDocker Desktopを入れる際にハマったポイント3つの解決策を共有です。
まだまだ学習中の身で、涙目で8時間ハマって苦しんだ思いを他の方はしなくて済むように残しておきます。💧

# 1ハマり
Docker Desktopを起動するも`Docker desktop stopped...`

## 解決
1. powershellを管理者で起動
1. コマンド`& "C:\Program Files\Docker\Docker\DockerCli.exe" -SwitchDaemon`を**2回**実行

https://stackoverflow.com/questions/64131567/why-docker-cant-detect-wsl-2-distro-in-windows-10-home

# 2ハマり
Docker Desktopの設定ページを開くが、ずっと読み込みのグルグルのまま…

## 解決
1ハマりの時と同じく、`& "C:\Program Files\Docker\Docker\DockerCli.exe" -SwitchDaemon`を**2回**実行

# 3ハマり
設定ページの「Use the WSL 2 based engine (Windows Home can only run the WSL 2 backend)」
がグレーアウトでチェック入れられない…

## 解決
2022/02/11時点で最新4.5.0 **ではない**古いバージョンをインストール
（ちなみに私は4.3.2にて再インストールするとチェック入りました！）

https://docs.docker.com/desktop/windows/release-notes/

![2022-02-11 (1)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/e948b629-9e68-c996-b75f-7c222c9aee60.jpeg)


# おわりに
お読みいただきありがとうございました。
あっさりとハマりと解決法を書きましたが、「制御フローガード(CFG)のシステム設定」を変えてみたり、煮詰まってPC自体を初期化してみたり😂色々苦労しまして、解決にたどり着けました笑
自分と同じく初学者の参考になれば嬉しいです。
ありがとうございました！😄
Azure Container Registryで作成したStreamlitアプリをSSL対応すーる（ドメインはRoute 53）

# はじめに
Azure Container RegistryでStreamlitアプリを作りました。SSL対応します。

https://qiita.com/SatoshiGachiFujimoto/items/d8273194e88d8eb30213

1．こちらを参考にしてください

https://qiita.com/mym/items/b5b7207f062a04d94cb0

2．AWS Route53でドメインを作成しています

3．SSLなうを用いてLet’s Encryptの証明書を申請します

https://sslnow.ml/

4．Let's Encryptへ登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/6af09579-58b1-174a-68a0-84b0071f5b64.png)

5．チャレンジトークンの取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/4ecba2ce-64ae-2d6b-a8bf-2b8a5e0ef9be.png)

6．ドメイン名の所有確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5bfe90d3-81e1-a836-342f-9512411b3eec.png)

7．Route53に設定し、確認ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/db13844c-0a84-5428-e1ae-a79fed10cc18.png)

8．RSAの鍵を生成し、privkey.pemとして保存します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/c7395ec6-7c2b-2ad8-2093-5215bfb32c5b.png)

9．証明書発行申請をクリック、cert.pem、chain.pem、fullchain.pemとして保存します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/8fa33469-8bd9-7515-22ea-66e5bd344aa7.png)

10．コマンドプロンプトからpemをpfxへ変換します

https://tekitoumemo.hatenablog.com/entry/2018/04/11/220701

~~~
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out gachimoto.pfx
~~~

pfxのパスワードを入力

11．Azure Portalのキーコンテナーで作成したpfxファイルをアップロードします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/6ed73808-dbe3-80b4-5c05-0f5516ac5da7.png)

12．App Serviceの証明書の設定でキーコンテナーから証明書をインポートします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/09749160-7d2f-1dca-cb38-16d513b4a6eb.png)

13．SSLバインディングします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a58e7bae-a723-4809-0d32-426e4fdb8369.png)

14．サイトにアクセスして問題なければ完了です

お疲れ様でした