OmniAICreator/Qiita-1.07M huggingface dataset:
MetapsAnalyticsの導入


## はじめに
[アイエンター #1 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/i-enter)、22日目の記事を担当しますNecorinです。

Analyticsといえば、Googleくらいしか思いつきませんが、Metaps Analyticsなるものがあるらしい。
案件都合でiOSアプリに導入することになったので備忘録として書き留めておきます。

## 導入方法

### 1. AnalyticsSDKの導入
CocoaPodsに下記内容を記載

```PodFile
pod 'analytics-ios'
```

※ Frameworkを直接追加する方法もありますが割愛します。

### 2. AnalyticsSDKの初期化・計測

```AppDelegate.swift

import UIKit
import AnalyticsSDK

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Analytics Framework の初期設定
        Metaps.initialize("applicationID")

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // 計測の終了
        MetapsAnalytics.stop()
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // 計測の開始
        MetapsAnalytics.start()
    }
}
```

これで導入は終了です。
あとは適当なタイミングで購入処理や独自のイベントを計測することが可能になります。

### 3. デバッグログ表示

```swift
// デバッグログの有効化
MetapsAnalytics.enableLog(true)
```

### 4. 購入イベントの計測

```swift
// 購入処理の計測
MetapsAnalytics.trackPurchase("任意の文字列", price: "金額", currency: "JPY")
```

## まとめ
公式のドキュメントがしっかりしており、かなり簡単に導入することができた。
今度はGoogleAnalyticsを使ってみたいと思う。
SSG

# 残念！さやかちゃんでした！

[Secure Services Gateway](https://www.hs-juniperproducts.jp/security/ssg/)のことではなくて、Static Site Generator(静的サイトジェネレーター)の話をしたいと思います。

# 静的サイトジェネレーターとは
基本的にはMarkdown形式の原稿から静的なHTML/CSS/JSを作成してくれるツールのことを指します。

* PHPやMySQL等を使用しない
    * 動的なページ生成を行わないので速い
    * [さくらのレンタルサーバ ライト](https://www.sakura.ne.jp/lite.html)でも使えますね
* 静的なHTMLなので、WordPressでよくあるセキュリティ上の問題は発生しにくい
    * とはいえレンタルサーバ側をちゃんと管理しないと改ざんされたりするリスクは当然あるので、そこは気をつけましょう

当然ながら、DBが必須になるような、会員限定サイトのようなものやECサイトのようなものを作るのには向いていません。また、基本的にはMarkdownファイルをエディタで編集して静的サイトのファイルを生成するため、WordPressのような動的CMSのようにブラウザ上のエディタで操作したりすることは基本的にはできません。ブラウザ上新着記事や人気記事を出すことは一応できるそうですが、リアルタイム性はWordPressのような動的CMSには劣るわけです。

なので私は静的サイトジェネレーターとWordPressを使い分けて、いくつかのサイトを運営しています。複数人で運営するときや、プラグインを使いたいときや、こまめにブラウザ上で更新したいときはWordPressを使いますね。一方で、一人で運営するとき、ブラウザ上で更新する必要性があまりなく更新頻度もそれほど高くないとき（読み物系のブログサイトなどですね）は、リソースを食わずにセキュアに運営できる静的サイトジェネレーターでサイトを運営しています。

# 静的サイトジェネレーターの種類
いくつか挙げておきます。

* [jekyll](https://jekyllrb.com/)
    * Ruby製。
* [Hugo](https://gohugo.io/)
    * Go製。
* [Hexo](https://hexo.io/)
    * Node.js製。

私はHexoを使っているのでHexoについて書きます。

# Hexoとは
何て読むんですかね……ヘクソ？ヘキソ？アジア圏で人気のある静的サイトジェネレーターだそうです。[テーマ](https://hexo.io/themes/index.html)も中文のものが結構ある気がします。あと[これ](https://blog.shanamaid.top/)、著作権大丈夫なのか。大丈夫じゃないんだろうなぁ……

Hexoを使うようになった理由ですが、周囲にHexoを使っている人が多かったことがありますね。私の周りだとHexoが一番多くて、次はHugoという感じです。

# How to Use Hexo
1台のサーバ上に編集環境とWebサーバをたてている例でご説明します。これがベストだとは思っておらず、できればローカル上に編集環境をつくって、レンタルサーバにアップロードするようにしたいなと思っています。Apache使っているのもたまたまで、Nginx使っているところもあります。まちまちです。

## Install httpd
```bash
$ yum -y install httpd
$ systemctl start httpd
$ systemctl enable httpd
$ firewall-cmd --add-service=http --permanent
$ firewall-cmd --add-service=https --permanent
$ firewall-cmd --reload
$ curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
$ chmod 700 /usr/bin/certbot-auto
$ certbot-auto certonly --webroot -w /var/www/html -d example.com --email hogehoge@fugagfuga.com
$ vi /etc/httpd/conf.d/ssl.conf
$ systemctl reload httpd
```

## Install Hexo
インストールはほんとこれだけ。

```bash
yum install nodejs
npm install -g hexo
```

## Use Hexo
まず最初にサイトのひな形を作ります。コマンドは `hexo new` です。以下の例ですと `/usr/local/src/newsite` というディレクトリが作成されます。

```bash
cd /usr/local/src/
hexo init newsite
```

新しいページの作成は `hexo new` です。 `/usr/local/src/newsite/source/_posts/` の配下に.mdファイルが生成されています。

```bash
$ cd newsite
$ hexo new newentry
$ vi /usr/local/src/newsite/source/_posts/newentry.md
```

`hexo gen` で、HTML/CSS/JS等を生成します。生成されたファイルは `/usr/local/src/newsite/public` にあります。これをWebサーバのドキュメントルートにコピーすると更新完了です。

```bash
$ cp -R public/* /var/www/html/
```

また、 `hexo gen` する前に `hexo server` とすると、ファイル生成前に https://example.jp:4000 でテストサイトを見て確認することができます。
【小技】DockerのTensorFlowイメージに日本語環境を導入する。

##はじめに
日本語の文書分類タスクをDockerのTensorFlowイメージを用いて学習、評価、予測を行いたかったのですが、pullしたてのそのままじゃ日本語使えなかったよ〜って話です。

##TensorFlow with Docker
TensorFlowやKerasを手軽に試したいときの選択肢として、
Dockerイメージを利用する方法が挙げられます。
Docker Hubには[TensorFlow公式のイメージ](https://hub.docker.com/r/tensorflow/tensorflow)があるので、使わない手はありません。

```bash
$ docker pull tensorflow/tensorflow:latest-py3
```

　Python3系が使いたかったので、タグに`latest-py3`を指定しています。

```bash
$ docker run --rm tensorflow/tensorflow:latest-py3 python -V
Python 3.5.2
```

バッチリですね。
ところが、

```bash
$ docker run --rm tensorflow/tensorflow:latest-py3 python -c "print('ほげ')"
Unable to decode the command from the command line:
UnicodeEncodeError: 'utf-8' codec can't encode character '\udce3' in position 7: surrogates not allowed
```
pullしたてのイメージでは、日本語を取り扱うことが出来ないようです。

ここでイメージのlocaleを確認しましょう。

```bash
$ docker run --rm tensorflow/tensorflow:latest-py3 locale -a
C
C.UTF-8
POSIX
```
なるほど確かに日本語環境を導入する必要がありそうです。

##日本語ナイズなDockerイメージを作る。

冒頭でpullしたイメージをもとに、日本語使用可能なイメージをビルドしましょう。

```:Dockerfile
FROM tensorflow/tensorflow:latest-py3
ENV LANG ja_JP.UTF-8

RUN apt-get update \
    && apt-get install language-pack-ja-base language-pack-ja -y

CMD ["/run_jupyter.sh", "--allow-root"]
```

こちらのDockerfileをビルドしましょう！

```bash
$ docker build -t tf-jp .
```

pull直後のイメージでは失敗した`python -c "print('ほげ')"`を日本語ナイズされたイメージで再び実行してみます。

```bash
$ docker run --rm tf-jp python -c "print('ほげ')"
ほげ
```

お疲れ様でした！！
無事tensorflowコンテナで日本語が扱えるようになりました。

##終わりに
そもそもの動機は日本語の文書をCNNで分類させたかったということでした。
最近はDockerにどっぷりなのですが、今回のように公式イメージに日本語環境が入っていないことが結構あったのでまとめてみました。
閲覧ありがとうございました！
GitHubでブランチの切り替えで躓いた点：メモ用

チーム開発でGitHub利用するにあたり今回自分が躓いた点を説明していきます。

そもそもGitとは
変更履歴を記録・追跡するための分散型バージョン管理システム
過去のある状態に戻したりもできる

ここではローカルとリモートの関係を元にコマンドの内容を見ていきます
`git clone`
リポジトリの複製
リモートからローカルへcloneする場合は
GitHub上のcloneしたいページからssh URLをコピーしてターミナル上で実行する
`git clone <<URL>>`

`git push`
ローカルからリモートへpushする場合
`git push orign <branch名> `
この時pushしたいbranchにいるかは
`git branch -a `
で確認すると良い

`git pull`
`git pull remote名 branch名 `
リモートリポジトリの履歴を取得することができる

`git merge`
branchAからbranchBに更新内容を取り込むこと。
`git branch -a`
でbranchBにいることを確認
`git merge branchA `

`branch`
開発場所の複製、branchを作成する(切る)ことにより複数に作業が並行して行うことができる。

`Pull request`
branchを作成し変更点を実装したあと編集リクエスト(他人に確認してもらう)をお願いすること。
また確認をお願いされた者が変更点が問題ないことを確認し元のブランチに戻す(反映)ことをmerge(マージ)という。

自分が躓いた点

内容：
masterから develop branchを作成し
developからクラスごとに新たに3つのbranchを作成
feature/classA
feature/classB
feature/classC
feature/classAで実装を終えremote上でgit developへpushしpullrequestしmergeしたのち
feature/classBへbranchを変更し実装をしたがfeature/classB、feature/classAで実装した内容が消えていた。

理由：
ローカルのdevelop branchにリモートの最新版のdevelopを取得していなかった。

解決方法：
develop branchの状態で
git pull origin developとリモートの最新版を取得する。
そののちfeature/classBの状態で
git merge  developとする
feature/classBも更新することで機能の作業が終わったら作業内容の差分がdevelop branchへ取り込まれるため。
また最新のdevelop branchを追随しておくことで他のfeature branchで実装したファイルも確認できる。

自分が今どこの状態までコミット、マージしたのかわからなくなった場合
`git log`
で直近のコミットやマージ内容も確認できる。
参考にした記事
https://backlog.com/ja/git-tutorial/intro/intro1_1.html
https://qiita.com/KosukeSone/items/514dd24828b485c69a05 （編集済み）
Processingでシンメトリー

#はじめに
Processing Advent Calendar 2018 の記事です。

#実行結果
![test.gif](https://qiita-image-store.s3.amazonaws.com/0/205129/3dfe0a62-e92d-2a79-440b-1dc306ea71cf.gif)
　　　　　　　　　↓
![test2.gif](https://qiita-image-store.s3.amazonaws.com/0/205129/764b1937-5562-ab40-fba3-a3fbfbac0f7d.gif)



#コード
```java
PImage img;
void setup() {
  size(400, 400);
}

void draw() {

  stroke(random(115), random(115), random(115), 40);
  fill(random(155)+100, random(155)+100, random(155)+100, 40);
  rect( random(0, width), random(0, width), random(0, width), 
    random(0, width) );
  symmetry();
}

void symmetry() {

  if (mousePressed) {
    save("test.gif");// 現在のスケッチを保存 
    int j = 0;       // 現在の列
    int w = width/2; // 真ん中  
    int n = w + 1  ; // 次の段へ
    int d = 1;       // シンメトリーにする場所を計算するのに使う

    background(255);
    img = loadImage("test.gif");
    image(img, 0, 0);
    strokeWeight(1.2); //1.2より値が小さいと、透ける
    loadPixels();

    for (int i=0; i<width*height; i++) { 
      if (i<w+(width*j)) {
        color cp = img.pixels[i];
        stroke(cp);
        point(width-d, j);
        d++;
      } else {
        i+=w;
        d=1;
        j++;
      }
    }    
    noLoop();
    save("test2.gif");
  }
}
```
#解説

[pixelsのリファレンス](https://processing.org/reference/PImage_pixels.html)

画像は↓テーブルのような順番で、pixels[]の配列にcolorが格納される。
シンメトリーにしたいので。

|1  |2  |3  |4  |
|---|---|---|---|
|5  |6  |7  |8  |
|9  |10  |11  |12|
|13   |14   |15   | 16 |

　　　　↓

|1  |2  |2  |1  |
|---|---|---|---|
|5  |6  |6  |5  |
|9  |10  |10 |9|
|13   |14   |14   | 13 |
こんな風にpoint()で、色を上書きする。

#おわりに
良いお年をお迎えくださいませ。
Auto Layoutデバッグ問題集（１）

Auto Layout エラー / ワーニングが発生しているレイアウトを、問題編と解答編に分けて説明する記事になります。問題集ということで、継続して書く気持ちはあります。

今回の内容に関連して、過去にこのような記事も書いています。

[Auto Layoutのワーニング解読には「WTF?」が便利](https://qiita.com/akatsuki174/items/ccf394c03677ac62191e)
[AutoLayoutのデバッグをする（1）](https://qiita.com/akatsuki174/items/6935bb6ff64f4df51c5a)
[Auto Layoutのデバッグに役立つメソッド/プロパティ集](https://qiita.com/akatsuki174/items/550f885c002fb881674c)
[デバッグのためにView階層を把握する](https://qiita.com/akatsuki174/items/45d4bd7cb150defbf116)
[Debugging your layout ([WWDC2015] Mysteries of Auto Layout, Part 2より)](https://qiita.com/akatsuki174/items/66c6a92ab52b458f5414)

# GitHub

以下の Git リポジトリに問題となっているコードを置いています。 question ブランチに切り替えると、エラー / ワーニングが発生している状態のプロジェクトをいじることができます。今回の対象は「Priority View」という画面です。
https://github.com/akatsuki174/AutoLayoutDebugSample

# 問題編

こんなレイアウトを作りたいとします。

* 両端に20のマージン
* text field と button の間隔は10
* button の横幅は文字サイズぴったり
* 残りの横幅は text field で埋める

<img width="324" src="https://qiita-image-store.s3.amazonaws.com/0/100736/39aa91c3-12d2-8f2f-2f8f-412ef3c2ce0c.png">

しかし上記の条件に素直に従って Storyboard 上で制約を付けるとこのようにエラーが発生し…
<img width="324" src="https://qiita-image-store.s3.amazonaws.com/0/100736/23900bda-f166-1475-3ca6-e9de5d16acd8.png">

構わず実行してみると text field が潰れてしまっています。

<img width="324" src="https://qiita-image-store.s3.amazonaws.com/0/100736/1069eb88-7c88-a42c-d961-9b3636a5c7f7.png">

さてどうすればいいでしょうか？

# 解答編

まずは Storyboard 上でどのようなエラーが出ているのかを見てみます。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/100736/1fcd5255-3532-a6bb-0b12-dfea60bb476c.png">
horizontal hugging priority が云々と出ています。ここで hugging priority の説明をします。

---

**Content Hugging Priority**

* 大きくなりにくさ / コンテンツに沿う優先度 を表す
* Hug = 沿って進むという意味
* この値が小さいと他の制約に影響されて大きくなりやすくなる
* 固有サイズより大きなサイズが指定されたときに使われる

Xcode上だとここにあります。
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/100736/4de95128-db7d-88ea-0d78-934117310e22.png">

---

ここで text field, button の Content Hugging Priority を確認すると、どちらも250でした。制約の優先度をわざと低くしない限りはコンテンツの大きさにかかわらず制約が優先されるということもあり、このようになってしまうことがあります。

---

もう一度今回やりたかったことをおさらいすると、

* text feild はできるだけ広く幅を取りたい
* button は最低限の幅が取れていればいい

ということだったので、buttonのハグする力を高めてあげれば良いことになります。ということで button の Content Hugging Priority を 251 に上げます。
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/100736/769733b2-0ebb-47c8-8aeb-709e418da652.png">

これで期待通りのレイアウトを作ることができました🎉
<img width="324" src="https://qiita-image-store.s3.amazonaws.com/0/100736/d0cad62e-527c-58fd-f373-d7c778117cc4.png">
Angularプロジェクトを実機で見たい

Angular CLI で開発中のものをスマホで確認したく、
色々調べてみたが、なかなかうまくいかなかったので備忘録。

`ng serve` 時にIPを指定すれば良いそう。

# 手順
1. PCとスマホを同じネットワークに接続

2. IPを指定して `ng serve`

```
$ ng serve --host <PCのIPアドレス>
```

# 確認
実機のブラウザから `http://<PCのIPアドレス>:<ポート>` に接続
【深層学習】AIにブレイクダンスの動きを識別させてみた【行動認識】

タイトル通りですが、ブレイクダンスのモーションセンサーデータを深層学習させたAIにリアルタイムでダンサーの動きを認識させてみました。
まずは動画をご覧ください。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/fN873xzIX9s/0.jpg)](http://www.youtube.com/watch?v=fN873xzIX9s)
内容はモーションセンサーが内蔵された靴型のウェアラブルデバイス [Orphe](https://orphe.shoes) を用いた、ブレイクダンスの基本的な技やステップの分類&ウィンドミルの熟達度評価となっています。
※こちらの記事はAI活用事例のご紹介なので技術的な内容は控えめにしています。
#ざっくり仕組みをご紹介
![20181014174949.jpg](https://qiita-image-store.s3.amazonaws.com/0/218869/6128aae5-a51f-05fa-b857-297ae47838e1.jpeg)
Orpheから得られたセンサーデータが記録されたCSVから加速度を行列データとして抽出し、CNN（畳み込みニューラルネットワーク）で構築したモデルに深層学習（Deep Learning）させます。学習データは動作別にラベル分けされており、クラス分類の手法を用いています。

![20181014175006.jpg](https://qiita-image-store.s3.amazonaws.com/0/218869/ae73f898-e9de-330a-f46d-199a7d3dbe4e.jpeg)
そして、[OrpheのセンサーデータをBLEで受信してくれるアプリ](https://sites.google.com/view/orphe-developers/hub-app)に学習済みモデルを組み込んで、靴の着用者の動作をリアルタイムで認識するというシステムです。
モデルは[Keras](https://keras.io/ja/)上で学習させたものを[coremltools](https://github.com/apple/coremltools)を使ってSwiftで組み込めるように変換しています。
さらに認識結果を良さげにビジュアライズするために[openFrameworks](https://openframeworks.cc/ja/)を使っていたりします。
TensorFlowで学習させたモデルをC++用に変換してoFアプリに直接組み込むみたいなこともやったりしたんですが、昔のことでよく覚えていないので気が向いたら記事にします。
#感想とか
ご察しの通りデータ収集が死ぬほど大変です、文字通り血と汗と涙の結晶となっています！
もちろん学習手法やモデルの構造、ハイパーパラメーターの調整も大切なんですが、やはり質の良いデータをいかに効率よく大量に集められるかが機械学習の鍵になってきますね。

今回の[元記事](http://hahaeatora.hateblo.jp/entry/2018/10/14/183000)は過去に自分のブログに載せたりしたんですが、AIで面白いことやってみたいという技術者の方やダンサーだけどテックにも興味あります！って人にもっと読んで欲しいなあということで、Qiitaにも少し加筆・修正して載せてみました。

良かったらこちらもチェックしてみてください（大半が中身の無い記事ですが……）。
http://hahaeatora.hateblo.jp

Dance AI English Info
https://link.medium.com/5QGCJgcDUX

スマホでもダンスAI
[【CoreML】iPhoneのセンサーデータを機械学習させてロックダンスの動きを識別してみた](https://qiita.com/FollowTheDarkside/items/e4b1dbb689101c882610)
GUIのみでGitHubにプライベートリポジトリを作る

#はじめに
GitHubが無料でプライベートリポジトリを作れるようになったのでやってみました。
今回はターミナルを使わずにPushまでやります。
#環境
GitHub Freeプラン
macOS Mojave 10.14.2
GitHub Desktop 1.5.1

#リポジトリを作る
"Create New Repository"を押す。
<img width="960" alt="スクリーンショット 2019-01-10 22.46.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/340416/298936d4-9a27-3b71-72fa-ed088efd0fc8.png">

<img width="500" alt="スクリーンショット 2019-01-10 22.52.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/340416/073242ed-dcac-534f-da10-4994d66fab6f.png">

#コミットする
<img width="960" alt="スクリーンショット 2019-01-10 23.06.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/340416/d3215729-4f5a-2447-4a5a-c6b638dadb49.png">


#プッシュする
"Keep this code private"にチェックを入れるとプライベートになる。
<img width="520" alt="スクリーンショット 2019-01-10 23.12.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/340416/337ea30e-7173-d5af-69ba-3ef546809052.png">
オーバーライドとオーバーロードの違いが一目でわかる絵を描いた

よくオーバーライドとオーバーロードを間違えます。
名前は似ているが、全然別の概念ですね。
けれど何度定義を読み返しても、混同してしまいます。
あまりにも間違えるので、絵を描きました。
![ink-image.png](https://qiita-image-store.s3.amazonaws.com/0/333454/bd8948ac-4388-67ce-d962-a7e7a03763e1.png)

# オーバーライド（override）
> オブジェクト指向プログラミングにおいてオーバーライド (override) とは、スーパークラスで定義されたメソッドをサブクラスで定義し直し、動作を上書き（変更）することである。

つまり、オーバーライドする目的は、継承したサブクラスにおいて、スーパークラスのメソッドに処理を追加することです。
メソッドの型、及び引数の数や型は基本的には変えられません。

# オーバーロード（overload）
> 多重定義 (たじゅうていぎ) あるいは オーバーロード (英: overload) とは、プログラミング言語において同一の名前（シンボル）を持つ関数あるいはメソッドおよび同一の演算子記号について複数定義し、利用時にプログラムの文脈に応じて選択することで複数の動作を行わせる仕組みである。 

こちらは、基本的には同一クラスでの話。
メソッド名は同じだが、メソッドの型や引数の数や型も変えるし、処理も変えるという場合に使う。
目的としては、あるメソッドでインプットの種類によって処理や戻り値も変えるが、
メソッドとしては同じことなんだよなあ……という場合に使う。
[OpenCV]画像全体を赤くする

OpenCV for Unityで死神の目を作った際（[記事はこちら](https://qiita.com/takaya901/items/9f4c87a3d51ea019520f)）に，雰囲気を出すために画像全体を赤くしたいと思いました．

C#で書いていますが，どの言語でも同じ処理でできると思います．

```cs
Mat ConvertToRed(Mat rgba)  //RGBでも同じ
{
    var channels = new List<Mat>();
    var zeroMat = new Mat(new Size(rgba.width(), rgba.height()), CV_8UC1, new Scalar(0));
    var redMat = new Mat();

    split(rgba, channels);      //チャンネルごとに分離
    channels[1] = zeroMat;	    //GとBチャンネルの全画素を0で置き換える
    channels[2] = zeroMat;
    merge(channels, redMat);    //マージしてRGBA画像に戻す
    return redMat;
}
```

zeroMatで置き換えるチャンネルを変えればいろんな色に変換できます．
ksnctf 18 USB flash drive 80pt

#問題

https://ksnctf.sweetduet.info/problem/18

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/f11080da-c25c-2728-8bab-dd86834d1998.png)

#解いてみた

zipをダウンロードします。
解凍するとイメージが入ってました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/318618cc-3845-2a38-dde6-d646b2b96ff5.png)

FTKimagerで見てみますか。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/ffc165b1-982f-005a-f527-d85b8c20881e.png)

画像ファイルがいくつか入ってまして、1つだけ削除データになってたので怪しいです。
と思ったら下の方にこのファイルにflagがあります的なことが書いてある。
ダウンロードしてバイナリエディタ見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/4b5f5dd0-6b2e-c39e-e3b4-1753951d7b06.png)

検索してみましたが「FLAG_」から始まる文字列はありませんでした。
Exif情報か？
Exif確認君（http://exif-check.org/ ）で調べました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/8cd2af36-2888-0164-2bde-fb7fb8f413df.png)

なし。
もう一度イメージに戻ります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/e82dcf20-dedf-719a-6e1d-a5108e9e207f.png)

ADSあった。
00から06までつなげるとflagになってました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/e9eec763-03c2-43be-d227-9a3f9112baf4.png)

いまさらながら常設CTFはフラグあまり書かない方が良い気がしてきたので、これからは黒塗りで。。。
UnityとARkit(Blendshape)を使ったアプリ　Scene遷移ができない

先に言うと、初心者です。

今回、UnityとARkitを使ったアプリを作っているのですが、
そのアプリの仕様でSceneの切り替えがどうしても発生してしまします。

自分からは
     UnityEngine.SceneManagement.SceneManager.LoadScene("FaceBlendshapeScene 1");

等の遷移ようのコードしか打っておらず、残りは全てSDKpluginに入っている、Exsanple
「FaceBlendshapeScene」の上にシーン遷移用のボタンを配置し動かすのみです。

Unity上ではARkitを起動していないのもあって、落ちたりエラーが発生することはないが、iPhoneXsにビルドしていざメイン画面→ARkitを使用したsceneへ遷移
無事にフェイストラッキングを楽しんだ後、メイン画面に戻るボタンを押すとどうしても落ちてしまいます。

Xcode上だと
  UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
でとまってしまう。

UnityとARkitを使ったsneneの遷移を取り入れたアプリってあったっけ？という状態で、仕様なのかな？と思ってしまってます。

もし、アドバイス等ありましてら教えていただきたいです！
BitbucketのプライベートリポジトリをGithubに移行する

Githubが無料ユーザーでもプライベートリポジトリが無制限に利用できるようになったので移行手順の備忘録。

1. https://github.com/new/import にアクセス
1. Githubに移行したいBitbucketのプロジェクトのURLを入力(https://bitbucket.org/<ユーザー名>/<リポジトリ名>)
1. インポート先のGithubリポジトリ名とリポジトリの公開、非公開を指定
1. プライベートリポジトリの場合、認証情報を聞かれるのでBitbucketのログイン情報を入力する
1. 移行が始まる（ちょっと時間がかかるので気長に待つ）

これだけ。空のプライベートリポジトリを用意してgitコマンド使って移行する方が時間的には早いと思うけど設定してほったらかしておけばそのうち終わるので片手間で移行したい場合に利用。
NETATMOが送信した温度/湿度/二酸化炭素濃度をAPIで取得する

[前回](https://qiita.com/ikemura23/items/8af757dc818d6c2b7cd0)は認証トークンを取得する事ができた。

今回は会社に設置してあるNETATMOが送信したWeather Stationsデータの **温度、湿度、二酸化炭素濃度** を取得する。

## 使用するNETATMO API
`getstationsdata` APIを使ってみる

https://dev.netatmo.com/en-US/resources/technical/reference/weather/getstationsdata

## コード

前回のトークン取得コードを改造して、値を取得してみた

```js
const axios = require('axios')
const qs = require('qs')

const axiosClient = axios.create({
  baseURL: 'https://api.netatmo.com',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

/**
 * トークン取得
 */
function getAccessToken() {
  const auth = {
    client_id: 'xxx',
    client_secret: 'xxxxx',
    username: 'xxx',
    password: 'xxxx',
    grant_type: 'password'
  }
  return axiosClient
    .post('/oauth2/token', qs.stringify(auth))
    .then(respons => {
      console.log('Post token Success')
      console.log(respons.data)
      return respons.data.access_token
    })
    .catch(error => {
      console.log('Post token Fail')
      console.log(error.response.config)
      console.log(error.response.data)
    })
}

/**
 * ステーションデータ取得
 */
function getStationsData(token) {
  const param = {
    access_token: token
  }
  return axiosClient
    .post('api/getstationsdata', qs.stringify(param))
    .then(respons => {
      console.log('Post getstationsdata Success')
      console.log(respons.data)
      return respons
    })
    .catch(error => {
      console.log('Post getstationsdata Fail')
      console.log(error.response.config)
      console.log(error.response.data)
    })
}

// 取得開始
getAccessToken()
  .then(token => getStationsData(token))
  .then(station => console.log(station.data.body.devices[0].dashboard_data))

```

かなりのレスポンス量が返ってくるが、今回欲しいのは`dashboard_data`の中にある。

## 温度/湿度/二酸化炭素濃度を得る

dashboardの中身

```
{ time_utc: 1547127010,
  Temperature: 23.3,
  CO2: 688,
  Humidity: 28,
  Noise: 46,
  Pressure: 1004.5,
  AbsolutePressure: 1004.5,
  min_temp: 16.6,
  max_temp: 24.9,
  date_min_temp: 1547073639,
  date_max_temp: 1547113757,
  temp_trend: 'stable',
  pressure_trend: 'down' }
```

現在の会社は、

- 温度は`Temperature`で`23℃`
- 湿度は`Humidity`で`28％`
- 二酸化炭素濃度は`CO2`で`688`

寒くて湿度が低すぎるが、二酸化炭素濃度はいい感じのようだ。
この記事を書いてる時間は夜だし誰もいないし当然か…

## 最後に
とりあえず欲しいデータは取得する事ができた。

あとはSlackに通知したり、スマートスピーカーから取得できるよう色々作っていきたい。

## 参考
API Reference Getstationsdata
https://dev.netatmo.com/resources/technical/reference/weather/getstationsdata
PHP: iterable型はiterator_to_array()に渡しちゃいけない

PHPには[iterable]型という疑似型があり、`array`や`Traversable`がこの型と互換している。`iterable`型は「`foreach`で回せるもの」を指す型と考えて良い。

例えば、次のように戻り値に`iterable`の型を宣言すると、配列を返しても`Traversable`を返すことになるジェネレーター構文(`yield`)を使ってもどちらでも構わないことになる。

```php
interface FileList {
    public function getList(): iterable;
}

final class ArrayFileList implements FileList {
    public function getList(): iterable {
        return ['a.php', 'b.php', 'c.php'];
    }
}

final class GeneratorFileList implements FileList {
    public function getList(): iterable {
       yield 'a.php';
       yield 'b.php';
       yield 'c.php';
    }
}
```

## iterator_to_array関数はイテレータを配列に変換する

PHPには[iterator_to_array]関数がある。これは「イテレータを配列にコピーする」関数だ。第一引数に「コピーしたいイテレータ」を渡すと、配列に変換して返してくれる。

```php
$files = (new GeneratorFileList)->getList();
assert($files instanceof Generator);
assert(iterator_to_array($files) === ['a.php', 'b.php', 'c.php']);
```

## iterator_to_array関数に`iterable`型は渡さないほうがいい

この[iterator_to_array]には注意点がある。**`iterable`型は渡さないほうがいい**という点だ。公式マニュアルをよく読むと分かるが、`iterator_to_array`の第一引数の型は`Traversable`でなければならないからだ。

<img width="850" alt="Screenshot_2019_01_10_22_45.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/7a2fe3bb-5740-02ed-ccd7-dc4089948390.png">

この関数の説明には「イテレータを配列にコピーする」と書いてあるので、一見すると`foreach`でイテレートできるものなら何でもいけそうな気がしてくるが、そこはドキュメントをちゃんと読まねばならない。`Traversable`は`iterable`だが、その逆の`iterable`は`Traversable`ではないし、`Iterator`でもない。この場合**`iterable`と`Iterator`は名前が似ているが別ものと考えたほうがいい**。

したがって、次のコードのように配列の`iterable`型の値を渡すと、「TypeError: Argument 1 passed to iterator_to_array() must implement interface Traversable, array given」というエラーが発生する。

```php
$files = (new ArrayFileList)->getList();
assert(is_array($files));
iterator_to_array($files); // TypeError
```

## iterable型をarray型に変換する方法

PHPには残念ながら、`iterable`を`array`に変換する関数が無いので、次のような関数を自作する必要がある。

```php
function iterable_to_array(iterable $iterable): array
{
    $array = [];
    \array_push($array, ...$iterable);
    return $array;
}
```

この実装であれば、`array`の`iterable`型を渡した場合でも、`iterable`型を配列に変換することができる。

```php
$files = (new ArrayFileList)->getList();
assert(is_array($files));
assert(iterable_to_array($files) === ['a.php', 'b.php', 'c.php']);
```

本稿で取り上げた、`iterator_to_array`の実験コードは[GitHub](https://github.com/suin/php-playground/tree/master/IterableToArray)で公開しているので、試したい方はご覧ください。


[iterable]: http://php.net/manual/ja/language.types.iterable.php
[iterator_to_array]: http://php.net/manual/ja/function.iterator-to-array.php
1000円/年で証明書が買えたのでgitlabをssl化してみた

## ことのほったん
常時SSL化の時流でSafariが「このWebサイトは安全ではありません」と警告する。
「ボクはわるいGitLabじゃないよ」と言いたいけどSafariは聞く耳を持たない。かなしい。
ひっそりこっそり使っているので正直わざわざSSL化する必要性はあまりなかったけど、[1000円/年でドメイン認証型SSL証明書を発行][sakura]してもらえると知った。
.jpドメインを管理しているJPRSが発行しているらしいので多少安心感がある。（さくらインターネッツのことはよく知らない）

ということでGitLabのコミュニティ版をDV型SSL化した話。
状況は[^元々]
+ GitLab 10.6.4
+ Apache 2.4.7
+ JPRSのSSL証明書（をさくらインターネットで利用）

[sakura]: https://ssl.sakura.ad.jp/jprs/
[^元々]: 元から別の独自ドメインを持っていてウェブサイトをApacheで垂れ流していたので、サブドメインにGitLabをリバースプロキシでアクセスさせていた。それは、[gitlab-apache24.conf](https://gitlab.com/gitlab-org/gitlab-recipes/blob/master/web-server/apache/gitlab-apache24.conf) を拾ってきて適当に編集してApacheのconf-enabled/に入れて、適当なプラグインを有効にしてrestartさせればよかった。

基本的な流れは
1. opensslを使って.keyファイルと.csrファイルを作る
2. さくらインターネットに申し込み[^CA]
3. さくらイにSSL化したいドメインが自分のものだと示す
4. CAから.crtファイルを受け取る
5. 中間CA証明書をJPRSから拾ってくる(.pemファイル)
6. 4と5で得た.crtと.pem、1で作った.keyをサーバの置いて認識させる
7. Hello, 常時SSL＼(^o^)／

## 1. opensslを使って.keyファイルと.csrファイルを作る
https://knowledge.digicert.com/ja/jp/solution/SO23384.html でも参考にして .keyファイルと .csrファイルを生成する。

## 2,3 さくらインターネットとあれこれ
[さくらインターネットのページ][sakura]で、ドメイン認証型の申し込みページからアカウント作って支払いを済ませる。

「申請受け付けるよ」メールが来るので、メールにあるリンクから認識文字列の書かれた.txtファイルをダウンロードして、GitLabのドメイン下に置く。

## 4. CAから.crtファイルを受け取る
「JPRS SSLサーバ証明書発行のお知らせ」というメールが来るはずなので、そこにある「SSLサーバ証明書 ご利用開始までの手順」の通りにする。

## 5. JPRSのサイトから中間CA証明書を取得する
https://jprs.jp/pubcert/service/certificate/ から取得する。

## 6. ApacheとGitLabの設定
今回は、[gitlab-ssl-apache24.conf](https://gitlab.com/gitlab-org/gitlab-recipes/blob/master/web-server/apache/gitlab-ssl-apache24.conf) を拾ってきて、

```gitlab-ssl-apache24.conf
35  SSLCertificateFile /etc/httpd/ssl.crt/YOUR_SERVER_FQDN.crt
36  SSLCertificateKeyFile /etc/httpd/ssl.key/YOUR_SERVER_FQDN.key
37  SSLCACertificateFile /etc/httpd/ssl.crt/your-ca.cer

```
上の
35 に 4.で手に入れた.crtを指定
36 に 1.で作った.keyを指定
37 に 5.で拾ってきたJPRSの中間CA証明書を指定

```gitlab.rb 
external_url 'https://gitlab.hoge.jp/'
```
とhttpsを指定する。

## 参考
https://qiita.com/rocca0504/items/988cefb7bbc1b92d8118
https://docs.gitlab.com/omnibus/settings/ssl.html
【HTMLからstyleタグでCSSを指定できるし、多くの要素を詰め込める】

【HTMLからstyleタグでCSSを指定するとき、いっぺんに詰め込める】

```
 <h2 style="width: 90%; margin: 0 auto; text-align: left;">今日やったこと</h2>
```
こんな感じでここでは3つの要素（width, margin, text-aligin）が入っている
最終的にもっといれた

```
 <h3 style="width: 90%; margin: 0 auto; text-align: left; padding: 0px;">今日やったこと</h3>
```
Go の json.Unmarshal の罠

実際に仕事でミスった話。

まあまずはソースコード。

```go:go
package main

import (
	"encoding/json"
	"fmt"
)

type hoge struct {
	m map[string]interface{}
}

func (h *hoge) load(text string) error {
	var bytes = []byte(text)
	return json.Unmarshal(bytes, &h.m)

}

func main() {
	h := hoge{}

	h.load(`{"foo":"bar"}`)
	fmt.Println(h) //=> {map[foo:bar]}

	h.load(`{"baz":"qux"}`)
	fmt.Println(h) //=> {map[foo:bar baz:qux]}
}
```

上記のとおり。

要するに。
空っぽじゃない map を `json.Unmarshal` に渡すと、もともと入っていた値は消されずに残る。
[ドキュメント]( https://golang.org/pkg/encoding/json/#Unmarshal )にもそう書いてある。

まあ、オブジェクトを使いまわしたのが敗因だね。
毎回ちゃんと綺麗な体で仕事に当たろうというのが今回の教訓かな。
MySQLの基本SQL文(挿入、取得、更新、削除)


よく使うけどたまに頭から抜けてしまうので記載。

### 挿入(insert文)

```SQL
insert into [table_name] (column1, column2, ...) values (value1, value2, ...);
```
または

```SQL
insert into [table_name] values (value1, value2, ...);
```

### 取得(select文)

```SQL
select * from [table_name] where 条件式(xxx = xxx);
```

個別カラム取得の場合

```SQL
select column1 from [table_name] where 条件式(xxx = xxx);
```

### 更新(update文)

```SQL
update [table_name] set column1 = value1 where 条件式(xxx = xxx);
```

### 削除(delete文)

```SQL
delete from [table_name] where 条件式(xxx = xxx);
```
または(truncate)

```SQL
truncate table [table_name];
```
[ESP32] GPSで自分の位置を確認する。その１

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137182/e8a11dcf-feb1-84eb-d277-285bf23d5ac2.png)

## ESP32 

![20190110_214458.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/03ad0a7b-2705-5a8f-8f1d-d9f4422e06c4.jpeg)

## GPS

![20190110_214522.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/55e05c3d-cff0-3801-6300-c9a8be11839e.jpeg)


## Code

```c++:gps101.ino
HardwareSerial gps(2);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Start GPS... ");
  gps.begin(9600, SERIAL_8N1);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (gps.available())
  {
    Serial.write(gps.read());
  }

}


```


## 結果

![Inkedgps_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/137182/b83db125-ffc3-4d60-6418-0143b495ad66.jpeg)


HardwareSerial の０が動かなかったので、2番目のUARTを使って
moduleと通信した。

Serial０でリセットボタン押しているとGPS　moduleと通信できた。
Serial0はESP32で基本のUARTポートで、GPIO１と３になり、GPIO１はTX３はRXである。

後はトラッカーも作ってみようと、
Microsoft SQL Serverの認証モード切替をコマンドラインから行う方法(Windows版)

# はじめに

Microsoft SQL Server(以後MSSQL)のインストール初期段階で、認証方式を選択する所がある。
この認証方式を、インストールされた後から切り替えたい場合についての手順を書いておく。

# 認証方式について(Windows)

Linux版は未確認だが、Windows版のMS SQL Serverには、ログインユーザーの認証方式は以下のものがある。

* SQL認証
    * MSSQL自身が認証用データベースを持ち、ログイン管理する方式
    * PostgreSQLでいう所のpostgresにあたるsaアカウントもこれに含まれる
* Windows認証
    * MSSQLからシステム(この場合Windowsユーザー)にユーザーの正当性を認証依頼を出す方式
    * AD等との連携が可能
    * C#のMSSQL接続情報で`IntegratedSecurity=true`にするとこちらが使用される
    * PostgreSQLでいう所のpeerに近いかもしれない

問題は、**デフォルトでSQL認証は無効となっている**点である。なお、Windows認証を無効にする方法は不明。
このため、SQL認証が前提のシステムだと、ログインができなくなる(エラーコード18456)。
そのため、うっかりSQL認証を無効にしてインストールしてしまった場合、これを切り替える必要が出てくる。

# インストール後の切り替え方法

基本的に [MS公式の"サーバー認証モードの変更"](https://docs.microsoft.com/ja-jp/sql/database-engine/configure-windows/change-server-authentication-mode?view=sql-server-2017) というドキュメントに従えば問題ない。
だが、リンク先の方法だとどうしてもSSMSでサーバーオプションを切り替える必要がある。
サーバーの制約でSSMSを使用できない場合、この方法は使えない

では、どうすればいいかというと下記のようにする

1. レジストリを以下のように書き換える
    * キー: `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[インスタンスID]\MSSQLServer`
        * `[インスタンスID]` については [公式ドキュメントでいう所の`MSSQL{nn}.[インスタンス名]`がそれにあたる](https://docs.microsoft.com/en-us/sql/sql-server/install/file-locations-for-default-and-named-instances-of-sql-server?view=sql-server-ver15) 
    * 値名: LoginMode
    * 値: 2(Windows認証のみにする場合は1)
2. SQL Serverサービスを再起動する
3. 必要ならば、SQLCMDを使い、`alter login [ユーザー名] enable`でログインユーザーを有効にする
4. 必要ならば、SQLCMDを使い、`alter login [ユーザー名] with PASSWORD='[パスワード]'`でパスワードを設定する
# プログラミング練習ルール

# プログラミング練習ルール
- masterにpushするの禁止(forced push禁止)
- 新しい機能を追加するときはissueに追加したい機能の詳細を追加すること
- ブランチを切って機能を実装してPullRequestを作ること
- PullRequestはreviewerからLGTMをもらったらマージ可能 

## 手順

### 1. githubにissuesを作成する

### ２. gitにbranchを作成する

＜branch名ルール＞
feature/xxxxxx → 新機能とか
fix/xxxxx → バグの修正とか
hotfix/xxxx → 緊急の修正とか

コマンド

```
> git checkout -b branch名
```

### ３. 開発をする

### ４. コミットする
- こまめにコミットをする
- statusで変更内容等を確認

コマンド

```
> git add .
> git status
> git commit -m "開発、編集内容等のメッセージ"
```

### ５. pushする
コマンド

```
> git push origin branch名
```

### ６. PullRequestを送る
githubでPullRequestを送る。LGTMをもらったらマージできる。

#### PullRequestの送り方
1. githubでPullRequestをクリック
2. new PullRequestをクリック
3. baseをmaster、compareをbranchにする
4. reviewersを入れ、Assigneesに自分を入れる
5. コメントにissuesの番号（＃を入れて）を記入すると結びつく
6. LGTMをもらったらマージする

### 7.ローカルのmasterにpullする
コマンド

```
> git checkout master
> git pull origin master
```
ArgumentParser(argparse)使い方メモ

# ArgumentParser(argparse)とは
Pythonの標準ライブラリ。
コマンドライン引数の設定を色々できる優れもの。

# サンプルコード
```args.py
import argparse


def get_args():
    parser = argparse.ArgumentParser(description='This is sample argparse script')
    parser.add_argument('-n', '--name', default='hogehoge', type=str, help='This is name.')
    parser.add_argument('-a', '--age', default=30, type=int, help='This is age')
    parser.add_argument('-s', '--sex', default='male', type=str, choices=['male', 'female'], help='This is sex')

    return parser.parse_args()


def main():
    args = get_args()
    print(args)
    print("name: %s" % args.name)
    print("age : %d" % args.age)
    print("sex : %s" % args.sex)


if __name__ == '__main__':
    main()
```
# 使用例
```
$ python args.py -h
usage: args.py [-h] [-n NAME] [-a AGE] [-s {male,female}]

This is sample argparse script

optional arguments:
  -h, --help            show this help message and exit
  -n NAME, --name NAME  This is name.
  -a AGE, --age AGE     This is age
  -s {male,female}, --sex {male,female}
                        This is sex

$ python args.py -n 田中 -a 20 -s male
Namespace(age=20, name='田中', sex='male')
name: 田中
age : 20
sex : male
```

# 解説

## ArgumentParser()

parserの作成。descriptionには--helpで出てくる説明文の値をセットする。

```
parser = argparse.ArgumentParser(description='This is sample argparse script')
```

## add_argument()

引数を設定できるメソッド。

```
parser.add_argument('-n', '--name')
```

**default**でデフォルト値を設定できる。
実行時に引数を設定しない場合、デフォルトの値が反映される。

```
$ python args.py
Namespace(age=30, name='hogehoge', sex='male')
name: hogehoge
age : 30
sex : male
```

**type**で引数の型を指定できる。
違う型の値が渡されるとエラーとなる。

```
$ python args.py -a hogehoge
usage: args.py [-h] [-n NAME] [-a AGE] [-s {male,female}]
args.py: error: argument -a/--age: invalid int value: 'hogehoge'
```

**choices**で引数として許される値を指定することができる。
choicesで指定したもの以外の値が渡されるとエラーとなる。

```
$ python args.py -s man
usage: args.py [-h] [-n NAME] [-a AGE] [-s {male,female}]
args.py: error: argument -s/--sex: invalid choice: 'man' (choose from 'male', 'female')
```

**help**で引数の説明を加えることができる。

```
$ python args.py -h
usage: args.py [-h] [-n NAME] [-a AGE] [-s {male,female}]

This is sample argparse script

optional arguments:
  -h, --help            show this help message and exit
  -n NAME, --name NAME  This is name.
  -a AGE, --age AGE     This is age
  -s {male,female}, --sex {male,female}
                        This is sex
```
【超簡単】MetaTrade4からLINE＠へメッセージを送る

MetaTrede4からLINE＠へメッセージを送る方法を調べたところ、直接送信する記事がなかったので書いてみようと思いました。
LINE Messaging APIを使ってMT4からLINE@へメッセージ通知を行います。
# 事前準備
・LINE developersでユーザーIDとチャネルトークンを取得する
（ここでは取得方法は書かないので、他で確認してください。）

# ソース
`code`
```LINE_Send.mq4
string url = "https://api.line.me/v2/bot/message/push";
string UserID       = "＜ユーザーID＞";
string ChannelToken = "＜チャネルトークン＞";

message = "{\x0022to\x0022 : \x0022" + UserID + "\x0022, \x0022messages\x0022:[{\x0022type\x0022:\x0022text\x0022,\x0022text\x0022:\x0022ラインテスト\x0022},{\x0022type\x0022:\x0022text\x0022, \x0022text\x0022:\x0022Hello, world2\x0022}]}";

headers="Content-Type: application/json\r\n";
headers+="Authorization: Bearer "+ChannelToken;
             
string data = ArrayResize(post,StringToCharArray(message,post,0,WHOLE_ARRAY,CP_UTF8)-1);
   œœ
int rest=WebRequest("POST",url,headers,5000,post,result,headers);
```
Qiitaのソース表示がうまくいってないですが、ソース自体は簡単ですね。
ポイントはダブルクオーテーションを「\x0022」で書くことですね。

# 追加で注意
<img width="670" alt="スクリーンショット 2019-01-10 21.22.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/123755/65bb3f9b-2d7f-1291-8a8f-727675e98e8b.png">
MT4のツール＞オプションを選択し、エキスパートアドバイザタブを開きます。
そこで、WebRequestを許可するURLリストにチェックし、下記URLを追加しましょう！
https://api.line.me/v2/bot/message/push
インジケーターではWebRequestを使用できないので、EA化するかDLLを使用して対応する必要があります。
minitestでloggerの出力内容をテスト

バッチ処理のテストを書いた時のメモみたいなものです。

## バージョン

* Rails 5.2.1
* minitst 5.11.3


## サンプル

以下のような、DBのデータを削除するバッチ処理があったとします。

```ruby
class DeleteBatch

  # データ削除バッチ（適当）
  def run
    Rails.logger.info("#{self.class.name} run")

    begin
      ActiveRecord::Base.transaction do
        deleted_something_models = SomethingModel.where("deleted_at < ?", Time.current.ago(1.month)).destroy_all
      end
      Rails.logger.info("#{self.class.name} #{deleted_something_models.count} records deleted")
      Rails.logger.info("#{self.class.name} successed")
    rescue => e
      Rails.logger.error("#{self.class.name} failed")
    end
  end

end
```

ログの出力内容をテストします。

```ruby
require 'test_helper'
require 'minitest/mock'

class DeleteBatchTest < ActiveSupport::TestCase

  test "ログの内容をテスト" do
    # 削除される想定のデータを投入（省略）

    # 期待するログの内容を定義
    expected_log = [
      "DeleteBatch run",
      "DeleteBatch 10 records deleted",
      "DeleteBatch successed",
    ]

    index = 0
    assert_arg_proc = -> (actual_log) do
      assert_equal(expected_log[index], actual_log)
      index += 1
      return
    end

    Rails.logger.stub(:info, assert_arg_proc) do
      # stubによって、このブロック内では Rails.logger.info は assert_arg_proc に置き換わる。
      # Rails.logger.info("abc")が呼ばれたら、assert_arg_proc("abc")が実行されるということ。

      delete_batch = DeleteBatch.new
      delete_batch.run
    end

    assert_equal(expected_log.size, index)
  end
end
```

サンプルのケースでは処理が単純なのでログを見る必要性はあまり無いですが、
色々する長いバッチ処理を書いてしまった時には使えるかと思います。
Python3.5 + Selenium + Chrome + CentOS7でスクレイピング環境を構築してみた

# はじめに
スクレイピングするためにCentOS７上にPython3.5 + Selenium + Chrome環境を構築しました。historyから手順を思い出しながら書いたので間違っていたらすみません。

## きっかけ
実は最初はCentOS6上でPhantomJSを使っていましたが、PhantomJSがもうメンテンスされないことと、なぜかdriver.get(URL)が成功したり失敗したりするので(Connection refused)されるのでPhantomJSから変えてみようと思ったのがきっかきです。そしてCentOS6上で`Python3.5 + Selenium + Chrome`環境を構築していたのですが、

```
/home/g-api/scraping/lib64/python3.4/site-packages/chromedriver_binary/chromedriver -v

/lib64/libc.so.6: version `GLIBC_2.14' not found
```
glibcが古いらしくクロームのドライバが使えませんでした。glibcを変えるのはさすがにシステムへの影響を懸念してOSもCentOS7に変えて構築しました。
※クロームに変えてdriver.get(URL)が成功したり失敗したりすることはなくなりました👴。原因はよくわかっていない。

# CentOS7
* CentOS Linux release 7.6.1810 (Core)
* glibc 2.17

# python
デフォルトではpython3入ってない。yum install python3もできません。

```
[root@host3 ~]# python3
-bash: python3: コマンドが見つかりません
```
## リポジトリ追加
まずは、pythonパッケージを導入するためにリポジトリを追加します。

```
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
```
## pythonインストール
関連パッケージもまとめてインストール

```
[root@host3 ~]#  yum install -y python35u python35u-libs python35u-devel python35u-pip

```

## python仮想環境作成
pipでインストールするモジュールはプロジェクトで閉じたいので仮想環境を作成。


```
python3.5 -m venv 環境名
```
仮想環境を有効化

```
. 環境名/bin/activate
```
# Chromeインストール
yumでインストールするために、リポジトリを追加する必要があります。
リポジトリを追加後にインストール。リポジトリ

```:/etc/yum.repos.d/google-chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl.google.com/linux/linux_signing_key.pub
```

クロームインストール

```
yum install google-chrome-stable
```

# pythonモジュールインストール
## クロームドライバインストール
SeleniumとSeleniumからクロームを扱うためにクロームドライバインストールします。

```
pip install selenium
pip install chromedriver-binary
```

# スクレイピングしてみる
options.add_argument('--no-sandbox')が無いとエラーになります。

```python:scraping.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()

options.add_argument('--headless')
options.add_argument('--no-sandbox')

driver = webdriver.Chrome(executable_path='/path/to/chromedriver',chrome_options=options)

driver.get('https://yahoo.co.jp')
print(driver.title)
```
うまくできました😃！
Anaconda 環境で python-socketio を使う際の注意点

## 結論
```
$ conda install python-socketio
```
ではなく

```
$ conda install -c conda-forge python-socketio
```
と叩いて入れましょう

## 経緯
以下の文を記述したところ

```python:socket_client.py
import socketio
socket = socketio.Client()
```

以下のようなエラーが出ました

```:エラー画面
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    from socketClient import Socket
  File "/home/chankane/Documents/Python/monopoly/socketClient.py", line 4, in <module>
    class Socket:
  File "/home/chankane/Documents/Python/monopoly/socketClient.py", line 5, in Socket
    socket = socketio.Client()
AttributeError: module 'socketio' has no attribute 'Client'
```
<br>
``socketio``くんは``Client``なんてモノ持ってないようです
<br>
<br>

###~~そんなわけないだろ~~
<br>

## 解決
Anaconda のリストを確認

```
$ conda list | grep socketio

python-socketio           2.1.2                    py37_0
```
今入ってるのは**バージョン 2.1.2**
[公式サイト](https://anaconda.org/conda-forge/python-socketio)は **バージョン 3.0.0**
<br>

###ぜってーこれじゃん
<br>

上記[公式サイト](https://anaconda.org/conda-forge/python-socketio)に書いてある通り、

```
$ conda update -c conda-forge python-socketio
```
でいけました
<br>
これからはちゃんと公式サイト見ます
Linux 特定文字を含むファイルを検索するには

【Linux】複数あるファイルの中から特定の文字列を検索するコマンド

$ find ./ -type f -print | xargs grep 'hoge'

【上記コマンドの説明】

find

find の次で指定したディレクトリ以下のファイルを検索する。 ファイル検索の構文は「find [path] [検索条件] [アクション]」

—

./

今いるディレクトリ以下が検索対象。「~/」とするとホームディレクトリ以下が検索対象となる。 ./ の代わりにフルパスでも可。この場合も指定したディレクトリ以下が検索対象になる。

—

-print

検索結果を標準出力する。このとき結果をフルパスで表示する

—

-type f

指定したファイルタイプを検索する。fが通常ファイルを，cまたはdとするとディレクトリを，lとするとシンボリック・リンクを検索します。

—

xargs

標準入力からコマンドラインを作成し、それを実行する

—

grep

ファイルから文字列を検索する。grep の後に検索したい文字列を指定する。
amazon dash buttonのハック続き

# はじめに
この記事は[amazon dash buttonのハック](https://qiita.com/tomokinex/items/0e72e2f1dee15180ce32)の続きです

前回の記事ではamazon dash buttonの処理を受け取る部分を紹介しましたが,
今回の記事では実際のサーバで運用する部分を紹介します


サーバの環境はraspberry pi(UNIX系)を前提にしています
前回の記事と同じく[github](https://github.com/tomokinex/dash_button)のdemonブランチにあげてあります

# deamon process
arpを受信する処理をサーバで常に実行するためにdeamon process化します

deamon processというのは, 簡単にいうと制御端末のないプロセス(バックグラウンドで勝手に動くプロセス)です

unix系では, unistd.hにdeamon関数を用意してくれているので簡単に実現できます

```c++:daemon
#include <unistd.h>
#include <errno.h>
if(daemon(0, 0) == 0) {
  main_loop();
}else{
  perror("Make daemon process");
  return 1;
}  
```

main_loopの中でarpの受信を行います
前回の記事であったソケット作成とバインドはmain_loopに入る前に実行しておきます

# deamon processの確認
psコマンドでオプションaxをつけると, すべてのプロセスの情報を確認できます

```shell
% ps -ax
PID TTY      STAT   TIME COMMAND
 -- 略 --
17725 ?        Ss     0:00 ./main
```
TeXの入門教材を作りました。ご自由にお使いください。


# TeX入門 - TeXでレポートを書く程度に必要最低限のこと

表題のタイトルでTeXの入門教材を作りました。
理系の学生がレポートをTeXで書くために必要最低限と思われることを解説しています。

texファイルと、それをタイプセットしたpdfファイルを見比べながら学習する、
という形式になっています。両方とも、以下のリンクからダウンロードできます。
よしなにご利用ください。
[TeX入門 - TeXでレポートを書く程度に必要最低限のこと](https://www.dropbox.com/s/yqehmdu9v5yniqt/TeX_basis_ver1.3.zip?dl=0)


# もろもろ

「作りました」と書きましたが学生時代に作ったものなので、そうか……もう4年も前か……。
そんな高度な・複雑な機能は解説してないので、今でも問題なく使えると思います。

**目次**（pdfで全10ページ）:

1. 基本的なこと 前編 （字下げ、改行、空白、節の設定、改ページ）
2. 基本的なこと 後編 （強調、箇条書き、脚注、文字の大きさ）
3. 数式の基本的なこと
  1. 文中に数式を入れる
  2. 行を改めて数式を入れる
  3. 数式の微調整
  4. 数式を引用する
  5. 数式を書くときによく使う命令
  6. 複雑な数式の例
4. 図を組み込むには
5. 小ネタ
6. 初心者がやりがちなミス
7. 最後に

ただし、「TeXとは何か」というレベルから解説してはいません。
ざっくり、「TeXがどんなものか分かった。TeXを使えるソフト（このテキストではTeXworks）も入れた。それで、実際TeX使うとしてこれからどうすればいいの?」というレベルの読者を想定しています。
ダウンロードしたzipに入っているreadmeもご覧ください。

ちなみに、p8に「リメディアル教材」という単語が出てきます。
これは、筑波大学 生命環境学群 生物資源学類の奈佐原顕郎先生が作成し、授業で使われている数学の教材です。
[氏のウェブサイト](http://pen.envr.tsukuba.ac.jp/~nishida/) からダウンロードできます。すごいいい教材ですのでダイマします。

# TeXはいいぞ

こういうのとかをきれいに書けるんです:

![texex.png](https://qiita-image-store.s3.amazonaws.com/0/150194/f976c035-bbc3-c17d-d4ed-346ea0b59029.png) ... [本文: ケプラーの3法則の導出](https://www.dropbox.com/s/7kv8h58imcwgn38/2013_RemoteSensing_report.pdf?dl=0)

かっこいい数式が書かれているQiitaの記事もあります。
あれらも実はTeXの記法で記述されています。
ピンと来た方はレッツTeX。
RecyclerViewでスクロール位置を復元する

RecyclerViewでスクロール位置を復元したい場合、だいたい `position` を保持しておいて、それを使って復元するのが王道な感じですが、別の方法もあるようだったのでメモがてら投稿。

```kotlin
// 保持
val state: Parcelable = recyclerView.layoutManager?.onSaveInstanceState()

// 復元
recyclerView.layoutManager?.onRestoreInstanceState(state)
```

`LayoutManager` の `onSaveInstanceState` を呼ぶことで、スクロール位置などの情報を持った `Parcelable` を取得できるので、それを使う方法です。

`onSaveInstanceState` の場合、オフセットなども良しなに？計算してくれているようなので、 `position` を保持する方法よりも、いいかもしれないです。
【Watson Studioメモ】Watson StudioのJupyter Notebookでplot_modelを使えるようにする

# はじめに
Watson StudioのJupyter Notebookは、普通に使うライブラリはほぼ全部最初から入っていて大変便利なのですが、plot_modelがいつも使えなくて苦労します。
一番簡単な手順がわかったので備忘録としてメモしておきます。

# 現象
例えば、次のようなコードを初期状態で実行するとエラーになります。

```py3
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')

from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import RMSprop

# モデル定義
model = Sequential()
model.add(Dense(64, activation='relu', input_dim=784))
model.add(Dense(10, activation='softmax'))

# モデルのグラフ化
from keras.utils import plot_model
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

plot_model(model, to_file='sample-model1.png', show_shapes=True, show_layer_names=True)
im = Image.open('sample-model1.png')
plt.figure(figsize=(8,8))
plt.axis('off')
plt.imshow(np.array(im))
plt.show()
```

**エラーの様子**

![スクリーンショット 2019-01-10 19.50.00.png](https://qiita-image-store.s3.amazonaws.com/0/206130/5a4f8c6b-cbc1-f80a-eb78-45c5c6055d7a.png)

しかし、メッセージの指示に従い``pip``コマンドで``pydot``と``graphviz``を追加導入してもエラーは消えず、いつも悩むのでした。

# 対策
わかってしまえば簡単なのですが、Watson StudioのJupyter Notebook上で、次のコマンドを実行します。  
``graphviz``に関しては、``pip``コマンドと``conda``コマンドを両方実行するのがポイントです。

```
# 必要モジュールの追加導入
!pip install graphviz
!conda install graphviz
!pip install pydot
```

``graphviz``がちゃんと動いているかどうかのテストは以下のコマンドで可能です。

```
# 動作確認
!dot -V
```

これに対して次のような結果が返ってくればテストOKです。  
逆にセットアップがうまくいっていない場合は、次のコマンドでなんらかのエラーメッセージが表示されます。

```
dot - graphviz version 2.40.1 (20161225.0304)
```

# 実行結果
テストがOKの状態で上記のプログラムを再度動かすと、めでたくネットワーク図表示がされるようになります。

![スクリーンショット 2019-01-10 19.57.43.png](https://qiita-image-store.s3.amazonaws.com/0/206130/7ecf7b9d-3404-f62d-1886-188abfd1a159.png)
ルール違反のgitブランチ名をpre-commitで防ぐ

チームでgitを用いて開発する際、ブランチ名にある一定のルールを設けることがあると思います。

ただ、周知しても忘れるのが人間。
ドキュメントを読まないのも人間。

なので、自動でブランチ名をチェックして、不正な場合はコミットをさせないように設定できます。

# 前提

※macOSでの動作を確認しています。Windows等の場合は少し書き方が変わると思います（すみません、未検証です）。

# pre-commitファイルを用意

クローンしているレポジトリのルートに移動してください。

```bash
mkdir -p .git/hooks
touch pre-commit
```

viではなくてもいいですが、好きなエディタで以下のファイルを編集してください。

**2019/01/18追記** インタラクティブリベースで困るのでHEADを追加しました。

```bash:.git/hooks/pre-commit
#!/usr/bin/env bash

readonly BRANCH_NAME_RULES='^(HEAD|master|develop|release\/(.+)|(?:bugfix|feature|hotfix)\/PROJECT-[0-9]+(?:-.*)*)$'
readonly BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
readonly BRANCH_NAME_LENGTH=$(echo ${BRANCH_NAME} | grep -E ${BRANCH_NAME_RULES} | wc -c | tr -d ' ')
if [ ${BRANCH_NAME_LENGTH} -eq 0 ] ; then
    echo ""
    echo -e '\033[0;31;43m ERROR! \033[m in pre-commit hook.'
    echo ""
    echo -e "Your branch name "'\033[1m'${BRANCH_NAME}'\033[m'" is not suitable for our rule."
    echo "Please fix your branch name before commiting!"
    echo ""
    echo "Abort commiting."
    echo ""
    exit 1
fi
```

`BRANCH_NAME_RULES` がルールチェック用の正規表現です。
このファイルの例では、

* master
* develop
* release/hogehoge
* bugfix/PROJECT-123
* bugfix/PROJECT-123-foo
* feature/PROJECT-456
* feature/PROJECT-456-bar
* hotfix/PROJECT-789
* hotfix/PROJECT-789-baz
* HEAD

などが許可されます。

https://www.debuggex.com/ で図解すると、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/143240/69b86f81-3a41-f6a3-5320-91b221486b3d.png)
こんな感じです。


# pre-commitに実行権限を付与

```bash
chmod +x pre-commit
```

これで準備完了です。

# テスト

![image.png](https://qiita-image-store.s3.amazonaws.com/0/143240/61bb676b-cf84-1018-528c-c6efd8b958b6.png)

ブランチ名 `feature/payment` （pre-commit設定前に作成）にコミットしようとすると、エラーが表示されてコミットがキャンセルされます。

# 問題点

* クローンする度に設定しなければならない
* 設定してくれるかどうかは人次第

1行コマンドで自動設定する、といったいい方法を考えないとですね。
Dell PowerEdge T330 に ubuntu server 18.01 を RAID1 構成でインストールしようとしてハマったメモ

# 概要
新しいサーバ Dell PowerEdge T330 を買ったのでちゃちゃっと ubuntu server を入れるだけなはずだったのだが、何度もハマったのでメモ
主にRAIDコントローラPERC S130 の問題とインストールディスクの問題

## PERC S130 では ubuntu は入らない（みたい）
以前もT330はセットアップしたことがあって、その時はなんの問題もなくubuntuを入れることができた
その時のRAIDコントローラは PERC H330 でこれはハードウェアRAIDだ
今回は予算がギリギリだったので適当に PERC S130 を選んだらこれがよくなかった
実はこれはソフトウェアRAIDでしかも Windows Server もしくは [RHEL と SLES しかサポートしていない様子](https://www.dell.com/support/manuals/jp/ja/jpbsd1/poweredge-rc-s130/sw130_ug_pub/linux-raid-%E3%81%AE%E8%A8%AD%E5%AE%9A?guid=guid-32a068ae-ff8b-491e-899f-cc715fb409a0&lang=ja-jp)
Lifecycle Controller というDell独自の設定ソフトを使って該当OSを選択してインストールするのが正しいやり方らしい
そして選択肢にubuntuは無い
だけどまあ、それは関係なくインストールDVD作って普通にインストールすればいいんじゃね？ と思ってとりあえずインストールしてみた
2つあるHDDのうち、片方に普通にインストールできたのだが、これがbootできない！
boot元として選べるのがDVDかPXEだけで、HDDがないのだ！
ここから結構ハマったのだが結論だけ書くと
System Setup → Device Settings → S130 Configuration Utility → Physical Disk Management で、Convert To NON-RAID Disk をしなければいけなかった
これでようやく物理ディスクがシステムから見えるようになったみたい
この段階で一応RAIDなしのubuntuはインストールおよび起動に成功

# RAID 設定する時はLive版ではなく従来版インストールディスクを使おう （この項はubuntu18.04のもの、後ろにubuntu20.04の追記あり）

さて、ようやくubuntuはインストールできたのだけどHDDも2つ積んでるし、なんかubuntuのインストーラーからソフトウェアRAIDの設定ができるっぽいので、それなら是非ソフトウェアRAIDしよう……と思って始めたがまたこれがハマった
ubuntuのページから普通にインストーラーをダウンロードするとLive版のインストーラーがダウンロードされる
Live版でもRAIDの設定ができる（あるいはできそうに見える）のだが、どうも設定がうまくいかない
うまく設定したつもりでもDoneがグレーアウトしてしまっていてどうしていいかわからないのだ
さんざハマった後に[こちらのブログ](https://ginkyo.hatenablog.jp/entry/2018/11/06/135154)をみたら、RAIDの設定をするのにLive版より従来版を使った方がいいと書いてある
たしかにubuntuのダウンロードページをよく見ると [Alternative Ubuntu Server installer のところ](https://www.ubuntu.com/download/alternative-downloads)に、RAID とかやりたかったら従来型の方がいいよって書いてある
工ｴｴｪｪ(´д｀)ｪｪｴｴ工
もしかしたらLive版でもうまくやればできるのかもしれないけど、従来版でやりなおし
やりたかったことは上記のブログと全く同じだったので、その通りに設定しました
めでたしめでたし

# 2021年12月 追記

再び PERC S130 で ubuntu をソフトウェアRAIDでインストールする機会があった
上の文はubuntu 18.04 だったが、今回は ubuntu 20.04 を利用
本当はでDesktopを使いたかったけど、ソフトウェアRAIDはServerのインストーラーでしかできないとのことでServerをインストールしてからaptでDesktopにアップグレードする
詳細は[ここのブログ](https://setaria.rwc.0t0.jp/2021/08/22/ubuntu20-04-server%E3%81%A7software-raid/)の通り
以前みたいに特殊なことしなくてもGUI（TUI?）で普通にインストールできるのでありがたい
`/dev/sba`と表示されるとか書いてあるところはHDDの名前が書いてあるけど、気にしない
`new. bios_grub`とか表示されるってところが`primary ESP`とかだったりするけど、気にしない 
ただ、インストールしたあとなぜかrebootしても Unavailable:ubuntu とか出て起動しなかった
原因は結局よくわからなかったが、BIOSやファームウェアの設定を全部defaultに直したら起動した
前に別の人がいじっていたので、何かが変更されていたのかもしれない