OmniAICreator/Qiita-1.07M huggingface dataset:
いにしえの Force.com ソースコードをデプロイする

この記事は、[Salesforce Platform Advent Calendar 2017](https://qiita.com/advent-calendar/2017/salesforce-platform) 18日目の投稿になります。

# はじめに

昔作った Force.com のソースコードを新しい Developer 環境にデプロイしたいと思います。
pacakage.xml の Version タグによると、バージョンは「16.0」です。
現在「38.0」ですので、なかなか古いと言えるのではないでしょうか。

# 準備
## Eclipse 
Eclipse 4.5 に Force.com プラグインをインストールします。
まさかのここからスタートですが、気を確かにいきましょう。

![2017-11-29_09h01_07.png](https://qiita-image-store.s3.amazonaws.com/0/59985/7d43ce06-72bf-6428-3ba2-d758f23591f9.png)

## ソースコード
SVN に保管してあったソースコードをローカルに展開します。
package.xml の Version を 38.0 に修正します。（これはしなくてもよいかも）

# デプロイ開始
## 1回目のデプロイ

サーバへのデプロイは、「Deploy to Server」というメニューから行います。
まずなにも考えずにプロジェクトのルート上で右クリックして、「Deploy to Server」を実行。
画面に沿って進めます。
![2017-12-18_17h25_07.png](https://qiita-image-store.s3.amazonaws.com/0/59985/5beb6b58-0d66-4716-f8de-e9c4ad7967e5.png)

「Destination archive」のチェックは外しました。
![2017-12-18_08h53_57.png](https://qiita-image-store.s3.amazonaws.com/0/59985/0a60fed5-bda4-c158-87e9-822bc4fac5cc.png)

![2017-12-18_08h54_19.png](https://qiita-image-store.s3.amazonaws.com/0/59985/1a8188bd-3c81-6dd1-2e7d-da4a0d8f85e4.png)

![2017-12-18_08h55_05.png](https://qiita-image-store.s3.amazonaws.com/0/59985/08b5d84c-9b29-bf9d-d9cc-d2b9d4f2301e.png)

「次へ」を押下するとエラー
![2017-12-18_09h04_10.png](https://qiita-image-store.s3.amazonaws.com/0/59985/73a8ace7-9f95-fa36-4518-2ff98e9a122c.png)

package.xml のエラーが出てしまいました。ファイルの文字コードがおかしいようです。
ざっとファイルの文字コードを確認してみますが、UTF-8になっているように見えます。
Salesforce のサイトを見ると、解決策がでていたので、それで対応します。
[Force.com IDEのデプロイ時にエラー発生](https://help.salesforce.com/articleView?id=000004051&language=ja&type=1)

## 2回目のデプロイ
1回目と同じ手順を踏んで、デプロイを進めます。
デプロイ失敗しますが、エラー内容は変わっています。（画像取得洩れ）
エラー内容を見て、一度にすべてのデプロイは難しいと判断して、少しずつデプロイすることにしました。

## n回目のデプロイ
まず カスタムオブジェクト をデプロイします。
デプロイ成功です！ものすごくうれしい。
![2017-12-18_16h17_23.png](https://qiita-image-store.s3.amazonaws.com/0/59985/c2a14d9f-5255-1ba1-d2dd-976905b9f14c.png)

Visualforce Page や Apex Class は依存しあっていることが多いので、小分けにして少しずつデプロイしていきます。
ここからは、デプロイ失敗時のログをみながら進めていきます。

----

試行錯誤の結果、
カスタムオブジェクト → 静的リソース → Apex Class, Trigger, tab → テストクラス  → レポート, ダッシュボード → アプリケーション 
という順番でデプロイしていくのがよさそうです。




以下はデプロイが成功したクラスです。
![2017-12-18_18h07_53.png](https://qiita-image-store.s3.amazonaws.com/0/59985/e579d33d-c816-3200-c215-3f6621c93615.png)


API バージョンが低いので、最終的にはここもバージョンアップしますが、今回はここまで。
デプロイの試行錯誤に時間がかかりすぎました。
時間を見つけてこの記事は成長させていけたらなと思います。
iOSアプリ開発でのリソース管理

最近、Swiftを触り始めたのですが、画像と文字列の管理がわかりにくかったのでまとめておきます。
基礎的なことだと思いますが、同じような人の助けになれば。

試したバージョンは下記です。

- Xcode 9.2
- Swift 4
- R.swift 4.0.0

# R.swiftのインストール
リソースへのアクセスに R.swift というライブラリを使います。
ライブラリの説明とインストール方法は以下を参照してください。
https://github.com/mac-cain13/R.swift#installation

# 文字列リソースの管理

## リソースファイルの作成

Xcodeの文字列リソースファイルを利用します。

ファイルの作成（Cmd+N）で開くダイアログから `Strings File` を選択します。

![スクリーンショット 2017-12-18 17.48.52.png](https://qiita-image-store.s3.amazonaws.com/0/20940/459088cb-3bb0-2562-f775-1754a9ce8a51.png)

名前（ここでは `settings.strings` とします）をつけて保存すると、空のファイルが作成されるので、`"KEY" = "VALUE";` の形式で記述します。
文末にセミコロンが必要です。


```:settings.strings
"welcome" = "こんにちは!";
"bye" = "さようなら"
```

## アクセス方法

下記のように取得可能です。

```
R.string.[ファイル名].[KEY]()
```

```swift:文字列の所得
let welcome = R.string.settings.welcome() // こんにちは!
```

# 画像リソースの管理

## リソースの登録

アセットカタログに画像をドラッグして登録します。
![スクリーンショット 2017-12-18 21.03.03.png](https://qiita-image-store.s3.amazonaws.com/0/20940/e3cd7a3e-6785-af4e-c13a-d52959956f54.png)

アセットを登録したら、一度プロジェクトをビルドします。
すると `R.generated.swift` に登録した画像が追加されます。

```swift:R.generated.swift
  struct image {
    /// Image `sick_kebyou_man`.
    static let sick_kebyou_man = Rswift.ImageResource(bundle: R.hostingBundle, name: "sick_kebyou_man")
```

## アクセス方法

あとは以下のようにして取得可能です。

```
R.image.[リソース名]
```

```swift:画像にアクセス
let image1 = R.image.sick_kebyou_man()
```
![スクリーンショット 2017-12-18 21.08.29.png](https://qiita-image-store.s3.amazonaws.com/0/20940/3c627ffc-4c80-c50e-de9e-0cdf7c18db97.png)

補完されるので、画像名を間違える心配もありません。

## namespace付きでアクセス
画像はグルーピングして管理することもできます。

下図のようにアセットカタログにフォルダーを追加して `Provides Namespace` をチェックしておきます。

![スクリーンショット_2017-12-18_21_16_10.jpg](https://qiita-image-store.s3.amazonaws.com/0/20940/3ace641e-e051-25d3-c233-3072e95d2f84.jpeg)

すると、フォルダー配下の画像に `フォルダー名.リソース名` でアクセス可能となります。

```swift:namespace付きで画像にアクセス
let image2 = R.image.hogehoge.sick_byouketsu_man()
```
Symfony 3.4 の新機能: 設定ファイルのパラメーター変換

[Symfony Advent Calendar 2017](https://qiita.com/advent-calendar/2017/symfony) の 18日目の投稿です。

最近は JavaScript ばかり使っており、Symfony 3.4 以降のキャッチアップができてなく、かなり取り残されている感な日々です :sweat_smile: Advent Calendar でいろいろな情報がキャッチアップできいて、感謝です！

この投稿では Symfony Blog で紹介されていた Symfony 3.4 から追加されたパラメーター変換の新機能について Tips を紹介します。

※ 私自身、まだ利用していないので間違いがあればスミマセン

## パラメーターの型変換

PHP 7.1 からスカラー型宣言の機能が追加されました。

```php
public function connect(string hostname, int port)
{
    // ...
}
```

Symfony で設定ファイルからセットした値は全て `string` 型となってしまい、型宣言を利用するためには自前で型を変換するなどの工夫が必要でした。

```yaml
parameters:
    app.connection.port: '%env(DATABASE_PORT)%' #=> string
```

Symfony 3.4 から環境変数を取り扱う処理に改善がなされ、設定ファイルで任意のスカラー型への変換ができるようになりました。

```yaml
parameters:
    app.connection.port: '%env(int:DATABASE_PORT)%'
```

この記述は以下と等価です。

```php
(int) getenv('DATABASE_PORT')
```

現在は `array:`、 `bool:`、`int:`、`float:`、`string:`　が利用できるようですね :smile_cat: 細部の機能ですが、これによってこれまで以上にスカラー型宣言を手軽に利用できるようになりましたね :smile_cat:

## その他の演算子

スカラー型の変換以外にも、以下の演算子が提供されています。

### `resolve:`

変数をセットした文字列型の値に変換します。

```yaml
parameters:
    project_dir: '/foo/bar'
    env(DB): 'sqlite://%%project_dir%%/var/data.db'
    db_dsn: '%env(resolve:DB)%'
```

### `file:`

指定したファイルパスを読み取り文字列に変換します。

```
parameters:
    env(SECRETS_FILE): '/etc/secure/example.com/secrets.json'
    app.secrets: '%env(file:SECRETS_FILE)%'
```

### `json:`

JSON を PHP の配列に変換します。さらに `json:` と `file:` の併用することで JSON ファルのファイルパスを読み取り PHP の配列に変換することも可能です。

```yaml
parameters:
    env(SECRETS_FILE): '/etc/secure/example.com/secrets.json'
    app.secrets: '%env(json:file:SECRETS_FILE)%'
```

### `base64:`

base64 でエンコードします。

```yaml
parameters:
    env(SOME_VALUE): 'NWE3OWExYzg2NmVmZWY5Y2ExODAwZjk3MWQ2ODlmM2U='
    app.some_value: '%env(base64:SOME_VALUE)%'
```

### `constant:`

PHP の定数にします。

```yaml
parameters:
    env(NUM_ITEMS): 'App\\Entity\\BlogPost::NUM_ITEMS'
    app.num_items: '%env(constant:NUM_ITEMS)%'
```

## カスタマイズ

さらに処理を自作することもできるようです・・・！`EnvVarProcessorInterface` を実装し `container.env_var_processor` のタグを利用するようです。

実際に試してみて、実装例を紹介しようと思ったのですが、時間の都合でできませんでした :sweat: 試してみてうまくできたら紹介しようと思います。

# 最後に

今回の新機能で設定ファイルで様々な処理が実現できるようになった一方で、自由度が高まった分、設定ファイルのコンパイルでどこまでの変換処理を行うかは設計・実装のポイントの一つになりそうですね。うまく活用してよりよいアプリケーションを開発したいものです。

自分はまだ機能を使っていないので、まずは使ってみて感触を掴んでみたいと思ってます。既に使ってる人がいたら感想をぜひ教えてください :smile_cat:

それでは :smile_cat:
新Python生活七日目【PyQ/初級①】

初級編を進めていきます。
一旦「入門編～初級編」まで終わらせて、理解出来るまで繰り返してから次の「中級編」に進もうと思います。

#組み込み関数(= Pythonに組み込まれている関数)
```py3
numbers = [123, 345, 9, 234, 77] #numbersリストには適当な数字が入ってるよ
saidai = max(numbers) #変数saidaiにnumbersリストの最大値を代入するよ
print(saidai) #変数saidaiを表示するよ
```

#自作関数(= 自分で定義した関数)
「大体は組み込み関数でまかなえるのでは？」と
超初心者な自分は思ってしまいますが、勉強して行きます。

```py3
def xyz(num): #xyzって適当な関数を定義
    if num % 2 == 0: #2で割って余りが0の時は
        print(num, 'is 偶数!') #偶数って表示するよ
    else: #それ以外は
        print(num, 'is 奇数!') #奇数って表示するよ

check_even_odd(24)
check_even_odd(31)
```

```text:出力結果
24 is 偶数!
31 is 奇数!
```

#戻り値：戻ってくる処理結果の事
```py3
def aisatsu(name): #関数aisatsuを定義
    greeting = 'Hai,' + name #変数greetingにHai,名前 代入するよ(関数aisatsuの中身)
    return greeting #変数greetingのループを抜けるよ(関数aisatsuの中身)

Haoumaru = aisatsu('Haoumaru') #変数覇王丸に関数aisatsuを代入
Terry = aisatsu('Terry') #変数テリーに関数aisatsuを代入

print(Haoumaru)
print(Terry)
```

```text:出力結果
Hai, Haoumaru
Hai, Terry
```

#別ファイルの関数を利用する
```py3
from ファイル名(ファイルパス) import 関数名
```

同じ階層にある複数の関数を利用したい場合は、関数名の後にカンマで区切って追記する

```py3
from ファイル名(ファイルパス) import 関数1, 関数2, 関数3
```
個人開発のJavaScriptビルドをWebpackに乗り換えた話

最近はほぼ手付かずになっていますが、GitHub Page上に[パズルソルバー](https://jkr2255.github.io/js_puzzle_solvers/index.html)を作っています。数ヶ月前に、ビルドをWebpack経由に乗り換えました。

# 以前の問題点

もともとは、GruntやGulpのように変化し続けるプロセスランナーに嫌気が差して、[Browserify+Rakeで組んでいました](https://qiita.com/jkr_2255/items/7e3f464721bb39c457da)。Rakeもビルドツールということで、多様なファイルの交錯するJavaScript環境でも問題なく使えたのですが、使っていくに連れて、いくつかの問題に気づきました。

## 一時ファイルの問題

Rakeが「ファイルをファイルに変換する」というプロセスをベースにしている関係上、最終生成物以外に中間の結果をファイルに置く必要があります。そして、元のファイルを消したときに中間ファイルも消えないと余計なものが残り続けるのですが、ここがどうにもうまくできませんでした。

## 速度の問題

もともとの思想から言えばそうなるのも必然といえば必然なのですが、1ファイルを処理するために1プロセスを立ち上げる必要があるため、2桁のファイルを処理しようとすれば分単位のビルド時間がかかって、かなりの負担となっていました。

# Webpackに乗り換えた結果

Webpackに乗り換える前にCoffeeScriptは捨てていて、ふつうのJavaScriptとRiot.jsだけになっていたので、Webpackに`uglifyjs-webpack-plugin`と`riot-tag-loader`を足して、そしてRiotのタグもJavaScriptに変換してからBrowserifyしていたものをそのまま使うために`resolve.extensions`に`.tag`も追加するようにしてビルドプロセスを組み立てたところ、ビルドは数秒で片付くようになり、Watchしてのビルドも一瞬で片付くなど、だいぶ気持ちよく処理できるようになりました。


# 結論

やっぱり、速さは魅力。
SORACOM API + Jupyter notebookでネットワーク利用状況の分析

ど〜もみなさん、おはこんばんにちは（言ってみたかった）。SORACOMの中の人の[@imai_factory](https://twitter.com/imai_factory)です。

[SORACOM Advent Calendar 2017](https://qiita.com/advent-calendar/2017/soracom)の12/18分の記事です。もともとはSORACOM Endorseの話もしくは時系列データの話をします、という前フリをしていたのですが、SORACOM APIを使ったアプリケーションやネットワーク利用状況の監視/可視化について書いてみたいと思います。

IoTアプリケーションには様々なユースケースがありますが回線やデバイスの数が数千や数万を超えてくるということも珍しくはありません。こうなってくると回線の利用料やエラーの発生状況などを手動でトラッキングするのは無理が出てくるのは言うまでもありません。

例えば「大量の回線の全体の利用量や、ほかと比べてずば抜けて大量の通信をしている回線を把握したい。更にSORACOM BeamやSORACOM Funnel、SORACOM Harvestなど各種サービスにおいて特に気にすべきエラーが発生していないかを把握したい」という状況を仮定しましょう。

下記はすべて、そうった要件を実現するために、Jupyter notebookを使ってSORACOMプラットフォームの利用状況を可視化したものです。

例えばまずは全体の利用量を把握するところから始めることにしましょう。下記は、あるSORACOMアカウントのすべてのSIMについて過去7日間の下り方向通信量（単位：MB）を、速度クラスごとに合計して可視化したものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10292/2aa4522a-c257-18e5-fd8c-74d93edbf968.png)

これは、[exportAirStats](https://dev.soracom.io/jp/docs/api/#!/Stats/exportAirStats)というAPIを利用して実現しています。

なんとなく全体の利用量が見えるようになったので、こんどはSIMごとの通信量を可視化してみましょう。下記のグラフは、同じAPIで取得した過去7日かんのデータのうち、ダウンロード通信量Top10のSIMについて回線ID(IMSI)ごとに可視化をしたものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10292/825bef2d-dd04-89c1-9e78-9f3a6300fecf.png)

明らかに1回線だけ、他と較べて大量の通信をしているものがいますね。ただ、回線IDだけでは、どのSIMなのかが読み取りづらいですね。では、これをもう少し読みやすくするために、回線IDではなく、SIMに付けられた名前でグラフを書き直してみましょう。実はこれも先程取得した同じデータからグラフ化が可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10292/4f4844a5-1842-8a70-2379-effab6b0c44b.png)

名前をそのままお見せすることができないのでモザイクを掛けていますが、今度はSIMに付与した名前毎にグラフが描画されました。こうなってくるとなんとなく「誰が何に使っているSIMだ」みたいなことが検討付けやすくなりますよね。

前述のとおり、これはexportAirStatsで取得したデータをつかっているのですが、この「名前」はSORACOMコンソールで付与しているSIMの名前によってグルーピングしているのです。

さらに、SORACOMではエラーログをAPI経由で取得することもできます。[getLogs](https://dev.soracom.io/jp/docs/api/#!/Log/getLogs)というAPIなのですが、これを使うと、SORACOM Beam、SORACOM Funnel、SORACOM Endorse、SORACOM Harvestなどのアプリケーションレイヤのサービスのエラーログを取得することができます。例えば「設定がされていないのにSORACOM Beamを使おうとしているSIMがいる」といったようなエラーです。

下記は、同APIにて取得した、過去7日分のデータを使ってエラーメッセージの種別毎に回数を数えたものです。文字が小さくて見えづらいですが「Configuration for SORACOM Harvest is not found」というエラーメッセージで、これは`harvest.soracom.io`にデータが送信されてきたが、実際に当該SIMに対してSORACOM Harvestの設定がされていない、という状況を表します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10292/a1090718-e250-ede1-2348-31a6b1e2aecc.png)

こうなってくると当然、「どのSIMでその問題が起こっているのか？」というのを確認したくなりますよね。もちろん簡単です。先程取得したデータのグルーピングを「エラーメッセージごと」から「エラーメッセージx回線IDごと」に変えてやれば以下のようにどのSIMで問題が発生しているのかがさっと可視化できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10292/c52c4dc1-1c12-93fe-1f97-a968af3842f2.png)


結果として、ある特定の2枚のSIMにおいてSORACOM Harvestの問題が多発していることがわかりました。あとはやることは簡単ですよね？そのSIMの設定を見直してやればOKです。

というように、SORACOMのAPIを利用すると、回線数が増えてきてもいろいろ便利に管理できるよというお話でした！

今回お見せしたグラフ化のためのnotebookは下記にアップロードしておきました。

https://gist.github.com/yuta-imai/a0ac981598216ec1f014a4b8bb14bbda

下記のコマンドラインを、環境変数をご自分の環境のものに書き換えて起動していただければ、上記のコードをそのままみなさんの環境で実行可能です。

```bash
operatorId=YOUR_SORACOM_OPERATOR_ID authKeyId=YOUR_SORACOM_API_KEY_ID authKey=YOUR_SORACOM_API_KEY jupyter notebook
```

コード自体はたいしたものではありませんが、SORACOMのAPIを使った回線管理に触れるためのきっかけになれば幸いです。
ゆるふわエンジニアがRustを触り始めた話

## 自己紹介

### 山下 秀平

* 30歳
* Java生まれRuby育ち
    * 以前の会社のJava環境がアレで嫌気がさす
    * Rubyを触り始めて息をふきかえす
* 今はC#せっせと書いてます
* 趣味は料理

-----------------------------------------------

# なんでRust？

-----------------------------------------------

* ElixirとかGoとかもあるやん？
    * むしろRuby畑ならElixirでは
        * ふぇ、ふぇにっくすのHello World記事は書いたし
* スターティングGo言語も買ったやん
    * ま、まだ読み終わってない
* Rubyですらまだまだだよね？
    * 前職だと布教に失敗(宗教戦争)

-----------------------------------------------

# なんとなく

-----------------------------------------------

* 最初は本当になんとなく
* なんか一部ではやってそう
* 元Googleエンジニア「今はほぼrustで書いてる」
    * こんな記事を見た気がする

-----------------------------------------------

# で、とりあえずやってみてどうよ？

-----------------------------------------------

# ( ﾟДﾟ) ちょっと難ない・・・？

-----------------------------------------------

* move/borrow/ライフタイム
    * 使うと消える？？なんで？？？？
* コンパイラ様にめっちゃ怒られる
    * この引数型合わねぇから！！！！
* できるまでコンパイル通さねぇからな！！
    * (/ω＼)

-----------------------------------------------

# Q. なぜそう思うのか？

-----------------------------------------------

# A. 今まで意識してこなかったから

-----------------------------------------------

* もともと趣味でコーディング → 実際にエンジニアに
* 体系的に学んでない
* メモリ周りのことちゃんと気にしたことない
    * C++やってたらきっと・・・
* 実務上で必要になる領域以外にはあまり目を向けられてなかったのでは？
* プログラムとは・・・？俺はいったい今まで何を・・・？

-----------------------------------------------

# コンパイラ様に導いてもらった

-----------------------------------------------

* Rubyに戻ると自由感がすごいけど、自由すぎて不安になる
* 今までと世界(ソースコード)が違って見える
    * 視界が広がった感じ
* 作ってみたいものが増えた
    * NESエミュ作ってみたい

-----------------------------------------------

# 第二言語としてのRust(本日最初のLTに戻る)

-----------------------------------------------

# Rustはいいぞ
Force git status to Output Color on the Terminal

`git status | less` とすると、色が付かないので……。

```sh
% git status -c color.status=always status | less -R
```

以下のそのまんまです。
[shell - force git status to output color on the terminal (inside a script) - Stack Overflow](https://stackoverflow.com/questions/16073708/force-git-status-to-output-color-on-the-terminal-inside-a-script)
PHPのフレームワーク、レガシーなZendとモダンなLaravelを入社してから使ってみた感想

新卒アドベントカレンダー18日目です！Webエンジニアの高木です。
日頃は、PHP,JS,HTML,CSSを書いています。

今回は研修中や業務で使ったPHPのフレームワーク、
レガシーなZend frameworkとモダンなLaravelを使ってみた感想を紹介したいと思います。
（爆速で書いたため、間違いがあったらコメント欄にでも書いていただけるとありがたいです。）

ちなみに両方ともWebサービスを作る時に使いました。

#Zend Framework について
2006年3月にイスラエルのZend Technologiesによって公開されたフレームワークです。
今はPHP7.0まできましたが、当時5.0が出たばかりの時に、まだまだ使えないフレームワークが多かった中、PHP5でも使えるようにと開発されたものでもあります。

#Laravel について
2011年6月に出た、MVCのWebアプリケーション開発用の無料・オープンソースです。最近ではPHPのフレームワークとしてとても有名で、人気のフレームワークの一つとなっています。

#書きやすいと思ったフレームワークは・・・
まあそうだろうなと思うかもしれませんが、もちろん、**Laravel**です。

<img width="1157" alt="スクリーンショット 2017-12-18 20.27.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/97496/dc32cc22-3f22-9924-1579-1bc42a8f9000.png">

青がLaravelなので、Googleトレンドで見ても歴然の差です。


#Laravelのいいなと感じたところ

##ドキュメントや日本語ドキュメントが充実している
日本語ドキュメントも非常に充実しているのと、使っている人が多いので、日本語での解説やブログなども多いです。
http://laravel.jp/

##学習コストが低い
個人的な感想なのですが、会社の新卒研修で今回Laravelを使ったのですが、PHPが初めての子でもあんまり悩まず使いこなしていたので、学習コストも低いのではないかと思いました。

##デフォルトでログインや会員登録機能が備わっている
Laravelでは、ユーザ登録、ログイン機能が標準機能として、コントローラーが用意されています。個人でサクッとWebサービスを作りたいときにとても便利だなと思います。

##ライブラリも豊富
画像アップロードといった手軽に使えるライブラリが豊富です。Composerを使ってサクッと入れることができます。

##Vue.jsといったモダンなフレームワークとの相性がいい
研修中にも使ったのですが、Vue.jsという今話題のJSのフレームワークと相性が良く、またVue.jsのドキュメントもしっかりとしているため使いやすい印象を受けました。

##Eloquent ORMというORMがフレームワークにデフォルトで入っている
標準でORMが入っているため、簡単にデータベースやテーブルを作成することができ、また、LaravelのModelと結びついているので、データ連携がしやすいです。

##seederがあるので簡単にデータを入れることができる
テスト用にデータを入れたりするのって意外と大変ですが、Laravelは標準でseederが入っているので簡単にデータを入れることができます。またユーザーであったり、文字といった設定もしやすいのが特徴です。

```php
<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * データベース初期値設定の実行
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => str_random(10),
            'email' => str_random(10).'@gmail.com',
            'password' => bcrypt('secret'),
        ]);
    }
}
```


#Zend Frameworkのよくないと感じたところ

##ドキュメントが非常に少ない
あまり人気が出なかったフレームワークでもあるので、ドキュメントが少ないのが印象です。日本語となるとさらに減ってくるので、エラーや予想しない動作になったときに解決するのが大変です。

##非常に重い
フレームワーク自体が非常に重く、通常27MBで、最小構成でも5MBあるらしいです。大規模Webアプリケーションには向いてないのかなとも思います。

##標準のORMがない
Laravelと違い、標準のORMがないため、もし使いたい場合は外部のORMを自分で導入しなければいけません。それか頑張ってSQLを書くかということになるのかなという感じです。Zendと一緒に使われているORMとして多いのは、Doctrine2だと思います。

##SQLとの相性が悪そう
上記のDoctrineを使っているのですが、デフォルトのメソッドでデータを呼び出したりするとオブジェクトごととってきて、稀にメモリリークを起こします。個人的にSQLと相性が悪いなと感じ、それってWebサービスを作る上で致命的だなと感じました。

#まとめ
てなわけで、PHPを書くならLaravelを書きたい、せめてSymfonyといったところでしょうか・・・。
これからもPHPと向き合っていきたいと思います！

#参考記事
http://laravel.jp/
http://www.itmedia.co.jp/enterprise/articles/0702/28/news028.html
https://rdlabo.jp/codeigniter-228.php
BEAR.Sundayのキャッシュ


>There are only two hard things in Computer Science: cache invalidation and naming things.

>-- Phil Karlton

# BEAR.Sundayのキャッシュ

BEAR.Sundayではフレームワークが再利用する`$app`キャッシュの保存に**APC+ファイル**の[チェーンキャッシュ](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#cache-chaining)を利用しています。APCのキャッシュが利用可能ならそれを利用し、なければファイルキャッシュを読み込みます。ファイルキャッシュもなければキャッシュを生成しますが、その生成タイミングでAPCにも保存します。

# APCキャッシュは取り扱い注意

チェーンキャッシュを採用する理由はコンソールでの操作、つまりdeployツール使用時にコンソールの操作でキャッシュを生成するためです。APC関数はwebスクリプトでしか利用できないため、APCにデータを保存することができません　（apc.cliオプションの設定はエラーを出さないだけです）

削除も同様です。コンソールからの消去はできないので専用のスクリプトやAPC付属の`apc.php`を用意する必要があります。認証も必要でしょう。deployプロセスに組み込むのも面倒です。

APCキャッシュはwebサーバーに対してグローバルなので`apc_clear_cache()`を行うと同じwebサーバーで動作する他のアプリケーションもあれば影響を与えてしまいます。

webでしか動作しない。グローバルでキャッシュのグルーピングができない。ーとかくAPCキャッシュは取り扱いが面倒です。CakePHPは以前、APCキャッシュがデフォルトだったのをファイルキャッシュに戻してしまいました。

多くのフレームワークがファイルキャッシュをデフォルトにしています。ファイルキャッシュは取り扱いは簡単ですが速度は劣ります。

# 安全なキャッシュクリアの方法

A) 新しいプロジェクトフォルダを用意してsymlinkでリンクを貼り直します。

または

B) `src`ディレクトリの日付を更新します。

```bash
touch src
```

APCキャッシュは実際には消去されず、キャッシュIDが更新されるために以前のキャッシュが無効化されます。（`src`のタイムスタンプをキャッシュキーに含んでいます）

# コンパイル

コンパイルとはDIとAOPのPHPコード生成を含むキャッシュの手動生成です。

キャッシュがない状態のアプリケーションを実行すると最初の実行でキャッシュが生成されますが、高負荷のサイトではその負荷が問題になります。

キャッシュやPHPコードを事前に生成して置くとその問題を避けることができますこれを**コンパイル**と呼びます。コンパイルは全てのページクラスのファクトリーコードも生成するので、DIの依存解決に問題があればアプリケーション実行前に検知可能です。

```
vendor/bin/bear.compile 'Polidog\Todo' prod-html-app /path/to/project
```

# リソースキャッシュ

キャッシュには以下の種類があります。

* DIの設定で作られるPHPの生のファクトリーコード　(`tmp/`ディレクトリ)
* メソッドインターセプターを可能にするAOP用のコード　(`tmp/`ディレクトリ)
* ルートオブジェクト`$app`のキャッシュ
* リソース（リソースステートや表現）のキャッシュ

（最初の２つは自動で生成されるPHPのコードですがここではキャッシュとして扱います）

リソースキャッシュはアプリケーションのキャッシュで、apcやファイルキャッシュ以外のキャッシュストレージ、つまり`redis`や`memcacache`を利用しているときにはキャッシュを無効化するかしないかを`CacheVersionModule`で決定することができます。

```php
$this->install(new CacheVersionModule('1')); // リソースキャッシュのバージョン指定
```

アプリケーションのキャッシュが再利用できる場合にはバージョンをそのままに、再利用できないプログラムの変更を行ったらバージョンをあげると無期限指定のキャッシュをも消去します。deployまいに全部消去するなら日付時刻を指定すればいいでしょう。

# .do_not_clearファイル

`prod-`または`stage-`のプリフィックスがついたコンテキストだけです。それ以外はキャッシュは保存されません。

それ以外のコンテキストでファイルキャッシュを有効にするためには、`var/tmp/{context}`の中に`.do_not_clear`というファイルを設置すればそのフォルダのファイルは消去されなくなります。
Qiitaで"![Payload Too Large]()"エラーが出る場合の解決法

#事象
Qiitaで記事を書いていると…
!![Payload Too Large]()
というエラーが出ました。

#原因
どうやら原因は、記事の容量制限のようです。
最初の投稿は月2MBまでの制限がかかっています。
画像などをたくさん貼り付けているとすぐにオーバーしてしまいます。

#解決法
1回でも投稿をすると月2MB→100MBまで容量制限が上がります。
2MB以上の記事を書きたい場合は、まず簡単な記事を何か1つ書いて見ると解決します。

#終わりに
ということで、私も本記事を最初の記事にして、100MBの容量で記事を書いていきたいと思います。

>引用
http://blog.qiita.com/post/75674629515/image-capacity-expansion
https://qiita.com/keroppi0_0/items/31863410490aff13e90a
【Neo4j】CypherでUNION後の結果をGROUP BYしてSORTする

#はじめに
UNION後の処理で躓いたので備忘録として記載する。

以下のようなグラフを例として挙げる。(作成するためのクエリーは末尾のおまけに記載。)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/38637679-eaa7-d0e1-2612-f178bbe8d553.png)

上記のグラフに対して、User1の気分とUser1の友達の好きな曲をもとに、曲をおススメしたい。
1.User1の友達が好きな曲とスコアを出す。
2.User1の気分にマッチする曲(泣ける曲)とスコアを出す。
3.1と2の合算値をSORTして一番スコアが高い曲をおススメとして抽出する。

リレーションの数を元におススメする曲を決めても良いが、今回はリレーションのプロパティにスコアを持たせて、スコアをもとにおススメする曲を決めることとする。


#クエリー
1～3の処理のために実行するクエリーを記載する。

1.User1の友達が好きな曲とスコアを出す。

```
MATCH (a:Music)-[b:fit]->(c:Feeling{name:"泣ける曲"})
WITH a.name AS name,
     b.score AS score
RETURN name,score
```

2.User1の気分にマッチする曲(泣ける曲)とスコアを出す。

```
MATCH (:User{name:"user1"})-[:knows]->(a:User),
(a)-[b:likes]->(c:Music)
WITH c.name AS name,
     b.score AS score
RETURN name,score
```

3.1と2の合算値をSORTして一番スコアが高い曲をおススメとして抽出する。

```
MATCH (a:Music)-[b:fit]->(c:Feeling{name:"泣ける曲"})
WITH a.name AS name,
     b.score AS score
RETURN name,score
UNION ALL
MATCH (:User{name:"user1"})-[:knows]->(a:User),
(a)-[b:likes]->(c:Music)
WITH c.name AS name,
     b.score AS score
RETURN name,score
with name as name,SUM(score) as score order by score desc
return name,score
```

#結果
1と2はそれぞれ正常に結果が返る。
1.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/51e7e51e-b320-0053-1493-cb4911376f64.png)

2.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/0aa25ee0-c830-d594-e743-eb48a93bbc3a.png)

しかし3.が失敗する。
3.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/8223e01f-4e48-3683-18c0-636c3cca6869.png)

単にUNION ALLをするだけであれば正常に終了するため、GROUP BYとSORTの箇所が怪しい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/06b1d0fc-2338-9775-9e85-b78c4dba4fbe.png)


#原因
CypherクエリーではUNION後の処理ができないため。

ORDER BY the result of UNION of subqueries
https://stackoverflow.com/questions/41448935/order-by-the-result-of-union-of-subqueries

#解決策
APOCを使う。

neo4j-contrib/neo4j-apoc-procedures
https://github.com/neo4j-contrib/neo4j-apoc-procedures

```
CALL apoc.cypher.run('
MATCH (a:Music)-[b:fit]->(c:Feeling{name:"泣ける曲"})
WITH a.name AS name,
     b.score AS score
RETURN name,score
UNION ALL
MATCH (:User{name:"user1"})-[:knows]->(a:User),
(a)-[b:likes]->(c:Music)
WITH c.name AS name,
     b.score AS score
RETURN name,score', {} )yield value
with value.name as name,SUM(value.score) as score order by score desc
return name,score
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/31d4fa77-e31e-3231-472f-0b74a4f40fe2.png)


#おまけ
テストデータを作成するためのクエリーを記載する。

```
CREATE (a:User{name:"user1"})
CREATE (b:User{name:"user2"})
CREATE (d:Music{name:"卒業写真",Artist:"松任谷由実"})
CREATE (g:Music{name:"ひまわりの約束",Artist:"秦基博"})
CREATE (j:Music{name:"負けないで",Artist:"ZARD"})
CREATE (k:Music{name:"何度でも",Artist:"DREAMS COME TRUE"})
CREATE (m:Feeling{name:"泣ける曲"})

CREATE (d)-[:fit{score:4}]->(m)
CREATE (g)-[:fit{score:5}]->(m)
CREATE (j)-[:fit{score:2}]->(m)
CREATE (k)-[:fit{score:2}]->(m)
CREATE (a)-[:knows]->(b)
CREATE (b)-[:knows]->(a)
CREATE (b)-[:likes{score:4}]->(d)
CREATE (b)-[:likes{score:3}]->(g)
CREATE (b)-[:likes{score:5}]->(j)
```
BotFramework Emulatorでプロキシを超える方法

BotFramework Emulatorでボットと会話する際、Azure上のボットからの通信は、一旦[ngrok](https://ngrok.com)クラウドサービスに送信されます。ローカルマシンのngrokプロセスは、ngrokクラウドサービスからその内容を受け取り、その内容をBotFramework Emulatorに転送します。プロキシの内側にあると、ngrokプロセスはngrokクラウドサービスから直接データを取得できません。つまり、ngrokプロセスにプロキシ経由でデータを取得してもらうための設定が必要になります。

現時点(3.5.34)のBotFramework EmulatorのApp Settingsダイアログでは、プロキシを設定できません。このため、システム環境変数に`http_proxy`を追加するか、`ngrok.yml`というngrok設定ファイルに`http_proxy`という項目を追加するかします。本記事では、環境変数に色々入れたくない方向けに、後者の方法を説明します。

## 急いでいる人はこれだけ読んで

1. 自分のホームディレクトリに`.ngrok2`という名前でディレクトリを作る
2. その中に`ngrok.yml`という名前でファイルを作る
3. そのファイルに以下の内容を書いて保存する

```
http_proxy: "http://ユーザ:パスワード@プロキシホスト名:ポート"
```
## BotFramework Emulator で読み込まれる`ngrok.yml`の場所

現時点の実装では、[ngrokマニュアルの「Default configuration file location」](https://ngrok.com/docs#default-config-location)で説明されている、デフォルトの場所のngrok.ymlだけを、ngrokの設定ファイルだと認識します。

つまり、以下の場所となります。

* `~/.ngrok2/ngrok.yml` (Unix系、OSX)
* `%HOMEPATH%\.ngrok2\ngrok.yml` (Windows系)

`ngrok.exe`などと同じディレクトリに`ngrok.yml`を作っていくら頑張っても無意味ですので、ご注意を。

### `ngrok.yml`どころか、`.ngrok2`ディレクトリもないんだけど？

ngrokを使い込んでいて有料プランを使っているような人でない限り、`.ngrok2`ディレクトリは存在しないはずです。ホームディレクトリに`.ngrok2`という名前のディレクトリを作って、その中に`ngrok.yml`という名前のファイルを作ればいいです。

ただ、それすら面倒だったり、本当にそこがデフォルトなの？と疑わしかったりする場合は、`ngrok authtoken .`と実行すると、ngrokがデフォルトと認識している場所に`ngrok.yml`を作ってくれます。

```
C:\>ngrok authtoken .
Authtoken saved to configuration file: C:\Users\User/.ngrok2/ngrok.yml
```

上記の場合、`C:\Users\User\.ngrok2\ngrok.yml`が作成され、デフォルトのngrok設定ファイルと認識されるようになります。

生成された`ngrok.yml`を開くと、`authtoken: .`という文字列が入っています。これは消してください。残っているとngrokでエラーとなります。

## `ngrok.yml`に書く内容

以下の行を追加します。これだけ。

```
http_proxy: "http://ユーザ:パスワード@プロキシホスト名:ポート"
```

現時点で`no_proxy`には未対応のようですので、プロキシ内の他のマシンにあるボットをテストする場合は、`ngrok.yml`を書き換えて切り替える必要がありそうです。

## それでも何かエラーが出てるんだけど？

ここまでの設定で、Azureボットとは会話できるようになっているはずです。それでも赤い文字でエラーが出ているかと思います。

```
[21:28:42] Checking for new version... 
[21:28:43] Command failed: 4294967295 System.AggregateException: (以下略
```

BotFramework Emulatorが起動するたびに更新がチェックされます。その際、Emulator内部で[Squirrel](https://github.com/Squirrel/Squirrel.Windows)というサードパーティのライブラリを呼び出しています。Squirrelライブラリ単独ではプロキシ設定を行うことができず、BotFramework EmulatorからSquirrelにプロキシ設定を渡す必要があるようですが、それをやってないために発生している模様です。

現状、プロキシ環境下では自動更新を諦め、定期的に[配布サイト](https://github.com/Microsoft/BotFramework-Emulator/releases)を確認するしかなさそうです。将来はSquirrel以外の方法での更新を検討しているようです。

参考: [Bot Framework-Emulator Auto-Update dose not support authentication proxy #329](https://github.com/Microsoft/BotFramework-Emulator/issues/329)
Amazon RDS(MySQL)で1億レコードのテーブルをTRUNCATE TABLEしてみる

MySQL(InnoDB)でトランザクションを張らずに大量のレコードを全行削除する場合、DELETEよりTRUNCATE TABLEの方が速いが、1億レコードの規模のテーブルでもサクッと削除できるのか検証。

# 環境
**下記の環境で新規インスタンスを構築**
DB：Amazon RDS (MySQL 5.7)
インスタンスサイズ：db.m4.large (2vCPU, mem=8GB)
ストレージサイズ：SSD 100GB (300IOPS)
リージョン：ap-northeast-1c (Single-AZ)

# 下準備
```sql
-- データベース作成
mysql> CREATE DATABASE `sampledb` DEFAULT CHARACTER SET utf8;
mysql> use sampledb;

-- テーブル作成
mysql> CREATE TABLE `sample` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data` varchar(255) NOT NULL,
`create_date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- 単純結合用のレコードをINSERT(１０行)
mysql> INSERT INTO `sample` VALUES
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00'),
(NULL, 'sample', '2017-12-18 00:00:00');

-- INSERTした10行を、8回単純結合すると1億レコードになる(10^8=100000000)
mysql> SELECT count(*) FROM sample, sample sample2, sample sample3, sample sample4, sample sample5, sample sample6, sample sample7, sample sample8;
+-----------+
| count(*)  |
+-----------+
| 100000000 |
+-----------+
1 row in set (11.16 sec)
```
# 実際に1億レコードをINSERTする
```sql
-- 実際に1億レコードをINSERTする
mysql> INSERT INTO `sample` (
select
sample.id = NULL,
sample.data,
sample.create_date
from sample, sample sample2, sample sample3, sample sample4, sample sample5, sample sample6, sample sample7, sample sample8
);
Query OK, 100000000 rows affected (10 min 17.67 sec)
Records: 100000000  Duplicates: 0  Warnings: 0

-- ファイルサイズを確認してみる
mysql> SELECT NAME,FILE_SIZE,ALLOCATED_SIZE 
FROM information_schema.innodb_sys_tablespaces WHERE NAME LIKE '%sample%';
+-----------------+------------+----------------+
| NAME            | FILE_SIZE  | ALLOCATED_SIZE |
+-----------------+------------+----------------+
| sampledb/sample | 3779067904 |     3779072000 |
+-----------------+------------+----------------+
1 row in set (0.00 sec)
```
# TRUNCATE実行
```sql
mysql> TRUNCATE TABLE `sample`;
Query OK, 0 rows affected (2.06 sec)
```
2秒程度で全行削除できました。

# 参考
* [なんとなくやりたかった。MySQLのクエリのみで簡単に1億ものデータを作成する方法](https://liginc.co.jp/programmer/archives/2707
)
* [InnoDBテーブルサイズのいろいろな確認方法](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0056)
新Python生活六日目【PyQ/9章】

学習は終わってはいましたが、
下書き途中にして放置してしまってました＞＜；

ほぼ一ヶ月も。。
**PyQからの引き落とし完了通知メール**で目が覚めました。

早く吸収して自己学習に切り替えないと！安月給なんだから･･･(お金は大事だよ)

#ファイルへの出力

```py3
with open('tmp/sample.txt','w',encoding='utf-8') as f: #ファイル名と文字コードの間に'w'を入れる
    f.write('hello, world\n') #ファイルに hello～ を書き込みました

print('書き込み完了')
```

#ループを使って出力してみる
```py3
lunch = ['月はカレー' #リストlunchに一週間の昼メニューを設定
         ,'火はうどん'
         ,'水はラーメン'
         ,'木はチャーハン'
         ,'金はうどん']

with open('tmp/sample.txt','w',encoding='utf-8') as f: #出力してくよ
    for menu in lunch: #lunchリストの一個ずつを変数menuに順に代入していくよ
        f.write(lunch + '\n')

print('書き込み完了')
```

```text:tmp/sample.txtの中身
月はカレー
火はうどん
水はラーメン
木はチャーハン
金はうどん
```

#ループを使って出力してみる②
```py3
zaiko = {'赤':5 #zaiko辞書
         ,'青':3
         ,'緑':1
         ,'黄':4
         }

with open('tmp/zaiko.txt','w',encoding='utf-8') as f: #出力してくよ
    for key, value in zaiko.items(): #キー と 値 をzaiko辞書を元に(?)
        f.write(key + 'は' + str(value)) #1行ずつ「キー」と「文字」と「値」を連結して書き込んでくよ
        f.write('\n')
print('書き込み完了')
```

```text:tmp/zaiko.txtの中身
赤は5
青は3
緑は1
黄は4
```

#日時をファイルに出力(出勤だけの打刻システムを作るよ)
```py3
from datetime import datetime #datetimeオブジェクトを利用するよ

now = datetime.now() #変数nowに代入するよ(now:2017-12-18 10:47:44.049200)
str_now = now.strftime('%Y/%m/%d %H:%M') #文字列に変換するよ(str_now:2017/12/18 10:47)

with open('tmp/kinmu.log','a',encoding='utf-8') as f: #出力するよ
    f.write(str_now + ' - 出勤\n') #変換した文字列と連結するよ(yyyy/mm/dd hh:mm - 出勤)
print('書き込み完了')
```

#続き(打刻した時刻によって出勤か退勤かを判断するシステム)
```py3
from datetime import datetime #datetimeオブジェクトを利用するよ

now = datetime.now() #変数nowに代入するよ(now:2017-12-18 10:47:44.049200)
str_now = now.strftime('%Y/%m/%d %H:%M') #文字列に変換するよ(str_now:2017/12/18 10:47)

with open('tmp/kinmu.log','a',encoding='utf-8') as f: #出力するよ
    if 6 <= now.hour <14: #打刻した時刻が6-14時なら
        f.write(str_now + ' - 出勤\n') #時刻の後に 出勤 と付ける
    else: #それ以外なら
        f.write(str_now + ' - 退勤\n') #時刻の後に 退勤 と付ける
    print('書き込み完了')
```
CentOS7にsambaをインストールして共有アクセス設定まで 

開発環境にサクッとsambaをインストールして、ファイルのやり取りをスムースに行いたい。
セキュリティ的にはゆるゆるなので、自己責任でお願いします。

# SELinuxの停止 

#### 設定変更

```
 # vi /etc/selinux/config
 
 #SELINUX=enforcing
 SELINUX=disabled
```

#### 反映

```
  # reboot
```
#### 確認

```
 # getenforce
 Disabled
```
 
# firewallの停止

```
 # systemctl disable firewalld
```

#### 確認 

```
 # systemctl is-enabled firewalld
 disabled
```

# 共有ディレクトリの作成

```
 mkdir /home/samba
 chmod -R 0777 /home/samba
 chown -R nobody:nobody /home/samba
```

# sambaインストール

```
 # yum install samba
```

#### 設定

```
 # cd /etc/samba
 # vi .conf

 [global]
 	workgroup = WORKGROUP    # 変更 環境に合わせて
 	security = user

 	passdb backend = tdbsam

 	printing = cups
 	printcap name = cups
 	load printers = yes
 	cups options = raw
 	map to guest = Bad User   # 追加 ゲスト許可
 	guest account = nobody    # 追加
  
 [homes]
 	comment = Home Directories
 	valid users = %S, %D%w%S
 	browseable = No
 	read only = No
 	inherit acls = Yes

 [printers]
 	comment = All Printers
 	path = /var/tmp
 	printable = Yes
 	create mask = 0600
 	browseable = No

 [print$]
 	comment = Printer Drivers
 	path = /var/lib/samba/drivers
 	write list = root
 	create mask = 0664
 	directory mask = 0775

# 以下、全て追加
 [samba]                
 	path = /home/samba/
 	browsable = yes
 	writable = yes
 	guest ok = yes
 	read only = no
```


#### 設定ファイルの確認

```
 # testparm
```

#### sambaをサービス登録、起動

```
 # systemctl enable smb.service
 # systemctl enable nmb.service
 # systemctl restart smb.service
 # systemctl restart nmb.service
```

# 接続確認
あとはwinなりmacなりで接続確認を行う。
配列とスライスとVecの挙動の違いについて調べてみた

#はじめに

いつも使っている言語のArrayのような存在がrustには３種類あった…

- 配列
- スライス
- Vec

みんな微妙に挙動が違う
いつまでも雰囲気で扱っていないでテーマを絞って挙動の違いについて掘り下げてみる

---
#テーマ

- 所有権
- ライフタイム
- 使用できるmethod

---
#概要

|　 　　　　　|配列  　　　　　　　　　　　　　　|スライス  　　　　　　　　　　　　|Vec  　　　　　　　　　　　　|
|:--:|:--:|:--:|:--:|
| 簡易説明  | 単一の型のオブジェクトの集合  | データへのポインタと長さ  | データへのポインタと長さ、容量  |
| 構造体サイズ  | 静的 | 動的(DST) | 静的 |
| 動的可変長 | × | × | ○ |
| プリミティブ  | ○ | ○ | × |
---
#所有権

Vecのみ非プリミティブ

---

プリミティブとCopy

- 全プリミティブの型はCopyを実装している
- Copyを実装していると所有権が移るのではなくオブジェクトのコピーが新しく生成される

---
配列はプリミティブ。Vecは非プリミティブ

```rust
fn main() {
  let tempArrayA: [i16; 3] = [1, 2, 3];
  let tempArrayB: [i16; 3] = tempArrayA;
  assert_eq!(tempArrayA, tempArrayB);

/* 所有権が移動した変数を使用したためエラー */
//  let tempVecA: Vec<i16> = Vec::new();
//  let tempVecB: Vec<i16> = tempVecA;
//  assert_eq!(tempHogeA, tempHogeB);
}
```

--- 
#ライフタイム

スライスのみ動的サイズの型(DST)

---
動的サイズの型(DST)とファットポインタ

- スライスはDynamically Sized Type(DST: 動的サイズの型)
- DSTはサイズやアライメントが静的には判断できない
- rustが型を静的解析するために他のポインタを利用してファットポインタを生成し、サイズやアライメントを示してやる必要がある

---

```rust
pub fn return_vec() -> Vec<i16> {
    vec![1,2,3]
}

pub fn return_array() -> [i16; 3] {
    [1, 2, 3]
}

// スライスだけではファットポインタを生成できないのでエラー
// pub fn return_slice() -> [i16] {
//     &[1, 2, 3]
// }
```

---

```rust
// エラー
// pub fn return_slice() -> [i16] {
//     &[1, 2, 3]
// }

// 引数を使ってファットポインタを生成してやる
pub fn return_slice<'a>(slice: &'a [i16]) -> &'a [i16] {
    slice
}

// 引数を使ってファットポインタを生成してやる
pub fn return_slice_implessly(slice: &[i16]) -> &[i16] {
    slice
}
```

---
#使用できるmethod
特定条件でスライスに型が強制変換される

---
型の強制変換

- rustはポインタやライフタイムのために型を強制的に変換する時がある
- mutable => immutableとかderefrenceとか

---
#配列を使っているつもりが実はsliceを使っている

```rust
  let tempArrayA = [1, 2, 3];
  
  // sliceに型を強制変換
  for i in &tempArrayA {
    println!("{:?}", i);
  }

  // sliceに型を強制変換
  for i in tempArrayA.iter() {
    println!("{:?}", i);
  }
```
---
まとめ

- Vecのみ非プリミティブ
- スライスのみ動的サイズの型(DST)
- 特定条件でスライスに型が強制変換される


---
# ご静聴ありがとうございました


---
参考リンク

- https://doc.rust-lang.org/std/primitive.array.html
- https://doc.rust-lang.org/std/slice/
- https://doc.rust-lang.org/std/vec/struct.Vec.html
- https://doc.rust-lang.org/beta/nomicon/exotic-sizes.html
- https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/ownership.html
- https://doc.rust-lang.org/nomicon/coercions.html
- https://stackoverflow.com/questions/30794235/what-is-the-difference-between-slice-and-array
Sublime Text3 + Shift_JIS > ConvertToUTF8 > Has changed on disk. Do you want to reload it?

```txt:動作環境
Windows 7 Pro (32bit)
Sublime Text 3 Build 3143 (以下SL3)
```

### 症状

SL3で編集中に数分おきに以下のメッセージが表示される。

> Sublime Text
> [ソースファイル名]
>
> Has changed on disk.
> Do you want to reload it?

Shift_JISファイル(.c, .h)を修正しているときに起きるようだ。
Shift_JISにはConvertToUTF8を使用しているが、その処理を"Has changed on disk."と認識してしまう。

Sublime Text2では起きなかった症状だ。

### 対策

1. UTF8で編集して、チェックイン前にShift_JISに変換する
2. Sublime Text2 + ConvertToUTF8を使う
3. 他のエディタ(Visual Studio Codeなど)を使う

方法1はエンコーディング変換忘れが起きそう。
方法2は古いSL2をいつまで使って問題ないかという懸念はある。
方法3は、VS Codeの[「関数リスト取得できない不具合」](https://qiita.com/7of9/items/a2286df53c1384b9fba6)がなければ使うのだが。

過去の膨大なソースがあるため、Shift_JISのコードをUTF8にするのは現実的ではないだろう。
iOS11のスクリーンショットをApp Extensionで使う方法


この記事は[Swift その2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/swift2) 18日目のコンテンツです。


# App Extensionとは
iOS8からある機能
四角から上に矢印伸びたボタンを出てくるアレ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37217/2bce1f44-a3d1-09c5-2ca1-b3eae483644d.png)

# App Extensionの基本的な使い方

```swift
if let extensionContext = self.extensionContext,
   let item = extensionContext.inputItems.first as? NSExtensionItem,
   let attachments = item.attachments as? [NSItemProvider],
   let attachment  = attachments.first {
   let contentType = kUTTypeImage as String
            
   attachment.loadFileRepresentation(forTypeIdentifier: contentType) { (url, error) in
   // Do Something with url
   // url -> Image,  url -> Data
  })            
}
```

loadFileRepresentation()というメソッドを使って画像URLを取得 していました。URLあれば、なんでもできそうだったからです。URLからUIImageに変換したり、URLからDataに変換したり。

# iOS10以前と11でのURLの違い。

```swift
if let extensionContext = self.extensionContext,
   let item = extensionContext.inputItems.first as? NSExtensionItem,
   let attachments = item.attachments as? [NSItemProvider],
   let attachment  = attachments.first {
   let contentType = kUTTypeImage as String
            
   attachment.loadFileRepresentation(forTypeIdentifier: contentType) { (url, error) in
   // Do Something with url
   // iOS10
   // “file:///private/var/mobile/Containers/**/P105.PNG”
   // 
   // iOS11
   // “file:///private/var/mobile/Containers/**/image”
  })            
}
```
しかし、Screenshotを取った時にApp Extensionで取得できるURLが上記のように末尾が `/image` なってしまいました。このURLをもとにUIImageやDataに変換しようとしてもエラーが出てしまいます。

そこで以下のように対処しました。

```swift
if let extensionContext = self.extensionContext,
   let item = extensionContext.inputItems.first as? NSExtensionItem,
   let attachments = item.attachments as? [NSItemProvider],
   let attachment  = attachments.first {
   let contentType = kUTTypeImage as String
            
   attachment.loadItem(forTypeIdentifier: contentType, options: nil) { (data, error) in
       if type(of: data!) == UIImage.self {
          // iOS 11 screenshot
       } else if type(of: data!) == NSURL.self {
                    
       }
   }            
}
```

この方法にはいくつか欠点があります。

- 想定していないタイプが来たらどうする？
- ドキュメントは？ -> 観測範囲ではない

最後に紹介した方法で動くは動くのですが、他になにかいい方法あったら教えてください。
awsrmを使ってAWS EC2用のAnsible Dynamic Inventoryを作ってみる

[awsrm](https://github.com/k1LoW/awsrm)で気楽にAWSのリソース情報を取得する例として、awsrmを使ってあるELB（`my-elb`）配下のEC2群に対してAnsibleでプロビジョニングをしてみます。

## 前提

- 同じVPC内の踏み台インスタンスからAnsibleを実行するとします
- SSHの公開鍵設定などは終わっているとします
- Ansibleのsite.ymlの `hosts` には `web` が設定されているとします

## gemのインストール

まずGemfileを作成します。

```ruby
# Gemfile
source 'https://rubygems.org'

gem 'awsecrets'
gem 'awsrm'
```

[awsecrets.gem](https://github.com/k1LoW/awsecrets)はawscliのように各種AWS関係の環境変数を読み込んでくれるライブラリです (awspecの中で使われています）。

今回作成するinventory.rbで `AWS_PROFILE` を読み込んでAWSのクレデンシャルを設定して欲しいので利用します。

bundle installでgemをインストール

```sh
$ bundle install
```

## inventory.rbの作成

```ruby
#!/bin/bash bundle exec ruby

require 'awsecrets'
require 'awsrm'
require 'json'

# AWSのクレデンシャル情報の読み込み
Awsecrets.load

# my-elb 配下のEC2インスタンスの `private_ip_address` を取得
instance_private_ips = Awsrm::Ec2.all(elb: 'my-elb').map(&:private_ip_address)

# Dynamic Inventoryのフォーマットで出力
puts JSON.dump(web: instance_private_ips)
```

上記のRubyスクリプトで、ELB `my-elb` 配下のEC2のPrivate IPを取得して[Dynamic Inventoryのフォーマット](http://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html)で出力ができます。

ポイントとしては、Shebangを `#!/bin/bash bundle exec ruby` とすることでrbenvのRubyやBundler配下のgemを利用するようにしています。

## Ansibleの実行

最後に実行権限を与えて

```sh
$ chmod +x inventory.rb
```

あとは `ansible-playbook` でプロビジョニングが可能です。

```sh
$ AWS_PROFILE=produciton ansible-playbook -i inventory.rb site.yml
```

## awsrm

このようにawsrmは「直感的にAWSリソースを取得できれば。。」と思ってのんびり開発をしています。

対応リソースの要望や機能追加のアイデアがあれば是非。
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十四章 モデルの整合性を維持する3 継続的な統合

# これまでの十四章
- [第四部 戦略的設計 第一四章 モデルの整合性を維持する](https://qiita.com/YasuhiroKimesawa/items/6e8e5503a05ce9515a79)
- [境界づけられたコンテキスト](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61)

# 継続的な統合(Continuous Integration)

技術的には一般的にいうCI。DDDでも同様だが、**モデル概念の統合**という意味も含まれています。

> コンテキスト内で行われるすべての作業について、頻繁にマージして一貫性を保つことにより、**分派**([前回の記事参照](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61))が見られた時に直ぐに発見して修正できるようにすることを意味する。

## 概念の統合

概念の統合とは以下のことを言います。

> モデルとアプリケーションに関する議論における、ユビキタス言語の絶え間ない鍛錬

前回読んだように、概念は別々の人の頭のなかで進化していく。分派もそのなかで起こる。なので、大前提として、モデルに対する共有された見方を練り上げることが大事。

その上で技術的なCIを実施し、モデルの分裂に対して素早く警告する自動化されたテストを実施する。

## 継続的統合を実施する基準

まず、継続的統合は**境界づけられたコンテキスト内だけ**でOK。逆にそれ以上広げると結合が難しくなる。他のコンテキストとのペースを合わせなくてはならなくなるからですね。

また、境界づけられたコンテキストが２人以上で作業するのであれば、継続的な統合は有効とのことです。これには自分も同意です。
Amazon ElastiCache Redis ClusterにPythonからアクセスする

Amazon ElasticCache Redis Clusterに[redis-py-cluster](https://github.com/Grokzen/redis-py-cluster)で接続する際に、
hostとportだけではダメで、

https://github.com/Grokzen/redis-py-cluster/issues/166

ここに書いてある通り、
 `skip_full_coverage_check=True` のフラグを立てると

```
r = StrictRedisCluster(host="xxx.cache.amazonaws.com", port=6379, skip_full_coverage_check=True)
```
アクセス出来る。


--- 
#### error内容
> r = StrictRedisCluster(host="xxx.cache.amazonaws.com", port=6379)
> `redis.exceptions.ResponseError: unknown command 'CONFIG'` 


#### ちなみに
[redis-py](https://github.com/andymccurdy/redis-py)はredis-clusterには対応しなさそう。 [ソース](https://github.com/andymccurdy/redis-py/issues/931)
terraformを使ってhelmをコードで管理する

# はじめに

この記事は[Kubernetes Advent Calendar 2017](https://qiita.com/advent-calendar/2017/kubernetes)の18日目の記事です。

helm便利ですよね。各種アプリケーションをコマンド一発でk8sクラスタにデプロイできます。
でも`helm install`でリソースデプロイしてるとちょっと不安になってきませんか。
IaC的にも何のhelm chartをデプロイしているかコードで管理したくなります。

そこでhelmをコードで管理する方法を探したところ

- [terraform-provider-helm](https://github.com/mcuadros/terraform-provider-helm)
- [helmfile](https://github.com/roboll/helmfile)

というものがありました。

この記事では`terraform-provider-helm`の使いかたについて説明します。
`helmfile`の方がスター数はあったんですが、やはりTerraformによるワークフロー抽象化の流れに組み込めるってのは魅力かなと思います。
なお、helm自体やterraform-provider-helmのpluginのインストールについては割愛します。

## 使用バージョン

- kubernetes: 1.7.7
- helm: 2.6.1
- terraform: v0.11.0
- terraform-provider-helm: v0.3.2

# helm providorの設定

providerの設定ですが、概ね3通りの設定方法があります。

## 何も設定しない

```
provider "helm" {
}
```

providorに何も設定しないと`~/.kube/config`のcurent_contxtのクラスタに対してhelm chartがデプロイされます。楽ですが、複数クラスタを運用していると事故の元なので明示的にクラスタを指定する以後の方法が良いと思います。

## クラスタのconfigを指定する / contextを指定する

```
provider "helm" {
    kubernetes {
        config_path = "~/.kube/config-cluster-a-1"
    }
}
```

or

```
provider "helm" {
    kubernetes {
        # 省略可能
        config_path = "~/.kube/config"
        
        config_context = "config-cluster-b-1"
    }
}
```

クラスタの個別の接続情報を指定する、あるいは`~/.kube/config`から接続情報を読んでコンテキストを明示的に指定する方法です。この方法なら複数クラスタ環境配下でも現在のコンテキストに依存せず、デプロイできます。

## 接続設定を全部書く

```
provider "helm" {
    kubernetes {
        host     = "https://104.196.242.174"
        username = "ClusterMaster"
        password = "MindTheGap"

        client_certificate     = "${file("~/.kube/client-cert.pem")}"
        client_key             = "${file("~/.kube/client-key.pem")}"
        cluster_ca_certificate = "${file("~/.kube/cluster-ca-cert.pem")}"
    }
}
```

接続情報をTerraformに全部載せることも可能みたいです。

# helm_chartリソースの設定

helm_chartリソースが実際にデプロイするhelm chartの定義になります。
nginx-ingressをデプロイする例です。


```
resource "helm_chart" "nginx_ingress" {
    name      = "nginx-ingress"
    chart     = "stable/nginx-ingress"
    namespace = "nginx-ingress"

    set {
        name = "controller.ingressClass"
        value = "ingress-1"
    }

    set {
        name = "controller.kind"
        value = "DaemonSet"
    }
    
    set {
        name = "controller.service.externalTrafficPolicy"
        value = "Local"
    }
}
```

helm charに渡すパラメータはset内にkvとして渡せます。

また、普通のchatsと同様に`values`キーに`values.yaml`のファイルパスを渡してファイルからパラメータを設定することも可能そうです。

# 終わりに

ざっくりとした使い方の説明は終わりですが、最後に1点だけ。
`terraform-provider-helm`はまだ安定していないのか、普通に使ってると`unexpected EOF`が頻発してして上手く`apply`や`plan`ができなくなります。
[こちら](https://github.com/mcuadros/terraform-provider-helm/issues/25)に該当のissueが上がっており、`-parallelism=1`をつけると回避できるそうです。
`terraform-provider-helm`を使用する際はしばらくは基本的につけておいた方が良いと思います。

以上`terraform-provider-helm`の紹介でした。
Terraformでデプロイするhelm chartの定義をコード化しておけば、クラスタ作り直す際も楽で良いです。
Web開発者がスマートコントラクト開発で戸惑いがちなポイント8個

こんにちは、[@kojamam](https://twitter.com/kojamam)です。10日目の記事をを代わりに投稿させていただきます。

最近、Solidityによるスマートコントラクト開発の講義することがあったのですが、Web業界に浸っていた人が戸惑いがち、つまりがちなポイントが共通してあるなと思ったので書き留めておきます。

Webとブロックチェーンはかなり性質の異なる技術なので、これからブロックチェーンに触れ、スマートコントラクトを書き始める人のためになればうれしいです。

以下では特に断りがない限りPublicなEthereumネットワークの話をします。また感覚的に理解してほしいため、厳密性には欠ける部分があります。

## 言葉の対応
まず、簡単な対応表を書いておきたいと思います。厳密には一対一ではないですが、感覚的にはこんな感じです。

|Web|Ethereum|
|:--:|:--:|
|クラス|コントラクト|
|メンバ変数|ステート変数|
|メソッド|メソッド|
|リクエスト|トランザクション, コール|


## 戸惑いポイント
### その1: アプリケーションサーバーがない
Webだとアプリケーションサーバーを立てて、そこにコードをデプロイして、アプリケーションが動くという一連の流れがあります。それに対し、EthereumのスマートコントラクトはEVMと呼ばれる「すべてのEthereumノードが構成するブロックチェーンネットワーク上に構成された単一のVM」上にデプロイされ動作するため、特定のサーバーで動くというわけではありません。つまり、スマートコントラクトを動作させるのに自前のサーバーを持っておく必要もありません。
このような特徴を持っているため、Ethereumは「ワールドコンピュータ」と呼ばれることもあります。

### その2: デプロイ=インスタンス化
スマートコントラクトは"コントラクト"と言う単位でデプロイを行います。コントラクトはクラスのようなもので、変数やメソッドが含まれたまとまりです。

コントラクトは前項で説明したようにEVM上にデプロイされるわけですが、デプロイと同時にインスタンス化が行われ、コンストラクタが実行されます。デプロイされる度にコントラクトには固有のアドレスが発行され、永続化されます。

一つのコントラクトを複数インスタンス化するためにはインスタンス化する度にデプロイする必要があります。デプロイには多くのGas(手数料)を消費するのでむやみに行うものではありません。

### その3: DBMSやファイルストレージはない
WebではアプリケーションがDBMSとやり取りをし、データを処理をするというのが一般的です。しかし、スマートコントラクトはそのようなことは出来ません。[^1]

コントラクトのインスタンスは永続化されているため、ステート変数(メンバ変数のようなもの)にデータを保持しておくことになります。データを保存する度にGasがかかるため、その辺も考慮しておきましょう。

ファイルストレージもないので必要ならば別に用意する必要があります。[^2]

### その4: リクエストには2種類ある
コントラクトに対するリクエストには2種類あります。

一つ目は"トランザクション"といい、コントラクトの状態を変更する、つまりマイナーに処理を行ってもらいチェーンにデータを書き込むリクエストです。これはEthereumに限った話ではありませんが、チェーンにデータを書き込むトランザクションにはGasがかかります。

二つ目は"コール"といい、コントラクトの情報を読み取るリクエストです。こちらは書き込みが発生しないのでGasはかからず実行できます。なお、状態を変更が必要なメソッドをコールで呼び出すことは出来ません。

コールとトランザクションを区別してコントラクトを設計しましょう。

### その5: アップデートや停止はできない

スマートコントラクトは一度デプロイするとEVM上で自律的に動作します。開発者のサーバーで動いているものではありません。これがどういうことを意味するかというと、デプロイされたコントラクトは開発者の手を離れてしまい、アップデートや停止といった操作はできません。
ブロックチェーンは過去の履歴を改竄されないことがその特徴なので、一度デプロイされてチェーンに書き込まれたものを書き換えることが出来ないのです。

アップデートしたい場合は別インスタンス、別アドレスとしてデプロイし直す必要があります。この場合も以前のコントラクトは消えません。

### その6: コントラクトの内容はすべて公開される

コントラクトへのトランザクションがEVMで実行されるにはすべてのマイナーがその内容を取得できなければなりません。ですのでコントラクトに書いたメソッド、変数などは全世界に公開されます。公開されていることでトランザクションの処理と証明が行えるのです。

外に漏らしてはいけない機密情報をコントラクトに保存するのは避けましょう。

### その7: 乱数は作れない

コントラクトでは基本的に乱数を作ることは出来ません[^3]。すべてのマイナーでトランザクションの実行結果が同じにならないといけないので不確定の要素は含めることは出来ないのです。

### その8: 時間とカネがかかる

先程からGasを消費するというという話をしてきましたが、トランザクションの実行には必ずGasと呼ばれる手数料がかかります。GasはEtherで支払うので結果的に現実のお金を消費することになります。基本的にはトランザクションの送信元ユーザーに手数料を毎回負担してもらうことになります。

また、各トランザクションはその承認を待たないといけないため、処理に時間がかかります。通常のWebアプリケーションのように即時処理をするのは不可能です。

## まとめ

以上となります。思いついたものを書いたため、不足もあるかもしれませんがWebとはだいぶ違うんだなと言うことが分かっていただけたかなと思います。

ブロックチェーンエンジニアが増えていって情報もどんどん増えていってくれればれしいです。


[^1]: これに対し[Bluzelle](https://bluzelle.com/)(未リリース)といったソリューションもあります。
[^2]: [IPFS](https://ipfs.io/)というP2Pファイルシステムを使う場合もあります。 
[^3]: こんなものはありますが、これを使っても乱数の即時生成は出来ません。→[RANDAO](https://github.com/randao/randao)
UserDefaultsへのCodableの保存とmigration

こんにちは！リードエンジニアの[@Utmrer](https://twitter.com/Utmrer)です！ヴァイオレット・エヴァーガーデンが楽しみ過ぎて早く年越したいと毎日思っています。
この記事は[コネヒト Advent Calendar 2017](https://qiita.com/advent-calendar/2017/connehito)の18日目の記事です。

今日はCodableについて書くのですが、Swift4に追加されたCodableはとても便利で、JSONを構造体にマッピングするために使っている方が多いと思います。
Codableに準拠すればDataクラスへの変換を挟むことでUserDefaultsへ保存することができ、弊社では一部のデータモデルでその処理を行っています。
この記事ではUserDefaultsへのI/Fをサッと説明して、データモデルの変更(migration)についてもサッと説明します。

## UserDefaultsへのCodableの保存
それではまず`id`と`name`を持つUserをCodableに準拠して定義します。

```swift:User.swift
struct User: Codable {
    let id: Int
    let name: String
}
```

ではUserDefaultsに保存してみましょう。

```swift
let user = User(id: 1, name: "violet")
let data = try? JSONEncoder().encode(user)
UserDefaults.standard.set(data, forKey:"auto_memories_doll")
```

簡単ですね。では取り出してみましょう。

```swift
guard let data = UserDefaults.standard.data(forKey: "auto_memories_doll") else {
    return
}
let user = try? JSONDecoder().decode(User.self, from: data)
```

簡単ですね。Decodeに失敗した時は`nil`になります。

## Userを変更する(migration)
ではここでUserに年齢を表す`age`を追加したくなったとします。

```swift:User.swift
struct User: Codable {
    let id: Int
    let name: String
    let age: Int
}
```

このようにデータモデルが変更された時、UserDefaultsには変更される前の情報しか無く、Optionalではない`age`の情報がないためUserDefaultsから以前保存したUserを取得出来なくなってしまいます。

```swift
// ageを追加しただけだと`user`がnilになっちゃう
let user = try? JSONDecoder().decode(User.self, from: data)
```

以前保存した`id=1`, `name=violet`というデータを失いたくない時はDecodableに定義されている`init(from decoder: Decoder)`を実装してあげましょう。
「UserDefaultsに保存されていない」が「ageはOptionalではない」ので、下記のように初期値を与えてあげるといいでしょう。

```swift:User.swift
struct User: Codable {
    enum CodingKeys: String, CodingKey {
        case id
        case name
        case age
    }

    let id: Int
    let name: String
    let age: Int

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(Int.self, forKey: .id)
        name = try values.decode(String.self, forKey: .name)
        age = (try? values.decode(Int.self, forKey: .age)) ?? 0
    }
}
```

## まとめ
以前、自分のブログで[Swift4のCodable(Decodable)でStringの値をIntにcastする](http://blog.yutmr.com/posts/codable-string-to-int)というのを書いたのですが、Codableは「ちょっと頑張れば痒い所に手が届く」って感じですね。
以上、田村でした！明日は[@super_manner](https://twitter.com/super_manner)の「API Client ToolのPawのExtension周りの話」かもしれないし、違うかもしれません！
良いお年を！

[コネヒト Advent Calendar 2017](https://qiita.com/advent-calendar/2017/connehito)
任意のURLに1行メモを残す1行JavaScript

```js
javascript:(function(s,k,v,w){v=s.getItem(k)||"";w=prompt(k,v);if(w!=null)s.setItem(k,w)})(localStorage,"$Memo> "+location.href)
```

こちらをブックマークに保存するだけ。
任意の URL をキーにしてメモを残すことが出来る。
ブラウザに保存されるため端末を変えると見ることが出来ないので注意。

# 用途例

- Twitter で随分前にフォローした／されたこの人、何つながりだったっけ…
    - → フォローした／された時にその人の TL を開いてメモを書いておけば、忘れた時にこっそり思い出せる！
- Facebook で友達になったこの人、何つながりだったっけ…
    - → 友達になった時に以下略
- LinkedIn でむっちゃオファー来る…この会社どんな会社だっけ…
    - → 以下略
- mixi で以下略