OmniAICreator/Qiita-1.07M huggingface dataset:
ローカルにACL(Atcoder Library)導入

##はじめに
初投稿です。nagoyanといいます。
競技プログラミング「Atcoder」で公式ライブラリACLが公開されたみたいなので今後のコンテストに備えて自分の環境で設定したことをまとめようと思います。
競プロの環境構築についてはこちらの記事を参考にしています。

[Visual Studio Codeで競プロ環境構築(導入編)](https://qiita.com/AokabiC/items/e9312856f588dd9303ed)
##環境

* Windows10 Home 64bit
* WSL Ubuntu 18.04 LTS
* gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

##ACLの導入
まずはACLをダウンロードします。
https://github.com/atcoder/ac-library

atcoderフォルダをCドライブ直下の/includeに保存します。
WSL上のパスは`/mnt/c/include`です。

##コマンドの設定
専用のコンパイルオプションを関数化しておきます。
~/.bashrcを以下のように編集します。

```~/.bashrc
//末尾に挿入
function acg(){
        command g++ $1 -std=c++14 -I /mnt/c/include -g -fsanitize=undefined,address -D_GLIBCXX_DEBUG
}
```

必要なのは`-std=c++14 -I /mnt/c/include`の部分です。その後ろはおまけのデバッグオプションです。
編集後、`source ~/.bashrc` をするか、WSLを再起動してください。

##使い方
mintの例を示します。ほかのライブラリの使い方はACL同梱のドキュメントを参照してください。

```shojin.cpp
#include<bits/stdc++.h>
#include<atcoder/modint>
using namespace std;
using namespace atcoder;
using lli = long long;
using mint = modint1000000007;


int main(void){
    mint a = 123456789;
    mint ans = a*a;
    cout << ans.val() << endl;
    //643499475
    return 0;
}
```

`acg shojin.cpp`のようにコンパイルして実行します。

##終わりに
atcoder提出の際には言語選択で
`C++(GCC 9.2.1 with AC Library v1.1)`
を選択する必要があるので忘れないよう気を付けてください。
まだ過去問では使えないみたいですが、今後使えるようになると精進もはかどりますね。
「Lookerは単なるBIではない」というが、では一体なんなのか

# LookeはBIではない　?   

「Lookerはデータプラットフォームです」みたいな話はアチコチで聞くがいまいちよくわからん。
プラットフォーム、、、__プラットフォームってなんだろう？__　　　謎。
しかし巷ではLookerはシリコンバレー発の新しいコンセプトのクールなデータプラットフォーム(??)という噂である。謎を解明する為、実際に使ってみようと思い理由を考えて仕事で使ってみる。

色々と触ってわかった事。

---------------------------------------

## 「Model」は大きな仮想テーブル

Lookerの世界ではLookMLというDSLを書いて「Model」と呼ばれる論理構造を構築できる。
LookMLは、データベース上のたくさんのテーブルを全部結合して、集計の定義をたくさん書く感じ、なんというか、巨大なSQLをバラして書く感じだ。
Modelというのは「一つの巨大な情報全部入りの非正規化テーブル」みたいなものだ。これがLookMLによって論理的に（viewの感じに似てる）定義される。

---------------------------------------

## Exploreは仮想SQL（造語だ）を操作するGUI

このModelを操作するのがExploreというLookerのキラー・アプリである。
Exploreはディメンションという集計キー/軸/単位と、メジャーと呼ばれる集計値/項目、を選択したり、フィルタを設定する事で先ほどのModel（仮想テーブル）からデータを取得できる。
ディメンションはGroupingに、メジャーは集計関数に、フィルタはWhereに、、といった具合に__Exploreの操作は単純なSQLに喩えて考える事が可能__であり、これは仮想的なSQLとして考える事ができる。
仮想的なSQLを仮想的なテーブルに発射して集計処理を簡略化しよう、というのがLookerの世界だ。
ちなみに、ExploreだけでなくAPI（SQLに似たセマンティクスを持つ）でもModelを操作できる。このあたりの設計思想に「プラットフォーム」感がある。

---------------------------------------

## Lookerの正体は動的ビュー管理システム+BI（Lookerは単なるBIツールではない！！）

ところで、これらは全部仮想的なもので、実際に行われている事は仮想SQL(つまりExploreの操作)をLookMLの定義によって複雑なSQLに変換し実行する事である。
必要なテーブル、必要な結合、必要な計算は「仮想的SQL」の内容によりLookerのランタイムにより動的に決まる。これは動的ビュー（造語その2）みたいなもので、Lookerを処理系として見ると「SQLをSQLに変換するもの」そのように見える。

---------------------------------------

## DWH今昔物語

たくさんのテーブルデータを非正規化して巨大なテーブルにしたものをデータマートと呼んだ時代があった。
データマートはディメンションの主要な組み合わせ毎に作成される事が多く、これは計算時間を短くする為の工夫だった。
昔は巨大なバッチ処理を一晩中サーバーでグルグルと回して実際にデータを実際に加工（それでもその日のデータを処理するのがやっとだった）してた。そのように作られ日々累積していくデータマートの管理は慎重に恭しく行われた。__LookerはこれをSQLの変換だけで、あくまで論理的・仮想的に行う__。[^1]
昔は事前に計算しないと無理だったのが、分散技術の進歩で計算能力が上がった為に事前計算の必要が無くなった、という見方もできる。（このあたり関数型言語っぽい雰囲気、、、lazyナントカ、、、を感じる）

---------------------------------------

#### 太古（データマートという物理の時代）

![スクリーンショット 2020-09-30 22.07.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72976/1072cb05-3dd0-9f48-007a-5ab86650b3e3.png)

---------------------------------------

#### 現代（Lookerによる仮想Model）

![スクリーンショット 2020-09-30 22.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72976/09b2b76b-395b-df72-eef6-c4eba164ee72.png)

---------------------------------------

# データが無いと気軽にぽんぽんデプロイできるようになる

Lookerは（概念的には）データを持たないので__デプロイのコストは0に等しい__。（超重要）
昔は分析系のバックエンド処理プログラムのリリースというのは「行事」であった。集計項目を一つ追加するだけで数ヶ月かかった気がする。
ガントチャート、冪等性、ワークフロー、再計算、不整合の解消、部分的再実行、リカバリ、バックアップ、プログラムのコピー、エラー処理、入念なテスト、早朝リリース、居酒屋で打ち上げ、、、みたいな。これを数人のチームでやってた。
Lookerはデータを持たないのでデプロイのコストは数千分の一（主観による）になった。ボタンを押すだけだ。__特に考えなくぽんぽんとリリース__できるのは本当にありがたい。便利な世の中になったな〜と思う。


[^1]: 実際にはPDTと呼ばれる中間集計データを使う事も多いが、管理の仕組みが面白く、存在をあまり感じさせない？設計になっている。
【AWS】CloudFrontのBehaviorsを使った分岐でハマったところ

## とりあえずメモレベルで残す
装飾とかまとめはまた別途書きます。

## やりたかったこと
Route53に登録したホストゾーンのドメインに対して、URLから判定してS3かAPIGatewayに飛ばす

- Default (*)の場合はS3（Staticページ）に飛ばす
- `/api/*`の場合はAPIGatewayに飛ばす

## ハマったところ
- APIGatewayのStageが`dev`を設定
- CloudFrontの`Origins`に設定したAPIGatewayの設定の`Origin Path`に`/dev`を設定
- `CloudFront`の`Behaviors`の`Path Pattern`には`/api/*`されていた
- `<cloud front path>/api/*`でAPI叩いたら`"message": "Missing Authentication Token"`が返ってきた

## 原因
- 上記の設定だと、APIGatewayの`/api/dev/`Stageにアクセスしようとするため、リソースがないと言われる
 - CloudFrontの`Behaviors`の`Path Pattern`に設定する値と、APIGatewayのStageが一致している必要がある
 - CloudFrontの`Origins`に設定したAPIGatewayの設定の`Origin Path`の値は設定しない

## 対応
- APIGatewayのStageに`api`を追加
- CloudFrontの`Behaviors`の`Path Pattern`に`/api/*`を設定
- CloudFrontの`Origins`の`Origin Path`の設定値はなし

## 参照ページ
[“Missing Authentication Token” — CloudFront/APIG Troubleshooting](https://medium.com/@dalumiller/missing-authentication-token-cloudfront-apig-troubleshooting-252d8a33c412)
【npm】パッケージとモジュールの違いって何？

#はじめに
普段、Node関連の記事を書いていたり、業務で説明をする時などに、曖昧になりやすい **パッケージ** と **モジュール** の違いについて公式のドキュメントをもとに簡単にまとめます。

#npmにあるのはパッケージなのかモジュールなのか
>The npm registry contains packages, many of which are also Node modules,

公式にはnpmレジストリーにはパッケージが含まれており、その多くはNodeモジュールです。

#そもそもパッケージとは何なのか
>A package is a file or directory that is described by a package.json file.

パッケージとは `package.json` によって記述されるファイルもしくはディレクトリのことを指します。

#そもそもモジュールとは何なのか
>A module is any file or directory in the node_modules directory that can be loaded by the Node.js require() function.

モジュールとは、Node.jsの `require` 機能によって呼び出すことができる `node_modules` 内のファイルまたはディレクトリのことを指します。

>To be loaded by the Node.js require() function, a module must be one of the following:
・ A folder with a package.json file containing a "main" field.
・ A folder with an index.js file in it.
・ A JavaScript file.



モジュールとして `require` 機能によって読み込まれる為には、次のいずれかである必要があります。

* `package.json` を含むフォルダーであり、`main`フィールドを含むファイルであること。
* `index.js` というファイルが入っているフォルダであること。
* `JavaScript` ファイルであること。

#結局のところ何が違うのか
npm経由でインストールされたパッケージは、ほとんどがファイルの中でロードされて使用されます。

つまり、これらはモジュールと言えるでしょう。

#モジュールに該当しないパッケージもある
npm経由でインストールされるパッケージは、ほとんどがファイルの中でロードされる為、モジュールであると書きましたが、中にはターミナルなどのコマンドラインで実行するパッケージもあると思います。

このように `main` フィールドを持たないパッケージはモジュールとは言えません。

#まとめ
長々と書きましたが、簡潔にかくと以下のようになります。

**ファイルの中で`require`して読み込みNode.jsが使用する`main`フィールドが含まれていればモジュールという認識でOK**

#参考文献
[About packages and modules](https://docs.npmjs.com/about-packages-and-modules)
Firebase Crashlyticsを導入してCould not get GOOGLE_APP_ID in Google Services file from build environmentが出た場合の対処法


## エラー発生
iOSのプロジェクトにFirebase Crashlyticsを導入したところ、以下のエラーが発生。

```
Could not get GOOGLE_APP_ID in Google Services file from build environment
```

GoogleService-Info.plistは正しいパスに置いてあるはず。何故…

## 原因

[公式ドキュメント](https://firebase.google.com/docs/crashlytics/get-started?hl=ja)に書いてありました。

> 注: 新しいビルドフェーズがプロジェクトの最後のビルドフェーズであることを確認してください。そうでないと、Crashlytics が正しく初期化されません。

対象のプロジェクトではXcodgenでプロジェクトファイルを生成していました。
**Xcodegenは必ず最後にCocoaPodsのスクリプトが走るようになっている**ため、正しく初期化されなかったようです。
(`postCompileScripts`よりも更に後に走る)



## 解決策

CocoaPodsのscript_phaseで、最後のビルドフェーズにスクリプトが走るようにして解決。


```ruby:Podfile

target 'Project' do
    pod 'Firebase/Crashlytics'

    script_phase :name=> 'FirebaseCrashlytics',
                 :script=> '"${PODS_ROOT}/FirebaseCrashlytics/run"',
                 :input_files=> ['$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)']
end
```

ビルドフェーズの最後に追加されたことが確認できます。

|Build Phases|
|---|
|<img alt="スクリーンショット" width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563972/0b79ab2f-65a8-818f-7c38-b8c4169477a4.png" >|



## 参考文献
https://qiita.com/yosshi4486/items/73a627c1e3daf8f4f509
Fabricだった頃からあるようです。Xcodegenにスクリプトまとめたいですね…
言語処理100本ノック2020（Rev1)をやってみました。

# 1.言語処理100本ノックについて

言語処理100本ノックは、以下のサイトで公開されています。

[言語処理100本ノック2020（Rev1)][url]
[url]:https://nlp100.github.io/ja/

2011-2012年ごろに東北大学の乾・岡崎研究室（当時）（現在は乾・鈴木研究室）で作成され、新人研修の一つであるプログラミング基礎勉強会で使われてきたとのことです。
2020年4月には、言語処理100本ノック2020が公開されました。
2020版では、RNN/CNNや機械翻訳の章が追加されています。

# 2.このサイトについて
自然言語処理とpython初学者の筆者が、試行錯誤しながら解いた結果をまとめていこうと思います。
ご指摘があればご教示いただけると嬉しいです。

[第1章: 準備運動](https://qiita.com/takoyakiya/private/e43ead64893296b25d0f)
[第2章: UNIXコマンド](https://qiita.com/takoyakiya/private/db897e26af784e83af06)
[第3章: 正規表現](https://qiita.com/takoyakiya/private/45999e9d07e84bd9cd17)
[第4章: 形態素解析](https://qiita.com/takoyakiya/private/956dc45c62193fde54d1)
[第5章: 係り受け解析](https://qiita.com/takoyakiya/private/fd94102ae8c6c3182522)
[第6章: 機械学習](https://qiita.com/takoyakiya/private/03f4f1e9707ab0ed5eff)
[第7章: 単語ベクトル](https://qiita.com/takoyakiya/private/e398bae3720316731af7)
[第8章: ニューラルネット](https://qiita.com/takoyakiya/private/777c6966aefcc58f1655)
[第9章: RNN, CNN](https://qiita.com/takoyakiya/private/178acaa3f7d00f56b466)
第10章: 機械翻訳
AWS Route53 親ドメインを移行しないでEC2にサブドメイン設定

#やりたいこと
一つドメインを持ってるのですが、それは別なサイトに使ってるので、サブドメインでやりたいなーとおもった


#前提
EIPと紐付いているEC2がある
EC2はnginx導入済み

下記記事の続き
https://qiita.com/ntm718/items/f896c8e4fb801777954b

ドメイン取得済み
ちなみにお名前ドットコム(DNS設定するだけなのでどこでも良いですが)

#1.サブドメインのRoute 53ホストゾーンを作成します。

ホストゾーンの作成を選択

注意
ホストゾーン1つにつき、0.50 USD/月発生します(50円ほど)


![スクリーンショット 2020-09-16 0.48.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/d3eb80eb-86a6-0f29-c0eb-161977f4cfd5.png)

ドメイン名につけたいサブドメインを含むドメイン名を入力
`test`部分がサブドメイン
パブリックホストゾーンのまま、作成

![スクリーンショット 2020-09-16 1.09.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/187e4e71-d2e9-6f99-cea5-7b12439ec4cb.png)


作成するとネームサーバーが振られます
このNS値を、現在の親ドメインのDNSレコードに追加します

![スクリーンショット 2020-09-17 23.56.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/812ccff1-81da-0305-3431-6417d8c44dcb.png)


#DNS設定
登録している親ドメインのDNS設定できるページに行きます
自分の場合、お名前ドットコムなので下記のような画面です

![スクリーンショット 2020-09-18 0.01.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/78c39f70-8134-5fb2-8a77-b42593a7bcfe.png)

そして、レコードに
 - サブドメイン
 - Type: NS
 - TTL: 900 (キャッシュ時間なので増やしても良い)

で入力し、
VALUEに、Route53の手順で作成された、タイプ`NS`の`ns`から始まる値を入力します
NSは4レコードなのでVALUEだけ4レコードを追加します

![スクリーンショット 2020-09-18 0.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/2c1ab1ba-1229-5d1b-da28-150a9231fe73.png)

![スクリーンショット 2020-09-18 0.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/a2e63dc8-24d5-f3f5-4400-176b72a4299b.png)


お名前ドットコムの場合DNSレコード設定用ネームサーバー変更確認を選択せず、設定まで行き完了です

# EC2と紐付け
AWS Route53の作成したホストゾーンにレコードを追加します
レコード作成を選択


![スクリーンショット 2020-09-18 0.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/edea52fd-7acf-7982-4fdc-e51dff7a860a.png)

シンプルルーティングで次へ


![スクリーンショット 2020-09-16 2.27.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/30d9b429-0f92-9c7d-a6cd-49b9f7a5e63b.png)

シンプルなレコードを定義を選択し、
 - レコード名: 空欄
 - 値/トラフィックのルーティング先: レコードタイプに応じた~~
 - 値: EIPのパブリックIPv4
 - レコードタイプ: A

![スクリーンショット 2020-09-16 2.30.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/fdbe74f3-c628-7afe-f55c-12d0f92e6048.png)


作成後、サブドメインホストゾーンに戻り、レコードをテストするを選択

![スクリーンショット 2020-09-18 0.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/edea52fd-7acf-7982-4fdc-e51dff7a860a.png)


レスポンス取得を押し、EIPのパブリックIPが返却されたらOK

![スクリーンショット 2020-09-18 0.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/676abf65-6b11-53e8-58a3-3802b9577dec.png)

# nginx設定
server_nameの設定する

EC2にssh接続し

```
sudo vi /etc/nginx/nginx.conf
```

`server_name`の箇所を、サブドメイン含むドメインを入力

再起動して、反映させる

```
sudo systemctl restart nginx
```

# 確認
ブラウザでドメイン入力、表示されたら成功
**`https`** ではなく **`http`** で確認しましょう(SSLがまだの場合)

# 感想
netlifyでブログをサブドメインで運用しており、そのときにドメインのDNSを移しているのに気づかずハマり、SSLしてないからhttpなのに、httpsにして少し溶かしてしまいましたが、簡単な構成だと楽にできますね
テーブルタグからほしい情報を取り出す

新型コロナウイルス感染症に関する報道発表資料（発生状況、国内の患者発生、海外の状況、その他）
https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000121431_00086.html


データサンプル
https://www.mhlw.go.jp/stf/newpage_13640.html

```javascript

const html = `(上のテーブルをコピペする)`

// カンマ区切りの数字のカンマ削除、タブを,に変換して CSVライクにする
const csv = html.replaceAll(',', '').replaceAll('\t', ',')
// 改行ごとに配列に変換
const arr = csv.split('\n')
// ほしいデータに整形
const data = arr.map(d => {
  const [name, a,b ] = d.split(',')
  return {name, a: parseInt(a, 10), b: parseInt(b, 10)}
})
// 感染者数の降順にする
data.sort((a, b) => -(a.a - b.a))
```
Reactルータ

Reactのルーターについての基本！！

##基本形


```
import React from "react";
import { Link } from "react-router-dom";

export default function App() {
  return (
    <div>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users">Users</Link>
    </div>
  );
}

```

##コンポーネント
:exclamation:全てreact-router-domからimportする必要がある:helmet_with_cross:
###1. routers
:point_up_tone1: `<BrowserRouter>`: 通常のURLパスを使用
:point_up_tone1: `<HashRouter>`: URLにhashを含むパスを使用（e.g. http://example.com/#/your/page）

###2. Route Matchers
:point_up_tone1:`<Switch>`の中で`<Route>`を使う。現在のページが`<Route>`に記載されているページと同じならページ遷移しない。

:anchor:ポイント:anchor:
途中まで同じURLの時はより詳細の方を先に書く
:warning:`Route exact path=`を使えば書く順番は問わない。

```
<Route path="/contact/:id">
  <Contact />
</Route>
<Route path="/contact">
  <AllContacts />
</Route>
```

###3. Navigation
:point_up_tone1:`<NavLink>`: パスが変わらなくても押せばアクティブになる

##Scroll
:point_up_tone1: `<ScrollToTop>`TOPにスクロール

```
export default function ScrollToTop() {
  const { pathname } = useLocation();

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return null;
}
```
enum classを使った際のnamespaceエラー

##発生コード
```c++
enum class GameStates {
  WAIT_START_STATE,
  TRACER_STATE,
};

int nowState = static_cast<int>(GameStates::WAIT_START_STATE); // error
```
## 発生した原因
gccコンパイルのオプションに```-std=c++03```を指定していたため

## 解決策
1. gccコンパイルのオプションで```-std=c++11```か```-std=gnu++11```の指定に変更する
1. gccのオプションで最小限の驚きには反するがenumで暗黙的にint型にする

```C++
enum GameStates {
  WAIT_START_STATE,
  TRACER_STATE,
};

int nowState = WAIT_START_STATE;
```

今回は開発環境の都合上2.の解決方法を選択した．

## 参考文献
(1) [How to automatically convert strongly typed enum into int?](https://stackoverflow.com/questions/8357240/how-to-automatically-convert-strongly-typed-enum-into-int)
(2) [enum class is not a class or namespace](https://stackoverflow.com/questions/24028372/enum-class-is-not-a-class-or-namespace)
[CentOS7]pythonのバージョン関係なしにaws cliをインストール

## 前提

aws cliはv1,v2があります。
v2はpythonを必要なくなったので、バージョンに悩むことがなくなりました。
v1のインストール方法は[こちら](https://qiita.com/samichi_valley/items/58b42de4151ee8b13af0)から。

## インストール

- インストール前のコマンドの確認

```sh
$ aws --version
-bash: aws: コマンドが見つかりません
```

- pythonのバージョン確認

```sh
$ ll /usr/bin/python*
lrwxrwxrwx. 1 root root    7  9月 10 22:29 /usr/bin/python -> python2
lrwxrwxrwx. 1 root root    9  9月 10 22:29 /usr/bin/python2 -> python2.7
-rwxr-xr-x. 1 root root 7136 11月  6  2016 /usr/bin/python2.7
```

- インストール

```sh
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install
```

- インストール後のバージョン確認

```sh
$ aws --version
aws-cli/2.0.47 Python/3.7.3 Linux/3.10.0-514.el7.x86_64 exe/x86_64.centos.7
```
> aws cliv2が入ってます。
> また、python3.7を使用しているようです。

- pythonのバージョン確認

```sh
$ ll /usr/bin/python*
lrwxrwxrwx. 1 root root    7  9月 10 22:29 /usr/bin/python -> python2
lrwxrwxrwx. 1 root root    9  9月 10 22:29 /usr/bin/python2 -> python2.7
-rwxr-xr-x. 1 root root 7136 11月  6  2016 /usr/bin/python2.7
```
> pythonは2.7のみ入っています。

## 参考

- [Linux での AWS CLI バージョン 2 のインストール](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html)
[PHP]LINE bot開発での簡易デバッグ

#今回の題
今回は完全に個人的なメモです。
LINEbotのsdkなどに関する説明等はいたしません。

#どうやるのか
受け取ったリクエストの内容をerror_logでログファイルに書き出し、ブラウザ上で確認できるようにする。

```php
error_log(print_r($event, true) . "\n", 3, '書き込むログファイルへのパス');
```

以下は全体像。

```php
<?php
require('vendor/autoload.php');

use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;

$http_client = new CurlHTTPClient(チャネルアクセストークン);
$bot = new LINEBot($http_client, ['channelSecret' => チャネルシークレット]);
$signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE];
$request_body = file_get_contents('php://input');
$events = $bot->parseEventRequest($request_body, $signature);
$event = $events[0];

error_log(print_r($event, true) . "\n", 3, '書き込むログファイルへのパス');

```

このログファイルをブラウザで表示させると、以下のように表示される。

```
LINE\LINEBot\Event\MessageEvent\TextMessage Object
(
    [emojis:LINE\LINEBot\Event\MessageEvent\TextMessage:private] => 
    [message:protected] => Array
        (
            [type] => text
            [id] => XXXXXXXXX
            [text] => テスト
        )

    [event:protected] => Array
        (
            [type] => message
            [replyToken] => XXXXXXXXX
            [source] => Array
                (
                    [userId] => XXXXXXXXX
                    [type] => user
                )

            [timestamp] => 1600355946638
            [mode] => active
            [message] => Array
                (
                    [type] => text
                    [id] => XXXXXXXXX
                    [text] => テスト
                )

        )

)
```

以上！

#一言
息抜きにLINEbotを作成中です。
もっといい簡易的なデバッグ方法があればコメントにお願いいたします🙇‍♀️
form_withについて

#そもそもform_withってなんですか？
情報を送信するためのヘルパーメソッドです！
Q.ヘルパーメソッドって何ですか？
A.railsにおける、主にビューでHTMLタグを出現させたりテキストを加工するために使用するメソッドの総称のことです。要は、railsでビューの加工をするメソッドといったもので覚えておくといいと思いました。（同じことを言ってますねこれ😄）

#form_withが何かわかりました！じゃあ、どのように使うのですか？
ビューファイルに記載していきます！
次のように記述します。

```ruby:index.html.erb
<%= form_with url: "パス",local:true do |form| %>
```

上記のような記述ではデータベースには保存されません。

```ruby:index.html.erb
<%= form_with(model: モデルクラスのインスタンス,local:true,) do |form| %>
```

で、保存するためのボタンを作成するには

```ruby:index.html.erb
 <%= form.submit %>
```

と記述をすることで、ボタンを表示させ保存等を行うことができます。（ルーティングからコントローラーの設定ができていればの話ですが！）

#まとめ
form_withは、要するに、ビューで使用するデータを受け渡すメソッドといった考えでいたらいいのかなと思っております。間違っていたら、ご指摘お願いします！
dumpされた改行入りのCSVファイルをtableにインポートした話

# 概要
またまた業務を進めるにあたって、MYSQLコマンドで程々にいい感じの手順をまとめておきたくなったので
メモがてら更新。

## mysqlコマンドでインポート

CSVファイルをそのまんまテーブルに突っ込みたくなったときのやつ。

```
LOAD DATA LOCAL INFILE TBL.txt INTO TABLE （テーブル名） FIELDS TERMINATED BY ',';
```

## mysqlでテーブル内の改行を再置換

これはたまに使う。文字列を一斉置換するやつ。

```
UPDATE （対象のテーブル名） SET （対象のカラム名）=REPLACE(（対象のカラム名）, "[[br]]", "\n") WHERE （WHERE句の条件）;
```

## 参考記事
* http://blog.chatlune.jp/2018/03/01/mysql-import-csv/
* https://qiita.com/katsukii/items/fcd161ffaadd157e63ed
Automation Anywhere A360でQRコードを生成してみる その2 ～ 文字化け対策

#はじめに
【前回の記事】
[Automation Anywhere A360でQRコードを生成してみる - Qiita](https://qiita.com/zamaezaaa/items/2deb31fb44f3fdd8ff54)

###現在のバージョンのQR Code Generatorは日本語未対応
前回はAutomation Anywhere Automation 360によるQRコード生成をご紹介しましたが、
実は現在のバージョンのQR Code Generatorアクションは、日本語などの文字コードに未対応となっています。
そのため、日本語を含む文字列をQRコード化し、読み込もうとすると以下の写真のように文字化けしてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/08bb5c84-f596-38a4-42f7-1e898a056158.png)

#解決方法
このQRコード生成パッケージ自体を日本語化してくれたら話が早いんですが、
今回はこのままでも何とかする方法を考えてみます。
色々方法はあると思いますが、今回は文字列をURLエンコードして、QRコード生成を生成し、
読み取り後に複合し、日本語を含む文字列に戻す方法を取ろうと思います。
（同パッケージの日本語対応依頼も出してはいますが、対応時期は不明です。）

#処理の流れ
- 日本語を含む文字列を生成
- JavaScriptで文字列をURLエンコードする
- URLエンコードした文字列を元にQRコードを生成する
- QRコードを読み取る
- 読み取った文字列をJavaScriptでデコード（復号）する
- 終了

#実際に組んでみる
ということで、実際にやってみましょう。
###JavaScript部分
```javascript:エンコードに使うJavaScriptコード
function getEncodedText(a){
  return encodeURI(a);
}
```

```javascript:デコードに使うJavaScriptコード
function getDecodedText(a){
  return decodeURI(a);
}
```

###大枠はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/2a8251e4-2ad0-b9a8-7676-c30b2617bee1.png)
###Stepの中を展開するとこんな感じになってます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/1b1d8485-ba7e-ff8d-454d-349881a9aaac.png)

###各アクションの設定値
※デコードする部分もほぼエンコード時と設定内容は一緒で、呼び出す関数名を変えるくらいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/bb29d4db-ab34-5617-8855-428d73d2a1b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/c2c29fb5-71cd-9c31-c54c-a08e7bf16e0e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/f2ecc2d8-1d90-647a-ae63-41ed4abd9222.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/348152ad-3ea4-c3d3-f309-33ae42a42fa5.png)

#結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/038de740-1e0a-559c-ad8a-624d5d0fca68.png)
上記をQRコード化し、それを読み取り、デコードした結果がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/0fa7aa8c-6f62-67fd-9987-2def3b379032.png)

#まとめ
ということで、日本語対応していないQRコード生成用アクションで日本語を扱ってしまうことが出来ました。
気を付けないといけないのは、QRコードで扱える最大文字数ですが、一般的な用途であれば大丈夫なんじゃないかと思っています。

#参考ページ、記事
[URLエンコードとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word13354.html)
[URLエンコードについておさらいしてみた - Qiita](https://qiita.com/sisisin/items/3efeb9420cf77a48135d)
ハブとスイッチの違い

#ハブとスイッチの違い

- ハブ：データ転送機能のみ

- スイッチ：データ転送機能 ＋ 各種管理機能やVLAN機能

※ もともとハブとスイッチは本来同じものを指す言葉であった。略さずに言えばどちらも**`「スイッチングハブ」`**となる。

しかし、昨今では`データ転送機能だけを持つ単機能のものをハブ`と呼び、それ以外の`各種管理機能(Web画面での設定、内部情報の読み出しなど)やVLAN機能などを持つものをスイッチ`と呼ぶことが多い。
Maxでunable to open wave input deviceエラーで起動できない時に最初に見るところ

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#症状
パッチャーの右下の電源ボタンを押しても数秒で落ちてしまう。
コンソールを見ると
**admme: unable to open wave input device** の出力がっ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0f623072-e90f-9b9f-03c7-0887eb1c9475.png)

#まずどこを見れば？
オプションのオーディオ・ステータスをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ab15fe6a-2176-8e37-c95d-5355ace6f666.png)
Input Deviceで指定されているデバイスが問題を抱えている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0bb05a2b-3b88-e1f8-a0e3-86f8407f4d76.png)
**あたいの場合は** そもそもInput自体が必要なかったのでNoneにすることで解決しましたです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/783a4e10-1e03-7016-8565-4c1e336a88a3.png)
環境やパッチャーの要件によって対処は様々になると思います。
ARKitにボタンやラベルを表示する

[このチュートリアル](https://www.youtube.com/watch?time_continue=11&v=2bGa4bhOHeY&feature=emb_logo)のようにやってもならない。
次のようにするとOK

+ 新しいプロジェクトを作成する
+ Reality KitAppを選択
+ ProductName を入力してください。 コンテンツテクノロジーにはRealityKit、ユーザーインターフェースにはStoryboardを選択します。
+ Main.storyboardを選択します。
+「+」を押して、ARVIewの上にUIVIewを追加します
+ もう一度「+」を押してRealityKit ARViewをドラッグします
+ 新しいARViewをView ControllerのarViewコンセントに接続します。

これで、ARビューを置き換えることなく、UI要素も追加できます。
GNOME-Boxesの仮想マシンイメージファイルの場所を変更する

# 環境
Ubuntu 20.04.1
GNOME 3.36.3

# デフォルトのイメージファイルの場所
以下にありました。

```sh
~/.local/share/gnome-boxes/images
```

# シンボリックリンクを作成
今回は以下の場所に変更します。

```sh
/media/masato/SD/gnome-boxes/images
```

シンボリックリンク作成
**すでに仮想マシンを作成している場合はリンク先のディレクトリに移動しておく**

```sh
cd ~/.local/share/gnome-boxes
sudo rmdir ./images
sudo ln -s /media/masato/SD/gnome-boxes/images images
```

**できた**

### インストール編はこちら
[GNOME-Boxesを使ってみる](https://qiita.com/MHANAYAMA/items/64be4fb75287c7e0c392)
備忘録　マックの初期設定

2020/9/17
WindowsからMacに変えたため、とりあえず行った初期設定を自分のメモとして残しておく
あくまで自分用の設定でこれからプログラミングの勉強と共に更新する予定のため、参考にはならないと思います。

①初期設定
このサイトを参考
https://matome.naver.jp/odai/2138629469334511401

②vscode　のダウンロード

③vscode　のプラグイン
Auto Rename Tag
Bracket Pair Colorizer
Code Spell Checker
CSS Peek
CSSTree validator
Debugger for Chrome
Easy Sass
HTMl CSS Support
HTML Preview
HTMlHint
htmltagwarap
indent-rainbow
intelliSence for Css class names in HTML
Japanese Language Pack for Visual Studio Code
Live Server
Path intellisense
Ruby
SFTP
VSCode Ruby
zenkaku

③vscode のショートカットキーの編集
設定→キーボードショートカット
→editor.emmet.action.balanceOut→⌘＋⇧＋A（好み）

④アプリクリーナーとショートカットのインストール
https://www.kashi-mo.com/media/63051/
Pythonによる画像処理100本ノック#2 グレースケール化

## はじめに
どうも、らむです。
画像処理ではお馴染みのグレースケール化を実装します。

## 2本目：グレースケール化
グレースケールは様々な画像処理の前処理として使われる事が多いです。画像処理を学ぶならば必ず知っておきましょう。
グレースケール化とは画像を黒色、白色、及びその中間色である灰色の濃淡を用いて画像を表現する手法です。
モノクロ画像は白黒2色のみであるのに対し、グレースケール画像では通常256色を用います。

なお、各画素は以下の式によって算出されます。
$$
P = 0.2126 R + 0.7152 G + 0.0722 B
$$

```grayscale.py
import cv2
import matplotlib.pyplot as plt
import numpy as np
plt.gray()

def grayscale(img):
  # グレースケール画像用配列作成
  dst = np.zeros((img.shape[0], img.shape[1]))

  # グレースケール化
  dst[:,:] = (0.2126*img[:,:,2] + 0.7152*img[:,:,1] + 0.0722*img[:,:,0]).astype(np.uint8)

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# グレースケール化
gray = grayscale(img)

# 画像保存
cv2.imwrite('result.jpg', gray)
# 画像表示
plt.imshow(gray)
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/503ea715-4889-241f-3c31-bc173a763746.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/7dede0f4-9fd9-583e-e289-abb7ab83bc12.jpeg">

画像左は入力画像、画像右は出力画像です。
しっかりグレースケール画像が作成できていますね。

## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_2.py)に公式の解答が載っているので是非そちらも確認してみてください。
新人エンジニアが見返すべきGitコマンド　【随時更新】

## いま自分がどこのブランチにいるか確認
```
$ git branch
```
## これでブランチを作成&移動までできる。
```
$ git checkout -b [ブランチ名]
```
## いま自分がいないブランチを削除することができる。
```
$ git branch -D [ブランチ名]
```
## これで他のリポジトリのデータを取得する。リモートのデータを取得したければ、通常は[origin]でいける。
```
$ git fetch [リポジトリ]
```
## だれかのブランチで作業したい・・・
```
$ git checkout [誰かが作業していたブランチ名]
```
## これで直前のコミットを削除することができる。間違ってmasterにpushしてしまったときに使える。
```
$ git reset --hard HEAD^
```
## PUSH。originはリモートリポジトリのこと。ブランチ名は作業しているブランチ名を入力すればいい。→このあとGIthubやGitlabでプルリクエストを作成する。
```
$ git push origin [ブランチ名]
```
## 変更したファイルをステージングさせる。という認識ではいるけど、奥が深そう。
```
$ git add -A
```
## コミットするときに簡単にメッセージを入力できるやつ。
```
$ git commit -m “[コミットメッセージを書く]"
```
## 作業ツリーのファイルすべてをステージする
```
$ git add .
```
## Git 管理対象のファイルの変更、削除をすべてステージする。（新規ファイルは無視。）
```
$ git add -u
$ git add --update
```
## および作業ツリーのファイルをすべてステージする。引数なしで、すべての作業ツリーのファイルを反映。
```
$ git add --all
$ git add -A 
```
## これで、bookmark.rbだけをステージングエリアに追加できる。
```
$ git add api/app/models/bookmark.rb
```

>git addに関しての参考記事
https://www-creators.com/archives/4939 

## 直前のコミットを取り消したいとき。 —hardとすることにより、変更した内容も取り消される。
この—hardの部分を —softにすると変更はそのままで、コミットだけ取り消される。

```
$ git reset --hard HEAD^
```
## ローカルに最新のリーモートのmasterを取り込む
```
$ git pull origin master
```

★常にmasterブランチを新しい状態で作業をすることが大事、、、

そのあとにcheckoutで作業ブランチに移動する。そして

```
$ git merge origin master
```

をすると最新のmasterブランチの変更を取り込むことができる。
するとコンフリクトが起こる→コマンド＋クリックでコンフリクトしているファイルを開ける。
どの変更を残すか、それとも両方の変更を適用するかを決めることができる。

``随時更新していきます。``
``間違っている点などあればご指摘お願いします。``
GNOME-Boxesを使ってみる

# 環境
Ubuntu 20.04.1
GNOME 3.36.3

# インストール
次のコマンドを実行してインストール。

```sh
sudo apt install gnome-boxes
```

**インストールされた！！**
![Screenshot from 2020-09-17 23-02-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567239/87d078d9-07af-d367-dcd9-8155c3744874.png)

# 互換性がない的なエラーが表示されて仮想マシンを作成できないときは
kvmのユーザーグループに実行しているユーザーを追加する。

```sh
sudo usermod -aG kvm 実行しているユーザー名
```

# おわり
あとは左上の『＋』ボタンから仮想マシンを追加します。
お手軽楽チンだしお気に入りツールになりました。
ただ情報がいまいち少ない気がするので展開。
機械学習 | 教師あり学習と教師なし学習の違い

機械学習 | 教師あり学習と教師なし学習の違い

# はじめに
こんにちは、uniです。

今回は、``教師あり学習``と``教師なし学習``の違いについて、簡単に説明していこうと思います。私自身、色々なサイトを見てきましたが、数式やら専門用語やらが多く、わかりやすいサイトがほとんどありませんでした。ですので、ここで詳しく説明していこうと思います。

# 目次
* 教師あり学習と教師なし学習とは
* この2つの違いとは？
* 強化学習と半教師あり学習について

## 教師あり学習と教師なし学習とは

まず、教師あり学習と教師なし学習とはなにかを詳しく見ていきましょう。

教師あり学習について。
> 教師あり学習（きょうしありがくしゅう, 英: Supervised learning）とは、機械学習の手法の一つである。事前に与えられたデータをいわば「例題（＝先生からの助言）」とみなして、それをガイドに学習（＝データへの何らかのフィッティング）を行うところからこの名がある。
ーhttps://ja.wikipedia.org/wiki/%E6%95%99%E5%B8%AB%E3%81%82%E3%82%8A%E5%AD%A6%E7%BF%92

教師なし学習について。

> 教師なし学習（きょうしなしがくしゅう, 英: Unsupervised Learning）とは、機械学習の手法の一つである。「出力すべきもの」があらかじめ決まっていないという点で教師あり学習とは大きく異なる。データの背後に存在する本質的な構造を抽出するために用いられる。
ーhttps://ja.wikipedia.org/wiki/%E6%95%99%E5%B8%AB%E3%81%AA%E3%81%97%E5%AD%A6%E7%BF%92

といわれても、という感じですよね。笑

簡単に説明すると、
教師あり学習と教師なし学習の違いは、__目的が明確か__ということです。

## この2つの違いとは？
``教師あり学習``の例を見てみましょう。

* 事前に犬と猫の画像を与えて、渡した画像がどちらの動物か判定する
* 過去の気象データを与えて、明日の天気予報を予測する
* 不動産データに基づいて、家の販売価格を予測する

このように``教師あり学習``は、なにかしてほしいことがあって、つまり目的が明確な上で行われています。

続いて、``教師なし学習``を見てみましょう。

* 様々な画像を渡して、それぞれを特徴ごとに振り分ける
* 沢山のメールから、スパムメールや通常のメールなどグループ分けする
* 多くの顧客の購入データから、商品の買い合わせの傾向を調べる

このように``教師なし学習``は、答えを与えないまま、機械にものごとを判断させています。

以上をまとめると、``教師あり学習``は、部下が部長に命令されてもくもくとタスクをこなすこと、``教師なし学習``は、部下が多くのデータから自分で判断したり、新しいアイデアを生み出したりすること、という感じです。

## 強化学習と半教師あり学習について
上記以外にも、``強化学習``と``半教師あり学習``というものがあります。

``強化学習``とは、価値を最大化するような学習法です。つまり、もっとも利益が出るところはどこかを考えて行動します。強化学習は、囲碁や将棋のような最終的な勝ち負けで決まってしまうようなものに使われています。

``半教師あり学習``とは、簡単に言うと、完全に答えを教えずにアドバイスだけをして学習を進めさせるものです。命令形の教師あり学習と自発形の教師なし学習のちょうど中間に位置しているため、半教師あり学習と呼ばれています。私たち人間を機械とすると、__クロスワードパズルを解かされているようなもの__です。

# まとめ
いかがだったでしょうか。教師あり学習と教師なし学習、それぞれの違いが伝わっていると幸いです。
常に、自分が投稿したものをログインしている自分だけに表示したい

【概要】
----------------------------------------
<b>1.結論</b>

<b>2.whereメソッドとは何か</b>

<b>3.どのように使うか</b>

<b>4.ここから学んだこと</b>



1.結論
----------------------------------------
<b>whereメソッド</b>をつかう！
<br>

2.whereメソッドとは何か
----------------------------------------
欲しい条件を探すメソッドです！

```ruby
モデル.where(条件名: 条件の内容)
```
で使用できます！

ブログや、ニュース記事での検索ワード欄にて特定の文字を探すプログラムを記載する時に頻繁に使います！

<br>
3.どのように使うか
----------------------------------------
自分は下記のように使用しました！

```ruby:time_controller.rb
@times = Time.where(user_id: current_user.id).includes(:user).order("created_at DESC")
```
現在ログインしているユーザーが投稿した物を、投稿した人＝ログインしているユーザー(current_user.id)のみに表示させたかったのでwhereメソッドを使用しました！
includes(:user)はN+1問題解決（プログラムの無駄な処理を軽減）し、order("created_at DESC")は新規投稿順にしています！

参考にしたURL:
<a href="https://teratail.com/questions/229386">[Rails]ログインユーザーidを使って、異なるテーブルに存在する値を出力したい[ActiveRecord]</a>
<br>
5.ここから学んだこと（エラーの時に使用）
----------------------------------------
if条件式で場合分けしようとしましたが、いくら条件式作っても表示自体を制限しないと、条件式下で全部表示されてしまいます。whereメソッドは検索ワード欄を作りたいと意識するあまりに、本質は”表示を制限する”ことが抜けていました。具体的な事象➡︎抽象的な事象に変換するともっとメソッドに対しての活用視野が広がると確信しました。
<br>
勉強日誌12日目

今日は割と早く上がれたけど職場の方と少し雑談をしてたら結局遅くなってしまった
明日は残業結構するスケジュールだから今日気分転換できて良かった！

正答率　71％　（前回　58％）

/etc/chrony.conf
Chronyの設定ファイル

date 月日時分年.秒
システムクロックの設定

peer
時刻を取得するNTPサーバを指定するもの

timedatectl
現在のシステム時刻や時刻同期の状態を表示

ntpdate pool.ntp.org
タイムサーバ　pool.ntp.org　から現在時刻を取得

tracking
chronycコマンドのサブコマンドで、時刻同期の詳細を表示

activity
chronycコマンドのサブコマンドで、オンライン/オフラインを表示

sources
chronycコマンドのサブコマンドで時刻のソースを表示

pool
複数のNTPサーバを集約

正答率　55%（前回　59%）


-b
--boot
特定の起動時のログに限定して表示させるオプション

logger Test
Test　というメッセージをジャーナルファイルに書き込む

system.journal
systemd-journaldのバイナリ形式のジャーナルファイル名

-l
--full
画面表示可能なログを全て表示

-u
--unit
特定のユニットのログに対して表示させるオプション

-n
--lines 10
ログ出力を10行だけ表示させる

＿SYSTEMD_UNIT=eeee
eeeeeからのログを指定

-a
--all
画面表示できない文字も含めて全て表示

-r
--reverse
最新のログから出力させるオプション

rsyslog
syslog-ng
次世代のsyslogの名前

/etc/systemd/journald.conf
systemd-journaldデーモンの設定ファイル

systemd-cat
指定したコマンドの実行結果をsystemd-journaldのジャーナルファイルに書き込む

-f
--follow
journalctlコマンドのオプションのうち出力をリアルタイムに表示させる

--since
--until
特定の期間のログに限定して表示させる

*.notice @hoge 
、全てのファシリティのプライオリティがnotice以上のログを、
  リモートホストhogeに送信したい

正答率　72％　（前回　72%）

631
cupsデーモン　が待ち受けるデフォルトのポート番号

lprm -PPrinterB -
PrinterBの印刷ジョブを全て削除

/etc/cups/printers.conf
CUPSの印刷システムで、プリンタの設定ファイル

/etc/cups
印刷サービスCUPSの設定ファイルが置かれるディレクトリ

/var/spool/mqueue
sendmailの送信待ちのメールを保存するディレクトリ

/etc/aliases
sendmailで、メールを転送するための別名を設定するファイル

lprm
レガシーな印刷コマンドでプリントキューにある印刷ジョブを削除するコマンド
【オブジェクト指向豆知識(2)】「オブジェクト指向の3要素」の原典

オブジェクト指向の3要素として、カプセル化・継承・ポリモーフィズムがよく言われます。
ただ、原典がよくわからないことが気になります。「オブジェクト指向の3要素」の原典について調べてみました。

## 結論

[B.ヘンダーソン-セラーズ「オブジェクト指向ソフトウェア工学(1991)」(邦訳は1994)](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E5%B7%A5%E5%AD%A6%E2%80%95%E5%88%86%E6%9E%90%E3%83%BB%E8%A8%AD%E8%A8%88%E3%83%BB%E5%AE%9F%E7%8F%BE-B-%E3%83%98%E3%83%B3%E3%83%80%E3%83%BC%E3%82%BD%E3%83%B3%E3%83%BB%E3%82%BB%E3%83%A9%E3%83%BC%E3%82%BA/dp/4303726001/ref=sr_1_1?dchild=1&qid=1600348848&refinements=p_27%3AB.+%E3%83%98%E3%83%B3%E3%83%80%E3%83%BC%E3%82%BD%E3%83%B3%E3%83%BB%E3%82%BB%E3%83%A9%E3%83%BC%E3%82%BA&s=books&sr=1-1)が原典ではないかと思われます。

同書P19には、
>オブジェクト指向に対して共通の認識はなく、それぞれの研究者が異なる面を強調していることを図8は示すが、この図から概念をグループに分けることができる。

とあり、実際にこの図8では12人の研究者による11種類のオブジェクト指向の「必須要素」が並んでいます（1人で6要素を挙げる研究者もいます）。これが書かれた時点ではオブジェクト指向の必須要素について共通認識がないことは事実のようです。この11要素を著者はグループ化し、以下のように要約しています（同書P19）。

> (1) 情報隠蔽とカプセル化の概念
> (2) クラス化による抽象化
> (3) 継承を通して実現される多態

これは、現在言われている3要素と以下のように対応させることができます。

|現在の3要素|同書による3要素|
|:--|:--|
|カプセル化 | (1) 情報隠蔽とカプセル化の概念
|継承 | (2) クラス化による抽象化
|ポリモーフィズム | (3) 継承を通して実現される多態


## 参考文献

- [バードラント・メイヤー, オブジェクト指向入門　第2版 原則・コンセプト](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E5%8E%9F%E5%89%87%E3%83%BB%E3%82%B3%E3%83%B3%E3%82%BB%E3%83%97%E3%83%88-Architect%E2%80%99Archive-%E3%82%AF%E3%83%A9%E3%82%B7%E3%83%83%E3%82%AF%E3%83%A2%E3%83%80%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0/dp/4798111112)
- [B.ヘンダーソン-セラーズ, オブジェクト指向ソフトウェア工学](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E5%B7%A5%E5%AD%A6%E2%80%95%E5%88%86%E6%9E%90%E3%83%BB%E8%A8%AD%E8%A8%88%E3%83%BB%E5%AE%9F%E7%8F%BE-B-%E3%83%98%E3%83%B3%E3%83%80%E3%83%BC%E3%82%BD%E3%83%B3%E3%83%BB%E3%82%BB%E3%83%A9%E3%83%BC%E3%82%BA/dp/4303726001)
【MonoDepth】mono cameraによるdepth estimation基礎理解(Deep Learning編)

うまく説明出来てないかもしれませんが、ざっくりとニュアンスを組み取って頂けたら嬉しいです。
stereo depthについてもまとめたので、気になる方はどうぞ
https://qiita.com/minh33/items/55717aa1ace9d7f7e7dd
https://qiita.com/minh33/items/6b8d37ce08f85d3a3479

<h1>目次</h1>
1. Depth Estimation
2. Image warp
3. Loss

<h2>Depth Estimation</h2>
人が片目で物体の大まかな位置が分かるように単眼のカメラでも位置を推定することが出来ます。例えば、カメラの角度を固定しておけば、近い物は画像のしたの方に位置していて、遠いものは画像の上の方に位置しています。基本的に物体は地面の上にあるので、接地面の距離がわかれば物体の位置も推定出来ます。他には物体間の相対位置や物体の大きさなども情報として使えます。CNNを用いて学習しているので、実際どんな情報を得てモデルが推定してるかはわかりにくいのですが、実験をしたという面白い論文があったので興味のある人は是非


<h2>Image warp</h2>


[<h3>単眼の場合</h3>](
https://arxiv.org/pdf/1910.01765.pdf7)
カメラを載せた車が動く事によって、一つ前のフレームに変換することが出来ます。まずt=tの時の画像の距離をネットワークで推定します。距離を推定出来たので3次元のポイントクラウドを計算する事が出来ます。カメラを載せた車の移動量を自己位置推定を使い求めます。自己位置推定はVSLAM、オドメトリー、GPS、IMUなどが使えます。x,y,z,roll,pitch,yawの1フレームの変化量を先程計算した3次元ポイントクラウドをTransfomationする事によって、t=t-1の3次元ポイントクラウドを推測する事が出来ました。それをImage Viewに変換する事で、t=tの画像をt=t-1の画像にwarpさせる事が出来ます。ただし自分が動いていいないと学習出来ないのと、相手の物体が動いているとwarpしてもずれてしまうというデメリットもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/e734f4cc-cfa3-6e3c-a9bb-9d4056795d48.png)
It=>target Image(t=t)
Is=>source Image(t=t-1)
Dt=>target Depth(LiDARを用いた距離のGround Truth)
D^t=>Estimated target Depth
I^t=>Estimated target Image
View Synthesis=>画像のReconstruction
Photometric Loss=>推定画像と実際の画像の比較

[<h3>双眼の場合</h3>](
https://arxiv.org/pdf/1609.03677.pdf')

3番でLossを計算する為に使われるのですが、求めたDepthをDisparityに変換し、右の画像を左の画像にワープさせることが出来ます。ちなみにmono depthなのに双眼なのって？って思う人もいると思うんですが、距離推定は単眼で行い、学習のGround Truthとして反対のレンズを使います。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/5d5e68b9-e60a-d862-601d-11a3137e1bfa.png)

<h2>Lossの定義</h2>
[<h3>Unsupervised Monocular Depth Estimation with Left-Right Consistency(2017)</h3>](
https://arxiv.org/pdf/1609.03677.pdf')

monodepthで多分この論文が一番有名

・ Reconstruction Loss
右の画像を推定した左のDisparityを用いてwarpする事によって左のReconstruction画像が出来る。その画像と左の入力画像のSADとSSIMを計算する。逆も行う

・LR Consistency Loss
右のDisparity Mapを左のDisparity MapへとwarpさせてDisparityの絶対値の差を計算する。逆も行う

・Smoothness Loss
近傍のPixelのDisparity(Depth)は同一物体であればほぼ同じであるはずなので、Laplacian Smoothnessなどを用いてDisparityのSmoothnessを計算する。右と左のDisparityMapそれぞれで行う。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/837a9e8e-2d75-12db-a480-0005f8127aaf.png)
matplotlib.pyplot で積分区間をに色をつける

先日グラフの積分によって求められる面積に色をつけたいと考えた時に使用した関数が便利だったのでメモします。

#matplotlib.pyplot.fill_between#

```
matplotlib.pyplot.fill_between(x, y1, y2=0, where=None, interpolate=False, step=None, \*, data=None, **kwargs)
```

今回私が使った関数はこれです。
今回私はグラフの下を塗りつぶしたかっただけなので使用するのは

```
matplotlib.pyplot.fill_between(x, y1, color='color',alpha=(float))
```

のみのパラメータです。
基本的なplotと同じように最初の2つはx軸とy軸のデータを入れます
そして**kwargsで指定できる他のパラメータからcolor='色'と、alpha='透過度'で指定しています。

#実装#
実装して見ました

```ex_fill_between.py
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-10,10,100)
y = -0.1*(x**2)+10

plt.plot(x,y,'blue')
plt.fill_between(x,y,color='blue',alpha=0.1)
plt.show()


```

結果
![スクリーンショット 2020-09-17 22.15.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707273/b0a97860-fd08-d6ff-6e90-109e670c7e6f.png)

こんな感じです。
もし二つの曲線に挟まれたエリアを塗りつぶしたいならy2の値を入れればいいので

```ex_fill_between2.py
import numpy as np
import matplotlib.pyplot as plt
           
x = np.linspace(-10,10,100)
y = -0.1*(x**2)+10
y2 = 0.05*(x**2)+1
plt.plot(x,y,'blue')
plt.plot(x,y2,'red')
plt.fill_between(x,y,y2,where = y>y2,color='blue',alpha=0.1)
plt.show()
~              
```
結果
![スクリーンショット 2020-09-17 22.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707273/5e02f767-d049-fbed-564a-a43e348d4f36.png)

となります。ここでwhereを使っていますが、これは適応する場所を選択するようでboolで指定するようです。
これによって赤線と青線で囲まれた場所（青線＞赤線）のみ場所だけに適応しています。

余談ーーー
これとは別に図形を塗りたいならfill関数を使うのがいいみたいです。

```ex_fill.py
import matplotlib.pyplot as plt
  
x = [-1,0,1,0]
y = [0,-1,0,1]

plt.fill(x,y,color='blue',alpha=0.1)
plt.show()
```
結果
![スクリーンショット 2020-09-17 22.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707273/8d52f9ae-0412-7ecb-1c48-8484ffde6c47.png)

ーーーーー
#終わりに#
もしかしたらこの程度は常識かもしれませんが個人的に便利だと思いました。
小さなことをコツコツアウトプットすることも大事かと思うのでこういうものも書いていこうかと思います。

##[参考]##
http://cranethree.hatenablog.com/entry/2015/07/25/204608 matplotlibで領域の図示
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.fill_between.html matplotlib公式
https://sabopy.com/py/matplotlib-28/ [matplotlibの使い方] 28. 折れ線グラフの下を塗りつぶしたグラフ
ループ中にリストの要素を削除する場合の注意点


リストをループで回している中で、そのリストの要素を削除する場合は、ループを**逆順**で回しましょう。

```C#:NG
        for (int i = 0; i < enemyList.Count; i++) {
            if (!enemyList[i].IsAlive) {
                enemyList.RemoveAt(i);
            }
        }
```

```C#:OK
        for (int i = enemyList.Count - 1; i >= 0; i--) {
            if (!enemyList[i].IsAlive) {
                enemyList.RemoveAt(i);
            }
        }
```

なぜ逆順にしなければならないのか？を示したものが以下の図になります。NG側では、要素`C`を削除した際に後ろにある要素が一つ前に詰められる影響で、要素`D`が正しく処理されない問題が発生しています。

![figure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495108/ddfd2855-1f40-185a-6d95-80fca50e94f3.png)


ちなみに、リストの要素を削除したいけど**ループ中に処理する必要はない**時には`RemoveAll`が便利です。

```C#:
        enemyList.RemoveAll(enemy => !enemy.IsAlive);
```

#参考リンク
- [リスト（List）の列挙中にリスト要素を削除するには？](https://www.atmarkit.co.jp/ait/articles/0812/04/news140.html)
【初心者でもわかる】字下げ、字上げのインデント。リストを表示した時に、・の下に文字をもぐりこませないようにする方法

# どうも7noteです。CSSで字上げ・字下げする方法。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/indent/
Rails spec アソシエーション 

本日は、アプリケーション作成のモデル単体テストコード実装中のアソシエーション記述忘れを書きます。

ユーザが商品出品画面にログイン
⬇️
商品の詳細を記入　←今回はここから保存までの実装
⬇️
商品出品をクリクでDBへデータが保存される

テストコードを記述し実行・・・目的のエラーが出ません。
全て『ユーザを入力したらいいよ』というエラーメッセージでした。

そこでモデル同士のアソシエーションに不備があると思い見返しますが、間違いがありません。
次にbinding.pryを使ってcreateでのデータ内容を確認してしました。

![binding.pry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683447/65bb4b1a-c006-9d10-bfe7-bb23c3eb4944.png)

そこでも、不足しているデータは無いようでした。

もう一度、アソシエーションを確認したところ

![テストコードアソシエーション無し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683447/c7465344-a567-0dc5-e6bc-16d19df154c7.png)

この記述に不備を見つけました。
そうです、FactoryBot内のuserとのアソシエーション 記述漏れでした。

![テストコードアソシエーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683447/3b3c87a7-3c3d-e8fe-607a-dafce5ba9a3b.png)

userとのアソシエーションを記述し無事にテストで求めていた事が出来ました。

初学者のため、間違った解釈をしているかもしれませんので、何かあれば教えてください。
自分用の開発ツールまとめ

## はじめに

忘れっぽい私用に使いたい、もしくは使っているツールをまとめていく。

順次追加していく予定です。

### json2ts
http://json2ts.com/

jsonを貼ると、typescriptのinterfaceを返してくれる。

### codic

https://codic.jp/

英語が苦手な私用。日本語を英訳してくれる。

### Commitizen

https://github.com/commitizen/cz-cli

cli形式でConventional Commits準拠のコミットメッセージを生成してくれるツール
Rails 簡単な簡単ログイン機能の追加

#欲しい結果
"簡単ログイン"のボタンを押すと、
登録済みのゲストユーザーでログインするボタンの設置。

#前提条件
RailsチュートリアルをベースにしたWEBアプリ。

#やること
1. sessions_controllerのcreateアクションとは別にeasy_loginアクションを作成して登録済みのゲストユーザーの
 emailを渡す。
2. routs.rbにeasy_loginのルーティングを記載。
3. viewで`簡単ログイン`ボタンを設置する。


1. `sessions_controller.rb`に作成して登録済み（seeds.rb）の
ゲストユーザーでログインできる様にeasy_loginアクションを追記する。

```sessions_controller.rb
    def easy_login
      user = User.find_by(email: "test@example.com")
          log_in user　#session_helperで事前に定義ずみ。
          redirect_back_or user #session_helperで事前に定義ずみ。
    end  
```

2. `config/routes.rb`で以下を追記　　

```config/routes.rb
  post   '/easy_login',   to: 'sessions#easy_login'
```

3. `app/views/sessions/new.html.erb`の任意の場所に以下を追記

```app/views/sessions/new.html.erb
<p><%= link_to "簡単ログイン", easy_login_path, method: :post, class: 'btn btn-primary' %></p>

```

#結果
とりあえずは簡単ログインボタンから、ゲストユーザーでのログインができた。
STSをセットアップしたときにハマった話

## 概要
タイトルの通り、STSのセットアップについて備忘録を書いておきます。
また自分がハマらないために。

## STSとは
STSとはeclipseベースのIDEで、
Springの各プロダクトを使いやすくするために
カスタマイズされています。

ちなみに
STS = **S**pring **T**ool **S**uite
「Springトッピング全部乗せ」みたいな
ニュアンスです。

## セットアップしてみる
まず[STSをダウンロード](https://spring.io/tools/sts)します。
zipの方をダウンロードします。

ダウンロードしたらzipを展開します。
c:\stsに展開してみました。
20分ほどかかりました。

![展開したzip](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/23a8b89f-2bf4-c221-fb90-320c8bd3654e.png)

C:\sts\sts-bundle\sts-(バージョン番号).RELEASEに移動、
sts.exeを起動します。
![sts.exe](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/40689857-4569-0ab7-c506-49c81eb9103c.png)

## ハマった箇所
起動しようとして
 **Error: Failed to load the JNI shared library** 
で起動しない。
このエラーメッセージはアプリケーションとOSのbitが
合っていないときに発生します。
例えばWindowsとJavaが64bit、でもSTSが32bit。
この記事を書いたとき、STSのトップページに32bitのzipが置いてあります。
私には罠でした。

## 無事解決
というわけでSTSを起動しました。
![起動しました](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533981/4209db91-6569-dd5b-3063-a11e72b753fc.png)

## 補足(2020/09/22補足)
[STSをダウンロードする画面](https://spring.io/tools)で64bit版のダウンロードだけが表示されていました。
Linux,Max OS,Windowsとそれぞれにリンクも分かれていたため、
罠になることも無いはず。
Pythonによる画像処理100本ノック#1 チャネル入れ替え

## はじめに
どうも、らむです。
突然ですが私は画像処理系の研究室に所属しています。私の研究室では来月から後輩にゼミで画像処理手法について教えていかなければなりません。

正直最近勉強不足で基本的な画像処理の実装や説明ができない気がします。そこでimori_imoriさんの[画像処理100本ノック](https://qiita.com/yoyoyo_/items/2ef53f47f87dcf5d1e14)をやってみることにしました。

ここでは1本ずつ画像処理を実装し軽く解説していこうと思います。なお、pythonは最近始めたばかりなのでコーディング力はお察しください。

## 1本目：チャネル入れ替え
記念すべき1本目の画像処理はチャンネル入れ替えです。
カラー画像には赤・青・緑の3色成分、つまり3チャネルの成分が存在します。
openCVを用いて読み込むと青・緑・赤の順番になりますが、今回はこれを赤・緑・青の順番に入れ替えます。

```reverseChannel.py
import cv2
import matplotlib.pyplot as plt


def reverseChannel(img):
  # 画像コピー
  dst = img.copy()
  # チャネル入れ替え
  dst[:, :, 0] = img[:, :, 2]
  dst[:, :, 2] = img[:, :, 0]

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# チャネル入れ替え
img = reverseChannel(img)

# 画像保存
cv2.imwrite("result.jpg", img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/503ea715-4889-241f-3c31-bc173a763746.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/8e6ef2cd-2c7c-d63d-a624-4f6ebeb8ded6.jpeg">

画像左は入力画像、画像右は出力画像です。
赤成分と青成分が入れ替わったことによって刺し身の赤色が青色に変わっています。

## おわりに
このような感じでアウトプットしていこうと思います。もし、質問がある方がいらっしゃれば気軽にどうぞ。
ちなみに、画像処理100本ノック公式サイトのGithubに公式の解答が載っているので是非そちらも確認してみてください。
TypeScriptを導入しているプロジェクトでBlockly.JavaScriptを使う

普通にアンビエント宣言を使えば行けます。以下を記述したファイルをプロジェクト内に置くだけです。

```typescript
import { Generator } from 'blockly';

declare module 'blockly' {
  export const JavaScript: Generator;
}
```

`Blockly.JavaScript`は`Blockly.Generator`クラスのインスタンスのようです。
CodePipelineで誰でもお手軽自動デプロイ（静的webページ編）

## 今回作るやつ概要
GitHub × CodePipelineで自動デプロイ :rocket:

### ◯おすすめな人
■ フロント系の方、weｂ制作系の方
■ SPA公開したい方
■ CI/CDで挫折した方
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/751b024e-6e77-528a-05d4-7e9b69f9525d.png" width="600">

### 準備しておくもの
#####■ GitHubアカウント
#####■ AWSアカウント
#####■ 静的webホスティングの設定をしたS3バケット
下記が個人的にわかりやすかったです！
・[【参考】AWS S3で静的Webページをホスティングする]
(https://qiita.com/dogwood008/items/a92abae789f4b0466f38)
・[【参考】独自ドメインを使ってAmazon S3で静的Webサイトをホストする](https://qiita.com/Ichiro_Tsuji/items/c174d580587a622d3358)


## CodePipeline構築

####CodePipelineを開き`パイプラインの作成`を選択。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/d566c81e-bc7a-a703-e23a-cc9c11cca1ac.png" width="800">
####【Step1】パイプライン設定を選択する
■パイプライン名
▫️わかりやすいものならなんでもOK
■サービスロール
▫️新しいサービスロール
■ロール名
▫️自動で入る

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/883fcb0e-932e-ae3b-2844-69fd16495a94.png" width="800">

####【Step2】ソースステージを追加する
■ソースプロバイダー
▫️GitHub
■検出オプションを変更する
▫️GitHubウェブフック（推奨）

**■`GitHubに接続する`を選択**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/0b8cc182-36c0-3427-287d-7711f0d6564f.png" width="800">
■GitHubへSign inします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/98793677-940d-7bc6-067f-f4dee96be154.png" width="800">

■接続完了！！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/3f7c4a82-befe-483d-5772-0bb15600a5fe.png" width="800">

■リポジトリ
▫️自動デプロイの対象としたいリポジトリを選択

■ブランチ
▫️対象のブランチを選択（masterでpushしたら発火的な）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/dbfb864b-dad2-ebd4-4479-27c0389b37ec.png" width="800">

####【Step３】ビルドステージを追加する
今回は使用しないので`ビルドステージをスキップ`を選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/638c1777-858e-2b7a-e854-99d57f04162a.png" width="800">


####【Step4】デプロイステージを追加する
■デプロイプロバイダー
▫️Amazon S3
■リージョン&バケット
▫️静的webホスティングの設定をしたS3バケット
■デプロイする前にファイルを抽出する
▫️チェック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/a7d1c3ed-756c-1e2e-4385-2422a30628bc.png" width="800">

####【Step5】レビュー
■設定内容の確認をして下さい！

####完成！！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/85c0dfdb-0cf8-41ab-3ab6-967d27e89c20.png" width="800">

デプロイステージに設定したバケットを見てみると、ちゃんと反映されてる！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/2478361f-1a18-68f2-2d26-da4ee0825745.png" width="800">

もちろん対象のブランチでpushしたら変更が反映されます！

####感想
静的webということもありましたが意外と簡単に実装できたと思います！
今回は説明しませんでしたがCloudFrontを前段に置くことで独自ドメインを使用することも出来ます！
プログラマーの市場価値

#転職しました
この年(ギリでアラフォーの40代)になって、転職をすることになりました。
11月から新しい職場になります。

色々思うところがあって決断したわけですが、一番大きいのは、
__「今の職場にいても自分のスキルアップにつながらない」__と感じたためです。

#年齢と市場価値
年齢が上がると転職が難しくなる、というイメージを持っている方が多いと思います。
それは、__スキルが向上していない場合__、年齢とともに市場価値が下がっていく、
というのが原因だと思います。
大体、以下のイメージです。
(あくまで僕のイメージです)
![年齢-市場価値.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/724841/faa41c8f-7458-ccb4-efce-94587bbc6330.png)

20台のうちは、ポテンシャル的な意味で、スキルが無くても価値を保てていますが、
30代からはスキルが伴わないと価値が下がっていきます。
この価値低下を超える分のスキルアップをしていければ、市場価値を高めていけるはずです。

#自分の市場価値
今回、自社製品、自社サービスの開発を行っている会社を希望していましたが、
以下の点を評価していただき、転職することが出来ました。

* 開発経験と技術力
* チームメンバーの育成に注力していたこと
* コミュニケーション力

スキルアップを意識していたおかげで、
ある程度は市場価値を維持できていた、ということかと思います。

#転職のリスクとスキルアップできないリスク
正直、この年で転職するのはリスクが高いです。
ただ、転職前の職場で、スキルアップできないことによる市場価値低下の方が
リスクが高いと判断し、転職に踏み切りました。

もちろん、この転職が成功かどうかはまだ分かりませんが、
この年でも希望する会社に転職できるという事実が、
同じように今の職場で悩んでいる方の救いになればと思います。
Nuxt.jsをGAEにデプロイして、serverMiddlewareが動かなかった話

## はじめに

Nuxt.jsのserverMiddlewareを使ってBFFを作成し、Google App Engineにデプロイした時に、フロント側は動いているのですが、serverMiddlewareが動かなかった出来事の備忘録です。

## nuxtのインストールからデプロイまでのプロセス

### nuxtのインストール

```
$ yarn create nuxt-app <project-name> // ここでtypescriptを選択しています
```

### /server/index.jsの作成

``` /server/index.js
import express from 'express';

const app = express();

app.get('/api', (_: express.Request, res: express.Response) => {
  res.send('hello world!');
});

module.exports = app;
```

### app.yamlの作成

``` app.yaml
runtime: nodejs10

instance_class: F1

handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client
    secure: always

  - url: /(.*\.(gif|png|jpg|ico|txt))$
    static_files: static/\1
    upload: static/.*\.(gif|png|jpg|ico|txt)$
    secure: always

  - url: /.*
    script: auto
    secure: always

env_variables:
  HOST: '0.0.0.0'
```

### serverMiddlewareの追加
``` nuxt.config.js

export default {
  [...],
  serverMiddleware: [
    '~/server'
  ],
  [...]
}
```

### .gcloudignoreの追加
```.gcloudignore
*
!.nuxt/**
!static/**
!package.json
!yarn.lock
!tsconfig.json
```

### build&deploy
```
$ yarn build
$ gcloud app deploy app.yaml --project [project-id]
```

## デプロイ結果

フロント側は普通に表示されるのに、serverMiddleware側は `404`に。。。

## 動かなかった原因

動かなかった原因は `.gcloudignore`ファイルの記述が間違っていました所にありました。

```serverMiddlewareが動かなかった.gcloudignore
*
!.nuxt/**
!static/**
!package.json
!yarn.lock
!tsconfig.json
```

```serverMiddlewareも動いた.gcloudignore
.gcloudignore
.git
.gitignore
node_modules/
```

`.gcloudignore`をwhitelist形式で書きたかったのですが、デプロイすべきものまでignoreしてしまっていたそうです。。。

今回は一旦、ほぼ全てデプロイする形で対応しましたが、いつか必要なものだけデプロイできるようにして行きたいです。
Docker run コマンドを分解すると。。。

# Docker runコマンドを分解すると
```
docker run　#イメージを取得して、イメージからコンテナを起動するコマンド
```
以下の三つのコマンドの処理が順に実行することと同じ処理になる。

```
docker pull #イメージの取得
```

```
docker create #コンテナの作成
```

```
docker start #コンテナの起動
```

Docker run コマンドは便利！