OmniAICreator/Qiita-1.07M huggingface dataset:
Unity(Android)でFirebase+GTMを使う

# 概要

Unity + Firebase + GTM(Google Tag Manager) on Android
の組み込みで非常に詰まったので
導入手順をログっておきたいと思います。

なおここでいうGTMは、タグを使ってGoogleAnalyticsに飛ばす用途で使用しています。

### -閑話休題- 使えるかな？と思ったAsset
https://assetstore.unity.com/packages/tools/integration/google-tag-manager-25051

こちら買ってみたんですが、GTMで様々なconfigを設定して、
アプリを作り直さなくても更新ができるという点にフィーチャーしたアセットだったので
GTMでGAにログを送るという目的とはちょっと違うかなということで採用はしませんでした。

# 導入手順
## FirebaseSDKの導入

https://firebase.google.com/docs/unity/setup?hl=ja
普通にインストールします。
google-services.jsonはUnity内のどこにおいてもいいようです。

## GTMの導入
https://developers.google.com/tag-manager/android/v5/
用意されているドキュメントがNative Android用だけなので非常に詰まりました。

結果こちらの記事を参考にさせていただき
https://qiita.com/tkyaji/items/b838c97228f99f194bcd

```GTMDependencies.cs

using Google.JarResolver;
using UnityEditor;

[InitializeOnLoad]
public static class GTMDependencies
{

    static GTMDependencies()
    {
        PlayServicesSupport svcSupport = PlayServicesSupport.CreateInstance(
                                             "tagmanager", EditorPrefs.GetString("AndroidSdkRoot"), "ProjectSettings");
        svcSupport.DependOn("com.google.android.gms", "play-services-tagmanager", "11+");
    }
}
```

上記のソースをEditorフォルダに入れることで
tagmanager関係のjarを取り込むことができました。

### コンテナーの設置

>Create the app/main/assets/containers folder if it doesn't exist. Copy the downloaded container to the folder.

コンテナーの置き場所ですが、こちらはStreamingAssets以下に
containerフォルダを作成しそちらにjsonファイルを置いたら無事読み込んでくれました。

## Unity上での記述

```
Firebase.Analytics.FirebaseAnalytics.logEvent("hogeEvent", hogeParms);
```

こちらでイベントが発火できます。

## 検証方法
ターミナルでこの辺りを打つと、関係するログを出力してくれます。

```
adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb shell setprop log.tag.GoogleTagManager VERBOSE
adb logcat -v time -s FA FA-SVC GoogleTagManager
```

以上です。
bashで環境変数(PATH)の設定

#経緯
常日頃Windowsでゲームばかりしている私は、いざLinux機を触ると度々忘れてしまうのでメモついでにご紹介。

#対象
bash使ったことある人。

#PATHの設定方法
といってもそんなに難しい事をするわけでは無くて、使うコマンドは次の1つだけ

```bash:export
export PATH=$PATH:＜追加したいパス＞

# 例：~/path/bin/ を追加したい場合
export PATH=$PATH:~/path/bin/
```

ただ、コマンドを打っただけでは、ログインしなおしたり、bashを再起動したりすると追加したパスが消えてしまう。
そこで、.bash_profileを使います。

.bash_profileは、bashのログイン時に自動的に読み込まれる設定ファイルです。
設定ファイルと言っても、ログイン時に実行してほしいコマンドを記述しておくだけのものですが

この.bash_profileに、さきほどのコマンドを記載しておけば、毎ログイン時に自動的にPATHを設定しなおしてくれます。
テキストエディタ等で、~/.bash_profileに前述した一文を追加したら完了です。

私だけでしょうか、初めてこの設定の仕方を知った時、
PATHって、疑似的に永続化させてるだけなんだ・・・って悲しい気持ちになったのは


###export
環境変数を設定するためのコマンド

###.bash_profile
ログイン時に読み込まれるbashの設定ファイル
systemd-nspawn の Gentoo Linux コンテナを作る


*systemd-nspawn*の**Gentoo Linux**コンテナ作成方法です。

# ホスト環境
| 項目 | 詳細  |
|:----:|:-----:|
| OS | Gentoo Linux |
| Kernel | 4.9.76-gentoo-r1 |
| Systemd | systemd-236-r5 |

# コンテナ作成
## *Stage3*のインストール
```
cd /tmp
mkdir gentoo
wget http://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64-nomultilib/stage3-amd64-nomultilib-<日時>.tar.xz
tar xpf stage3-*.tar.{bz2,xz} -C gentoo --xattrs-include='*.*' --numeric-owner
```


## ベースシステムのインストール

### *chroot*
```
cp /etc/portage/make.conf gentoo/etc/portage/make.conf
cp --dereference /run/systemd/resolve/resolv.conf gentoo/etc/
cp /etc/locale.gen gentoo/etc/
cp /etc/timezone gentoo/etc/
mkdir gentoo/etc/portage/repos.conf
mkdir gentoo/usr/portage
mount --types proc /proc gentoo/proc
mount --rbind /sys gentoo/sys
mount --make-rslave gentoo/sys
mount --rbind /dev gentoo/dev
mount --make-rslave gentoo/dev
mount --bind /etc/portage/repos.conf gentoo/etc/portage/repos.conf
mount --bind /usr/portage gentoo/usr/portage
chroot gentoo /bin/bash
source /etc/profile
export PS1="(chroot) ${PS1}"
```

### プロファイルの選択
```
eselect profile list
```
で表示された*profile*の中から使いたいプロファイルを下記のコマンドで選択

```
eselect profile set <プロファイル番号>
```
プロファイルの選択で**systemd**を選ばなかった場合は、*/etc/portage/make.conf*の*USE*フラグに**systemd**を追加すること。

### アップデート
```
emerge -auvDN @world
```

### システム設定
```
locale-gen
emerge --config sys-libs/timezone-data
env-update && source /etc/profile && export PS1="(chroot) $PS1"
systemctl enable systemd-networkd
systemctl enable systemd-resolved
passwd
```

### ネットワーク設定
コンテナ側を固定IPにして、ホストのブリッジ経由でネットワークに接続する設定です。(DHCPを使用する場合は必要ないかも)

```
ln -s /dev/null /etc/systemd/network/80-container-host0.network
cat << 'EOF' > /etc/systemd/network/host0.network
[Match]
Name=host0

[Network]
DNS=192.168.1.1
Address=192.168.1.101/24
Gateway=192.168.1.1
EOF
```


### 終了処理
```
exit
umount -l gentoo/dev{/shm,/pts,}
umount -R gentoo/sys
umount gentoo{/proc,/etc/portage/repos.conf,/usr/portage}
```

## 起動
```
systemd-nspawn --boot --link-journal=try-guest --network-veth --network-bridge=br0 --directory=gentoo --machine=gentoo 
```


# *machinectl*

## 設定
*machinectl*でコンテナを操作するための設定です。

```
mv gentoo /var/lib/machine/
cat << 'EOF' > /etc/systemd/nspawn/gentoo.nspawn
[Exec]
Boot=on

[Files]
Bind=/usr/portage
BindReadOnly=/etc/portage/repos.conf
BindReadOnly=/usr/src/linux
TemporaryFileSystem=/tmp

[Network]
VirtualEthernet=yes
Bridge=br0
EOF
```

## コンテナを起動
```
machinectl start gentoo
```

## コンテナへログイン
```
machinectl login gentoo
```

## コンテナをシャットダウン
```
machinectl poweroff gentoo
```
いまさら聞けないVim Tips(インデント編)

# ソースコードのインデント

## 単一行

インデントしたい行で `==`

## バッファ全体に適用

`ggVG=`

`gg`: バッファの1行目に移動
`V`: 行選択モードに入る
`G`: バッファの最終行に移動
`=`: オートインデント

# インデント幅の調整

## 4カラムインデント

```vim:sample
set ts=4 sts=4 sw=4 
```

## 2カラムインデント

```vim:sample
set ts=2 sts=2 sw=2
```

`ts`: tabstop
`sts`: softtabstop
`sw`: shiftwidth

# インデントをタブではなくスペースにする

```vim:sample
set et
```

`et`: expandtab、タブをスペースに展開する

# ファイルタイプ毎にインデント幅を設定する

## 拡張子毎にファイルタイプを判別できるようにする

以下を.vimrcや.vimrc.localに書く

```vim:.vimrc
" あまりメジャーではない拡張子の場合、プレーンなvimではファイルタイプを判別してくれない
" *.coffeeをcoffeescriptと判別させる
autocmd BufRead,BufNewFile,BufReadPre *.coffee set filetype=coffee
```

## インデント幅の指定

```vim:.vimrc 
" ファイルタイプに対して、インデント幅を指定
autocmd FileType coffee setlocal ts=2 sts=2 sw=2 et
```
[ios]脱初心者！　storyboardを使用せずに、tableViewを表示して見た

ios開発を始めて、３ヶ月ぐらいが経ちました。
まだまだ勉強中ではありますが、四苦八苦しながら開発しています。
少しでもレベルアップしたいと思い、今回はstoryboardを使用せず、コードだけでtableViewを表示してみました。

[開発環境]
Xcode9
Swift4

storyboardを使用せずに、tableViewを表示させようとした時に、「cellのidentifierはどうやって表示させればいいんだ？」と思いました。
色々調べてみると下記のようなコードになりました。
今回は、UITableViewControllerを使用しましたが、UIViewControllerにdelegateを設定する方法もできると思います。
ただ、storyboardに慣れてしまうと、なかなかやりにくいのが正直なところですね。
慣れていくしかないかなと・・・頑張ります！！


```swift:TableViewController.swift
class TableViewController: UITableViewController {
    
    let dataList = ["0時〜6時","7時〜12時","12時〜18時","18時〜0時",]
    
    let cellIdentifier = "Cell"

    
    override func viewDidLoad() {
        super.viewDidLoad()
       
        let backButton = UIBarButtonItem(title: "戻る", style: UIBarButtonItemStyle.plain, target: self, action: #selector(TableViewController.back(_:)))
        self.navigationItem.leftBarButtonItem = backButton
        self.navigationItem.title = "周辺の交通状況"
        //空白のセルは非表示に設定
        self.tableView.tableFooterView = UIView(frame: CGRect.zero)
        self.tableView.rowHeight = 70
　　　　　　　　　　　　　　　　//セルの境界線を端まで表示
        UITableView.appearance().separatorInset = UIEdgeInsets.zero
　　　　　　　　　　　　　　　　//cellIdentifierをここで設定。
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @objc func back(_ sender: UIButton) {// selectorで呼び出す場合Swift4からは「@objc」をつける。
        self.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - Table view data source
    override func tableView(
        _ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)

        cell.textLabel?.text = dataList[indexPath.row]
        cell.textLabel?.font = UIFont(name: "Helvetica", size: 20.5)
        cell.textLabel?.frame = CGRect(x: 0, y: 1000, width: 100, height: 100)
        return cell
    }
}

```
Windows Server 2016でのNested Hyper-Vのかんたんな設定方法

この記事は、「[クラウド時代のシステム管理](https://www.takanyan.net/easy-nested-hyper-v/)」の記事を転記したものです。

Windows Server 2016の機能の一つとして、入れ子の仮想化（Nested Hyper-V）が導入されています。本番システムで使うことは少ないかもしれませんが、諸事情で必要になった時のため、使い方を紹介します。

<!--more-->

## 1. Nested Hyper-Vとは

Nested Hyper-Vは、Hyper-VゲストOSの中でさらにHyper-V仮想化機能を利用することです。Hyoer-Vでは仮想化のためにCPUの仮想化支援機能（Intel VTなど）が必須となっているため、Nested Hyper-V実現のためには仮想マシンにCPUの仮想化支援機能を認識させる必要があります。また、二重に仮想化しているため、実際に利用する際はどの階層の仮想化基盤を操作しているか意識しないと間違いやすいです。

Nested Hyoer-Vは検証環境、開発環境などでたくさんの仮想化基盤を用意したいときに便利です。私がNested Hyper-Vを利用することになった諸事情も、検証環境を1台のPCで賄うためでした。

## 2. Nested Hyper-Vを利用する前提条件

Nested Hyper-Vを動かすために必要な条件は以下の通りです。

* ホストOS、ゲストOSはどちらもWindows Server 2016以上、もしくはWindows 10 Anniversary Update以上
* CPUはインテル製であり、かつ仮想化支援機能（EPT、Intel VT-x）対応
* UEFIでIntel VTなどを有効にしている

AMD製CPU搭載のPCではサポートされていないことに注意してください。また、Intel VT-x機能がない安価なCPUも対象外なのでご注意を。

## 3. PowerShellスクリプトでNested Hyper-Vを設定

ホストOS上のHyper-V仮想マシンにNested Hyper-Vを利用可能にする設定を一度に実施できるPowerShellスクリプトがGithubにて公開されています。ここではScriptをダウンロードして実行することにします。

### 3-1. Nested Hyper-V設定Scriptの入手

設定Scriptは<a href="https://github.com/MicrosoftDocs/Virtualization-Documentation/tree/master/hyperv-tools/Nested" rel="noopener" target="_blank">Githubのこちらのリンク</a>で公開されている「Enable-NestedVm.ps1」です。中身をコピーするかダウンロードします。

### 3-2. Nested Hyper-Vの設定

事前に以下の条件を満たす仮想マシンを作成します。

* 電源OFF状態である
* Dynamic Memoryは無効にして、割り当てメモリを4GB以上にする
* 保存状態やスナップショットがない

次に、さきほど入手したScriptをPowerShellを開いたうえで実行します。実行の際質問が出ますので、すべて「Y」と入力します。

```
PS D:\> .\Enable-NestedVm.ps1 【VM名】
This script will set the following for 【VM名】 in order to enable nesting:
    Virtualization extensions will be enabled
    Optionally enable mac address spoofing
Input Y to accept or N to cancel:Y
Mac Address Spoofing isn't enabled (nested guests won't have network).
Would you like to enable MAC address spoofing? (Y/N)Y
```

これで、Nested Hyper-Vを使い、かつNested Hyper-Vホスト（1階層目の仮想マシン）のNetworkは物理Networkと同じセグメントになるようためのMAC Address Spoofing（MACアドレス偽装）の有効化も完了します。
あとは仮想マシン内でWindows Server 2016のインストールやHyper-V構築を通常の物理マシンに行うのと同じ手順で実施するだけとなります。


GUI上で設定状況がみられるわけではないので、実際に設定されたかわかりにくいですが、利用していると確かに仮想マシンの上でHyper-Vのセットアップができます。
scpでPermission deniedになるファイルを無理やり転送する

複数のサーバを保守運用していると、
Permissionの問題やら、差分のあるなしの確認やらでいろいろ面倒なことがある。

都度、解決した方法について自分でノートに書き留めていたが、
そろそろちゃんとした形にしないとノートが見辛い。ということでここに残すことにした。

# scpでPermission deniedになるファイルを転送する

リモートのファイルをlocalに転送しようとすると、
Permissionの問題でエラーになることがある。
残念ながらscpコマンドは標準でsudoを使うことができない。

```
$ scp TargetServer:/tmp/sample /tmp/sample
scp: /tmp/sample: Permission denied
$ 
```

しかし、1ファイルだけだったらsshでsudoでcatする、標準出力を使って事実上の転送すればいいじゃないか。scpだけが転送ツールじゃない。
普通にsshでつなぎsudoでcatする。当然sudoersへの登録は必要。

```
$ ssh TargetServer "sudo cat /tmp/sample" >  /tmp/sample
$ 
```

また、ddコマンドを使っても代用できる。

```
$ ssh TargetServer "sudo dd if=/tmp/sample" | dd of=/tmp/sample
0+0 レコード入力
0+0 レコード出力
0 バイト (0 B) コピーされました、 3.3649e-05 秒、 0.0 kB/秒
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.212011 s, 0.0 kB/s
$ 
```

# リモートのファイルとdiffで差分を取る

localのファイルがリモートと正しいか、確認したいが、
デフォルトでdiffコマンドではリモートと差分をとるオプションがない。
しかし、どうしても差分を取りたいことはよくある。

```
ssh TargetServer "cat $remoteFilename" | sudo diff - $filename 
```

diff - オプションを使えば、
標準出力と差分を取ることができる。
リモートのファイルを標準出力させ、localのファイルと差分を取る。
という仕組み。

```
$ ssh TargetServer "cat /etc/logrotate.d/test" | diff - /tmp/test 
6,8d5
<     #added
$ 
```
【IBM Cloud k8s】WebUI (Dashboard)への認証方法のメモ


Kubernetesのダッシュボードにログインしたいんだけど、StackOverflow に書いてある通りには、Secretの名前が異なっていて解決しなかったので、IBM Cloudではどうするか？　とのメモです。

背景としては、IBM Cloud Container Service すなわち Kubernetes で バージョン 1.8以降にすると、WebUI ダッシュボードにアクセスする際に認証を要求する様になった。　次の様な画面が出てくる。 この認証をスキップすると、必要な情報が何も表示されないので、認証をパスすることは必須となりました。　
 
![スクリーンショット 2018-01-26 14.31.05.png](https://qiita-image-store.s3.amazonaws.com/0/42829/83d3ab9b-3dcf-afd6-db53-b93a9446da94.png "スクリーンショット 2018-01-26 14.31.05.png")



## トークンの取得方法

ネームスペースにkube-systemを指定して、default-token- から始まる secret を探す

~~~
$ kubectl -n kube-system get secret
NAME                               TYPE                                   DATA      AGE
...
default-token-96msl                kubernetes.io/service-account-token    3         56d
...
~~~

default-taken-96msl の詳細を表示して、token のフィールドをコピーする。

~~~
$ kubectl -n kube-system describe secret default-token-96msl 
Name:         default-token-96msl
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=default
              kubernetes.io/service-account.uid=c066f292-d63b-11e7-b348-52739e8f8ad5

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1887 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5(長いので以下省略）
~~~



## ダッシュボードの起動とログイン

環境に合わせて、パラメータを調整して、ダッシュボードを起動する

~~~
kubectl proxy --address="0.0.0.0" -p 8001 --accept-hosts='^*$'
~~~


ブラウザからアクセスして、tokenをコピペして、SIGN INをクリック

![スクリーンショット 2018-01-26 15.01.22.png](https://qiita-image-store.s3.amazonaws.com/0/42829/200a8e20-89fb-1ac0-e56a-72f4b8c4418e.png "スクリーンショット 2018-01-26 15.01.22.png")

認証が成功すると、トップ画面が表示される。


![スクリーンショット 2018-01-26 15.03.05.png](https://qiita-image-store.s3.amazonaws.com/0/42829/1fca895f-eadd-6f3d-2c4d-d2a0f07adb5b.png "スクリーンショット 2018-01-26 15.03.05.png")



# 参考資料

1. How to sign in kubernetes dashboard? https://stackoverflow.com/questions/46664104/how-to-sign-in-kubernetes-dashboard
2. Kubernetes 1.8のアクセス制御について。あとDashboard。 https://www.kaitoy.xyz/2017/10/31/retry-dashboard-on-k8s-cluster-by-kubeadm/
PhotoLibraryから写真を取得し、表示させる方法(途中に編集画面を挟み、正方形に切り取る方法も解説)

#はじめに
自分の写真フォルダにアクセスして、その中の写真を扱いたいという時があると思います。(サムネイルの設定など)
しかし、ネット検索でそういった情報を探そうとすると、情報が古かったり、あまりまとまった内容ではないものが多かったりします。
なので、自分がまとめておきたいと思います。

#完成図
![selectPhoto.gif](https://qiita-image-store.s3.amazonaws.com/0/204266/c65357ef-56bb-d0c2-5dc3-8b410d2a4ae6.gif)



#開発環境
- Xcode9
- Swift4
- iOS 10.0

#PhotoLibraryから写真を取得し、表示させる方法
まず、info.plistにPhotoLibraryを使う旨を教えます。

![スクリーンショット 2018-01-26 14.56.04.png](https://qiita-image-store.s3.amazonaws.com/0/204266/8856d0be-0016-3329-df2b-d4bcac9200f7.png)

上記の青枠で示されているように設定します。
※設定をしないと、PhotoLibraryにアクセスすることができません。

次に、選択された写真を表示するためのimageViewと、PhotoLibraryにアクセスする時にトリガーとして扱うButtonを配置します。

![スクリーンショット 2018-01-26 14.57.09.png](https://qiita-image-store.s3.amazonaws.com/0/204266/ea8c05d0-c9c5-d819-edb8-c75e856a2353.png)

上記のように配置します。そしてViewController.swiftと繋ぎます。

次にソースコードを書きます。
下記にソースコードを示す。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate{

    //storyboardと接続
    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    
    //PhotoLibraryにアクセスする処理。
    @IBAction func pictureSetting(_ sender: UIButton) {
        let ipc = UIImagePickerController()
        ipc.delegate = self
        ipc.sourceType = UIImagePickerControllerSourceType.photoLibrary
        //編集を可能にする
        ipc.allowsEditing = true
        self.present(ipc,animated: true, completion: nil)
    }
    
    
    //写真を選択した時の処理を書く。
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        
        //編集機能を表示させたい場合
        //UIImagePickerControllerEditedImageはallowsEditingをYESにした場合に用いる。
        //allowsEditingで指定した範囲を画像として取得する事ができる。
        //UIImagePickerControllerOriginalImageはallowsEditingをYESにしていたとしても編集機能は表示されない。
        if info[UIImagePickerControllerOriginalImage] != nil {
            let image = info[UIImagePickerControllerEditedImage] as! UIImage
            //画像を設定する
            imageView.image = image
        }
        
        //編集機能を表示させない場合
        //let image = info[UIImagePickerControllerOriginalImage] as? UIImage
        //imageView.image = image
        
        dismiss(animated: true,completion: nil)
    }
}
```

上記のソースコードは、写真を選択し終えた後に、正方形に切り取ることができる編集機能付きのソースコードになっています。
コメントを所々挟んでいるので、それを読んで理解してもらえればと思います。

ここまで実装をすることができれば完成です！
以下、余談。


#余談
写真の設定画面は、初期設定だと下記のように英語表記になっていると思います。

<img width="375" alt="selectPhoto1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/204266/1dbcb12a-af44-0404-bc70-048fdb3324c0.png">

それを日本語表記にするには、下記のようにinfo.plistのLocalization native development regionをJapanに設定します。

![スクリーンショット 2018-01-26 14.56.29.png](https://qiita-image-store.s3.amazonaws.com/0/204266/03027e8d-2fd1-cbf6-ecc6-b732f854867d.png)

これを設定することにより、下記のように日本語表記になります。

<img width="375" alt="selectPhoto.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/204266/86d034b4-013c-31d6-8c17-986511cd10be.png">



※注意：実機だと日本語表記になるが、シミュレーターだとなぜか英語表記のままだった。
Gitのbranch名をわかりやすくしたいの


# branch名を考える

[この記事](http://kurog.hatenablog.com/entry/2018/01/26/150035)

と同じ内容です。

## branch名にprefixと修正箇所を入れる

[prefix]/[修正モデル]/[修正箇所]
とすることで、すんなり収まりそう。

- add/user/description
- bugfix/user/name
- add/editor/getdata

## branch名の変更時に、masterにmergeさせる

branch名にprefixと修正箇所があるために、他の部分で変更する場合branch名も変更必要がある。
このタイミングでmergeしてバージョン管理する


add/user/description →　master　→ buffix/user/description

みたいに
Thinkpad x230 を改造BIOSにして、hackintoshでwi-fiとbluetoothを動かす夢を見たお話

#Thinkpad x230 hackintoshのwi-fiとbluetoothを動かす夢を見たお話
この記事は <a href="https://qiita.com/Pa_Pi_Pudding/items/ad7c59109528717f77ff">Thinkpad x230でhackintosh-highsierraが動いた夢を見たお話</a> の続きです。


 さて、今回はThinkpad x230でhackintosh-highsierraが動いた話の続きで
前回はhackintoshをインストールして無事成功しました。
次はhackintoshなx230でwi-fiとbluetoothを動かすお話です。
<a href = https://qiita.com/Pa_Pi_Pudding/items/8c3d3dea8984b96fe66b>Thinkpad x230でhackintoshを作る夢を見ようとしてこけた話</a>でも説明しましたが、thinkpadはサードパーティ製の無線ランカードをwhitelistで認証していません。
なのでwhitelistを消さなければいけません。
今回はPCの中身をこじ開けてBIOSチップを書き換えます。

###参考URL
ThinkPad X230にcorebootをインストールする
http://ymdtr519.hatenablog.com/entry/2017/03/09/080656

Installing Coreboot On An X230 Laptop
https://vimeo.com/177951809

coreboot-x230
https://github.com/merge/coreboot-x230

[REQUEST] Lenovo Thinkpad X230 Whitelist removal
https://www.bios-mods.com/forum/Thread-REQUEST-Lenovo-Thinkpad-X230-Whitelist-removal

このへんです。実際にはcorebootを入れないで、whitelistを除去した改造BIOSを入れます。
corebootはlinuxBIOSです。これはlinuxを早く動かすものなので今回は関係ないです。

###必要アイテム
- ラズベリーパイ　
- panoma 5280 クリップ [https://www.marutsu.co.jp/pc/i/15943557/ ]
- メスメスジャンパーケーブル
- ACアダプター

###やり方
1.僕のgitのModBIOSを落としてください。
https://github.com/Pa-Pi-Pudding/hackintosh-ThinkpadX230-HighSerra

2.参考URLを参照にしてください、
※ラズパイのOSにfrashromを落として、makeコンパイルする時にエラーを吐くことがあるんですけど、エラー回避のコマンドがあるので（忘れたごめんなさい）

![IMG_4956.JPG](https://qiita-image-store.s3.amazonaws.com/0/218546/71149206-cb40-7eab-e6f3-f574352d09a1.jpeg)

![IMG_4958.JPG](https://qiita-image-store.s3.amazonaws.com/0/218546/8ef29c91-78e5-3909-809e-414635cc04a8.jpeg)

こんな感じに繋げて、書き込みます。BIOSのバックアップデータなどはとれるっぽいので取っておいてください。

ここの<a href = https://www.bios-mods.com/forum/Thread-REQUEST-Lenovo-Thinkpad-X230-Whitelist-removal>掲示板</a>に「BIOSのROMダンプデータを送るからwhitelist消して」って人と「消したぜ！アップしたわ」って人がrom載せまくってるので、そこから落とすと良いです。僕もそこから落としました。

書き換えると、こいつがenableになりまして。

![IMG_4623.JPG](https://qiita-image-store.s3.amazonaws.com/0/218546/1d504318-8cca-6303-5069-99746b12f322.jpeg)

こうなります。

![IMG_4969 2.JPG](https://qiita-image-store.s3.amazonaws.com/0/218546/3b4826c5-b23d-ed52-1066-cda1a9ffd100.jpeg)


以上です。

何かありましたら、

<a href = https://twitter.com/Pa_Pi_Pudding>僕のtwitter</a>にお願いします。
もしくはコメントでお願いします。
ストアド実行時にSQLSTATE[HY000]: General error: 1267 Illegal mix of collations

# 環境
mysql 5.6

# ストアド実行時にエラーが出た
SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='

# 原因
 ```show create procedure プロシージャ名 \G```
で確認したところ

```
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_unicode_ci
```

collation_connetcionとDatabase Collationがずれている。
Databaseのcollationがutf8_unicode_ciの時にストアドを作成し
その後、Databaseのcollationをutf8_general_ciに変えたようだ。
ストアドを再作成したらなおった。
C++ Builder XE4 | Memory corruption > bool値がtrueからfalseに変更される要因 > インデックス指定ミス

```txt:動作環境
C++ Builder XE4
```

### 概要

bool型変数の値をtrueにセットしたのに関わらず、処理の途中でfalseになっている。

調べたところ、配列のインデックス指定ミスだった。

### 再現code

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

static const int kNum = 5;

static void debugPrint(bool bfStart)
{
	if (bfStart) {
		OutputDebugString(L"True");
	} else {

		OutputDebugString(L"False");
	}
}

bool flags1[kNum] = { true, true, true, true, true };
bool bfAfter1 = true;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	debugPrint(bfAfter1);
	for(int idx=0; idx<kNum; idx++) {
		flags1[kNum] = false;
	}
	debugPrint(bfAfter1);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
	bool bfBefore2 = true;
	bool flags2[kNum] = { true, true, true, true, true };
	bool bfAfter2 = true;

	debugPrint(bfAfter2);
	for(int idx=0; idx<kNum; idx++) {
		flags2[kNum] = false;
	}
	debugPrint(bfAfter2);
}
//---------------------------------------------------------------------------
```

### 実行例

Button1押下時にMemory corruptionが起こる (True -> False)。

```
デバッグ出力: True プロセス Project1.exe (3212)
デバッグ出力: False プロセス Project1.exe (3212)
```

Button2押下時はMemory corruptionは起きない (True -> True)。

```
デバッグ出力: True プロセス Project1.exe (3212)
デバッグ出力: True プロセス Project1.exe (3212)
```

## 理由

```cpp
...
    for(int idx=0; idx<kNum; idx++) {
        flags1[kNum] = false;
    }
...
    for(int idx=0; idx<kNum; idx++) {
        flags2[kNum] = false;
    }
```

上記において、`flags1[idx] = false;`とするところを`flags1[kNum] = false;`としていた。
flags1[]とflags2[]はkNumのサイズを定義しているため、`配列名[kNum] = false;`は「定義外の変数」を変更し、Memory corruptionを生じる。

ただし、Memory corruptionがどのように影響するかは、配列のアドレスによって異なる。

デバッグ > インスペクタでアドレスを確認した。

### Button1押下時

- flags1[]は00406234から5個のアドレスに配置(00406238まで)
- bfAfter1は00406239に配置

このため、`flags1[KNum] = false;`はbfAfter1の値をfalseにする (Memory corruption)。

### Button2押下時

変数の配置はスタック領域になる (参考: [ヒープとスタック](https://www.uquest.co.jp/embedded/learning/lecture16.html))。
 
- flags2[]は0012F4C8から5個のアドレスに配置
- bfAfter2は0012F4C7に配置

このため、`flags2[kNum] = false;`はbfAfter2の値は変更しない (が、他の変数領域を破壊している）。

### 修正code

```cpp
...
    for(int idx=0; idx<kNum; idx++) {
        flags1[idx] = false;
    }
...
    for(int idx=0; idx<kNum; idx++) {
        flags2[idx] = false;
    }
```
switch文撲滅委員会

## はじめに

* 条件分岐の構文で`switch`構文がありますが、これは思わぬ罠があったりするので極力使いたくない
* その割にどの参考書にも出てくるし新人プログラマは割と使いがち→結果罠を踏んでデバッグすることに…
* そうならないようによくある罠を知っておくのと、`switch`文を使わないでやりたいことを実現できるテクニックを紹介します
* 今回は`PHP`の`switch`文について取り上げます

## 罠1

`PHP`の`switch`文は曖昧比較されます。例えば以下の出力は何になるでしょうか？

```php:sample1.php
<?php
$sample = 1;
switch($sample){
case true:
    echo 'これはtrueです'."\n";
    break;
case 1:
    echo 'これは数値の1です'."\n";
    break;
default:
    echo 'これは1ではありません'."\n";
    break;
}
```

出力は以下になります

```bash
これはtrueです
```

内部的には`$sample == true`になってるからですね。
曖昧比較はバグの温床になりやすいのでオススメできません。
## 罠2

フォールスルーと呼ばれるものです。以下のコードの出力は何になるでしょうか？

```php:sample2.php
<?php
$sample = 'a';
switch($sample){
case 'a':
    echo 'これはaです'."\n";
case 'b':
    echo 'これはbです'."\n";
case 'c':
    echo 'これはcです'."\n";
default:
    echo 'これはa,b,cではありません'."\n";
}
```

出力

```bash
これはaです
これはbです
これはcです
これはa,b,cではありません
```

うっかり`break`を書き忘れるとその下のcase文まで実行されてしまいます。
これを使ったテクニックなどもありますが、意図せず複数のcaseが実行される可能性がありこれもバグの温床になりやすくオススメできません。

## 回避テクニック

上記のような罠があるので`switch`文を使うのをやめましょう。
代わりに以下のような形にすると回避できることがあります（100%全ケースに対応できるわけではないので注意）

```php:sample1_improvement.php
<?php
$sample_array = array(
    true => 'これはtrueです',
    1    => 'これは1です',
);

$sample1 = 1;
if(isset($sample_array[$sample1])){
    echo $sample_array[$sample1]."\n";
} else {
    echo 'これは1ではありません'."\n";
}

```

出力

```bash
これは1です
```

```php:sample2_improvement.php
<?php
$sample_array = array(
    'a' => 'これはaです',
    'b' => 'これはbです',
    'c' => 'これはcです',
);

$sample1 = 'a';
if(isset($sample_array[$sample1])){
    echo $sample_array[$sample1]."\n";
} else {
    echo 'これはa,b,cではありません'."\n";
}

$sample2 = 'd';
if(isset($sample_array[$sample2])){
    echo $sample_array[$sample2]."\n";
} else {
    echo 'これはa,b,cではありません'."\n";
}
```

出力

```bash
これはaです
これはa,b,cではありません
```

あらかじめ配列を用意しておき、それのキーアクセスを利用することで分岐を減らしています。
これの良いところは正解として通す一覧を配列で持つことで分かりやすいのと、case文の分コードが長くならないところです。
例えばd,e,f,gまであと4つ増やしたとしてこの例では配列に4つ足すだけで実現可能です。
配列もホワイトリストとして利用できるのでcase文より使いまわしやすい形になっているかと思います。
反面、配列内にあるかどうか`isset`で調べる必要はあります。

## おわりに

タイトルで撲滅って言ってますが、別に撲滅しなくてもいいです。
罠を把握した上で適切な使い方をしていきましょう :muscle:
ファイル一覧を取得し、新しいシートに出力する

ファイルの一覧取得処理(fileutilクラス)は以下の記事のものを使わせてもらった。
[VBAマクロでファイル一覧を再帰的に取得するFunctionプロシージャを作成してみた。](https://qiita.com/Tterima/items/72d56ee5e2be0a77c898)


```vb.net:ファイル一覧を新シートに出力
Sub FileList2NewSheet()
    'ファイル一覧取得
    Dim targetpath As String: targetpath = InputBox("ファイル一覧を取得したいフォルダパスを入力してください。", "入力", "")
    Dim fu As fileutil: Set fu = New fileutil
    Dim result As Collection: Set result = fu.getFileListRecursive(targetpath).Files

    '新シート作成
    Sheets.Add
    
    'ヘッダ作成
    Range("A1:D1").Interior.Color = RGB(220, 120, 120)
    Range("A1:D1").Value = Array("フォルダ", "ファイル名", "日付", "サイズ")
    Range("A2").Select
    ActiveWindow.FreezePanes = True
    
    '結果出力
    Dim r: r = 2
    Dim objFiles As File
    For Each objFiles In result
        Dim p1: p1 = objFiles.ParentFolder 'フォルダ
        Dim p2: p2 = objFiles.Name 'ファイル名
        Dim p3: p3 = FileDateTime(objFiles) '日付
        Dim p4: p4 = Format(objFiles.Size / 1024, "#.0") 'サイズ
        Range(Cells(r, 1), Cells(r, 4)) = Array(p1, p2, p3, p4)
        r = r + 1
    Next

    '列幅調整
    Columns("A:D").EntireColumn.AutoFit
End Sub
```
```vbnet:fileutil
Option Explicit

Private m_fso As FileSystemObject
Private m_files As Collection

Property Get FSO() As FileSystemObject
    Set FSO = m_fso
End Property

Property Get Files() As Collection
    Set Files = m_files
End Property

' ファイル一覧を再帰的に取得する関数
' 引数： folder_path 取得する起点のフォルダ
' 引数： pattern 取得対象のパターン（正規表現）
Public Function getFileListRecursive(folder_path As String, Optional pattern As String = "") As fileutil
    ' ファイル一覧の結果格納用
    Dim file_list_tmp As Collection

    ' ループ用変数の宣言
    Dim folder As Variant
    Dim file_path As Variant
    Dim dir As Variant

    ' オブジェクトの初期化
    Set file_list_tmp = New Collection

    ' 現在ディレクトリ内の全ファイルの取得
    For Each file_path In FSO.GetFolder(folder_path).Files
        If file_path Like "*" & pattern & "*" Then
            DoEvents    ' フリーズ防止用
            Call Files.Add(file_path)
        End If
    Next

    ' サブディレクトリの再帰
    For Each dir In FSO.GetFolder(folder_path).SubFolders
        Call getFileListRecursive(dir.Path, pattern)
    Next


    Set getFileListRecursive = Me
End Function

' メンバ変数の初期化
Private Sub Class_Initialize()
    Set m_fso = New FileSystemObject
    Set m_files = New Collection
End Sub

' メンバ変数の解放
Private Sub Class_Terminate()
    Set m_fso = Nothing
    Set m_files = Nothing
End Sub
```
windowsMRのモーションコントローラーのボタンの取得ではまったのでメモ

# 値の取得方法

UnityでwindowsMRのモーションコントローラーのボタンのイベント取得ができなかったので調べていたんですが、僕のわかるレベルでの簡単な資料がなかったのでメモしておきます。

以下のコードで取得できます。

```csharp
//Gripのボタンの取得
Input.GetKey("joystick button 5")
```

使い方は、

```csharp
void Update(){
 //押し続けてる間イベントを取得
 if(Input.GetKey("joystick button 5")){
  Debug.Log("GripKey");
 }
 //押したイベントを取得
 if(Input.GetKeyDown("joystick button 5")){
  Debug.Log("GripKey");
 }
 //離したイベントを取得
 if(Input.GetKeyUp("joystick button 5")){
  Debug.Log("GripKey");
 }
}
```

モーションコントローラーのボタンの対応表はこちら。
https://developer.microsoft.com/en-us/windows/mixed-reality/gestures_and_motion_controllers_in_unity

なんか無茶苦茶にはまったので。。。これだから僕のような初心者は…
ELB+nginxでhttpsリダイレクトを実現する為のnginx設定

# 何がやりたかったか
AWS上のサーバにhttpでアクセスしてきた人をhttpsにリダイレクトをさせたかった。nginxで。

ちなみにApacheでやっている記事は結構ある
https://qiita.com/ruddy95/items/377428f4d8219608bdbd
https://qiita.com/michimani/items/88973c5e2ae76a8e84aa
https://qiita.com/tihimsm/items/2c58a3425e446261940b

# 先人の知恵
ELBの設定で(80|443)→80としているとリダイレクトループになる恐れがある。

https → 443 ELB 80 → nginx
http  →  80 ELB 80 → nginx

リダイレクトの対象は「ELBにhttp(80)でアクセスしてきたリクエスト」のみを対象としなければいけない

# 判別方法
nginxの場合、下記の変数でELBへのリクエスト形式取得ができる

```
$http_x_forwarded_proto
```


# 設定

```
location / {
    if ($http_x_forwarded_proto = http) {
        return 301 https://$host$request_uri;
    }
}
```

上記のように`$http_x_forwarded_proto`がhttpの場合のみ、
301リダイレクトするように返してあげましょう。
serverlessでdeployしたときのエラー対応メモ

## aws lambdaの名前をserverless.ymlで変更した際にdeployに失敗し起きたエラー
```serverless.yml
functions:
  test: 
    handler: main.test
    name: ${self:provider.stage}-test

↓

functions:
  test2: 
    handler: main.test
    name: ${self:provider.stage}-test


```
```zsh
$ sls deploy -v
```
実行

```
  Serverless Error ---------------------------------------

  An error occurred: TestLogGroup - /aws/lambda/development-test already exists in stack arn:aws:cloudformation:${region}:${account_id}:stack/aws-nodejs-development/xxxxxxx.

```


### そして始まる削除祭り
もうあるっていってるので一度消してみよう。と消す。
serverless.ymlを再度deployすれば大丈夫でしょう。と謎の自信。

lambda削除。

### そしてcloud watchのスタック削除へ

cloudwatchのlog削除。

よし、cloud formationも念のためスタック削除。。。としたら
削除に失敗。
｡・ﾟ・(ﾟ`ω´ﾟ)・ﾟ・｡ しんどい
DELETE_FAILED

おおっと、と思い。
[公式documentのトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/troubleshooting.html#troubleshooting-errors-delete-stack-fails)にすがる。

うーん、この状態で再度デプロイしたらどうなるのか興味が沸いて、まあ、失敗するだろうと思いつつも

```
$ sls deploy -v
```

実行。
以下エラーで失敗。（予想通りだ！ドヤア

```
Stack:arn:aws:cloudformation:${region}:${account_id}:stack/aws-nodejs-development/xxxxxxx. is in DELETE_FAILED state and can not be updated.
```
### 公式ドキュメントにすがる。

よし。と
[公式documentのトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/troubleshooting.html#troubleshooting-errors-delete-stack-fails)に戻ってくる。

削除保護つけてると失敗しますよ。という文言が。。。
(このときはドキュメントをちゃんと理解できていなかったのですが、ここでいってる削除保護というのは、cloud formationのスタックにつける削除保護のことだったのだと思います。

```serverless.yml
resources:
  Resources:
    TestDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain

```

そういえば[削除保護 DeletionPolicy: Retain](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html)つけてた。面倒なことになったなあと落ち込む。（´・ω・｀）

### コンソールに失敗した理由全てが書いてあった。

コンソールに戻ってどこで失敗したか見てみよう。話はそれからだ、とcloud formationのページにいってどこでfailしてるか確認。
すると、

```
- iamロール
- s3 bucket
```

この２つが失敗してるらしい。

状況の理由を確認すると、
iamは、アタッチしてるpolicy全部デタッチしてね。
s3はobject空にしないと削除できないよ〜

とわかりやすく書いてある。
ok!とやってみる。

再度スタックの削除に挑戦。
すると、
- iamロール
- s3 bucket
これらのresourceを保護する？
チェックされたresourceは消さないよ〜
とポップアップが丁寧に出たので、もちろんけさないで！とチェックして実行したら無事消せました！

わーいヽ(○´∀｀○)ﾉ

### 再度デプロイに挑戦。

再度デプロイすると、

```
$ sls deploy -v

```

```
An error occurred: IamRoleLambdaExecution - TestRole already exists.
```

IAMのroleもうあるんだけど、って怒られる。
では、と消す。

ついに、デプロイに成功できた。

日々勉強だなあ。頑張ろう。
PaperclipでPDFのサムネイルが作れない場合はフォントが足りてないのかも

# Paperclip::Errors::NotIdentifiedByImageMagickErrorが出た

開発環境であるMacでPaperclipを使ってPDFをDBに登録していた時は普通に動いていたのだけれど、Amazon Linux環境で実行したら上記のエラーが出て大変困惑した。

## 原因：ghostscriptにフォントを登録しなければいけなかった

[Qiita: Paperclip::Errors::NotIdentifiedByImageMagickError](https://qiita.com/soudai_s/items/90a5b9d46c5d88f05edf) のページを見て、Paperclipのログを出すようにした。

```rb
# config/environments/development.rb
Rails.application.configure do

  # 以下を追加し再起動
  Paperclip.options[:log] = true
  Paperclip.options[:log_command] = true
end
```

すると、「このフォントわからん」というエラーメッセージが出ていた。
作業中に焦っていたのでそのエラーメッセージを残せてないのが自分でもミスったな…と思うのだけれど、`idenfity`コマンドの結果、Meiryo-Boldがないと言われていた。

## 解決策：IPAフォントを入れて割り当てた

[Qiita: Amazon LinuxにIPAフォントをインストールして、Ghostscriptのcidfmapに登録する](https://qiita.com/iharakenji/items/476e8b32e4e7a3c1a274)

このページを参考に、IPAフォントをインストールして、フォントを割り当てた。本物のMeiryo-Boldではないけれど、生成するのはサムネイルで文字の大きさはほとんど見えないレベルなのでそこは気にしないことにした。

### フォントのインストール

```bash
sudo yum install -y ipa-gothic-fonts ipa-mincho-fonts
```

### フォントを設定する

```bash
sudo vi /etc/ghostscript/<バージョン>/cidfmap.local
```

```:cidfmap.local
/IPAMincho     << /FileType /TrueType /Path (/usr/share/fonts/ipa-mincho/ipam.ttf) /CSI [(Japan1) 6] >> ;
/IPAGothic     << /FileType /TrueType /Path (/usr/share/fonts/ipa-gothic/ipag.ttf) /CSI [(Japan1) 6] >> ;

/Ryumin-Light /IPAMincho ;
/Ryumin-Medium /IPAMincho ;
/GothicBBB-Medium /IPAGothic ;
/HeiseiKakuGo-W5 /IPAGothic ;
/HeiseiMin-W3 /IPAMincho ;
/MSGothic /IPAGothic ;
/MSMincho /IPAMincho ;
/Meiryo-Bold /IPAGothic ;
/Meiryo-BoldItalic /IPAGothic ;
```

このあと、PaperclipでPDFを保存したら、サムネイルが生成された😄

# まとめ

ImageMagickのエラーの場合はghostscriptも疑うこと！！
submoduleまで含めてgitリポジトリの内容をzipファイルにする

gitのソースコードをzipで圧縮したいとする。その際、git cloneしたものをzipすると.gitディレクトリが入ってしまったりする。
その際に便利に使えるコマンドが`git archive`である。こちらの記事がわかりやすいので参照していただきたい。
[Git リポジトリの内容を zip ファイルにする](https://qiita.com/usamik26/items/9a2d14aea30cb01a60c6)

リポジトリにサブモジュールが含まれない場合はこれで問題ないのだが、submoduleまで含めて再帰的にarchiveしたい場合はどうすれば良いか？
こちらの[StackOverflowの記事](https://stackoverflow.com/questions/14783127/git-archive-export-with-submodules-git-archive-all-recursive)に非常に簡単な手法が紹介されていた。
https://github.com/Kentzo/git-archive-all を使う。

```shell-session
$ pip install git-archive-all
$ git-archive-all my_repo.zip        # my_repo.zipファイルが作られる
```
SwiftのGCDで最新のキューだけを処理し続ける

重たい画像処理のパラメータをGUI Sliderで操作しつつ結果をプレビューしたいとき、
画像処理にかかる時間よりもGUIからイベントが送られて来る間隔の方が圧倒的に短くて

- 同期処理だとUIがカクカクする
- 非同期直列処理だとプレビューへの反映が遅い
- 非同期並列処理だとプレビューが最新であることが保証されない

という問題にぶちあたった。

UIをストレスなく操作させつつなるべく最新の結果をプレビューできるようにするためには

- 非同期処理
- 処理中に溜まっていくタスクは最新のもののみ保持して残りは捨てる

という実装がよさそう。
ということでできたものがこちらです。

```Swift:Swift3.0
class ViewController: UIViewController {
	// 同時実行数を1に制限するためのセマフォ
	let semaphore = DispatchSemaphore(value:1)
	let queue = DispatchQueue(label: "imageproc", qos:.userInteractive)
	var workItem : DispatchWorkItem?

	// このハンドラがえげつない回数呼ばれる
	@IBAction func imageProc(_ sender: Any) {
		// 前回追加したタスクが未処理の場合はキャンセルされる
		workItem?.cancel()
		
		workItem = DispatchWorkItem {
			// 処理中のタスクがある場合は待つ
			self.semaphore.wait()
			self.imageProcImpl()
			// プレビューへの反映はメインスレッドで
			DispatchQueue.main.async {
				self.imageProcAfter()
				// プレビューへの反映が終わってからセマフォを解放
				self.semaphore.signal()
			}
		}
		// キューに追加
		queue.async(execute: workItem!)
	}
	func imageProcImpl() {
		// 重たい画像処理
	}
	func imageProcAfter() {
		// プレビューに反映
	}
}
```
Pythonの自作パッケージの作り方

自作パッケージを作る際に、MANIFEST.in に記載したjsonファイルが
`pip install`した時にライブラリに入っていなかったので調査した結果メモ。

## 結論
setup.pyに `include_package_data=True` と記載すればよかった。

## ディレクトリ構成
```
.
├── tests
├── requirements.txt
├── MANIFEST.in
├── setup.py
└── src
    ├── config
    |   └── config.json
    └── main.py
```

大まかにこんな感じ。

## requirements.txt
依存ライブラリを記載しておく。
現環境で使用しているライブラリの書き出しは以下コマンドでできる。

```
pip freeze > requirements.txt
```

## MANIFEST.in
何も指定しないと、 `.py` のファイルしかパッケージに入れないため
`.json` などの設定ファイルも入れたい場合は、用意する必要がある。

```
include requirements.txt
include src/config/*.json
```
ワイルドカードが使用できる。

## setup.py
```
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages

import os

def load_requires_from_file(fname):
    if not os.path.exists(fname):
        raise IOError(fname)
    return [pkg.strip() for pkg in open(fname, 'r')]

setup(
    name='package_name',

    version='0.0.1',

    url='GitHubのURLなど',

    install_requires=load_requires_from_file('requirements.txt'),
    
    # testsはパッケージに入れる必要が無いので除外
    packages=find_packages(exclude=['tests']),

    # MANIFEST.in を使うために必要
    include_package_data=True,
)
```
Linux便利コマンドメモ

マイボスから伝授して頂いた便利コマンド備忘録
##**プロジェクトのファイル内で、hogeという文字列が存在するファイルを探すとき**

```
$ find . -type f | xargs grep -n "hoge"
```

##**指定フォルダ内の合計サイズ**

```
$ du -sk [フォルダ名]
```

##**検索対象ファイル内のhogeが出てくる行の前後3行を表示**

```
$ grep -B 3 -A 3 "hoge" [検索対象ファイル名]
```

##**アクセスログみるとき**

```
$ tail -f access_log
```

##**アクセスログ監視時特定の文字のログだけ追いたいとき**

```
$ tail -f access_log | grep "hoge"
```

##**プロジェクトをtarしてからgzip**

```
$ tar zcvf プロジェクト名.tar.gz [プロジェクト名]
```

##**tar.gzを展開**

```
$ tar zxvf プロジェクト名.tar.gz
```
Fiddler で iPad の HTTPS(SSL) 通信を解析する - Qiita

# 公式手順
http://docs.telerik.com/fiddler/configure-fiddler/tasks/configureforios

# 私が検証した環境
- Surface Pro (Windows10 64bit)
- iPad (iOS 10.3.2)

# 手順
### コンピュータ作業
1. http://getfiddler.com/ から Fiddler をインストール
2. Fiddlerを起動
3. [Tools] > [Options] > [HTTPS]Tab で下記のように設定
<img width="267" alt="2018-01-26_12h57_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/233812/e877efdc-67c1-5c2d-2ebc-3f345cacd2b5.png">

4. [Connections]Tab で下記のように設定
<img width="267" alt="2018-01-26_12h57_49.png" src="https://qiita-image-store.s3.amazonaws.com/0/233812/f5ac1f7e-289e-adbe-bdd4-91266e46e39a.png">

5. Fiddler を終了
6. [CertMaker for iOS and Android](https://www.telerik.com/fiddler/add-ons) をインストール
7. コマンドプロンプトを起動し、 ipconfig /all コマンドで自分のIPアドレス(IPv4アドレス)をチェック
<img width="460" alt="2018-01-26_12h58_40.png" src="https://qiita-image-store.s3.amazonaws.com/0/233812/151ed253-0f59-dec1-a0f6-6919fa027450.png">

8. Fiddlerを起動

### iPad作業
1. iPadでSafariを起動し、先ほど調べたIPアドレス:8888( http://xxx.xxx.xxx.xxx:8888 )にアクセス
<img width="384" alt="IMG_0022.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/233812/8092f8b3-1ad4-a5b9-584a-bbc5609b4202.jpeg">

2. 「You can download the FiddlerRoot certificate」をクリック、証明書をiPadにダウンロード＆インストール
3. iPadの設定 > Wi-Fi > 今接続しているWi-Fiをタップ > HTTPプロキシ で、サーバー（先ほど調べたIPアドレス）とポートを設定
<img width="384" alt="IMG_0023.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/233812/3fbdc6b1-c185-d2b8-6c4f-ce1cb30ca960.jpeg">


4. これで設定作業は完了。iPadでブラウザ通信すると、コンピュータ上のFiddlerにiPadの通信状況が流れてきます。

※全ての作業が終わったら、プロキシ設定を戻したり、iPadからFiddlerの証明書を削除する等しましょう。
【DB】名寄せ？重複のランダム抽出？の際のメモ

# 重複データをランダムで取得するというお題があり、なかなか出てこなかったのでメモを書く
重複を抜き出すとかdistinctとかでできるのですが、
重複したデータをランダムで取得する方法が見つかりませんでした。

# 例えばこんな時
世界中にいる同じ苗字の人の1人から鬼ごっこの鬼を決めたい
ランダムで
佐藤さんがいっぱいいます、高橋さんがいっぱいいます、田中さんが。。。
選ばれた世界の佐藤さんの中の1人、世界の田中さんの中の1人にメールを送付しなければいけない

# 結論は

パフォーマンスとか気にしてないし、DB側で処理しなくてもいいなどありますが...

```sql:nayose.sql

    SELECT id,苗字,名前,住所, メール
            ,row_number() over (partition by 苗字 order by dbms_random.random) as 当選番号
    FROM 人類
    WHERE 当選番号=1


```

# 解説
## 当選番号
当選番号をカテゴリごとにランダム付与します。今回は世界中の佐藤さんの中の一人を選ぶため1としています。
## partition by
苗字で一人に絞り込み
## order by dbms_random.random
苗字でカテゴライズされた人たちにランダムに番号を振ります
DB設計と正規化

# データベース設計の流れ
概念設計 -> 論理設計 -> 物理設計の順で行われる

## 概念設計

- 業務で扱う情報を整理する
- システム化に影響を受けない
- データを永続化しない範囲も含まれる

## 論理設計
各キーや関係性が関係性が確立することが目標

- データを論理的に構造化する
- 正規化や非正規化を行う
- データを永続化する範囲に限られる

## 物理設計

- データの型やフィールド名を決定する
- インデックスの設計を行う
- CPUやメモリ等を決定する

# 正規化
冗長を排除し、データの独立性（関係従属性のことではなく、不必要な依存のこと）を高める更新異常が発生しないようにする
第1 ~ 第5正規形まで定義されている（ボイス・コッド正規形は3.5正規形と呼ばれる）

- 冗長化（じょうちょうか）とは、システムの一部に何らかの障害が発生した場合に備えて、障害発生後でもシステム全体の機能を維持し続けられるように、予備装置を平常時からバックアップとして配置し運用しておくこと。

### 「1事実1箇所」（1 fact in 1 place）にすることが正規化の目的
一つの事実が、一つのテーブルの１行の中にだけ存在していること。
あるいは、一つの従属性（事実関係）だけが一つのテーブルに実装されていること。

## 更新時異常
正規化が不十分だと、挿入・更新・削除する際に様々な異状が発生すること。
つまり、冗長性がある状態のこと。

## 情報損失分解
分解しても分解前の関係を復元できる分解のこと。

## 非正規形
リレーションRの属性の中に、単一でない値（一つの属性の中に繰り返し項目があるもの）が含まれている
（例）一つのレコードに対し、複数の商品のデータが入ってしまっているような場合

## 第一正規形
リレーション R のすべての属性が、単一値である。
（例）全てのレコードに対し、1レコード1カラムに対応するような場合
目的 : 全てのレコード・カラムを1:1対応させるような表にする（まとめずに対応表をつくる）

## 第二正規形
リレーションRが次の条件を満たす

- 第一正規形であること
- すべての非キー属性は、いかなる候補キーにも部分関数従属 していない（完全関数従属である）こと

目的 : 部分関数従属している部分を切り出すこと（部分的な塊の群を抜き出す）

what's 完全関数従属

- 関数従属性「（候補キー：X）→（非キー属性：Y）」が成立する（YはXに関数従属している）
- （候補キー：Xの真部分集合）→（非キー属性：Y）が成立しない

真部分集合 : ある集合に対して部分集合であるが、一致しないもの
（例）A={1, 2, 3}の場合、{1, 2, 3}以外の部分集合（{1,2}等）

## 第三正規形
リレーション R が次の二つの条件を満たす。

- 第２正規形であること
- すべての非キー属性は、いかなる候補キーにも推移的関数従属 していない
- 導出項目を削除する（例）商品の請求額など、計算によって得られる項目

推移的関数従属  : 以下の条件を満たしている場合
集合Rの属性X, Y, Zにおいて、

- X → Y（YはXに関数従属している）
- Y → Xでない
- Y → Z（ただし、ZはYの部分集合でない）

目的 : 推移的関数従属している部分を排除する（同じものが利用されている箇所をまとめて切り出す）

## 高次正規形
※ 基本的に第三正規形になった時点で第3.5正規化以降は満たされているので、ほとんどない（基本的にそうなる）。
むりくり後からデータ構造を変更した場合や、設計がおかしい場合などに限られる。

## 第3.5正規形 : ボイス・コッド正規形
第3正規形であり、非キー属性が、主キーに関数従属をしている場合は、ボイス・コッド正規形にする。

## 第4正規形
ボイス・コッド正規形を満たしており、一つのリレーションの中に、互いに独立な意味を持つ多値従属性（Aが決まるとBの集合が決まる関係）が存在する事

目的 : 第4正規化では、 自明ではない多値従属性「X→→Y｜Z」を「X→→Y」「X→→Z」という 2つの自明な多値従属性に分解する

## 第5正規形
ボイス・コッド正規形を満たしており、まだ分割できるような状態（情報無損失分解）ができる状態のこと
[test014] 複数オブジェクトのトリガーを実行

# 複数オブジェクトのトリガーを実行

## 概要

querySelectorAllやgetElementsByClassNameなどでえられる複数のオブジェクトのトリガーを実効する

## ソース

### HTML
```test014.htm
<html>
<head>
<script type="text/javascript" src="test014.js">
<title>複数オブジェクトのトリガーを実行</title>
</head>
<body>
<input type="button" id="all" value="all">
<input type="button" onclick="console.log(1)" class="hoge" value="1">
<input type="button" onclick="console.log(2)" class="hoge" value="2">
<input type="button" onclick="console.log(3)" class="hoge" value="3">
</body>
</html>  
```
※hogeクラスのボタンは便宜上直にonclickを書き込んであります

### javascript
```test014.js
[NodeList,HTMLCollection].forEach(function(x){
  x.prototype.trigger=function(eventStr){
    var ret=[];
    Array.prototype.map.call(this,function(ele){
      if (document.createEvent) {
        var e = document.createEvent("HTMLEvents");
        e.initEvent(eventStr, true, true );
      return ele.dispatchEvent(e);
      } else {
        var e = document.createEventObject();
        return ele.fireEvent("on"+eventStr, e);
      }
    });
  };
});
window.addEventListener('DOMContentLoaded', function(e){
  document.querySelector('#all').addEventListener('click',function(e){
    document.querySelectorAll('.hoge').trigger('click');
    document.getElementsByClassName('hoge').trigger('click');
  });
});
```

## その他

### 参考

- [JavaScriptでjQueryを使わずにイベントをtriggerする](https://qiita.com/ryounagaoka/items/a48d3a4c4faf78a99ae5)

### 元ネタ
- [JavaScriptのクリックについて](https://teratail.com/questions/110662)

### 動くサンプル

- [codepen](https://codepen.io/yambejp/pen/OzKVwE)
BashでPromptの色を変更する方法

複数のサーバを管理していると、サーバの属性を即座に判断したいことがある。
もちろん、例えばホスト名に環境(本番・開発etc.)やサーバ種類・用途(Web, DB etc.)を意味する文字列を含めることも一般的ではあるが、パッと見で判別する直感性にはイマイチ欠ける部分がある。
そこで、より直感的に自分が操作しているサーバ種別や環境別を認識するために、Promptの色を変更する方法を紹介する。
これは、オペレーションミスを防ぐ意味でも有用である。
# 設定箇所
BashのPromptの書式に関する情報は、`PS1`というShell変数に格納されている。

```
$ echo $PS1
[\u@\h \W]\$
```
## 設定例
```PS1="\[\e[1;34m\][\u@\h \W]\\$ \[\e[m\]"```

# 書式
例: **\\[\e[1;34m\\]** *Promptに表示する変数や特殊文字* **\\[\e[m\\]**

Promptに表示する変数や特殊文字については、以下を参照
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/002cngprmpt.html

上記設定例の`1;34`の部分が色とフォントの設定値。

最初の設定値`1`の部分が、フォント。`0`にすると標準の字体、`1`にすると**Bold**になる。
`34`の部分が、色コード。上記設定例では、青色に設定されている。

|Color|Code|
|:-:|:-:|
|`#000000`|30|
|`#ff0000`|31|
|`#00ff00`|32|
|`#ffff00`|33|
|`#0000ff`|34|
|`#ff00ff`|35|
|`#00ffff`|36|
|`#ffffff`|37|

一番後ろの`\[\e[m\]`で設定を閉じておかないと、入力した文字も色付きで表示される。
# 設定方法
Bashの設定ファイル(e.g. /etc/bashrcとか)に、以下のような一文を追記すればOK!
```export PS1="\[\e[1;34m\][\u@\h \W]\\$ \[\e[m\]"```
一度Log-outして、Shellに入り直せば、色付きの設定が反映されている。
GitのArchiveで日本語ファイル名が文字化けするのを回避する


# 目的
zipでArchiveすると日本語ファイル名が文字化けをするので何とかする。

```
git archive HEAD -o Archive.zip
```
# 環境
* Windows7
* git 2.13.0.windows.1

# 結果
tarにしてから7zでzipする。

```
git archive HEAD -o Archive.tar --prefix=Archive/
"C:\Program Files\Git\usr\bin\tar.exe" -xvf Archive.tar
"C:\Program Files\7-Zip\7z.exe" a Archive.zip ./Archive/
```
MNISTのACGANを利用して、カラー画像のGANをやってみる

MNISTのACGANが比較的簡単なコードで公開されていたので、これを利用してGANをやってみた。
【参考】lukedeo/keras-acgan 
https://github.com/lukedeo/keras-acgan

ほぼ語りつくされた感があるけど、実際やってみると結構苦労したので、共有しておこうと思う。

#実際やったこと
①入力をCifar10を扱えるように（RGB）の３ｃｈに拡張
　Cifar１０や１００のデータ数を変えて、収束性を見た
②画像をYahooから取得等して、乃木坂46のメンバーと欅坂46のメンバー＋どうでもの人たちのデータを利用できるようにした
　①で決めた、ターゲット数になるまで収集。。。＋以下のサイトのデータを利用
【参考】Aidemy Inc. (id:aidemy-blog) の以下のサイト
http://blog.aidemy.net/entry/2017/12/17/214715
③イメージの大きさを自分で指定して利用できるような関数を用意した
④そして、これらでACGANを回してみた

#それぞれのpythonプログラムをGithubに掲載した。
https://github.com/MuAuan/DL-ACGAN
データ取得等は以下
https://github.com/MuAuan/DataManage

#※なお、1／27現在、まだまだ収束途中なので、途中経過を掲載します。

データ数4820、テストデータ数500、
(img_rows,img_cols) =（１２８×１２８）
５００epoch
![plot_epoch_120_akb_generated.png](https://qiita-image-store.s3.amazonaws.com/0/233744/6e7f7ebe-eeab-e59a-d11e-bf7dde229c3e.png)

１３５０epoch
![plot_epoch_030_akb_generated.png](https://qiita-image-store.s3.amazonaws.com/0/233744/937ca529-da5c-41fe-0af7-89f5e89130cc.png)
。。。
Xamarin.Formsでソフトウェアキーボードで入力欄が隠れないようにする2018

# はじめに

LINEのチャット画面のようにListViewの下に入力欄があるような画面で、なにも考えずに実装すると、画面が隠れるなど問題がいくつかあります。これの対策については素晴らしい過去の記事があります。[Xamarin.Forms でソフトウェアキーボードが表示された時に画面が隠れないようにする](https://qiita.com/amay077/items/6fcdec829a96bc604532)

ただ、iOSで現在うまくいかないので最新版のベストプラクティスを載せておきます。Androidについては上記の記事を参考にしてください。

# iOS

PageRendererをカスタムして対策します。

```csharp:KeyboardResizingPageRenderer.cs
public class KeyboardResizingPageRenderer : PageRenderer
{
    NSObject _onKeyBoardShow;
    NSObject _onKeyBoardHide;
    nfloat _barHeight;
    double _initialHeight;
    bool _isInitial;

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        _isInitial = true;

        if (NavigationController != null && NavigationController.TabBarController != null && NavigationController.TabBarController.TabBar != null)
        {
            _barHeight = NavigationController.TabBarController.TabBar.Frame.Height;
        }

        _onKeyBoardShow = UIKeyboard.Notifications.ObserveWillShow(OnKeyBoardShow);
        _onKeyBoardHide = UIKeyboard.Notifications.ObserveWillHide(OnKeyBoardHide);
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);

        if (_onKeyBoardShow != null)
        {
            NSNotificationCenter.DefaultCenter.RemoveObserver(_onKeyBoardShow);
        }

        if (_onKeyBoardHide != null)
        {
            NSNotificationCenter.DefaultCenter.RemoveObserver(_onKeyBoardHide);
        }
    }

    void OnKeyBoardShow(object sender, UIKeyboardEventArgs args)
    {
        var page = Element as ContentPage;

        if (_isInitial)
        {
            _initialHeight = page.Bounds.Height;
            _isInitial = false;
        }

        if (page != null)
        {
            var keyboardHeight = args.FrameEnd.Height - _barHeight;

            var pageFrame = Element.Bounds;

            // Padding変更じゃなしにページをLayoutTo
            Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
                                           pageFrame.Width, _initialHeight - keyboardHeight));
        }
    }

    void OnKeyBoardHide(object sender, UIKeyboardEventArgs args)
    {

        var page = Element as ContentPage;
        if (page != null)
        {
            var pageFrame = Element.Bounds;
            Element.LayoutTo(new Rectangle(pageFrame.X, pageFrame.Y,
                                           pageFrame.Width, _initialHeight));
        }
    }
}
```

こんな感じです。

キーボードの高さをとるのに苦労しましたが、UIKeyboardEventArgsのFrameEnd.Heightからとれます。変換候補の高さも考慮して上下してくれます。どうもTabBarを使っていると空白ができるようなのでTabBarの高さを引いてください。
webサイトを再帰的にダウンロードして、ローカルでも閲覧できるようにする

まあ端的に言えば以下です。

```
$ wget -rkp -linf -H example.com
```

wgetを使って再帰的にダウンロードしています。また、絶対リンクはすべて相対リンクに置き換えてくれます。
ただ、あまりにも多すぎると永遠に終わらないので、-lで階層を指定しましょう。
また、-Hを外すと、違うドメインの場合はダウンロードしないようになります。

ちなみに、シェル芸でクロールする裏技もあります。

```
$ curl -Ss http://www5a.biglobe.ne.jp/~todoroki/nct.htm|rg data|rg pdf|sed -e 's/.*[href|HREF]=\"//'|sed -e 's/pdf\".*$/pdf/'|while read name;do echo http://www5a.biglobe.ne.jp/~todoroki/$name;done|xargs wget
```
MemoryEnhancer > MEDC > test_get_markdown_180126.py > Markdownをとってくる

```txt:動作環境
Ubuntu 16.04.3 LTS desktop amd64
tmux 2.1-3build1
Python 2.7.12
Python 3.5.2
```

### 処理概要

- GitHub上のMarkdownをとってくる
- 特定の位置にある文字列を表示する
    - `<td>`を含む行の一つ目

### MEDC
 
Memory Enhancer Data Collectorの意味。

### 参考

- [クローリングしてきたテキスト、画像をローカルに保存](https://qiita.com/nimani76/items/1d2507d9bcb4ada357f9)

### code

```test_get_markdown_180126.py
import requests as rq

IN_URL = "https://github.com/yasokada/TechEnglish_170903/blob/master/data/5290.html.md"

res = rq.get(IN_URL)
for elem in str(res.content).split('\\n'):
	if "<td>" in elem:
		print(elem)
		break

```

```txt:run
$ python3 test_get_markdown_180126.py 
  <td><div>Cycle the power by powering down the device, then powering it on again.</div></td>
```

https://github.com/yasokada/TechEnglish_170903/blob/master/data/5290.html.md
Kubernetes Meetup - 2018.01.25



#  Cluster Deployment

- Kops
- juju
- kubespray

# Kubernets Scale design

 - Container orchestration
  - scale up / scale down
   - 正しい閾値の設定
   - しかるべきwarningの検知
    -　Pending
    - no resource
    - and so on...
 
 - Auto scaling
  - machine learning
   - 正しい閾値・効率的な閾値の算出に machine learning を活用している。

 - About network scaling
  - Instance, container network capacity depends on CPU, memory, and so on...
   - Scale up or down CPU, memory can be scale up or down network bandwidth.