OmniAICreator/Qiita-1.07M huggingface dataset:
[LaTeX] mintedの設定は問題ないはずなのに何故か動かなかった話

LaTeXでプログラムのコードの体裁を整えてくれる`minted`というパッケージがある。「latex minted」で検索すれば簡単に設定の方法が出てくるため、本記事では扱わない。

# 遭遇したエラー

`minted`が問題なく動くように設定(-shell-escapeなど)したはずなのだが、1度は成功したものの**文書作成の途中で**急に以下のようなエラーが発生し、以降ビルドに失敗するようになった。

```
Package minted: Missing Pygments output; \inputminted was
probably given a file that does not exist--otherwise, you may need 
the outputdir package option, or may be using an incompatible build tool,
or may be using frozencache with a missing file.
```

エラーをみると、なんとなく`pygments`が動いていないか`pygments`が作成したファイルをTeXが上手く認識していないような印象を受ける。しかし原因は違った。

# [失敗]試したこと
いろいろググってみて、

```tex
\usepackage[cache=false]{minted}
```
や

```tex
\usepackage[cache=false, outputdir=hoge]{minted}
```
を試してみたが、残念ながら私の場合では上記のエラーは解決しなかった。`cache=false`を設定すると、コンパイル自体は成功した(エラーメッセージは出ない)ものの、できたPDFファイルにはコードが一切出力されていなかった。

さらにpygments関連が悪いのではないかと考え、Python 2.7の仮想環境を別途つくりこちらでも試してみたが解決には至らなかった。

# [本題]エラーの原因は？

実は途中で追加したパッケージが悪さをしていることが発覚した。なんとプリアンブルで`fancybox`と`minted`の`\usepackage`を書く順番が重要であることが分かった。エラーが出ていた時には、

```tex
\usepackage{minted}
\usepackage{fancybox}
```
の順番でプリアンブルに書いていたのだが、

```tex
\usepackage{fancybox}
\usepackage{minted}
```
と書くことであっさりとビルドが成功した。おそらく二つのパッケージ間で何かしらの衝突が起きていたのだろう。`cache=false`の設定も必要無かった。

# 結論
`minted`と`fancybox`を共存させたい場合には、`fancybox`を先に書きましょう。

# LaTeX環境
最後におそらく今回のエラーの原因とは直接関係無いと思われるが、念のため私のLaTeX環境を書き留めておく。

* OSは`Linux version 3.10.0`
* LaTeXは`texlive2020`でインストール
* `uplatex`を指定。
* `VSCode`の`LaTeX Workshop`を使用しbuild。
SQL　命令集

###SQLとは
データベースを扱う言語
クエリを書くための言語

###データベースとは
テキストやデータを保存するためのツール
###クエリとは
データベースに送る命令のこと

###クエリ集
```SQL
SELECT + カラム名　→　データを取得する　
例）SELECT name

FROM + テーブル名　→　テーブルを選択する　
例）FROM purchases;

WHERE + カラム名 = "カラム要素"　→　レコードを取得する　
例）WHERE  category = "食品";

WEHRE + カラム名 ≤ or ≥ + "カラム要素"　→　比較演算子でレコード取得　
例）WHERE  price　≥ or ≤ "1000";

WHERE + カラム名 + LIKE + ”文字列”　→　文字列を含むでレコードを取得　
例）WHERE  name  LIKE "%プリン%";　ワイルドカード使用OK

WHERE + NOT + カラム名　→　その条件を満たないデータを取得　
例）WHERE  name LIKE "%プリン%"

WHERE + カラム名 + IS NULL　→　そのカラムがNULLのデータを取得　
例）WHERE name IS NULL

WHERE + カラム名 + IS NOT NULL　→　そのカラムがNULLじゃないデータを取得　
例）WHERE name IS NOT NULL

WHRE + 条件1 + AND + 条件2　→　条件が2つありどちらも満たすデータを取得　
例）WHERE character_name = "kizumo" AND category = "食費"

WHRE + 条件1 + OR + 条件2　→　条件が2つありどちらかを満たすデータを場合　
例）WHERE character_name = "kizumo" OR category = "食費"

ORDER BY + 並び替えたいカラム名 + 並べ方　→　取得したデータを並び替える　
例）ORDER BY price DESC

ASC = 昇順, DESC = 降順

LIMIT + データ件数　→　取得データ数の制限　
例）LIMIT 5;

DISTINCT(カラム名)　→　指定したカラムの重複データを除く　
例）DISTINCT(name)

SELECT + カラム名 + 四則演算 + 数字　→　取得したデータを加工する　
例）SELECT price * 1.08

SUM(カラム名)　→　集計関数の合計値　
例）SELECT SUM(price)

AVG(カラム名)　→　集計関数の平均値　
例）SELECT AVG(price)

COUNT(カラム名)　→　カラムに保存されているデータ数　
例）SELECT COUNT(name)

MAX(カラム名)　→　カラムに保存されている最大値のデータを取得　
例）SELECT MAX(price)

MIN(カラム名)　→　カラムに保存されている最小値のデータを取得　
例）SELECT MIN(price)

GROUP BY + カラム名　→　指定したカラムをグループ化する　
例）GROUP BY name

GROUP BY + カラム1 + カラム2　→　複数のカラムをグループ化する　
例）GROUP BY purchased_at, character_name

GROUP BY (WHERE)　→　WHEREでカラムを絞りさらにグループ化する　

例）WHERE　category = "食費" GROUP BY purchased_at, character_name

HAVING ;　→　グループ化後さらにデータを絞る　
例）HAVING SUM(price) > 2000;
```

###処理の順番
```SQL
WHERE(検索)→　GROUP BY(グループ化)→　COUNT/SUM/AVG/MIN/MAX etc..(関数)→ HAVING
```
laravel6 Carbonを使用して先月の月を取得する

# 目的

- 日付取得系ライブラリであるCarbonを使用して先月の月を取得する方法をまとめる

# 環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.11 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.21 for osx10.15 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 方法

1. コントローラファイルに下記を追記する。

    ```php
    use Carbon\Carbon;
    ```

1. コントローラの任意のアクション内に下記の内容を記載することで先月の月を取得できる。

    ```php
    $execDate = Carbon::now();

    $previous_month = $execDate->copy()->firstOfMonth()->subMonth(1)->month,
    // 下記のように記載することで1桁の月の場合0でパディングされた値が取得できる
    $previous_month = $execDate->copy()->firstOfMonth()->subMonth(1)->format('m'),
    ```
Yellowfinのコードモードダッシュボードでレポートのグラフ表の切り替えを一括で行う



#概要
これまでYellowfinv9が発表されてからいろいろなダッシュボードのカスタマイズを検証してきましたが、今回はダッシュボードに表示されているレポート全てをボタンクリックでグラフ表示・表の表示を切り替える方法を試してみました。
組み込みの場合はこちらもご参照ください。[Yellowfinのダッシュボードを埋め込んだ外部ファイルからグラフ表の表示切り替えを行う](https://qiita.com/celery/items/bbf74f99f24a46bdc90e)

![](https://user-images.githubusercontent.com/34874755/107453199-dc914200-6b8d-11eb-9adc-6f4660354841.gif)

#前準備
ダッシュボードを作成し、適当にレポートを並べて、switchという名前のボタンをダッシュボード上に配置します。
今回はサンプルであらかじめインストール後に使用できるSkiTeamのダッシュボードで解説していきます。

#レポートの名称とJSタブの書きっぷり

さっそくコードを下記に表示しているのですが、switchボタンをクリックした際に、
表示を変更したいレポートの名前をthis.apis.canvas.selectで指定してそれぞれのdisplay-typeを検証し変更しているだけです。

```javascript:JStab.js
this.onRender = function () {
    // ここにコードを記述します。これは、イベントリスナーを設定するのに理想的な場所です
    let button = this.apis.canvas.select('switch');
    button.addEventListener('click', () => {
        let report1 = this.apis.canvas.select('Campaign Summary');
        let report2 = this.apis.canvas.select('Revenue by Campaign and Demographic');
        let report3 = this.apis.canvas.select('Agency Sales by Profitability');
        let report4 = this.apis.canvas.select('Profitability by Customer Age & Location Breakdown');
        let report5 = this.apis.canvas.select('Revenue by Media Category');
        let reports = [report1,report2,report3,report4,report5]
        reports.forEach(report => {
            let currentDisplay = report.getAttribute('display-type');
            if(currentDisplay === "CHART") {
                    currentDisplay = "REPORT";
            } else {
                    currentDisplay = "CHART";
            }
            report.setAttribute('display-type', currentDisplay);
        })
    });
};
```

#感想
意外と簡単に実現できました。
注意点としては、display-typeにはCANVASというスタイルもあるらしいのでその際は別途else分の追加で対応してください。
えっ、著作権の帰属を表すHTMLタグがあるんですか？

## `small`タグ

`small`タグです。

かつては文字を小さく表示するために使われるタグでしたが、今ではセマンティックな役割が与えられています。

そのうちの1つが`著作権の帰属を表す`です。

## なんでこの記事を書いたのか

- `small`の役割って意外と知られていない気がする
- 最近レビューで連続でこの話をした

という2つの理由から記事を書きました。

## 内容の補足

コピーライト表記ってありますよね？

`© 2019-2021 Example Corporation All rights reserved.` みたいなやつです。

色々なサイトのマークアップを見学していて`span`タグで実装されていることが多いことに気がつきました。

しかし[HTML Living Standardのsmallタグの章](https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-small-element)を見てみると

> Small print typically features disclaimers, caveats, legal restrictions, or copyrights. Small print is also sometimes used for attribution, or for satisfying licensing requirements.

とあります。これを翻訳すると（DeepL使用）

> スモールプリントは、通常、免責事項、注意事項、法的制限、または著作権を特徴としています。スモールプリントは、帰属表示やライセンス要件を満たすために使用されることもあります。

このように著作権表記が代表的な使い方の1つとして記載されています。

正直、著作権表記がセマンティックじゃなくても大きな問題はありません。
しかしこれだけしっかりハマる要素、せっかくなら使いたいと私は思います。

## おまけ1

すぐ上で引用した内容にあるように、免責事項や注意事項を表すのも`small`の役割です。

マークアップでちゃんと`small`を使っていれば「ここに誤字があってはまずいな」と気をつけて見ることも出来るのではないでしょうか。

## おまけ2

著作権表記をするにあたって

`© 2019-2021 Example Corporation All rights reserved.`

こういう書き方はよく見るのですが、実は

`© 2019 Example Corporation`

これだけで十分です。

`©`と`公開した年`と`著作権者`さえ記載されていればOK。

`All rights reserved.`なんかは意外と場所を取るので、覚えておいて損はないと思います。

※[こちらのコメント](https://qiita.com/xrxoxcxox/items/b35c638a77342750a694#comment-16edcbb8c4f3ce26b86d)で指摘いただいたように、内容に不備があったので修正しました
[Googleスプレットシート] 残り営業日の算出について

# はじめに
全体及びチームタスク管理としてGoogleスプレットシート(以後、スプレ)を使っています。
スプレに各Versionごとの残り営業日を記載して進捗管理に役立ってるので忘却録です。

## 残り営業日の算出について
スプレの関数に`NETWORKDAYS.INTL`がありますのでこれを使います。
関数詳細: https://support.google.com/docs/answer/3295902?hl=ja

```
= NETWORKDAYS.INTL(Today(),終了日-1,"0000011",A1:A2)
```
- `Today()`は本日開始。
- `終了日-1`ここはQA開始日を入れてるので開始日から`-1`を引きます。
- `0000011`指定すると土曜日と日曜日が週末扱いになります。
- `A1:A2`ここは休日とする日付のセルの範囲を指定します。


![スクリーンショット 2021-02-10 10.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022988/d5a9b9bb-2beb-e8f2-d06b-1e39f6927e21.png)
休日は記載してセル指定で管理しています。

本日から指定したQA開始日までの日数がこれで取得出来るので意外と営業日少ないなーなど無理のないスケジュールが引けるかもしれません。
結局最後は気合で終わらすことになる場合が多いですが....
OpenBSD 6.8 + XFCE Desktop インストール後の備忘録

1. isoファイルは、右のサーバーからダウンロード　 http://ftp.riken.jp/pub/OpenBSD/6.8/amd64/install68.iso
2.    私の環境では、USBドライブでは起動しないので、CD-RWにイメージファイルを書き込んで起動させる。
3. インストール時は、Default の X Window System で起動できるように初期設定した。
4. pkg_add でインストールしたのは、noto-cjk(日本語フォント)、firefox(ブラウザー)、scim-anthy（かな漢字変換）、nano(エディター)、xfce(ウィンドウマネージャー)、xfce-extras(必要？)、gvfs-smb(ファイラーからNASへのアクセス)、python-idle(Hobby)
8. .xsession は下記のとおり。

```ruby:.xsession
# japanese input
export LANG=ja_JP.UTF-8
export XMODIFIERS="@im=SCIM"
export QT_IM_MODULE=scim
export GTK_IM_MODULE=scim
scim -d

exec startxfce4
```

今回は、privoxy が稼働する家庭内プロキシサーバーを導入したいと考えて、OpenBSD を入れてみたのだけれど、そちらの方はこれからの課題。いつものとおり、Xを入れてしまった。

以上
React／Material UIのCSSでアニメーションが動かない原因（@keyframes）

## Material UIのCSSの正体

Material UIで扱うCSSの実体は[JSS](https://cssinjs.org/?v=v10.5.1)です。
`makeStyles`や`createStyles`を利用している場合、
記法はJSS公式ドキュメントを確認する必要があります。

ここでは記法については説明しませんのでご了承を。



## CSSアニメーションが動かない場合

デベロッパーツールのConsoleでこんなwarningログが出ていませんか？

```
Warning: [JSS] Unknown rule @-webkit-keyframes xxxxx
Warning: [JSS] Unknown rule @keyframes xxxxx
```

`@keyframes`で設定した`animation-name`が読み取れない、というメッセージですね。
このようなログが出る原因は`@keyframes`の記法が間違っているからです。
実装例を見ながら確認していきましょう。


## @keyframesの実装例
### まずはJSS公式ドキュメントを確認
[>>公式ドキュメント](https://cssinjs.org/jss-syntax/?v=v10.5.1#keyframes-animation)



```
const styles = {
  '@keyframes slideRight': {
    from: {opacity: 0},
    to: {opacity: 1}
  },
  targetClass: {
    animationName: '$slideRight'
  }
}
```
**ポイント**
**animationNameの先頭に`$`を付けて呼び出す**

一般的なCSSの記法と異なるのでびっくりした方もいるのではないでしょうか。
warningログが出ていた原因はこれだったのです。
では、実装に落とし込んでみましょう。


### 実装例

ここでは、ローディング画面でくるくる回るスピナーの実装を想定しています。
細かいCSSは省略して`@keyframes`に関わる部分だけを抜粋。

**ローディング画面のspinnerスタイル**

```
import React from 'react';
import { createStyles, Theme, makeStyles } from '@material-ui/core/styles';

const commonStyles = makeStyles((theme: Theme) =>
    createStyles({
        '@-webkit-keyframes spin': {
            '0%': {
                '-webkit-transform': 'rotate(0deg)',
                transform: 'rotate(0deg)',
            },
            '100%': {
                '-webkit-transform': 'rotate(360deg)',
                transform: 'rotate(360deg)',
            }
        },
        '@keyframes spin': {
            '0%': {
                '-webkit-transform': 'rotate(0deg)',
                transform: 'rotate(0deg)',
            },
            '100%': {
                '-webkit-transform': 'rotate(360deg)',
                transform: 'rotate(360deg)',
            }
        },
        spinner: {
            // 省略
            '-webkit-transform': 'translateZ(0)',
            '-ms-transform': 'translateZ(0)',
            transform: 'translateZ(0)',
            '-webkit-animation': '$spin 1.1s infinite linear',
            animation: '$spin 1.1s infinite linear',
        },
```

このように
animationのショートハンドを使って呼び出すことも可能です。

```
animation: '$spin 1.1s infinite linear',
```

これでアニメーションが動くようになるはずです。
参考になれば。


## 参考記事
[JSS公式サイト](https://cssinjs.org/?v=v10.5.1)

Qiita
[React: Material-UI 4.0のコンポーネントへのCSS設定はwithStyles()からmakeStyles()に](https://qiita.com/gumiTECH/items/9e0f3172b8f85e93cbbe)
Chocolateyをプロキシ環境下でインストールする

## この記事について

公式のインストールシェル実行時に下記のエラーが出た時の対処法。

``` install.ps1
警告: An existing Chocolatey installation was detected. Installation will not continue.
For security reasons, this script will not overwrite existing installations.

Please use choco upgrade chocolatey to handle upgrades of Chocolatey itself.
```

## 推測と対応
- 公式の案内後にWindows側が変わっている
- シェルを見ると古いversionが残っている場合は念のため上記の警告を出してインストールを中断している雰囲気(実行時は新品PCだったが。。)
    - →シェルのこの判断を無効化したところ成功

## インストール手順

- 公式から [ps1ファイル](https://chocolatey.org/install.ps1) を取得
- 新規ファイル`my_install.ps1`を作成して、上記をコピペ
    - `install.ps1`を直接編集すると署名不一致で実行できなくなるため
- 下記をコメントアウト

``` my_install.ps1
# if (Test-ChocolateyInstalled) {
#     $message = @(
#         "An existing Chocolatey installation was detected. Installation will not continue."
#         "For security reasons, this script will not overwrite existing installations."
#         ""
#         "Please use `choco upgrade chocolatey` to handle upgrades of Chocolatey itself."
#     ) -join [Environment]::NewLine
#     Write-Warning $message
#     return
# }

```
- 環境変数を設定
    - chocolateyIgnoreProxy=false
    - chocolateyProxyLocation=http://x.x.x.x
    - chocolateyProxyUser=ユーザーネーム
    - chocolateyProxyPassword=パス
- 管理者権限のpowershell起動
    - 権限修正`>Set-ExecutionPolicy -ExecutionPolicy RemoteSigned`
    - 編集したスクリプトを実行 `> my_install.ps1`
    - コマンド`> choco`でversinoが出れば成功

``` 
Chocolatey v0.10.15
```


## 参考URL
- 公式
    - https://docs.chocolatey.org/en-us/guides/usage/proxy-settings-for-chocolatey
- 認証プロキシ環境下でのchocolateyインストール
    - https://qiita.com/geotrader/items/33b5db1832bb42979ba9
docker-compose could not translate host name "db" to address: Name or service not known

<b>結論： </b>networksで外部ネットワークを指定している場合は、中のnetworkについての default も指定しておくこと。

例えば、webプロキシーサーバーを外部コンテナで立てていてnewtworks externalで参照している場合に、中のdbをhostとして参照するとき必要（かもしれない）。

```yml
services:
  app:
    build: .
    volumes:
      - .:/app
    depends_on:
      - db
    networks:
      - default       　# <- これです
      - proxy_network
    environment:
      RAILS_ENV: development

  db:
    image: postgres:11
    environment:
      - POSTGRES_PASSWORD=password
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

networks:
  proxy_network:
    external: true
```
Raspberry Pi 4で YOLOv4を動かす

* Raspberry Pi 4 4GB
* logicool C270N

* 2021-01-11-raspios-buster-armhf-full

##パッケージの更新とスワップ領域の設定
sudo apt update
sudo apt upgrade

sudo nano /etc/dphys-swapfile

```test:/etc/dphys-swapfile
CONF_SWAPSIZE=4096
CONF_MAXSWAP=4096
```

sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

##各種パッケージのインストール
sudo apt install python-opencv
sudo apt install libopencv-dev
sudo apt install libopm-dev
sudo pip3 install opencv-python

##YOLOv4のmake
git clone https://github.com/AlexeyAB/darknet
cd darknet/
nano Makefile

```text:Makefile
 OPENCV=1
 OPENMP=1
 LIBSO=1
 USE_CPP=1
```

make -j4

##ウェイトファイルのダウンロードと動作確認
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights

__静止画の検出__
./darknet detector test cfg/coco.data cfg/yolov4-tiny.cfg yolov4-tiny.weights data/dog.jpg

__cfg/yolov4-tiny.cfgにて入力画像サイズ（width、height）を変更した時の推論時間__
416x416 data/dog.jpg: Predicted in 5673.473000 milli-seconds.
256x256 data/dog.jpg: Predicted in 2625.850000 milli-seconds.
128x128 data/dog.jpg: Predicted in 516.762000 milli-seconds.

128x128 Overclocking:1800MHz
data/dog.jpg: Predicted in 436.980000 milli-seconds.

__動画の検出__
./darknet detector demo cfg/coco.data cfg/yolov4-tiny.cfg yolov4-tiny.weights -c 0

FPS:1.1 	 AVG_FPS:1.1
RでのCSV読み込み

RでCSVファイルを読み込む際には関数read.csvを用いる。標準で入っているため、ライブラリのインポートは必要ない。読み込むデータは作業ディレクトリに置いておくと、パスの記述が不要となるので楽。以下コードで作業ディレクトリの変更ができる。

```r:workDir
setwd(dir = "C:/Users/user/Desktop/R")
```

以下コードでCSVファイルの読み込みができる。

```r:readCsv.R
df <- read.csv("FileName")
```

ちなみにURLを指定することでWebから直接読み込むこともできる。以下の例は[UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/datasets/Water+Treatment+Plant)からWater Treatment Plant Data Setを読み込んでいる。

```r:readCsvFromWeb.R
df <- read.csv(file="https://archive.ics.uci.edu/ml/machine-learning-databases/water-treatment/water-treatment.data")
```

またread.csvにはさまざまなオプションがある。実際に自分がCSVファイルを読み込む際には以下を実行した。

```r:readCsvWithOption.R
df <- read.csv(file="Filename", header=FALSE, skip=2, na.strings=" ")
```

<dl>
  <dt>header</dt>
  <dd>ヘッダ読み込みの有無（デフォルト：TRUE）</dd>
  <dt>skip</dt>
  <dd>読み込み時に指定行をスキップ</dd>
  <dt>na.strings</dt>
  <dd>指定した文字列をNAに変換</dd>
</dl>

上記コードでは、" " の形式で空白が存在していたため、 na.strings=" " としている。Water Treatment Plant Data Set の場合は、? が入っているので、 na.strings="?" と指定する。ちなみに ?read.csv のように ? のあとに関数名を打つとヘルプを見ることができる。便利。
特定のプロパティだけrequiredにする型を作ってみる

## はじめに
typescriptには組み込みで、Requiredという型があります。

```typescript
type Dummy = {
  hoge?: string
  fuga?: string
  bar?: string
}

Required<Dummy>

//{
//  hoge: string
//  fuga: string
//  bar: string
//}
``` 
Requiredの第一ジェネリックスに型を入れると、全て必須プロパティにしてくれます。
いわゆるUtility Type ですね。

## 指定したプロパティだけ必須にしてほしい
組み込みのRequiredでは、全て必須プロパティになってしまいます。

組み込みで駄目ならパッケージを使う？
このためだけにパッケージを入れるのも煩わしい。

そういうときはサクッと自分で実装してしまいましょう。

## 実装
``` typescript
type Dummy = {
  hoge?: string
  fuga?: string
  bar?: string
}

type Required<T,K extends keyof T> = T & {
  [P in K]-?: T[P]
}

Required<Dummy,"hoge">
//{
//  hoge: string
//  fuga?: string
//  bar?: string
//}
```
自分で実装したRequiredは第一ジェネリクスに型、第二ジェネリクスに必須にしたいプロパティ名を入れると、特定のプロパティだけ必須にすることができます。

## 解説
``` typescript
type Required<T,K extends keyof T>
```
`extends keyof`はプロパティをジェネリクスとして扱える機能です。
今回の場合は`T`型に含まれるプロパティを`K`としています。

```typescript
= T & {
  [P in K]-?: T[P]
}
```
typescriptで`in`は反復処理を表します。
`Require<Dummy,"hoge"|"fuga">`のように複数のプロパティが渡された時は、それぞれ`hoge:string`・`fuga:string`と処理されることになります。

`-?`で`?`を消去してくれます。

`T`型と`&`で結合しています。
必須プロパティと省略可能プロパティを結合すると、必須プロパティが優先されます。

## 指定したプロパティだけ省略可能プロパティにする方法は？

``` typescript
type PickPartial<T,K extends keyof T> =  Omit<T,K>&{
  [P in K]?: T[P]
} 
```
Omitで一度プロパティを消去してから、省略可能プロパティを追加しています。

## 最後に
パッケージを使いたいという方はこちらがおすすめです。
https://github.com/piotrwitek/utility-types
Node.js+AWS Lambda+DynamoDBで作るLINEBot

先日、[X-HACK勉強会](https://x-hack.connpass.com/)でLINEBotの作り方を学びました。

勉強会ではおうむ返しをしてくれるBotを作ったのですが、自分がほしいBotを作ってみよう！と思いアレンジして作ってみました。

# 電車発車時刻を送ったら準備開始時間と家を出る時間を教えてくれるLINEBot

**家から駅が近い・電車が数分おきに来る都会の人には完全不要Botです。**

![IMG_CFDC000E4F39-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/0ee8d915-4901-5611-7a5e-970ddf43d39a.jpeg)

## 機能
- 電車発車時刻を送ると準備開始時間・家を出る時間を返信してくれる
- 準備時間を変更する（デフォルトは30分）
- 家から駅までの時間を変更する（デフォルトは15分）
- 現在の設定されている準備時間・家から駅までの時間を確認する

## 作ろうと思ったきっかけ
数ヶ月前に引っ越しをして新しい土地の最寄り駅では、時間によっては1本逃すと次の電車まで15~20分待つことがあります。準備時間と家を出る時間を絶対にミスってはいけません。

いつも電車の時間を調べて準備時間、家を出る時間を計算していたのですが、これが地味にめんどくさい。そして時々計算を間違えて駅まで走ることもありました。毎回自動で計算して教えてくれる何かが…欲しい…！と思い作りました。

# 使用技術
- AWS Lambda / DynamoDB
- Severless
- Node.js
- LINE Messaging API

## 全体構成
![Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/947919e7-500b-df66-9c99-1aa6cc2a74d1.png)

## ざっくり使用サービスの説明
### Lambdaとは
Lambdaはサーバレスを実現するためのサービスです。

[公式サイト](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)より

> 「AWS Lambdaを使用すれば、サーバのプロビジョニングや管理なしでコードを実行できます。課金は実際に使用したコンピューティング時間に対してのみ発生し、コードが実行されていないときには料金も発生しません。」

簡単に言うと

**プログラムを実行するためのサーバを用意する必要がないよ、Lambdaを動かした時だけにお金がかかるよ。**

ということです。

本来AWS上でWEBアプリケーションを動かしたいと思ったときにはEC2など仮想サーバを立てる必要がありますが、Lambdaの場合は必要ないということになります。実行したいプログラムのことだけ考えれば良いのです。

### DynamoDBとは

DynamoDBはNoSQL(Not Only SQL)データベースサービスです。

[公式サイト](https://aws.amazon.com/jp/dynamodb/)より

> Amazon DynamoDB は、どのような規模でも信頼性が高いパフォーマンスを維持できる、非リレーショナルデータベースです。 完全マネージド型、マルチリージョン、マルチマスターのデータベースで、レイテンシーを 10 ミリ秒未満に維持でき、 組み込みのセキュリティ、バックアップと復元、インメモリキャッシュを利用できます。

簡単に言うと

**完全マネージドのNoSQLデータベースで、OSやミドルウェアのことを気にしなくて良いよ。システムが停止することなく稼働し続ける能力を考慮したインフラの構築、パッチの適用等はAmazonがやるからきにしないで。高速で予測可能なパフォーマンスとシームレスな拡張性を提供するよ。**

Lambdaとも相性が良くAPIGateway+Lambdaと合わせて利用されることが多いとのことです。

今回DynamoDBを使用するにあって以下の設計にしました。

user_id 
need_time (準備時間)
leave_time （駅までの時間）
status　（none/leave/need）

# LINEBotのやりとりの流れ
1. LINEでメッセージを送る
2. DynamoDBにuse_idがあるかどうかを確認

    ある→ 3.statusの確認

    ない→user_id、デフォルトで準備時間30分、家から駅までの時間15分を新規登録

3. 時間変更中かどうか現在のstatusの確認

4. 送られたメッセージの内容を確認

5. 時間だったら計算して返信

    準備時間・駅までの時間を更新

    それ以外だとテンプレを返信

# 使い方
### 電車発車時刻を送信
準備開始時間と出発時間を計算して送ってくれる
![IMG_F240A8A51576-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/dee4e3fa-5e1e-4239-590f-989b2df9bea6.jpeg)

### 時間の変更
「準備時間の変更」「駅までの時間を変更」ボタンを押して、任意の時間を送信して変更する
![IMG_266EF169F278-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/3ed818e9-7f8c-19d5-1217-398613748fe2.jpeg)

### 「確認」と送信
現在設定されている準備時間と駅までの時間を送ってくれる
![IMG_08E25CFE04F5-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/5d50f9b8-e378-cda3-f005-915245f7989e.jpeg)


### 時間や時間変更、確認以外のメッセージを送る
送られてきたメッセージをおうむ返し＆使い方の説明
![IMG_7B033232D018-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311806/f36bab07-d063-7338-7ddb-2ad770cede3e.jpeg)

# おわり
一通りやりたい機能はできましたが、さらに準備時間や家を出る時間になったらリマインドしてくれる機能も追加したいです。

JavaScriptをもっと勉強したい！実務で使えるレベルになりたい！という方は[ゲームを作りながら学ぶWeb開発塾](https://id.js-dojo.com/)がおすすめです！
JetBrains製品で鍵認証でSFTP接続できない

mixhostのcpanelで生成したkey-pairを使おうとしたが、エラーが出て上手くいかない

ちなみにteratermでは問題なく接続できる

RSAの2048bitで作った鍵だが、1024bitで作り直したところ、intelliJで接続できるようになった
tmpfs とは

## 勉強前イメージ

tmpで作るなにか・・・？
ファイルシステムっぽい

## 調査

### tmpfs とは

linuxで使える一時的にデータを格納するために使えるファイルシステムです。
tmpfsをマウントするだけで、パーティションのようにファイルの読み書きなどに使用することができます。
ただしメモリ上に作成されるので、電源を落としたり再起動をするとファイルは消えてしまいます。

### 確認方法

使用されているかどうかは `df -T` で確認することが出来る。
タイプが `tmpfs` になってる箇所がそれにあたる。

```
[root@localhost ~]# df -T
ファイルシス            タイプ   1K-ブロック     使用    使用可 使用% マウント位置
devtmpfs                devtmpfs      495564        0    495564    0% /dev
tmpfs                   tmpfs         507376        0    507376    0% /dev/shm
tmpfs                   tmpfs         507376     6920    500456    2% /run
tmpfs                   tmpfs         507376        0    507376    0% /sys/fs/cgroup
/dev/mapper/centos-root xfs          6486016  1652272   4833744   26% /
/dev/sda1               xfs          1038336   171260    867076   17% /boot
tmpfs                   tmpfs         101476        0    101476    0% /run/user/0
```

### RAMディスクとの違い

他にもメモリー上にファイルシステムを作成する仕組みとして `RAMディスク` がある。
RAMディスクとtmpfsとの違いは以下になります。

- 読み込みについて

RAMディスクはブロックデバイスとして認識されるので、フォーマットしないといけないですが
tmpfsは最初からファイルシステムとして認識されます

- 作成される場所

RAMディスクは物理メモリ上に作成されますが
tmpfsはswap領域を含んだ仮想記憶上に作成されます

- 割り当てについて
RAMディスクは事前に固定のメモリ量を割り当てないといけないですが
tmpfsは使用した分だけ容量が増えます

## 勉強後イメージ

今回RAMディスクも初めて知った。
メモリでやったほうが早いって認識はファイルシステムとかまでもメモリで実施されるのか

## 参考

- [tmpfs](https://xtech.nikkei.com/it/article/Keyword/20080808/312545/)
- [tmpfsをマウントする方法](https://armadillo.atmark-techno.com/howto/mounting-tmpfs)
django api and vue(2)

２０２１/1/29
2021/2/1


```vuejs：FBButton.vue
 <template>
    <div>
        <button @click="open">Login with Facebook</button>
    </div>
</template>
<script>
 
export default {
    name: 'FBButton',
     methods: {
        open() {
            document.location.href = 
            ’https://www.facebook.com/v9.0/dialog/oauth?client_id={app-id}&redirect_uri=http://localhost:8080’　　　　　　　　　　　　　　　
        }
      },
　　　 　data(bounted(){
        let code = this.$route.params.code
         if (code){
            this.info = code
        }
       axios
         .get()
         .then(respose => (this.info = response))
      }
    }

</script>
```
vuejs devtoolsをインストールする
&(yarn dev)

URLに表示されるtokenを画面に表示したい
↓
vue routerを使う（yarn add vue-router）
tokenを使ってfacebookから情報を取得



```python:serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
from core.models import Account
import uuid
import facebook


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'url', 'first_name', 'last_name', 'email', 'is_staff']



class AccountSerializer(serializers.ModelSerializer):
    fb_token = serializers.CharField(required=False)
    ig_token = serializers.CharField(required=False)
    user = UserSerializer(read_only=True)
    class Meta:
        model = Account
        fields = ['id', 'user', 'fb_token', 'ig_token']
        read_only_fields = ['user']



    def create(self, validated_data):
        token = validated_data.get("fb_token")
        graph = facebook.GraphAPI(token)
        #fields = ['first_name', 'location{location}','email','link']
        profile = graph.get_object('me',fields='first_name, last_name, location,link,email')
        user = User(username=str(uuid.uuid4()))
        user.first_name = profile['first_name']
        user.last_name = profile['last_name']
        user.email = profile.get('email', '')
        user.save()
        account = Account()
        account.user = user
        account.fb_token = validated_data.get('fb_token')
        account.ig_token = validated_data.get('ig_token', '')
        account.save()
        return account
```
Word2Vec-Python実装

#Word2Vec-Python実装の概要解説

##Word2Vecとは
深層学習を使用し、単語をベクトルに変換するアルゴリズムです。

■入力：単語
■Word2Vec
■出力：配列(50次元)

##白ヤギが作った日本語Word2Vecモデル
Word2Vecを使用し単語をベクトルに変換するためには、事前にWord2Vecの深層学習の重みの学習を完了させておく必要があります。
「word2vec.gensim.model」、「word2vec.gensim.model.syn1neg.npy」、「word2vec.gensim.model.wv.syn0.npy」は白ヤギコーポレーションがPython用ライブラリGensimに用意されているword2vecを実装し、学習を完了させた深層学習の重みデータを使用するためのファイルです。

##白ヤギが作った日本語word2vecモデルのインストールから実装
__①データを取り込む__
http://public.shiroyagi.s3.amazonaws.com/latest-ja-word2vec-gensim-model.zip
上記のファイルをダウンロード、解凍します。

__②ファイルを格納__
下記の3ファイルを格納します。
・word2vec.gensim.model
・word2vec.gensim.model.syn1neg.npy
・word2vec.gensim.model.wv.syn0.npy

__③Word2Vecの実装__

```「```:pythonを使用したWord2Vecの実装
#Word2Vecをインポートする
from gensim.models.word2vec import Word2Vec

#Word2Vecで使用するデータのパス指定
model_path = './word2vec.gensim.model
#モデルのロード
w2v_model = Word2Vec.load(model_path)
#単語をベクトルに変換
w2v_model[u'単語']
```

#参考文献
[1]岡谷貴之，深層学習，2015 講談社サイエンティフィク， 講談社．

[2]word2vecの学習済み日本語モデルを公開します-https://aial.shiroyagi.co.jp/2017/02/japanese-word2vec-model-builder/

[3]15分でできる日本語Word2Vec - Qiita
Node-RED を Azure Web Apps for Containerで動かす。

## Node-REDをWeb Apps for Containerで動かす。

掲題の通りです。
AzureのWeb Apps for Containerで動かしたいです。。
ただ、ネット上にあまり記事がなかったので自分が実施した内容を書いてみようと思います。

## やりたい事

1 Node-REDをWeb Apps for Container で動かす。
2 Azureのネットワークシェアにデータ永続化を行う。

特に2が結構苦労しました。

## 1 Node-REDをWeb Apps for Container で動かす。

Node-REDをWeb Apps for Containerで動かす事自体は結構簡単です。

Web Appsで下記のdockerイメージを基にビルドすればとりあえず動かせます。

https://hub.docker.com/r/nodered/node-red/

ただ、このままだと settings.jsを書き換える事ができていないので、誰でもNode-REDのソースを触れてしまう事やプロジェクト機能が使えない事が問題です。
なので、自作でdockerイメージを作成します。
以下では主に
settings.jsやflows.json,flow_cred.jsonをコピーしています。
settings.jsで、ユーザ認証の設定、projects有効されている事が前提です。
>ADD --chown=node-red:node-red projects/ /data/projects/

projectsの所有者設定を書かないとフローを更新する際にエラーが出ます。

<details><summary>Dockerfile</summary><div>

```

FROM nodered/node-red

# Copy package.json to the WORKDIR so npm builds all
# of your added nodes modules for Node-RED
COPY package.json /usr/src/node-red/package.json
RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production

# Copy _your_ Node-RED project files into place
# NOTE: This will only work if you DO NOT later mount /data as an external volume.
#       If you need to use an external volume for persistence then
#       copy your settings and flows files to that volume instead.
COPY .config.json /data/.config.json
#COPY --chown=node-red:node-red projects/ /data/projects/
COPY settings.js /data/settings.js
COPY flows_cred.json /data/flows_cred.json

ADD --chown=node-red:node-red projects/ /data/projects/

# You should add extra nodes via your package.json file but you can also add them here:
#WORKDIR /usr/src/node-red
#RUN npm install node-red-node-smoothd

```

</div></details>

上記のdockerイメージをdockerhubか azure container registry へアップロードして下さい。
それを基にWeb Appsをビルドするように設定します。

これで、とりあえずWeb Apps for ContainerでNode-REDを動かせます。
ただ、永続ストレージは現段階では使えていません。
コンテナが再起動するごとにソースコードがぶっ飛びます。

## 2 Azureのネットワークシェアにデータ永続化を行う。

これは、正直綺麗な方法がわかりませんでした。
が、とりあえず動く事が大事です。

結論から書くと Docker-Composeを利用しました。

Azure Web Apps for Containerでdocker run -v を使用できれば良かったのですが、設定の方法がわかりませんでした。

まず、最初にAzureの構成を以下設定へ変更します。

`WEBSITES_ENABLE_APP_SERVICE_STORAGE` => true
これで、Web Apps for Container のネットワークシェアを使用できるようになります。
( 初期値が trueと書かれている記事もありましたですが、自分の場合は初期値はfalseでした )

そして、以下のDocker-compose.ymlを元に設定すればネットワークシェアを利用してデータ永続化ができます。
${WEBAPP_STORAGE_HOME}は、Web Apps for Containerで利用する際には、固定でこちらで設定する必要があります。

<details><summary>Docker-compose.yml</summary><div>

```
version: "3.7"

services:
  node-red:
    image: hogehoge/node-red:latest
    environment:
      - TZ=Asia/Tokyo
    ports:
      - "1880:1880"
    networks:
      - node-red-net
    volumes:
      - ${WEBAPP_STORAGE_HOME}/data:/data/projects/



networks:
  node-red-net:
```

</div></details>



### 最後に
自分用のメモ的に書いているので、文章が適当ですいません。。
画像とかあればもっと分かりやすいと気づいたのは書き終わった後。。。
また、内容に間違いあれば是非教えて下さい。
FizzBuzz問題の次を考えた！その名も「LevelLabel問題」 

## はじめに
FizzBuzz問題と言えばプログラマ志願者の人を見極める手法として有名な問題です。非常にシンプルなルールのため内容をパッと実装できるかを確認したり、縛りなどを入れることで難易度を上げて遊ぶ人も居ます。

> FizzBuzz問題
> コードが書けないプログラマ志願者を見分ける手法をJeff AtwoodがFizzBuzz問題 (FizzBuzz Question) として提唱した。その提唱はインターネットの様々な場所で議論の対象になっている。
> https://ja.wikipedia.org/wiki/Fizz_Buzz#FizzBuzz%E5%95%8F%E9%A1%8C
> 

今回はFizzBuzz問題より、もう少し難しくてパッと解ける問題を考えてみました。
プログラマを見極めるのにはもっと色々なポイントを見たほうが良いとは思いますが、一段上のFizzBuzz問題として楽しんでくれると嬉しいです。


# 新しい問題を考えました!その名もLevelLabel問題
数字の配列を引数として下記の条件を満たすラベルを出力せよ。
ただし与えられる配列は昇順に数字が格納されているものとする。

1. 配列の最初の数字を表示し、次に来る数字の条件に応じて表示を変える。
2. 次の数字が連続している場合、連続している数字の末尾まで`~`を表示し、連続する最後の数字を表示する。
3. 数字が連続していない場合は`・`を挟み次の数字を表示する。

```
入力例       => 出力例
[1,2,3,4,5] => 1~5
[3,4,5]     => 3~5
[1,3,4,5]   => 1・3~5
[1,2,4,5]   => 1・２・4・5
```

## あとがき
ロジックを見る問題なので言語とかは問いません。実際に自分が出てきた業務をより簡素にした問題としました。
回答例や改善案などあればお気軽にコメントください。希望する人がいたら応用編と解答編を書こうかなと思います。
統計の基礎公式集（おまけ：TeX記法）

統計を勉強しているが、期間が空くと公式とかけっこう忘れちゃう。
なので自分用に基礎的な公式をまとめてみる。
ついでに**TeX記法**を使って数式を書く練習をする。
随時更新していく予定。

# 平均

* 言わずもがな。

```math
\bar{x} = \frac{1}{n}(x_1 + x_2 + x_3 + \cdot \cdot \cdot + x_n) = \frac{1}{n}\sum_{i=1}^{n} x_i
```

```TeX
\bar{x}
= \frac{1}{n}(x_1 + x_2 + x_3 + \cdot \cdot \cdot + x_n)
= \frac{1}{n}\sum_{i=1}^{n} x_i
```

# 分散
* データの散らばりの度合いを表す値。

```math
s^2 = \frac{1}{n}\sum_{i=1}^{n} (x_i - \bar{x})^2
```

```TeX
s^2 = \frac{1}{n}\sum_{i=1}^{n} (x_i - \bar{x})^2
```

# 標準偏差

* これもデータの散らばりの度合いを表す値。
* 分散との違いや関係はそのうち別の記事に書く予定。

```math
s = \sqrt{s^2}
```

```TeX
s = \sqrt{s^2}
```

# 標準化得点（Z得点）
* 平均が0、分散が1となるように変換した値。

```math
Z得点 = \frac{x_i - \bar{x}}{s}
```

```TeX
Z得点 = \frac{x_i - \bar{x}}{s}
```

# 偏差値（T得点）

* 平均が50、標準偏差が10となるように変換した値。

```math
T得点 = Z得点 \times 10 + 50
```

```TeX
T得点 = Z得点 \times 10 + 50
```

# 変動係数

* 相対的な散らばりの度合いを表す値。
* 単位や平均が異なるデータの散らばりの度合いを比較する際に有用。

```math
CV = \frac{s}{\bar{x}}
```

```TeX
CV = \frac{s}{\bar{x}}
```

# ジニ係数

* ローレンツ曲線をもとに不平等さを測る指標。
* 0に近づくほど平等。1に近づくほど不平等。
* ローレンツ曲線についてはそのうち別の記事に書く予定。

```math
Gini = (完全平等線とローレンツ曲線との間の面積) \times 2
```

```TeX
Gini = (完全平等線とローレンツ曲線との間の面積) \times 2
```


# 共分散

* 2種類のデータの関係の強さを表す指標。

```math
s_{xy} = \frac{1}{n}\sum_{i=1}^{n}(x_i -\bar{x})(y_i - \bar{y})
```

```TeX
s_{xy} = \frac{1}{n}\sum_{i=1}^{n}(x_i -\bar{x})(y_i - \bar{y})
```

# 相関係数

* 2種類のデータの直線的関係の強さを表す指標。
* -1から1までの値をとる。

```math
r_{xy}
= \frac{s_{xy}}{s_x s_y}
= \frac{\sum_{i = 1}^n (x_i - \bar{x})(y_i - \bar{y})}
{\sqrt{\sum_{i = 1}^n (x_i - \bar{x})^2}\sqrt{\sum_{i = 1}^n (y_i - \bar{y})^2}}
=\frac{1}{n}\sum_{i=1}^n \frac{x_i - \bar{x}}{s_x} \cdot \frac{y_i - \bar{y}}{s_y}
```

```TeX
r_{xy}
= \frac{s_{xy}}{s_x s_y}
= \frac{\sum_{i = 1}^n (x_i - \bar{x})(y_i - \bar{y})}
{\sqrt{\sum_{i = 1}^n (x_i - \bar{x})^2}\sqrt{\sum_{i = 1}^n (y_i - \bar{y})^2}}
=\frac{1}{n}\sum_{i=1}^n \frac{x_i - \bar{x}}{s_x} \cdot \frac{y_i - \bar{y}}{s_y}
```

# 偏相関係数

* 2つの変数の相関が第3の変数の影響を受けている場合に、その第3の変数の影響を取り除いて求めた相関係数。

```math
r_{xy\cdot z}
= \frac{r_{xy} - r_{xz}r_{yz}}
{\sqrt{1 - r_{xz}^2} \sqrt{1 - r_{yz}^2}}
```

```TeX
r_{xy\cdot z}
= \frac{r_{xy} - r_{xz}r_{yz}}
{\sqrt{1 - r_{xz}^2} \sqrt{1 - r_{yz}^2}}
```

# 【参考にした本・サイト】
* [統計学入門](https://www.amazon.co.jp/%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80-%E5%9F%BA%E7%A4%8E%E7%B5%B1%E8%A8%88%E5%AD%A6%E2%85%A0-%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E6%95%99%E9%A4%8A%E5%AD%A6%E9%83%A8%E7%B5%B1%E8%A8%88%E5%AD%A6%E6%95%99%E5%AE%A4/dp/4130420658/ref=zg_bs_500906_15?_encoding=UTF8&psc=1&refRID=6PQTF8K4ZJNWF70Y359N)（通称：赤本）
  * 文字の多い本が苦手じゃなければけっこうおすすめ
* [統計学基礎](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%89%88-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A2%E7%B4%9A%E5%AF%BE%E5%BF%9C-%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%9F%BA%E7%A4%8E-%E7%94%B0%E4%B8%AD%E8%B1%8A/dp/4489022271/ref=zg_bs_500906_9?_encoding=UTF8&psc=1&refRID=6PQTF8K4ZJNWF70Y359N)
  * 統計初心者の私には難しかった
* [統計学の時間](https://bellcurve.jp/statistics/course/)
  * 神サイト
RDBMSとは？データベースの概要と基本解説

「ん？RDBMSってなんだ？」
「ま、あとで調べればいっか」

こんなふうに思っていた人にちょうどいい記事です。
この記事では以下のことがわかります。

* **RDBMSとはなにか。どんな仕組みなのか**
* **RDBMSを理解するために重要な主キーと外部キーについて**

3分ほどで読めるのでさくっとどうぞ。

## データベースの種類
まずはどんなデータベースの種類があるかみてみましょう。
主に3つのデータベース型があります。

* 階層型
* ネットワーク型
* 関係型

今回は、もっとも広く使用されている関係型（RDBMS）について解説していきます。

## RDBMSとは
RDBMSは「Relational DataBase Management System」の頭文字をとった略称です。
> リレーショナルデータベースを管理するソフトウエアまたはコンピューターシステム。行と列で配列されたデータについて、照会言語を用いてデータの検索・抽出・並べ替え・結合などを行うことができる。オラクルデータベース、MySQL(マイエスキューエル)、PostgreSQL(ポストグレスキューエル)などがある。リレーショナルデータベース管理システム。関係データベース管理システム。
*Weblio辞書から引用*

まずエクセルの表をイメージしてください。
RDBMSは、**複数のエクセルの表を関係付けして扱うことができる**イメージです。

関係付けるので、**関係データベース**とも呼ばれます。
データベース型には、他にも種類がありますが、現在の主流は関係データベースです。
最近では、RDBMSの問題点を解消した「NoSQL」というデータベースも存在します。
まずは事項でRDBMSのメリット・デメリットをみていきましょう。

### RDBMSのメリット
* データの処理の一貫性が保証されている
* SQLを使用した複雑なデータの検索ができる

### RDBMSのデメリット
* データの整合性を保つ代わりに処理が遅くなる
* データ構造をあらかじめ定義しているため、拡張にはコストがかかる

NoSQLは、これらの問題点を解消した構造になっていますが、SQLを使った複雑な検索はできないなどの理由もあり、まだまだRDBMSが主流であるといって、問題ないです。

## 主キーと外部キーを理解する
RDBMSを理解するためには、主キーと外部キーについて理解しておくべきです。
関係データベースといわれるように、それぞれ配列されたデータを関連付けます。
その際に使用するのが主キーと外部キーです。
それぞれ見ていきましょう。

### 主キーとは
主キーとは、作成したデータベース（テーブル）の行を特定できる一意のIDです。
![スクリーンショット 2021-02-10 8.06.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/1c8f51f4-e86a-7dad-5641-2c6e2a10729f.png)
この例でいうと`id:　integer`が**主キー**になります。
主キーを設定することでデータの重複を防止しています。
身近な例でいうと、社員番号や学生番号と同じ意味ですね。

主キーに設定できる条件は2つあります。

①表の中で内容が重複しないこと
②内容が空ではないこと

この2つの条件を満たすことで主キーとして設定できます。

### 外部キーとは
外部キーとは、**表と表を関係付けるため、他の表の主キーを参照する列**のことです。
下記の画像では`（FK）`の部分が外部キーです。
![digihai_ER.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/4c1f465d-563a-36a4-41dc-57a2d90b62a1.jpeg)
他の表の主キーを使うことで、表を関係付けるからこそ**RDBMS（関係データベース）**といえるでしょう。

## まとめ
今回お伝えしたいことをまとめます。

* **RDBMSとは、表と表とを関係付けるデータベース型のこと**
* **主キーを使うことで、他の表と関係付けをおこなう**

最初は難しく感じるかもしれませんが、慣れてくるとイメージしやすくなるはずです。
興味のある方はここからさらに深掘ってみてください。
【cmake】cmakeの最も簡単なversionのupdate方法

<h1>背景</h1>
cmakeのversionをupdateするのってかなりややこしい。
しかもミスると色々と大変



pipでcmakeのversionをupdate出来るそうな


```
pip3 install cmake --upgrade
```


```
$ cmake --version 
cmake version 3.18.4
```
【apps】flameshot : ubuntuで便利なスクリーンショットアプリ

<h1>背景</h1>
ubuntuのデフォルトのスクリーンショット使いにくくない？windowsもだけど


個人的にflameshotが使いやすい(たまにバグるけど...)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3fd67e9a-c020-de3f-f7c5-4439d3985bb2.png)


<h2>インストール</h2>

aptからインストール

```
sudo apt install flameshot
```

バージョンの確認

```
flameshot -V
```

<h2>エラー対処</h2>

```
$ flameshot -V
error while loading shared libraries: libQt5Widgets.so.5
```
とエラーが出た場合もう一度libqt5関連のライブラリをインストール

```
sudo apt install --reinstall libqt5*
```



```
$ flameshot -V
flameshot: error while loading shared libraries: libdouble-conversion.so.1: cannot open shared object file: No such file or directory
```
とエラーが出た場合もう一度libdouble-conversion1のライブラリをインストール

```
sudo apt install --reinstall libdouble-conversion1
```



<h1>参考文献</h1>
https://www.virment.com/how-to-install-use-flameshot-ubuntu/
ConfigDict()の基本のき

# ConfigDict()とは
> This is a container for configurations. It behaves similarly to Lua tables.
  Specifically:
  - it has dot-based access as well as dict-style key access,
  - it is type safe (once a value is set one cannot change its type).

Lua tables?
使ったことないからわからない。

# 簡単に辞書が作れるイメージで返り値はyamlっぽいやつ

```python
from ml_collections import config_dict
dict_name = config_dict.ConfigDict()
dict_name.key = value
dict_name.new_dict = config_dict.ConfigDict()
dict_name.new_dict.new_key = new_value
dict_name.tuple = (0, 1)

print(dict_name)
# key: value
# new_dict: 
#   new_key: new_value
# tuple: !!python/tuple [0, 1]

# Pythonのdictでそれっぽく示すと以下の感じ
# dict_name = {'key': value, 
#	           'new_dict': {new_key: new_value}
#              'tuple': (0, 1)}
```

# 参考
https://github.com/google/ml_collections/blob/master/ml_collections/config_dict/config_dict.py
each文によるNameError解決の一例

ローカルホストにアクセスすると下記エラー

NoMethod Error in Posts#index
Showing/Users/○○/projects/ourblog_error1/app/views/posts/index.html.erb where line #1 riased:
undefeined method 'each'for nil:NilClass

undefeined method 'each'for nil:NilClass
上記は、nil(空のもの)に対してeachメソッドを使用することができないという意味です。

each文の先頭に@postsが定義されておらずnilと認識されeach文が実行できていません。
@postsはどのファイルのどのアクションで定義されているのか？

どのアクションなのかは、routes.rbで
今どのルーティングで遷移しようとしているのか確認します。

ローカルホストにのみアクセスしているので　root to:'posts#index' より
posts_controller.rbのindexアクションで遷移しようとしていることが分かります。

posts_controller.rbのindexアクションには、
```@post = Post.includes(:user)```と記述されています。

@postと定義されているが受け渡し先のviews/posts/index.html.erbには、
@postsが定義されています。

includes(:user)は、データを複数とるため複数形が好ましいです。
よって、posts_conroller.rbの@postを@postsに修正します。
Keyhac 超入門

ここ数日、Python の学習を兼ねて Keyhac というツールと格闘していまして、
やっと使い方がわかってきたので、シェアしたいと思います。

## Keyhac とは

[@craftware](https://github.com/crftwr) 様が公開されている、キーボード操作を柔軟に変更できるアプリケーションです。

[変換]キーが押されたら、IMEをONにする のような単純なキーの置換から、
エクセル操作中は[F1]キーを無効にするなどのアプリケーション別の設定、
特定のキーを押すだけで、キーボードマクロの実行や別アプリケーションの起動など幅広いことができます。

また、設定スクリプトを Python で記述できるため、
Python の柔軟な文法と強力な機能を使うことができます。

## Keyhac の導入

下記の公式サイトからダウンロードしてください。
Windows版と、Mac版があります。

- https://sites.google.com/site/craftware/keyhac-ja

## Keyhac の設定方法

Keyhac の設定は、config.py に記載します。

config.py は、初回起動時に`%AppData%\Keyhac`内に作成されます。
※keyhac.exe のワークディレクトリ内に存在する場合は上記は作成されないようです。

初回起動時に生成される config.py （またはワークディレクトリ内の _config.py ）には、
設定例としていろいろな処理が記載されていますが、
今回は超入門ということで、簡単なキー変更の設定例を紹介します。

### 単純な config.py の設定例

まずは、以下のコードをご覧ください。
下記のみで動作します。

```python
def configure(keymap):
    # 指定された条件でキーマップを取得
    keymap_app = keymap.defineWindowKeymap("EXCEL.exe")

    # ホットキーを定義
    hotkeys = {"C-E": "F2",               # Ctrl+E を F2 に変更
               "C-Right": ["A-H", "R"],   # 複数キーのシーケンスに置換する場合はリストにする
               }
    # ホットキーの内容をキーマップに設定
    for key, value in hotkeys.items():
        keymap_app[key] = value
```

エクセル上で [Ctrl]キー と [E]キー を押した場合に、[F2]キーに変更する（セルの編集を行う）場合の設定例です。

処理の内容としては大きく2つ

1. キーマップの取得
2. 取得したキーマップにホットキーを設定

を行っています。

それぞれの処理についてざっくり説明します。

#### 1. キーマップの取得

Keyhac では、キーマップというオブジェクトに対してキーの設定行います。

そこで、まずはキーマップオブジェクトを取得します。

```
keymap.defineWindowKeymap()
``` 

このときにパラメータを指定することで、設定を特定のウインドウに限定することができます。
※上記の例ではエクセルに限定していますが、パラメータなしの場合はグローバルなホットキーを設定できます。

設定できるパラメータについては、[公式サイト](http://crftwr.github.io/keyhac/doc/ja/classkeyhac__keymap_1_1_keymap.html#a087213e94e8a1d56589c0cc4c7a58cb2)を参照してください。

#### 2. 取得したキーマップにホットキーを設定

取得したキーマップに対して、キーの設定を行います。

```
keymap_app["C-E"] = "F2"
```

という様に都度設定しても良いですが、例では記述量を減らすため辞書に定義してから for 文で設定しています。

## 参考となるサイト

- 公式ドキュメント (http://crftwr.github.io/keyhac/doc/ja/)
- KT Sofrtware 様 仮想キーコード一覧(http://kts.sakaiweb.com/virtualkeycodes.html)

## さいごに

今までは、AutoHotKey（AHK）というツールを主に使っていたのですが、
文法が 新・旧 入り乱れていたり、イベントの取合いなどうまく動かない場面があったため、
この Python の文法が使えるという部分が大きなメリットと感じています。

もっと流行ってほしいと思って、Qiita 初投稿してみました。
不備などあれば教えて下さい！

私の設定を置いておきます。ご参考になれば。
https://github.com/roppi/KeyhacScripts
形態素分析(MeCab)について

#形態素分析とは
「自然言語」(普通の言葉)を形態素にまで分割する技術のこと

例)形態素解析
「私は球場で野球します」を形態素解析した場合

私(代名詞)
は（副助詞）
球場(名詞)
で(助詞)
野球（名詞）
し(動詞)
ます（助動詞）

##形態素解析：ライブラリ
形態素解析のライブラリに「MeCab」があります。
「MeCab」の特徴として、コーパス(言語や辞書の言語資料)に依存しない、汎用的な設計があげられます。
MeCabで使用できる言語はC、C＃、C＋＋、Java、Perl、Python、Ruby、R等です。

##形態素解析：実装
```「```:MeCab実装(例)
import MeCab
tagger = MeCab.Tagger()
words = tagger.parse('形態素分析したい文字列')
```

#参考文献
[1]岡谷貴之，深層学習，2015 講談社サイエンティフィク， 講談社．

[2]PythonとMeCabで形態素解析(on Windows) - Qiita
Swiftでの関数定義（guard-else文・defer文）

今回は関数定義の基礎を復習。
guard-else文・defer文について見ていきたいと思います。

簡潔にまとめると、

guard-else文は条件が合致していないときに実行！
defer文は関数が終了したときに実行！

ということです。詳しく見ていきましょう。

## 戻り値のない関数
まずは基礎として、戻り値がない関数から。

```swift
func 関数名(){

}
```
戻り値がないのでreturnがなく、戻り値の型もありません。

さらに、こんなふうに書くこともできます。

```swift
func 関数名()->Void{

}

func 関数名()->(){

}
```



## guard-else文

関数の中で処理を途中で抜ける場合は、returnを実行することで抜け出せることができます。

途中で抜け出すことを明確に示すために、guard-else文を使います。
こんな感じでつかいます。

```swift
guard 条件式 else{
  return
}
```

例

```swift
func call(num:Int){
  guard num>= 100 else{
    return
  }
  print(num)
}
```

この場合、numが100以上でないときのみnumが表示されます。
if文に似ていますが、こちらは「~でないとき」に呼ばれるので注意しましょう。


## defer文

defer文は、関数が抜ける直前で必ず呼ばれる関数です。
こんな感じで使います。

```swift
func call(num:Int){
  defer{
    print("終わったーーー！！！")
  }
  guard num>= 100 else{
    print("数字は100以上でした")
    return
  }
  print("数字は100未満でした")
}

//100以上の場合
//"数字は100以上でした" "終わったーーー！！！"

//100未満の場合
//"数字は100未満でした" "終わったーーー！！！"
```

どちらにしても必ずdeferのなかが呼び出されるわけですね！


## まとめ
というわけで、今回はguard-else文・defer文について振り返りました。

guard-else文は条件が合致していないときに実行！
defer文は関数が終了したときに実行！

ということを覚えておきましょう！
GitHubPageで過去バージョンもホスティングさせつつ楽に管理する方法論

`<username>.github.io`のGitHubPageを使って**過去バージョンのサイトもホスティングさせつつ楽に管理する方法論**を考えたのでここに残す。

## 前提

- `https://<username>.github.io`にアクセスすると最新のAboutMeページを表示させたい
- このAboutMeページ自体も作品として残しておきたいし、長期的にみたらリプレイスするので各バージョンごとにどこかにホスティングさせておきたい。つまり、「AboutMe v1」 / 「About Me v2」などをどこかにホスティングさせつつ残しておきたい。
  - 普通に管理すると１つのリポジトリでgit-tagする方法だと思う。確かにコード管理はできるけど、過去のバージョンをどこかにホスティングさせるのが面倒。
  - カスタムドメインを使えば自分のドメインでも管理できるけど、管理を楽にしたいのでGitHubPageの機能周りだけですべてを済ませたい。


## 解決方法

- `v1`、`v2`などのリポジトリを作成。
  - ここに自分が作成したAboutMeの実際の成果物の残しておく。
  - このリポジトリに対応するGitHubPageのURLは`https://<username>.github.io/v2`になる。
- `<username>.github.io`リポジトリにはリダイレクトをするHTMLだけを置く
  - リダイレクト先はLatestバージョンのGitHubPageのURLにする

---

実際にこれでうまく動くので楽に運用できそう

* [GitHub - snamiki1212/snamiki1212.github.io: Portofolio](https://github.com/snamiki1212/snamiki1212.github.io)
2021年にオンラインビジネスを効率的に実行するためのトップShopifyアプリ（パート2）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/d4c2cd1e-8765-b491-7cfe-b6706d1edafc.png)

ご存知かもしれませんが、Shopifyはeコマースストアを作成するための柔軟で完全なソリューションです。さまざまなアプリを使用して、マーチャントはデフォルトのShopify機能を改善したり、まったく新しい機能を追加したりできます。この記事は、市場で入手可能な最高のアプリを強調することで、時間を節約するのに役立ちます。

ここでは、SEOやウェブサイトの最適化のためのトップShopifyアプリを含む、最高のマーケティングおよび販売アプリを見つけることができます。

Shopifyの最高のマーケティングアプリ

マーケティングとプロモーションは、新しい顧客を引き付け、既存の顧客を維持し、売上を伸ばすことに焦点を当てた包括的な戦略の重要な要素の一部です。

アプリをShopifyしてトラフィックを増やす

無料のトラフィック$ Easy Adsは、その幅広い機能と集中した機能により、トラフィックに最適なShopifyアプリの1つです。これにより、ユーザーは1つのアカウントでFacebook、Instagram、およびGoogleの広告を管理できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/6cc17ab6-2188-52bd-405d-b5204229439b.png)

FacebookとInstagramにのみ広告を掲載したい場合は、Facebookチャンネルアプリが適しています。このShopify広告アプリは、FacebookとInstagramで販売とマーケティングを成功させるためのすべてのツールを販売者に提供します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/e68e8468-e9c3-e7f6-2547-8f22c0cd6a43.png)

ShopifyビジネスがGoogleアドワーズネットワーク上の人々をターゲットにしたい場合、Google広告用の賢いeコマースアプリは素晴らしいオプションです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/01f2346b-70a6-1893-95dc-c880d61278d4.png)

トップShopifyメールマーケティングアプリ

トラフィックの現実は、ターゲットを絞ったとしても、あなたの店に来るほとんどの訪問者は戻ってこないということです。メーリングリストを作成し、プロモーションメッセージを送信すると、トラフィックを維持するのに役立ちます。 1つまたはいくつかのShopifyメールアプリを使用してメールを収集できます。

Privy-Shopifyに最適なメールマーケティングアプリ。販売者は、すべてのサブスクリプションフォームから顧客のメールを収集するために使用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/74deebc1-6d4c-58d9-75ce-1c4877305a12.png)

Omnisend Email Marketingは、EメールおよびSMSマーケティングプラットフォームです。ドラッグアンドドロップのメールビルダーとさまざまな既製のメールテンプレートを使用して、美しく買い物可能なメールを数分で作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/5aadbdff-3c51-78e7-d4ab-b3f1dd45a810.png)

Klaviyoは、企業が顧客との永続的で価値の高い関係を構築するのに役立つ最高のShopifyメールアプリです。メール、SMS、ウェブ、アプリ内通知など、使用するすべてのマーケティングチャネルで機能します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/f3d48ca9-0d62-98ca-6bcc-807716fc864b.png)

紹介キャンディは、ShopifyとShopifyPlusの両方のeコマースストアと統合できます。ドラッグアンドドロップテンプレートエディターまたはCSS.programsを使用して、電子メールからポップアップまで、すべての要素の外観を制御するための幅広いカスタマイズオプションを提供します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705866/f1d535cf-a58e-fed6-7b58-ce89aa693cee.png)

最高のShopify分析アプリ

CartKitによるライブセッションレコーディングの再生は、最高のShopify分析アプリです。ストアの各訪問者のライブセッション記録を作成すると、eコマースチームは、訪問者がWebサイトで実際に何をしているのか、どこで混乱したり行き詰まったりするのかを確認できます。

詳細[こちら](https://whidegroup.com/blog/top-shopify-apps-part-2/)
【Python備忘録】random関数について学んだので記します( random関数 / randint() / choice() )

# はじめに
数字やリストの中の要素からランダムに選ぶ機能を持った「random関数」について学んだので、randintとchoiceのふたつの使い方について備忘録として記します。

# 使用する関数
「random関数」を用います。
使用する際は、randomモジュールをimportしてから使用します。

```sample.py
import random
```

Pythonには print() や max() のようにいつでも使える機能があります。
しかしそれ以外に、使いたい時に取り込む機能もあります。
毎回使わないものは、 import してから使うように作られています。

# 「最小の整数 <= n <= 最大の整数」の範囲の整数をランダムに返す
「randint()」を使用します。

```sample.py
random.randint(最小の数, 最大の数)
```

これにより、最小の数と最大の数の間に含まれている数の中からランダムに数値を選択することができました。

# リストからランダムに1つの要素をえらぶ
「random.choice()」を使用します。

```sample.py
random.choice(リストの名称)
```

これによりリストの中に含まれる要素のなかからランダムに要素を選択することができました。

# さいごに
今回は、random関数について学んだので備忘録として記してみました。
randomモジュールには他にもたくさんの機能があるようなので、いろいろと学んでみます。ここまで読んでくださりありがとうございました！

# 参考
公式ドキュメント
https://docs.python.org/ja/3/library/random.html
【Python備忘録】対象の文字列の中に特定の文字列が含まれているかの判別をする (in演算子)

#はじめに
pythonで、「in演算子」を用いて対象の文字列の中に特定の文字列が含まれているかの判別をする方法を学んだので、備忘録として記します。

#使用する関数
今回使用するのは「in演算子」というものです。

```sample.py
"特定の文字列" in "対象の文字列"
```

上記のように記すことで、「対象の文字列」の中に「特定の文字列」が含まれているかどうかを判別することができます。

#実際に使ってみる
if文での条件分岐と組み合わせて実際に使用してみます。
今回は「いちごりんごみかんなしももブドウパイナップル」という対象の文字列の中に「りんご」という特定の文字列が含まれているか判別し、含まれていた場合、「りんごが含まれています」という文字列を表示することを目標に使用してみます。

```sample.py
line = "いちごりんごみかんなしももブドウパイナップル"

if "りんご" in line:
    print("りんごが含まれています")
```

これを実行すると、「りんごが含まれています」と無事表示されました。
したがって、対象の文字列の中に、「りんご」という文字列が含まれていることを判別することができました。

#さいごに
今回は、対象の文字列の中に特定の文字列が含まれているのかの判別を「in演算子」を用いてやってみました。とても便利な機能なので、学べてよかったです。

#参考
公式ドキュメント
https://docs.python.org/ja/3/reference/expressions.html#membership-test-operations
[小ネタ]Next.jsの全体設定について

# 概要
Next.jsで全体のCSS設定をしたいというご質問を頂いたので、``_document.js(tsx)`` と``_app.js(tsx) ``について。

この2つはpages/ディレクトリに設置し、Routeにならない特殊なファイルです。
``_document.js(tsx)``は吐き出されるHTMLファイルの構成を変えることができ、``_app.js(tsx) ``はすべてのRouteコンポーネントがここで書いた``<App>``コンポーネントによってラップされるようになります。

# _document.js(.tsx)

``_documet.js(tsx) ``はDocument コンポーネントを継承したクラスを実装します。
Headタグの中に``<title>`` など、全ページ共通の設定を行うことができます。

```typescript:_documet.js(tsx)
class SampleDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html lang={this.props.locale.split("-")[0]}>
        <Head>
          <meta name="viewport" content="width=device-width,height=device-height" key="viewport" />
          <link rel="shortcut icon" href="/static/shortcut-icon.png" key="shortcutIcon" />
          <meta name="theme-color" content="#087da1" key="themeColor" />
          <link rel="dns-prefetch" href="//www.google.co.jp" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default SampleDocument
```

注意点としては以下のことがあります。

- SSR(サーバサイドレンダリング)のみの実行なので、クライアントサイドの処理を書くべきではありません。
- ``<Main />`` 内に入る外部のReactコンポーネントはブラウザによって初期化されないため、ここでアプリケーションのロジックや、styled-jsxのようなCSSを設定してはいけません。代わりに_app.js(tsx)を使ってください
- DocumentのgetInitialPropsは、クライアントサイドの遷移中には呼び出されず、ページが静的に最適化されている場合にも呼び出されません

# _app.js(tsx)

``_app.js(tsx)``はデフォルトのAppコンポーネントを上書きできます。
全ページで必要な処理をここに書くことができます。他にも以下のようなことができます

- ページ間の共通レイアウトを持たせることができる
- 共通のstateを持つことができる
- グローバルなCSS(全ページ共通の)を定義できる
- componentDidCatchを利用したカスタムエラー処理
- 各Routeコンポーネントをラップするもの
- ReduxのProvider設定をする

また、``_document.js(tsx)`` と異なり、AppはPageコンポーネントと同じ動きをするので、``_app.js(tsx)``はSSRされ、ライフサイクル周りのイベントはクライアントサイドでも実行することができます。

なお、すべてのページで必要な依存物を全て詰め込んでしまうと、サーバーサイドレンダリングでそのRouteにとって無駄な処理をしてしまう上、Next.jsが自動的にコード分割をできなくなってしまい、HTTPで配信されるJSファイルのサイズも肥大化してしまいます。各Routeで必要なだけ参照するようにするという形を取ることも時には検討した方が良いです。

```typescript
import * as React from "react";
import { Provider } from "react-redux";

function MyApp({ Component, pageProps }) {
  return (
		<Provider store={store}>
      <Layout>
        <Component {...pageProps} />
          <style jsx global>
            {`
              #container {
                min-width: 800px;
              }
            `}
          </style>
        )}
      </Layout>
    </Provider>
	)
}

export default MyApp
```


# まとめ
Next.jsでは``_document.js(tsx)``, ``_app.js(tsx)``を用いることでページ間の共通処理や共通レイアウトを定義することができます。

# 参考

https://nextjs.org/docs/advanced-features/custom-document
https://nextjs.org/docs/advanced-features/custom-app