OmniAICreator/Qiita-1.07M huggingface dataset:
Graphvizのインストール方法・使い方

#1. 環境設定
・http://ruby.kyoto-wu.ac.jp/info-com/Softwares/Graphviz/
　にアクセス
・graphviz-2.38.zipをダウンロードして展開、適当に場所に保存
・例えば、C:\graphvizに保存した場合、C:\graphviz\release\binにPathを通す
・パソコンを再起動する

#2. 具体的なコードの書き方
```python

from graphviz import Digraph
g = Digraph(engine='neato', format='png')
g.node('0', label="place1", fontname='Meiryo UI', shape = "box", pos="0,0!")
g.node('1',label="place2", fontname='Meiryo UI', shape = "box", pos="10,0!")
g.edge("0","1",label="100", fontname='Meiryo UI')
g.view()#これで描画
```
・engineの種類は、
　circo	円形のグラフ.
　dot	階層型のグラフ. 有向グラフ向き. デフォルトのレイアウトエンジン
　fdp	スプリング(ばね)モデルのグラフ. 無向グラフ向き.
　neato	スプリング(ばね)モデルのグラフ. 無向グラフ向き.
　osage	配列型のグラフ.
　sfdp	fdpのマルチスケール版. 大きな無向グラフ向き.
　twopi	放射型のグラフ. ノードは同心円状に配置される.
特定サイトだけローカルプロキシを通す設定

#はじめに
家のV6プラス環境では一部サイト（というか勤務先）につながりにくいという問題があります。
このままだと将来的に行うことになるかもしれないテレワークの障害になりそうだったので、VPNで接続しているさくらVPSにローカルプロキシを構築し、該当サイトのみプロキシを経由して接続するようにしてみました。
（まあ全部プロキシ経由でもいい気はしますが、うっかりYoutubeなんかでVPSの帯域制限に引っかかっても嫌なので・・・）

#前提環境
 - サーバ：debian 10 Buster
 - クライアント：Windows 10
 - 自宅サーバとVPSが拠点間VPNで接続されている

#作業の概要

##VPS(debian 10 Buster)

- squidのセットアップ

##自宅サーバ(debian 10 Buster)

- nginxのインストール（デフォルト設定のみ）
- PACファイルの配置

##LAN内PC(Windows 10)

- 自動プロキシの設定

#構築手順

##VPS

###squidのインストール

```bash
# apt install squid
```

###squidの設定

```bash
# vi /etc/squid/squid.conf
```

```conf:/etc/squid/squid.conf
# ローカルネットワークのネットワークアドレス
acl lan src 192.168.1.0/24

# 接続先として指定されているポート以外を拒否
acl Safe_ports port 80      # http
acl Safe_ports port 21      # ftp
acl Safe_ports port 443     # https
acl Safe_ports port 70      # gopher
acl Safe_ports port 210     # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280     # http-mgmt
acl Safe_ports port 488     # gss-http
acl Safe_ports port 591     # filemaker
acl Safe_ports port 777     # multiling http
http_access deny !Safe_ports

# SSL接続時に 443 ポート以外の CONNECT を拒否
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports

# ローカルホストを許可
http_access allow localhost

# ローカルアドレスを許可
http_access allow lan

# その他のアドレスを拒否
http_access deny all

# 応答ポートを指定
http_port 8080

# コアダンプ出力場所
coredump_dir /var/spool/squid

# キャッシュの設定
refresh_pattern ^ftp:       1440    20% 10080
refresh_pattern ^gopher:    1440    0%  1440
refresh_pattern -i (/cgi-bin/|\?) 0 0%  0
refresh_pattern .       0   20% 4320

# squidを経由していることを隠す
request_header_access Referer deny all
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all
forwarded_for off

# ログローテートの設定
logfile_rotate 0
```

設定が終わったらsquidを再起動する。

```bash

# systemctl restart squid
```

##自宅サーバ

###nginxのインストール

設定は何もいりませんｗどうせローカル運用だし。

```bash
# apt install nginx
```

###PACファイルの配置

nginxのデフォルトルートフォルダ(/var/www/html)配下にproxy.pacを作成する。

```bash
# vi /var/www/html/proxy.pac
```

```javascript:/var/www/html/proxy.pac
function FindProxyForURL(url,host){
        if(shExpMatch(host,"<ホスト名のマッチング文字列>")){
                return "PROXY <VPSのVPNアドレス>:<ポート番号>";
        }
        return "DIRECT";
}
```

作成したproxy.pacの所有者をwww-dataに変更

```bash
# chown www-data:www-data /var/www/html/proxy.pac
```

作成したproxy.pacのパーミッションを変更

```bash
# chmod 644 /var/www/html/proxy.pac
```

##LAN内PC(Windows 10)

###自動プロキシ設定

[**スタートメニュー**] → [**設定**] → [**ネットワークとインターネット**] → [**プロキシ**] と開き、
[**自動プロキシ セットアップ**] の
[**セットアップ スクリプトを使う**] をオンにし、
[**スクリプトのアドレス**] に
 `http://<VPSのVPNアドレス>/proxy.pac` と入力する。
![proxy_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298004/c87a3897-d682-de28-8752-bb280f574015.png)
あとはブラウザを開き、サイトに正常にアクセスできるか確認して終了です！
Vuetify の パンくずリスト (Breadcrumbs) のリンクが効かない


`exact` に `true` を指定してください。これで改善する場合があります。

```vuejs
<template>
  <v-breadcumbs :items="[
    { text: 'タイトル1', to: '/path/to/link1/', exact: true },
    { text: 'タイトル2', to: '/path/to/link2/', exact: true },
    { text: 'タイトル3', to: '/path/to/link3/', exact: true },
    //                                         ^^^^^^^^^^^^ これです。
  ]" />
</template>
```

マニュアルを読み落としていました... orz

> デフォルトでは、 v-breadcrumbsはネストされたパスの現在のページまでの、すべてのbreadcrumbを無効にします。 items配列の該当する各breadcrumbで exact: true を使用することで、この動作を防ぐことができます。
>
> * [パンくずリスト (Breadcrumbs) - Vuetify](https://vuetifyjs.com/ja/components/breadcrumbs/)

また、関係ないですが `to` ではなく `href` にパスを記述すると画面が更新され、SPA 的な動作をしなくなります。
bit全探索を使用して「C - Skill Up」を解こう

##[ビット全探索を学ぶ](https://qiita.com/RubyLrving/items/dd79f8a3d1494439b5eb)
前回の記事でbit全探索を学びました。


##[C - Skill Up](https://atcoder.jp/contests/abc167/tasks/abc167_c)
問題文はAtcoderを参照してください。

- N冊文のbit列を用意
- 1のフラグの箇所を各列加算して全ての列の合計がXを超えているか
- 全ての列の合計がXを超えていた場合の金額を集計
- 最小金額を表示
- 何も存在しない場合は-1を表示
- bitsetは最大値の12を指定

```C++:C++
#include <iostream>
#include <vector>
#include <cmath>
#include <bitset>
 
using namespace std;
using ll = long long;

int main(int argc, const char * argv[]) {
    
    int N, M, X;
    cin >> N >> M >> X;
    
    vector<int> c(N, 0);
    vector<int> money;
    int** A = new int*[N];
    
    for(int i=0; i<N; i++){
        cin >> c[i];
        A[i] = new int[M];
        for(int j=0; j<M; j++){
            cin >> A[i][j];
        }
    }
    
    for(int tmp=0; tmp < (1 << 12); tmp++){
        bitset<12> s(tmp);
    
        int m=0;
        vector<int> skill(M,0);
        for(int i=0; i<12; i++){
            if(i>=N) continue;
            if(s.test(i)==1){
                for(int j=0; j<M; j++){
                    skill[j]+=A[i][j];
                }
                m += c[i];
            }
        }
        
        int count=0;
        for(int i=0; i<M; i++){
            if(skill[i]>=X){
                count+=1;
            }
        }
        
        if(count>=M){
            money.push_back(m);
        }
    }
    
    if(money.size() > 0){
        int ans=money[0];
        for(int i=1; i<money.size(); i++){
            ans=min(ans, money[i]);
        }
        cout << ans << endl;
    }else{
        cout << "-1" << endl;
    }
    
    for(int i=0; i<N; i++){
        delete A[i];
    }
    delete[] A;
    
    return 0;
}
```

##[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)
おすすめの過去問が終わりました。
代表的なアルゴリズムでした。

| グリッドに関する処理 | ABC 075 B, ABC 096 C | 今後超頻出です |
|:--|:--|:--|
| 区間の重なりを求める処理 | ABC 070 B | 今後頻出です |
| 答えを 1000000007 (など) で割った余りで求める | ABC 055 B | 途中計算ごとに % をとってよいことを理解しましょう |
| 数学的問題 | ABC 046 B, ABC 048 B |  |
| 状態がループするシミュレーション処理 | ABC 060 B, ABC 065 B | 今後頻出の考え方です |
| 累積和 | ABC 087 C, ABC 098 C | 今後超頻出のテクニックです |
| bit 全探索 | ABC 079 C | 2n2n 通りを調べる手法です |

次回から[AtCoder 版！蟻本 (初級編)](https://qiita.com/drken/items/e77685614f3c6bf86f44)に挑戦していきます。
chart.js使ってグラフ作成してみた

#Railsで作成したアプリにグラフを簡単に入れる方法

##環境

ruby 2.5.0p0
Rails 5.2.4.2
slim

##サンプルイメージ

こんなグラフが簡単に出来上がります。

<img width="574" alt="スクリーンショット 2020-05-12 18.20.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381043/ab8abd43-424f-e38f-8ece-d8e225e456fa.png">


##手順

gem インストール

```
$ gem 'chart-js-rails', '~> 0.1.4'
```

```
bundle install
```

chart.js インストール

```ruby:package.json
{
  "name": "hoge",
  "private": true,
  "dependencies": {
    "chart.js": "^2.7.1" ←★追記
  }
}
```

```
$ yarn install
```

// = require Chart.min　を追記

```javascript:hoge/app/assets/javascripts/application.js

// = require Chart.min
// = require rails-ujs
// = require activestorage
// = require turbolinks
// = require_tree .

```

view側

```slim:app/views/hoge/index.html.slim
<canvas id="myChart" width="400" height="400"></canvas>
javascript:
  draw_graph();
```


```javascript:hoge/app/assets/javascripts/hoge.coffee

window.draw_graph = -> 
    ctx = document.getElementById("myChart").getContext('2d')
    myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
            datasets: [{
                label: '# of Votes',
                data: [12, 19, 3, 5, 2, 3],
                backgroundColor: [
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255,99,132,1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero:true
                    }
                }]
            }
        }
    })
```

動作確認

```
$ rails s
```

下記の記事を参考に自分でも試してみましたが、30分ぐらいですぐに作成することができました。アプリにグラフを導入してみたい方にオススメです。

次はユーザーが見やすいようにカスタマイズしていきます。


##参考記事


https://www.chartjs.org/docs/latest/

https://railsguides.jp/asset_pipeline.html

https://qiita.com/mikuhonda/items/e94bdb8b6778ce9df59c

https://qiita.com/Y_uuu/items/ef107a02c27836696545
Check running Linux's kernel configs

You can check under `/boot`, but sometimes there is nothing. Then you can get it from `/proc/config.gz`:

```shell
cat /proc/config.gz | gunzip > running.config
```

or

```shell
zcat /proc/config.gz > running.config
```

or 

```shell
zgrep CONFIG_PROC_EVENTS= /proc/config.gz
```

or

```shell
zless /proc/config.gz
```
【エンジニア向けドリンク？】ZONe ver.1.0.0！

# デジタルパフォーマンスエナジー ver.1.0.0
いつもならコンビニに行くときには必ず[モンスター白](https://www.monsterenergy.com/jp/ja/products/monster-energy)を買っているのですが、さすがに本日は2本も飲んでいることもあり、別の飲み物を探していました。
そんな時、目に映ったのが
**ver. 1.0.0**
という文字！
これを見た瞬間ちょっとわくわくしちゃって買ってしまいました。
![IMG_6086.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119747/d83f6218-3eaf-db66-945a-2dd07d16db03.jpeg)
ver. 1.0.0という切りのいい数字、そういえば意外と見たことなかったのでびっくり！

そしてこちら
**[デジタルパフォーマンスエナジー ver.1.0.0](https://zone-energy.jp/)**
という商品らしくなんとなくエンジニア向け？な気がしましたｗ

そしておもしろいことに以前まで「Zone β ver. 0.8.5」という商品があったそうです。（[参考](https://ameblo.jp/musiclove-rock/entry-12596491912.html)）

なので本日5月12日の販売開始はちゃんと**正式**販売開始という扱いらしくこれからどのようにアップデートされていくか楽しみです。

# 感想
[こちら](https://ameblo.jp/musiclove-rock/entry-12596491912.html)にも書いてあるのですが、いつも[モンスター白](https://www.monsterenergy.com/jp/ja/products/monster-energy)を飲んでいる自分からすると結構王道な感じの味がしました。
いつもエナジードリンクを飲んでいる方からするとかなり飲みやすくせっかくver.1.0.0なので初期ユーザとして乗り換えても良いかもしれませんね。
ちなみに今回は黒を飲んでいますが、近所のコンビニには赤もありました。

# 復習
せっかくなのでバージョン管理のおさらい！

- バージョン管理は一般的に正式提供で「1.0.0」というバージョン番号が振られます。
- そこからマイナーバージョンでの改良があると「1.1.0」となります。
    - 一般的には互換性のある変更を表します。
- 小規模なバージョンアップでは「1.0.1」といったように一番下の数字が変更
    - 一般的には仕様修正のない簡単なバージョンアップを表します。
- 大規模なバージョンアップでの改良があると「2.0.0」となります。
    - 一般的には互換性のあるへんこうを表します。

つまり、
**メジャーバージョン.マイナーバージョン.リビジョン**
といった書き方になります。
ただし、上記で「一般的に」といった書き方をしていることでもそうですが、バージョン管理の仕方やそのプロジェクトの考え方で変わってくることも多くあります。
そもそも
**メジャー.マイナー.ビルド.リビジョン**
となっていたり...等々

何はともあれ、デジタルパフォーマンスエナジーの今回のリリースのバージョンは
**ver. 1.0.0**
なので今後が楽しみですね！

p.s. 初めてのQiita投稿をエナジードリンクに使ってしまった...。
個人開発のUnityアプリをGoogle Playに公開するまで

#概要
個人開発したUnity製のアプリをGoogle PlayとApp Storeに公開したのでプロセスを整理がてらまとめてみた。
App Store版はこちら -> [個人開発のUnityアプリをApp Storeに公開するまで](https://qiita.com/tanakaPH/items/727e3951a68a2b2a56e2)

#前提
- PCはMac or Windows

- Unityで開発

- Android Studioインストール済

- [Android Developer](https://developer.android.com/distribute)に登録済
 （$25が**1回限り**必要、筆者は時価で税込&yen;2,744だった）

- ストア公開に必要な情報が準備済
参考 -> [Androidアプリ申請要綱まとめ【Google Play Console】](https://qiita.com/umi_mori/items/201004a5bdacda6237e2)



#Google Playへの公開手順
全体像は以下の通り、非常にシンプル。
![qiita用.003.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/5dc62d53-98a9-a7b0-f748-fb8955996abf.jpeg)

事前にUnityのPreferenceからAndroid SDK, JDK, NDKのパスを通しておくこと。
ただし、最近のUnityはUnity Hubからインストールして自動でバスを通せる、超便利。
参考URL -> [Android SDK, NDKをUnity Hubからインストールする方法](https://yanpen.net/unity/install_android-sdk-ndk_from_unity_hub/)

###1. UnityのPlayer Settingsで必要な情報を登録する
- Product Name -> アプリアイコンの下に表示されるアプリ名（主言語）
- Package Name -> いわゆる識別子。ドメインを逆にしたもの（jp.co.[団体名].[アプリ名]）が一般的。
- バージョン番号 -> 公開用のバージョン番号（ex. 1.0, 1.1, 2.0 ...）
- ビルド番号 -> 内部ビルド用のバージョン番号（ex. 1, 2, 3, ...）
- アイコン画像 -> インストール後のアプリアイコン画像

※アプリをローカライズしていて、副言語のアプリ名を指定したい場合は、下記URLを参考にstrings.xmlを配置する。
参考 -> [[Unity]アプリ名ローカライズ対応メモー](https://qiita.com/ptkyoku/items/3f25872ae0f356966c88)

###2. 自身の電子署名付証明書を発行する
下記URLを参考にKeyStore Managerから証明書を発行し、PCに保存する。
保存した後は証明書を読み込ませればOK
（Unity再起動後のビルドはパスワードを聞かれるので忘れないように）。
参考 -> [[Unity]KeyStore作成メモー](https://qiita.com/ptkyoku/items/3fb1ae542ff04423c781)

###3. Unityでビルド
そのままapkとしてビルドしてもいいが、オプションでaabを選択するとGooglePlayConsoleアップロード時に、自動でアプリサイズを最適化したapkを作成してくれるのでオススメ。

###4. GooglePlayConsoleで必要情報を登録し、ファイルをアップロード
下記URL等を参考にGooglePlayConsoleで情報を登録していく。
各言語でのローカライズ方法も説明されている。
参考 -> [[Android] アプリを Google Play Console に登録する](https://akira-watson.com/android/developer-console.html)

###5. 審査後にアプリ公開
審査が通れば晴れて公開となる。
執筆時点では、大体審査に出してから4日ぐらいで公開されるイメージ。

#結論
Androidの場合はUnityで全て完結できてしまうので素晴らしい。
プロビジョニングファイル周りがややこしいiOSとは大違い・・・。

ちなみに作ったゲームアプリはこちら -> [とんずらぺーちゃん（Android）](https://play.google.com/store/apps/details?id=com.EgoTechCommunity.EscapingGoldfish)
![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/f6150684-d629-2c99-f69c-fdf5586a2c07.png)
UnityのPrefabのAsset Path

CustomEditorでPrefab modeでの選択時に何故かとれなかったので
#### Scene上のInstanceの場合

```
var assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab)
```

#### Prefab Modeの場合
PrefabStageを取得してそこからとる

```
using UnityEditor.Experimental.SceneManagement;

var prefabStage = PrefabStageUtility.GetPrefabStage(prefab);
if (prefabStage != null)
{
    var assetPath = prefabStage.prefabAssetPath
}
```
rails routes member と collectionの違い

#rails routes member と collectionの違い

`resources(RESTfulルーティング)`を利用すると7つのデフォルトのルーティング`(index,create,new,edit,show,update,destroy)`が自動で生成されます.

ただ,自分で定義した独自のアクションへのルーティングを設定する場合は`member`または`collection`というオプションを利用する必要があります。

その際に,memberとcollectionの違いが気になり調べたので両者の違いをまとめます。

## 目次
* [はじめに](#はじめに)
* [やりたいこと](#やりたいこと)
* [やり方](#やり方)
* [おまけ](#おまけ)

## はじめに

検証用にPostsコントローラへのルーティングファイルを作成します.

```ruby:routes.rb
Rails.application.routes.draw do
    resources :posts 
end
```
デフォルトで以下の7つのルーティングが生成されます.`(index,create,new,edit,show,update,destroy)`

```bash
 Prefix Verb   URI Pattern               Controller#Action
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy
```

## やりたいこと

今回,Postsコントローラにmypostsアクションを定義したのでルーティングを追加したい

## やり方

collectionを以下のように追記します.

```ruby:routes.rb
Rails.application.routes.draw do
 resources :posts do
  +  collection do
   +   get 'myposts'
  +  end
  end
end
```

mypostsアクションへのルーティングができています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/e949c2ad-7e5f-61e1-37ec-bf4726b0e953.png)
## memberとの違いは？

一言でいうと:idが付くか,付かないかです。
試しに実装してみます。

```ruby:routes.rb
Rails.application.routes.draw do
  resources :posts do
  +  member do
   +   get 'myposts'
  +  end
  end
end


```

idがついているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/36318ee5-c37e-85a4-2260-b8b734802041.png)

つまり以下の用途で使い分けます。

1. アクションにidを渡したいとき -> memberオプション
2. idを渡す必要がないとき -> collectionオプション

*[詳細はRailsガイド参照](https://railsguides.jp/routing.html#restful%E3%81%AA%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%81%95%E3%82%89%E3%81%AB%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)

## おまけ

### アクションが1つだけのとき

今回のようにカスタムアクションが1つだけの場合は`on :`オプションが使えます。

```ruby
Rails.application.routes.draw do
  resources :posts do
      get 'myposts', on: :collection
  end
end
```

```bash
       Prefix Verb   URI Pattern               Controller#Action
myposts_posts GET    /posts/myposts(.:format)  posts#myposts
        posts GET    /posts(.:format)          posts#index
              POST   /posts(.:format)          posts#create
     new_post GET    /posts/new(.:format)      posts#new
    edit_post GET    /posts/:id/edit(.:format) posts#edit
         post GET    /posts/:id(.:format)      posts#show
              PATCH  /posts/:id(.:format)      posts#update
              PUT    /posts/:id(.:format)      posts#update
              DELETE /posts/:id(.:format)      posts#destroy
```
redux-percistでストア永続化（React Native）

# ストア永続化
reduxではストアがグローバル管理されているので、永続化も簡単です。
加えて、redux-percistを使うとさらに簡単に永続化ができます。
https://github.com/rt2zz/redux-persist

以下はReact Nativeでの例ですが、もちろんstorageを変更することでReactJSでも利用できます。

# 導入方法

### configureStore.jsを作成

```jsx
import { createStore, compose, applyMiddleware } from 'redux';
import { persistStore, persistCombineReducers } from 'redux-persist';
import AsyncStorage from '@react-native-community/async-storage';
import { createLogger } from 'redux-logger';

import rootReducers from 'app/reducers'; // where reducers is a object of reducers

const config = {
  // 保存データのrootキー
  key: 'root',
  // React NativeなのでAsyncStorageを使用
  storage: AsyncStorage,
  // loadingReducerは保存しないようにする、whitelistも可能
  blacklist: ['loadingReducer'],
  debug: true, //to get useful logging
};

const middleware = [];

if (__DEV__) {
  middleware.push(createLogger());
}

const reducers = persistCombineReducers(config, rootReducers);
const enhancers = [applyMiddleware(...middleware)];

const persistConfig = { enhancers };
const store = createStore(reducers, undefined, compose(...enhancers));
const persistor = persistStore(store, persistConfig, () => {
  console.log('テスト', store.getState());
});
const configureStore = () => {
  return { persistor, store };
};

export default configureStore;
```

### エントリポイントをPersistGateでラップする

```jsx
import React from 'react';
import { ActivityIndicator } from 'react-native';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/es/integration/react';

import Navigator from 'app/navigation';
import configureStore from 'app/store/configureStore';
const { persistor, store } = configureStore();

export default function Entrypoint() {
  return (
    <Provider store={store}>
      <PersistGate loading={<ActivityIndicator />} persistor={persistor}>
         <Navigator />
      </PersistGate>
    </Provider>
  );
}
```

# データの削除
persistor.purge()で永続化されたデータを削除できます。

# マイグレーション
ストアの構造が変わることを想定して、schemaVersionなどを設定しておくと便利。

```typescript
const schemaVersion = persistConfig.schemaVersion;

AsyncStorage.getItem('schemaVersion').then((localSchemaVersion) => {
  const schemaUpdated = localSchemaVersion !== schemaVersion;
  if (schemaUpdated) {
    persistStore(store, config, callback).purge();
    AsyncStorage.setItem('schemaVersion', schemaVersion);
    return;
  }
  persistStore(store, config, callback);
}).catch(() => {
  persistStore(store, config, callback);
  AsyncStorage.setItem('schemaVersion', schemaVersion);
});
```

# まとめ
そのままStoreを保存しておいてくれるのでとても便利。
laravelでcsvファイルImportするだなも

#csvファイルのインポート
今回はLaravelでのcsvインポート機能を簡単にまとめました。
結構使い回せるので自分のメモとしても。

また、今回は配列に入れて返すだけなので、DBに保存とかする場合はまた別の機会にまとめます。



```php:CsvService.php
protected static $csv_header = [
    'name', 'age', 'gender', 'height', 'weight'
];

private static function validateHeader($header)
{
    return $header === self::$csv_header;
}

public static function csvImport($file)
{
    $csv_array = [];

    $csv = new \SplFileObject($file);
    $csv->setFlags(
            \SplFileObject::READ_CSV |        // CSV 列として行を読み込みます。
            \SplFileObject::READ_AHEAD |      // 先読み/巻き戻しで読み出します。
            \SplFileObject::SKIP_EMPTY |      // ファイルの空行を読み飛ばします。この時READ_AHEAD フラグを有効に。
            \SplFileObject::DROP_NEW_LINE     // 行末の改行を読み飛ばします。
    );

    foreach ($csv as $index => $row) {
        $row = Utf8BomService::remove($row);  //BOM付いてたらBOM外す　ここは別のServiceクラスで
            
        if ($index === 0) {
            if (! self::validateHeader($row)) {
                return false;
            }
            continue;
        }

        $csv_array[$index]['name']   = $row[0];
        $csv_array[$index]['age']    = $row[1];
        $csv_array[$index]['gender'] = $row[2];
        $csv_array[$index]['height'] = $row[3];
        $csv_array[$index]['weight'] = $row[4];
    }

    return $csv_array;
}
```

##SplFileObject クラス使おう
世の中には便利な機能があるもんで、空行読み飛ばしてくれたり面倒なことは全部彼がやってくれます。

[SplFileObjectクラスのドキュメント](https://www.php.net/manual/ja/class.splfileobject.php)

##まとめ
基本的にはこれでcsvの中身を取ってこれます。
基礎的な箇所のみまとめたのでエラーハンドリングとかバリデーションとかは今回省いてます。
こっからは実装したいものによって拡張して下さい。

次はexport書きます。
AndroidとiOSでテキストフィールドの入力文字を制限する


# やること
- Android/iOSそれぞれで、テキストフィールドに半角文字のみ入力できるように実装する。

# Android

```RegexInputFilter.kt
open class RegexInputFilter(private val pattern: String) : InputFilter {
    override fun filter(
        source: CharSequence,
        start: Int,
        end: Int,
        dest: Spanned,
        dstart: Int,
        dend: Int
    ): CharSequence {
        return if (source.toString().matches(Regex(pattern))) {
            source
        } else {
            ""
        }
    }
}

class AlphanumericInputFilter : RegexInputFilter("^[a-zA-Z0-9]+$")
```

EditTextのfiltersに、半角英数のInputFilterをセットします。

```SampleFragment.kt
edit_password.filters = arrayOf(AlphanumericInputFilter())
```


# iOS

UITextFieldの`Editing Changed`イベントで、不正な文字を削除します。

```SampleViewController.swift
@IBAction func textFieldDidChange(_ sender: UITextField) {
    sender.text = (sender.text ?? "").filter({ String($0).isMatch("^[a-zA-Z0-9]+$") })
}
```

## ❌ダメだった方法

以下のように UITextFieldDelegate の `shouldChangeCharactersIn`で制限する方法だと、日本語入力された場合に対応できませんでした。

```Bad.swift
// ❌ 日本語入力に対応できない
extension SampleViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let pattern = "^[a-zA-Z0-9]+$"
        return string.isEmpty || string.range(of: pattern, options: .regularExpression, range: nil, locale: nil) != nil
    }
}
```

参考: [UITextFieldで入力された文字の判定や、文字数、Byte数を取得する](https://qiita.com/tananonaka/items/537b9768c15408289afa)
【Redash】pythonの関数内で標準ライブラリが使えない

Redashでpythonをデータソースとして使っていて、ちょっとハマったので残しておきます。

## 環境
* Redash 7.0.0
* python 2.7

## 関数内で標準ライブラリが使えない

以下のように、先頭でimportした`datetime`ライブラリを`hoge`関数の中で使いたかったのですが、

```python
import datetime

def hoge():
    print(datetime.datetime.now())

hoge()
```
↓  　Executeしたらエラーが発生しました。（！？）

```
Error running query: <type 'exceptions.NameError'> global name 'datetime' is not defined
```


## 解決
関数内でimportしたら動作しました。

```python
def hoge():
    import datetime
    print(datetime.datetime.now())

hoge()
# -> [2020-02-12T09:59:05.617825] 2020-02-12 09:59:05.617767
```
【覚書】Linuxだけで構築するDiscord配信環境

# やりたいことと環境
Droidcamとデスクトップの映像を合成し、自分の声とPC内の音も合成してDiscordで配信する。

OSはArchLinuxでPCはSandy世代の古いやつ。

# DroidcamをPCと接続する
これはあくまでカメラだけ。
[こちらの記事を参照](https://qiita.com/Hayao0819/items/2c9ed47ab7f1e7a3fb62)

# PC内部音声
PC内部音声を全てミックスして仮想的に出力する。
[ArchWikiの複数のサウンドカード・デバイスの同時出力](https://wiki.archlinux.jp/index.php/PulseAudio/トラブルシューティング#.E8.A4.87.E6.95.B0.E3.81.AE.E3.82.B5.E3.82.A6.E3.83.B3.E3.83.89.E3.82.AB.E3.83.BC.E3.83.89.E3.83.BB.E3.83.87.E3.83.90.E3.82.A4.E3.82.B9.E3.81.AE.E5.90.8C.E6.99.82.E5.87.BA.E5.8A.9B)を参考にする。

```bash
# 必要ないかも
sudo modprobe snd-aloo

yay -S paprefs
```

# 自分の声
今回はFinal E3000を使用する
PCは3極にしか対応してないので変換アダプターを使う

# 声と内部音声を合成して出力する
さっきのPulseAudioで作成した仮想マイクをDiscordのマイクに設定する。
**PCの音量が低いとマイクの音声も小さくなってしまうので感度を手動で調整**

# DroidcamとOBS Studio
Droidcam（v4l2loopback）や画面キャプチャなどをOBSで合成して仮想カメラに出力する。

[https://github.com/CatxFish/obs-v4l2sink](これ)を使用する。
ArchLinuxの場合はAURにあるのでそれを使う。

```bash
sudo modprobe v4l2loopback
# Droidcamで使うモジュールはv4l2loopback_dcで全く別物

yay -S obs-v4l2sink-git
# OBSを仮想カメラに出力する拡張機能
```
必ず形式を`YUV420`にする。
また、`/dev/video0`をDroidcamで使用していないか確認する。

仮想カメラをDiscordに認識させるには必ずDiscordのクライアントが必要。
ブラウザだとなぜか使用できなかった。
仮想カメラを起動したら必ずクライアントを再起動させる。

# Discordの設定
マイクとカメラをそれぞれ作成した仮想デバイスに設定しテストする。
うまく動けば完了。

ただしDroidcamやOBSなどのウィンドウを閉じてしまうと止まってしまうので仮想デスクトップなどの機能を利用すると良い。
よく使うartisanコマンドまとめ

##モデルの作成
モデル名の頭文字は**大文字**にする

```sh
php artisan make:model Models/Test
```

##マイグレーションの作成

```sh
php artisan make:migration create_tests_table
```

####:bell:ルール
- モデル名と同じ名前にする（ただし頭文字は小文字）
- モデル名の複数形にする

###マイグレーションの実行

```sh
php artisan migrate
```

##ルートの確認

###1. ターミナルで確認

```sh
php artisan route:list
```

###2. テキストファイルで確認
テキストファイルにしたほうがターミナルより見やすいです

```sh
php artisan route:list > route.text
```

##コントローラ作成
頭文字は大文字にする

```sh
php artisan make:controller TestController
```

##シーダー作成

```sh
php artisan make:seeder ContactFormSeeder
```

###シーダー実行

```sh
php artisan db:seed
```

####:bell:エラーが出るなどして実行できない場合
リフレッシュしてから実行してみてください

```sh
php artisan migrate:fresh --seed
```

##対話型コンソール

```sh
php artisan tinker
```
macにpostgresql入れたメモ

# postgresql入れてみた

よく考えたら、いままでUbuntu,CentOS,Windowsに入れたことはあったけど、
macに入れるのは初めて。Dockerではなく、brewで入れてみた。

```
brew update
brew install postgresql
brew services start postgresql
```

postgresユーザを作る

```
onnect to server: FATAL:  database "nagasaki" does not exist
(base) http2 $ psql --version
psql (PostgreSQL) 12.2
(base) http2 $ psql postgres
psql (12.2)
Type "help" for help.

postgres=# create user postgres SUPERUSER;
CREATE ROLE
postgres=# exit
```

入れた後に、database作ったり。

```
postgres=# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
-----------+----------+----------+---------+-------+-----------------------
 postgres  | nagasaki | UTF8     | C       | C     | 
 template0 | nagasaki | UTF8     | C       | C     | =c/nagasaki          +
           |          |          |         |       | nagasaki=CTc/nagasaki
 template1 | nagasaki | UTF8     | C       | C     | =c/nagasaki          +
           |          |          |         |       | nagasaki=CTc/nagasaki
(3 rows)

postgres=# create database sample owner=postgres;
CREATE DATABASE
postgres=# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
-----------+----------+----------+---------+-------+-----------------------
 postgres  | nagasaki | UTF8     | C       | C     | 
 sample    | postgres | UTF8     | C       | C     | 
 template0 | nagasaki | UTF8     | C       | C     | =c/nagasaki          +
           |          |          |         |       | nagasaki=CTc/nagasaki
 template1 | nagasaki | UTF8     | C       | C     | =c/nagasaki          +
           |          |          |         |       | nagasaki=CTc/nagasaki
(4 rows)
```

postgresqlユーザでtableを作ってみる

```
(base) http2 $ psql sample -U postgres
psql (12.2)
Type "help" for help.

sample=# create table account(id varchar(8));
CREATE TABLE
sample=# \d
          List of relations
 Schema |  Name   | Type  |  Owner   
--------+---------+-------+----------
 public | account | table | postgres
(1 row)
```

postgresqlを停止

```
brew services stop postgresql
```

参考
[macにbrewを使ってpostgreSQLをインストールする](https://qiita.com/ipepi/items/58dedbc0434fa9ea3b71)
Pythonひよっこが『言語処理100本ノック 2020』に挑戦【00-05】

Pythonひよっこのわたしが、『言語処理100本ノック 2020』の第1章の前半部分に挑戦してみました。
一般の方が公開されている解答と比べながら、1問ずつ学んだことなどをまとめていきたいと思います。

#わたしのこと
大学の授業でC言語(の基礎)を1年半学びました。
Pythonも一部の授業で触れましたが、細かい文法などを学んだのはここ1ヶ月くらいです。
独学で(C言語とちがうところを中心に)基本的な文法を学び、paizaの『レベルアップ問題集』を解いて実装力(?)を高めました。
*詳しいことはブログで書いています: [【Python】paizaのレベルアップ問題集をやってみた！](https://tulip-rabbit.hatenablog.com)
そんなPythonひよっこが、Pythonの練習もかねて言語処理100本ノックに挑戦してみました！

#第1章:準備運動
##00.文字列の逆順
```python
#00.
text="stressed"
print(text[::-1])
```
リストのスライスを使います。
3つめの引数(?)stepを -1 にすることで後ろからひとつずつ遡って出力できます。
スライスのこと学んだときは、"スライスに負の数使うときなんてあるの？"って思ってたけど、ありました。

##01.「パタトクカシーー」
```python
#01.
text="パタトクカシーー"
print(text[::2])
```
構造は00.と同じです。
奇数番目だけ出力すれば良いので、step=2 になります。

##02.「パトカー」＋「タクシー」＝「パタトクカシーー」
```python
#02.
text1="パトカー"
text2="タクシー"
text3=""

for i in range(len(text1)+len(text2)):
    if i%2==0:
        text3=text3+text1[i//2]
    else:
        text3=text3+text2[i//2]
        
print(text3)
```
演算子を使って文字列を増やすのに慣れません....
ほかの方の解答を見ると、for文を回す回数をもっと減らすこともできるようです。計算量に関わることなので、回数は少ない方が良いですね。勉強になりました。

##03.円周率
```python
#03.
text="Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
text_new=text.replace('.','').replace(',','')

num_list=[len(x) for x in text_new.split(' ')]
```
print(num_list)
step1:入力文の , と . を消す
step2:先頭の単語から順番に文字数をカウントする
の順番で実装しました。
step1 は replace() を使って、 ' と　 . を ''(スペースもなにもないもの)に変換することで , と . を文章中から消します
step2 はfor文の内包表記を利用して、カウントした文字数を num_list に入れていきます。
(内包表記はpaizaのレベルアップ問題集に取り組んだときに身に付けました！)

##04.元素記号
```python
#04.
text="Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
word_list=text.split(' ')

element={}

for i in range(len(word_list)):
    if i+1 in [1,5,6,7,8,9,15,16,19]:
        word=word_list[i]
        element[i]=word[0]
    else:
        word=word_list[i]
        element[i]=word[0:2]

print(element)
```
パッと浮かんだアルゴリズムでコーディングしましたが、ほかの方の解答をみて、ディクショナリへの追加を一つの関数として定義することでもっと綺麗に書けることがわかりました。
はじめ、 word=~ の処理を忘れてしまったのでちゃんと出力することができませんでした(><)
＊問題で求められているようにコーディングしたので、マグネシウムがちがうのはスルーすることにしました。

##05.n-gram
```python
#05.
def n_gram(text,n):
    text_len=len(text)
    result=[]
    
    for i in range(text_len-n+1):
        result.append(text[i:i+n])
    
    return result

text="I am an NLPer"

##単語bi-gram
print(n_gram(text.split(' '),2))
##文字bi-gram
print(n_gram(text,2))
print(n_gram(text.replace(' ',''),2))
```
単語n-gramが欲しいときは単語ごとに分けた text を、文字n-gramが欲しいときは text そのままを渡せば n-gramが返ってくるような関数n-gram を作成しました。
単語n-gramのときに単語間のスペースを入れて良いのか忘れてしまったのでとりあえず2パターン作りました。
→スペースを認めないn-gramにしたい場合、関数に渡すときにスペースを消去したtextに書き換えます



#おわりに
まだ準備運動、ということもあってどの問題もわりとスラスラと書けたと思います...が、まだ細かいPythonの関数とかに慣れていないので、そのあたりを重点的に練習を続けていきたいと思います！
Sapper で SCSS を使う方法（ rollup 利用時）

「えらく rollup 推しだなー」なんて思っていましたがなるほど、 `Svelte` の開発者が `rollup` の開発者であることを最近知りました。
以前、 [SapperでSCSS（や他のCSSプリプロセッサ）を使う方法](https://qiita.com/azukisiromochi/items/7313c958b46048c7bcdc) というのを書きましたが、 `rollup` 利用時の方法も残しておきたいと思います。



## インストール

インストールするパッケージは `webpack` のときと同様に [svelte-preprocess](https://github.com/kaisermann/svelte-preprocess) と `node-sass` 。

```
$ npm i -D svelte-preprocess autoprefixer node-sass
```

（ベンダープレフィックスを解消する [Autoprefixer](https://github.com/postcss/autoprefixer) も便利なので一緒にインストールしてしまっています）



## セットアップ

webpack の場合は `webpack.config.js` でしたが、 rollup の場合は `rollup.config.js` を編集していきます。

```diff:rollup.config.js
// Using sass
+ import sveltePreprocess from 'svelte-preprocess';
+ const preprocess = sveltePreprocess({
+   scss: {
+     includePaths: ['src'],
+   },
+   postcss: {
+     plugins: [require('autoprefixer')],
+   },
+ });

// ...

export default {
  client: {
    plugins: [
      svelte({
        // ...
+         preprocess, // 🚀 Add
      }),
  },
  server: {
    plugins: [
      svelte({
       // ...
+         preprocess, // 🚀 Add
      }),
    ],
  },
};
```



## 使い方

わかりやすいようにインストールした状態の Sapper（v0.27.12）アプリケーションの `index.svelte` を編集してみます。

```vue:index.svelte
<style lang="scss">
    $gradient: linear-gradient(-90deg, #2af598, #009efd);

	h1 {
		background-image: $gradient;
	}
</style>
```

グラデーション背景用の `$gradient` 変数を用意して、 `<h1>` に設定しています。

すると……
![sapper-scss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/2291b048-c5d7-0d80-f9d0-0fe26cb8f2f8.png)
（ ~~おじさんじゃなくなりましたね~~ ）



## まとめ

ググって出てくるのは大抵の場合 `webpack` のものばかりで個人的には苦労しました 💦

開発者が `rollup` 推しのようなので、今後は rollup を使って `Sapper` （ `Svelte` ）を触っていこうと思います！
日本語の情報も少ないので、どなたかの役に立てば幸いです :yum: 



## 参考

:link: [Svelte / Sapper with Sass!](https://medium.com/@sean_27490/svelte-sapper-with-sass-271fff662da9)
[Angular] 古いバージョンでFormBuilder#groupのvalidatorsオプションを使用する際の注意

[クロスフィールドバリデーション](https://angular.jp/guide/form-validation#%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)を実装する時などに注意が必要になります。
最新バージョンだと問題ないのであまり需要はなさそうですが。。

## オプションは2種類ある
`validators` と `validator` オプションが指定できます。
`validator`がレガシー設定となります。

## 注意すること
`FormBuilder`と`validators`の組み合わせだとバリデーションが効かない。

## 回避策
- `FormGroup`と`validators`の組み合わせでバリデーションを行う
- `validator`を使用する

## そもそもAngular6以前では
`validator`しかなかったらしいのでこちらを指定しておいたほうがよさそうです。

## 参考
[FormBuilder#group](https://angular.io/api/forms/FormBuilder#group)
docker -v オプションではホスト側のフォルダが存在していなくてもエラーは出ない

久々にdockerをいろいろ使ってみていたので（再入門レベル）ちょっと気になったことを書いてみる。

## 結論
`-v`オプションではなく、`--mount`オプションを使いましょう。

## 経緯
dockerを使っていると、`-v`オプションでたまにフォルダ名をタイポしたりしていて、思ったとおりマウントできていなかった。
（あとWindowsの方使ってるとパスの表記でハマったりする。ドキュメントしっかり読めばいいだけなんですけどね）

### 例
`docker run -it -v $(pwd)/somedisk:/hoge alpine sh`
→ホスト側に`somedisk`というフォルダがなくても、コンテナ側に`hoge`というフォルダは作られる。（中身は空）

``` sh
$ docker run -it -v $(pwd)/somedisk:/hoge alpine sh
/ # ls
bin    dev    etc    hoge   home   lib    media  mnt
opt    proc   root   run    sbin   srv    sys    tmp    usr    var
```

`docker run -it --mount type=bind,src=$(pwd)/somedisk,dst=/hoge alpine sh`
→ホスト側に`somedisk`がないとエラー

``` sh
$ docker run -it --mount type=bind,src=$(pwd)/somedisk,dst=/hoge alpine sh
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /home/user/docker/somedisk.
See 'docker run --help'.
```

## 調べた
https://github.com/moby/moby/pull/21666
https://github.com/moby/moby/issues/13121
以前は`-v`で存在しないホスト側ディレクトリを指定すると勝手に作成していたみたい。
で、勝手に作成されないようになったんだけど、エラーは出たりしない、ということかな。

なので`-v`は`--mount type=bind,...`に変えて使いましょう。

## Windows Docker Desktopでは

WSLから`docker.exe`を使う場合

``` powershell
$ docker.exe run -it --mount type=bind,src=$(pwd)/hoge,dst=/hoge alpine
C:\Program Files\Docker\Docker\resources\bin\docker.exe: Error response from daemon: invalid mount config for type "bind": bind source path does not exist:
```

windows形式のパスを指定しないとエラーになる。(wslのaptとかで入れるとエラーにならないのかも)
`docker.exe run -it --mount type=bind,src=$(wslpath -w $(pwd)/hoge),dst=/hoge alpine`
こんな風にwindowsのパスに変換しましょう。

ただし、記事時点のDocker Windowsではホストパスが存在しない場合は`--mount`オプションでもホスト側に**フォルダが勝手に作成される。**
エラーも出ません。気をつけましょう。
GoogleGlass内の写真をMacで吸い出す

##はじめに
GooleGlassのセットアップのために使用するアプリケーション「Myglass」が遂に使用できなくなった。
Web上のMyglassにもアクセスできなかった。
開発は終了しても使えるようにはしておいて欲しかった。カメラとして買ったので、写真が吸い出せないのは大変困る。
新型のGoogle Glass EE2を買えってことなのか。しかし、個人が使うには高すぎる。
ってことで、騙し騙し初代GoogleGlassを使うために頑張って吸い出そうと思った。

##Android Platform Toolsをインストールする
```sh
$ brew cask install android-platform-tools
```
##ファイル名をチェック
GoogleGlassをMacに接続し、ファイル名をチェックする。
デバッグモードはオン。
以下のコマンドを入力し、GoogleGlass側でコンピュータを信頼する。

```sh
$ adb shell
```
/mnt/sdcard/DCIM/Camera/
に写真が置かれているのでファイル名をチェックする。

```sh
$ ls /mnt/sdcard/DCIM/Camera 
```

##macへ吸い出す
⌘+Nで新しいタブを開き、対象のファイルを読み込む。

```sh
$ adb pull /mnt/sdcard/DCIM/Camera/{読み込みたいファイル.jpg} {保存したい場所}
```
以上で完了。

##おわりに
こんな事書いたけど、そもそもまだGoogleGlass使ってる人いるのか？なんて思っている。しかもGoogleGlassは開発者向けに販売されたわけだし、画像の吸い出しぐらい持ってる人にはわかるのでは…？Wi-Fiの設定ファイルがどこにあるか教えてください。
Oculus QuestやGoogle Glass。いつも画像ファイルの吸い出しで困っている。
アプリ作ってみようと思ったりもしたけど、初代Google Glassはもう使い物にならないし、大人しくカメラとして使用する。

##参考にさせてもらったサイト
https://roy.vanegas.org/thoughts/copy-images-and-movies-from-google-glass-using-the-terminal/
golang test coverage 100%を目指してみる

# golangでtestを書いてみたら、coverageが75%だったので、100%を目指してみる

## そもそもどこが通ってないのか調べてみる

coverageをhtmlで可視化してくれるツールがあるので、それを流してみる。

```
go test  -coverprofile=cover.out
go tool cover -html=cover.out -o cover.html
open cover.html
```

これで、coverしているところは緑色に、してないところは赤になる。

関数ベースでみることもできる
```
$ go tool cover -func=cover.out
http2/http2.go:21:	ServeHoge	100.0%
http2/http2.go:40:	main		0.0%
total:			(statements)	75.0%
```

## mainが通ってなかったけど、どうするのこれ？

go でmainを並列処理にしてサーバを立てたあとに、Getを使って、サーバにアクセスすることでテストする。
deferでBodyをCloseするのを忘れないようにしろ、とのこと。

```http2_test.go_part
func TestServer(t *testing.T) {
    go main()
    resp, err := http.Get("http://localhost:12344")
    if err != nil {
    t.Fatal(err)
    }   
    defer resp.Body.Close()
}                                                                                               
```

テストのカバレージの基準として、命令網羅(C0)、分岐網羅(C1)、条件網羅(C2)
という基準があるけど、このgoのtestは、C0でのカバレージを出しているとのこと。
たまにCIでカバレージ70%を基準にするという話を聞くけど、C1なのかなと思っていたけど、
どうなんだろ。今度見かけたら意識してみよう。
vscodeで正規表現でファイル内検索した結果全てに、マルチカーソルを当てる方法

# 以下方法で実現可能(Macの場合)

```
Command + Fで検索パネルを開く
正規表現で検索するボタンをクリック
正規表現を書いて、検索する
Option + Enter
```

## 結論
既出かもですが、自分は編集作業かなり捗るようになりました。
Arduino(C++11)で関数呼出の引数に配列を直接指定する

小ネタです。

今まで、C++で関数呼出の引数に配列を指定する際、予めポインタ変数として宣言してからでないとダメだと思っていました。

```c++:C++
void myFunc(uint8_t* arg){
    // hogehoge
}

uint8_t* val = {0xAA, 0xBB, 0xCC};

myFunc(val);
```


# やりたかったこと
以前からずっと、C++でもJavaScriptみたいに引数に配列を直接指定してスッキリさせたいなーと、空き時間に調べていたのですが、なかなか上手く行きませんでした。

```js:JavaScript
function myFunc(arg){
    // hogehoge
}

myFunc([0xAA, 0xBB, 0xCC]);
```

Arduinoでは古来から、文字列リテラルをポインタ型にキャストすることで配列のように扱えるハックがありますが、文字列ってそれ元の`\0`はどこいったの？など精神衛生的にどうにも気持ち悪く、他の方法を探していました。

```c++:C++(Arduino)
void myFunc(uint8_t* arg){
    // hogehoge
}

myFunc((uint8_t*)"\xAA\xBB\xCC");
```

# 試したこと
純粋に考えて、配列初期化子`{}`をポインタ型にキャストすれば行けるんじゃね！？と思って試しましたが、そう簡単にはいきませんでした。

```c++:C++
void myFunc(uint8_t* arg){
    // hogehoge
}

myFunc((uint8_t*){0xAA, 0xBB, 0xCC});
```

```:Error
too many initializers for 'uint8_t* {aka unsigned char*}'
invalid conversion from 'int' to 'uint8_t* {aka unsigned char*}' [-fpermissive]
```


# 解決したこと
試した方法では、ズバリ構文記法が問題でした。
キャスト構文に用いるポインタ記号は`*`ではなく`[]`を使用する必要がありました。

その2つは同じポインタ型を示す記号だと思っていたので、思わぬ落とし穴でした。

```c++:C++
void myFunc(uint8_t* arg){
    // hogehoge
}

myFunc((uint8_t[]){0xAA, 0xBB, 0xCC});
```

なお`memcmp()`など、いくつかの特殊な関数の場合、ただポインタ型にキャストしただけだと "一時的な配列は駄目だよ" とエラーが出てしまうので、その場合は`const`を付けて、ポインタ型定数としてキャストします。

```c++:C++
uint8_t* buf = {0xAA, 0xBB, 0xCC};

memcmp(buf, (const uint8_t[]){0xAA, 0xBB, 0xCC}, sizeof(buf));
```
iOS Safariでインラインフレームを使った場合に、レンダリング位置がズレる問題

スマホ用のWebサイトで、iframeを使っていたのですが、たまにiframeの中身のレンダリング位置がズレる問題に遭遇して原因の解明と対策に時間がかかったので共有します。

## そもそもはiframeの高さを中身の高さと合わせたかった
なので、jQueryで、

```javascript
$("iframe").load(function(){
   $(this).height(0);//一旦iframeの高さを0に
   $(this).height(this.contentWindow.document.documentElement.scrollHeight);//中身の高さに揃える
   $(this).scrollTop();//念のためiframeの中身の一番上にスクロール
});

```
としていたのですが、何故かたまに中身のレンダリング位置がズレる。具体的には中身のコンテンツの上の方がiframeからはみだして見れなくなる。

## 原因はiframeロード時の親フレームのスクロール
色々いじくりまわした結果、iframeの中身のロード、高さを揃える処理の最中に実機でページをぐいんぐいん上下にスクロールさせると100%で再現することがわかった。

## 対策
原因はわかったが、対策はわからない。
とりあえずこの高さを揃える処理のところでのiframeのサイズ変更が悪さをしている様なので、```$(this).height(0);```で高さを一旦0にするのを止め、iframeの高さの初期値を中身が丸っと入るぐらいの高さに指定。

すると今度はiframeの中身の高さを2倍に認識してしまい、iframeが余計に長くなってしまう不具合に遭遇。

とりあえず初期値をできるだけ小さくし、ブラウザのキャッシュをクリアしてみたら解決した。

もっとなんかちゃんとした解決方法を知りたい...
AirflowからSlackWehookを使ってSlack投稿する

# 背景
シンプルにAirflowのDAGでSlack投稿したい

# 方法
[SlackWebhookOperator](https://airflow.apache.org/docs/stable/_api/airflow/contrib/operators/slack_webhook_operator/index.html)を使って実装

```py

import airflow
from datetime import timedelta
from airflow import DAG
from airflow.contrib.operators.slack_webhook_operator import SlackWebhookOperator

default_args = {
    "owner": "airflow",
    "start_date": airflow.utils.dates.days_ago(1),
    "retries": 3,
    "retry_delay": timedelta(minutes=5)
}

dag = DAG("slack_dag", default_args=default_args, catchup=False, schedule_interval="@daily")

slack = SlackWebhookOperator(
    task_id='slack_test',
    webhook_token="https://hooks.slack.com/services/xxxxxx",
    channel="your_channel",
    message="message",
    icon_url="https://some-image/xxx",
    attachments= [{
        "title": "title",
        "text": "text",
        "color": "good"
        }],
    username="airflow_slack",
    dag=dag
)
```
UnityでのVRTKパッケージを用いたVR開発 "Design, Develop, and Deploy for VR"unityコースの目次(oculus)

#概要
　unityが出しているVR開発者のための学習コース
**"Design, Develop, and Deploy for VR"**
https://learn.unity.com/course/oculus-vr
本格的な開発者向けのコースなのでコンテンツ制作の構想の練り方や市場戦略などのunitもあるのでただ単にunityで、パパッと開発をやってみたい人には不必要な情報も多い。やりたいことがあるときにどの動画を見ればいいのか簡単な目次を作成。全編英語だが、動画付きなので見ながら操作すれば、動画内のことは簡単にできる。コース内容要約も下記に。

#目次

- VRTKの導入やproject settingの初期設定　→　Unit3 
- テレポート機能の追加　→　Unit4
- ハンドインタラクションの追加「つかむ」「引く」「入れる」　→　Unit5
- ハンドインタラクション「指で押す・突く」　→　Unit6(動画6)
- UI（テキスト、シリンダー、ボタン）などの追加　→　Unit6
- サウンドの追加　→　Unit7
- コンテンツ動作の最適化・処理の軽量化　→　Unit8
- パフォーマンスの確認　→　Unit9


#環境
　このコースはOculus Rift用だが、Oculus Quest用に注釈もついている。
今回は、Oculus Questを用いて作成を行った。

#コース内容
###Unit1
　コース全体の紹介。パパっとやりたい人には必要ない。

###Unit2
　ここでは、開発前にコンテンツの構想を練ることや共同開発の準備をするための知識を教えてくれる。マーケットに出すことを前提に開発を行う人には重要かもしれませんが、パパっとやりたい人には必要ない。

###Unit3
　Unity Project開発前のprojectの初期設定を全体を通して行う。Oculus VR開発の場合、インポートしただけではVRTKがうまく動かないので処理が必要。

**・動画２**
　OculusのVR開発に便利なOculus IntegrationsやVRTKの導入を行う。他のサイトを見ても導入がわかりにくかったりするため動画付きで分かりやすいかと思う。Questの場合もPDFがあるのでそちらに従うとできる。

**・動画３**
　　Player settingを行う。こちらもいちいち調べるのは面倒なので動画下の指示に従うと楽。

**・動画４**
　ここでは、コースを通して、使用するEscapeRoom_VSというチュートリアル用のシーンをインポートしているが、他の開発をする場合は必要ない。初期設定として、カメラやハンドトラッキングの設定は共通するかと思うので楽。

###Unit4
　前半の動画はVRのコンテンツで使われる動きだったりを紹介している。テレポートの種類も紹介しているが、このUnitで導入できるのは、

**どちらのコントローラーでもスティックでテレポート先を表示し、スティック押し込みで発動できるテレポート**

**片方のスティックはカメラの位置を変える用、片方はテレポート用**

という機能。


**・動画6～8**
　スティックで位置を決め、押し込みで発動する（両手）基本的なテレポートの作成方法を説明。

**・動画9~10**
　テレポート可能なレイヤーの設定と目的地の作りかた

**・動画11**
　片方の手をカメラのスナップ用に（首を動かさずにカメラの位置を変えられる）もう片方をテレポート用に（スティックを離した瞬間発動）カスタマイズ。この動画だけではテレポートを作れないが、動画6から基本のテレポートの作り方を学ぶことで自分なりのテレポートルールをカスタマイズできそう。

###Unit5
　Unitを通して、「つかむ」「引く」「入れる」などの手のアクションを実装する。基本の流れはコントローラーのボタンやObjectなどにVRTKのScriptを張って、それぞれのGameObjectをリンクさせていく。Scriptが用意されているので、これらのアクションのためのC#でのプログラムは不要。

**・動画2**
　Oculusのパッケージに入った手のモデルの追加方法。Oculusコントローラーのモデルも追加できる。

**・動画3**
　コントローラーのボタン側の設定とつかむことができるGrabbableなオブジェクトの設定の仕方。

**・動画4**
　追加で「つかむ」以外のアクションを可能にさせる。引き出しの引くアクション。つまり、x軸、y軸、z軸の内一方向だけに動かすことができるオブジェクトの設定。
　オブジェクトを所定の位置に「置く」あるいは「入れる」というアクションを可能にするための設定。

###Unit6
　前半の動画はVR内特有のUIの考え方を学べる。2m～5mの間にテキストがあるほうがVR内では心地がいいとか円柱形にテキストが設置されている方が見やすいとか。あまり意識しない部分なので見ると便利かも。実装は動画4から。

**・動画4**
　VR内で使えるUI機能を説明。　

**・動画5**
　コントローラーのポーズボタンからポーズメニュ―に移動する方法。
動画4で紹介された機能をシーン内に実装していく。

**・動画6~7**
　VR内のナンバーキーを押すとテキストに反映される機能の実装。
人差し指を指すとオブジェクトを動かせるというフィジカルな機能も付ける。

**・動画8**
　ナンバーキーに入力された数字がパスワードと一致していれば扉が開くというロジックの実装。こちらはEscapeRoomに初めから用意されているものを使用するので、実際の開発ではあまり使えない？

###Unit7

**・動画2~3**
　VRコンテンツ特有のサウンドが遠くにいれば小さくなり、近寄れば大きくなるという機能のつけ方がわかる。ほぼ、シーンに追加するだけ。

###Unit8
　コンテンツをマーケットに出す前に動作を軽くしたり、マーケットに出すための規定をクリアするための工夫がある。開発したコンテンツが重かったりした場合、あまり意識しない部分なので意外と重要かも。

**・動画3**
　AssetsをMesh Bakerというパッケージを使って、合体させる方法。動画内では、床がタイルのように分かれたAssetsで構成されているが、これを一つにすることによってパフォーマンスが上がる。

**・動画4**
　動作を軽くするための設定の確認。何か開発した後にここを確認すると便利そう。

**・動画5**
　Materialsの設定をちょっと変える。つやつやなMaterialだと光の反射を計算したりしている？

**・動画6**
　Lightningの設定をいじる。

###Unit9
　開発したコンテンツのパフォーマンスの確認方法。ProfileやFrame Debugといった機能を活用して、コンテンツの処理がどれくらいされているのか可視化できる。

###Unit10
　コンテンツを出す前のTestの手法をいろいろ教えてくれている。

###Unit11
　VRコンテンツを売り出すマーケティング手法などを説明しているが、とりあえず開発だけが目的なら必要はない。
ABC167 Dをダブリングで解いた（Python）

#ダブリングとは
本番では<a src="https://atcoder.jp/contests/abc167/tasks/abc167_d">ABC167D</a>の問題を周期性を利用して解いたがダブリングでも解けるらしいので、Pythonでダブリング書いてみました。ダブリング自体初めて知りました。
ダブリングはdoublingというテーブルを用意してdoubling[i]に2^i移動した時のインデックスをn個分格納するというもの。
今回の場合、kが10^18なのに計算量が間に合うのはすごい。
#コード
```python
n, k = list(map(int, input().split()))
a = [i - 1 for i in list(map(int, input().split()))]
logk = k.bit_length()
doubling = [[-1 for _ in range(n)] for _ in range(logk)]
for i in range(n):
    doubling[0][i] = a[i]
for i in range(1, logk):
    for j in range(n):
        doubling[i][j] = doubling[i - 1][doubling[i - 1][j]]
index = 0
k_bin = list(map(int, [list(bin(k))[-i] for i in range(1, logk + 1)]))
for i in range(logk):
    if k_bin[i]:
        index = doubling[i][index]
print(index + 1)
```

最後のkを２進数に変換してint型のリストにしているk_binはだいぶ頭が悪い書き方をしているとは自覚しているので、今まで避けてきたBit演算を勉強してもっときれいに書けるようにしたい。
iOSでaタグタップ時にグレーにならない（-webkit-tap-highlight-color: initialが効かない）

aタグをタップした時、普通はaタグの領域が一瞬グレーになります。
ところがグレーになってほしいのにならなかった時があるのでその対処方法を残しておきます。
※グレーになるのをやめるのはいくらでも出てくるのですが、逆に出なくなったのを出すようにする方法は出てこなかったので…

理屈は分からなかったのですが、試行錯誤の結果こうすれば良いことが分かりました。

```css
a {
   -webkit-touch-callout: none;
}
```

あとはaタグがグレーにしたい領域全体に掛かっていることを確認してください。block要素にする必要があると思います。
続・組合せ最適化でN Queen問題を解く

## これなに

N Queen問題を題材にした、組合せ最適化で求解するときのTipsです。

元記事：[組合せ最適化でN Queen問題を解く](https://qiita.com/SaitoTsutomu/items/8ae87b08668307b58006)

## 結論

制約の順番を変えると、計算時間が変わることがある。
4パターンで検証してみましょう。

## N Queen問題を解く

まずは、8x8で実際に解けるのを確認します。

```py
from ortoolpy import pd, addbinvars, model_min, lpSum, addvals
n = 8
df = pd.DataFrame([(i, j) for i in range(n) for j in range(n)],
                  columns=['X', 'Y'])
addbinvars(df);
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%time m.solve()
addvals(df)
cc = df.Val.astype(int).map('.O'.__getitem__).values.reshape(n, n)
print('\n'.join(''.join(c) for c in cc))
```

出力

```
Wall time: 27 ms
..O.....
O.......
......O.
....O...
.......O
.O......
...O....
.....O..
```

次から 100 x 100 のサイズで4通りの定式化で実行時間を確認します。

## パターン1（4.0秒）

```py
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()

```
3.97 s ± 702 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

## パターン2（4.7秒）

```py
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()
```
4.7 s ± 423 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)


## パターン3（2.2秒）

```py
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
for i in range(n):
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()
```
2.24 s ± 36.5 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

## パターン4（6.4秒）

```py
m = model_min()
for i in range(n):
    m += lpSum(df[df.X == i].Var) == 1
for i in range(n):
    m += lpSum(df[df.Y == i].Var) == 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X + Y == {i + 1}').Var) <= 1
for i in range(2 * n - 3):
    m += lpSum(df.query(f'X - Y == {i - n + 2}').Var) <= 1
%timeit -r 3 -n 3 m.solve()
```
6.44 s ± 129 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

## どうすればよいのか

4パターンは同じ定式化で、制約条件の順番が違うだけです。
しかし、3倍近く計算時間が変わってます。
しかも、nによって傾向が違います。

こういった場合は、今回のように複数パターンを用意して同時に実行し、答えが1つでも見つかったらすべて止める方法が良いかもしれません。

## 補足

計算は ThinkPad X280 でしました。
ライブラリーのインストールは、`pip install ortoolpy`です。

100 x 100 のN Queen問題は、0-1変数が1万個あります。
組み合わせは$10^{3010}$です。途方もない組み合わせ数ですが、無料のソフト（[PuLP](https://coin-or.github.io/pulp/)）で2秒ちょっとで解けるのがすごいですね。
Raspberrypi4 aeroTAP 3D USBカメラをOpenNi2 で動かす

# aeroTAP 3D USBカメラをRaspberry Pi4上でOpenNI2で動かす方法について説明します。
先のブログで Raspiberry Pi4でaeroTAP 3D USBカメラを起動するための手順を解説しました。

いちおう、設定は続きの前提です。

#結果
![2020-05-12-184138_1920x1080_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/17dd7eb8-7f98-1fb8-367e-9620557be208.png)


#準備
aeroTAP 3D USB カメラ
RaspberryPi4

aeroTAP OpeNI2 ドライバ

#aeroTAP OpenNI2 ドライバのダウンロード
[ aeroTAP_OpenNI2.zip ] http://www.aeroTAP.com/Help.SDK/sample/aeroTAP_OpenNI2.zip

Raspberry Pi4ターミナル画面から
wget http://www.aeroTAP.com/Help.SDK/sample/aeroTAP_OpenNI2.zip

unzip aeroTAP_OpenNI2.zip
cd aeroTAP_OpenNI2

#OpenNI2サンプルのビルド
ビルド済のバイナリがBinフォルダーにすでにあるので、そのまま実行が可能ですが、サンプルを再ビルドするには、下記のコマンドを実行します。

make PLATFORM=Arm

Bin/Arm-Release にバイナリがあります。
cd Bin/Arm-Release

#サンプルの実行
サンプルを実行する前に、環境変するを設定します。
export LD_LIBRARY_PATH=/home/pi/aeroTAP_OpenNI2/Bin/Arm-Release

SimpleViewer 実行しますが、ビルドしていない場合は、属性の変更を行ってください。
chmod 777 SimpeViewer
./SimpleViewer

#サンプルの動かし方
サンプル画面で、キー1,2,3を押すと、Depth Map->カラー、カラーマスク表示に切り替わります。

OpenNIからDepthMapを取得する具体的な方法は、ソースファイルがあるので参照してください。

[ その他 aeroTAP に関する情報] http://www.aeroTAP.com