OmniAICreator/Qiita-1.07M huggingface dataset:
【翻訳記事】中堅エンジニアになるには(チームワーク編)

# はじめに
[Insanely Fastで有名なコミュニティ](https://dev.to)で記事が上がっていたので翻訳・共有します。(許可いただきました。)
元記事: [The road to senior dev](https://dev.to/veloceronte/the-road-to-senior-dev--b6k)
今回は同記事の後半、TeamWorkに関しての部分。
前記事: [【翻訳記事】中堅エンジニアになるには(プロジェクト編)](https://qiita.com/S-Elly/items/d158f10d284fe9644e06)
以下翻訳

# チームワーク

## 質問を恐れないこと
キミの同僚や、テックリードから無知なやつだと思わるのが怖いというのは分かる。
だが、いいチームというのは「納期通りにリリースすること」が大好きで、遅れとその原因が大嫌いなものだ。
だからキミが何かの質問をし損ねて、結果としてプロジェクトが遅れればそれはもう大混乱になる。
それよりは些細なことでも質問して、それを乗り越えて学んでくれた方がよっぽどマシだ。

## リリースを恐れないこと
新人の内は、「終わりました」と言うことほどのトラウマ体験もない。
だが覚えていてほしいのは、キミたちは「リリースする」という単純明快なことに対して給料を貰っているんだ。
「終わりました」を遅らせる言い訳を探すくらいなら、リリースして、出てくる問題に対応して、
失敗と成功から学んで、怖くなくなるまで改善を繰り返していくべきだ。

## 経験豊富なチームメイトにリスペクトを向けること
テックリードの判断に納得できないこともあるだろう。
それはいいが、「テックリードが間違っている」と怒り心頭になる前に、以下を試して欲しい。

- テックリードに対して、その判断の理由を尋ねること。
- その判断に際して描いているビジョンを理解すること。

恐らく、キミが想像もしていなかった制約がビジョンの中にあるだろう。
その判断が間違っているにせよ正しいにせよ、反対されたからといってすぐに癇癪を起こすよりは、
テックリードの意思決定のプロセスを理解することの方がよほど価値がある。

## 盲従と反抗のバランスを取り、そして自分のケツは自分で守ること
こんな逸話がある。

>ビジネスアナリストとしてあるプロジェクトに参画した際、私の担当は、ビジネスロジックに則ってストアドプロシージャを実装することだった。顧客の受け入れテストは中国で実施されて、テックリードがそれに参加することとなっていた。
ユーザの試験環境へのリリースの一週間前に、テックリードは私に「ビジネスロジックが間違っている、このように修正してくれ」と告げてきた。彼の言ったことは全くの的外れで、敬意を込めてそれを伝えたが、跳ね除けられた。
私は「内容をメールで具体的に送信して下さい」とお願いし、後で見つけやすいようメールにフラグを付けた。また、必要な時にいつでも使えるよう、ストアドプロシージャのバックアップを行った。
一週間後、中国での受け入れテストはパスをせず、テックリードから電話がかかってきた。「なぜこんな風に書かれたのか、誰の指示なのか」　私はテックリードの指示であることを説明し、メールを転送した。30秒後、彼は元に戻すのにどの程度かかるかを尋ねた。「手元にバックアップがありますので、すぐにでも」

時には、キミが正しくて、テックリードが間違えることもあるだろう。
こういったケースでは、「具体的な説明をメール、ないしその他の後から見られる手段で明文化してもらう」のが良い。キミの考えている方法を返信しておいても良いかもしれない。
どんな問題が起きるにせよ、キミは守られていて、正しいやり方は別で保存されている。
必要ないことと思うかもしれないが、上司が部下を見捨ててしまうこともあるので、ここはスマートにやることをおすすめしたい。

## メールを返すこと
特に理由がなければ、礼儀作法として「ありがとう」だけで十分だから返信しよう！
「確認しました」だけでもいい。全く返信しないのとは、天地ほどの差がある。

以上翻訳
「リリースするためにお金をもらっている」のは刺さるなぁ……。終わりました、完璧ですということは怖いけど、100点満点で遅れるよりは(というか一度リリースするだけでは絶対に100点にならないから)60点70点でもまずはリリースをする、動かしてみるのが大事なのかもしれない。
【python2.x】（備忘録）日本語の扱い方

未だにpythonでの日本語の扱い方を間違えることがあるので、気を付けるべき場所に気づき次第まとめていきます
（英語以外のすべての文字に言えることですが、とりあえず日本語用、としておきます）
ひとまずは２系向けの内容にしておきます。

##日本語が入ったファイルを読み込むとき
```python:
import codecs
jp_file = codecs.open('nihongo.txt', 'r', 'utf-8')
```
とりあえずこうしておけばファイルから読み込んだ内容をunicodeの文字集合に割り当ててくれる
(ファイルのエンコード方式にかかわらずunicode型になる）


##コードに日本語を書きたい時
```python:
# -*- coding: utf-8 -*-

nihongo = '日本語が書ける'
# 日本語のコメントも書けるようになる
```
\# -*- coding: utf-8 -*-とやってコードのエンコード形式を明示してやらないと、
pythonはコードがASCII（英数字と簡単な記号しかない）でエンコードされていると解釈してしまう

##日本語が含まれるunicode型文字列を出力したい時
```python:
nihongo = 'ああああ'
print nihongo.encode('utf-8')
```
pythonは外部に文字を出力する際、エンコード形式を明示してやらないとASCIIで（略
printだけでなくファイル出力の際も同じ
codeigniterをcloud9で触ってみた①(環境構築編)

4月からエンジニアとして働くことになり、「CodeIgniter」というphpフレームワークを扱うことになりました！
学習のために、公式のチュートリアルをやってみました！理解を深めるという意味で、チュートリアルの解説を記事にしてみたいと思います。今回は、環境構築をメインに書きます。


#Codeigniterとは
Guthubのreadmeにはこう書かれていました。
>CodeIgniter is an Application Development Framework - a toolkit - for people who build web sites using PHP. Its goal is to enable you to develop projects much faster than you could if you were writing code from scratch, by providing a rich set of libraries for commonly needed tasks, as well as a simple interface and logical structure to access these libraries. CodeIgniter lets you creatively focus on your project by minimizing the amount of code needed for a given task.

他のフレームワークよりは、軽量であるのが特徴かと思います。チュートリアルをやるだけだったら、ターミナルを叩く必要もないので、phpを学習した後にフレームワークを学習するには、そんなに抵抗なく学習できるかなと思いました（自分はphpの学習をした後に、Laravelを学習したのですが、ターミナルの操作もおぼつかなかったので、苦労しました）

[公式サイト](http://codeigniter.jp/user_guide/3/index.html)はこちらです。ユーザーグループの方が翻訳をしてくれているので、かなり助かりました。

[Github](https://github.com/bcit-ci/CodeIgniter)はこちらです。スター数が15000を超えているので、突然メンテナンスしなくなるとはあまり考えにくいかと。ただし、最近流行りの[Laravel](https://github.com/laravel/laravel)は40000を超えているので、人気は少し落ち着いている印象です。

#環境構築
今回は学習することに集中したかったので、cloud9を使用します。ローカルの環境も汚れないので、意外と使っています。cloud9とはなんぞや？という方は[こちら](https://www.sejuku.net/blog/385)をご覧ください。

#バージョン
バージョンは下記のようになります。
codeigniter 3.1.8 
→vendor/codeigniter/system/core/CodeIgniter.phpに記載あり
php  5.5.9

#インストール
php開発をする際に、ライブラリの依存関係を管理してくれるツールに「composer」というものがあります。公式で紹介されているインストール方法はZip形式でダウンロードするのですが、有志の方が[composerでもインストールできるようにパッケージ](https://github.com/kenjis/codeigniter-composer-installer)を用意してくれています！今回はこれを利用します。

cloud9を開いて、下記のコマンドを実行します。
最後の「test」はディレクトリ名になります。

```
$ composer create-project kenjis/codeigniter-composer-installer test
```
#homeディレクトリの設定
この設定をしないと下記のような画面が出ます。
なので、下記のコマンドを実行し、設定を下記のように変更します。
```
sudo vim /etc/apache2/sites-available/001-cloud9.conf
（修正前）DocumentRoot/home/ubuntu/workspace
（修正後）DocumentRoot /home/ubuntu/workspace/test/public
```
<img width="1280" alt="スクリーンショット 2018-03-27 11.07.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/175906/f9e96cc9-0ebc-7011-ac1c-18d4ba4cb763.png">

#phpmyadminのインストール
phpmyadminはインストールしなくてもいいのですが、データベース操作をわかりやすくできるので行います。インストールは簡単で下記のコマンドを実行するだけです。
```
phpmyadmin-ctl install
```
その後、DBの設定を変える必要があるので、test/application/config/database.phpの設定を下記のように変更します。
変更したのはusernameとdatabaseのところだけです。

```php:database.php
$db['default'] = array(
        'dsn'	   => '',
	'hostname' => 'localhost',
	'username' => getenv('C9_USER'),//変更
	'password' => '',
	'database' => 'c9',//変更
	'dbdriver' => 'mysqli',
	'dbprefix' => '',
	'pconnect' => FALSE,
	'db_debug' => (ENVIRONMENT !== 'production'),
	'cache_on' => FALSE,
	'cachedir' => '',
	'char_set' => 'utf8',
	'dbcollat' => 'utf8_general_ci',
	'swap_pre' => '',
	'encrypt' => FALSE,
	'compress' => FALSE,
	'stricton' => FALSE,
	'failover' => array(),
	'save_queries' => TRUE
);
```
その後下記のコマンドを実行すれば、dbを触ることができます。
```
$ mysql-ctl start（mysqlの起動）
$ mysql-ctl cli（mysqlの画面）
```
次回、公式のチュートリアルの解説を記事にしたいと思います。

#参考記事
https://rdlabo.jp/codeigniter-302.php
https://qiita.com/HitomiHoshisaki/items/17912a872f8e71316ec2
slackで自分が管理・追加しているapi/appの確認方法

#自分が追加しているappの一覧

https://[userName].slack.com/apps/manage から表示出来るアプリの一覧。無料ユーザーはアプリ10個まで というのはここのカウント。Googleカレンダーアプリの中で、さらに別のカレンダーを追加してもカウントには影響しないという事。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/fa4f8e53-9096-6b40-5984-be37ab41acdb.png)

この画面に遷移する方法を確認。

この辺、古い記事だとレイアウト変わってる事が多い気がするので二通り。

チャットルーム左上のメニューからその他管理項目、app管理。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/c8b9f898-77b7-6079-eec1-d9eb955e0efd.png)

もしくは、同じく左上のメニューからカスタマイズ。その後app管理。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/b45fa287-c615-77ab-0a7d-515d78f76eb5.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/a86d3282-cafc-661e-35a2-60bfdeff208a.png)

# 自分が開発者登録しているappの一覧

https://api.slack.com/apps から表示出来るアプリの一覧。前述の一覧と違って自分のワークスペース外に見えるのが混乱の元？

前述の中にあったデフォルトアイコンのアプリ＝自分が自分用に作るアプリも一旦こっちに登録する。Distribution StatusがNot distributedだからプライベートモードみたいな感じか。こっちの数は無料ユーザーでも10個に限らない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/fdf188fc-f39e-e88f-115a-3fe11292e490.png)

自分で作った自分用のアプリでも、ワークスペースにインストールする時に10個の制限が適用される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/06c3bf09-1a7f-963c-1fc5-b9b39fde12c1.png)

この画面の遷移方法は、前述のアプリ一覧ページ上部のビルドをクリック。https://api.slack.com/ に飛ぶので、ヘッダーのYour Appsをクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/dd26dfa6-f7b8-f003-a508-d7d708c12a76.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/461bf22c-6409-50a5-1138-8e9d03132f2c.png)

これがわかれば自分が登録してるアプリ、apiの理解が出来るかも

自分用のアプリ、apiを使う時も 一旦アプリをストアにプライベートモードで作る。それを自分のワークスペースにインストールする という概念という事？
Autoencoderで訓練済みモデルから中間層encoderの出力方法

後で利用したい/出力したいレイヤーに名前を付ける。

サンプルコード

```python
from keras.utils import plot_model
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model,load_model

#変数定義
x_train = #(省略)
x_test = #(省略)
epoch = 50
batch_size = 100
model = define_model()

#モデル訓練
model.fit(x=x_train,
          y=x_train,
          epochs=epoch,
          batch_size=batch_size,
          shuffle=True
)

#モデル保存
model.save('aaa.h5')

#モデルロード
model = load_model('aaa.h5')

#中間層(encoder)出力
encoder = Model(inputs=model.input, outputs=model.get_layer('encoder_layer').output)

#評価
result = encoder.predict(x_test)

# CNN Autoencoderの定義
def define_model():
    input_img = Input(shape=(3, 256, 256))

    # 3x256x256 -> 8x128x128
    encoded = Conv2D(8, (3, 3), activation='relu', padding='same', data_format='channels_first')(input_img)
    encoded = MaxPooling2D(pool_size=(2, 2), padding='same', data_format='channels_first')(encoded)

    # 8x128x128 -> 8x64x64
    #(省略)

    # 8x64x64 -> 8x32x32
    #(省略)

    # 8x64x64 -> 8x16x16
    encoded = Conv2D(8, (3, 3), activation='relu', padding='same', data_format='channels_first')(encoded)
    # ★この層を後ほど出力したいので、nameを追加★
    encoded = MaxPooling2D(pool_size=(2, 2), padding='same', data_format='channels_first', name='encoder_layer')(encoded)

    # 8x16x16 -> 8x32x32
    #(省略)

    # 8x32x32 -> 8x64x64
    #(省略)

    # 8x64x64 -> 8x128x128
    #(省略)

    # 8x128x128 -> 8x256x256
    decoded = Conv2D(8, (3, 3), activation='relu', padding='same', data_format='channels_first')(decoded)
    decoded = UpSampling2D(size=(2, 2), data_format='channels_first')(decoded)

    # 8x256x256 -> 3x256x256
    decoded = Conv2D(8, (3, 3), activation='sigmoid', padding='same', data_format='channels_first')(decoded)

    # モデルの定義
    model = Model(inputs=input_img, outputs=decoded)
    model.compile(optimizer='adam', loss='binary_crossentropy')

    return model
```
参照：
https://keras.io/ja/getting-started/faq/#keras-model
http://nobunaga.hatenablog.jp/entry/2017/10/18/000827
[test019] 複数のセレクトボックスが競合しないようにする

# 複数のセレクトボックスが競合しないようにする

## 仕様
複数のセレクトボックスがあった場合、その選択肢が他のものと
同じにならないようにする

## ソース

### javascript
```javascript:test019.js
window.addEventListener('DOMContentLoaded', function(e){
  var nodes=document.querySelectorAll('.s');
  Array.prototype.forEach.call(nodes,function(n){
    n.trigger=function(eventStr){
      if (document.createEvent) {
        var e = document.createEvent("HTMLEvents");
        e.initEvent(eventStr, true, true );
        return this.dispatchEvent(e);
      } else {
        var e = document.createEventObject();
        return this.fireEvent("on"+eventStr, e);
      }
    };
    n.addEventListener('change',function(){
      Array.prototype.forEach.call(nodes,function(n){
        Array.prototype.forEach.call(n.querySelectorAll('option:disabled'),function(n){
          n.disabled=false;
        });
      });
      Array.prototype.map.call(nodes,function(n){
        return n.value;
      }).filter(function(v){
        return v!=="";
      }).forEach(function(v){
        Array.prototype.forEach.call(nodes,function(n){
          if(n.value!==v) n.querySelector('option[value='+v+']').disabled=true;
        });
      });
    });
  });
  nodes[0].trigger('change');
});
```
### HTML
```html:test019.htm
<html>
<title>複数のセレクトボックスが競合しないようにする</title>
<script type="text/javascript" src="test019.js"></script>
<body>
<h1>複数のセレクトボックスが競合しないようにする</h1>
<select name="s1" class="s">
<option value="">------</option>
<option value="りんご">りんご</option>
<option value="みかん">みかん</option>
<option value="いちご" selected>いちご</option>
<option value="バナナ">バナナ</option>
<option value="もも">もも</option>
</select>
<select name="s2" class="s">
<option value="">------</option>
<option value="もも">もも</option>
<option value="みかん">みかん</option>
<option value="バナナ">バナナ</option>
<option value="いちご">いちご</option>
<option value="りんご" selected>りんご</option>
</select>
<select name="s3" class="s">
<option value="">------</option>
<option value="いちご">いちご</option>
<option value="みかん" selected>みかん</option>
<option value="りんご">りんご</option>
<option value="もも">もも</option>
<option value="バナナ">バナナ</option>
</select>
</body>
</html>
```

## その他

### サンプル
- [CodePen](https://codepen.io/yambejp/pen/BrYrwj)

<p data-height="265" data-theme-id="0" data-slug-hash="BrYrwj" data-default-tab="js,result" data-user="yambejp" data-embed-version="2" data-pen-title="test019" class="codepen">See the Pen <a href="https://codepen.io/yambejp/pen/BrYrwj/">test019</a> by yambe jp (<a href="https://codepen.io/yambejp">@yambejp</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
The implementation of Linked List with PHP

```php
$ll = array();
for($i=0;$i<count($arr);$i++) {
        list($o, $n) = explode(" ", trim($arr[$i]));
        switch($o) {
                case "insert":
                        array_unshift($ll, $n);
                        break;
                case "delete":
                        for($j=0;$j<count($ll);$j++) {
                                if ($ll[$j]==$n) unset($ll[$j]);
                        }
                        break;
                case "deleteFirst":
                        array_shift($ll);
                        break;
                case "deleteLast":
                        array_pop($ll);
                        break;
        }
}
```
mrubyのJIT2 (仮称)

mrubyのJIT2(仮称)なるものを作ろうとしているのだが、考えがまとまらないので取りとめもなく書く。真に受けて何か損害をこうむっても知らん、その代わり何かいいことがあっても私は何も貰えない。

mrubyのJIT2(仮称)はLLVMベースを考えています。これまでLLVMのトラウマがあったわけですが、LLVMもいろいろ変わっていて(変わり過ぎですけど)、ちょっと試してみたい気もあるってのもあるしラズベリーパイも買ったのでこれでも動かしたいってのもある。
今考えている構造はこんな感じ

- mrubyのバイトコードからさらにSSAベースの中間コード(IR)にする
- IRを生成する際にある程度の型推論を行いその型情報はIRに入れられるようにする(LuaJITのパクリじゃなくてLuaJITにインスパイアされたって奴ですね)
- 前作と違い、Tracingではなくmethod JITにする(LLVMでTracing JITは困難そう)
- 今回は出来る限りmrubyで書く。 前回もmrubyそのもので書きたかったのだが、言語の完成度がそれを許さなかった。今はそれが可能であると思う。こうすることでコンパイラ自身をJITコンパイルしたりコンパイラ機能のカスタマイズをmrubyで行うとか夢が広がる
- LLVMで使いたい機能ってのはコードにバイナリパッチが当てられるというもので、これを使って現状と同じレベルのmrubyとの互換性を狙いたい

# IRについて
IRの生成は、mruby-meta-circrier　mrbgemを使って行う。
レジスタについて単一代入になるようにリネームをおこなうのだが、メソッド呼び出しのパラメータになるレジスタについてはスタックと言う形にした方がいいのか悩む。つまり、ローカル変数のレジスタとパラメータのレジスタは区別すべきではないかと思う
LuaJITはIRに64bit整数を割り当てているが、mrubyではこんなんでは足りなさそう。オブジェクトにした方がいいのか悩む。複雑な型がつく場合何か特にね
IRは分岐の無いBasic Blockのグラフとして表現する。

#LLVMについて
LLVMでパッチを当てて要らなくなった領域を解放することって出来るのかしらん。カスタムアロケータをしてい出来ればいいのだけど、C++レベルでnewをオーバーライドするとかできるのかしらん
GCのライトバリアをLLVMのGCサポート機能を使って高速化出来ればいいのだけど出来るのかしらん
そもそもmrubyにLLVMのバインディングが無いっぽい。ありそうな気がしたんだけどなー。
【Scrapy】トップページから各記事のクローリング


ICS MEDIAのトップページからだと各記事の"更新日"がわからない。
エンジニアにとってその情報がメンテされているかどうかの方が、"投稿日"よりも重要だったりするので、"更新日"を一覧で見えるように取得してみた。

▼流れ
- Itemsでデータ構造をつくる
- トップページにアクセスし、話題の記事のURLをスクレイピング
- 各記事をクローリングして、各ページの情報をスクレイピング

## Items
https://doc.scrapy.org/en/latest/topics/items.html

まずデータ構造の定義を行うため、`items.py` に以下を追加する

```python:items.py
class ArticlesItem(scrapy.Item):
    url = scrapy.Field()
    title = scrapy.Field()
    dateModified = scrapy.Field()
```


## Requests and Responses
https://doc.scrapy.org/en/latest/topics/request-response.html

エントリポイントのページからさらに深くクローリングするため、リクエストを投げる

```python:ics_request.py
# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import ArticlesItem

class IcsRequestSpider(scrapy.Spider):
    name = 'ics_request'
    allowed_domains = ['ics.media']

    start_urls = ['https://ics.media/']

    def parse(self, response):
        for href in response.css('.groupFeatures > div a.thumb::attr(href)'):
            yield scrapy.Request(href.extract(), callback=self.parse_item)

    def parse_item(self, response):
        item = ArticlesItem()
        item['url'] = response.url
        item['title'] = response.css('.pageTitle span::text').extract_first()
        item['dateModified'] = response.css('time[itemprop="dateModified"]::attr(datetime)').get()

        yield item
```


## 実行

```bash
scrapy crawl ics_request -o ics-request.json
```


```json:ics-request.json
[
    {
        "dateModified": "2018-03-23", 
        "title": "現場で使えるwebpack 4入門 – JS開発のモジュールバンドラ", 
        "url": "https://ics.media/entry/12140"
    }, 
    {
        "dateModified": "2018-03-13", 
        "title": "絶対つまずかないGulp入門(2018年版) – インストールとSassを使うまでの手順", 
        "url": "https://ics.media/entry/3290"
    }, 
    {
        "dateModified": "2017-10-23", 
        "title": "人工知能Adobe Senseiの画像処理が凄すぎてAdobe MAX 2017の会場は狂喜乱舞に", 
        "url": "https://ics.media/entry/16643"
    }, 
    {
        "dateModified": "2018-03-13", 
        "title": "CSS Grid Layout入門。対応ブラウザが出揃った新しいレイアウト仕様", 
        "url": "https://ics.media/entry/15649"
    }
]
```



> 参考
[PythonとかScrapyとか使ってクローリングやスクレイピングするノウハウを公開してみる！](http://orangain.hatenablog.com/entry/scrapy)
【Scrapy】ミニマムサンプル


Scrapyとは、クローリングとスクレイピングを行うフレームワーク
プロジェクト単位で複数のSpiderと関連するクラスをまとめて管理する

https://scrapy.org/

ドキュメント
https://docs.scrapy.org/en/latest/


## 準備

### startproject

プロジェクトをつくる

```python
scrapy startproject <project_name> [project_dir]
```

https://doc.scrapy.org/en/latest/topics/commands.html#std:command-startproject


### genspider

`spiders/`に移動し、Spiderをつくる

```python
scrapy genspider [-t template] <name> <domain>
```

https://doc.scrapy.org/en/latest/topics/commands.html#std:command-genspider

> Spiderとは、クロールの実行方法、データの抽出方法など、サイトをスクレイピングする際のカスタム動作を定義したもの。
https://doc.scrapy.org/en/latest/topics/spiders.html



## サンプル

ミニマムなサンプル。
ICS MEDIAの最新の記事を取得するだけ。

```python:ics.py
# -*- coding: utf-8 -*-
import scrapy


class IcsSpider(scrapy.Spider):
    # Spiderを実行する際に呼び出す名前 ex. scrapy crawl ics
    # 必ずユニークであること
    name = 'ics'
    allowed_domains = ['ics.media']

    # クローリングのエントリポイント
    start_urls = ['https://ics.media/']

    def parse(self, response):
        for article in response.css('#app-articles > .row > div'):
            yield {
                "url": article.css('a.thumb::attr(href)').extract_first(),
                "title": article.css('.entryTitle a::text').extract_first()
            }
```

### 保存

`-o`のオプションでJSON形式で保存する。

```bash
scrapy crawl ics -o ics.json
```

https://docs.scrapy.org/en/latest/intro/tutorial.html#storing-the-scraped-data

```json:ics.json
[
    {
        "title": "上下中央揃えのCSSまとめ。Flexboxがたった3行で最も手軽", 
        "url": "https://ics.media/entry/17522"
    }, 
    {
        "title": "サンプルで理解するWebGL 2.0 – Transform Feedbackによるパーティクル表現", 
        "url": "https://ics.media/entry/17505"
    }, 
...
]
```


### セレクタ

`.extract_first()`で最初の要素を抽出している。
https://doc.scrapy.org/en/latest/topics/selectors.html

> 参考
[scrapyでよく使うxpath, cssのセレクタ](https://python.civic-apps.com/scrapy-xpath-css/)
WindowsでのJavaアプリのメモリ計測

## Javaの使用メモリサイズの調査
Windows環境下でJavaアプリが実際に使用しているメモリ量を確認したい時、タスクマネージャーのプロセスタブでは確認できません。**タスクマネージャーには、JVMが全体で確保しているメモリのサイズが表示されます。**
今回は、2つの方法を使用して、Javaが実際に使用しているメモリのサイズの大まかな値を確認する方法を説明します。本方法を使うことで、アプリの改修無しに、処理にあまり影響を与えず、大まかな使用メモリ量を見ることができます。

## 1. Jstatを使用する方法
jstatコマンドを使用した使用メモリの計測は[別の記事](https://qiita.com/N_G/items/2dab8694fdebce2de868)を参照ください。
**Windows環境でもコマンドプロンプトからJstatコマンドを使用することができます。**Windows環境ではJDKのbinフォルダにjstat.exeファイルが存在します。また、jstatコマンドで指定するプロセスIDはタスクマネージャーのPIDと同じ値です。

## 2. jvisualvmを使用する方法
GUI環境の場合、**[Java VisualVM (jvisualvm)](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/visualvm/intro.html)** を使用することで簡易なメモリ使用量の確認が可能です。**jvisualvmはJavaアプリケーションに関するデータをすばやく参照できるような形式で図示するツールです。** 本ツールを使用したメモリ計測方法を説明します。

### jvisualvmのインストール
jstat同様、こちらのツールもOracle JDKに最初から付属しています。JDKのbinフォルダにjvisualvm.exeのファイルが存在します。見つからない場合は、[公式サイト](https://visualvm.github.io/)からダウンロードします。

### jvisualvmでのJVMのメモリの監視
JAVAアプリのヒープメモリの使用量を確認してみます。まずあらかじめjvisualvmを起動しておきます。その後メモリを確認したいアプリケーションを起動してください。アプリを起動すると、左側のjavaアプリの一覧に起動したアプリが表示されますので、それをクリックします。
![visualVM](https://i.imgur.com/OSjEnWk.png)


"監視"のタブをクリックすると、JVMに関する様々なグラフが表示されます。ヒープメモリの確認をする場合は、右上のグラフとなります。わかりやすいグラフ表示で現在の使用済みヒープサイズが確認できます。

![visualVM(グラフ)](https://i.imgur.com/YNJvKlc.png)

### 詳細な使用メモリの確認
一点注意すべきなのは、**上のヒープグラフの"使用済みヒープ"のサイズは、そのタイミングで実際に使われているデータと、もう使われていないがメモリに残っているデータが混在しています。** 実際に使用されているヒープのサイズが見たい場合は、その中から実際に使われているデータの量だけを確認する必要があります。
フルGCの発生後のタイミングに注目することで実際の使用メモリを確認できます。詳細は[Jstatの記事](https://qiita.com/N_G/items/2dab8694fdebce2de868)を参照してください。

### GC情報の追加
アプリにプラグインを追加することで、GCの状態を確認することが可能です。
[ツール]⇒[プラグイン]でウインドウを開いた上で、[使用可能なプラグイン]タグを選択します。
いくつかのプラグインの中から、**"Visual GC"** のプラグインを追加してください。追加が成功すると、新しく"Visual GC"というタブが追加されます。このタブを選択することで、GCの状況をグラフで確認することも可能です。
![visualVM(GC)](https://i.imgur.com/McUSQqP.png)


### jvisualvmを使用する上での注意
jvisualvmはJVMに関する色々なデータをすばやく図形で表示することに特化しています。そのため、**グラフの表示範囲の指定や、数値の出力が出来ず、詳細の調査をするには向いていません。**今動いているアプリのリアルタイムの情報を手軽に確認したい場合はjvisualvmを使用。もう少し詳細に調査したい場合は、jstatを使用した方法を使うなどの使い分けをすると良いと思います。
Node.js:[Error: Cannot find module 'ejs']の対処方法

#はじめに
初歩的なエラーかと思いますが、私が初心者のため備忘録を含め記録として残したいと思います。


#結論:ターミナル上で`nmp init`を実行後`npm install -save ejs`を実行する。


```Swift:ターミナル
Error: Cannot find module 'ejs'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/kojikenn 1/Desktop/mini_board/app.js:3:13)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
```
とありましたので、検索をしましたが下記の記事は私のケースには当てはまりませんでした。
該当する方もいらっしゃると思料されますから、念のためにURLを掲載いたします。

`
https://stackoverflow.com/questions/44585980/com-apple-webkit-webcontent-drops-113-error-could-not-find-specified-service/44623268#44623268
`

#encodeURL.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed）を使用することで解決。


```Swift:solved
let encodeURL = String(format: "https://www.amazon.co.jp/gp/search?ie=UTF8&keywords=hoge")
let itemUrl = encodeURL.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
```

ご参考になれば幸いです。
TypeScript のオブジェクト型リテラルいろいろ

# はじめに

この記事は、TypeScript のオブジェクト型リテラルを主とした型定義メモです。

現在携わっている開発環境では、変数を宣言する際に指定する型の多くが、
クラスやインターフェースによって定義されています。
そのため、即席の型を定義する記述「オブジェクト型リテラル」に触れる、または書くケースが少ないです。
そんなわけでこれらの確認も兼ねて、本記事にまとめました。
TypeScript を使う以上、あまり any は使いたくないものですし。


# 型定義の種類

※ この記事のサンプルは数ある型定義の抜粋です。

```typescript:type-sample.ts
export class typeSampleModel {

  // プリミティブな型
    str: string;                              // 文字列
    num: number;                              // 数値
    boolean: boolean;                         // 真偽値

    // なんでもOKの any型
    data: any;

   // オブジェクト型リテラル
    array: any[];                             // 配列
    strArray: string[];                       // 配列内に文字列
    numArray: number[];                       // 配列内に数値
    multiArray: string[][];                   // 多次元配列
    objectArray: {key: string}[];             // 配列内にオブジェクト

    object: {key: string};                    // オブジェクト
    arrayObject: {key: string[]};             // オブジェクト内に配列
    strKeyObject: { [s: string]: string };    // 任意の文字列キーを許容したオブジェクト
    numKeyObject: { [n: number]: string[] };  // 任意の数値キーを許容したオブジェクト

    constructor () {
        this.str = "A";
        this.num = 1138;
        this.boolean = true;
        this.object = { key: "A"};
        this.array = [ "A" ];
        this.strArray = [ "A", "B" ];
        this.numArray = [ 1, 2 ];
        this.multiArray = [ [ "A", "B" ], [ "C", "D" ] ];
        this.objectArray = [ { key: "A" }, { key: "B" } ];
        this.arrayObject = { key: ["A", "B", "C"] };
        this.strKeyObject = { "a": "A", "b": "B", "c": "C" };
        this.numKeyObject = { 1: ["a", "A"], 2: ["b", "B"] }
    }

    // 関数を示すFunction
    // 関数の戻り値がない場合に使うvoid
    var method: Function = (): void => {
        var a:number = 1;
    }
}
```

## 参考
* [TypeScriptチートシート](http://qiita.com/morrr/items/4b555e0642ad57c987f3)
vue-routerで遷移時にスクロールアニメーションさせる

なんとか実装できたので、メモ。

## 概要

やっていることは、これだけです。

1. vue-routerで遷移をするのを`beforeEach`で取得します
2. 遷移するときにparamsにフラグを持たせます
3. フラグを見てアニメーションスクロールします

## 開発環境

こんな感じです。

```json:package.json
  "dependencies": {
    "smooth-scroll": "^12.1.5",
    "vue": "^2.5.16",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1"
  }
```

## コードの抜粋

関係しているところだけ、まとめました。

```javascript:app.js
// vue-routerを設定している箇所（とくに何もなし）
const router = new VueRouter({
  routes: routes,
})

// スクロールアニメーションのライブラリ
import SmoothScroll from 'smooth-scroll'
const scroll = new SmoothScroll ()
// スクロール位置の要素をアンカーとしてセット
const anchor = document.querySelector ('.anchor')
// ここで遷移を見まもります
router.beforeEach((to, from, next) => {
  // paramsにlinkというフラグをもたせているので判定
  if (to.params.link) {
    scroll.animateScroll (anchor)
  }
})
```

```vuejs:page.vue
<template>
  <div>
    <router-link :to="{ name: 'top', params: { link: true } }">リンク</router-link>
  </div>
</template>
```

## ゆるぼ

やり方が分からなかったので、無理やり感があります。
もっとスマートな方法を募集です。
Linux/UNIX用 file archiver 'ezio' について

# なぜ ezio か？

[ezio](https://github.com/managata/ezio) は、Linux や UNIX を主要な環境として動作するアーカイバです。このドキュメントでは、ezio を使うメリットがどこにあるのか、言い換えると既存の archiver のどこに不足を感じたのか、そのあたりを見ていきたいと思います。

## tar(pax, star)

- 標準的な tar は、巨大な file や Extended Attribute のような、現代的な需要に対応していないことがあります。pax や star などの拡張版は、tar ほど普遍的にインストールされていません。

- tar 系の根本的な問題は、file を全て archive した後に compress/encrypt するところです。このため、archive の末尾に近い場所の file を取り出したくても、最初から全て decompress/decrypt していく必要があります(厳密には、必ずしもそうではないこともある)。

- 同様の理由で、archive の一部が破損したり失われたりすると、そこよりも後の file が取り出せなくなる可能性があります。

- compress/encrypt を外部ツールに頼っていて、gzip/bzip2/xz のような例外は別として、暗号や署名に標準的な作法が定まっていません。このため外部ツール選択の自由がある反面、archive file を他人に渡すだけでは済まず、手順や別 file も渡す必要が出てきます。

- tar は POSIX で規格が定義されていて、さまざまな環境、さまざまなシナリオで使えるという利点があります。また、archive の後に compress することから、afio や ezio のような file 単位の処理よりも良い圧縮率が期待できます。

- オプションが多すぎます。


## afio

- cpio 系の afio は完全に static な header を持ち、拡張が困難です。

- 特に問題となるのは、metadata の暗号化や、Extended Attribute に対応するのが不可能な点です。独自に拡張してしまうと、afio と互換性を失ってしまいます。

- data の暗号化は一応は可能ですが、外部ツールに頼ることから tar 系と同様の問題を抱えます。

- afio の弱点は static な header ですが、逆に decode が容易という利点でもあります。decoder を作成するのは簡単ですし、構造が簡単ゆえにバグも発生しにくいです。

- オプションが多すぎます。


## dar

- [dar](http://dar.linux.free.fr/) は tar の拡張の一つ思われがちですが、file ごとに compress/encrypt するという点では afio と同様です。

- 署名や消失訂正符号を除いて、各種機能への対応は非常に良いです。

- backup tool としての性格が強く、高機能すぎて、archiver として使おうとすると少し難しいです。

- オプションが多すぎます。


## WinRAR

- [WinRAR](https://www.rarlab.com/) は Windows では標準的ですが、UNIX 対応が進んだのが比較的最近であるため、それほど使われていません。

- symbolic/hard link に対応していますし、uid/gid も保存します。一般的なユーザーの一般的な用途としては充分に UNIX 上で使えます。

- 圧縮率や速度は良好な性能で、暗号化も自前で処理します。Quick Open や Recovery Record といった機能もあり、非常に優れた archiver です。

- WinRAR の問題はライセンスです。家に Raspberry Pi が何台かあって、クラウド上に少しばかりの仮想環境が存在するような良くある環境であっても、ホスト数ベースのライセンスはナンセンスです。


## その他 Windows 用 archiver

- Windows の世界では WinRar 以外にも 7-zip を初めとして優れた archiver が存在して、そのうちのいくつかは UNIX でも動作しますが、残念ながら実用的なレベルで対応しているものは、ほとんどありません。


## ezio

- file 単位で圧縮・暗号化を処理するため、特定の file の取り出しが効率的です。

- 同様の理由で、破損した archive の未破損部分を取り出すことも容易です。

- 自前で圧縮・暗号化・署名を処理するため、外部ツールが必要ありません。

- filename や size のような metadata も全て暗号化できます。

- 認証付き暗号を使っていて、archive の改竄に耐性があります。

- 圧縮アルゴリズムの標準が、高速かつ良圧縮の zstd です。

- 消失訂正符号を付加できて、ある程度までの破損を修復できます。

- metadata のみの list を archive 末尾に付加できて、これにより高速に file list を取得できます。

- Linux の Extended Attribute に対応していて、SELinux や capability といった属性も保存できます。

- フォーマットが論理的な意味で XML ライクで、互換性を保ったままの拡張がある程度可能です。

- Go 言語で書かれていて、改造が容易です。

- 必要最低限のオプションしか用意されていないため、簡単に使えます。


- 現時点では、充分にテストされていません。

- エラー等のイレギュラーに対して、少し弱いところがあります。

- compression rate や speed は、重要ではありますが、1st priority ではありません。


- Go 言語で記述されているため、速度的に C/C++ で最適化したコードに及びません。とはいえボトルネックは I/O だったり、圧縮や暗号化だったりするので、どの程度 Go だから不利なのかと言われると、なんとも。なお zstd/lz4/xz などは C ライブラリを利用しています。

- フォーマットが論理的な意味で XML ライクで、encode/decode が少し重く、相対的にバグが入り込みやすいです。


# 参考リンク

- [2016年のOSS圧縮ツール選択カタログ](https://qiita.com/nishemon/items/818cc64dc2f8577edd87)
- [新しいTLSの暗号方式ChaCha20-Poly1305](http://d.hatena.ne.jp/jovi0608/20160404/1459748671)
- [なぜ afio か？](http://archive.linux.or.jp/JF/JFdocs/Backup-mini-HOWTO/afio.html)
- [ezio の暗号関係仕様](https://qiita.com/managata/items/2b98f8af964714ede1ae)
ansibleをオンプレ運用に活用しよう

全サーバに一気にコマンド叩きたいときにめっちゃ便利。

今回はこのシーン。zabbixに独自itemを追加したとき。これ、全サーバにitemを配置して `zabbix-agent` を再起動しないといけない。

業務ではubuntuだけ、とかcent6だけ、とか叩きたいシーンが多いのであらかじめ `/etc/ansible/hosts` にそういうグループを作っておく。これだけでいろんな調査がめっちゃはかどる。

```yml
ubuntu:
  hosts:
    host1:
    host2:
cent6:
  hosts:
    host3:
    host4:
cent7:
  hosts:
    host5:
    host6:
```

テストはこのコマンド

```sh
      ansible all --list-hosts            # 勝手にgroupのhostsが all にまとまってくれる
      ansible ubuntu --list-hosts
```

Childrenにするのがいいのか親にするのがいいのかはよくわかってない。


で、これを叩くと、一発でzabbix itemが動き始める！

# zabbixにitem追加した時に叩くヤツ

全サーバ一気に更新＆zabbix-agent再起動

```sh
ansible all  -a "bash -c 'cd /tools && git pull --ff-only && git push && update-zabbix-item'"
ansible cent6 -a "service zabbix-agent restart"
ansible "ubuntu cent7" -a "systemctl restart zabbix-agent"
```

`update-zabbix-item` は独自コマンドで、 `/tools` にいるitem用conf/shをzabbixが使うdirに`ln -s` して `chmod +x` してくれるやつです。

もちろんリスタートするまでをshにしてしまってもいいんだけど、こうして対象サーバ群を便利に変えられるのがansibleのすごいところなので、しばらくこんな感じで使ってみようと思います。
IEから指定したエクスプローラを開く方法

```html
<html>
<script type="text/javascript">

var path = "C:¥test¥test1";
path.replace(/\u002f/g,'\\​');

$('a').on('click', function (e){
  var openForlder = 'explorer.exe /n,/e,/root,' + path;
  var ActiveXobj = new ActiveXObject("WScript.Shell");
  ActiveXobj.Run(openForlder);
}

</script>
<a id="open_explorer" style="cursor:pointer;">Open</a>
</html> 
```

ただし、 ActiveXObject を使用するには、Internet Explorer で関連するセキュリティ ゾーンのセキュリティ設定を調整することが必要になります。  
たとえば、[ローカル イントラネット] ゾーンでは、通常、[スクリプトを実行しても安全だとマークされていない ActiveX コントロールの初期化とスクリプトの実行] を有効にするようにカスタム設定を変更する必要があります。 

参照：
https://msdn.microsoft.com/ja-jp/library/7sw4ddf8(v=vs.94).aspx
typescriptのimport/export

## 一つだけexport

```:myclass.ts
export default class MyClass{}
```

```:myclass.js
exports.default = class MyClass{}
```

```:main.ts
import MyClass from './myclass'
const mc = new MyClass()
```

## 複数export

```:myclass.ts
export class MyClass1 {}
export class MyClass2 {}
```

```:myclass.js
exports.MyClass1 = class MyClass1{}
exports.MyClass2 = class MyClass2{}
```

```:main.ts
import {MyClass1, MyClass2} from './myclass'
const mc1 = new MyClass1()
const mc2 = new MyClass2()

import * as MyClass from './myclass'
const mc1x = new MyClass.MyClass1()
const mc2x = new MyClass.MyClass2()
```

## node.jsでmodule.exportsをする必要がある場合

```:myclass.ts
export = class MyClass{}
```

```:myclass.js
moudule.exports = class MyClass{}
```

```:main.ts
import MyClass = require('./myclass')
const mc = new MyClass()
```

* npm等でmodule.exportsをした場合に互換性を維持する場合につかう？
JupyterLab-Hubで快適な分析環境を共有しよう!

# はじめに
Jupyterをマルチユーザーで使えるようにするJupyterHub、
画面分割などの拡張が使えるようになるJupyterLab
これらを組み合わせたJupyterLab-Hubを用いて、社内の分析環境を構築した．

# 導入の利点
JupyterNotebookだけでは個人で環境を作る必要があり、複数人での分析環境の共有が難しい面がある．
JupyterLab-Hubを用いることで

- 複数人での環境共有
- リッチなGUIのIDE導入
- 新規メンバーの導入
を簡易化をすることができる．

以降設定方法を箇条書きで書き連ねていく．

# 導入環境
- OS:CentOS7
- Anaconda(4.2.0)
- Python3

# 作業目次

- [Anaconda,JupyterHubのインストール](#anacondajupyterhubのインストール)
- [JupyterHubのConfig](#jupyterhubのconfig)
- [JupyterLab-Hubを導入](#jupyterlab-hubを導入)
- [service化](#service化)

## Anaconda,JupyterHubのインストール

```
$ wget https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh

# インストールフォルダを聞かれるので/opt/anaconda3 など 誰でもアクセスできるところにインストール
$ bash Anaconda3-4.2.0-Linux-x86_64.sh

# secure_pathに/(anacondaのインストール先)/binを追加
$ sudo visudo
```
(参考 Anaconda3のダウンロード：https://www.anaconda.com/download/)

システム全体でanacondaのpythonを使えるようにしたいので以下を記入(ファイルがなければ作る)

``` /etc/profile.d/anaconda.sh
export PATH=/opt/anaconda3/bin:$PATH
```

```
$ conda install -c conda-forge jupyterhub
$ conda install notebook
# この後の実行でImportErrorが出るようなら適宜install

$ npm install -g configurable-http-proxy
$ pip install git+https://github.com/jupyter/sudospawner
```

## JupyterHubのConfig

```
# (Anacondaのinstallディレクトリで)
$ sudo jupyterhub --generate-config
```

続いてエディタで jupyterhub_config.py を開き、以下のように書き換え，追記

``` jupyterhub_config.py
# 各ユーザーのhome直下のnotebookディレクトリを参照するため
c.Spawner.notebook_dir = '~/notebook'

# 使用ユーザーをホワイトリストに追加
c.Authenticator.whitelist = {'user01', 'user02'}

# admin権限を持つユーザーを追加
c.Authenticator.admin_users = {'user00'}
```
※各ユーザーhome直下の~/notebookは利用前にmkdir等で作成しておくこと
(参考 JupyterHubの構築：https://qiita.com/cvusk/items/afa46c35d8d5f0d930ed)


## JupyterLab-Hubを導入
```
$ sudo conda install -c conda-forge jupyterlab
$ jupyter labextension install @jupyterlab/hub-extension
```

defaultでlabを使うために以下を記入

``` jupyterhub_config.py
c.Spawner.default_url = '/lab'
```

## service化
(CentOSの場合、他OSの場合には参考先参照)
/lib/systemd/system/jupyterhub.serviceに以下を記入

``` /lib/systemd/system/jupyterhub.service
[Unit]
Description=Jupyterhub
[Service]
User=jupyterhub
ExecStart=/usr/bin/jupyterhub --JupyterHub.spawner_class=sudospawner.SudoSpawner
WorkingDirectory=/etc/jupyterhub
[Install]
WantedBy=multi-user.target
```

```
# serviceの起動
$ sudo systemctl start jupyterhub
```

(参考 Run jupyterhub as a system service：https://github.com/jupyterhub/jupyterhub/wiki/Run-jupyterhub-as-a-system-service)

## その他参考サイト
https://github.com/jupyterlab/jupyterlab
https://github.com/jupyterhub/jupyterhub
https://github.com/jupyterhub/jupyterlab-hub

## 宣伝
JupyterLabでPlotlyのグラフを表示させる
https://qiita.com/hasoya/items/0e4d260592dcc36285f2
PowerShellを使って適用されいてる更新プログラムの一覧を取得してみた

# はじめに

Windows PowerShellで[Win32_QuickFixEngineering](https://msdn.microsoft.com/ja-jp/library/aa394391(v=vs.85).aspx)クラスを指定して[Get-WMiObject](https://technet.microsoft.com/ja-jp/library/ee176860.aspx)コマンドレットを呼び出すことで更新プログラムの一覧を取得することができるようです。

これをASTERIA WARPのEXEコンポーネントからも呼び出してみました。

# 環境
OS:Windows Server 2012 R2
ASTERIA WARP:1712
Java:1.8.0_151

# PowerShellの記述概要
以下のような記述で確認しました。

```
Get-WmiObject win32_quickfixengineering
```

取得した結果
![winUpdate01.png](https://qiita-image-store.s3.amazonaws.com/0/180292/11edeee5-0af2-7983-fd64-7287fa78a09b.png)


# フロー概要

フローのEXEコンポーネントから実行してみます。

## 1.フロー（Start -> EXE -> EndResponse）
Start -> EXE -> EndResponseだけのシンプルなフローで出力結果を確認してみました。
![winUpdate02.png](https://qiita-image-store.s3.amazonaws.com/0/180292/b714aea5-1a9b-108c-5afd-32f9dc795eb4.png)


実行結果
![winUpdate03.png](https://qiita-image-store.s3.amazonaws.com/0/180292/de6f1346-31c9-b9c6-4ce1-14c9a5a85ef4.png)

## 2.フロー（Start -> EXE -> Converter -> EndResponse）
EXEコンポーネントの出力ストリームはコマンドの標準出力ですが、
固定長っぽく出力されていたのでフローを変更してみました。

  + EXEコンポーネントの出力ストリームをFixedLengthに変更
  + ConverterコンポーネントでCSVストリームに変換

![winUpdate04.png](https://qiita-image-store.s3.amazonaws.com/0/180292/52795bca-3494-9e84-2325-4bb9b33b7439.png)

実行結果
![winUpdate05.png](https://qiita-image-store.s3.amazonaws.com/0/180292/19787db3-a853-7dc3-8f2f-cbfe4e11fb73.png)

## 3.フロー（Start -> EXE -> Mapper(trim) -> EndResponse）
空白埋めをtrimしたかったのでMapper関数をつかってみました。
![winUpdate06.png](https://qiita-image-store.s3.amazonaws.com/0/180292/8518a4be-b44f-9645-f66e-983fc64a8ac9.png)

実行結果
![winUpdate07.png](https://qiita-image-store.s3.amazonaws.com/0/180292/dae71983-98c6-1e7d-9e21-75f3a088f5ec.png)


## 4.フロー(Start -> EXE -> EndResponse)
PowerShellの[Export-Csv](https://technet.microsoft.com/ja-jp/library/ee176825.aspx)コマンドレットにパイプすることでもCSVファイルとして出力できるようなので試してみました。

![winUpdate08.png](https://qiita-image-store.s3.amazonaws.com/0/180292/767f4f99-285c-265d-99f1-a73a9026c5a2.png)


# おわりに
PowerShellのコマンドレットもEXEコンポーネントから特に問題なく実行できるようです。PowerShellでもCSVエクスポートのコマンドレットが用意されていますが、フローで標準出力のデータをそのまま使い回すこともできそうです。

以上です。
Gem "devise"を使用する際のストロングパラメーターの追加について

deviseでは初期状態でサインアップ時にメールアドレスとパスワードのみを受け取るようにストロングパラメーターが設定されている

追加したキーのパラメーターは許可されていません。
追加のパラメーターを許可したい場合は、

application_controllerにおいてbefore_actionconfigure_permitted_parametersメソッドを設定。

```
  class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception
    before_action :configure_permitted_parameters, if: :devise_controller?

    def configure_permitted_parameters
devise_parameter_sanitizer.permit(:追加したいアクション名, keys: [:追加するキー])
    end
  end
```
Linuxのユーザーランドをinitから全てまるごとgolangで書く

gokrazy を試してみました。

# gokrazyとは

https://gokrazy.org/
"gokrazy is a pure-Go userland for your Raspberry Pi 3 appliances"

Linuxのユーザーランドをinitから全てまるごとgolangで書いてあるシステムで、しかもコマンド一発でRaspberry Pi 3用にビルドして、ブートするSDカードを作成してくれます。

[Quick start](https://gokrazy.org/quickstart.html)の手順通りにSDカードを作って動作することを確認しました。
(ただし、host名gokrazyの解決ができなったので、別の方法でラズパイのIPアドレスを特定してIPアドレス直接指定で、そこで動くWebサーバに接続しました。)

# びっくりする小ささ

SDカード上に作られたルートファイルシステムを見てみました。

```
$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdc2        11M   11M     0 100% /media/koba/gokrazy1
```

サイズが11MBしかありません。ファイルシステムはFAT16です。内容にぴったりのサイズでつくるらしく100%の使用率になっています。

```
$ find .
.
./perm
./gokrazy
./gokrazy/dhcp
./gokrazy/ntp
./gokrazy/init
./cacerts
./dev
./etc
./tmp
./user
./user/hello
./localtim
./gokr-pw.txt
./proc
./sys
./hostname
```

全ファイルでたったこれだけしかありません。
実体のあるファイルのサイズを見てみると

```
$ ls -lh `find . -type f`
-r--r--r-- 1 koba koba 228K Oct 11 01:16 ./cacerts
-r--r--r-- 1 koba koba 1.7M Mar 29 07:01 ./gokrazy/dhcp
-r--r--r-- 1 koba koba 5.4M Mar 29 07:01 ./gokrazy/init
-r--r--r-- 1 koba koba 2.0M Mar 29 07:01 ./gokrazy/ntp
-r--r--r-- 1 koba koba   21 Mar 27 08:24 ./gokr-pw.txt
-r--r--r-- 1 koba koba    7 Mar 29 07:01 ./hostname
-r--r--r-- 1 koba koba  292 Feb  2 03:49 ./localtim
-r--r--r-- 1 koba koba 1.2M Mar 29 07:01 ./user/hello
```

golangで書かれたコマンドの実行ファイルが4つあって、それがサイズの大部分を占めています。
実は最初はgolangの実行ファイルがstripされていない状態だったので、もっとサイズは大きかったのですが、自分で修正してstrip済みにしたサイズです。

その修正はプルリクエストしました。
https://github.com/gokrazy/tools/pull/8

# 制約

- libc や busybox のコマンドを含んでいない。sshでログインして対話的に何かをすることはできません。
- カーネルモジュールを含んでいない。必要なカーネルモジュールはスタティックに組み込んでおくことを想定していると思います。

# 必要最小限のシステムを理解するのは勉強になる

これを見ると動かしたいgolangの実行ファイルのサイズに10MBを追加するだけでよいことがわかります。組み込みLinuxの人だけでなくて、サーバーサイドの人でgolangのアプリを動かす最小のコンテナを作りたい人も興味を持つのではないでしょうか。

中でどんなことをしているのか非常に興味があるので、おいおい調べてまた書こうと思います。 
サイズについては、initとdhcpとntp の3つをひとつのバイナリにまとめてしまえば、さらに小さくできると思います。

--> 書きました。 [minimumgo: Linuxでgolangの実行ファイルをひとつだけ動かすときに必要最小限の初期化処理をしてくれるgolangのパッケージ](https://qiita.com/tetsu_koba/items/059849c0871a7e3bd94f)

# Go Conference

このネタで[Go Conference 2018 Spring](https://gocon.connpass.com/event/82515/)で話をしました。
そのときの発表資料。
https://www.slideshare.net/tetsu.koba/linuxinitgolang

# 関連
[golangのruntimeからアクセスする/etcのファイル](https://qiita.com/tetsu_koba/items/d9447eadf9c419264603)
[minimumgo: Linuxでgolangの実行ファイルをひとつだけ動かすときに必要最小限の初期化処理をしてくれるgolangのパッケージ](https://qiita.com/tetsu_koba/items/059849c0871a7e3bd94f)
[Golangの実行ファイルを複数まとめてトータルのファイルサイズを減らす工夫(busybox方式)](https://qiita.com/tetsu_koba/items/53d84286ba5d87de607a)
[組み込みLinuxでGolangのススメ](https://qiita.com/tetsu_koba/items/7435ef8d0c77844d751e#_reference-3d93a29a067c6fa9baed)
Firefoxからローカルフォルダーをブラウザで開く方法(file://～)

通常はセキュリティで禁止されているので、設定変更が必要です。

#firefox設定変更手順

1. firefoxブラウザーを開いて、右上のopen menuボタンをクリックします。
2. open help menuボタンをクリックし、Troubleshooting Informationを選択します。
![スクリーンショット 2018-03-29 17.15.38.png](https://qiita-image-store.s3.amazonaws.com/0/199523/3733bdcf-b93b-e6e6-162a-6bcb9d9d4027.png)

3. 開かれたページの中、Application Basics>Profile Folder>Show in Finderボタンをクリックします。
![スクリーンショット 2018-03-29 17.20.52.png](https://qiita-image-store.s3.amazonaws.com/0/199523/836ae356-ea4f-dd74-a5a0-fb587b9f461a.png)

4. 開かれたフォルダーにuser.jsファイルを作成して下記を追記します。
同じファイル名が既に存在している場合には、user.jsを開いて追記

```javascript

user_pref("capability.policy.policynames","localfilelinks");
user_pref("capability.policy.localfilelinks.sites","http://(ここにURLを記入します)");
//例：http://localhost:3000/
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");
```

#確認
ブラウザーを再起動し、ファイルURI（file://～）が埋め込まれたリンクを開けるかを確認します。
仕事に没頭しすぎてカップラーメンの３分を見逃さない方法〜Slack活用〜

#1.はじめに
ひょんなことからデータサイエンシストへ弟子入りし、プログラミングの世界に導かれやってきました、都会で頑張る田舎者です。文系大学卒の元OLです。

今回は仕事のやりとりで主に使用しているSlackの便利機能を紹介したいと思います！

#2.[Slack](https://slack.com/intl/ja-jp)について
>Slack（スラック）は、スチュワート・バターフィールド（英語版）によって開発されたチームコミュニケーションツール。

参考:[wiki](https://ja.wikipedia.org/wiki/Slack_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))

今ビジネス向けチャットとして大流行中のようです！

#3.カップラーメンと３分と仕事
仕事に没頭しながら
Slackでやりとりしながら
ラーメンにお湯を入れて
ほんで、また仕事して・・・あ、ラーメン忘れてた（笑）

という時が多々あると思います。

そんな時**（以外でも）**Slackのリマインド機能が便利です。

**スラッシュコマンド**を使用しましょう！

#4.スラッシュコマンドとは
>Slack では、スラッシュコマンド が特定の操作のショートカットとして機能します。メッセージの入力ボックスにスラッシュコマンドを入力するだけで、一つの操作で簡単にタスクを実行することができます。

参考：[Slackの使い方　スラッシュコマンド](https://get.slack.help/hc/ja/articles/201259356-%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)

#5.方法
スラッシュコマンド`/remind`を使いましょう！

メッセージ投稿欄に`/remind　+　"宛先"　+　"メッセージ”　+　"希望の日時"`を入力するだけでOK!

例えば・・・
` /remind me ラーメン食べれるよ！ in 3 minutes`
![スクリーンショット 2018-03-29 16.44.10.png](https://qiita-image-store.s3.amazonaws.com/0/241094/2beebf8a-d5a8-2a38-c4cb-6ad159399695.png)

すると、タイムラインに下記が表示されます。
![スクリーンショット 2018-03-29 16.43.43.png](https://qiita-image-store.s3.amazonaws.com/0/241094/4ed89ad9-b948-0cfc-78c3-c683258a3406.png)
ちなみに英語バージョン
![スクリーンショット 2018-03-29 16.47.46.png](https://qiita-image-store.s3.amazonaws.com/0/241094/e08604fc-511d-4c43-0079-614131fc1547.png)
・・・3分後。
![スクリーンショット 2018-03-29 16.50.01.png](https://qiita-image-store.s3.amazonaws.com/0/241094/49129c26-6d39-1cfd-9df8-4215bb219646.png)

お！きたきた！

アプリ上では、
左のバーにある「Direct Masseges（ダイレクトメッセージ）」の「slackbot」のタイムラインに表示されます。
![スクリーンショット 2018-03-29 16.50.59.png](https://qiita-image-store.s3.amazonaws.com/0/241094/bae39edf-dbcd-0915-8ebc-4839b75e2a5c.png)

のびのびの汁吸ったラーメンがええんや！って方はスヌーズへ。
よし食べるぞ！！って方は完了にするへ。

・誰かのカップラーメン管理をする時は、
` /remind @その人のアカウント ラーメン食べれるよ！ in 3 minutes`
・チャンネルのみんなのカップラーメンを管理する時は、
` /remind #チャンネル名 ラーメン食べれるよ！ in 3 minutes`

#6.おまけ
こんなリマインダー方法もあります。
メッセージを普通に送信し、
タイムラインの右側の「・・・」→「後でリマインドする」→「ご希望のタイミング」でもOK!
![スクリーンショット 2018-03-29 17.00.32.png](https://qiita-image-store.s3.amazonaws.com/0/241094/c9a2eb64-6209-2864-a341-4b6ec85305de.png)

#7.参考URL
[便利なSlackリマインダーの使い方を徹底紹介！](https://lab.sonicmoov.com/tool/slack-reminder/)
[Slack の使い方 リマインダーを設定する](https://get.slack.help/hc/ja/articles/208423427-Set-a-reminder)

---
スヌーズの間隔やメッセージをリマインドする際に細かく時間設定できないのでしょうかね。

おなかすきました。
DockerイメージのAlpineでApacheをインストールした際のつまづきどころ

# 前書き

多分 `Apache` + `PHP-FPM` 環境を一つのコンテナに入れるのがかっこよくない気はするのだが、
実際に動いているスクリプトは、
「MVCなんて知るか。PHPは PHP: Hypertext Preprocessor だろ」
と言わんばかりに、ロジックと出力HTMLの入り混じったソースコードなので、
そういうスクリプトが現状動いているサーバーの環境を再現した方が早いなと思った次第で
[効率的に安全な Dockerfile を作るには](https://qiita.com/pottava/items/452bf80e334bc1fee69a)をみながらやり始めました。 

# つまづき1: /run/apache2 ディレクトリを手動で作る力技

tl; dr

`apk add --no-cache apache2` で、全部よろしくやれてると思ったのですが、 `httpd -D FOREGROUND` と実行しても、すぐ終了してしまう。

そこでコンテナ内の `/var/log/apache2/error.log` の中身を眺めたら、こんなログが。

```
[Thu Mar 29 07:25:47.233959 2018] [core:error] [pid 54] (2)No such file or directory: AH00099: could not create /run/apache2/httpd.pid
[Thu Mar 29 07:25:47.233971 2018] [core:error] [pid 54] AH00100: httpd: could not log pid to file /run/apache2/httpd.pid
```

試しに `ls /run/apache2` で確かめると、ディレクトリが存在しない。
ということで、 `mkdir /run/apache2` を実行。

そして無事Apache2は立ち上がりました。

これを `Dockerfile` にもちゃんと追記してビルドしたイメージを実行したところ、ビルドしたイメージでもApache2の動作を確認できました。

# まとめ

* ログ見るのはやっぱり基本

*もしかしたら追記するかもしれません*
RubyのHTTPClientで受信にモタつくと死ぬ

[HTTPClient](https://github.com/nahi/httpclient)を利用したダウンロードでファイルの欠損が出た話。
結果的にRubyもHTTPClientも関係無かったんですけど、最初全く原因がわかりませんでした。

#症状

[HTTPClient](https://github.com/nahi/httpclient)を使用してあるURLからファイルをダウンロードしつつ、進捗状況を確認していました。

```ruby
require 'httpclient'

client = HTTPClient.new
open('temp', 'wb') do |file|
  client.get_content('<url>') do |chunk|
    # 進捗状況を確認するちょい重い処理
    file.write chunk
  end
end
```

処理が完了した時、処理自体は正常に終了したように見えましたが、ダウンロードされたファイルを見てみると1/10もダウンロードできていませんでした。また、「ちょい重い処理」を外して再度実施したところ、ファイルは欠損なくダウンロードできました。

正確に計測したわけではありませんが、「ちょい重い処理」の代わりに`sleep 0.1`を入れてもダメでした。少なくとも0.1秒の遅延はアウトのもよう。

#原因

全く原因が分からず、藁にも縋る思いでWiresharkでキャプチャしていたら、**TCP ZeroWindow**という異常が多発しているのを発見。
**TCP ZeroWindow**自体はエラーではなくサーバーからのデータ送信に対しクライアントの受信処理が捌き切れない場合に発生するもので、サーバーが「受信遅すぎもう知らない！」と`TCP RST`を送ってしまう現象。`chunk`のデフォルトサイズが`16384`バイトなのでその度に「ちょい重い処理」が走ってたらそら詰まるよねっていう状況だった。

#処方箋

原因から分かるようにそもそも「ちょい重い処理」挟むなよっていう話なのですが、ある程度の「ちょい重い処理」ならば許容できるようにする方向で解決を図りたいと思います。

HTTPClientの`get_content`メソッドのソースを追っていくと、socketを使用した低レベルな受信を行っていることが分かります。

```ruby:lib/httpclient/session.rb
def read_body_chunked(&block)
  ... 省略
    @socket.read(@chunk_length, buf)
  ... 省略
end
```

一度の`read`処理で`@chunk_length(=16384)`分のデータをバッファから読み取り、そのたびに「ちょい重い処理」が走る状態です。
対策は単純に、バッファから一度に読み取る量を増やしてあげます。（「ちょい重い処理」が走る機会を減らす）
以下では`read_block_size`を10倍にすることで、一度に処理する`chunk`サイズを増やしています。

```ruby
require 'httpclient'

client = HTTPClient.new
client.read_block_size *= 10 # <- 追加

open('temp', 'wb') do |file|
  client.get_content('<url>') do |chunk|
    # 進捗状況を確認するちょい重い処理
    file.write chunk
  end
end
```

「ちょい重い処理」の代わりに`sleep 0.5`を入れても正常にダウンロードできるような状態にはなりました。

#参考
https://qiita.com/AKB428/items/a0a7c269e0e910dc18d4
https://wiki.wireshark.org/TCP%20ZeroWindow
https://blog.goo.ne.jp/nobuoman/e/e2da59b317a98926cfa0398ebbe547e7
Excel2013で経験した問題2つ

#####※しょぼい問題ですが、地味に面倒だったので忘却録として記載

##【問題1】Excel2013であるファイルを開いて、編集しようとするも右クリックでコンテキストメニューが出なかった。。

##【原因/解決方法】
Excel2013で右クリックが出来ない場合、自動保存されたファイルが悪さをしているらしい。
自動保存されたファイルを削除すると直る可能性がある。(少なくとも私の場合は直った)

##【具体的な対処方法】
###以下に記載されたパスのファイルを削除して下さい。
・Excel左上のファイルボタン→【オプションタブ】→【保存】→自動回復ファイルの場所







##【問題2】Excel2013で閲覧チェックした書類をExcel2010で開いて再度確認した場合に、文書レイアウトがずれてしまっていた。

##【原因/解決方法】
excel2013には文書を自動的に修正したものをプレビューしてくれる機能がある。その為、もともとExcel2010ではレイアウトがずれているものでもexcel2013で開いたら、問題なく見える可能性があるようだ。

##【具体的な対処方法】
Excel2013で作成されていないファイルは、作成したバージョンのExcelで確かめる。
もしくは、最初からExcel2013で作成する。
iOS - Firebase Crashlyticsの手動追加

# はじめに
Firebaseに統合されたCrashlyticsを導入するのに、Carthageを使っているのでマニュアルで追加しました。
その時に少しハマったのでメモします。

## エラー
[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/get-started?authuser=0)通りに進めていた所、`Undefined symbols for architecture arm64`というエラーがでてビルドが通りませんでした。

## 解決手順
[stackoverflow](https://stackoverflow.com/questions/32200183/crashlytics-error-undefined-symbols-for-architecture-arm64?answertab=votes#tab-top)の回答を参考に以下の4つを追加すると無事ビルドできました。
`target -> Build Phases -> Link Binary with Libraries -> add`から

- Security.framework
- SystemConfiguration.framework
- libc++
- libz


でもまだwarningが残ります。
`DEBUG_INFORMATION_FORMAT should be set to dwarf-with-dsym for all configurations.`
`Make sure your project build settings are generating a dSYM file. `
[ここ](https://stackoverflow.com/questions/29209582/make-sure-your-project-build-settings-are-generating-a-dsym-file-debug-informat)や[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/force-a-crash?hl=ja)を参考に[Debug Information Format] 設定を [DWARF with dSYM File] に設定して解決します。

## 実装確認時のポイント
最後にちゃんと実装できたか[Firebaseのドキュメント](https://firebase.google.com/docs/crashlytics/force-a-crash?hl=ja)通りに確認します。
シミュレータで確認していました。ここでのポイントは

1. 最初はXcodeのRunで起動してStopで停止する。
2. 次にXcodeのRunじゃなく、**シミュレータ上で**アプリアイコンをタップして起動、クラッシュさせる。
3. その後にXcodeのRunで起動すると、logでレポート送っているのが確認できました。

## dSYMのアップロード
FirebaseコンソールのCrashlyticsのDSYMが不足してると警告がでていたので、iTunes connectのマイAPP > アクティビティ > すべてのビルド > ビルド番号 からdSYMをダウンロード。
`$ zip -r dSYM.zip appDsyms`
zipしかアップロードできないようなのでzipにしてアップロードしました。
Tensorflow/Keras複数セッション(tf.session)並行処理

ある類似画像検索アプリを開発した時、
・evaluate処理：訓練済みモデル（モデル1）を用いる検索処理
・train処理：新しいモデル(モデル2)のトレーニング処理
同じサーバー、同じtensorflowバックエンドでその二つ処理を一緒に走らせるとエラーが出ました。
```
Cannot interpret feed_dict key as Tensor: Tensor Tensor(shape=(3, 3, 3, 64), dtype=float32) is not an element of this graph
```
下記コードで解決できたのでシェアしておきます。
つまりセッションは別々にすればお互いに共存できます。


train.py

```python

import tensorflow as tf

with tf.Session() as sess:
  #train処理

```

evaluate.py

```python

import tensorflow as tf

with tf.Session() as sess:
  #evaluate処理
```

同じtf.sessionでtrain処理の直後に新しいデータでevaluate処理を実行すると、
上記エラーが出るケースもあります。
train処理の実行が終わった時

```python

from keras import backend as K
K.clear_session()
```
で解決できる。
AWS CLIで階層の違う項目を一緒に出力する方法と注意点

##やりたい事
ec2 describe-instancesの情報からインスタンスIDとステータス（異なる階層の情報）を並べて表示したい。

##やってみた
AWSの公式サイトに以下のサンプルがあったので・・・

```
aws ec2 describe-volumes \
--query 'Volumes[*].{ID:VolumeId,InstanceId:Attachments[0].InstanceId,AZ:AvailabilityZone,Size:Size}'
```

以下のコマンドを作成して実行！

```
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{INSTANCE_ID:InstanceId,INSTANCE_TYPE:InstanceType,STATE:State[0].Name}'
```

・
・
・
が、駄目！
で、色々試してみたところ、以下のコマンドで表示する事に成功！

```
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{INSTANCE_ID:InstanceId,INSTANCE_TYPE:InstanceType,STATE:State.Name}' \
```

##わかった事
describe-volumesとdescribe-instancesの情報を見ていて微妙な違いを発見！
###describe-volumesで表示している項目の内容

```
"Attachments": [
    {
        "AttachTime": "2018-03-29T02:01:46.000Z", 
        "InstanceId": "i-xxxxxxxx", 
        "VolumeId": "vol-yyyyyyyy", 
        "State": "attached", 
        "DeleteOnTermination": true, 
        "Device": "/dev/xvda"
    }
], 
```

###describe-instancesで表示したい項目の内容。

```
"State": {
    "Code": 16, 
    "Name": "running"
}, cribe-instances
```

describe-volumesは大括弧で囲まれていて、describe-instancesは表示したい項目が中括弧で囲まれてる！！
だからいくら同じ書き方しても駄目だったんですねー。
これからもっと注意してデータを確認しようと思います...orz