OmniAICreator/Qiita-1.07M huggingface dataset:
商用Webアプリの導入検証をするにあたって詰まりがちなこと

業務として商用Webアプリを導入する際、試用版を用いて社内の運用上問題は無いか、使いづらいところはないかなどを調査することがあります。
ここでは導入検証にするにあたって詰まりがちなことを紹介します。
今回想定しているのは

* 社内で一部の利用者が利用するWebアプリケーション
* 認証はSAML
* 社内でサーバを用意しインストールする

Webアプリケーションとなります。

## アカウントの権限
多くのWebアプリケーションのアカウントは

* 管理者
* 編集権限を持つユーザー
* 読み込み専用のユーザー

の3段階に分かれています。
多くのケースではこれで問題ないのですが、Webアプリによってはユーザーに渡す権限を想定よりも強いものにしなければならない場合があります。
想定する用途に対して適切に設定できるかを確認しましょう。

検証したとあるWebアプリケーションでは、プロジェクトごとにユーザーを関連付けるWebアプリケーションで、プロジェクトの外部リポジトリとの連携を設定変更するのにシステム全体の管理権限を必要だったので、想定以上に強い権限を渡さなければならなかったということがありました。

アプリケーションの試用に関しては、要望を出す以外にはマニュアルを手厚く書いて運用でカバーということが多くあります…

## SAML認証
SAML認証対応と表記してあるWebアプリケーションでも、いざ実際にSAML認証を有効化しようとするとトラブルが起きることがあります。

* SAML認証設定自体のトラブル
    * 属性のマッピング自体の説明が抜けている
    * マッピングの対応関係が公開されていない
* SAML認証で作成されたアカウントのトラブル
    * SAML認証で作成されたアカウントが削除できない
    * SAML認証で作成されたアカウントが無効化できない
    * アカウントの属性のバリデーションがSAML認証経由ではバイパスされて不整合が起こる

などがありがちです。
早めに検証環境を作り、開発元に問い合わせましょう。

## ブラウザの言語設定
Webアプリによってはインタフェースやドキュメントが日本語化されていることがあります。しかしながら

* 日本語訳されている部分に誤訳がある
* 日本語訳のドキュメントが英語よりも古いバージョンしかない

など、英語版のインタフェースやドキュメントに切り替えたい場合があります。
各ユーザーのアカウント設定で、使用する言語を切り替えられる場合には問題ないのですが
一部のWebアプリではそのような設定が出来ません。
このような場合にはブラウザの言語設定を切り替えて、英語を優先的に使用するようにすると
英語版のインタフェースやドキュメントを手に入れることができます。
普段使いのブラウザとは別に、検証用に英語を優先的に使用する別のブラウザを用意しておくと便利です。
SmartGit > Visual Studioの新規プロジェクト(WPFアプリ)作成からpushするまで

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
SmartGit v17.1.2 #11190
Sublime Text 2
```

SmartGitでVisual Studioのプロジェクトを管理する。
新規プロジェクト作成からの手順について記載する。

### 手順

1. Gitリポジトリをサービス上で作成
    - bitbucketやGitHubなど
2. Visual Studioで新規プロジェクトを作成
    - WPF アプリ(.NET Framework)
    - 「新しいGitリポジトリの作成」にチェックを入れておく
3. SmartGitにてリポジトリを追加
    - Repository > Add or Create...
    - 手順2で作成したプロジェクトのフォルダを選択
4. SmartGitにてリモート設定
    - Remote > Add
    - URL or PathにGitリポジトリのURIを入力する
    - Name: origin
5. SmartGitにてPushする

### 備考

手順2で作ったGitリポジトリにより、以下の２つの日本語コミットが生成される(日本語OSにて)。

- .gitignoreおよび.gitattributesを追加します。
- プロジェクトファイルを追加します。

Visual Studioのチームエクスプローラでリモート設定することも可能だが、SmartGitで他の言語のリポジトリも扱っているので、SmartGit上での方法を使う。
イミュータブルデータモデルと webアプリケーションにおける現実解

これは第2のドワンゴ Advent Calendar 2017の5日目です
5日11時時点で2日担当の yonex がまだ記事書いてないですが、気にせず続けます。niconico(く)のリリースが来年と聞いて残念な気持ちです。

# おめー誰よ？
ドワンゴ Advent Calendar皆勤賞っぽいですが、私はドワンゴ社員ではありません。
定年をとうに過ぎたおじさんです。

# 前置き
web アプリケーションの開発において、データモデリングはとても重要です。
SIerではDBAとか言って専門の設計担当がいるみたいですが、中小webサービス企業でそこまでの分業ができるわけもなく、大体においてwebアプリケーション(サーバサイド)エンジニアが担当することになります。

# [イミュータブルデータモデル](https://www.slideshare.net/kawasima/ss-40471672)
詳細はリンクに譲りますが、「履歴を全て残すようなデータ設計にし、 UPDATE を廃することで情報の追跡可能性を確保、堅牢な設計にする」モデリング手法です。
原則この手法に従うと、そうそう汚いモデルにはならないという優れもの(雑)

# イミュータブルデータモデルの欠点
イミュータブルデータモデルを適用すると、イベント(状態変更のトリガー)を別テーブルに置く、ということになります。それは「状態が他のテーブルに依存する」ことを意味します。
状態を取得したい場合には、対象のテーブルに、関連イベントのテーブルを全部joinして最新イベントを取得して…って手順を踏むこととなり、リアルタイム性が重要視される web アプリケーションではパフォーマンス面での問題が発生します。

状態のほか、口座に対する入金イベントと出金イベントがあるような場合だと、残高を取得する際に同様のパフォーマンスの問題が起きます。

# 欠点への対応方法
1. DB の性能をあげて頑張る
1. あるタイミングでの状態を含むスナップショットを保存して、状態取得の際に必要なイベントの量を減らす
1. 「キャッシュとしての状態カラム」を作り、イベントの発生タイミングで状態カラムを書き換え、状態の取得についてはそのカラムを参照する

## DB の性能をあげて頑張る
「札束で殴る」パターン。これで大丈夫なら大丈夫ですが、だいたいイベントデータが増えると破綻します。

## スナップショットを保存して、状態取得の際に必要なイベントの量を減らす
スナップショット用のテーブルを用意し、特定時点での状態(を含んだ各種データ)を保存します。
取得データ量の減少と信頼性の担保の両立ができますが
* ロジックが複雑になる(スナップショットをいつ作成するかを考える必要がある)
* イベントの量によってはスナップショットのデータ量がバカにならない

といった欠点もあります。
スナップショットの存在を要件としてポジティブにできれば採用できそうです[^1]

## 「キャッシュとしての状態カラム」を作り、状態の取得についてはそのカラムを参照する
状態取得のコストをミニマムにできます。
書き込みと読み込みを比べて極端に読み込みが多い場合[^2]に有効です

キャッシュとしてのカラムが存在するということは、
* 冗長である(イベントレコードの作成とキャッシュカラムの変更を同一トランザクションで行う必要が出てくる)
* 読み込みはキャッシュ不使用に比べて速い
* (厳密なイミュータブルデータモデルではなくなる)

ということになります。
厳密な設計に限定的な妥協をして、書き込みの手間を増やして読み込みを効率化します。

「限定的な妥協」の限定がなくなってしまうと、ただの崩れた設計になってしまうので、
ドキュメント等で「基本はイミュータブルデータモデルで、このカラムはキャッシュである」という認識を共有するのが大事です


# まとめ
堅牢な設計は大事だけど、パフォーマンスも大事。要求に応じて適切な設計を選びましょう。


[^1]: 残高の話の場合は採用しやすそうな気がします
[^2]: だいたいの web サービスはそうなると思います
BigQueryでセキュリティ関連の機能が追加

2017年12月4日にBigQueryに機能が追加されました。

この投稿は下記ページのメモです。
https://cloud.google.com/blog/big-data/2017/12/focus-on-security-bigquery-announces-support-for-customer-managed-encryption-keys-and-custom-roles-for-identity-access-and-management

#1. 暗号化鍵の管理をユーザができるようになった
BigQueryを使うとき、デフォルトでデータは既に暗号化されていますが、このときの暗号化鍵をユーザが管理できるようになった。鍵の管理はCloud KMSで実施。組織のポリシーで鍵の管理を自分たちでコントロールできるようにしないといけないという要件があった場合などは、この機能で対応できるようになった。

#2. IAMのカスタムロールをサポート
BigQueryがIAMのカスタムロールをサポートするようになったので、組織の要件にあった細かな設定ができるようになった。

#3. クエリフィルタリングの改善
BigQueryのUIでQuery Historyをクリックすると、実行したジョブをフィルタリングする機能（Sort by)があるが、このときソートする指標が増えた。

#4. ワイルドカードを使って複数のテーブルに対してクエリをかけられるようになった
例えば以下のように指定すると、bigquery-public-dataプロジェクトのnoaa_gsodデータセットにあるgsodで始まるテーブル名のテーブルに対してクエリを発行できる。

```
FROM
  `bigquery-public-data.noaa_gsod.gsod*`
```

詳細は以下を参照
https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_partitioned_tables_using_partitiontime
PeerCast プログラミング配信 Advent Calendar 2017 5日目

#やったこと
【完】CentOSにJavaのコンパイルできる環境を作る
【完】JavaでHelloworldのプログラムを作る

【途中】ヌメロンのプログラムをJavaで作る
・Randomな数値を表示させた
・入力した文字列を数値に変換させた
代数ビジョン入門

## はじめに
[数学とコンピュータ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/math-and-computer)
12月5日の記事として、代数ビジョンについて簡単に紹介します。

代数ビジョン（algebraic vision）とは、コンピュータビジョンのさまざまな問題に代数幾何の道具を応用しちゃおう、という比較的新しい研究分野です。この記事では、代数ビジョンの基本的な研究対象である多視点多様体（multiview variety）を定義したいと思います。

## 射影空間
$n$ 次元の射影空間 $\mathbb{P}^n= \mathbb{P}\bigl( \mathbb{C}^{n+1} \bigr)$ とは、$n+1$ 個の複素数の比
$$ [x_0: \dots : x_n ] \quad  \text{（少なくとも1つの $x_i$ はゼロでない）}$$ が構成する空間です。

0でない複素数の集合を $\mathbb{C}^\*$ とかくと、全ての $\lambda \in \mathbb{C}^\*$ に対して、
$$[x_0: \dots : x_n ] = [\lambda x_0 : \cdots : \lambda x_n] \in \mathbb{P}^n$$ は同一の点を表します。 

## 線形射影（ピンホールカメラ）
$n>m$ を自然数とし、次のように行列 $P$ で表される全射線形写像 $s: \mathbb{C}^{n+1} \rightarrow \mathbb{C}^{m+1}$ を考えます。
$$
\begin{pmatrix}
y_0 \\\\
\vdots\\\\
y_m
\end{pmatrix} =
P
\begin{pmatrix}
x_0 \\\\
\vdots\\\\
x_n
\end{pmatrix}.
$$

この写像は定数倍を保つため、 $[x_0 : \cdots : x_n]\in  \mathbb{P}^n$ を $[y_0 : \cdots : y_m]\in \mathbb{P}^m$ に移す射影空間の間の写像とも思えそうですが、$$P
\begin{pmatrix}
x_0 \\\\
\vdots\\\\
x_n
\end{pmatrix}=\mathbf{0}$$ を満たすような点 $[x_0 : \cdots : x_n] \in \mathbb{P}^n$ は、射影空間 $\mathbb{P}^m$ 上の点に移すことができません。
（$\mathbb{P}^m$ の点 $[y_0 : \cdots : y_m]$ では、少なくとも1つの $y_i$ はゼロでない、と定めたのでした。）

このように写像が定義されない点（不確定点という）もあるのですが、不確定点の集合 
$$Z:= \mathbb{P} \bigl( \mathrm{ker} (s)\bigr) \subsetneq \mathbb{P}^n$$ を除けば、大部分の点に行き先が定まります。

このとき、$s$ が定める「写像もどき」を、$\varphi: \mathbb{P}^n \dashrightarrow \mathbb{P}^m$ のようにダッシュ矢印で表し、射影空間の線形射影と呼びます[^1]。 線形射影は、一般の次元のピンホールカメラモデルに対応します。

[^1]: このような代数多様体から低次元の不確定点集合を除いて定まる写像（の同値類）を、有理写像と呼んで、同様のダッシュ矢印で表します。


| 線形射影 | ピンホールカメラ |
|:------:|:------:|
| $n$ | 空間の次元 |
| $m$ | 写真の次元 |
|行列 $P$ | カメラ行列（定数倍を除く） |
|不確定点集合 $Z$ | カメラの中心、焦点 |

## 多視点多様体
$r$ 個の線形射影 $\varphi_i : \mathbb{P}^n \dashrightarrow \mathbb{P}^{m_i} \ (i=1,\dots , r)$ を用いて、次のような有理写像を考えます。
$$\Phi = (\varphi_1, \dots , \varphi_r) : \mathbb{P}^n \dashrightarrow \prod_{i=1}^r \mathbb{P}^{m_i}$$ この $\Phi$ の像[^2] $X$ を多視点多様体（multiview variety）と呼びます。

代数ビジョンでは、さまざまな次元、さまざまな配置のカメラに対する多視点多様体や、そのモジュライ空間の幾何学を調べることで、複雑なコンピュータビジョンの問題をシンプルに解くことが目指されています。

[^2]: 不確定点集合を除いた部分集合の像の閉包のこと。

たとえば、$n=3, r=2, m_1=m_2=2$ の場合（[エピポーラ幾何](https://en.wikipedia.org/wiki/Epipolar_geometry)の場合）の対応を表にすると次のようになります。

| 多視点多様体 $X$  | エピポーラ幾何 |
|:--------------:|:--------------:|
| $X$ の点 | 2枚の写真の間の点の対応 |
| $X$ の定義式 | 基礎行列、エピポーラ制約|
| $X$ の特異点 | エピポール |

## おわりに
代数ビジョンはまだ文献も少なく、基本的な問題でも分かっていないことが多いです。今後、発展していくことを期待しますが、日本語の文献が見つかれば / 自分で書けば、この記事に追記したいと思います。

一般的な $\Phi$ に対する射影再構成定理について[私たちの論文](https://arxiv.org/abs/1710.06205)でも議論しましたので、代数幾何に馴染みのある方は眺めて頂けると嬉しいです。
誰も教えてくれないググり方

# ググれますか？
スマホの普及により現代人にとって検索を行うことは、水道が使えることと同レベルに普通になりました。
ところが、同じモノを調べるにしても人によって検索にかかる時間や、正しい情報が引き当てられるかという最も大事な部分でさえ違っています。

仕事に関連する内容を調べることは**普通の検索**よりも高度なスキルが必要です。しかし、検索は誰でもできるという認識があるため「**ググり方を教えてください**」と質問をする新人も、ググり方を教えてくれる先輩もいません。

ググり方に絶対の正解はありません[^1]。
また、生まれた時から上手に検索できる人もいれば、慣れで上手くなる人も、てきとーに検索している人も様々です。この記事は実例の一つとして、何も考えずに検索していた人やググり方が分からない人のきっかけになれば幸いです。

[^1]: 拡張子指定の検索や完全一致検索など、正解のある効率的なググり方はいくらでも情報があると思いますのでググってください


# 1. 検索キーワードの策定
## 1.1. 最適な検索キーワード
Go というプログラミング言語があります。過去形で書けば went 、過去分詞形で書けば gone となる動詞と同じ綴りであるため、このままでは**激しくググラビリティが悪い**です。Goの場合は「go-lang」や「golang」といった文字列でググると目的の情報が出て来ます。
このように検索対象ごとに、ある種のデルタ関数的な検索キーワードが存在しますが千差万別であり、それら挙げつらうことは困難であるため経験を蓄積していくしかありません。

## 1.2. **英語でググる**
この記事の中で最も大事な内容がこれです。
公式リファレンスなどの一次ソースは英語であることがほとんどであるため、情報量が違います。最近では中国語で検索すると日本語より情報が多いといったライフハックもあるようですが、私は中国語を知らないので真偽は不明です。

### 1.2.1. 簡単な英語でいいからググる
英語圏の質問サイトは当然のごとく英語で質問がされていますが、書き込みを行なっているのは非英語圏である場合も多いです。そのため、比較的簡単な英単語で検索を行っても意外と情報は出て来ます。
実例として、リストに追加を行うメソッドの名前が「append」だったとして、それを検索する場合は「List　add」や「List　put」といった中1で習うような単語で検索しても出てきます。「Listにaddしたい時ってなんのメソッドを使えばいいのさ？(英語です)」といった質問がされているいるのでそういった検索ワードでも引っかかります。

### 1.2.2. 英語の綴りとかどうでもいいから英語でググる
Androidの開発では「XMLではこのプロパティ足せばいいけど、プログラムで同じことを実現したい場合はどうすればいいんだべ？」と思う場面がたまにがあり、そういう時は「**programmatically**」という副詞を使うと便利です。ところがこの単語は、中学校の教科書に載っているような単語でもなければ16文字もあるため覚えるのもめんどくさいという属性を併せ持っています。
英単語のテストであれば違いますが、ググるという目的のためならこの長い単語の綴りを覚える必要は**全く**ありません。たとえ適当に「programatilcaly」と打ったとしてもIMEやグーグル先生が直してくれます。正しい綴りは全く気にせずググるが吉なのです。


# 2. リンクを開く前に
表示された検索結果が一覧表示されている時点でもたくさんの情報が載っています。
検索結果の件数、サイトURL、投稿日時、タイトル、見出し文、過去に閲覧した日時、etc…
それらは意味もなく並んでいるわけではありません。

# 2.1. 検索結果の件数って見る？
検索結果の件数は情報の多さを示しています。しかし件数が多すぎるというのは、裏を返せば検索対象のキーワードが漠然としすぎているということを示しているかもしれません。

# 2.2. 見出し文だけでスキップすべき記事が見えたりする
検索結果に表示されている見出し文は情報の宝庫です。同じ記事をコピペしているサイトや、複数の質問サイトへのマルチポストや、正解の傾向など、検索結果として並べられると見えないものが見えてきます。
急がば回れではありませんが、見出し文を斜め読みして必要のないサイトの目星をつけることは、開く必要のなかったサイトを閲覧する時間の100分の1の時間でできるのでオススメです。むしろ簡単な内容であれば見出し文だけで解決してしまったりします。

# 2.3. その記事古くないですか？
Qiitaなど古い記事の場合には「◯年前の記事です」といった表示をしてくれる親切なサービスもありますが、個人ブログなどは必ずしもそういった表示がされているわけではないので、いつの記事かというのは大事です。


# 3.戻るボタンって使わないですよね？
一次ソースは不要ですが、質問サイトや個人ブログに書いてある情報を利用する場合は、複数ソースによる検証が必須です。
複数のページを見るときに「リンク開く」->「戻る」を繰り返すことは効率が悪いです。そんなときはCtrl (Macであれば⌘キー)を押しながらリンクをクリックすると新しいタブで開けます(私が普段使う、ちょろめ,火狐,Safari で確認)。
別案として
　・リンクの右クリックメニューの「新しいタブを開く」を選択する
　・マウスのスクロールホイールがボタン式であれば、ホイールクリックを押す
などは片手でできるので、臨機応変に楽しましょう。


# 4. ググるとはGoogleだけとは限らない
いまさらですが、**Googleで検索を行うこと**が本来の"ググる"というスラングの意味です。その言葉に囚われてググるときにGoogle検索だけを使用するのはもったいないです。
## 4.1. Twitterでググる
今年の8月25日に大規模なネット障害が発生したことは記憶に新しいと思います。障害発生から1,2時間後ならいざ知らず、障害発生5分後ではまだググっても情報が出てきません。そういった生の情報はTwitterなどのSNSで検索を行うと便利です。
## 4.2. 書籍でググる
もはやネット上ですらなくなりましたが、書籍は便利です。出所の確かでない書籍はともかく、本として売られている以上は技術検証されたものが印刷されています。ググった場合は複数の情報を検証したりが必要になる場合もありますが、本なら一発です。

# おわりに
私の経験上3ページより後ろのページに最適解が書いてあるケースは無いです。
と、いうことを書こうとしたのですが書く場所がなかったのでここに書きます。
おわり
ワイランナーでmysqlからデータを操作する。〜mysqlオプション編〜

####概要
- 通常、bashなどのCLI上からmysqlからデータを取得したい場合、

```bash:mysql
$ mysql -u ${user} -p 
mysql >
...
```

のような形で起動してmysqlのデータを確認したりしていると思いますが、オプションの-eを使うとbashのCLI上でデータ操作が可能になります。


>--execute=statement, -e statement
ステートメントを実行して、終了します。デフォルトの出力形式は、--batch で生成されるものと同様です。例については、セクション4.2.4「コマンド行でのオプションの使用」を参照してください。このオプションでは、mysql は履歴ファイルを使用しません。 
[4.5.1.1 mysql のオプション](https://dev.mysql.com/doc/refman/5.6/ja/mysql-command-options.html)

####実例
```bash:mysql
$ mysql -u ${user} -p -D ${db_name} -e "select * from ${table_name}";
Enter password: 
+--------------+---------------------+
| id    | created_at                 |
+--------------+---------------------+
| aaaaa | 2016-04-18 18:07:42.000000 |
| bbbbb | 2016-04-18 18:07:42.000000 |
+--------------+---------------------+
```

※カラム名は例です。

#### Tips集
ちなみに取得データをファイルに落としたい場合もあるとおもいます。その場合は、リダイレクトを利用してファイルに落とすことも可能です。
[リダイレクションの「>」「 >>」とパイプ「 | 」の違い。](https://qiita.com/i35_267/items/a19f065691fdc17ae476)

```bash:mysql
$ mysql -u root -p -D memberprovision -e "mysql -u ${user} -p -D ${db_name} -e "select * from ${table_name}" > test.list
Enter password: 

$ head -n 10 test.list 
id	created_at
aaaaa	2016-04-18 18:07:42.000000
bbbbb	2016-04-18 18:07:42.000000
```

また、取得したものの中でヘッダー部分がいらない場合は、オプション「-B」と「-N」をつけます。
そうすると「id」と「created_at」が消えます。

```mysql:bash
$ mysql -u root -p -D memberprovision -B -N -e "mysql -u ${user} -p -D ${db_name} -e "select * from ${table_name}" > test.list
Enter password: 
$ head -n 10 test.list 
aaaaa	2016-04-18 18:07:42.000000
bbbbb	2016-04-18 18:07:42.000000
```

以上です。他にもこんなTipsあるよという方はぜひコメントください！
Pythonのワードクラウド作成用ライブラリwordcloudですべての単語を同じ色にする方法

今回は小ネタです。

* [https://github.com/amueller/word_cloud](https://github.com/amueller/word_cloud)

上のワードクラウド作成用ライブラリをデフォルトの設定で実行すると、デフォルトのカラーマップからランダムに色が選ばれて単語が描かれます。しかし、ワードクラウドを作成する目的によっては、色の情報が余計な場合もあるかもしれません。

そこで、すべての単語を同じ色で描く方法を紹介します。

まず、以下のような関数を定義します。

```py
def color_func(word, font_size, position, orientation, random_state, font_path):
    return 'black'
```

これは、常に同じ色名`'black'`を返す関数です。そして、例えばもともとは

```py
wordcloud = WordCloud(max_font_size=40).generate(text)
```

となっていたところを、

```py
wordcloud = WordCloud(max_font_size=40, color_func=color_func).generate(text)
```

のように変更し、先ほど定義した関数を引数color_funcの値としてセットします。

これでOKです。得られたワードクラウドの例を下に示します。

![033_10.png](https://qiita-image-store.s3.amazonaws.com/0/136528/c6a41d2c-3f1e-16fc-ebc7-ccb15db2944d.png)
LaravelをLaradockを使わずにDocker環境で開発

# 実現したいこと

- 下記ミドルウェアを使いたい
    - PHP 7.1
    - MySQL 5.6
    - Redis 2
    - Mailhog
    - Nodejs 8.4
- PHP-FPMで安定させたい
- Larvel Dusk ヘッドレスで使いたい
- WebpackのHMR機能は是が非でも使いたい
- Linuxじゃない人のことは知りません

# 他の選択肢

- `Laradock` は色々入りすぎてて使いたくない。
- `Homestead` はVagrantで重い。
- `Laravel Valet` Linuxで開発しているので。

# 作ったファイル

まずはこれ。`log` は無くてもいいけど、エラー出しておきたいのでこうした。

```yaml:docker-compose.yml
version: "2"
services:

  web:
    build: .
    ports:
      - "8000:8000"
      - "9222:9222"
    volumes:
      - "./:/var/www/html"
    working_dir: /var/www/html
    command: "php artisan serve --host 0.0.0.0 --port 8000"
    links:
      - db
      - redis
      - mail
    dns: 8.8.8.8

  db:
    image: mysql:5.6
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: homestead
      MYSQL_USER: homestead
      MYSQL_PASSWORD: secret

  redis:
    image: redis:2
    ports:
      - "6379:6379"

  mail:
    image: mailhog/mailhog
    ports:
      - "8025:8025"

  nodejs:
    image: node:8.4
    ports:
      - "8080:8080"
    volumes:
      - "./:/var/www/html"
    working_dir: /var/www/html
    command: "npm run hot"

  log:
    image: alpine
    volumes:
      - "./:/var/www/html"
    working_dir: /var/www/html
    command: "tail -f storage/logs/laravel.log"
```

次にこれ。PHP。
Laravel Dusk使いたいので、こうした。 `libgconf-2-4` がポイント。

```bash:Dockerfile
FROM laradock/php-fpm:1.4-70

RUN apt-get -y update && apt-get -y install chromium libgconf-2-4
```

`artisan` 系のタスクは下記で実行する。

```bash
docker-compose exec web php artisan dusk
```

各種設定は

```bash:.env
DB_HOST=db
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
```

とか。
Ruby（およびRails）で漢字、ひらがな、カタカナをローマ字に変換する

#**はじめに**
Ruby（およびRails）で漢字、ひらがな、カタカナをローマ字に変換するのに便利なgemとその使い方を紹介します。
本稿が少しでもみなさまの参考になれば幸いです。

#**検証環境**
・Ruby 2.4.2
・Rails 5.1.4
・Java 1.8.0_151

#**使用するgem**
１．gem 'rjb'
Javaのライブラリを使うためのgem。
kuromojiで必要。

２．gem 'kuromoji'
Javaで作成されたオープンソースの日本語形態素解析エンジンkuromojiを使うためのgem。
zipangで必要。

３．gem 'romaji'
ローマ字とカナを相互変換するライブラリを使うためのgem。
zipangで必要。

４．gem 'zipang'
日本語をＵＲＬ用ローマ字に変換するgem。
漢字仮名交じりの文字列からでもローマ字化できる。

#**使用方法**
Ruby on railsとJavaが動作する環境になっていることを前提としています。

###**１．gemをインストール**
Gemfileに以下の内容を記述して、bundle install。

```txt:Gemfile
gem 'rjb'
gem 'kuromoji'
gem 'romaji'
gem 'zipang'
```

```txt:linux
$ bundle install
```

###**２．gemの使い方**
Zipangのto_slugメソッドを使って、漢字をローマ字に変換します。

```txt:
Zipang.to_slug "日本語のタイトル"
=> "nihonngo-no-taitoru"
```

数字やローマ字などを全角のまま、Zipangで変換すると、以下のように日本語読みで出力されてしまいます。

```txt:
Zipang.to_slug "０１ＡＢひらカタ漢字"
=> "zero-ichi-ei-bi-hira-kata-kanji"
```

数字は数字、ローマ字はローマ字のまま変換したい場合は、trメソッドによる処理をはさみます。

```txt:
Zipang.to_slug "０１ＡＢひらカタ漢字".tr('０-９ａ-ｚＡ-Ｚ　', '0-9a-zA-Z ')
=> "01-ab-hira-kata-kanji"
```

"-"はいらないという場合は、gsubメソッドで取り除きます。

```txt:
(Zipang.to_slug "０１ＡＢひらカタ漢字".tr('０-９ａ-ｚＡ-Ｚ　', '0-9a-zA-Z ')).gsub(/\-/, '')
=> "01abhirakatakanji"
```

ここまでで、Zipangでもほとんどの文字は適切に処理できますが、一部うまく変換できないものがあります。

```txt:
(Zipang.to_slug "カービィー".tr('０-９ａ-ｚＡ-Ｚ　', '0-9a-zA-Z ')).gsub(/\-/, '')
=> ""
```

そこで、romajiによる変換処理をはさみます。

```txt:
require "romaji/core_ext/string"
(Zipang.to_slug "カービィー".tr('０-９ａ-ｚＡ-Ｚ　', '0-9a-zA-Z ').romaji).gsub(/\-/, '')
=> "kabi"
```

#**まとめ**
数字は数字、ローマ字はローマ字のまま、"-"はいらない場合、以下のようにして、漢字、ひらがな、カタカナをローマ字へと適切に変換することが出来ます。

```txt:
require "romaji/core_ext/string"
(Zipang.to_slug "０１ＡＢひらカタ漢字カービィー".tr('０-９ａ-ｚＡ-Ｚ　', '0-9a-zA-Z ').romaji).gsub(/\-/, '')
=> "01abhirakatakanjikabi"
```

何か不具合などありましたら、コメントなどで教えていただけるとありがたいです。


参考：
[日本語をＵＲＬ用ローマ字に変換するgem Zipangを作った](https://qiita.com/kozo002/items/a9b434925a92900d2b85)
　
　
**最後に**
オリジナル音楽の投稿配信サービス[Micstack](https://www.micstack.com/)を運営しています。
よろしければご利用ください。
Vim初心者のためのコマンド備忘録

## 最初に
時間のある人はVimのチュートリアルができるのでそちらを利用することをおすすめします。
とりあえずVimtutorをやっておけばなんとかなる
> Vimチュートリアルは`vimtutor`コマンドで実行できます

## モード
|コマンド|機能|
|:--|:--|
|`i`|カーソルのある位置で挿入モード|
|`A`|行の末尾で挿入モード|
|`o`|新規行を追加して挿入モード|
|`R`|上書きモード|
|`v`|ビジュアルモード|
|`Ctrl + v`|ビジュアルモード（矩形選択）|
|Esc|ノーマルモード|

## 移動
|コマンド|機能|
|:--|:--|
|`h`|左に1文字移動|
|`j`|上に1行移動|
|`k`|下に1行移動|
|`l`|右に1文字移動|
|`w`|1ワードごとに移動|
|`^`|行頭に移動|
|`$`|行末に移動|
|`G`|ページ末尾移動|
|`gg`|ページ頭に移動|
|`g<行番号>g`|特定の行へ移動|

## 削除
> 削除された文字（文字列）は無名レジスタに上書き保存されます

|コマンド|機能|
|:--|:--|
|`x`|1文字削除|
|`dw`|1ワード削除|
|`dd`|現在行を削除|
|`d<行数>d`|特定の行数を削除|
|`vd`|選択されている部分を削除|
|`vx`|vdと同じ|
|`vc`|選択されている部分を削除して挿入モード|

## ヤンク（コピー）&ペースト
> ヤンクに関しては以下のサイト様に詳しく載っています
> http://cohama.hateblo.jp/entry/20130108/1357664352

|コマンド|機能|
|:--|:--|
|`<ビジュアルモード>y`|ビジュアルモードで選択されている部分をコピー|
|`yw`|1ワードをコピー|
|`y<ワード数>w`|任意のワード数をコピー|
|`yy`|現在行をコピー|
|`y<行数>y`|任意の行数をコピー|
|`p`|無名レジスタの内容をペースト（無名レジスタの状態によってはヤンクしたものがペーストできない）|
|`"0p`|0レジスタの内容をペースト（ヤンクした内容が確実にペーストできる）|

## ウィンドウ
|コマンド|機能|
|:--|:--|
|`:sp`|画面の水平分割|
|`:vs`|画面の垂直分割|
|`Ctrl + wh`|操作ウィンドウを左に切り替え|
|`Ctrl + wj`|操作ウィンドウを下に切り替え|
|`Ctrl + wk`|操作ウィンドウを上に切り替え|
|`Ctrl + wl`|操作ウィンドウを右に切り替え|
|`Ctrl + wc`|現在ウィンドウを閉じる|
|`Ctrl + wo`|現在ウィンドウを以外を閉じる|

## 検索
|コマンド|機能|
|:--|:--|
|`/正規表現`|正規表現による検索を行う|
|`n`|次の検索結果に移動|
|`N`|前の検索結果に移動|

## 置換
|コマンド|機能|
|:--|:--|
|`:%s/置換前/置換後/`|一番初めにヒットした文字を置換|
|`:%s/置換前/置換後/g`|ヒットした文字を置換|
|`:%s/置換前/置換後/`c|確認しながら置換|

## その他
|コマンド|機能|
|:--|:--|
|`u`|最後に実行したコマンドを取り消す|
|`U`|行全体で取り消す|
|`Ctrl + r`|取り消したコマンドの再実行|
|`:e <ファイルパス>`|現在のウィンドウでファイルを開く|
|`:! <実行したいコマンド>`|外部コマンドの実行|
|`:w`|保存|
|`:q`|終了|
|`:wq`|保存して終了|
|`:q!`|変更を保存せずに終了|

## 最後に
間違い等あれば報告お願いします
ngx_mrubyの裏(不人気)機能(2)

今日のngx_mrubyの裏（不人気）機能を紹介したいと思います。

ngx_mrubyにRubyのクラスや新しいメソッドを追加したい場合に、直接コードを書いたものを`mruby_init`に渡したり、mrbgemとして切り出して書いているだろうと思います。

ただ、ngx_mrubyに依存したメソッドをシュッと追加しつつも、nginx起動時ではなくてnginxビルド時にリンクさせておきたい場合もあるでしょう。その時に改めてmrbgemを作るのも面倒な時があると思います。

実はngx_mrubyの裏（不人気）機能として、リポジトリの`ngx_mruby/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb`というファイルがあり、その中にRubyのクラスやメソッドを直接追加することで、nginxビルド時にリンクしてくれます。今だとこんな便利メソッドが書かれていますね。

```ruby
class Nginx
  class Request
    def scheme
      self.var.scheme
    end

    def document_root
      Nginx::Server.new.document_root
    end

    def body
      self.read_body
      self.get_body
    end

    def uri_args
      args_to_hash(self.args)
    end

    def uri_args=(params)
      raise ArgumentError unless params.is_a?(Hash)
      self.args = params.map{|k,v| "#{k}=#{v}"}.join("&")
    end

    def post_args
      args_to_hash(self.body)
    end

    private

    def args_to_hash(args)
      Hash[*args.split("&").map{|arg| arg.split("=")}.flatten]
    end
  end

  class Headers_in
    def user_agent
      self["User-Agent"]
    end
  end

  def self.var
    Var.new
  end
end

module Kernel
  def get_server_class
    Nginx
  end
end
```

実は、ngx_mrubyのrack-base-apiも`ngx_mruby/mrbgems/`以下に定義されていたりします。

ということで、nginxビルド時にmrubyにこういったクラスやメソッドをリンクしておきたい、かつ、mrbgemに切り出すには汎用性にかけるような実装は、ここにシュッと書いてしまうのも良いかもしれません。
日付の範囲検索を汎用的にしたら、SQLインジェクションってbrakemanに警告された話

# 日付の範囲検索
ActiveRecordのscopeを使って、created_atなどのdatetime型を範囲検索したくなりました。
前にqiitaで日付の範囲検索をするっていう記事があって、それを参考にモデルにscopeを書きました。

```ruby:hoge.rb
 class Hoge < ApplicationRecord
   scope :created_at_between, lambda{ |from, to|
     if from.present? && to.present?
       where(created_at: from..to)
     elsif from.present?
       where('created_at >= ?', from)
     elsif to.present?
       where('created_at <= ?', to)
     end
   }
 end
```

これを他のモデルでも使いたいと思って、concernに書き出してみました。

```ruby:between_scope.rb
module BetweenScope
  extend ActiveSupport::Concern

  def between_scope(*columns)
    columns.each do |column|
      scope "#{column}_between", lambda{ |from, to|
        if from.present? && to.present?
          where(column => from..to)
        elsif from.present?
          where("#{table_name}.#{column} >= ?", from)
        elsif to.present?
          where("#{table_name}.#{column} <= ?", to)
        end
      }
    end
  end
end
```

そして使いたいところでこんな風に使えます。

```ruby:hoge.rb
 class Hoge < ApplicationRecord
   extend BetweenScope
   between_scope :created_at
 end
```

```ruby:fuga.rb
 class Fuga < ApplicationRecord
   extend BetweenScope
   between_scope :created_at, :updated_at
 end
```

# brakemanから警告
グッと使いやすくなって意気揚々とpushしたら、brakemanに怒られてしましました。


```
== Warnings ==

Confidence: Medium
Category: SQL Injection
Check: SQL
Message: Possible SQL injection
Code: where("#{table_name}.#{column} <= ?", to)
File: app/models/concerns/between_scope.rb
Line: 14

Confidence: Medium
Category: SQL Injection
Check: SQL
Message: Possible SQL injection
Code: where("#{table_name}.#{column} >= ?", from)
File: app/models/concerns/between_scope.rb
Line: 12

```

様々な対処法を探しましたが見つからず、、、
結局例外を吐くようにして、安全性を保つようにしました。

```ruby:between_scope.rb
module BetweenScope
  extend ActiveSupport::Concern

  def between_scope(*columns)
    columns.each do |column|
      check_column column
      scope "#{column}_between", lambda{ |from, to|
        if from.present? && to.present?
          where(column => from..to)
        elsif from.present?
          where("#{table_name}.#{column} >= ?", from)
        elsif to.present?
          where("#{table_name}.#{column} <= ?", to)
        end
      }
    end
  end

  private

  def check_column(column)
    return if columns.select { |col| col.name.to_sym == column.to_sym && col.type.to_sym == :datetime }.present?
    raise ArgumentError, "Invalid argument: #{column}"
  end
end

```

こうしてもbrakemanの警告は出続けるので

```
bundle exec brakeman -I
```

で警告を無視するような対処をしました。

# 最後に
結果としてSQLインジェクションの危険性はなくなったと思ってますが、もっとスマートなやり方はないのかなと模索しています。
どこまでリスクを考えるべきなのか、線引きが難しいです。

# 参考記事
## 日付の範囲検索
https://qiita.com/ishidamakot/items/4ca054a2204c174003b9
## brakemanの警告無視
https://qiita.com/mah_lab/items/dc09a457e549a9132d90
## SQLインジェクションを考慮しつつ、selectするカラムを動的に変更する
https://qiita.com/jnchito/items/e3a144b07f578cda5ee2
Laravel DuskをDockerコンテナ内で起動するまで

Laravel DuskをDocker内で起動するまで

とりあえずDockerfile書く。

```bash:Dockerfile
FROM laradock/php-fpm:1.4-70

RUN apt-get -y update && apt-get -y install chromium libgconf-2-4
```

諸々インストールしたら、 `--no-sandbox` フラグを追加。 Dockerだと`root`で起動することになるため必要。

```php:tests/DuskTestCase.php
<?php

namespace Tests;

use Laravel\Dusk\TestCase as BaseTestCase;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

abstract class DuskTestCase extends BaseTestCase
{
    use CreatesApplication;

    /**
     * Prepare for Dusk test execution.
     *
     * @beforeClass
     * @return void
     */
    public static function prepare()
    {
        static::startChromeDriver();
    }

    /**
     * Create the RemoteWebDriver instance.
     *
     * @return \Facebook\WebDriver\Remote\RemoteWebDriver
     */
    protected function driver()
    {
        $options = (new ChromeOptions)->addArguments([
            '--disable-gpu',
            '--headless',
            '--no-sandbox', // <-- これ追加
        ]);

        return RemoteWebDriver::create(
            'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
                ChromeOptions::CAPABILITY, $options
            )
        );
    }
}
```

# 経緯

こんなエラーが出た。

```
1) Tests\Browser\ExampleTest::testBasicExample                                         
Facebook\WebDriver\Exception\WebDriverCurlException: Curl error thrown for http POST to /session with params: {"desiredCapabilities":{"browserName":"chrome","platform":"A
NY","chromeOptions":{"binary":"","args":["--disable-gpu","--headless","--no-sandbox"]}}}
                                                                          
Failed to connect to localhost port 9515: Connection refused                  
```

Dockerfileでの`libgconf` が盲点。

`ldd ./vendor/laravel/dusk/bin/chromedriver-linux` で気付いた。
Auto iruca Powered by RODEM Ver.2.0 を作った話

[ヴァル研究所 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/val)の8日目は、昨年のアドベントカレンダーで書いたAuto iruca Powered by RODEM のバージョンアップについて書こうと思います。

##忙しい方向け[今北産業](http://dic.nicovideo.jp/a/%E4%BB%8A%E5%8C%97%E7%94%A3%E6%A5%AD) 
- 「Auto iruca Powered by RODEM」は、カレンダーの予定に連動して在席確認ツール「iruca」のステータスを更新する仕組み
- IFTTTのアップデートによって、昨年の課題(予定開始の通知ズレ、予定終了が検知できない)が解決
- まだ少しirucaの更新タイミングがズレるものの、在席状況の確認としては十分なレベルにはなった

##Auto iruca Powered by RODEMとは
私のチームでは、メンバーの在席状況確認に「[iruca](https://iruca.co/)」というツールを使っています。
これを手動で更新することすら面倒になった私は、RODEM、Googleカレンダー、IFTTTの組み合わせでirucaのステータス更新を自動化する仕組みを作りました。
※詳細は[作成時の投稿](https://qiita.com/valitoh/items/40f5dff14a1c0e95f500)をご参照ください

##前バージョンにおける残課題

- IFTTTのGoogleカレンダー予定開始トリガーは、予定開始時刻〜15分前のどこかで通知を出す仕組みになっていた
→本当は予定開始時刻ぴったりに更新される方が気持ちがいい

- 予定の完了に反応するトリガーが無かった
→社内の打ち合わせ予定終了後は「在席」に更新したい

これが、[今年10月のIFTTTのアップデート](https://ifttt.com/blog/2017/10/google-calendar-got-a-huge-update)で解決できそうということに気づいたので対応してみました。

##予定開始時刻ぴったりにirucaのステータスを更新
IFTTTのアップデートによって、ステータス更新のタイミングを設定できるようになりました。
今回の場合は予定開始と同時にステータスを変更したいので「0 minutes」に設定しています。

<img width="400" alt="スクリーンショット_2017-12-05_19_25_11.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/152460/a9dce10f-9e67-6dab-d10b-b56f4a777a16.jpeg">

##予定の終了時にirucaのステータスを更新
カレンダーの予定終了を検知できるトリガーは下記2種類が用意されています。

<img width="500" alt="スクリーンショット 2017-12-05 19.20.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/152460/2b3e1bed-7365-8aeb-d4ee-db2cefbd507e.png">

- Any event ends：カレンダー内のあらゆる予定の終了時に反応
- New event from search ends：特定のキーワードを含む予定の終了時に反応

「Any event ends」を使うと、移動予定の終了にも反応してしまい、客先に着いたと同時に一旦「在席」になってから「取込中(打ち合わせ)」になってしまいます。

<img width="450" alt="スクリーンショット 2017-12-04 14.18.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/152460/8abca339-4496-0375-6272-8a81954d5228.png">

そこで今回は「New event from search ends」のトリガーを使い、社内の打ち合わせが終了した時にだけ反応するようにキーワードを設定しました。
社内打ち合わせ予定に使われるキーワードは会社によって様々だと思いますが、「社内」や「会議室の名前」などを設定するのが良さそうです(私の場合は後者)。

##Auto iruca Powered by RODEM Ver.2.0
こうしてできあがったものがこちら
<img width="717" alt="スクリーンショット_2017-12-06_13_33_10.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/152460/d5ee9f82-94fd-dd09-d932-df9931058784.jpeg">

連動している！と思いきや、ちょっとズレているところが…

・社内打ち合わせの開始で「取込中」→11:00に更新 :o: 
・社内打ち合わせの終了で「在席」→12:00終了なのに12:05に更新 :x: 
・移動の開始で「外出」→12:12に移動開始しているが、12:15に更新 :x:
・客先打ち合わせの開始で「取込中」→13:00に更新 :o:
・移動の開始で「外出」→14:12に移動開始しているが、14:15に更新 :x:
・自社に戻る時刻で「在席」→14:55に帰社しているが15:00に更新 :x:

どうやら、

- 予定の終了トリガーは、予定の終了時刻〜15分後のどこかで通知を出す仕組み
- 時刻の判定が5分刻み？

というのが影響しているようです。
これを使って工数管理までやろうと思うともっと正確であることが望ましいですが、在席状況の確認としては許容範囲です。

##まとめ
- IFTTTアップデートのおかげで、カレンダーに予定さえ入れていればirucaのステータスが自動的に更新されるようになった
- irucaの更新はちょっと時刻がズレるものの、在席状況の確認としては十分そう
S3ファイルをまとめてダウンロードできる環境をテストイベントの設定を利用して作る

[S3ファイルをまとめてダウンロードできる環境を作る](https://qiita.com/HorieH/items/736c3ae67eaaffa02e3f) の続きになります。

追加仕様
-------
設定情報をLambda内ではなくテストイベントに保存する。
そうすることでコードを修正することなく何パターンも設定を作ることができる。

テストイベントの作成
-----------
1. テストイベントの設定
2. 新しいテストイベントの作成
3. イベント名は適当にわかりやすい名前にする
4. テストコードとPythonコードを修正する

```json:json
{
  "s3": {
    "in": {
      "bucket": "s3inbucket",
      "prefix": "hoge/neko/",
      "extension": ".jpg",
      "max": 1000,
      "marker": ""
    },
    "out": {
      "bucket": "s3outbucket",
      "dir": "out/",
      "filenmae": "archive"
    }
  }
}
```

Pythonコード
---------

```python:lambda_function.py
import boto3
import tarfile
import os

s3_client = boto3.client('s3')


def lambda_handler(event, context):
    response = s3_client.list_objects(Bucket=event['s3']['in']['bucket'], Prefix=event['s3']['in']['prefix'], MaxKeys=event['s3']['in']['max'], Marker=event['s3']['in']['marker'])
    if 'Contents' not in response:
        return

    s3_files = [c['Key'] for c in response['Contents'] if c['Key'].endswith(event['s3']['in']['extension'])]

    if s3_files:
        get_s3_files(event, s3_files)
        create_archive(event)
        return s3_files


def get_s3_files(event, s3_files):
    for s3_file in s3_files:
        basename = os.path.basename(s3_file)
        tmp_file = os.path.join('/tmp/', basename)
        s3_client.download_file(event['s3']['in']['bucket'], s3_file, tmp_file)


def create_archive(event):
    out_file = os.path.join(event['s3']['out']['dir'], event['s3']['out']['filenmae'] + '.tar.gz')
    archive_file = os.path.join('/tmp/', event['s3']['out']['filenmae'] + '.tar.gz')

    archive = tarfile.open(archive_file, mode='w:gz')
    archive.add('/tmp/', arcname=event['s3']['out']['filenmae'])
    archive.close()

    s3_client.upload_file(archive_file, event['s3']['out']['bucket'], out_file)
    print('output ' + event['s3']['out']['bucket'] + ':' + out_file)
```
Kotlinでバイト配列を圧縮・展開する

Javaには圧縮・展開を行うための[Deflater](https://docs.oracle.com/javase/jp/8/docs/api/java/util/zip/Deflater.html),[Inflater](https://docs.oracle.com/javase/jp/8/docs/api/java/util/zip/Inflater.html)というクラスがあります。これを使うと簡単なAPI呼び出しでバイト配列の圧縮と展開が行えます。

今更Javaの記事書いてもおもしろくないのでKotlinでやってみました。

## 圧縮する

```kotlin
// 圧縮元データ
val rawData: ByteArray = getData()

// 圧縮データを格納する配列。余裕を持った大きさで宣言する。元データより大きくはならないはずなので、元データと同じ大きさで宣言している。
val compressedData = ByteArray(rawData.size)

val compressor = Deflater()

// 入力データを設定
// compressor.reset() // 圧縮処理後にインスタンスを再利用する場合はこれを呼ぶ
compressor.setInput(rawData)
compressor.finish() // 入力データがこれ以上ないことを宣言する

// 圧縮を行う。結果はcompressedData[0]～compressedData[compressedDataLength-1]までの範囲に格納される。
val compressedDataLength = compressor.deflate(compressedData)

val result = compressedData.copyOfRange(0, compressedDataLength) // 圧縮結果の部分だけを取り出す
```

## 展開する

```kotlin
// 圧縮データ
val compressedData: ByteArray = getData()

// 展開データを格納する配列。圧縮データの長さからだけでは元のデータの長さを判断できないので、余裕を持った大きさで宣言している。
val originalData = ByteArray(10000)

val inflater = Inflater()

// 入力データを設定
// inflater.reset() // 展開処理後にインスタンスを再利用する場合はこれを呼ぶ
inflater.setInput(compressedData)
inflater.finish() // 入力データがこれ以上ないことを宣言する

// 展開を行う。結果はoriginalData[0]～originalData[originalDataLength-1]までの範囲に格納される。
val originalDataLength = inflater.inflate(originalData)

val result = originalData.copyOfRange(0, originalDataLength) // 展開結果の部分だけを取り出す
```

たとえばSocketやDatagramSocketなどでデータを送る時にこれを利用することで送信前にデータを圧縮して受信後に展開することで、通信帯域を節約することができます。
社内勉強会のすすめ

[ディップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/dip-dev)の11日目です。

今年のGoogle I/OでKotlinが正式にサポートされることになり、是非ともKotlinを自社プロダクトに取り入れて行きたいと思ったので、既存メンバに「Kotlinやろうぜ！」という体で社内で勉強会を開催しているので、そこでの得られた知見を共有していきたいと思います。


## なんでやっているの？
今年の[Dev Fest 2017](https://tokyo.gdgjapan.org/)に参加した時に

- みんなAndroidアプリのKotlin化を進めてきている。
- フルKotlin化は確かに作り直しでもない限りハードルが高いけど、拡張機能からKotlin化を進めることができる。
- Javaは古代語となろうとしている。若い子はSwift読めるけどJava読めない。

という知見を得て、

- コミュニティが活発化しているんだなと感じ、一人で勉強するよりみんなで学びあった方が良いのかも。
- Kotlinやっていかないと、これから先新しいメンバにJoinしてもらう時、その機会が失う理由になりそう。
- でもやっぱりKotlinかわいいよね。

という思いから、自社内でKotlinを布教してみようというアクションに至りました。


## 進めている内容
毎週一回、定時退社後の１時間に集まって実施中。
メンバは私とAndroidエンジニアが数名、iOSエンジニアにも興味を持ってもらって参加してもらっています。

## まずは読書会で
題材は[Kotlinスタートブック](http://www.ric.co.jp/book/contents/book_1039.html)を章ごとに読む形式を取っています。
一般的な勉強会といえば、知見を発表して共有し合う会だと思いますが、まだ誰もKotlinの知識があんまりない中で進める必要があったので、まずはみんなで本読もうぜ、という体で進めています。


## わからないことがあればつぶやく。
最初の数分はみんな黙々と読むのですが、書いてあることがわからない、という瞬間が必ずあるので、そういう時はつぶやくことを推奨しています。
つぶやくとわかる人がいればその場で教えてくれるので躓いても先に進めることができ、そこから議論が生まれることがあるので、この手法はイケてるかなと思っています。


## コード書かなきゃわからないこともある。
当たり前ですけど、サンプルコード眺めていても身につかないこともあるので、そういう時は[TryKotlin](https://try.kotlinlang.org/)でその場で書くことも推奨しています。


## やってよかったなと思うこと。
まだ始めたばかりなのであまりないのですが、個人的によかったと思うこと。

### 思った以上に知見を共有し合っている。
参加者にJavaができる人、Swiftができる人がそれぞれいるので、本を読んでてそれぞれ違う箇所で躓いたり、それぞれのバックボーンでこうだよ、という会話が生まれるので、一人でやるより確実に得られる知見が多いな、と感じた。

### Kotlin、Swift、Javaの言語的な違いに気づけて面白い。
やっぱり、「Javaではこう、Kotlinではこう。」、「Swiftではこう、Kotlinではこう。」という話が生まれるので、実際に同じことをSwiftやJavaでやろうとコード書いてみるとそれぞれの違いを知ることができて、単純に面白い。
まとめられたら、別の機会に投稿しようかと思います。


## おわりに。
簡単ですが、社内勉強会を開催すると、いいことばかりだと思います。
特に開催して悪かったこともないので、自分だけで勉強するのに限界を感じた時は、周りを巻き込んで一緒にやるのも良いと思います。

Kotlinかわいいよ。
フロー起動時にパラメーターを渡す方法 (flow-ctrl)

# はじめに
フローを外部から実行するときにパラメーターを渡すことができます。
今回はflow-ctrlからフローを起動するときの双方のパラメーターの設定について確認してみました。

# 環境
- OS:Windows Server 2012 R2
- ASTERIA WARP:1703
- Java:1.8.0_121

# フロー側の設定
フロー変数を作成し、公開しておきます。
![パラメーター確認1.png](https://qiita-image-store.s3.amazonaws.com/0/180292/f9863b67-1eac-172b-fdee-4fa0217e64a0.png)

# flow-ctrlからの起動
flow-ctrlからフローを実行するときに設定したフロー変数と同名のパラメーターを設定します。
例) execコマンドで実行する場合
`>exec flowvalTest Flow1 -p:param1=abc -p:param2=123`
![flowctrl01.png](https://qiita-image-store.s3.amazonaws.com/0/180292/1a88ef48-4c4e-e05c-4008-7d3eef23c73d.png)


# 結果確認
フローは2つのパラメーターを結合してレスポンスとして戻す簡単な作りで確認しました。
![flowctrl3.png](https://qiita-image-store.s3.amazonaws.com/0/180292/7acb2db7-c494-7267-0c26-c75efbf15190.png)
execコマンドでフロー実行時に渡している[abc]と[123]を結合した結果[abc123]がレスポンスとして返ってきています。

# 終わりに
スケジュール起動のフロー説明には記載がありました。
> フローのパラメーター
> フローのパラメーターとは、起動するフローのフロー変数を公開しておくことにより、呼出し元から設定する値を取得できる仕組みのことです。スケジュール起動のフローでは、任意の名前のフロー変数を定義して公開しておくと、実行設定時に固定値を指定することができます。フローが起動されると、フローサービスが自動的に実行設定時に指定した値をフロー変数に設定します。

([フローサービスマニュアル - はじめに - トリガーごとのフローの作成 - スケジュール起動のフロー](https://help.asteria.com/documentation/warp/ja/current/flow/designer/flowservice/flowtype_schedule.html)より)

[フローサービスマニュアル - はじめに - 詳細なトピック - 変数 - フロー変数](https://asteria.jp/documentation/warp/current/flow/designer/index.html#variable_flow.html)にも記載がありましたが、
> フロー変数を公開する
> フロー変数を公開するとは、フローが別のフローから呼び出される際に呼出し元フローにフロー変数公開することを意味します。サブフロー、エラー処理フロー、NextFlowコンポーネントやTimerコンポーネントで呼出すフローなど、別のフローから呼び出されるときのパラメーターになります。公開しない場合、フロー内部のみで参照・設定可能です。変数ペインで、公開チェックボックスをオンにします。

フロー変数を公開すると外部から実行するときのパラメーターが自動でセットされるようです。
mongodb 気を付けること

シェルでmongodbに入りデータを取得する処理中にコメントアウトを使う場合
「#」等を癖で使わないようにする。
シェル上では使えるがmongodbでは使えない。(当たり前だが自分はやってしまうため）
mongodbに入って「#」使用していたためにコメントアウトにならず記号？として読み込ませたため
表示されない。

例
#!/bin/sh

TARGET=$1; # /^\/user\/test\/日報\/2017\/10\//

cat <<EOF |mongo | `dirname $0`/ekimukanri_formatorder.awk | sort
use crowidb
db.pages.find( { "path": ${TARGET}} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
#　 item.body.match(/\|\d+:\d+\|[^\|]*\|[^\|]+\|[^\|]*\|[^\|].*\|.*\|/gi).forEach(　　←★ここです
        item.body.match(/\|\d+:\d+\|[^\|]*\|[^\|]+\|[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*\|[^\|]*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})

EOF
CentOS7のweeklyローテーションの仕様について

はじめまして。
みなさんに質問があります。

現在CentOS7を利用しています。
syslogのローテーションをweeklyで行っているのですが、
messages等のログファイルのローテーションが毎週日曜日ではなく
日曜日と月曜日が交互にローテーションされます。

11月  5 03:49 cron-20171105.gz
11月 13 03:19 cron-20171113.gz
11月 19 03:27 cron-20171119.gz
11月 27 03:38 cron-20171127.gz
12月  3 03:15 cron-20171203.gz

これが正常な動作（仕様）なのでしょうか？

また、これを毎週日曜日にローテーションさせることは可能なのでしょうか？
mysql コマンドでファイルから複数行のクエリを読み込んで実行する

# 手順

## 適当なファイルを用意する

```sql:sample.sql
SELECT
 1 AS A,
 2 AS B,
 3 AS C
```

## mysql コマンドにファイルの中身を渡す

```
mysql -e "$(cat sample.sql)"
```

# 結果

```
+---+---+---+
| A | B | C |
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
```

# 追記

もっと良い方法があったような‥。良い子は真似しないでください案件だったらゴメン。

# 環境

- bash
- mysql  Ver 14.14 Distrib 5.5.56, for osx10.12 (x86_64) using  EditLine wrapper








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
kippoの収集記録

# kippo
不正なSSHのアクセスを収集するためのハニーポット．

## 国名ランキング
|国名  |回数  |
|---|---|
|ベトナム |16839  |
|中国  |6957  |
|アメリカ|3005|
|ロシア|1607|
|チェコ|1038|
|トルコ|654|
|オランダ|567|
|クロアチア|514|
|ウクライナ|339|
|フランス|242|

## ユーザー名ランキング
|ユーザー名  |回数  |
|---|---|
|root|	22777|
|admin|	7970|
|support|2241|
|user|	1380|
|ubnt|	1211|
|ftp|	1148|
|guest|	1147|
|apache|1144|
|PlcmSpIp|1134|
|0|619|

## パスワードランキング
|ユーザー名  |回数  |
|---|---|
|root|	5581|
|admin|	3564|
|support|2243|
|12345|	1810|
|password|1665|
|ubnt|1243|
|user|1224|
|alpine|1209|
|guest|1148|
|ftp|1141|

## ユーザー名とパスワードの組み合わせランキング
|ユーザー名|パスワード|回数  |
|---|---|---|
|root|root|5567|
|admin|admin|3527|
|support|support|2237|
|admin|password|1571|
|user|user|1221|
|ubnt|ubnt|1211|
|root|alpine|1206|
|guest|guest|1144|
|apache|apache|1140|
|ftp|ftp|1138|

## 使ってみて
* 約2ヵ月ハニーポットを運用した結果
* 使ったサーバーのIPアドレスの一つが一度root権限を乗っ取られたことがあるためか，比較的多く集まった（誰かさんが root/root にしていた）．

* マルウェアの採取には向いていない．
    * echoのリダイレクトが適用されていないため⇒Cowrieならこれを解決している
* 同じIPアドレスからのアクセスが多い．
* SSH接続に成功した人の中で，手慣れている人は，まずハニーポットかどうかを確認してくる．
* SSH接続に成功した人は，中を探索することはなく，踏み台にしようとしてくる．
* alpineってなに？
* 自分がSSH接続する際のポート番号を10022にしていたが，これはばれていた．
   * 10022番以外のポート番号を使うべき
    
この投稿を見てドキッとした人は今すぐ変更しましょう！
あらゆるgitコマンドがエラーを吐く際の解決方法

## 状況

あらゆるgitコマンドが同じエラーを吐くようになってしまった．

```terminal
$ git --version
```

以下がエラーの内容．

```terminal
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

コマンドラインツールが無いとのことなので，xcode-selectをインストールする

```terminal
$ xcode-select --install
```

インストーラが出てくるのでそれに従えばインストールできる．

## 結果

```terminal
$ git --version
git version 2.20.1 (Apple Git-117)
```

どうやらmac OSをSierraにアップデートした所為らしい．
地に足つけた、サイバー攻撃対策 

株式会社LITALICOでインフラエンジニアをやっています。@5kakrです。

『LITALICO Advent Calendar 2017』6日目の記事です。

もう年の瀬、今年も色々なサイバー攻撃や脆弱性が世の中を騒がせました。

どんどん進化するサイバー攻撃に驚かされない様に、「セキュリティ対策ってどういうもの？」ということを
運用者目線で書くことで、イメージしやすく書ければと思います。


# まずは事前対策
## サイバー攻撃の85%を防ぐ要素
セキュリティ対策として以下の事前対策と技術的前提にて全体の85%を防御できるといわれています。

![技術事前対策.PNG](https://qiita-image-store.s3.amazonaws.com/0/120589/c30dc02e-992c-e99b-1635-fdbd7e53d74a.png)
出典：総務省『サイバー攻撃（標的型攻撃）対策防御モデルの解説（簡易版）（別紙2）』

## ネットワーク標準構成機器について
ファイアウォールにて、業務外通信の遮断、外からの侵入を防ぎます。

しかし、外からの攻撃だけを注意していても、外部サイトに悪意が仕込まれていて、従業員がアクセスした際にマルウェアをインストールされたり、最悪PCの操作を奪われてしまうことになりかねません。

そのため、IDS/IPS、URLフィルタリング、アンチウィルスソフトウェアにて危険な通信やデータを遮断させる機能を持たせています。

## セキュリティ運用は地道な積み重ねである。

対策については、常にアップデートを最新にすることが基本となります。

また、被害を最小限に抑えるため、アプリケーションの利用制限、ネットワークセグメント分け、アクセス権限設定を最新に運用していくことが日々の活動で必要になっていきます。

しかし、「セキュリティ対策だ！」となんでもかんでも遮断すると、業務上必要なアクセスもできなくなってしまう場合があります。

そのため、脆弱性に対する全端末のアップデートを状況の管理を行い、どこまで対策されているかのリスクを評価していく、地道な活動が大切です。

# 人・組織対策とセットで初めて意味を持つ

また、脆弱性が見つかってから、対策完了までは、リスクに晒されるケースも多々あります。

その場合を想定し、事前のインシデントレスポンスプランニングを決めておくことが大切です。

![インシデントレスポンスプランニング.PNG](https://qiita-image-store.s3.amazonaws.com/0/120589/3dd274c1-0e90-a112-6140-5888ffa6ecd9.png)
出典：総務省『サイバー攻撃（標的型攻撃）対策防御モデルの解説（簡易版）（別紙2）』

具体的な運用例では以下によって、いざという時に慌てずに済むかと思います。

- どのシステムに対しての攻撃で、どれほど影響が出るか事前に把握しておくこと
- アクセスのログがすぐに追求できること
- 進捗報告のフローが明確で、フロー内の本人も理解していること
- 関連部門への協力してもらうための働きかけ

# 関係するみんなの協力が必要

サイバー攻撃対策は上記の様な、地道な作業となりますが、システム担当だけではすべてを網羅し対策することは不可能となります。

経営層を巻き込んだCSIRTでの活動はもちろんですが、利用者の皆様がセキュリティ日頃意識を持っていけるようになれば幸いです。

- アップデートは常に最新にしないと、という意識
- データの取り扱いにおいては、外部流出する可能性もあるのだ、という意識
- 変だなと思ったら、連絡しなきゃ、という意識


さて明日は@yossan4343434さんが『ディレクターが社内ハッカソンを企画してrailsを書いてみた話』を書かれる予定になります！お楽しみに！
Project Euler Q37 【切り詰め可能素数】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
$3797$は面白い性質を持っている. まずそれ自身が素数であり, 左から右に桁を除いたときに全て素数になっている $(3797, 797, 97, 7).$ 同様に右から左に桁を除いたときも全て素数である $(3797, 379, 37, 3).$

右から切り詰めても左から切り詰めても素数になるような素数は$11$個しかない. 総和を求めよ.

注: $2, 3, 5, 7$を切り詰め可能な素数とは考えない.

## 解答

```bash
seq 11 999999 |
grep -v "^[0|1|4|6|8|9]" |
grep -v "[0|1|2|4-6|8|9]$" |
awk '{for(i=1;i<=length;i++){printf substr($1,i,length+1-i)" "substr($1,1,length-i)" "};print "1"}' |
factor |
awk 'NF==1{print "@"} NF==2{print $2,"1"} 3<=NF{print $1*1,"0"}' |
tr '\n' ' ' |
tr '@' '\n' |
grep -v " 0" |
awk '{s+=$1}END{print s}'
748317
```

## 答え合わせ
こちらのサイト様と一致していればOKとした。
http://kingyojima.net/pje/037.html
大規模イベントをする上でのノウハウ


とある200名オーバーの方が参加するイベントを3回ほど主催した際に気をつけていたことや学んだことを羅列しておきます。

## 開催時期として避けるところ
* 3月：年度末でみんな忙しい
* 4月：年度始まりでバタバタしている
* 6月：株主総会でハコが空いていない＆偉い人の送別会ラッシュ
* 7月上旬：新しく来た偉い人の歓迎会ラッシュ
* 9月：上期〆でみんな忙しい
* 10月〜11月：OSS系の国内外イベントラッシュ
* 12月：師走でみんなそわそわしてる

1月〜2月、5月、7月下旬〜8月が個人的にはおすすめです。

## 会場関係
* 大体の時期が決まったところで数カ月分の空き状況を聞いて抑える
* 電源 & Wi-Fiの提供は必須ではないがあったほうがよい
	* フロアを貸し切るとNW構築をさせてくれるところもある

## 企画
* やっていることはスタッフに限らずなるべく共有する
	* 何をしている
	* 何を考えている
	* 何に困っている
* 他のイベントを参考に「どんなイベントが面白かったか」逆に「どんなイベントは面白くなかったか」を思い出す
	* アンカンファレンスはOpenStack SummitのDesign Summitなどを参考にしました
* メンバが提案してくれたアイデアはひとまず拾って考える
	* 何をオモシロイと思ったか、どうすれば面白いかを話し合う
* 前回のイベントの振り返りを見直して改善を検討する

## 説明回り
* 資料は事実ベース（アンケート結果）をメインで作成して可能な限り使いまわす
	* 必要なときだけ追加資料を作成
* 相手が手伝いやすい建前を用意してあげると話が進みやすい
	* ex. ソフトウェア人材の育成, コミュニティの醸成, etc...

## 運営
* 設営の前に現状復帰できるように会場の写真をとっておく
	* ものを移動する際には養生テープなどをつかってどこにあったかを記載しておく
* 会場レイアウトを事前に作成して共有し、当日はそれを元に設営
* 当日作業のToDoリストを作成し、イベントで使いまわす
* 頑張りすぎないようにスタッフの負荷は分散する
	* スタッフが見たいセッションを見に行けるようにスタッフ間タスクの融通を行う

## アンケートフォーム
* 質問の文面をポジティブに書くとポジティブな意見がもらいやすくなります
	* ex.次はどんな話が聞きたいか、もっとどうすれば面白くなるか
* 日本人らしく「遠慮なく奇譚ないご意見をお聞かせ下さい」的なことを書くと **本当に遠慮のないコメントが来てダメージを受けます** 

## 懇親会
* 懇親会費をタダにすると懇親会だけに現れてご飯だけ食べて変えるタダ飯おじさんが現れることもある・・・
	* 対策としては本編参加を条件に付けるなどが必要（怠って参加登録されてから追記したが間に合わず・・・）
	* 本編参加していないのに申し込んでくる人は他にどんなイベントに参加しているのかを見てみると・・・

## 振り返り
* KPTを使って思いつく限りをHackmdなどで共有して書き連ねる
* 終わったあとにちゃんと前回のKPTが活かせたかは確認する
ReactNative 開発するとき用 ATOM メモ

## パッケージ

### autocomplete-paths

他のファイルのimportとか画像とかの相対パスを入力する際に補完してくれる。
[![autocomplete-paths](https://qiita-image-store.s3.amazonaws.com/0/10609/a591166d-ddc7-cb40-4632-82fc26999041.gif)](https://atom.io/packages/autocomplete-paths)

### language-javascript-jsx

jsxシンタックスハイライト  
https://atom.io/packages/language-javascript-jsx

## Keymap

### `Cmd+¥` でファイルツリーの開閉をする

```
'atom-workspace':
  'cmd-¥': 'nuclide-file-tree:toggle'
  'cmd-0': 'unset!'
  'cmd-ctl-¥': 'nuclide-file-tree:toggle-focus'
```

## ショートカット

### 編集中のファイルをツリーに表示する


> `Cmd-shift-\` （ `Cmd-alt-shift-¥` ）
https://qiita.com/hatta/items/bafdcdaa7899dbffd267
AmazonLinux に Zabbix3.0 をインストールした話


## 構成
Zabbix Server : EC2
Database : RDS(MariaDB)

###### EC2やRDSの構築は飛ばします

## 必要パッケージのインストール
EC2にSSHでログインして、以下。

#### PHP & Apache
```
yum -y install httpd24 mysql php70 php70-devel php70-gd php70-mbstring php70-mcrypt php70-pdo php70-pecl-apcu-devel zlib-devel php70-mysqlnd php70-bcmath
```

#### mariadb
RDSを使うので不要

## PHP の設定
```
vim /etc/php.ini
```

> 

## リポジトリのインストール
```
rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/6/x86_64/zabbix-release-3.0-1.el6.noarch.rpm
```

AmazonLinux は init 制御なので RHEL6 版をインストールします。
systemd に変わったら RHEL7 版に変更。

## Zabbix3.0 のインストール
```
yum install zabbix-server-mysql.x86_64 zabbix-web-mysql.noarch zabbix-web-japanese.noarch zabbix-get zabbix-agent
```

## 設定
```
cp /usr/share/doc/zabbix-web-3.0.9/httpd24-example.conf /etc/httpd/conf.d/zabbix.conf
vim /etc/httpd/conf.d/zabbix.conf
```

以下を変更します。

+ 読み込むモジュールの変更  

	変更前：\<IfModule mod_php5.c>
	変更後：\<IfModule mod_php7.c>

+ タイムゾーンの設定

	変更前：\#php_value date.timezone Europe/Riga
	変更後：php_value date.timezone Asia/Tokyo
額面月収20万、ボーナスなし、株なし、将来の報酬なしでスタートアップで一人目のエンジニアやってた話

昨日、エンジニア採用に必死なスタートアップのCEOと食事をする機会がありました。私がちょうどスタートアップにいたことがあったため色々話してきたので、せっかくだからxスタートアップでエンジニアをやった経験をQiitaにも共有しようかなと思い筆を取っています。

過去の会社を悪く言う意図はあまりありません。過去の会社の情報を暴露する気はありません。

## 額面月収20万、ボーナスなし、株なし、将来の報酬なし

我ながらひどい条件で働いていたと思います。ここまで待遇が劣悪なスタートアップで働いていたエンジニアはそんなにいないんじゃないかな？　夢も希望もあったもんじゃないね。

率直に言えば足元を見られていました。当時の私は、25歳職歴なし、非情報系、エンジニア経験インターン3か月、プログラミング歴半年、でもエンジニアになりたい、と言う、すねに軽い傷のある人間でした。

こんなプロフィールでエンジニアとして雇ってもらうのはなかなか大変です。なんとか見つけたインターン先でも大した成果を出せずに、当時の私は焦りまくっていました。

そんな時に手を差し伸べてくれたのが当時の企業でした。待遇は劣悪とは言え、エンジニアとしての職歴を得られると言うのは私に取っては大きなことで、喜んで参画することにしました。

## 一人目のエンジニアとして

会社として一人目のエンジニアとしての経験は面白く辛いものでした。なんでも自分で好きにできる代わりに、やる必要のあることは重くのしかかってくる。そんな環境が嫌で結局は大きめの企業に移る事になります。

ただ、今から考えれば、向こうも私みたい未経験者を責任者にするほど人材に困窮していた、と言う背景があります。昨日の会食でやっと気づいた事ですが、前職で働くという決断は私に取って妥協であったと同時に、会社側にとっても妥協の産物だったのだろう、と。

昨日お会いした会社さんは、非常に魅力的で、ここに入っても良いと思うエンジニアならいそうなものだけど……みたいに考えながら話を聞いていたのですが、それでも求めている人材はなかなか見つからないそうです。世の中には、エンジニア採用で困っているスタートアップがごまんとあるんだなぁ、などと月並みな感想を持って帰ることとなりました。

## 学生や素人でも良いからエンジニアが欲しいスタートアップが世の中にはいっぱいあるらしい

スタートアップにJoinするメンタルを持ったエンジニアは稀有な存在であるようです。一応、ストレスに耐えられてある程度見る目があれば、スタートアップはおいしいと言うのが私の考えです。しかし、世の中スタートアップにフルコミットする人は多くないようです。

人手不足本当に深刻なんだなと。

私は当分は、転職する気はありませんが……。

## まとめ

あなたが優秀なエンジニアで、魅力的なスタートアップに転職するなら思いっきりふっかけましょう。

あなたが素人でエンジニアになりたいなら、スタートアップ界隈に顔を出してみましょう。
Golang で charset を指定して URL から要素をひっぱってくる

### やりたかったこと

URL からそのページのタイトルタグ情報をひっぱってきたかったです。
最初は安直にやってみたのですが、 `charset` が `euc-jp` とかのサイトで文字化けしちゃったので、そこを補正するようなサンプルになります。

### 基本方針

`github.com/PuerkitoBio/goquery` を使います。


### iconv 系パッケージの選択

じつは、iconv系のパッケージとして、 `github.com/djimenez/iconv-go` をつかって
[ここのTips](https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks) を見ながらやったのですが、なぜか、ランダムでうまく動かない謎の挙動になってしまって。...
最終的には、 `gopkg.in/iconv.v1` を使うことでなんとかできました。


### charset の取得部分は他記事を参照

なお、以下のサンプルは簡単のため、 URL と charset を固定で書いていますが。
[こちらの記事](https://qiita.com/mochizukikotaro/items/ddc0c6b1b98cd33f451e#comment-8fe21a269ff3c071059a) でおしえていただいた下の記事を使うことで、汎用的に記述できるとおもいます。

 [Golang で HTTP コンテンツの charset 判定をするには](https://mattn.kaoriya.net/software/lang/go/20171205164150.htm) 


```go:main.go
package main

import (
	"net/http"
	"fmt"
	"gopkg.in/iconv.v1"
	"github.com/PuerkitoBio/goquery"
)

func main() {
	url := "http://d.hatena.ne.jp/higepon/20150806/1438844046"
	// url = "https://www.wantedly.com/projects/173027"

	charset := "euc-jp"
	// charset = "utf-8"

	cd, err := iconv.Open("utf-8", charset) // convert charset to utf8
	if err != nil {
		fmt.Println("iconv.Open failed!")
		return
	}
	defer cd.Close()

	res, err := http.Get(url)
	if err != nil {
		fmt.Println(err)
	}
	defer res.Body.Close()

	input := res.Body
	bufSize := 0 // default if zero
	r := iconv.NewReader(cd, input, bufSize)

	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
			fmt.Println(err)
	}

	doc.Find("meta").Each(func(_ int, s *goquery.Selection) {
		property, _ := s.Attr("property")
		if property == "og:title" {
			title, _ := s.Attr("content")
			fmt.Println(title)
		}
	})
}
```

```bash
$ go run main.go
 Tech Lead（TL/テックリード）の役割 - サンフランシスコではたらくソフトウェアエンジニア - Higepon’s blog
```
Project Euler Q36 【二種類の基数による回文数】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
$585 = 10010010012$ ($2$進) は$10$進でも$2$進でも回文数である.

$100$万未満で$10$進でも$2$進でも回文数になるような数の総和を求めよ.

(注: 先頭に$0$を含めて回文にすることは許されない.)

## 解答

```bash
seq 999999 |
paste -d" " - <(seq 999999 | rev) |
awk '$1==$2{print $1,int(log($1)/log(2))}' |
awk '{printf $1" ";v=$1;for(i=$2;0<=i;i--){printf int(v/2^i);v-=int(v/2^i)*2^i};print ""}' |
awk '{printf $0" ";s=1;for(i=1;i<=int(length($2)/2);i++){s*=(substr($2,i,1)==substr($2,length($2)+1-i,1))};print s}' |
awk '$3==1{s+=$1}END{print s}'
872187
```

`bc`コマンドも`xxd`コマンドもなかったので、普通に$16$進数変換してやった。
$10$進数の回文チェックは`rev`したものを`paste`で横に並べて比較した。
$2$進数の回文チェックは先頭と末尾から$1$byteずつ比較した。
特定の列だけ`rev`とかできればいいんですけどね。。

## 答え合わせ
こちらのサイト様と一致していればOKとした。
http://kingyojima.net/pje/036.html
iTerm2でcmd+enterのフルスクリーン切り替えショートカットを無効化する

普段ターミナル環境として iTerm2 を使っているのですが、cmd+enter でフルスクリーンがトグルされてしまうのに微妙に使いづらさを感じていました。
そこで、今回はこのショートカットを無効化しました。

やり方は簡単で、`iTerm2 -> Preferences -> Keys` の設定に
`⌘Return↩ : Ignore`
のKey Mappingを追加してやるだけです。

![スクリーンショット 2017-12-05 17.25.06.png](https://qiita-image-store.s3.amazonaws.com/0/16445/0f462d28-7630-b3d5-e1ff-51991cfd347b.png)

Ignoreっていう設定があることにしばらく気づいていませんでした...

以上、小ネタでした。