OmniAICreator/Qiita-1.07M huggingface dataset:
Windows7 32bitのPowerShellでdein.vimとckw-modを使う

# 目次
* [vim-KaoriYa](https://www.kaoriya.net/software/vim/)
* [dein.vim](https://github.com/Shougo/dein.vim)
* [ckw-mod](http://ckw-mod.github.io/)

## vim-KaoriYa
 - ダウンロードして解凍したフォルダにパスを通す
https://www.kaoriya.net/software/vim/

 - "vi"と打っても起動できるようにvi.batを作成して同じフォルダに入れる

```vi.bat
vim %*
```

## dein.vim
- ホームディレクトリに.vimrcを作成、'~/.vim/rc/' に'dein.toml', 'dein_lazy.toml'を作成

- runtimepathは絶対パスにしないといけなかった、相対パスでは「未知の関数です dein#begin」などと出る
- "syntax on"はdein.vimの設定の後でないと反映されない

```~/.vimrc
set tabstop=4
set shiftwidth=4
set hlsearch
set ignorecase
set smartcase
set smartindent
set expandtab

nmap <Esc><Esc> :nohlsearch<CR><Esc>

let s:dein_dir = expand('~/.cache/dein')
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

"set runtimepath+=~/.vim/dein/repos/github.com/Shougo/dein.vim  " これではだめだったので
set runtimepath+=C:\Users\USERNAME\.cache\dein\repos\github.com\Shougo\dein.vim  " 絶対パスで指定しました

if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)

  let g:rc_dir = expand('~/.vim/rc')
  let s:toml = g:rc_dir . '/dein.toml'
  let s:lazy_toml = g:rc_dir . '/dein_lazy.toml'

  call dein#load_toml(s:toml, {'lazy': 0})
  call dein#load_toml(s:lazy_toml, {'lazy': 1})

  call dein#end()
  call dein#save_state()

  if dein#check_install()
    call dein#install()
  endif
endif

syntax on
```

```dein_lazy.toml
[[plugins]]
repo = 'cespare/vim-toml'
on_ft = 'toml'


# python
[[plugins]]
repo = 'davidhalter/jedi-vim'
on_ft = 'python'
on_i = 1
hook_add = '''
  autocmd FileType python setlocal completeopt-=preview
'''

[[plugins]]
repo = 'hynek/vim-python-pep8-indent'
on_ft = 'python'
on_i = 1

[[plugins]]
repo = 'andviro/flake8-vim'
on_ft = 'python'
on_i = 1

[[plugins]]
repo = 'scrooloose/syntastic'
on_ft = 'python'
hook_add = '''
  let g:syntastic_python_checkers = ['pyflakes', 'pep8']
'''

[[plugins]]
repo = 'tell-k/vim-autopep8'
on_ft = 'python'
```

## ckw-mod
 - ダウンロードして解凍、”ckw-cfg”ファイルで設定
http://ckw-mod.github.io/
 -  参考にさせていただきました：http://softwaretest.jp/labo/tech/labo-267/

設定は好みだと思いますが...
- "Ckw*transp"の値を小さくすると透過していく
- "!"がコメントアウト
- powershell.exeにパスが通ってない場合は絶対パスで書く

あとは毎回ckw.exeを起動するだけです

```ckw.cfg
Ckw*title: ckw[cmd]
Ckw*exec:  c:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
Ckw*chdir: c:\Users\USERNAME

Ckw*scrollHide:  no
Ckw*scrollRight: yes
Ckw*internalBorder: 1
Ckw*lineSpace: 0
Ckw*topmost: no
Ckw*transp: 200

Ckw*font: MeiryoKe_Console
Ckw*fontSize: 12

Ckw*geometry:  100x38+0+0
Ckw*saveLines: 10000
```
HaproxyでFTPをプロキシさせる方法

## 通信のながれ

Traffic -> Firewall -> Haproxy -> virtual machine(localIPのみ)

Haproxyはグローバルのvlanをきり、仮想マシンはローカルのみのvlanをきっている
これにより、仮想マシンには、踏み台経由からかWeb経由からのアクセスしかできなくなる。
※踏み台経由だと接続元制限をしているため、セキュリティを担保している。

## 経緯

仮想マシンにFTPでファイルをアップロードしたいとの要望があり、FTP通信は必ずHaproxy経由で仮想マシンにアクセスする必要があるため、
検証した。

## 環境

・Haproxy
 CentOS 7
 Haproxy version 1.5.4

・virtual machine
  CentOS 6.7
  vsftpd version 2.2.2

## 設定

### Haproxy

```
frontend web01-ftp
 mode tcp
 bind [HaproxyサーバのIP]:50021
 default_backend web01-ftp

frontend web01-ftpdata
 mode tcp
 bind [HaproxyサーバのIP]:50022-50029
 default_backend web01-ftpdata

backend web01-ftp
  server web01 [FTPアップロード対象サーバ] check port 50021 inter 10s rise 1 fall 2
backend web01-ftpdata
  server web01 [FTPアップロード対象サーバ] check port 50021 inter 10s rise 1 fall 2
```

### FTPサーバ（vsftpdの場合）
以下の設定を追加

```
listen_port=50021
pasv_address=［haproxyサーバのIP］
pasv_min_port=50022
pasv_max_port=50029
pasv_enable=YES
port_enable=YES
port_promiscuous=NO
```

この環境は1本足構成のため、全ての通信はFirewallを通り、制御している。
そのため、この作業のあと、Firewallで通信許可をして、完了。
L7の設定とL4の設定を共存させてみたが、デフォルト設定がL7だとうまくいかなかった。。
【android】apkのuploadを自動化

# play storeへのapkのuploadを自動化する

[gradle-play-publisher](https://github.com/Triple-T/gradle-play-publisher#google-play-service-account)というライブラリを利用して、play storeに自動でapkをuploadする方法を紹介します

# 前準備

## サービスアカウントの作成

* DeveloperConsoleのAPIアクセスにアクセス

https://play.google.com/apps/publish/#ApiAccessPlace
にアクセスをして一番下のサービスアカウント作成を押します

![スクリーンショット 2016-10-24 20.48.03.jpg](https://qiita-image-store.s3.amazonaws.com/0/22527/f8fdf1f8-db35-4737-e336-ee8535179c3e.jpeg)

* サービスアカウントを作成

![スクリーンショット 2016-10-24 20.49.53.png](https://qiita-image-store.s3.amazonaws.com/0/22527/e073d5a5-4ea5-9b31-6f12-e27eb0776dde.png)

* Google API コンソールを押してGoogle APIsに移動します

![スクリーンショット 2016-10-24 20.50.29.png](https://qiita-image-store.s3.amazonaws.com/0/22527/2326279d-6edc-716d-2e42-12817bbd42ad.png)

* 青で表示されているサービスアカウントの作成を押してアカウントを作ります

![スクリーンショット 2016-10-24 20.52.38.jpg](https://qiita-image-store.s3.amazonaws.com/0/22527/f3e2ec6a-fef2-a426-7780-4a23129bcc6b.jpeg)

役割をオーナーにして秘密鍵はP12を指定しましょう。作成したら作成されるP12ファイルは後ほど使用するので適切な場所に保管して下さい。

* 作成後最初の画面に戻ってくると、先程作成したアカウントが追加されています

次にアクセスを許可を押します

![スクリーンショット 2016-10-24 21.01.00.jpg](https://qiita-image-store.s3.amazonaws.com/0/22527/acdf6a9b-baa4-fbe3-8c79-15362c0138e0.jpeg)

* ここで適切な権限を設定して下さい。ここに表示されているメールアドレスは後ほど使います。

![スクリーンショット 2016-10-24 21.05.30.jpg](https://qiita-image-store.s3.amazonaws.com/0/22527/2bcbd7ce-0e10-125f-0080-998a6d534b6f.jpeg)

# Upload

## grade

* rootディレクトリのbuild.gradleに追記します(執筆時点は1.1.5なので各自最新バージョンを取得して下さい)

```
buildscript {

    repositories {
        mavenCentral()
    }

    dependencies {
        // ...
        classpath 'com.github.triplet.gradle:play-publisher:1.1.5'
    }
}
```

* applicationディレクトリのbuild.gradleに追記します  
`serviceAccountEmail`に先程作成したアカウントのmail addressと`pk12File`に作成したp12ファイルのpathを追記します。

```
apply plugin: 'com.github.triplet.play'

android {
    play {
        track = 'alpha'
        serviceAccountEmail = 'your email address'
        pk12File = file('your p12 path')
    }
}
```

ここでは
* `uploadImages` で画像
* `track = 'production'`, `userFraction = 0.2` で20%リリース  
等の細かな指定が可能です。ここは各自ライブラリのドキュメントを見て下さい。

## tasks

ここまで設定できたら
`./gradlew tasks`を実行するとpublish用のtaskが追加されていると思います。

build variantの名前によりますが、apkが既にある状態ならば
`./gradlew publishProductRelease`でuploadされるかと思います
他にも作成されるのでドキュメントを見て下さい。

現在のプロジェクトではCircleCIを利用しているので、例としてmasterブランチにマージされたらapkを上げるとすると
circle.ymlにこのように追加すると自動でapkがstoreにuploadされます

```yaml

deployment:
  master:
    branch: master
    commands:
      - ./gradlew publishProductRelease
```
ruby-gmailでGmailの内容をslackに投稿する

# 概要
* ruby-gmailを使って、タイトルと本文をslackに投稿する
* 投稿したメールは既読にする

# slackのincoming webhook用URL取得
* ネットで調べて取得しちゃいましょう

# 端末用パスワードの取得
https://security.google.com/settings/security/apppasswords
こちらのサイトで取得する

# gem install
```bash
$ gem install ruby-mail
```

# コード
```ruby
# -*- coding:utf-8 -*-
require 'gmail'
require 'kconv'
require 'slack-notifier'

USERNAME = 'hoge@example.com' # gmailのアドレス
PASSWORD = '端末用パスワード'
WEBHOOK_URL = 'https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxx'

def get_body(mail)
  if !mail.text_part && !mail.html_part
    return mail.body.decoded.encode("UTF-8", mail.charset)
  elsif mail.text_part
    return mail.text_part.decoded
  elsif mail.html_part
    return mail.html_part.decoded
  end
end

def send_slack(webhook_url, subject, body)
  notifier = Slack::Notifier.new webhook_url, channel: '#slack-channel', username: 'bot-name'
  notifier.ping "#{subject}\n```\n#{body}```"
end

def get_gmail_and_post_slack(mail_box)
  gmail = Gmail.new(USERNAME, PASSWORD)

  # utf8にデコードしてます。最後のmarkで既読にさせてます 
  gmail.mailbox(mail_box).emails(:unread).each do |email|
    mail_subject = email.subject.toutf8
    mail_body = get_body(email)
    send_slack(WEBHOOK_URL, mail_subject, mail_body)
    email.mark(:read)
  end

  gmail.disconnect
end

get_gmail_and_post_slack('gmailのbox名')
```

# 問題点
* awsなどホスティングで動かしたかったが、Macじゃないと動かなかった。なぜだろう。
JavaFX で Snackbar を表示する

# 概要
JavaFX で [Snackbar](https://material.google.com/components/snackbars-toasts.html) を表示する方法について述べます。なお、標準に Snackbar に相当する機能は用意されていないので、OSS ライブラリを用いました。

## Snackbar とは
[Material design](https://material.google.com/) のコンポーネントの1つで、アクションに対する簡易的なフィードバックをユーザに提供します。下からせり出してメッセージを一定時間表示し、下に引っ込むというポップアップです。Android アプリでは Toast の代替として普及しはじめています。トースト小僧としてはちょっと悲しいです。

Snackbar というのは、私は Snickers や一本満足バーやカロリーメイトのようなものを想像していたのですが、どうも違うようで、[Wikipedia 英語版](https://en.wikipedia.org/wiki/Snack_bar) によると軽食堂だったり移動アイスクリーム店などを指すようです。

## [JFoenix](http://jfoenix.com/) とは
JavaFX で Material design を実装するためのライブラリです。Material design に対応した各種 Control が用意されています。JavaFX の標準にないコンポーネントもいくつか実装されており、 ```JFXSnackbar``` は Material design の Snackbar を JavaFX で実装したものです。

## 実行環境

| Java | SE 1.8.0_102
|:---|:---
| OS | Windows 10
| Eclipse | Mars 4.5.2
| JFoenix | 1.0.0

----

# 実装

## build.gradle
JFoenix は Maven Central で公開されています。

```groovy:dependencies
compile 'com.jfoenix:jfoenix:1.0.0'
```

## FXML

```xml:fxml
<?import com.jfoenix.controls.JFXSnackbar?>
......
<JFXSnackbar fx:id="snackbar" prefWidth="300" />
```

## Controller クラス
```registerSnackbarContainer``` を忘れると ```fireEvent``` 時に ```NullPointerException``` が出ます。Android の Snackbar だとこの辺は上手いことやってくれるのですが……まあ、仕方ないですね。

```java:imports
import com.jfoenix.controls.JFXSnackbar;
import com.jfoenix.controls.JFXSnackbar.SnackbarEvent;
```

```java:使う前にContainerを登録
snackbar.registerSnackbarContainer(root);
```

```java:ポップアップを表示
snackbar.fireEvent(new SnackbarEvent("Hello!"));
```

## (Optional) CSS
JFXSnackbar のデフォルトは透明背景に黒字という、一見 Snackbar に見えない色設定なので、下記の CSS を用意しました。黒背景に白字へと変化させます。

https://github.com/toastkidjp/menu_label/blob/qiita/src/main/resources/snackbar.css

```css:
.jfx-snackbar-content {
  -fx-background-color: #323232;
}
.jfx-snackbar-toast {
  -fx-text-fill: WHITE;
}
```

Java のコードで、scene オブジェクトの StyleSheets に対し CSS の URL を追加すると、適用されます。

```java:CSS適用
scene.getStylesheets()
     .add(getClass().getClassLoader().getResource("snackbar.css").toExternalForm());
```

## スクリーンショット
下記のように画面下部にポップアップが下からせり上がって表示され、一定時間が経過すると下に引っ込みます。

![screenshot2.png](https://qiita-image-store.s3.amazonaws.com/0/102004/bb632cc2-eed2-1b5d-e9d4-d253e243a248.png)

----
# まとめ
JavaFX で Snackbar を表示する方法について紹介致しました。ユーザに簡単なメッセージを通知したい場合に利用を検討してみてはいかがでしょうか。

----
# リンク
- [Snackbar(Material design)](https://material.google.com/components/snackbars-toasts.html)
- [JFoenix 公式サイト](http://jfoenix.com/)
- [JFoenix(GitHub Repository)](https://github.com/jfoenixadmin/JFoenix)
- [今回のサンプルコード全体](https://github.com/toastkidjp/menu_label)
- [JFoenix で Material design を JavaFX に適用する](http://qiita.com/y_q1m/items/15f316a8adf02dc0da0b)
deviseでnicknameカラムを追加して、nicknameの重複を禁止するアレを実装してみる

deviseって超便利ですよね。

今回は

deviseでnicknameカラムを追加した後

sign up時にnicknameの重複を禁止するようにしてみたいと思います。

すでにカラムが追加されているというところから始めたいと思います。


1.add_カラム名がdownになるまで

```ruby:ターミナル
rake db:rollback
```

downになっているかは

```ruby:ターミナル
rake db:migrate:status
```
で確認できます

downになっているのが確認できたら

2.

```ruby:db/mirgate/******_add_nickname_to_users.rb
class AddNicknameToUsers < ActiveRecord::Migration
  def change
    add_column :users, :nickname, :string
    add_index :users, :nickname, unique: true
  end
end
```

こんな感じに編集して

3.

```ruby:ターミナル
rake db:migrate
```

そしたら

4.

```ruby:models/user.rb
validates :nickname, presence: true, uniqueness: true
```

これを追記したらおしまい。

そしらた

```ruby:ターミナル
rails s
```
実際にsign upして同じnicknameで登録してみてください

多分
「あのね。その、nickname、登録されてんのよ。」

って感じで登録させてもらえないと思います。
そうなっていればOK

もし、このままやってみて、できなかったら
コメントつけてもらえたら確認して訂正します。
dmenuとwmctrlで、選択的インターフェースなウィンドウ切り替えを実現した

# 動機

今流行りの「選択的インターフェース」。

初めて`peco`を触った時は、いたく感動しました。

コマンドラインの履歴を`peco`で追いかけるなどすると、もうこれ無しではターミナル生活はできないというほど快適ですよね。

また、僕がメインで使っているEmacsには、`Helm`というプラグインがあり、現在開いているファイル、最近開いたファイルなどが一覧化できます。
最近は`helm-do-ag.el`無しではコーディングできません。

Vimでも同様のことをする`unite`というプラグインがあります。

このような、「一覧を表示」 => 「絞り込んで選択」 というインターフェースで、
ブラウザのタブ操作を実現できないかと考えたのが事の始まりでした。

# 試したこと

同様のことをするGoogle Chromeの拡張もあったのですが、いまいち使いづらかったので止めました。

そこで、Linuxのウィンドウ切替を丸ごと選択的にしてしまうという解決策を考えつきました。

# 成功イメージ

こんな感じで、ウィンドウタイトルを絞り込んで選択できます。

![Screenshot_2016-10-24_20-15-45.png](https://qiita-image-store.s3.amazonaws.com/0/103885/f289536d-8862-07d4-d34c-5e712715de68.png)

# やり方

事前に、`dmenu`と`wmctrl`をインストールします。Arch Linuxなら

```sh
sudo pacman -S dmenu wmctrl
```

です。

インストールしたら、下記のシェルスクリプトを、パスの通った場所に置きます。

```sh:select_window
#!/bin/bash

target=`wmctrl -l | cut -d ' ' -f 5- | dmenu -ib -l 30`

if [[ "$target" =~ ^$ ]]; then
   exit 1
else
    wmctrl -a "$target"
fi
```

`dmenu`の動きとしては、

- 標準入力を受け取る
- ユーザーに1行の絞り込みをさせる
- 選択した行を標準出力に出す

ということをしています。シンプルなので、使い方次第で色んなことができそうですね。

あとは、ターミナルなどで`select_window`コマンドを叩くだけです。

# オプション

`Alt-Tab`のように使うために、下記のようにキーボードショートカットを設定しています。

私は、`Openbox`というウィンドウマネージャーを使っていますので、その設定例です。

```xml:~/.config/openbox/rc.xml
  <keyboard>
    <keybind key="W-b">
      <action name="Execute">
        <command>select_window</command>
      </action>
    </keybind>
  </keyboard>
```

これにより、`Super + b`で`select_window`コマンドが発動するようになります。

`Super + Space`で発動するようにしたいな。できるのかな。


# 追記

これはこれで便利だけど、新興ブラウザ`vivaldi`なら、コマンド機能が標準で有り、タブの切り替えがHelmみたいにできる。乗り換えようかな。
BIND9で権限しっかり変更してるのに「permission denied」が消えなかった件

#前提
BIND9で権限関係をどんなに調整しても、slaveのサーバーでzoneファイルが反映されなかった時のメモ。

#今回ぶつかった壁
[CentOS 7 のBINDを設定する (プライマリ コンテンツサーバー)](https://www.ipentec.com/document/document.aspx?page=linux-centos-7-bind-configuration&culture=ja-jp)
上記サイトを参考にしながらmaster1台、slave2台のDNSサーバーを構築していたところ、masterで作成したzoneの情報がslaveの方に反映されなくて涙目に…。

#環境
| OS | DNS |
|:----------------:|:-----------------:|
| CentOS 7.2 | BIND 9.9.4-29 |

#やったこと

```bash
yum -y install bind bind-utils bind-chroot
```
して、サイトの通りに色々やったができない…。
もちろん53番ポートも開けてある。

##とりあえずログを見てみる

```bash:/var/log/messages
zone example.com/IN: transfer: could not set file modification time of 'slaves/example.com.zone': permission denied
```

ん？`permission denied`？
権限が足りてないってか…。

##ならNo permission deniedにしてやろう

```bash
chown -R named:named /var/named
chmod -R u+rwx /var/named
```

これで文句は無いだろう、と`named-chroot`を再起動してログを確認。

```bash:/var/log/messages
zone example.com/IN: transfer: could not set file modification time of 'slaves/example.com.zone': permission denied
```

うーん、寸分違わぬ感じで…。

##エラー内容の精査

[DNS(BIND9) 　　エラーと原因](http://www.geocities.jp/yasasikukaitou/DNS_error.html)
>セカンダリDNSサーバで出力されるエラーです。
セカンダリDNSサーバは、ゾーンのリフレッシュをするとゾーンファイルの更新を行います。（これによって最終更新時間が変わります）
しかし、namedサービスを起動しているユーザがそのゾーンファイルの更新を許可されていないためにゾーン転送に失敗してしまいます。
ゾーンファイルのあるディレクトリやゾーンファイルのパーミッションを、namedサービスを起動しているユーザが書き込めるように変更してください。

いや、書き込める様にしてるんだよなー、と思いつつ、ふと思い立って`getenforce`してみる。

```html
# getenforce
Enforcing
```

…うん、どう考えてもこれだ。
急いで環境構築したからSELINUX無効にし忘れてた…。


##確認してみる
取り敢えず無効にして確認してみる。

```html
# setenforce 0
```

```html
# getenforce
Permissive
```

```bash:/var/log/messages
zone example.com/IN: transferred serial 2016102001
```

ｷﾏｼﾀﾜｧ・゜ﾟ・:.｡..｡.:・゜(n'∀')ηﾟ・:.｡..｡.:・゜ﾟ・
Androidのandroid.support.v7.app.AppCompatActivity向けアクションバーの共有の実装方法  2016年10月版

Androidのアクションバーの共有ボタン、 ShareActionProviderまわりなのですが、
とにかく公式のドキュメントも、v4以前、v4の頃、v7の頃のいろんな時代のAPI
のサンプルが混ざっていて魔境すぎる感じになっています...。

いろいろ調べてみて2016年10月時点 Android Studio v2.2.2 現在で信用できる
ドキュメントは以下2点でした。

- [Action Views and Action Providers](https://developer.android.com/training/appbar/action-views.html)
- [JavaDoc:ShareActionProvider](https://developer.android.com/reference/android/support/v7/widget/ShareActionProvider.html)

これ以外のドキュメントは、ウソだったり古かったりと地獄。とにかくひどい。ひどすぎる！

最終的に以上のドキュメントに忠実に実装すると、

```res/menu/share_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:shareingsimpledata="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_share"
        android:title="@string/share"
        shareingsimpledata:showAsAction="ifRoom"
        shareingsimpledata:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
</menu>
```

```java/com/example/sharingsimpledata/MainActivity.java
package com.example.sharingsimpledata;

import android.content.Intent;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.ShareActionProvider;
import android.view.Menu;
import android.view.MenuItem;

  // ...

public class MainActivity extends AppCompatActivity {

  // ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.share_menu, menu);
        MenuItem shareItem = menu.findItem(R.id.action_share);
        ShareActionProvider myShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem);

        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, "Shared Massage Sample");
        shareIntent.setType("text/plain");
        myShareActionProvider.setShareIntent(shareIntent);

        return super.onCreateOptionsMenu(menu);
    }

  // ...

}
```

以上2つを追記するだけでOKです。これで共有ボタンのメニューが出てきて、共有の履歴も自動でボタンとして追加されます。

StackOverflowで検索すると出てくる `onOptionsItemSelected` をオーバーライドするとか、
`ShareActionProvider.setOnShareTargetSelectedListener()` を使って、 `OnShareTargetSelectedListener` を実装したインスタンスを設定するとかは全部昔のやり方です。 `doShare` メソッドなどを実装しなきゃいけないなんてこともないです。

教訓としては、基本的に JavaDoc のクラスコメントだけが一番信用でき、他のものは古くて使えない可能性がある、ということに尽きます。今後も公式ドキュメント、特に JavaDoc を正として追いかけて行きたいところです。良い教訓になりました。
linux CentOS5.9 にGradleインストール

## 環境
OS : Linux CentOS 5.9

## 前提
Javaがインストールされていること

## Javaにパスを通しておく
* Gradle使うユーザの ~/.bash_profile
```export JAVA_HOME=`readlink /etc/alternatives/java | sed -e 's/\/bin\/java//g'````

* 反映
```source ~/.bash_profile```
* 確認
```java -version```

## Gradleインストール
* ダウンロード
https://gradle.org/gradle-download/ より最新を確認し
```wget https://services.gradle.org/distributions/gradle-3.1-all.zip --no-check-certificate```

* 解凍
```unzip gradle-3.1-all.zip -d /usr/local/```

* シンボリックリンク作成
```ln -s /usr/local/gradle-3.1 /usr/local/gradle```

* パス通ったか確認
```ll /usr/local/gradle/bin/```

* Gradleにパスを通す
```vi ~/.bash_profile```
```export PATH=$PATH:/usr/local/gradle/bin```

* 反映
```source ~/.bash_profile```

* 確認
```gradle -v```
PowerShellで起動演算子(&)を利用した時にハマったこととその回避策


## 前提環境

```posh

> &PSVersionTable

Name                      Value
----                      -----
CLRVersion                2.0.50727.5485
BuildVersion              6.1.7601.17514
PSVersion                 2.0
WSManStackVersion         2.0
PSCompatibleVersions      {1.0, 2.0}
SerializationVersion      1.1.0.1
PSRemotingProtocolVersion 2.1

```

### やりたいこと

起動演算子(&)経由の呼び出しであってもメッセージをそのまま出力したい

### 事象

起動演算子(&)を利用した時、メッセージの内容によっては正しく外部コマンドへ渡されない

例:
  &でeventcreate.exeに引数としてメッセージを渡すscript

```eventcreateTest.ps1

$cmd      = "C:¥WINDOWS¥system32¥eventcreate.exe"
$severity = "ERROR"
$id       = "1000"
$kind     = "APPLICATION"
$msg      = args[0]

$ret      = & $cmd /T $severity /ID $id /L $kind /D $msg

if ($LASTEXITCODE -ne 0) {
  throw "error! $LASTEXITCODE"
}

```

上記のとき、$msgが

```text

  "abcd"    -> abcd
  "ab cd"   -> ab cd
  "ab cd¥"  -> ab cd"     ## "がエスケープされてエラーが返却されて欲しい
  "ab`tcd¥" -> ab[tab]cd" ## 同上
  "abcd¥"   -> abcd¥      ## ?!
  "a¥bcd"   -> a¥bcd
  "a¥b cd"  -> a¥b cd
  
  ## " -> ' でも結果は同じ
```

動きだけ見ているとC#コンパイラの解釈に沿った動きに見える
参考: http://www.msdn.microsoft.com/ja-jp/library/78f4aasd(VS.80).aspx

### 回避策

こんな処理を入れる

```posh

function escape($msg) {
  if($msg.Contains(" ") -or $msg.Contains("`t")) {
    $match      = [Regex]::Match($msg, "¥¥+$")
    $firstPart  = $msg
    $secondPart = ""
    if($match.Success) {
      ## 末尾の¥の塊とそれ以外にわける
      $firstPart  = $msg.SubString(0, $match.Index)
      $secondPart = $msg.SubString($match.Index)
    
      ## 末尾の¥を倍にする
      $secondPart = $secondPart -replace "¥¥", "¥¥"
    }
    ## メッセージ中の"や¥を文字列として表示したい場合のescape
    $firstPart = $firstPart -replace "¥¥`"", "¥¥¥`""
    $firstPart = $firstPart -replace "(?<!¥¥)`"", "¥`""
    $msg       = $firstPart + $secondPart
  }
  return $msg
}

```

上記でコマンド上の " は ¥" 末尾 n¥ は 2n¥ でエスケープしたメッセージとして渡される
あと ¥" や " も文字列としてエスケープされる。
_正規表現の先読み/後読みって便利_

### 結果

```eventcreateTest.ps1

function escape($msg) {
  if($msg.Contains(" ") -or $msg.Contains("`t")) {
    $match      = [Regex]::Match($msg, "¥¥+$")
    $firstPart  = $msg
    $secondPart = ""
    if($match.Success) {
      ## 末尾の¥の塊とそれ以外にわける
      $firstPart  = $msg.SubString(0, $match.Index)
      $secondPart = $msg.SubString($match.Index)
    
      ## 末尾の¥を倍にする
      $secondPart = $secondPart -replace "¥¥", "¥¥"
    }
    ## メッセージ中の"や¥を文字列として表示したい場合のescape
    $firstPart = $firstPart -replace "¥¥`"", "¥¥¥`""
    $firstPart = $firstPart -replace "(?<!¥¥)`"", "¥`""
    $msg       = $firstPart + $secondPart
  }
  return $msg
}

$cmd      = "C:¥WINDOWS¥system32¥eventcreate.exe"
$severity = "ERROR"
$id       = "1000"
$kind     = "APPLICATION"
$msg      = escape(args[0])

$ret      = & $cmd /T $severity /ID $id /L $kind /D $msg

if ($LASTEXITCODE -ne 0) {
  throw "error! $LASTEXITCODE"
}


```

```text

  "abcd"    -> abcd
  "ab cd"   -> ab cd
  "ab cd¥"  -> ab cd¥     ## OK
  "ab`tcd¥" -> ab[tab]cd¥ ## OK
  "abcd¥"   -> abcd¥      ## OK
  "a¥bcd"   -> a¥bcd
  "a¥b cd"  -> a¥b cd
  
```

:ok:
Swiftでカスタムモデルオブジェクトをアーカイブファイルで永続化する（ドゥタンバヌマサカノ燕返し編）

![SwiftReverse](https://yumemi-my.sharepoint.com/personal/k_sugio_yumemi_co_jp/_layouts/15/guestaccess.aspx?guestaccesstoken=cEI%2fG099Gp%2fwreN8Ob49k45TbMKalHLp%2fo6%2bSYy%2bNMo%3d&docid=018e4a3486596427799bb59859b9ad08a&rev=1)
# 概要
- RealmSwift を用いて特定のデータの永続化を行なうことになった
    - `RealmSwift` 箇所でアーカイブビルド時にエラーが発生（シミュレータやXCodeから直接実機に入れた際には問題なし、配布形式ビルドだとダメ）
        - おそらく RealmSwift `0.120.1` に混在する不具合らしきことが分かった
        - XCodeのバージョンを上げる必要があったため、やむを得ずRealmSwiftを断念
- 代わりに `CoreData` を導入しようとしたが、マイグレーションや導入コストがかかり期間的に厳しい
    - Documentファイルで永続化
        - どの言語でもファイル操作は意外と基本的な事ぽいが調べてもなかなか情報が出てこなかった
        - `NSUserDefaults` に保存するパターンや単純な文字列をテキスト保存するなどはたくさん紹介されている

    
# やりたい事
- ある登録フォームの特定情報を一定期間保持したい
    - `NSUserDefaults` での保存ではなく単純なファイルとして保存したい

# アプローチ
- 永続化対象データをシリアライズしてバイナリ化しDocumentファイルとして保持
    - `NSKeyedArchiver` でシリアライズ保存、 `NSKeyedUnarchiver` で取り出す


# 設計
![](https://yumemi-my.sharepoint.com/personal/k_sugio_yumemi_co_jp/_layouts/15/guestaccess.aspx?guestaccesstoken=iwzHihwrZHkkonrKKoo0PdFRMxPwpHAgvJCLUC5c0r0%3d&docid=08bb1c14d00234643a7749dcf4a4db151&rev=1)

# 実装
- キーポイントは `NSObject` クラスは `NSCoding` を継承しなければアーカイブ化できない
- ※今回は ViewController は割愛
    
## model
```swift
import Foundation

//MARK: - FormModel
public class FormModel: NSObject, NSCoding {
    public var id: String
    public var registerDatetime: NSDate
    public var name: String
    
    public override init() {
        self.id = NSUUID().UUIDString
        self.registerDatetime = NSDate()
        self.name = ""
    }
    
    required public init?(coder aDecoder: NSCoder) {
        self.id = aDecoder.decodeObjectForKey("id") as! String
        self.registerDatetime = aDecoder.decodeObjectForKey("registerDatetime") as! NSDate
        self.name = aDecoder.decodeObjectForKey("name") as! String
    }
    
    public func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(self.id, forKey: "id")
        aCoder.encodeObject(self.registerDatetime, forKey: "registerDatetime")
        aCoder.encodeObject(self.name, forKey: "name")
    }
}

```

## manager
```swift
import Model

class CacheManager {
    static let instance = CacheManager()
    private let path: String
    private let fileName: String
    
    init() {
        self.path = NSHomeDirectory() + "/Documents/"
        self.fileName = "FormCache.cache"
    }
    
    internal func add(form: FormParam) -> Void {
        let cache = FormModel()
        cache.id = form.id != nil ? form.id! : 0
        cache.registerDatetime = form.registerDatetime
        cache.name = form.name
        
        NSKeyedArchiver.archiveRootObject(cache, toFile: self.path + self.fileName)
    }

    
    private func get() -> [FormModel] {        
        return NSKeyedUnarchiver.unarchiveObjectWithFile(self.path + self.fileName) as! [FormModel]
    }
}

```

# まとめ
- 単純な少量データには適しているが、本来ならば横着せずにCoreDataやSQLiteなどを用いて管理した方がいい
    - もちろんファイルで管理するメリットもたくさんあるのでケースバイケース
- しっかし、iOSアプリ開発はなにかとトラップが多い気がする。XCodeにしろ、細かい制約にしろ、いろいろと難しい
Chainerの基本オブジェクトについて〜Variable編〜

#本記事について
この記事では，現在深層学習について勉強中の私が

>新納浩幸　Chainerによる実践深層学習　オーム社

を読んで学んだChainerの基本オブジェクトについてまとめています．

間違った解釈を載せている場合もありますので，おかしな点に気づかれた方はご指摘していただけると幸いです．

#Chainerについて
[Chainer](http://chainer.org/)はPFI／PFN（株式会社Preferred Infrastructure/株式会社Preferred Networks）が開発する深層学習のフレームワークです．
深層学習を実装する上で必要な計算を行うライブラリを豊富に備えています．
特徴をまとめると，
-Python（2.7以上）から利用することができる
-あらゆるニューラルネットワークの構造に対応
-動的な計算グラフ構築による直感的なコード
-GPUの強力なサポート
です．
特に，Linux環境下であれば（基本Linux上での動作を想定している）pip一発でインストールができます．

```
pip install chainer
```

#基本オブジェクト
Chainerはニューラルネットワークを実装する上で必要なコンポーネントをオブジェクトとして提供します．
基本的なものとして
-Variable
-functions
-links
-Chain
-optimazers
があります．
今回はVariableについて説明します．

#Variables
Variableはニューラルネットワークにおけるノードに対応するオブジェクトです．例としては下の図指しているy2です．
![38364563-eef6-259b-93f8-6d0531dad801.png](https://qiita-image-store.s3.amazonaws.com/0/28622/90907543-82bd-4125-e132-8eeac21fe7a0.png)

使用する際は

```
import numpy as np
import chainer
from chainer import Variable
```
と記述してください．numpyも配列操作に必要なため，chainerを使用する際は基本importします．

例えば，ノードx1,x2,x3は次のように宣言します．（以下から対話モード）
ノードの実体は配列です．

```
>>> x1 = Variable(np.array([1], dtype=np.float32))
>>> x2 = Variable(np.array([2], dtype=np.float32))
>>> x3 = Variable(np.array([3], dtype=np.float32))
```

Chainerでは実数はnp.float32，整数はnp.int32に固定しなければいけません．



```math
z = 2(x_1 - 2x_2 -1) + (x_2x_3 - 1) + 1
```
 
この式をVariableで表すと

```
>>> z = (x1 -2**x2 -1)**2 + (x2*x3 -1) + 1
```
となります．zの中身はdataという属性から参照できます．式の通り，dataは順
伝搬させた結果です．

![variable.png](https://qiita-image-store.s3.amazonaws.com/0/28622/a3612a6e-1e19-0365-01d5-5752b2db54c2.png)


```
>>> z.data
array([42.], dtype=float32)
```

また，backwardメソッドを使うことで逆伝搬の計算を行うことができます．

```
>>> z.backward()
```

ニューラルネットワークでは，重みの更新をするために[誤差逆伝搬法](http://qiita.com/moroku0519/items/3188382ad85a8654cc42#%E8%AA%A4%E5%B7%AE%E9%80%86%E4%BC%9D%E6%92%AD%E6%B3%95)という手法を用います．（細かい説明についてはリンク先を参照）その際，誤差関数の傾きが重要なパラメータとなるのですが，backwardメソッドを使ったノードに対して，その前のノードのgradという属性に微分値がセットされます．

```
>>> x1.grad
array([-8.], dtype=float32)
>>> x2.grad
array([46.], dtype=float32)
>>> x3.grad
array([20.], dtype=float32)
```

実際，それぞれの変数で微分してみると，（Markdownのmathにてflalignが効かない・・・）

```math
\frac{δz}{δx_1} = 2(x_1 - 2x_2 - 1) \\
\frac{δz}{δx_2} = -4(x_1 - 2x_2 -1) + 2x_3(x_2x_3 -1) \\
\frac{δz}{δx_3} = 2x_2(x_2x_3 - 1)
```

そして，

```math
x_1 = 1\\
x_2 = 2\\
x_3 = 3
```
を代入すると

```math
\frac{δz}{δx_1} = 2\times(1 - 2\times2 - 1) = -8\\
\frac{δz}{δx_2} = -4\times(1 - 2\times2 - 1) + 2\times3(2\times3 - 1) = 46\\
\frac{δz}{δx_3} = 2\times2\times(2\times3 - 1) = 20
```

となることが確認できます．
微分計算をあっという間にすることができました．

#終わりに
今回はVariableオブジェクトについて書きました．
自分でも書いてて曖昧な部分があるのでご指摘していただけると幸いです．
次回はfunctionsオブジェクトについて書きます．

#参考
新納浩幸　Chainerによる実践深層学習　オーム社

Chainerのソースを解析。順伝播と逆伝播の仕組み
http://ailaby.com/chainer_foward_backward/

ニューラルネットワークとは
http://qiita.com/moroku0519/items/3188382ad85a8654cc42
MQTTでSubscribeしているトピックにキーワードが出現したら別のトピックにPublishする


# 【概要】
…という処理を、もう何度も書いていて、いい加減再利用しようとようやく思い立った。
イメージ的には下記の図みたいな感じで、左側のTopic Aに対してはSubscribe, 右側のTopic Bに対してはPublishするイメージ。

![Kobito.jocseL.png](https://qiita-image-store.s3.amazonaws.com/0/35808/d420ae70-0bc6-cbaf-9257-6f1006ec6c10.png "Kobito.jocseL.png")

スクリプト中では左側のTopicを「SUB_TOPIC」、右側のTopicを「PUB_TOPIC」と表現。ついでに、ひょっとしたらSUB側とPUB側でホストとかも違うかもしれないじゃん、ということで接続情報についてはSUB側とPUB側でそれぞれに情報を持つようにしてみた。

# 【スクリプト】
こんな感じ。

```python:sample.py
#!/usr/bin/python
# encoding:utf-8

import paho.mqtt.client as mqtt
import re
import sys

# このスクリプトがSubscribeするトピック関係の設定
SUB_TOPIC = "subtopic"
SUB_USERNAME = 'username'
SUB_PASSWORD = 'password'
SUB_HOST = 'localhost'
SUB_PORT = 1883

# このスクリプトがPublishするトピック関係の設定
PUB_TOPIC = "pubtopic"
PUB_USERNAME = 'username'
PUB_PASSWORD = 'password'
PUB_HOST = 'localhost'
PUB_PORT = 1883

# Sub側トピックでこのキーワードが出現したらPub側トピックへの出力を行う
KEYWORD = "TEST"

# デバッグ出力制御用のフラグ
ISDEBUG = True

def sub_on_connect(client, userdata, flags, rc):
    client.subscribe(SUB_TOPIC)

def sub_on_message(client, userdata, msg):
    # 受信したメッセージはmsg.payloadに格納されています
    debug_echo(msg.payload)

    match = re.match(KEYWORD, msg.payload)

    if match is None:
        debug_echo("Not Match")
    else:
        debug_echo("Match")
        publish("OK")


def publish(msg):
    pub_client.publish(PUB_TOPIC, msg)
    pass


def debug_echo(msg):
    if ISDEBUG :
        print msg
        sys.stderr.write(msg+"\n")

if __name__ == '__main__':
    # 送信側クライアントの準備
    pub_client = mqtt.Client(protocol=mqtt.MQTTv311)
    pub_client.username_pw_set(PUB_USERNAME, password=PUB_PASSWORD)
    pub_client.connect(PUB_HOST, port=PUB_PORT, keepalive=60)

    # 受信側クライアントの準備
    sub_client = mqtt.Client(protocol=mqtt.MQTTv311)
    sub_client.on_connect = sub_on_connect
    sub_client.on_message = sub_on_message
    sub_client.username_pw_set(SUB_USERNAME, password=SUB_PASSWORD)
    sub_client.connect(SUB_HOST, port=SUB_PORT, keepalive=60)

    # 受信ループ開始
    sub_client.loop_forever()
```

追記：デバッグ内容を標準エラー出力に吐き出すように変更しました。
Fedora 24 ServerにsSMTPをインストールしてGmailを踏み台にする

# やりたいこと

定番メールサーバといえばsendmailだけども
設定ファイルがイケてないので、sSMTPを使うことにした

用途としては、簡単な自動通知メールの送信。

また、OB25Pを回避するためにGmailを踏み台にしてメールを送ることにする。


# sSMTPって何？

sendmailがいわゆるメールサーバ(デーモン)であるのに対し
sSMTPは、単なるメール配送プログラム。

機能も限定的(キュー管理が出来ない等)だが、
sendmailに比べると設定ファイルの可読性や簡単さが雲泥の差。

インストールすると、sendmailに成り代わる。


# 動作確認環境、使用ライブラリ等

- Fedora 24 (Server Edition) 64bit
 - ssmtp-2.64-16.fc24.x86_64
- 踏み台にするGmailアカウント

# 下準備

踏み台にするGoogleアカウントにログインした状態で下記URLにアクセスし
「安全性の低いアプリのアクセス」を「有効」にする。
https://www.google.com/settings/security/lesssecureapps


「安全性の低いアプリがアカウントにアクセスするのを許可する」ヘルプページ
https://support.google.com/accounts/answer/6010255?hl=ja


この設定を忘れると、

```text
Authorization failed (534 5.7.14  https://support.google.com/mail/answer/78754 - gsmtp)
```

というエラーがmaillogに出続ける。

# インストール作業

```shell-session

# dnf install ssmtp

```

以上

# 設定作業

```shell-session

# vim /etc/ssmtp/ssmtp.conf

```

```ini:ssmtp.conf

root=YOUR_GMAIL@gmail.com

mailhub=smtp.gmail.com:587

# Auth
AuthUser=YOUR_GMAIL@gmail.com
AuthPass=YOUR_GMAIL_PASSWORD
AuthMethod=LOGIN

RewriteDomain=gmail.com

Hostname=localhost

FromLineOverride=NO

UseTLS=YES
UseSTARTTLS=YES
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt

```

必要最低限の項目だけ列挙


# 簡単な解説

Gmailの認証情報を渡してあげることにより、ユーザに成り代わってメールを送るイメージ？

FormLineOverrideを「YES」に設定することによって送信元を偽装できるようになる(らしい)。
YESで有効になるのか無効になるのかよくわからないからmanで調べた。

```text
FromLineOverride
     Specifies whether the From header of an email, if any, may override the default domain.  The
     default is “no”.
```

YESで上書き可能になるようだ。


# 所感

sendmailのdnl無双と比べると超見やすいし分かりやすい。
しかし逆に言うと、出来ることも少ない。

confファイルにGmailのパスワードを平文で書かないといけない。
いくら簡単っていっても平文ってどうよ？ というのはある。
安全な環境でだけ使うようにしたい。

また、「安全性の低いアプリのアクセス」を許可することにより Gmailの安全性低下するようなことが書かれていたので
基本中の基本ではあるが、パスワードの使いまわしは止め、推測されにくい複雑なパスワードを設定するべし。
SCPの使い方(permissionで二度とはまらないために)　

#SCPとは？
sshを使用してネットワーク越しに、ファイルをコピーするコマンドです。

##注意点

scpを使う場合に、コピー先に同名のファイルやディレクトリがあった場合に上書きされてしまうので注意

##オプション

```
-i 秘密鍵ファイル　　秘密鍵ファイルを使用する際に使用
-P ポート番号　　　　SSHの接続ポート番号が接続先で変更されている場合に使用
-p  　　　　　　　　　コピー元データの更新時間やパーミッション情報を保持させる
-r                ディレクトリ内のデータを再帰的にコピーする
-C                データを圧縮し、コピーする
```
##scp書式(リモートホストからのローカルへコピー)

```
scp [オプション] [接続ユーザ]@ホスト名(IPアドレス):コピー元　　コピー先
```

例；scp ec2-user@00.000.00.000: /var/log/nginx/access.log  (空白) ./

##scp書式(ローカルからリモートへコピー)

```
scp [ オプション ] コピー元  [接続先ユーザ]@ホスト名(IPアドレス):コピー先
```

##設定ファイル(~/.ssh/config)を使用した方法

scpを利用するときにconfigを設定しておくと、オプションの設定の必要がなくなる
```
Host [設定名]
Hostname [接続先ホスト名 or IPアドレス]
Port [接続ポート番号]（必要があれば）
IdentityFile [秘密鍵]（必要があれば）
User [接続ユーザ名]　（必要があれば）
```
例

```
Host oda
Hostname ~~~~~~~~~
Port 8080
IdentityFile ~/.ssh/id_ecdsa
User oda
````

上記の例でいくと

 ```
scp oda:/var/log/nginx/access.log  ./
```

というような感じです。
ちなみに成功すると
```
access.log-20161021.gz                                                                               100%     889KB 888.9KB/s   00:00
```
のように表示される

##はまったところ

```
[oda]$ scp oda:/var/log/nginx/access.log ./
scp: /var/log/nginx/access.log: Permission denied
Killed by signal 1.
```

このようなエラーが出てきます。

権限問題です。ここでは権限を変えない解決方法を提示

##解決策

```
ssh  oda　（サーバに入る)
sudo -i   (rootに)
cd /var/log/nginx   (ここではnginxのディレクトリまで移動)
cp <提供するログファイル名>  /home/ec2-user   (コピーをして対象のファイルを移動させたいパスを指定)
exit        
```

ここで行ったことは権限を変えるのではなく
コピーしてファイルを移動させ、権限のないところに移動させることでscpを可能にするということ

```
scp oda(host):~/<取得するログファイル名>  ./(移動させるパス)
```

上記のようにオプションなしでhostを指定できるのはconfigに書いている場合だけです

##よく出てくるエラーメッセージ

```
Permission denied
```
コピーするディレクトリ、ファイルに書き込み権限がない場合に表示
→ファイルの所有者やパーミッションを確認する必要がある

```
not a regular file
```

ディレクトリをコピーする際に[-r]オプションを使用しない場合に表示
突然のAndroidStudioでのエラー『Can't start Git』とその対処法

# 状況

![androidstudio.png](https://qiita-image-store.s3.amazonaws.com/0/75564/a967e237-d0e8-2fdd-dd96-fa4db54d1519.png "androidstudio.png")

さっきまで問題なくビルドとかできていたAndroidStudio。
一度PCを再起動すると、

```AndroidStudio
Can't start Git: /usr/bin/git
Probably the path to Git executable is not valid.
```

だと・・・？
ずっとgitと一緒に仲良くやってきたはずなのになぜ？
原因と対処法をまとめました。
ちなみに開発環境はMacです。

# 原因

ファイルやディレクトリがなくなったりしてるわけではなく、
Xcodeの更新にともなう同意要求が原因でした。
Xcodeが7.3.1から8.0にアップデートされていました。
Xcodeの利用規約に同意しないとgitが実行ができないようです。

# 対処法

## ターミナルから対応

terminalを起動し、gitのある場所に移動。

```shell
cd /usr/bin
./git
```
-> Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
（ライセンスに同意してね。sudoで起動してね）

```shell
sudo ./git
```
->You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode.
Hit the Enter key to view the license agreements at '/Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf'
（Xcode規約にまだ同意してないから同意してね。Enterキー押したら規約見せるね。）

```shell
[Enter]
```
-> （利用規約いろいろ〜略）
By typing 'agree' you are agreeing to the terms of the software license agreements. Type 'print' to print them or anything else to cancel, [agree, print, cancel] agree
（同意したらagreeってタイプしてね。印刷ならprint、それ以外はcancelね。）

```shell
agree[enter]
```
同意しました。

以上で完了です。
【Memo】SetVarHash・SetVar・Varで自由に特定の記事を取り出しできるようにする


何がしたいのかというと、インデックステンプレート上で自由にEntryの記事を取り出して配置する方法になります。
あまりうまい方法とかではないと思いますが、メモとして残しておきます。

## mt:Entriesをセット

```
<mt:ignore>** 記事を変数に格納 **</mt:ignore>
<mt:Entries lastn="0"　sort_order="ascend">
<mt:EntryID setvar="this_entryID" />
<mt:EntryTitle setvar="title" />
</mt:Entries>
```

* 使用するデータをすべて変数に渡す

## 記事の連番に名前をつける

```
<mt:ignore>** 連想配列（Entries Sort番号順） **</mt:ignore>
<mt:SetVars>
_entry_name01=0
_entry_name02=1
_entry_name03=2
</mt:SetVars>
```

連番に名前をつけた理由としては、一箇所にまとめておけば、エントリー順が変わっても変更箇所は名前の連番をかえることで変更箇所を最小限に抑えることができます。

## 出力先の設定

```
<mt:ignore>** 特定の記事データを呼び出す **</mt:ignore>
<mt:Var name="entry_title[$_entry_name01]">
```

あまり使う機会ないと思いますが、こういった形で呼び出すことも可能だということを学びました。
呼び出したいところにEntriesを配置するのも良いと思いますが、なるべくmt:Varで完結させたかったというメモエントリーになります。
Javaを学び始めてから１週間で僕が学んだこと

Javaを学び始めてから１週間で僕が学んだことを書いていきます

シンプルな箇条書きのみです


<h1>１．Javaってなに</h1>

<h1>２．Javaのスペルを間違えると嘲笑される</h1>

<h1>３．Javaの歴史</h1>

<h1>４．Javaを扱うにはEclipsというエディタ（一番人気）が必要</h1>

<h1>５．Eclipsのインストールが超ハイパーメディア難しい</h1>
これは以前、記事にしました

<h1>６．Eclipsのプラグインを一通り入れると便利</h1>

<h1>７．Eclipsで好きなJavaアプリをとりあえず開いてみる</h1>

<h1>８．好きなJavaアプリを解読しようとして挫折する</h1>

<h1>９．コードの解読解析というのは奥深いジャンルだということを知る</h1>
＞＞「入れ子」のレベルが深すぎるのはコード作者が良くない、という意見を知る
https://qixil.jp/q/2338

<h1>１０．コードの解読解析のひとつの補助ツールとして、フローチャート化するソフト「Visustin」を無料お試しする</h1>

<h1>１１．フローチャートを眺めてもわからない</h1>

<h1>１２．仕方ないからようやくコードを読み始める（やれやれ）</h1>
　<br>
　<br>
- - - - - - - -
　<br>
　<br>
<h1>１３．ほとんどの文字列が意味わからない</h1>
（Swiftで初心者本を読んでたから少しはわかる）

<h1>１４．クラスとは…</h1>
クラスとは＞＞設計図
メソッドとは＞＞機能
フィールドとは＞＞データ
フェイトは＞＞文学
エアーは＞＞芸術
クラナドは＞＞人生

スーパーとは＞＞上の階層の設定を参照
コンストラクタとは＞＞初期値を自分で設定
コンパイルとは＞＞変換
forとは＞＞繰り返し
ifとは＞＞条件Yesの奴にだけ命令
if-eleseとは＞＞Yesの奴とNoの奴、それぞれに別命令
while＞＞たくさん繰り返し
switch＞＞たくさん分岐

publicとは＞＞アクセス修飾子（？）（なんとなくスルーしておけばいい系）
extendsとは＞＞extendsの後に継承したいスーパークラス名を記述

<h1>１４．Eclipsのアウトライン (Outline) ビューというのがクソ便利</h1>
＞＞イラレで例えると、レイヤーウィンドウ
＞＞CUBASEで例えると、コード進行トラック
＞＞広辞苑で例えると、目次

これがあると、長ったらしいコードとかいう暗号の羅列の構造がわかる
しかもプラスとマイナスの記号で折りたたんだり、開いたりできる
同様に本文の方も、プラスとマイナスの記号で折りたたんだり、開いたりできる

<h1>１５．アウトライン (Outline) ビューは、記号が何を指しているのかがわかってないとちょっと困惑</h1>
中抜き緑の丸… フィールド
塗りつぶし緑の丸 … メソッド
（その他いろいろ）

<h1>１６．continueとは</h1>
continue文…まるごとスキップ
break文…次へスキップ

<h1>１７．オブジェクトって何？</h1>
# http://nobuo-create.net/java-beginner-17/
より引用
>オブジェクトを作るというのは「自分で定義したクラス型変数を作る」ということと同義と言えます。
Human human;
↑このように型名は大文字、変数名は小文字であることに注意！

<h1>１８．thisって何？</h1>

# http://nobuo-create.net/java-beginner-17/
より引用
>はい、出ました。「this」です。初心者を苦しめるやつです。と言ってもそんな大したことないのでサクッとやっつけましょう。
「this( )」は、「このインスタンス」を意味する「this」とは全く関係ありません。「this( )」は「このクラスのコンストラクタ」という意味なんです。</quote>
大規模ソフトウェアを手探る Firefox


大学での実験課題の一つ，『大規模ソフトウェアを手探る』のまとめページです．
各項目について詳しくはリンク先の記事を参照してください．

1. ビルド
	* [Firefox 49.0をビルドして実行する][build]
2. デバッガ
	* [Firefox自身のJavaScriptをデバッグする][debugger]
[debugger]:http://qiita.com/kagutitan/items/f5ff3876c11e9c2d50e6
[build]:http://qiita.com/fujibo/items/59c74113389ba8a8b49d

3. 機能追加
    * [表示されるURLを隠蔽する，"タブを複製"メニューの追加][saka]
    * [Firefoxのタブ機能をソースコードをいじって改変した
][tsubo]
	* [jとkでページのスクロールをする][naga1]
	* [ブラウザバックをした後今開いていたタブを新しいタブで開き直す][naga2]
	* [選択したタブだけを残し他のタブを削除する][naga3]

[saka]:http://qiita.com/kagutitan/items/9cac5cd71672195752ca
[tsubo]:http://qiita.com/fujibo/items/fc5201b497f3834dd854
[naga1]:http://qiita.com/nagashim4/items/8b758cd5c45e17d55dd3
[naga2]:http://qiita.com/nagashim4/items/2218bea12ad43901c4a7
[naga3]:http://qiita.com/nagashim4/items/d8eb64c0f1def63780ae
LJの力計算のSIMD化(たぶん完結編)

# はじめに

これまでのあらすじ。

* [LJの力計算をフルアセンブラで書いてみる](http://qiita.com/kaityo256/items/03e0240af4e9a6469bcb)
* [LJの力計算を組み込み関数で書いてみる](http://qiita.com/kaityo256/items/0d3094de324f0e63d1f4#_reference-bb9db355c8eb79f6c96f)
* [LJの力計算を組み込み関数で書いて馬鹿SIMD化](http://qiita.com/kaityo256/items/bf10fdb0f90809e3d2bf#_reference-1a416859bca0af6833d1)

とりあえずO(N^2)ループでインテルコンパイラより早そうなコードが書けた。しかし、

* 実用的なMDコードはペアリストによる間接参照、およびカットオフがあるが、それが反映されていない
* 上記のコードはAoSでやっているが、実はSoAでやったらインテルコンパイラはもっと良いコードを吐くかもしれない

という疑念があった。というわけで、

* 相互作用ペアリストを作成し、間接参照とカットオフがある状態で速度を計測
* AoSとSoAの速度差を調べる

ということを目的としてベンチマークコードを書いた。ただしペアリストは手抜きでO(N^2)で作っている。

# コード

コードは長くなったのでhttps://github.com/kaityo256/lj_simd においておく。それぞれ

* force_aos.cpp: AoSで、力の計算を何種類かと、シャッフル命令を使って手でSIMD化したコードを含む。
* force_soa.cpp: 上記のSoA版。シャッフル命令を使わない馬鹿SIMD化を含む。

力の計算ルーチンは以下の通り。

* force_pair: ペアごとにループを回す。一重ループになる。
* force_sorted: 相互作用相手でソートして、二重ループにしたもの。
* force_next: 手で二段のソフトウェアパイプライニングを施したもの。手持ちの、intrinsicsを使わない条件ではx86系で一番早いコード。
* force_intrin: 手でSIMD化したもの。

計測条件、パラメータは以下の通り。

* Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
* icpc (ICC) 16.0.3
* コンパイルオプション: -xHOST -O3 -std=c++11
* カットオフ3.0、ペアリストに登録する距離3.3
* 数密度: 1.0
* 粒子配置: FCC+ランダムな摂動

# SIMD化の方針

相互作用相手でソートした状態で、外側をi粒子、内側をj粒子と呼ぶと、j粒子のループを4倍にアンロールして馬鹿SIMD化する。ただし、データをAoSで持っておき、xyz座標を_mm256_load_pdで一度にYMMにロードする(1要素無駄になる)。その後シャッフル命令とか使ってなんとなく4ペアの力を同時に計算する。カットオフがあるため、カットオフ距離以上にいる奴は力をゼロクリアしないといけない。そのため、[前回](http://qiita.com/kaityo256/items/bf10fdb0f90809e3d2bf#_reference-1a416859bca0af6833d1)のコードに

* (カットオフ距離 - 粒子間距離)でマスクを作る 
* 距離が負の時、カットオフ距離よりも粒子間距離の方が長いため、マスクを使って_mm256_blendv_pdで、力をゼロクリアする

という処理が追加される。後は同じで、データがAoSになってるから、YMMの転置っぽいことをして、それぞれを_mm256_store_pdを使って運動量に書き戻せばOK。

# 結果

それぞれの関数を100回実行するのにかかった時間。粒子数が119164(〜5.5MB)とかなので、完全にキャッシュにのっていると思われる。

| データ配置 | 計算手法 | 実行時間 | 備考 |
|:-:|:--|:--|:--|
| AoS  | force_pair  | 8.194431  | ペアごとにループをまわしたもの  |
| AoS  | force_sorted  | 7.010013 | 相互作用相手でソートして、二重ループにしたもの  |
| AoS  |  force_next | 5.818571 |   手で二段のソフトウェアパイプライニングを施したもの |
| AoS  | force_intrin  | 3.888375  | 手でSIMD化したもの (シャッフル命令あり)  |
| SoA  | force_pair  |  9.554387 | ペアごとにループをまわしたもの(SoA版、以下同様)  |
| SoA  | force_sorted  | 7.105266 |  相互作用相手でソートして、二重ループにしたもの |
| SoA  | force_next  | 5.634103  | 手で二段のソフトウェアパイプライニングを施したもの  |
| SoA  | force_intrin  | 5.846895  | 手でSIMD化したもの (シャッフル命令なし) |

# まとめのようなもの

AoSで持つよりも、SoAで持つ方が若干速度が向上したが、その差はほんの少しだけだった。O(N^2)ループのような、きれいなデータアクセスだともっと差がつくのだが、間接参照だらけだとあまり差がつかないっぽい。

手でSIMD化したバージョン、結構がんばって書いた割に速度向上は33%程度。これも比較的高密度だからで、もう少し低密度、数密度0.5だと13%程度。うーん、もう少し早くなって欲しかったなぁ。手で書いた二段ソフトウェアパイプライニングがそれなりに効果的なので、手で四段とかパイプライン組んで、なおかつそれをSIMD化とかしたら早くなるのかなぁ。もはや人内が書けるコードではない気がするけど。

倍以上になったら詳細な説明でも書こうとおもったけど、思ったほどでもなかったので、ソースだけ置いておきます。

# 追記(SoA版のSIMD化)

もともとの動機は普通に馬鹿SIMD化すると、データのパック/アンパックの処理が重いため高速化しないのでは？というところだったので、データのパック/アンパックを伴う、シャッフル命令を全く使わないバージョンのSIMD化コードを追記。SIMD化する前のコード(7.105266秒)よりは高速化された(5.846895)けれど、手でソフトウェアパイプライニングしたもの(5.634103秒)よりは遅いので、やっぱりシャッフル命令を使ってload/storeをケチった方が早いですな。
CGRectContainsPoint - Swift 3 調整記

今天寫了這個：

``` Swift
CGRectContainsPoint(rect, anotherRect.origin)
```

Xcode 8 告訴我，
這個方式被調整成這個寫法：

``` Swift
rect.contains(anotherRect.origin)
```

除了移除 C style 的全域方法呼叫方式，使用時的語意相較起來比較合理清楚，也更加物件導向。
Azure FunctionsでAzure SDK for Node.jsを使い、BlobのSAS付きURLを取得する

## 準備
Kuduを使ってAzure SDK for Node.js をインストールしておく

参考
<a href="http://qiita.com/Banchi0123/items/eb05717941138d778005" target="_blank">Azure Functionsで npmモジュールを使う</a>



## 実装
```js
var azure = require("azure");

//ここを書き換える
var storageAccount = "your-storage-account";
var storageAccessKey = "your-storage-access-key";
var container = "your-container-name";
//ここを書き換える

var blobService = azure.createBlobService(storageAccount, storageAccessKey);


function getSAS(context, blob) {


    var startDate = new Date();
    startDate.setMinutes(startDate.getMinutes() - 5 );
    var expiryDate = new Date(startDate);
    expiryDate.setMinutes(startDate.getMinutes() + 10);


    context.log("blobService: " + JSON.stringify(blobService.host));
    context.log("startDate: " + startDate.toISOString());
    context.log("expiryDate: " + expiryDate.toISOString());


    var sharedAccessPolicy = {
        AccessPolicy: {
            Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ,
            Start: startDate.toISOString(),
            Expiry: expiryDate.toISOString()
        }
    };

    context.log(JSON.stringify(sharedAccessPolicy));

    var signature = blobService.generateSharedAccessSignature(container, blob, sharedAccessPolicy);
    console.log("signature: " + signature);

    return signature;

}


module.exports = function(context, req) {
    context.log("Node.js HTTP trigger function processed a request. RequestUri=%s", req.originalUrl);

    var fileKey;

    if (req.query.fileKey|| (req.body && req.body.fileKey)) {
        fileKey = (req.query.fileKey || req.body.fileKey);
    }

    if (!fileKey) {
        context.res = {
            status: 400,
            body:  { result: "ng", error: "Please pass a fileKey on the query string or in the request body" }
        };
        context.done();
        return;
    }


    var sas = getSAS(context, fileKey);
    var url = blobService.getUrl(container,fileKey,sas);
    
    console.log(url);

    var responceBody = {
        url: url
    };
    
    context.res = {
        // status: 200, /* Defaults to 200 */
        body: responceBody
    };

    context.done();

};
```
上記の例では、現在時刻の5分前 から　10分間有効なSASを発行している。


## 実行時の要求本文（例）
```json
{
    "fileKey": "sastestdir/sastestfile.txt"
}

```

## アクセスポリシのパーミッションの複数指定
```js
var sharedAccessPolicy = {
        AccessPolicy: {
            Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ + azure.Constants.BlobConstants.SharedAccessPermissions.LIST,
            Start: startDate.toISOString(),
            Expiry: expiryDate.toISOString()
        }
    };
```
.READは単純に文字列で"r"、.LISTは"l"なので
＋で繋げて渡してやれば良い。
Permissionsを変更すると、クエリストリングのspが sp=rになったり、sp=rl　になったりするので、
urlを見て確認できる。


****
何か間違ってたり、もっとこうしたほうがいいよなどあれば是非コメントにて指摘、アドバイスください:blush:
Notification key name 寫法的改變 - Swift 3

碰到需要用到 Notification 內建的 key name ，
發現在 Swift 3 / iOS 10 的寫法改變了


iOS 10 SDK 很大的改變之一就是很多取得的方式都物件化了，
大大降低 C style 的取用方式

今天是碰到觀察 keyboard 變化發現的，
例如：

```
UIKeyboardWillHideNotification
```

這是用來觀察鍵盤即將隱藏的 notification 的 key name ，
在 Xcode 8 裡面則會被發現被 IDE 告知：

> 'UIKeyboardWillHideNotification' has been renamed to 'NSNotification.Name.UIKeyboardWillHide'

這時候 IDE 會幫你改成

```
NSNotification.Name.UIKeyboardWillHide
```

這樣物件類型的寫法即可。

## 巢狀 struct

在追這個 `NSNotification.Name` 的定義的時候，
發現官方是用巢狀 struct 的方式定義這一群的 notification names 。

這個寫法應該不是新的，只是目前還沒這樣寫過。
之後可以看情境來嘗試看看來包裝這一類的環境變數方便存取。

這個用法詳細的原因就還要再去找找資料了～
ionic2プロジェクトをfirebaseのweb appとしてデプロイ


## 前提
 - firebaseサーバにアカウントの作成及び、プロジェクトの登録を行なっていること
 - ionic2を使用してアプリケーション作成を行なっていること(なにもいじってなくてもいいですが。)


## ローカル開発ディレクトリをfirebase開発環境にする

既存のローカルionicプロジェクトをfirebaseの開発環境として登録します。

```bash
firebase init
```

`Database`か`Hosting`かを問われるので、`Hosting`を選択します。(何が違うのかは不明です。)

```bash
◉ Database: Deploy Firebase Realtime Database Rules
❯◉ Hosting: Configure and deploy Firebase Hosting sites

```

`firebase`の設定ファイル名が問われますが、特に問題がなければそのまま`database.rules.json`で行きます。

```bash
? What file should be used for Database Rules? (database.rules.json)
```

デプロイ元のディレクトリが問われるので、今回はionicのbuild先である`www`に指定します。

```bash
? What do you want to use as your public directory? www
```

SPAかどうか問われるので、yを入力してすすめます。

```bash
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y
```

これでローカルのプロジェクトがfirebaseのプロジェクトになりました。

## ionicのbuild

buildにより、ionicはandroidやios用にバイナリを生成しますが、今回使用するのは`www`ディレクトリに生成されるwebのSPAのものだけです。

以下のコマンドによりbuildを実行します。

```bash
ionic build
```

buildが成功すると`www`ディレクトリにSPAソースが生成されます。

>  `Property 'プロパティ名' is private and only accessible within class
`のエラーが発生した場合・・・

>ionicでは`private`プロパティは許可されていない模様です。
>プロパティを`private`からデフォルト(`public`)に変更します。ただし、`constructor`に指定した`provider`はprivateでもいける様です。

### 修正
web版であっても`cordova.js`を使用しようとしてコンソールに404エラーを吐きます。
正しいやり方ではなさそうですが、`www/index.html`の `cordova.js`を読み込むところをコメントアウトしてしまいましょう。

```html
<!-- cordova.js required for cordova apps -->
<!-- <script src="cordova.js"></script> -->
```

## firebaseサーバへデプロイ

firebaseサーバへ、`www`のソースをデプロイします。

```bash
firebase deploy
```

デプロイに成功すると、`Hosting URL`に、デプロイされたURLが表示されますので、ブラウザなどからアクセスしてみてください。
できるプログラマになる!"伝える"技術　1章まとめ

上司の「できるプログラマになる!"伝える"技術」（ISBN978-4-7741-4642-3）の1章を読み、感想を書けとのお達しで作成。
重要と思ったところだけ掻い摘んでいます。

## 1.1 頭脳労働の極端な例

- プログラマとは、人間とコンピュータの境界に立つ特殊な職業である

### 単純作業と頭脳労働の違い

- 単純作業においては成果は「線形」であり、労力と成果は比例すると筆者は主張している。
- 頭脳労働は、ゴールに向かうに連れて失速していく
- 頭脳労働は、現在の作業を少しづつ改良していく作業である

### プログラムの困難さは、近づいてもゴールが見えないこと

- プログラムは全体を作り上げて初めて「一本道」となっているので、完成させるまでは道筋が見えない。それがストレスの原因である。

## 1.2 プログラマとして何を目指すか

### エンジニア・職人・芸術家

||エンジニア|職人|芸術家|
|--:|:-:|:-:|:-:|
|汎用的・明示的か？|汎用・明示的|特殊・属人的|特殊・属人的|
|実用的か？|実用的|実用的|非実用的|

- この３つの軸のどこに足を置くかは当人や当人の職場によって決まる

## 1.3　どうやって上達していくか？

### ゆっくりとした大きな動きを見る

- 仕事に本当に役立つ技術というのは、身につけるのに長い年月が必要であり、コンピュータ雑誌に乗っているような流行り廃りのある情報ではない。
- 「露天掘り」のように広く深く知識を吸収せよ

## 1.4 プログラマが持つべき３つの説明力

### 3つの説明相手

#### 自分向け
+ 説明することで自分の頭の中を整理する
  * 現在の脳の「コンテクスト」を外部に保存する
  * 以前の事後で作り上げたコンテスクトを頭のなかから出して切り替える。
+ その瞬間の脳内コンテクストを固定する
  * プログラマとして成長していくは、「__将来の自分__」へ現時点での脳内コンテクストを伝えていく必要がある

#### コンピュータ向け
+ プログラミングが上達するとは、コンピュータへの説明そのものがうまくなること
+ デバッグとはコンピュータへ説明したことと、コンピュータの解釈との齟齬を見つけること

#### 他人向け
+ 動的な説明
  - 会議・プレゼン・会話・授業などの、自分で喋ることを前提とした説明
  - 相手に応じて臨機応変に対応できる
+ 静的な説明
  - メール・マニュアル・書類・本などの、相手に自由なペースで読んでもらうことを前提にした説明
  - 相手からのフィードバックはない為、起こりうる疑問は予め解消しておく必要がある
英語でプレゼンしてスベったので反省する

# スベった
何がスベッかというと、**プレゼン後に会場にいた人に言いたいことが伝わってなかった。**

# 想定していた発表内容
弊社で定期的に開催している、日本国内にいる海外エンジニアなどを呼んで発表会から懇親会まで英語盛りだくさんの[Tech Talk Tokyo](https://techtalktokyo.doorkeeper.jp/)というイベントで英語でプレゼンする機会をいただき、今回はMVVMについて話そうと思った。LT時間は5分である。

また別の勉強会でお話しさせて頂いた時の[コチラ](http://www.slideshare.net/kenjhaneda/ss-66621373)の資料からMVVMで作ったアーキテクチャの部分を切り離して、なおかつ先月骨折もしたので、その話も含め**簡潔かつユーモラスに話すつもりであった。**

発表まで残り二週間というとことで、余裕を持ってcopy and pasteで、前の資料から作り直し、ドヤ顔でタイトルを英語にして保存した。

# 結果として出来上がった資料

[こちらです](http://www.slideshare.net/kenjhaneda/mvvm-is-like-born-fraction)

日本人向けであればこれでもそれなりに話せるんですが、この資料には話しして＋話した後に気づいた問題が幾つかあります。

## 問題と考察
- タイトルがハイコンテキストすぎる
    - 「結局どういうことなんだ」と言われてしまった
    - ▶️「こういうことである」と言ってから説明したほうがよかった
- 自己紹介までが長い
    - 他の外国人のプレゼンターの方はほとんど自己紹介してなかった
    - 自己顕示欲が出てしまった
    - ▶️次回は役職と会社名だけでいいと思った
- 口頭で説明と資料の文章が両方ないと意味が通じない
    - 例えば10pから「アプリの画面にはいろんな状態があり、MVVMが適している」「しかし理解が難しい」「骨折にたとえて話そう」と進めているんだけど、1箇所でも抜けるとわかりにくい
    - ▶️ヘッダに今何を話しているのか書くか、常に何のための説明かがわかるイメージをつけてあげて、代わりに説明文字を減らすべきだと思った
- スライドが見難い
    - keynoteの「モダンタイプ」というのが見やすくて好きだけど、吹き出しの中身などが大文字になってしまう。
    - ソースコードの文字が小さい、着色されてない
    - ソースコードはその時々で必要な部分だけ見えればいい
    - 1slideに1message以上入れない
    - 章節ごとに「何を言いたかったか」「どういう結論か」を書く
    - 1slide内の一部に着目する時、それに対して吹き出しを出すと英語では説明を書き切れないので別スライドにする
    - 文字サイズがまばらである
        - ▶️3サイズぐらいでまとめる
    - そもそも前回の資料からでなく、スクラッチで作るべきだった
        - 開発の進め方 -> MVVM になった時点で気づくべきだった
 
というのが、終わって振り返ってみての考察です。

## 笑いについて
**「骨折したという事実を少しでも笑いに変えて話しつつ、MVVMが画面がいろいろな状態を持つアプリには適している」**という話を5分で、しかも英語で伝えようと思うと、笑いをとったりオチをつけるのには難しかった。

資料にもある通り、骨折の写真や、必死にMVVMと紐付けている資料の部分で必死さをアピールしつつも**間を考慮した笑いを作るには完全に英語力が不足していた。**もっとシンプルに面白い画像とか、シュールな画像で1メッセージ・1素材で笑いを挟むべきだった。ここが一番後悔。

# 次回に向けて
日本語と英語のプレゼンの違いについて発表を通して少し理解できたので、日々のレッスンで伝え方を学びつつ、今回の反省点を生かして次回は頑張ろうと思います。

私のつたない英語でも懇親会で嫌な顔せず、話してくれた皆様ありがとうございました :)
次回のTech Talk Tokyoでお会いしましょう！！
ど素人が C#.net の保守でライブラリ変更してどハマりした話


## 注意
全く面白くないです。

## 結論
ビルド前にソリューションのクリーンをしろ。

## 経緯
とある Web アプリが内部で外部ベンダのサービスを利用していて、そこの仕様変更に伴いいくつかライブラリを差し替えなければならなかった。
ライブラリの API やライブラリ名は変更されておらず、後方互換があるとのことで、サクッと終わると思っていたが、なんとそのライブラリはそのサービスだけじゃなく、アプリ自体で利用していたため依存関係で死んだ。

## 作業した人のスキル感
自分はいわゆる LAMP 環境のエンジニアで、 IIS/.netFramework/C# などは門外漢である。
近しい言語で言えば C/Java あたりはちょこっと触ったことあるけど、ガチ開発の経験はない。

## 闇
このアプリを開発した人はとっくに退社済み。
ドキュメントもほぼない。
超手探り。
ベンチャーあるある。

## 症状
何をやってもライブラリないですエラーがでる。
ライブラリの要求バージョンがうんたらってエラーがでるが、ようわからん。
該当のバージョンを新しくしたらアプリ本体でエラーがでるし、バージョンを戻したらベンダ連携部分でエラーがでる。
死ぬ。

## 閃き
Java で Android アプリを開発したときはそう言えばクリーンしたなと思いつく。

## 教訓
保守できる人間手放すな。
どこで何の経験が活きてくるかわからないから、色々やっとくといいかも。