OmniAICreator/Qiita-1.07M huggingface dataset:
Electron & Gulp 環境で Watch して LiveReload な感じのことする時にハマったのでメモ

趣味でプログラミングを触っていて、友人と一緒にチーム開発をしているのですが、Electron & Gulp の環境でライブリロードみたいなことできたらすごい楽だよなーとか軽い気持ちやってみたらすごいハマったのでメモ。

# :tools:  環境
```package.json
{
  ...

  "scripts": {
    "start": "gulp start",
    "build": "gulp build"
  },
  "devDependencies": {
    ...

    "electron-connect": "^0.6.3",
    "gulp": "^4.0.0",
    "gulp-plumber": "^1.2.1",
    "gulp-useref": "^3.1.6",
  },
  "dependencies": {
    "npm": "^6.5.0",
    "electron": "^4.0.0",
    ...
  }
}
```

dependencies と devDependencies の整理ができていないので使い分け的に正しいとは限りません... :sweat: 

Babel, SCSS/SASS, ファイルのバンドルなどは webpack です。

全て webpack で終始したかったのですが、色々あって Gulp でビルドなどのタスク管理はすることになりました。

また Electron の起動・リロードなどの処理は [electron-connect](https://github.com/Quramy/electron-connect) を使いました。

# :no_good:  最初の実装 （正しく動かなかった）
Gulp には`watch`という、ファイルの状態を監視して、変更が発生すれば渡された処理を行う、というメソッドが用意されています。

そこでこの `watch` メソッドを使って、以下のようなコードを書いてみました:

```gulpfile.js
const gulp = require('gulp');
const useref = require('gulp-useref');

const electron = require('electron-connect').server.create();

// ...略...

gulp.task('build', gulp.series( gulp.parallel(
  'compile-js',
  'compile-styles',
  'compile-renderer'
)));

gulp.task('start', gulp.series('build', () => {
  electron.start();
  gulp.watch(['src/scripts/main/**/*.js'], gulp.series('compile-js', electron.restart()));
  gulp.watch(['src/styles/**/*.{scss,sass}'], gulp.series('compile-styles', electron.reload()));
  gulp.watch(['src/**/*.html'], gulp.series('compile-renderer', electron.reload()));
}));
```
`electron.start()` で Electron を起動、 `reload()` でレンダラープロセスの方を再起動、
`restart()` で再起動、といった感じです。

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello!</title>
    <!-- build:remove -->
    <!-- Connect to server process -->
    <script>require('electron-connect').client.create()</script>
    <!-- end:build -->
  </head>
  <body>
    <!-- ...略... -->
  </body>
</html>
```
Electron に用いるHTMLファイル。

#  :bug: :boom: これだとうまく動かない

これだと正しく動きませんでした。
具体的には、一度は変更を検知してくれますが、二度目以降、それぞれの watch タスクがきちんと動いてくれない... というものです。

最初の `index.html` の更新は検知するけど、二度目は検知してくれない... といった感じ。
 

# :bulb: 解決した

ログは貼れないのですが、よくよくみたら、 `electron.reload` や `electron.resart` のタスクの `finished` の出力がされていない... ということがわかりました。

額にしわを寄せつつ英語の Docs を読むなどして色々と試して、

> `electron.reload` や `electron.resart` の終了がきちんとされているかどうかがGulp 側が検知されてない
= Gulp にとってはそれらがまだ動いているつもり、(実際は終わってる)
= 新しいファイル検知が行われない (Gulp がまだビルド・再起動の途中と認識してるから)

ということではないかと仮説を立てました。

Gulp の仕様としては callback を返せば良い (= 逆に何も帰ってこなかったら処理中とみなされる) ということが Docs を頑張って解読した結果解釈できたので、全部無名関数で囲って callback を返してあげればいいのでは...? と思い、

```gulpfile.js
gulp.watch(['src/scripts/main/**/*.js'], gulp.series('compile-js', 
  done => {
    electron.restart();
    done();
  }
));

gulp.watch(['src/styles/**/*.{scss,sass}'], gulp.series('compile-styles',
  done => {
    electron.reload();
    done();
  }
));

gulp.watch(['src/**/*.html'], gulp.series('compile-renderer',
  done => {
    electron.reload();
    done();
  }
));
```

これによってきちんと動くようになりました。

英語だろうがなんだろうが Docs を読むことはめんどくさがってはいけないということがわかった一件でした。
google cloud storage バージョン管理 lifecycle の設定


原稿データのバックアップに　google cloud storage のバケットを使っていて
ライフサイクルルールを再検討したので記事にしました

バケットのバージョン管理オン
```
$ gsutil versioning set on gs://bucket-name
```

ライフサイクルのセット
```
$ gsutil lifecycle set lifecycle.json gs://bucket-name
```

ライフサイクルルールファイル(lifcycle.json)の内容
３個前のバージョンは自動削除、60日経過した古いバージョンも自動削除
```
{
"lifecycle": {
  "rule": [
  {
    "action": {"type": "Delete"},
    "condition": {
      "NumberOfNewerVersions": 2,
      "isLive": false
    }
  },
  {
    "action": {"type": "Delete"},
    "condition": {
      "age": 60,
      "isLive": false
    }
  }
]
}
}
```
CSSで、同じクラス名で見た目を変えるのをやめろ。

こんなコードが有りました。

```button.css
.button {
  background-color: white;
}
```

```a.css
.page-a .button {
  background-color: red;
}
```

```b.css
.page-b .button {
  background-color: blue;
}
```

```index.html
...
<div class="page-a">
  <button class="button">button1</button>
</div>
<div class="page-b">
  <button class="button">button2</button>
</div>
...
```
あら不思議。同じクラス名を使っているのに、button1 と button2 では色が違うのです！

もちろん、これくらいのコードなら全部読めばわかります。しかし何十とある css で、同じようなことが行われていたらどうでしょう。その html にかかれている button クラスの見た目は、どこで定義されているのでしょうか。

違うということには意味があるのです。見た目を変えるのであれば、名前も変えなければなりません。決して、html で同じクラス名を使えると楽だという理由で同じクラス名を使ってはいけません。CSS にはマルチクラスにできるという素晴らしいメリットが有るのですから、そちらを使うべきでしょう。

1. html の構造に依存した css を書くのをやめよう
2. 1つのクラス名は、1つの場所で見た目を定義しよう
Ionic 3とAWS Amplifyを使ってみる (その2: Cognito Userpoolを使った認証編)

(承前)[Ionic 3とAWS Amplifyを使ってみる (その1: S3へのデプロイ編)](https://qiita.com/masayang/items/2ae4e2f11552b283c5e1)

### Cognito設定
今回はAmplifyを使って、AWS CognitoのUserpoolを設定し、Cognitoを使ってIonicアプリからSign Up/Sign Inを行う部分を実験してみます。前回作ったアプリを拡張していきます。

```bash
amplify add auth
 Do you want to use the default authentication and security configuration? (Use arrow keys)
❯ Yes, use the default configuration.
  No, I will set up my own configuration.
```

ここではデフォルトの設定を使う、を選択します。デフォルトとはCognito Userpoolを使った認証において「email/passwordを使う」「本人確認のための乱数コードは、登録したメールアドレスに送付される」です。これ以外の組み合わせをしたい場合は、「No, I will set up my own configuration」を選択すれば良いようですが、まだ試していません。

```bash
amplify push
```

あとはamplify pushコマンドを実行すればAWS側の設定は自動実行されます。楽ちん。


### Ionicアプリ実装

Ionic側ではAmplifyサービスのライブラリを読み込んで、認証フォームと、認証後のコールバックを実装するだけです。

```html:home.html
<ion-header>
  <ion-navbar>
    <ion-title>
      I'm on S3
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-item>
    Logged In={{signedIn}}
  </ion-item> 
  <ion-item *ngIf="signedIn">
    {{user.username}}
  </ion-item> 
  <ion-item *ngIf="signedIn">
    <button ion-button button-full (click)="logout()">Logout</button>
  </ion-item> 
  <ion-item *ngIf="!signedIn">
    <amplify-authenticator></amplify-authenticator>
  </ion-item>
</ion-content>
```

認証フォームはAmplifyが提供するdialectがあるのでそれを使ってみます。

```typescript:home.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AmplifyService }  from 'aws-amplify-angular';
import { Auth } from 'aws-amplify';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  private amplifyService: AmplifyService;
  private signedIn: boolean = false;
  private user: any;

  constructor(public navCtrl: NavController, public amplify: AmplifyService,) {
    this.amplifyService = amplify;

    this.amplifyService.authStateChange$
    .subscribe(authState => {
      this.signedIn = authState.state === 'signedIn';
      if (!authState.user) {
        this.user = null;
      } else {
        this.user = authState.user;
        console.log(this.user);
      }
    })
  }

  logout() {
    Auth.signOut()
    .then(data => {
      console.log(data);
    })
    .catch(err => {
      console.log(err);
    })
  }
}
```

ロジック側ですが、AmplifyServiceを読み込んでおいて、認証後のコールバックを受信できるようにしておくのと、Logoutのロジックを作ることくらいですかね。

### 実行

```bash
amplify push
ionic serve
```

さてIonicアプリを起動してみると...

![Ionic App画面](https://cdn-ak.f.st-hatena.com/images/fotolife/m/masayang/20190110/20190110180716.png)

当たり前ですがCSS指定してないので配置がいまいちです。それっぽいCSSファイルはnode_modules/@aws-amplify/ui/src/ の下にあるので、これらを@importしろってことなのでしょう。

### 実行してみる

Create Accountリンクをクリックし、ユーザー名、メールアドレスとパスワード、電話番号を入力してSignupボタンをクリックすると、登録したメールアドレスに確認コードが届くので、それを確認フォームに入力すると、アカウント登録が完了します。あとはユーザー名とパスワードを使ってログインが可能になります。

AWSコンソールからCognito Userpoolを見てみると、ユーザが登録されたことがわかるはずです。

AWS周りの設定が自動化されたことで、サーバレスモバイルアプリ開発がたしかに楽になりそうな感じはしてきました。

次回はS3へのアクセスあたりを触ってみます。
【ThinkPad】VirtualBoxの初期設定で詰まって解決した


# PC

- ThinkPad E570
- Windows 10

# ThinkPadでVirtualBoxを動かすためにはBIOSの設定を変更する必要がある

この記事を参考にして、VirtualBoxでisoファイルからUbuntuを起動させようとした:
https://qiita.com/baikichiz/items/1b06c82ba1edbb607bbf

"Ubuntu用仮想マシンの作成" の節まで進んで、

> ディスクマークの横に、選択したisoファイルの名前がセットされるので、「OK」ボタンを押してダイアログを閉じます。

OKボタンが非アクティブで困った:
![thinkpad_virtualbox_01.png](https://qiita-image-store.s3.amazonaws.com/0/150194/ed2ff540-137a-dc51-5a3b-638565f5adf4.png)


エラーメッセージ:

> The hardware virtualization is enabled in the Acceleration section of the System page although it is not supported by the host system. It should be disabled in order to start the virtual system.

いろいろググって以下のサイトにたどりついた:
https://support.lenovo.com/se/ja/solutions/ht500006

> 現在のCPUは、ハードウェアの仮想化機能を搭載しており、VirtualBoxや VMware、 Hyper-V、その他の仮想マシンのアプリケーションを加速します。しかし、 Intel VT-xは、常にデフォルトで有効になっていません。

よくわからないけど、ThinkPadだとBIOSのなにがしの設定を変更しないといけないらしい。

変え方:

1. PCを再起動してF1連打でBIOSに入る。
2. "Security"タブの"Virtualization"を選択する。
3. その中の"Intel (R) Virtualization Technology" を"Enabled"にする。
4. 上手いことしてBIOSを抜ける。

2の画像:
![thinkpad_virtualbox_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/150194/7104dc69-7703-0ae7-714a-cb540685a517.jpeg)


3の画像:
![thinkpad_virtualbox_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/150194/29b002c1-66d8-fbdf-0863-19f35883bc80.jpeg)


無事に、OKボタンがアクティブになり、Ubuntuを起動させることができました:![thinkpad_virtualbox_04.png](https://qiita-image-store.s3.amazonaws.com/0/150194/d82cd96f-d38d-5f49-263e-473b2c48cc14.png)
VueでSSRしている際エラー「TypeError: e._ssrNode is not a function」

素のVueでSSRしてたら、上手くいってた時から大してコード変えてないのに、急に`TypeError: e._ssrNode is not a function`というエラーが出て困った。

[Evan You 先生](https://github.com/vuejs/vuepress/issues/492#h5o-19)もおっしゃっている通り、ただのキャッシュの問題だった。

```console
rm -rf node_modules/.cache
```

さらに、自分はVSCodeを使っているのだが、画面左のファイル操作するところで削除しても、どうやらバックでは残ってしまっているらしく、上手くいかない。ちゃんと、コンソールからやるべし（これで、数時間無駄にしましたorz

日本語のドキュメントが見当たらなかったので残しておく。
[PHP]PAY.JPで決済する

意外と参考になるとこがなかったんで書く。

[ドキュメント](https://pay.jp/docs/started)
[API リファレンス](https://pay.jp/docs/api/)
[テストカード](https://pay.jp/docs/testcard)
[ライブラリ](https://github.com/payjp/payjp-php)

WordPress使ってるので適宜かえてもらえば

```php:controller.php

get_template_part('lib/payjp-php/init');
\Payjp\Payjp::setApiKey( SECRET_KEY );

$customer_id;//pay.jpにおける顧客ID

try {
  if ( empty($customer_id) ) {//初回
    $customer = \Payjp\Customer::create([//顧客登録
      'card' => $form['payjp-token'],
      'description' => 'メモなど'
    ]);
  }

  $charge = \Payjp\Charge::create([//課金処理
    'customer' => $customer_id,
    'amount'=> $form['amount'],
    'description' => '注文IDなど',
    'currency' => 'jpy'
  ]);

  if ( isset($charge['error']) ) {
    $this->errors[] = $charge['error']['message'];
  )

} catch (\Payjp\Error\Card $e) {
  $body = $e->getJsonBody();
  $this->errors[] = "ステータス: {$e->getHttpStatus()}";
  $this->errors[] = "タイプ: {$err['type']}";
  $this->errors[] = "コード: {$err['code']}";
  $this->errors[] = $err['message'];

} catch (\Payjp\Error\InvalidRequest $e) {
  $this->errors[] = $e->getMessage();

} catch (\Payjp\Error\Authentication $e) {
  $this->errors[] = $e->getMessage();

} catch (\Payjp\Error\ApiConnection $e) {
  $this->errors[] = $e->getMessage();

} catch (\Payjp\Error\Base $e) {
  $this->errors[] = $e->getMessage();

} catch (Exception $e) {
  $this->errors[] = $e->getMessage();

} finally {
  if ( !empty($this->errors) ) {
  )
}

//DBでいろいろやる
```

```php:view.php
<?php
$customer_id;//pay.jpにおける顧客ID
?>
<form method="post">

<input type="hidden" name="amount" value="<?php esc_attr_e($amount);?>">

<?php if ( empty($customer_id) )://初回?>
<script type="text/javascript"
      src="https://checkout.pay.jp/"
      class="payjp-button"
      data-key="<?php echo PUBLIC_KEY;?>"
      data-partial="true">
</script>
<?php else://2回目以降?>
登録済みのカードで支払う
<?php endif;?>

<button class="button">注文を確定する</button>

</form>

<script>
(function ($) {
  $('form').on('submit', function() {
    $(this).find('button').attr('disabled', 'disabled');
  });
}(jQuery));
</script>
```

ちなみにカートは
[seikan/Cart](https://github.com/seikan/Cart) が使いやすかった
Vue でのエラー「Content placeholder not found in template.」

素のVueでSSRしている時に発生したエラー

```console
/mnt/c/react-apps/vue-cli-ssr-example/node_modules/vue-server-renderer/build.js:7882
    throw new Error("Content placeholder not found in template.")
    ^

Error: Content placeholder not found in template.
```

つまり、[ページテンプレート用のコメント](https://ssr.vuejs.org/ja/guide/#ページテンプレートを使用する)が足りないよということ。

[参考: stackoverflow](https://stackoverflow.com/questions/41644371/vuejs-2-server-side-rendering-not-working#h5o-6)

## 解決策 - ”<!--vue-ssr-outlet-->” を正しく埋め込む

SSRの際のテンプレートとして使用しているhtmlファイルに、この文字列を埋め込んでおく必要がある。

```index.template.html
<body>
  <!--vue-ssr-outlet-->
</body>
```

## 原因 - ビルドの際にhtmlファイルをminifyしていたため、コメントが消えていた

自分はVue CLI3でSSRを行っているが、その際にテンプレートファイルとして、publicフォルダ内の"index.html"を使用している。

[Vue CLI3のDocs](https://cli.vuejs.org/guide/html-and-static-assets.html#html)によると、この"public/index.html"は`vue-cli-service build`すると、"html-webpack-plugin"が噛ませられるようだ。

そのため、["html-webpack-plugin"の"minify"オプション](https://github.com/jantimon/html-webpack-plugin#minification)（正確には["html-minifier"のオプション](https://github.com/kangax/html-minifier#options-quick-reference)）をいじることで解決した。

```vue.config.js
chainWebpack: config => {
    config.plugin('html').tap(options => {
      options[0].minify.removeComments = false;
      return options;
    })
  },

// chainの使い方は以下
// https://cli.vuejs.org/guide/webpack.html#chaining-advanced
```

これで、minify時にコメントが削除されないようになる。

詳しくは、[サンプル：Vue-CLI3_SSR_TypeScript_Firebase_Workbox_example](https://github.com/Mizumaki/Vue-CLI3_SSR_TypeScript_Firebase_Workbox_example)を確認していただければと思う。
Laravel環境構築、上から順番にコマンドを実行するだけ。

# Laravel 以下のコマンド通り叩けば環境構築完了
こちらの記事よりコマンドのみ抜粋
https://qiita.com/hosono/items/dd404f3f074722ef989d

```bash
git clone https://github.com/laradock/laradock.git
cd laradock
cp env-example .env
cp nginx/sites/default.conf default.conf.backup
vi nginx/sites/default.conf
```

```nginx
server {

    listen 80;
    listen [::]:80;

    # For https
    # listen 443 ssl;
    # listen [::]:443 ssl ipv6only=on;
    # ssl_certificate /etc/nginx/ssl/default.crt;
    # ssl_certificate_key /etc/nginx/ssl/default.key;

    server_name laravel.test;
    root /var/www/app01/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }

    error_log /var/log/nginx/laravel_error.log;
    access_log /var/log/nginx/laravel_access.log;
}
```

```bash
docker-compose up -d nginx
composer create-project laravel/laravel app01
# warningが出るので無視してenterを押してしばらく待つ
docker-compose up
```



## mysqlを追加した場合はこちら
https://qiita.com/maejima_f/items/34cf3b8eb5ffbe256ad9
bundler: failed to load command: rspecとエラーが出た際の対処法

#はじめに
`bundle exec rspec`コマンドでrspecを実行しようとしたら、`bundler: failed to load command: rspec`とエラーが発生し、rspecが実行できませんでした。
対処法を載せておきます。

#対処方法について
##1. bundle doctorを実行
まずは、`bundle doctor`コマンドでトラブルの診断をしましょう。
私の場合は以下のようなエラーが出ました。

```
The Gemfile's dependencies are satisfied
The following gems are missing OS dependencies:
 * charlock_holmes: /usr/local/opt/icu4c/lib/libicudata.62.1.dylib
 * charlock_holmes: /usr/local/opt/icu4c/lib/libicui18n.62.dylib
 * charlock_holmes: /usr/local/opt/icu4c/lib/libicuuc.62.dylib
```

以下のgemにはOSの依存関係がありません、と言われています。この場合は「charlock_holmes」というgemですね。

##2. 指摘されたgemのuninstall
`bundle doctor`で指摘されたgemをまずはuninstallして、`bundle install`します。

```
bundle exec gem uninstall gem名
```

```
bundle install
```

そして、再度`bundle doctor`コマンドを実行し、以下のように返って来れば成功です。

```
The Gemfile's dependencies are satisfied
No issues found with the installed bundle
```
ElectronのlocalStorageのデータを覗き見る方法

# 経緯
A「bot作ったからそのアプリのシステムユーザID教えて」
僕「おｋ　どこで見ればいいん？」
A「見れないよ」
僕「は？」
A「開発者コンソール開けなくなっちゃったからねー」
僕「は？」

僕「は？」

# 覗き見る
とりあえずそのアプリがelectron製だったのと、アプリを開きなおしてもログイン状態を保持していることからlocalStorageにデータがあると推測

electronがlocalStorageのデータを入れている場所は大体同じ

調べればわかるがwindowsだと以下になる

```
C:\Users\%USERNAME%\AppData\Roaming\package.jsonのnameフィールド\
```

localstorageはsqlite3とかで開けるので、今回は[sqliteをGUIで触れる感じのソフト](https://forest.watch.impress.co.jp/library/software/sqldbbrowser/)を使って当該ファイルを開いた

# 結果
ビンゴ

テーブルの中に目的のデータがあった

ただ、対象のデータはblob形式だったのだが上記ソフトだとフォントがおかしいのか"O"と"C"の区別がつかなかったのが微妙

まぁファイルに対象のテキストをエクスポートみたいな機能があるから何とかなったが

# 蛇足
僕「localstorageからユーザID拾ってきたぞ」

A「ああ、slackの特定チャンネルでこのコマンド叩くとユーザID分かるってさ」

僕「は？」



僕「は？」
仕事始め、SmartTrade始め

#　あんた誰よ
本日からSmartTradeでインターンとしてご厄介になります、早稲田大学某理工学部4年生k0miyaと申します。
面接落ちたわ～と思ってたので働けて驚きですね。。

・金融に関してはド素人。2chのFX板まとめは中学生の頃読んでました
・Pythonで遺伝的アルゴリズムの研究をしています
・データ分析は数年前に授業でやったきりご無沙汰

（余談ですが、最近埼玉の婆ちゃんがAmazonを材木会社と思って株を買っていました）


#　QuantX Factoryと戯れる
これからの遊び相手は[QuantX Factory](https://factory.quantx.io/)　
この記事読んでる人はまあ皆ご存知でしょうね。
投資アルゴリズムを開発するためのプラットフォームです。
サンプルコードが用意されているのでド素人の私にも親切設計。
出勤早々自由に任せられたので、なんとなく[モメンタムで売買](https://factory.quantx.io/developer/1a62e6dcbcd143149f250a24f5041757)してみました。
理由はシンプルで面白そうだったからです。
強気状態で買う、弱気状態で買う、で実装。

    def _my_signal(data):
    
      cp = data["close_price_adj"].fillna(method="ffill")
      MOM10 = pd.DataFrame(data=0,columns=[], index=cp.index)
      for (sym,val) in cp.items():
        MOM10[sym] = ta.MOM(cp[sym].values.astype(np.double), timeperiod=10)
      #モメンタムが0以上で強気状態＝買い
      buy_sig = MOM10[(MOM10 >0)]
      #モメンタムが0以下で弱気状態＝売り
      sell_sig = MOM10[(MOM10 <0)]
      return {
        "MOM10": MOM10,
        "buy:sig": buy_sig,
        "sell:sig": sell_sig,
        
      }

# 気になる結果は…

じゃかじゃん！
![スクリーンショット (96).png](https://qiita-image-store.s3.amazonaws.com/0/340650/683fe7b5-4db1-bd53-163f-ad2f982717a9.png)

損益率-4.06%。

ウケる。

#　春の大学対抗アルゴリズム祭り
今春、SmartTradeによる大学対抗アルゴリズムコンテストの開催が決定しました。
詳細についてはまだ未定ですが、「どうせ身内しか読まないし」の一声で、めでたくwebページが全世界に公開です。
[公式ＨＰはこちら](https://algorithmcup.wordpress.com/)

#　次回出勤までの目標
アルゴリズムでパラメータとなる株式用語を理解する。
やはりアルゴリズムを弄るにしても金融への理解が無いと珍紛漢紛だと自覚させられました。
SmartTradeにあった入門書の中でも取り分け分かりやすそうな[こちら](https://www.amazon.co.jp/%E6%9C%80%E6%96%B0%E7%89%88%E5%85%A5%E9%96%80%E3%81%AE%E5%85%A5%E9%96%80-%E2%80%9C%E6%A0%AA%E2%80%9D%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF%E2%80%95%E8%A6%8B%E3%82%8B%E3%83%BB%E8%AA%AD%E3%82%80%E3%83%BB%E3%82%8F%E3%81%8B%E3%82%8B-%E6%9D%89%E6%9D%91-%E5%AF%8C%E7%94%9F/dp/4534021895)で勉強したいと思います。


#　ふんわり考えたこと
例えば、遺伝的アルゴリズムを応用したものがあったらどうだろう。
短期決算＝世代として銘柄を選抜しつつ売買を繰り返していくとか面白そうです。
評価方法、選抜に関するパラメーターなど考える事は多そうです。
まあこんなこと書いて、後日無知に赤面するかもしれませんが…。
#　退勤、退勤
上野に密談しに行きます。
決まったらここでも宣伝しようと思います。
【MySQL】良く使う調査コマンド・クエリ

# SHOWコマンド
## プロセス一覧
```
show processlist;
```

## MySQLパラメータ確認
```
SHOW VARIABLES [like 'パラメータ名'];
```
パラメータ名に **hostname** と入れればホスト名が取得できるし、
 **buffer** と入れるとメモリ関連、 **dir** と入れればディレクトリ情報などが確認できる。

SHOW VARIABLES で表示しきれない長い値については、回避策として **SELECT @@パラメータ名;** で表示可能

## データベーススキーマ一覧
```
show databases [like 'スキーマ名' ] ;
```

## ユーザ権限確認
```
SHOW GRANTS [FOR ユーザ名];
```

## 直前のクエリのエラーやワーニング確認
```
SHOW ERRORS;
SHOW COUNT(*) ERRORS;

SHOW WARNINGS;
SHOW COUNT(*) WARNINGS;
```

## テーブル定義確認
```
show create table スキーマ名.テーブル名;
```

## インデックス確認
```
show index from スキーマ名.テーブル名;
```

参考：https://dev.mysql.com/doc/refman/5.5/en/show.html
参考：https://dev.mysql.com/doc/refman/5.7/en/show.html

# DB、テーブルサイズチェック
## DBスキーマサイズ
```
SELECT 
    table_schema,
    SUM(data_length + index_length) / 1024 / 1024 AS all_tab_mb,
    SUM(data_length) / 1024 / 1024 AS data_mb,
    SUM(index_length) / 1024 / 1024 AS index_mb
FROM
    information_schema.tables
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
```

参考：https://qiita.com/ikenji/items/b868877492fee60d85ce

## テーブルサイズ
```
SELECT 
    table_name,
    engine,
    table_rows AS tbl_rows,
    avg_row_length AS rlen,
    FLOOR((data_length + index_length) / 1024 / 1024) AS all_tab_mb,
    FLOOR((data_length) / 1024 / 1024) AS data_mb,
    FLOOR((index_length) / 1024 / 1024) AS index_mb
FROM
    information_schema.tables
WHERE
    table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC;
```

参考：https://qiita.com/ikenji/items/b868877492fee60d85ce

# InnoDBテーブル断片化チェック
```
SELECT 
    table_schema, table_name, data_free, table_rows
FROM
    information_schema.tables
WHERE
    table_schema = 'スキーマ名'
AND
    table_name = 'テーブル名';
```

## 断片化解消するには？(INNODB前提)
```
ALTER TABLE テーブル名 ENGINE INNODB;
```

参考：http://d.hatena.ne.jp/yohei-a/20180610/1528650004

# ロック競合
## MySQL5.6以前
```
SELECT 
    t_b.trx_mysql_thread_id blocking_id,
    t_w.trx_mysql_thread_id requesting_id,
    p_b.HOST blocking_host,
    p_w.HOST requesting_host,
    l.lock_table lock_table,
    l.lock_index lock_index,
    l.lock_mode lock_mode,
    p_w.TIME seconds,
    p_b.INFO blocking_info,
    p_w.INFO requesting_info
FROM
    information_schema.INNODB_LOCK_WAITS w,
    information_schema.INNODB_LOCKS l,
    information_schema.INNODB_TRX t_b,
    information_schema.INNODB_TRX t_w,
    information_schema.PROCESSLIST p_b,
    information_schema.PROCESSLIST p_w
WHERE
    w.blocking_lock_id = l.lock_id
        AND w.blocking_trx_id = t_b.trx_id
        AND w.requesting_trx_id = t_w.trx_id
        AND t_b.trx_mysql_thread_id = p_b.ID
        AND t_w.trx_mysql_thread_id = p_w.ID
ORDER BY requesting_id , blocking_id;
```

## MySQL5.7以降
```
SELECT 
    *
FROM
    sys.innodb_lock_waits;
```

参考：http://d.hatena.ne.jp/sh2/20090618
参考：https://qiita.com/hmatsu47/items/607d176e885f098262e8
Clipkitで数式を表示する方法

クラウド型CMSの[Clipkit](https://clipkit.co)というサービスがあります。

うちの会社の若いもんが、「コンテンツ内でTex形式で書いた数式使いたい」と言い始めたので調べてみたら、超簡単に使えたので、記録として残しておきます。
なお数式の表示には[MathJax](https://www.mathjax.org)を利用しています。

# 手順

Clipkitにログインして「＋新しい記事を作成」で編集を始めます。

## MathJaxの読み込み
最初に「HTML」ブロックを追加して次のコードを入力します。
MathJaxのロゴを表示する部分は別になくてもいいですが、ライブラリ作成者に敬意を込めて。

```HTML
<script type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<a href="https://www.mathjax.org">
  <img src="https://www.mathjax.org/badge/mj_logo_60x12.png" border="0" alt="Powered by MathJax" />
</a>
```

## インライン
「テキスト」ブロックで文章を作成している中で、インラインで数式を使いたい場合は、数式を、\\( と )\\ で囲みます。

```
もし \(x<y\) の場合、...
```

こんな感じで表示されます。
<img width="190" src="https://qiita-image-store.s3.amazonaws.com/0/184457/9b195c44-9345-53e3-ae34-c16276b5c5de.png">


## 数式
普通に数式を表示したい場合は、「テキスト」ブロック内で、数式部分を\\[ と \\] で囲みます。

```
\[
f ( a ) = \frac { 1 } { 2 \pi i } \oint _ { \gamma } \frac { f ( z ) } { z - a } d z
\]
```

こんな感じで表示されます。
<img width="232" src="https://qiita-image-store.s3.amazonaws.com/0/184457/09877655-2d90-07c1-7887-1acf23a50a74.png">



# 最後に
読み込んでいるMathJaxのライブラリとかは全部入りのやつなので、使っているうちに弊社にあった設定が見つかれば更新したいと思います。

また、弊社からの問い合わせに快くご対応いただきましたClipkitのサポートの方にも感謝申し上げます！
Google Formsで「その他」の回答があると次回の選択肢に追加するGoogle Apps Script(GAS)

インフラ屋なのでGAS初心者で、JavaScript初心者です。

グーグルフォームを使ったアンケートで「その他」を入れておくと選択式の質問に記述式の選択肢が表れます。
フォームに回答があった時をトリガーにして下記のスクリプトを走らせると、「その他」で書かれた回答が次回から選択肢に追加されるので手書きする必要がなくなる、そんな内容です。

**悪意を持った回答者がいない環境で使いましょう。その他にでたらめな文字を入れて回答すると再現なく選択肢が増えてどんどん荒れていくので使う場面には注意が必要です。**

見よう見まねで書いてみてこれで追加できるようになりました。

##スクリプトの内容
1/11追記 スクリプトを手直ししました。違う型同士で比較してたからif文が機能してなかったっぽい。
これで自分なりに思っていた動作をする、無駄がない感じの文になりました。

```
function AddChoice() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("フォームの回答 1");
  var form = FormApp.openById("自分のIDで置き換える。URLの中に書かれている長い文字列です");
  var title = "○○は？"; //ここに対象の質問文を入れる
  //対象の質問を探す
  var items = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
  for (var i = 0; i < items.length; i++){                                                                                          
    if (items[i].getTitle()== title){                                           
      var question = items[i].asMultipleChoiceItem()
      break;
    }
  }
  var choices = question.getChoices();
  //1行目から質問文と同じ列を探して、その列の最終行の回答を探す
  for (var i = 1; i <= sheet.getLastColumn(); i++){
    if (sheet.getRange(1, i).getValue() == title){
      var newchoice = sheet.getRange(sheet.getLastRow() , i).getValue()
      break;
    }
  }
  //対象の回答が選択肢の中に既にあるか比べてあったら終わる
  for (var i = 0; i < choices.length; i++){
    if (choices[i].getValue() == newchoice){
    return;
    }
  }
  //選択肢の最後に追加する
  choices.push(question.createChoice(newchoice));
  question.setChoices(choices);
}

```

##トリガーの設定
回答があるとこのスクリプトが実行されるように仕込みます。
1. スクリプトエディタのメニューの「編集」ー「現在のプロジェクトのトリガー」
2. 右下にある「トリガーの追加」
3. 「イベントの種類を選択」を「フォーム送信時」にして、「保存」します。

その他を使って回答して、「別の回答を送信」（次回以降）で項目が増えていれば成功です。


####参考文献
ありがとうございます。
https://developers.google.com/apps-script/reference/forms/form
https://tonari-it.com/gas-form-add-items/
https://tonari-it.com/gas-form-generate-choices/
https://teratail.com/questions/45539
https://qiita.com/Gunsei_Paseri/items/2245a10a31b26b68953f
https://takakisan.com/gas-form-send-email-tutorial/
https://www.genius-web.co.jp/blog/cat-118/gasskip.html
Windows10 PATH追加(ユーザアカウント設定)

参考  https://qiita.com/yuki12/items/9723f60907508b11504b

手動で入れたツールをコマンドラインで任意の場所から実行するためにはPATHを通しておくと便利です。
Windows10ではシステム詳細設定に追加するには管理者権限が必要なので、ユーザアカウント設定で設定するのがおすすめです。
\#以下のWindows10 は英語表示ですが日本語でも同じです。

----
画面左下の検索窓にコマンド"control userpasswords" を打ち込みます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309536/6d217a12-0188-9370-4816-d1eb2a8fabb3.png)


左下の「change my environment variables」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309536/fcfbe7a4-9f06-5c35-ad90-6d23756b321c.png)

User variablesの Path を選択、Editボタンを押して編集します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309536/e0d4cac7-6f5e-050c-02ea-939804431bd2.png)

Newボタンを押して追加したいパスを追加します。
注意:既存の行の末尾に追記するのはダメ。1行に1パスを書くこと。ここではOpenSSHとVirtualBoxのパスを追加しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309536/1c150176-9c23-b82b-d460-901ff4dce252.png)

設定後、ログオフして再ログインします。

再ログイン後、パスが追加されていることを確認します(確認コマンド→  echo %path% )

```
c:\Program Files\OpenSSH>echo %path%
C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\cmd;C:\HashiCorp\Vagrant\bin;C:\Program Files\PuTTY\;C:\Users\tajimh1\AppData\Local\Microsoft\WindowsApps;C:\Program Files\OpenSSH;C:\Program Files\Oracle\VirtualBox

c:\Program Files\OpenSSH>
```
Kaggle APIをGoogle Colaboratory上で使う【メモ】

# 前提条件

- Google Drive上にkaggle.jsonをUploadしている
- 以下の例ではDriveのディレクトリの下に、Kaggleというフォルダをおいて、その中にkaggle.jsonをおいている

以下のコードを毎回流せば、マウントされるはず。

## 1. Google Driveをマウント

```
from google.colab import drive
drive.mount('/content/drive')
```
## 2. Google Driveからkaggle.jsonをコピー

```
# .kaggleというフォルダをColab上に作成
!mkdir ~/.kaggle

# .kaggelフォルダにコピーし、権限を変更
!cp /content/drive/'My Drive'/Kaggle/kaggle.json ~/.kaggle/
!chmod 600 /root/.kaggle/kaggle.json
```

終わり。あとは分析を頑張る。

ちなみに、書き終わってから気づいたのだが、https://qiita.com/yukkyo/items/eb9bae0b82248f9abd28 のコメント欄に説明があったので、わざわざ書き直さなくてよかった気がしてきた。

(文系非エンジニアが初めてQiitaに投稿してみたので、誤った表現があっても許して下さい)
discordpyのrewrite/asyncとは何なのか

<font color="Red">※ 2019/04/09のrewrite版正式リリースに伴い内容を修正しました。</font>

discord.py を知らない方はこちらをお読みください。
[Pythonで実用Discord Bot(discord.py解説)](https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f)

# 要は
新バージョンが rewrite
旧バージョンが async

互換性はありません。

python2系/3系と同様の問題と考えてください。

呼称はGithubリポジトリのブランチ名が由来
- https://github.com/Rapptz/discord.py/tree/rewrite
- https://github.com/Rapptz/discord.py/tree/async

# rewrite版 について
- [ドキュメント(英語)](https://discordpy.readthedocs.io/en/stable/) / [日本語版(翻訳中)](https://discordpy.readthedocs.io/ja/stable/)
- 別称 v1.0.0
- 2019/04/09 にリリース
    - 過去ではgithubからのみインストール可能だった
- `pip install discord.py` でインストール
- python3.7に対応
- 現在解説している記事は少ない

```console:githubからのインストール方法
pip install git+https://github.com/Rapptz/discord.py.git@rewrite#egg=discord.py[voice]
```

# async版 について
- [ドキュメント(英語)](https://discordpy.readthedocs.io/en/v0.16.12/)
- 別称 v0.16.12 or 旧版
- 2019/04/08 まで `pip install discord.py` でインストールできたもの
- <font color="Red">python3.7 では動かない</font>
    - 3.4.2 から 3.6.* で動く
- 現在殆どの記事で解説されているのがこのバージョン
- <font color="Red">最終更新日 2017/11/13</font>

# rewrite版とasync版の仕様変更点
目立つところでは、チャンネルへのメッセージ送信の構文が変更されており、
以下のような違いがあります。

```python:rewrite版の構文
await channel.send('Hi!')
```

```python:async版の構文
await client.send_message(channel, 'Hi!')
```

その他詳細は公式ドキュメントに記載されています。
[v1.0への移行](https://discordpy.readthedocs.io/ja/stable/migrating.html)

# 後書き
現在多くの記事は discord.py の <font color="Red">async版</font> を扱っており、
現行版の <font color="Red">rewrite版</font> に対応していません。
そのため混乱が多く、理解を得るための記事が必要と考え執筆しました。

以後説明が面倒な際はこちらの記事を投げてください。
エラー監視には Sentry が超便利！

# 避けられないアプリケーションのエラー監視
アプリケーションを運用する上でエラー監視は避けて通れませんよね。
とはいえ、エラー監視のツールやサービスは今やたくさんあるので、どれを使ったらいいか迷うところでもあります。

僕はお仕事で [Sentry](https://sentry.io/welcome/) を使っているのですが、これまでエラー監視ができてなかった処理に [Sentry](https://sentry.io/welcome/) での監視を追加したらめちゃくちゃ簡単すぎて感動を覚えたのでご紹介します。

この記事では python での設置についてだけ書きますが、 [Sentry](https://sentry.io/welcome/) が対応している言語であれば基本的に同じようなやり方で設定できるようになっていると思います。

https://github.com/getsentry/sentry

# Sentry の設定方法
## 1. sentry-sdk のインストール
`sentry-sdk` を pip でインストールします。

```
$ pip install --upgrade sentry-sdk
```

## 2. Sentry の設定
以下のコードをプログラムの実行時に必ず呼ばれるどこかに記述します。
例えば設定ファイルを扱うパッケージの `__init__.py` の中に書くのがいいかと思います。

``` python
import sentry_sdk

sentry_sdk.init('< DSNの値 >')
```

**なんと、たったこれだけでエラー監視の設定ができます！**
あとはエラーが起きるのを待つだけ。
※エラーが出ないのが一番いいんだけど・・・

# エラー通知を試してみる
エラー通知を試すために以下のようなプログラムを実行してみます。

``` python:sentry_test.py
import logging
import sentry_sdk

# sentry sdk 初期化
sentry_sdk.init('< DSNの値 >')

# ログを出力
logging.debug('DEBUG レベルのログ')
logging.info('INFO レベルのログ')
logging.warning('WARN レベルのログ')
logging.error('ERROR レベルのログ')

# 例外
raise Exception('this is exception.')
```

すると Sentry の画面をみると以下のように、 ERROR レベルのログと例外の2つのエラーが通知されたことがわかります。
`BREADCRUMBS` の箇所にエラーが発生するまでに出力されたログが表示されます。

例外の通知の場合は例外が発生するまでのスタックトレースも一緒に表示されます。
※ ERROR ログの場合でもスタックトレースを表示できるので、後の方にやり方を書いてます。

logger の設定がデフォルトのままだと WARN レベル以上のログしか表示されませんが、これは設定を変えれば DEBUG のログを出すこともできます。
めちゃ便利！

#### Sentry の issue
![スクリーンショット 2019-01-10 16.51.52.png](https://qiita-image-store.s3.amazonaws.com/0/43699/7e3c4a08-11e6-3ff6-fa86-4d09c8231782.png)

#### ERROR レベルのログ
![スクリーンショット 2019-01-10 16.52.05.png](https://qiita-image-store.s3.amazonaws.com/0/43699/c6f0e9bc-993e-1190-9340-d46222d33475.png)

#### 例外
![exception.png](https://qiita-image-store.s3.amazonaws.com/0/43699/43be6104-1f0d-7c09-977e-0a3a9d2e42ae.png)

# `ERROR` レベルのログでもスタックトレースを表示する
以下のように `logger.error()` の引数に `exc_info=True` を指定すると ERROR ログの通知の場合でもスタックトレースが sentry で表示されるようになります。

``` python:sentry_test.py
import logging
import sentry_sdk

# sentry sdk 初期化
sentry_sdk.init('< DSNの値 >')

# ログを出力
logging.debug('DEBUG レベルのログ')
logging.info('INFO レベルのログ')
logging.warning('WARN レベルのログ')
logging.error('ERROR レベルのログ', exc_info=True)

# 例外
raise Exception('this is exception.')
```

![error.png](https://qiita-image-store.s3.amazonaws.com/0/43699/fb2cf6e9-4724-0ca4-fa8c-c9b98584cf1e.png)

最高じゃん！

# まとめ
とりあえず `sentry_sdk.init()` を呼んでおけばエラー通知が使えるというこのお手軽さがまじで最高じゃないですか？？？

エラー通知以外にもなんらか検知したいイベントの通知や、sentry 上で見たい情報をいろいろ付け足すこともできます。
とにかくめちゃ便利です。

強いて欠点をあげるなら、 [Sentry](https://sentry.io/welcome/) から送られてくるエラー通知の数に上限が設定されていて、その上限を上げるには課金が必要なくらい。
でもここまでのクオリティのサービスなら課金するに値する価値が十分にあると思います。

さあ、あなたも今日から [Sentry](https://sentry.io/welcome/) を始めよう！
https://docs.sentry.io/error-reporting/quickstart/?platform=python
AmazonLinuxにJRE8/JDK8を入れたDockerコンテナイメージを作成する

# 背景
* AmazonLinuxにJRE(色々な経緯がありver8)が入ったコンテナイメージを作成する
    * 過去の様々な経緯があり 8 です
* JDK, JREをそれぞれのパッケージ名が混乱したのでメモ
* それぞれのイメージサイズもメモしておく

# JREコンテナイメージ作成

* JREの方のDockerfileです
* headlessというのがJREのみ入っています
    * 無印の `java-1.8.0-openjdk` はiconなどが入っている分容量が大きいらしい
* 実際はマルチステージビルドで利用することが多いかと思いますが、今回は簡略化してベースイメージで動かします

```dockerfile:Dockerfile
FROM amazonlinux:2.0.20181114
RUN yum install -y java-1.8.0-openjdk-headless && yum clean all
```

* イメージを作成 &　(アンチパターン感ありますが、sshで入って) java, javac のバージョンを確認します

```sh
# Dockerコンテナイメージを作成
$ docker build -t amazonlinux-jre8 .
(省略)

# （確認のため） コンテナにsshで入ってversionを確認 
$ docker run -it amazonlinux-jre8 sh
sh-4.2# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
sh-4.2# javac -version
sh: javac: command not found
```

* 無事、javaコマンドは実行でき、javacコマンドは（当然）インストールされていません


# JDKコンテナイメージ作成

* JDKの方のDockerfileです
* `devel` 付きがJDKになります
* マルチステージビルド側で利用することが多いと思いますが、シンプルにベースイメージで確認します
 
```dockerfile:Dockerfile
FROM amazonlinux:2.0.20181114
RUN yum install -y java-1.8.0-openjdk-devel && yum clean all
```

* JRE版と同じくイメージを作成 & java, javac のバージョンを確認します

```sh
# Dockerコンテナイメージを作成
$ docker build -t amazonlinux-jdk
(省略)

# （確認のため） コンテナにsshで入ってversionを確認 
$ docker run -it amazonlinux-jdk sh
sh-4.2# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
sh-4.2# javac -version
javac 1.8.0_191
```

* 無事、java, javac の両方のコマンドが利用可能


# サイズを確認

* `docker images` コマンドでイメージサイズを取得可能なので取得
    * ベースのamazonlinuxとの差分が、JRE,JDKのパッケージサイズ追加コマンドで生じたもの

```sh
$ docker images --format "table {{.Repository}}\t{{.Size}}" | grep amazonlinux
amazonlinux                  162MB
amazonlinux-jre8             308MB
amazonlinux-jdk              362MB
```

# まとめ
* JREしか使わないときは `java-1.8.0-openjdk-headless`
* JDKを使うときは `java-1.8.0-openjdk-devel`
* サイズの差は約54MB。のためJDKを使う場合はマルチステージビルドを利用したほうが手堅いですね
【sql学習】MySQLコマンド 簡単な日本の都道府県別の人口表を作る

# about
日本の都道府県別の人口表(簡易版)のテーブルを作るのに使ったMySQLコマンドを乗せます。

# todo
下記のような日本の都道府県別の人口表を作る。

|pref_name|population|
|---|---|
|徳島|200|
|香川|400|
|愛媛|300|
|高知|400|
|福岡|600|
|佐賀|200|
|長崎|400|
|東京|800|
|群馬|100|


# index
* MySQLにログイン(mysql -u root -p)
* データベース（database）
	* データベース一覧を確認(show databases)
	* データベースを選択する(user db_name)
* テーブル（table）
	* テーブル一覧を表示(show tables)
	* テーブルを作成(create table tbl_name)
	* テーブルに値(データ)を挿入(insert into tbl_name)
	* テーブルに値(データ)が追加されたか確認(select * from tbl_name)
* カラム（Columns）
	* カラムの追加(alter table tbl_name add column column_definition)
	* カラムの削除(alter table tbl_name drop column col_name)
	* カラムの確認(show columns from tbl_name)

# truouble(対応中)
* ①テーブルに値(データ)を挿入したとき（たとえば、”富山”）char型カラムに1文字しか表示されない。
* ②上記の問題を解決するため、テーブルを新規作成するとき、カラムの型に"varchar"を指定したいが下記のエラーが出る。

  >ERROR 1064（42000）: You have an error in your SQL syntax;
    check the manual that corresponds to your MySQL server version for the 
    right syntax to user near ' population int),' at line 1

# Done List
* mysqlにログイン
  `$ mysql -u root -p`
* データベース一覧を確認する
  `$ show databases;`
* データベースを選択する
  `$ use data_name;`
* テーブル一覧を表示する
  `$ show tables;`
* テーブル作成
 `$ create table tbl_name
	col_name1 data_type1, 
	col_name2 data_type2
);`
* テーブル削除
  `drop table tbl_name;`
* テーブルに値(データ)を挿入
`$ insert into tbl_name(col_name1,col_name2) values(date1,date2);`
	* 実行結果（オーバーフローエラー）。5.6からチェックが厳格になっている
	`ERROR 1406(22001): Data too long for column 'pref_name' at row1`
	* 対策：SQL文にIGNOREを入れる
	`$ insert ignore into tbl_name(col_name1,col_name2) values(date1,date2);`
	* テーブルに値が追加されたかを確認する
	  `mysql> select * fom PopTbl;`
* テーブルの構造を表示する
`show columns from tbl_name;`
* カラムを削除する
`alter table tbl_name drop [column] col_name;`
	* カラムの情報を取得して、削除されたことを確認する
	` show columns from tbl_name;`
* カラムを追加する
`mysql> alter table goods `
  型にvarcharを指定すると下記のエラーが出る
  
>ERROR 1064(42000): You have an error in your SQL syntax;
   check the manual that corresponds to your MySQL server version
   for the right syntax to use near '' at line 1
ログをS3へエクスポート時に「The specified log group does not exist.」でハマった話

#🔷 現象
CloudWatch logsのログを、S3のバケットにエクスポートする処理を用意。

```js
'use strict';

const aws = require('aws-sdk');
aws.config.update({region: 'ap-northeast-1'}); // リージョン指定

/**
 * メイン処理
 * @param event : 呼び出し元サービスから渡される値
 * @param context : AWS側の各種情報
 * @param callback : 呼び出し元サービスへ返す値
 * 
 */
exports.handler = (event, context, callback) => {
  const cloudwatchlogs = new aws.CloudWatchLogs(); 
  let params;
  

  /* 
  "destination"で設定したS3バケットに、"destinationPrefix"で設定したフォルダを作り、
  "logGroupName"で設定したCludWatchのロググループのlogをexportする。
  exportするlogの範囲は、"from"から"to"で設定した範囲。
  */
  params = {
    'destination': 'hoge',
    'from': 1546905600000,
    'to': 1546992000000,
    'logGroupName': '/aws/apigateway/piyo',
    'destinationPrefix': 'fuga',
    'taskName': 'testTask'
  };

  /* logのexport処理 */
  cloudwatchlogs.createExportTask(params, (err, data) => {
    let response;
    if (err) {
      console.log(err, err.stack);
      response = err.stack;
    } else {
      console.log(data);
      response = data;
    }
    callback(null, response);
  });
};
```
これを実行したところ、以下のようなエラーが発生。

```
 ResourceNotFoundException: The specified log group does not exist.
（訳　：　指定されたロググループは存在しません。）
```
ロググループ名の不備かと思ったが問題なし。
一応、バケット名や権限周りも確認したが、問題なし。

#🔷 原因

結局、原因はリージョンの設定不備。

ソースの4行目で**東京リージョン**を指定しているが、本Lambdaは**バージニア北部リージョン**。

よって、以下のようにリージョンを修正したら、無事に動きました。

```js
// aws.config.update({region: 'ap-northeast-1'});  // リージョン指定
aws.config.update({region: 'us-east-1'});  // リージョン指定
```

地味にハマったので、ソースを使い回す時とかは、リージョン設定は要注意です。
C#でTelloを操作する。TelloLibを使って。前進後退左右旋回など

#はじめに
[前回](https://qiita.com/shuhey/items/1cbccca534e4ec965e0c)は`TelloLib`というライブラリを使ってプログラムからTelloを操作する、ということをやりました。

しかし、離陸と着陸だけでした。
まったく物足りませんよね。

ということで今回は前進や後退、右旋回、左旋回などをやってみたいと思います。

#離着陸以外のTelloの操作
離着陸はそれぞれメソッドが用意されていました。
それでは前進後退、旋回などの操作を行うにはどうするかというと、以下の`setAxis`というメソッドがあり、それを使うことでそれらの動作を行うことができます。

```csharp
Tello.controllerState.setAixs(float lx,float ly,float rx,float ry);
```

引数のそれぞれの役割は以下のとおりです。
各引数は-1.0~1.0の値をとります。
例えば、lxに-0.5を設定すると左方向に回転します。0.5を設定すれば右方向に回転します。
すべての引数に0を設定すると、その場に静止します。

- lx：右回転(+)、左回転(-)。
- ly：上昇(+)、下降(-)。
- rx：右スライド(+)、左スライド(-)。
- ry：前進(+)、後退(-)。

各引数の値を調整することで「ゆっくり左旋回」や「前進しながら上昇」といった動作を行うことができます。

さて、`setAxis`メソッドでTelloの動きを設定しましたが、それだけでは動き始めません。
設定した内容をTelloに送る必要があります。
それが`sendControllerUpdate`メソッドです。
このメソッドを呼び出すと、先ほど設定した内容でTelloが動き出します。

```csharp
Tello.sendControllerUpdate();
```

では実際にやってみましょう、と言いたいところですが、ちょっと待ってください。

仮に以下のように記述して前進させたとしましょう。

```csharp
Tello.controllerState.setAixs(0, 0, 0, 0.5);
Tello.sendControllerUpdate();
```

すると、ひたすら前進し続けて、室内であればやがて壁に激突するでしょう。
「40度右回転」とか「1m前進」といった指定はできないのです。

そこで、その動作を「何（ミリ）秒続けるか」といった考えで動作をコントロールします。
つまり、Telloにコマンドを送った後に任意の時間、待機してから静止させればよいということになります。
例えば以下のような感じです。

```csharp
//前進開始
Tello.controllerState.setAixs(0, 0, 0, 0.5);
Tello.sendControllerUpdate();

await Task.Delay(1000);//1秒待つ

//静止
Tello.controllerState.setAixs(0, 0, 0, 0);
Tello.sendControllerUpdate();
```

このように秒数で進む距離をコントロールできます。
どのくらいの値で何秒間動かすと何mすすむのかは、試行錯誤が必要になると思いますが。
それによって引数の値と秒数、距離の関係式を求めることができれば「面舵いっぱいよーそろー！」みたいなこともできるかと思います。

`Main`メソッドで`await`使う場合は言語バージョンをC#7.1以上にしてくださいね。


ついでに右旋回はこんな感じです。

```csharp
//前進開始
Tello.controllerState.setAixs(0.5, 0, 0, 0.2);//遅めに右旋回
Tello.sendControllerUpdate();

await Task.Delay(1000);//1秒待つ

//静止
Tello.controllerState.setAixs(0, 0, 0, 0);
Tello.sendControllerUpdate();
```

#おわりに
前回と今回合わせてTelloを自由自在に操作することができるようになりました。
おわかりのとおり、コード的にはまったく難しいところがありません。
このライブラリの素晴らしいことったらありません。
感謝です。

今回は入力コマンドに応じて動作させましたが、例えば矢印キーで操作することももちろんできますし、モバイルアプリケーションから利用することもできます（サンプルコードにもありますしね）。

もちろんAlexa（Google Homeでも）で操作することもできるはずです。
以前に`ngrok`を使ってローカルで実行しているAzure Functionsにインターネット側からアクセスする方法を書きましたが、この方法を使ってAlexaのエンドポイントとしてローカル上のAzure Functionosを指定してやれば、きっとできるはずです（試してない）。


#追記
あと、Telloのアクションのメソッドとして離着陸以外に`フリップ`があるのを忘れていました。

```csharp
Tello.doFlip();
```

これで後ろに宙返りします。
バッテリー残量が規定値以上という制約がありますが。
[PHP] 配列で同じキーのものは数値を足し算したい

## コード

```php
$arr = ["hoge" => 1, "piyo" => 2, "fuga" => 1];
$arr2 = ["hoge" => 1, "fuga" => 3, "hogehoge" => 0];

foreach ($arr2 as $key => $val) {
    if (array_key_exists($key, $arr)) {
        $arr[$key] = $arr[$key] + $val;
    } else {
        $arr[$key] = $val;
    }
}

print_r($arr)
```

## 返り値

```
Array
(
    [hoge] => 2
    [piyo] => 2
    [fuga] => 4
    [hogehoge] => 0
)
```
[ESP32]Dual Coreってどうなの？ その1

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/b2dd6ef2-3913-273e-a5ab-60956181deac.png)

ESP32には三つのプロセッサーがあります。

Core & Memoryというブロックに二つのプロセッサーがあり、自由に使うことができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/3cf8703a-1e53-9085-62fa-e1643ab2f8b5.png)

RTCにCo-processorが１個あってまとめて、3個になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/fe3c163b-abd1-cdc2-0cb2-9c3fa131150c.png)


## xPortGetCoreIDで確認してみよう。

```c++:getCoreId.cpp

  Serial.print("setup() running on core ");
  Serial.println(xPortGetCoreID());

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/49b9254b-df2e-8b06-0ec7-b03c370764ea.png)

## 参考

1. https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/freertos.html
macにTensorFlowを入れてみた

#そうだ、TensorFlow使ってみよう

ということで[Python3 TensorFlow for Mac 環境構築
](https://qiita.com/tom_ato/items/bbdf4574b3ecb0048fa1)を参考に導入してみた。

##環境
OS: Mac OS Sierra 10.14.2
言語 : Python 3.6.0
(事前にPython 3.7.1がインストールしてあったものの後述の理由でダウングレード）

##手順
中途半端に構築されていたところからなので自分のやったことだけ記載すると
1:pyenv-virtualenvのインストール
2:TensorFlowのPython環境を構築
3:pipのインストール(アップデート）
4:TensorFlowのインストール
です。
詳細はリンク先の記事におまかせするとして困った点、気付いた点のみ記載します。
1~3までを無事終えて4の手順に入ったのですが以下のエラーが表示され実行できませんでした。
```
Could not find a version that satisfies the requirement tensorflow (from versions: )
No matching distribution found for tensorflow
```
仕方ないので`pyenv install 3.6.0`でPythonのバージョンをダウングレード。
その後4の手順を無事実行し動作確認まで行きました。

```
 Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
```
このような警告が表示されましたが[macOS で「this TensorFlow binary was not compiled to use: AVX2 FMA」エラー](https://qiita.com/KEINOS/items/4c66eeda4347f8c13abb)の記事にある内容であったため一応一安心。
``b'Hello, TensorFlow!'
``と謎のbが付いたものの一応動作確認できました。
eclipseでテーブルからJPAエンティティを作成する

eclipseでテーブルからJPAエンティティを作成する方法をメモ。

1.エンティティを作成したいプロジェクトを右クリックし、「新規＞テーブルからJPAエンティティ」を選択。

2.「接続の追加」を押下します。
![01.png](https://qiita-image-store.s3.amazonaws.com/0/306544/18df7af8-d0fd-4449-812a-4206e73b0eb4.png)

3.接続プロファイルを作成します。今回はOracleを使用します。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/306544/24c58828-83ce-d944-bdd5-4c83ff34c36c.png)

4.「新規ドライバー定義」を押下します。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/306544/67f28a7f-783e-d4f9-8285-9e54edd8db3f.png)

5.ドライバー・テンプレートを選択します。今回は「その他のドライバー/Oracle/11」を使用します。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/306544/1db301fd-91b6-2317-47c5-67e3bbcfbe68.png)

6.「Jarリスト」タブに移動し、「Jar/Zipの追加」を押下します。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/306544/c32c0beb-2324-4706-b248-076c4fb604ea.png)

7.jarファイルを追加します。

8.「プロパティ」タブに移動し、必要な情報を入力していきます。
このとき、接続URLは「jdbc:oracle:thin:@<host>:1521/<sid>」の形式で指定してください。よく紹介されている形式ではsidの前が「/」ではなく「:」になっているのですが、これだとsidを認識できずにORA-12505エラーになってしまいます。
![06.png](https://qiita-image-store.s3.amazonaws.com/0/306544/69103646-3064-dc4b-019e-84782b25e0db.png)

9.「OK」ボタンを押下して入力を完了させます。新規接続プロファイル画面に戻るので、「接続のテスト」で接続の確認をするのも忘れずに。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/306544/64e5cc0a-eca2-6911-2b86-2df5545ed840.png)

10.「完了」ボタンを押下すると、カスタム・エンティティーの作成画面に戻ります。スキーマとテーブルを指定してください。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/306544/e8eb48ea-3e18-cfb8-aeaa-2e8cdc786cbc.png)

11.「完了」ボタンを押下すると、エンティティクラスが作成されます。
![09.png](https://qiita-image-store.s3.amazonaws.com/0/306544/bf3076cb-9d58-aeef-7114-d11c985be19b.png)
RAK811 Lora ButtonをThe Thing Networkにつなげるよ

RakwirelessのLoraButtonのセッティングです。

マニュアル参照ですが
teraTermなどで接続します。
ビットレート:115200
改行コード受信：Auto
送信：CR-LF
ローカルエコーありにします。

OTAA:
at+mode=0 /* set the module to LoRaWAN work mode */
at+band /* get Region V2.0.2.0+ support */
at+get_config=dev_eui /* get Dev_EUI check,if need can set */
at+set_config=app_eui:xxxxxxxxxxxx/* set the LoRaGateway app_eui,big endian */
at+set_config=app_key:xxxxxxxxxxxxxxxxxx
/* set the LoRaGateway app_key,big endian */
at+set_config=join_mode:1 /* join OTAA type.( the command only Button firmware) */
at+reset=0 /* Reset the module */

一例です。
・バンド設定
at+band=AS923
OKAS923

・at+get_config=dev_eui
を打つと、DevEUIが入手できます。
ex)OKxxxxxxxxxxxx

これをThe Thing Networkに登録します。

![lora-button-2-0.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/cb96bf8f-1a93-f806-6a47-e49d393d5194.jpeg)

Dev EUIに先ほどのOK以降を入力し、Registorします。
![lora-button-2-1-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/19e92f05-8ca7-5b71-b260-e8d07ebe3ead.jpeg)

Application EUIとApplication Keyが出てきます。
赤印を押す事でKeyをコピーできます。
at+set_config=app_eui:xxxxxxxxxxxx/* set the LoRaGateway app_eui,big endian */
at+set_config=app_key:xxxxxxxxxxxxxxxxxx

![lora-button-2-1-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/5c9a9abe-066b-09e1-7af9-70e9cc213c0e.jpeg)

最後に以下を入力します。
at+set_config=join_mode:1
at+reset=0

以下が出てくれば成功です。
![lora-button-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/708cbe9a-2b27-8586-b707-7cc6d0b10b76.jpeg)
[selenium] Pythonで動かすまで


# パッケージインストール

``` sh
$ pip install selenium
```

# ブラウザのドライバをインストール

ドライバをDLしてきて、/usr/local/bin におく。

- chrome: http://chromedriver.chromium.org/
- firefox: https://github.com/mozilla/geckodriver/releases/tag/v0.23.0

# サンプルコード

``` python
#-*- coding: utf-8 -*-                                                                                                                                                                                                                                                          

from selenium import webdriver

def main():
    """                                                                                                                                                                                                                                                                         
    """
    driver = webdriver.Chrome()
    driver.get('https://www.google.co.jp/')
    driver.find_element_by_name('q').send_keys("How to Become a Hacker")
    driver.find_element_by_name('f').submit()
    driver.close()                                                                                                                                                                                                                                                             

    driver = webdriver.Firefox()
    driver.get('https://www.google.co.jp/')
    driver.find_element_by_name('q').send_keys("How to Become a Hacker")
    driver.find_element_by_name('f').submit()
    driver.close()                                                                                                                                                                                                                                                             

if __name__ == '__main__':
    """ entry point                                                                                                                                                                                                                                                             
    """
    main()
```
SPSS Modelerグラフ加工：0件データのカテゴリを追加したい

例えば、下記のようなグラフで、データのない月は度数0として、X軸には全ての月を載せたいとします。
この例の場合は、2015年7月はデータが存在しない(0件データも存在しない)ため、下記のグラフではそもそも「2015年7月」自体がありません。0件としてデータ自体を追加登録する場合もあると思いますが、グラフ上の表示だけ変えたい場合もあると思います。
ここでは、グラフ上の表示だけ変える方法を紹介します。

【Before】
![0件データ1.JPG](https://qiita-image-store.s3.amazonaws.com/0/305774/46707cf2-0b31-21cc-466b-b6751ffeeed2.jpeg)
【After】
![0件データ2.JPG](https://qiita-image-store.s3.amazonaws.com/0/305774/4fb59d28-9037-ca6c-45d0-27bbca858479.jpeg)

1. 「表示」→「編集モード」に変更して、「カテゴリ」にチェックを入れます。
![0件データ3.JPG](https://qiita-image-store.s3.amazonaws.com/0/305774/0f6b0f49-93e3-3478-91ef-a7c94b213124.jpeg)

2. 上記例では日付ではなくて文字列として認識されているので、[「棒グラフの並び順を変えたい」](https://qiita.com/tokamo10/items/11ffdfa8cfb6f41e3dee)の手順で並べ替えます。

3. グラフの左側にカテゴリ編集画面で「＋」をクリックして、新しいカテゴリを追加します。一覧の最後に追加されるので、任意の位置に並べ替えます。
![0件データ4.JPG](https://qiita-image-store.s3.amazonaws.com/0/305774/3a96ffbf-c247-de18-60a3-f9c58ca87a02.jpeg)

4.「表示」→「探索モード」に変更して、更新後のグラフを確認してみると、こんな感じです。
(赤枠の部分に度数なし(0件)の新しいカテゴリが追加されています。)
![0件データ5.jpg](https://qiita-image-store.s3.amazonaws.com/0/305774/198bb787-d233-10b8-6041-0c417f1055fd.jpeg)


## 試した環境

Modeler 18.1.1
Windows 7