OmniAICreator/Qiita-1.07M huggingface dataset:
Memcached、Redisをコマンドからサクッとset、get、delete

動作確認を行っていると、キャッシュ（Memcached, Redis）に何が入ってるのか確認したくなることが多々あるのでその備忘録（1ラインコマンド）。

# Memcached
## set
setの書き方は2段階で「set key flags 有効期限(秒) valueのバイト数」と「value」

```shell:KEY1に有効期限60秒で、6バイト文字列のVALUE1を格納
$ (echo set KEY1 0 60 6; echo VALUE1; sleep 1; echo quit) | telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
STORED
Connection closed by foreign host.
```
※setのflagsについてはここがわかりやすかった
https://songmu.jp/riji/archives/2013/05/memcachedflags.html

## get
```shell:KEY1を取得
$ (echo get KEY1; sleep 1; echo quit) | telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
VALUE KEY1 0 6
VALUE1
END
Connection closed by foreign host.
```
## delete
```shell:KEY1を削除
$ (echo delete KEY1; sleep 1; echo quit) | telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
DELETED
Connection closed by foreign host.
```

# Redis
## set
setは「set key value」

```shell:KEY2にVALUE2を格納
$ redis-cli -h 127.0.0.1 set KEY2 VALUE2
OK
```
## setex
setexは「setex key 有効期限（秒） value」

```shell:KEY3に有効期限60秒のVALUE3を格納
$ redis-cli -h 127.0.0.1 setex KEY3 60 VALUE3
OK
```
## get
```shell:KEY3を取得
$ redis-cli -h 127.0.0.1 get KEY3
"VALUE3"
```
## keys
```shell:キー一覧取得
$ redis-cli -h 127.0.0.1 keys "KEY*"
1) "KEY2"
2) "KEY3"
```
## del
```shell:KEY2を削除
$ redis-cli -h 127.0.0.1 del KEY2
(integer) 1
```
laradock を複数プロジェクトで使い回す

# 解決する課題

- 複数のlaravelプロジェクトがある
- それらを同時に開発することはない
- このとき、laradockを使いまわしたい

# やり方

## Directory構成

下記構成にします

- _laradock/ `使い回すlaradock`
    - .env.base `.envのベースとなる`
    - .env
- project1/
    - www/ `project1 の ソースコード`
    - .laradock/ `project1 の DB data`
    - docker.sh
- project2/
    - www/ `project2 の ソースコード`
    - .laradock/ `project2 の DB data`
    - docker.sh

## .env.baseの中身

プロジェクト別に変えたい項目を下記のように書き換えます。
下記は一例です。

```ini:.env.base
APPLICATION=../%APPLICATION%/www
DATA_SAVE_PATH=../%APPLICATION%/.laradock/data
NGINX_HOST_HTTP_PORT=%NGINX_HOST_HTTP_PORT%
```

## docker.shの中身

```bash:docker.sh
cd ../_laradock

docker-compose down

cp .env.base .env

sed -i -e s/%APPLICATION%/project1/ .env
sed -i -e s/%NGINX_HOST_HTTP_PORT%/9105/ .env

docker-compose up nginx mysql
```

## プロジェクトの起動

それぞれのプロジェクト下の docker.shを実行すればいけます。

```bash
cd project1
docker.sh
# http://localhost:9105
```
7日目　メディアクエリ以外のレスポンシブ対応指定方法！

#メディアクエリ以外のレスポンシブ対応指定方法！
今までPC版、スマホ版の画像の切り替えは、以下のように
メディアクエリを使用して行なっていました。

```HTML
<!-- HTML -->
<img class="pcImg u-pcOnly" src="...">
<img class="spImg u-spOnly" src="...">
```

```CSS
/*CSS*/
.u-spOnly {
   display: none;       /*こっちはPC版では表示しない*/
}

@media all and (max-width:768px) {
   .u-pcOnly {
      display: none;    /*こっちはスマホ版では表示しない*/
   }
   .u-spOnly {
      display: block;   
   }
}
```

ユーティリティクラスにして、タグに付けはずしするイメージです。
しかし、他にも方法があることを今日学びました！

##①解像度ごとの表示切り替えなど

```CSS
<img sizes="(min-width: 960px) 75vw, 100vw" srcset="img-1440.png 1440w, img-720.png 720w, img-360.png 360w" src="default-image.png">
```

sizes属性、srcset属性の使用方法です。
こちらで注意が必要なのは、**HTML5.1**から追加された機能なので、一部非対応のブラウザがあるということです。

**secset属性**
使用される画像の選択候補を設定する。
画像ファイルの横幅（w）もしくはデバイスピクセル（x）のどちらかを指定することができる。

**sizes属性**
画像の表示サイズ（横）を指定できる。初期値100vw。
メディアクエリでブレイクポイントを設けることができる。割合では%でなくvwを使用する。

###注意！
secset="small.png 768w,large.jpg 1280w"
sizes="50vw"
で、ビューポートが1280wのとき、何が表示されるでしょうか、、？
→sizesがビューポートの５０％(=640w)なので、smallが表示されます。

##②pictureタグでの表示切り替え
```HTML
<picture>
  <source media="(min-width: 960px)" srcset="img-pc.jpg">
  <img src="img-sp.jpg">
</picture>
```
pictureタグの使用です。
上の例だと、スマホ（幅960pxまでの時）にはソースタグの画像が、
pc（幅960以上の時）には下の画像が表示されます。

こちらも**HTML5.1で新しく加わった要素**なので、対応ブラウザには注意しないといけないです。

うまく指定して、レスポンシブ対応を目指します！
CentOS7でGoのHelloWorldを動かす手順

Go言語の[公式ページ](https://golang.org/)にあるHelloWorldをCentOS7で実行してみます。

#実行環境
[こちら](https://qiita.com/jellyjelly/items/be7e4f7462fcc4b4023b)で構築しました。

#実装準備
ソースを保存するディレクトリを作成します。

```
$ mkdir -p ~/go/src/hello
```
#実装

`$ vim ~/go/src/hello/hello.go`

```hello.go
package main

import "fmt"

func main() {
	fmt.Printf("hello, world\n")
}
```

#ビルド

```
$ cd ~/go/src/hello
$ go build
$ ls
hello  hello.go
```
hello（実行ファイル）ができました。

#実行

```
$ ~/go/src/hello/hello
hello, world
```
hello, world が出力されました。

#後始末
作成した実行ファイルを消します。

```
$ cd ~/go/src/hello
$ go clean -i
$ ls
hello.go
```

以上です。
ESP32-CAM で撮影した画像を SDカードに書き込む

# 概要
Ai-ThinkerのESP32を載せたカメラモジュール
https://amzn.to/2FAvrNa

ちょっとこれを触る機会があったのですが、Arduinoサンプルを動かしている人はたくさんいたもののSDカードに画像を保存する方法がなかなか見つからなかったので、とりあえずメモしておきます。

# 環境
Arduino IDE を使う想定です（その辺の使い方とかは割愛しますが、、）

# いきなりコード
たいした量ではないし、難しいことをやっているわけでもないので、ソースを見るのが一番早い気がするのでソース載せておきます（必要なところだけの抜粋です）。

どうやら "SD.h" ではなくて "SD_MMC.h" を使う必要があるらしい、というところだけがポイント。

```sd_save.c
#include "FS.h"
#include "SD_MMC.h"
#include <time.h>

bool isSDExist = 0;

int setupSD(){
  int sdRet = SD_MMC.begin();
  Serial.printf("setupSD: SD_MMC.begin() -> %d\n", sdRet);

  uint8_t cardType = SD_MMC.cardType();
  if(cardType != CARD_NONE){
    isSDExist = 1;
  }

  switch(cardType){
    case CARD_NONE: Serial.println("setupSD: Card: None");      break;
    case CARD_MMC:  Serial.println("setupSD: Card Type: MMC");  break;
    case CARD_SD:   Serial.println("setupSD: Card Type: SDSC"); break;
    case CARD_SDHC: Serial.println("setupSD: Card Type: SDHC"); break;
    default:        Serial.println("setupSD: Card: UNKNOWN");   break;
  }
}

void takePic(camera_fb_t* fb){
  Serial.println("takePic: Start");
  if(!isSDExist){
    Serial.println("takePic: SD Card none");    
    return;
  }

  if (!fb) {
    Serial.println("takePic: image data none");
    return;
  }

  time_t t = time(NULL);
  struct tm *tm;
  tm = localtime(&t);
  
  char filename[32];
  sprintf(filename, "/img%04d%02d%02d%02d%02d%02d.jpg",
    tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    
  fs::FS &fs = SD_MMC;
  File imgFile = fs.open(filename, FILE_WRITE);
  if(imgFile && fb->len > 0){
    imgFile.write(fb->buf, fb->len);
    imgFile.close();
    Serial.print("takePic: ");
    Serial.println(filename);
  }else{
    Serial.println("takePic: Save file failed");
    Serial.printf("takePic: imgFile: %d\n", imgFile);
    Serial.printf("takePic: fb->len: %d\n", fb->len);
  }
}
```

# 備考
setup() あたりで setupSD() を呼んでおいて、何か画像を保存したい契機で

```
fb = esp_camera_fb_get();
takePic(fb);
esp_camera_fb_return(fb);
```

こんな感じで takePic() を呼んでもらうと "img_現在時刻.jpg" みたいなファイルが保存されます。

# 全ソース
こちらを使用したWebカメラ的なものを以下で公開しています。
ご参考にどうぞ。
https://github.com/manontroppo1974/MiniWebCamera
2019, 最近のpythonの環境管理を調べ始めた

# 今更pythonを使い始める

わけあってpythonを使う必要性に駆られたので、最近の環境分離系のデファクトについて調べたのでメモしておく。

## 前提とする環境

- macos
- python3.6以降

## python仮想環境の概要

## 環境分離

pyvenvがpython3.3以降標準で使える。virtualenvを標準に取り込んだもの。
これを使うのが間違えなさそう。

ライブラリの場所を切り替えることができる。

### 処理系切り替え(使わない方向で)

pyenvというのがある。
python処理系のバージョンを複数管理することができる。
基本的に最新のpythonで動作させる方が良さそうなので、pyvenvで事足りるのであればあまり使わない方がいいかも。

### pipenvとかどうよ(使うか悩ましい。)

pyvenv, pipでできることを、`よりクールでヒップに`できるようにするツール。
rubyのbundlerみたいな感じ。

- pipenvコマンドを起点にする。
- pyvenv, pipの雑多な操作をラップしてくれる。
- `pip freeze`よりも高度なパッケージロックを提供してくれる。

pyvenv, pipでミニマルにやるのが良さそうだけど、どうなんだろう。

### rubyとの比較

|                          | python       | ruby    |
| ---                       | ---           | ---      |
| パッケージリポジトリ     | pip          | gem     |
| パッケージバージョン固定 | pip          | bundler |
| 環境分離                 | pyvenv(venv) | bundler |
| 処理系切り替え           | pyenv        | rbenv   |

rubyがgemとbundlerで解決していることを、pythonはpipとvenvで解決している。
ここでいう解決したいこととは、

- パッケージの名前空間を分離する。
- パッケージのバージョン依存を管理する。
- パッケージのバージョンを固定する。

処理系切り替えは、あまり関わらない方が良さそうだ。
rbenvもいい思い出がない。

## venv, pipを使ってみる

### 分離環境作成

```
$ python -m venv ~/dev/py1
```

### 分離環境に入る

```
$ . ~/dev/py1/bin/activate # "." === "source" on bash
$ pip install tensorflow
```

シェルスクリプトの`activate`を読めばわかるけど、
`~/dev/py1/bin`を`PATH`の先頭に設定することで、python, pipコマンドを仮想環境のものを呼ぶようにしているだけ。

## pipenvを使ってみる。

```
## install pipenv
$ sudo python -m pip install pipenv

$ mkdir ~/dev/pipenv1
$ cd ~/dev/pipenv1

## ref:https://docs.pipenv.org/en/latest/advanced/#configuration-with-environment-variables
## `.venv`を`~/dev/pipenv1`配下に作るよう環境変数を設定する。
$ export PIPENV_VENV_IN_PROJECT=1

## pipenv環境を初期化する。`.venv`, `Pipfile`などを生成する。
$ pipenv --python 3.7

## 試しにhylangをインストールする。Pipenv.lockを生成or更新してくれる。
$ pipenv install hy=0.17.0

## 環境配下でコマンドを実行する。rubyの`bundle exec`に相当する。
$ pipenv run pip list

## 環境に入る。
$ pipenv shell
```

使ってみた感じまあ良さそう。絵文字とか色制御文字が多用されているのがヒップな感じで鬱陶しいけど。
`venv`同様、pythonが公式に取り込むかもしれない。

pythonてユーザが多いせいか、javascriptと同じ感じでえらくヒップになってるな。

## 結論

`pipenv`使ってみるかな。`Pipenv`, `Pipenv.lock`の仕組み以外は`pip`と`venv(virtualenv)`をラップしているだけのように見えるので、
いざとなれば抜けることはできそう。

`flask`でもいじってみるかな。

## 個人的は背景

過去にjythonやcpythonで簡単な処理を書いたり、zopeやploneでwikiを立ち上げて運用していたことはあるけど、
長らくperl, ruby (そしてcommon lisp)を使う日々が続いた。

もちろんC, SQL, javascriptはこれまでも、そしてこれからも長く付き合っていく言語である。
posix, 永続化, webブラウザというプラットフォームを握っている以上逃れることはできない。

業務でpythonを使うこともなくはなかったけど、メインはperl, ruby, cだった。

個人的にperlは、レシシカルクロージャが作れてシンタックスも簡潔だし、
弱点がない言語であると(今だに)思うものの、人気が低下してしまい、仕事の量が少ないのは個人の力ではどうしようもない。

事情があってpythonを使うことになったので、最近のpython事情について調べつつメモしていこうと思う。

pythonのインデントシンタックスは言語的な欠陥だと思うものの、まあいざとなったらhylangでしのぐかと考えている。
Google Coral Dev Boardを購入する場所

きっとこの新しい技術は、愛好家にとっては高すぎるのでしょうか。
意外なことに、いいえ、Coral Dev Boardの価格は149.99ドルで、同様のハイエンド開発用ボードに匹敵するものですが、USB Acceleratorはまだ安価で、まったく新しい開発用ボードを購入したくない場合には最適な選択肢です。
GoogleパートナーのGravitylink Store Webサイトからコンポーネントを入手できます。

https://store.gravitylink.com/global

開発ボード： $149.99
USBアクセラレータ：$ 74.99
カメラモジュール：$ 24.99

Google Coral Dev Board

![unnamed-_3_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/1a0384ed-7662-a510-9626-746a7b7dcf8b.jpeg)



Coral Dev Boardは、eMMC、SOC、ワイヤレスラジオ、およびGoogleのEdge TPUを含む、取り外し可能なシステムオンモジュール（SOM）を搭載したシングルボードコンピューターです。小型フォームファクタでの高速ML処理。ただし、SOMの評価キットとしても機能します。

Dev Boardを使用して、モノのインターネット（IOT）デバイスや高速オンデバイスML推論を必要とするその他の組み込みシステムをプロトタイプ化し、40 mm x 48 mm SOMボードとカスタムPCBを組み合わせて実運用に拡張できます。ボード間コネクタを使用したハードウェア
Edge TPUの主な利点
・高速TensorFlow Lite推論
・ローパワー
・小さい足跡
ベースボードには、USB 2.0 / 3.0ポート、DSIディスプレイインターフェイス、CSI-2カメラインターフェイス、イーサネットポート、スピーカー端子、40ピンGPIOヘッダーなど、プロジェクトのプロトタイプ作成に必要なすべての周辺機器接続が含まれています。

Google Coral USB Accelerator

![unnamed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/02455cff-cb5b-187e-2e74-cb9cfe9f8b33.jpeg)

Coral USB Acceleratorは、Edge TPUコプロセッサをシステムに追加するUSB​​デバイスで、USBソケットを備えているため、Linuxベースのシステムに接続して高速化ML推論を実行できます。
オンボードのEdge TPUは、高性能のML​​推論を低消費電力で提供する、Googleが設計した小型のASICで、たとえばMobileNet v2などの最先端のモバイルビジョンモデルを100+ fpsで実行できます。
oneWEXにWatson Knowledge Studioのモデルを連携してみた

#はじめに
Watson Explorer Analytical Componentの既存機能として、Watson Knowledge Studio（WKS）のモデルを連携し、機械学習によってテキストをエンリッチすることができます。
同様のことが、oneWEX 12.0.2.2 からできるようになったため、試してみました。

（参考）
Watson Knowledge Studio
https://www.ibm.com/watson/jp-ja/developercloud/knowledge-studio.html

Release Notes - IBM Watson Explorer oneWEX, Version 12.0
https://www-01.ibm.com/support/docview.wss?uid=swg27050305#new12022

**お断り** 
・WKSの操作についてはここでは解説しません。
・WKSで作成したモデルをoneWEXに連携するためにはモデルをExportする必要がありますが、モデルをExportするためにはWKSの有料ライセンスが必要となりますのでご注意ください。
・WKSでExportしたモデルがあることを前提に試した手順を紹介します。

#WKSのモデルをoneWEXに取り込む
oneWEXのAdmin Consoleにログイン後「リソース」タブに移動。
「アノテーターの追加」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/8cad5497-2e92-186d-b0af-5b72c477d142.png)

「名前」に適当な名前を入力し、「アノテーター・タイプ」で「機械学習」を選択し、
「次へ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/76aacd91-1c7e-1573-54b6-295e2044dd6e.png)

タイプがWatson Knowledge Studioになっていることを確認し、
「ファイルの選択」でWKSからExportしたモデルを指定する（モデルはzipファイルでダウンロードされるのでそのまま指定）。
ファセット・パスに任意の名前を入力し「保存」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/6152fc7c-803c-0a4a-b7ae-0a8dd400e601.png)

内容を確認し「クローズ」
　　基本タブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/4b0f3a24-06e7-dd16-aaf0-3f40359a1966.png)
　　機械学習タブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/7d534b03-4ad7-57fc-4e7c-8c67c3d0df32.png)


#コレクションへの適用
Admin ConsoleからWKSモデルによりエンリッチさせたいコレクションを開き「エンリッチ」タブに移動。
先ほど連携したモデルがアノテーターに表示されるため、チェックを入れて「保存」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/41d4abe1-27b2-dc44-1c4c-35c882a9df88.png)

変更を有効にするために索引の再作成が必要なため「はい」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/a65e0edf-4045-2129-c28a-c9c659b5b89e.png)

設定は以上。
索引再作成が完了したら結果を確認する。

#確認
Content Minerからコレクションを開くと、設定時に指定したファセットが表示される。
そのサブファセットにWKSでアノテートしたEntityやRelationが表示される。
PART_OF_CARはWKSで車のパーツについて学習させたEntity。
車のパーツが抽出されているのがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/4ad82060-2fe7-b358-69b4-d28b8c320d97.png)

Relationも同様。
WKSで車の症状について学習させている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148302/3e2b18e1-dec8-6679-9805-d727ffd98718.png)


以上
---

**お断り**
このサイトの掲載内容は私自身の見解であり、必ずしも所属会社の立場、戦略、意見を代表するものではありません。 記事は執筆時点の情報を元に書いているため、必ずしも最新情報であるとはかぎりません。 記事の内容の正確性には責任を負いません。自己責任で実行してください。
How to create /metrics on connexion

# Overview

connexionとはOASを利用してAPIエンドポイントとpython関数をmapするためのpythonパッケージです。

https://connexion.readthedocs.io/en/latest/

Flaskベースで作成されており、flaskではdecorationで @app.route("/") 等と
エンドポイントを指定してHTTPリクエストと関数の関係を記述していたものを、OAS側に記載することで
ドキュメントと機能の実装を同時にできるという優れもの。

使い方やConnexionの説明は今回の趣旨では無いので詳しくは下記等を参照していただけると良い。

https://qiita.com/amuyikam/items/1454177a7030e3b3ce80

## How to create /metrics for Prometheus

connexionはAPIのフロントエンドを作る上で非常に便利だが、そういう使い方なので
実際のAPIを提供しているものについて監視などもできると非常に便利。
昨今はPrometheusを使うのが流行っているようなので同様に作ってみようと思うと
なんらかのexporterを使う or 作ることになる。

flaskをそのまま使っているならばこちらを組み込み、flaskとしてhttp serverを起動する際に
フックしてやればいいのだが、残念ながらconnexionをフックするだけでは動作しない模様。
https://pypi.org/project/prometheus-flask-exporter/

swagger.ymlを読んでいるが故に起動プログラムの所にいきなりの記述はできない。
ということでswagger.ymlから呼ばれるプログラムを上手いことやってやる必要があるようだ。

### Create swagger.yml

こんな風に /metrics　パスを切り、ここをprometheus向けのexporter URLとする。

```yaml

  /metrics:
    get:
      summary: Prometheus metrics exporter page
      description: Return metrics for prometheus 
      operationId: prometheus_exporter.Prometheus_exporter.showmetrics
      tags:
        - prometheus
      responses:
        default:
          $ref: '#/components/responses/example'
```

### python method

呼ばれるプログラム自体はこんな風にしておく。
prometheus_clientをロードしREGISTRY等を登録する。
こうしておけばmetricsをええ具合に公開できるようになる。
どのようなデータを公開するかはprometheus_clientの仕様と
入れたいデータに依存するのでこれまた割愛。

```python
#!/usr/bin/env python3
#  -*- coding: utf-8 -*-
from prometheus_client import generate_latest
from prometheus_client import Gauge
from prometheus_client import REGISTRY
from api import hpe


class Prometheus_exporter(object):
    registry = REGISTRY

    @classmethod
    def showmetrics(self):

        metrics = generate_latest(self.registry)
        return metrics, 200

```
SQLで年月の連続データを作成する（Oracle）

Oracleのデータベースを使って集計クエリを書いたときに使った内容

* 年月を基軸にして集計データを作成するときに使いました
    * データ上にない年月を集計データ上、NULL行として抽出したい場合

```
SELECT
  TRUNC(ADD_MONTHS(A.YM_FROM, ROWNUM - 1),'MM') AS YM_DATE,
  TO_CHAR(TRUNC(ADD_MONTHS(A.YM_FROM, ROWNUM - 1),'MM'),'YYYYMM') AS YM_CHAR
FROM
(
  SELECT
    TRUNC(TO_DATE('201801', 'YYYYMM'),'MM') AS YM_FROM,
    TRUNC(TO_DATE('201912', 'YYYYMM'),'MM') AS YM_TO
  FROM DUAL
) A
CONNECT BY LEVEL <= MONTHS_BETWEEN (A.YM_TO , A.YM_FROM) + 1
```
Google AIY VoiceおよびVision Kitは、Gravitylink Storeから入手可能です

AIY Projects Voice and Vision Kitsが大成功を収めた後、GoogleはRaspberry Pi Zero WH、Camera Module、およびプリロードされたSDカードを含むアップグレードキットのリリースを発表しました。
![微信截图_20181112135837.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/9f762c3e-23a5-0905-98e3-e1aa82225d11.png)

Vision Kit

![微信截图_20181112135812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/5fbd7d38-34a4-8e88-36a3-367aa0359731.png)

Voice Kit
キットには、最近発売されたRaspberry Pi Zero WHが含まれています。これには、インスタントデジタルメーカのアクセスを容易にするために、はんだ付けされたヘッダーピンが追加されています。 キットの購入者は、カードを自分でセットアップする必要なしにそれらが始められるのを助けるためにプリロードされたOSが付いているマイクロSDカードも手に入れるでしょう。


Googleは、Android、iOS、およびChrome用のAIYプロジェクトコンパニオンアプリケーションの作成にも懸命に取り組んでいます。 Androidアプリは、アップグレードされたキットの発売と同時に発売される予定です。他の2つは近日中にリリース予定です。 熱心なコーダーはまだ彼らのプロジェクトによりよく合うように彼らをハッキングすることができるでしょうがアプリはAIYキットの無線設定をサポートします。

 

最新のVoice and Vision Kitは、Gravitylink Storeから入手可能です:

( https://store.gravitylink.com/global )
BigQuery のデータのロケーション移行

(追加で備忘録残したくなったら随時更新)

## 1. ワイルドカードテーブル

### 経緯

- BigQuery 便利だけどロケーションを跨げない
- 昔から使ってると US ロケーションだったりして
- でも asia-northeast1 (Tokyo) とかとっくに出てるからそっち使っちゃいたいし
- 直接コピーすらできないから GCS を介してやり取りする
- けどワイルドカードテーブルとか日時でテーブル作ってると膨大にあってだるい

### 解決策

- コマンド組んで一気にやるしかなかろう

```bash
# --- local ---

$ # gcloud / gsutil / bq コマンドが叩ける docker コンテナ
$ docker run -it --rm --name gcp-sdk google/cloud-sdk:latest

# --- container ---

% # jq を使うので追加でインストール
% apt-get install -y jq

% # 認証
% gcloud auth login

% # bq コマンドの初期起動時の stdout に流れるうるさいメッセージを出さないためのファイル用意
% touch .bigqueryrc

% project=ppp
% old_dataset=old_ddd
% new_dataset=new_ddd
% target_table=ttt
% bucket=bbb

% # bq コマンドが叩けるはず
% # e.g. bq --bigqueryrc=.bigqueryrc --project_id=${project} ...

% # とりあえず移行したいテーブルのスキーマを取得する (--autodetect は DATETIME 型とか使ってると困るのでやらない)
% last_table=$(\
    bq --bigqueryrc=.bigqueryrc --format=json --project_id=${project} ls -n 10000 ${old_dataset}\
    | jq -r --arg tbl_prefix ${target_table} '[.[] | select(.tableReference.tableId | startswith($tbl_prefix)).id] | last'\
  )
% bq --bigqueryrc=.bigqueryrc --format=json --project_id=${project} show ${last_table} | jq '.schema.fields' > ${target_table}.schema.json

% # GCS にいっぺんに持ってくる
% bq --bigqueryrc=.bigqueryrc --format=json --project_id=${project} ls -n 10000 ${old_dataset}\
  | jq -r --arg tbl_prefix ${target_table} '.[] | select(.tableReference.tableId | startswith($tbl_prefix)).id'\
  | xargs -t -I {table} -P30 bash -c "bq --bigqueryrc=.bigqueryrc --project_id=${project} extract --destination_format=NEWLINE_DELIMITED_JSON {table} gs://${bucket}/backup/${target_table}/{table}/data.json"

% # GCS のデータをいっぺんにアップロードする
% bq --bigqueryrc=.bigqueryrc --format=json --project_id=${project} ls -n 10000 ${old_dataset}\
  | jq -r --arg tbl_prefix ${target_table} '.[] | select(.tableReference.tableId | startswith($tbl_prefix)).id'\
  | xargs -t -I {table} -P30 bash -c "bq --bigqueryrc=.bigqueryrc --project_id=${project} load --source_format=NEWLINE_DELIMITED_JSON --replace=false \$(echo {table} | sed 's/${old_dataset}/${new_dataset}/g') gs://${bucket}/backup/${target_table}/{table}/data.json ${target_table}.schema.json"
```
Vim で Python 用の設定が効かないときの対処

主に自分用メモとして：

`vim/ftplugin/python.vim` などで以下のような設定をしているのに、いざ`.py`ファイルを開いてみると反映されてないとき

```vim
setlocal tabstop=4
setlocal noexpandtab
```

`.vimrc` とかに以下を追記する

```vim
let g:python_recommended_style = 0
```

Vim はデフォルトで PEP8 準拠な表示になるようにいろいろやってくれているらしい。
[勉強用] React hooksで非同期処理を書く (ステップ3)

## はじめに

[前ステップ](https://qiita.com/daishi/items/2c40e27f7589231dbcef)から続き、勉強用のuseFetchを書いていきます。今回のテーマはローディング処理です。

## 課題

非同期処理は、結果が得られるまでに時間がかかることが多いです。そこで、処理が完了するまでは何らかのローディング状態を表示するなどしておくことが望ましいです。

## ステップ3: loadingフラグ

```javascript
const useFetch = url => {
  const [result, setResult] = useState({});
  useEffect(() => {
    let cleanedUp = false;
    const fetchData = async () => {
      const response = await fetch(url);
      const data = await response.json();
      if (!cleanedUp) {
        setResult({ data });
      }
    };
    setResult({ loading: true });
    fetchData();
    const cleanup = () => {
      cleanedUp = true;
    };
    return cleanup;
  }, [url]);
  return result;
};
```

非同期処理を開始する直前にloadingフラグをセットします。これにより、非同期処理開始後にコンポーネントが再描画されて、loadingフラグにより表示制御ができるようになります。


ちなみに、Suspenseが使えるようになれば、そちらが主流になることが予想されるため、loadingフラグによる処理は過渡的なものになるかもしれません。

## 動作確認

実際に動くコードはこちらです。[codesandbox](https://codesandbox.io/s/epic-blackwell-bv1ux)

## おわりに

本コードは勉強用ですので、そのままでは使わないでください。(ちゃんとした実装は[こちら](https://qiita.com/daishi/items/f12f524e9d1df0b52d2b))
さらなる課題と解決は[次のステップ](https://qiita.com/daishi/items/873dca99cd18bb86239c)へ。
ELECROW 3.5インチ HDMI液晶モニターの設定に苦労した話

# 概要
ELECROW 3.5インチ HDMI液晶モニター
https://amzn.to/2NayEsX

Raspberry pi につなげるための小さいモニターを探してた。
レビューを読むとHDMI接続でとても簡単そうなのであまり苦労もなさそうだと思って買ってみた。映像はたしかに簡単に出たのだけど、タッチパネルが全然言うことを聞いてくれなくて大変だったので、ここにメモしておく。

# 症状
ELECROW のサイトからドライバをダウンロードしてきて所定のコマンド入れてみた。多くの人はそれでちゃんと動いているらしいのだけど、どうもタッチパネルの座標がおかしい、タッチしたまま指を上下方向に動かすとマウスカーソルが左右に動く。指を左右に動かすとマウスカーソルは上下に動く。。こいつ、XY軸間違ってないか？

# 環境
- Raspberry Pi 2（うちで余ってた）
- ELECROW 3.5インチ HDMI液晶モニター（上記のやつ）

# とりあえず調べてみた
大抵の人はドライバ入れたら動いてるみたいだけど、タッチパネルがおかしいって人もちょいちょいいるらしい。その方々がやってるのはタッチパネルのキャリブレーション。

```
> sudo apt-get xinput-calibrator
> DISPLAY=:0.0 xinput_calibrator
```
こんな感じ？
（PCからTeraTermでつないでコマンド実行してるのでDISPLAY指定）
で、これだと症状改善しませんでした。
調べた限りだと多くの人はこれで直ってるっぽいんだけどな。。

こんな感じのエラーが出てます。
> Calibrating standard Xorg driver “eGalax Inc. USB TouchController”
> current calibration values: min_x=0, max_x=65535 and min_y=0, max_y=65535
> If these values are estimated wrong, either supply it manually with the ?precalib option, or run the ‘get_precalib.sh’ script to automatically get it (through HAL).


# 解決まで
行き当たったのがこのページ
https://github.com/swkim01/waveshare-dtoverlays/blob/master/README.md

/etc/X11/xorg.conf.d/99-calibration.conf
このファイルで

```
Option “SwapXY” “0” # unless it was already set to 1
Option “InvertX” “0” # unless it was already set
Option “InvertY” “0” # unless it was already set
```
この辺の "0" を　"1" に変更してやれば XY軸入れ替えたりできるらしいんだけど、全然効いてくれない。
ただし、

```
Option "TransformationMatrix" "0 -1 1 1 0 0 0 0 1"
```
このオプションだけは働いてくれているようなので、これを使うことにする。
どうやらこの "0 -1 1 1 0 0 0 0 1" これは 3x3の行列らしい。

```
⎡ 0 -1 1 ⎤
⎜ 1  0 0 ⎜
⎣ 0  0 1 ⎦
```
こういうことか。
で、上記のページによると XY軸を入れ替えるのは

```
⎡ 0 1 0 ⎤ 
⎜ 1 0 0 ⎥ 
⎣ 0 0 1 ⎦ 
```
これね。なので、/etc/X11/xorg.conf.d/99-calibration.conf これに以下を追記して動きを見てみる

```
Option "TransformationMatrix" "0 1 0 1 0 0 0 0 1"
```
うーんと、今度は指を右に動かすとマウスカーソルは左に、、左に動かすと右に、、（以下略）。ようするに 180度回転状態か。。180度回転させるのは、、

```
⎡ 1  0 1 ⎤ 
⎜ 1 -1 1 ⎥ 
⎣ 0  0 1 ⎦ 
```

こんな行列。えーっと、さっきのXY入れ替えつつ 180度回転させるのはこの2つをかけ合わせればいいのかな、、？

```
⎡ 0 1 0 ⎤ ⎡ 1  0 1 ⎤   ⎡  0 -1  1 ⎤
⎜ 1 0 0 ⎥ ⎜ 1 -1 1 ⎥ = ⎜ -1  0  1 ⎥
⎣ 0 0 1 ⎦ ⎣ 0  0 1 ⎦   ⎣  0  0  1 ⎦
```
あってる？（行列忘れた）
で、これを

```
Option "TransformationMatrix" "0 -1 1 -1 0 1 0 0 1"
```
こうやって /etc/X11/xorg.conf.d/99-calibration.conf に書き込んで無事に動くようになりました。

# おまけ
いちいち /etc/X11/xorg.conf.d/99-calibration.conf に書き込むの面倒くさいので、一時的になら以下のコマンドで確認できるみたいです。

こうやってインストールして、、（入ってなければ）

```
> sudo apt-get install xinput
```
これで確認

``` 
> xinput set-prop 'ADS7846 Touchscreen' 'Coordinate Transformation Matrix' 0 -1 1 -1 0 1 0 0 1
```

# こんな感じで動いてます
とりあえず動くようになったので、時計＆天気予報閲覧端末として部屋の隅にぶら下がってます。画面をクリックすると表示が変わるようになってるんですが、画面全体どこをクリックしても同じ動作なんで、タッチ座標がおかしいとか全然関係ない。。

![D98ZdrjU4AAdBX0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/fce57175-fd67-6f64-81dc-60f847857008.jpeg)
![D98ZehVU0AAHqN2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/87ef9bf0-3714-a410-6014-a2ba2ed30630.jpeg)
PHPUnitのテスト失敗でSerialization of 'Closure' is not allowedが発生した場合の対応

# 背景

PHPUnitを実行していたところテストが失敗する箇所で `Serialization of 'Closure' is not allowed` が発生するテストがあることがわかりました。

# エラーが発生するコード

テストコードを単純にして検証を繰り返したところ、以下のコードで再現しました。

```php
<?php
use Mockery;
use \PHPUnit\Framework\TestCase;

class HogeTest extends \PHPUnit\Framework\TestCase {

    protected function setUp(): void
    {
        $mockService = Mockery::mock('fuga');
        parent::setUp();
    }

    protected function tearDown(): void
    {
        Mockery::close();
    }

    public function testHoge() {
        $this->assertEquals(1, 2);
    }
}
?>
```

# 対応

`parent::tearDown();` が呼び忘れていたので追加することで対応できました。

```php
<?php
use Mockery;
use \PHPUnit\Framework\TestCase;

class HogeTest extends \PHPUnit\Framework\TestCase {

    protected function setUp(): void
    {
        $mockService = Mockery::mock('fuga');
        parent::setUp();
    }

    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public function testHoge() {
        $this->assertEquals(1, 2);
    }
}
?>
```

# 余談

- `parent::tearDown();` を呼ばなくてもテストに成功する場合はエラーになりません
- [PHPUnitとの統合:Mockery1.0](https://readouble.com/mockery/1.0/ja/phpunit_integration.html) のサンプルコードも `parent::tearDown();` を呼び出していないので注意が必要です
VSCode Live Shareすげぇ

## Live Shareとは

複数人でソースを編集したりできます。

ちなみにチャットとコール機能もあります。



## 手順

LiveShare

拡張のインスコします

https://visualstudio.microsoft.com/ja/services/live-share/



<img width="1680" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/e45b6135-b0ec-52bc-3d8a-4763919a0d8a.png">




赤枠で囲っている所から下記のアカウントでログインできます

- Microsoftアカウント
- GitHubアカウント



ログインしてから ` Live Share` ボタンを押したら下記画面が出てきます。

<img width="1680" alt="2-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/bbfe3e80-6cc5-3282-78d2-7597113189b1.png">


共有フォルダ選びます。

<img width="1680" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/fd724309-5f45-5ac2-03bc-cff4083a66e2.png">


赤枠で囲った `Copy again` を選択したらクリップボードに共有URLがコピーされるので共同作業者に送りましょう。


![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/51fce293-253a-eb31-612c-f45b95e8bbf3.png)


リンクを開いたらこのようにセッションに参加できます。
ここからソースを編集したりできますとりあえずさわてみてください。

<img width="1680" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/32dbf982-e23a-8144-be0a-546c076c31f6.png">


 `Chat Channel`を選択すればチャット画面を　`Start audio call` をCallをスタートできます。



<img width="1680" alt="6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/9f6dd8e2-fc25-8a0f-bbb3-8bd89d65c743.png">


灰色縦線を選択すれば行ごとにコメントを入れられます。


<img width="1680" alt="7-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115687/f8126c45-980a-dd18-06a6-148ed0f475b4.png">



 ` Live Share` を終了したい際は赤枠で囲ってある箇所を選択し

`Stop Collaboration Session`を選択すれば終了できます。
【Maven】OWASP Dependency Checkで依存ライブラリの脆弱性を解析する


この記事では`OWASP Dependency-check-maven 5.0.0`を使って脆弱性を解析します。

# やり方
## pomにpluginを追加する
pluginに以下を追加します（公式サイトからのコピペなので、バージョンアップ等の確認は[公式サイト](https://jeremylong.github.io/DependencyCheck/dependency-check-maven/)からどうぞ）。
オプションやコンフィグに関してはここでは解説しませんので、こちらも[公式サイト](https://jeremylong.github.io/DependencyCheck/dependency-check-maven/configuration.html)から確認をお願いします。

```xml:導入方法
<project>
    ...
    <build>
        ...
        <plugins>
            ...
            <plugin>
              <groupId>org.owasp</groupId>
              <artifactId>dependency-check-maven</artifactId>
              <version>5.0.0</version>
              <executions>
                  <execution>
                      <goals>
                          <goal>check</goal>
                      </goals>
                  </execution>
              </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
    ...
</project>
```

## コマンドを打つ
以下のコマンドをプロジェクトルートから打つことで、デフォルトではTarget以下に調査結果のHTMLが出ます。

```bash
mvn dependency-check:check
```

出力されたHTMLは以下のようになります（ぼかしている部分にはプロジェクト名とパッケージ名が入ります）。

![スクリーンショット 2019-06-28 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/381527bf-3b6e-5d4b-a729-a01d6098b1a0.png)

# （おまけ）アップデートする
結果には脆弱性を持つjarが表示されますが、そのjarが具体的にどのライブラリによって追加されたか（=どのライブラリのアップデートが必要か）は分かりません。
自分は`mvn dependency:tree`でどのjarが何によって追加されているか確認し、手動でアップデートしました。

もっといい手段が有れば教えていただけるとありがたいです。

# 続き
- [【Maven】OWASP Dependency Checkで警告を抑制する \- Qiita](https://qiita.com/wrongwrong/items/fcf8bbae22afc98c9434)

# 参考にさせていただいた記事
- [dependency\-check\-maven – Usage](https://jeremylong.github.io/DependencyCheck/dependency-check-maven/)
- [OWASP Dependency\-check\-mavenを使ってmavenで管理している依存ライブラリの脆弱性をスキャン \- Qiita](https://qiita.com/0x003f/items/c853ff6b71b8ef1d4524)
- [OWASP Dependency\-Checkを使って依存ライブラリの脆弱性をスキャン \- Qiita](https://qiita.com/0x003f/items/c594c912cb7dc15b7284#_reference-7a84613715ed8c206387)
日々の進捗ノート_言語処理100本ノック07

# 07. テンプレートによる文生成
>引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ．さらに，x=12, y="気温", z=22.4として，実行結果を確認せよ．

####190628追記
・tempはtemporaryの意味に見えるから使っちゃダメらしい

```gen07.py
def temp(x, y, z):
    return(str(x) + "時の" + str(y) + "は" + str(z))

def temp2(x, y, z):
    return("{a}時の{b}は{c}".format(a=x, b=y, c=z))

def temp3(x, y, z):
    return(f"{x}時の{y}は{z}")

print(temp(12, "気温", 22.4))
print(temp2(12, "気温", 22.4))
print(temp3(12, "気温", 22.4))

```
####結果
`12時の気温は22.4
12時の気温は22.4
12時の気温は22.4`

####備忘録
・f-stringsがつよい
・今日の12時の気温は29度
絶対path忘備録(Mac)

#絶対パスの入手方法

今まではC#で適当にやったらできていたが、Python3を使うと詰まったので解決方法。
ちなみに、デスクトップあたりのパスが欲しかった。
対象のファイルかフォルダを右クリック。optionキーを押す。
対象のそれのパス名が表示されるからコピー。
プログラムの変数などに入れて利用できる。
/Users/えすえー(ユーザ名)/Desktop
みたいな感じ。
AWS Well-Architected Framework ホワイトペーパーまとめ 6 【コスト最適化】

## はじめに
コスト最適化の柱は、パフォーマンス効率の柱と信頼性の柱との間で、トレードオフの関係にあります。
これは[**導入の稿**](https://qiita.com/Catetin0310/items/6e5bd6cb573aa38f0fc0)でも触れたとおりです。

![AWS study - frame.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/3ca4e4df-8ad4-86f3-d4b1-3f1e3fc7cc0b.jpeg)

具体的には、下記のような問いを通して、各種要件の優先順位を決定していきます。

- 市場投入までのスピードを重要視する？
- コスト最適化されたアーキテクチャを練るための時間を割ける？
- 万が一を想定して多めにリソースを投資したほうが良い？

ホワイトペーパーでは、

- 初期コスト最適化の方法
- 継続的コスト最適化の方法

についてのガイダンスが提供されています。

#### 連載目次
[AWS Well-Architected Framework ホワイトペーパーまとめ 1 【導入編】](https://qiita.com/Catetin0310/items/6e5bd6cb573aa38f0fc0)
[AWS Well-Architected Framework ホワイトペーパーまとめ 2 【運用上の優秀性】](https://qiita.com/Catetin0310/items/179f9c587a6b8b540a8a)
[AWS Well-Architected Framework ホワイトペーパーまとめ 3 【セキュリティ】](https://qiita.com/Catetin0310/items/08e1c4843cc5571cd3a5)
[AWS Well-Architected Framework ホワイトペーパーまとめ 4 【信頼性】](https://qiita.com/Catetin0310/items/c973552de5098fdda795)
[AWS Well-Architected Framework ホワイトペーパーまとめ 5 【パフォーマンス効率】](https://qiita.com/Catetin0310/items/12837377ab2d1c8f6c77)
AWS Well-Architected Framework ホワイトペーパーまとめ 6 【コスト最適化】 → 本記事

## 設計原則とベストプラクティス
まず、設計原則と概要を見てみましょう。
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/309f7c25-83bd-e301-bfa5-0cbb1ec6880c.jpeg)


次はベストプラクティスと、それに紐づくチェック項目。
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/bff93ac8-6a38-9356-4804-fbda578108e8.jpeg)


最後に各ベストプラクティスの概要です。

|-|概要|
|:--------------|:--------------|
|***コスト効率に優れたリソース***|対象システムの属性を考慮したうえで、**インスタンス単価 x 実行時間**がもっとも少なくなるように設計する、**マネージドサービス**、**リザーブドインスタンス**、**スポットインスタンス**を利用する。AWS使用料を***頻繁にモニタリング***し、デプロイを調節する。|
|***需要と供給の一致***|プロビジョニングの時間、障害、管理コスト、自動化を考慮し、需要と供給の一致を目指す|
|***費用の把握***|それぞれのビジネスオーナー、製品オーナーに属するコストを明確にし、**支出の内訳を把握**する|
|***継続した最適化***|アーキテクチャが引き続き最もコスト効率に優れたものであることを確認する。新たに、**最適化に寄与するマネージドサービス**が出ていないか確認する|


## 候補サービス一覧
この柱のベースとなるサービスは、**Cost Explorer**です。

加えて、**CloudWatch**や**Trusted Advisor**で費用の経時変化を可視化し、各種コスト効率の高い**マネージドサービス**を利用します。パフォーマンス効率の柱と同様、**最新情報のトラッキング**が重要になっています。

一覧表にまとめてみましょう。
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/32dc3a43-5afe-5dd3-b86b-7d0cbfa0fe1c.jpeg)


##  さいごに
Well-Architectedフレームワークのホワイトペーパーの概要、本稿まで6回に分けてご紹介しました。

このフレームワークは、クラウドに限らず、システム開発プロジェクトや組織運用などにも活用できる、きわめて汎用的な思考フレームだと思います。

どんな観点で全体を最適化するか、どこをゴールに設定し、どのようにカイゼンしていくか。悩んだ際はぜひご活用を！

## 参考リンク
[オフィシャル W-Aホワイトペーパー](https://d1.awsstatic.com/International/ja_JP/Whitepapers/AWS_Well-Architected_Framework_2018_JA_final.pdf)
xcodeインストールのxcodebuildの確認でエラーで対応したログ

swiftを勉強するため、xcode(10.2.1)をインストールして、 ```xcodebuild -version``` でバージョン確認しようとしても、エラーになってしまう。

```
$ swift -version
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.2.0
$ xcodebuild -version
error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

```
この様にswiftのバージョンチェックはOKだったのだが、xcodebuildのバージョンチェックはエラーに。
```command line tools instance```と書いてあるので、```Command Line Tools for xcode```を入れて解決と思いきや、同じエラーのまま。
以下のコマンドを入れると xcode-selectは生きている模様。

```
$ xcode-select -p
/Library/Developer/CommandLineTools
```

ググってみると、どうやらこのパスがいけないらしい？

```
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
```

これでどうだ？

```
$ xcodebuild -version
Xcode 10.2.1
Build version 10E1001
```

できたー（ふぅ）
[Java] removeAll()の使い方

### 使用法
```[1, 2, 3, 2, 5]``` から ```2``` と ```5``` を削除したい場合、removeAllで以下のように実装できる。

```java
		List<Integer> list = new ArrayList<>();
		list.add(1); list.add(2); list.add(3); list.add(2); list.add(5);
		System.out.println(list);  //=> [1, 2, 3, 2, 5]
		System.out.println(list.removeAll(Arrays.asList(2, 5)));  //=> true
		System.out.println(list);  //=> [1, 3]
```

### 注意点
```list.removeAll(2)``` のように要素を直接渡すことはできない。（コンパイルエラー）
VagrantでUbuntu(GUI)の開発環境作ってみた

# Vagrantを使用したUbuntu開発環境構築

Docker for Macの動作が重いため、Ubuntuを使いたいな〜と思いつつ、
Macでデュアルブートして壊すのが怖いので仮想環境を立ち上げてみました。

実用性があるかは分からないですが、何かの参考になれば。

## 出来ること

- VirtualBox上にUbuntu(GUI)環境を生成
- Visual Studio Codeを自動インストール
- Dockerを自動インストール

## 使用方法

### [VirtualBoxのインストール]

以下のリンクから自身のOS用インストーラーを取得し、インストール
https://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp

### [Vagrantのインストール]

以下のリンクから自身のOS用インストーラーを取得し、インストール  
https://www.vagrantup.com/downloads.html

### [実行]

リポジトリをクローンし、コマンド実行

```bash
git clone https://github.com/MasanoriIwakura/ubuntu-dev.git
cd ubuntu-dev
# vagrantの実行　※初回はインストールに時間がかかります。
vagrant up
```

up後、VirtualBoxが立ち上がりますが、プロビジョニングが行われるので暫く我慢です。

後からプロビジョニング内容を変更したい場合は`Vagrantfile`修正後、以下のコマンドを実行
何らかのインストールに失敗した場合も取りあえず以下のコマンド実行してみてください。
※私はなぜかDockerのインストール失敗して再度コマンド実行しました。

```bash
vagrant provision
```

### [ログイン情報]

ユーザー: vagrant
パスワード: vagrant

---

## Vagrantfileの解説

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.box = "ubuntu/xenial64"
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.network "private_network", ip: "192.168.33.10"

  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
    vb.memory = "4096"

    vb.customize [
      "modifyvm", :id,
      "--vram", "256", # フルスクリーンモード用
      "--clipboard", "bidirectional", # クリップボード共有
      "--draganddrop", "bidirectional", # ドラッグアンドドロップ
      "--cpus", "4",
      "--ioapic", "on" # I/O APICを有効化
    ]
  end

  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get upgrade

    apt-get install -y \
      ubuntu-desktop \
      apt-transport-https \
      ca-certificates \
      software-properties-common
    
    snap install --classic code
    
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    add-apt-repository \
      "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) \
      stable"
    
    apt-get install -y docker-ce
    usermod -aG docker vagrant

    reboot
  SHELL

  # 起動時にファイル転送しておきたい場合は以下を記載
  # config.vm.provision "file", source: "転送元", destination: "転送先"
end

```

>config.vm.box = "ubuntu/xenial64"

→使用するOSの指定

>config.vm.network "forwarded_port", guest: 3000, host: 3000

→ホストOSのポートと紐付け

>config.vm.network "private_network", ip: "192.168.33.10"

→ゲストOSのIPアドレス設定

>config.vm.provider "virtualbox" do |vb| 付近

→仮装マシンスペックの設定

>config.vm.provision "shell", inline: <<-SHELL

→プロビジョニング設定。初期起動時に入れておきたいツール等を記載

## 参考画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/14d58fbe-126e-1af7-59a5-f00b0c58e381.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/4eba67de-6cbe-03a3-5dc8-3f24a05fd634.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/24c759b9-92ed-54c8-9087-0df3b4501cac.png)



以上。
進展あればこちらの記事も修正します。
Chromium OSをビルドしてisoファイルにする

自分用メモ

## いろいろ用意

Debian前提で

```sh:install_dependencies
apt-get update && apt-get install -y \
      git-core \
      gitk \
      git-gui \
      gnupg \
      curl \
      lvm2 \
      thin-provisioning-tools \
      python-pkg-resources \
      python-virtualenv \
      python-oauth2client \
      sudo
```

## repoのインストール

Androidと似ている

```sh:install_repo
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /opt/depot_tools
export PATH=$PATH:/opt/depot_tools
```

## ソースコードをダウンロード

Androidと似ている

```sh:download
repo init -u https://chromium.googlesource.com/chromiumos/manifest.git --repo-url https://chromium.googlesource.com/external/repo.git
repo sync
```

`-j8` とかつけるとパラでダウンロードされたりするのかな。

## ビルド

```sh:build
export BOARD=amd64-generic
cros_sdk -- ./build_packages --board=${BOARD}
cros_sdk -- ./build_image --board=${BOARD}
```

## イメージ作成


```sh:build_image_for_flash
cros_sdk -- cros flash --board=${BOARD} file:///tmp/chromiumos.iso
```

のようなコマンドを打つと、 `/tmp/chromiumos.iso` に成果物が出来上がるのだが、↑の `/tmp/chromiumos.iso` はchroot環境？のパスをさすらしい。ホストから見えるようにごにょらないといけない。

手順は簡単で、https://www.chromium.org/chromium-os/tips-and-tricks-for-chromium-os-developers#TOC-How-to-share-files-for-inside-and-outside-chroot あたりに説明があるとおり `src/scripts/.local_mounts` に

```
mkdir /tmp/chromiumos_build
echo "/tmp/chromiumos_build /chromiumos_build" > src/scripts/.local_mounts
```

で

```src/scripts/.local_mounts
/tmp/chromiumos_build /chromiumos_build
```

こんな感じでマウントするパスを追加してから `cros_sdk -- cros flash --board=${BOARD} file:///chromiumos_build/chromiumos.iso` すればよさそう。
[Java] flatMapとは

# 公式ドキュメントでは
 <R> Stream<R>	flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
>このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るストリームを返します。

[Stream (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html)

# 要するに

以下の手順で処理される
1. Stream内のオブジェクトを受け取りStreamに変換
2. 変換された各Streamを１つのStreamにまとめる


## 例

```abcde``` が出力される

```java

Arrays.asList("a,b,c", "d,e")
    .flatMap(str -> Arrays.stream(str.split(','))
    .forEach(str -> System.out.print(str));
```

※2重リストから作られる ```Stream<List<List<String>>``` であれば、mapping関数の引数(上の例でstr)はListになるが、Listでなくてもよい。
RecyclerViewでリストの先頭にアイテムを移動した時に隠れないようにする

Android の [RecyclerView](https://developer.android.com/reference/android/support/v7/widget/RecyclerView) では [DiffUtil](https://developer.android.com/reference/android/support/v7/util/DiffUtil) を使用することで変更前後のリストアイテムの差分を計算して、その結果（アイテムの追加、削除、変更、移動）に応じて適切なアニメーションで RecyclerView を更新してくれます。

参考記事: [DiffUtilを使ってRecyclerView.Adapterをいい感じにする](https://qiita.com/kubode/items/92c1190a6421ba055cc0)

この仕組みを使ってランキング表示のようにアイテムが上下に移動するようなビューを実装していた際に、下位のアイテムが先頭に移動するケースで僕の意図しない動作となってしまったため、その対策方法のメモです。

### 先頭にアイテムを移動した時に隠れてしまう

下図のとおり **A~J** の10個のアイテムがあり、スクリーンには先頭から8個のアイテムが表示されている状態を例とします。

ここでアイテム **E** のランキングが上がって先頭にくるような場合、僕の期待する結果としてはアイテム **E** が先頭に移動してスクリーン上に表示されている状態なのですが、実際に DiffUtil による RecyclerView の更新結果はスクリーンより上側の隠れた位置に移動してしまいました。これを何とかしたい。

<img width="1081" alt="スクリーンショット 2019-06-28 13.38.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/4161a88d-b999-798b-4736-0697b5af4c67.png">

### 先頭にダミーアイテムを置くことで解決する

結論として、RecyclerView の先頭に常に見えないダミーアイテムを置いておくことで解決しました。

RecyclerView では下記の参考記事にあるとおり、`viewType` を上手く利用することで、アイテムごとに ViewHolder を切り替えることができるため、先頭のダミーアイテムについてはスクリーン上には表示されない（高さ0の）ビューを置いておきます。

参考記事: [RecyclerViewでセクション分けをする](https://qiita.com/cattaka/items/22e07f96b3d016548d92)

この状態でアイテム **E** が先頭に移動する時は、実際にはダミーアイテムの下に移動することになり、僕の期待していた結果が得られるようになりました。

<img width="866" alt="スクリーンショット 2019-06-28 13.51.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/39875ef0-3362-354d-3735-396691bc3d46.png">
51歳からのプログラミング　備忘　server send event(sse) - laravel 非同期通信

非同期通信　なかなかできなかった。

とりあえず、出かける時間なので、コード。
後で備忘記録的に追加しよう。

チャットモドキは
https://qiita.com/old_cat/items/1a7a6a25619544247b56

client - side
--
```html:index.blade.php
<script>
$(function(){
  var source = new EventSource('sse');
  source.onmessage = function(event){
         alert(event.data);
  }
});
</script>
```


route
--
```php:route
route::get ('index',function(){return view('index');});
route::get ('sse', 'XController@sse');
```


controller
--
```php:XController
class XController extends Controller{
      public function sse(){
             header('Content-Type: text/event-stream');
             header('Cache-Control: no-cache');

             echo "data:'test'\n\n";
             flush();
      }  
}
```

複数ﾃﾞｰﾀの送受信
--
```php:controller
$array = ['A'=>'a','B'=>'b','C'=>'c'];

header('Content-Type:text/event-stream');
echo 'data:'.json_encode($array);
echo "\n\n";
flush();
```

```html:
source = new EventSource('sse');
source.onmessage = function(d){
  var receive = JSON.parse(d.data);
  var A       = receive.A;
  var B       = receive.B;
}
```

二次元配列の取り出し
--
```php:controller
$user = User::all()->toArray();
header('Content-Type:text/event-stream');
header('Cache-Control:no-cache);
echo "data:".json_encode($form);
echo "\n\n";
flush();
```

```html:javascript
var source = new EventSource('sse');    //controller public function sse(){}
    source.onmessage = function(m){
           message   = JSON.parse(m.data);
           message.user.forEach(function(mess){
                   console.log(mess);
                   console.log(mess.user_name);
           }
     }
```




EventSource -property
--
サーバーからの情報は、message-eventで配信される。

|プロパティ|使用例とか|説明的とか戻り値とか
|:--------|:-------|:-------|
|onerror  |ev.onerror=function(){};|
|onmessage|ev.onmessage=function(e){};|
|onopen   |ev.onopne=function(){};|connection was just opened|
|readyState|0-connectiong 1-open 2-close|read-only|
|url|source's Url|read-only|
|withCredentials|cross orgin set|boolean|

下記サイト様。
参考になりました。ありがとうございました。
>https://developer.mozilla.org/ja/docs/Web/API/EventSource
>https://qiita.com/okumurakengo/items/cbe6b3717b95944083a1
>https://qiita.com/okumurakengo/items/cbe6b3717b95944083a1
一部の行だけ特定のコミット状態に戻す



「この機能はやっぱり必要ない」という指示を受けて、一部の行だけ削除。
その後も開発を進めて何度もコミットを繰り返してから「やっぱりあの機能を戻して:smiling_imp:」という指示。
私はよくあります:cry:

# 一部の行だけあのときに
```
git checkout -p <commit> <file>
```

Hunkに基づいてワーキングツリーとステージングに上げたファイルを元に戻すか問われます。
`Apply this hunk to index and worktree [y,n,q,a,d,s,e,?]?`
この問いに`y`,`n`で答える。

今ワーキングツリーで編集中のファイルがステージングに上がってない場合、
`The selected hunks do not apply to the index!`
`Apply them to the worktree anyway?`
追加で質問されるので`y`。

## 思うように分割されていないとき
`s`でもっと細かく分割してくれます。

## それでも上手くいかないとき
`e`で手作業で編集します。

現状を保持したいなら、
-行の - を空白に変える
+行は丸ごと削除
ブラウザベースのUIテストツールを色々試してみた感想

ブラウザベースのUIテストツールの感想です。

- [Selenium](https://www.seleniumhq.org/)
- [Puppeteer](https://github.com/GoogleChrome/puppeteer)
- [WebdriverIO](https://webdriver.io/)
- [Protractor](https://www.protractortest.org)
- [TestCafe](https://devexpress.github.io/testcafe/)

個人の主観（かつ根拠薄い点も多い）ですので、あくまでそういう意見もあるのね程度で見てください。

## 要件（要望？）

- 「ブラウザ操作」できる（当たり前か）。
- マルチブラウザ対応（同じテストを別のブラウザでも実行できる）
- ヘッドレステスト（EC2-Linuxなど GUIが無いOS上でも動作）できる。
- テスト記述をGit管理できる。
- Nodejs(JavaScript/TypeScript)でテスト記述できる。
- テストを並行実行できる。
- ドキュメントが充実している。ドキュメントを読むだけですぐ利用できる。

## UIテストツール達

- [Selenium](https://www.seleniumhq.org/)
    - マルチブラウザ対応。
    - 対応言語も豊富。
    - Selenium IDE：ブラウザ(Firefox)だけで簡単に操作を記録・再生できる。2018年夏に刷新された模様。
    - Selenium WebDriver：ブラウザを操作する標準仕様（WebDriver）を利用してテスト実行する。
    - 所感：知名度高い。WebDriverが機能不足かつ不安定。ブラウザ毎の微妙な仕様差異もあり、苦労しそう（した）。とはいえ、テストツールとしては老舗で情報も豊富なので、安心感はある。
- [Puppeteer](https://github.com/GoogleChrome/puppeteer)
    - Chorme限定だが、セットアップが簡単。EC2上でもヘッドレステストが簡単にできそう。
    - 所感：Chrome限定という時点で、見送り（試していない）。CIでのSmokeテストにちょいと組み込むのには良さげ。でも、他のテストツール併用するぐらいなら、使わない方が良い気がする。
- [WebdriverIO](https://webdriver.io/)
    - マルチブラウザ対応。
    - 言語はJavascript
    - 所感：なんか便利っぽい。が、やっぱりWebDriver利用している点が不安なので、試してない。
- [Protractor](https://www.protractortest.org)
    - Angular向け。Angular以外でも使用可能。
    - 言語はJavascript（TypeScriptにも対応）
    - WebDriver利用。インストールされているブラウザに応じて、WebDriverを自動設定するコマンドラインツール（webdriver-manager）も用意されている。
    - 所感：悪くは無いが、特に良くも無い。Angular利用しているなら、便利なのかも。
- [TestCafe](https://devexpress.github.io/testcafe/)
    - マルチブラウザ対応。言語はJavascript（TypeScriptにも対応）
    - NPMでインストール＆セットアップ完結。
    - Wait処理が自動（ビルトイン）。「XXX要素が表示されるまで待つ」系のテスト処理を記述する必要が無い。
    - 所感：シンプルでスマート。WebDriverを経由しないからか、細かい点でも考慮が行き届いていて、使い勝手が良い。

他にも色々なツールがありましたが、実際に触ってみたのは以上です。

## まとめ

まずは、Selenium（Selenium IDE）をお試し。Firefoxにプラグインを入れるだけで、自動テストを体験できます。用途によってはこれで充分かも。

その流れで、Selenium WebDriverに挑戦。そして、テスト記述の難しさに辟易する。

Seleniumに消耗してきたので、とある方にお勧めされたTestCafeに切り替え。「最初からTestCafe使えばよかった」← 今現在。
[Java] IntStreamでorElseとorElseGetの違いを確認

# osElse
OptionalIntがnullのとき、引数のint値を返す

```java
System.out.println(IntStream.of(1, 2, 3).findFirst().orElse(100)); //=> findFirstで獲得した1を返す

System.out.println(IntStream.of().findFirst().orElse(100)); //=>findFirstで獲得できないため、引数の100を返す
```

# orElseGet
OptionalIntがnullのとき、引数のSupplierを実行

```java
System.out.println(IntStream.of(1, 2, 3).findFirst().orElseGet(() -> 100)); //=> findFirstで獲得した1を返す

System.out.println(IntStream.of().findFirst().orElseGet(() -> 100)); //=>findFirstで獲得できないため、()-> 100 が実行され戻り値の100を取得する
```
---

### orElseという名前について...
ifPresentというメソッドにちなんで命名されたと考えられる
ifPresentはvoidメソッドなので、メソッドチェーンでorElseと共存させることはできない。

```java

// 以下はコンパイルエラー
ifPresent(System.out::println).orElse(0);
```
PowerShell 上で GNU find ライクな検索コマンド

## はじめに

GNU の findutils に慣れている人が Powershell で実行したいコマンドの一つが `find` です。
PowerShell では、ファイルを検索するために `Get-ChildItem` を提供していますが、いちいち API を覚えてもいられない (せっかく苦労して `find` も覚えたのに・・・) ので、PowerShell 上で GNU find のように `Get-ChildItem` を呼び出せるラッパー関数を書きました。

## コード

以下の関数を `$profile` に定義してください。

```powershell
function find {
  param(
    [parameter(Mandatory=$True)]
    [String]$path,
    [String]$name,
    [String]$iname,
    [String]$type,
    [Int]$maxdepth=-1
  )
  
  $command = "Get-ChildItem -Path $path -Recurse"
  
  if ($type -eq "f") {
    $command += " -File"
  }
  elseif ($type -eq "d") {
    $command += " -Directory"
  }
  
  if ($name) {
    $command += " -Filter `"$name`""
  }
  elseif ($iname) {
    $command += " -Filter `"$iname`""
  }
  
  if ($maxdepth > 0) {
    $command += " -Depth $maxdepth"
  }
  
  Write-Host $command -ForegroundColor Green
  Invoke-Expression $command
}
```

## Example

上記の `find` は次のように呼び出すことができます。

```powershell
find . -type f -name "*.py" -maxdepth 3
```

まだ必要最低限のパラメータ指定しか出来ないので、今後改良していきたいです。

## Reference

- [find(1) - Linux manual page](http://man7.org/linux/man-pages/man1/find.1.html)
- 公式の Powershell ドキュメント：[Get-ChildItem](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-6)
- [Use Windows PowerShell to search for files | Scripting](https://devblogs.microsoft.com/scripting/use-windows-powershell-to-search-for-files/)
- [Recursive file search using PowerShell - Stack Overflow](https://stackoverflow.com/questions/8677628/recursive-file-search-using-powershell)
日々の進捗ノート_言語処理100本ノック06

# 06.集合
>"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ．

```gengo06.py
def l_n_gram(sentence, n):
    res = set()
    for i in range(len(sentence)-n+1):
        res.add(sentence[i : i+n])
    return(res)

x = l_n_gram("paraparaparadise", 2)
y = l_n_gram("paragraph", 2)
print("和", x | y, 
"積", x & y,
"差", x - y,
"xにse存在", "se" in x,
"yにse存在", "se" in y,
sep="\n")
```

####結果
`和
{'gr', 'di', 'se', 'ag', 'ar', 'ra', 'ap', 'pa', 'ad', 'is', 'ph'}
積
{'pa', 'ap', 'ra', 'ar'}
差
{'is', 'di', 'se', 'ad'}
xにse存在
True
yにse存在
False`

####備忘録
・{}だと辞書型になっちゃう
Macbook(Pro)から音声が出ない時の対策

Macbook Proを使っていますが、音声が出ない（スピカー、イヤホン両方）場合が偶にあります。
再起動すると治りますが、以下の手順でやれば再起動せずにスピカーを復活させることが出来ます。

1. 「アクティビティモニタ」開く
2. 「coreaudiod」で検索
3. プロセスを強制終了
4. <img width="797" alt="スクリーンショット 2019-06-28 13.24.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72076/2e6178ae-9af4-8d85-b08a-e779210b25fd.png">
ReactNativeでAndroidが起動しない

## 概要

※自分の場合はAndroidXのリリースの影響でした

2019年6月末くらいにReactNativeプロジェクトでAndroidが起動しなくなった。

```
Android resource linking failed
...
Daemon:  AAPT2 aapt2-3.2.0-4818971-osx Daemon #0
```
省略していますが、私の環境でのエラー内容はこんな感じです。
環境によって違うかと。
(別の環境では使用しているパッケージでエラーが出ていた)

AAPT2で調べてたけど、全く解決せず。

## 前提

react-native 0.54.4(verは関係なさそう)

## 理由
AndroidXのリリース
https://developers.google.com/android/guides/releases/#june_17_2019

`com.google.android.gms:play-services-gcm`
`com.google.firebase:firebase-messaging`
がAndroidXをサポートしたから？

`implementation "com.google.android.gms:play-services-gcm:${safeExtGet('googlePlayServicesVersion', '+')}"`
のように最新バージョンを取ってくるとダメぽい


### パッケージも同じ

`react-native-push-notification`のエラーが出て悩んだ結果

[React NativeでAndroidXに関する変更でAndroidのビルドができなくなったのに対応した
](https://qiita.com/kuronomagi/items/7c6e9aa278a5fd5ac1f2)

こちらの記事にたどり着いた。

`react-native-device-info`
`react-native-push-notification`
など、同じ問題が発生している。

## 解決
#### ※私の場合

1.android/build.gradle

```gradle
googlePlayServicesVersion = "+"
firebaseVersion = "+"
```
自分のプロジェクトではこうなっていたので

```gradle
googlePlayServicesVersion = "16.+"
firebaseVersion = "17.6.0"
```
バージョンを固定する。

2.android/gradle.properties

```gradle
googlePlayServicesVersion=16.+
firebaseVersion=17.6.0
```
追記しておけば、パッケージはこっちのバージョンを見に行くので個別に変更しなくていい

3.react-native run-android

## 最後に

Twitterを見てたら解決しました。

### 参考

[React NativeでAndroidXに関する変更でAndroidのビルドができなくなったのに対応した
](https://qiita.com/kuronomagi/items/7c6e9aa278a5fd5ac1f2)

[AndroidX関連の変更によるReact Native Androidのビルドエラーを回避した
](https://qiita.com/shin_79030/items/8f7afa142dd358aa32d7)
gitの複数アカウントを使ってる場合に気をつける事

## 自分へのメモ
gitを複数アカウント使う時はリポジトリを作った際に意図しないコミット名になってしまうことがあるので、必ず設定をする

## 設定内容
git cloneしてきたディレクトリの下に .git/config というファイルが有るので下記を追記

```
[user]
        name = [コミットした時の名前]
        email = [コミット名に適したメールアドレス]
```