OmniAICreator/Qiita-1.07M huggingface dataset:
Clovaで「抵抗値換算」のスキルを作ってみる（１）

# はじめに
ずっと前にやりかけだった（記事には投稿してない）LINE Clovaの「抵抗値換算」のスキルをちゃんと作ってみました。サーバは[別記事](https://qiita.com/ufoo68/items/48cb29e6a14f2be3f076)と同様に「Firebase」を使いました。

# 「抵抗値換算」について
電子工作に使う抵抗素子には「カラーコード」と呼ばれるものが表示されています。このカラーコードの並びから抵抗値を読み取ることができますが、電子工作に慣れていない人には「カラーコード -> 抵抗値」への変換がすぐには難しいです。そこでこのスキルを使ってClovaの前でカラーコードの色の並びを読み上げて、それを抵抗値に変換したものをClovaに読んでもらうものを作りました。

このスキルでは精密抵抗器を無視した4つのカラーコードの並びで、[このサイト](http://part.freelab.jp/s_regi_list.html)の「よく使われる抵抗の一覧表」の抵抗素子に対応します（ArduinoでLEDやセンサを使う場合は1kか10kの数値のものしか基本は使わないかと）。 

# Firebaseの初期設定
手順については[この記事](https://qiita.com/n0bisuke/items/909881c8866e3f2ca642)を参考にしてます。  
まずはFirebase CLIをインストールします。  
```npm install -g firebase-tools```  
`-g`を使ってグローバルにインストールします。場合によってはpermissionではじかれる可能性もあるので`sudo`が必要かも？  
次にログインします。  
```firebase login```  
ここら辺はターミナルに言われるまま操作すれば問題ないかと。次にプロジェクトを作成します。  
```firebase init functions```  
既存のプロジェクトを選択・新しくプロジェクトを作成する、の2択が選べます。  
次にFirebaseにデプロイします。  
```firebase deploy --only functions,hosting```  
  
## その他の設定
環境変数は以下のコマンドで設定可能です。  
```firebase functions:config:set clova.extension.id="your extension id"```  
環境変数の確認は以下のコマンドを用います。  
```firebase functions:config:get```  
コード上で用いたい場合は、以下のようにして呼び出します。  

```JavaScript
const extensionId = encodeURIComponent(functions.config().clova.extension.id);
```  

また、`firebase.json`は以下のように設定しました。  

```JavaScript
{
    "hosting": {
        "public": "./",
        "rewrites": [{
            "source": "/clova",
            "function": "clova"
        }],
        "ignore": [
            "firebase.json",
            "**/.*",
            "**/node_modules/**"
        ]
    }
}
```

# Clovaの開発について
expressを用いたスキルの開発は[このサイト](https://dotstud.io/blog/clova-cek-nodejs-tutorial/#node-js%E3%81%AE%E7%92%B0%E5%A2%83%E6%BA%96%E5%82%99)を参照して行いました。  
`functions/`上で以下のコマンドを用いて必要なpackageをインストールします。  
```npm install --save https://github.com/TanakaMidnight/clova-cek-sdk-nodejs express body-parser```  
Clovaの公式SDKを用いない理由は[この記事](https://blog.tanakamidnight.com/2018/09/firebase-clova-sdk-node8/)を参照してください。  

## カラーコードから抵抗値への変換
まず連想配列を用意しました。色を`key`に対応する数値を`value`に設定してます。  

```JavaScript:
const colorcodes = { 黒:0, 茶:1, 赤:2, 橙:3, 黄:4, 緑:5, 青:6, 紫:7, 灰:8, 白:9 };
```  
抵抗値の計算は以下の式で求めます

```math
RegistorValue = (FirstColor\times 10 + SecondColore) \times 10^{ThirdColor}
```
`FirstColor ~ ThirdColor`は「金」を最終端としたときの各色です。  

# 進捗
このスキル開発の記事は何回かに分けて投稿します。とりあえず今回はスキル起動時のメッセージのレスポンスと、「カラーコード -> 抵抗値」まで実装しました。こんだけの内容に今日の一日のほとんどを費やしましたw（カラーコードからの変換をCloud Firebaseを使ってやろうとしたけど非同期処理をうまく操れなかったとか、Clovaの公式のSDKとexpressの相性の悪さで悩むとか）また、Clovaのテストは今日は[Clova Developer Center](https://clova-developers.line.biz/#/)のテスト機能を用いました。

## 起動時の挨拶
こんな感じです。
![てすと１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/28ef3238-b266-ef26-e855-37996748cdf2.jpeg)

## カラーコードから抵抗値への変換
こんな感じです。
![てすと２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209689/4df9d384-e3b1-b27d-a8d2-6d306c797333.jpeg)

# 今後やりたいこと
- 「抵抗値 -> カラーコード」への変換
- 1000以上の抵抗値をキロ読みにする
- 「カラーコードの覚え方」のインテントを作る

# さいごに
[レポジトリ公開してます](https://github.com/ufoo68/clovaRegistorValueConverter)。GWまでには完成させたいです。そして[Tシャツ](https://robotstart.info/2018/07/25/clova-tshirts-present.html)欲しいです。
「統計的工程管理」を読んでRで実装　#1

統計的工程管理をオススメされた記憶があったので買って読んでみる。

![103031.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b1f57fef-7476-f1c0-26cd-b54c5a237f3f.jpeg)

vmaskがわからない。

#シューハート管理図
閾値を設定して正常と異常を判断する。
単変量でかつ、閾値が設定しやすいような場合につかえる。
**偶然原因による工程変動に対して異常原因による工程変動を統計的に可視化することが意義であり目的**
3シグマ法を使ったりする


```R
data1 <- rnorm(300, 200, 1)

plot(data1,pch="")
#とりあえず閾値で設定
abline(h=202)
abline(h=198)

for(i in 1:length(data1)){
if(data1[i]>202){
points(i,data1[i],col="red")
}else if(198>data1[i]){
points(i,data1[i],col="red")
}else{
points(i,data1[i])
}
}

```

![0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/8a34b3ae-78b8-f9b3-d2c9-896cc45294cf.png)

普通198~202までしか数値が出ないはずのシステムで3シグマなど閾値設定した部分を超えたものが確認できる。
本文中ではx-R管理図のようにR(=範囲)を設定してサンプルをして採取し、平均を並べていき、閾値を超えるかどうかを見ていた。





ここからデータをつくっておく

```R
data10 <- rnorm(20, 0, 0.5)
data10[10:15] <- c(0, 1, 2, 1, 2, 2)
#10からのデータがだんだん異常と仮定
data = data10-data10[1]
```

#累積和管理図(区間決定法)

```R
plot(1, pch="", xlim=c(0,25),ylim=c(-5,5),main="interval")
abline(h=0, lty=2)
abline(h=5*0.5)
abline(h=-5*0.5)

ARLu<-0
for(i in 1:length(data)){
ARLu <- max((ARLu+data[i]-0.5*0.5),0)
points(i-1,ARLu,type="b",pch=7)
}

ARLl<-0
for(i in 1:length(data)){
ARLl <- min((ARLl+data[i]+0.5*0.5),0)
points(i-1,ARLl,type="b",pch=6)
}
```
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/dd20b425-4ee7-68d5-e897-efd056283696.png)

累積和で0より上側か下側かでplotが分かれている。
10を超えたあたりから累積和が上がり始めている。

#累積和管理図(Vマスク法)


```R
plot(1, pch="", xlim=c(-1,25),ylim=c(-5,10),main="Vmask")
abline(h=0, lty=2)

tan_theta <- (1*0.5-0)/(2*0.5)
dd= (-2*((0.5)**2)*exp(0.00135)) / ((1*0.5-0))
hh=dd*tan_theta
kk=0.5*tan_theta

for (i in 1:length(data)){
ssc<-sum(data[0:i]-data[1])
points(i,ssc,type="b")
segments((-dd)+i,ssc,i,x+ssc)
segments((-dd)+i,ssc,i,-(x)+ssc)
}
```

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3200c08c-587b-6f75-5770-c8e4dec799ad.png)

うまくできないのでこの辺りはもう一度読み直す
Statworksのように組み込まれているものを使ったほうがわかりやすい

```
https://nitech.repo.nii.ac.jp/?action=pages_view_main&active_action=repository_view_main_item_detail&item_id=6076&item_no=1&page_id=13&block_id=21
```

[「統計的工程管理」を読んでRで実装　#2]()
Unityでライセンスエラーが出たときの対処

久しぶりに *Unity Hub* を起動すると無慈悲なライセンスエラーが発生し復旧までに時間を取られたので、再度発生した場合に備えて手順を残しておきます。

## 解決方法（失敗）

適当なバージョンのUnityを起動して認証を通せばよいとの [記事][link-1] を見つけ実行するが、
**Machine identification is invalid for current license.** というエラーが出てしまう。

![Machine identification is invalid for current license.](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238841/0f8f0ea3-ce68-a91b-5113-766a31dd440f.png "無慈悲なError")

## 解決方法（成功）

上記エラーについて [こちらの記事][link-2] によると、現状のライセンスファイル `Unity_lic.ulf` を一旦削除し、再度Unityを起動してライセンス情報の設定を行えば解決するとのこと。

ただし自分の環境、*Unity Hub* を使って *Unity5* と *Unity2017* の両バージョンを残していた環境では、`Unity_lic.ulf` ファイルがUnityを起動するたびに復活するという現象が発生。

最終的に、下記の操作手順により復旧しました。

1. *Unity* および *Unity Hub* の終了を確認
1. `C:\ProgramData\Unity` 内にある `.ulf` ファイルをすべて削除
    下図のような `.ulf` ファイルを
    ![20-23-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238841/81227bd2-3938-5b16-7896-dba0fc280e6c.png "ulfファイル削除前")
    すべて削除。
    ![20-27-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238841/68162984-e881-f1aa-bce2-3e1be60dabd3.png "ulfファイル削除後")

1. *Unity Hub* を通さず直接 *Unity* を起動
1. ライセンス設定画面が表示されるので、再度設定を行う
    ![20-27-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238841/c1d46372-f0b6-015f-1876-4016d8af4356.png "ライセンス設定ウィザード")
1. 復旧！
   *Unity Hub* からの起動も問題なくできます。

---

おそらく上記手順では無駄な操作も入ってるとは思いますが、とりあえずはこれで解決しました。

## 参考

* [UnityHubでライセンス認証が通らない時の解決法 – ニムサイト][link-1]
* [Unityを起動すると machine identification is invalid for current license. と表示される - Qiita][link-2]

[link-1]:https://nimushiki.com/2018/05/31/757/
[link-2]:https://qiita.com/naoto_tateno/items/941257b3df1176ef3b98
複数ANDにORを追加する時の評価順序に注意する

軽い修正かと思ってDELETEやUPDATEで気づかないと結構あわわなので注意

## 背景
WHEREに対する3つのAND条件にOR条件を追加する必要があった。
具体的にはNULLを条件に含める必要があり、比較演算子では対象から抜け落ちてしまうため条件を追加した。

## 結論
間のANDにOR条件を追加したい場合、評価のされ方が変わるので()で囲む必要がある

```
# 現行
A AND B AND C

# 追加
## 誤
A AND B OR X AND C
-> (A AND B) OR (C AND D) 

## 正
A AND (B OR X) AND C
```

# 例
## 定期格納実施後に不正データを削除するSQL
格納したばかりのデータと同じデータが過去のデータに合った場合に削除する

```
DELETE FROM ${data_warehouse.database.table}
WHERE
  /* 定期格納したデータの対象期間 */
  TD_TIME_RANGE(time, TD_TIME_PARSE('${date_since}', '${date_timezone}'), TD_TIME_ADD(TD_TIME_PARSE('${date_until}', '${date_timezone}'), '1s'))
AND
  /* 過去に格納されているデータ */
  (updated_at < ${import_time} OR updated_at IS NULL) /* <-- ここにNULLを()なしで入れた */
AND
  /* データを一意とする条件(スキーマの構造的にPKがないので) */
  ARRAY_JOIN(ARRAY[${primary_keys}], ',')
IN (
  /* 格納したばかりのデータ */
  SELECT
    ARRAY_JOIN(ARRAY[${primary_keys}], ',')
  FROM
    ${data_warehouse.database.table}
  WHERE
    TD_TIME_RANGE(time, TD_TIME_PARSE('${since_date}', '${timezone}'), TD_TIME_ADD(TD_TIME_PARSE('${until_date}', '${timezone}'), '1s'))
  AND
    updated_at = ${import_time}
  )
```

直前に格納したデータの対象期間
かつ
過去に格納されているデータまたはNULL
かつ
格納したばかりのデータと同じ

という条件のデータだけを削除するはずが、

直前に格納したデータの対象期間
かつ
過去に格納されているデータ
を全部削除するという形になってしまった。

つまり格納したデータ全部削除していた。(何も格納していないことになっていた。)

## 雑感
シンプルな対応でも少し複雑な処理に対して行う場合は、周辺の再確認時間を適切に確保して安直に行わないようにする

一意じゃないデータが入り得るのに一意のデータを入れていけないとなると大変
Window関数について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257568/87033c40-9e97-3434-60bf-8b59500bee4b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257568/eb6d5ffe-9939-db44-b20f-d810660e29c9.png)
こちらの本を読んで
データ分析における中核となるような関数のため
Window関数について

## Window関数とは
テーブルを区間ごとに集計する機能

- 集約機能を除いたGROUP BY句のようなもの
- 複数の行がまとめられることはなく、行それぞれが返却される
- windowという名前の関数はあるが一般的には省略して使われている

## 構文
複数の構文とセットで使うことで成立する

```
分析関数(column) OVER (PARTITION BY ... ORDER BY ...) 
```

大きく3つの要素になる

1. PARTITION BY句によるレコード集合のカット
2. ORDER BY句によるレコードの順序付け
3. フレーム句によるサブセットの定義

OVERは集計対象の範囲指定ができる句

## ポイント
- **セッションを利用したアクセスログの分析**などに利用できる
- PARTITION BYとORDER BYの組み合わせの使い方から覚えるのが良い
- GROUP BYとCASE式を組み合わせると強力な表現力がある

## 例
user_idごとにaccess_time順に並べた後、1レコード前のaccess_timeの値を取得する

```
SELECT
  user_id
, access_time
, LAG(access_time) OVER (PARTITION BY user_id ORDER BY access_time) AS preview_access_time
FROM
  access_log
;
```

LAG関数は対象カラムからn個前の「値」を取得

## 参考書籍
ミック. 達人に学ぶSQL徹底指南書 第2版
https://amzn.to/2vzf6Tb

ミック. SQL実践入門
https://amzn.to/2PBY6oG

## 雑感
分析ケースとセットでインプットしないと定着しづらい
フレーム句も分析関数も多い
dockerでcreate-react-native-appをやる時に詰まったこと

# qr imageの読み込みの後、接続できない

![IMG_0007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/fe70704b-76b3-02f8-34f0-bdabb119da45.png)

error message
There was a problem loading the requested app. It looks like you may be using a LAN URL. Make sure your device is on the same network as the server or try using a tunnel.

##解決策

```
expo start --tunnel
```

###参考
https://qiita.com/shoichi1023/items/ae0a285aea1950841934
> --tunnel                     # ネットワークの外部から接続できます。

###失敗
普通にexpo start すると、docker containerのipアドレスに接続するためのqr imageが開きます。
docker-compose.ymlに

```
ports:
       - 19000:19000
       - 19001:19001
       - 19002:19002
```

と設定したり、

```
network_mode: "host"
```

を設定して、ipアドレスを固定にして、portも同じにしてみたのですがうまく接続できませんでした。

...ブラーバいいよ、ブラーバ
Viewについて(DB)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257568/eb6d5ffe-9939-db44-b20f-d810660e29c9.png)
こちらの本を読んで
Viewについて

## Viewとは
SELECT文をデータベースに保存してしまうもの

よく使うものをDB上で管理する

## 構文
```
CREATE VIEW view_name(column1, column2) AS セレクト文
```

## ポイント
- エンジニアが運用上、複雑なSQLで定期的にデータチェックしたい場合などに使える
- プログラム上で使用するSQLに利用してしまうと分かりづらい

## 書籍情報
ミック. SQL実践入門
https://amzn.to/2PCdZeJ

## 雑感
たまに聞くけど使ったことなくて使い道が気になった。
Leetcode #134: Gas Station

```swift
func canCompleteCircuit(_ gas: [Int], _ cost: [Int]) -> Int {
    var diff = Array(repeating: 0, count: gas.count)
    var possibleStartIndex = Set<Int>()
    for i in 0..<gas.count {
        diff[i] = gas[i] - cost[i]
        if diff[i] >= 0 {
            possibleStartIndex.insert(i)
        }
    }
    for i in possibleStartIndex {
        var possible = true
        var remain = diff[i]
        for j in i+1..<gas.count {
            remain += diff[j]
            if remain < 0 {
                possible = false
                break
            }
        }
        if possible {
            for j in 0..<i {
                remain += diff[j]
                if remain < 0 {
                    possible = false
                    break
                }
            }
            if possible {
                return i
            }
        }
    }
    return -1
}
```
Envoy: リスナ

# tldr
勉強がてらにEnvoyのドキュメントにある[Getting Started](https://www.envoyproxy.io/docs/envoy/latest/start/start)を邦訳してみました。ベースはGoogle Translateで、ところどころ不自然な箇所を直しています。

原文としたのEnvoyのドキュメントは[こちらのディレクトリ以下](https://github.com/envoyproxy/envoy/tree/master/docs)にあります（ライセンス：[Apache License 2.0](https://github.com/envoyproxy/envoy/blob/master/LICENSE), [NOTICE](https://github.com/envoyproxy/envoy/blob/master/NOTICE)）。

## リスナ

Envoy の設定は単一プロセス内のリスナーをいくつでもサポートします。通常、設定されたリスナーの数に関係なく、1台のマシンにつき1つの Envoy を実行することをお勧めします。これにより、操作が簡単になり、統計情報が1つになります。現在 Envoy は TCP リスナのみをサポートしています。

各リスナは、いくつかのネットワークレベル（L3/L4）フィルタで個別に設定されています。新しい接続がリスナで受信されると、設定された接続ローカルフィルタスタックがインスタンス化され、後続のイベントの処理を開始します。汎用リスナアーキテクチャは、Envoy が使用されているさまざまなプロキシタスクの大多数（たとえば、レート制限、TLS クライアント認証、HTTP 接続管理、MongoDB スニッフィング、生の TCP プロキシなど）を実行するために使用されます。

リスナは、オプションで、いくつかのリスナーフィルタでも設定されます。これらのフィルタはネットワークレベルのフィルタの前に処理され、接続メタデータを操作する機会があります。通常は、接続が後のフィルタまたはクラスタの処理方法に影響を与えるためです。

リスナはリスナ検出サービス（ LDS ）を介して動的に取得することもできます。

リスナ構成
MySQL8.0における「rank」について

#背景
実は[前回記事](https://qiita.com/RINYU_DRVO/items/86d9f7a55060e524f6c0)より前の話。

ドットインストールMySQL入門
「\#17 ENUM型を使ってみよう」にて、
説明動画とバージョンが違う環境でエラーが発生したので
記事に残します。

#開発環境
MacOS Mojave
MySQL8.0.15

#内容
学習内容は、
「ENUM型を使い、
　複数の文字列の中から一つだけを選んで格納する」
というものです。

SQL文は以下の通り。

```sql:myapp.sql
DROP TABLE IF EXISTS users;
CREATE TABLE users(
    id INT unsigned PRIMARY KEY auto_increment,
    name varchar(20),
    score float,
    rank enum('gold','silver','bronze')
);

INSERT INTO users (name,score,rank) VALUES ('taguchi',5.8,'silver');
INSERT INTO users (name,score,rank) VALUES ('fkoji',8.2,'gold');
INSERT INTO users (name,score,rank) VALUES ('dotinstall',6.1,'red');

SELECT * FROM users;
```

実行してみると...

```
mysql> \. ./myapp.sql
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank enum('gold','silver','bronze')
)' at line 5
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank) VALUES ('taguchi',5.8,'silver')' at line 1
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank) VALUES ('fkoji',8.2,'gold')' at line 1
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank) VALUES ('dotinstall',6.1,'red')' at line 1
ERROR 1146 (42S02): Table 'myapp.users' doesn't exist
```

こいつぁ厳しい。
翻訳したら、
「SQL構文エラーですよ。まあマニュアル読めや」
って感じだったので、公式マニュアルを
読んでみましたが、
ENUM型に対して怪しい項目は見当たらず...

新バージョンのENUM型に対して検索を掛けても、
あんまりパッとした解決策は出て来ませんでした。

#発見
マニュアルを読んでいる中で、
怪しい場所を見つけました。

それは、MySQL8.0で新しく追加されたという
「ウインドウ関数」です。

どうやら、この関数の中に

```
RANK()
```

という関数があるそうで。

今回ENUM型のカラム名に使用したのが「rank」
だったので、カラム名を関数と認識されて
エラーになったみたいです。

#改善
その為、「rank」カラム名を「`」（バッククオート）で括ってみました。

```sql:myapp.sql
DROP TABLE IF EXISTS users;
CREATE TABLE users(
    id INT unsigned PRIMARY KEY auto_increment,
    name varchar(20),
    score float,
    `rank` enum('gold','silver','bronze')
);

INSERT INTO users (name,score,`rank`) VALUES ('taguchi',5.8,'silver');
INSERT INTO users (name,score,`rank`) VALUES ('fkoji',8.2,'gold');
INSERT INTO users (name,score,`rank`) VALUES ('dotinstall',6.1,'red');

SELECT * FROM users;
```

実行結果は以下の通り。

```
ERROR 1265 (01000): Data truncated for column 'rank' at row 1
+----+---------+-------+--------+
| id | name    | score | rank   |
+----+---------+-------+--------+
|  1 | taguchi |   5.8 | silver |
|  2 | fkoji   |   8.2 | gold   |
+----+---------+-------+--------+
```

カラム名は「rank」のままテーブルが出来ていますね。

ENUMの中で指定が無い「red」を含んだレコードは
ERRORで弾かれていることも確認出来ました。

#結論
バージョンアップで新たに追加された機能に使用される単語は
予約語になり使用できなくなります。

何らかのバージョアップを実施した際は
こまめに更新内容をチェックしましょうね。

#参考文献
[ドットインストールMySQL入門
「\#17enum型を使ってみよう」](https://dotinstall.com/lessons/basic_mysql_v3/40117)

[MySQL公式マニュアル:Window関数について](https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html)
平成最後の日に平成の文字を描いてみた

最近CSSで図形を描いてその文字数で点数を競う、[CSSBattle](https://cssbattle.dev/)というものでよく遊んでいることもあり、
平成最後ということもあるので、CSSで**平和**の文字を作ってみました。

# できたもの
以下のものになります

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="yoshida0129" data-slug-hash="qwwGRv" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Heisei-goshic">
  <span>See the Pen <a href="https://codepen.io/yoshida0129/pen/qwwGRv/">
  Heisei-goshic</a> by Tatsuya Yoshida (<a href="https://codepen.io/yoshida0129">@yoshida0129</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 苦労したところ
平という漢字は直線のみなので、比較的簡単だったのですが、成という漢字は曲線があったりと、色々考える点が多かったです。

# 最後に
本来は明朝体で書くつもりでしたが、平成のうちに投稿したかったこともあり、比較的簡単そうなゴシック体で書きました。
そのうち、令和の文字も作ってみようと思います。
PythonでWordPressに投稿する

# はじめに
WordPressへ定期的・自動的に記事を投稿したい。
Python + Crontab で実現できそう。
この記事は「Python」部分の忘記録です。


# 前準備
`python-wordpress-xmlrpc`のライブラリを活用する

```sh
pip install python-wordpress-xmlrpc
```


# コード部分

```python

wp = Client(wp_client, uid, passwd)

post = WordPressPost()
post.title = title
post.content = content

post.terms_names = {
'post_tag': tag_lst,
'category': category_lst
}

if publish:
    post.post_status = 'publish'
post.date = datetime.now() - timedelta(hours=9) + timedelta(minutes=5+(5*delay))

wp.call(NewPost(post))
```

## パラメータの説明

- wp_client: 「投稿先のWordPressのURL + /xmlrpc.php」
    -  例： https://hmd.site/main/xmlrpc.php
-  uid: WordPressのユーザーID
-  passwd: WordPressのパスワード
-  title: 記事タイトル
-  content: 記事の内容（htmlで記述）
-  category_lst: 記事のカテゴリー
-  tag_lst: 記事のタグ（任意）
-  post.post_status: 投稿状態（デフォルトはdraft)
-  post.date: 投稿日時（任意）。連続投稿するときはずらそう。
Leetcode #5: Longest Palindrome Substring

Time Complexity: O(n2)
Space Complexity: O(n2)

```swift
func longestPalindrome(_ s: String) -> String {
    if s.isEmpty {
        return ""
    }
    var length = 0, left = 0, right = 0
    let str = Array(s)
    var dp = Array(repeating: Array(repeating: false, count: s.count), count: str.count)
    for i in 0..<str.count {
        dp[i][i] = true
        for j in 0..<i {
            dp[j][i] = (str[i] == str[j]) && (dp[j+1][i-1] || i - j < 2)
            if dp[j][i] && i - j + 1 > length {
                length = i - j + 1
                left = j
                right = i
            }
        }
    }
    return String(str[left...right])
}
```
初学者はRubyを習得すべき理由

こんにちは、アキトです。

僕はいま、Rubyを学習しています。

なぜ、Rubyを学んでいるのか？

その理由は、「習得のしやすさ」と「転職のしやすさ」です。

下記でもう少し深掘りして解説していきます。

## 習得のしやすさ

十分Rubyの学習に手こずっているのですが、Rubyは他の言語と比べて習得しやすいと言われています。

"Hello World"と画面に表示するプログラムを例としてJavaと比べてみましょう。

### Javaの場合

<img width="663" alt="スクリーンショット 2019-04-30 21.02.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349810/d24283a9-2731-2a48-99dd-fe0a3390aecc.png">

### Rubyの場合

<img width="662" alt="スクリーンショット 2019-04-30 21.05.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349810/e17ac787-4e16-cb43-6eed-b12f25909086.png">


このようにコードの量がRubyの方が少なくてシンプルなんですね。

## 転職のしやすさ

未経験からプログラミングを学ぶ目的は、職に就くことだと思います。

市場が爆速で伸びていて、需要があるIT人材になるためにまずIT業界に入れなければプログラミングを身につける意味がなくなります。

Rubyの他にも、PHPやPythonなどの言語がありますがRubyは下記のような特有の特徴があります。

・未経験可の募集が比較的多く、かつ経験の浅いエンジニアでも担当可能な保守改修案件が比較的多い。

・モダンな環境である可能性が高い


つまり、未経験者がWeb業界の第一歩として選ぶ言語としては最適なんですね。

## まとめ

以上まとめると
未経験者にとって他の言語と比べて習得しやすい
未経験可の募集が比較的多く、かつモダンな開発環境の可能性が高い

これらを踏まえるとRubyが最適そうです。
個人的に変数の扱いで気にするポイント

メイン言語が Java なので Java で特に気にしているところの個人的なまとめ
細かいところ重視なのでインターフェースや設計はこの記事では触れていない。

# ポイント
* 変数のスコープは必要最低限であるか
* 変数名はスコープに応じて適切であるか
* 変数はイミュータブルであるか

## 変数のスコープは必要最低限であるか
スコープが広くなればなるほどその変数は役割が増えてしまう。
また、予期しないタイミングでの使用、変更といったバグを埋め込みやすくなる。
スコープは必要最低限にしたい。

ID(int)の配列から名前を問い合わせるfindメソッドがあるとする。

```java
        String name;
        for (int id : identities) {
            name = find(id);
            // name を使った何かしらの処理
        }
```

このコード例ではname変数をループ外で定義しているが、ループ内のみで name を使っている場合にループ内で定義するとスコープが狭くなる。

```java
        for (int id : identities) {
            final String name = find(id);
            // name を使った何かしらの処理
        }
```

## 変数名はスコープに応じて適切であるか

前述のスコープとも影響するが変数名やメソッド名の命名はスコープに準じてより厳格にする必要がある。
逆にいえばスコープが狭ければ厳格である必要性がなくなることも意味する。

ループのカウンタである `int i` などは極端に短いケースであるが、2-3行以内で使われるような変数は `name` や `age` など単純な変数名で良い。
一方で定数などはドメインに応じて厳格にする必要がある。
たとえば、 `public static final String DEFAULT_USER_NAME_VALUE = "名無しさん";` のように。
`USER` に種類がある場合にはその分定数が増え、変数名もより厳格にする必要があり、長くなってしまう。

ループの内外で何らかの名前を意味する変数を使いたい場合、`name` と `name2` のような名前ではなく `userName` `adminUserName` のようにする必要が出てくる。


## イミュータブルであるか
変数はカウンタなど一部を除きイミュータブルにできる。
ミュータブルな変数の場合、予期しないタイミングで変更や名前空間の上書きなどが発生してしまう可能性がある。
IntelliJ などの IDE によっては変数作成時にローカル変数であっても final で定義されるものもある。
ただし、Map や List などは変数そのものは final であっても中身は書き換えられるため要注意。
Javaの場合、インスタンス変数として持っている `private final List` を return しているメソッドなどは、deepcopy を返す、 `UnmodifiableList` にしてから返すといった方法が望ましい。

```java
    private final List<String> nameList = new ArrayList<>();

    public List<String> getNameList() {
        return nameList;
    }
```

これは以下のように置き換えることを検討したい。

```java
    private final List<String> nameList = new ArrayList<>();

    public List<String> getNameList() {
        return Collections.unmodifiableList(nameList);
    }
```
 
## プリミティブな定数で良いか

(プリミティブではないが)String や int の定数を用いるケースはそれなりに多いと思うが、列挙型やそれを表すクラスに置き換えることを検討したい。
たとえば、ファイルにデータを書き込む処理があるとして書き込みモードとして以下のような定数を用意したと考える。

```java
    /**
     * 追記モード
     */
    public static final String WRITE_MODE_APPEND = "append";

    /**
     * 上書きモード
     */
    public static final String WRITE_MODE_OVERWRITE = "overwrite";

    /**
     * 新規作成モード（ファイルがあったらエラー）
     */
    public static final String WRITE_MODE_NEW = "new";
```

このモードを使用した書き込みメソッドは次のようなシグニチャになるだろう。

```java
public void write(String data, String mode)
```
第一引数と第二引数がどちらも `String` であり引数名を確認しなければ判別しにくい。
また、`mode` が String のために対応していない文字列の場合も考慮する必要が出てきてしまう。

たとえば列挙型やModeクラスにすることで第二引数に本来の data を渡してしまうようなミスが発生しなくなる。

```java
    enum WriteMode {
        /**
         * 追記モード
         */
        APPEND,
        /**
         * 上書きモード
         */
        OVERWRITE,
        /**
         * 新規作成モード
         */
        NEW;
    }
```

この場合、シグニチャは次のようになるだろう。

```java
public void write(String data, WriteMode mode)
```

# 「まぁとりあえずこれで」の危険性

これ単独でみると当たり前のことを言っているが、検証しながらコーディングをするなどしていると「まぁとりあえずこれで」としてしまったコードが残っていたり、リファクタリング漏れによってこういったコードが入ってしまうことがあるので自戒を込めて注意したい。
アプリをSwift4.2に対応させる。

前職のエンジニアに連絡が取れず、仕方なくデザイナーである自分が更新作業などを行なっている。Swift5になってしまったので、Swift3のアプリをSwift4.2に移行する必要が発生した。
そのための備忘録として書き留めておきたい。

#前提
前提として、このアプリに携わっていると言っても、Swiftはこれを触るまで全くやったことがなく、いつもの業務はデザインがメインで、かたわらでフロントエンド＋PHPを触る程度。


#やってみる
##Swift4.2にコンバート
現在のアプリがSwift3なんで、まずは、Xcode10.1で開いてSwift4.2にコンバートさせる。
1. `Conversion to Swift 4.2 is available`をクリック
2. `Selecttarget to Convert:`で全てのライブラリを選択（最初っから選択されている状態）でNEXTをクリック
3. `Minimze Inference`を選択し、 NEXTをクリック
4. `Manual steps necessary`というアラートが表示されるのでOKをクリック
5. 1箇所「Action」のライブラリで変更点が発生するがそのままSave
	※ライブラリを変更するのでUnlockする必要がある

##Pod の Setting をアップデートする
`Update to recommended Setting`をクリック
CryptoSwift で使用している`Compilation Mode`を使っているが、これを解消してしまうとエラーが発生するので、このチェックを外してDoneをクリック


##Willow のエラーを解消

相変わらず、このWillowというライブラリが悪さをするようで、エラーが発生する。

```
```
       for key in values.keys where key.rawValue & bitValue > 0 {
                    valuesForBit += values[key]!
                }
```
```


```
       for key in values.keys where key.rawValue & UInt.init(bitValue) > 0 {
                    valuesForBit += values[key]!
                }
```

##Clean Build Folder を行う

##Snapkitのアップデート
SnapKitの変更点が多すぎるため、snapkitだけアップデートを行った。
SnapKit3.2.0 → SnapKit 4.0.0

```Snapkit/Typealiases.swift
    typealias LayoutRelation = NSLayoutRelation
    typealias LayoutAttribute = NSLayoutAttribute
```
>ERROR
'NSLayoutRelation' has been renamed to 'NSLayoutConstraint.Relation'

>ERROR
NSLayoutAttribute' has been renamed to 'NSLayoutConstraint.Attribute'

```Snapkit/Typealiases.swift
typealias LayoutRelation = NSLayoutConstraint.Relation
typealias LayoutAttribute = NSLayoutConstraint.Attribute
```

##キャッシュのクリア
Xcodeのキャッシュによって変なエラーが発生

キャッシュをクリアする

```
rm -rf ~/Library/Caches/com.apple.dt.Xcode/
```

参考：https://qiita.com/shtnkgm/items/c96a58579ec406194fa8

##RxSwift と RxCocoa をアップデート
RxSwift と　RxCocoa にエラーが出ているが解消方法がわからないため、ライブラリ自体のアップデートを行う。部分的な改修を行うと他に影響が出る可能性が高いため、アップデートをした

RxSwift とRxCocoaのアップデートには他のライブラリもアップデートしなければいけない。

- RxSwift 3.6.1 → 4.0.0
- RxCocoa 3.6.1 → 4.0.0
- RxDataSouces 2.0.2 → 3.1.0
- RxOptional 3.2.0 → 3.6.2
- Action 3.2.0 → 3.11.0
- RxTest 3.6.1 → 4.0.0

#最後に
これでなんとかビルドすることができた。
今度はSwift5に対応する必要性があるが、徐々にやっていこうと思う。
ひとまずSwift4.2に対応できてよかった。

一つ学んだことはライブラリはむやみにアップデートしてはいけないってことだ。
特に前任のエンジニアがマニアックなライブラリを使っている場合、アップデートするのは超危険だということがわかった。
closure_treeでツリー構造

# 概要
* ツリー構造の実装のための[closure_tree](https://github.com/ClosureTree/closure_tree)を使ってみました

# 環境
* rails 6

# 背景
部署の上下構造を表現するために導入しました
今回対象とした部署のテーブル名は `organizations` です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/f5b50710-8933-8d33-4597-05e1562c6a91.png)


# 手順
## インストール

普通にgemをインストールします

```Gemfile
gem 'closure_tree'
```

```console
bundle install
```

## マイグレーション

ツリー構造を追加したいモデルに `has_closure_tree` を追加します。

```app/models/organization.rb
class Organization < ApplicationRecord
  has_closure_tree
end
```

[ここを見ながら](https://github.com/ClosureTree/closure_tree#installation) 、必要なmigrationを追加します。

```console
rails g closure_tree:migration organization 
```

下記のファイルが追加されます

```db/migrate/20190430101958_create_organization_hierarchies.rb
class CreateOrganizationHierarchies < ActiveRecord::Migration[6.0]
  def change
    create_table :organization_hierarchies, id: false do |t|
      t.integer :ancestor_id, null: false
      t.integer :descendant_id, null: false
      t.integer :generations, null: false
    end

    add_index :organization_hierarchies, [:ancestor_id, :descendant_id, :generations],
      unique: true,
      name: "organization_anc_desc_idx"

    add_index :organization_hierarchies, [:descendant_id],
      name: "organization_desc_idx"
  end
end
```

```console
rails g migration AddParentIdToOrganization 
```

`add_column :organizations, :parent_id, :integer` を追加します

```db/migrate/20190430102217_add_parent_id_to_organization.rb
class AddParentIdToOrganization < ActiveRecord::Migration[6.0]
  def change
    add_column :organizations, :parent_id, :integer
  end
end
```

```console
rail g db:migration
```

これで準備完了です。

# 使い方
## 既存のデータにツリー構造を付与

適当に `rails c` を起動します。

*  `add_child` でツリー構造を付与します。

```irb
irb> bucho_a = Organization.find(1)
irb> kacho_a = Organization.find(2)
irb> kakaricho_a = Organization.find(3)
irb> kakaricho_b = Organization.find(4)

irb> bucho_a.add_child(kacho_a)
irb> kacho_a.add_child(kakaricho_a)
irb> kacho_a.add_child(kakaricho_b)
```

上記コマンドを打つと、テーブルは下記のようになります。

* organizations テーブル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/841eb011-f47d-df12-1f5f-689c91e1323e.png)

* organization_hierarchie テーブル


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/21bf170d-2add-ef3b-4dcc-4a26780a966b.png)

* ツリー構造を削除するには `parent_id` を修正してください。 ([参考](https://github.com/ClosureTree/closure_tree#moving-nodes-around-the-tree)) 関連する organization_hierarchie テーブル もあわせて修正されます。

```irb
irb> kakaricho_a = Organization.find(3)
irb> kakaricho_a.update(parent_id: nil)
```

* ツリーをつけかえるには、おなじく `parent_id` を修正してください。

```irb
irb> kakaricho_b = Organization.find(3)
irb>kakaricho_b.update(parent_id: 1) # 課長Ａから部長B直下に付け替え
```

以上
bitbucket-pipelines テストサマリを表示

# 概要

bitbucket pipelinesではjunitの形式のxmlからテストのサマリを表示することができる。
pipelinesで取得できたサマリーはpipelinesのページに表示される

* bitbucket pipelinesでテストサマリを表示する
* 参考
    * https://confluence.atlassian.com/bitbucket/test-reporting-in-pipelines-939708543.html?_ga=2.232127897.749828169.1556589067-173695553.1556334628

# 環境

* golang
* https://bitbucket.org/hiro15/bitbucket-pipelines-test/src/master/

# 手順

* bitbucket pipelinesを使える状態にする

参考
[bitbucket pipelines セットアップ](https://qiita.com/honeytrap15/items/edfaa2e3eb3b5a9ace6b)はこちら

* golangでjunitの形式でテストのレポートを作成する場合は `go-junit-report` を使用するのが便利

```
$ go get -u github.com/jstemmer/go-junit-report 
```

* テスト時に特定のディレクトリにレポートを出力することでpipelinesで表示してくれるようになる。以下がpipelinesファイルの例

```bitbucket-pipelines.yml 
# This is a sample build configuration for Go.
# Check our guides at https://confluence.atlassian.com/x/5Q4SMw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: golang:1.7

pipelines:
  default:
    - step:
        script: # Modify the commands below to build your repository.
          - PACKAGE_PATH="${GOPATH}/src/bitbucket.org/${BITBUCKET_REPO_FULL_NAME}"
          - mkdir -pv "${PACKAGE_PATH}"
          - tar -cO --exclude-vcs --exclude=bitbucket-pipelines.yml . | tar -xv -C "${PACKAGE_PATH}"
          - echo "${GOPATH}"
          - cd "${PACKAGE_PATH}"
          - go get -v
          - go build -v
          - go get -u github.com/jstemmer/go-junit-report
          - mkdir -p "/opt/atlassian/pipelines/agent/build/test-reports/"
          - go test -v 2>&1 | go-junit-report -set-exit-code=1 > /opt/atlassian/pipelines/agent/build/test-reports/junit.xml
```

* `mkdir -p "/opt/atlassian/pipelines/agent/build/test-reports/"` で出力先のディレクトリを作成
* `go test -v 2>&1 | go-junit-report -set-exit-code=1 > /opt/atlassian/pipelines/agent/build/test-reports/junit.xml` でjunit形式のレポートを作成したディレクトリに出力する
* `-set-exit-code=1` をgo-junit-reportの実行オプションに指定することで、`go test` の実行でFAILがあったときに、中断することができる
* 上記のpipelinesファイルでpipelineが実行された場合、テストの失敗時にビルドが失敗する。（成功時にもレポートに失敗した情報が入っている場合はサマリが表示されるが、コマンドが成功した場合は後段のコマンドが実行されてしまう。）
* 失敗したテストケースがない場合はサマリは表示されない
    * https://bitbucket.org/hiro15/bitbucket-pipelines-test/addon/pipelines/home#!/results/16

成功時

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70029/432bb8d3-df19-c17e-582a-75673467b0da.png)

* 失敗時にはタブにTestsが追加されており、サマリが表示される
    * https://bitbucket.org/hiro15/bitbucket-pipelines-test/addon/pipelines/home#!/results/17/steps/%7B67189114-440b-49a1-b09c-ece7ebb13f26%7D/test-report

失敗時

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70029/6b8535e8-4ab4-174c-552f-bd7c8e6d811f.png)
PythonGUIでNEMを扱う（第1回: 単純な残高表示)

私はアプリ開発やデータ解析でpythonを使うことが多いのですが、
NEMをpythonで実装し、顧客に提案しようと考えたときに、
グラフィカルになっていないと中々響かないな、と感じています。
(顧客にも黒画面に抵抗ある人が多い。。)

そこで、GUI向けで強力なツールであるpyqt5を用いたコード整備を少し時間をかけて進めたいな、と思います。
これらを用いて、顧客等へのPOC(proof of concept)に活用いただけると幸いです。

今回は第1回として、自分のwallet内のxemと日本円換算を行います。

# 開発環境

- ubuntu 16.04
- python3.5.2
- pyqt5

# ソフトウェアのインストール
まず、githubからソフトウェアをダウンロードしてください。
https://github.com/naisoa/pyqt_nem

そして以下でソフトウェアを実行します。
`cd pyqt_nem`
`python3 main.py`

nem関連のAPIについては、下記を参照しています。
https://qiita.com/oden_umai/items/df6dd02b2b6f2711ccd7
@oden_umaiさんに感謝!!

# 実行結果
「zaif」と「自分のwallet」を選択して、合計金額[円]を算出するようにしています。

自分のwallet

![my_wallet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389180/02b711e7-53b4-8ddd-f691-ffa635a630ed.png)

zaifのwallet?

![zaif.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389180/70c6b7ed-033a-7ba0-b7dd-08bdbd580832.png)

やば!!　zaif、xem持ち過ぎーー。(うらやましい）

#末筆
さて、pyqt5を今回使ってみましたが、
ライセンスには注意が必要です。
つまり、ソースコードの公開を要求される可能性があるので、
事業化に向けては別の手段が必要になるかもしれませんね。

#参考文献
Python3でNEMのAPIを叩く-001-概要
https://qiita.com/oden_umai/items/df6dd02b2b6f2711ccd7
Anaconda環境に Fbprophet を導入

# Anaconda環境に Fbprophet を導入
上手くインストールができない＋Anaconda環境がおかしいという問い合わせがあったので、補足資料＋備忘録として。
詳細不明ですが、condaでパッケージが無いので、pip installして詰んだんではないか と思われます（推測）

## Fbprophet (Prophet) とは
Facebookが開発したオープンソースの時系列解析パッケージです。
[Prophet](https://facebook.github.io/prophet/
)
Prophet is a forecasting procedure implemented in R and Python. It is fast and provides completely automated forecasts that can be tuned by hand by data scientists and analysts.
  
1) 時系列データの解析は大変ですが、簡単に予測が可能で使い勝手が良い！ 
2) 「トレンド」「季節効果」「イベント」から時系列を解析する賢さ！！  

## Fbprophetのインストール
作成済みの仮想環境である fbprophet を以下では利用します。  
Anaconda環境ではcondaコマンドを必ず利用、conda installでパッケージがなければ、conda install -c conda-forge を試してください。

```
$ conda activate fbprophet
$ conda install -c conda-forge fbprophet
```

以上。
iOSアプリの実機テストのやり方

ずっとシミュレータで動作検証してたのですが、いよいよ自分のiPhoneで実機検証してみようと思いました。
証明書まわりで詰まったので、メモです。

# 必要なこと
僕はiPhone XSを使っているのですが、XCodeが最新版じゃなかったため、最初実機でアプリが起動しませんでした。
普通に対応している機種だったら、PCにケーブルで直接つないだ状態で、XCodeのシミュレータの、
機種を選ぶところに自分のiPhoneの名前が選択対象として出ます。
ただこれだけだとダメで、
Project名 > Generalの中に、Signingという項目があるので、そこで実機を登録してやる必要があります。
登録して、証明書を発行してもらってから、実機検証可能となります。

# 証明書まわり
で、証明書の発行をポチポチやっていたら、キーチェーンが突然開いたので、うっかり拒否してしまったのですが、
これをやってしまうと、二度と先に進めなくなります。
ただ下記の手順を踏むと、進めました。

>
(1)Xcode - Preferenceのメニューを選択して設定画面を出し、
   Accounts画面に登録されているApple IDを「-」ボタンで削除する。
(2)Xcode - Quitのメニューを選択してXcodeを終了する。
(3)キーチェーンアクセスを起動し、画面左の選択で
   キーチェーン欄を「ログイン」、分類欄を「自分の証明書」とする。
   証明書一覧の中に「iPhone Developer: (自分のアカウント名)」
   という名前の証明書があるはず。
(4)指定の証明書を右クリックし、表示されたメニューから削除を選択して削除する。
(5)Macを再起動する。
(6)Xcodeを起動し、再度アカウントを登録する。
(7)Xcodeのプロジェクトを開いて、実機実行ボタンを押す。
   確認画面が出てきたら、Macにログインする際のパスワードを入れて「常に許可」
   を選択する。
[Xcodeの「キーチェーン」ログインパスワードで誤って拒否](https://teratail.com/questions/131204)
Azure Functions (Node.js) で npm パッケージを追加して利用する方法 (コンソール利用)

Azure Functions の関数作成画面の「コンソール」を使ってお手軽に npm install する方法です。
今回は HTTP リクエストをする [request](https://www.npmjs.com/package/request) をインストールしてみます。

**追記:** HTTP リクエストをするだけなら、[標準モジュールの HTTP/HTTPS が使えます](https://qiita.com/ma2shita/items/a9844a3a8e618600a109)。npm で追加インストールする際に参考にしてくださいね。

**更新(2021/9/22):** [2021年秋版のアップデート](https://qiita.com/ma2shita/items/cca1983c0428be0ec24b)を書きました。ここから下は古い情報です。

---

### npm install をする

Azure Functions の関数作成画面の [コンソール] で以下コマンドを入力していきます。

```console
> npm init --yes
> npm install request
```

おしまいです。ポイントは `npm init --yes` で `package.json` を作成しておく必要があります。この辺は npm の運用ノウハウですね。

### Azure Functions の実装

[PostBin](https://postb.in/) に POST するコードを実装してみます。

```javascript
const request = require('request');

module.exports = async function (context, req) {
    const url = `https://postb.in/XQh4ljyY`;
    const payload = {value1: "a", value2: "b", value3: "c"};
    request.post(url, (error, response, body) => {
        context.log(response);
    }).json(payload);
    context.done();
};
```

## あとがき

Azure Functions で Node.js を利用する際、npmパッケージを利用したくなる時があります。[Kudu を使ってインストールする](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-reference-node)方法もあるそうですが、ポータル内で小さい関数を作りたいときは強烈に面倒なので、それを回避してみたという話です。

もう平成もおわりですね。

### 参考資料

* [Azure Functions の npmモジュール の使い方](https://qiita.com/567000/items/582da1c0f0b45eb25bfd)

EoT
プログラミング学習記録73〜パッケージ〜

##今日やったこと
- Progate Javascript4,5そのまま復習

昨日の続きで、ProgateのJavaScriptを復習しました。

具体的には、.jsファイルの分割、パッケージの使い方について復習しました。

全ての記述を1つのファイルにまとめると長くなれば長くなるほど、訳がわからなくなります。
そのため、記述が長くなる場合は、ファイルの　分割・継承をうまく使って記述した方が良いです。

読み取る側と読み取られる側を明らかにすることが大事です。

この2つをしっかり理解して、記述できればこの章は大丈夫だと思います。
<br>
また、誰かが作ったプログラムをパッケージという形で利用できるのは便利だな、と思いました。
全てを０から自分で作る必要はありません。

色々なパッケージがあるので、どう使いこなしていくかが難しそうですが、とりあえずパッケージというものの存在を知れたのはよかったなと思います。

ということで、明日からも引き続き頑張ります。

おわり
Anaconda環境に spm-image を導入

# Anaconda環境に spm-image を導入
README.mdの記載通りですが、備忘録として。

## spm-image とは
HACARUSが公開されているスパースモデリング・圧縮センシング用Pythonライブラリ。
[hacarus/spm-image](https://github.com/hacarus/spm-image)

勉強中です。

## 特徴
scikit-learn、NumPy、scipyのみ依存。
k-SVD、ADMM(Lasso) 、ZCA Whiteningなどが実装済み。
scikit-learnでLasso使った線形回帰を、ADMMでやったらどうなるか気になった夜にオススメ？

## spm-image のインストール
Anaconda 環境に作成済みの仮想環境 spm を利用する場合。

```
$ conda activate spm
$ conda instrall matplotlib
$ pip install spm-image
$ cd ~/notebook/
$ wget https://github.com/hacarus/spm-image/archive/development.zip
$ unzip development.zip
$ cd spm-image-development
$ pip install -r requirements.txt

```

## spm-image のテスト
```
$ conda activate spm
$ cd spm-image-development
$ python -m unittest discover
```

以上。
Matplotlibの棒グラフの横軸の順番が勝手に入れ替わるときの対処法

Matplotlibで, x軸にカテゴリ変数, y軸に数値をとるような棒グラフを描きたいとき, グラフが思った通りの順番に並ばないことがあります。

## 改善前 〜棒グラフが思った通りに並ばない〜
#### コード

```Python3
import numpy as np
import matplotlib.pyplot as plt

# 棒グラフをyの値が大きい順に並べたい
data = np.array(['much', 1.11], ['more', 2.22], ['most', 3.33])

# dataをyの降順にソート
data_sorted = data[np.argsort(data[:,1])[::-1]]

# x, yの配列を取得
x = data_sorted[:, 0]  #['most', 'more', 'much']
y = data_sorted[:, 1].astype(np.float64)  #[3.33, 2.22, 1.11]

# 棒グラフを描画する
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.bar(x, y)
plt.show()
```

#### 結果

配列x, yをyの降順となるようにソートした状態で棒グラフを描画しました。
しかし, 棒グラフはそのように並んでいません。

![53AAC8FD-6837-451A-9154-93F869DF7C8A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/93e2aed7-052e-ce37-fcb7-ac1975badbde.png)

なぜでしょうか？

グラフの描画時にデータが自動的にxの昇順となるようにソートされてしまうため, グラフが more -> most -> much のようにxに関する辞書順で並んでしまうようです。



## 改善後

改善する方法の1つとして「x軸の値そのもの」と「x軸のラベルに振る値」を分離するというアイディアがあります。


#### コード

```Python3
'''
    先ほどの続き
    x = ['most', 'more', 'much']
    y = [3.33, 2.22, 1.11]
'''

# [0, 1.11], [1, 2.22], [2. 3.33] がプロットされた棒グラフのx軸に ['most', 'more', 'much'] の順でラベルを振る
x_temp = range(len(x))
ax2 = fig.add_subplot(1, 2, 2)
ax2.bar(x_temp, y, tick_label=x, color='green')

# 描画
fig.subplots_adjust(wspace=0.4)
plt.show()
```

#### 結果
今度は狙いどおり, 左側からyの降順となるよう棒グラフを並べることができました。
![079DECE9-3D9B-41A6-B906-5B0C5C15380B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/2973a55a-5eab-dae6-7812-b8d92e69f4e3.png)
WiFiに一見繋がっているのに、ネットワークに繋がらない時の対処法

#はじめに
家とかでWiFiお馴染みの扇型の電波マークが付いているのにネットワークに繋がらない（Webページが見れない）時に意外と盲点な確認事項を紹介いたします。

#確認すべきこと
###1. エラー画面が以下のようになっているかどうかを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259323/f9a6d8db-0f27-0494-299a-d9342ae8b5c0.png)


ファイヤーウォールが〜、プロキシが〜と言われている場合は、また別の対処法になります。

###2.光ファイバーケーブルが、モデムに接続しているか、また、電源が入っているかをきちんと確認する

大抵のケースはモデムの電源がきれていたという原因が多いと思います。灯台下暗しです。また、WiFiルーターとモデムの間に普通のルーターを挟んでいる場合、そちらとの接続も確認しましょう。

###3.モデムに異常なしの場合、WiFiアクセスルーターとの接続を確認する

WiFi自体とは接続できていた場合はここに問題はないかと思われます。何度か、WiFiをON/OFFを繰り返してネットワークに繋がるか確認しましょう。

###4.回線代行業者もしくはプロバイダに問い合わせる

それでも繋がらなければ、回線か、WiFiルーター、端末どれかの問題である可能性が高いので、回線代行業者もしくはプロバイダに問い合わせてみましょう。

モデムとの接続ができていなかった場合でもWiFiルーターの電源が入っていれば、WiFiルーター側で電波の発進と端末側でのSSIDの認識及び電波の受信は問題なく行えます。この電波は信号の乗っていないただの電波ということなのですが、なぜWiFiに繋がっているのにネットワークに繋がらないのかと勘違いして焦ることにも繋がりますので、注意しましょう。
【Ruby on Rails】 コントローラー 色々

#目次

+ 指定したアクションやビューに遷移する(redirect_to)
+ コントローラーのアクションが実行される前に〇〇を実行する(before_action)


###指定したビューに遷移する(redirect_to)
redirect_toメソッドをアクション内で利用すると、そこからさらに別のアクションを実行したり、ビューに遷移させたりできます。

```:controller
redirect_to :action => "index"
```
###コントローラーのアクションが実行される前に〇〇を実行する(before_action)
before_action:メソッド名　と記述することでコントローラのアクションが実行される前に「before_actionで指定したメソッド」を実行することができます。
【オプションなし】

```
before_action :実行前メソッド名 
```
【onlyオプション】
〇〇に限り。

```
before_action :実行前メソッド名, only: 
```
【exceptオプション】
〇〇以外の場合は。

```
before_action :メソッド名, except: :メソッド名
```
JuliaでAPIを実装する

今回はJuliaで簡単なAPIを実装していきます。  
Juliaは科学技術計算やデータサイエンスに強い言語ということで、
JuliaでAPIを作れると、上記のような分野のアプリケーションを開発しやすくなると期待してます。

# おしながき
- Genieとは？
- HTTP.jl
- 実装解説

# Genieとは？
「Ginei」はJulia製のWebフレームワークです。
JuliaのWebフレームワークの中では一番開発が盛んに行われています。
[Geine公式](http://genieframework.com/)

![genie.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254013/4ecc2475-5127-9811-5941-e577f510a63c.png)

インストールはREPLから行います。

```julia

$ julia
julia>] #]を入力することでPkgモードに切り替えられます
Pkg> add https://github.com/essenciary/Genie.jl
```

# HTTP.jl
APIの実装を確認するために、リクエストを送るコードも実装します。
リクエストはHTTP.jlを使用して実装していきます。
HTTP.jlはPythonでいう「requests.py」のようなパッケージで、
RESTリクエストの他に、WebSocketやサーバー機能の実装も可能です。
APIの実装はHTTP.jlでもできそうですがGenieの方が好きなので、リクエストにしか使いません。

インストールはGenieと同じく、REPLから行います。

```julia

$ julia
julia>] #]を入力することでPkgモードに切り替えられます
Pkg> add HTTP
```

# 実装解説
まずはAPI側の実装を説明します。
今回作成するAPIはPOSTでTODOを登録し、GETでTODOを返すシンプルなものになります。

まずは、必要なパッケージをインポートします。

```julia

using Genie, Genie.Requests
import Genie.Router: route
import Genie.Renderer: json!
```

サーバーを同期的に起動させるためのパラメーターを設定します。

```julia

Genie.config.run_as_server = true
```

次にPOSTメソッドを定義します。
エンドポイントは`/todo`となり、後から実装するGETメソッドと同じにします。
POSTメソッドでは、JSONを受け取りリストに保存します。
POSTが成功すれば、メッセージを返えします。
APIの戻り値はGenie.Rendererにパイプします。

```julia
route("/todo", method = "POST") do
    message = jsonpayload()
    push!(todo, (message["todo"],message["day"]))
    (:message => "POST success") |> json!
end
```
> ちなみにですが、"|>"はパイプ演算子といって、左側になんらかの値を指定し、
> 右側に関数を指定することで、左側の値を関数の引数として指定する演算子です。
> 複数の関数に連鎖的に値を入れたい時などに使うと便利です。


次に、GETメソッドを定義します。
エンドポイントは`/todo`となり、POSTと同じです。

```julia

route("/todo", method = "GET") do
    message = join(todo, ", ")
    (:message => message) |> json!
end
```

最後にサーバーの起動を指定します。

```julia
Genie.AppServer.startup()
```

一応、コード全体を書きます。↓
サーバーの起動は`julia rest.jl`です。

```julia:rest.jl

using Genie, Genie.Requests
import Genie.Router: route
import Genie.Renderer: json!

Genie.config.run_as_server = true
todo = []

route("/todo", method = "POST") do
    message = jsonpayload()
    push!(todo, (message["todo"],message["day"]))
    (:message => "POST success") |> json!
end

route("/todo", method = "GET") do
    message = join(todo, ", ")
    (:message => message) |> json!
end

Genie.AppServer.startup()
```

### リクエストコード実装
次に、APIを叩く側の実装を見ていきます。

```julia:stb.jl

using HTTP

base_url = "http://127.0.0.1:8000/todo"
headers = [("Content-Type", "application/json")]
body = """{"todo":"create api", "day":"5/1"}"""

post_request = HTTP.request("POST", base_url, headers, body)
println(post_request.body |> String)


get_request = HTTP.request("GET", base_url, headers, body)

println(replace(get_request.body |> String, "\\\"" => ""))

```
叩く方の実装はそんな難しくないと思います。
リクエストは`HTTP.request`でメソッド・URL・ヘッダー・リクエストデータを指定するだけです。
`julia stb.jl`で実行すれば
{"message":"POST success"}
{"message":"(create api, 5/1)"}
が、帰ってくるはずです。

# まとめ
Juliaで簡単なAPIを実装しました。
次はWebアプリケーションを実装したいですね。
Boto3のMockのMotoに未実装のAPIを追加してみた

# きっかけ

AWS Lambdaのユニットテストって皆さんどのように実装しているのでしょうか？
私は[前回の記事](https://qiita.com/ttkiida/items/be17388c7de121635e22)でも少し登場していた[Moto](https://github.com/spulec/moto)を使用しています。テストケースにデコレータを付けるだけでBoto3をモック化してくれるのでとても便利なのですが、先日ついに恐れていたことが起きてしまいました。

```console
NotImplementedError: The create_group action has not been implemented
```

cognito-idpの`create_group()`を使用した関数をテストしたら「残念だったな、そのAPIはまだ未実装だぜ！」と言われてしまったのです。（口調は私の想像）

こんな時には（通常）のMockでどうにかするのが良いと思うのですが、私のPython力不足でMockの使い方がよく分からず、足掻きに足掻いた結果、**Boto3のMockのMotoの関数をMock化する**ことでどうにか解決できたので、その方法をまとめておきます。

# 問題のテストケース

テストケースと言うよりもエラーが出た処理なのですが、単にCognitoユーザープールを作成して、それにグループを作成するだけです。`create_user_pool()`は問題なく動きますが、`create_group()`が未実装のためエラーとなります。

```python
import boto3
from moto import mock_cognitoidp

@mock_cognitoidp
def cognito_mock_test():
    cognito = boto3.client('cognito-idp')
    response = cognito.create_user_pool(
        PoolName='TestUserPool'
    )
    user_pool_id = response['UserPool']['Id']
    response = cognito.create_group(  # ここでNotImplementedError
        GroupName='TestGroup',
        UserPoolId=user_pool_id
    )
```

# `create_group()`のMock化

CognitoIdpResponseというクラスに各関数のMockを実装しているので、そこに`create_group()`をpatchしてあげます。これで`create_group()`を呼び出した時には、代わりに`mock_create_group()`が呼び出されるようになります。元のCognitoIdpResponseには`create_group()`が存在しないので、`create=True`を指定する必要があります。

```python
from unittest import mock

@mock_cognitoidp
@mock.patch('moto.cognitoidp.responses.CognitoIdpResponse.create_group',
            new=mock_create_group, create=True)
def cognito_mock_test():
    # 上と同じ
```

そして、`mock_create_group()`の実装が以下です。
`self.body`に引数が入っています。戻り値は3つ指定する必要があり、順にステータスコード、追加のヘッダー、コンテンツです。

```python
import json

def mock_create_group(self):
    group_name = json.loads(self.body)['GroupName']
    return '200', {}, json.dumps({
        'Group': {
            'GroupName': group_name
        }
    })
```

本物の`create_group()`はGroupName以外にもコンテンツがありますが、ひとまずこれだけにしておきます。

```console
{'Group': {'GroupName': 'TestGroup'},
 'ResponseMetadata': {'HTTPHeaders': {'server': 'amazon.com'},
                      'HTTPStatusCode': 200,
                      'RetryAttempts': 0}}
```

これで元の関数を実行すると、見事に`create_group()`がレスポンスを返してくれるようになりました！

# オチ

こんな感じでMotoに不足していたAPIをMock化してみたのですが、Motoが1.3.8にアップデートされ、`create_group()`が実装されちゃっていました！ｗ　本家のレスポンスはコチラ。

```console
{'Group': {'CreationDate': datetime.datetime(2019, 4, 30, 19, 41, 39, tzinfo=tzlocal()),
           'Description': '',
           'GroupName': 'TestGroup',
           'LastModifiedDate': datetime.datetime(2019, 4, 30, 19, 41, 39, tzinfo=tzlocal()),
           'UserPoolId': 'ap-northeast-1_717df8345675458c98e2b9190a1fc580'},
 'ResponseMetadata': {'HTTPHeaders': {'server': 'amazon.com'},
                      'HTTPStatusCode': 200,
                      'RetryAttempts': 0}}
```

Mock実装は無駄になってしまいましたが、色々勉強になったし、今後も未実装のAPIが出てきた時には使えそうなので、これはこれで良かったのかな。

ちなみにMotoが1.3.8になって、依存性で今まで`aws-xray-sdk==0.95`が入っていたのが、ついに`aws-xray-sdk==2.4.2`（最新）になりました。早速プロジェクトで使っているものもバージョンアップしなければ！
RaspberryPiで機械学習TensorFlowセットアップ

#概要
RaspberryPiでディープラーニング環境を簡単に構築したい。
簡単なTensorFlowのサンプルプログラムで動作確認できるまでを作成します。
#環境
- RaspberryPi (RaspberryPi 3 model b+にて確認)
- SDカード
- WindowsPC（SDカード作成とターミナルソフト）
- LAN環境（家庭内Wi-Fiを想定）
 
#起動ディスク(SDカード)準備
balenaEtcherのWindowsアプリケーションなどでイメージ下記のイメージファイルをSDカードに展開する
2019-04-08-raspbian-stretch\2019-04-08-raspbian-stretch.img

PCにてSDカードドライブ直下に「ssh」ファイルを作成（中身は空でOK）
　（テキストファイルを置いて名前作成でよい）

ssh


家庭内LANがあり、接続できるならば、同じくSDカードドライブ直下に下記のファイルを作成しておく（任意です）

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="（無線LANのSSID）"
    psk="（無線LANのPSK）"
}
```


#RaspberryPi初期設定
##電源ON
SDカードをRaspberryPi3に差し込んで電源ON

##vimをインストール（任意）
```
sudo apt-get install vim
```
　※viのキーボードアサインが影響してか、バックスペース等が効かないため。

##Wi-fi DHCP (IP固定設定  任意）
xxxやyyyなど各人のネットワーク環境に合わせて設定してください。

```
sudo vim /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.xxx.yyy
static routers=192.168.xxx.1
static domain_name_servers=192.168.xxx.1
```

##OSアップデートしておく
```
sudo reboot
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo reboot
```

#TensorFlowsセットアップ

##python3 入っているか？チェック
```
python3 -V
```
（あった）
Python 3.5.3

```
pip3 -V
```
（あった）
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.5)

##各種インストール
```
sudo apt install libatlas-base-dev
```
```
pip3 install tensorflow
```

**tensorflowをインストールをすると、エラーで中断されました。何度か繰り返してインストールすることで完了しました。

#最後に
サンプルを作成して実行するとワーニングが表示されました。
Pythonのバージョンの違いによるもののようです。
(下は試しにTensorFlowでHello表示させたものです）

```
/usr/lib/python3.5/importlib/_bootstrap.py:222: RuntimeWarning: compiletime version 3.4 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.5
  return f(*args, **kwds)
/usr/lib/python3.5/importlib/_bootstrap.py:222: RuntimeWarning: builtins.type size changed, may indicate binary incompatibility. Expected 432, got 412
  return f(*args, **kwds)
b'Hello, TensorFlow!'
```



以上です。
Raspberry Pi のスワップ領域拡張

最近我が家のRaspberry Piのupgradeが失敗するようになりました。スワップ領域拡張を行うことで解消しましたので、そのメモです。

# スワップ領域拡張

/etc/dphys-swapfile の CONF_SWAPSIZE を例えば以下のように編集します。

```
# set size to absolute value, leaving empty (default) then uses computed value
#   you most likely don't want this, unless you have an special disk situation
# CONF_SWAPSIZE=100
CONF_SWAPSIZE=1024
```

設定を反映するには、`sudo /etc/init.d/dphys-swapfile restart` を実行します。反映を確認するには`swapon -s`を実行します。

```
Filename     Type   Size    Used    Priority
/var/swap    file   1048572 0       -2
```


# 参考にしたサイト
[Raspberry Pi Zeroを使ってAmazonの商品を即購入するデバイスを作る](https://qiita.com/gates1de/items/3e532e7834f370361972)
コマンドプロンプトのwriteが使いにくいから秀丸を入れた話

###コマンドプロンプトのwiteが使いにくすぎる
コマンドプロンプトの **write** が使いにくすぎる
 → 何とかwindowsでも開発しやすい環境を作りたい
 → 会社の先輩から　**秀丸**　をお勧めされた（テキストエディタ）
 → **writeコマンドの代わりになるhidemaru.batなるものを作成**
 → 秀丸凄かった笑

##詳細
<details><summary>1.[秀丸をインストール(←クリック)](https://hide.maruo.co.jp/software/hidemaru64.html)</summary>
![2019-04-30_18h37_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/e39bd28b-2d77-7bac-1c31-84b9de33e9ca.png)
インストールしたらお好きな場所で展開して下さい
（defaultだとProgram File配下になるはず）
</details>
<details><summary>2.hidemaru.batを作成</summary>
![2019-04-30_18h33_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/91cea302-54cc-9d5f-c1d9-d17e0da698a6.png)
バッチファイルの中身はこれだけ
hidemaru.exeに引数渡して実行します。という意味
**＊自分のhidemaru.exeファイルのpathに書き換えて下さい**
</details>
<details><summary>3.pathを通す</summary>
![2019-04-30_18h26_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/cac41bf8-c500-d283-d19e-ecf90c8ade6d.png)
環境変数を編集するを開く
![2019-04-30_18h27_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/d3b7d053-8378-88a9-44ae-a4ac8595786f.png)
上記のようにpathが通っているところを確認しその直下にhidemaru.batを格納する
![2019-04-30_18h25_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/684583c4-50d0-7564-6a53-935de2c60885.png)
これでhidemaruコマンドが利用可能になった。
</details>
<details><summary>4.完成</summary>
![2019-04-30_19h01_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222041/d43c2c62-cf70-0e80-7eb5-a04bfedd7fe3.png)
もちろん既存ファイルの編集も可能
</details>

##感想
なんだかんだ、こういうことを教えてくれる先輩ありがたいな～と感じた。
地味なところのフラストレーションが解消されてコマンドプロンプトを少し好きになれた気がする

（実はyamlファイルを編集することが増えたのでコマンドプロンプトから編集できる方法を模索していたところでした。）

あと、これをまねしてくれる皆様には**hidemaru=4000yen**と**ググる**ことをお勧めします。
あくまで！　あ く ま で 、 、　**[ググること](http://members.tripod.com/for_beginers/hidemaru_install4.html)**　をお勧めするだけです。