OmniAICreator/Qiita-1.07M huggingface dataset:
toioをWindows PCとBluetoothでペアリングする

[toio](https://toio.io)を[PowerPoint用のコントローラー（a.k.a クリッカー、プレゼンター）にする記事](https://qiita.com/kaz399/items/8b41ae811c26a3c8bac8)を見てぜひ使いたいと思ったのですが、この中にある「toioをPCにペアリングする」という説明を補足した方がより迷う人が減るかなと思いましたので解説したいと思います。
なお、toio自体は例えば[ビジュアルプログラミング](https://toio.io/programming/visual-programming.html)ではペアリングしなくても使用できますので必ず必要な作業ではなく、アプリケーションに依存します。


# toioのWindows PCとのペアリング方法（Windows10）

- toioの電源を入れます。

![2019-12-23_10h02_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/ff82dbe7-c127-86bf-f021-e401cb051c41.png)
(画像は[こちら](https://toio.io/programming/visual-programming.html)より引用)

- タスクバー（Windows10の場合右下）にあるBluetoothのアイコンを右クリックし、「Bluetoothデバイスの追加」を選択
![2019-12-23_09h51_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/91643a14-c0ea-756e-7a6a-d854b717d67d.png)

- 「Bluetoothまたはその他のデバイスを追加する」を選択
![2019-12-23_09h51_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/c8e979cb-065b-4159-7529-b356e64cc1f8.png)

- 「Bluetooth」を選択
![2019-12-23_09h52_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/7ce1ca74-91b4-b6e3-9fc2-ab97142937f7.png)


- 「toio Core Cube」を選択
![2019-12-23_09h52_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/236f3f2b-6206-55ae-3c7c-e8e74620badf.png)

- 接続中の様子
![2019-12-23_09h53_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/81860655-3d57-e388-f827-5aedf5d441d6.png)

- 接続完了
![2019-12-23_09h53_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/027581fc-df84-a66a-327a-b3078f837319.png)

- 以上でペアリング終了です

# toioをPowerPoint用のコントローラーとして使ってみる

この状態で[GitHub上にある「cubekey」](https://github.com/kaz399/rs_toio_cube/releases/tag/v0.1.0)をダウンロードしてcubekey.exeを実行すると、toioがPowerPoint用のコントローラーになります。
（※動作に関しては無保証のため自己責任でお願いします）

![2019-12-23_10h16_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33040/d365e860-220a-6878-9a61-aee2ad2c5de1.png)

使い方は[こちらの記事](https://qiita.com/kaz399/items/8b41ae811c26a3c8bac8)および[こちらの説明](https://github.com/kaz399/rs_toio_cube/blob/master/cubekey.md)をお読みください。

ぜひみなさんtoioをPowerPoint用のコントローラーとして使ってみてください！
RevealApp - 接続できるデータソース(REST API, SQLServer, MySQL, OneDrive, Oracle, PostgreSQL, SharePoint, ウェブリソース etc..)

# はじめに

## Revealとは
[Reveal  ダッシュボードをアプリケーションに組み込み](https://www.revealbi.io/jp)
> Reveal Embeddedは、アプリケーションに組み込み可能なデータ可視化SDKです。シンプルな価格体系、組み込みの容易さでアプリケーションの価値を最大限向上することができます。

## この記事は
2019年12月時点でReveal App で利用できるデータリソースを紹介します！

# RevealAppで接続できるデータソース一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48623/80177e9a-e966-6d7c-d7d2-650f88b05d2a.png)

- BOX
- Dropbox
- Google ドライブ
- Microsoft Analysis Services
- Microsoft Dynamics CRM
- Microsoft SQL Server
- MySQL
- OData フィード
- OneDrive
- Oracle
- PostgreSQL
- REST API
- SharePoint オンライン
- Sybase
- ウェブリソース

# RevealSDKの場合
RevealSDKを利用頂く場合は、アプリケーションに組み込んでいただくことでインメモリのデータも参照できますので、実質なんでもデータソースにする事ができます。

# まとめ
2019年12月時点ですが、15ものデータリソースへの接続をサポートしています！
メジャーなDBから、汎用性が高いREST APIもサポートしています。
世に存在しているほとんどのデータソースを可視化できるのがRevealの強みです。

それでは、Revealの魅力と使い方についてお伝えしていきますので、
引き続きアドベントカレンダーをよろしくお願いいたします！
機械学習を仕事に使うには？ 01_機械学習の目的を理解する

皆さんこんにちは。
本日からQiitaをはじめました。

普段は機械学習エンジニアとして、AI開発やWebアプリケーション開発に関わっています。

プライベートでは新米パパになりました。
４ヵ月になる長男を抱っこしながら記事を書いています（笑）

記事を書くキッカケとして、まだ参考書がなかった2017年から機械学習に取り組んできましたが、
地道に苦労して機械学習を習得した経験は必ず誰かの役に立つと感じています。


そこで、キャリアアップを目指す人達をサポートできる記事を書こうと決めました。
記念すべき初投稿のテーマは『**機械学習は何のために作られたのか？**』です。


どんなに良い参考書を読んでも、**機械学習の目的が分かっていないと何も習得できない**と思います。
まずは全ての基礎となる全体像を理解していきましょう。


SNS でも色々な情報を発信しているので、記事を読んで良いなと感じて頂けたら
 [Twitterアカウント「Saku731」](https://twitter.com/digisaku710) もフォロー頂けると嬉しいです。


## 機械学習とは
皆さんこんな苦労を味わった経験が有るのではないでしょうか？

**「機械学習の何から学んだ良いのか分からない」**
**「ロジステック回帰、決定木、サポートベクターマシン、、色んな手法がありすぎる」**


機械学習を習得する上で苦しむポイントの１つに **覚えるべき手法の多さ** が挙げられます。
参考書を１冊読み解くだけでも５～１０個の手法を理解する必要があります。

しかも、それらの手法を **「いつ」「どうやって」使い分ける**のか、
丁寧に説明されている参考書に出会った事がありません。

それなら逆に、**様々な手法が存在する理由**や、それらの**共通点**から理解してはどうでしょう？
その方がスピードを持って機械学習の全体像を理解する事が出来ます。


機械学習すべてに共通する目的。
それは**良いモデル**を作るということです。

<img width="100%" alt="image02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/98a68998-8c17-72bd-2858-ea7492db1d34.png">



図を見て頂くと分かる通り、これが機械学習のすべてです。
『 **コンピュータに大量のデータを与えて、予測を行うための法則性を見つけ出す** 』


しかし、世の中には様々な種類のデータが存在します。

- CSV（エクセル）：売上データ、顧客データ
- 画像：インスタに投稿された写真、監視カメラの映像
- 音声：会議のボイスメモ、コールセンターの通話録音


どういったデータであれ、良いモデル（精度の高い予測）を作る事が機械学習エンジニアには求められます。
そのための道具箱として様々な手法が用意されているのです。

- 売上データ ⇒ 回帰（重回帰, 回帰木 など）
- インスタの写真 ⇒ CNNベースの手法（VGG16, LesNet など）
- ボイスメモ ⇒ 時系列解析（RNN, LSTM など）


料理で例えるとすべてに共通する目的は「**おいしい料理を作る**」です。
そのためには、**材料（＝データ）**に応じて適切な**レシピ（＝手法）**を使い分けるのと同じです。


## 機械学習に関連する用語の整理
機械学習の目的が見えてきた所で、もう少し視野を広げてみましょう。

機械学習で最初に苦戦する部分として、
　**AI / 機械学習 / ディープラーニング** 
これらの違いを理解できない人が多い印象です。

AI（機械学習）が流行りだした2018年のニュースや記事を読むと、この３つに関して
「書いた本人もあまり理解できていないのかな？」と感じる文章が多かった記憶があります。


ここの違いを理解しておかないと、せっかく勉強しても
使える知識として体系的に整理されないので重要な論点です。


まず３つの用語 **AI / 機械学習 / ディープラーニング** には図の様な包括関係があります。


![image01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555158/12de9679-7e64-7c79-5ebd-b47ad902a226.jpeg)

（出典：https://www.shikaku-square.com/media/ai-license/001-how-to-study-deep-learning-for-general/）


見て頂くと分かるように、「AI ＞ 機械学習 ＞ ディープラーニング 」という包括関係です。
言葉で整理すると以下の様になります。

- AI ( Artificial Intelligence )：
    - 1950年代の第一次AIブームで誕生した概念のこと
    - 人間の知性 ( Intelligence ) をコンピュータで人工的 ( Artificial ) に再現する事が目的
- 機械学習：  
    - AIを実現するために考えられた具体的な手法のこと
    - 大量のデータから法則性を見つけ出して、将来を予測する事が目的  
- ディープラーニング
    - 機械学習の中でも、 **ニューラルネットワーク** という技術を使用する分野のこと  
    - **特徴抽出** と呼ばれる最も重要な（かつ手間のかかる）AI開発工程を自動化することが目的



こういった基礎知識を大事にすることで、記事・参考書の理解が一気に深まります。
また、機械学習の案件に関わると、プログラマーでなくとも当たり前に知っておくべき知識となってきます。


## さいごに
次回は **AI開発のプロジェクト全体像**を整理したうえで、
**「どこで」「どのように」**して機械学習が使われるのか書こうと思います。
※（2019/12/24 追記）「[第２回：AI開発のプロジェクト全体像](https://qiita.com/Saku731/items/4bbb0798cd55a17e34f0)」を投稿しました

機械学習を勉強した方なら聞いた事があるかもしれない
**「前処理」「学習」「チューニング」「検証」**などの各トピックを
AI開発プロジェクトの進行と紐づけて整理します。


その次の記事では、プログラミング言語 **Python** をベースにして
具体的な勉強方法を整理して行くのでご期待ください。
※（追記）「[第３回：Pythonのコーディング手順を全公開](https://qiita.com/Saku731/items/7f444e1312b85996842f)」を投稿しました。

最後までお読み頂きありがとうございました。



【P.S.】
SNS でも色々な情報を発信しているので、記事を読んで良いなと感じて頂けたら
 [Twitterアカウント「Saku731」](https://twitter.com/digisaku710) もフォロー頂けると嬉しいです。
json からデータを検索、取得し computed にて反映

vue.js で設定ファイルの json に書く

```config.json

  "work":[
    {"key":0,"value":"マッチング後にまずは会いたい"},
    {"key":1,"value":"気が合えば会いたい"},
    {"key":2,"value":"条件が合えば会いたい"},
    {"key":3,"value":"メッセージを重ねて"},
    {"key":4,"value":"その他"}
  ],

```

jsonを読み込む

```hoge.vue

import configJson from '../assets/config.json'

export default {

    data () {
        return {
            configJson:configJson,

```

対応したデータを取得

```

computed: {

    work() {
        const key = this.user.work;//2。
        const computed_tmp = this.configJson.work.find((v) => v.key === key);
        return computed_tmp.value;//条件が合えば会いたい
    }

```

んで取得したデータを表示

```

{{work}}//条件が合えば会いたい

```

と表示される。
まぁ、これがベストなんじゃないでしょうか。
代入演算子"||="の使い方

##||=の意味
||=は代入演算子である。

a ||= b　→　a = a || b

他にも使い方がある
a = a + b　→　a += b 
a = a - b　→　a -= b
a = a * b　→　a *= b
a = a / b　→　a /= b

##||=の使い方
「変数の値がnilなら変数に代入するが、nilでなければ代入しない (変数の値を変えない)」という操作を行いたい時に使う。

```
>> @foo 
=> nil
>> @foo = @foo || "bar"
=> "bar"
>> @foo = @foo || "baz"
=> "bar"
```
vue.js NAN になるのを防ぐ

どう NAN ?
数値を入れるところに一瞬 NAN と表示されるのは。
ちょっと見苦しいじゃありませんか。

ということで。

```

{{age||'-'}} 歳

```

とやると
・数値が異常な場合
・ageに値が代入される前は

`- 歳`と表示される。
エンジニアは朝に弱い

## 概要
この記事はDMMグループ [Advent Calendar 2019](https://qiita.com/advent-calendar/2019/dmm) 23日目の記事です。
2019年5月から[DMMにもフレックスが導入](https://inside.dmm.com/entry/2019/08/28/flextime)されました。
それによって朝の出社時間が揃うことは稀になり、無くなるものがあります。

そう **朝に行うデイリースクラムです。** 

しかし夕方に行うデイリースクラムをやってみて、様々なメリットがあることに最近気が付きました。
私が経験した朝会と夕会のやってることをまず並べますが、そんなに違いは有りません。

| 過去いたチームの朝会       |  今のチームの夕会 |
| :--------- | :----------------------------- |
| 1.やった作業  | 1.昨日やったこと |
| 2.完了した作業  | 2.今日やること |
| 3.困っていることの相談  | 3.困っていることの相談 |
| 4.共有事項があれば  | 4.共有事項があれば |

しかし夕方にデイリースクラムをやることによって変わったことが3つあります。

1. 問題点、困っていることが出やすくなった。
2. ベロシティ(生産性)が上がった。
3. レトロスペクティブ（ふりかえり）の時間が短くなった。

何故変わったのかを考えてみます。

## 1.問題点、困っていることが出やすくなった。

`タイトルどおりエンジニアは朝に弱いので`、朝から昨日の課題をはっきり覚えていて、相談出来る人が少ないように思います。
※説明するために事前に準備することが私も多かったです

なので、その日に困ったことや作業の共有を夕方にすることで、記憶が鮮明なうちに相談・共有することが出来て相談しやすくなったように思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/0cc69beb-07f5-7477-31eb-bff973740630.png)

## 2.ベロシティ(生産性)が上がった。

夕方に今詰まってることなどを気軽に相談すると、気にしてくれたメンバーが次の日手伝ってくれることが増えます。
なので詰まっても解決までが早く、問題を持ち越すことが少なくなりました。
そのため次のタスクに取り掛かる時間が短くなりベロシティが上がりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/3095d38c-889f-04c3-67de-571cb90ab8a3.png)

## 3.レトロスペクティブ（ふりかえり）の時間が短くなった。
**過去によくあった振り返りのボード**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/e69d201c-683c-4fa0-ba81-461b148d6c0d.png)

Problemに問題として初めて認識するものが多く出てきていたイメージがあります（特に開発初期）
そのため1時間の振り返り時間ではすべてをさばき切れないので、ドット投票等を行って話をする問題を絞ります。

その問題についての詳細を知るのが初めてなので、当然記載した人に説明の詳細を求めることも多く、ドット投票を行っても時間が足りないことも多かったです。あとは実は話さなかった付箋が次のスプリントでも解決してなくてまた振り返りで掲載されて、1週間遅れて話をする等もありました。

**今のチームの振り返りのボード**
※今のチームはFDL(Fun/Done/Learn)にProblemを足した形で振り返りをしてますが、わかりやすくするためにKPTで表現します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/b7d0506e-85b4-ef0b-9e12-969cdb687ba4.png)

普段から10分〜30分程度、「問題の共有」をしているので「解決した問題」の再掲載が多い。
また解決してなくても付箋が貼られた時点で内容を把握してることが多くなり、Tryだけに時間を使えるようになりました。

## 最後に
これはあくまで自分のチームの場合うまく行っただけなので、全員が朝型で「夕方以降に相談を受けるのキツイ」という場合もあると思いますが、この記事に思い当たる点があれば、チームで話し合いデイリースクラムを行う時間を変えてみるのも良いかもしれません。
kvmのチューニング

## 参考

* [KVMのパフォーマンスを上げるためにしたこと | 人と情報](https://www.tmp1024.com/articles/enhance-kvm-performance)

## 設定

* ホストCPUの設定をコピーする
* proxmox だと `host` に該当。

![スクリーンショット_2019-12-23_09-41-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/8c8d2bb7-0e69-6ecb-d0f0-49365c52573f.png)
時間制限のある環境下(kernel, colab等)においてDeep Learningの学習を引き継ぐ時の注意点

# 時間制限のある環境下(kernel, colab等)においてDeep Learningの学習を引き継ぐ時の注意点

この記事は、kaggle その2 Advent Calendar 2019のアドベントカレンダー23日目の記事です。


Deep Learningで学習を行う際、オンプレのマシンを持っていない場合は、Kaggleのnotebook(旧kernel)やgoogle colaboratoryなど時間制限のある環境下で学習を行う人も多いと思いますが、そこで起こりうる問題と対処法を書きたいと思います。実装は全てPyTorchです。

## 問題
Kaggleで開催される画像コンペティションの多くは学習に時間がかかるものが多く、最終的なモデルは9時間で終わらないことが多い印象です。その場合途中で学習を切って、checkpointとしてmodelを保存し、別notebookを立て、そのmodelを読み込んで学習を続けることになります。その際2つの問題が発生します。

① optimizer, scheduler, epoch, best_score, best_accなどの状態が引き継がれない  
② seedを固定している場合、各batchに含まれる画像のランダム性が失われる  

## ①optimizer, scheduler, epoch, best_score, best_accなどの状態が引き継がれない  
①についてはmodelと同じくschedulerやbest_scoreなども保存しておかなければ、途中まで学習し終わった状態から再開できません。learning rateが一定であれば関係ないのですが、通常learning rateはExponentialLRや、CosineAnnealingLRなどで変動させることが多いはずです。

![lr_sample_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250105/e4907658-2f60-87bd-3326-a45fa195db25.png)



モデルだけ引き継ぐようにすると、上記の図のように、学習を引き継いだ際にまた最初からschedulerが動いてしまい、意図したものになりません(これはこれで悪くなさそうなんですが)。

### 解決法
毎epoch、モデルとともにoptimizer, scheduler等を保存して、引き継ぐ際に読み出すだけです。


## ② seedを固定している場合、各batchに含まれる画像のランダム性が失われる  
PyTorchのDataLoaderでshuffleをTrueにすると、指定したバッチサイズで毎回データをランダムに吐き出してくれます。

```python
train_loader = DataLoader(train_dataset,batch_size=batch_size, shuffle=True)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)
```

しかし、Kaggleで学習を行う際は再現性を担保するため下記のようなコードでseedを固定する場合が多いと思います。

```python

def seed_everything(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.backends.cudnn.deterministic = True

SEED = conf.SEED
seed_everything(SEED)
```

しかし、学習を引き継ぐ場合、seedが固定されているので、1回目の学習でサンプルされた順番と全く同じ順番でデータが出力されます。下の図は画像が全部で10枚、バッチサイズが2、epochが2で引き継がれたときのイメージです。

![order_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250105/51d50084-ea8c-2dfe-1069-13fcf88d1b83.png)


例えば9時間で10epochしか回せない学習の場合、1~10epoch目の画像の順番と11～20epoch目の画像の順番は全く同じになってしまいます。これが精度にどう影響を与えるのかは要検証なのですが、極端な話毎epoch同じ順番だったらまずそうとは感じるので、なんとかします。

方法はいろいろあるのですが、seed_everythingのseedはあまり変えたくないので、私は学習の引き継ぎ回数をconf.stageで管理しているので、train_datasetを作るときに、seedにconf.stageを入れてsampleして順番を強制的に変更しています。課題によってdatasetの書き方が異なるのであくまでも参考ですが、seed_everythingとは違う引き継ぎごとに変わるseedでshuffleを行うのがもっとも簡易だと思います。

```python
train_dataset = Dataset(conf, df_trn.sample(frac=1, random_state=conf.stage), train_transforms)
```

## 参考
以下は[Recursion Cellular Image Classification](https://www.kaggle.com/c/recursion-cellular-image-classification)の時のnotebookです。途中まではこんな感じでkernelのみで頑張ってました。重いモデルでは9時間で6epochぐらいしか回せずstage10ぐらいまで引き継いで学習していたと思います。

https://www.kaggle.com/c/recursion-cellular-image-classification
byebugでよく使うコマンド

##バッチ処理のコンテナに入る

```
$ docker attach container_name
```


##よく使うコマンド
###byebugで止めた場所を確認

```
(byebug) list
```


###byebugコマンド一覧を表示

```
(byebug) help
```

###next

```
(byebug) n
```

###次のループに回す

```
(byebug) c
```

###byebugの終了

```
(byebug) quit
```
c# 参考サイト メモ

個人メモですみません。


<h4>★Uipath-C#</h4>
<a href="http://okwakatta.net/index.html">猫の気ままなC#日記</a>
<a href="">【C#,LINQ】Select,SelectMany～配列やリスト内の要素の形を変形したいとき～うら干物書き </a>
<a href="">【C#,LINQ】ToDictionary～配列やリストからDictionaryを作りたいとき～</a>
<a href="">C#でExcelを読み込んで操作する方法を公開</a>
<a href=""> 未確認飛行 C OfType<T>メソッドとCast<T>メソッド neue cc</a>
<a href="">未確認飛行 C 日付や時刻を文字列に変換するには？</a>
<a href="https://qiita.com/pizyumi/items/c406f5619e7713ebe701">C#でJSONパーサ</a>


御勉強、アンチョコサイト例 
C# と VB.NET のサンプル：Wankumaさんの処 
http://jeanne.wankuma.com/tips/ 
DOBON.NET プログラミング道：Dobonさんの処 
http://dobon.net/vb/index.html 
++C++; //未確認飛行 C：C#について粗網羅 
http://ufcpp.net/study/csharp/ 
nonsoft ：通信系サンプルで困ったら 
http://homepage2.nifty.com/nonnon/ 
すぐ使えるADO.NET と、関連サイト：DB系含めサンプルが、C#用に書直ししやすい。お勉強用ネタ 
http://park5.wakwak.com/~weblab/ 
MSDN：情報隠しの上手なMSなので、検索にはコツがあります。 
https://msdn.microsoft.com/ja-jp/dn308572.aspx 
TechNet：情報隠しの上手なMSなので、検索にはコツがあります。 
https://technet.microsoft.com/ja-jp/ 
Visual Basic と Visual C# 
https://msdn.microsoft.com/ja-jp/library/hh334523.aspx 
https://msdn.microsoft.com/en-us/library/hh334523.aspx 
ja-JP と en-us 同じ番号で公開されている事も多いです。
おまえは今まで食ったパンの枚数をおぼえているのか？(local変数とState)

#はじめに
この記事は、[VCI Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vci)の23日目の記事です。
VCIにおけるlocalの変数及びSTATEに関する初歩的な内容の記事となってます。
そのため、それ以外の部分の説明は省略しています。
(最終的に「今までに」の部分を満たしていないため若干タイトル詐欺入ってます。)

#おまえは今までに食ったパンの枚数をおぼえているのか？
この言葉は誰しも一度は耳にした事がある言葉だと思います。
しかしあなたはこの言葉をかけられた時、すぐに答えることができるでしょうか？

答えることが出来なければただただ歯を食いしばって怒りを「グ・・・」とこらえることしかできなくなります。
そんな思いをしなくてもいいようにVCIを使って食べたパンの枚数を覚える手順を紹介します。

# おまえは今までに食ったパンの枚数をおぼえていない(level 1)
まずはベースとなる状態です。
![level1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/6b2286f4-99a1-140b-8d43-f72255672682.gif)
見た分かる通り、ただただパンを食べているだけの状態です。
自分が何枚食べたかは全く把握できていません。
ここからちゃんとパン管理できるようにLevelを上げていきましょう


# おまえは今までに食ったパンの枚数をおぼえている(level 2)
食べた枚数を覚えるために、以下のように食べた枚数をカウントする処理を追加します。

```lua
--"Slice N":8枚切りのパンの名前。Nは1~8のいずれか
local count = 0
function onCollisionEnter(item, hit)
  if string.find( item , "Slice" ) and hit == "Counter" then --口元にある見えないオブジェクトにあたったらカウント
    count = count + 1
    vci.assets._ALL_SetText("CounterText", count)
    ---[パンを非表示にする処理(省略)]---
end
```
countという変数で食べた枚数を記憶しておき、CounterTextというで食べた枚数を表示しています。

![level2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/fbe41b7c-0764-6bed-d406-5a247f9e4c8d.gif)
このように今まで食べたパンの枚数を覚えることが出来ました。

# おまえはあいつが今までに食ったパンの枚数もおぼえている(level 3)
level2でローカル変数を使い、自分の食べた枚数を数えることは出来ました。
しかし、実際には止む終えぬ事情で首だけになり、他人の体を乗っ取ることがあるかと思います。
その場合は体が入れ替わるため、今まで相手が食べた枚数を引き継いで覚えていかなければいけません。

ですが、level2の状態では以下のように体(カウンター)を乗っ取っても値を引き継ぐくことは出来ません。
![level3-0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/28d0d24b-0c2d-66d2-ef55-9bcd43024a31.gif)
これはcountの値を各ユーザーばらばらで持っており、
相手が食べた枚数を自分が食べた枚数で上書きしてしまうためです。
(上記の例だと左の赤い子は11枚食べていたためcountが11ですが、右の赤い子は1枚も食べておらずcountが0の状態のため、0+1で表示が1となります)

これを解決するために、他の人と変数を共通で持てる**state**という機能を機能を使用します。
stateでは**Set**で値の設定、**Get**で値の取得をすることが出来ます。
上記機能を使って、変数を共有できるようにしたコードが以下です。

```lua

if vci.assets.IsMine then
  vci.state.Set("eatCount",0)
end

--"Slice N":8枚切りのパンの名前。Nは1~8のいずれか
local count = 0
function onCollisionEnter(item, hit)
  if string.find( item , "Slice" ) and hit == "Counter" then
    local count = vci.state.Get("eatCount") + 1
    vci.state.Set("eatCount",count)
    vci.assets._ALL_SetText("CounterText 1", count)
    ---[パンを非表示にする処理(省略)]---
  end
end
```
(注意点として、「vci.state.Set("eatCount",0)」の部分はvci.assets.IsMineをつかって自分だけ動くようにする必要があります
そうしないと凸者が来るたびに初期化スクリプトが走り、値が0に戻ってしまいます。)

このコードにより無事に今までに食べたパンの枚数を引き継ぐことが出来ました
![level3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/66cce909-2536-41e5-8d9f-e2d50714b7fa.gif)


#いかがでしたか？
今回はVCIにおけるローカル変数とstateの差をパンを数えながら紹介しました。
実際には今回紹介した方法ではVCIを出してから削除するまでの枚数しか数えられていないため、厳密には「今までに」食ったパンの枚数は覚えていない状態です。(タイトル詐欺)
いずれVCIで変数などを保存する方法が追加されたら、「今までに」食ったパンの枚数も数えられるときが来るでしょう。
その時はみんなでパンの枚数を覚えて行きましょう！
Let's enjoy Remember pan！٩( 'ω' )و
Google Apps Scriptを使ってQualityForward APIのテスト集計結果をWeb API化する

[QualityForward](http://bit.ly/2seisx6)はテスト管理のクラウドサービスを提供しています。Web APIも提供しているのですが、各モデルの一覧を返すAPIのみとなっています。検索したり、並び替えるなどの機能がないので、操作が不便に感じる人もいるかも知れません。

そこでGoogle Apps Scriptを間に挟んでQualityForwardの集計結果を返すWeb APIを実現してみます。

## QualityForward用Google Apps Script SDKを使う

Google Apps ScriptでのプロジェクトIDは `1ppRPLjuClG0MhtnXYbskdZ8uYGbyCFHv7MFhr0GYa-3IAKEh8B7lmTMb` になります。これを取り込んでください。以下はデフォルトの `QualityForward` として取り込んだ場合の書き方です。

## 初期化

初期化はAPIキーを適用して行います。

```js
var apiKey = 'aaa';
var qf = new QualityForward.Client(apiKey);
```

## セットアップ

GET処理でデータを取得するので、doGet関数を使います。そしてAPIキーはパラメータとして与えられるようにします。

```javascript
function doGet(e) {
  var out = ContentService.createTextOutput();
  if (!e.parameter.apiKey) {
    return out;
  }
  var qf = new QualityForward.Client(e.parameter.apiKey);
  // :
}
```

## 日々の作業件数を取得する

今回は日々の作業件数を、その結果毎に集計していきます。すべてのテスト結果を得るためには、すべてのテストフェーズ → テストアサインメント → テストサイクル → テスト結果とドリルダウンしながらデータを取得します。それらのデータについて日ごとに集計していきます。

```javascript
var ary = {};
var testPhases = qf.getTestPhases();
for (var i in testPhases) {
  for (var j in testPhases[i].test_suite_assignments) {
    var testSuiteAssignment = testPhases[i].test_suite_assignments[j];
    var testCycles = testSuiteAssignment.getTestCycles();
    for (var k in testCycles) {
      var testCycle = testCycles[k];
      var results = testCycle.getTestResults();
      for (var l in results) {
        var testResult = results[l];
        var d = testResult.executed_at;
        var date = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate();
        if (!ary[date]) {
          ary[date] = {
            pass: 0, fail: 0, skip: 0,
            cut: 0, block: 0, na: 0,
            qa: 0
          }
        }
        ary[date][testResult.result]++;
      }
    }
  }
}
```

後はこの結果をJSONで返すだけです。

```javascript
//JSONテキストをセットする
out.setContent(JSON.stringify(ary));
return out;
```

## ウェブアプリケーションとして公開する

スクリプトができあがったら、公開メニューから「ウェブアプリケーションとして導入する」を選択します。

<img width="500" alt="ScreenShot_ 2019-12-20 15.38.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8d132b19-bb40-ef8d-559e-1503a0a87006.png">

## 実行してみる

では実行してみます。APIキーは皆さんが使っているものに置き換えてください。また、Google Apps ScriptのURLも皆さんのものに変更してください。

```
$ curl -L https://script.google.com/macros/s/AKf...5Xg/exec?apiKey=0aa...340 | jq
{
  "2019-8-16": {
    "pass": 2,
    "fail": 1,
    "skip": 0,
    "cut": 0,
    "block": 0,
    "na": 0,
    "qa": 0
  },
  "2019-11-26": {
    "pass": 4,
    "fail": 1,
    "skip": 1,
    "cut": 1,
    "block": 1,
    "na": 0,
    "qa": 1
  },
```

このように結果が返ってくれば問題ありません。

## まとめ

後はこの結果をCSVとして保存しておいたり、メールしたりできるでしょう。皆さんのテスト管理に役立ててください！

[QualityForward](http://bit.ly/2seisx6)
ドアにスマホを翳して鍵を開ける！

# はじめに
この記事は、Hamee Advent Calenderの23日目です。
https://qiita.com/advent-calendar/2019/hamee

3つ同時に進めてたんだけど残りの2つは終わらず、、この記事だけ公開。
残りの2つは追々公開するかな(Qiitaには書かないけど)。

# きっかけ
家のスマートロックに使ってるQrioの自動解錠機能の反応が悪い時にドアにスマホを翳すだけで開けたくて。

# どうやって実現するのか
スマートロックのSESAMEならAPIが公開されてるからもっと簡単にできるんだろうけど、
うちはQrioなので物理的にボタンを押下する苦肉の策。結果ノンコーディング。
iOS 13.1でショートカットアプリに追加されたオートメーションを利用します。
![EHkwiJYUUAAfca_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/185ec1a1-7197-30dc-fe79-1807428ca962.jpeg)

# やっていく
zozoTシャツのタグについてるNFCタグを切り取る
![IMG_0502.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/8a99013e-6d1a-6e37-48b6-73a297c3ab0c.jpeg)
![IMG_0503.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/18071390-369a-72f6-95a8-2ff62bdf7836.jpeg)
剥く。
![IMG_0504.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/84c6c322-828f-543b-6e33-1b74f7a4d66b.jpeg)
ショートカットアプリのオートメーションを作成する
![IMG_0505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/8bc49f3e-ade9-0487-314b-da05d4bad4f9.png)
NFCを選択する
![IMG_0506.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/55e0972b-692d-a25f-6e60-44146919efd3.png)
RFIDをスキャンして記憶させる
![IMG_0507.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/4cb712a1-39d7-dbe6-0498-bb87bf992ccb.png)
![IMG_0508.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/7689cca2-eca4-78cc-c47c-59132cfdfdc4.png)
![IMG_0512.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/99cf2f35-9b3d-3d6c-da01-9a9b93626ec8.jpeg)
Qrio Key と Switch botを結束バンドでくっつける

![IMG_7088.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71312/73b795c8-f72b-9a71-fe06-b53d10b33bba.jpeg)
ドアにNFCタグを貼り付けて完成。

あとは、iPhoneをNFCタグに翳せば鍵が開く。
Google Apps Scriptを使ってQualityForward APIを便利にする

[QualityForward](http://bit.ly/39Pr5iF)はテスト管理のクラウドサービスを提供しています。Web APIも提供しているのですが、各モデルの一覧を返すAPIのみとなっています。検索したり、並び替えるなどの機能がないので、操作が不便に感じる人もいるかも知れません。

そこでGoogle Apps Scriptを間に挟んでQualityForwardへのアクセスを容易にしてみたいと思います。

## QualityForward用Google Apps Script SDKを使う

Google Apps ScriptでのプロジェクトIDは `1ppRPLjuClG0MhtnXYbskdZ8uYGbyCFHv7MFhr0GYa-3IAKEh8B7lmTMb` になります。これを取り込んでください。以下はデフォルトの `QualityForward` として取り込んだ場合の書き方です。

## 初期化

初期化はAPIキーを適用して行います。

```js
var apiKey = 'aaa';
var qf = new QualityForward.Client(apiKey);
```

## 簡単な使い方

今回はGET処理でデータを取得します。APIキーはパラメータとして与えられるようにします。

```javascript
function doGet(e) {
  var out = ContentService.createTextOutput();
  if (!e.parameter.apiKey) {
    return out;
  }
  var qf = new QualityForward.Client(e.parameter.apiKey);
  // :
}
```

今回はテストフェーズを取得します。

```javascript
var testPhases = qf.getTestPhases();
```

後はこの内容をJSONとして返却します。全件返却なので特に意味はありません。

```javascript
var out = ContentService.createTextOutput();
//Mime TypeをJSONに設定
out.setMimeType(ContentService.MimeType.JSON);

//JSONテキストをセットする
out.setContent(JSON.stringify(testPhases));
return out;
```

## 試す

では実際に呼び出してみます。

```
$ curl -L "https://script.google.com/macros/s/AKfycbzb7QkA-EbdynKorbaAqi3pxD8Ue-91w4jrRW1oxob5AGDXxqaN/exec?apiKey=0aa...340" | jq
[
  {
    "id": 3328,
    "project_id": 748,
    "name": "Redmine連携",
    "start_on": "2019-08-16T00:00:00.000Z",
    "end_on": "2019-09-16T00:00:00.000Z",
    "redmine_issues_url": "https://moongift.planio.jp/projects/website-redesign/issues.json?key=9fac1c578db4ea6a2bc2362ee0435539",
    "test_suite_assignments": [
      {
        "id": 16492,
        "test_phase_id": 3328,
        "test_suite_version_id": 13288
      }
    ],
    "created_at": "2019-08-16T03:26:32.781Z",
    "updated_at": "2019-08-16T03:35:14.758Z"
  },
```

このようにQualityForward APIの結果が返ってきます。後はパラメータを追加して検索結果をフィルタリングしたり、ソートするのも簡単にできそうです。また、集計結果を返す専用のAPIを作るのも難しくないでしょう。

[QualityForward](http://bit.ly/39Pr5iF)
MapをColumnやListViewに表示させるときはMap<key, value>よりもList<MapEntry>の方が便利



# 経緯

```dart

  final Map<String, Color> colors = {
    "yellow": Colors.yellow,
    "blue": Colors.blue,
    "red": Colors.red,
    "green": Colors.green,
    "purple": Colors.purple,
  };
```

上記のようなkey/value形式のデータがあって、これを`.map()`をつかってColumnに表示させようとしたら

> The argument type 'Map' can't be assigned to the parameter List<Widget>

とエラーになってしまった。

MapはListではないのでダメなんですね

# MapEntry

ちょっと調べてみたらいい方法があった
MapEntryというkey/value形式でデータを格納できるものがあるらしい

MapEntryを使うと今回の例だとこうなります

```Dart
  final List<MapEntry<String, Color>> colors = [
    MapEntry("yellow", Colors.yellow),
    MapEntry("blue", Colors.blue),
    MapEntry("red", Colors.red),
    MapEntry("green", Colors.green),
    MapEntry("purple", Colors.purple),
  ];
```

MapEntryを使うとcolorsをListとして扱うことができるのでColumnやListViewと相性がよくなりました
`.map()`の中でも.keyと.valueでkey/valueに触れるのでとても安全ですね

```Dart
            Column(
              children: colors.map((color) {
                return Container(
                  color: color.value,
                  child: ListTile(
                    contentPadding: EdgeInsets.all(20),
                    title: Text(color.key),
                  ),
                );
              }).toList(),
            ),

```

# 最後に

割と普通のこと？なのかもしれないけど今までずっと`Map<key, value>`を使っていたのでやっと存在に気づけてよかった。
結構知らない便利なクラスやWidetがまだまだある気がする

[全体のコードはこちらです](https://gist.github.com/ysknsn/d4d3305f86ac5a234d699d75fc47e5d9)
js table操作

```html
<html>

<head>
<title>title</title>
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>

<body>
	<table>
		<thead>
			<tr>
				<th><input id="all" type="checkbox" onclick="all()" />check</th>
				<th>id</th>
				<th>name</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td><input name="chk[]" type="checkbox" checked /></td>
				<!-- 				<td><input type="checkbox" /></td> -->
				<td>1</td>
				<td>sample1</td>
			</tr>
			<tr>
				<td><input name="chk[]" type="checkbox" /></td>
				<!-- 				<td><input type="checkbox" /></td> -->
				<td>2</td>
				<td>sample2</td>
			</tr>
			<tr>
				<td><input name="chk[]" type="checkbox" checked /></td>
				<!-- 				<td><input type="checkbox" /></td> -->
				<td>3</td>
				<td>sample3</td>
			</tr>
		</tbody>
	</table>
	<button type="submit" onclick="go()">go</button>
</body>
<script type="text/javascript">
	function changeHeader() {
		// tbody以下のチェックボックスとtbody以下のinput要素数が同じか判定
		if ($('tbody :checked').length == $('tbody :input').length) {
			// 全てのチェックボックスにチェックが入っている場合
			$('#all').prop('checked', true); // 「全選択」 = checked
		} else {
			$('#all').prop('checked', false); // 「全選択」 = not checked
		}
	}

	function go() {
		// tbody以下のtr以下の1つ目のtdの値をリスト化
		let list = [];
		$("tbody tr").each(function(i) {
			// checkedの状態か判定
			if ($(this).find("input").prop("checked")) {
				list.push($(this).find("td").eq(1).text());
			}
		})
		console.log(list);
	}

	// 1. 「全選択」する
	$('#all').on('click', function() {
		$("tbody :input").prop('checked', this.checked);
	});
	// 2. 「全選択」以外のチェックボックスがクリックされたら、
	$("input[name='chk[]']").on('click', function() {
		changeHeader();
	});

	// 画面ロード時のfunction
	$(function() {
		changeHeader();
	});
</script>
</html>
```
Vue.js で Android 向けに明朝体を使いたい

Android に明朝体がないのは割と知られてる話で、そういう場合は Google Web フォントとか使うのが一般的ですが、
Vue.js でやったときにちょっとハマったのでメモ。

## TL;DR

- npm パッケージのフォントだとダメっぽい（パッケージ内での実装方法にもよるかも？）
- CSS の `@import` で読ませればOK
- または vue-head パッケージ使ってるならそれを使ってもOK


## Vue.js で Google Fonts を使う

実は、Google Fonts で公開されているフォントはほとんどが npm パッケージからの導入もできて、
typaface/xxx （あるいは typeface-xxx）みたいな感じで検索するとでてきます。

main.js でインポートすればすぐつかえるので、私はいつもこの方法でやっていました。

たとえば、さわらび明朝ならこんなふうに。

インストール

```bash
npm install typeface-sawarabi-mincho --save
# or
yarn add typeface-sawarabi-mincho
```

インポート

```js:main.js
import 'typeface-sawarabi-mincho/index.css'
```

ところが、この方法だと Android でちゃんとウェブフォントが反映してくれませんでした。

## Vue.js で Android でも表示できるように Google Fonts をつかう

じゃあ、どうすればよいのかという話ですが、普通に CSS の `@import` で CDN からインポートすればOKでした。
というかこうしないとうまく行かなかった…。

```vue:FrontPage.vue
<style>
@import url('https://fonts.googleapis.com/css?family=Sawarabi+Mincho');
</style>
```

もしも、普段は sass とか scss で書いていて、 style ブロックに `lang="scss"` とかつけていた場合は、それとは別に style ブロックを追加してあげます。

```vue:FrontPage.vue
<style>
@import url('https://fonts.googleapis.com/css?family=Sawarabi+Mincho');
</style>

<style lang="scss">
html {
  font-size: 62.5%;
  font-family: "Sawarabi Mincho", "Hiragino Mincho Pro", "MS Mincho", sans-serif;
}

#app {
  .section {
  // ...
  }
}
</style>
```

これでOKでした。

## vue-head で読ませる

CSS の `@import` はつかいたくないなぁ、って場合は、HEADタグに突っ込むわけですが、できれば public/index.html は触りたくないなぁ、ということで、`<header></header>` にいろいろ追加できる vue-head を使えばできます。
これは、meta とか title を書き換えるのに使うことが多いですが、スタイルシートや JS、favicon なんかも読ませることができます。
（これらも HEAD 内に書いてるんでまぁ当たり前なのかもしれませんが、意外と忘れがちなのは私だけ？）

```vue:FrontPage.vue
<script>
export default {
  head: {
    link: [
      { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Sawarabi+Mincho' },
    ]
  },
}
</script>
```

## まとめ

- とりあえず、vue-router も使ってて、タイトル書き換えとかしてるなら vue-head つかってるだろうから、そこで読ませる。
- ルーター使ってないような LP などの超シンプルページの場合は、 style ブロックに `@import` するか、それでもヘッダーにはいろいろ書くだろうから、vue-head 入れちゃうのがやっぱり楽かも。
- Vue + Electron みたいな感じで、PC/Mac 向けのアプリにするとかで、Android 全く考慮しないで良い＆どうしてもオフラインで使わなくちゃいけないってときは、 npm の typeface シリーズを使ってもよいのかも
codeanywhereでgitにハロワをプッシュしよう！

# 前置き

codeanywhereを使って、スマホのみでgitにRubyのハロワをプッシュする流れについて解説します。

# 手順

まずはハロワの実行ファイルを作成します。
手順は↓を参照して下さい。
[Codeanywhereを使ってスマホでプログラミングをしよう](https://qiita.com/Auggie_2345/items/b34ea80b5da8b08acdf2)

githubにて、リポジトリを作成します。

Repositories>Desktop versionをタップ。
<img width="375" alt="3C80F71A-8BD3-49F5-A99B-E649A680729A.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/7ee924a1-8bf5-4144-3e18-346062c5a20e.jpeg">


Newをタップ
<img width="375" alt="AFDD3438-E1F9-4211-A944-B81267A92FF2.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/956c1041-c9b1-d6f9-d2be-e28dc5357198.jpeg">

下記のようにリポジトリを作成します。
<img width="375" alt="C9A43831-B59B-4E21-8A22-574288AF2BD9.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/71ad120b-4c60-121e-f852-57c2410aa671.jpeg">



SSH画面にて、下記のリンクの通り操作します。

https://techacademy.jp/magazine/6235

結果はこんな感じです。
<img width="375" alt="959B207B-79E5-4E44-906B-97A994FD8EB1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/083cbce7-6f45-cec3-521b-54a64d38fb97.png">

下の通り、ソースがgitにプッシュされています。
<img width="375" alt="594BD42D-A52A-4784-9115-4C8D6144C1B2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/db208378-39f1-6f3b-52f9-c23f1e9fc527.png">
Rustでchronoを使ってTwitterAPIが返す日付を変換する

# 目的
TwitterAPIを叩くと以下のような日付が返ってきます。

```json
{
"created_at": "Thu Apr 06 15:28:43 +0000 2017"
}
```

この値をchronoのDateTime&lt;Utc&gt;に変換したいです。当初ただparse()を呼べばよいのかと思ったら、きちんとフォーマットを指定して変換しないとダメなことがわかりました。
serde_json::Valueとjsonのキーを渡して、日付を返すメソッドを作成しました。ここではパースに失敗した場合Utc.timestamp(0, 0)を返しています。

# プログラム
```rust:Cargo.toml
[package]
name = "json"
version = "0.1.0"
edition = "2018"

[dependencies]
serde_json = "*"
chrono = "*"
```

```rust:main.rs
#[macro_use]
extern crate serde_json;
use chrono::prelude::*;
fn main() {
    let p = json!({
        "created_at": "Thu Apr 06 15:28:43 +0000 2017"
    });
    let t = get_date_time_from_json(&p, "created_at");
    println!("{}", t);
}

fn get_date_time_from_json(src: &serde_json::Value, key: &str) -> DateTime<Utc> {
    match src[key].as_str() {
        Some(timestamp) => {
            Utc.datetime_from_str(timestamp, "%a %b %d %T %z %Y")
                .unwrap_or(timestamp.parse().unwrap_or(Utc.timestamp(0, 0)))
        }
        None => Utc.timestamp(0, 0),
    }
}
```

```text
2017-04-06 15:28:43 UTC
```
Property Wrappersで値にアクセスしたら自動的に指定した値に戻る仕組みを作る

SwiftのProperty Wrappersで値にアクセスしたら指定した値に戻る仕組みを作ってみました。

指定した値に戻るとは`true -> false`や`Optional.some -> Optional.none`のようなことです。戻る値はProtocolで指定することができます。

私は例えば

- エラーメッセージを表示したい場合に一度アクセスして表示したら次回は値が存在しなくなる
- 画面遷移を発生させる時にtrueをセットしておいて、値アクセス後はfalseに自動で戻る

という様に利用しています。

## 値用Protocolの作成

まず戻る値を指定するProtocolを作成します。
以下のように、否定値として定義しました。

```swift
protocol Negatable {
    static var negativeValue: Self { get }
}

extension Bool: Negatable {
    static var negativeValue: Bool { false }
}

extension Optional: Negatable {
    static var negativeValue: Optional<Wrapped> { .none }
}
```

## Property Wrappersの作成

次にその値に戻る仕組みをProperty Wrappersで作成します。
とても簡単な仕組みで、getしたら保存してある値をnegativeに変更するだけです。

```swift
@propertyWrapper
class Negativile<N: Negatable> {
    private var value: N = N.negativeValue
    
    var wrappedValue: N {
        get {
            let result = value
            value = N.negativeValue
            return result
        }
        set {
            value = newValue
        }
    }
}
```

## 使い方

以下のようなクラスを作成して利用してみると自動的に値が変更されているのが分かります。

```swift
class A {
    @Negativile var b: Bool
    @Negativile var s: String?
}

let a = A()
a.b = true
print(a.b)  // true
print(a.b)  // false
a.s = "test"
print(String(describing: a.s))  //Optional("test")
print(String(describing: a.s))  // nil
```
wslでubuntu その6

#概要

wslでubuntuやってみた。
syscall調べてみた。

#x86 syscall

動かん。Segmentation fault (core dumped)

```
.code32
.text
.global main

main:
	mov		$4, %eax
	mov		$1, %ebx
	mov	 	$msg, %ecx
	mov 	$6, %edx
	int	 	$0x80
	ret

.data
msg:
	.ascii 	"hello "



```

#x64 syscall

動く。

```
.code64
.text
.global main

main:
	mov    $msg, %rsi
	mov    $1, %rdi
    mov    $6, %rdx
    mov    $1, %rax
    syscall
    ret

.data
msg:
	.ascii 	"hello "
```

以上。
mvnコマンドでのSObject生成時にログイン先URLが指定できます

[Apache camel](https://camel.apache.org) では [Salesforce](https://camel.apache.org/components/latest/salesforce-component.html) を使用する際の DTO である SObject を [mvn コマンドから生成](https://camel.apache.org/components/latest/salesforce-component.html#_camel_salesforce_maven_plugin)できます。

ドキュメントでは「POM にclientId, clientSecret, userName や password を設定するのはよくないから、次のコマンドを発行する方がよいですよ」とあります。

> mvn camel-salesforce:generate -DcamelSalesforce.clientId=clientid
> -DcamelSalesforce.clientSecret=clientsecret
> -DcamelSalesforce.userName=username
> -DcamelSalesforce.password=password

.m2 フォルダ配下の setting.xml に  pluginGroups タグ配下に pluginGroup として org.apache.camel.maven を追記して、Salesforce **開発環境** での SObject を生成しようと上記のコマンドを実行すると、以下のエラーが発生しました。

> [INFO] Logging in to Salesforce
> [INFO] Login at Salesforce loginUrl: https://login.salesforce.com/services/oauth2/token
> [INFO] ------------------------------------------------------------------------
> [INFO] BUILD FAILURE
> [INFO] ------------------------------------------------------------------------
> [INFO] Total time:  8.221 s
> [INFO] Finished at: 2019-12-23T08:17:14+09:00
> [INFO] ------------------------------------------------------------------------
> [ERROR] Failed to execute goal org.apache.camel.maven:camel-salesforce-maven-plugin:3.0.0:generate (default-cli) on project ins_sfdc: Error connecting to Salesforce: Salesforce login error {errors:[{"errorCode":"invalid_grant","message":"Login err
or code:[invalid_grant] description:[authentication failure]","fields":null}],statusCode:400} -> [Help 1]

ログイン URL が https://login.salesforce.com/services/oauth2/token になっています。
開発環境では URL が https://test.salesforce.com なので（当然ですが）パラメータが異なるためです。
これは上記の mvn コマンドに -DcamelSalesforce.loginUrl=https://test.salesforce.com を付けると解決できました。

> mvn camel-salesforce:generate -DcamelSalesforce.clientId=clientid 
> -DcamelSalesforce.clientSecret=clientsecret
> -DcamelSalesforce.userName=username
> -DcamelSalesforce.password=password
> -DcamelSalesforce.loginUrl=https://test.salesforce.com

実行すると以下のように処理が進みました。

> [INFO] Login at Salesforce loginUrl: https://test.salesforce.com/services/oauth2/token
> [INFO] Login successful
> [INFO] Salesforce login successful

簡単ではありますが、ご参考になればと思います。

[Japan Camel User Group(JCUG)](https://jcug-oss.github.io/article/why-do-we-have-to-learn-camel-q)では毎月[読書会](https://jcug-oss.connpass.com)を開いています。毎回すごく勉強になる内容なので、ぜひ遊びに来てください。
モバイル環境でNetwork Errorでハマった。「EC2にDocker Caddy Laravel, S3にVuejsの構成」


指摘などウェルカムです。
クロスオリジン(CORS)に関連するエラーなんだと思うけどPCでは動くが、携帯 IOS Iphone7(古い)からのブラウザ（最新）ではsafariもchromeも動かないって現象で結構ハマった。

# 環境

大体の構成
route53から分岐
-> CloudFront+S3にvuejs
-> ALBからEC2(Ubuntu)にDocker Caddy Laravel

# 解決策

サーバー側のクロスオリジンの設定をちゃんと設定する。

Access-Control-Allow-Origin
Access-Control-Allow-Headers
をざっくり設定して * としていた。
これが原因だった。
ちゃんとフロントs3側のホスト名を指定したら動いた。
この記事で必須と書いてあるので、ん？と思って設定したら動いた。


```php
:OK.php
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
  public function handle($request, Closure $next)
  {
    return $next($request)
      //ちゃんとホスティングしてるs3のドメインを指定
      ->header(‘Access-Control-Allow-Origin’, ‘https://hoge.s3.com’)
      ->header(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’)
      ->header(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, X-Token-Auth, Authorization’);
  }
}
```

```php:駄目.php
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
  public function handle($request, Closure $next)
  {
    return $next($request)
      ->header(‘Access-Control-Allow-Origin’, ‘*’)
      ->header(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’)
      ->header(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, X-Token-Auth, Authorization’);
  }
}
```

https://whatsupguys.net/programming-learning-135/


# 調べた履歴

Laravelのルーティングについて結構大事だと思う。
axiosでget, post以外にoptionも使うのでルーティング注意。

```
Route::match(['options', 'patch']'/{test_id}', 'TestController@update');
Route::match(['options', 'delete'], '/{test_id}', 'TestController@destroy');
```

[CORSを許可したLaravel製APIサーバーでput, patch, deleteが出来なくて泣いてたけど、ようやく解決出来た話](https://qiita.com/TsukasaGR/items/8f5713cee20d92f63c07)


CSRFが問題か？
X-Requested-Withヘッダか？

Laravel/Vue SPAs: How to send AJAX requests and not run into CSRF token mismatch exceptions
https://medium.com/@serhii.matrunchyk/laravel-vue-spas-how-to-send-ajax-requests-and-not-run-into-csrf-tokens-mismatch-exceptions-da3b71b287ab
https://www.techalyst.com/posts/vuejs-axios-laravel-x-csrf-token-x-xsrf-token-csrf-protection


axiosが悪いのか？
https://qiita.com/terrierscript/items/ccb56b6fc05aa7821c42

crossのエラーぽいが。
https://stackoverflow.com/questions/50873764/cross-origin-read-blocking-corb
https://stackoverflow.com/questions/38749605/cors-access-control-allow-origin-on-laravel
https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-get-a-no-access-control-allow-origin-header-is-pr
https://github.com/laravel/framework/issues/13643
https://medium.com/@petehouston/allow-cors-in-laravel-2b574c51d0c1

サーバの.htaccessが悪いのか？
https://forum.laragon.org/topic/1435/access-control-allow-origin-is-already-set/6

モバイルではそもそも動かないのか？

Axios doesn't work with Android (emulator) raising a Network Error
https://github.com/axios/axios/issues/973
物体検出について読むならこれ！

Deep Learning論文多すぎませんか？
「物体検出のためのDeep Learning論文」だけでも多すぎませんか？
多すぎて全容を把握できないせいで、逆に R-CNN, YOLO, SSD, CornerNet とその発展ばかり紹介されてませんか？

いやー、**物体検出のためのDeep Learningについての良いサーベイ**があると良いんですけどねー。
という方におすすめなのがこちら！
Deep Learning for Generic Object Detection: A Survey [Li Liu+, IJCV2019]
https://arxiv.org/abs/1809.02165
https://doi.org/10.1007/s11263-019-01247-4

**日本語訳しておきました！**
https://shinya7y.github.io/note/detection/ObjectDetectionSurvey_jp.pdf
アドベントカレンダー合わせでまだ修正途中ですがぜひお読みください。
Railsチュートリアル 第13章 ユーザーのマイクロポスト - 「ユーザーが削除されると、当該ユーザーのマイクロポストも同時に破棄されるようにする」という実装を、Userモデルに追加する

# 「ユーザーが削除されると、当該ユーザーのマイクロポストも同時に破棄されていること」に対するテストを実装する

テストの内容は以下のようになります。名前は「associated microposts should be destroyed」とします。

```ruby:
test "associated microposts should be destroyed" do
  @user.save
  @user.microposts.create!(content: "Lorem ipsum")
  assert_difference 'Micropost.count', -1 do
    @user.destroy
  end
end
```

テストを追加する箇所は、`test/models/user_test.rb`となります。`test/models/micropost_test.rb`ではありませんので注意が必要です。

```diff:test/models/user_test.rb
  require 'test_helper'

  class UserTest < ActiveSupport::TestCase

    def setup
      @user = User.new(name: "Example User", email: "user@example.com",
                      password: "foobar", password_confirmation: "foobar")
    end

    ...略
+
+   test "associated microposts should be destroyed" do
+     @user.save
+     @user.microposts.create!(content: "Lorem ipsum")
+     assert_difference 'Micropost.count', -1 do
+       @user.destroy
+     end
+   end
  end
```

# 「ユーザーが削除されると、当該ユーザーのマイクロポストも同時に破棄されていること」に対するテストを追加した時点でのテストの結果

```
# rails test test/models/user_test.rb
Running via Spring preloader in process 1718
Started with run options --seed 27055

 FAIL["test_associated_microposts_should_be_destroyed", UserTest, 1.2237603999965359]
 test_associated_microposts_should_be_destroyed#UserTest (1.22s)
        "Micropost.count" didn't change by -1.
        Expected: 4
          Actual: 5
        test/models/user_test.rb:81:in `block in <class:UserTest>'

  13/13: [=================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.61126s
13 tests, 22 assertions, 1 failures, 0 errors, 0 skips
```

以下のようなメッセージが表示されて、テストが失敗しています。

```
"Micropost.count" didn't change by -1.
```

「マイクロポストの数が1つ減っていなければならないのに、1つ減っていない」という趣旨のメッセージですね。想定通りの動作です。

# 「ユーザーが削除されると、当該ユーザーのマイクロポストも同時に破棄される」という実装を追加する

`has_many`メソッドに`dependent :destroy`オプションを追加すれば、上記の機能を実装することができます。具体的には、`app/models/user.rb`を以下のように変更します。

```diff:app/models/user.rb
  class User < ApplicationRecord
-   has_many :microposts
+   has_many :microposts, dependent: :destroy
    ...略
  end
```

# 「ユーザーが削除されると、当該ユーザーのマイクロポストも同時に破棄される」という実装を追加した時点で、再びテストを実行してみる

`test/models/user_test.rb`を対象とするテストを再度実施してみましょう。

```
# rails test test/models/user_test.rb
Running via Spring preloader in process 1731
Started with run options --seed 63273

  13/13: [=================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.56839s
13 tests, 22 assertions, 0 failures, 0 errors, 0 skips
```

無事テストが成功するようになりました。
wslでubuntu その5

#概要
wslでubuntuやってみた。
練習問題やってみた。

#練習問題

真理値表を表示せよ。

#サンプルコード

```
.code32
.text
.global main

main:
    mov     $sin, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi

    mov     $0, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $0, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $0, %eax
    mov     $0, %ebx
    xor     %ebx, %eax
    mov     %eax, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi

    mov     $1, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $0, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $1, %eax
    mov     $0, %ebx
    xor     %ebx, %eax
    mov     %eax, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi

    mov     $0, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $1, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $0, %eax
    mov     $1, %ebx
    xor     %ebx, %eax
    mov     %eax, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi

    mov     $1, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $1, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $1, %eax
    mov     $1, %ebx
    xor     %ebx, %eax
    mov     %eax, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi

    ret

.data
sin:
    .asciz  "A B X"
fmt:
    .asciz  "%d "
cr:
    .byte   13
    .byte   0   







```

以上。
wslでubuntu その4

#概要

wslでubuntuやってみた。
練習問題やってみた。

#練習問題

九九を表示せよ。

#サンプルコード

```
.code32
.text
.global main

main:
    mov     $1, %esi
    mov     $1, %edi
loop:
    mov     %esi, %eax
    push    %esi
    mov     %edi, %ebx
    push    %edi
    mul     %bl
    mov     %eax, %esi
    mov     $fmt, %edi
    mov     $0, %eax
    push	%esi
	call 	printf
	pop	 	%esi
    pop     %edi
    pop     %esi
    add     $1, %esi
    cmp     $10, %esi
    jnz     loop
    push    %esi
    push    %edi
    mov     $cr, %edi
    push	%esi
	call 	puts
	pop	 	%esi
    pop     %edi
    pop     %esi
    mov     $1, %esi
    add     $1, %edi
    cmp     $10, %edi
    jnz     loop
    ret

.data
fmt:
    .asciz  "%d "
cr:
    .byte   13
    .byte   0



```

以上。
plunkerでvue その44

#概要

plunkerでvueやってみた。
俺のvueがie11で、動かない。

#SCRIPT1002: 構文エラーです。

ie11は、アローが無い。

```
    axios.get("cart.php").then(response => (this.shop = response.data))
```


```
    var self = this
    axios.get("cart.php").then(function(response) {
       self.shop = response.data
    })
```

#SCRIPT1003: ':' がありません。

ie11は、省略を、許さない。

```
	computed: {
		total() {
			var total = 0;
			for (var i = 0; i < this.items.length; i++)
			{
				total += this.items[i].price;
			}
			return total;
		}
	},
```

```
	computed: {
		total: function() {
			var total = 0;
			for (var i = 0; i < this.items.length; i++)
			{
				total += this.items[i].price;
			}
			return total;
		}
	},
```


#SCRIPT5009: 'Promise' は定義されていません。

ie11は、以下を追加。

```
<script src="https://www.promisejs.org/polyfills/promise-6.1.0.min.js"></script>
```


以上。
PlantUMLでFirebaseのアーキテクチャを書く

シーケンス図を書く時とかはPlantUMLを重宝していて、Firebaseを使ったアーキテクチャを作るときにアイコンがあると少し見栄えがよくなるなと思ったので作りました。


https://github.com/k2wanko/firebase-icons-plantuml

使い方はREADMEに書いてあるのそのままですが、下記のようになっています。

```
@startuml
left to right direction
!define FirebasePuml https://raw.githubusercontent.com/k2wanko/firebase-icons-plantuml/master/plantuml
!includeurl FirebasePuml/FirebaseCommon.puml
!includeurl FirebasePuml/FirebaseAll.puml

actor "Person" as personAlias
Firestore(db, "Database", "Document Database")
Functions(func, "onCreate", "node8")
Analytics(ga, "Analytics", "")
PerformanceMonitoring(monitor, "Performance Monitoring", "")


personAlias --> db
db --> func: firestore.create
func --> personAlias: push notification

personAlias --> ga
personAlias --> monitor
@enduml
```

![](https://github.com/k2wanko/firebase-icons-plantuml/raw/master/assets/activity/activity.svg?sanitize=true)


```
@startuml
!define FirebasePuml https://raw.githubusercontent.com/k2wanko/firebase-icons-plantuml/master/plantuml
!includeurl FirebasePuml/FirebaseCommon.puml
!includeurl FirebasePuml/FirebaseAll.puml

actor "Person" as personAlias
FirestoreParticipant(db, "Database", "Document Database")
FunctionsParticipant(func, "onCreate", "node8")

personAlias --> db
db --> func: firestore.create
func --> personAlias: push notification
@enduml
```

![](https://github.com/k2wanko/firebase-icons-plantuml/raw/master/assets/sequence/sequence.svg?sanitize=true)

それでは良いお年を
GraphQL Javaでのスキーマ定義ファイルのコメントの書き方とGraphiQLやGraphQL Playgroundへの反映

[初めてのGraphQL Webサービスを作って学ぶ新世代API](https://www.oreilly.co.jp/books/9784873118932/)によると、スキーマ定義ファイルにて各スキーマにコメントをする場合は、以下のようにダブルクォーテーション3つで囲むということになっています。

```scheme.graphqls
"""本"""
type Book {

    """ID"""
    id: ID

    """名前"""
    name: String

    """ページ数"""
    pageCount: Int

    """著者"""
    author: Author![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23101/6f44c6e0-4691-8ca9-a029-0d5ef55f6d7e.png)

}
```

上記のように書くことで、GraphiQLやGraphQL PlaygroundのDescriptionにもダブルクォーテーション3つで囲ったコメントが表示されるようになるとのことでした。
ただ、当方Java + Spring BootでGraphQLを軽く書いている中で、上記の書きっぷりだとGraphiQLやGraphQL Playgroundへは反映されず、No Descriptionとなってしまうことに気付きました。

そのため、以下のように先頭に#を置く書くことで解決しました。

```scheme.graphqls
# 本
type Book {

    # ID
    id: ID

    # 名前
    name: String

    # ページ数
    pageCount: Int

    # 著者
    author: Author
}
```

GraphiQLとGraphQL Playgroundで確認すると以下の通り表示されるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23101/37317e85-2081-be25-4104-b1f8cbb269ca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23101/20f08711-396c-1911-d8dd-242843e3ad3e.png)
以上です。