OmniAICreator/Qiita-1.07M huggingface dataset:
iOS開発者がFlutterの開発環境を構築してみた

Flutterの環境構築のメモです。
普段からXcodeを使ってiOSアプリを開発しているユーザー向けの手順です。

# まとめ
基本、[公式ドキュメント](https://flutter.dev/docs/get-started/install/macos)の手順に従いましょう。

# 環境
* macOS: 10.14.6
* Xcode: 10.3
  * Command line toolsもインストール済み
* Homebrew: 2.1.9

# Xcodeのセットアップ
普段から使っていれば、特に新しくインストールするものはありません。
ただし、このコマンドだけは実行しておきましょう。

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

このコマンドを実行しておかないと、FlutterからiOSシミュレータを認識しない場合があります。
特に、Xcodeのベータ版をインストールしているような場合は忘れずに実行しましょう。

# Android Studioのインストールとセットアップ
はじめにAndroid Studioをインストールします。
[公式ページ](https://developer.android.com/studio)からダウンロードしたものを使いましょう。

無事起動したら、`Configure -> Plugins` から Flutter plugin と Dart plugin をインストールします。

## AVDでエミュレータのセットアップ
あとで動作確認するときに必要になるので、`Configure -> AVD Manager` でエミュレータを作成しておきます。
x86_64のイメージをダウンロードしてきて、任意のデバイスで作成しましょう。

`~/.android`にアクセス権が付与されていないとき、エミュレータの作成に失敗する場合があります。
その時は `sudo chown -R <username> ~/.android` しておきましょう。

# Flutter SDKのインストール
Flutterの[MacOS install](https://flutter.dev/docs/get-started/install/macos)から、SDKをダウンロードして展開します。
展開した後、適当なディレクトリに移動します。

```zsh
$ cd ~/bin
$ unzip ~/Downloads/flutter_macos_v1.7.8+hotfix.4-stable.zip
$ mv ~/Downloads/flutter .
```

移動先のディレクトリにパスが通っていなければ `.bash_profile` などに追記しておきましょう。

```zsh
export PATH="$PATH:$HOME/bin/flutter/bin"
```

# flutter doctorで環境の診断
ここまで進んだら、`flutter doctor` で環境をチェックします。
足りないものがあれば指示が出ていますので、適宜インストールしましょう。

```zsh
❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.7.8+hotfix.4, on Mac OS X 10.14.6 18G84, locale ja-JP)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
[✗] iOS tools - develop for iOS devices
    ✗ libimobiledevice and ideviceinstaller are not installed. To install with Brew, run:
        brew update
        brew install --HEAD usbmuxd
        brew link usbmuxd
        brew install --HEAD libimobiledevice
        brew install ideviceinstaller
    ✗ ios-deploy not installed. To install:
        brew install ios-deploy
[✓] Android Studio (version 3.4)
[!] VS Code (version 1.36.0)
    ✗ Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[!] Connected device
    ! No devices available

! Doctor found issues in 3 categories.
```

# アプリを作成して実行する
適当なディレクトリに移動して、Flutterアプリを作成します。

```zsh
$ cd ~/dev/flutter
$ flutter create my_app
```

成功したら、iOSシミュレータかAndroidのエミュレータを起動します。

iOSは `open -a Simulator`。
Androidは AVD Manager から任意のエミュレータを起動してください。

ここまで進んだら、`flutter run -d all` しましょう。
iOSシミュレータとAndroidのエミュレータの両方でアプリが起動します。

## iOSの実機で実行する
iOSの実機で実行したい場合、以下の手順で実行できます。

1. アプリのルートディレクトリに移動する
2. `pod setup`を実行する
3. `ios/Runner.xcworkspace`をXcodeで開く
    * Bundle Identifier、（必要あれば）Teamsを変更する
5. `flutter run -d <device_id>` でアプリを実行する
    * `<device_id>`は`flutter doctor -v`などで確認できる
Luaでスターリンソート（不真面目編）

# はじめに
今、最高にロックで、最高に不謹慎なスターリンソートが話題なので話題に乗り遅れないように参加してみました。
関数名は、JSSort(配列)[^1]となります。

# Luaで素直に書くと、多分こんな感じ
```lua:jssort.lua
-- 普通にFor文使って条件に合うものを集める
function JSSort(org)
  local sorted = {}
  local siberia = {} -- シベリア?!
  for i,value in ipairs(org) do
    if (i==1) or (value >= sorted[#sorted]) then
      sorted[#sorted+1] = value
    else
      siberia[#siberia+1] = value
    end
  end
  siberia = {} -- zap!
  return sorted
end
-------- Main ----------
local org_array = {1,2,5,3,7,7,4,10}
local sorted_array = JSSort(org_array)
print(table.concat(sorted_array, " "))
```

普通ってなんだっけ。最適化よりも粛清感をマシマシでお送りしました。

本家のGitHubに、ブラジルの方[^2]がLua版を投稿しているけど、さすがにそれはひねくれすぎだと思う。でもこういうのも大好き。
https://github.com/gustavo-depaula/stalin-sort/blob/master/lua/sort.lua

# おまけ
Luaの機能を紹介する意味で、ジェネリックForループを使った版も作ってみました。

LuaのジェネリックFor文の解説はこちら。
https://qiita.com/hevo2/items/604b5405a981fd5fd207

```lua:jssort2.lua
-- 「イテレータを回す関数」の仕様
--    (1)実行するたびに何らかの値を返すこと、(2)終了するときはnilを返すこと
-- クロージャを使って「イテレータを回す関数」を作成
local my_iterator = function(_array) 
  local pos = 0
  local max = 0
  return function()
    while (pos < #_array) do
      pos = pos + 1
      if ((pos == 1) or (_array[pos] >= max)) then
        max = _array[pos]
        return _array[pos]
      end
    end
    return nil
  end
end
-- ジェネリックForループ(独自定義イテレータ)を使って条件を満たす要素を集める
function JSSort(org)
  local sorted = {}
  for v in my_iterator(org) do
    sorted[#sorted+1] = v
  end
  return sorted
end
-------- Main ----------
local org_array = {1,2,5,3,7,7,4,10}
local sorted_array = JSSort(org_array)
print(table.concat(sorted_array, " "))
```
[^1]: そういえばスターリンのフルネームはJoseph-Stalinだから、略すとJSだよね・・・。閃いた！
[^2]: Lua言語はブラジル生まれです。Luaはポルトガル語で月を意味するそうです。さすがLuaの本場（？）ですよね。
AtCoder Beginner Contest 023 D - 射撃王

# AtCoder Beginner Contest 023 D - 射撃王

二分探索で解く問題。

https://atcoder.jp/contests/abc023/tasks/abc023_d

最小スコアを求めるのは難しいが、ある数x以下のスコアで風船を割り切れるかを判定するのは難しくない。
よって、スコアの有り得る最も小さい値と大きい値で二分探索する。
スコアk+1は可能だが、スコアkは無理、という値kを見つければ良い。

```python
from math import ceil


t, *l = list(map(int, raw_input.split()))
pos=[l[i] for i in range(0, len(l), 2)]
speed=[l[i] for i in range(1, len(l), 2)]
low=max(pos)
high=max(pos)+max(speed)*(t-1)
while low<=high:
    mid=(low+high)//2
    print(high, mid, low)
    time_limit=sorted([ceil((mid-pos[i])//speed[i]) for i in range(t)])
    print(time_limit)
    for i in range(t):
        if time_limit[i] < i:
            flag=False
            low = mid+1
            break
    else:
        flag=True
        high=mid-1
if flag:
    print(mid)
else:
    print(mid+1)
    # 最後Trueで終わったらそれが答え, 最後Falseで終わったらその1個上答え。 
```
Watson Studio Experiment BuilderでGPUを時間課金利用する

# はじめに
Watson StudioのExperiment BuilderはDeep Learning用のGPUを時間課金で利用するのに便利な環境です。ただ、バッチ処理の特殊な環境のため、ちょっとしたノウハウが必要です。
そのためのメモ

# 環境変数
メインプログラムに制御が移る時点で、いくつかの重要な環境変数がセットされています。
その意味と目的を記載します。

|変数名  |目的  |備考  |
|---|---|---|
|${DATA_DIR}  |入力データ用  |実体はCOS Bucket  |
|${RESULT_DIR}  |出力データ用  |実体はCOS Bucket  |
|${MODEL_DIR} |プログラム用 |制御が移ってくる時点でのカレントディレクトリ|
|${HOME} |ユーザーホームディレクトリ| 自由に書き込み可能なワーク用として使う|

# 注意点
ディープラーニングの学習時には数万枚のオーダーの学習用イメージファイルを使う必要があります。
上の役割分担で考えると、`${DATA_DIR}`に置くのが自然ですが、COSに大量のファイルを置くと、パフォーマンスが悪くなり実用に耐えません。
そこで、次のような対応をすることになります。

* 学習用データをtar/zipなどなんらかの形でアーカイブしたファイルを`${DATA_DIR}`に配置
* pythonのメインプログラムを起動する前処理として、アーカイブファイルを解凍するコマンドを入れる
* 解凍先はユーザーホーム(${HOME})配下が望ましい
* pythonアプリ上のデータディレクトリ(学習用データの保存先)は上のステップで解凍したユーザーホーム配下を指定
* pythonアプリに制御を入れる際には、カレントディレクトリは元の`${MODEL_DIR}`に戻す

# コマンド指定例
解凍コマンドなど、前処理のコマンドはpythonのメインプログラム呼出し前に `&&` でつなぎます。

例えば、次のような形にコマンド指定を行う形になります。

```
cd ${HOME} && unzip ${DATA_DIR}/TRAIN_IMAGES.zip  && cd ${MODEL_DIR} && python main.py --iters 1000 --input_path ${HOME}/TRAIN_IMAGES --output_path ${RESULT_DIR}
```

# 複数ジョブ同時実行時のbest practice
Experiment Builderの便利さが最大限に発揮できるのは、条件を少し変えただけの学習を同時並行でいくつも行える点です。その際は、ジョブごとに出力バケットから別にする(=Experimentを別にする)と、出力がまざらなくて便利です。
Java の Stream で複数オブジェクトのメソッドが返す文字列を連結する

## 概要

- List に入っている複数のオブジェクトが返す文字列を連結する
- Java 8 から導入された java.util.stream.Stream を利用する

## ソースコード

### MyData.java

```java
/**
 * キー・バリューなデータを表します。
 */
public class MyData {

  private final String k;
  private final String v;

  public MyData(String key, String val){
    this.k = key;
    this.v = val;
  }

  public String key(){
    return k;
  }

  public String val(){
    return v;
  }
}
```

### Main.java

```java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args) {

    // データを構築
    List<MyData> list = new ArrayList<MyData>() {
      {
        add(new MyData("KEY", "VALUE"));
        add(null);
        add(new MyData("キー", "バリュー"));
        add(new MyData("きい", "ばりゅう"));
        add(new MyData("鍵", "値"));
        add(null);
        add(new MyData("key", null));
      }
    };

    // Stream オブジェクトを生成して処理
    String s = list.stream()
      .filter(Objects::nonNull) // 要素が null のものは排除
      .filter(myData -> myData.val() != null) // バリューが null のものは排除
      .sorted(Comparator.comparing(MyData::key).reversed()) // キーで逆順ソート
      .map(myData -> myData.key() + ":" + myData.val()) // 要素ごとに文字列を生成
      .collect(Collectors.joining(", ")); // 文字列を連結

    // 連結した文字列を出力
    System.out.println(s);
  }
}
```

## 実行結果

```
$ javac *.java
$ java Main
鍵:値, キー:バリュー, きい:ばりゅう, KEY:VALUE
```

## 動作確認環境

- OpenJDK 8
- Debian 9.9 (stretch)

## 参考資料

- [Stream \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html)
- [Collector \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Collector.html)
- [Collectors \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Collectors.html)
- [Comparator \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html)
- [Objects \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Objects.html)
ファイルを作る際に既にディレクトリが存在するか調べ、調べてなければ新しく作る方法[shell script]

何回も調べるのでメモ

# やりたいこと
　適当な名前の（パラメータ名やサンプル名など）ディレクトリをつくり、そこに実行結果のファイルを出力したい。
　ただ、以前の解析でそのサンプル、パラメータのディレクトリがあれば、そこに保存する
　また、親ファイルも存在しなければ作りたい。最初に親ファイルを別に作るみたいな、手間を省ける

## コード
work_dir という変数のディレクトリの下のref_genomeというディレクトリに保存したいとする。

```make_dir.sh
if [ ! -d ${work_dir}/${ref_genome} ];then
        mkdir -p ${work_dir}/${ref_genome}
fi
```

`mkdir -p `で親ファイルがなければ作ってくれる
`if [ ! path/to/dir ];`で存在するかを確認する。
リモートブランチで誤ってpushしてしまったときのpushの取り消し方法

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#間違えてpushしてしまった
新しい作業環境で開発リポジトリのmasterリポジトリをcloneしたあと必要な機能を実装できたのでレビューしてもらう為にpushしようと思ったですが。
初歩的なミスでmasterブランチでpushしてしまいました。
慌てて直前のpushを取り消す為に以下のコマンドを入力しました。

```
$ git reset --hard HEAD^
```

これで一安心、無事取り消せました。

次はdevelopブランチに切り替えたいのですがリモートのブランチだったのでローカルでcheckoutしました！

```
$ git checkout -b local_branch_name origin/remote_branch_name
```
remote_branch_nameリモートブランチから派生するlocal_branch_nameローカルブランチを新たに作成する。

-bオプションをつけることで「新しいブランチを作り、チェックアウトする」という動作になる。

今回の場合はdevelopブランチに作成した機能をレビューしてもらった後にマージして貰いたかったので作成した機能用のブランチを作成してpushします。

以下の流れでpushして無事成功しました。


```
$ git pull upstream develop
$ git checkout feature
$ git rebase develop
$ git push origin feature
```
Jupyterで、dtreevizを実行したら、表示がおかしくなった時の解決策

Jupyterで、dtreeviz（決定木の結果を可視化するライブラリ）を実行すると、表示がおかしくなってしまった時の解決の一例を紹介します。

# このような事象です。

例えば、タイタニックデータを分析しようとして、決定木の結果をdtreevizを用いて、Jupyter上で可視化しようとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/fdce7519-1e97-ea25-7216-fa0f3cc2f30c.png)

```python
import pandas as pd

df = pd.read_csv('train.csv')  # Kaggleでダウンロード
label = df["Survived"].tolist()
feature = pd.get_dummies(df[df.columns[df.columns != 'Survived']])
feature = feature.fillna(0)

from sklearn import tree

clf = tree.DecisionTreeClassifier(max_depth=3)
clf = clf.fit(feature, label)

from dtreeviz.trees import dtreeviz  # pipでインストールする必要あり
import numpy as np

viz = dtreeviz(clf, feature, np.array(label), target_name='status', feature_names=list(feature.columns), class_names=["Dead", "Survived"]) 

display(viz)  # 可視化用

```

このスクリプトを実行すると、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/24978bf0-d6de-b29e-c4a9-a3ea9a88be65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/28a81520-b0d1-dad0-268e-f702134ffe9d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/1635a09f-30e7-3853-0c4d-e8302094f242.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/a05e080f-5b55-49ed-60b2-04b2978b4a03.png)


このように、表示がおかしくなることがあります。

# 解決方法

色々試してみましたが、一番シンプルで楽なのは、以下の解決策でした。

```python
import pandas as pd

df = pd.read_csv('train.csv')  # Kaggleでダウンロード
label = df["Survived"].tolist()
feature = pd.get_dummies(df[df.columns[df.columns != 'Survived']])
feature = feature.fillna(0)

from sklearn import tree

clf = tree.DecisionTreeClassifier(max_depth=3)
clf = clf.fit(feature, label)

from dtreeviz.trees import dtreeviz  # pipでインストールする必要あり
import numpy as np

viz = dtreeviz(clf, feature, np.array(label), target_name='status', feature_names=list(feature.columns), class_names=["Dead", "Survived"]) 

viz.view()  # 修正：SVGで出力

```

この修正を加えると、別タブでSVGファイルが出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254780/8579c450-e4e8-744f-0fd2-1f15caff0980.png)

notebook上に図は残せないですが、個人的には、この解決策で特に問題なかったので採用しました。

# 最後に

私自身、些細な事で、つまずくケースは結構多いので、今回の件も情報共有しました。
dtreevizを利用する際の参考にして頂けると嬉しいです。

# 参考
[dtreevizの実行エラーとその対策](https://qiita.com/onodism/items/329efd2aeeef54937794)
LambdaとLocalstackを使ったDynamoDBのテスト

## LambdaからLocalStackを使用してローカル環境でDynamoDBのテストをしたので、備忘録として。 
エンジニア歴1ヶ月のベビーエンジニアがこれを書いているので、間違いやぬけ、勘違いがあれば指摘いただければありがたいです。

###LocalStackの準備

すでにLambdaは用意済みなので、LocalStackを用意するところから。

が、その前にLambdaとLocalStackを同じネットワーク内に用意しておかないといけないので、dockerのlocalnetworkを構築します。

```
$ docker network create -d bridge 任意のネットワーク名
```

dockerのlocalnetworkを用意したら、localstackを起動します。


```
$ docker run -it --network ネットワーク名 --name=localstack -p 4563-4593:4563-4593 -p 8080:8080 -e LOCALSTACK_SERVICES=dynamodb localstack/localstack
```

これでLocalStackでDynamoDBのモックが用意できました。

###LocalStack内DynamoDBにTableを作成



次は、DynamoDB内にTableを用意します。

```
$ aws --endpoint-url=http://localhost:4569 dynamodb create-table \
  --table-name YOUR_TABLE_NAME --attribute-definitions AttributeName=YOUR_ATTRIBUTE_NAME1,AttributeType=S --key-schema AttributeName=YOUR_ATTRIBUTE_NAME2,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
```

最後のReadCapacityUnitesとWriteCapacityUbitsはオプションなので、ここでは１にしていますがアプリに合わせて変更が必要です。

これでLocalStackとLambdaの連携が完了です！

あとはLambda側の関数でput_itemやget_item等のメソッドを記述すれば、LocalStackのDynamoDBにストアしたデータを取ってくることができます。

##まとめ

LambdaとLocalStackのDynamoDBを同じdocker network内に配置し、（仮）DynamoDBのテストができるまでの流れでした。
PHP 連想配列をObject(stdClassのインスタンス)へ変換 

```php5
$testarr = ['t1' => 'sss1','t2' => 'sss2'];
dump($testarr);
dump((object)$testarr);

echo $testarr['t1'];
echo ((object)$testarr)->t1;
```

![stdClass.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125746/e1b4f529-4c76-b3ae-bc71-11910b86ad8a.png)
【jQuery】Google画像検索のような動きをプラグインなしで簡単実装

#やりたいこと

Google画像検索のように、画像をクリックすると詳細が下にアコーディオンで出てくる動き。

プラグインなしの方法を検索してみると、多くの変数を屈指して細かい動きを指定した実装が多かったのですが、
極力シンプルで簡潔な方法で実装してみます。
<img width="1384" alt="スクリーンショット 2019-08-01 18.44.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287877/457e184b-e6d8-f978-8a90-cf39ca277af0.png">



#HTML

```html:
<div class="wrap">

  <div class="itemThumbnail">image 1</div>
  <div class="itemDetail">
    <div class="itemDetail__inner">
      <div class="itemDetail__img">image 1</div>
      <div class="itemDetail__text">テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</div>
      <div class="itemDetail__close"><img src="img/close.png" alt="クローズボタン"></div>
    </div>
  </div>

</div>
```
`.itemThumbnail`要素：横並びで表示され、クリックされる部分。
`.itemDetail`要素：クリックで下にアコーディオンで表示される部分。

`.itemThumbnail`と`.itemDetail`でワンセット。表示したい分だけ繰り返す。

#CSS
Google画像検索のような動きを実装するのに、必須なCSSだけ紹介します。

##ポイント1：横並び要素には`inline-block`を使う
```css:
.itemThumbnail {
  display: inline-block;
}
```

`display:inline-block`にすることで、詳細部分を展開しても、**サムネイル要素をつめて表示してくれます。**
代わりに`float:left`にしてしまうと、詳細部分を展開した時、サムネイル要素を詰めて表示してくれません。
要素の横並びといえば`display:flex`が便利ですが、今回の場合思い通りの動きになってくれません。

##ポイント2：展開要素には`float:left`を使う

```css:
.itemThumbnail {
  float: left;
}
```

##ポイント3：展開したら画面幅いっぱいに広げる
```css:
.itemThumbnail {
  position: relative;
  width: 100vw;
  left: 50%;
  transform: translateX(-50%);
}
```
なくても良いですが、よりそれっぽく仕上がります。

#jQuery

展開の動きは、最低限のjQueryで。

```javascript:
$(function() {
  //サムネイル画像がクリックされたら
  $('.itemThumbnail').on('click',function(){
      // １）全部非表示
      $('.itemDetail').hide();
      // 2)何番目か取得して表示
      var index = $('.itemThumbnail').index(this);
      $('.itemDetail').eq(index).slideToggle();
   });
  // ×ボタンがクリックされたら
  $('.itemDetail__close').on('click',function(){
    $('.itemDetail').slideUp();
  });
});
```
1)、2)は、サムネイル画像がクリックされてからの一連の動作です。
それでは上のコードを解説していきます。

## 1) 全部非表示

サムネイルがクリックされた時、**まず始めに展開している詳細を全て閉じる必要があります**。
そうしないと、クリックする度にどんどん展開が起きてレイアウトが崩れてしまいます。
もしくは、いちいちバツボタンを押して閉じないといけない面倒な仕様になってしまいます。

## 2) 何番目か取得して表示
`.itemThumbnail`と`.itemDetail`は同じページ内に複数存在しています。
何番目の`.itemThumbnail`がクリックされ、何番目の`.itemDetail`が展開するのかを指定することで、任意の箇所だけが開閉します。


#おわりに

ホンモノのGoogle画像検索は、詳細を展開すると左右矢印が付いていて、矢印のクリックで詳細表示を切り替えられるようになっています。
今回はそこまで実装しませんでしたが、時間があるときに挑戦してみようと思います。
【回路編】micro:bitで戦車を操縦する

ここでは，戦車の車体に組み込む回路の配線を紹介します．モータードライバー(TOSHIBA TA7291P)を2つ使い，2つのモーターを制御する回路を紹介します．

## 配線図
![2motorControl_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/22a29e56-4433-ff30-846f-ade7e0220013.png)


回路は前の記事「[micro:BitでDCモーター制御(TOSHIBA TA7291P)](https://qiita.com/kikpond15/items/6e4f2e13ab89d67a4a21)」の配線図を元にモータードライバーを2つ使えるように変更しています．
モータードライバーAの左から**4番目，5番目，6番目のピン**は，micro:bitの**0番，8番，1番**にそれぞれ接続されています．
同じくモータードライバーBの，**4番目，5番目，6番目のピン**はmicro:bitの**0番，2番，12番**にそれぞれ接続されています．
Rubyでスクレイピング行う．(windows)

#Rubyでスクレイピングを行う際に発生したエラー

この手の記事はたくさん書かれていますが，google先生で探すのに時間がかかったので自分用にまとめます．

Rubyでスクレイピングを行う際には，openurlとNokogiriを使う方法が一般的かと思います．
しかし，その二つだけだと，SSLやredirect系のエラーが発生します．
kconvを利用しているのはwindowsだからです，，

```
require 'open-uri'
require 'nokogiri'
require 'kconv'

url = 'http://qiita.com/search?q=ruby'

charset = nil

html = open(url) do |f|
	charset = f.charset
	f.read
end

doc = Nokogiri::HTML.parse(html, nil, charset)
#p doc
doc.xpath('//h1[@class="searchResult_itemTitle"]').each do |node|
	print(Kconv.tosjis(node.css('a').inner_text)<<"\n")
end
```
上記で実行すると以下のエラーが発生します．
これは,http->httpsのリダイレクトをしようとしてエラーになっています．
まぁ，qiitaだとurlをhttpsに変更するだけでいいのですが
これは，open_uri_redirectionsを追加すれば大丈夫になります．

```
open-uri.rb:225:in `open_loop': redirection forbidden: http://qiita.com/search?q=ruby -> https://qiita.com/search?q=ruby (RuntimeError)
```
次

```practice.rb
require 'open-uri'
require 'open_uri_redirections'
require 'nokogiri'
require 'kconv'

url = 'http://qiita.com/search?q=ruby'

charset = nil

html = open(url,:allow_redirections => :safe) do |f|
	charset = f.charset
	f.read
end

doc = Nokogiri::HTML.parse(html, nil, charset)
#p doc
doc.xpath('//h1[@class="searchResult_itemTitle"]').each do |node|
	print(Kconv.tosjis(node.css('a').inner_text)<<"\n")
end


```

上記で実行すると以下のエラーが発生します．

```
http.rb:933:in `connect_nonblock': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)
```

これは，SSLの証明書エラーになっています．
ライブラリのcertifiedを入れると対応可能です．
そして，最終的なものがこちらです．

```
require 'open-uri'
require 'open_uri_redirections'
#require 'openssl'
require 'certified'
require 'nokogiri'
require 'kconv'

url = 'http://qiita.com/search?q=ruby'

charset = nil

html = open(url,:allow_redirections => :safe) do |f|
	charset = f.charset
	f.read
end

doc = Nokogiri::HTML.parse(html, nil, charset)
#p doc
doc.xpath('//h1[@class="searchResult_itemTitle"]').each do |node|
	print(Kconv.tosjis(node.css('a').inner_text)<<"\n")
end
```
実行結果です．（qiitaからruby記事の検索を行い．タイトルを取得しています．利用価値ゼロ）

```
Ruby
Ruby
Ruby
Ruby
Ruby
ruby
【Ruby】Rubyにおける正しいshebangの書き方
【Ruby】Ruby入門：繰り返し処理
【Ruby】Ruby入門：クラスについて
RubyでRubyを描く
```

以上です．
スクレイピングで何か遊びたい．
【Watson Machine Learning メモ】新認証方式 apikeyによるwebサービス呼出し

# はじめに
Watson Machine LearningにデプロイしたWebサービスを呼び出す際に、1段階目としてtokenを取得します。従来はWatson Machine LearningのCredentcial情報のうち、userid/passwordのセットを使って、Basic認証を使って取得していたのですが、この方法が使えなくなった模様。
新しいWatson ML API呼出し方法のメモ(Pythonケース)を記載します。

参考リンク
https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-authentication.html

# サンプルコード
新しい方式でのtoken取得のサンプルコードを以下に記載します。
payloadデータの渡し方以降は従来通りなので省略します。

```py3
import urllib3, requests, json

# 新しい方式は認証にapikeyを利用し、userid/passwordは不要となります。
wml_credentials = {
  "instance_id": "xxxx",
  "apikey": "xxxx",
  "url": "https://us-south.ml.cloud.ibm.com"
}

# トークン取得
apikey = wml_credentials["apikey"]

# Get an IAM token from IBM Cloud
url     = "https://iam.bluemix.net/oidc/token"
headers = { "Content-Type" : "application/x-www-form-urlencoded" }
data    = "apikey=" + apikey + "&grant_type=urn:ibm:params:oauth:grant-type:apikey"
IBM_cloud_IAM_uid = "bx"
IBM_cloud_IAM_pwd = "bx"
response  = requests.post( url, headers=headers, data=data, 
        auth=( IBM_cloud_IAM_uid, IBM_cloud_IAM_pwd ) )
iam_token = response.json()["access_token"]
print('iam_token = ', iam_token)

# API呼出し用ヘッダ
# API呼出し用のヘッダには新しく`ML-Instance-ID`を追加する必要があります。
ml_instance_id = wml_credentials["instance_id"]
header = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + iam_token, 
      'ML-Instance-ID': ml_instance_id}

# これ以降の呼出し方法は従来通りなので、省略します。
```
pyinstaller ビルド時の”UnicodeDecodeError: 'utf-8' codec can't decode byte ....”

# 1 状況
前回記事 [pyinstaller ビルド時の”Cannot find existing PyQt5 plugin directories”](
https://qiita.com/tatsuruM/items/cd657f25022c93d0284f)
に引き続き、PyInstallerでexeファイルを作ろうとしたところ、これまで問題なくビルドできていたプロジェクトにエラーが発生しました。

今回のエラーは
>UnicodeDecodeError: 'utf-8' codec can't decode byte ....

ファイルの入出力で文字コード処理がどこかおかしいか...かなりの数の該当部があったので、頭を抱えました。

# 2 対策
以下のサイトに解決方法を発見
[Error when using pyinstaller: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff]
(https://stackoverflow.com/questions/47692960/error-when-using-pyinstaller-unicodedecodeerror-utf-8-codec-cant-decode-byt)

まず以下のファイルを探します。
（見つけにくければエクスプローラー等で「PyInstaller」を検索しましょう。）

>Anacondaインストールフォルダ\Lib\site-packages\PyInstaller\compat.py

以下の部分（私の場合は370行目）を
out = out.decode(encoding)
をコメントアウトし、以下のように書き換えます。

```
            if encoding:
                # out = out.decode(encoding)
                out = out.decode(encoding, errors='ignore')                
```


再ビルドで無事にexeファイルが作成できました。
Ubuntuに最新版Node.jsを一撃で簡単にインストールする

## コマンド

```
sudo snap install node --edge --classic
```

## 説明

Ubuntu 16.04 LTS 以降には、[Snapcraftがあらかじめ入っています。](https://snapcraft.io/docs/installing-snap-on-ubuntu)
Snapcraftは `The app store for Linux` と言っており、ディストリビューション横断で使えるパッケージマネージャです。

上記コマンドでは、Snapcraft経由でNode.jsのSnap（パッケージ）をインストールしています。
Snapの詳細はこちら https://snapcraft.io/node

現時点では、上記コマンドで入るのは、v13.0.0-nightly版でした。（つまり、新しすぎる）
また、snapcraftでは、Snapは[自動でアップデートされます。](https://snapcraft.io/docs/keeping-snaps-up-to-date)
よって、バージョン固定したり、複数バージョンを管理したい用途には向きません。

---

UbuntuにNode.jsをインストールする方法は数多くあります。毎回悩んでググってしまうので、改めて書きました。
これなら覚えられそうです。

ndenv や n のようなバージョン管理システムを使う方法とは一味違いますが、どちらも、向き不向きがあるので、自分の用途に合った方法を選んで使うようにしましょう。
Javaで月の最終日を導出する方法

#Javaで月の最終日を求めたい
Javaで月の最終日を求める必要があったのですが意外とはまったのでメモ。

#java.util.Calenderを利用
日付系ののライブラリを使用することも可能ですが、以下のように、java.util.CalenderクラスのgetActualMaximum()メソッドを用いれば可能です。

```test.java
//2019年1月の最終日を求める
int year = 2019;
int month = 1;

Calendar cal = Calendar.getInstance();
cal.clear();//場合によっては必要

cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month-1); //月は１月が0

int lastDayOfMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
```

#注意点1：月を設定する場合のclear()
最初にカレンダーのインスタンスを生成する際に引数なしでgetInstance()すると、現在の日付でインスタンスが作成されます。メソッドを呼び出すのが31日などの場合には、次に30日までしかない月を設定した場合、おかしなことになります。これは、事前にclear()を呼び出すことで回避できます。

#注意点2:月を設定する場合の値
Calrenderクラスでは、Calendar.Monthは月の値から1引いたものが実際の値です。
月をセットする際に、実際の月数より１小さい数をセットする必要があります。
夏休みの工作特別企画 電気ポットをwifiにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/91c08cca-4d32-1ea3-db8a-51308c169e05.png)
ソノフは、コンセントをwiifiにするスマートプラグです。標準でスマートフォンから制御できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/f169822e-8cd9-aa95-a151-5bb52a7f7080.png)

中身は、ESP8266でpythonから制御できるはずでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/2b2aaf39-457e-b83f-47a0-ae572bc09706.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/39813a58-76f4-b83d-32ea-f692b510e337.png)
ともにバグのために停止しました。

色々ググった結果iftttにsonoffのアクションサービスがあることがわかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/55be4f22-65f4-092d-511b-cc898587bd42.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/b58009d8-9ee6-923a-62c6-8d1683e8990f.png)

Createを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/c9ef3711-b608-70f0-249a-0c955e676b57.png)
+を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/09fd4865-c61e-b54e-4fda-fb10d49c544f.png)
Webhooksを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/86950e94-1ec1-58ed-f307-c6cc14a8fcb8.png)
トリガーは、Web requestを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/2d4a7e59-c59b-2187-2b0b-6e53a1fd31a8.png)
適当な名前を付けます。ここでは、plugOn
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/9e5bc7cf-ecb7-3020-aa96-6a6f83ec68a6.png)
that + を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/2daba146-d898-6cfc-679c-03415ec272e6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/d73dd2ad-61a5-9e79-cbf0-55e063c1cfec.png)
Turn 1 Channel plugを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/eca44e12-b70b-e8a0-3548-0166b7eccd5e.png)

Create Action します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/03abc317-7601-3c28-e9cd-3aa1e2d18e2d.png)

Finishします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/c1083f81-5ab9-a9b3-60ba-86c00ce06161.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/ba11c265-cc65-05eb-6c8e-c4356d143279.png)
赤丸をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/6605068c-a550-502d-b870-8f1619978c23.png)
Documentationをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/5d9175bf-597e-5c5c-4fb6-9bbe7d0aeec9.png)

on と　offを作成し各々のweb requestをコピーします。

```test.py
import requests,time
on= 'https://maker.ifttt.com/trigger/switchOn/with/key/xxxxxxxxxxxxxxxx'
off='https://maker.ifttt.com/trigger/switchOff/with/key/xxxxxxxxxxxxxxxx'

r = requests.post(on)
print(r.text)
time.sleep(3)
r = requests.post(off)
print(r.text)
```
Ubuntu18 * NginxでVirtualHostの設定

#UbuntuにNginxを入れてVirtualHostを設定する
備忘録も兼ねて
(さくらのクラウドUbuntu18.04で確認済み)

### 1. Nginxインストール
パッケージマネージャ経由でインストール。事前にapt update/upgradeはやっておく。

```
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install nginx
```

### 2. Nginxの設定ファイルを開く
```
$ sudo nano /etc/nginx/sites-available/default
```

### 3. VirtualHostのserver設定を追記する
```
server {
        listen 80;

        server_name www.example.com;
        root [ドキュメントルートのパス];
}
```

ハマりどころとして、デフォルトで入っている設定に

```
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
}
```

とVirtualHost設定の肝である `server_name` にアンダースコアが設定されており、これが入っていると全てのserver_nameとマッチさせることになるので用がなければ外しておくのが良い。

### 4. configtestと再起動
Nginxのconfigをテストする

```
$ sudo /etc/init.d/nginx configtest
 * Testing nginx configuration                                           [ OK ]
```
OKならnginx restartして、ドキュメントルートにindex.html置いてサイトを確認。
Firebase CloudFunctionsのregionは手動で設定する必要アリ

# Firebase CloudFunctionsのregionは手動で設定する必要アリ

## TL;DR;
* CloudFunctionsのリージョンのデフォルトは常にus-central1
* プロジェクト単位でデフォルトロケーションを持つCloudFireStoreやStorageと異なり関数単位で別々設定可能
* CloudFireStoreとリージョンがずれると外部アクセス扱い(課金あり)になるので注意

## CloudFunctionのregion
FirebaseCloudFunctionでは、リージョン指定が可能です。
各関数について、以下のようにソースベースで指定します。

```js

exports.somFunction = functions.region('asia-northeast1').//起動トリガーの指定など
```
exportする関数で指定していることから分かるように、関数単位でregionは指定可能です。
なお、指定しない場合のus-central1(アイオワ)になります。
FirestoreやFireStorageなどデフォルトロケーションを持つサービスは、
一つ指定すれば他のロケーションも同じものに設定されてくれますが、CloudFunctionについてはデフォルト値が切り替わりません。忘れずに毎回指定するようにしましょう。

## リージョンを指定しないとどうなるのか
基本的に、日本国内で利用するアプリに利用する場合にはasia-northeast1(東京)にしておくのが無難です。
理由としては、物理的なネットワークコストかかってしまう(場合によって数100ミリ秒)ことと、
FireStoreやFireStorageとロケーション・リージョンがずれてしまうと外部アクセス扱いとなってしまうからです。
同一リージョン内だとデータ通信量は無料(無課金アカウントでも利用できる)ですが、
リージョンを跨ぐと通信料に応じて従量課金されてしまいます。
参考:https://cloud.google.com/functions/pricing?hl=ja

無駄にリージョンを跨がせてもいいことは特にないので、利用するサービスのregionは統一しておきましょう。
jqueryでHTTP通信をしないページ遷移　複数ページ版

前記事　
[jqueryでHTTP通信をしないページ遷移](https://qiita.com/sui625/items/7fd4582f1cf4700d4a22)

前回の記事で実装した機能で複数ページを遷移できるようにしました。
![qiita投稿.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465210/b090f48e-822d-4296-6651-85022bb16f27.gif)
<br>
コードは以下の通りです
<font color="Red">*コピペするときはコード中のコメントアウトは消してください</font>

```haml:haml
.kabaokun
  .zyuuhati
    .keikoku-box
      %P.top-keikoku
        = fa_icon 'venus-mars'
        %span 警告！
      %p.keikoku-bunsyo 当サイトは18歳以下の利用を固く禁じます。あなたは18歳以上ですか?
      //yabababaクラスが共通の発火点です
      %a.yabababa.ryoukai はい
      %a.nigeru いいえ

  .waller.yabai
    .aaaaaaa 
      //aaaaaaaは空の要素です。wallerクラスまでのネストを2段にするためのものです。
      %P.yabababa まじ卍字

  .wall-of-manzi.yabai
    .aaaaaaa
      %P.yabababa おこ

  .wall-burn.yabai 
    .aaaaaa
      %p.yabababa 激おこ

  .wall-big-fire.yabai
    .aaaaaaa
      %P.yabababa 激おこプンプン丸

  .wall-burnout.yabai 
    .aaaaaa
      %p.yabababa 激おこカムチャッカファイヤー

  .nakayoshi.yabai
    .aaaaaa
      %p.yabababa 仲直りしよ



```
```css:css
.yabai{
  display: none;
}
以下略

```
```javascript:js
$(function(){
  $('.yabababa').on('click', function(e){
    e.preventDefault(); 
    $(this).parent().parent().addClass('yabai'); //発火点の2つ上の要素(現在の画面全体を持つクラス)にyabaiクラスを与える
    $(this).parent().parent().next().removeClass('yabai'); //発火点の2つ上(現在の画面全体を持つクラス)の次の要素からyabaiクラスを奪う
  });
});
```
　各ページの発火点のクラスを`yabababaクラス`に統一することでjqueryの記述を全ページで使い回せるようにしました。
　この時注意するのは、ページ全体を指す要素から発火点までの階層数を全ページで統一していないとうまく作動してくれない点です。上記のコードでは最初の画面と以降の画面の発火点までのネスト数を合わせるために、2枚目以降のページには何もCSSを当てていないaaaaaaというクラスの要素を作っています。
関数の再帰呼び出しの速さを調べる。

関数の再帰呼び出しの速さを調べてみた。
functoolsをうまく使うと再帰呼び出しも高速化できる。

```python:codes.py
# 再帰版->絶望的に遅い
def fibonacci_re(n):
    if n < 2:
        return n
    return fibonacci_re(n-1) + fibonacci_re(n-2)

# 再帰改良functool版->キャッシュを使うので圧倒的に速い
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci_functool(n):
    if n < 2:
        return n
    return fibonacci_functool(n-1) + fibonacci_functool(n-2)
```
```python:test.py
import codes

### Functions                                                                                                                                                     
def main():
    import time

    import sys
    sys.setrecursionlimit(10000)

    start=time.time()
    [codes.fibonacci_re(n) for n in range(10)]
    end=time.time()
    print(f'fibonacci_re処理（再帰版）にかかった時間は{end-start}秒です。')
#> fibonacci_re処理（再帰版）にかかった時間は5.507469177246094e-05秒です。
#↑ 10個でこれだけかかる！

    start=time.time()
    [codes.fibonacci_functool(n) for n in range(1000)]
    end=time.time()
    print(f'fibonacci_functool処理（再帰、メモ化）にかかった時間は{end-start}秒です。')
#> fibonacci_functool処理（再帰、メモ化）にかかった時間は0.0008387565612792969秒です

### Execute                                                                                                                                                       
if __name__ == "__main__":
    main()
```
スターリンソートwithPHP

まだPHPで書いてる人が見当たらなかったので。居たらごめんなさい。

```php
<?php
$array = [1,3,4,2,3,7,3,9];
print_r(stalin_sort($array));

function stalin_sort($arr){
	$ret[] = $max = $arr[0];
	foreach($arr as $el){
		if($el <= $max) continue;
		$ret[] = $max = $el;
	}
	return $ret;
}
```

本当は練習がてらアロー関数でやろうと思ってたけど、端末に入ってたPHPが7.1だったのでやめた。
粛清というか、どちらかというと消えゆく関数の中に取り残して見捨てるみたいなコードになりました。

---

[2019/08/05 追記]
なんかすごく真面目な記事にメンション張られてしまって申し訳なくなったのでアロー関数やろうと思います。

>本当は練習がてらアロー関数でやろうと思ってたけど

すみません、正確には「アロー関数触ってみたい」レベルの話です。ごめんなさい。ここしばらくレガシー保守に居てPHP7すらひょっとしたら一年近く触ってないです。
で、先に結果言うんですけど、「PHPのアロー関数でスターリンソートやるの無理くない？」となりました。最大値の管理をどうやればいいんだろう……。以下はアロー関数を使ってみただけのコードになります。

Vagrant準備

```
[root@localhost vagrant]# history
    1  yum list php
    2  yum list php* ←7がないことを確認
    3  yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
    4  yum install yum-utils
    5  yum-config-manager --enable remi-php74 ←適当に入力してみて弾かれる
    6  yum-config-manager --enable remi-php70
    7  yum list php*
    8  yum install php74
    9  php -v ←出ない。あれ？develいるんだっけ？
   10  yum list php-devel ←無い
   11  yum list php74-devel ←無い。あれ？
   12  yum list php74* ←確認
   13  yum install php74-php-devel ←なるほど
   14  php -v ←やっぱり出ない。あれ？
   15  yum install php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt ←バージョン見たら7.0だったので却下
   16  php74 ←試し打ち
   17  php74 -v ←バージョンが表示された
```

VagrantにPHP入れるのが久しぶりすぎてこんなことになるんだっけ……？と首をかしげるものの、まあいいやと判定。遊ぶだけだし。

@tadsanさんの[PHPの無名関数式とは何か、そしてPHP7.4のアロー関数にそなえよう](https://qiita.com/tadsan/items/b2a37d1a7fed1b5b2cb1)を見ながらコードを記述。

```php
<?php
$array = [1,3,4,2,3,7,3,9];
$sorted[] = $max = $array[0];

$stalin_sort = fn($max, $el) => $max < $el ? $el: false;

foreach($array as $el)if($ret = $stalin_sort($max, $el)) $sorted[] = $max = $ret;
print_r($sorted);
```

```
[root@localhost vagrant]# php74 sort.php 
Array
(
    [0] => 1
    [1] => 3
    [2] => 4
    [3] => 7
    [4] => 9
)
```

一行で書くのがかっこいい気がして一行で書いてみました（コード6行目）。
可読性が下がっただけのような気もします。

```展開.php
foreach($array as $el){
  if($ret = $stalin_sort($max, $el)){
   $sorted[] = $max = $ret;
 }
}
```

書きながら「後置ifほしい〜(Ruby, Python)」とか「あれっPHPの論理式の戻り値って真偽値だっけ……？(JavaScript)」となったりしました。もうだめだ何がどの言語だったか境目が曖昧になりつつある……。
[Next 2019聴講メモ] Cloud Run ~Knativeを使った新しいサーバーレス

※※2019/08/14 追記 YouTubeに投稿されたセッションのリンクを追加しました。※※

# Cloud Run ~Knativeを使った新しいサーバーレス
- 篠原一徳
  - Google Cloud
    - Anthos
    - serverless
    - k8s
- [YouTube](https://www.youtube.com/watch?v=nkAblPrBKow&t=23s)

-----
## そもそもserverlessって?(Googleの定義)
- no infra management
  - インフラの管理はユーザーでは行わない
- fully managed security
  - Google側でセキュリティ問題が完結している
- pay only for usage
  - 従量課金制

### googleのサーバーレスコンピュート
- Functions
- App engine
- Cloud Run

## why Cloud Run?
- Cloud Run以外で起こる問題点
  - 使用できる言語、ライブラリに制約
  - ベンダーロックイン
  - GPU/TPUなど特定のハードへのアクセスができない
- 解決のために
  - Knative
    - k8sクラスタにFaaS/PaaS実行環境を構築
      - OSS(Google発祥)
      - コンテナをサーバーレス**ライク**に使える
      - k8sクラスターのハードウェアリソースが使える(GPU/TPU)
    - building block
      - platform
             - k8s
             - istio
      - Primitives(use Knative)
             - build
             - serving
             - Events
      - Products
             - SAP
             - Cloud Run
             - Cloud Run on GKE
             - etc

### 特徴
- 高速なデプロイ
  - ステートレスなコンテナ
  - 高速に0から無限にスケール
  - 数秒でデプロイ
- サーバーレスネイティブ
  - コードに集中できる
      - ランタイムの制約がなくなる
- 高いポータビリティ
  - コンテナベースのため
  - Knativeベースであれば他ベンダーでも使える

### 2つのCloud Run
- Cloud Run
  - 完全にサーバーレス
  - 使った分だけ
  - Borgが使われている
  - VPCアクセスできない
- Cloud Run on GKE
  - クラスターの費用に依存する
  - VPCアクセスできる

２つの対比としては[こちら](https://twitter.com/ahmetb/status/1116041166359654400)がよくわかりやすい(らしい)

#### リソースモデル
- Service
  - Cloud Runの主リソース
  - Service毎にエンドポイントを提供
- Revision
  - デプロイする毎に生成される
  - デプロイされるとリクエストが割り振られる
- Container Instance

### ユースケース
- 外部サービス公開
- IAMをつかってプライベートにアクセス
  - エンドポイント自体はネットワークに公開される(ファイアウォールはない)
  - ソースに認証トークンを埋める
- 非同期タスク
- Cloud Schedulerを使って定期的に呼び出す
- DB接続

### なぜ高速にデプロイできるのか
- gVisorを使っている
  - システムコールを阻害
- concurrencyを使ったリソース消費とコストの最適化
  - １つのコンテナインスタンスに投げられるリクエストの最大数
  - コンテナとかを適切に制御
  - **チューニングポイントになる**
      - レイテンシーとかに関わる
  - 時間課金の考え方
      - 完全にアクセスがなくなるまで
- Stackdriverとの連携
  - Monitoring
  - logging
  - error reporting

## どうサーバーレスを使い分ける？
- Functions
  - ソースベース
  - イベントドリブン
- App Engine
  - ソースベース
  - １プロジェクトにつき１リージョンの制約
- Cloud Run
  - コンテナベース
  - ランタイム制約・ロックインなし
​

## まとめ
- Cloud Runはコンテナをサーバーレスに使える
- 様々な制約がない(言語、ランタイム)
- [YouTube](https://youtu.be/nkAblPrBKow)

## 個人的に調べたいToDo
- gVisor
- Cloud RunとCloud Run on GKEの対比
PHP内のHTML/JSを含む複数行文字列がつらいとき

ヒアドキュメント

```php
function traditionalHereDoc()
{
    // $ を使うとき \ でエスケープが必要
    // でも PhpStorm の Language Injection で \$ はシンタックスエラー
    html(<<< HTML
<div class="abc"></div>
<script>
    \$(function() {
        var \$var = \$('.abc');
        \$var.text("123");
    });
</script>
HTML
    // 次のカンマを打つのに改行しないといけない
    , false);
}

function html($html, $encode = true)
{
    if ($encode) {
        $html = htmlspecialchars($html);
    }
    echo $html . "\n";
}
```

Q. 不愉快ですなんとかなりませんか?

A. 文字列リテラル内で改行できますよ

```php
function multilineStringLiteral()
{
    // シングルクオート内でシングルクオートを使うときつらい
    html(
'<div class="abc"></div>
<script>
    $(function() {
        var $var = $(\'.abc\');
        $var.text("123");
    });
</script>', false);
}
```

A. 俺の文字列の囲み記号は `ob_start ?>` と `<?php ob_get_clean` だぜ

```php
function outputBufferingTrick()
{
    // ハック臭がキモい。邪道
    ob_start();
?><div class="abc"></div>
<script>
    $(function() {
        var $var = $('.abc');
        $var.text("123");
    });
</script><?php
    html(ob_get_clean(), false);
}
```

最初にもどって、ヒアドキュメントを Newdoc `<<< 'HTML'` にするのがいちばんマシな方法か...

でも結局シュッとインデント揃わないし、終端マーカーのあと改行しないといけないし、てかむしろ、本当に欲しいのは Ruby 2.3 の `<<~` なんですよわかってくださいよ。

PHP 7.3 がわかってくれた!

```php
function php73FlexibleNewDoc()
{
    // $ を展開しないしインデントもできるし終端マーカーの後にコード書けるし最高
    html(<<< 'HTML'
        <div class="abc"></div>
        <script>
            $(function() {
                var $var = $('.abc');
                $var.text("123");
            });
        </script>
        HTML, false);
}
```

結論 = さっさと PHP のバージョンを 7.3 にしましょう。

参考: [フレキシブルなheredocがやってくる - Qiita](https://qiita.com/tadsan/items/3e5a094cd57e430b6ea9)

かぶってるけど大事なことなのでじゃんじゃん上げていきますよ
最近Enumについて気になったことをまとめておく

## はじめに
- 今回のお題は表題の通りです

## きっかけ
- チーム開発をしていて、Enumにおける情報の持たせた方って結構人によってまちまちで、~~ちょっと不満があったので記事にして鬱憤を晴らそうという今回の魂胆であります~~　自分の知識整理に生かそうと思いました。

## 問題のコード
- さっそく本題に入っちゃおうかと思いますが、まず前提としてEnumの定数の名前って、基本的に大文字+アンスコってのは共通理解だと思います(Enumじゃなくても)
- そんで、下みたいな感じで書いていくと思うんですけど

```WeatherEnum.java

public enum WeatherEnum {

    WEATHER_SUNNY("weather_sunny", "sunny"),
    WEATHER_CLOUDY("weather_cloudy", "cloudy")
    ;
    
    private String lowerCase;
    private String shortName;

    // GetterとConstructorは省略
}
```

- 気になったのは、定数名の全小文字をEnumの情報として持つような実装をしてるケースがあって、それってどうなのかなと個人的にもやもやした次第なのです。

### 気になった理由
- 保守性をあまり考えてない気がした(定数名と値の両方を修正する必要がある)
- toString().toLowerCase()すればいいじゃんというツッコミ

## それでどうしたかというと・・・
- 値としては持たずに、呼び出し側でtoLowerCase()するのがベターな気がしたので、その場はそうする方向で倒したのですが、ちゃんと調べてみると色々できそうな気がしたので、ベストかはわからないけど、何個かアンサーを出して置こうかなと思います(多分、チーム内で合意が取れてればいいと思う)

### 案１
- 呼び出し元で毎回.toLowerCase()する
- これは多分、一番簡単なやり方な気がします。ただ、呼び元のコードが冗長になる気もします。

### 案2
- Enum側でメソッドを定義してしまう
- ほぼGetterみたいなメソッドを新たに定義するって感じです。
- 個人的にはあんまり好きじゃないです

```WeatherEnum.java
public enum WeatherEnum {

    WEATHER_SUNNY("sunny"),
    WEATHER_CLOUDY("cloudy")
    ;

    private String shortName;

    // GetterとConstructorは省略

    public String getLowerCase() {
        return toString().toLowerCase();
    }
}
```

### 案3
- toString()をオーバーライドする
- Enumの定数名の取り方ってname()かtoString()どちらかで取れると思うんですけど、name()がオーバーライドできなくて、toString()ができるって違いだと思うんですが、[oracleDocs](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Enum.html)を読んだ感じ、定数名として定義したものより、もっとプログラマフレンドリなワードがある場合はtoStringをオーバーライドするといいよって書いてありますね。
- なので、全小文字の方がユースケース多いよって言うなら、オーバーライドしちゃって全然問題ないってことですね
- 個人的にはこれが本来の正しい使い方なのかと

```WeatherEnum.java
public enum WeatherEnum {

    WEATHER_SUNNY("sunny"),
    WEATHER_CLOUDY("cloudy")
    ;

    private String shortName;

    // GetterとConstructorは省略

    @Override
    public String toString() {
        return name().toLowerCase();
    }
}
```

### 案4（おまけ）
- 結論としては、案３がいいのですがせっかく他にも思いついたので書くだけ書こうかと思います
- Java8からinterfaceに実装を持てるようになったので、interfaceで定義しておいて、EnumはimplementsしてOverRideするというやり方です
- 今回のような簡単なケースではメリットはなく、やりすぎ感は拭えないのですが、とはいえやり方の1つとして知っておいたもいいのかなと思います

```HelloInterface.java
public interface HelloInterface {

    String getLowerCase();
}
```

```HelloEnum.java
public enum HelloEnum implements HelloInterface{

    WEATHER_SUNNY( "sunny"),
    WEATHER_CLOUDY( "cloudy")
    ;

    private String shortName;

    // GetterとConstructorは省略
    
    @Override
    public String getLowercase() {
        return name().toLowerCase();
    }
}
```

## まとめ
- EnumのtoString()をオーバーライドして、自分たちのユースケース的に１番欲しい、定数名の表示形式を返すように実装してあげるのが良さそう
- その際に、全大文字が欲しいとかの稀なケースに出くわしたらname()で回避してあげようねって話でした

## 参考リンク
- [Enum - Oracle Docs](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Enum.html)
vscodeのRemote SSHを古いWindowsで使う方法 

Windows 8.1でvscodeのRemote SSHを使おうとしたところ、SSH接続の部分で
`An SSH installation couldn't be found`
のエラーがでて使えなかった。
sshコマンドのパスが通っていないためだった。

`Ctrl+,`を押して、settingsを開き、`Search settings`に
remote.SSH.path
と入力する
Remote.SSH:Pathの欄にsshコマンドのパスを入力する
`C:\Program Files\Git\usr\bin\ssh.exe`

参考
https://code.visualstudio.com/docs/remote/troubleshooting#_installing-a-supported-ssh-client
AWS 認定資格 アソシエイトレベルの デベロッパー と アドミニストレーター

1年近く伸ばし続けてきた デベロッパー と アドミニストレーター のアソシエイトに合格しました。

ここに書いてあることは、私の主観で書かれています。必ずしも試験の内容を反映しているとは限りません。

## 私のバックグラウンド

- 主に携わっている構成
    - EC2に搭載した LAMP環境
    - ECSで稼働する Node.jsのAPIサーバ
    - DBは Aurora(MySQL互換)
- CI/CDは GithubとCircleCIを主に利用している
- CloudWatch でメトリックスを監視
- CloudWatch Logsにログを集約
- バッチ処理のキュー管理にSQS
- SNSでPush通知

## 全体的な印象

2018年に改定されたことで、 *サーバレス* に関係する問題が多くなりました。

- Lambda
- CloudFormation を利用して Lambdaにデプロイ
- DynamoDB
- ECS
- CodeDeploy/CodeBuild/CodePipeline

一方で出題数は減少したものの、継続して出題される分野もあります。

- DynamoDB
- SQS
- SNS
- IAM
- KMS
- S3

最後に、出題数が大きく減らした分野です。

- Elastic Beanstalk

## 勉強方法

多くの試験対策記事に書かれていることはやっていません。公式のチュートリアルを写経しました。

- DynamoDB
- Elastic Beanstalk

## 雑感

以前からだけど、ベンダー試験を受けたときに、業務での利用頻度が低い分野は特典が低い。暗記系は苦手なので手を動かさないと頭に入ってこない。
公式のチュートリアルをやった後にリファレンスを読むが楽。
ストレージについてまとめてみる①

#ストレージについてのまとめ①
##0.動機
社会人１年目ががんばるためのアウトプットです。
最初のおつかいは、ストレージのお勉強になったので今日調べたことをまとめます。
##1.ストレージとは
ストレージとは一言で言ってしまうと補助記憶装置。
外付けのメモリである場合が多く、HDD、SSD、光ディスク、SDカードやUSBなんかもそうですね。
これはITあるあるだと思っているのですが、コンシューマが使用する場合と法人が使用する場合で呼び方やくくりが少しずつ違います。
メモリ（主記憶）との違いは
メモリは処理メイン（記憶＜処理）に対してストレージは記憶メイン（記憶＞処理）になることでしょうか。
そもそも揮発性と不揮発性で分けているので当たり前ちゃ当り前ですよね。

##2.どういった種類があるのか
ストレージの種類は主に３つ
・HDDストレージ
　HDDを使ったストレージ
・フラッシュストレージ
　SSDを使ったストレージ
・オンラインストレージ
　クラウドサービスの1種（SaaS)のストレージ

##3.じゃあベンダーは何をしているのか
2でHDDやSSDなんて言葉が出てきましたが、それを組み合わせる技術に、データ保護のためのRAIDやサポートといった保守運用があります。ケーブルやコントローラーのことも考える必要がありますよね。
また、法人で使う場合には、または、使用台数とが業務内容によって負荷がどれくらいかかるのかは専門家に任せたほうが早いです。そのためにベンダーがいるのです。

##4.HDDとSSD
今までのストレージはHDDを使うことが多かったですが、最近になってSSDを使うオールフラッシュストレージが急成長中だそうです。
SSDは何より容量が大きくて安い。しかも、これまでの課題であった信頼性をピュア・ストレージのPurityOSという技術によって大幅に改善されたようです。

##まとめ
ストレージとは何かについて調べました。
次回は成長中のピュア・ストレージと他社との比較を用いて書いていきます！
マークアップ初心者のhtml,css謎現象と対処方法

## css,html謎現象
マークアップ時に「おやっ？」と遭遇した謎の現象と、
それに対処した方法を再現しつつメモ

深く追求したい気持ちは山々だけども、
とにかく解決せねばということで解決方法のみです。

原因、対処不可ケース、ブラウザ依存に関しては発見次第随時更新していきたいので、
コメント等大歓迎です！

## inline-blockの隙間
### 現象
メニューなどでよく使う`inline-block`
「あれっ？」と思った隙間はまずこれを疑うべし！

<img width="291" alt="スクリーンショット 2019-08-01 17.02.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348630/3b56193d-2886-f976-d863-35cb4d6b865b.png">


```
<div class="parent">
  <div class="child">inline-block</div>
  <div class="child">inline-block</div>
  <div class="child">inline-block</div>
</div>
```

```
.parent {
  display: block;
}
.child {
  display: inline-block;
  font-size: 16px;
  background-color: red;
}
```

### 対処方法
親要素に`font-size: 0;`を指定で解決
<img width="291" alt="スクリーンショット 2019-08-01 17.11.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348630/922968b0-f1da-d844-00e2-c5bbe3454bed.png">

```
    .parent {
      display: block;
      font-size: 0;  ←これ
    }
    .child {
      display: inline-block;
      font-size: 16px;
      background-color: red;
    }
```
母平均の区間推定で「中心極限定理」を使う

[Pythonで「中心極限定理」を確かめてみる](https://qiita.com/sand/items/5adfa593abe928bf266c)
[母平均の区間推定で「中心極限定理」を使う](https://qiita.com/sand/items/924e072f92ab1ae419db)



# 中心極限定理

nが大きいときは、中心極限定理は以下のように言い換えることができます。つまり**母分散**がわからなくとも**不偏分散**を計算すればよいわけです。


```math
\begin{align}
\\
&【中心極限定理】\\
\\
&平均値\mu、分散\sigma^2 の分布に従う独立したn個の確率変数X_1、X_2、...、X_n について、\\
&次のように\bar{X}を定義する。\\
\\
&\bar{X} = \frac{X_1 + X_2 + ... + X_n}{n}  \qquad （標本平均）\\
&nが大きいとき、この確率変数\bar{X}は平均値\mu、分散\frac{\sigma^2}{n}の正規分布に従う。\\
\\
&またnが大きいときは、母分散\sigma^2は不偏分散s^2で近似できるので、結局\\
&確率変数\bar{X}は平均値\mu、分散\frac{s^2}{n}の正規分布に従うと言える。\\
&ちなみに不偏分散の定義は以下の通り。\\
\\
&s^2 = \frac{(X_1-\bar{X})^2+(X_2-\bar{X})^2+...+(X_n-\bar{X})^2}{n-1}  \qquad （不偏分散）\\
&\qquad \qquad  \qquad \qquad  \qquad \qquad  \qquad \qquad \qquad  \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad  \qquad  \\
\end{align}
```

上の定理のポイントは以下の2点です。

* 母分布について正規分布の前提を置く必要がない
* 母分散を知る必要がない

母分布が正規分布で、母分散がわからない場合であれば、**t分布**が使えます。ここでは母分布が正規分布であるという前提を置かない代わりに、**nが大きい**という前提条件を置き**中心極限定理**を使っています。


# 母平均を区間推定する

正規分布の特徴はよく調べられています。上の「中心極限定理」から、以下のような「信頼度95％」が簡単に導くことができます。


```math
\bar{X} -1.96 \times \frac{s}{\sqrt{n}} \leqq \mu \leqq \bar{X} +1.96 \times \frac{s}{\sqrt{n}} \qquad （信頼度95％の公式）
```


つまりn個の標本Xをとると標本平均の区間が上記公式のように推定できます。**信頼度95％というのは、確率的に次のことを意味しています。n個の標本Xを100回採った時に100個の区間が考えられるが、母平均を実際に含むのは95区間で、残りの5区間は外します。**


```math
\begin{align}
&【例題】
\\
&埼玉県の15才の男子1000人を選び標本とします。\\
&標本の平均身長は162.0で、不偏分散は5.8^2でした。\\
&埼玉県の15才の平均身長\mu（母平均）を信頼度95％で推定しましょう。\\
\\
&【解答】\\
&161.64 \leqq \mu \leqq 162.36
&\qquad \qquad  \qquad \qquad  \qquad \qquad  \qquad \\
\end{align}
```


信頼度95％の公式を、以下のような簡単なPythonプログラムで計算させ、解答が得られます。


```
import numpy as np
d=1.96*5.8/np.sqrt(1000)
print(162-d)
print(162+d)

# 出力結果
# 161.64051227559204
# 162.35948772440796
```


今回は以上です。
Power BI Tips - 公開したWebページを削除する

#概要
Power BI Desktopを入れていないお客さんに、
Power BIの画面イメージを見せようと思って
Power BI Serviceにpbixを発行し、ページをWebで公開する
・・・なんてシチュエーション、結構あると思うんです。

で、お客さんに見てもらって、不要になったのでURLを消したいと思ったけど、
パッとわからなくて調べた際の備忘録です。


#手順
公開したワークスペースを開いて、いろいろそれっぽいメニューの中を探しても
URLを削除するボタンは見つからないです。

どこにあるかというと、ここ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/4660b164-9605-050e-8f2c-64c92d9750e1.png)

この「埋め込みコードの管理」にあります。
ここをクリックすると、以下のような画面が表示されます。
対象ワークスペースの「・・・」をクリックし、削除を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/acdee0aa-c6c4-9d16-1cf0-900dc6319ff1.png)

確認画面が表示されるので、「削除」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/d81d3c06-14be-324b-9956-0609a51766b5.png)

#余談
Webの公開機能って、埋め込みコードの作成と一緒になっちゃってるんですよね。
自分はWebの公開機能のURL削除って思って、
そのキーワードで検索しちゃってました。
⇒ワークスペースのファイルメニューの中には、「Webに公開」って書いてあるし。

削除の方のメニューは「埋め込みコードの管理」って書いてあって、
パッとわからなかったです・・・。



#参考
[Power BI から Web への公開](https://docs.microsoft.com/ja-jp/power-bi/service-publish-to-web)
UnityでAssembly Definition Fileを追加したらエディタでのコンパイルは通るがビルドできなくなった人が見るページ

# はじめに

Assembly Definition Fileの概要は分かっている前提での説明です。

参考: [Unity2017.3のAssembly Definition Filesを適切に設定してコンパイルにかかる時間を削減する - Qiita](https://qiita.com/nkjzm/items/aaad87dc7f7bc9703449)

# 原因

恐らく`Editor`ディレクトリ以下をビルドしようとしていることが原因。

通常Unityでは`Editor`ディレクトリ以下はUnityエディタ上でのみ動作し、ビルドには含まれない扱いになる。実は内部的にEditorディレクト内にAssembly Definition Fileが定義されている状態である。

手動でAssembly Definition Fileを追加した場合、それ以下に含まれる`Editor`ディレクトリではAssembly Definition Fileが作成されなくなることからビルド時にエラーが発生する。

# 解決方法

該当の`Editor`ディレクトリに対し、手動でAssembly Definition Fileを定義してやればいい。

<img width="537" alt="スクリーンショット 2019-08-01 16.33.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/01b72d6e-f2a9-0926-b44d-23331eee72ea.png">

気をつけるポイントとしては以下の通りです。

- `Platform`を`Editor`のみにする
    - `Any Platform`のチェックを外した状態で、`Include Platforms`の`Editor`のみにチェックに入れている状態
    - `Any Platform`のチェックが入った状態だと`Exclude Platforms`(対象外のプラットフォーム)の表示になり、全く逆の状態であることに注意
- Assembly Definition Referencesに親のAssembly Definition Fileを追加する
    - これをしないと恐らくエディタ上でもコンパイルエラーが発生する

# 最後に

いちいちコンパイルが走るので、作業量の割に時間がかかって面倒くさいけど、がんばってください
waitしたい時に直接idやclassで指定できないDOMでも指定する方法

あるDOMをクリックするとこんなDOMに遷移する。

```html:test.html
<ul id="hogehoge" class="fugafuga">
 <li class="hoge fuga">...</li>
 <li class="hoge fuga">...</li>
 <li class="hoge fuga">...</li>
 <li class="hoge fuga">...</li>
</ul>
```
このliタグはクリックすると別のページに遷移する。
3番目のliタグをクリックして遷移したかった。

```python:test.py
driver.find_element_by_id('hogehoge').find_elements_by_class_name('hoge')[2].click()
```
これはいい。ただ1つ問題が。
冒頭に書いた通り別のところから遷移してきてこのDOMにくるのだが、
処理が速すぎてNoSuchElementExceptionを喰らうことがあった。

```python:test.py
time.sleep(5)
driver.find_element_by_id('hogehoge').find_elements_by_class_name('hoge')[2].click()
```
これは確実なやり方だが時間を待ちすぎてしまう。
なのでwaitを使いたかったのだが、

```python:test.py
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CLASS_NAME, 'XXXXXXXXXXXXXX')))
driver.find_element_by_id('hogehoge').find_elements_by_class_name('hoge')[2].click()
```
このXXXXXXXXXXXXXXに何をぶっこむべきかが分からない。

teratail先生に伺ったところCSSセレクタを使えとのこと。

```python:test.py
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.fugafuga li:nth-child(3)')))
driver.find_element_by_id('hogehoge').find_elements_by_class_name('hoge')[2].click()
```
やはりteratailは神。
そして一度CSSをちゃんと勉強しようと思った。