OmniAICreator/Qiita-1.07M huggingface dataset:
ParameterGridクラスを用いてグリッドサーチを自力で行う

### はじめに
グリッドサーチを行うにあたり細かい制御を行う必要があり、パラメータの組み合わせ生成等が面倒だったため調べたときのメモ

### 環境
- Windows 10
- Python 3.6
- scikit-learn 0.20

### やり方
グリッドサーチをやる場合、各パラメータの探索範囲をDictで定義し、それをGridSearchCVの引数に与えると思う。同じ形のDictをインプットとして、グリッドサーチを自力でやろうとした場合、Dictからモデルのset_paramsの引数に与えられる形式で、全パラメータの組み合わせを生成する必要があるが、この実装がかなり面倒くさい。

scikit-learnのGridSearchCVクラスのソース等をいろいろ調べたところ、ParameterGridクラスを用いると簡単にできることが分かった。

百聞は一見に如かず、とりあえずソースを見てみよう。まずは必要なものをインポートする。

```python
import pandas as pd
import numpy as np

from sklearn.model_selection import ParameterGrid
from sklearn.model_selection import KFold

from sklearn.metrics import matthews_corrcoef
from sklearn.metrics import roc_auc_score

from sklearn.ensemble import ExtraTreesClassifier
from sklearn import metrics
```

次にモデルおよびGridSearh用のDictの定義。そして、ParameterGridを用いてDictに対する全パラメータの組み合わせのリストを生成。

```python

   clf = ExtraTreesClassifier()
   param_grid = {
        "class_weight" : ["balanced", "balanced_subsample", None],
        "max_features" : ["sqrt", 0.3, 0.6, 0.9],
        "n_estimators" : [10]
       }

   param_dicts = list(ParameterGrid(param_grid))

```

そして、全パラメータの組み合わせのリスト毎にモデルの評価を実施することで、自前のグリッドサーチを実施。

```python

   auc_all = []

   for i, param_dict in enumerate(param_dicts):
        auc_cvs = []

        for train_index, test_index in KFold(n_splits=10, random_state=42, shuffle=True).split(X):
            X_train, X_test = X[train_index], X[test_index]
            y_train, y_test = y[train_index], y[test_index]

            clf.set_params(**param_dict)
            clf.fit(X_train, y_train)
            y_predict = clf.predict(X_test)
            y_predict_score = clf.predict_proba(X_test)[:, 1]
            auc_cvs.append(metrics.roc_auc_score(y_test, y_predict_score))

        auc_all.append(np.array(auc_cvs).mean())

   print(auc_all)

```

decision threshold等を変化させて指標を最適化するなど、より細かいグリッドサーチを行う場合は、こんな感じグリッドサーチを実装すればでできますよ、という話でした。
flynn使ってみた #GWアドベントカレンダー10日目


 #GWアドベントカレンダー[「使いたかったもの使ってみたカレンダー（1人アドベントカレンダー）」](https://gw-advent.9wick.com/calendars/1)の10日目、5/6記事です。


# flynn使ってみた

DokkuをGWの前半で使ってみましたが、dokkuを調べてる最中にでてきた[flynn](https://flynn.io/)も使ってみました。
どちらもmini heroku と言われるOpenPaasの一種です。

## 良さそうなところ/面白かったところ

全体的にdokkuの上位互換感がありました

- **UIがある！**
- githubと連携すればgithubからcloneしてデプロイできる
- 複数のサーバーでクラスタが組める
- dokkuにできることはだいたいできる

## あんまりイケてないところ

- SSL系がdokkuよりも難しそう/めんどくさそう

## 総合評価

dokkuに惚れた！と思ってましたが、１週間立たず、dokkuよりもflynnだ！と思うようになりました。
残念ながら個人サーバーにdokkuを導入済みなので、次にサーバー借りるときはflynnにしたいと思います。

クラスタ構成にするつもりがないので、今のサーバーを切り替える労力ほどのメリットとは感じなかったです。
DRFのviewで使えるHTTPメソッドを見分ける

人が作ったAPIを利用するとき用、SWAGGER/OPEN APIが導入されてない環境用。

```python
from rest_framework.generics import RetrieveUpdateDestroyAPIView #
```

viewのclassが何を継承してるかで見分けていく


|クラス|`GET`|`POST`|`PUT`|`PATCH`|`DELETE`|
|---|---|---|---|---|---|
|`ListAPIView`| ✅|-|-|-|-|
|`RetrieveAPIView`| ✅|-|-|-|-|
|`CreateAPIView`|-|✅|-|-|-|
|`DestroyAPIView`|-|-|-|-|✅|
|`UpdateAPIView`|-|-|✅|✅|-|
|`ListCreateAPIView`| ✅|✅|-|-|-|
|`RetrieveUpdateAPIView`|✅|-|✅|✅|-|
|`RetrieveDestroyAPIView`| ✅|-|-|-|✅|
|`RetrieveUpdateDestroyAPIView`| ✅|-|✅|✅|✅|


```py
# 例えばこれは、GET、POST両方OK
class HogeHogeList(ListCreateAPIView):
```


## 参考

Documentに書かれてるが早見表的ものが欲しかった

https://www.django-rest-framework.org/api-guide/generic-views/#concrete-view-classes

## 備考

viewが関数とデコレーターで実装されてる場合は、この辺は読んでて全然困らない


```py
@action(methods=['POST'],detail=True)
def register_token(request, code):
```
Nuxt.js + ikonate(npmパッケージ中のsvgファイルのロード)

Nuxt.jsやVue.jsを利用していて、npmパッケージ内のsvgファイルを描画したくなることってありますよね？
私は最近トレンドに上がっていた、[ikonate](https://www.ikonate.com/)というsvgなiconライブラリを利用する際にハマりました。

ただ表示するだけなら、`img`タグの`src`に指定すればよいのですが、色やスケールを変化させたい場合、この方法だと難しいようです。

参考: [【Vue】svg画像をそのまま出力して色を変える](https://qiita.com/totto357/items/7e59bb4a034bfb340490)

## vue-svg-inline-loader

[vue-svg-inline-loader](https://github.com/oliverfindl/vue-svg-inline-loader)を使うことで、色の指定やスケールが可能な状態でsvgファイルを描画することができます。

今回実装したプロジェクトは[reireias/nuxt-ikonate-example](https://github.com/reireias/nuxt-ikonate-example)で公開しています。

### 環境
今回使用したライブラリのバージョンは下記の通りです。

- Node.js: v12.0.0
- Nuxt.js: 2.6.3
- vue-svg-inline-loader: 1.2.15
- ikonate: 1.0.1

### プロジェクト作成
プロジェクトを作成していきます。

```sh
yarn create nuxt-app nuxt-ikonate-example
# 選択肢は適当に(例ではvuetifyを利用しています)
```

vue-svg-inline-loaderとikonateを追加します。

```sh
yarn add -D vue-svg-inline-loader
yarn add ikonate
```

vue-svg-inline-loaderの[README](https://github.com/oliverfindl/vue-svg-inline-loader/blob/master/README.md)に従い、`nuxt.config.json`に設定を追加します。

```json:nuxt.config.json
  build: {
...
    extend(config, ctx) {
      // Run ESLint on save
      if (ctx.isDev && ctx.isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
      // vue-svg-inline-loader
      const vueRule = config.module.rules.find(rule => rule.test.test('.vue'))
      vueRule.use = [
        {
          loader: vueRule.loader,
          options: vueRule.options
        },
        {
          loader: 'vue-svg-inline-loader'
        }
      ]
      delete vueRule.loader
      delete vueRule.options
    }
...
```

※ Vue.jsの場合は[vue-svg-inline-loader]()のREADMEに書かれている設定を参考にしてください。

### svgファイルの読み込み

あとは下記のように`img`タグに`svg-inline`属性を追加して読み込むと、表示されます。
この状態ならcssによる色の指定も効きます。

```vue:pages/index.vue
<template>
  <v-layout column justify-center align-center>
    <v-flex xs12 sm8 md6>
      <div class="text-xs-center">
        <h1>Nuxt.js + ikonate example</h1>

        <img
          svg-inline
          svg-sprite
          class="ikonate ikonate-red"
          width="24px"
          height="24px"
          src="ikonate/icons/activity.svg"
        />
        <p>24px</p>

        <img
          svg-inline
          svg-sprite
          class="ikonate ikonate-green"
          width="32px"
          height="32px"
          src="ikonate/icons/chart.svg"
        />
        <p>32px</p>

        <img
          svg-inline
          svg-sprite
          class="ikonate ikonate-blue"
          width="48px"
          height="48px"
          src="ikonate/icons/camera.svg"
        />
        <p>48px</p>
      </div>
    </v-flex>
  </v-layout>
</template>

<style>
.ikonate {
  fill: none;
}
.ikonate-red {
  stroke: red;
}
.ikonate-green {
  stroke: green;
}
.ikonate-blue {
  stroke: blue;
}
</style>

```

上記ページを表示すると下記のように表示されます。

![ikonate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/ebf803c7-7133-2841-74ef-23604b4027f5.png)

## まとめ
Nuxt.jsでsvgファイルを色・サイズを変更可能な状態で読み込むことができました。
Lambda から Google API を呼ぶと権限ファイルの書き込みで `[Errno 30] Read-only file system` になる

# 背景

- 以下の記事に沿って Gmail API を叩く Python スクリプトを作成
  - https://news.mynavi.jp/article/zeropython-22/
- スクリプトを Lambda で動くようにして、実行したところ `[Errno 30] Read-only file system` が発生
  - ローカルで実行したときには起きなかった

# 原因

- 権限ファイル (client_id.json) の書き込みでエラーになっている模様
- エラーのスタックトレースを見ると、oauth2client ライブラリ内で発生しているようだった

```json
"errorMessage": "[Errno 30] Read-only file system: 'client_id.json'",
  :
    [
      "/var/task/oauth2client/file.py",
      79,
      "locked_put",
      "f = open(self._filename, 'w')"
    ],
  :
```

- `self._filename` は Storage クラスのコンストラクタ引数
  - https://github.com/googleapis/oauth2client/blob/master/oauth2client/file.py#L33
  - 作成したスクリプトでは client_id.json のパスを渡しており、client_id.json はスクリプトと同じディレクトリに置いていた
- Lambda が書き込みできるのは `/tmp` 配下のファイルのみなので、Read-only エラーとなった

# 対応

- client_id.json を一旦 `/tmp` に退避させてから Storage クラスを作成する

```python:before
    user_secret_file = 'client_id.json'
    store = Storage(user_secret_file)
    credentials = store.get()
```

```python:after
import shutil
 :
    user_secret_file = 'client_id.json'
    user_secret_tmp_path = '/tmp/' + user_secret_file
    shutil.copy2(user_secret_file, user_secret_tmp_path)

    store = Storage(user_secret_tmp_path)
    credentials = store.get()
```

# 参考

- https://stackoverflow.com/questions/45608923/aws-lambda-errormessage-errno-30-read-only-file-system-drive-python-quic
[メモ]継承とは

この記事は「オブジェクト指向設計実践ガイド　～Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方」を読んだまとめです。
# 継承
継承はあるメッセージに応答できなければ、他のオブジェクトにそのメッセージを移譲する動きをする

スーパークラス（抽象クラス）はサブクラス間で共有される振る舞いの共有する格納場所を提供する。サブクラスがそれぞれに特化したものを用意する。いきなりスーパークラスを作るのではなく、サブクラスになり得るクラスが複数ある場合、共通の振る舞いを確認してスーパークラスに昇格する形で継承関係を作るようにする。

- 共通の振る舞いはスーパークラスに定義して、サブクラスで固有の振る舞いを定義する。以下の例では、サブクラスはdefault_tire_sizeを実装しているが、default_chainは実装していない。タイヤのサイズはサブクラスで定義する必要があるが、チェーンのサイズは共通しているのでスーパークラスで定義されている。(「テンプレートメソッド」パターン)

- default_tire_sizeが定義されていない時にエラーを発生させることで、default_tire_sizeが定義されていないサブクラスが作られることを防いでいる。
sparesメソッドはスーパークラスで共通する値を定義して、サブクラスでそれぞれ特化した値をマージしている。
- オブジェクトのクラスを確認し、どのようなメッセージをそのオブジェクトに送るか決める、自分の分類を保持する変数などを確認して、自身に送るメッセージを変えるこのパターンは、相手が誰だか知っているから、特定のメッセージを送る状態であり依存関係が生まれているので注意が必要。


```ruby

class Bicycle
  attr_reader:size,:chain,:tire_size
  
  def initialize(args={})
    @size = args[:size]
    @chain = args[:chain] || default_chain
    @tire_size = args[:tire_size] || default_tire_size
  end
    
  def spares 
    {tire_size:tire_size,
    chain:chain}
  end
    
  def default_chain
    '10speed'
  end

  def default_tire_size
    raise NotImplementedError
  end
end


class RoadBike < Bicycle
  attr_reader:tape_color
  
  def initialize(args)
    @tape_color = args[:tape_color]
    super(args)
  end
  
  def spares 
    super.merge({tape_color:tape_color})
  end
  
  def default_tire_size
    '23'
  end
end

class MountainBike < Bicycle
  attr_reader:front_shock,:rear_shock
  
  def initialize(args)
    @front_shock = args[:front_shock]
    @rear_shock = args[:rear_shock]
    super(args)
  end
  
  def spares
    super.merge({rear_shock:rear_shock})
  end
  
  def default_tire_size
    '2.1'
  end
end
```
RailsアプリをHerokuでデプロイする際の注意点

<h2>はじめに</h2>
初投稿です。本とネット教材で半年学んだ程度のヒヨッコです。
AWS cloud9でRuby on Railsプロジェクトを作成し、GitHub経由でHerokuでデプロイしました。
その際に発生したエラー・注意点を備忘録として投稿させていただきます。

<h2>Herokuの注意点</h2>
Herokuではsqlite3が使えないようなので、本番環境用のgemを別に設定する必要があります。
以下リンクを参考にPostgreSQLを入れました。
（参考）HerokuではSQLite3が使えない？！ https://qiita.com/MosamosaPoodle/items/7149aa66f1c087472777
<h4>・Rails Gemfileを修正</h4>

```rails:Gemfile
gem 'sqlite3' 
```
↓変更する

```rails:Gemfile
gem 'sqlite3', groups: %w(test development), require: false
gem 'pg', groups: %w(production), require: false
```
<h4>・Rails Gemfile.lockを削除しbundle installし直す</h4>
```rails:Terminal
$ rm Gemfile.lock
$ bundle install
```
これでRails上の設定は完了です。

<h2>AWS cloud9からgit push時の注意点</h2>
安全性の観点から、GitHubを二段階認証で管理すべきなのですが、
そうするとcloud9からpushする際にGitHubアカウントパスワードを入力してもエラーになります。

```rails:Terminal
Username for 'https://github.com': hoge-user
Password for 'https://hoge-user@github.com':
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/hoge-user/github-repository-name.git/'
```
対策として
・GitHubでPersonal Access tokensを発行し、tokenをPassword欄に入力する（https接続）
・SSH接続するよう設定を変更する
の2つがありますが、今回は前者を選びました。
（参考）GitHub「Personal access tokens」の設定方法　https://qiita.com/kz800/items/497ec70bff3e555dacd0

ちなみに個人的にハマった罠が2つありますのでそちらも書いておきます。
1. Terminal上のPassword入力時は、画面は反応しないが文字はちゃんと入力されている。心配せずに入力する！
2. コピーした文字をTerminal上にペーストするときはcommand+v (Ctrl+v)で入力しない。右クリック→Pasteでペーストする。

<h2>成果</h2>
半年間HTML, CSS, JavaScript, Ruby, Rails, AWS cloud9などと悪戦苦闘しましたが、素人でもHerokuでデプロイできました。
飲み会のお会計をシチュエーション別で傾斜計算する簡単なツールです。
Warikan - https://warikanappbygmnori.herokuapp.com/

デザインや計算方法の拙さは本人が一番実感しています。次はもっと良いものを作れるよう頑張ります。

<h2>参考リンク</h2>
HerokuではSQLite3が使えない？！ https://qiita.com/MosamosaPoodle/items/7149aa66f1c087472777
GitHub「Personal access tokens」の設定方法　https://qiita.com/kz800/items/497ec70bff3e555dacd0
vueのpropで型エラーが出ても値が入ってしまうパターンがある

以下のように指定して、vue-cli-service build --target wc でビルド。その後カスタムエレメントの属性で制約違反の値をセットしても、その値が入ってしまう。

コンソールにエラーは出るが、値が入るんじゃ全く意味がない。指定方法はこれで間違いはないと思うんだけどな。

```js

export default class TestVue extends Vue {
  @Prop(Number) readonly prop_a!: number
  @Prop({ type: Number, required: true, default: 999, validator: function () { return false; } }) readonly prop_b!: Number
  @Prop({ type: String, required: true, default: "デフォルト", validator: function () { return false; } }) readonly prop_c!: string
  @Prop({ type: Boolean, required: true, default: true, validator: function () { return false; } }) readonly prop_d!: boolean
略
}
```

自力で値チェックして、エラー時は` this.$el.parentNode.removeChild(this.$el);`で無理やり使えなくする処理が必要かな。
エラーが出ても画面上は変化がないからユーザは気付かずに使ってしまうだろうし。
[メモ] ダックタイピングとは

この記事は「オブジェクト指向設計実践ガイド　～Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方」を読んだまとめです。
# ダックタイピング
ダックタイピングはいかなる特定のクラスとも結びつかないパブリックなインターフェース
「もしもオブジェクトがダックのように鳴き、ダックのように歩くのなら、そのクラスは何であれ、それはダックである」というのが名前の由来。
パブリックインターフェースをクラスから切り離して抽象的にする。
何であるかではなく、何をするかによって定義される抽象的な型をを見つける。隠された抽象的なインターフェースを見つけることがダックタイピングにつながりクラス間の依存を取り除き柔軟な設計につながる。

```ruby
class Trip
attr_reader:bicycles,:customers,:vehicle

  #この'mechanic'引数はどんなクラスのものでもよい。
  def prepare(mechanic)
    mechanic.prepare_bicycles(bicycles)
  end
end

class Mechanic
  def prepare_bicycles(bicycles)
      bicycles.each{|bicycle|prepare_bicycle(bicycle)}
  end
  def prepare_bicycle(bicycle)
    #...
  end
end
```

Tripのprepareメソッドはprepare_bicyclesに応答できるオブジェクトに依存している。旅行の準備がメカニックにメッセージを送り自転車を準備するだけであれば問題はないが、準備工程が増えた時にこのままでは以下のようになり、Tripクラスは３つのクラス名と具体的なメソッドメソッドを知ってしまい依存してしまう。
Tripはメカニックにしかメッセージを送らないと想定していると、工程が増えたときに行き詰まってしまう。

```ruby

class Trip
  attr_reader:bicycles,:customers,:vehicle

  def prepare(preparers)
    preparers.each{|preparer|
      case preparer
      when Mechanic
        preparer.prepare_bicycles(bicycles)
      when TripCoordinator
        preparer.buy_food(customers)
      when Driver
        preparer.gas_up(vehicle)
        preparer.fill_water_tank(vehicle)
      end
    }
  end
end

class TripCoordinator
  def buy_food(customers)
    #...
  end
end

class Driver
  defgas_up(vehicle)
    #...
  end
  def fill_water_tank(vehicle)
    #...
  end
end
```

> 依存を取り除くための鍵となるのは、「Tripのprepareメソッドは単一の目的を果たすためにあるので、その引数も単一の目的を共に達成するために渡されてくるということを認識すること」です。
> どの引数も同じ理由のためにここに存在し、その理由自体は引数の背後にあるクラスとは関係しません。

MechanicもDriverもTripCoordinatorもそれぞれの役割は異なるが目的は、「旅行の準備をする者」である。この発想からダックタイプを生み出すことができる。
この視点で考えればprepare_trip(旅行の準備をする)振る舞いをするのが、「旅行の準備をする者」と言い換えることができる。

抽象的な「旅行の準備をする者」というインターフェースを想定して、prepare_tripを実装しているものは「旅行の準備をする者」というダックタイプができる。MechanicもDriverもTripCoordinatorも「旅行の準備をする者」として振る舞う必要がある。


```ruby

class Trip
  attr_reader:bicycles,:customers,:vehicle

  def prepare(preparers)
    preparers.each{|preparer|
      preparer.preparer_trip(self)
  end
end

class Mechanic
  def prepare_trip(trip)
    trip.bicycles.each{|bicycle|
      prepare_bicycle(bicycle)}
    end
  end

class TripCoordinator
  def prepare_trip(trip)
    buy_food(trip.customers)
  end
end
```

設計をどこまで抽象的にするかはトレードオフ。ifとクラス名で分岐させて具体的にコーディングすれば必要な時間は少なく済むだろうしぱっとはわかりやすい。しかし今後の拡張、変更にコストがかかる。抽象化は手間はかかるが今後の拡張、変更は容易になる。
PostgreSQLの CREATE (DATABASE|USER) で IF NOT EXISTS のようなことをしたい

# 要約

Vagrantや、あるいはChefのようなプロビジョニングを行うツールで活用することを目的としています。
PostgreSQLでは、CREATE DATABASE, CREATE USER で IF NOT EXISTS がサポートされていないので、psql と grep で代替します。

## CREATE USER IF NOT EXISTS の代替

```bash
sudo -i -u postgres psql -c "SELECT * FROM pg_shadow" | grep "(ユーザ名)"; \
if [ $? -ne 0 ]; then \
  sudo -i -u postgres psql -c "CREATE USER \\"(ユーザ名)\\" WITH PASSWORD '(パスワード)'"; \
fi
```

## CREATE DATABASE IF NOT EXISTS の代替

```bash
sudo -i -u postgres psql -l | grep "(データベース名)"; \
if [ $? -ne 0 ]; then \
  sudo -i -u postgres psql -c "
    CREATE DATABASE \\"(データベース名)\\"
      WITH OWNER \\"(ユーザ名)\\"
          ENCODING = 'UTF8'
          LC_COLLATE = 'ja_JP.UTF-8'
          LC_CTYPE = 'ja_JP.UTF-8'
  "; \
fi
```

## 補足
ユーザ名、データベース名で「\\\\"」とエスケープしていますが、ハイフンなど、そのままだとSQLエラーになるユーザ名やデータベース名の対処です。
家に帰ったら風呂が沸いている。これに勝る幸せはあるだろうか（いや、ない）。

本記事は[LINE Developer CommunityのGWアドベントカレンダー](https://gw-advent.9wick.com/calendars/18)最終日の記事となっております。
#はじめに
家に帰ったら風呂が沸いている。これに勝る幸せはあるだろうか（いや、ない）。
という訳で、家の外から風呂を入れる事ができるLINEBotを作りました。
本当は最近流行りのLINEThingsとかやりたかったんですけどね...。C言語苦手なので...。
#こんな感じ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">風呂のボタン押してみた<a href="https://twitter.com/hashtag/IoT?src=hash&amp;ref_src=twsrc%5Etfw">#IoT</a> <a href="https://t.co/04YkAMXIe7">pic.twitter.com/04YkAMXIe7</a></p>&mdash; しんぶんぶん@時間割bot (@shinbunbun_) <a href="https://twitter.com/shinbunbun_/status/1125212225914818560?ref_src=twsrc%5Etfw">May 6, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
botが超手抜きなのはアレですね。ちょっと忙しくて。そのうちリッチメニューとか活用したものを作リます。
#使ったもの
- [ESP32-DevKitC-32D](http://akizukidenshi.com/catalog/g/gM-13628/)*（秋月電子で購入。）
- [ブレッドボード](http://akizukidenshi.com/catalog/g/gP-05294/)（秋月電子で購入。裏に両面テープが付いている。）
- ジャンパワイヤ（家にあったやつをてきとーに。）
- [サーボモータ](http://akizukidenshi.com/catalog/g/gM-08761/)（秋月に売っていたやつをてきとーに。多分これだった気がする。）
- MicroUSBケーブル（キャンドゥで購入）
- 延長コード(キャンドゥで購入)
- ACアダプタ（家にあったやつをてきとーに。）
- メンディングテープ（同上）
- 両面テープ（同上）

*ESP32DはESP32の新しいやつらしいです。仕様に大きな違いはないらしいので取り敢えず新しい方を買ってみました。

#システム構成
<img width="1440" alt="スクリーンショット 2019-05-06 20.32.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260292/43cd6242-1884-0a7e-86dc-d9d80471bffc.png">

Moddableを使ったおかげで、良い感じに全部JSで統一出来ました。
べ、別にC言語書けないからModdable使ったわけじゃないんだからね！
LambdaでWSやるのがめんどくさそうだったのでWSのサーバはLightsailで動かしてます。

#ソースコード
https://github.com/shinbunbun/huro
汚いところはそのうち修正します。多分。
#参考サイト
##LINEBot

僕が書いたハンズオン資料がありますので,まだLINEBotを作った事がない方は是非ご参照ください。
https://qiita.com/shinbunbun_/items/b1d82f5bd85786a7f06e

##Moddable
JSでESP32を動かせるやつです
###環境構築
Moddableは環境構築がとても面倒臭いです。僕は以下の記事を参考にさせて頂きました。
https://make.kosakalab.com/make/electronic-work/moddable-sdk_build_how-to/
###実装
Moddableに関する日本語の記事はとても少なかったので、なけなしの英語力をフル活用してGithubを解読しました。
https://github.com/Moddable-OpenSource/moddable
数少ない日本語の記事だとこちらの記事がとても役に立ちました。
https://qiita.com/kimio_kosaka/items/3102911f4d09b16583b3

#問題点
- なぜか1回目にサーボが動かない事がある。2回目は必ず動く。
- これを作っていたせいでGWの宿題が終わらなかった

#最後に
IoTたのしいな。
自分用勉強メモ9日目

# tips

## 502 Bad Gateway

HTTPのエラーコードの1つ．
400番台がクライアント側のエラー（File not found とか）であるのに対し，500番台はサーバ側のエラーを示す．
今回は，ゲートウェイやプロキシが不正なリクエストを受け取ったことを示している．

参考：[HTTP502（Bad Gateway）の原因と対処法](https://uxmilk.jp/51406)

## SQLインジェクションの1つの解

管理者でのログインを試みる際，ユーザ名が`admin`で決め打ちだった場合，

```
admin'--
```

と入力すればパスワードが何であれログインに成功する．

# 調べた知識

## Base64

英数字と「+」「-」「=」のみを使って，マルチバイト文字等をエンコードする方式．これによって，英数字+@しか使えない通信環境でもマルチバイト文字等を扱うことができる．
エンコード・デコードには以下のサイトが便利である．

[オンラインBase64でデコーダ](http://www.convertstring.com/ja/EncodeDecode/Base64Decode)

## [ヴィジュネル暗号](https://ja.wikipedia.org/wiki/%E3%83%B4%E3%82%A3%E3%82%B8%E3%83%A5%E3%83%8D%E3%83%AB%E6%9A%97%E5%8F%B7)

換字式暗号の1つ．
アルファベットの対応表をもとに平文を暗号化する．
1つ1つ目で追って解読しても解けるが，スクリプトを書いて楽にしたい．

```Python:vigenere_cipher.py
import sys


class MyVigenere:
    def encode(text, key):
        ret = ''
        for i in range(len(text)):
            offset = (ord(text[i]) + ord(key[i]) - 2 * ord('a')) % 26
            ret += chr(ord('a') + offset)
        return ret

    def decode(text, key):
        ret = ''
        for i in range(len(text)):
            offset = (ord(text[i]) - ord(key[i])) % 26
            ret += chr(ord('a') + offset)
        return ret


if __name__ == '__main__':
    plaintext = sys.argv[1]
    key = sys.argv[2]
    flag = MyVigenere.decode(plaintext, key)
    print(flag)
```

## [John The Ripper](https://www.openwall.com/john/)

パスワードクラッキングツール．
以下，Ubuntuでの実行例を示す．

```bash
// ツールのインストール
# apt install john
// パスワードファイルとシャドウファイルを結合する
$ unshadow passwd shadow > tmp
// johnコマンドに渡す
$ john --show tmp
```

## [robots.txt](https://www.seohacks.net/basic/terms/robots_txt/)

検索エンジンのクローラーのアクセスを制限するためのファイル．
見せたくないページはここに記述するらしい．

# [picoCTF](https://2018game.picoctf.com/news)

きなこ(@kinako_software)さんのブログ([こちら](https://kinako-mochimochi.hatenablog.com/entry/2019/02/20/131937))を拝見して，cpawCTFの次はこれをやるといいよと書いてあったので取り組んでみる．
ヒントが書かれているので，もしわからなかったとしても調べればなんとかなりそう．

## Logon

ユーザ名とパスワードを入力してログインする．
何を入力してもログインに成功するが，adminでログインしたい．
Cookieを見ると，ログイン成功後に`admin`という変数が`False`で格納されている事がわかる．
これを`True`に書き換えてリロードするとログイン成功．

## Recovering From the Snap

ディスクイメージファイルが渡される．
`file`で見てみると，FATであることがわかる．
Ubuntuで，以下のコマンドを実行してマウントする．

```
# mount -t vfat animals.dd /mnt/animal/
```

これで`/mnt/animal/`以下に4つの画像が現れた．
Linuxでは，jpgファイルは`eog`コマンドで開くことができる．
しかし，どの画像を見てもフラグに関係するようには思えない．
ヒントを見てみると，いくつかのファイルが削除されてしまっているらしい．
[FTK Imager](https://accessdata.com/product-download)というツールを使うと，ディスクイメージをマウントしたときに削除済みのファイルにもアクセスできるらしい．
MacやLinuxではコマンドラインツールしか利用できず使い方が難しかったので，Windows版をダウンロードした．
与えられたイメージを開くと，フラグが書かれている画像が削除されていることがわかる．
そのファイルを開けばフラグを獲得できる．

## admin panel

与えられたpcapファイルをWiresharkで開く．
`/login`にPOSTしている部分があるので，そのパケットを見ると，パスワードのところにフラグが書かれている．

## hertz

換字暗号だったので，便利そうなツールを調べたところ，[quipqiup](https://quipqiup.com/)というのを見つけた．
「Puzzle:」の部分に暗号化されたテキストを貼り付けて「Solve」を押すだけ．
PDOを使ってデータベースに接続する方法を解説！

# はじめに
- データベースに接続する方法について本やネットの情報から調べて理解したことをまとめました。
- もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。

# 接続するデータベースとテーブル
- 以下のようなデータベースとテーブルがあると仮定して実行します。
- PDOを利用してデータベースに接続します。

**データベース名：** test_db1
**テーブル名：** user

|  name  |  email  |
| ---- | ---- |
|  てすと太郎  |  test-taro@test.test  |

# PDOとは
- 「PHP Data Objects」の略で、PHPからデータベースへ接続するためのクラスのことです。

# データベース（MySQL）に接続する方法
- データベースに接続するには、どこにある何というデータベースにどのユーザーが接続するのか情報を記述します。
- PDOクラスをインスタンス化するときに、引数にデータベースの接続に必要な情報を記述することで接続できます。


## 書き方
```php
インスタンス名 = new PDO("データベースの種類:host=接続先アドレス, dbname=データベース名,charset=文字エンコード" "ユーザー名", "パスワード", オプション)
```
###  引数
引数について解説します。

#### データベースの種類
- 使用したいデータベースを指定

#### ホスト名(host)
- 接続先アドレス

#### データベース名(dbname)
- 使用したいデータベース名

#### 文字コード(charset)
- 文字コード（utf8）

#### ユーザー名
- データベースにログインするユーザー名

#### パスワード
- データベースにログインするパスワード

#### オプション
- オプションは連想配列で指定します。
- オプションはデータベースに接続する時に様々な機能を使うことができます。

## コード例
```php
$user = "ここにユーザー名が入ります";
$password = "ここにパスワードが入ります";

$dbh = new PDO("mysql:host=localhost; dbname=test_db1; charset=utf8", "$user", "$password");
```
- 作成したインスタンスを$dbhという変数に代入しています。
- dbhはデータベースハンドラの略です。

## データベースに接続した後にオプションを指定する方法
- データベースに接続した後にオプションを指定するには [PDO::setAttribute](https://www.php.net/manual/ja/pdo.setattribute.php)メソッドを使用します。

### 書き方
```php
$dbh->setAttribute(属性 , 値);
```
- [PDO::setAttribute](https://www.php.net/manual/ja/pdo.setattribute.php)メソッドは属性をセットするメソッドです。
- 第1引数に属性を、第2引数に値を指定します。

## コード例
```php

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
```
### `setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)`とは
- `PDO::ATTR_ERRMODE`という属性で`PDO::ERRMODE_EXCEPTION`の値を設定することでエラーが発生したときに、`PDOException`の例外を投げてくれます。

## データを取得する
- ここまでデータベース接続ができたので、次からデータを取得する方法について紹介します。

### コード例

```php

$stmt = $dbh->query('SELECT * FROM user');
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
```

### [PDO::query](https://www.php.net/manual/ja/pdo.query.php)メソッドとは

```php
$stmt = $dbh->query('SELECT * FROM user');
```
- [PDO::query](https://www.php.net/manual/ja/pdo.query.php)メソッドを実行するとクエリを実行します。

###  [PDOStatement::fetchAll](https://www.php.net/manual/ja/pdostatement.fetchall.php)メソッドとは 
```php
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
```
- [PDOStatement::fetchAll](https://www.php.net/manual/ja/pdostatement.fetchall.php)メソッドは該当する全てのデータを配列として取得します。
- `FETCH_ASSOC`でカラム名をキーとする連想配列で返します。

### データベースの接続を閉じる方法
- データベースの接続を閉じるには`$dbh = null;`を使います。

# データベースに接続するコード例
```php:コード例
<?php

$user = "ここにユーザー名が入ります";
$password = "ここにパスワードが入ります";

$dbh = new PDO("mysql:host=localhost; dbname=test_db1; charset=utf8", "$user", "$password");
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

	$stmt = $dbh->query('SELECT * FROM user');
	$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
	
	var_dump($result);

	$dbh = null;

```
```php:実行結果
array(1) { [0]=> array(2) { ["name"]=> string(15) "てすと太郎" ["email"]=> string(19) "test-taro@test.test" } }
```
mallocで確保したメモリーをunique_ptrで管理する

呼び出し例。

```c++:hoge.h
#pragma once

struct Hoge
{
	int _data1;
	unsigned char _data2[1];
};
```

```c++:main.cc
#include "uniqueptr1.h"
#include "uniqueptr2.h"
#include "uniqueptr3.h"

int main()
{
	auto p1 = CreateHoge1(100);
	auto p2 = CreateHoge2(100);
	auto p3 = CreateHoge3(100);
	return 0;
}
```

# カスタムデリーターに関数オブジェクトを使用する場合

関数freeを呼び出すためだけにclass(またはstruct)が必要なため冗長。

```c++:uniqueptr1.h
#pragma once

#include <memory>
#include "hoge.h"

class MyCustomDeleter
{
public:
	void operator()(void* p) const;
};

std::unique_ptr<Hoge, MyCustomDeleter> CreateHoge1(int dataSize);
```

```c++:uniqueptr1.cc
#include "uniqueptr1.h"
#include <stdlib.h>

std::unique_ptr<Hoge, MyCustomDeleter> CreateHoge1(int dataSize)
{
	auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
	return std::unique_ptr<Hoge, MyCustomDeleter>(hoge, MyCustomDeleter());
}

void MyCustomDeleter::operator()(void* p) const
{
	free(p);
}
```

# カスタムデリーターにstd::functionを使用する場合

std::functionで関数オブジェクトより簡潔に書けた。

```c++:uniqueptr2.h
#pragma once

#include <functional>
#include <memory>
#include "hoge.h"

std::unique_ptr<Hoge, std::function<void(Hoge*)>> CreateHoge2(int dataSize);
```

```c++:uniqueptr2.cc
#include "uniqueptr2.h"
#include <stdlib.h>

std::unique_ptr<Hoge, std::function<void(Hoge*)>> CreateHoge2(int dataSize)
{
	auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
	return std::unique_ptr<Hoge, std::function<void(Hoge*)>>(hoge, &free);
}
```

# カスタムデリーターに関数ポインターを使用する場合

std::functionを関数ポインターで書き直してみた。

```c++:uniqueptr3.h
#pragma once

#include <memory>
#include "hoge.h"

std::unique_ptr<Hoge, void (*)(void* p)> CreateHoge3(int dataSize);
```

```c++:uniqueptr3.cc
#include "uniqueptr3.h"
#include <stdlib.h>

std::unique_ptr<Hoge, void (*)(void* p)> CreateHoge3(int dataSize)
{
	auto hoge = static_cast<Hoge*>(malloc(sizeof(Hoge) - 1 + dataSize));
	return std::unique_ptr<Hoge, void (*)(void* p)>(hoge, &free);
}
```
移動速度が変わらないベジエ曲線アニメーションの作成

# ベジェ曲線上の点を一定の移動速度で描画したい

鉄道シミュレーションゲームを作成したいのですが、一定速度でカーブを移動できるような動作が必要になりました。
通常の円の方程式から距離を計算して描画をしてもいいのですが、鉄道には緩和曲線と呼ばれる要素があり、それを実現させるためにベジェ曲線が使えたらなと色々調べた結果です。

参考にしたサイトはこちら
[Ko-Taのバ・ー・ルのようなもの 移動速度が変わらないベジエ曲線](http://d.hatena.ne.jp/Ko-Ta/20091025/p1)

こちらのコードをPythonに書き換えたものが以下になります。

# コード
```python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# 参考: http://d.hatena.ne.jp/Ko-Ta/20091025/p1

def _bezier(p1, p2, vp1, vp2, t):
    """ベジェ曲線の座標を返す関数
    
    :param p1: 始点
    :type p1: float
    :param p2: 終点
    :type p2: float
    :param vp1: 第1制御点
    :type vp1: float
    :param vp2: 第2制御点
    :type vp2: float
    :param t: パラメーター
    :type t: float
    :return: 座標
    :rtype: float
    """
    p = (1-t)**3 * p1 + 3 * (1-t)**2 * t * vp1 + 3 * (1-t) * t**2 * vp2 + t**3 * p2
    return p


def _bezier_linearlen(x1, y1, x2, y2, vx1, vy1, vx2, vy2, t, n=16):
    """ベジェ曲線の距離均等変換
    
    :param x1: 始点x座標
    :type x1: float
    :param y1: 始点y座標
    :type y1: float
    :param x2: 終点x座標
    :type x2: float
    :param y2: 終点y座標
    :type y2: float
    :param vx1: 第1制御点x座標
    :type vx1: float
    :param vy1: 第1制御点y座標
    :type vy1: float
    :param vx2: 第2制御点x座標
    :type vx2: float
    :param vy2: 第2制御点y座標
    :type vy2: float
    :param t: パラメーター
    :type t: float
    :param n: 分割数, defaults to 50
    :type n: int, optional
    :return: 
    :rtype: float
    """
    ll = []
    x = y = 0.0
    px = py = 0
    tt = ni = 0
    i = 0

    # 最低分割数
    if (n<4):
        return t
    
    # 0.0～1.0外はそのまま返そう
    if (t<=0.0) or (t>=1.0):
        return t
    
    ni = 1.0/n
    tt = 0.0

    px = _bezier(x1,x2,vx1,vx2,0.0)
    py = _bezier(y1,y2,vy1,vy2,0.0)
    ll.insert(0,0.0)

    for i in range(1, n+1 ):
        tt = tt + ni
        x = _bezier(x1,x2,vx1,vx2,tt)
        y = _bezier(y1,y2,vy1,vy2,tt)
        ll.insert(i, ll[i-1] + np.sqrt((x-px)*(x-px) + (y-py)*(y-py)))
        px = x
        py = y
    
    x = 1.0/ll[n]

    for i in range(1, n+1 ):
        ll[i] = ll[i]*x

    for i in range(n):
        if (t>=ll[i])and(t<=ll[i+1]):
            break
        if (i>=n):
            return t

    x = (ll[i+1]-ll[i])
    if (x<0.0001):
        x = 0.0001        # 例外対策
    x = (t-ll[i]) / x                   # 区画内の比率を求めて
    return (i*(1.0-x) + (i+1)*x) * ni # 線形補間

x1 = 0
y1 = 0
x2 = 1
y2 = 1
vx1 = 0.55
vy1 = 0
vx2 = 1
vy2 = 1-0.55

n = 100

# グラフ描画用
fig = plt.figure(figsize=(5,5))

ims=[]
for i in range(n):
    tt = i/n
    tt = _bezier_linearlen(x1,y1,x2,y2, vx1,vy1,vx2,vy2,tt)
    dx = _bezier(x1,x2, vx1,vx2, tt)
    dy = _bezier(y1,y2, vy1,vy2, tt)
    im = plt.scatter(dx, dy)
    ims.append([im])

# アニメーション設定
ani = animation.ArtistAnimation(fig, ims, interval=0.1, repeat_delay=1000)
plt.show()
```

## 実行結果
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165191/04214fbe-dd3e-91c4-30aa-6bf9314c5334.gif)

1/4円弧の描画がうまくできていると思います。
リファクタリングしたいところは山ほどありますが、とりあえず期待通りの動作をしてくれたというところで。
Kubebuilderを/usr/local以外にインストールした場合の設定事項

# Kubebuilder

https://book.kubebuilder.io/

# はじめに

`/usr/local` に、独自のツールを入れたくない。(CoreOSなどではread onlyになるからハマるし・・・)
その際の設定などについてです。
同じ事をしてハマった人向け。
KUBEBUILDER_ASSETSでGoogle検索しても、ほとんどサイトがヒットしなかったのでとりあえずの記録。

# インストール

https://book.kubebuilder.io/getting_started/installation_and_setup.html

の手順です。 `/usr/local` の場所は任意の場所に変更します。

# 設定すること

- KUBEBUILDER_ASSETSの環境変数に、archiveを展開したディレクトリを指定する。
- 環境変数PATHに、{展開したディレクトリ}/binを含める。

```例：/opt/k8sに展開した場合
$ # 必要に応じて.bash_profile,.zprofileに追加。
$ export KUBEBUILDER_ASSETS=/opt/k8s/bin
$ export PATH=$PATH:$KUBEBUILDER_ASSETS
```

# 設定しないとなにが起こるか？

## KUBEBUILDER_ASSETSを指定しなかった場合

下記のように、 `make test` で `/usr/local/kubebuilder/bin/etcd: no such file or directory` とエラーになります。

```shell
$ make test
go generate ./pkg/... ./cmd/...
go fmt ./pkg/... ./cmd/...
go vet ./pkg/... ./cmd/...
go run vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go all
CRD manifests generated under '/Users/hiroki-matsumoto/Dev/go/src/github.com/h-r-k-matsumoto/gcs-crd/config/crds' 
RBAC manifests generated under '/Users/hiroki-matsumoto/Dev/go/src/github.com/h-r-k-matsumoto/gcs-crd/config/rbac' 
go test ./pkg/... ./cmd/... -coverprofile cover.out
?       github.com/h-r-k-matsumoto/gcs-crd/pkg/apis     [no test files]
?       github.com/h-r-k-matsumoto/gcs-crd/pkg/apis/storage     [no test files]
2019/05/06 20:56:46 failed to start the controlplane. retried 5 times: fork/exec /usr/local/kubebuilder/bin/etcd: no such file or directory
FAIL    github.com/h-r-k-matsumoto/gcs-crd/pkg/apis/storage/v1beta1     0.045s
?       github.com/h-r-k-matsumoto/gcs-crd/pkg/controller       [no test files]
2019/05/06 20:56:47 failed to start the controlplane. retried 5 times: fork/exec /usr/local/kubebuilder/bin/etcd: no such file or directory
FAIL    github.com/h-r-k-matsumoto/gcs-crd/pkg/controller/googlecloudstorage    0.035s
?       github.com/h-r-k-matsumoto/gcs-crd/pkg/webhook  [no test files]
?       github.com/h-r-k-matsumoto/gcs-crd/cmd/manager  [no test files]
make: *** [test] Error 1
$
```

内部で利用されている、 [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime)のGoDocにこの変数は記載されています。
https://godoc.org/sigs.k8s.io/controller-runtime/pkg/envtest

> Control plane binaries (etcd and kube-apiserver) are loaded by default from /usr/local/kubebuilder/bin. This can be overridden by setting the KUBEBUILDER_ASSETS environment variable, or by directly creating a ControlPlane for the Environment to use.

テストだけであれば、 

https://book.kubebuilder.io/beyond_basics/running_tests.html#optional-change-control-plane-test-binaries

に記載されている通り、 `TEST_ASSET_KUBECTL` , `TEST_ASSET_KUBE_APISERVER ` , `TEST_ASSET_ETCD` の環境変数で、直接指定しても良さそうです。 
でも、今回のケースでは、意味合い的に `KUBEBUILDER_ASSETS` を変更する方が正しいかな？と思い、こちらを変更しています。

## 環境変数PATHにbinディレクトリを追加しなかった場合

`kubebuilder` などのコマンドが、絶対パスで実行しないといけなくなるくらい。

## 参考

- https://book.kubebuilder.io/getting_started/installation_and_setup.html
- https://godoc.org/sigs.k8s.io/controller-runtime/pkg/envtest
- https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/envtest/server.go#L51-L58
Python3 初心者　制御構造(if,elif,else,while)

#if,else,elifによるデータの扱い
皆さんはお店のアルバイトをしている時にレジのバイトをしていると考えてください。それで130円のアイスを買いに来ているお客様がいるとします。その時もらったお金によって、「ちょうどお預かりいたします。」なのか、「お釣りのお返しです。」なのか「お金が足りません」と返すのかということをif文でそれぞれ処理をしてくれます。elifは条件２〜みたいなものです。

```py
#もし支払った金額がちょうどだったら、、、ここは払ってもらっている金額をかく。
cost=130
#もらった金額が130円だった時の処理
if cost==130:
    print('ちょうどお預かりいたします。')
#もらった金額が130円より少ない時
elif cost < 130:
    print('お金が足りません。')
#もらった金額が130円より多い時
elif cost > 130:
    print('お釣りのお返しです。')
#それ以外（お金をもらってない時）
else:
    print('金額をおっしゃってください。')
```

このようにして条件文はできています。それでは少し応用のinput()を使ってみましょう。これは自分で値段を書いてその時に応じてかくというものです。
一回例を書いてみますね！！

```py
while True:
    number=input('支払金額: ')
#ここで数字を文字列化していく
    cost=int(number)
#もらった金額が130円だった時の処理
    if cost==130:
        print('ちょうどお預かりいたします。')
#もらった金額が130円より少ない時
    elif cost < 130:
        print('お金が足りません。')
#もらった金額が130円より多い時
    elif cost > 130:
    print('お釣りのお返しです。')
#それ以外（お金をもらってない時）
    else:
        print('金額をおっしゃってください。')
```

このようにすれば自分が金額を指定してそれに応じた金額を出力することが可能です。ここで使っているのがwhile文になるwhile文はその条件があっている限り処理を繰り返していくというもの。例えば５以下の場合はずっと同じ処理を繰り返していくなどというもの。簡単な例を示していきます。

```py
cost=2
while cost<11:
   print(cost*cost)
   cost+=1

4
9
16
25
36
49
64
81
100
```

ここでは数字の２から１０までの数字をcostに代入してそれを二乗するということです。

##breakによるループ中止
やばい、渡すお釣りが無くなっちゃた！これはもうちょうど支払って欲しいなって思った時にこのように言いましょう！！！

```py
while True:
    cost=input('支払金額: ')
    number=int(cost)
#もらった金額が130円だった時の処理
    if number==130:
        break
    print('ちょうどいただきたいです')
```

これだったらお釣り渡さなくてもいいですよね？？？

## continueによる次のループの開始
continueは大雑把にいうとスルーみたいなものです！！ここでは釣りが出るとダメだよ！！みたいなことを言ってちょうどの時はもう処理を終了する。そしてお金が足りない時は何も言わないことにしよう

```py
while True:
    cost=input('支払金額: ')
    number=int(cost)
    if number==130:
        break
    if number<130:
        continue
    print('ダメ！！！')
```

こんな感じでやってみればできると思います！！
>もしこの表現ムカつくとかありましたら編集リクエストもしくはコメントにておしらせください！お願い申しあげます。GWは投稿休んでしまい申し訳ございませんでした
Amazon WorkSpacesで利用できるショートカットキー

WorkSpacesに接続した際、クライアントからアクセスした時とブラウザからアクセスした時で挙動が異なっていたため、まとめました。

##試した環境
- バンドル：Standard with Windows 10
- Amazon WorkSpacesクライアント：Version 2.5.5.1172
- Amazon WorkSpaces web client：version 2.4.1

##挙動
一般的なWindows端末と同様の挙動をしたところは〇、そうでないところには挙動を記載しました。

|    ショートカットキー    |    目的    |    クライアント    |    ブラウザ    |
|:------------------:|:------------------:|:------------------:|:------------------:|
|Ctrl + C|選択した項目をコピーする。|〇|〇|
|Ctrl + V|選択した項目を貼り付ける。|〇|〇|
|Alt + Tab|ウィンドウを切り替える。|〇|作業端末でアプリの切り替えが行われる。|
|Windows ロゴ キー + L|PC をロックする。|作業端末とクライアントの両方でロックがかかる。|作業端末のみロックがかかり、WorkSpace内ではスタートメニューが開く。|
|Windows ロゴ キー + A|アクションセンターを開く。|〇|アクションセンターが開くと同時にスタートメニューも開く。|
|Windows ロゴ キー + ↑|ウィンドウを最大化する。|〇|ウィンドウの大きさは変わらず、スタートメニューが開く。|
|Windows ロゴ キー + P|プレゼンテーション表示モードを選択する。|〇|作業端末のみプレゼンテーション表示モードの選択画面が開き、WorkSpace内ではスタートメニューが開く。|
|F2|選択された項目の名前を変更する。|〇|〇|
|Ctrl + Alt + Tab|方向キーを使って、ウィンドウを切り替える。|〇|作業端末でアプリの切り替えが行われる。|
|Ctrl + Alt + delete|Windowsのセキュリティやタスクマネージャを呼び出す。|作業端末とクライアントの両方で呼び出される。|作業端末のみ呼び出される。|
nginxをデフォルトport以外で起動してnode.jsのAPIを動かすまで

nodeでREST-APIを作ってnginxで動かすまでのメモ書き
以前からさくらVPSを使用しており。既にApacheが80番portを使用。
Apacheは設定を結構いじってしまっていたり、すでに複数サービス運用していることから、
この際、お試し用のWEBサーバとしてnginxを立ててみようという経緯

# 前提
+ port80はすでにapacheで使用している
+ node.jsのExpressを利用してREST-APIを作成
+ 環境はさくらVPS
+ 将来的には複数ドメインでの運用を検討

# node.jsのアプリを起動
バックグラウンド実行。
ここら辺は任意の起動法で

```
$ nohup npm start &
```

>! note
>外部に公開する場合はエラー時のブラウザ表示内容に注意！
>NODE_ENVがdevelopのままで起動していないか注意してください。
>けっこうな情報量を晒すことになります。
>対処などは[こちら](https://www.kennejs.com/entry/2019/01/04/012606)が参考になります


# nginxの設定
### nginx.conf修正
portをデフォルトの80から81に変更

```/etc/nginx/nginx.conf
...
    server {
        listen       81 default_server;
        listen       [::]:81 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
```

### devt-api.conf作成
node.jsのアプリはport3000を使って起動。
外部に公開するportとして4999とする。


```/etc/nginx/conf.d/devt-api.conf
upstream sampleAPP {
    server localhost:3000;
}
server {
    listen       4999;
    server_name  {{YOUR_DOMAIN}};
    index        index.php;
    access_log   /var/log/nginx/{{APP_NAME}}.access.log;
    location / {
        proxy_pass http://sampleAPP/;
    }
}
```

### nginxの起動

```
自動起動設定
$ sudo systemctl enable nginx
起動
$ sudo systemctl start nginx
```

### port 4999開放
このままだと、外部から呼び出せないため、portを開放

```
port4999を許可
$ firewall-cmd --zone=public --add-port=4999/tcp --permanent
設定を反映
$ firewall-cmd --reload
```

### ブラウザからアクセス
以下のURLでアクセス可能なはず
http://{{YOUR_DOMAIN}}:4999/


# SSLの設定
### 証明書の取得
SSL証明書(Let’s Encrypt)を導入
手順とかは省略
[ここらへん](https://knowledge.sakura.ad.jp/10534/)がわかりやすかったです。

### devt-api.confの編集
証明書と中間証明書の`fullchain.pem`と秘密鍵の`privkey.pem`を追記してあげる

```
...
server {
    listen       4999 ssl;
    server_name  {{YOUR_DOMAIN}}
    ssl_certificate     /etc/letsencrypt/live/{{YOUR_DOMAIN}}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{YOUR_DOMAIN}}/privkey.pem;
...
```
### nginx再起動

```
再起動
$ sudo nginx -s reload
```

### ブラウザからアクセス
httpsでのアクセス可能になるはず
https://{{YOUR_DOMAIN}}:4999/
MYSQLのエラー関連のエラーってわかりにくいよね

# エラー発生：SQLSTATE[HY093]

Invalid parameter number: number of bound variables does not match number of tokens

例外処理時のExceptionにてキャッチした際に発生したエラー。

catch(Exception $e){
            debug('エラー発生：'.$e->getMessage());
        }

debug()関数でエラー文をエラー時に別ファイルに作成

##エラーの考えられる原因
1.SQL文のミス
主にINSERT　INTOの対象となるパラメーター以外の記述はしてはいけない（と思う）
対象プレースホルダーに注意。
[初学者向け]Pythonで便利なライブラリ

##はじめに
こんにちは。
僕はプログラミング歴3ヶ月の初心者なのですが、今回はそんな初心者の目から見た「覚えておくと便利なライブラリ」を紹介したいと思います！
すでにいくつか記事を書いてるので、よかったらそちらもついでに見てやってください。下のリンクの記事から繋げやすい内容になっています。
[プログラミングしてみたい方はまずPythonのインストールを！(Mac向け)]
(https://qiita.com/cr-fun/items/f0f7e36dffa3e79ad03e)

##ライブラリってなんだ？

プログラミング(この記事でいうとPython)初心者の方はまずライブラリという言葉を聞き慣れていないかもしれません。
ライブラリとはプログラミングをする上で欠かせないものであり、画像を編集したいときや、ファイルを整理するときなどに使えるいわば飛び道具のようなものです。すでに完成されているので僕たちは決められた書き方をするだけでその飛び道具が使えてしまうんです。
**import 〜**という決まり文句で呼び出すと使えるようになります。

ではそんな便利なライブラリをいくつか見ていきましょう！

###Numpy

Numpyは数値計算をするときや、画像をピクセルごとに分解して配列にしたい時に使えるライブラリです。ディープラーニングで画像分類をする時などに必ず必要になってくる知識なので、AI関係のことに興味のある方は必ず覚えておきましょう！
![スクリーンショット 2019-05-06 20.29.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405324/f8b5c8a5-517d-b62a-4e19-b7371c71d95f.png)
こんな感じで使うのですが、今は全く分からなくて構いません。「へー、そんなものがあるのか」ぐらいの認識で結構です。
Numpyを使うにあたって学習（人によってはおさらい）しておくべきなのが**行列**です。高校の数学で習った方もいるとは思うのですが、指導要領の変更で外れている年もあるので、習ったことのない方はぜひ学習してみましょう。全然難しい内容じゃないですし、ググったら簡単に噛み砕いて教えてくれているサイトが山ほど出てきますよ！

###Pandas

Pandasはデータ分析を行う上で必須のライブラリです。Pandasを使うとデータの読み込み(エクセルのデータなど）や不必要なデータの除外など、機械学習をする上では欠かせない作業が一気に簡単になります。機械学習に必要な作業の大部分がこのデータ分析になってくるので、覚えておくとめちゃくちゃ強いです！データサイエンティストになりたい方には特に必須ですよ。
Pandasの発展的な内容では株価分析などもできるようになるので、株に興味がある方にもおすすめです。プログラミングと組み合わせてトレードなんかできたらカッコよくないですか？（笑）

###Matplotlib

MatplotlibはPythonの描画ライブラリで、線グラフや棒グラフなどデータを可視化したい時に使えるライブラリです。
例えばパワーポイントなどを使ってプレゼンをしないといけない場面でグラフを使いたい時、Matplotlibが大きな力を発揮します。データをグラフにしたい時、シンプルなやり方で緻密なグラフが描画できるのでとても便利ですよ！
![スクリーンショット 2019-05-06 20.49.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405324/56218c99-cddd-b726-9ad3-9ce7fa6a5390.png)
これはMatplotlibの公式サイトから引用したグラフです。こんなグラフが数行のプログラミングで実現できるってすごくないですか！？
勉強し始めの頃はなんの意味もないグラフをかくだけでも構いません！「こういう使い方をするんだな」ぐらいの軽い気持ちで色々書いてみましょう。まずは自分で書くことが大事ですし、こういうグラフの形で目に見えるとシンプルに楽しいです。

###Keras

Kerasは今までの3つとは少し毛色が違って、本格的に機械学習をする時に使うライブラリです。僕の今までの記事でも何度か出ている画像分類などで力を発揮します。
また、Kerasは公式ドキュメントに使い方が多く載っていたり、Kerasを使ったコードレシピもネット上にたくさん転がっているので何かを形にしたい時に即座に使いやすいライブラリです。
なんでこんなにサンプルが転がっているかというと、そのシンプルさが理由なんです。これまでにあったライブラリよりもはるかに少ない記述量で機械学習が簡単にできちゃう優れものであり、みんなが使うから必然的にネットに情報量も多いので勉強しやすいのがおすすめポイントです。
「エラーメッセージが出てきたけど何が書いてあるか分からない😂」なんて時も同じエラーメッセージが出た人が掲載した解決法をググればなんの問題も無しです。安心して勉強しちゃいましょう！

僕が書いたこんな記事もありますので、ある程度勉強が進んだ方はこのやり方を真似て画像分類してみると面白いかもしれません。
[VGG16で画像分類(2クラス)](https://qiita.com/cr-fun/items/3f2331c688717aee73be)

###その他のライブラリ・モジュール

上の4つを特におすすめしたかったので詳しく書きましたが、その他にも以下のようなライブラリがあるので気になった方はぜひググってみてください！今は使わないとしても結局使うことになるライブラリばかりだと思うので、覚えておいて損はないです。
・os(ファイル操作で使う）
・dlib(顔認証などで使える）
・OpenCV(画像の処理はこれさえあれば困りません！）
・sklearn
・sys
・glob

etc.....

こんな感じでたくさんあるのでぜひ調べてみてください！

##参考にしたサイト
[Numpy公式サイト](https://www.numpy.org)
[Matplotlib公式サイト](https://matplotlib.org)

##終わりに
いかがだったでしょうか？
この記事では書ききれない量の便利なライブラリがあるので、各自で調べてみるとさらに勉強の質が上がります！少しでも気になることはどんどんググって自分のものにしていきましょう！
また、この記事で書いたものはどれも僕の最初の記事で紹介したネット講座で勉強できるものばかりなのでそちらの記事も見ていただけたら嬉しいです！
[プログラミングやディープラーニングの勉強、何から手をつければ良い！？]
(https://qiita.com/cr-fun/items/90fa4fa39cf1269e38d9)

では、また次の記事で！
QMLのプロパティバインディングについて

Qt 5.11.2あたりの情報です。

#qmlの配列が期待通りにバインドしない
下記のように、配列の要素を使ってxを記述するとします。
配列の要素を書き換えても、バインドが期待通りに動きません。

```qml
    property var data: [0, 1, 2, 3, 4, 5]
    x: data[2] //バインドしない

    function setData2() {
        data[2] = 6
    }
```
どうやら、xはdataとバインドされていますが、data[2]とはバインドされていないようです。
そこで、下記のようにすると期待通りの動作をします。

```qml
    function setData2() {
        data[2] = 6
        dataChanged() //直接シグナルを読んで、無理矢理更新させる。
        //するとxは6になり、めでたしめでたし。
    }
```
配列でバインディングをしたくて、なんとか考え出した方法です。
これが正しいやり方なのかどうかは、正直わかりません。
他に良い方法があれば、誰か教えてください。

#リードオンリーのプロパティ
リードオンリーのプロパティを作ることができます。

```qml
    readonly property int test: 10
    readonly property int taste: test * 10 //バインドも効く
```

#関数でバインディング
下記のように書けば、関数でバインディングできます。
（[Qt Documentation](https://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html)より抜粋）

```qml
Rectangle {
    width: 100
    height: width * 2

    focus: true
    Keys.onSpacePressed: {
        height = Qt.binding(function() { return width * 3 })
    }
}
```
rubyでカラオケマシーンを作ってみた

今日は[こちらのブログ](https://blog.jnito.com/entry/2014/06/06/104420)に載っている問題をやりました。
このようなコードになりました。

```rb
#キーを引数分あげるプログラムです。

#ドレミファソラシドをアルファベットに変換して配列に入れています。
KEY = [
  'c','c#','d','d#','e','f','f#','g','g#','a','a#','b'
]

class KaraokeMachine
  attr_reader :melody

  def initialize(melody)
    @melody = melody
    new_array = []
  end

  #与えられた引数分コードをあげる
  def up_key(n)
    #インデックスに引数を足して返す。11以上はない為超えたら12を引いて返す
    new_index = melody_array.map do |i|
      if add(i,n) > 11
        add(i,n) - 12
      else
        add(i,n)
      end
    end

    # 新しいインデックスに対応する要素配列に入れて結合する
    new_array = new_index.map do |i|
      KEY[i]
    end
    new_array.join
  end

  private
  #メロディーを配列に入れ、各要素のインデックスを調べ配列に入れ返す
  def melody_array
    melody.chars.map do |m|
      KEY.index(m)
    end
  end

  def add(a,b)
    a + b
  end
end
```

このような感じになりました。
KEY配列がわかりにくいから、キーに音階入れたハッシュにしようか悩み中です。
WSL で AtCoder 用の環境(Python3)を整える

# 概要
Windows の WSL(Ubuntu)で AtCoder と同じバージョンの Python(`3.4.3`), numpy(`1.8.2`), scipy(`0.13.3`) の環境を構築をするための手引き。

`apt` で導入できるPython3のバージョンは、AtCoderで利用できるバージョン `3.4.3` ではないので tarball からコンパイルする必要がある。しかし、Ubuntu同梱の openssl のバージョン `1.1.0g` と Python `3.4.x` の相性が悪いことが知られていて処方が必要。

# ざっくりした手順
後から振り返っており かっちりした手順ではないので、疑問等あればコメントください。

- Step1: WSLの導入
    - ググった通りにやればできる
- Step2: pyenvの導入
    - pyenv 自体はただの shスクリプトなので前準備は必要ないが `git` をインストールして clone すると簡単に導入できる。
- Step3: Python 3.4.3 用インストールスクリプトを実行
    - Pythonをコンパイルするためのパッケージを `apt`で入れる。
    - `pyenv install 3.4.3`だと相性の問題でエラーが出るので、StackOverflowで見つけた修正スクリプト(末尾に記載)を使って 3.4.3 をインストールする
- Step4: AtCoder用のディレクトリを作成
    - 例えば `~/atcoder` など
    - pyenv で上記ディレクトリでは 3.4.3 を使うように指示 (`pyenv local`コマンド)
- Step5: numpy, scipy の導入
    - 必要なパッケージを `apt` で入れる
    - `sudo apt-get install gcc gfortran python-dev libopenblas-dev liblapack-dev`
    - (3.4.3を利用するディレクトリで) `pip install numpy==1.8.2`と`pip install scipy==0.13.3`

```pythonインストールスクリプト.sh
#!/bin/bash -e

# Note by 41semicolon: slightly modified from
# https://stackoverflow.com/questions/50126814/ignoring-ensurepip-failure-pip-requires-ssl-tls-error-in-ubuntu-18-04

# Note: it is a script to solve Ubuntu 18.04 LTS
#       different version of pythons compiling
#       header confliction problems
#
# The idea is got from @JustAnotherArivist
# From URL: https://github.com/pyenv/pyenv/issues/945
#
# The script used in here is with slightly modifications
# to fit many different SSL header versions


# First under your home directory make OpenSSL library
# and extract useful package

mkdir ~/libssl1.0-dev
cd ~/libssl1.0-dev
apt-get download libssl1.0-dev
ar x libssl1.0-dev* data.tar.xz
tar -xf data.tar.xz --strip-components=2


# Second, specifically get your current system's SSL headers
# and make symbolic-links

libcrypto=$(ls /usr/lib/x86_64-linux-gnu/ | grep libcrypto.so......)
libssl=$(ls /usr/lib/x86_64-linux-gnu/ | grep libssl.so......)

ln -s /usr/lib/x86_64-linux-gnu/${libcrypto} ~/libssl1.0-dev/lib/x86_64-linux-gnu
ln -s /usr/lib/x86_64-linux-gnu/${libssl} ~/libssl1.0-dev/lib/x86_64-linux-gnu


# Set your CFLAGS LDFLAGS compile options
# And use pyenv install the python version <3.4.5 or <3.5.3

# Note: it is a one line command
# Please change the version of python that you want to compile
CFLAGS="-I${HOME}/libssl1.0-dev/include -I${HOME}/libssl1.0-dev/include/x86_64-linux-gnu" \
LDFLAGS="-L${HOME}/libssl1.0-dev/lib/x86_64-linux-gnu" \
pyenv install 3.4.3


# Remove tempor libssl1.0-dev direcotory
rm -rf ~/libssl1.0-dev
```
OpenSSL で暗号化したデータを PowerShell で復号する

# OpenSSL で暗号化したデータを PowerShell で復号する

2006年頭に Java で書いて、2012年7月に DESede から AES に書き直したコードの PowerShell 移植.
いつの間にか deprecated になってる上に、鍵導出に使うハッシュアルゴリズムのデフォルト値も md5 から sha256 に変更されているし(笑).

```sh
$ openssl version
OpenSSL 1.1.1b  26 Feb 2019
$ echo -n "secret message" | openssl enc -e -aes-128-cbc -md md5 -a -pass pass:password
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
U2FsdGVkX18U/R0E7RLGe1YX9DMAQ7lxSaUpRngdj8s=
```

```powershell
PS> $encryptedText = [Convert]::FromBase64String("U2FsdGVkX18U/R0E7RLGe1YX9DMAQ7lxSaUpRngdj8s=")
PS> $salt = $encryptedText[8..15]
PS> $md5 = [Security.Cryptography.MD5]::Create()
PS> $seed = [Text.Encoding]::UTF8.GetBytes("password") + $salt
PS> $kiv = $md5.ComputeHash($seed)
PS> $kiv += $md5.ComputeHash($kiv + $seed)
PS> $md5.Dispose()
PS> $aes = New-Object Security.Cryptography.AesManaged
PS> $aes.Key = $kiv[0..15]
PS> $aes.IV = $kiv[16..31]
PS> $aes.BlockSize = 128
PS> $aes.Mode = [Security.Cryptography.CipherMode]::CBC
PS> $aes.Padding = [Security.Cryptography.PaddingMode]::PKCS7
PS> $decryptor = $aes.CreateDecryptor()
PS> [Text.Encoding]::UTF8.GetString($decryptor.TransformFinalBlock($encryptedText[16..($encryptedText.Length - 1)], 0, $encryptedText.Length - 16))
secret message
PS> $decryptor.Dispose()
PS> $aes.Dispose()
PS>
```

PowerShell で暗号化したデータを OpenSSL で復号するのは以下.

```powershell
PS> $plainText = "secret message"
PS> $salt = 0..7 | % { Get-Random -Maximum 255 }
PS> $md5 = [Security.Cryptography.MD5]::Create()
PS> $seed = [Text.Encoding]::UTF8.GetBytes("password") + $salt
PS> $kiv = $md5.ComputeHash($seed)
PS> $kiv += $md5.ComputeHash($kiv + $seed)
PS> $md5.Dispose()
PS> $aes = New-Object Security.Cryptography.AesManaged
PS> $aes.Key = $kiv[0..15]
PS> $aes.IV = $kiv[16..31]
PS> $aes.BlockSize = 128
PS> $aes.Mode = [Security.Cryptography.CipherMode]::CBC
PS> $aes.Padding = [Security.Cryptography.PaddingMode]::PKCS7
PS> $encryptor = $aes.CreateEncryptor()
PS> $plainBytes = [Text.Encoding]::UTF8.GetBytes($plainText)
PS> [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("Salted__") + $salt + $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length))
U2FsdGVkX18h9BZVxCv8LUEoORGQg4XKivd4mq6r/q4=
PS> $encryptor.Dispose()
PS> $aes.Dispose()
PS>
```

```sh
$ echo -n "U2FsdGVkX18h9BZVxCv8LUEoORGQg4XKivd4mq6r/q4=" | base64 -d | openssl enc -d -aes-128-cbc -md md5 -pass pass:password
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
secret message
```