OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】処理負荷の軽減に繋がるコーディング【Unity】


簡単だけど意識しておくだけで負荷軽減に繋がるコードの書き方を紹介します。

1.毎回取得する必要のないものはキャッシュする
------------
```cs
        void Start()
        {
        }

        void Update()
        {
            // 毎回呼ばれる
            Text text = GetComponent<Text>();

            // テキストの文字を変更
            text.text = "文字";
        }
```
↓

```cs
        // キャッシュ用メンバ変数
        Text m_text = null;
        
        void Start()
        {
            // 最初の一回だけGetComponentを呼び出しキャッシュする
            m_text = GetComponent<Text>();
        }

        void Update()
        {
            // テキストの文字を変更
            m_text.text = "文字";
        }
```

2.毎回処理する必要のないものはUpdateに書かない
------------------------------

```cs
        Text m_text = null;      
        void Start()
        {
            m_text = GetComponent<Text>();
        }

        void Update()
        {
            // テキストの文字を変更
            m_text.text = "文字";
        }
```
↓

```cs
        Text m_text = null;      
        void Start()
        {
            m_text = GetComponent<Text>();
            // テキストの文字を変更
            m_text.text = "文字";
        }
        
       // 不要なUpdate関数は削除しましょう
```

頭の隅に入れて書くだけでも後々負荷軽減に繋がりチームメンバーからいいねを貰えると思います。

[偉大な公式の最適化マニュアル](https://docs.unity3d.com/ja/current/Manual/MobileOptimizationPracticalScriptingOptimizations.html)
データのコスト2019

2019年末時点で大量のデータをクラウドに上げて保管する際の費用感を調べてみました。費用感を出すのが目的なので最安と言っても厳密ではないです。
抜け漏れや計算間違いがあればご指摘頂けるとありがたいです。

# TL;DR
## データ保管

|保管レベル|最安単価(GB・月)|最安サービス|
|:--|--:|:--|
|RDBMS|9.9円|GCP Cloud SQL(HDD)|
|オブジェクトストレージ|2.14円|Azure BLOBストレージ(ホット・LRS・500 TB 超/月)|
|アーカイブ|0.109円|Amazon S3 Glacier Deep Archive|

## データ転送(上り)

|転送経路|最安単価(GB)|最安サービス|
|:--|--:|:--|
|モバイル|51.7円|BIGLOBE biz. M2M専用プラン/SMSなし/上り高速・下り低速|
|光回線|5.56円|フレッツ光+上り30GB制限の月額5000円プロバイダ|
|オフライン転送|0.344円|AWS Snowball|

# レギュレーション

- 逓減課金(500TB未満いくら、以上いくらのような方式)の場合最安帯とする
- クラウドはAWS/Azure/GCPを対象とする
    - 一般に最も安いと思われるリージョンとする
        - AWS オハイオ
        - Azure 米国東部
        - GCP アイオワ
- データ容量によってスケールする金額を対象とする
    - RDBMSのインスタンス費やオフライン転送の延滞料金などは対象としない
- 冗長化やパフォーマンスは最小限とする
- 為替レートは1$110円とする
- 有効数字は3桁で四捨五入
- クラウド上での活用を目的としアップストリームのみ考慮する

# 詳細

## データ保管

### RDBMS

#### AWS
[Amazon Aurora](https://aws.amazon.com/jp/rds/aurora/pricing/): 10USD/GB・月=11円/GB・月

#### Azure
[Azure Database for PostgresQL(or MySQL)](https://azure.microsoft.com/ja-jp/pricing/details/postgresql/server/): 11.2円/GB・月

#### GCP
[Cloud SQL(HDD)](https://cloud.google.com/sql/pricing?hl=ja#1st-gen-pricing): 0.09USD/GB・月=9.9円/GB・月

### オブジェクトストレージ

#### AWS
[Amazon S3標準(500 TB/月以上)](https://aws.amazon.com/jp/s3/pricing/)： 0.021$/GB・月=2.31円/GB・月

#### Azure
[Azure BLOBストレージ(ホット・LRS・500 TB 超/月)](https://azure.microsoft.com/ja-jp/pricing/details/storage/blobs/)： 2.14円/GB・月

#### GCP
https://cloud.google.com/storage/pricing?hl=ja#price-tables
のストレージ料金表がバグっていて読めないので割愛。

### アーカイブ

#### AWS
[Amazon S3 Glacier Deep Archive](https://aws.amazon.com/jp/s3/pricing/)： 0.00099$/GB・月=0.109円/GB・月

#### Azure
[Azure BLOBストレージ(アーカイブ・LRS・500 TB 超/月)](https://azure.microsoft.com/ja-jp/pricing/details/storage/blobs/)： 0.111円/GB・月

#### GCP
https://cloud.google.com/storage/pricing?hl=ja#price-tables
のストレージ料金表がバグっていて読めないので割愛。

## データ転送

### モバイル

見付けた中で最安は[BIGLOBE biz.](https://biz.biglobe.ne.jp/sim/index.html): M2M専用プラン/SMSなし/上り高速・下り低速： 15500円/300GB=51.7円

### 光回線

制限のないプロバイダなら建前上はいくらでも転送可能なはずだが、現実には難しいと思われる。
速度制限をしているプロバイダは上り30GBで制限をかけている例が多い。
また、フレッツ光のプロバイダ込み料金が5000円前後であることを考慮して、
5000円/30GB/30日=5.56円 とする。

### オフライン転送

#### AWS
[AWS Snowball](https://aws.amazon.com/jp/snowball/pricing/): 250USD/80TB=0.344円/GB

#### Azure
[Azure Data Box](https://azure.microsoft.com/ja-jp/pricing/details/databox/)： (28000+10640)円/100TB=0.386円/GB

#### GCP
[Transfer Appliance](https://cloud.google.com/transfer-appliance/docs/2.0/pricing?hl=ja): 1800USB/480TB=0.413円/GB

# 所感・考察

- RDBMSでインスタンス費を無視したが現実には無視できず実際にはもっと高価
- クラウド間での差はあまりない
- BIGLOBのM2Mは上り特化とはいえ安過ぎて何か間違えている気もする
- 光回線については現実的に月間900GBも上げられるのかは疑問がある
ログイン中ユーザーの投稿内容をshowアクション以外で出力する方法

SNSっぽいアプリケーションのマイページで、ログイン中ユーザの投稿一覧を取得したかっただけなのにかなり詰まったので備忘録として残しておきます。

アプリの仕様上showアクションやshow.html.erbファイルを使用できず、index.html.erbで表示させるというレア？パターンではありますが。
#環境
Rails 5.2.3
Ruby  2.5.1
gemのdeviseを使用
当記事で使用しているモデル名はplace
#詰まった所
homes/index.html.erbファイル内にてeach doを利用し投稿内容を全部出力したい。

```homes/index.html.erb
<% @myplaces.each do |myplace| %>
  #省略
<% end %>
```

全部のplaceを取得するのはhomesコントローラー内のindexアクションで

```:./controllers/homes_controller
@places = Place.all
```
こう書けばいい。そりゃそうだ。
問題はログイン中ユーザの投稿内容だけを取得したい時。

```:./controllers/homes_controller
@myplaces = Place.find(current_user.id)
```
と入力するとundefined method 'each' for nil:NilClassでエラーが発生する。これは@myplacesが空だからeachする元ネタがありませんよっていう怒られ方。できそうな気もするのに。

試しにターミナルでfind(1)として出力してみる。

```:ターミナル
pry(main)> Place.find(1)
   (0.5ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  Place Load (0.3ms)  SELECT  `places`.* FROM `places` WHERE `places`.`id` = 1 LIMIT 1
=> #<Place:0x00007f831ad85618
 id: 1,
 name:　#以下省略
```
問題ない。
idが1であるcurrent_user.idを適当な変数に代入して出力してみる

```:./controllers/homes_controller
@user = current_user.id
```

```:homes/index.html.erb
<%= @user %>
#=> 1
```
こっちも問題がない。
なんで出力されないのか不思議で仕方がなかったんですが、驚いた事にこんな書き方だけで解決しました。

```:./controllers/homes_controller
@places = Place.all
places = @places
@myplaces = current_user.places
```

```homes/index.html.erb
<% @myplaces.each do |myplace| %>
  #省略
<% end %>
```

目ン玉飛び出そうになりました。こんな簡単な記述でよかったんかと。。。普通にidを指定すれば出来るやろって余裕こいてたら痛い目見ました。

原因は今度時間を見つけて探してみます。今度作る時にはハマらないように…
TwistのchatbotをGoで作ってみた

Advent Calendarの間、毎日なんか作ってます。
https://qiita.com/advent-calendar/2019/project25

今回はTwistのchatbotを作ってみました。
Slackbotは作ったことあるし、いっぱい転がってるので

# What is Twist?

Todoistで有名なdoistが作った、SlackやMS Teamsなどのようなチャットツールです。
フルリモートな会社が自分たちのために作ったサービスを商用化しただけあって、メッセージが流れて負えないとか一般的にチャットツールで聞かれる不満は一通り解決されています。
Integrationはまだ、Slackに分がありますが、ただのチャットツールとして使っているのであれば乗り換えたほうがハッピーになれそうです。

（ファンですが、中の人ではありませんよ）

https://twist.com/
<img width="1233" alt="title.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/037edc49-87d5-1dce-487f-971868dd7fe3.png">

# Bot

## Webhookの仕様

Slackなどであればポーリングしないといけませんが、TwistはREST Hookを採用しているので、subscribeに登録すれば、イベントが発生したときに登録したURLに勝手にリクエストが送られるのでポーリングは不要で、普通のREST APIの応用で作成できます。
https://resthooks.org/

Botの場合、`General Integration`を設定すればsubscribeの登録も不要なのでかなり楽です。

## 設定方法

1. 自分のTeamにログインし、 `Add integrations` をクリックします
<img width="1836" alt="add-integrations.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/53b59c4b-688a-f63c-9335-a17e95515998.png">
2. Manageをクリックして新規追加をします
<img width="1312" alt="integrations-dashboard.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/1dc0e0d8-90c6-de8e-28cd-eeb4189f54c0.png">
3. 名前や説明を書きます。`Integration type`は`General Integration`を設定してください。

`General Integration`を設定するとOutgoing Hookを別途設定しなくても全てのイベントに反応してくれます。
<img width="1312" alt="new-integration.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/2fc1a03e-28a4-0e7d-ff93-06ac8a15265e.png">
4. `Bot`をクリックし、`Outgoing webhook URL`を設定します。

URLはベーシック認証付きのものだとエラーで設定できないようなので、セキュリティを考慮したいときはパラメータでトークンを渡すかIPなどで制限するしかなさそうです。
<img width="1379" alt="bot-settings.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/af745fbf-ee3b-35e2-72d1-0ff13331785f.png">

## Goの設定

Handlerの設定は下記のように作りました。
リクエストボディの内容がわからなかったので、とりあえずリクエストボディの内容をオウム返ししてもらうようにしました

```go
func botHandler(w http.ResponseWriter, r *http.Request) {
	if r == nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte("can not get request"))
	}
	defer r.Body.Close()
	bs, _ := ioutil.ReadAll(r.Body)
	w.Write([]byte(fmt.Sprintf("header: %s, body: %s", r.Header.Get("Content-Type"), string(bs))))
}
```

上記のように設定して、botにコメントを送ると下記のようになります

<img width="1177" alt="スクリーンショット.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9094/41711891-6fa5-9095-d6b6-033cd55f5a61.png">

作ったものはここにあります。
作ってみたい方は参考にどうぞ。

page: https://github.com/usk81/twistbot
release: https://github.com/usk81/twistbot/releases/tag/v0.0.1-alpha1
PHP基礎 Part4

# 概要
PHPの独学で学んだことをアウトプットしていく

# 前回の内容
[PHP基礎 Part3]
[PHP基礎 Part3]:https://qiita.com/k__aizawa/items/405735a41c18c60c9335

## 配列
変数は値を1つしか割り当てることが出来なかったが、配列の場合は複数の値を扱うことができる。
配列から値を出力する時は、配列のデータにそれぞれ割り当てられた__「インデックス」__を利用する
なお、インデックスは0から始まる

```php:sample.php
<?php
  $fruits = array("りんご","みかん","ぶどう"); // 配列のデータを定義
  echo $fruits[0];                        // インデックスを指定し出力する

// 結果:りんご
?>

```

また、配列の値を追加したり、上書きする際は以下のようにする

```php:sample.php
<?php
  $fruits = array("りんご","みかん","ぶどう"); // 配列のデータを定義
  $fruits[] = "いちご";                     // 「$配列名[] = 値」とすることで、配列の末尾に値を追加
  echo $fruits[3];                        // インデックスを指定し出力

  $fruits[2] = "パイナップル";               // 配列名にインデックスを指定することで、値を上書き
  echo $fruits[2];                        // インデックスを指定し出力

  // 結果:いちごパイナップル
?>
```

## 連想配列
配列と同じように複数のデータを扱う役割があるが、配列とは異なり
データの管理をキーという文字列を活用することである。

```php:sample.php
<?php
  $customer = array(
        "name" => "紀伊田 太郎", // 「"キー名" => 値」という形を取る
        "age"  => 30,          // データとデータの間に「,」を入れる
        "address" => "東京都"
  );

  echo $customer["name"];      // 連想配列の出力は $配列名["キー"] となる

  // 結果:紀伊田 太郎
?>
```
また、以下のように連想配列に値を加えることも可能

```php:sample.php
<?php
  $customer = array(
        "name" => "紀伊田 太郎", // 「"キー名" => 値」という形を取る
        "age"  => 30,          // データとデータの間に「,」を入れる
        "address" => "東京都"
  );

  $customer["job"] = "engineer";    // 連想配列の値の追加
    echo $customer["job"];          // インデックスを指定し、出力

  // 結果:engineer
?>
```

## 次回
* for文
* while文
* foreach文
[Cocoa][Swift]XCFramework

<p>Darwinで採用されています実行形式のバイナリ・フォーマットMach-oは、一つのファイルに複数のアーキテクチャのバイナリが格納できるという素晴らしい特徴があるのですが、同じCPUで異なるシステム向けのバイナリは同時に格納できないという欠点があるようです。以前だと、これで問題はなかったのですが、例えば、iPad OS向けアプリのソースからmacOSアプリを作ることができるUIKit for Mac (Catalyst)だと、x86_64でiOSとiPhoneシミュレータ（macOS）という場合が発生して、同一ファイルに格納できないという問題が発生します。</p>

<p>おそらく、これの対策として用意されたのが、Xcode 11から利用できるXCFramework。簡単に説明すると複数のフレームワークを一つにできるというものだ。</p>

<p>具体的には、MoltenGLというライブラリはiOSとmacOS向けのフレームワークが用意されていて、これを以下のコマンドでXCFrameworkにまとめられる。</p>

<pre><code>% xcodebuild -create-xcframework \
> -framework MoltenGL-0.25.0/MoltenGL/iOS/framework/MoltenGL.framework \
> -framework MoltenGL-0.25.0/MoltenGL/macOS/framework/MoltenGL.framework \
> -output MoltenGL.xcframework
xcframework successfully written out to: MoltenGL.xcframework
</code></pre>

<p>この中身をtreeコマンドで確認してみる。</p>

<pre><code>% tree MoltenGL.xcframework
MoltenGL.xcframework
├── Info.plist
├── ios-armv7_arm64
│   └── MoltenGL.framework
│       ├── Headers
│       │   ├── MoltenGL.h
│       │   ├── mglDataTypes.h
│       │   ├── mglEnv.h
│       │   ├── mglGLKitDataTypes.h
│       │   ├── mglMetalState.h
│       │   ├── mglext.h
│       │   └── mln_env.h
│       └── MoltenGL
└── macos-x86_64
    └── MoltenGL.framework
        ├── Headers -> Versions/Current/Headers
        ├── MoltenGL -> Versions/Current/MoltenGL
        └── Versions
            ├── A
            │   ├── Headers
            │   │   ├── MoltenGL.h
            │   │   ├── mglDataTypes.h
            │   │   ├── mglEnv.h
            │   │   ├── mglGLKitDataTypes.h
            │   │   ├── mglMetalState.h
            │   │   ├── mglext.h
            │   │   └── mln_env.h
            │   └── MoltenGL
            └── Current -> A
 
10 directories, 18 files
</code></pre>

<p>単なるx86_64でなく、macOSのx86_64となっている。</p>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
Livedoorニュースコーパスで主成分分析 - 前準備 - 

#この記事について
[前回](https://qiita.com/torahirod/items/7a2aa0465f25d99599a9)、テキストデータの主成分分析に挑戦したのですが、
もっと別のテキストデータでやってみたいなということで、
株式会社ロンウイット様が公開されている[Livedoorニュースコーパス](http://www.rondhuit.com/download.html#ldcc)を使って主成分分析に挑戦したいと思います。

その前処理として、1記事毎に分かれているテキストファイルの内容を順次読み込んで、形態素解析した後、1つのcsvファイルにまとめるということをやっていきたいと思います。

形態素解析ライブラリは、janomeを使用しました。

#参考
-  [Livedoorニュースコーパス](http://www.rondhuit.com/download.html#ldcc)

#Livedoorニュースコーパスのディレクトリ構成
上記のリンクよりファイルをダウンロードし、解凍すると、textフォルダ配下に、it-life-hackといった分類毎に分かれた9つのフォルダがあり、各フォルダ配下にその分類の記事が1記事1ファイル単位で格納されています。

#前処理プログラム
```Python:
import pandas as pd
import numpy as np
import pathlib
import glob
from janome.tokenizer import Tokenizer
tnz = Tokenizer()

pth = pathlib.Path('c:/temp/text')

l = []
for p in pth.glob('**/*.txt') :
    # 記事データ以外はスキップ
    if p.name in ['CHANGES.txt','README.txt','LICENSE.txt']:
        continue
        
    # 記事データを開き、janomeで形態素解析⇒1行1単語の形式でリストに保持
    with open(p,'r',encoding='utf-8-sig') as f :
        l.extend([[p.parent.name, p.name, t.surface, t.part_of_speech] for s in f for t in tnz.tokenize(s)])

# リストをデータフレームに変換
df = pd.DataFrame(np.array(l))

# 列名を付与
df.columns = ['記事分類','ファイル名','単語','品詞']

# データフレームをcsv出力
df.to_csv('c:/temp/livedoor_corpus.csv', index=False)

```

# 出力結果
出力結果はこのような感じです。
![出力結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490521/272333de-581e-65e5-b18e-86ad745a1acc.png)
Rustで自然数を作ってみた

みなさん、自然数というと、何を思い浮かべますか?
まずは、ゼロですよね。(**本記事では自然数はゼロを含むものとします。異論は認めません**)

他にどんな自然数があるのか、よく分からないんですが、ゼロの次にくる自然数があるような気がします。その次にくる自然数もあるような気がします。
もっと言うと、どんな自然数に対しても、それの次の自然数があるような気がします。

これを、Rustのenum型で表すと次のようになります。

```rust
#![allow(dead_code)]
use std::rc::Rc;

#[derive(Clone, Debug)]
enum Nat {
    O,
    S(Rc<Nat>),
}
```

ここで、ゼロを`O`, なにかの次の自然数を`S`で表しました。

つまり、

|アラビア数字|Nat|
|--:|:--|
|0|`Nat::O`|
|1|`Nat::S(Rc::new(Nat::O))`|
|2|`Nat::S(Rc::new(Nat::S(Rc::new(Nat::O))))`|
|...|...|


と表せています。

`Nat::S(Rc::new(...))` はめんどくさいので、succというメソッドを生やしましょう。

```rust
impl Nat {
    fn succ(n: Nat) -> Nat {
        Nat::S(Rc::new(n))
    }
}
```

|アラビア数字|Nat|
|--:|:--|
|0|`Nat::O`|
|1|`Nat::succ(Nat::O)`|
|2|`Nat::succ(Nat::succ(Nat::O))`|
|...|...|

と書けるようになりました。`Nat::`も外せるように`impl`の外に書きたい、とか、いろいろ思うところはあるかもしれませんが。とりあえずこれでいきましょう。

さらに、succをいっぱい書くのもめんどくさいので、もっとメソッドを生やしてみましょう。

```rust
impl Nat {
    fn from_u32(n: u32) -> Nat {
        if n == 0 {
            Nat::O
        } else {
            Nat::succ(Nat::from_u32(n - 1))
        }
    }
}
```

再帰的にsuccをする関数です。

我々はu32型には詳しいので、u32型でこうやれば再帰ができることを知っていて、こういうコードが書けました。
Natでも再帰ができる気がするので、ちょっと考えてみます。

- u32での再帰と同様、Natでも、再帰をどこかで止めたいです。具体的には`Nat::O`のとき、何かを返すようにしたいです
- `Nat::O`じゃないとき、先ほどのelse節`Nat::succ(Nat::from_u32(n - 1))`のような雰囲気の形にしたいです
- `n - 1` ←こんな計算しらない。けど、`Nat`では、`Nat::S(m)`の`m`の部分を使えばよさそうです。

これらを考えたとき、例えば次のような実装ができます。

```rust
impl Nat {
    fn rec<T>(c0: T, cs: &dyn Fn(&Nat, T) -> T, n: &Nat) -> T {
        match n {
            Nat::O => c0,
            Nat::S(m) => cs(m, Nat::rec(c0, &cs, m)),
        }
    }
}
```

これで、再帰ができるようになりました。
再帰によって、Natをu32に戻すには、次のようにすればいいですね。

```rust
impl Nat {
    fn to_u32(&self) -> u32 {
        Nat::rec(0, &|_, cnt: u32| cnt + 1, self)
    }
}
```

以下を動かすと、動作が確認できます。

```rust
fn main() {
    println!("Except: 100, Actual: {}", Nat::to_u32(&Nat::from_u32(100)));
}
```

最後に、足し算を定義してみます。

```rust
use std::ops::Add;

impl Add for Nat {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Self::rec(other.clone(), &|_, n: Nat| Nat::succ(n), &self)
    }
}
```

これは、u32での再帰風に書くと

```rust
fn add(this: u32, other: u32) -> u32 {
    if this == 0 {
        other
    } else {
        1 + add(this - 1, other)
    }
}
```

です。とても愚直ですが、確かに、足し算になっていることが分かります。
以下のコードで動作確認してみましょう。

```rust
fn main() {
    println!("Except: 7, Actual: {}",
             Nat::to_u32(&(Nat::from_u32(3) + Nat::from_u32(4))));
    println!("Except: 100, Actual: {}",
             Nat::to_u32(&(Nat::from_u32(43) + Nat::from_u32(57))));
}
```

## 続く……のか?
続けたいのですが、Rustだと、高階関数を作ろうと思うと、関数自体の置き場所、クロージャに渡すものの所有権やライフタイムなどが問題になってきて、非常につらいです。

余力のある方は、例えば、recの定義に適当に参照をつけたりとったり、あるいはrecの定義をCurry化してもコンパイルが通るかどうか、試してみて下さい。非常に苦労されると思います。

そのため「進捗が出たら続きを書く」という方式を取ります。

## 参考文献
[HoTT book](https://homotopytypetheory.org/book/)の最初の方
Rails Girlsのカリキュラムをこうしていきたいみたいな提案

# 動機

Rails Girlsのカリキュラムが時代に合わなくなりつつあるのでは、みたいな議論を複数人としたことがあるので、個人的な想いを書きたいと思いました。

# TL;DR

「動き」のあるアプリケーションを作れるようにするといいんじゃないか。

# 本編

## 前提

まず、エンドユーザー（Rails Girlsの参加者の多くはこのタイプ、ここではアプリケーションの生産者ではなく消費者であるという意味合い）が利用するアプリケーション（特にウェブアプリケーション）の品質は年々向上しており、今やSPA（Single Page Application）を利用することすら当たり前の人もいる。

一方、Rails Girlsのワークショップで作るアプリケーションは伝統的なCRUDのアプリケーションであり、そこには現代的なアプリケーション作成における重要なパーツであるインタラクションが欠けている。

## 問題意識

Rails Girlsの目的は参加者に良いアプリケーションを作ってもらうことではなく、成功体験を持ち帰ってもらうこと。それはそうなのだけど、「普段自分が使うアプリケーションよりもインタラクションの面で明らかに劣るもの」を作って得られる成功体験の質はどれだけ高いのか。この問題意識がこの記事を書かせている。

## 解決に向けた案

やはりインタラクティブな現代的ウェブアプリケーションを作る上でJavaScriptは欠かせない。しかしRails Girlsの趣旨を考えても、そのために重量級のライブラリを導入するのは避けたい。
色々を除外した結果、ワークショップの方針として、

1. Stimulusを使う
2. ライブラリを使わない（Vanilla JS）

の2つを挙げたい。

### Stimulus

https://stimulusjs.org/

Stimulusを使うことにはいくつかのメリットが考えられる。

* DOMに記述が必要なのは`data-target`などの属性だけで、これはコピペするHTMLに含めてしまうことができる
* 新しく必要になるJSは単一ファイルなので、説明も比較的容易
* インストールが簡単（`rails new --webpack stimulus`でインストール可能）

一方、無視できない欠点もある。

* インストール時に一手間（`webpack`関連の記述）が増える
* 概念は必ずしも易しくはない
* 魔法が多く、書いてないことが行われる

総じて、個人的にはアリな選択肢だと思われる。

### Vanilla JS

http://vanilla-js.com/

要はライブラリを使わないで書くということ。こちらのメリットは、

* インストール不要
* 書いたままのことが起こる

欠点は、

* やろうとすることの複雑さ次第ではライブラリを使うよりもコードが多く複雑になる可能性がある

正直、Vanilla JSで何かちゃんとしたことをやるのが初学者に対してどの程度簡単に感じられるのか次第になってしまう気はする。

# まとめ

実は、Stimulusを使ったRails Girlsのワークショップ向け事例を作れないかと思ったのだけど、案の定間に合わなかったので、ふわっとした議論になってしまっていることは否めない。
しかし、2020年になろうというときにせっかく作ったアプリケーションに動きがないのも寂しいと思うので、なんとかしてアプリケーションに動きを付ける方法を模索していきたいと思う。
個人的にはStimulus推し。

# 最後に

カリキュラムを更新する場合、本家のRails Girlsの方とも一緒にやらないといけないと思われるので、実際はそちらが大変だと思うのだけど、そちらも含めてやっていきたい。
あらためて「ソフトウェアテストの7原則」を読んでみる

# ソフトウェアテストの7原則
ソフトウェアテストの業界に身を置く人なら、「ソフトウェアテストの7原則」は誰しもが一度は聞いたことがあるかと思います。
今回はそんな有名な「ソフトウェアテストの7原則」についてあらためて触れたいと思います

## 「ソフトウェアテストの7原則」ってそもそもなに？
国際的な資格である[ISTQB](https://www.istqb.org/)で解説されており、ISTQBの国内版である[JSTQB](http://jstqb.jp/index.html)のFoundation Level（FL）のシラバスでも最初の方のページでも触れられている、ソフトウェアテストで提唱されている原則です。


1. **テストは欠陥があることは示せるが、欠陥がないことは示せない**
2. **全数テストは不可能**
3. **早期テストで時間とコストを削減（初期テスト）**
4. **欠陥の偏在**
5. **殺虫剤のパラドックス**
6. **テストは条件次第**
7. **バグゼロの落とし穴**

## 「ソフトウェアテストの7原則」の内容について紹介

### 1.テストは欠陥があることは示せるが、欠陥がないことは示せない
これは書いてある通りですね。
テストでは欠陥があることを示すことはできます。
ただ、テストをやったからと言って、欠陥が無いことは示せないです。
これは、用意したテストケースが全てPassだとしても、それで「欠陥がありません」とは言えませんよね？

テストでは、バグが無いことを証明するのではなく、**バグがあること**を証明するのではないでしょうか。

### 2.全数テストは不可能
昨今のシステムは機能数が膨大にあり、入力条件などの組み合わせを全てをテストするには莫大な時間がかかってしまいます。
また、様々なシステムと関連しているシステムの場合には、その関連しているシステムの条件も考慮しなければなりません。
それこそ**天文学的な数字のテストケース数となり、テストは不可能**かと思います

### 3.早期テストで時間とコストを削減
テストを早期に実施することで欠陥をより早く見つけ出すことができます。一般的な開発サイクルでは、テストは最後にやることになっている場合が多いかと思います。
その場合、テストで見つかった欠陥を修正すると、その欠陥があった箇所以外にも影響し更なる欠陥に繋がることがあるかと思います。
そうして見つかった欠陥を修正するのに、時間・金がかかります。

そうならないよう、**テストは早期に実施すること**が提唱されています。
テストはコードがないとできない物ではありません。
ドキュメントへのレビューや静的テストなどアプローチの仕方は数多くあります。
**早期に欠陥を改善することで、結果的に時間とコストを節約することができ、品質もより良いものになるかと思います。**

### 4.欠陥の偏在
欠陥はシステム内で全般的にあるわけではなく、特定の箇所に集中しています。これを「欠陥の偏在」と呼びます。
テストを行う際には全体的に満遍なくテストをするのではなく、過去の不具合傾向や、類似システムの不具合を参考にして、重点的にテストを行う箇所を決めることができます。

### 5.殺虫剤のパラドックス
例えば、殺虫剤をずっと使っていると、その殺虫剤への抵抗力を持った虫が生まれてきます。
テストも同じで、ずっと同じテストケースや同じ観点のテストを続けていくと、最初こそ欠陥を見つけることができますが、いずれその箇所での欠陥は品質が上がり、欠陥が見つかることは無くなってきます。

### 6.テストは条件次第
システムをテストするときの条件にもよってテストも変えていくことが必要です。
例えば、自動車をテストする場合と、スマホゲームをテストする時は条件が異なります。
車であれば欠陥があると最悪、人命にも影響を及ぼしてしまいます。そのため、アクセルやブレーキといった制御部分に重きを置くかと思います。
スマホゲームでは欠陥があったとしても、人命にはあまり影響がありません。課金要素があるゲームの場合では、二重決算などのお金に関することに重きを置いたりするかと思います。
**同じテストを異なるシステムでは行わない**ですよね

### 7.バグゼロの落とし穴
テスト技法などを用いて作成したテストケースが全部Passで欠陥が見つからないと言っても、それは品質が高いと言うことにはすぐには繋がらないです。
欠陥がゼロだからと言って、そのシステムが絶望的に使いにくかったら、それは品質が高いとは言えません。
テストで欠陥をなくすことはもちろんですが、我々は**より良い品質**のものを提供するんだ！と言う気持ちを持って、テストに取り組むべきかなとマーガリンは考えています。

# 終わりに
この記事を書くのにあたり、あらためて「ソフトウェアの7原則」を読んでみると、初めてこの原則を読んだときとは、違った感想を抱きました。

おそらく、また期間を開けてこの原則を読むと違った感想を持つのかな？って思います。

今回の「ソフトウェアテストの7原則」を初め、様々な原則や定石があるので、今後それらをまとめて行きたいと思います。
会社でエンジニアブログ立ち上げて軌道に乗せるまでやった事

存在が割と謎なアドカレでなんか書けと突然言われたので、会社でエンジニアブログを立ち上げよう！となった時に立ち上げ、運用まで軌道に乗せた時に感じた事、思ったことをつらつらと書きます。

３日目担当の渋谷某社でゲームエンジニアをしているAzukiです。よろしくお願いします。


さて、突然ですが僕が働いている会社ではエンジニアの正社員が少ないという問題が出てました。
そのため、「エンジニア広報に力を入れよう！」という話になり、その一環でエンジニアブログを作って発信する習慣をつけようじゃないかという事になりました。幸か不幸かその一連の担当を任せてもらえる事になったので伸ばすために意識した事などを紹介します

# 1.エンジニアブログとしての軸（方向性）を決める

ブログを作る前に会社の広報の方たちと相談をしました。
皆さんご存知の通り、世の中にはエンジニアブログというものはかなりの数があります。
有名なところだと[クックパッド](https://techlife.cookpad.com/)さんだったり[メルカリ](https://tech.mercari.com/)さんだったり。かなり記事の内容もボリュームがあるし更新頻度も高いです。すごい。

ゲーム業界でもテックブログはよく見ますし、実際の開発について書かれてるブログも多く、とても参考になります。
そんな中で**エンジニアブログを作り、伸ばしていくにはどうしたら良いのか**、というのをまずしっかり相談する事にしました。所謂**生存戦略ですね。**

とはいえ、ゲームの新規プロジェクトの話は書きにくい（情報漏洩の観点とか）ですし、運用プロジェクトだと結構古い技術だしなぁ…と悩んだのですが結果、
エンジニアはわからない事ググる→ググった時の検索上位が日本語だと嬉しいよね　という話になり
UnityとかCocosとかゲーム系の情報で、ググった時に検索上位が日本語じゃないもの且つ、自社でノウハウがあるもの　を記事にする事にしました。

また更新頻度が低いとブックマークなどもしてくれないので、最低でも２週間に１本くらいのペースで出そう。という事にしました。
本当は毎週書きたいのですが書いてくれる人だったり**文化として根付いてないうちにそんな急ペースでやっても誰もついてこなくなるのが実情だろうなという事もあり**、無理せずにできる範囲で２週間に１本にしました。

# 2.記事の品質を保つように意識
インターネットには皆さんご存知だとは思いますが間違った情報であったり、正しいけど雑な記事というのは結構あります。
個人ブログなどではまぁそこまで大きな問題ではないのですが、エンジニアブログは会社のブログとして出すので、適当な事は書けません。
誤った内容の記事を出してしまうと**「この会社はそこまで技術強くないな」**　という印象を持たれる可能性があり、ブログのせいでエンジニアからのイメージが悪くなる恐れがあります

そのため、立ち上げたブログでは原則として**エンジニアによる記事のダブルチェックと、広報の方にもチェックをしてもらい両方OKが出たら公開**、という流れにしました。

**エンジニアが読む記事という事でちゃんと正しい事が書かれているかをエンジニアのチェックで担保し、
読みやすさ、会社として出す上で問題ないかを広報の方に見てもらってます。**
手間は掛かりますが記事のクオリティのバラツキを抑える意味でも大切なポイントだと思ってます。

# ３.記事の対象者を冒頭で伝える
エンジニアブログを訪れる大半の方はエンジニアだと思うのですが、エンジニアにもレベルの差が当然あります。
例えば**Unityで作ったプロジェクトをAndroidでビルドする！という記事を書いたとして、**
読む相手がUnityの存在をこの記事で知るかもしれないし、Unityは知っているけどAndroidビルドはした事ないとか、いろんなレベルの方が記事を見る可能性があります。

記事として書く上で、まず**Unityとは！**　**Androidとは！**　**ビルドとは！**　**AndroidSDKとは！**と、いちいち解説していたらとんでもなく長くなりますし、内容の本質である**ビルドをする手順を知りたいだけの人にとっては早く本題書けやという気持ちになるだけでクソまとめサイトを読んでいる気分になってしまいます。**（いかがでしたでしょうか？

なので出す記事は全て、どの程度のユーザーに対して向けた記事であるということをなるべく記事の序盤で伝えるようにしました。
例えば先ほどの例だと記事の最初の方に
・この記事ではUnityをインストール済みで基本的な操作は理解している人向けに解説します
みたいな一文を加えています。

また、導入の手順がしょっちゅう変わるようなSDKであったり、情報が古くなった時にこの手順でやられると困る、みたいな手順に関しては公式のスタートガイドのページを貼ったりしておくようにも心がけました。

# 4.社内で文化として根付かせる
~~これはまだ実現できてない事ではあるのですが~~エンジニアブログは一人だけでは絶対に回りません。書いてもらう様に依頼したり書く時間を業務として割いてもらえる様な理解が必要です。
幸い私の会社ではその辺の理解はあったためスムーズでしたが、まだ書いてもらう文化は浸透していないのが現状です。
なので更新の度に会社のSlackなどで告知をしたりして、**会社としてこんな事をやっているんだと言う当事者意識を持ってもらえるよう動くのが大切です。**

また、エンジニアブログの編集長的な人間は必要ですが記事のリリース手順やブログのメンテナンス手順などはしっかりドキュメント化しておき、属人化させないようにしましょう。編集長的な人間が辞めた瞬間に更新止まるエンジニアブログとか、よく聞く話かと思います。

# まとめ　エンジニアブログを作る意義
駆け足でエンジニアブログ作る上で意識した点を紹介しましたが如何でしたでしょうか。事例の一つとして参考にしていただければと思います。

正直任せられた時は「会社のエンジニアブログを作る上で自分個人にメリットはあるのか？」と思っていたのですが、個人ブログよりも伸びやすいので書いた記事がいろんな人に見てもらえると言うのはメリットの一つだと思います。また業務としてアウトプットができる（仕事の時間を使える）と言うのも良くて、アウトプットの習慣付けにもなります。
勿論、記事に関してコメントをしてくれる方や日に日に上がるPV数などもモチベーションに繋がると思います。

後はまぁ、転職の時とか見せれるものが増えるので多少は有利になるんじゃないでしょうか（知らんけど）

まぁまぁ駄文ですがこの記事が誰かの参考になれば幸いですー。
なぜなにTJBot / TJBot zeroよくある質問と答え

この記事は[TJBot Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tjbot) 2日目の記事です。

１日遅れですが、寄稿します。(って毎日言いながら寄稿するのかな、って戦々恐々としてます
よくある質問と答えをまとめてこの記事に書いていきます。
自分自身が聞かれたことが中心なので、すごく偏りがあるかもしれません。
また記事のコメント欄で質問を常時受け付けていますので気兼ねなくどしどしお願いします。

# TJBotって何？

１日前の記事を書いたのでまずはこちらを参考にしてください。

[TJBot / TJBot zeroってなぁに？](https://qiita.com/ssakaigawa/items/3e7ee0f2de421a3d9a39)

# どこで手に入るの？
無償で公開されているレーザーカット用のデータ、3Dプリンタのオブジェクトデータなどで、
ご自身で制作する事ができます。(TJBot zeroは3Dプリントデータは未公開。誰かつくってー（他力本願）)

パーツリストなども公開されているため、ハンズオンと同じ構成で組み立てることも可能です。
パーツ集めも部品点数が割と多めだったり、入手が面倒なもの、加工が必要なものも多数あり、
電子工作の経験が無い方などがすべてを自分で対応してみようとするとちょっと根気が必要です。

## 自分でコツコツ部品を集めて買いたい方
後日公開の記事で最新パーツリストを公開しますのでもうしばらくお待ちください

## セットになっているものを買いたい
TJBotはAdafruitという海外のサイトがAdafruit版TJBotキットとして販売されています。
TJBot zeroは[TJBot Fanコミュニティショップ](https://shop.tjbotfan.tokyo)でキットを購入することができます。

## 体験したい方
キット貸出で、TJBot zeroを作って操作してみる体験ハンズオンを各地で開催しています。
[TJBot Fan コミュニティサイト](https://tjbotfan.tokyo)にイベント情報を掲載していますので、
ぜひお近くで開催されるイベントなども参加してみてください

# 1日目の写真で乗っていたステンドグラスのTJBotって何？

![D2TnmYGU8AAnVwx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126158/1d5d93e3-e8e0-353c-e995-8bf127112277.jpeg)

右側のガラスの子はステンドグラス用のガラスをカットして制作したTJBotです。
家内がステンドグラス初めてすぐ取り掛かった作品です。
真中のオリジナルTJBotのレーザーカット図面からガラス用に改めて厚さ調整・中の構造変更を行って制作しています。
ガラス同士はハンダで接合しているため、パーツをあやまって触れるとショートするという問題がこないだ発覚しました。
中身はRaspberry pi 2Bが乗っていますが、中身はTJBot zeroのアンプキットが乗っています。
口のところは12桁のLCDディスプレイになっています。



## 質問どしどしお待ちしています。
最近勉強して知ったこと、まとめてみた２

## はじめに
Qiitaアドベントカレンダー３日目です。
今日も最近学んだことについて自分なりにまとめていきたいと思います。

## BDD(ビヘイビア駆動開発)
TDD（テスト駆動開発）から発展したもの。
TDDと同様、テストコードを書くが、「要求される仕様」に近い形でテストコードを記述する。仕様（スペック）とテストがかなり近いものとなるので、BDDでは、「スペックファースト」となる。私は、Rubyを使ったプロジェクトの開発で、Rspecを使いました。

## REST
リソースを扱うための考え方である。
リソースはそれぞれ固有のURIを持っていて、そのURIにアクセスすることで、それぞれのリソースを操作することとなる。操作はHTTPのメソッドを正しく使うことで行う。

|メソッド |役割 |
|---|---|
|GET  |リソースの取得  |
|POST  |リソースの新規作成  |
|PUT  |既存のリソースのアップデート  |
|DELETE  |リソースの削除 |

## form_with,form_for,form_tagの違い
form_tagは以前まで、modelがない場合に使用されていたもので、逆にform_forはmodelがある場合に使用されていました。ですがRails５.１以降では、modelの有無に関係なく、２つを統合したようなform_withができたので、今はform_withを使うことが推奨されている。(url,modelの指定など可能)

## HTMLフォーム
ユーザとWebサイトやアプリケーションの対話の要となるもの。
フォームによって、ユーザはWebサイトへデータを送ることができる。
だいたい、１つ以上のウィジェットとで作られ、テキストフィールド、エリア、セレクトボックス、ボタン、チェックボックス、ラジオボタンなどがある。
ウィジェットには、用途を説明するためのラベルがついていることが多い。
フォームで集めたデータは、だいたいWebサーバに送られる。

## 最後に
Ruby on Railsなどで開発をしていると学ぶことが多くて大変です。:sweat_smile: 初めてのことが多くて躓くことが多いですが、その度に、トライアンドエラーで乗り越えることが大切だなって最近思います。まだ、説明が曖昧なのでもっと勉強して、知識の幅を広げていきたいと思います。
Goでsliceをappendすると予想と違う動作をするらしい

# はじめに
こんにちはRIN1208です。今回は[ITRCアドベントカレンダー](https://adventar.org/calendars/4759)の二日目の記事です。  
今回書くのは本日12月2日に六本木ヒルズで行われたStep up Go で初めて知って今後もハマりそうなことを勉強しましたので忘れないように書いていきたいと思います。  

実行環境は[play.golang](https://play.golang.org/)を使用します(なぜかmacだと問題を再現できませんでした)

#今回の問題
```go

package main

func main() {
    a := []int{1, 2, 3}
    b := append(a, 4, 5)
    a[0] = 10
    c := append(b, 6, 7)
    b[1] = 20
    println(c[0] + c[1])
}
```

こちらのコードです。  
実行すると....

```
21
```


**は??????**

なんで？？？3じゃないの?と思いました。普通ポインタとスライスの中身を見てみると

```go

package main

import "fmt"

func main() {
	a := []int{1, 2, 3}
	b := append(a, 4, 5)
	a[0] = 10
	c := append(b, 6, 7)
	b[1] = 20
	
	println("%p", a)
	println("%p", b)
	println("%p", c)

	fmt.Println(a, b, c)

	println(c[0] + c[1])
}

```
出力結果

```
%p [3/3]0x40e020
%p [5/8]0x456000
%p [7/8]0x456000
[10 2 3] [1 20 3 4 5] [1 20 3 4 5 6 7]
21

```

bとcが同じポインタ??????

goのsliceは[こちら](https://golang.org/pkg/reflect/#SliceHeader)のような構造になっているらしいです。  

また同じポインタを参照しているので反映されてしまっているみたいです。  



ちなみにcapを更新?するとポインタも変わるみたいです

``` go
package main

import "fmt"

func main() {
	a := []int{1, 2, 3}
	b := append(a, 4, 5)
	a[0] = 10
	c := append(b, 6, 7)
	b[1] = 20
	d := append(c, 6, 7)
	c[1] = 30

	println("%p", a)
	println("%p", b)
	println("%p", c)
	println("%p", d)

	fmt.Println(cap(a), cap(b), cap(c), cap(d))
	fmt.Println(a, b, c, d)

	println(c[0] + c[1])
}
----------------------------

%p [3/3]0x40e020
%p [5/8]0x456000
%p [7/8]0x456000
%p [9/16]0x430080
3 8 8 16
[10 2 3] [1 30 3 4 5] [1 30 3 4 5 6 7] [1 20 3 4 5 6 7 6 7]
31

```


#結論
goの配列は途中保存するときは上記の書き方ではなくcopy関数を使用し別の変数に格納した方がいいみたいです

#終わりに
今回、自分の未熟さゆえに曖昧な部分が多いのに加え適切な言い方ではない箇所があるためとてもいい記事ではないと思います。ですが今回初めてこんな挙動をすると知ったので知らない人に知っていただければと思い書きました。また本記事について詳しく知っている方はコメントにて教えて頂けるととても助かります。
VirtualBoxのインストールやdocker-QuickstartTerminalのhost-only adapterの作成が失敗して、再起動やVBのバージョン変更でも直らなかった時用の記事

#背景1
windows 10 Proでdocker-QuickstartTerminalを実行しても下記のようなエラーメッセージが表示されてインストールが完了しなかった…

```
Running pre-create checks...
Creating machine...
(default) Copying C:\Users\me\.docker\machine\cache\boot2docker.iso to C:\Users\me\.docker\machine\machines\default\boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to create a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Creating a new host-only adapter produced an error: C:\Program Files\Oracle\VirtualBox\VBoxManage.exe hostonlyif create failed:
(default) 0%...
(default) Progress state: E_FAIL
(default) VBoxManage.exe: error: Failed to create the host-only adapter
(default) VBoxManage.exe: error: Querying NetCfgInstanceId failed (0x00000002)
(default) VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component HostNetworkInterfaceWrap, interface IHostNetworkInterface
(default) VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleCreate(struct HandlerArg *)" at line 71 of file VBoxManageHostonly.cpp
(default)
(default) This is a known VirtualBox bug. Let's try to recover anyway...
Error creating machine: Error in driver during machine creation: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue
Looks like something went wrong in step ´Checking if machine default exists´... Press any key to continue...
```
[GitHubのissue](https://github.com/docker/machine/issues/4066)でも似たようなケースが報告されているが、再起動やVBのアップグレード、パーミッションの変更で解決している。が、なぜか幣PCでは解決しない、やむ（夢見りあむ）

#背景2
あと大学の講義でVBをインストールする際、ほぼ全員のPCでインストールが失敗して阿鼻叫喚だったりのケースも下記の対策で解決したので併記しておきます。

#対策
（インターネットから切り離してから）セキュリティソフトを止めてみてください（弊環境ではウイルスバスターcorpでした）
止めてから再インストールすると無事に入ります。

#理由
VirtualBoxでのホストオンリーアダプター作成時、セキュリティソフトの影響で作成が失敗してるもようです。
```
VBoxManage.exe: error: Failed to create the host-only adapter
```
GUIからのインストールだとエラーメッセージが表示されないのでわかりづらいですが、ログファイルみるとおそらく同じような記載があると思われます。
ウイルス定義ファイル内にホストオンリーアダプターの作成が含まれてたりするんですかね…
PyTorchを使った株価予想

# PyTorchを使った株価予想

https://qiita.com/creaith/items/f47c33e78fb97349b4c8
を参考にAnacondaとPyToachをインストール

メモ：PyToachをインストールするときにAnacondaを管理者権限で立ち上げないとエラーになった


https://github.com/melissa135/mlp_stock
のソースを使用する。
学習したAIで中国？のETFを売買したときの資産推移を予想してくれるようです。

READMEには以下のように書かれている。
（MLPは multi layer perceptronのこと）

===================
・Usage
1. Run `train_net.py` to train a group of MLPs with `sz_train.csv`, saved in `/MLPs`.
2. Run `test_net.py` to predict stock market trend (in `sz_test.csv`) using ensemble MLP.

・Result
The train error rate (black) and test error rate (red) of a single MLP, changing with epoches.
![](https://github.com/melissa135/mlp_stock/blob/master/error_rate.png

The red line is asset sequence if we buy/sell CISSM-ETF according to our ensemble MLP, comparing with CISSM (black).
![](https://github.com/melissa135/mlp_stock/blob/master/asset.png) 

===================

メモ：mlp_stock-masterの中のcsvには一、二、三、四、五という中国語文字が入っているため、train_net.pyを使用するとエラー。notepad++で1,2,3,4,5にreplaceして解決した。

train_net.pyとtest_net.pyを実行しグラフが作成されましたが、まだどういう事か理解が追い付いてないです。

理解が深まり次第更新していきます。
グローバル・プライベート（ローカル）MACアドレスの見分け方

# 追記(2024-09-17)
- 実際には`2,6,A,E`を確認すれば良いとのこと
- [How to Identify Private MAC Addresses](https://www.oasys.net/fragments/identify-private-macs/#:~:text=This%20is%20the%2002%20bit,it%20is%20a%20private%20MAC.)


>This is the 02 bit of the first octet in the MAC. If it is set, this is a locally-administered address. Essentially, if the second hex digit is 2, 6, A, or E, it is a private MAC.
>
>x2:xx:xx:xx:xx:xx
>x6:xx:xx:xx:xx:xx
>xA:xx:xx:xx:xx:xx
>xE:xx:xx:xx:xx:xx
>

>What about MAC addresses with the next bit set, such as when the first octet is 03 or 07? Those still have the local bit set. Yes, but the 01 bit is the unicast/multicast bit (individual/group, I/G bit). We seldom see use of locally-administered multicast layer 2 addresses, so can be ignored for the purposes of “private MAC addresses”.

---

# 概要

- 下記の図より、上位8bitの`b1`部分が1ならばプライベートMACアドレスである。
- つまり16進数表記のMACアドレス`x○-xx-xx-xx`を考えると、`○`の部分が`2367abef`のいずれかならばプライベートMACアドレスである。（後述の進数対応表を見ると分かりやすいかと思います。）

>[MAC address](https://en.wikipedia.org/wiki/MAC_address#Address_details)より引用

> ![](https://i.imgur.com/HuKeudg.jpg)

|10進数|2進数<br>（右から二桁目が0か1か）|16進数|isPrivate|
|:---:|:---:|:---:|:---:|
|1|0001|1||
|2|0010|2|○|
|3|0011|3|○|
|4|0100|4||
|5|0101|5||
|6|0110|6|○|
|7|0111|7|○|
|8|1000|8||
|9|1001|9||
|10|1010|A|○|
|11|1011|B|○|
|12|1100|C||
|13|1101|D||
|14|1110|E|○|
|15|1111|F|○|

# 参考
* [EthernetでのID「MACアドレス」を理解する](https://ascii.jp/elem/000/000/417/417556/)
    * 主に上記を参照しました
* [MAC address](https://en.wikipedia.org/wiki/MAC_address#Address_details)
* [MACアドレス](https://ja.wikipedia.org/wiki/MAC%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9)
* [MACアドレスっぽいものを生成する](https://www.boldweb.jp/genmac/)
    * ランダムなMACアドレスの生成に使用

# Code（Objective-C）
- プライベートMACアドレス識別用の関数

```objc
/**
 @brief プライベートMACアドレスかどうか
 */
- (BOOL)isPrivateMACAddress:(NSString *)macAddress {
    // 2文字目が下記ならプライベートMACアドレス
    NSCharacterSet *privateMACAddressCharSet = [NSCharacterSet characterSetWithCharactersInString:@"2367abefABEF"];
    return [privateMACAddressCharSet characterIsMember:[macAddress characterAtIndex:1]];
}
```

- 呼び出し例

```objc
NSArray *macAddresses = @[@"5924a970c0a2",
                          @"723d614ed27a",
                          @"55002cd18b38",
                          @"e193cb9c4945",
                          @"3a60d8d5551e",
                          @"c5c08c6cc511",
                          @"42a8887ccb5e",
                          @"76c209ad50b2",
                          @"3b4d3a1db4b5",
                          @"8d9b8ad08047",
                          ];
for (NSString *macAddress in macAddresses) {
    if ([self isPrivateMACAddress:macAddress]) {
        NSLog(@"'%@'はプライベートMACアドレスです。", macAddress);
    }
}
```

- 出力結果

```sh
'723d614ed27a'はプライベートMACアドレスです。
'3a60d8d5551e'はプライベートMACアドレスです。
'42a8887ccb5e'はプライベートMACアドレスです。
'76c209ad50b2'はプライベートMACアドレスです。
'3b4d3a1db4b5'はプライベートMACアドレスです。
```
Powershellで色々とJSON形式に変換する

# Powershellで色々とJSON形式に変換する。

PowershellのConvertTo-JSONを使って何でもJSON形式にしてみる。

ソースコード
https://github.com/digitalMagicbox/ConvertToJSON

## CSVファイル

### 1.CSVは、Import-CSVがあるのでとても簡単。

１行目をキーとして変換します。

```powershell:CsvToJson
Import-CSV $csvfilename -Encoding Default | ConvertTo-Json | Out-File -FilePath $jsonfilename -Encoding UTF8 
```

```csv:入力：CSVファイル
Item1,Item2,Item3,Item4,Item5
1AAAA,1BBBB,1CCCC,1DDDD,1EEEE
2AAAA,2BBBB,2CCCC,2DDDD,2EEEE
3AAAA,3BBBB,3CCCC,3DDDD,3EEEE
```

```json:出力：JSONファイル
[
  {
    "Item1": "1AAAA",
    "Item2": "1BBBB",
    "Item3": "1CCCC",
    "Item4": "1DDDD",
    "Item5": "1EEEE"
  },
  {
    "Item1": "2AAAA",
    "Item2": "2BBBB",
    "Item3": "2CCCC",
    "Item4": "2DDDD",
    "Item5": "2EEEE"
  },
  {
    "Item1": "3AAAA",
    "Item2": "3BBBB",
    "Item3": "3CCCC",
    "Item4": "3DDDD",
    "Item5": "3EEEE"
  }
]
```

## レジストリファイル

### 1. Subkey内のキーをメンバーとしたオブジェクトを作成する。

* 型は、とりあえずDWORD型、文字列型だけに対応。
* 正規表現で文字列を分解する。
* オブジェクトを作成する。
* メンバーに値を格納する。

```powershell
$obj = $l -match '^\"(?<Name>.*)\"=(?<Type>(\"|dword:))(?<Value>.*)$' | 
ForEach-Object { New-Object PSObject -Property $Matches } | 
Select-Object -Property Name, Type, Value
```


### 2. ルートキーは、HKLMなどの省略形に置換する。
```powershell
# ルートキー置換用のリスト
$replacerootkeys = @{
    'HKLM' = 'HKEY_LOCAL_MACHINE';
    'HKCU' = 'HKEY_CURRENT_USER';
    'HKCR' = 'HKEY_CLASSES_ROOT';
    'HKU'  = 'HKEY_USERS';
    'HKCC' = 'HKEY_CURRENT_CONFIG';
}
# サブキーを囲んでいる”[”と”]”を消す。
$subkey = $l -replace '\[|\]', ''
# ルートキーを置換する。
foreach ($rootkey in $replacerootkeys.GetEnumerator()) {
    $subkey = $subkey -replace $rootkey.Value, $rootkey.Key
```

```ini:入力：レジストリ
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE¥¥Software¥¥SubKey1]
"Key1"=dword:00000001
"Key2"="Value2"
"Key3"=""

[HKEY_CURRENT_USER¥¥Software¥¥SubKey2]
"Key4"=dword:000000FF
"Key5"="ABCDEFG"
"Key6"="[]"

[HKEY_CURRENT_USER¥¥Software¥¥SubKey3]
```

```json:出力：JSONファイル
[
  {
    "Subkey": "HKLM¥¥Software¥¥SubKey1",
    "Key1": 1,
    "Key2": "Value2",
    "Key3": ""
  },
  {
    "Subkey": "HKCU¥¥Software¥¥SubKey2",
    "Key4": 255,
    "Key5": "ABCDEFG",
    "Key6": "[]"
  }
]
```

## INIファイル

### 1. セクションで１つのオブジェクトにする。

```powershell
# セクションを囲んでいる”[”と”]”を消す。
$sec = $l -replace '\[|\]', ''
# 空のオブジェクトを作成
$keys = @{ }
# ConvertFrom-StringDataで変換するために、セクションをKey=Value形式にする。
$l = "Section=" + $sec
```

### 2. KeyName=Valueの形式は、「ConvertFrom-StringData」でオブジェクトに変換できる。

```powershell
# ”+=”でオブジェクトに追加していく。
$keys += ConvertFrom-StringData($l)
```

```ini:入力：iniファイル
[Section1]
Key1=Value1
Key2=Value2

[Section2]
Key2-1=Value2-1
Key2-2 = Value2-2

[Section3]
Key3=

[SEction4]
```

```json:出力：JSONファイル
[
  {
    "Section": "SEction4"
  },
  {
    "Key2": "Value2",
    "Section": "Section1",
    "Key1": "Value1"
  },
  {
    "Key2-1": "Value2-1",
    "Section": "Section2",
    "Key2-2": "Value2-2"
  },
  {
    "Key3": "",
    "Section": "Section3"
  }
]
```
プログミラミング学習始めて６週間、感動した関数

プログラミングを学んで**２ヶ月**が経過しました。
主にHTML, CSS, Java Script, PHPの学習をしました。
学んだ事は山のようになるのですが、その中でも今回は個人的に驚いた関数をランキング形式で記載します。
初心者のただの忘備録です。

#ベスト３ PHPの日付取得
JSしか知らない時は、日付取得って結構大変なんだなと驚きました。
書いていたコードこちら。

```javascript
$(function() {
  var now = new Date();
  var y = now.getFullYear();
  var m = now.getMonth() + 1;
  var d = now.getDate();
  var w = now.getDay();
  var wd = ["日", "月", "火", "水", "木", "金", "土"];
  const today_time=(y+"年"+m +"月"+d+"日"+"(" + wd[w] + ")");
  console.log(today_time);
  $("#today").text(today_time)
});
```

いや〜プログラムで日付取得って結構大変じゃん！と毎回思いながらコピペ。
それがPHP学んだ途端に出てきた

```PHP
<?= date(Y年m月d日)?>
```
これだけで取得と言うことに衝撃を受けました。
なんやこれ！？この１ヶ月私は何をしてたんや！？
と思いました。

#ベスト２ Hash
これすごくないですか！？この４文字導入するだけですごい暗号作ってくれる！！何これ！？
感動しました。

#ベスト１ 新しいファイル作成

```PHP
$file = fopen("data/data.txt","a");
```
PHPのコレです。
あったものに上書きとか追加ならまだわかるものの、ないのを作る、存在しないものをゼロから作ってるんですよ、この１文字です。
授業中思わず声が出た関数です。
みんな結構普通でしたが、すごくないですか！？私びびったんですけど。
ある意味怖いとも感じた関数です。

余談
アルゴリズムの授業で２進数、８進数、１６進数を学美ました。私バカなのでイマイチ２進数とかのイメージがつかず、自分で簡単な電卓を作ったんです。理解を深めるために。
その時に驚いたのがparseInto, toString 。
これで10進数が一瞬で2進数に！！
驚きました！！

来週は制作物をあげられれば良いなと思っています。
(ただ今JSと戦っている最中です。機能１個付けるのにまだまだ時間がかかります）
arduinoでRS485を使用する

とある仕事でOMRONの温度調節器[E5GC](https://www.fa.omron.co.jp/products/family/3370/)を使うことになりました。
![E5GC](https://www.fa.omron.co.jp/Images/l_3370-14-217303-198x198.jpg)
この機器を外部からコントロールするにはRS485でやり取りする必要があります。
ネットで調べてみるとこの形のRS-485モジュールがいっぱい出てきます。
![M485-4P](https://www.aitendo.com/data/aitendo/product/20140911_52bb1e.gif)
値段も安いし買ってみました。
通信方法はarduinoから Serial.write() でデータを送り、 
Serial.read() でデータが返ってくるというとても単純なものです。
実際に試してみたところ、ちゃんと問題なく動作はするのですが、
![IMG_8318.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/723998e9-6ae6-77e1-6318-995c9b4d6de0.jpeg)
幅がありすぎてブレッドボードに刺さらず、ちょっと試すのに不便です。
機能も単純そうだし、IC単体でも行けるかなと思い探してみました。
![LTC485 CN8](http://akizukidenshi.com/img/goods/C/I-02792.jpg)
ピンの機能もモジュールと同じ感じだし、ますますいけそうな感じです。
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/a7b67495-9817-4777-a964-1ce7cc18e22c.png)
秋月電子で[こんなの](http://akizukidenshi.com/catalog/g/gI-02792/)を見つけたので試してみたところ
同様に機能しました。
こんな感じでコンパクトにまとまっていい感じです。
ちなみに画像にはありませんが(外れてたの気が付かずスミマセン)、 *AB間に220Ωの終端抵抗が必要です* 
![IMG_8319.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/abddab53-0a08-d7f8-1aa0-68a9c30b8e07.jpeg)
■おまけ
[OMRON CompoWay/F BCC calculator](https://elix.jp/app/tools/omron_bcc.html)
[Modbus CRC calculator](https://elix.jp/app/tools/modbus_crc.html)

![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/6f8b4f8c-2235-a3d3-2e6e-fce9ec1e8440.png)
動く人形キボウちゃんを支える技術


![ezgif.com-optimize (5).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34295/6b9e8e04-aea9-3c30-0f96-d4cc0ea9cc92.gif)

[動く人形キボウちゃん](https://www.pixiv.net/fanbox/creator/44998054)（以後キボウちゃん）とは現在 [Segawa](https://twitter.com/segawachobbies) が開発中の機械が内蔵された人形です。ソフトウェアは OpenSiv3D を基本として、動きの情報の入力、関節角度の計算、サーボモータへの出力の三段階で構成されています。これから各段階で使用したライブラリ等について紹介します。

# 入力

動きの情報の入力として、モーションキャプチャのトラッキングデータを活用します。 
現在は OpenVR によってトラッキングデータを取得しています。
https://github.com/ValveSoftware/openvr

OpenSiv3D からかんたんに使えるように OpenVRManager と呼ばれるラッパーを作りました。

```cpp
//VR Device
OpenVRDevice device;
device.init();

//略

if(device.isActive())
{
	device.update();
	targetPos1 = GetTargetPos(device.getRightControllerPos());

//略
```

また、MMD のモーションデータ（.vmd）の再生や Switch のコントローラ、ゲームパッドにも対応しています。
近いうち OpenSiv3D に LeapMotion、Kinect、Realsense、顔認識が実装されると思われますので基本全てに対応します。

# 処理

リンク機構のシミュレーションや逆運動学 (IK) 処理には線形代数ライブラリ Eigen を使用しています。
目標とする姿勢を入力すると、それを実現する角度を算出する処理を実装しました。
http://eigen.tuxfamily.org/index.php?title=Main_Page

# 出力

サーボモータはすべて Robotis の Dynamixel シリーズを用いているため、サーボモータへの角度制御には Dynamixel SDK を使用しています。
https://github.com/ROBOTIS-GIT/DynamixelSDK

これも OpenSiv3D からかんたんに使えるように DynamixelManager と呼ばれるラッパーを作りました。

```cpp
//Dynamixel
Dynamixel dyna1;
dyna1.connectPort(U"COM3", Dynamixel::BaudRate::Rate1000000, ham::ProtocolType::Protocol2);

//略

dyna1.setWriteRequest(ham::XL320_GoalPosition(4), GetXL320ValueFromRad(motorAngles1.x));
dyna1.sendData();
```

# おわりに

今回紹介した機能は将来的に OpenSiv3D の機能の一部として実装される予定です。
キボウちゃんのプロジェクトは、小規模の量産と普及を一つの目標として取り組んでいます。

また、本プロジェクトは現在は個人で進めており、応援してくださる方を募集しています。
よろしくおねがいします。
https://www.pixiv.net/fanbox/creator/44998054
（最新情報もこちらで公開しています。）
BitVisorのNMI処理の競合対策

ご存知の通りBitVisorのNMI処理には以下のパターンがあります:

* 仮想マシン上のプログラムを実行中のNMI - #VMEXITで処理
* ハイパーバイザーを実行中のVMI - NMIハンドラーで処理

いずれにしても、VMM側のpanicの場合を除き、仮想マシン上のオペレーティングシステムのNMIハンドラーが呼び出される形になります。

それで、#VMEXITであればすぐにNMIをinjectすればいいし、NMIハンドラーが実行された場合は内部でカウンターをインクリメントしておき、適切なタイミングでinjectすればいいのですが、特にvmlaunch/vmresume/vmrun命令の周辺では、際どいタイミングというものが存在するわけです。それをどう対策しているのか簡単に紹介します。

# Intelプロセッサ用

Intelプロセッサの場合NMIをマスクすることができません。そのためvmlaunch/vmresume命令の直前までNMIが発生する可能性があります。それを逃さず処理する仕掛けがあります。

その仕掛けを設定している部分は、`core/asm.s`の中を`%gs:gs_nmi_critical`というキーワードで検索していただくと見つかります。vmlaunch/vmresume命令を使うより前にここにアドレスを設定し、後で0を設定しています。このアドレスに書き込まれている3つのアドレスは、順に、際どい部分の開始アドレス、際どい部分の終了アドレス(範囲の次のバイト)と、際どい部分を実行中にNMIが発生した場合の戻り先のアドレスを表します。この範囲内を戻り先アドレスとするNMIが発生したら、戻り先アドレスを書き換えて、残りの部分は強制的にすっ飛ばしてしまう仕掛けです。

そして、この範囲内で`%gs:gs_nmi_count`をチェックします。これは通常のNMIの際にインクリメントされます。範囲外でNMIが発生して、そのままここに来た場合はこのチェックに引っかかり、NMI用の脱出口にジャンプするのでvmlaunch/vmresume命令は実行されません。範囲内でNMIが発生した場合はNMIハンドラーから戻り先のアドレスが変更され、強制的に同じ脱出口にジャンプします。

なぜこのような範囲を設定しているかというと、vmlaunch/vmresume命令を実行する直前までは、すっ飛ばして欲しいけれど、実行した後は、そのVM Exitを処理する必要があって、すっ飛ばしてほしくないためです。NMIがマスクできない以上、際どい部分はそのようにNMIハンドラー側で何とかする必要がありました。

NMIハンドラーは`core/nmi_handler.s`にあります。戻り先のアドレスを見て差し替える処理があります。

# AMDプロセッサ用

AMDの場合はSVMの機能によりNMIをマスクできますのでもう少し簡単です。`core/asm.s`の中を見ていただくと、vmrun命令より手前にclgiという命令があります。これが、NMIを含めて割り込み禁止にする命令です。(sti命令でセットされる割り込み許可フラグよりも優先されるので、clgiを実行した状態では外部割り込みもすべて発生しません。) この状態で`%gs:gs_nmi_count`をチェックすれば、ここからvmrun命令までにNMIが発生して値が変化することはありません。

vmrun命令はclgiのまま実行します。仮想マシン上に実行が移った時には自動的にstgiを実行したのと同じ状態になっており、NMIも受け付けられます。clgi命令実行後にNMI信号が入っていた場合、そのNMIはvmrun命令の直後に受け付けられ、即座に#VMEXITとなります。

また、#VMEXIT後はclgiの状態になるので、必要なレジスターの切り替え処理後にstgi命令を実行してNMIを受け付けられるようにしています。
あなたはMySQLの挙動を本当に理解していますか？

#はじめに
この記事は、[CyberAgent 20新卒 エンジニア Advent Calendar 2019](https://adventar.org/calendars/3976)の3日目の記事です。

今回の記事は今年の夏に内定者バイトを行った際に、
僕「sqlでORDER BYをつけない場合の並び順ってprimary key順じゃないんですか？」
トレーナーさん「それは実行計画に依存するかな」
僕「？」
となったので、自分なりに調べたことをまとめたものになります。

内定者バイトの記事はまた後日書きます(遅くなっており本当に申し訳ございません。)。
ちなみに内定者バイトではこういうことをしていました。
https://twitter.com/ue_knnk/status/1192731466070806530

#実行計画とは
SQL文はざっくりと以下の図のように処理されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/b3b8f1a5-f121-f395-ad3e-f2d99851a724.png)

つまり、実行計画とは統計情報を元にオプティマイザが、どのようにデータアクセスを行いSQLを実行するかをまとめたものになります。

#実験
それでは本題のORDER BYをつけない場合の並び順はprimary key順なのかについて実験していきます。

MySQLのバージョンは8.0.18です。
また、ストレージエンジンはバイト先に合わせ、InnoDBを使います。

まず、日付をprimary keyとして降順に初期データを投入します。
イメージとしては動画配信サイトのコメントのテーブルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/ae990560-afc3-8512-a65e-912eb6974e8e.png)

InnoDBのデータ構造はクラスタードインデックスなのでprimary keyを持つテーブルの場合データはprimary keyのキー値でソート済みになっています。
なので、ORDER BYをつけなくてもprimary key順になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/52760098-8e3a-edcc-78ec-e6565f144e0a.png)

実行計画も見てみるとインデックスを使っていないことが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/f54f74d3-a01f-233f-eb84-640d5bf2ed91.png)

次にインデックスを使うようにsqlを実行すると、インデックスで指定したキー順が優先されて並んでいることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/bfefc5e3-3596-eddc-c867-de55c44972c3.png)

実行計画を見ると、インデックスを使っていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/81f6f7df-d784-2156-512b-e80df8a824df.png)

このように実行計画でインデックスを使用している場合、インデックスのキーが優先されてソートされるため、primary key順で並べたい場合は以下のようにORDER BYをつけてsqlを実行する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154457/63b62c82-1c80-80a2-5c77-adfefd39896a.png)

#まとめ
今回は内定者バイト中に思った、考えてみたらそうだなあってなったことを調べて、まとめてみました。
挙動を理解していないとトラブルになりかねないので、知っておいて損はないのではと思います。
今回の例だと、動画配信サイトのコメントは基本的に投稿順で表示するため、primary key順でソートされていないと困りますよね。
読んでいただいてありがとうございます。

#参考
https://blog.kamipo.net/entry/2016/12/24/234944
https://qiita.com/at_1016/items/33186523cfc20fb58675
【LINE Messaging API】Pythonでオウム返し BOTを作成



##チュートリアル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331630/f51262c3-35e7-4e99-c3aa-8f6df57dc030.png)

####【メッセージを受信する場合】
WebhookHandlerを下記の様に設定
@handler.add(MessageEvent, message=**TextMessage**)

```python:lineapi.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('YOUR_CHANNEL_SECRET')


@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))


if __name__ == "__main__":
    app.run()
```
[**LINE Messaging API SDK for Python**](https://github.com/line/line-bot-sdk-python)の**Synopsis/Usage**から引用


####【メッセージをリプライ】
reply message API（ line_bot_api.**reply_message**）を呼ぶ
引数を、下記にすることで、オウム返しされる
・event.reply_token
・**TextSendMessage**(event.message.text)


####＜event＞
handle_messageメソッドの引数(**event**)

```json:event
{
  "message": {
    "id": "10951288714213",
    "text": "Hello",
    "type": "text"
  },
  "replyToken": "73fb2d4ab910457443a96c3483f478dc",
  "source": {
    "type": "user",
    "userId": "U0d47ada1d7ca738641228d4599c9d347"
  },
  "timestamp": 1574264703712,
  "type": "message"
}
```







##引用
[LINE Messaging API SDK for Python](https://github.com/line/line-bot-sdk-python)
kintone + Backlog API 連携やってみた

kintone Advent Calendar 2019 ２日目の記事です。

kintone と Backlog API の連携をやってみました。
とりあえずkintone側からBacklogのAPIを叩いてデータが取れるところまでで時間切れとなりました。

続きはBacklogのAdvent Calendarでやります。

# 対象読者 or 前提条件 or 環境

* Backlogとkintoneを連携したい方

# 取り急ぎコード

```javascript
(function() {
  'use strict';
  kintone.events.on('app.record.index.show', function(event) {
    const APIKEY = "<API-KEY>";
    const BACKLOG_URL = "<URL>";
    kintone.proxy(BACKLOG_URL + '/api/v2/users/myself?apiKey=' + APIKEY, 'GET', {}, {})
    .then(function(resp)
    {
      console.log(resp[1], JSON.parse(resp[0]), resp[2]);
      const body = JSON.parse(resp[0]);
      kintone.proxy(BACKLOG_URL + '/api/v2/users/' + body.id + '/activities?apiKey=' + APIKEY, 'GET', {}, {})
      .then(function(resp)
      {
        console.log(resp[1], JSON.parse(resp[0]), resp[2]);
      });
      return event;
    }).catch(function(error) {
      console.log(error);
      return event;
    });
  });
})();
```

# ログ

スクリーンショットです。
<img width="970" alt="スクリーンショット 2019-12-02 23.54.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/a2390f29-e1cd-362e-4f16-7dd5a07d586e.png">

# 参考

- [Backlog APIを使って自分のアクティビティを調べよう](https://dev.classmethod.jp/tool/get-activity-using-backlog-api/)
- [Backlog API とは](https://developer.nulab.com/ja/docs/backlog/#backlog-api-%E3%81%A8%E3%81%AF)
- [Backlog ショーケース](https://backlog.com/ja/developer/showcase/)

# 次にやること

良い感じにkintoneにレコード登録する

# あとがき

思ったより時間がかかった。