OmniAICreator/Qiita-1.07M huggingface dataset:
mod_small_lightをApache2.4で使う（CentOS 7）

## はじめに
mod_small_lightを数年ぶりに使う機会があって、[こちら](https://www.takedajs.com/entry/2017/02/26/195556)のページを参考にしながらセットアップしていたのですが、いざApacheを起動しようとするも、起動しないという状況に……。

ログをみると、"small_light module only works with mpm prefork mode"と怒られているので、慌ててMPMを確認するもprefork…。どうもMPMの判定が上手く行っていない様子。なので、その部分を修正してあげると、無事起動するようになりました。（この判定の不具合がsystemdがらみ？なのかもしれないので、それ以外では普通に使えるかもしれない）

最近はApache使うことも少なくなり、mod_small_lightを使う人も少ないかもしれないのですが、古いシステムを2.4系に移す必要性があり、なおかつsmall_lightを使い続けなければならないという人の助けになれば幸いです。



### 環境
* CentOS 7.5
* Apache 2.4.6


## 準備
### yumのリポジトリにepelを追加
```console
$ sudo yum install -y epel
```
### 必要なものをまるっと導入
```console
$ sudo yum install -y httpd-devel ImageMagick ImageMagick-devel imlib2 imlib2-devel
```
### パスを確認
```console
$ which apxs Wand-config imlib2-config
/bin/apxs
/bin/Wand-config
/bin/imlib2-config
```

## mod_small_lightのセットアップ
### gitからソースをclone
```console
$ cd /usr/local/src
$ git clone https://github.com/yamac/smalllight.git
$ cd smalllight
```

### ソースを修正
このまま make installすると、先述したとおり、"small_light module only works with mpm prefork mode"という致命的エラーがログに吐かれ、静かにApacheが息を引き取ってしまいます。
なので、ApacheのMPMの判定部分を書き直してあげます。

```diff
@@ -93,7 +93,7 @@
 {
 #if APR_HAS_THREADS
     int mpm_threads;
-    ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads);
+    ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_threads);
     if (mpm_threads >= 1) {
         ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
             "small_light module only works with mpm prefork mode"
```

これで、mpm_threadsは正しくpreforkなら0, workerなら1となります。

### あとは流れで
あとは通常通り、先ほど確認したそれぞれのパスを指定して、makeするだけです！

```terminal
$ ./configure --with-apxs=/bin/apxs \
              --with-Wand-config=/bin/Wand-config \
              --with-imlib2-config=/bin/imlib2-config \
$ sudo make
$ sudo make install
```

無事成功したら、メッセージどおり、chmodしてあげます

```shell
$ sudo chmod 755 /usr/lib64/httpd/modules/mod_small_light.so
```

これで怒られずに無事Apacheが起動します。（もちろんMPMはpreforkで）

```shell
$ sudo systemctl start httpd
```

## あとがき
Apache/Nginxに限らず、こういったリサイズできるものって今は何が使われてるんですかね…？　そもそもこういった方法で画像編集すること自体がイケてないのだろうか…。

## 参考
https://www.takedajs.com/entry/2017/02/26/195556
https://qiita.com/tototoshi/items/472f2b09e48ae9717a2d
https://ci.apache.org/projects/httpd/trunk/doxygen/group__qcodes.html
RubyMineでデバッグモードを使おうとしたら、Permission ErrorでGem Installができず起動できない問題の解決方法

※ 最近VSCode → RubyMine（Jetbrains）に乗り換えはじめました。すごくいい感じです。

環境:
Mac OS High Sierra 10.13.3（17D47）

RubyMineはデバッグ機能を使うときに `debase` と `ruby-debug-ide` を自動インストールしてくれるが、

Permission Errorで以下のエラーが出ていた。

```
Error running 'Development: wedding-x': Failed to Install Gems. Following gems were not installed: /Applications/RubyMine.app/Contents/rb/gems/debase-0.2.3.beta2.gem: While executing gem ... (Errno::EACCES) Permission denied @ dir_s_mkdir - /Users/myname/.anyenv/envs/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/extensions/x86_64-darwin-17/2.2.0-static/debase-0.2.3.beta2 Building native extensions. This could take a while... /Applications/RubyMine.app/Contents/rb/gems/ruby-debug-ide-0.7.0.beta6.gem: While executing gem ... (Errno::EACCES) Permission denied @ dir_s_mkdir - /Users/myname/.anyenv/envs/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/extensions/x86_64-darwin-17/2.2.0-static/ruby-debug-ide-0.7.0.beta6 Building native extensions. This could take a while...
```

該当のディレクトリに行ってみると

```
cd ~/.anyenv/envs/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/extensions:
ls -l
drwxr-xr-x  3 root  staff  96 Jun 24 21:11 x86_64-darwin-17
```


`x86_64-darwin-17` のディレクトリだけ rootになっていた。
いつかのMacのバージョンからデフォルトがこうなった模様。
ここの権限を手動で自ユーザーに変えるとインストールできるようになる。

```
sudo chown -R myname .
```

参考:
RubyMineでデバッグモードが動かなかった
http://jnst.hateblo.jp/entry/2016/08/12/215438
Docker for windowsでマウントしていたホストのフォルダが見えなくなった場合の対応

## 現象
ノートPCとデスクトップにそれぞれDocker for windowsをいれて楽しいdockerライフを送っています。
ある日、ノートの方のコンテナで、ホスト側のディレクトリをマウントしていますが、ある日からホスト側のファイルが見えなくなって困っていました。
nfsマウントしているディレクトリは見える。はてはて。

そんなある日、今度はデスクトップの方のdocker コンテナをstartしようとしたら、

```
Error response from daemon: error while creating mount source path '/host_mnt/c/Users/xxx': mkdir /host_mnt/c: file exists
```

みたいに怒られて、startできなくなった！

## 解決方法
リンク先のとおりです。
[Docker for Windowsでホストのフォルダがマウントできなくなった場合の対処方法](http://www.nuits.jp/entry/docker-for-windows-mkdir-file-exists)


![docker_for_win_setting.PNG](https://qiita-image-store.s3.amazonaws.com/0/143174/acea8503-eafa-2ee2-ec3a-12bec2398616.png)

Docker for windowsの設定画面で「Shared Drives」の「Reset credentials」をクリックして一度認証を外し、再度、認証し直しました。

これでデスクトップのほうでdocker startできるようになり、ノートの方も同じ対応をしたら、めでたくホストのフォルダの中が見えるようになりました。
v-forでmountedしたものを展開しようとしたらできなかった

```html
<template lang="html">
  <v-ons-page>
    <component
    v-for="category in allCategories"
    :is="CategoryIndexPage"
    :key="category.id"
    :title="category.title"
    :image="category.image"
    :categoryAll="category.title"
    PropsWidth="25"
    :page-stack="pageStack"
    class="all-category"
    ></component>
  </v-ons-page>
</template>
```
```js
<script>
// 省略
  data () {
    return {
      allCategories: []
    }
  },
  created: function () {
    const self = this
    var listSet = []
    this.axios
    .get(process.env.BASE_URL + 'all_category')
    .then(function (res) {
      listSet = res.data
      self.allCategories = listSet
    })
  }
}
</script>
```

これで本来self.allCategoriesが更新されるはずなのに更新されなかった…
これだけで数日悩んでしまったので記事にします

# 結果：divで囲って上げるだけだった
```html
<template lang="html">
  <v-ons-page>
    <div>
      <component
      v-for="category in allCategories"
      :is="CategoryIndexPage"
      :key="category.id"
      :title="category.title"
      :image="category.image"
      :categoryAll="category.title"
      PropsWidth="25"
      :page-stack="pageStack"
      class="all-category"
      ></component>
    </div>
  </v-ons-page>
</template>
```

### 備考：なぜdivで囲わないといけないのか？

これは、コンポーネントを展開した時

```html
<ons-page>
  <div class="page__background"></div>
  <div class="page__content">
  </div>
  <div v-key="1">hoge</div>
  <div v-key="2">hogehoge</div>  <!-- データ上は追加されている -->
</ons-page>
```

…ということで、divで囲っていないせいで、page__contentの中に入っていないのが根本的な原因でした。
divで囲ってあげると

```html
<ons-page>
  <div class="page__background"></div>
  <div class="page__content">
    <div v-key="1">hoge</div>
    <div v-key="2">hogehoge</div>  <!-- データ上は追加されている -->
  </div>
</ons-page>
```
という形にすることで、中に含めることができます。
これで晴れて正しく表示されるわけですね。
住所から緯度経度を取得するスプレッドの関数

# 住所から緯度経度を取得するスプレッドの関数
システム投入データ等で、住所から緯度経度を求めたかったのでユーザー関数を作成

### 使い方
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172765/4b596bd3-1857-ca25-8152-69479a867f1c.png)
関数を赤色のセルに貼り付けてね

### 以下のコードをスクリプトにコピペ
```
// フィールド変数
var apiKey = "xxxx"; //Google Cloud Platform >認証情報 >APIキー　を入れる

//緯度
function getLat(address) {
  var location = getLatLng(address);
  return location['lat'];
}

//経度
function getLng(address) {
  var location = getLatLng(address);

  return location['lng'];
}

//APIを呼び出して住所から緯度経度を求める
function getLatLng(address) {
  if (address === '') {
      return
    }

    var api_url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURI(address);
    api_url += '&key='+apiKey;
    var response = UrlFetchApp.fetch(api_url);

    var result = JSON.parse(response);
    var location = result['results'][0]

    if (typeof location === 'undefined') {
      return
    }
    location = location['geometry']['location'];
    return location;
}
```

### 注意
1. APIキー単位で1日当たり呼び出しの上限回数がある
2. 住所1件あたり緯度、経度で計2回呼び出す
Nuxt.jsでSSR時に手軽にサーバ時刻を得る

投稿時間や出退勤時間、或いはcreated_atでもmodified_atでも何でも良いのだが、渡ってくるデータには絶対時刻があり、しかし表示上はTwitterの時間表示のように、「n日前」「n分前」等の相対時刻を扱いたいときが偶にある。

このとき、比較用の現在時刻を得るのに

1. ローカル時刻を使う
2. APIが現在時刻を返すようにする
3. サーバ時刻を取得するAPIを作成する

あたりが考えられるが、ローカル時刻はもちろんクライアント機器の時刻に依存してしまうためクリティカルな用途では使えず、2⃣が出来れば良いのだがAPIの改造が許されていない場合もある（アグリゲーションレイヤーを使う手はあるが）。となる3⃣が良さそうだがもっと簡単な方法がある。

**折角SSRを使っているなら`state`または`data`に`Date.now()`で値を入れてしまえばいい**のだ。
運用上、更新できないように`state`にして`mutation`を設定しないのが良いだろう。

## 差が一分未満かどうかで判定するサンプル

```javascript:store側
const store = new Vuex.Store({
  state: {
    current_time: Date.now()
  }
})
```

```javascript:コンポーネント側

import { mapState } from 'vuex'
export default {
  data(){
    created_at:0
  },
  async asyncData ({ params }) {
    let { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { created_at: data.created_at}
  },
  computed: {
    ...mapState(['current_time']),
    created_at_lavel(){
      const diff = this.current_time - this.created_at;
      // 例として差が一分未満かどうかで判定する
      return (diff < 60*1000)?'たった今':'1分以上前'
    }
  }
}
```
## ※APIに現在時刻も含めてもらうのが正攻法
【C#】小ネタ・IISだけインストールしてさくっとASP.NETのHello World!を表示する

そのうち別記事で書こうかなと思いますが、私は**「Visual StudioにめぐまれないC#er」**なのです。

んで例えば「C# Visual Studio なし」とかでネット検索すれば、「Visual Studioなしでコマンドラインのプログラムは作れるぜ！」的な記事は出てきますし、その方法で、がんばればフォームアプリケーションだってゴリゴリかけるんです。てかそれを業務でやってるワシはなんなんだ。はよVisual Studioください。

んで。今回ご紹介するのは、**「Visual StudioなしでカンタンなASP.NETフォームページを書いて動かそう！」**というものです。なんだよそれ需要あんのかよ。

Windows PC上で(7と8で確認してます。10はあとで確認してちがったら修正します)。
コントロールパネル＞プログラムを開き、プログラムの機能＞Windowsの機能の有効化または無効化をクリックし、「インターネット インフォメーション サービス」のツリーを開きます。とりあえず、World Wide Web サービス＞アプリケーション開発機能＞ASP.NET (x.x)を有効化しましょう(それ以外はお好みで

![test01.jpg](https://qiita-image-store.s3.amazonaws.com/0/269237/668f7233-de2d-0bb0-7abc-8fb22a78fc81.jpeg)


んで例えばこういうものを動かしてみる。

**helloworld.aspx**

```C#
<%@ Page Language="C#" AutoEventWireup="true" %>
<script runat="server">
  protected void Button1_Click(object sender, EventArgs e)
    {
      Label1.Text = "Hello,World!";
    }
</script>

<html>
<head runat="server"></head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
      <asp:Label ID="Label1" runat="server" Text="Label" />
    </div>
  </form>
</body>
</html>
```

上記のソースをwwwのルートフォルダに配置し、ブラウザから http://localhost/helloworld.aspx にアクセスするとボタンとラベルを持ったページが表示されます。
ボタンを押すとラベルに、Hello, World!って表示されます。そんだけ。

![tes002.jpg](https://qiita-image-store.s3.amazonaws.com/0/269237/353d130d-fc2c-f7d2-1c36-c18a436d33bd.jpeg)
EC2にスワップを設定する

# 内容
AWSのEC2インスタンスは起動時点でスワップ領域が設定されていないため、手動で設定する必要がある。

# 手順
## SSHでEC2インスタンスにログインする
当然ながらインスタンスへのログインが必要
```ssh -i [pemファイル(xxx.pem)] ubuntu@[IPアドレス or ドメイン]```

## スワップを作成する
```bash

# 管理者権限になる
sudo su -

# スワップ用フォルダの作成
mkdir /var/swap

# 2Gのスワップ用のファイル作成
dd if=/dev/zero of=/var/swap/swap0 bs=1M count=2048

# パーミッションの設定
chmod 600 /var/swap/swap0

# スワップ割り当て
mkswap /var/swap/swap0
swapon /var/swap/swap0

# 起動時に自動でスワップが割り当てられるように設定
echo '/var/swap/swap0 swap swap defaults 0 0' >> /etc/fstab
```

## 反映されたか確認
topコマンドなので確認できる
GitLabでmasterへのPushを防ぐ

チーム開発において、gitの使い始めではどうしてもmasterへPushしてしまうトラブルが付きものです。
GitLabにはProtected branchというPush権限を限定する設定があり、これを使えば誤ったPushを防ぐことができます。

# 設定方法
GitLabで、設定したいプロジェクトのルートに移動します。

### 設定する対象の権限の確認
GitLabで設定済みの権限を確認しましょう。
今回はDeveloperはmasterにPushできないようにすることにします。デフォルトブランチ名がmaster以外の場合は、masterを適宜読み替えてごらんください。

### 設定画面に移動
左のツリーから"Repository"を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/00002aa9-80da-f670-6f7b-bde6b58fbe0f.png)

"Protected branches"を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/91b7e87d-74a8-d552-ea8f-70d634aa43d2.png)

### 現在の設定を確認
下記の部分が現在の設定です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/a7003bcc-3569-3bb8-469d-c1424aa73ddd.png)

各列の説明は以下。

- Protected branch
PushやMergeに何らかの制限がかかっているブランチ名が表示されます。"Defalut"とマークがあるのがdefault branchです。

- Last commit
そのbranchの最後のPush日とcommitへのリンクです。

- Allowed to merge
ここで選択したユーザにのみMergeが許可されます。
Merge requestを可能にしたいグループをここで選択してください。

- Allowed to push
Pushを許可する権限です。指定branchに対して直接Pushができます。Merge requestを必須とする運用ならば、ここはno oneもしくはMasterだけに留めておくべきです。

- Unprotect
ここを押すと、そのブランチの権限設定が抹消されます。

### branchを追加する
下記の部分から制限を設けたい、新しいbranchの追加が出来ます。
BranchのInput boxにbranch名を記入しましょう。入力候補が出るのでそこで選ぶこともできます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/35c9fa51-96d5-eab8-9c3f-ca55dfd85e69.png)

あとは、各操作を可能にする権限を選択したら"Protect"を押して設定完了です。

# 注意
この設定はRepository毎に必要ですので、複数のProjectに対して設定を行いたい場合には、それぞれ設定してください。
IDを指定してLinuxにユーザを追加する


以下のコマンドで，既に使用されているIDを確認する。

`$ cat /etc/passwd`

スーパーユーザ(root)になってuseraddする。

```
$ su
# useradd -m hnishi -u 2065
```

`-m`オプションはユーザのディレクトリをつくる。
`-u`は，指定したいユーザID（グループIDも同じになる）。
研修（図解思考）

##図解思考
###目的
情報の本質を理解し、図解を使ってわかりやすく表現する
###概要
1．図解作成の3ステップを学ぶ
2．図解の「かた」を理解し活用する
3．演習を通じて図解表現の定着を図る

***
###図解とは
####■図解とは
・伝えたいことが一見してわかるように、図やグラフを用いてまとめること

***

####■図解の活用メリット
・図解を活用することで視覚効果を生かすことができる。
→人は文字で記憶せず、画像や動画といったイメージ記憶が主流のため相手の記憶に残りやすくなる
・文章が多い資料の弱点
→指示語がわかりにくい、抜け落ちができる、箇条書きは5つまで
・複雑なじょうほうが正確にわかりすく伝えることができる

####■図解の活用デメリット
・わかったつもりの錯覚が起こる
 →口頭補足する
・図解定義の不足による誤解が起こる
 →抽象化しすぎない、文字や口頭で認識齟齬が生まれ無いようにする

***

####■図解化の流れ
STEP1. 複雑な情報からキーメッセージを抽出する
 * 主張の明確化
 * キーメッセージの選定
STEP2. 抽出したメッセージを分類
 * MECEの活用
 * 一般的なフレームワークを使う（4P、時間軸、起承転結、プレゼンテーション）
STEP3. 構造と関係を明確にする（関連付け）
 * キーワードを出し、囲み、線でつなぐ

***

###型の活用（6つ）
さらにわかりやすい図解化をするために使用する
####■型のメリット
・読み手も見慣れているので一見でわかる
・図解表現の判断が容易
・必要情報の抜け漏れに気づくことができる

####■型の例
⑴ツリー型
→組織や情報の階層構図を示すのに用意
⑵マトリックス型
→異なる2軸の組み合わせて要素を整理する
⑶フロー型
→プロセスの流れを可視化する
⑷サテライト型
→複数の要素の相互関係を示す
⑸サイクル型
→循環するフローを示す
⑹グラフ型
→定量分析と傾向を示す

***

###ポイントメモ
・無意識ではなく、意識して活用することが大切
（相手のことを意識して作成できているか、意識して色を使用しているか…等）
・フレームワークを理解して引き出せるようにしておく（結論・理由・例は使いやすい）
・グラフを書くときのポイント
 タイトル、凡例（7±2）、出典
[macOS] ネイティブで殴るCEF - 備忘録

## 注意
これはただの備忘録です

### 最終目標
ブラウザの表示部分をNSView（のサブクラス）として簡単に取り扱えるようにする

### 導入
これをそのまま実行
https://bitbucket.org/chromiumembedded/cef/wiki/MasterBuildQuickStart#markdown-header-mac-os-x-setup

out/Debug_GN_x64 内の `Chromium Embedded Framework.framework`と`libcef_dll_wrapper.a`をリンクする。

`libcef_dll_dylib`はあとで調べる。

dSYMが5GBぐらいあるので注意。

### 何か変な時

#### create.shが失敗する時

`code/chromium_git/chromium/src`で`gclient runhooks`か`gclient sync`を実行してみる 

###次やること
 - なにしよう

### CEFに関して今までに分かったこと

#### CefBrowser

```c++
CefWindowInfo window_info;
window_info.hidden = true;
```
これを設定してCefBrowserを生成すれば生成時にウインドウが表示されない。

#### CefWindow
これが弄るターゲット。
native側のNSView（CefBrowserHostViewクラス）を持ってる。 Windowなのに。

```c++
auto nsview = (NSView *)browser_->GetHost()->GetWindowHandle();
```
で取得可能。

上記Viewから

```objc
NSWindow *window = view.window;
```
でCefBrowserが持つNSWindowが取得できる。
このウインドウのクラスはUnderlayOpenGLHostingWindow。
delegateとしてCefWindowDelegateのインスタンスが設定されている。
このウインドウを破棄するとviewも破棄されてしまう。

NSWindowControllerは設定されていない。


#### イベントループ
native側が無視するイベントを全部CEFに流し込む感じ？


#### UAの設定

```c++
CefSettings settings;
const char *ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) KCD(2.0a0) is not Chrome/70.0.3538.0";
    
CefString(&settings.user_agent).FromASCII(ua);
```

#### Accept-Languageの設定

```c++
CefSettings settings;
CefString(&settings.accept_language_list).FromASCII("ja-JP,en-US;q=0.5,en;q=0.1");
```
### わからん

windowless_viewとかあるがちょっと意味が違う。

view-baseとかあるがmacOSは非対応。
【NUCLEO_F446RE】USER_BUTTONで1回だけHello,World.【メモ】

``` main.cpp
//前略
int main(){
    int b1;
    button.mode(PullUp);
    while(1){
        b1=button;
        if(!b1){
            printf("Hello,World.\n\r");
            while(b1 == 0){
                b1=button;
            }
        }
    }
}

```
サービスを管理 - Ubuntu Server 18.04 LTS

#はじめに
systemdでサービスを管理する。

#コマンド

unit一覧

```text:
$ systemctl
```

すべてのunit一覧

```text:
$ systemctl -a
```

確認・起動・停止・再起動

```text:
$ systemctl status hoge.service
$ systemctl start hoge.service
$ systemctl stop hoge.service
$ systemctl restart hoge.service
```

自動起動の確認・有効化・無効化

```text:
$ systemctl list-unit-files
$ systemctl enable hoge.service
$ systemctl disable hoge.service
```






#リファレンス
- [http://manpages.ubuntu.com - systemctl](http://manpages.ubuntu.com/manpages/bionic/en/man1/systemctl.1.html)
JavaScriptの分割代入は undefined のときにだけ初期値が設定される

JSだと、`0`とか`""`とか`null`とか`false`が全てfalsyとして扱われるので、少し気になり、調べてみました。

```js
const object = { 
  a: 0, 
  b: "", 
  c: null, 
  d: false, 
  e: undefined,
};
const {      // 結果
  a = 1,     // 0
  b = "foo", // ""
  c = "foo", // null
  d = true,  // false
  e = "foo", // "foo"
  f = "foo", // "foo"
} = object;
```

ということで、`undefined`の時にだけ初期値が適用されるようです。falseだったらどうしようとか悩まなくてよいようです。

以上です。よろしくお願いいたします。
Scikit-learnでオートエンコーダーっぽいものを実装してみる

# はじめに

色々とセミナーをさせて頂くことが多くなり、特にAI関連技術のセミナーではあまり知らないで話をしていると、実は間違っていました...なんてことになりかねない。

ということで、勉強のためにAutoEncoderをScikit-learnで実装してみたので、その手順を以下にまとめます。

# データセット

手書きの数字データがScikit-learnに用意されているのでこちらを利用します。
読み込んだら、いくつかの画像を表示して、どんな感じか確認します。

```python:

from sklearn.datasets import load_digits
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

dig = load_digits()

for i in [10, 230, 450]:
    npimg = np.array(dig.data[i])
    npimg = npimg.reshape((8, 8))
    plt.imshow(npimg, cmap='gray')
    plt.show()
```

実行結果は以下のとおり。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114240/4b4efb2a-80ed-decc-916f-46bbc9b441db.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114240/700a5954-5817-2113-1bf3-cc65909868d4.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114240/be6b436e-143e-8361-70f4-304f0b1c49a7.png)

# 入力データ作成

データセットから入力と出力のデータを取得し、学習用と検証用にデータを分けます。
ここで、エンコーダーの学習にもデータの一部を使うので、半分ずつにわけています。

```python
import pandas as pd

X = pd.DataFrame(dig.data)
y = pd.DataFrame({"y":dig.target})

from sklearn import model_selection
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=.5, random_state=42)

# 後で使うので先にとっておきます
y_proba = pd.DataFrame(X_test)

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)

X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
```

# 学習

先ほどのデータをニューラルネットワークで学習します。

```python:
from sklearn.neural_network import MLPClassifier

model = MLPClassifier(random_state=42)
model.fit(X_train, y_train.as_matrix().astype("int").flatten())
model.score(X_test, y_test)
```

実行してみると、スコアは「0.9699666295884316」でした。

# エンコーダー

次にエンコーダーを作ります。
ここで、検証用のデータからpredict_probaを使って10個の配列データを取得し、入力データとします。

そして、教師データとして検証データのセルごとの値をy_proba_cellsに分解します。

モデルをセルの数と同じだけ用意し、それぞれのセルごとに入力値に対する出力を学習させます。

```python:
X_proba = pd.DataFrame(model.predict_proba(X_test))

y_proba_cells = []

for col in y_proba.columns:
    y_proba_cells.append(y_proba[col])

model_proba = []

for i in range(y_proba.shape[1]):
    model_proba.append(MLPClassifier(max_iter=500, random_state=42))

for i in range(y_proba.shape[1]):
    model_proba[i].fit(X_proba, y_proba_cells[i])
```

# 画像生成

学習後のモデルに、出力したい数値に応じた配列を入力し、得られたセルごとの予測値から、画像を生成してみます。

```python:
X_encode = 6

m = [0] * 10
m[X_encode] = 1
X_encode = m

result = []

for i in range(y_proba.shape[1]):
    result.append(model_proba[i].predict([X_encode])[0])

npimg = np.array(result)
npimg = npimg.reshape((8, 8))
plt.imshow(npimg, cmap='gray')
```

実行した結果は、こちらです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114240/d1c1a315-d008-db04-1e52-34dc8fc831eb.png)

6っぽい(^-^)

次は0と9の確率が0.5づつの場合を試してみます。

```python
X_encode = [0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5]

result = []

for i in range(y_proba.shape[1]):
    result.append(model_proba[i].predict([X_encode])[0])

npimg = np.array(result)
npimg = npimg.reshape((8, 8))
plt.imshow(npimg, cmap='gray')
```

実行すると...

![image.png](https://qiita-image-store.s3.amazonaws.com/0/114240/78ebc3d0-fea7-7477-d805-51f84fb415ad.png)

0のような9のような...新しい数字が生まれた感じ(^_^;)

できた！
Amazon Kinesisを使ってRedshiftにJSONを投入

# 事前準備
Redshiftの作成は省略します。
いい記事がたくさんあるので。。。

# Redshiftにテーブルを作成
今回はこんなテーブルを作りました。

```
create table logs (
  id int not null,
  value varchar(30) not null,
  created_at timestamp not null
);
```

# Kinesis streamsの作成
名前はlog-stream、Number of shards は1にしました。

<img width="953" alt="スクリーンショット 2018-09-07 10.32.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/36192/3657bac4-b8bd-bf3c-79af-54733de79a9a.png">

# Firehoseの作成
名前はlog-stream-firehoseにしました。

SourceでKinesis streamを選択、さっき作ったlog-streamを選んで

<img width="831" alt="スクリーンショット 2018-09-06 20.41.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/36192/228b76da-ca82-2b26-65c0-fb1bd5a0d8d7.png">

## Step2: Process records
全てデフォルトで。。

## Step3: Choose destination

### Select destination
Amazon Redshiftを選択

<img width="687" alt="スクリーンショット 2018-09-06 20.42.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/36192/a632cfee-b185-6c0a-7ede-25e51ec1b3b4.png">

Amazon Redshift destinationに事前に準備したRedshiftの情報を設定した後
Redshiftのセキュリティグループを編集してFirehoseからアクセスを許可します。
(水色の箱にFirehose IP addressが書かれているのでそれを許可してやる)

### intermediate S3 destination
RedshiftにCOPYコマンドでデータを転送する前に一度S3にあげる先みたいです。
今回は新しく作りました。

### Amazon Redshift COPY command

COPY optionsに`JSON 'auto';`を設定
<img width="690" alt="スクリーンショット 2018-09-06 20.42.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/36192/591e0fac-1572-c400-6cf8-628d5cbd4d16.png">

## Step 4: Configure settings
全てデフォルト値で。IAM roleも今回新しく作りました。

# 動作確認
AWS コマンドラインインターフェイスをつかってデータを登録してみます。

こんなファイルを作成

``` log.json
{
  "Records": [
    {
      "Data": "{\"id\": 12345, \"value\": \"click\", \"created_at\": \"2018-09-05 00:00:00\"}",
      "PartitionKey": "124"
    }
  ],
  "StreamName": "log-stream"
}
```

AWS CLIでデータを登録

```$ aws kinesis put-records --cli-input-json file:///tmp/event.json```

こんな値が帰ってきたら成功です

```
{
    "FailedRecordCount": 0,
    "Records": [
        {
            "ShardId": "shardId-000000000000",
            "SequenceNumber": "xxxxx"
        }
    ]
}
```

ちょっと待ってからRedshiftでlogsテーブルをselectしてみると。。

```
 select * from logs;
  id   | value |     created_at
-------+-------+---------------------
 12345 | click | 2018-09-05 00:00:00
```

# 注意点
JSONのキーはダブルクォーテーションで囲む

[トラブルシューティング]
(https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/troubleshooting.html#data-not-delivered-to-rs)
Firebase FunctionsにAuthenticationの認証をつける

リクエストを受けた時にfunctions側でFirebase Authenticationでログインしているかをチェックしたい。
ちょっとした内製のツールを作る時にG Suiteのアカウントで認証したい。

#　Authenticationと連携する機能はないのでクライアント側で対応する

公式のサンプル
https://github.com/firebase/functions-samples/tree/Node-8/authorized-https-endpoint

クライアント側でAuthenticationにログインをしてtokenを作成して、
FunctionsのAPIにリクエストする際にHeaderとしてtokenを渡しています。
そのtokenをFunctions側で認証をチェックしていました。

### クライアント側

```:javavscript
import axios from "axios"

firebase.auth().currentUser.getIdToken().then(function(token){
  axios.get("/api/xxxx", {
    headers: { 'Authorization': `Bearer ${token}`  }
  })
})

```

### Functions側

```:javascript

const token = req.headers.authorization.split('Bearer ')[1];

try {
  const decodedToken = await admin.auth().verifyIdToken(token);
  console.log("success");
} catch (error) {
  console.error("error");
}
```

---

GAEみたいに簡単に強制的にログイン処理を挟めると思ったんですが難しいようですね。
IAM周りを使えば、できるのかもしれませんが。
cakephp3 ラジオボタンのグループ化

radio ボタンを グループ化したい。

http://bootstrap3.cyberlab.info/javascript/button-radio.html

hoge.ctp

```

    <?php
    $this->Form->templates([
        'nestingLabel' => '<label class="btn btn-default">{{input}}{{text}}</label>',
        'radioWrapper' => '{{label}}',
    ]);
    ?>

    <label class="control-label">どちらで登録しますか？</label>

    <div class="form-group text">

        <div class="btn-group btn-group-justified" data-toggle="buttons">
            <?php

//            デフォルト値をセット
            $default_value = 1;
            if(!empty($this->request->data['mode'])){
                $default_value = $this->request->data['mode'];
            }

            ?>

            <?=$this->Form->radio('mode',
                [
                    1 => '会員登録 ',
                    2 => '一般利用者'
                ],
                [
                    'label' => [
                        'class' => 'btn btn-default'
                    ],
//                    hidden があると ボタンが四角になるので false にしておく
                    'hiddenField'=>false,

//                    なぜか default が効かないので
                    'value' => $default_value
                ]
            );?>

        </div>


    </div>



    <script>

        $(function () {
            //ボタンを アクティブにする
            $("input:checked").parent().addClass('active')
        });

    </script>


```
intra-martのスクリプト開発で文字をバイト数指定で切り捨てる

# 対象となる開発形態
- intra-mart Accel Platform
   - スクリプト開発
   - IM-FormaDesigner(Ajax利用)

# やりたいこと
- 文字列をバイト数指定で切り捨てる。
- 指定バイト数が文字の途中だった場合、その前の文字までを取得する。

# コード
```byteTruncStr.js
function byteTruncStr(str, byteLen) {
   if (Module.string.size(str) <= byteLen) {
      return str;
   }

   let strLen = byteLen > str.length ? str.length : byteLen;
   let truncStr = str.substring(0, strLen);
   while (Module.string.size(truncStr) > byteLen) {
      strLen --;
      truncStr = truncStr.substring(0, strLen);
   }
   return truncStr;
}
```
- 引数
   - `str`: 切り捨て対象の文字列
   - `byteLen`: 切り捨てるバイト数
- 戻り値
   - `truncStr`: 切り捨て後の文字列

## 解説
intra-mart APIの`Module.string.size(str)`は、文字列のバイト数を取得するAPIです。
[intra\-mart Accel Platform SSJS API Documentation](https://www.intra-mart.jp/apidoc/iap/apilist-ssjs/doc/platform/Module.string/index.html)

```js
 if (Module.string.size(str) <= byteLen) {
     return str;
 }
```
で、そもそも対象文字列が指定バイト数内に収まっている場合にそのまま文字列を返却します。
収まりきっていない場合は切り捨て処理を行う訳ですが、それが次のコード。

```js
let strLen = byteLen > str.length ? str.length : byteLen;
let truncStr = str.substring(0, strLen);
while (Module.string.size(truncStr) > byteLen) {
   strLen --;
   truncStr = truncStr.substring(0, strLen);
}
```
切り捨て対象文字列を変数`truncStr`に入れ、そのバイト数が指定バイト数***以下***になるまで1文字ずつ減らしていきます。

単純に対象文字列全体から1文字ずつ減らしていくと、文字列が非常に大きく切り捨てるバイト数が非常に小さい場合にループ回数が極端に大きくなってしまうため、対象文字列を初めから制限するようにしました。
それがwhileループ前の変数宣言部分。
そもそも100文字300バイトを10バイトに切り捨てたいんなら、先頭10文字しか使わなくていいじゃん、って考えです。

# 通常のJavaScriptでは
`Module.String.size(str)`部分さえJavaScriptで実装できてしまえば、後は全く同じように利用できます。

cf: [JavaScript文字列のバイト数を数える - encodeURIComponent版](https://qiita.com/xtetsuji/items/a8490a7fea3f5a01e49c)
パッケージのアップデートとアップグレード - Ubuntu Server 18.04 LTS

#はじめに
パッケージのアップデートとアップグレードする。

#コマンド

アップデート (参照: /etc/apt/sources.list)

```text:
$ sudo apt-get update
```

アップグレード

```text:
$ sudo apt-get upgrade
```

#リファレンス
- [http://manpages.ubuntu.com - apt_1.6.1_amd64](http://manpages.ubuntu.com/manpages/bionic/en/man8/apt-get.8.html)
#pragma hdrstop 勉強メモ

# #pragma hdrstop ってなんぞや？

>\#pragma hdrstop の前の部分でプロジェクトの共通ヘッダーファイルをインクルードし，それ以降の部分で独自のヘッダーファイルをインクルードすることで，最高のコンパイラ性能を得ることができます。
by [RAD Studio](http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/JA/html/devwin32/pndsnpragmahdrstop_xml.html)


### プリコンパイル？
>大規模なプログラムを作ることになってくると、当然インクルードするヘッダファイルが増えてきますよね？  \~\~(略)\~\~ 
プリコンパイル済みヘッダとはコンパイルの最初にインクルードするヘッダを全て解析したヘッダファイルのことで、~~コンパイル時間が劇的に早くなります。

一方で、小規模なプロジェクトの場合、大して変わらない模様。

### stdafx.h 
Visual Studio環境下でよく見るプリコンパイル済みヘッダ。

先輩エンジニアに聞いたことだが、これが上書き禁止になったりして問題を起こしたりといったハマりやすさもあるようだ。
VSCode 比較・マージして貼り付ける拡張機能 merge-n-paste

以前、[AdventCalendarに参加させていただいた時](https://qiita.com/RAWSEQ/items/7c53596754d2a102499f)には拡張機能開発をメインに書いたのですが、設定画面のインターフェースが新しくなり、設定も簡単になったことですし、自作拡張機能の方の利用方法をメインに書きます。

# merge-n-paste 概要
コピー＆ペーストを行う際に、使い慣れた「比較・マージツール」を用いて、比較してからペーストすることができます。例では上の文字列をコピーして下の文字列に貼り付けていますが、選択範囲を指定しなければ、全文に対しても比較マージが可能です。マージがうまくいかなかった場合はキャンセルすることも可能です。
左が【クリップボード】（貼り付ける文書）・右が【エディタ】で、右方向にマージして右側を貼り付けています。
![mp.gif](https://qiita-image-store.s3.amazonaws.com/0/65983/7da65a22-22c8-4b0c-9ff5-2c581e6a4c52.gif)

マージツールはWinMergeを利用していますが、KDiff3等、その他マージツールにも対応しています。
マージツールを使うので手動よりは正確で、手軽に実施できるところが便利な拡張機能です。

## 導入方法

- VSCodeは最新版(当時は1.27.0)がインストールされた状態で <kbd>ファイル</kbd> > <kbd>基本設定</kbd> > <kbd>拡張機能</kbd> メニューを開きます。

![ins.png](https://qiita-image-store.s3.amazonaws.com/0/65983/fa6a35e1-183b-267c-d98e-de672168ac31.png)

- 左ペインの上部に検索窓があるので「`merge-n-paste`」と入力し、該当の「インストール」ボタンをクリックします。その後、「再読み込み」というボタンになると思いますので、そのボタンもクリックします。

## 設定方法

- マージツール（WinMerge等）は指定されていない状態なので、設定画面で設定します。<kbd>ファイル</kbd> > <kbd>基本設定</kbd> > <kbd>設定</kbd> メニューを開きます。

![set.png](https://qiita-image-store.s3.amazonaws.com/0/65983/e9db3703-b1dc-7c02-40fb-711dcc59c497.png)

- 左メニューから<kbd>拡張機能</kbd> > <kbd>Merge and Paste</kbd> > <kbd>Path To Merge Tool</kbd> にマージツールのパスを設定します。

WinMergeの場合は

```
"C:\Program Files\WinMerge\WinMergeU.exe" %C %E
```

<kbd>%C</kbd> : クリップボード側, <kbd>%E</kbd> : エディタ側, <kbd>%M</kbd> : マージ出力
KDiff3の様なマージ出力を別にすることができるツールであれば

```
"C:\Program Files\kdiff3\kdiff3.exe" %E %C -o %M
```

といった、出力ファイルも指定できますが、環境に合わせてください。
書き換えた時点で設定反映。すぐ使うことができます。

## 使用方法

![mp.gif](https://qiita-image-store.s3.amazonaws.com/0/65983/7da65a22-22c8-4b0c-9ff5-2c581e6a4c52.gif)

貼り付ける時、普通は「貼り付け」を選択しますが、その代わりに「Merge and Paste」を選択します。
慣れれば、ショートカット<kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>v</kbd>も使えます。

merge-n-paste
https://marketplace.visualstudio.com/items?itemName=rawseq.merge-n-paste
タイムゾーンの設定 - Ubuntu Server 18.04 LTS

#はじめに
デフォルトは、UTCになっているのでJSTに変更する。

#コマンド
タイムゾーンの確認

```text:
$ timedatectl status
```

タイムゾーン一覧を確認

```text:
$ timedatectl list-timezones
```

タイムゾーンの設定

```text:
$ sudo timedatectl set-timezone Asia/Tokyo
```

#リファレンス
- [http://manpages.ubuntu.com - timedatectl](http://manpages.ubuntu.com/manpages/bionic/en/man1/timedatectl.1.html)
Docker MachineとVMware FusionでmacosにDocker環境を構築する

Docker for Macだと、ディスクアクセスが実環境に比べて10倍程度も遅いため、VMWare fusionにDocker Machineを使ってDockerホストを構築する。

## Docker machineのインストール

```
brew install docker-machine
```

## VMWare fusionに仮想マシンを作成

```bash
docker-machine create --driver vmwarefusion vm
```

## Docker接続用の環境変数の設定

```
eval $(docker-machine env vm)
```

これは `.bashrc`や、 `.zshrc` などに書いておいてもよい。

## Dockerコマンドで接続試験

```
docker run hello-world
```

## TLSエラーが出たときの対処

下記の様なエラーが出たときは、

```
Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "172.16.3.69:369": x509: certificate signed by unknown authority
You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'.
Be advised that this will trigger a Docker daemon restart which might stop running containers.
```

下記コマンドで証明書を再生成する。

```
docker-machine regenerate-certs vm
```
iOSDC Japan 初参加しました。発表しました。スタッフやりました。


![_DSC2822.jpg](https://qiita-image-store.s3.amazonaws.com/0/219965/5d4c0773-04f3-f700-7be0-f91122a30ffa.jpeg)


ちょっとiOSDC前の話も入っていますが、
ここ最近感じたことも含めて感想書いてみました。

# やさしい

会の最中や終わった後の色々な方の感想などを見ていると、
「やさしい」というキーワードをよく見るなと思いました。


「やさしい」には色々な意味がありますが、私は３つのやさしいを感じました。


## 参加しやすいという意味での易しさ

私のような普段は1人で開発し、知り合いも少ないような人でも、
たくさんのスポンサーブースやアンカンファレンスなど
発表以外でも楽しめる仕組みがたくさん用意されていました。

## 人としての温かさという意味での優しさ

発表時は聞いていただいている方のリアクションがたくさんあり、
発表しやすい雰囲気づくりを会場全体でしているというように感じられたり、
全体的にみんなで楽しもうという空気が流れていると思いました。

## 学ぶ場所を見つけやすいという意味での易しさ
 
ただの馴れ合いではなく、
議論をしたり、間違っているところは指摘し合うなど
学ぶ、成長できる環境で溢れていると思いました。


# 深く関わることで良い循環が得られる

## 勉強会怖い

最近まで勉強会に参加するのが正直怖かったです。

人見知りで内気な私は、
初対面の人に話しかける勇気がなく、
話せたとしても次会った時に声をかけていいものかどうか悩み
結局勇気が出ず、参加するたびに自己嫌悪感が強くなる悪循環。


とはいうものの、
開発は1人で行い、周りにswiftを知っている人はほぼゼロという状況で
わからないことはとにかくネットで情報を集めて検証していくというこ
を繰り返していく日々の中で

「本当にこれで良いのだろうか？」

「もっと効率的な方法や書き方があるのでは？」

といった不安は常に持っています。


この不安を消すためにも
人と話すこと、人の経験を聞くことで
新しい知見を得るためにも勉強会に参加し続けていました。


## 初めての発表

そんな中で今年の６月に
たまたまご縁があって初めて勉強会で発表する機会がありました。

発表をすることで一番得られたことは、
**知り合いができた**
ということです。


少なくとも認知してくれる人が増えたため、
まず挨拶ができるようになりました。


発表することが深く関わるということではないのかもしれませんが、
積極的に会に参加することで
話せる相手が徐々に増えていったと私は思っています。


また、発表をしてみて感じたことですが、
ブログなどにまとめるよりも発表する方が
頭の整理に良いと個人的には思っています。


全然できているとは思いませんが、
発表する際には限られた時間で
どうやって伝えるかを考える必要に迫られているため、
それが自然とより簡潔に頭の中で整理できることに繋がると感じています。


発表することで知り合いが増え、
それと反対に勉強会への恐怖心が減りました。
とても良い循環だなと思いました。


## iOSDC2018のcfpに応募

そんなことを思い始めているときに、
iOSDC2018のcfpの募集を見つけました。

応募しようとすぐに思いました。


発表資料: https://speakerdeck.com/shiz/iosdc2018


テーマで選んだアクセシビリティは、
以前フロントエンドエンジニアの方の話を聞いていた際に
「今アクセシビリティ対応するのは当然」とおっしゃっており、
「確かにそうだよな」と思ったのと同時に
「モバイルアプリでアクセシビリティの話ってほとんど聞かないな」と
思って調べていたことがきっかけでした。


アクセシビリティって正直そんなに注目もされていないし、
確率は低いのかもしれないけど、
興味持ってもらえたらいいなと思ってこれにしました。


そうしたらLTルーキーズ枠で採択していただきました。


## どうせならもっと深く

せっかく参加が決まったので全日参加するために夏休みを取りました。

そのときたまたま見つけたスタッフの募集を見つけ、
もっと深く関わることで知り合いが増えるんじゃないかと思い、
勢いそのままスタッフの応募もして、幸いにも参加させて頂けました。


# 参加中に得たもの

## 多岐に渡っていて深くて濃い内容の素晴らしい発表

とにかくどれも内容が濃く、わくわくしながら聞いていました。

自分の知らない世界のことを知れたり、
日常の開発で役に立つことがたくさん学べました。

まだまだ消化しきれていないので、これからたくさん復習します。

## 知り合いが増える

一緒にスタッフとして参加したみなさまに加えて、
懇親会などでも知らない人とを話しをすることができました。
(パックマンルールのおかげですね)


## ずっとそわそわするw

スタッフとしてTrackBで進行をしていたのですが、
時間管理が大変だなと感じました。

QAで残り１分ぐらいのときに、
次の質問に行くべきかAskTheSpeakerで続きをしてもらうべきか
悩むことが多かったような気がします。
(15分セッションの間は特に時間がなかったりしていたので)

めったに経験できない体験でしたので、
すごいたくさんの学びを得られました。
またどこかで活かせる機会があれば活用できるようにしたいなと思います。


# 最後に

**ひたすら楽しかった**

この一言に尽きます。

来年はさらに多くのものを得られるように
準備して参加したいと思います。

参加者のみなさま、発表者のみなさま、スタッフのみなさま、
関わっていただいたみなさま、本当にありがとうございました！

これからもよろしくお願いします！


以上で、私のiOSDC Japan2018の締めくくりとさせて頂きます:grinning:
Git:マージ済みのトピックブランチを一括削除するコマンド



```shell
git branch --merged | grep topic- | xargs git branch -d
```

* `git branch --merged` … マージされたブランチ一覧を出力してくれる
* `grep topic-` … ブランチ名に `topic-` が含まれるものに絞り込んでくれる
* `xargs git branch -d` … それらを削除する
git pullのとき常にpruneするための設定

`git pull` の `--prune` オプションはリモートリポジトリで消されたブランチをローカルリポジトリに反映するオプションだが、毎回 `--prune` オプションを指定するのが面倒なことがある。`--prune`オプションを省略できる方法を紹介する。

## 全体的に`--prune`を有効にする方法

特定のリポジトリに限らず、常に `--prune` オプションを効かせたい場合、下記のコマンドで `.gitconfig` に設定を書き込む:

```
git config --global fetch.prune true
```

下記の設定が書き込まれる:

```php:~/.gitconfig
[fetch]
       prune = true
```

## 特定のリポジトリだけ `--prune` を有効にする方法

特定のリポジトリについて `--prune` オプションを効かせたいときは、特定のリポジトリにて下記コマンドを実行する。 `.git/config` に設定が書き込まれる。

```
git config remote.origin.prune true
```

下記の設定が書き込まれる:

```php:.git/config
[remote "origin"]
	prune = true
```
S3 Select でparquet ファイルを開く(parquet-tools入れるより楽かも)

# S3 Select が parquetフォーマットに対応しました。

## Parquetファイルはこれ

"[Glueの使い方的な①(GUIでジョブ実行)](https://qiita.com/pioho07/items/c9ce1d0677777f974ffe)"(以後①とだけ書きます)で出力したparquetファイルを使います。(とあるparquetファイルと思ってください。)

<img width="1148" alt="スクリーンショット 0030-09-07 8.37.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/0c4d7e64-7e80-c7d1-c2f0-54b6922bf3cd.png">

## parquetを開く

オブジェクトにチェックを入れて、"アクション"->"S3 Select"をクリック

<img width="726" alt="スクリーンショット 0030-09-07 8.38.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/b035556b-790d-01c5-1698-205cc4f3fe37.png">

"Parquet"にチェックを入れ、[ファイルプレビュー]をクリック、表示されました。簡単です。
SQLを書きたい時は画面の右下の[次へ]をクリック

<img width="1186" alt="スクリーンショット 0030-09-07 8.40.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/00a9cf9d-d559-6d02-6a31-5e9b4273c148.png">

## SQLを書く

SQL エディタにSQL書いて[SQLの実行]をクリック

```
select * from s3object s where s.deviceid = 'iphone'
```

<img width="1204" alt="スクリーンショット 0030-09-07 8.45.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/fda36ed7-aeb0-7eea-9111-3ac41b64449e.png">

サンプルもあります

<img width="1213" alt="スクリーンショット 0030-09-07 8.46.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/5cdc11d5-f4cd-5805-dccd-33b8905de0a6.png">

ちょっとした確認にはよさそうです。

## こちらも是非

Glueの使い方まとめ
https://qiita.com/pioho07/items/32f76a16cbf49f9f712f
ISTQB Certified Tester Advanced Level Syllabus Test Automation Engineer No.2

# 趣旨

ここでは、ISTQBにて提供されている"Test Automation Engineer" Syllabusを自分なりに解釈（そのままの翻訳もあり）したものである
そのため、実際の試験と相違がある場合もありますのでご注意
原本↓
https://www.istqb.org/downloads/category/48-advanced-level-test-automation-engineer-documents.html



# 2. Preparing for Test Automation

## 2.1 SUT Factors Influencing Test Automation

テスト自動化に影響する要素

- SUT interfaces : システムを動かすとき、UIやI/Fなど様々なlayerを経由して行われる。そのlayerのlevelに合わせたテスト自動化が選択される
- Third party software : システムは3rd partyを含むときがある。それもテストが求められる
- Levels of intrusion :  テストlevelに応じてテスト自動化アプローチは異なる
- Different SUT architectures : システムのarchitecture（例えば開発言語）次第でテスト自動化が変わってくる
- Size and complexity of the SUT : システムの複雑さでテスト自動化の構成を考える
- SUT not available, but can start :  テストscriptingはSUTが出来上がらなくても、設計があれば始めることは可能。

コードのwhite-boxテストするときはUnit Test、UIのWhite-boxテストするときは、E2E Testといった開発レイヤーにあったツールを選ぶということでしょう。

## 2.2 Tool Evaluation and Selection

TAE(Test Automation Engineer)は以下を留意して自動化ツールの評価・選定を行う

- 組織の成熟度とテストツールの導入機会を評価する
- テストツールの目的を評価する
- 適切なツールの情報収集
- ツールを分析
- コストメリットを分析
- ツールの選定
- システムの互換性を確認する

個人的には、メンバーのスキルセット（プログラマーのスキル有無）、コードの保守性（可視性、改修容易性）、ツールの保守性（バージョンアップのサポート）等に重点を置いた。
iOSやAndroidではOSのversion upが定期的に発生する。これに追従してくれるツールを事前に確認するとよい。


ツールでよく遭遇する課題

- ツールのI/F変更で連携が失敗する
- 依存ソフトウェア(Java等)の更新により動かなくなる
- オブジェクトを識別しない（ツールが要件を満たさない）
- ツールの機能が多すぎて複雑
- ほかのシステムと依存があり動かなくなる
- 自動化の有無でシステムの挙動が異なる
- 自動化のためにソース変更が発生する
- テスト環境のリソース（メモリ等）が不足する（本番と異なる）
- システムの更新でこれまでの環境が使えなくなる
- セキュリティの制約でテスト環境にアクセスできない
- 環境によってテストが動かない

モバイルのアプリは独自SDKをインストールしないと自動化が動かないといった経験があった。アプリのオブジェクト抽出が難しいのでしょう

## 2.3 Design for Testability and Automation

自動化に限ったことではないが、システムに安定したテスト自動化が行われるようにteatabilityを持つ必要がある

- Observability: システムの状態を正しく確認できるようなI/Fを持つ。機械が判断できる値、API等を提供しないと、自動化は合否判定できない
- Control(ability): システム操作するために適切なI/Fを用意する（上位層ではスイッチ等、中間層ではTCP/IP等のプロトコル）
- Clearly defined architecture: 上記I/Fがわかりやすく、判別しやすいものとする

テスト自動化のscriptは対象オブジェクトを一意に識別し、操作後それが正しいかを機械的に判断することができる判断軸があることが求められる。テスト結果が正しいかを判断するのが機械なので、機械が判断できるものをシステムが提供する必要がある。

上記をみたす例

- スタブなどの提供
- 故障モードを提供する
- 代替I/Fでテストが可能
- 状態遷移テストはカスタマイズしたI/Fを利用して再現する


testabilityを考慮することは、自動化だけでなく、マニュアルテストにも当然効果がある。
vs2010でmanaged directx その15

#概要
c#で、3Dやりたかった。
シェーダー書いてみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/ae90afb8-389d-609d-9e47-5e911dddfe9b.png)


#サンプルコード


```
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In)
{
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float4 PSmain(VS_OUT In): COLOR
{
	float4 color = float4(1.0, 1.0, 1.0, 1.0);
	float2 coord = In.coord;
	float2 center = float2(0.0, 0.0);
	float dist = distance(coord, center);
	if (dist < 0.5) color = float4(1.0, 1.0, 1.0, 1.0);
	else color = In.color;
	return color;
}

technique MyTechnique
{
	pass MyPass
	{
		VertexShader = compile vs_2_0 VSmain();
		PixelShader = compile ps_2_0 PSmain();
	}
}


```


以上。
AmazonDashButton＋Raspberry PiのHack メモ

100番煎じですが、ラズパイ上での「Dashボタン押し下げ検出」に成功したので備忘録として環境をメモします

・Raspberry Pi Model3B+
・Ubuntu Mate（当時の安定版）
・YARN（バージョン管理等）
・Node.js
・node-dash-buttonモジュール

これらを導入後、適当な位置に（私はnode-dash-button直下
usr/node_modules/node-dash-button/app.js
に置きました）
app.jsを作成します。

内容は以下の「node-dash-button」公式ReadMeをパクりました。
https://github.com/hortinstein/node-dash-button/blob/master/README.md

>//warning this may trigger multiple times for one press
//...usually triggers twice based on testing for each press
var dash_button = require('node-dash-button');
var dash = dash_button("xx:xx:xx:xx:xx:xx（ここにDashButtonのMACアドレス※を入れます）", null, null, 'all'); //address from step above
dash.on("detected", function (){
	console.log("omg found");
});

※MACアドレス取得は↓を使いました
https://qiita.com/1060ki/items/aaa0bc388eeb261ac682

そして実行します。
https://qiita.com/Sugima/items/39caa4f08ca022514a46
>$ sudo node app.js

これで検出できました。
Linuxのディストリビューション等、環境により動いたり動かなかったりするのでうまくいくものを使いましょう。
私の場合は当初、 Node.jsの実行にあたって「あのコンパイラが足りない、あのモジュールが動かない」等々エラーが多発していたのですが、
npm+Node.js+Dasher→YARN+Node.js+node-dash-buttonに変えたら嘘のように動きました。うそやろ。
あと、今回使った各ソフト・モジュールはそれぞれのVer同士の競合・相性がきびしいです。特に（今回使わなかった）Dasherは（開発が停止していることもあって）Node.jsが最新版だと動かなかったりと、苦労しました。
基本的にはYARNとnode-dash-buttonは最新版、Node.jsは安定版を使えば問題ないとは思うのですが。

##参考にしたページ
[Raspberry PiにUbuntu MATEをインストール + リモート接続](https://qiita.com/sasayabaku/items/ff96f700d2b65fdf085e)
コマンドラインでmicro SDにUbuntu Mateをインストールする方法です。
ただ、結局は[SD Card Formatter](https://www.sdcard.org/jp/downloads/formatter_4/) と [Etcher](https://www.gigafree.net/system/os/Etcher.html) を使いました。便利だった。
[Amazon Dash Buttonを(正しくない方向で)使ってみた](https://qiita.com/takustaqu/items/8539b33780c9675c8657)
勉強になります。
[node-dash-buttonの公式ドキュメント](https://github.com/hortinstein/node-dash-button/blob/master/README.md)
結局これが一番わかりやすかった。
[2017-12-14
Raspberry PiでAmazon Dash Buttonの入力を受け取る](http://www.taneyats.com/entry/raspi-dash-button#%E5%BF%9C%E7%94%A8)
YARNではなくnpmの場合はこちら。
RapberryPi (Raspbian Stretch LITE)のセットアップ

Raspbian Stretch LITEをRaspberryPi 3にセットアップしたので紹介する。Raspbian Stretch LITEは、通常利用されるRASPBIAN STRETCH WITH DESKTOPと異なり、標準状態でコンソール画面のみが使用できる。サーバー用途や機械制御などのGUIが不要な用途では便利だ。設定方法がGUIを利用したものとは異なる部分もあるので、まとめる。

#RaspberryPIの環境
インストールした環境を示す。
##画面とキーボード
HDMIでディスプレイ、USBでUSキーボードを接続した。

##ネットワーク環境

RaspberryPIを有線Ethernetを使い次のように接続した。

RaspberryPI==有線==ルータ==(インターネット)

最終的にRaspberryPIをIPアドレスに固定し、次のネットワーク設定を行う。

|IPアドレス|ルータ|DNS|
|---|---|---|
|192.168.0.19/24|192.168.0.1|1.1.1.1 (cloudflareのパブリックDNS)|

#ダウンロード

次のURLからRaspbian Stretch LITEのイメージをダウンロードする。
https://downloads.raspberrypi.org/raspbian_lite_latest
(リンク元ページ https://www.raspberrypi.org/downloads/raspbian/ )

#SDカード作成
Windowsを利用し、SDカード作成を行う。
##フォーマット
次のサイトからSD card formatterをダウンロード&セットアップする。これを使ってSDカードをフォーマットする。
https://www.sdcard.org/jp/downloads/formatter_4/

##イメージ書き込み
次のサイトからwin32DiskImagerをダウンロード&セットアップする。これを使ってダウンロードしたRaspbian Stretch LITEのイメージをSDカードに書き込む。

https://sourceforge.net/projects/win32diskimager/

#起動とログイン
SDカードをRaspberryPIにセットし電源を接続すると、次の認証情報でキーボードとディスプレイを使ってログインできる。

|項目|値|
|---|---|
|ユーザー名|pi|
|パスワード|raspberry|

#基本設定
各種基本設定を順番に記述する。

##キーボード
RaspberryPiではrasp-configという設定変更コマンドがあるので、これを利用する(方法1)。また方法2に、Debian一般の方法を紹介する。いずれのコマンドもsshでは利用できない。

###方法1(rasp-configを使う)
```sudo rasp-config ``````

4 Localisation Options
I3 Change Keyboard Layout

実際には、おそらく方法2を呼び出している。

###方法2(rasp-configを使わない)

```sudo dpkg-reconfigure keyboard-configuration```

generic104->other->で日本語キーボードが選択できる。

##ネットワーク設定 
この作業はDHCPで運用する場合不要である。catコマンドを使った上書き例を示すが、/etc/dhcpcd.confにコメントアウトで記載されているので、nanoコマンドで修正しても良い。ipアドレスなどの値は環境に合わせて欲しい。

```bash:nanoコマンドによる編集
sudo nano /etc/dhcpcd.conf
```

```bash:catコマンドによる上書き例
sudo cat > /etc/dhcpcd.conf<< EOF
interface eth0
static ip_address=192.168.0.19/24
static routers=192.168.0.1
static domain_name_servers=1.1.1.1
EOF
```

##仮日時設定
あとでntpで正確な時刻を取得する設定を行うが、この時点では日時が狂っている場合がある。dateコマンドで現在時刻を確認する。もし時刻がずれていた場合は各種パッケージのインストールがうまくいかない可能性があるので、おおよその時刻を合わせる。ここでは日本時間の2018-09-06 17:19にしている。

```sudo  date --date='TZ="Asia/Tokyo" 2018-09-06 17:19' ```


##ここまでの確認
設定変更後、リブートする。
```sudo reboot```


ログイン後、次のコマンドで上記設定が反映されていることを確認する。

```bash:
date                          #時刻設定の確認
ip a                          #ipアドレスの確認   
ping www.google.com           #外部へ接続されていることの確認
```

##ユーザーpiのパスワード変更

次のコマンドでユーザーpiのパスワードを変更する。

``` passwd ```

##その他のインストール
次の基本的なソフトウェアを一度に入れる。

|パッケージ|摘要|
|---|---|
|vim|テキストエディタ|
|ssh|sshサーバー・クライアント|

``` bash::
sudo apt update 
sudo apt install vim ssh
sudo service ssh enable #sshの自動起動
```
sshの設定については割愛するが、グローバルIPを設定する場合は注意を要する。

ntpは/etc/ntp.confではなく、 /etc/systemd/timesyncd.conf で行われている。ntpを使いたくない場合は次のコマンドを実行する

``` bash::
sudo systemctl disable systemd-timesyncd.service
```

##タイムゾーン設定
次のコマンドを実行し、asia⇒tokyoと選択する。

``` sudo dpkg-reconfigure tzdata ```

#おわり
基本的なものがインストールされたので、あとはsshを使いネットワーク経由で操作できる。

---
2018/08/10 1200 bash:catコマンドによる上書き例に>が抜けていたので修正 
2018/08/14 1330 win32DiskImagerのurlを修正
2019/03/13 keyboard設定方法をraspi-configに変更
2019/03/31 ntpに関する話題を追記
RasPiにssh接続してshutdownしたい

RasPiで作業をしているとき、他のRasPiをshutdownしたいときありますよね。
ないですか？ありますよね！！！

RasPi にパスワードなしでssh接続したいときは、

RasPi にパスワードなしでssh接続
https://qiita.com/hinemoss/items/2bdc2293c84bc1001214

で接続できるようになりました。

sshで接続して、shutdownをたたけばshutdownするのは分かります。
でも、シェルスクリプトで自動でshutdownしたいとき、そういう訳にはいきません。
てか、そんな時ある？あるんです！！！

とにかく

```
ssh pi@172.16.1.101 sudo shutdown -h now
```

とすれば、1行でパスワードの入力も不要でshutdownできます。

複数台、まとめてshutdownしたいときはシェルスクリプトで

```
ssh pi@172.16.1.101 sudo shutdown -h now
ssh pi@172.16.1.102 sudo shutdown -h now
ssh pi@172.16.1.103 sudo shutdown -h now
ssh pi@172.16.1.104 sudo shutdown -h now
```

としておけば、順次shutdownしてくれます。
macOS で charlock_holmes がインストールできないときの解決法

macOS で Rails アプリケーションの環境構築をするために `bundle install` をしたら、charlock_holmes のインストールでエラーが出ました。

```
An error occurred while installing charlock_holmes (0.7.5), and Bundler cannot continue.
Make sure that `gem install charlock_holmes -v '0.7.5' --source 'https://rubygems.org/'` succeeds before bundling.
```

そんなときは以下のコマンドを実行します。

```bash
$ brew install icu4c cmake
# 'x.x.x' をインストールしたいバージョンに置き換える
$ gem install charlock_holmes -v 'x.x.x' -- --with-cppflags=-DU_USING_ICU_NAMESPACE=1 --with-cxxflags=-std=c++11
```

`x.x.x` の箇所は、インストールしたい charlock_holmes のバージョンを指定します。たとえば上記のエラーでは `0.7.5` をインストールしようとしているので、その場合は `x.x.x` の箇所を `0.7.5` に置き換えます。

これで charlock_holmes がインストールできるようになりました。

# 参考
- [Unable to install version 0.7.3 on Mac OS Sierra - issuecomment-393214583](https://github.com/brianmario/charlock_holmes/issues/117#issuecomment-393214583)
RasPiにパスワードなしでssh接続

#パスワードなしでssh接続したい！

よくあるネタなのですが、備忘録として

##1.クライアント側でキーを作成
3回ほど、入力を求められますが、入力せずEnterで進めます。
やんごとなき事情で、一部、加工しています。

```
pi@raspberry:~ $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pi/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/pi/.ssh/id_rsa.
Your public key has been saved in /home/pi/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx pi@raspberry
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+-----------------+
pi@raspberry:~ $
```

##2.クライアント側でキーの確認
```
pi@raspberry00:~ $ cd .ssh
pi@raspberry00:~/.ssh $ ls -al
drwxr-xr-x 2 pi pi 4096 Sep  6 02:41 .
drwxr-xr-x 8 pi pi 4096 Sep  4 12:55 ..
-rw------- 1 pi pi 1679 Sep  6 02:41 id_rsa
-rw-r--r-- 1 pi pi  397 Sep  6 02:41 id_rsa.pub
```
id_rsa.pubができていればOK

##3.サーバー側にキーを配置します
サーバー側での準備
もし、ディレクトリ/home/pi/.sshがなければ作成

```
pi@raspberry:~ $ mkdir .ssh
pi@raspberry:~ $ chmod 700 .ssh
pi@raspberry:~ $ cd .ssh
pi@raspberry:~ $ touch authorized_keys
pi@raspberry:~ $ chmod 600 authorized_keys
```
で、authorized_keysを開いてクライアント側で作成したキーid_rsa.pubの内容を入力します（ウソ）
でも良いのですが、間違えるので切り貼りします（面倒）
なのでコピーします。

クライアント側のIPアドレスが、172.16.1.100
サーバー側のIPアドレスが、172.16.1.101
とします。

ちなみに、サーバー側にはauthorized_keysがないか、空の場合を想定しています。既にサーバー側のauthorized_keysに有効なキーの情報が記述されている場合は、次の方法では上書きされるので登録済の情報はなくなります。サーバー側に違うファイル名でコピーして混ぜ混ぜしてください。

```
pi@raspberry:~ $ scp pi@172.17.1.100:/home/pi/.ssh/id_rsa.pub pi@172.17.1.101:/home/pi/.ssh/authorized_keys
```
ついでにクライアント側にもコピーしておくと、ddで複製したときにコピーの手間が省けてちょっとらくちんです。

##4.セキュリティ向上
必要に応じて、sshのポート番号(デフォルトでは22)、rootでの接続拒否などの設定をしたい場合は、/etc/ssh/sshd_configを適宜編集してください。


##参考にさせていただいたのはコチラ
俺的備忘録 〜なんかいろいろ〜
https://orebibou.com/2015/01/%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%81%8B%E3%82%89%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E5%85%A5%E5%8A%9B%E7%84%A1%E3%81%97%E3%81%A7ssh%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B3/