OmniAICreator/Qiita-1.07M huggingface dataset:
RailsのGem Active adminを使用して管理画面を作成する。

## 検索ワード
**Deviseを導入済みの場合**
rails devise active admin
http://qiita.com/cooltiger/items/205628642ed229e14ab9

active admin
active admin カスタマイズ
http://qiita.com/hkusu/items/3b0fb7f94a254e2ed6fd
http://morizyun.github.io/blog/active-admin-gem-rails/

## 実装手順
Active admin 公式サイト
https://github.com/activeadmin/activeadmin

**Gemfile**
gem 'activeadmin', github: 'gregbell/active_admin'
gem 'devise'
gem 'rails-i18n' # 無ければ

$ bundle install --path vendor/bundle

**active admin初期設定生成(Deviseを導入済みの場合、usersテーブルなど生成しないようにスキップオプション)**
$ bundle exec rails g active_admin:install --skip-users

**以下はDevise導入済みの場合**

```config/intializers/active_admin.rb
config.current_user_method = :current_admin_user
↓
config.current_user_method = :current_user(or current_company)

config.logout_link_path = :destroy_admin_user_session_path
↓
config.logout_link_path = :destroy_user_session_path
config.logout_link_path = :root_path(ログアウト後の遷移先をrootにする場合)
```

```app/application_controller.rb
def authenticate_admin_user!
  authenticate_user!

  # current_userはdevise提供のメソッドです。
  # 権限ユーザのroleについては、好きな方法でよいです。（自分の場合、has_roleメソッドで実装）
  unless current_user.has_role 'admin'
    flash[:alert] = "管理者用ページです。権限があるアカウントでログインしてください。"
    redirect_to root_path
  end
end
```

**テーブル名をAdminCompanyにしたい場合は、マイグレーションファイルを変更**
$ bundle exec rake db:migrate

・初期ユーザーを作成
http://qiita.com/Yinaura/items/6753acab94ea246e2d41

方法1.
ActiveAdminがseedファイルを用意してくれているので、

$ bundle exec rake db:seed

方法2.
rails c
AdminUser.create!(email: 'admin@example.com', password: 'password')

bundle exec rails s
ブラウザで http://localhost:3000/admin/ へアクセス

User: admin@example.com
Password: password

・Active Admin の管理対象にするモデルを指定する。
rails generate active_admin:resource inquiry(モデル名)

create  app/admin/inquiry.rb が作成される。

app/admin/inquiry.rb を編集する。
登録を許可するパラメータを以下のように追加する。
permit_params :company_name, :name, :email, :phone, :content

http://localhost:3000/admin/ へアクセスする。メニューが追加されています。

**・has_manyでアソシエーションをしているテーブルの登録**
検索ワード： active_admin has_many
http://qiita.com/ryumu/items/251bac841f1a0257eafe

```app/models/post.rb
def Post < ActiveRecord::Base
  has_many :images, dependent: :destroy
  accepts_nested_attributes_for :images, allow_destroy: true
end
```
permit_params :title, :body, images_attributes: [:image, :_destroy, :id]

## Rails 管理画面 bootstrap
Bootstrap 管理画面 レイアウト
https://www.imd-net.com/column/2760/

https://miningoo.com/785

オススメブログ
http://inter-arteq.com/tag/ruby-on-rails/
FreeNASでスタートアップスクリプトを設定する方法


## きっかけ

FreeNASにて、サーバ側でOpenVPN接続を実施し、
バックアップ先の領域をSambaマウントする案件がありました。
Sambaマウントの用途としては、Cronによる定期バックアップが主になります。
ただ要件として、万が一サーバの電源が落ち復電後に自動起動した際、
マウントまで自動で行うことが条件として上げられていました。

## 概要

サーバの環境は以下のとおりです。

<pre>
- FreeNAS 9.3
- OpenVPN(pkg コマンドでインストールされるもの、version 2.3.6)
</pre>

## 設定方法

1. 起動スクリプトで実行することはできない

	当初、 `rc.conf` に起動スクリプトを記載して実行しておりました。
	しかし、この方法では

	 「 Sambaのマウントが行えない 」

	起動完了後、sshやコンソールからrootでの実行でマウントできても、 `rc.conf` の中ではマウントできない状態に悩まされました。

2. 「Init/Shutdown Script」という起動スクリプトの存在

	FreeNAS 9.3 では、「Init/Shutdown Script」というものが利用できるようになっていました。
	これは、起動時・終了時に任意のコマンドやスクリプトを実行できる、というものです。

	FreeNASのWeb GUI画面では、
	システム -> Init/Shutdown Script -> Init/Shutdown Scriptの追加　で設定することができます。

	また、今回はCUIにて操作をしていましたが、 `/conf/base/etc/ix.rc.d/` に起動スクリプトを配置することで、設定をすることができました。

3. スクリプト例

```
#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ix-postinit
# REQUIRE: LOGIN
# BEFORE: cron

. /etc/rc.subr

mount_start()
{
    while :
    do
    /sbin/ping -c 10 10.8.0.1 > /dev/null
    status=$?
        if [ $status -eq 0 ] ; then
            /usr/sbin/mount_smbfs -N -I 10.8.0.1 -g (ユーザのGID) -u (ユーザのUID) //(Sambaユーザ名)@10.8.0.1/workgroup /mnt/(マウントポイント)
            break
        fi
    done    
}

name="ix-mount"

start_cmd='mount_start'
stop_cmd=':'

load_rc_config $name
run_rc_command "$1"
```
Perl CGI::Session->load() は呼出毎に最終アクセス時間が更新される(知らなかった

#WebSocketとCGI::Sessionのハイブリッドシステムで起こる怪奇現象
以前作った[「Perl Net::WebSocket::Server + CGI::Session で認証付きソケット作成」](http://qiita.com/Urushibara01/items/55fb464a582ce6f782e2)のシステムで、接続中の全セッションのタイムアウト処理にCGI::Session->load()を使ってタイムアウト判別を行っていました。


こんなシステムで、セッション管理と有効期限の判別にCGI::Sessionを利用。

```
誰かがWeb認証経由でWebSocketへアクセスする 
   -> セッションの有効期限が切れてる他のメンバーがいれば強制切断
```

```Perl:セッションチェック部分
sub check_session {
	# IPアドレスとポートからセッションIDを取り出す
	my $conn = $_ && $_->can("socket") || !$_[1] ? $_: $_[0];
	my $addr = $conn->socket->peerhost(). ":". $conn->socket->peerport();
	my $sid = $_ && $_->can("socket") || !$_[1] ? $clients{$addr} : $_[1];
	my $session = CGI::Session->load(undef, $sid, {Directory=>'/.session'});
	# 生存チェック
	if (!(defined $session->id) || $sid ne $session->id) {
		$conn->disconnect($conn->socket); #お前はもう死んでいる
		print "dead session: ",$sid,"\n";
		undef $user_ids{$sid};
		undef $clients{$addr}; #セッションIDも消す
		return 0;
	}
	if(!defined($user_ids{$sid})){
		$user_ids{$sid} = $session->param('u');
	}
	return 1;
}
```

しかしセッションの有効時間中に他のアカウントがアクセスすると、接続中の全セッションの_SESSION_ATIMEが更新されてしまい誰もタイムアウトになりません。

「``load()``関数は有効期限を延長させない」と過信していたのが災いしました・・・。

![image](https://qiita-image-store.s3.amazonaws.com/0/102207/fa031386-5013-22dc-13d1-2035b7584829.png)
こんな感じで全員同じ時間で更新されてます。orz

やはり、[「Node.jsでPerl CGI::Sessionで生成されたSessionIDからセッションを取得する」](http://qiita.com/Urushibara01/items/838ef50d9219033f8ad9)でやったように、perlでもCGI::Sessionを介さず、直接セッションファイルを読んだほうが確実かもしれませんね・・・。

こんな用途にCGI::Session使う人は少ないと思いますが、アクセス時間を更新しないメソッドを追加して欲しいものです。

<span class="label label-default">追記</span>

```Perl:CGI-Sessionを使わずにセッションを読む
sub getSession {
	my ($sid, $dir) = @_;
	my $filename = $dir . '/cgisess_' . $sid;
	my $text;
	if (-e $filename) {
		open (my $FILE, "<$filename") or die;
		$text = do { local $/; <$FILE> };
		close($FILE);
	}
	if($text && length($text) > 0){
		my $session = eval($text);
		#現在時刻
		my $now = time;
		#制限時間
		my $limit = $session->{_SESSION_ATIME} + $session->{_SESSION_ETIME};
		#現在時刻が制限時間を超えていたらアウト
		if($now >= $limit){
			return undef;
		}
		return $session;
	} else {
		return undef;
	}
}
```

ううんダサい。。。他にいい方法はないものか
[Linux] 共有メモリの最大値設定の確認方法

GitLabのパフォーマンスチューニング検討の関係で調査したメモ
PostgreSQLの設定値を変える前に確認が必要とのこと

# 検証環境

+ Ubuntu 16.04 x86_64 (Linux kernel 3.13.0-83-generic)

# 確認方法

| 種別 | 設定値の意味 |
|:--|:--|
| /proc/sys/kernel/shmall  | 一度にシステム上で使用可能な共有メモリー**ページ**の合計数 |
| /proc/sys/kernel/shmmax  | カーネルが許可する共有メモリー**セグメント**の最大数 [Byte] |
| /proc/sys/kernel/shmmni | システム全体の共有メモリ**セグメント**の最大数(注意: minではなくmni)  |

マニュアルやブログ記事等にはshmminも存在するとのことですが、検証環境のUbuntu16.04では見当たりませんでした。

```console:設定例(Ubuntu16.04)
$ cat /proc/sys/kernel/shmall
4194304

$ cat /proc/sys/kernel/shmmax
17179869184
$ echo $(($(cat /proc/sys/kernel/shmmax) / 1024 / 1024 / 1024 )) GB
16 GB

$ cat /proc/sys/kernel/shmmni
4096
```

以前のカーネルではわかりませんが、16GBあれば大丈夫じゃないですかね・・・？

# デフォルト設定値の定義箇所

[Linux/include/uapi/linux/shm.h - Linux Cross Reference - Free Electrons](http://lxr.free-electrons.com/source/include/uapi/linux/shm.h?v=4.9)

# 参考
[共有メモリ設定パラメータのshmallとshmmax - shibainu55日記](http://d.hatena.ne.jp/shibainu55/20090924/1253774971)
[5.4. 容量のチューニング](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-memory-captun.html)
[カーネルパラメタの調整](http://itdoc.hitachi.co.jp/manuals/3000/30003F5500/EEXD0085.HTM)
tarで「`/' を取り除きます」と言われた時の対処方法

#tarで「`/' を取り除きます」と言われた時の対処方法
tarで何かを固める時に下記のようなメッセージが出たことはないでしょうか？

```lang:
tar: メンバ名から先頭の `/' を取り除きます
```

また解凍の際もトップ、/からのディレクトリ構成になってしまうなど。
これらの事からtarは基本的に対象とした物があるディレクトリまで移動してからコマンドを実行するといった前提となっていると推測されます。

##shellの時にわざわざcd を書くのがかっこわるい or 面倒臭い
ターミナルから操作する時は100歩譲ってもshellでtar使うたびにcdなど書くのは邪魔臭いなと思ってました。
最近知ったのですが、tarには-Cオプションという「オプションで指定したディレクトリに移動してからコマンドを開始する」というものがあるようでこれで全て解決です。

```lang:
tar -C 対象のディレクトリまでのパス -czf 作成するtarのパス バックアップ対象のファイル名、ディレクトリ名など
```
eclipse 4.6でspring 4.7.3ベースのMVCプロジェクトを作成する

素人の備忘録として、eclipse4.6にSTSプラグインをインストールしてspring 4.3.7のMVCプロジェクトを作成する手順をメモしておく。
######前提環境
---
 - Eclipse 4.6.2
 - STS 3.8.3

#####作りたいプロジェクト
---
 - spring 4.7.3ベースの MVCプロジェクト

###手順
---
「Spring レガシー・プロジェクト」を選択して「次へ」。

![newProjectSelect.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/f540d7aa-3c37-75c0-b337-9d75ae0d673e.jpeg)

「Spring MVC Project」を選択して「次へ」。
![newLegacyProject2.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/d3c7372e-c47e-90c4-d25f-d1121b587b55.jpeg)

パッケージ名を指定して「完了」。
![topLevelPackage.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/33aad0fa-8454-9a4e-86df-1b083111878b.jpeg)

pom.xmlを開いて、依存関係のバージョンを変更して行く。
（テンプレートのデフォルトがspring4ベースなので、手で修正する。）
（なお、変更先のバージョンは、2017/3/16時点の最新版）

「概要」→「プロパティ」
   - java-version: 1.6 → 1.8
   - org.springframework-version: 3.1.1.RELEASE → 4.3.7.RELEASE
   - org.aspectj-version: 1.6.10 → 1.8.10
   - org.slf4j-version: 1.6.6 → 1.7.24

変更したら、保存してプロジェクトをリビルドする。

この時点では、プロジェクトのJavaビルドパスが1.6のまま（「マーカー」に警告が表示される）なので、1.8へ変更する。
「プロジェクト・エクスプローラー」の「JREシステム・ライブラリー」を右クリックし、「プロパティー」を選択する。
![projectExplorer.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/27b1c8e0-d4e7-9b27-6d5c-22f0bb040029.jpeg)

「実行環境」を「JavaSE-1.8」へ変更する。
![property.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/c70d065e-b555-1622-5208-aa3a69b603db.jpeg)

変更すると、ファセットで次のエラーが出るので、クイック・フィックスで修正する。
![problem.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/ecb5dff6-a01e-d3ff-66b7-8551b970b261.jpeg)

![quickfix.jpg](https://qiita-image-store.s3.amazonaws.com/0/170671/3f1fba61-ec60-7d02-c83e-d275e25b663b.jpeg)

これでとりあえず、エラーや警告がでなくなる。
ソースの変更は、また別の投稿で。
エリック・エヴァンスのドメイン駆動設計 読書メモ1

研修でエヴァンス本を読むという課題を頂いており、自席で読書に勤しんでおります。Scala + DDD でやっているので DDD の部分を身につけるという文脈です。読むだけだと忘れてしまうので、自分が特に重要だと感じた点に絞ってメモを残します。

## background

XP のプラクティスであるところの

- イテレーティブな開発
- ドメインエキスパートと開発者が密接に関わる

点を前提としている。

設計の方法論についての本だが開発プロセスにも言及する。設計を実践する上で開発プロセスは切り離せないため。

## 第1部 ドメインモデルを機能させる

ドメインとはソフトウェアユーザの活動、関心事のこと。ドメインをモデリングしたものがドメインモデル。
ドメインモデルを中心に据えてドメインの複雑さ、量に立ち向かおう。

モデリングは写実的であれば良いわけではない。詳細を省き、簡素化、抽象化することが重要。関心の薄いものはモデルから削除する。

ドメインモデルはコミュニケーション、分析、設計、実装において単一のものを用いることが重要。ドメインエキスパート、開発者間で通訳をなくすことで、コミュニケーションを円滑にする。
分析、開発を別の人が担当した場合、意図が伝わらない、フィードバックが得られないなどの理由により、分析と実装の間でモデルが別れてしまう。

オブジェクト指向設計というパラダイムにより、ドメインモデルを設計に反映する。（他の選択肢として論理というパラダイムでPrologに反映するという例が言及されている)

### ユビキタス言語

会話、設計書、コードを通じて一貫して使われる言葉を確立する。ユビキタス言語。開発者とドメインエキスパートがドメインモデルを確立するための対話を行うことにより確立していくことができる。モデルと言語が一致していること。
抽象化した概念を用いて実装詳細を隠蔽することでドメインエキスパートと円滑に会話できるように心がける。
声に出してモデリングすることが大事。人間に備わっている言語能力によりモデリングが助けられる。

### モデルの表現

UML のクラス図、オブジェクト相互作用図は便利。オブジェクト間の制約など表現しづらいものを自然言語で書き加える。
詳細を表現するにはコードが便利。コードを使おう。

ドキュメントは

- コードで満たされていることを重複してしない
- 最新に保つ
- モデルと結びついている

ことに留意。

### 説明用のモデル

ドメインのスコープを超えて話す場合などに、説明用のモデルが必要になる。ドメインモデルはドメインにスコープを区切っているため。
説明用のモデルはドメインモデルと表現を変えた方が良い。

## 感想

設計方法論にも関わらずプロセスまで踏み込んでしまうため違和感がある。しかし厳しい現実ではプロセスを抜きにして方法を語ることはできないという主張は納得できるところがある。

第1部を一言で表すなら「ドメインとモデルが重要。全員が使える一つの言語、一つのモデルを練り上げて複雑さに対抗しよう。」ということになるだろうか。

完読せよとのことなので、その2へ続きます(予定)。
多段SSHでも(Atom|VSCode)が使いたい！

_2018-01-12更新：VSCode派になったので、VSCodeでの方法を追加しました。_

# 背景
僕はコーディングはGUIなエディタでしたいポリシーなので、ローカルだろうがSSHだろうが2段SSHだろうが3段SSHだろうが(Atom|VSCode)を使います。

今回多段SSHのファイルを編集しないといけなくなったため、その時に行った作業をメモしときます。

以下では分かりやすいように踏み台サーバーをserver1、目的のサーバーをserver2としましょう。(いらすとやに圧倒的感謝！)

<img width="744" alt="サーバー構成" src="https://qiita-image-store.s3.amazonaws.com/0/16445/4828dbe6-661e-8504-2040-e6a5f8100c6b.png">

# 方法の検討
Atomでリモートのファイルを変更したい時に思いつく方法はこんな感じです。

### 1. [remote-ftp](https://atom.io/packages/remote-ftp)もしくは[sftp-deployment](https://atom.io/packages/sftp-deployment)を使う
これらはAtomでFTPやSFTPが使えるクライアントパッケージです。多少の機能の違いはありますが、どちらもローカルとリモートで同期が取れたりするので直接編集するのと変わらない感覚です。
ただこれらには致命的な欠点があります。**多段SSHに非対応**なのです。大事なことなのでもう一度言います。なんと、**多段SSHに非対応**なのです。

### 2. rmate + [remote-atom](https://atom.io/packages/remote-atom)で直接編集する
リモートで、``rmate hoge`` とするだけでhogeがローカルのAtomで開かれ、編集できます。vimを起動するのと同じ感覚ですね！

普段は1番の方法を使っているのですが、欠点に書いたように多段SSHに非対応なので、今回は2番の方法の手順を書きます。

# 導入手順
## リモートにrmateを導入する

まず通常どおりserver1を踏み台にserver2にSSHしましょう。
rmateを動かすのにRubyが必要なので入っていない人は入れといてください。
rmateをPATHの通ってる場所にダウンロードします。特に理由がなければ``/usr/local/bin``で良いでしょう。

```bash
$ # server2にて
$ curl -o /usr/local/bin/rmate https://raw.githubusercontent.com/aurora/rmate/master/rmate
$ sudo chmod +x /usr/local/bin/rmate
```

## [Atom] ローカルのAtomにremote-atomを入れる
Atomのパッケージインストーラ(Settings > Install)で"remote-atom"を検索してインストールしましょう。
<img width="744" alt="atom package installer" src="https://qiita-image-store.s3.amazonaws.com/0/16445/f9df3c17-53b2-b5f5-4227-1a59c36ef4c8.png">

## [VSCode] ローカルのVSCodeにRemote VSCodeを入れる
<img width="696" alt="スクリーンショット 2018-01-12 19.16.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/16445/9c7f0313-8161-ddda-8988-721a53dc6706.png">

## SSHポートフォワーディングの設定
rmateをつかってローカルのAtomにデータを転送するためにSSHのポートフォワーディングを使います。ポートはデフォルトでは52698番が使わますが、変更も可能です。
ローカルの``.ssh/config``に以下の設定を追加します。ファイル未作成の人は作成してください(permissionは600)。また、[公開鍵認証](http://qiita.com/HamaTech/items/21bb9761f326c4d4aa65)はすでに設定してある前提です。

```.ssh/config
Host server1
    HostName        server1のホスト名
    User            server1のユーザー名
    IdentityFile    server1の秘密鍵のパス
Host server2
    HostName        server2のホスト名
    User            server2のユーザー名
    IdentityFile    server2の秘密鍵のパス
    ProxyCommand    ssh -W %h:%p server1
    RemoteForward   52698 127.0.0.1:52698
```

# 使ってみる

## [Atom]
Atomを起動した状態で

```bash
$ ssh server2
$ rmate hoge
```

これでhogeがAtomで開かれれば成功です。

## [VSCode]
VSCodeを起動した状態でコマンドパレットを開き、`Remote: Start Server`を選択します。
<img width="600" alt="スクリーンショット 2018-01-12 19.19.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/16445/3961cab6-3aa8-4fe7-73a5-e4dbfff1600f.png">

エディタの右下にこんなマークが出ていたら待ち受けています。
<img width="29" alt="スクリーンショット 2018-01-12 19.19.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/16445/c934e22c-6c5c-9f74-9dbc-b7f222bfee0b.png">

```bash
$ ssh server2
$ rmate hoge
```

これでhogeがVSCodeで開かれれば成功です。

# おまけ
`.bashrc`とかにこれを書いておくとatom感、VSCode感が増します。

```bashrc
alias ratom=rmate
alias rcode=rmate
```

幸せな(Atom|VSCode)ライフを！

※Sublime Textでもrsubパッケージを使うことで同じことが出来ます。
FuelPHPのタスクをcrontabで実行する

#環境、プロジェクトを指定して実行する方法
##myapp1(production), myapp2(development)が同じサーバにあり、myapp1を選んで実行するサンプル

```
* * * * * FUEL_ENV=production php /path/to/myapp1/oil refine taskname
```

`FUEL_ENV=production`
は無くても大丈夫だと思う。このサンプルでは、myapp1のbootstrap.php内で環境判定をしているんだけど、タスク実行ではdevelopmentに判定されるようになっているため、強制的に指定している。
macOS の grep が遅い

macOS の grep が遅いので計測したメモ。
OS は、macOS Sierra Version 10.12.3 というバージョンでした。

適当なデータがなかったので、こちらから拝借したcsvを少し加工して ken.csv として利用。
http://www.post.japanpost.jp/zipcode/dl/roman-zip.html


# grep (BSD grep) 2.5.1-FreeBSD
BSD 版の grep です。多分もともと入っているやつ。

Average: 0.336

```
sh -c '\grep -i aoyama ken.csv > /dev/null'  0.32s user 0.01s system 96% cpu 0.347 total
sh -c '\grep -i aoyama ken.csv > /dev/null'  0.32s user 0.01s system 97% cpu 0.339 total
sh -c '\grep -i aoyama ken.csv > /dev/null'  0.30s user 0.01s system 97% cpu 0.322 total
sh -c '\grep -i aoyama ken.csv > /dev/null'  0.31s user 0.01s system 96% cpu 0.333 total
sh -c '\grep -i aoyama ken.csv > /dev/null'  0.31s user 0.01s system 97% cpu 0.336 total
```


# ggrep (GNU grep) 2.28
GNU 版の grep です。Homebrew でインストールしました。

```
brew update
brew tap homebrew/dupes
brew install homebrew/dupes/grep
```

Average: 0.0176

```
sh -c '\ggrep -i aoyama ken.csv > /dev/null'  0.01s user 0.01s system 63% cpu 0.025 total
sh -c '\ggrep -i aoyama ken.csv > /dev/null'  0.01s user 0.01s system 61% cpu 0.021 total
sh -c '\ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 59% cpu 0.014 total
sh -c '\ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 56% cpu 0.015 total
sh -c '\ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 53% cpu 0.017 total
```


# LANG=C ggrep
`LANG=C` 付き。

Average: 0.0136

```
sh -c 'LANG=C \ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 59% cpu 0.013 total
sh -c 'LANG=C \ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 65% cpu 0.014 total
sh -c 'LANG=C \ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 60% cpu 0.013 total
sh -c 'LANG=C \ggrep -i aoyama ken.csv > /dev/null'  0.01s user 0.01s system 59% cpu 0.025 total
sh -c 'LANG=C \ggrep -i aoyama ken.csv > /dev/null'  0.00s user 0.00s system 61% cpu 0.014 total
```


# ag (The Silver Searcher)
@sugitk さんからコメントをいただいたので、メモを追加。
Homebrew でインストールしました。

```
brew install the_silver_searcher
ag --version
ag version 1.0.2

Features:
  +jit +lzma +zlib
```

Average: 0.0723

```
sh -c 'ag -i aoyama ken.csv > /dev/null'  0.04s user 0.02s system 86% cpu 0.076 total
sh -c 'ag -i aoyama ken.csv > /dev/null'  0.05s user 0.02s system 85% cpu 0.090 total
sh -c 'ag -i aoyama ken.csv > /dev/null'  0.04s user 0.02s system 87% cpu 0.070 total
sh -c 'ag -i aoyama ken.csv > /dev/null'  0.04s user 0.02s system 87% cpu 0.071 total
sh -c 'ag -i aoyama ken.csv > /dev/null'  0.04s user 0.02s system 87% cpu 0.068 total
```
古いVAIO S15をHDDからSSDにした時のメモ

# 状況

Windows7世代の古いVAIO S15のHDDがエラー頻発で限界ぽいので
SSDへの換装を試みた際のメモ


# 準備

元HDDのエラーを修復しておきます。
コマンドプロンプトから

```
chkdsk /f
```

を実行。これでも今回はエラーが修復できなかったので更に

```
chkdsk /r
```

で不良セクタをチェック。通常は　/f　だけで十分です。


# 購入したもの

いずれもAmazonで。

### samsung ssd 250GB 750 EVO
- １万円くらい。８５０より省電力

### Cyberplugs SATA-USB 3.0 変換アダプタ　　　　
- USB3.0端子にこのケーブルで素っ裸のSSDをぶっさすだけです。1000円くらい。


# クローン

ソフトウェアは市販からフリーまで色々ありますが
色々試した結果、一番高速でお手軽だったのは結局、SAMSUNG純正の

Samsung Data Migration

でした。
パッケージに付属してませんが、ググって公式サイトからダウンロードできます。（無料）

SAMSUNG製品以外のSSDには使えないのかな？　（未確認）


# 問題発生

クローン作業自体は数十分で終わります。成功します。
しかし、HDDをSSDに交換してPCを再起動すると

```
operating system not found
```

みたいなメッセージが出るだけでブートできません。ギャフン！

どうもVAIO S15はドライブの最初のパーティションの先頭エリアをチェックするみたいで
そこがクローンするだけでは（データの引っ越しはできても）
ブート可能な領域として認識されないようでして。。。


# 修復

リカバリーメディアを用意して、
必要であれば電源ONしてすぐF2キーを押して
BIOSメニューから光学ドライブからブートするよう優先順位を上げておきます。

で、リカバリーメディアでブートしたあと
OSの修復に進むと、すぐに作業が完了します。

この後、メディアを取り出して
先程変更したBIOSの設定も元に戻して再起動すれば
引っ越したSSDからブートできるはずです。


# おまけ

別のVAIO S15でも似たような状況が発生したんですが
そちらはリカバリーメディアを用意してなくて。。。

しかもWindows7から10へアップデート済で
VAIO careのメニューからリカバリーメディア作成を選んでも
純正HDDから別のHDDへ交換済でリカバリー領域がHDDに残ってない。と。

なんとか純正HDDを探し出したんですが
外付けHDDとして流用しててOSエリアがパー。

ディスク管理からパーティションを確認すると
先頭にリカバリー領域は残ってる。
でもOSはもうないからこのHDDからはブートできない。

ダメ元で
純正HDDを外付けHDDとして接続した状態で
VAIO careからリカバリーメディア作成メニューをすすめると。。。

なんと外付けHDDのリカバリー領域からリカバリーメディアを作成できましたｗ　
セフセフｗｗｗあぶねぇｗｗｗｗｗ

WindowsPCを買ったら最初にリカバリーメディアは作っておきましょうね。
実サービスでの機械学習の活用に関するサーベイ

機械学習の仕組みはわかったけど、実際のサービスではどういう風に使われているんだろう？
学習の環境って、自前でGPUを買っているんだろうか。それともクラウドが主流なんだろうか？

というような実務における利用方法や開発に関する疑問は、誰しも一度は抱いたことがあるのではないかと思います。私自身疑問に思っていて、実務への活用を考えている方向けの講習を担当するにあたり、思い切ってアンケートを取ってみました。

対象は実務で機械学習を利用している方で、32の回答を得ることができました(ご回答頂いた方、ありがとうございました！)。なお、回答はTwitter/Facebookなどで募ったため、サンプリングバイアスが存在する可能性がある点についてはご留意を願います。
以下で、その結果について所見を交えながら公開をしたいと思います。
※生のアンケート結果も公開したかったんですが、自由記述の回答にプライバシー的な情報も含まれていたため、生データへのリンクを割愛しました。

# Q1.機械学習の利用用途を教えてください

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/78b3809b-c54f-7d7d-d73c-1d763fc805e1.png)

こちらは、「そもそもどんな目的で機械学習を利用しているのか？」を聞くための設問でした。レコメンドやカスタマーサポートの改善への利用は事例としても多いため納得の数字でしたが、製造業務の改善も結構伸びているのは意外でした。この辺りは(まことしやかな)ソリューションは多く売られているけれど実活用はまだ、という印象を持っていたのでここまで伸びてくるのは個人的には驚きでした。

# Q2.顧客への機械学習の提供形態を教えてください

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/5e21e80a-1ce5-ddb6-a80f-863bfc246700.png)

これは、機械学習と一口に言っても様々な提供形態があるため、それを確認するための設問でした。自社サービスへの組み込みが一位で、「自社サービスの改善に利用する」という用途が多いことが想定できます。個人的には機械学習コンサルのような形も多いかなと思っていたんですが、あまり伸びてこなかったです。

# Q3.利用している機械学習の分野について教えてください

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/264e2123-03de-0bd6-5681-3c6a497d1ec8.png)

これは活用されている技術の分野を問うための設問でした。画像と自然言語がやはり二台巨塔ですが、ここで確認したかったのはGANやNeural Conversational Modelのようないわゆる「生成系」の技術がどれくらい実サービスで使用されているか、でした。結果はまだあまり例がなく、やはり認識系の活用が中心ということがわかりました。
意外だったのが強化学習も5件ほどあったことです。広告のバンディット系かロボット制御か・・・そこまでは取ってなかったのでわかりませんが、私も実務で使ってみたいです。

# Q4.機械学習の学習に使用している環境について教えてください

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/ea7fdc44-f412-47df-86e4-b43d2ba16391.png)

これは機械学習の学習ってみんなどこでやっているの？というのを確認するための設問でした。結果は圧倒的に自社環境！やはりサービスで真面目に使うならしっかり環境構築を行うのが良いようです。ただ、各社GPU環境に力を入れているので、これは今後割合が変わってくるかもしれません。

# Q5.機械学習のためのデータの取得先について教えてください

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/0360537f-be9a-445b-ed36-248c4bf34e5c.png)

これは機械学習における大きな問題である、「データはどうやって用意するか？」という点について確認するための設問でした。自社データはもちろんですが、オープンデータとスクレイピングもかなり健闘しています。最初はもちろんデータがないところからスタートするので、どういった公開データがあるのか知っていること、そして(あまりおおっぴらにはやれませんが)スクレイピングの技術はデータを集める上で重要と言えると思います。

# Q6.機械学習に関する頭の痛い出来事を教えてください。

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/6a19cc27-8917-f31a-4c85-463e1cce2a6d.png)

これは個人的にも悩んでいる点について、どれくらい共感度があるのかを図る設問でした。やはり「データ」と「人材」の問題。これはどこでも頭の痛い問題なようです。次点として出てきた「精度が出ない」、そしてやはり出てきた「なんでもできると思われて説明に苦労する」というのも悩みどころとして多いようです。
この分野では新しい機械学習フレームワークや手法が続々登場していますが、その意味ではフレームワーク・手法の変化が速すぎる、というのがあまり伸びないのは意外でした。実務上では、おそらく決まったものが数個ありそれ以外のものを追うということはあまりないのかもしれません(個人観測範囲では、DNN系ではTensorFlow/Chainerでほぼ固まっている感じがあります(国内のみ))。

それと機械学習は成果が確約しにくいため受注金額や契約で結構問題があったりするのかなと思ったのですが、ここはあまり伸びなかったです。そもそも自社サービスに活用している割合が多いので、ここもそんなに伸びていないのかもしれません。

# Q7.その他ご意見

自由記述の設問であまり記入はなかったのですが、採用・そして育成をどうやるかという問題、また人が入力したデータに含まれる一貫性のなさ(ノイズ)などが頭の痛い問題としてあげられていました。
また、自然言語では成果が出たモデルについて「日本語で通用するのか？」という問題もあるという記載もあり、確かにここは難しい点だなと思いました。

いかがだったでしょうか。この結果が、「現場の機械学習」をより具体的にイメージするのに役立てば幸いです。うちではこうしている！といったようなお声があれば、ぜひコメントを頂ければと思います。
【自分用メモ】IE11以前について（2017年4月11日にサポート終了）

2017年4月11日の Windows Vista の延長サポート終了に伴い、IE11 以前のサポートが終了します。
が、さくっと簡単にズバッと検証対象ブラウザから切れたら最高だよね！！（そうは問屋が卸さないよ！）おそらく、まだまだ使われるんだろうなーと思われる古いブラウザについてのメモ。
※個人的な見解です。


##●IE9
まだしばらくの間は対応が求められるかも。（公共性の高い企業や社内システムの問題、対象ユーザー層を考慮）
特にガイドラインがある場合は、改定のタイミングを待つため、すぐには変更できなさそう。

**新しいことをゴリゴリやりたい企業サイトなどでは、もちろん IE11 推奨で！！**


##●IE7、IE8、IE10
Windows Vista・7・8 で現在も動作しますが、2016年1月13日にすでにサポート終了済み。
去年の夏頃からあまり聞かなくなった。公式サポート終了のアナウンスすごい。

なお、弊社にある IE8 が動作していた Windows 7 ノートは、「バッテリーから発火の恐れがある」というエラーが出ています。ハードがもう限界w


##●シェア
まだまだ XP がつよい。3位て！　IE8〜10 を合計すると 7% もあるので、これを完全に切るのは少し怖い気もする...。（もう全部サポート切れてるけどな！セキュリティとか大丈夫なの？）

・Windows 7が依然として人気 - 2月OSシェア | マイナビニュース
[http://news.mynavi.jp/news/2017/03/02/110/](http://news.mynavi.jp/news/2017/03/02/110/)
> **Windows 10 ： 25.19% （2位）**
> Windows 8.1 ： 6.87% （4位）
> Windows 8 ： 1.65% （7位）
> **Windows 7 ： 48.41% （1位）**
> Windows Vista ： 0.78% （10位）
> **Windows XP ： 8.45% （3位）**

・Chromeの増加続く - 2月ブラウザシェア | マイナビニュース
[http://news.mynavi.jp/news/2017/03/02/126/](http://news.mynavi.jp/news/2017/03/02/126/)
> IE11 ： 11.51%
> IE10 ： 0.88%
> IE9 ： 3.08%
> IE8 ： 3.18%
> IE7 ： 圏外（0.72%以下）


##まとめ（仮）
「IE7、IE8、IE10」の公式サポート終了後の動向からして、だいたい半年後ぐらいで制作時の検証対象ブラウザから IE9 を切っても大丈夫そうだと想像しています。
4〜5月のブラウザシェアの推移を見てから、改めて考え直したいです。


　
###［参照］ 
####●各Windows OS と IE のバージョン対応についての記事

・IEのサポート期限まとめ - Qiita
[http://qiita.com/sawadays0118/items/41bab56358742fe2a646]
(http://qiita.com/sawadays0118/items/41bab56358742fe2a646)

・Tech TIPS：一目で分かる、各Windows OSでのInternet Explorerのサポート終了時期 - ＠IT （2015年12月）
[http://www.atmarkit.co.jp/ait/articles/1503/11/news134.html](http://www.atmarkit.co.jp/ait/articles/1503/11/news134.html)

・Tech TIPS：古いInternet Explorerは2016年1月にサポート終了！ その対策は？ - ＠IT （2015年12月）
[http://www.atmarkit.co.jp/ait/articles/1507/13/news025.html]
(http://www.atmarkit.co.jp/ait/articles/1507/13/news025.html)
「間もなくサポートが終わる「古い」IEと、サポートが続くIEの各バージョン」の表がわかりやすい。

・Tech TIPS：各Windows OSで利用できるIEのバージョンを知る - ＠IT （2015年07月）
[http://www.atmarkit.co.jp/ait/articles/1405/30/news092.html](http://www.atmarkit.co.jp/ait/articles/1405/30/news092.html)
- （図より） Windows XP は IE6〜IE8 まで対応していました。
- Windows 8 では IE11 を利用できない（同梱の IE10 のみ）

・歴代Windows
[http://wakouji.sakura.ne.jp/ugoke_windows/ugoke3/pcsub56.htm]
(http://wakouji.sakura.ne.jp/ugoke_windows/ugoke3/pcsub56.htm)
- Windows XP は 2014年4月8日までのサポートだった模様。

　
####●制作者向け

・備忘録_IE7 / IE8 / IE9 対策 - Qiita
[http://qiita.com/y_sekitoba/items/2d41fa6c89aeed71cefb](http://qiita.com/y_sekitoba/items/2d41fa6c89aeed71cefb)

・備忘録_IE7 / 8 / 9 バージョン別使用できるセレクタまとめ - Qiita
[http://qiita.com/y_sekitoba/items/6cf6e5b9c1f410ecdea1](http://qiita.com/y_sekitoba/items/6cf6e5b9c1f410ecdea1)

・flexbox in IE9 - Qiita
[http://qiita.com/feo52/items/1cd0e6a24ea1ae50b1e9]
(http://qiita.com/feo52/items/1cd0e6a24ea1ae50b1e9)

・古の技術になりつつあるIE8・IE9対応でやること、使えないもの - Qiita
[http://qiita.com/nyawach/items/db480f176b165ae05528]
(http://qiita.com/nyawach/items/db480f176b165ae05528)
変数名と値を同時に表示する bash 関数（小ネタ）

Bash で、変数名とその中の値を同時に表示する関数（declare -p みたいなの）を書いてみました。

# コード
単刀直入に、こんな感じ。

```bash
print_var()
{
    [ -n "$1" ] && printf "%7s : %s\n" "$1" ${!1:-(null)}
}
```

### ポイント
- `${!1}` の部分で、第１引数の間接展開（indirect expansion）しています。bash でない場合は `$(eval echo '$'$x)` とかしないといけないですが、`!` だけで済む Bash は便利ですね！
- `:-(null)` の部分で、間接展開の結果が空だった場合、"(null)" という文字列を代わりに利用しています。


# 実行してみる
以下のスクリプトを実行してみました。

```bash:print_var.sh
#!/bin/bash

print_var()
{
    [ -n "$1" ] && printf "%7s : %s\n" "$1" ${!1:-(null)}
}

print_var

print_var some_var

some_var=4
print_var some_var
```

### 結果

```shell-session
$ ./print_var.sh
some_var : (null)
some_var : 4
```

期待通り、動作しているようです。 :smiley:
giboのreadme版を作ってみた

# TL;DR

giboをコピーしてREADME.mdを生成するreboを作った。

# 説明

- requirements
    - bash
    - (giboが動く環境ならOK)


もうgithubでREADME.mdをイチから書くの面倒くさい！ということで、giboのように生成するreboを作成。~~というかgiboのソースをコピーして書き換え。~~

```bash
# install

$ curl -O https://raw.githubusercontent.com/imasami/rebo/v1.0.0/rebo

# run

$ rebo heroku_button general
```


# リポジトリ

https://github.com/imasami/rebo

# その他

- 同じようなアプリが他にあれば教えてください、ソレ使います。
- 要望はfork&pullreqで受付けます
Azure でカスタムイメージを作成したときのメモ

# 概要

カスタムイメージを作ったときに何をしたかをメモしておく

# 前提

あらかじめ、Azure上にAzureで提供されているイメージから、必要な状態にしたマシンを作製しておく

# 結論

2017年3月17日の時点では、このページをみればよかった。

## PowerShell の場合
* [一般化された Azure VM からの VM イメージのキャプチャ | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-machines/virtual-machines-windows-capture-image)

## Azure CLI 1.0 の場合

* [テンプレートとして使用する Azure Linux VM をキャプチャする | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-machines/virtual-machines-linux-capture-image-nodejs?toc=%2fazure%2fvirtual-machines%2flinux%2ftoc.json)

## Azure CLI 2.0 の場合

* [Azure CLI 2.0 を使用した Linux VM のキャプチャ | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-machines/virtual-machines-linux-capture-image)

# 実際の作業

今回は Azure CLI 2.0 の方法を、Azure CLi 0.10.6 (docker)で実行し、
途中から Azure CLI 1.0 の方法に切り替えた。
作業はじめたときに見落としていたので。

```
azure config arm
```

なっている前提

## 1. 元となるVMのプロビジョニングを解除する



```
azureuser@standalonevm:~$ sudo waagent -deprovision+user -force
WARNING! The waagent service will be stopped.
WARNING! All SSH host key pairs will be deleted.
WARNING! Cached DHCP leases will be deleted.
WARNING! Nameserver configuration in /etc/resolvconf/resolv.conf.d/{tail,original} will be deleted.
WARNING! azureuser account and entire home directory will be deleted.
```

メッセージを読むと、SSH の鍵などが削除されるとある。

このコマンドの実行後確認してみた

```
azureuser@standalonevm:~$ ls -lar
total 0
```

## 2. azure vm deallocate で VM の割当を解除

sshを接続したままで、以下のコマンドを実行すると、sshの接続が解除されるので、
なにか作業があるときは、早めに行っておくこと。

```
azure vm deallocate --resource-group TESTRESOURCEGROUP1 --name standalonevm
```

数分ほど時間がかかって、終了した

```
azure vm deallocate --resource-group TESTRESOURCEGROUP1 --name standalonevm
info:    Executing command vm deallocate
+ Looking up the VM "standalonevm"                                              
+ Deallocating the virtual machine "standalonevm"   
```

## 3. azure vm generize で一般化する

このコマンドは、すぐにおわった

```
root@3371f3750d51:/# azure vm generalize --resource-group TESTRESOURCEGROUP1 --name standalonevm
info:    Executing command vm generalize
+ Looking up the VM "standalonevm"                                              
+ Generalizing the virtual machine "standalonevm"                               
info:    vm generalize command OK
```

## 4. azure vm capture で、VMをキャプチャする

これは
* [テンプレートとして使用する Azure Linux VM をキャプチャする | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/virtual-machines/virtual-machines-linux-capture-image-nodejs?toc=%2fazure%2fvirtual-machines%2flinux%2ftoc.json)
これの 5 に相当する

```
root@3371f3750d51:/# azure vm capture -g TESTRESOURCEGROUP1 -n standalonevm -p standalonevm -t standalonevm.json
info:    Executing command vm capture
+ Looking up the VM "standalonevm"
+ Capturing the virtual machine "standalonevm"
info:    Saved template to file "standalonevm.json"
info:    vm capture command OK
```
当たり前だけどハマった－2進数の世界で小数計算

# 何が起きたか

``` JavaScript
var d = 1;
obj.setPoint(1717 * Math.pow(0.1, d));
```
なんてコードを書いたら「171.7」ってセットされる。
と思ってしまった。
でも、実際には「171.70000000000002」がセットされた。

# どうして？

理由は簡単、コンピュータは2進数の世界で動いてます。
なので2進数で表現しきれないものは誤差が出る。
当たり前。。。
小数なんか使うから(。´･ω･)

# どうする？

小数を使わずに整数にしてから桁移動させればいいんじゃない？
っていうのが一般論なんだろうくらいによく言われてる。
でも、今ははなから桁移動させたいだけ。
整数にするなんてあまりにイケてない。

# どうしたか

小数の掛け算するからおかしくなるんで、整数で割ることにした。

``` JavaScript
var d = 1;
obj.setPoint(1717 / Math.pow(10, d));
```

これできれい。
[Laravel 5.2] Laravelでtest用DBにmigrateする方法

Laravel入門者の備忘録です。

# テスト用DBの設定を記載します。
mysqlでもpostgresでもsqliteでもなんでもいいｄせうが、surfixに `_testing`をつけておくとわかりやすいです。

```php:config/database.php
 'mysql_testing' => [
   'driver'    => 'mysql',
   'host'      => env('TESTING_DB_HOST', 'localhost'),
   'database'  => env('TESTING_DB_DATABASE', 'forge'),
   'username'  => env('TESTING_DB_USERNAME', 'forge'),
   'password'  => env('TESTING_DB_PASSWORD', ''),
   'charset'   => 'utf8',
   'collation' => 'utf8_unicode_ci',
   'prefix'    => '',
   'strict'    => false,
  ],
```

# 環境変数の設定
```php:.env
TESTING_DB_HOST=localhost
TESTING_DB_DATABASE=homestead_testing
TESTING_DB_USERNAME=homestead
TESTING_DB_PASSWORD=secret
```

# command
```
php artisan migrate --database=mysql_testing
```

# 参考
- https://laracasts.com/discuss/channels/general-discussion/how-to-migrate-a-testing-database-in-laravel-5
[Laravel 5.2] Laravelでテスト用のDBを指定する方法

laravel入門したてでわからないことばかりな人の備忘録です。

# 環境変数を使って、デフォルトで使用するDBを指定

```php:config/database.php
<?php

return [

    //

    'default' => env('DB_DEFAULT', 'mysql'),

    'connections' => [

        'sqlite_testing' => [
          'driver'   => 'sqlite',
          'database' => ':memory:',
          'prefix'   => '',
        ],

        'mysql' => [
          'driver'    => 'mysql',
          'host'      => env('DB_HOST', 'localhost'),
          'database'  => env('DB_DATABASE', 'forge'),
          'username'  => env('DB_USERNAME', 'forge'),
          'password'  => env('DB_PASSWORD', ''),
          'charset'   => 'utf8',
          'collation' => 'utf8_unicode_ci',
          'prefix'    => '',
            'strict'    => false,
          ],
        ],

    //
];
```

# Testの際に使用するDBを指定
putenvでDB_DEFAULTを書き換えます

```php:tests/unit/TestCase.php
<?php namespace UnitTests;

use Illuminate\Support\Facades\Artisan;

class TestCase extends \Illuminate\Foundation\Testing\TestCase
{

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        putenv('DB_DEFAULT=sqlite_testing');

        $app = require __DIR__ . '/../../bootstrap/app.php';
```

# 参考
- https://laracasts.com/discuss/channels/testing/how-to-specify-a-testing-database-in-laravel-5
C++ Builder XE4, 10.2 Tokyo > フォーム表示時にデフォルト フォーカスになるボタンを設定する > フォームの ActiveControlプロパティに設定する / FormShow()にてSetFocus()する

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/28)
```

複数のボタンがある時、フォーム表示に一番最初にフォーカスがセットされるボタンを指定したい場合がある。

### 方法1. フォームの ActiveControlプロパティ

http://stackoverflow.com/questions/15428004/how-to-force-a-focus-on-a-component-before-the-form-is-shown
を見ると、フォームの ActiveControlプロパティに指定すればいいようだ。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5e8e8f13-49f3-9a40-5f28-c00603f2b1cf.png)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/da832bf1-719d-ce23-5816-791980f05aa0.png)

こちらの方法の場合、フォームをボタンで閉じてから再表示した時に、閉じる時に使ったボタンにフォーカスが移っている。

### 方法2. FormShow()にてSetFocus()する

FormShow()において以下のようにする。

```
Button3->SetFocus();
```

こちらの方法の場合、フォームをボタンで閉じてから再表示した時に、Button3にフォーカスが移っている。
Djangoモデル属性命名のコツ

Djangoで開発する際に重要な、Model命名規約の標準を検討しました。

# モデル命名について

* キャメルケースで書く
* トランザクション/マスタなどModelごとの区別が出来るようにするため、接頭語を設ける
  * マスタには `Mst` とつける
  * 連携用モデルには、 `Itfc` とつける
  * トランザクションには接頭語をつけない
   
* プロジェクトの特性にもよるが、英単語の方が望ましい

# 属性名について

* スネークケースで書く
* 以下の接頭語/接尾語を使う
* そのモデルの名前、コード、番号を表すのであれば、接頭語/接尾語を使わず `name` , `cd` などシンプルな属性名にする(以下、例の通りコードがシンプルで直感的になる）

| 属性の種類       |  命名     |  備考     |
|:-----------------|:--------|:--------|
| 名前            |*_name |自分のモデルの名前の場合は、 `name` |
| コード           |*_cd |自分のモデルのコードの場合は、 `cd` |
| ID          |*_id | |
| 番号, No          |*_no |自分のモデルの番号の場合は、 `no` |
| 日にち          |*_date ||
| 日時          |*_dt ||
| 数値          |*_num ||
| 区分値          |*_type ||
| 真偽値, フラグ          |is_* ||
| ファイル          |*_file ||
| ForeignKey      | 参照先の属性名をスネークケースで書く ※1||
| ManyToManyField      | 参照先の属性名をスネークケースで書き、複数形にする ||

※1 ForeignKey はテーブルのカラムになると、属性名 + _id が自動付番される。参照先のモデル名を付けるとテーブルになった時に自然な名前になる

# 主キーについて

Djangoでは、モデルに主キーを明示的に設定しない場合は、id というカラムが作られ、連番が自動で付番される。
ケースによりますが、経験的には以下の様に使い分けると良い。

* マスタデータはなるべくこの連番を使わず、明示的に主キーを割り当てた方が良い。
* トランザクションデータは、この連番を使った方が良い。

# 例

以下の例で、cd, name を item_cd, item_name などと名付けてしまいがち。

```python:models.py

class Item(models.Model):
    cd = models.CharField("コード", max_length=10)
    name = models.CharField("名前", max_length=100)
    material_type = models.CharField("原材料区分", max_length=1, choices=ITEM_TYPE_CHOICES)
    is_enabled = models.BooleanField("有効フラグ", )
    factory = models.ForeignKey(Factory, verbose_name=_("工場"), null=True, blank=True)
    
```

```python:

item = Item(cd="i01", name="品物１", ・・・) 

# cd, nameなどの名前にすると簡潔になる
print(item.cd)
print(item.name)

# item_cd, item_name だとくどい
print(item.item_cd)
print(item.item_name)

# ForeignKey が絡むと更に簡潔さが増す
print(item.factory.name)

```
JAWS DAYS 2017 IoTハンズオン【後半】参加報告

# JAWS DAYS とは

- 日本の Amazon Web Services（以下AWS）のユーザーグループ最大のイベント。今年で5回目。詳細は[公式ページ](http://jawsdays2017.jaws-ug.jp/about/)参照。
- 今年は 3/11 （土) TOC五反田メッセでの開催でした。

# IoTハンズオン【後半】 とは

- Raspberry Pi に温度センサーつなげて、そのデータを時々刻々と AWS にアップロードし、AWS の QuickSight で可視化してみれるようにする、という一連の流れをハンズオンで参加者が手を動かして確認していく内容でした。

- 参加者の進捗は Google Document に記入して、下記の Qiita の記事に沿って作業していきました。
- 前半が Raspberry Pi に温度センサーつないで温度データを Firehose を使って S3　に投げ込んでくまで、後半が S3 上のデータを Athena, QuickSight で可視化するところまでです。
 - [RaspberryPi + Athena + Quicksightで可視化する＜前編＞](http://qiita.com/Ichiro_Tsuji/items/d366203c3621e6c15def)
 - [RaspberryPi + Athena + QuickSightで可視化する＜後編＞](http://qiita.com/ha_ru_ma_ki/items/ee77b3755ef50181bba4)

# 当日

- 当日まず、Raspberry Pi に差し込む用に会場ルーターが飛ばしている WiFi に接続する無線LAN設定がされた MicroSD カードが渡されるのですが、会場 WiFi の調子が悪いためか、 接続が困難でそこでつまづきました。
- IPアドレスごとに繋がりやすさに差があるようでしたので、途中で MicroSD　カードを別IPのものに交換してもらったらようやくまともにつながるようになりました。そのおかげで当日の時間内には前半部分までは完遂できました。
- こう聞くと「なんじゃそりゃ。ネットワークに繋がらないんじゃ全くお話にならないじゃないか」と思うかもしれませんが（ホントその通りです）、そもそも IoT とかハード・インフラ関係ではそうした泥臭い側面が常に付いてまわるのではないかという印象を持ちました。そういう意味では勉強になりました。

# 帰宅後
- 後半まで完遂し、家の部屋の温度モニタリングできるようになりました。
![スクリーンショット 2017-03-16 15.08.08.png](https://qiita-image-store.s3.amazonaws.com/0/92806/a4fe1396-a352-b4a3-7d83-78e3bca26b62.png)

- 例えば、3/15 夜ですが、10時頃に家に帰ってから部屋の暖房つけたため、約20℃ から 24℃ へと温度が上がっていく様子が見て取れます。これでいつでも外から自分の部屋の温度を確認することができますね。
- こんな感じで部屋の端のところに邪魔にならないように置いてます。ブレッドボードの黒いカマボコ形の素子が温度センサーです。
![aaa.jpg](https://qiita-image-store.s3.amazonaws.com/0/92806/c5f6c5bf-6508-0314-8afa-634727f6548e.jpeg)

# 今後
- 個人の遊びでやっているものなので、もし今後も続けて運用していくとすると、どの程度のコストがかかるのかという点を押さえておく必要があります。 [QuickSight の料金表](https://quicksight.aws/pricing/) や[AWSの料金表まとめ記事](http://qiita.com/teradonburi/items/a382a17e1e0245b7d831)等その他で適宜確認してこうと思います。
- 以上、ざっくりですが、JAWS DAYS 2017 IoTハンズオン【後半】参加報告でした。
【自分用まとめ】Flexboxでいつもぐぐるやつ

なんだかんだで毎回いっつもググってる気がするので、自分用まとめ。


floatより辛くない「flexbox」でざっくりレイアウトhttp://qiita.com/hashrock/items/939684b9207dbab1d59e

flexboxのバグに立ち向かう（flexboxバグまとめ）
http://qiita.com/hashrock/items/189db03021b0f565ae27

たった4行！ CSS3 Flexboxを使った史上最短の上下中央揃え2016年版
http://qiita.com/tonkotsuboy_com/items/a5aaa4a69fecfaf546a3

IE11のバグまとめ
http://qiita.com/sawadays0118/items/bd0731878e9eb49c03f5
迷路は幅優先探索？

# 迷路を解く

アルゴリズムの基本問題に迷路を解くというものがあります。
迷路をグラフの一種とすることで、グラフの探索アルゴリズムが使えます。
基礎的なグラフの探索アルゴリズムに幅優先探索と、深さ優先探索があります。

# 幅優先探索と深さ優先探索

それぞれ、どのように動作するのか見てみましょう。
まずは、空の迷路を幅優先探索で解いてみます。

左上をスタート、右下をゴールとすると、探索済みのセルを水色に塗ってます。
幅優先探索だと水が広がるように、探索が進んでいきます。これは、スタート地点から近いセルの順に見ていくというアルゴリズムだからです。余談ですが、幅優先探索は絵の塗りつぶしにも使われてます。
幅優先探索が迷路に向いてるのは、それぞれのセルに最短の前のセルと、そこまでの移動回数を保存しておくことで、迷路を解くと同時に最短経路も割り出せるからです。

![map_empty_bfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/2a42a0fc-f242-7560-04e2-a6021095f888.gif)

こちらは、猪突猛進　　深さ優先探索です。とにかく自分がいる場所から先に進んでいきます。
どちらのアルゴリズムでも全部のセルを探索してますが、深さ優先探索の場合の経路は無駄が大きいですね。

![map_empty_dfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/67c7ea78-36e1-c0c3-d609-16366cfadb0d.gif)

まぁ、でも迷路によっては特に変わりません
こちらは、幅優先

![map_sample1_bfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/c2bed6cb-f2a8-e895-2931-c8ae6e5c9b32.gif)

こっちは、深さ優先

![map_sample1_dfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/ef670227-d0d5-68f3-9e74-f07cd96a00ff.gif)

ゴールがスタート地点より、もっとも遠い場所にある場合で、最短距離が不要な場合は
そんなに変わらなく見えますね。

ゴールが近いと、幅優先探索の方が少ないステップで見つかります。
こちらは、深さ優先探索に不利な例

幅優先

![map_sample2_bfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/0bfc1804-bba5-3423-a22e-52d960bc7db4.gif)

深さ優先

![map_sample2_dfs.gif](https://qiita-image-store.s3.amazonaws.com/0/77716/e8bf16ee-9330-2abb-c72d-0c87d1b682f3.gif)

# 実装

深さ優先探索は、再帰関数で書くことが多いのですが、個人的にはWhileループを使った方法が
オススメです。一旦、やり方を覚えてしまえば、データ構造を変えることで、深さ優先、幅優先どちらもシンプルに書けるからです。

まず、幅優先探索から

基本的に、行けるセルをチェックして、Queueに積んでいきます。
Queueの場合、積まれたセルが一番後回しになるため、近い順に迷路をチェックしていけます。

``` go
func BFS(movie []image.Image, m CellMap) []image.Image {
	var n Point
	// Queue に初期値を積む
	queue := []Point{Point{1, 1}}
	for len(queue) > 0 {
		// queueから取り出す
		n, queue = queue[0], queue[1:]
		// 行けるセルとをチェック
		for _, d := range directions {
			if m[n.X+d.X][n.Y+d.Y] == GOAL {
				return movie
			}
			if m[n.X+d.X][n.Y+d.Y] == 0 {
				m[n.X+d.X][n.Y+d.Y] = VISITED
				// Queueに積む
				queue = append(queue, Point{n.X + d.X, n.Y + d.Y})
			}
		}
		movie = shot(movie, m) // GIFアニメを一コマ撮影
	}
	movie = shot(movie, m) // GIFアニメを一コマ撮影
	return movie
}
```

こちらは、深さ優先。
Queueの代わりに、Stackを使います。Stackでは、最後に追加した要素が、次で使われます。
ですので、見つかった順に深堀していくことができます。

``` go
func DFS(movie []image.Image, m CellMap) []image.Image {
	stack := []Point{Point{1, 1}}
	var n Point
	for len(stack) > 0 {
		n, stack = stack[0], stack[1:]
		m[n.X][n.Y] = VISITED
		for _, d := range directions {
			if m[n.X+d.X][n.Y+d.Y] == GOAL {
				return movie
			}
			if m[n.X+d.X][n.Y+d.Y] == EMPTY {
				stack = append([]Point{Point{n.X + d.X, n.Y + d.Y}}, stack...)
			}
		}
		movie = shot(movie, m)
	}
	movie = shot(movie, m)
	return movie
}
```

幅優先はQueue 深さ優先は、Stackとすることで基本的なコードの構造は全く同じですし、
デバッグも容易です。

# 余談

余談ですが、このデータ構造を優先度付きQueue(Priority Queue)にすると、ダイクストラ法を実装できます。ダイクストラ法は、グラフの辺に重み付けがある場合に使う最短経路探索アルゴリズムです。

GoでのStackとQueueの実装にはもっとうまい方法があります。上記のやり方だと、メモリがうまくGCされないのという欠点があります。 
[リンクリストを使うのが良いでしょう。　container/listを使った例](http://qiita.com/fmhr/items/fa5a7d9b785456446768)
スライスを使った例でも、stackも最後の要素を使うようにすれば、append部分を早くできますね。
C++Builderでフォームの内容を画像として保存する

## フォームを用意する。

**ファイル->新規作成->マルチデバイスアプリケーション**
でプロジェクトを作成したら、適当な名前をつけて保存。
例：
プロジェクト名::TestScreen
フォーム名::main.cpp

## 出力用フォームを用意する。

**ファイル->新規作成->マルチデバイスフォーム**
で出力フォームを作成。
フォーム名::screen.cpp

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/76058/13af7f9c-9174-7ddc-849f-79f9ffff7ade.png)

## 出力フォームにTPanelと出力内容を配置。

出力フォームにTPanelを配置して、その中に出力内容を入れる。
（TPanelじゃなくてもTControlを基底クラスにしているものなら出来ると思う。）
例：
TPanel::Name:Panel1
TLabel::Name:Label1
      ::Text:Test

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/76058/e45290ec-8750-b7a8-45f6-92ca29f1fe7e.png)

## メインフォームにボタンを設置

メインフォームにボタンを設置し、下記のようなスクリプトを記述

```c++:main.h
// --省略
// 出力フォームをinclude
#include "screen.h"
// --省略
```

```c++:main.cpp
// --省略
// ボタンスクリプト
void __fastcall TForm1::Button1Click(TObject *Sender) {
	// 出力フォームのインスタンス
	TForm2* print_form = new TForm2(this);
	// TBitmapのインスタンス
	Fmx::Graphics::TBitmap * bitmap;
	// MakeScreenMethodでビットマップを生成
	bitmap = print_form->Panel1->MakeScreenshot();
	// test.pngという名前で出力
	bitmap->SaveToFile(L"test.png");
	// 後処理
	delete bitmap;
	delete print_form;
}
// --省略
```

![test.png](https://qiita-image-store.s3.amazonaws.com/0/76058/f0eda7c5-78ba-5e72-ca20-74c1524842e4.png)


以上
Apple製「Bluetooth Explorer」でBLEデバイスを操作する

#はじめに
[Apple製開発ツール「Bluetooth Explorer」でBLEデバイスのGATT仕様を確認する](http://qiita.com/shu223/items/46dabad41cf2eed67d13)
の記事おかげで、BLEデバイスの開発がはかどりました。このBluetooth Explorerの"Low Energy Devices"というツールは仕様を確認するだけではなく、BLEデバイスにデータを書き込んだり、更新通知を受け取ってデータを表示することもできるので、このツールだけで簡単なテスト、デバッグができました。

#Low Energy Devices
このツールは、Bluetooth Explorerのメニュー"Devices"→"Low Energy Devices"で起動できます。起動したら右上の"Start Scanning"ボタンを押して、周辺のBLEデバイスをスキャンします。
<img width="1136" alt="Screen Shot 2017-03-15 at 8.26.05 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38304/355dd32d-ef0e-36c0-4ba1-8e01b0c6db92.png">

#BLEデバイスへの接続
接続したいデバイスを選択し、上の"Connect"ボタンを押します。多少時間がかかりますが、接続できると右のペインに発見したサービスとキャラクタリスティックが表示されます。
<img width="1164" alt="Screen Shot 2017-03-15 at 8.42.44 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38304/0e5e3600-37d0-2f2d-55fb-c2a2df81ec2a.png">

#データの書き込み
書き込みたいキャラクタリスティックを選択し、ツール下部のセレクトボックスで"Raw"を選択します（16進で書き込む場合）。テキストフィールドに書き込みたい値を16進で入力し、右の"Write"ボタンを押すと選んだキャラクタリスティックにデータを書き込みます。
<img width="1164" alt="Screen Shot 2017-03-15 at 8.47.17 PM copy.png" src="https://qiita-image-store.s3.amazonaws.com/0/38304/0f39a70d-8b87-3dc5-a86d-345d8b5f3b60.png">

#更新通知の受け取り
更新通知を受け取りたいキャラクタリスティックを選択し、右下の"Reg Notify”ボタンを押します。Notifyを受け取るごとに選択したキャラクタリスティックのValueが変化します。受け取りを中止するときは、同じボタン(表示は"Dereg Notify"になっています）を押します。

#終わりに
きちんと仕様書がまだないBLEデバイスのセントラル側のアプリを作るにあたって、どういうデータを書き込むとデバイスがどう反応するかを確認したかったので、この機能は大変役立ちました。書き込むデータフォーマットについては資料が見つからなかったので多少試行錯誤しましたが、想定通りには動いたので上記のフォーマトであっていると思います。
Dockerコンテナに固定IPを

[Dockerで簡単なCICDツールチェーンを構築](http://qiita.com/takahigashi/items/b914430ced520ecbeb11)したはいいけど、その時にはサボって固定IPを振らなかった。
が、ちょっと調べたら簡単な方法を[「今眠れない」さん](http://stackoverflow.com/users/4094678/cantsleepnow)が答えていた。
http://stackoverflow.com/questions/27937185/assign-static-ip-to-docker-container/35359185#35359185

### Dockerネットワークを作成
`$ docker network create --subnet=<CIDR> <network_name>`
### コンテナ実行時にそのネットワークに接続してipを指定
`$ docker run --net <network_name> --ip <ip_address>  <image>`

以上!

既存のコンテナをネットワークに接続しなおすことも
`docker network connect <network> <container>`
で出きるようだ。
これをつかって環境を組み直しておこう。
ついでにコンテナ名も整理してrestart=alwaysつけるとか、細かい修正も加えとく。φ(..)
Azure Storage Expolorerを使ってみた

# まえがき
Azureを利用してみると、案外StorageAccountにいろんな情報が残ってしまいがち・・・。
そんなときAzureポータルからはイマイチ、URLが全て見えなかったり、COPYができなかったりと操作性がイマイチ。
そんなときに利用するのが**Azure Storage Expolorer**

# インストール手順
１．次のURLにアクセスして、Windows版、Linux版のどちらかをダウンロードしましょう。
[Microsoft Azure Storage Explorer] (http://storageexplorer.com/)

２．ダウンローしたtorageExplorer.exe を実行します。
インストールパスなど変更があれば、実施ください。
基本的に画面の指示に従えば、すぐにインストールは完了します。

# 使ってみましょう！
Windows版の場合、Default設定であれば次の場所にexeファイルがインストールされます。
C:\Program Files\Microsoft Azure Storage Explorer

３．起動してみましょう。
４．すでにAzureアカウントを持っている場合には、一番上の選択肢のままSign in...しましょう。

![storageExplorer04.png](https://qiita-image-store.s3.amazonaws.com/0/109620/0a12bc60-9082-2683-4066-cde3dc8608d5.png)


５．Azureポータルに接続する時と同様の手順でログインします。

![storageExplorer05.png](https://qiita-image-store.s3.amazonaws.com/0/109620/3f12f2a6-34ab-4c66-f096-31a2ddcac701.png)



６．ログインが完了するとExplore画面が表示されます。
複数のサブスクリプションがある場合、左側ペインでサブスクリプションを選択します。

![storageExplorer07.png](https://qiita-image-store.s3.amazonaws.com/0/109620/00663796-44b8-39b2-d334-da4c48fba8e6.png)


Explorer画面に見事該当のサブスクリプション配下にあるStorageAccount情報が表示されました。

Azureポータル上ではできない、ファイルのRenameやCopyなど、明らかにこちらのExplore画面のほうが操作性がいいです。使いこなしてみてください。
QueryBuilderのfirst()の動きを調べてみた

「何気なく最初の値ほしいからって`first（）`してるけど、裏で実は全部取得してんじゃないの！？」
とかいう疑念が湧いたので調べました

# first（）の基本的挙動
## 役割
クエリを作った後、１件に絞って値の取得をする。

## コード
```php
    /**
     * Execute the query and get the first result.
     *
     * @param  array   $columns
     * @return \stdClass|array|null
     */
    public function first($columns = ['*'])
    {
        return $this->take(1)->get($columns)->first();
    }
```

### take()
limitを発行してます
ここでは引数が１なので１件取得の意味

### get()
おなじみです。
値を取得するぞーーーの気持ちです
返ってくるのはcollect()です

### first()
再帰呼び出し！？って思っちゃいますが、違います
collectionのfirst()です
get()からは`collect([0 => 'hoge'])`って返ってきてるので
これを`collect(['hoge'])`にしてる（一緒じゃんと思いますが)


# つまりfirst（）は....
ちゃんとlimitのクエリを発行してるので
全件取得とか危険なことはしてない
※デバッカーで発行クエリを見れば分かる話でした

# 5.1と5.3の挙動の違い
じつはfirst()は5.1の挙動と5.3の挙動で進化してる

## 5.1
```php
   /**
     * Execute the query and get the first result.
     *
     * @param  array   $columns
     * @return mixed|static
     */
    public function first($columns = ['*'])
    {
        $results = $this->take(1)->get($columns);
        return count($results) > 0 ? reset($results) : null;
    }
```
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Query/Builder.php#L1389

## 5.3
```php
    /**
     * Execute the query and get the first result.
     *
     * @param  array   $columns
     * @return \stdClass|array|null
     */
    public function first($columns = ['*'])
    {
        return $this->take(1)->get($columns)->first();
    }
```

https://github.com/laravel/framework/blob/5.3/src/Illuminate/Database/Query/Builder.php#L1615

## 8.x (追記)
８になっても、だいたい変わらずでした
しいていえば、書かれたファイルが移動したのと
`Model|object|static|null` と型が増えたところでしょうか

```php
    /**
     * Execute the query and get the first result.
     *
     * @param  array|string  $columns
     * @return \Illuminate\Database\Eloquent\Model|object|static|null
     */
    public function first($columns = ['*'])
    {
        return $this->take(1)->get($columns)->first();
    }
```


https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Concerns/BuildsQueries.php#L251


## 何が違う
**クエリ実行結果が得られなかった時の挙動が変わりました**

結果が無かったら
5.1では`null`
5.3から `collect([])`が返ってくるようです

個人的には5.3のcollectの空が返ってくるのが
無かった感があって好きです。
Python > empty XXX (XXX: dict, list, tuple, set) > {} / [] / () / set()

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
```

関連 http://qiita.com/7of9/items/1b78423cce1e75607195
関連 http://qiita.com/7of9/items/c1958d662ec776f7df61#comment-06571c9aff0fe06914ab

empty XXXについて。

http://qiita.com/7of9/items/664d0a772531692d9729
に記載の通り、`{}`はempty dictionaryを返す。

似たようなものは以下。

```
>>> type({})
<type 'dict'>
>>> type([])
<type 'list'>
>>> type(())
<type 'tuple'>
>>> type(set())
<type 'set'>
```

setだけempty setがないようだ。
[Empty set literal?](http://stackoverflow.com/questions/6130374/empty-set-literal)

setの属性は以下で見れそうだ。

`>>> dir(set())
['__and__', '__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
`
Swift3 - UITableViewでセル追加

#セルの配列

下記のような配列の値がセルに反映されていたとします

```swift

var myItems = ["TEST1", "TEST2", "TEST3", "TEST3"]

```

# 配列に文字列を追加してUITableViewをリロードする


僕の場合はUIボタンのアクションの中で下記の処理を実行しましたが、どんな感じでも構いません。要は、配列に値を追加してUITableViewをリロードするだけです

```swift

// myItemsに追加.
myItems += ["TEST4"]
// TableViewを再読み込み.
MainTableView.reloadData()

```

# 参考

[swiftUITableViewを編集モードにして、追加、削除、並べ替えをする](http://ameblo.jp/highcommunicate/entry-12059919502.html)

[Swiftで配列に要素を一つだけ追加する](http://swift.tecc0.com/?p=505)

[Inserting and Deleting Rows and Sections](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html)
Webページにプログラミング言語やwebサービスのアイコンを表示させる。

#Deviconを使ってwebページにプログラミング言語やwebサービスのアイコンを表示させる。
##概要
webページにDeviconを利用してアイコンを表示させる。
##Devicon
Deviconウェブサイト: http://devicon.fr/
##手順
Font versionとSVG versionがありますが、今回はFont versionを使用します。
1. Deviconのトップページ右側search for iconsから自分が使いたいiconを選択する。
2. ページの左側に選択したアイコンの4つのタイプが表示されるので、使いたいものを選択。
 **Font versionsの方を確認する。**
<img src="https://qiita-image-store.s3.amazonaws.com/0/170631/da5cbd4d-95b1-cb52-afd0-b59a43b7bcc0.png" width="50%;">

3.次にアイコンの下にある

```html:Devicon
<!-- in your header -->
<link rel="stylesheet" href="https://cdn.rawgit.com/konpa/devicon/master/devicon.min.css">
```
を使いたいhtmlファイルのhead内にコピペする。
4. 最後に

```html:Devicon
<!-- in your body -->
<i class="devicon-ここはアイコンによって変わる"></i>
```
を表示させたい位置に挿入する。


# 参照サイト
Devicon 2.0 http://devicon.fr/