OmniAICreator/Qiita-1.07M huggingface dataset:
Heroku+Flask+PostgreSQL(Heroku Postgres)でガラル地方のポケモンのタイプや強さを教えてくれるLINE bot作った


# はじめに

タイトル通りですが、ガラル地方（ソード・シールド）に登場するポケモンの情報を教えてくれる LINE bot 作ったので簡単にまとめたいと思います。以下、画面イメージです。

<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323251/88dc798b-635d-036d-eebc-4fd0f12c317a.png">

![system.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323251/00e61b5c-9d33-1207-d836-671f1971191c.png)

# ローカル環境

pipenv を使って以下の Pipfile から必要なライブラリをインストール。なぜか`psycopg2`が正常にインストールできないため、`psycopg2-binary`を入れています。（この辺りの原因分かっていません。）

```Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
flask = "==1.1.2"
line-bot-sdk = "==1.16.0"
sqlalchemy = "==1.3.17"
psycopg2-binary = "==2.8.5"

[requires]
python_version = "3.8"
```

# LINE API 側の設定

- （大体の人は持ってると思いますが）前提として LINE アカウントが必要になります。アカウントを既に持ってる方は[[LINE Developers]](https://developers.line.biz/ja/)からAPI利用の登録をしてください。
- 登録後に新規チャネルを作成します。
- チャンネルを追加したら、[チャネル基本設定]->[LINE Official Account Manager]->[応答設定タブ]から、`応答メッセージ OFF`（ON でも良いけど一々デフォルトのメッセージが挟まれるとちょっと微妙）、`Webhook ON`と設定します。
- チャネル基本設定にある`チャネルシークレット`、及び Messaging API 設定にある`チャネルアクセストークン`を確認します。これは後々、Heroku 側で環境変数の設定をする際に必要となります。

（こちらは Heroku での作業後に必要）

- Messaging API 設定から`Webhook設定`にいき、`Webhook URL`に、https://{アプリ名}.herokuapp.com/callback を入力。

# Heroku 側の設定

- [[Heroku]](https://id.heroku.com/login)に登録してください。
- 必要なコマンドを brew でインストールします。
- 下記コマンドにてログイン。
- 下記コマンドにて環境変数を設定。

```bash
$ brew install heroku
$ brew install postgresql
$ heroku login
$ heroku config:set LINE_CHANNEL_ACCESS_TOKEN="***********" --app {アプリ名}
$ heroku config:set LINE_CHANNEL_SECRET="***********" --app {アプリ名}
```

# PostgreSQL の用意

- heroku にログインした状況で空の DB を作成します。
- ターミナルから DB に接続します。
- DB のタイムゾーンを変更
- 良い感じの CSV データを Kaggle からダウンロードしてきます。
  - Kaggle ですが、結構ポケモンのデータが充実してます。（さすが世界的コンテンツ）
- table を作成します。（下記 SQL 文は一例です。）
- CSV データを DB にコピーします。下記の`with csv header`は CSV のヘッダーを無視して取り込むためです。必要に応じて変えていってください。

```bash
$ heroku addons:create heroku-postgresql:hobby-dev -a {アプリ名}
$ heroku pg:psql -a {アプリ名}

# 接続開始、テーブルcreate
app-name::DATABASE=> alter database {データベース名} set timezone = 'Asia/Tokyo';
app-name::DATABASE=> create table pokemon_status(
app-name::DATABASE=> id integer not null,
...
...
app-name::DATABASE=> type2 text,
app-name::DATABASE=> primary key (id));

# ローカルのCSVをDBへコピー
\copy pokemon_status from '{ファイル名}' with csv header;
```

こんな感じで登録されてるかと思います。
![スクリーンショット 2020-06-13 12.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323251/8d0011e0-7826-2973-a8ea-2da57229bbc9.png)

# 各種ファイル

## runtime.txt

Python のバージョンを記載します。

```
python-3.8.1
```

## requirements.txt

サーバー側で必要になるライブラリを記載します。

```
Flask==1.1.2
line-bot-sdk==1.16.0
psycopg2==2.8.5
```

## Procfile

Heroku で必要になるファイルで、プログラムの実行方法を記載します。

```
web: python main.py
```

# おわりに

PS5 楽しみ！！
オワコン大手SIerに学ぶアンチパターン

軽い読み物としておもしろおかしく読んでください。

## はじめて社外の人の仕事を見た

今まで社内の成果物しか目にしてこなかったのですが、ふとしたきっかけで外部ベンダーが作ったシステムを移行することになりました。

会社名を見て、よく知った会社でちょっと安心しました。
「ここなら設計書とかもきちんとしてるだろう、多少古臭くても堅実にやってるんじゃないかな」って思ってました。ええ。

## 実態は全然違った

とんでもない量のExcelが設計書として渡されました。

~~さすがに設計が専門だけあって~~設計書の量はすごいなぁ。と思って読んでいるといろいろ察してきました。
正直、「**オワコン大手SIer**」と呼ぶしかありません。設計しかできないと思っていたのに、何もできないなんて・・・

実際に自分が見た「**オワコン大手SIer**」のアンチパターンをご紹介していきます。
自分が多く当てはまっている場合は今すぐ直してください。移行する人がストレスで死にます。

**※念のためですが、この記事内で紹介しているのは実例ではありません。(転載はできないので・・・)**

## 設計書編

とんでもない量のExcelファイル。しかも、**ドキュメントを読めば読むほど分からなくなります。**

- 同じ情報が複数の設計書に書かれてある
    - しかも、ドキュメントがアップデートされていたり、されていなかったりする。
    - 結果、**どこを見れば正しい情報を知れるのかが分からない。**
    - なので、全部読むしかない。
      - しかし全部読んでも、ドキュメントAとドキュメントBで矛盾している。
- 無駄なシートがたくさんある
    - シートに大きなオブジェクトが貼られていて「●●参照」と書かれてある。
    - 何も情報が無い図が書かれてある (バッチが時間になると実行されます)
    - **いらない情報を書くな！**
- 説明されない社内用語が当然の如く使われる
    - `○○コード`とかいきなり出てきて、何も説明が無い
    - `XXX`みたいな3文字の略称がいきなりでてくる(どこにも説明が無い)
      - ローマ字の当て字だったりする(`QiitaShitsumonKo-na-`の略称で`QSK`とか)
    - 用語集も無いので、理解しようがない。

## 設計編

私が新人のときに「こう設計する気持ちが分からない」という指摘(?)をもらったことがありますが、
その気持ちが分かりました。

- 超絶賢いUIになっている
  - いろんなDBのいろんな値でコード値で変換をかけて画面表示をしている。
  - コード値×3をPKとしてコードを取得してさらに変換しているというものも！
  - ちなみに、DB登録時に変換しているものもあり、何の情報をもとに表示しているのかが分からない。
- 全部入りのエンティティが作られている
  - ひとつのエンティティの要素が800超え
  - 念のため追加した項目が多くみられる
     - `hogehogeコード1`
     - `hogehogeコード2`
     - ・・・
     - `hogehogeコード20`
- 一時テーブルをやたらと作りたがる
  - `テーブルA`から`X`の条件でレコードを抽出して一時テーブル`T1`に登録
  - `テーブルB`から`Y`の条件でレコードを抽出して一時テーブル`T2`に登録
  - `T1`にあって`T2`に無いものを一時テーブル`T3`に登録
  - `T3`にあるレコードを`テーブルA`から削除
     - **本当に気持ちが分かりません。**

## DB編

DBの設計書も膨大で、シートの数がとんでもないことになっています。

- テーブル名/カラム名がローマ字
  - `T_SHITUMON`
     - 質問テーブル
  - `QIITA_TOUKOUSHA_CDE_KNJ`
     - Qiita投稿者コード(漢字)
- `DATE`型使えばいいのに、すべて`CHAR`でDBに登録している
  - YEARカラム
  - MONTHカラム
  - DATEカラム
  - 曜日カラム
  - 休日フラグ
  - 祝日フラグ
- 1テーブル100カラム超え
  - 全部いれとけ精神
- 意味不明なカラム名
  - `HOGE_FLAG_12`
- カラムの真ん中あたりに突如でてくる論理削除フラグ
  - メタデータは末尾にもっていってほしい。

## コード編

javaで書かれていましたが、動いているのが本当にすごい。

- やっぱり変数はローマ字
- ハードコードの**嵐**
  - `String`はほぼすべてハードコード
    - 1300行のクラスの"(ダブルクオーテーション)の数が1000個近くあった
    - これでバグが出ずに動いているのが逆にすごいです。
- フォーマッターがあたっていない
  - ほぼ全ファイルあたっていませんでした。
  - 中カッコが縦に3つ並んでいた・・・
- インスタンスのフィールド変数へのstaticアクセス
    - 自分が見ていたところは参照でしたが上書きとかしていたら・・・
- 変数名が分からない
  - 引数 `aParam`, `bParam`
  - 変数名`a1`
- `if (boolean == false)`
    - `!`を知らないのだろうか
- メソッドが500行こえてる
    - 1メソッドの中に`if`が50個以上ありました。こわい。
- なぜか配列しか使っていない
    - `List`/`Set`/`Map`を知らない・・・？
    - 珍しく`HashMap`が登場したと思ったら`containsKey()`しか使っていないので`Map`である意味がない。

## まとめ

実際に自分が見たアンチパターンを紹介しました。
最後の方は少し書く気力も失せてしまうほど色々と衝撃だったのですが、自分はクラフトマンシップをしっかり持って仕事しようと心に強く誓いました。

~~国のシステムの仕様がイケていないのも、妙に納得がいきました~~
変数名に使う英単語を省略するのための4方式

## はじめに

変数（や関数）の命名にあたっては、明確な名前をつけよう、とよく言われる。たとえば、このあたりのトピックで有名な書籍『リーダブルコード』では、「名前に情報を詰め込む」ために

- 明確な単語を選ぶ
- 汎用的な名前を避ける（あるいは、使う状況を選ぶ）

ことが推奨されている。他にも、以下のような記事で似た内容が書かれている。

- [変数名・関数名の付け方についての個人的ルール - Qiita](https://qiita.com/Kunikata/items/0337c6744a7c8fbc1586)

一方で、変数名に使う英単語はなるべく短くしたいというニーズもある。そうでないと、何度も改行が必要になってコードが読みにくくなったり、アプリを構成するファイル名がエディタで表示しきれなくなったり、などの不都合が起きる。

したがって変数の命名にあたっては、なるべく短く、かつ元の形が推測できるようにしたまま単語を省略したい。この2つの条件を満たす省略法があれば、「このワードは変数名に入れた方がいいけど長くなるから止めよう」といった理由で情報量が不十分な変数名をつけてしまう事態も避けられるはず。

以上の目的から、変数名の省略にはどのような方法があるかを整理してみたい。

## 省略の4方式

### 1. acronym（`pwd`方式）

ここで紹介する省略法のうち、おそらく最も分かりやすいのがacronym（和訳は「頭文字語」らしいが、しっくりこないのでそのままacronymと呼ぶことにする）かと思う。何かというと、語句を構成する単語の先頭だけを取る形で省略したもの（ただし、`REpresentational State Transfer`が略されて`REST`になるように、頭文字より後ろの文字も使われる場合がある）。

たとえばUNIXコマンドの一つに`pwd`があるが、これは`Print Working Directory`を略したacronym。他にも、このタイプの略語としては以下のような例がある。

    cd # Change Directory
    re # Regular Expression
    html # Hyper Text Markup Language

ただ、世の中に浸透していないacronym（たとえばピコ太郎が登場する以前の「PPAP」）を急に使ってしまうと当然通じないので、オリジナルの略称を作る場合にはあまり適さないかもしれない。

### 2. ある子音より後を削る（`app`方式）

acronymほど単純ではないけれどよく見るのが、単語の中である子音より後を削る省略法。iOSアプリのプラットフォームApp Storeなどにも含まれる`app`という言葉が`application`の`l`より後ろを略した形であることから、ここでは`app`方式と呼ぶことにする。

以下ではRailsでの開発やPythonによる分析をしていてよく目にする`app`方式の略称を並べてみたが、このあたりは言語を問わず広く使われているのでは。

    dev # development
    env # environment
    col # column
    const # constant

末尾になる子音の選び方としては、なるべく前方の文字を選ぶけれど、これより前にある文字まで削ると意味が曖昧になってしまう、ぎりぎりのラインを目指すということかと思う。

例として、`category`を省略したい場合を考えてみる。最後の`ory`を落とすのはいいとしても、さらに2文字削って`cat`としてしまうと、読む人に「これは`catenation`かもしれないし`catch`かもしれない」などと考えさせることになる。だから`categ`ぐらいが適当なのでは、といった具合に調整するのがよさそう。

ちなみに、特定の母音より後ろを削るタイプの省略法もなくはない。たとえば日本語ではSFと略されるScience Fictionは、英語圏だとSci-Fiと呼ばれている。が、このパターンは上述のものと比べて稀なので、そういうパターンもある、くらいの認識をしておけば十分かもしれない。

### 3. 重要な文字だけを残す（`img`方式）

`app`方式はある文字より後ろをばっさり削るというものだったが、単語の先頭や末尾などポイントになりそうな文字だけ残してその他を間引くアプローチもある。このアプローチは、`image`から`a`と`g`を落とした略称`img`（これはHTMLのタグ名でもある）に倣って、`img`方式と呼ぶことにしてみる。

    btn # button
    usr # user
    idx # index

ここで挙げた`idx`は単に`i`と略されることも多いが、文脈によって`integer`とか`id (identification)`の略ではないことを明確にしたい場合は使う価値がある。

ちなみに日本語で対応する例も考えてみると、「ありがとうございます → あざす」や「ウッチャンナンチャン → ウンナン」などは、同じ発想による省略と言えそう。

### 4. 2と3の合わせ技（`jp`方式）

    tmp # temporary

このパターンは頻出ではないもののたまに見る。

`japan`を`jp`と略すのはもはや慣例になっているが、よく考えてみると`app`方式では`jap`、`img`方式では`jpn`までしか短くできないところで、この二つが併用されて`jp`という形になっていることが分かる。

## まとめ

いろいろ見てきたが、コーディングの現場で変数名を決めるにあたっては短さより分かりやさが重視されることが多い。分かりやすさを損なわない方法としては、基本的に`app`方式が無難なのではと思う（とはいえ他の方式も、省略形から原形を推測するにあたっては役に立つ）。

省略法を知っていることは、名前の衝突を避けたい場合も役に立つ。たとえばPythonの開発や分析では、リスト（一般的なプログラミング用語では配列）を意味するために`lst`という変数名が使われることがある。ここで`list`の代わりに`lst`という変数名を使うことには、`list()`という予約語（メソッド）を上書きしてしまう問題を避けるメリットがある。

なお、この記事では変数の例を中心に単語の省略法を見てきたが、これらは、関数、カラム、ディレクトリ、ファイルなどの命名にも当然ながら応用できる。
MaixCubeでTensorFlow Lite for Microcontrollersを試す

# はじめに

[nb.o](https://nextremer-nbo.blogspot.com/) さんの [TensorFlow Lite for microのHello worldサンプルをM5StickVで動かす（その1）](https://nextremer-nbo.blogspot.com/2020/01/tensorflow-lite-for-microhello.html) と [TensorFlow Lite for microのHello worldサンプルをM5StickVで動かす（その2）](https://nextremer-nbo.blogspot.com/2020/02/tensorflow-lite-for-microhello.html) を見つけた。M5StickVで動いているのでMaixCubeでも動くだろうと思って動かしてみた。

# PlatformIO

やっぱり使い慣れたPlatformIOを使いたいと思い。ブログを参考にファイルを配置した結果は [こちら](https://github.com/fukuen/maixcube-tensorflow-lite-micro)

# 動いた！

画面にサインカーブが表示されました。
[AWS] SQSの基本

####前置き
初学者がAWSについてまとめています。間違いありましたらご指摘よろしくお願いします。

#SQSとは
Simple Queue Serviceの略。分散されたコンポーネント間でのメッセージ(≒データ)のやりとりのためにキューを提供してくれるサービス。

#キューってなに？
先入先出し(先に入れたものが先に出てくる)構造になっている何か。SQSではでは先入先出し構造になっているメッセージ。

※後述するスタンダードキューではこの原理原則がごく稀に破れる。

# キューの種類
スタンダードキューとFIFOキューの2つがある。

**スタンダードキュー**
・ほぼ無制限のスループット(=処理性能)
APIアクション(SendMessage, Receive Message, Delete Message)ごとに1秒あたりほぼ無制限のAPIコールをサポート。

・少なくとも１回の配信
１回は確実にメッセージが配信される。しかし、複数のメッセージのコピーが配信される場合もあるので注意が必要。

・ベストエフォート型の順序づけ
基本的には先入れ先出しだが、処理性能を上げるためにその原則を無視することがある。

まとめると、スループットを重視する場合はこちらを用いる。

**FIFOキュー**
・高スループット
APIアクションごとに1秒あたり最大300のAPIコールをサポート。バッチ処理を適用することで処理性能をもう少し上げることができる。

・１回だけの処理
１回だけメッセージが配信される。重複は絶対にしない。

・先入れ先出し配信
必ず先入れ先出しでデータが配信される。

まとめると、イベントの順序を重視する場合こちらを用いる。

#ショートポーリングとロングポーリング
メッセージを受信する設定として、ショートポーリングとロングポーリングがある。デフォルトはショートポーリング。

**ショートポーリング**
・ReceiveMessageリクエストに対して、複数のサーバーのサブセット(≒一部分)のみに照会してレスポンスを返す。
・メッセージが見つからなくてもレスポンスをすぐに送信する。

利点は、すぐにレスポンスを返してくれること。

**ロングポーリング**
・ReceiveMessageリクエストに対して、すべてのサーバーに照会して指定された最大メッセージ数だけメッセージを見つけてくる。
・ポーリング経過時間(最大20秒)が経過した場合のみ空のレスポンスを送信する。

利点は、空のレスポンスの数を削減することでコストカットができること。ReceiveMessageAPIアクションの待機時間が0より大きい場合は非常に有効。

#SQSの様々な便利システム
**デッドレターキュー**
正常に処理できなかったメッセージの送信先として他のキュー(ソースキューという)を使用することができる。問題があったメッセージだけを分離して解析することで処理が失敗した理由を調べることができる。

**可視性タイムアウト**
コンシューマーがメッセージを受信した後、一定時間別のコンシューマーがメッセージを受信したり処理したり出来ないように設定できる機能。
SQSではコンシューマーがメッセージを受信してもメッセージは自動的に削除されず、キューに残ったままになっていて同じメッセージが2回処理される危険があり、この問題への対処法として使われる。

#最後に
参考
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html
ゼロから始めるLeetCode Day54 「1290. Convert Binary Number in a Linked List to Integer」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day53 「1365. How Many Numbers Are Smaller Than the Current Number」](https://qiita.com/KueharX/items/77f347c2e95dad58333b)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[1290. Convert Binary Number in a Linked List to Integer
](https://leetcode.com/problems/convert-binary-number-in-a-linked-list-to-integer/)
難易度はEasy。

問題としては、単方向の連結リスト`head`が与えられます。
各ノードは`0`か`1`を値として持っており、それらを2進法の値として扱います。ここではそれらの二進法表記の値を10進法に直し、数字を返すアルゴリズムを設計してください、というものです。

>Input: head = [1,0,1]
Output: 5
Explanation: (101) in base 2 = (5) in base 10

>Input: head = [0]
Output: 0

>Input: head = [1]
Output: 1

>Input: head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
Output: 18880

>Input: head = [0,0]
Output: 0

# 解法

進数変換はちょいちょいあるネタな気がします。
最初は面食らうかもしれませんが、よくよく見てみるとワンパターンなことが多いので問題を解いて慣れてしまうことをお勧めします、


この問題での大事なのは、

- 連結リストの要素を全て網羅する
- 二進数から十進数へと変換する

という点なので、そこについて理解できていれば簡単かもしれません。

配列を用意し、配列へ追加、次の要素へ移動、というのをwhile文で書いてあげれば事足りそうです。

進数変換ですが、例えば、Pythonでは、
`int('10',2)`
といった形で書くと2進数を10進数に変換してくれるため、それを使えば変換自体は簡単です。

詳しく知りたい方は[公式ドキュメント]
(https://docs.python.org/ja/3/library/stdtypes.html?highlight=find)を参照することをお勧めします。

ここまでの流れをPythonで書いてみましょう。

```Python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        ans = []
        while head:
            ans.append(str(head.val))
            head = head.next
        return int(''.join(ans),2)
# Runtime: 16 ms, faster than 99.88% of Python3 online submissions for Convert Binary Number in a Linked List to Integer.
# Memory Usage: 13.7 MB, less than 85.59% of Python3 online submissions for Convert Binary Number in a Linked List to Integer.
```
[join関数](https://docs.python.org/ja/3/library/stdtypes.html)は区切る要素を指定してあげると連結して文字列として返してくれる便利な関数です。

例えば、例で考えてみると、while文が終わった段階で、`head = [1,0,1]`を配列の`ans`に`str`で追加しているため、`ans = ['1','0','1']`となります。ここを連結するためにreturn以降の書き方をしてあげると`ans['101',2]`となるため、最終的にこれが10進数に変換されて返される、ということになります。


今回はここまで。お疲れ様でした。
TECH CAMP 10週間を終えて

遂に！TECH CAMPの全てのカリキュラムが終了しました！
約10週間、長いようでいてあっという間でした。

【これまでの歩み】
・[TECH CAMP入校](https://qiita.com/ruby55tomo/items/ee94693e68b05e875f96 #Qiita)
・[TECH CAMP入校前](https://qiita.com/ruby55tomo/items/75ec0c67752d379213ea #Qiita)
・[TECH CAMP 3週目](https://qiita.com/ruby55tomo/items/14a0877243784619a390 #Qiita)
・[TECH CAMP 4週目](https://qiita.com/ruby55tomo/items/a50f2bbc2100ae82f495 #Qiita)
・[TECH CAMP 5週目](https://qiita.com/ruby55tomo/items/467b5cddb4e228cc383f #Qiita)
・[TECH CAMP 6週目](https://qiita.com/ruby55tomo/items/69032cf98558825705fa #Qiita)
・[TECH CAMP 7,8週目](https://qiita.com/ruby55tomo/items/15b540c00a6ea9d595d5 #Qiita)
・[TECH CAMP 9,10週目](https://qiita.com/ruby55tomo/items/3f5c8c6759ba8dc1dc5b #Qiita)

そして本日は最終課題発表会をA、Bチーム合同で実施しました。実際に開発したフリマアプリを見せ合うのではなく、スライドでひとりひとりの想いを発表し合う場でした。チーム開発の苦労点、成長した点、これからどうしていくのか‥皆さんそれぞれの熱い思いを感じ取ることが出来ました。
<img width="843" alt="スクリーンショット 2020-06-12 20.11.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620703/9e603ce8-043c-1c30-f59e-1552c599f955.png">

個人的にはチーム開発はとても楽しかったです。コロナ騒動で教室利用が制限される中、SlackやZoomを使って連携をとっていきました。これからこういった方法が働き方のスタンダードになるのであれば、かなり良い練習になったのではないかなと思います。また、スクラムマスターとしてタスクの調整等を行っていく中で、責任感のあるメンバーに恵まれたことでかなり助かりましたし、とても感謝しています。
![5313ad44866f4042078066425ac60b72.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620703/3f70a3f7-e82a-863c-d792-0d00495957e4.gif)

##TECH CAMPをこれから受講していく方/受講を考えている方へ
・カリキュラムはまずは理解半分でOK！アプリを開発していく中で理解してくる！
・暗記よりも検索力を身につける！プログラミングだけでなく普段から検索する癖をつける！
・TECH CAMPのカリキュラムだけでなく、ProgateやYoutubeや技術書等で学習する！幅広い知識や多角的な視点を得るという意味で有利！というか受講前にやっておいた方が良い！
・メンターへ質問する力をつける＝職場の上司や先輩に質問する力がつく！という考え方で積極的かつ論理的に質問する！
・教室に通いたければコロナ騒動の今ではない！落ち着くまで待とう！
・70万円という金額の価値をどこに見出すか考えよう！単純にプログラミングを学習するのであれば他にも方法はある！チーム開発の経験？転職の為？挫折しないように？
・転職返金補償の条件は厳しいのであてにしない！どこに引っ越してもOK正社員じゃなくてもOK年収も特に条件ないですよって人が半年間就職先を見つけることが出来なかった時くらいしか返金されません！
・就職したらカリキュラムを見ることが出来なくなるので注意！
・仲間を大切に！同期の方々とはミーティングやチーム開発を通じて仲良くなっていきます！というかコミュニケーション能力はかなり必要！苦手だなって思う方もこれを機に変わりましょう！チーム開発は意見を言い合うことが大切！ひとりの声の大きい人の演説ではなく、みんなの対話でこそ物事の真理に辿り着く、とソクラテスも言っています！

##さいごに
私は、「他者貢献」という言葉を人生の格言としています。
仲間を信頼（≠信用）し、見返りを求めないギブをし、承認欲求を得ようとしない。
小さな事でも何かを他者に与えることに幸福を見出すと人生が豊かになります。あっ、お金とか物の話ではないです(笑)お金は少し考えます(笑)
TwitterやQiitaでの発信もギブだと思っています。特にこれまでの記事は自分自身のアウトプットの為と、それ以上にこれからTECH CAMPの受講を考えている方へ向けて書きました。実際に他のエンジニアや学習中の方の記事が大変参考になりました。感謝でいっぱいです。まだまだ初学者なのでテイクばっかりになっていますが、これからもギブしていきたいと思います。
Tableau Desktop から Amazon Athena への接続（IAMロール）

**IAMユーザではなく、IAMロールで Tableau Desktop から Amazon Athena へ接続したい場合の手順**

※ IAMユーザの認証情報（アクセスキーID、シークレットアクセスキー）を用いた接続方法
https://qiita.com/r18j21/items/e8a459c2544a80c46a70

## JDBCドライバの配置

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/connect-with-jdbc.html
から最新の `.jar` ファイルを取得し、OS にあわせて下記ディレクトリに配置

> Windows： **C:\Program Files\Tableau\Drivers**
> Mac： **~/Library/Tableau/Drivers**
> Linux： **/opt/tableau/tableau_driver/jdbc**

【参考】
https://help.tableau.com/current/pro/desktop/ja-jp/examples_otherdatabases_jdbc.htm

## credentials の設定

AWS CLI の `credentials` が設定されていない場合は `aws configure` で設定する

【参考】
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration

```
[default]
aws_access_key_id = ZZZZZZZZZZZZZZZZZZZZ
aws_secret_access_key = 9999999999999999999999999999999999999999
```

作成された `credentials` にIAMロールを追加

```
[default]
aws_access_key_id = ZZZZZZZZZZZZZZZZZZZZ
aws_secret_access_key = 9999999999999999999999999999999999999999

[【任意のIAMロール名】]
role_arn = arn:aws:iam::000000000000:role/iam_role
source_profile = default
```

## Tableau Desktop からの接続

Tableau Desktop データソース接続 > その他のデータベース (JDBC)

> URL： **jdbc:awsathena://【下記参照】**
> 方言 ( dialect のことらしい...何という和訳センスのなさ... ) ： **SQL92**
> その他はすべて空白

```
jdbc:awsathena://
  AwsRegion = 【リージョン】;
  S3OutputLocation = 【IAMロールで書込み可能なS3バケットおよびディレクトリ】;
  Profile = 【credentials で設定した任意のIAMロール名】;
```

記述例 

```
jdbc:awsathena://
  AwsRegion=ap-northeast-1;
  S3OutputLocation=s3://bucket/tableau/desktop/;
  Profile=iam_role;
```

![その他のデータベースJDBC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582725/f09837a1-a21f-6f70-590d-7c2598079fd7.png)


【参考】
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/connect-with-jdbc.html
→ JDBC ドライバーのインストールおよび設定ガイド
私のmacbook初期設定

# 備忘録
MacbookairからMacBookProに買い換えるにあたって
初期設定した記録を忘れないためにここに残す
導入ごとにここに追記していく
まだまだ、追加中。。。。。


# 入れたもの達
## アプリ
- Discord
- VisualStudioCode
- Biscuit
- iTerm2
- 1password
- CleanMyMac

## 常駐
- Alfred4： 
- BetterTouchTool
- Bettersnaptool
- RunCat

## CUI
- SDK
- .vim/color/
- .vimrc
- .zshrc
- im-select
    - https://qiita.com/tea-red/items/23dfc89edc11ecdced03
- docker
- homebrew

## VSCode
- Japanese Language Pack for Visual Studio Code
    - https://qiita.com/ntkgcj/items/e77331932c7983dea830
- Bracket Pair Colorizer
- indent-rainbow
- Live Share
- Material Icon Theme
- Quokka.js
- Rainbow CSV
- Remote - SSH
- Trailing Spaces
- Vim


## 設定
- finderにhomeアイコンを追加
    - https://dtmmethod.com/mac-finder-home
MySQL 接続エラー　

## 概要
環境構築の際にMySQLのエラーがよく起きるので備忘録を残します。


## エラー

```
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
```

```
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (38)
```

この辺りはよく見かけるエラーでQiitaでもたくさん解決法が載っていました。

https://qiita.com/hondy12345/items/d32ed749fb49e9da7de6
https://qiita.com/masa_stone22/items/38a286a89c309de7d44e

それでも解決しなかった。
特にこんなエラーがでてくるという場合は

```
The server quit without updating PID file
```


プロセスを一度キルすると動きました。

```
$ ps aux | grep mysql プロセス表示
$ kill プロセス
$ mysql.server start 再度起動させる
```

それでも治らなかったらbrew uninstallしてbrew installし直すと良いみたいです。
brew installする時バージョン指定をしていないと最新のバージョンがインストールされてしまうので注意してください。



以上です！
P5.js 日本語リファレンス(tint)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の tint関数を説明します。

## tint() 

### 説明文

画像を表示するための塗りつぶしの値を設定します。画像はアルファ値を含めることにより、指定した色に着色したり透明にしたりできます。

色に影響を与えずに画像に透明度を適用するには、濃淡色として白を使用しアルファ値を指定します。たとえば tint(255, 128) は画像を 50% 透明にします(colorMode() で変更できるデフォルトのアルファ範囲 0〜255 を想定)。

grayパラメータの値は colorMode() で指定された現在の最大値以下でなければなりません。デフォルトの最大値は255です。

### 構文

tint(v1, v2, v3, [alpha])

tint(value)

tint(gray, [alpha])

tint(values)

tint(color)

### パラメタ

- v1
Number：現在の色の範囲を基準にした赤または色相の値

- v2
Number：現在の色の範囲に関連する緑または彩度の値

- v3
Number：現在の色の範囲に関連する青または明るさの値

- alpha
Number：(オプション)

- value
String：カラー文字列

- gray
Number：グレイ値

- values
Number[]：色の赤、緑、青およびアルファコンポーネントを含む配列

- color
p5.Color：色


### 例1

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.jpg');
}

function setup() {
  createCanvas(500, 500);
  
  // 現画像を表示します
  image(img, 0, 0);

  // 色合い(tint)を青にして表示します
  tint(0, 153, 206); // blue
  image(img, 150, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/G06sEGo3_


### 例2

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.jpg');
}
function setup() {
  createCanvas(500, 500);
  
  // 現画像を表示します
  image(img, 0, 0);

  // 青に色付けし, 透明度を設定します
  tint(0, 153, 204, 126);
  image(img, 150, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/T4bjQYe--


### 例3

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.jpg');
}

function setup() {
  createCanvas(500, 500);
  
  // 現画像を表示します
  image(img, 0, 0);

  // 色を変更せずに透明度を適用します
  tint(255, 126); 
  image(img, 150, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/YisCOrEAl



### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
P5.js 日本語リファレンス(noTint)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の noTint 関数を説明します。

## noTint() 

### 説明文

画像を表示するための現在の塗りつぶしの値を削除し、元の色相の画像の表示に戻します。

### 構文

noTint() 


### 例1

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.jpg');
}

function setup() {
  createCanvas(500,500);
  
  // 現画像を表示します
  image(img, 0, 0);

  // 色合いを青にする
  tint(0, 153, 204); // blue
  image(img, 150, 100);
  
  // 色合いを無効にする
  noTint() ;
  image(img, 0, 300);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/PK3nq7TqB


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
firebase authで新規ユーザーがなぜか登録できないとき

#最初に結論
firebase authで複数のログイン方法をテストする際、元サービスでのメールアドレスが被っていないか確認しましょう

## 例) GoogleとGitHubでログインのテストをする

```js
  signInWithGoogle () {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().signInWithRedirect(provider)
  },
  signInWithGithub () {
    const provider = new firebase.auth.GithubAuthProvider()
    firebase.auth().signInWithRedirect(provider)
  }
```

firebase authの ```user``` は各サービスから取得したメールアドレスで登録されています。このように複数サービスを設定する場合、アドレスが被っているとユーザーが登録できなくなります。テストする際はメールアドレスが被っていないか気をつけましょう。
P5.js 日本語リファレンス(imageMode)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の imageMode関数を説明します。


## imageMode() 

### 説明文

画像モードを設定します。 image() に指定されたパラメータが解釈される方法を変更することにより、画像が描画される場所を変更します。

デフォルトのモードは imageMode(CORNER) で、image() の2番目と3番目のパラメータをイメージの左上隅として解釈します。 2つの追加パラメータが指定されている場合、それらは画像の幅と高さを設定するために使用されます。

imageMode(CORNERS) は、image() の2番目と3番目のパラメータを1つのコーナーの位置として解釈し, 4番目と5番目のパラメータを反対側のコーナーとして解釈します。

imageMode(CENTER) は、image() の2番目と3番目のパラメータを画像の中心点として解釈します。 2つの追加パラメータが指定されている場合、それらは画像の幅と高さを設定するために使用されます。

### 構文

imageMode(mode)

### パラメタ

- mode  
定数：CORNER、CORNERS または CENTER


### 例1

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.png');
}

function setup() {
  createCanvas(500, 500);
  
  // 表示する画像の左上隅の座標を (10, 10) にする
  // 表示する画像の幅と高さを 100 x 100 にする
  imageMode(CORNER);
  image(img, 10, 10, 100, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/dOy11H1iK


### 例2

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.png');
}

function setup() {
  createCanvas(500, 500);
  
  // コピー元画像を原寸大で表示します
  image(img, 0, 0);

  // 表示する画像の左上隅の座標を (50, 10) に、
  // 右下隅の座標を (150, 110) にする
  imageMode(CORNERS);
  image(img, 50, 10,  150, 110);
}

```

### 実行結果
https://editor.p5js.org/bit0101/sketches/ZkA-_gN6t


### 例3

```javascript
let img;
function preload() {
  img = loadImage('assets/mountain.png');
}

function setup() {
  createCanvas(500, 500);
  
  // コピー元画像を原寸大で表示します
  image(img, 0, 0);
  
  // 表示する画像の中心座標を (150, 100) に、
  // 幅と縦を 150 x 100 にする
  imageMode(CENTER);
  image(img, 150, 100,  150, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/3g_SuDMLU


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
Laravel 6.xでRouterをカスタマイズしてAPI共通レスポンスを自動で付与

## 概要

LaravelでAPIを作っていて共通レスポンスをAPI毎に入れ込むのではなくどこかで自動的に付与させたかった。
ぐぐったらmiddlewareを作ってhookさせるようなやり方が出てきたが一度作成されたデータをパースして作り直すのがなんか嫌だったのでもう少し調査し、このやり方にたどり着いた。

登場するコードは結構実際に利用した所からqiita用に起こしてるのでちょっと変な箇所があるかも。
筆者はLaravel初学者です。

## 環境

### PHP

```
PHP 7.4.3 (cli) (built: Feb 20 2020 21:53:46) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
    with Xdebug v2.9.5, Copyright (c) 2002-2020, by Derick Rethans
```

### Laravel

```
Laravel Framework 6.18.15
```

## そもそもレスポンスってどこで作られてんだろう？

レスポンス作ってるところが判ればカスタマイズの方法がわかるじゃろうと思い追っていったところ

[src/Illuminate/Routing/Router.php#L719](https://github.com/laravel/framework/blob/6.x/src/Illuminate/Routing/Router.php#L719)に`prepareResponse`を発見。
名前的にここだろうと的を絞る。

## 実際にRouterを拡張していく

### `app/Routing` ディレクトリを作成しRouterクラスを作成

```php:app/Routing/Router.php
<?php

namespace App\Routing;

use Illuminate\Routing\Router as BaseRouter;
class Router extends BaseRouter
{
    public function prepareResponse($request, $response)
    {
        // ここに独自の処理を追加する
        // toResponseの中で色々判断してるのでここで受けるresponseは配列、Arrayable、ArrayObjectの方が取り扱いやすい
        return static::toResponse($request, $response);
    }
}
```

### 拡張したRouterを利用できるようにする

`src/bootstrap/app.php`に定義を追加する

```php:src/bootstrap/app.php
$app->singleton('router', function ($app) {
    return new App\Routing\Router($app['events'], $app);
});

```

### コントローラーのレスポンスを変更

`response()->json`で共通パラメーターを含め返却していた部分をAPIの責任のあるパラメーターだけを配列で返却するだけにした。

```diff
 public function api()
 {
-  return response()->json([
-      'state' => 1,  // 共通レスポンス
-      'timestamp' => time(),  // 共通レスポンス
-      'result' => "API独自の結果"
-  ]);
+  return [
+      'result' => "API独自の結果"
+  ];
 }
```

## まとめ

このやり方なら一度JsonResponseに変換されたレスポンスを再度配列に変換し、データを結合してから再度JsonResponseに変換する必要がなくて良いのかなと。

参考:
[【Laravel】 ルーティングサービスを継承する](https://qiita.com/mpyw/items/5d6e992fb3c40c63942f)
条件式の書き方

# 条件式とは？
if文やwhile文で利用される式の一種で、
「処理を分岐する条件」や「繰り返しを続ける条件」
などを表現するためのもの。

例：

```java

if(tenki ++ true) {} //もし変数の中身がtrueなら

while(age > 18) //もし変数が１８より大きいなら

```
↑
上記のように条件式の中身が評価されて分岐や繰り返しが処理される。


関係演算子

```
＝＝  ：左辺と右辺が等しい
！＝  ：左辺と右辺が異なる
＞ 　：左辺が右辺より大きい
＜ 　：右辺が左辺より大きい
＞＝ ：左編が右辺より大きいか等しい
＜＝ ：左編が右編より小さいか等しい
```

関係演算子を使うと下記のような条件式が作れる

```
・sw  != false：変数swがfalseでなかったら
・deg -273.15 < 0：変数degから273.15を引いたものが０未満なら
・initialial == ’雅’：変数initialに入っている文字が雅だったら
```

「等しい」を表現する関係演算子はイコールが２つであること。
１つにすると、代入演算子になるから気をつける。

条件式では＝＝を使う

# まとめ

演算子とは、「前後の値と一緒に評価され、別のものに化ける記号のこと」
最新の Cuda + CuDNN を Ubuntu 18.04へインストールする＠2020年春版

# はじめに

昨年、「[最新の cuda + cudnn + cupy を Ubuntu 18.04 へインストールする＠2019年春版](https://qiita.com/aizakku_nidaa/items/3c97dbcc30e1995488a5) 」という記事を執筆したのですが、今年も Google Colaboratory では物足りず、本格的なGPUサーバーを使うための環境構築をしました。

その時の作業記録を忘備録として残しておきます。

# やりたいこと

- Tensorflow 2.2を使える環境をubuntuで作ります。~~(Chainerの更新が止まったので、仕方ないね）~~
- インストール対象は Ubuntu 18.04です。~~(cudaが20.04にまだ対応していないっぽいので、仕方ないね）~~


なお、[TensorflownのGPUサポート](https://www.tensorflow.org/install/gpu?hl=ja)を参考にしています。他のライブラリでも似たような手順で問題ないと思いますが、ご了承ください。

# インストール環境
マシン: GCP Computer Engine (Google提供のクラウドの仮想マシン)
CPU, メモリ: n1-standard-2（vCPU x 2、メモリ 7.5 GB）
OS: Ubuntu 18.04
GPU: NVIDIA Tesla K80


# 実際の手順

cuda、ドライバ、各種ライブラリのバージョンに注意しましょう。当然ですが、互換性がないとエラーを吐かれます。
投稿時点では以下のコマンドを実行しましたが、それぞれ必要なバージョンを指定してDLしてください。

```shell

# cuda関連のインストール
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.2.89-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo dpkg -i cuda-repo-ubuntu1804_10.2.89-1_amd64.deb
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt-get update

# ドライバのインストール
sudo apt-get install --no-install-recommends nvidia-driver-430

```

```shell
# cuda関連のパスを追加 .bashrcなどの設定ファイルに書き込む
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
```


この時点で１回リブートする。再起動後、`nvidia-smi` を叩き、正しく動くか確認する

```shell

# その他tensorflowで使うライブラリのインストール
sudo apt-get install --no-install-recommends cuda-10-2 libcudnn7 libcudnn7-dev
sudo apt-get install --no-install-recommends libnvinfer6 libnvinfer-dev libnvinfer-plugin6

# tensorflowのインストール
pip install tensorflow
```

## 動作確認

```python
import tensorflow as tf
tf.__version__
> '2.2.0'


from tensorflow.python.client import device_lib
device_lib.list_local_devices()

> '''
[name: "/device:CPU:0"
 device_type: "CPU"
 memory_limit: 268435456
 locality {
 }
 incarnation: 3998521659132627640,
 name: "/device:XLA_CPU:0"
 device_type: "XLA_CPU"
 memory_limit: 17179869184
 locality {
 }
 incarnation: 4355352578664011114
 physical_device_desc: "device: XLA_CPU device",
 name: "/device:XLA_GPU:0"
 device_type: "XLA_GPU"
 memory_limit: 17179869184
 locality {
 }
 incarnation: 5803845507802816222
 physical_device_desc: "device: XLA_GPU device"]
'''
```

TensorflorでGPUを認識しました。おわり

# 余談

実はGCPにはGoogleで準備されているGPU用のセットアップがあり、仮想マシン作成時に利用すれば上記のような面倒な手順を踏む必要はありません。便利な世の中になったもんだなぁ〜
Static変数の特徴

# Staticとは？

英語では、`静的`
という意味であり、メソッドの種類では「静的メソッド」の種類にあたります。

クラスをインスタンス化せずに使える変数を,staticな変数と言います。

#特徴
インスタンスの有無にかかわらず使える。
逆にstatic以外はインスタンスがないと使えない。


# static変数の使い方

まず、下記のように宣言します。

```
アクセス修飾子(publicなど) static 型名 変数名
```

変数ではデータ型を指定して宣言すると初期値が与えられる。

初期値の表

```
整数：0
float：0.0f
double型:0.0d
文字型：’\u0000′
boolean型：false
参照型(String)：null
```
# 呼び出し方

```
クラス名.変数名
```

クラスのインスタンスを生成せず、クラス名を使って呼び出す。

# static変数で変わること

newせずに指定メソッドやメンバ変数にアクセスできる。

例:

```
 public static String name = "";

    //staticメソッド
    public static String add(String , int b){
        return a + b;
    }
}
```
上記は、通常では、インスタンス化(new)してから呼び出しますが、「static」をつけることで、「new」せずに使うことができる。


# まとめ
・static変数は、静的変数の種類で、インスタンス化せずに使うことができます。

・逆にそれ以外は、インスタンス化しないと使用はできません。
Visual Studio 2019 + VsVimでCtrl + [ を有効にする

1. Visual Studio Installerで英語の言語パックをインストールする。
1. ツール->オプション->環境->国際対応の設定で言語をEnglishにする。
1. Visual Studioを再起動する。
1. Tools->Options->Environment->Keyboard->Show commands containingに以下をそれぞれ入力し、Ctrl + [ を使うショートカット全てに対してRemoveを押す。
    - SolutionExplorer.OpenFilesFilter
    - SolutionExplorer.PendingChangesFilter
    - SolutionExplorer.SyncWithActiveDocument

1. Tools->Options->VsVim->KeyboardのCtrl + [ がHandled by VsVimになっていることを確認する。
1. Tools->Options->Environment->International Settingsで言語を日本語に戻す。

# 参考

- [Ctrl + \[ is not working in Visual Studio 2013 · Issue #1193 · VsVim/VsVim · GitHub](https://github.com/VsVim/VsVim/issues/1193)
- [既定のキーボード ショートカット - Visual Studio | Microsoft Docs](https://docs.microsoft.com/ja-jp/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2019#bkmk_solutionexplorerGLOBAL)
【WBF】Windowsのサービス上で指紋認証を行う

#概要
Windowsのサービス等、画面UIを持たないプログラム上で指紋認証を行う場合は、"WinBioAcquireFocus"関数を使用してフォーカスを取得する必要があります。

# サンプルコード
1. Windowsのサービスを作成します。ここでは下記の記事で作成したプロジェクトを使用します。
[ATLを使用してWindowsのサービスを作成する]
https://qiita.com/Leeya/items/1f8f8db7e8cb7dbbbcf2

2. WBFが使用できるように、必要なファイルをインクルード及びリンクします。

```C++:ATLServiceSample.cpp
#include <Winbio.h>
#pragma comment(lib, "Winbio.lib")
```

2. サービスのメイン処理に下記のコードを実装します。

```C++:ATLServiceSample.cpp
// メイン処理
void RunMessageLoop() throw()
{
#if 1 // 追加 ここから
    // WBFサンプルコード
    WBFSampleCode();
#endif // 追加 ここまで

    MSG msg;
    while (GetMessage(&msg, 0, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

#if 1 // 追加 ここから
// WBFサンプルコード
HRESULT WBFSampleCode()
{
    HRESULT hr = S_OK, hrFocus = S_OK;
    WINBIO_SESSION_HANDLE sessionHandle = NULL;

    try
    {
        // システムプールに接続する
        hr = WinBioOpenSession(WINBIO_TYPE_FINGERPRINT, WINBIO_POOL_SYSTEM, WINBIO_FLAG_DEFAULT, NULL, 0, NULL, &sessionHandle);
        if (FAILED(hr))
            throw hr;

        // フォーカスの取得
        hrFocus = WinBioAcquireFocus();
        if (FAILED(hrFocus))
            throw hrFocus;

        // 指紋認証
        WINBIO_UNIT_ID unitId = 0;
        WINBIO_IDENTITY identity = { 0 };
        WINBIO_BIOMETRIC_SUBTYPE subFactor = 0;
        WINBIO_REJECT_DETAIL rejectDetail = 0;

        hr = WinBioIdentify(sessionHandle, &unitId, &identity, &subFactor, &rejectDetail);
        if (FAILED(hr))
            throw hr;
    }
    catch (HRESULT hrError) { hr = hrError; }
    catch (...) { hr = E_UNEXPECTED; }

    if (SUCCEEDED(hrFocus))
        WinBioReleaseFocus();

    if (sessionHandle != NULL)
        WinBioCloseSession(sessionHandle);

    // イベントログに結果を出力する
    wchar_t pwcLog[_MAX_PATH + 1] = { 0 };
    _snwprintf_s(pwcLog, _MAX_PATH, L"指紋認証結果 [0x%08X]", hr);
    OutputEventLog(pwcLog);

    return hr;
}

// イベントログ
HRESULT OutputEventLog(wchar_t *pwcLog)
{
    HRESULT hr = S_OK;
    HANDLE hEventSource = NULL;

    try
    {
        // イベントログのオープン
        hEventSource = RegisterEventSource(NULL, L"ATLServiceSample");

        // イベントログに出力
        const wchar_t* pwcMsg = &pwcLog[0];
        ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, &pwcMsg, NULL);
    }
    catch (HRESULT hrError) { hr = hrError; }
    catch (...) { hr = E_UNEXPECTED; }

    if(hEventSource != NULL)
        DeregisterEventSource(hEventSource);

    return hr;
}
#endif // 追加 ここまで
```

# 実行

1. このサンプルコードを実行する前に、Windowsの[設定]→[アカウント]→[サインインオプション]→[指紋認識(Windows Hello)]で指紋を登録してください。

2. ビルドしたEXEを下記コマンドでサービスとして登録します。
`"D:\Work\ATLServiceSample\x64\Release\ATLServiceSample.exe" /Service`
※ 実行ファイルのパスはそれぞれの環境のものを使用してください。

3. スタートメニューから[Windowsツール]→[サービス]を開き、[ATLServiceSample]を開始すると指紋センサーが認証の待機状態になるので、指紋センサーをスワイプorタッチしてください。

4. 指紋認証が完了すると、イベントログに結果が出力されます。
![イベントビューアー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608900/9f0b595b-feb1-ea2b-f549-82d890aac37c.png)
結果が[0x00000000]なら認証成功、[0x80098003]なら未登録の指紋です。
P5.js 日本語リファレンス(image)

2020/06/20 更新：図を添付しました。

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の image関数を説明します。

## image() 

### 説明文

画像を p5.js キャンバスに描画します。

この関数は、さまざまな数のパラメータで使用できます。最も簡単な使用方法は、img、x、yの3つのパラメータのみを必要とします。ここで (x, y) は画像の位置です。画像の幅と高さを指定するために、さらに2つのパラメータをオプションで追加できます。

この関数は、8つの数値パラメータ全てで使用することもできます。これらすべてのパラメータを区別するために、p5.js は、「コピー先長方形」(パラメタ dx、dy などに対応)および「コピー元画像」(パラメタ sx、syに対応) のワードを使用します。 「コピー元画像」のサイズを指定すると、全体ではなくコピー元画像の領域を表示したい場合に役立ちます。これはさらに説明するための図です：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43467/c0b7fe15-0c8d-18aa-4af6-d75d0ae6fe21.png)
### 構文

image(img, x, y, [width], [height])

image(img, dx, dy, dw, dh, sx, sy, [sw], [sw])

### パラメタ

- img  
p5.Image  |  p5.Element：表示する画像

- x  
Number：コピー元画像の左上隅のx座標

- y  
Number：コピー元画像の左上隅のy座標

- width  
Number：コピー元画像を描画する幅(オプション)

- height  
Number：コピー元画像を描画する高さ(オプション)

- dx  
Number：コピー元画像を描画するコピー先長方形のx座標

- dy  
Number：コピー元画像を描画するコピー先長方形のy座標

- dw  
Number：コピー先長方形の幅

- dh  
Number：コピー先長方形の高さ

- sx  
Number：コピー先長方形に描画するコピー先画像のサブセクションのx座標

- sy  
Number：コピー先長方形に描画するコピー先画像のサブセクションのy座標

- sw  
Number：コピー先長方形に描画するコピー先画像のサブセクションの幅(オプション)

- sh  
Number：コピー先長方形に描画するコピー先画像のサブセクションの高さ(オプション)


### 例1

```javascript
let img;
function preload() {
  img = loadImage('./assets/mountain.png');
}

function setup() {
  createCanvas(500, 500);
  
  // コピー元画像を原寸大で表示します
  image(img, 0, 0);

  // コピー先長方形の左上隅を(0, 200)に指定して、
  // 幅と高さを 150 x 100に指定して画像を表示します
  image(img, 0, 200, 150, 100);
}
```
### 実行結果
https://editor.p5js.org/bit0101/sketches/aHxVxs9lA


### 例2

```javascript
let img;
function preload() {
  img = loadImage('./assets/mountain.png');
}

function setup() {
  createCanvas(500, 500);
  
  // コピー元画像を原寸大で表示します
  image(img, 0, 0);
  
  // コピー先長方形の左上隅を(0, 200)に指定して、
  // 幅と高さを 180 x 120に指定して画像を表示します
  // コピー元画像の位置は(150, 0)から開始して、150 x 100の領域をキャプチャします
  // キャプチャした画像をコピー先長方形に表示します
  image(img,  0, 200,  180, 120,  150, 0,  150, 100);
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/HjcbbSK2E

### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
Kritaのワークスペースをシンプル化

# はじめに
デフォルトのワークスペースで利用しないものを非表示させた。
ワークスペースの削除機能がKritaツール画面に無いのでファイルをエクスプローラから削除する必要がある。

調整するとこんな感じになる。

![ワークスペースを調整.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/7cb61968-0925-decf-3acf-1ddf3ceb134d.png)

# デフォルトのワークスペース
ソフトウェアのインストール先にデフォルトのワークスペースが保存されている。使わないワークスペースはエクスプローラから直接削除することで表示しないようにできる。

![krita_作成したワークスペースの保存場所2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/094f2e1e-4973-ea60-dfa5-430ffcf090fc.png)


# 自分が作成したワークスペース
![krita_作成したワークスペースの保存場所.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/422d5cb7-88c0-f624-35c0-2241205e5199.png)


# 参考
https://ch.nicovideo.jp/SteelPanthersTokiedian/blomaga/ar1014100
P5.js 日本語リファレンス(saveFrames)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の saveFrames関数を説明します。

## saveFrames() 


### 説明文

ムービーの作成に使用できる一連のフレームをキャプチャします。コールバックを受け入れます。たとえば、フレームをサーバーに送信してサーバーに保存したり、ムービーに変換したりできます。コールバックが提供されない場合、ブラウザは作成されたばかりのすべての画像をダウンロードしようとして保存ダイアログをポップアップします。提供されるコールバックでは、画像データはデフォルトでは保存されませんが, 代わりにオブジェクトの配列として引数としてコールバック関数に渡されます。配列のサイズはフレームの総数と同じです。

saveFrames() はアニメーションの最初の15フレームのみを保存することに注意してください。より長いアニメーションをエクスポートするには ccapture.js などのライブラリを調べます。

### 構文

saveFrames(filename, extension, duration, framerate, [callback])

### パラメタ

- filename  
String：ファイル名

- extension  
String："jpg" または "png"

- duration  
Number：フレームを保存する秒単位の期間

- framerate  
Number：フレームを保存するフレームレート(単位時間あたりのフレーム数)

- callback  
Function(Array)：画像データを処理するために実行されるコールバック関数。この関数は, 配列を引数として受け入れます。配列には、指定された数のオブジェクトのフレームが含まれます。各オブジェクトには3つのプロパティがあります：
imageData-画像/オクテットストリーム、ファイル名、拡張子(オプション)


### 例1

```javascript
let num;
function setup(){
  num = 0;
}

function draw() {
  createCanvas(100, 100);
  background(255);
  stroke(0);
  textSize(24);
  text(num, 20, 40);

}

// マウスをクリックするたびにフレームを保存する
function mousePressed() {  
  saveFrames(String(num), 'png', 1, 1);
  num ++;
}

```

### 実行結果
https://editor.p5js.org/bit0101/sketches/Q6rovJ_dC



### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
phpでcsvを読み込んで項目名をキーにした連想配列をつくる[メモ]

最近仕事でcsvのデータをプログラム内で使う場面が多かったので
自分用のメモとして書きます。よかったら参考にしてください。

```php:csvToArray.php
// csvの1列目をキーにした連想配列を返す（引数：csvファイルのパス）
function csvToArray($csvPath){
  $csvArray = array();
  $firstFlg = true;
  $keys = array();
  $count = 0;
  $file = fopen($csvPath, 'r');

  while ($line = fgetcsv($file)) {
    if($firstFlg){
      for($i = 0; $i < count($line); $i++){
        array_push($keys,$line[$i]);
      }
      $firstFlg = false;
    }else{
      for($i = 0; $i < count($line); $i++){
        $csvArray[$count][$keys[$i]] = $line[$i];
      }
      $count++;
    }
  }
  fclose($file);
  return $csvArray;
}
```

コピペで使えますが、もうちょっと綺麗に書けたかもしれないですね(笑)

##使い方
1列目が項目名になっているcsvファイルのパスを指定してください

```csv:opening_day.csv
"area","name","opening_day"
"トゥモローランド","スペース・マウンテン","1983-4-15"
"ウエスタンランド","ビッグサンダー・マウンテン","1987-07-04"
"クリッターカントリー","スプラッシュ・マウンテン","1992-10-1"
```

```php:main.php
$opening_day = csvToArray("./opening_day.csv");
var_dump($opening_day);
```

##出力結果
```php:$opening_day
array(3) {
  [0]=>
  array(3) {
    ["area"]=>
    string(24) "トゥモローランド"
    ["name"]=>
    string(30) "スペース・マウンテン"
    ["opening_day"]=>
    string(9) "1983-4-15"
  }
  [1]=>
  array(3) {
    ["area"]=>
    string(24) "ウエスタンランド"
    ["name"]=>
    string(39) "ビッグサンダー・マウンテン"
    ["opening_day"]=>
    string(10) "1987-07-04"
  }
  [2]=>
  array(3) {
    ["area"]=>
    string(30) "クリッターカントリー"
    ["name"]=>
    string(36) "スプラッシュ・マウンテン"
    ["opening_day"]=>
    string(9) "1992-10-1"
  }
}
```

こうしてcsvファイルをキー付きの連想配列にできました。

##csvToArray関数の説明（興味ない人は読まなくて大丈夫です）
コメントアウトで行ごとに説明してます

```php:csvToArray.php
// csvの1列目をキーにした連想配列を返す（引数：csvファイルのパス）
function csvToArray($csvPath){
  $csvArray = array();                            // 返す配列（入れ物の準備）
  $firstFlg = true;                               // 1周目の判別フラグ
  $keys = array();                                // 1列目の項目をキーとして保持しておく配列
  $count = 0;                                     // 2列目以降カウントする用の数値
  $file = fopen($csvPath, 'r');                   // ファイルを読み込む（r:読み込みモード）

  while ($line = fgetcsv($file)) {                // fgetcsvで行数のループ
    if($firstFlg){                                // 1周目 ---
      for($i = 0; $i < count($line); $i++){       // 項目数のループ
        array_push($keys,$line[$i]);              // 先ほど宣言したキー用の配列に格納
      }
      $firstFlg = false;                          // 1周目フラグをfalse
    }else{                                        // 2周目以降 ---
      for($i = 0; $i < count($line); $i++){       // 項目数のループ
        $csvArray[$count][$keys[$i]] = $line[$i]; // 先ほど宣言した返す配列に追加
      }
      $count++;                                   // 配列カウントを +1
    }
  }
  fclose($file);                                  // ファイルを閉じる
  return $csvArray;                               // 返送
}
```

##感想
fgetcsv は便利
Heroku環境でnatto/mecab gemを使えるようにする

## 目的
Heroku環境にはmecabがインストールされていないので，単純にpushするとビルドで落ちる．
`heroku-buildpack-mecab`とか，`heroku-buildpack-linuxbrew`を使う方法とかいろいろあったけど，
調べてみればみるほどdeprecatedの嵐． 
なんとかbuildpackでできないかと試行錯誤した結果が今回の`heroku-buildpack-apt`を使う方法．
`heroku-buildpack-apt`と`heroku-buildpack-ruby`を使って環境を構築した方法を記録．

## 対象
- Heroku上のRails/Sinatra環境でgem natto/mecabを使いたい人
- Dockerには詳しくなくて，Dockerを使わない方法で上の環境を揃えたい人

## heroku-buildpack-apt
- [heroku-buildpack-apt](https://github.com/heroku/heroku-buildpack-apt)
- Herokuチームから公開されているものの，下の`heroku-buildpack-ruby`のようなOfficial Supported Buildpackではなく，サポート対象外のbuildpack
- ubuntu環境ではあるものの，ファイルシステムがロックされてるので，パッケージインストールとかはできない．そこで登場するのがこいつ．
- レポジトリのルートに`Aptfile`というファイルを作り，インストールしたいパッケージのリストを書く

## heroku-buildpack-ruby
- [heroku-buildpack-ruby](https://github.com/heroku/heroku-buildpack-ruby)
- HerokuのOfficial Supported Buildpack
- Ruby, Rack, Sinatra, Railsアプリケーションを走らせる環境をHerokuに作れるやつ
- Ruby製のアプリケーションをpushしたときに自動で使用されるのがこれ

## 手順
### Gemfile
Gemfileで以下のgemがインストールされるようにする

```ruby:Gemfile
gem 'mecab', '0.996'
gem 'natto'
```

### buildpackの設定
```bash:bash
heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-apt
heroku buildpacks:add --index 2 heroku/ruby
```
これで，この二つのbuildpackを使った環境ができる
[参考](https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app)

### 環境変数の設定
buildpack経由で`/app/.apt/usr/lib/x86_64-linux-gnu`配下にインストールされる．
mecabrcは`/app/.apt/etc/mecabrc`に入る．
そこにパスを通していく

```bash:bash
heroku config:set MECABRC=/app/.apt/etc/mecabrc
heroku config:set MECABRC=/app/.apt/etc/mecabrc
heroku config:set MECAB_PATH=/app/.apt/usr/lib/x86_64-linux-gnu/libmecab.so
```

### Aptfileの作成
`heroku-buildpack-apt`にインストールしてもらいたいパッケージを書いていく．
レポジトリのルートに`Aptfile`を作成する

```txt:Aptfile
mecab
libmecab-dev
mecab-ipadic
mecab-ipadic-utf8
```

### デプロイ
デプロイする

```bash:bash
git add .
git commit -m 'commit message'
git push heroku master
```


## 結論
buildpackで頑張ったけど，Dockerでやるのが圧倒的に平和だと思う．
アセンブリ言語(CASL2)を学習#2

#はじめに
　前回に引き続きCASL2をやっていきます。今回は簡単な演算をやります。
#CASL2について
 COMET2は１語(ひとつのデータ)を16ビットとし、#0000~#FFFF（0~65535）まで表すことができます。また、命令語は2語長で32ビット構成です。
#2の補数表現について
　２の補数でマイナスの表現ができます。
　２の補数とはビット反転し１を加えた値のことを言います。
　　例）-9を２の補数表現で表す。
　　　9 = (1001)₂
　　　ビット反転すると　(0110)₂
　　　さらに１を加えて　(0111)₂
　　　よって-9 = (0111)₂
#コード1(ADDA命令,SUBA命令)
```PULAS.cas
PULAS     START                  ;プログラムの開始
          LD      GR0, DATA1     ;GR0にDATA1を格納
          ADDA    GR0, DATA2     ;GR0にGR0+DATA2を格納    
          ST      GR0, KOTAEA    ;KOTAEAにGR0を格納
          RET
DATA1     DC      #FFFF          
DATA2     DC      1         
KOTAEA    DS      1              ;データ領域の確保
KOTAES    DS      1              
          END
```
##LD命令、ST命令
　LD命令はメモリから凡用レジスタにデータを格納します。
　ST命令は凡用レジスタからメモリにデータを格納します。
　いずれの場合も、オペランドはレジスタとアドレスです。
##DS命令
　DS命令はオペランドで指定した値の分だけデータ領域を確保します。
##ADDA命令、SUBA命令
 指定したレジスタとアドレスの値を足して(引いて)レジスタに格納します。
ADDA命令、SUBA命令では最上位ビットを符号として表します。
そのため　#FFFF=-1　となるため上のコードでは　
GR0 = #FFFF(-1) + #0001(1) = 0　となります。
#コード2(ADDL命令,SUBL命令)
```PURAS.cas
PULAS     START                  ;プログラムの開始
          LD      GR0, DATA1     ;GR0にDATA1を格納
          ADDL    GR0, DATA2     ;GR0にGR0+DATA2を格納    
          ST      GR0, KOTAEA    ;KOTAEAにGR0を格納
          RET
DATA1     DC      #FFFF          
DATA2     DC      1         
KOTAEA    DS      1              ;データ領域の確保
KOTAES    DS      1              
          END
```
##ADDL命令、SUBL命令
　指定したレジスタとアドレスの値を足して(引いて)レジスタに格納します。
ただし、ADDL命令、SUBL命令は符号なしで考えます。
そのため、#FFFF = 65535(2¹⁶-1)　となり、上のコードでは
GR0 = #FFFF(65535) + #0001(1) = #10000(65536)　となります。
ひとつのデータは16ビットであるのでオーバーフローとなります。
なので、GR0は0、OFに1が格納されます。

#コード(AND命令、OR命令、XOR命令)
```LOGIC.cas
LOGIC     START
          LD      GR0, DATA
          AND     GR0, DATA2
          RET
DATA      DC      13
DATA2     DC      8
          END
```
##AND命令
　指定したレジスタとアドレスの値で論理積を行い、レジスタに格納します。
DATA,DATA２を２進数で表すと　13 = (1101)₂、8 = (1000)₂　となります。
よって GR0 = (1000)₂ = 8　となります。
論理和、排他的論理和も同様になります。


#終わり
　#~は16進数、(~)₂は２進数をあらわします。次回は分岐条件をやろうと思います。
P5.js 日本語リファレンス(saveCanvas)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の saveCanvas関数を説明します。

## saveCanvas() 

### 説明文

現在のキャンバスを画像として保存します。ブラウザはファイルをすぐに保存するか、ダイアログウィンドウでユーザーに次の操作を促します。

### 構文

saveCanvas(selectedCanvas, [filename], [extension])

saveCanvas([filename], [extention])

### パラメタ

- selectedCanvas  
p5.Element  |  HTMLCanvasElement：特定のhtml5キャンバスを表す変数(オプション)

- filename  
String：(オプション)

- extention  
String：'jpg'または 'png'(オプション)


### 例1

```javascript
function setup() {
  let c = createCanvas(100, 100);
  background(255, 0, 0);

  // 背景色が赤色の画像をファイル名 myCanvas.jpg で保存する
  saveCanvas(c, 'myCanvas', 'jpg');
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/DUAUfrZWU



### 例2

```javascript
//この例は上記と同じ結果になることに注意してください
//キャンバスが指定されていない場合, メインキャンバスがデフォルトになります
function setup() {
  let c = createCanvas(100, 100);
  background(255, 0, 0);

  //以下のすべてが有効です
  saveCanvas(c,  'myCanvas',  'jpg');
  saveCanvas(c,  'myCanvas.jpg');

  // extention を省略すると png になります
  saveCanvas(c,  'myCanvas');

  // ファイル名を省略すると untitled.png になります
  saveCanvas(c);

  // ファイル名を省略すると untitled.png になります

  saveCanvas() ;}

```

### 実行結果
https://editor.p5js.org/bit0101/sketches/DROhpWIkR


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。