OmniAICreator/Qiita-1.07M huggingface dataset:
新宿LT#25

新宿LT第25回@渋谷の各LT内容まとめ

# 今やってるモブプロの共有 by [@8140i2865_3](https://twitter.com/8140i2865_3)

（todo: ここにスライド）

## メモ

* 今やっているモブプログラミングのやり方の共有と他の人のやり方を聞きたい。
* 1人45分。一般的なやり方よりはかなり長い。
* やってみた感じかなり良い。今後の増員時の回し方に不透明感はある。
* リモートのメンバーが居る場合の回し方は宿題。
* 設計もモブプロ。テストは書いてない。

# 一年の終わりにNetlifyのアドオンを試す by [@mnuma_](https://twitter.com/mnuma_)

https://qiita.com/mnuma/items/a366045f28fbeaa0b4d3

## メモ

* [Netlify](https://www.netlify.com/)\: 新宿LTでも使っている静的ウェブサイトのホスティング。FaaSサービスなどもある。
* FaaS, 認証機能などが「アドオン」
* AWS程本格的ではないがNetlifyに丸々乗る分には使いやすい？

# Event Sourcing 101 by [@disc99_](https://twitter.com/disc99_)

https://speakerdeck.com/disc99/event-sourcing-101

## メモ

* そもそもイベントソーシングとは→過去の情報を監査ログ等履歴として残す
* ~~霊圧の弱い者には~~はじめての人には耐えられないかも知れない
* CQRS（Command Query Responsibility Segregation）。Model部分をCommand、Queryに分ける
* ビジネスロジックの複雑化をどうにかする手法。負荷分散のために読み込み、書き込みのDBを分離したいような場合に有効。

# MySQLのロードバランサについて調べてみた by [@ftsan](https://twitter.com/futesi_nebusoku)

https://shinjukult.slack.com/files/U2ABL64F5/FENCNA540/mysql_loadbalancer.key

## メモ

* ロードバランシングの各手法のメリット・デメリット
* Aurora使いたいのに高いでござる

# "ねる"はいいぞ by[@to4iki](https://twitter.com/to4iki)

https://speakerdeck.com/to4iki/nel

## メモ

* けやき坂。因幡はねるではない。
* 配列操作の話。空だったり配列の中身が空だったり。型の扱いが面倒。
* NonEmptyList。型レベルで空でないことを保証しておく。巨人の肩の上で安心を得る。

# 結局エンジニアはアウトプットで決まる by [@moguru](http://blog.morugu.com/)

（todo: スライド）

## メモ

* 元ネタは元MSの人の書籍
* この先30代を生きのこるには
* ブログ名がとてもつよい。記事数成長率2400％！
* アウトプット大事

# エンジニアのUI/UX はじめの一歩 by [@HonMarkHunt](https://twitter.com/HonMarkHunt)

https://www.slideshare.net/HonMarkHunt/uiux-125439985

## メモ

* 総合格闘技は各格闘術オール8習得してる人が最強
* エンジニアも各分野オール8にすると強いはず
* デザイナーとレビュアーの意見相違に挟まれると困る
* UIは修正できるがUXは利用後の行動にも影響されるので完全には制御しきれない
JenkinsでローカルサーバーにJavaDocを自動生成する

JenkinsでローカルサーバーにJavaDocを生成するシェルスクリプトを作成したのでメモがてら公開します。
いちいちJavaDoc等の生成コマンドを手動でやるのは面倒なので、自動的に生成するようにしました。

今の時代、JavaDocを生成する機会があるかはわかりませんが……。
※Jenkinsのダウンロードは記載しません。

#環境

・Mac
Jenkinsインストール済み、既にAdminでログイン済みであること。
JavaDocのプラグインをインストール済み。
デフォルトで用意されているApacheを利用しています。

#実行するシェルスクリプト

定期的に実行に設定して、以下のシェルスクリプトを実行
Macの使用を前提としています。

```ruby:
#!/bin/sh -x
#-xを指定することで、あえてエラーを無視している

# Macで用意されているデフォルトのWebServerフォルダに移行
cd /Library/WebServer/Documents/〇〇
# Masterブランチから作成したいので「master」という名前のフォルダ名を作る
mkdir -p master

#パスを変数で所持する
path=~/Documents/〇〇
path2=~/Documents/〇〇

#Javadoc生成　
#-d JavaDocを生成するフォルダ指定
#-subpackages　サブパッケージ名を指定、サブパッケージ以下のフォルダを全て読む、「：」で複数のサブパッケージ指定
#-exclude　除外するサブパッケージ名　「：」で複数のサブパッケージ指定
javadoc -d master -private -charset utf-8 -docencoding utf-8 -windowtitle "〇〇APIドキュメント" -sourcepath ${path2}:${path}  -subpackages 〇〇:〇〇 -exclude 〇〇:〇〇
```

ドキュメントの自動生成出来ると便利ですね。他の言語でもDoc生成の仕組みがあれば、javadocの部分を書き換えで動作するとお思います。
【Python学習メモ】変数について

Pythonの学習メモです。

変数の定義について、以下のような理解しやすい説明があります。
「**変数とは、一言で説明するとデータの入った入れ物です。**」（「みんなのPython」by 柴田 淳）

特定のデータを繰り返しアクセスするためには、変数を定義します。代入という方法で、変数名とデータを対応付けます。つまり、変数名からデータへ参照します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/194463/48299614-8724-3a87-894e-535179a39a92.png" width="400">

例えば下記の例があります。同じ値へ参照する場合は、オブジェクトidは同じですが、別の値を代入すると、参照先が変わるため、当然オブジェクトidも変わります。

```python
>>> a = 1
>>> b = a
>>> print(a,b)
1 1
>>> print(id(a),id(b),id(1))
4512740128 4512740128 4512740128
>>> a = 2
>>> print(a,b)
2 1
>>> print(id(a),id(b),id(2))
4512740160 4512740128 4512740160
```
フローチャートから見ますと、
<img src="https://qiita-image-store.s3.amazonaws.com/0/194463/c437427b-a613-0182-1dbd-283339fbbb5d.png" width="400">
Repositoryパターンにおけるfetchタイミング制御

この記事は[Android Advent Calendar 2018 12/8](https://qiita.com/advent-calendar/2018/android)の記事です。

みなさん、アーキテクチャ、考えてますか？そうですよね、楽しいですよね！（？）
知らぬ間に[Guide to app architecture](https://developer.android.com/jetpack/docs/guide)というページが作られていました。

MVVMの記事は溢れているので、今回はGoogleのサンプルコードを用いて
Repositoryパターンにおけるfetchタイミング制御の方法を紹介します！

# RateLimiterクラス

[googlesamples/android-architecture-components](https://github.com/googlesamples/android-architecture-components)の[GithubBrowserSample](https://github.com/googlesamples/android-architecture-components/tree/master/GithubBrowserSample)では
キャッシュ時間制御のために[`RateLimiter`](https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/util/RateLimiter.kt)というUtilityクラスが定義されています。
実装は非常に簡素なものになっていて、Repositoryは`RateLimiter#shouldFetch`を呼び出し、
fetchをすべきかローカルから値をすべきかを判断し、ふさわしい処理をします。

サンプルのRepositoryでは`NetworkBoundResource`クラスで、ふさわしい処理を
よしなにやっていますが、今回はそこは説明しません。

## shouldFetchメソッド

メソッドだけ切り出すと、

```RateLimiter.kt
fun shouldFetch(key: KEY): Boolean {
    val lastFetched = timestamps[key]
    val now = now()
    if (lastFetched == null) {
        timestamps[key] = now
        return true
    }
    if (now - lastFetched > timeout) {
        timestamps[key] = now
        return true
    }
    return false
}
```
こんな感じです。単純ですね。

あるキーに対して、最後にfetchした時間と今の時間の差異を出します。
それがtimeoutの時間を超えていればtrue、そうでなければfalseを返すわけです。
キー毎にlastFetchedを設定できるので便利ですね。

このタイムアウト時間は生成時に、

```RateLimiter.kt
class RateLimiter<in KEY>(timeout: Int, timeUnit: TimeUnit) {
    private val timestamps = ArrayMap<KEY, Long>()
    private val timeout = timeUnit.toMillis(timeout.toLong())
    
    // メソッド省略
    ...
}
```
と設定できます。わかりやすいですね。
Repositoryはこれをプロパティに持ってあげてタイムアウト時間をセットするのみです。


#  まとめ

Googleのサンプルは参考にできるコードの宝庫ですね！！！
Pascal VOC形式のxmlファイルをPythonで読む

### Pascal VOC形式のxmlファイルをPythonで読む


### はじめに
***
ツールを利用してアノテーションをおこなったはいいが、さぁ物体検知を試そうという段階になって
想定しているフォーマットが微妙に違い加工が必要なケースは結構あるかと思います。

ということで、Pascal VOC形式のxmlファイルを読んで必要な情報を取り出すようにしました。

### xmlファイル
***
以下のようなものです。アノテーション作業はlabelImgを利用しました。
ペットボトル２本と缶の位置を記録しています。

```xml:IMG_1542.xml
<annotation>
	<folder>181208</folder>
	<filename>IMG_1542.JPG</filename>
	<path>/181208/IMG_1542.JPG</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>4032</width>
		<height>3024</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>petbottle</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>733</xmin>
			<ymin>507</ymin>
			<xmax>1383</xmax>
			<ymax>2232</ymax>
		</bndbox>
	</object>
	<object>
		<name>can</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>1608</xmin>
			<ymin>1412</ymin>
			<xmax>2028</xmax>
			<ymax>2292</ymax>
		</bndbox>
	</object>
	<object>
		<name>petbottle</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>2548</xmin>
			<ymin>547</ymin>
			<xmax>3143</xmax>
			<ymax>2467</ymax>
		</bndbox>
	</object>
</annotation>

```

### Pythonで情報の取得
***
以下の処理では、all_listに画像ファイル名と、クラスと位置の情報を格納しています。

```py
# coding:utf-8

import xml.etree.ElementTree as ET

FILE = 'IMG_1542.xml'

file = open(FILE)
tree = ET.parse(file)
root = tree.getroot()

all_list = []

img_file = root.find('filename').text  # 画像ファイル名を取得

for obj in root.iter('object'):
    cls = obj.find('name').text
    xmlbox = obj.find('bndbox')
    b = [int(xmlbox.find('xmin').text), int(xmlbox.find('ymin').text), int(xmlbox.find('xmax').text), int(xmlbox.find('ymax').text)]
    
    all_list.append([img_file] + b + [cls])

```

all_listは以下のようになります。

```
[['IMG_1542.JPG', 733, 507, 1383, 2232, 'petbottle'],
 ['IMG_1542.JPG', 1608, 1412, 2028, 2292, 'can'],
 ['IMG_1542.JPG', 2548, 547, 3143, 2467, 'petbottle']]
```
Pandasのcolumnがいつの間にかfloatになってた件について（NaNに注意）。

#困ったこと
pandasを使っているときに，`int`で入力していたはずなのにいつの間にか`float`に変換されていた。
例. `1`→`1.0`

#原因
この原因を探していたところ該当のcolumnに`nan`が入っていたことが原因だとわかりました。
__`NaN`は`float`として扱う__のです。
だからcolumnに`nan`が含まれているとそのcolumn全体が`float`として扱われるようです。

試しに以下のようなコードを実行すると`float`と出てきます。

```python
import numpy as np
x = np.nan
print(type(x))
```

#感想
これで長いことハマってしまったので，以後気をつけます。
DockerでサクッとUbuntu+任意のPython環境を用意する

## 動機

DockerでUbuntuに任意のPython実行環境を用意したい。出来るだけ簡単な方法で。ただし、condaは使いたくない。

## 実現方法

今回は、[python-build](https://github.com/pyenv/pyenv/tree/master/plugins/python-build)を利用。python-buildは、pyenvにバンドルされている、[任意のPython実行環境](https://github.com/pyenv/pyenv/tree/master/plugins/python-build/share/python-build)を構築するプラグイン。

### 依存関係のインストール

[必要なもの](https://github.com/pyenv/pyenv/wiki/common-build-problems#requirements)をインストール

```sh
$ apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev
```

### python-buildのインストール

以下で`/usr/local/bin`にpython-buildがインストールされる

```sh
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ cd ~/.pyenv/plugins/python-build
$ ./install.sh
```

### Python実行環境のインストール

バージョンとインストール先はお好みで。ここでは、バージョンを`3.7.1`、インストール先を`~/local/python-3.7.1`に指定。  
途中経過が不要なら`-v`オプションはなしで。

```sh
$ /usr/local/bin/python-build -v 3.7.1 ~/local/python-3.7.1
```

### pyenvのアンインストール

Dockerコンテナ内でPythonのバージョンを切り分ける必要はないので、不要になったpyenvはアンインストールしておく。

```sh
$ rm -rf ~/.pyenv
```

### パスを通す

```sh
$ echo 'export PATH="$HOME/local/python-3.7.1/bin:$PATH"' >> ~/.bashrc
```

## Dockerfile

最初のところの環境変数でバージョン・インストール先を書き換えるだけでサクッと環境構築。

```dockerfile:Dockerfile
FROM ubuntu:16.04

ENV PYTHON_VERSION 3.7.1
ENV HOME /root
ENV PYTHON_ROOT $HOME/local/python-$PYTHON_VERSION
ENV PATH $PYTHON_ROOT/bin:$PATH
ENV PYENV_ROOT $HOME/.pyenv
RUN apt-get update && apt-get upgrade -y \
 && apt-get install -y \
    git \
    make \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    wget \
    curl \
    llvm \
    libncurses5-dev \
    libncursesw5-dev \
    xz-utils \
    tk-dev \
    libffi-dev \
    liblzma-dev \
 && git clone https://github.com/pyenv/pyenv.git $PYENV_ROOT \
 && $PYENV_ROOT/plugins/python-build/install.sh \
 && /usr/local/bin/python-build -v $PYTHON_VERSION $PYTHON_ROOT \
 && rm -rf $PYENV_ROOT
```
Rails勉強ネタ redirect_to でのやりとりを実際にパケットキャプチャーして見てみた

![rails.png](https://qiita-image-store.s3.amazonaws.com/0/251648/cef96883-5eac-13fa-0824-bffbd51ed546.png)

redirecto_toってHTTPのリダイレクトと関係あるの？
と思い**wireshark**（ネットワーク・アナライザ）で実際にキャプチャーしてみた。

◇wireshark
![images.jpeg](https://qiita-image-store.s3.amazonaws.com/0/251648/aad2b298-0223-d810-731e-c71b2e20f89d.jpeg)
↓インストール方法
https://ichibariki.hatenablog.com/entry/2017/12/10/124732

#　やったこと
videos controllerがこんな感じになっていて、new_video_pathのテンプレートから
@videoをcreateするとします。
createできたらredirect_to でvideos_path(/videos つまりindex)にリダイレクトされます。

```videos_controller.rb
dew index
  @videos = Video.all
end

def new
  @video = Video.new
end

def create
  @video = Video.new
  if @video.save
    redirect_to videos_path
  eles
    render :new
  end
end
```


## 結果
![スクリーンショット 2018-12-09 16.12.34.png](https://qiita-image-store.s3.amazonaws.com/0/251648/382f497e-ff8e-f5a3-195e-e45e6bdc56e1.png)

↑SourceもDestinationもloopbackアドレス(127.0.0.1)でディスプレイフィルターしてます。
順番に

1. リクエスト　　　（クライアント　→　サーバー）
2. レスポンス　　　（クライアント　←　サーバー）
3. リクエスト　　　（クライアント　→　サーバー）
4. レスポンス　　　（クライアント　←　サーバー）

です。
2番目のパケットを見ると、`302 Found` の**リダイレクトパケット**を受け取っているのが分かります。

[302 Foundについてはwikipedia参照](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89#3xx_Redirection_%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)
リダイレクトを受け取り、クライアントは/videosへGet(videos_path)を送信しています。

【感想】
パケットレベルでHTTPリクエストとレスポンスを覗くとイメージしやすいです。
ReactNativeでAnimated.Valueの挙動をグラフ化してみた

先日アニメーションを初めて実装したのですが、 **アニメーションが動いているときに`Animated.Value` の値がどんな感じで遷移しているのか**、実際の**アニメーションの動きに合わせてグラフ化**することに興味を持ったので、やってみました。

グラフのアニメーションは最後の方にあるので、読み飛ばしてもらって構わないです。

※ 単にグラフ化しただけで、考察とかあるわけではないです。

### この記事の対象

- React Nativeの`Animated`ライブラリを使ってアニメーションを実装している、または実装しようとしているけど、**「よく分かんないな〜」な人**
 
### この記事で分かるようになる事
- Animatedライブラリの超基礎的な仕組み
- `Animated.timing()` と `Animated.spring()`　を使った時の`Animated.Value`の推移

### この記事で触れない事
- Animatedライブラリの使い方やパターンの詳細

詳細は、[公式](https://facebook.github.io/react-native/docs/animated)や以下などご参照ください。

- [React Native Animations Using the Animated API](https://medium.com/react-native-training/react-native-animations-using-the-animated-api-ebe8e0669fae)
- [Timing, Spring & Decay · Rangle.io: React Native Workshop](https://rangle-io.gitbooks.io/react-native-workshop/book/animation/animated/timing-spring-decay.html)

### Animatedの超基礎的な仕組み
そもそもAnimatedを使った事がない方向けに、 `Animated.Value`が何なのかっていうことをさらっと説明しておきます（詳しいことは分からないです）。

アニメーションと言うからには、対象に何かしらの「変化」があります。
対象コンポーネントの透過度だったり、x座標だったり、横幅だったりが変化します。

例えば透過度を変えて、最初は透明度100%だけど徐々に透明度を0にしたい場合には、 `opacity` の値を0から1に変えていけば良いです。

この時の「opacityの値」が`Animated.Value`で、初期値が0の場合には

```javascript
  state = {
    fadeAnim: new Animated.Value(0),  // Initial value for opacity: 0
  }
```

のように定義し、
そのopacity値を「10秒かけて1にする」時には

```javascript

  //componentDidMountと同時にアニメーションをスタートさせる場合
  componentDidMount() {
    Animated.timing(                  // 時間軸に沿って変化させる
      this.state.fadeAnim,            // アニメーションさせる値(value)
      {
        toValue: 1,                   // Valueを1まで増やす
        duration: 10000,              // 10秒かけて
      }
    ).start();                        // スタートする
  }

```
のようにします。
あとはこの値を、 `Animated.Image` などのアニメーション用コンポーネントのstyle `opacity` に指定してあげればokです。

```javascript
        <Animated.Image
          style={{
            opacity: this.state.fadeAnim, //opacityが上のルールに沿って0から1に増えていく（つまり10秒かけて見えるようになる）
          }}
          source={{ uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png' }}
        />
```

### Valueの値をグラフ化しみてた

ようやく本題。

アニメーションでよく使うらしい、 `Animated.timing`と`Animated.spring`のvalueの推移をグラフにすると以下のようになりました。

![demo.gif](https://qiita-image-store.s3.amazonaws.com/0/214755/52db9c65-f4b0-be26-4606-f98ad26dbbc7.gif)

上が`timing`で、下が`spring`です。

```
timing

- 初期値: 0
- オプション: 
 - toValue: 1
 - duration: 5500
```

```
spring

- 初期値: 0
- オプション: 
 - toValue: 1
 - friction: 0.3
```

**へ〜**ってなるだけですよね。

まぁこのグラフの軌跡は当たり前の結果なので、**だから何**と聞かれても**「興味本位にやってみただけなので。。。」**としか言えません。特に**考察があるわけではありません**。


ちなみにグラフ化は[react-native-svg-charts](https://github.com/JesperLekland/react-native-svg-charts)を使い、グラフのコンポーネントを
 `Animated.createAnimatedComponent()`を使ってアニメーションコンポーネントに変換しています。

ソースコードは一応[GitHubにあげています](https://github.com/nichiyoshi/react-native-animated-to-chart)。

###参考資料(その他のデモ)

アニメーションのvalueの「変化の仕方」を制御するには、`timing`の場合には`easing`を、`spring`では `friction`や`tension`を操作しますが、これらをいじった時のデモは、以下などが参考になると思います。

#### timing(easing)

- [Easing Function 早見表](https://easings.net/ja)

####spring

- [Rebound Spring Animations for Android](http://facebook.github.io/rebound/)
PyCharmのインストール

#PyCharmのダウンロード
下記のリンクからダウンロードする。

[JetBrains](https://www.jetbrains.com/pycharm/download/#section=linux)

有料の"Professional"と無料の"Community"が選択できる。
Professionalは、30日間のトライアルが可能である。
試した後に、正式に決定するのが良いと考える。

#参考サイト
[UbuntuでPyCharmインストールからHello Worldまでやってみた](https://qiita.com/m0p1nt/items/3c4cb0796f09fce0b591)
Kafka2.1.0のSASL_PLAIN認証について

# あったこと
卒論でkafkaを使うので、現状で最新のkafka(https://www.apache.org/dyn/closer.cgi?path=/kafka/2.1.0/kafka_2.12-2.1.0.tgz)  を使おうとした。 
が、これだとSASL_PLAINでの認証が通らない(設定詳細は他記事で沢山の記事があるので省略)
なんでかな〜と思っていたが、一つ前のkafka(https://archive.apache.org/dist/kafka/1.0.2/kafka_2.12-1.0.2.tgz) を使えば問題なかった。
# 様々な質問が出ていたけども..
自分的にはstackoverflowなら誰かが解決してくれてるでしょ笑って思っていたのだが、自分と同じ現象の物にはなんのAnswerもついていなかった。
また、kafkaのgithubでの議論でもあやふやな感じで終わってしまっていた。

# 所感
OSSなのでどこかに文句を言うわけにもいかない。本当はどこかでソースコードとか読んで直したいのだが、卒論が忙しいので一応ここに投稿することで終わりとする。エラー内容ももっと精査してから貼りたい。卒論終わってから。
Developer視点 組織の関係性の整理 (マイナスをゼロに補完するマネージャー防止) 用にゃ

## TL;DR

「成熟・検討要素」があって、「どこで・なにで」担うかを整理した
役立つとは言っていないよ

## 成熟・検討要素

**High Speed / High Scale**

* 小さいチームで専属化することで高速にする選択をした場合、事業・チームをスケールする観点では小さくしたためサイロ化が進み同品質でのスケールは困難が発生する関係で相反として記載。

**High Quality / Low Cost**

* 品質を重視すればコストは高くなる。コストを低くすると品質は下がる

**Leadership, Ownership / Management ≒ (Proactive / Reactive)**

* 自律・自主性をまかせたいが、ピーターの法則の観点から、そういう事業・人材管理は負債的に派生する

**Flat / Hierarchy (Role, Communication)**

* フラットな組織にして俊敏性、柔軟性を高めるためには優秀な人材が必要となる。人材・構造的負債箇所が出てくる場合は階層/隔離/レベル化したいずれかが混合したものが必要となる


## 組織構造

![org.jpg](https://qiita-image-store.s3.amazonaws.com/0/106271/1070649f-d6a3-973f-2840-0fcc6249f9ce.jpeg)


* 商品となる「人によるコンサルタントなどの活動」または「ハード/ソフトのサービス」が、マーケットへの価値を提供する
* 商品はハード的な「リソース」とソフト的な「文化」を提供する土壌を形成する
リソースは「人/チーム」と「環境」面の２つに分類する
* 「人/チーム」 は、ロールを含めた人の「人材」と「スキル/ナレッジ」に分解する
* 文化面は、「採用」によって人材供給があり、良い悪いといった「行動指針」による活動から「人材」「スキル/ナレッジ」の向上を図り「評価」を行う
（これ以上の類型化・体系化は各組織・事業体に依存すると思われる）


## 組織構造における成熟・検討要素の確認箇所

![relorg.jpg](https://qiita-image-store.s3.amazonaws.com/0/106271/20c9e2a2-b59f-48d2-469e-14c42a48d99a.jpeg)


**High Speed**

* マーケット・顧客への提供回数を確認する
可能であれば市場評価を計測する必要がある

**Leadership, Ownership/Management**

* 人材面と行動指針と人/チームの向上面からどちらにどれだけかを確認する

**Quality/Cost**

* スキル/ナレッジから品質とコスト面のバランスを確認する
※ 会計、売上面から判断すると高い安いの話になるので議論はしにくい
 しかし、スキル/ナレッジの議論をするためには文化面の評価が機能してる必要がある

**Flat / Hierarchy**

* 行動指針やスキル/ナレッジにおける特性から理想的な構造は推測可能
これは論理設計の部分なる、現実的には人材面を見てどのようになるか？検討し調整して構造化する必要がある

**High Scale**

* ハード的な「リソース」とソフト的な「文化」の両面からボトルネック箇所を明確にし対処する必要がある。現実的には高負荷箇所が出るので、ケアをする形をとり対処を行う必要がある


## まとめ

「マイナスをゼロに補完するマネージャー」（参考にあるもの）を産まないためには、どのように活動するべきか？考え始めるきっかけ/糸口にはなるかも感

## 参考

* [Engineering Managerをエンジニアのマネージャーとするのはやめませんか？](http://yunon-phys.hatenadiary.com/entry/2018/12/09/003520)  
「マイナスをゼロに補完するマネージャー」の志向性を引用
Rails環境の職場に中途で入ったときにやったこと

この記事はRubyOnRailsのアドベントカレンダー11日目の記事です。

さっそくですが、僕はこの12月にリンクアンドモチベーションに転職しました。リンクアンドモチベーションは約3年運用されてきたRailsアプリ「[モチベーションクラウド](https://www.motivation-cloud.com/)」を運営してる会社です。
この記事では、僕がリンモチに転職した際、全体像を把握するために行ったことをまとめています。RailsじゃなくてもWebフレームワークならだいたい同じだと思います。中途入社や社内移動で新規のプロジェクトに関わるとき、何から始めればいいかわからず途方にくれたら、一読していただければ幸いです。

## 1. Modelの数をチェック
```
# 単純にファイル数
ls app/models | wc -l
# rakeならメソッド数とかもわかる
./bin/rake stats | grep Models
```

数を見れば、なんとなーくアプリケーションの大きさや複雑度がわかります。
Railsアプリとして有名なCookpadでは2014年時点で、1525個あったみたいです。
[参考:クックパッド開発者ブログ](https://techlife.cookpad.com/entry/2014/08/28/194147)

自分の感覚としては
30個くらい... 2-3人規模
100個くらい... 8-10人規模
かなぁと思ってます。
（Model数に現れない複雑さや、開発体制などにもよるので一概には言えないですがなんとなくです）

## 2. 行数の多いModelファイルTop3をチェック
```
find app/models -type f | xargs wc -l | sort -r | grep -v total | head -n3
```

多くのロジックが書かれているところは、それだけいろいろなテーブルと関連を持っているアプリの核となるModelであることが多いです。
よって、ファイルの行数top3を確認しました。
（ruby, railsの基本的なコード規約が完全に守られていて、適切にmoduleに分離されている超理想的なコードではその限りではないかもしれないです）

## 3. Gemを確認
Gemfileを見るとインフラの構成がある程度わかります。また、コードを読む上でも、「このメソッドはgemで定義されてるのか？自分で書いてるのか？」を判別するのに役立ちます。自分が開発に携わるときも、車輪の再開発をしないで済むようにgemを抑えておくのはいいことです。

モチベーションクラウドの場合、toBアプリであるという特性上、スプレッドシートやcsvの処理に関わるGemが多く見受けられました。

## 4. レコード数確認
```
select table_name, table_rows from information_schema.TABLES where table_rows is not null order by table_rows desc;
```
レコード数を確認することで、取扱いに注意しなければならないテーブルがわかります。
自分は100万件以上あるテーブルを取扱い注意リストに入れてます。

## 最後に
転職や新規プロダクトへのジョイン時は、キャッチアップだけでかなりの労力がかかりますが、個人が成長するすごくいい機会です。どんどんチャレンジしていきましょー
BeagleBone Black（Angstrom）で WiFi ドングルを挿しても wlan0 が無いときの対処法

#環境
- BeagleBone Black Rev.C
    - Angstrom v2012.12 (Core edition)
- WiFiドングル
    - BUFFALO エアステーション 11n対応 11g/b USB2.0用 無線LAN子機 親機・子機同時モード対応 WLI-UC-GNM2S 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/324504/de0ed417-eb61-a5eb-92e3-6cb73008a2b6.png)

#手順
##1. settings ファイルの変更

```
#nano /var/lib/connman/settings
```

テキストエディタで settings を開き，[WiFi] の項を以下のように変更する．

```:/var/lib/connman/settings
[WiFi]
Enable=true
```

##2. 再起動する

```
#reboot
```

##3. wlan0 があるか確認する
```
#ifconfig
eth0      Link encap:Ethernet
          UP BROADCAST MULTICAST
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 Scope:Host
          UP LOOPBACK RUNNING Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:479 (479.0 B)  TX bytes:479 (479.0 B)

usb0      Link encap:Ethernet
          inet addr:192.168.7.2  Bcast:192.168.7.3  Mask:255.255.255.252
          UP BROADCAST RUNNING MULTICAST  Metric:1
          RX errors:0 dropped:0 overruns:0 frame:0
          TX errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          RX bytes:209413 (204.5 KiB)  TX bytes:94574 (92.3 KiB)

wlan0     Link encap:Ethernet
          inet addr:192.168.1.9  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: Scope:Global
          inet6 addr: Scope:Link
          UP BROADCAST RUNNING MULTICAST Metric:1
          RX packets:7813 errors:0 dropped:12 overruns:0 frame:0
          TX packets:461 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2090575 (1.9 MiB)  TX bytes:56177 (54.8 KiB)
```

wlan0 があることを無事に確認．

#注意点
- /var/lib/connman/settings のファイル名を誤って setting としていたので，wlan0 が表示されなかった．
JavaエンジニアがPythonで機械学習を学習した結果ｗｗｗ

# 自己紹介

前職はSIerにて、13年ほどWebアプリケーションの開発に携わっていた @mizai と申します。
サーバサイドにて、Javaをメインに使っておりました。(入社当時は、COBOLエンジニアへの可能性もあったなぁ、、、(しみじみ))

業務系のシステム作りがほとんどで、製薬会社、住宅メーカー、食品メーカー、銀行など色んな業種の色んな現場に行ってました。

銀行のシステム作りの現場では、オフショア(中国)開発をやっていて、実際に中国へ技術指導に行ったことも。(中国出張が決まったらすぐに、「地球の歩き方」を買いに行ったのは内緒です。<- 何しに行くと思ってんだ！ｗ)

そんなJavaエンジニアの私が、Pythonで機械学習をやってみた結果を書き記したいと思います。
(もちろん、業務でPython使ったことは一度もございませんし、Pythonの知識もほとんどないです。)

# 経緯
今は、他社様のシステム開発を担当するチームに所属しているのですが、弊社には、大量のデータがあるので、データを扱っているチームから、いつお声がかかってもいいように準備しておこうと、基礎的な学習を始めました。

使っている本はこれ。
![blog.jpg](https://qiita-image-store.s3.amazonaws.com/0/98909/068aa33f-9dca-6ad2-e9ce-51d54528d19d.jpeg)
実際にコード書きながらできそう、ということで選びました。

# 環境構築
最初に戸惑ったのは、Pythonの開発環境の構築でした。
まず、色んなツールやライブラリをインストールするところで、本ではバージョンを指定する方法が示されていました。

Anacondaって何？？
まぁ、ええとしよ。
※参考：[Anacondaのこと書いてくれている記事](https://www.sejuku.net/blog/59340#Anaconda)
(機械学習やるために便利なものなのかなー)

本では、Python3.6って書いてあるけど、3.7って出てきたよ??
まぁ、ええとしよ。最新が好きやし、3.7で進めよっと。

で、ライブラリインストールするところで、
`conda`や`pip`というコマンドでバージョン指定しながら色々インストール。

なんやろ、このコマンドの違いは。
まぁ、ええとしよ。

ほんなら、なんかのライブラリで（なんだったかは、わすれた。）

**インストールできません！** みたいなエラーが。。。

えええええ！！！って思って、調べたら、Python3.7だとダメって見つけました。
だから、あえてPython3.6にダウングレード(？)したら、無事成功。

おお、、バージョンに結構シビアそうやな。。。ってのが、最初の感想。

【参考】これがAnacondaの画面
![anakonda.PNG](https://qiita-image-store.s3.amazonaws.com/0/98909/b7ef13ef-a2e0-305f-49c4-cae5e44e8b2d.png)


# 開発
環境整って、いざプログラミング！！
となると、「Jupyter Notebook」(以下、Jupyter)というものを使います。

本の指示に従いながら　、AnacondaからJupyter起動すると、

こんな感じ。
![jupyter.png](https://qiita-image-store.s3.amazonaws.com/0/98909/3d8f5447-e1bb-7cf3-367e-57c08f5427ad.png)


え？なんかブラウザが起動したんやけど？？
![jupyter.PNG](https://qiita-image-store.s3.amazonaws.com/0/98909/e2b6526f-f15d-c8bf-07ff-8e6bd7a4c396.png)

どうやら、Inって書いてある欄にコード書いて実行するってスタイル。
コード書いて、「Shift+Enter」押すと実行される。

JupyterでPythonの基礎を進めているときには、
**なにこれ？なんでこんなんが開発環境なん？？これ使う必要あるん？？**
って思ってました。

そう、機械学習の話が始まるまでは、、、

# データの可視化
Pythonの基礎が終わって、機械学習の話が始まったときに、
**おおお！これは便利かも！！**

と思ったのです。

なぜか！？
![sanpuzu.PNG](https://qiita-image-store.s3.amazonaws.com/0/98909/67573e89-a03f-57b6-0eeb-c9561b880654.png)

こんな感じで、スクリプト書いて実行したら、データの可視化できるんですよ！！

なるほど、こういう感じでサクッと、データを可視化するのは、
**Javaでやろうとしたらめんどくさそうやな。**
**Python便利やな、おもろいな！**
と思いました。

ただ、Pythonで大規模開発やるのは、ちょっとしんどいんじゃなかろうか、、と。
(ここで言う大規模開発：色んな会社、色んなレベルの人が協同する業務系のでっかいシステム作り)

だから、

**1. Pythonで、データ処理を色々試して**
**2. いざ、プロダクトにするときはJava(みたいな固い言語)で書く**

みたいに、使い分ければいいんじゃないかなぁ、と。

今まで経験してない分野でも、少しでも触ってみると、イメージできる幅や深さが一気に増える気がしました。

# JavaエンジニアがPythonで機械学習を学習した結果

1. 初めての言語でも、なんとかなる！
2. やっぱりサンプルコードは自分で書いて、体感するべき！
3. 言語は、適材適所！必要ならば学習するべき！
4. AI、楽しそう～☆

と思いました。(小並感

**AI/IoT的なサービスのアイデアが何かひらめいたら造れるように準備しておくぞー！！！**

この本を一通り終わらせたら、**ブロックチェーン**の学習もやろうと思っています。
（あ！まだ、機械学習の本が終わってないってことを、自白してしまった。。。ORZ)

# 最後に
JavaとPythonの比較をまとめようと思っていたら、すでにこちらでまとめられてましたね。
https://www.sejuku.net/blog/36782


おわり
Chainerの無料Hands-on集「Chainer Colab Notebooks」を作ってみた

# TL;DR
- Colaboratoryで動くChainerのHands-on集 [Chainer Colab Notebooks](https://chainer-colab-notebook.readthedocs.io/ja/latest/) を公開しましたので、是非あそんでみてください

[<img width="1328" alt="スクリーンショット 2018-12-09 15.00.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/111482/76d2c9f4-2e98-2ef3-2367-686b25a5eeb6.png">](https://chainer-colab-notebook.readthedocs.io/ja/latest/)

# Colaboratoryとは
完全にクラウドで実行される Jupyter Notebook環境です。設定不要で、無料で利用可能です。細かい内容はtomo_makesさんの記事が詳しいのでご覧ください。

[【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)

# なにができるのか

- Jupyter Notebook形式のChainer/CuPyのexampleやhands-onをすぐに試すことができる
- 日本語と英語のコンテンツが用意されている(実は！)
- GitHubで管理しているので誰でもコントリビュートできる(実は！)

# なぜ作ったのか
Chainerには公式の[examples](https://github.com/chainer/chainer/tree/master/examples)や、それ以外にもいたる所にscriptやJupyter Notebookがころがっています。ただ、以下の課題があるなあと思っていました。

- 実は公式には[examples](https://github.com/chainer/chainer/tree/master/examples)が多数含まれているが、そこまで存在が知られていない
- 存在を知っていても、script形式で書かれているので、実行はしやすいもののinteractiveな形で実行できるJupyter Notebook形式ではない
- Jupyter Notebookを実行するときにはchainerの環境構築(というよりはGPU環境の構築！)をしないといけないので、一見さんにはハードルが高め

ボタンをポッチと押してColaboratoryで開けるようなwebページがあれば、これらの課題を解決できるかなと思い、作り始めたのがきっかけでした。


# どうやって作ったのか

- 作り方は本当に簡単で、[chainer-community/chainer-colab-notebook](https://github.com/chainer-community/chainer-colab-notebook)を[Read the Docs](https://readthedocs.org/)で配信しているだけです。
- Documentation自体は、Sphinxで作成しています。その際に、Jupyter NotebookをSphinxのドキュメントソースとして扱うためのSphinx拡張パッケージ「[nbsphinx](https://nbsphinx.readthedocs.io/en/0.2.15/index.html)」を使っています。
    - 参考:「[nbsphinx の紹介](https://qiita.com/kozo2/items/ec032ad80fe9a994f0ea)」
- Colaboratoryで開くための、「Show on Coraboratory」ボタンを作りました。現在見ているurlをパースして、Colaboratoryで開くためのurlを作成してくれます。
    - めちゃくそデザインはダサいので直したいです。

# 今後
## コンテンツを拡充する
今までは、手当たり次第コンテンツを足していきましたが、最近はある程度的を絞ってコンテンツを加えていっています。主に、以下のコンテンツを追加していこうとしています。

- `chainer-colab-notebook/hands_on_ja/chainer/begginers_hands_on/`
    - Googleなどでhands-onイベントを開くためにコンテンツを増やしています。できれば英語版もつくりたかったりしているが手が空いていない・・・
- `chainer-colab-notebook/official_example_en`
- `chainer-colab-notebook/official_example_ja`
    - 本家[chainer/examples](https://github.com/chainer/chainer/tree/master/examples)をJupyter Notebook化し、説明を付け足したものを置く場所。ここもできれば、すべてのexamplesに対してつくりたい・・・

## webページの認知度を上げる 
そもそもこの記事自体が宣伝ぽくなってしまっているのですが、実は色んな所で宣伝していたりします。実は公式ページからもリンクが貼られていたりもします。

[<img width="301" alt="スクリーンショット 2018-12-09 15.44.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/111482/98f68c1f-4e2c-6333-e872-1202ffe60569.png">](https://docs.chainer.org/en/stable/)

今後も、Chainerのイベントなどで紹介していければなーとおもっています。
Zabbix と CloudWatch を比較する

4年ほどまえに、AWSの運用監視でZabbixを使う理由を[公開](http://blog.serverworks.co.jp/tech/2014/11/27/why-zabbix-aws/)しました。

あれから4年CloudWatchも大幅に進化し
Zabbixも 4.0 になりましたので、改めて今
AWS監視でZabbixを薦める理由を書きたいと思います。

#メトリクス収集
監視データの収集について見ていきます。

## Zabbix
Zabbixは統合監視ツールですので、もちろんクラウドも、オンプレミスもネットワーク機器も
そして、Zabbix 4.0 からは HTTPアイテムによってAPIによってWEBサービスのメトリクスも収集できるようになりました。
監視項目はテンプレートやユーザーマクロによって一元管理を行う事ができます。
HTTPアイテムによるAWSの監視については、後日詳しく紹介します。

## CloudWatch
CloudWatchも2017年に新しいCloudWatchエージェントが発表されました。
これにより、これまでスクリプトなどを使って独自に設定する必要があったOS内部のメトリクス取得を簡単に行う事ができるようになりました。
収集アイテムの設定はSystemsManagerのパラメータストアによって一元管理することが可能です。

#メトリクス同士の計算
##Zabbix
Zabbixでは計算アイテム、アグリゲーションアイテム、値の前処理、依存アイテム、トリガーでの計算機能によって複数のアイテムを組み合わせたり、値の換算を行って監視を行うことがかのうです。
また、Forecast関数を使うことによって未来値も可能です。

##CloudWatch
CloudWatchではCloudWatch Metric Math の登場によりメトリクスに対する計算がかのうになりました。
また、Amazon Machine Learningと連携したダッシュボードを作成することで値の予測も可能になりました。

#ログ監視

##Zabbix
Zabbixでは正規表現を用いたキーワード一致でのログ監視が可能です。
Zabbix 3.2以降では 負荷がかかるログ本文を収集せずにlog.countアイテムを使うことで
キーワードの件数のみを収集することも可能になりました。
またZabbix 4.0 ではタグ機能を利用することによって、1つのログファイルから、アプリケーション名などをタグとして、障害だけではなく、回復を判定することもできるようになりました。

##CloudWatch
CloudWatchではCloudWatchLogsの登場によりログ収集のほかキーワードの件数によるアラート通知が可能となりました。

#値の保存期間
#Zabbix
Zabbixでは設定により保存期間を自由に設定可能です。
また、アップデートのたびにZabbixの内部ロジックが改善されていますので、現在は期限が過ぎたデータを消すためのHousekeeperが動作しても、値収集の遅延などはほとんど発生しなくなっています。

##CloudWatch
CloudWathcのデータ保存期間は以前は14日間となっていましたが、現在は455 日 (15ヶ月)のデータが保存されるようになっています。

#費用

##Zabbix
監視規模によってインスタンスサイズを検討する必要はありますが、t3.smallインスタンスで100インスタンス程度は監視が可能と思います。この場合のインスタンス費用は以下の通りです。
<img width="728" alt="2018-12-09_15h41_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/cb8e9368-baa4-be0c-6338-42cefbbd1036.png">
<img width="736" alt="2018-12-09_15h41_23.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/f9295ded-c0ad-6e7c-9302-f90064ef82f1.png">

月額$20 程度になります。

#CloudWatch
CloudWathAgentのデフォルト設定でLinuxのメトリクスを収集した場合の費用は以下の通りです。
<img width="745" alt="2018-12-09_15h45_17.png" src="https://qiita-image-store.s3.amazonaws.com/0/102020/b9d74fdd-a593-8f8c-4166-2da144932359.png">
大きなインスタンスでは気にならない金額ですが、安価なインスタンスの場合
インスタンス料金の50%近いCloudWathcメトリクス費用は意外と大きく感じるかもしれません。

#まとめ
| 機能 | Zabbix | CloudWatch |
|:--|:--|:--|
| OS情報の収集 | ZabbixAgent | CloudWatchAgent |
| AWS以外の統合監視 | ○（ZabbbixAgent,SNMP,IPMI,HTTPアイテム） | △（CloudWatchAgent） |
| メトリクスの演算 | ○ | ○ |
| 未来値の予測 | Forecast関数 | Amazon Machine Learning |
| 閾値のテンプレートと個別変更 | ○ | ○ |
| メンテナンス設定 | ○ | × |
| 障害通知 | メール Jabber SMS 任意スクリプト | Amazon SNS |
| データの保存期間 | 設定により長期間保持可能 | 15ヶ月 |

適材適所で組み合わせつつ、自信をもってクラウド監視にZabbixをご利用下さい。
PDFデータをテキスト化する方法

この記事ではWindows10にインストールしたAnacondaでPython3.6を使用しています。

#本記事でやったこと
・PDFデータをテキストデータにする。

#ツールのインストールとプログラム取得
##1.pdfminer.sixをインストール
まずはpdfをテキストに変換するツールを下記コマンドにてダウンロードします。（Anacondaのコンソール上にて実行する）

```
pip install pdfminer.six
```

##2.pdf2txtが下記フォルダに置かれるのでパスを覚えておく
環境変数に登録しておくと便利ですが、取り急ぎ今回はフルパス指定で使っていきます。

```
 C:\ProgramData\Anaconda3\Scripts\pdf2txt.py
```

さっそく実行させましたが、下記のようなエラーが発生しました。
※オプションの-oを加えることで出力ファイルを指定できます。

```
D:\s>python C:\ProgramData\Anaconda3\Scripts\pdf2txt.py -o test.txt test.pdf
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\Scripts\pdf2txt.py", line 136, in <module>
    if __name__ == '__main__': sys.exit(main())
  File "C:\ProgramData\Anaconda3\Scripts\pdf2txt.py", line 131, in main
    outfp = extract_text(**vars(A))
  File "C:\ProgramData\Anaconda3\Scripts\pdf2txt.py", line 63, in extract_text
    pdfminer.high_level.extract_text_to_fp(fp, **locals())
  File "C:\ProgramData\Anaconda3\lib\site-packages\pdfminer\high_level.py", line 80, in extract_text_to_fp
    check_extractable=True):
  File "C:\ProgramData\Anaconda3\lib\site-packages\pdfminer\pdfpage.py", line 132, in get_pages
    raise PDFTextExtractionNotAllowed('Text extraction is not allowed: %r' % fp)
pdfminer.pdfdocument.PDFTextExtractionNotAllowed: Text extraction is not allowed: <_io.BufferedReader name='test.pdf'>
```

どうやらPDFには編集権限がついているものがあり、編集可能でないとツールが読み取らないようです。


##3.PDFを編集可能にするソフトをダウンロード
[qpdf](https://sourceforge.net/projects/qpdf/)というソフトを使用するとPDFに編集可能にできるようです。
※あくまで自己学習で行っていることなので不用意に他人のPDFファイルのロックを解除しないでください。

　qpdf-8.2.1-bin-msvc64.zip

解凍して任意の場所に置く　私は下記の場所に置きました。

```
　C:\ProgramData\Anaconda3\Scripts\qpdf-8.2.1-bin-msvc64\qpdf-8.2.1\bin\qpdf.exe
```

#下記コマンドでPDFを編集可能にする。
対象PDFを[qpdf](https://sourceforge.net/projects/qpdf/)にかけて編集可能にしてみます。

```
D:\s>C:\ProgramData\Anaconda3\Scripts\qpdf-8.2.1-bin-msvc64\qpdf-8.2.1\bin\qpdf.exe --decrypt 対象ファイル　出力先ファイル
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/db748141-8c37-6570-c869-cb74dcc7ebf5.png)


エラーも出ずにうまく処理できたようです。
※今回使用したファイルはtest.pdfで編集可能にし、ファイル名はtest1.pdfとしました。

もしもこれでできない場合空白のパスワードがかかっているもしくは意図的にパスワードをかけているため下記を試してみて下さい。(実績なし）そう考えるとパスワードをかけずに編集不可にしているPDFは作者の意図せずPDF作成時に編集不可にしているのか意図的にやっているのかちょっとよくわからないですね。

```
　C:\ProgramData\Anaconda3\Scripts\qpdf-8.2.1-bin-msvc64\qpdf-8.2.1\bin\qpdf.exe --decrypt input.pdf --password='' output.pdf
```

#PDFをTXTにする

下記コマンドで再度PDFデータをテキストにしてみます。
```
　python C:\ProgramData\Anaconda3\Scripts\pdf2txt.py -o test1.txt test1.pdf
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/2a30e86a-7786-8c0e-9de1-2e2604cfbc03.png)

エラーも出ずにうまく処理できたようです。

肝心のTXTファイルも作成されております。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/612733c4-1a20-561a-862d-c95cada411e0.png)


中身を見たところ、スペース段落なしでびっちり書き込まれておりました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284597/6baf1d04-bd25-a063-e2d5-95246a458559.png)


#終わりに

自身で作成した人工知能プログラムで文章を学習させるため、他のサイトから参考にダウンロードした(もちろんサイト管理者から許可をいただいたもしくはダウンロード可能なサイトです。）PDFデータなどをテキストデータにして活用する際にこの方法を役立てられればと思います。
また、現場でPDFデータをテキストにしたいと思っている方がいらっしゃいましたらご参考までに試していただければと思います。
Synthetic Control Method

#Synthetic Control Methodとは
### Synthetic Control Methodって何？
　皆さんはSynthetic Control Methodという手法をご存知でしょうか？最近じわじわと日本でも話題になっている手法ですが、まだまだ日本語の文献、資料が少ないのでまずは概略だけでもざっくりとまとめさせていただきます。
　Synthetic：人工的な、人為的な、合成された
というような意味の単語でして、Synthetic Control Methodとはざっくりいうと、「ある刺激が発生したAに対し、その刺激が発生しなかった場合の事象を人工的に合成して作成(Bとする)し、AとBを比較することで、その刺激による影響を測る」というもので、平たく言うとシミュレーションの一種であり、ABテストのペアの作り方の一つと捉えていただけると良いかと思います。
　とはいえ、これだけではさっぱりかと思いますので、有名なSCMを用いた論文にカリフォルニア州におけるタバコ規制の影響を測ったものがあります。
　英語になりますが下記で読めます。
　Synthetic Control Methods for Comparative Case　Studies: Estimating the Effect of California’s　Tobacco Control Program　(https://web.stanford.edu/group/hainmuellerlab/cgi-bin/wordpress/wp-content/uploads/2014/05/ccs.pdf) 

### タバコの論文の概要
　これもざっくりまとめますと、カリフォルニア州だけタバコの規制が1988年に厳しくなったんですね。その影響で売上がどの程度減少したのか？といのをSCMを用いて推定している論文です。この事例では、SCMを用いることで、カリフォルニア州以外の州に重み付けをこない、それらを足し合わせることで仮想カリフォルニア州の売上を推定します。（他の州の売上を加重平均して、仮想カリフォルニア州の売上を作っています。）この論文の34ページが実際のカリフォルニア州と仮想カリフォルニア州の売上の推移のトレンドであり、87年にタバコの規制が施行されています。その結果、実際のカリフォルニア州では売上が減少し、他の州を合成して作成している仮想カリフォルニア州はその規制は施行されていないため（仮想カリフォルニア州は規制が行われなかった場合のカリフォルニア州となります）、売上に差が発生しています。この差分がタバコの規制によって減少したタバコの売上となります。

### SCMの肝
　このアプローチの肝は間違いなく「どれだけ高精度で仮想カリフォルニア州を作ることができたのか？」ということになります。刺激（タバコの例でいうと規制の施行）の前の期間(pre-period)において、うまく仮想カリフォルニア州を作れていなければ、刺激後の期間(post-period)において差分を測定しても、意味をなしません。そのため、pre-periodにおいて、MAPEやRMSEで実際のカリフォルニア州と仮想カリフォルニア州のズレが小さいことを確認することがSCMを用いる上で重要です

### SCMを行うために
　うまく仮想カリフォルニア州を作ることができれば結果の解釈は非常にわかりやすい分析であり、いろいろな事象に適応できるアプローチです。例えば、マーケティングの効果測定等でも（TVCMの効果を図りたいなど）十分行える上、従来の回帰分析を用いたMMM（マーケティング・ミックス・モデル）は多くの場合モデル作成者のさじ加減の影響が大きかったことを考えると今後は「SCMでMMMを」という流れが生まれるかもしれません。
その上で、SCMを行うためにはいくつか条件があります。
- test(介入が行われた対象、カリフォルニア州）とcontrol(介入がない対象、カリフォルニア州以外の州）が必要
　SCMではControl群を加重平均することで、介入のない場合の仮想testを作成し、実際に介入が起こったtestと比較します。そのため、介入が行われていないサンプルを作成する必要があります。

- Control群を多めに
　上記まで読んでいただくとおわかりかと思いますが、Control群の加重平均でうまく実際のtestを再現できないと、SCMはworkしません。そのため、ある程度多くのControl群を確保することが必要です。
　例えば「TVCMであれば、北海道だけTVCMをうち、46都府県には打たない」「会員10000人へのDMであれば、1000人にはDMをうち、9000人には送らない」など、事前にしっかりと施策設計した上でないとこのアプローチはうまくworkしません。

- 時系列データである程度過去までデータを取得できること
　pre-periodで仮想testを作成するので、分析に耐えうる程度に過去データが必要になります。（週次データなら52週くらいは季節性を考えてもあったほうが良いかも）

- 差分が発生する程度の刺激であること
　これはSCMに限らないのですが、「微妙にDMの文言を変えた」というような小さな刺激では、SCM（に限らず、統計的アプローチでは）その施策の結果を測定することは難しいです、ほぼ影響がないため、むしろ「差があるとは言えない」という結果になりがちです。（もちろんtabulationベースでポジティブ・ネガティブを評価することは可能ですが、というかそれしかできないというか。。。）


###　おしまい
私の初めての記事で読みにくかったと思いますが、ここまでお読みいただきありがとうございました。
今後もぽつりぽつりと更新していきたいと思います。SCMのR packageについてや、generalized synthetic control methodについて、はたまたMAPEやRMSE、ツリーモデルに関して、などテーマは決めていませんがよければまたお読みいただけると幸いです。
Angular Webpack Starterで作成したアプリにJestを導入した話

この記事は、[Business Bank Group Developers Advent Calendar](https://qiita.com/advent-calendar/2018/bbg_developers) 9日目の記事です。

# 前置き

この記事は、 [angular-starter](https://github.com/gdi2290/angular-starter)を利用して作成したアプリケーションに、[Jest導入記事](https://www.xfive.co/blog/testing-angular-faster-jest/)を参考にJestを導入して実際に動かすまでの過程を記した記事です。
また、すでにjasmine + karmaのテスト環境は存在している状態であり、
いきなりこのkarmaのテスト環境を無くすいうことはストレスになりそうだったので共存する方針を取る形で導入を目指しています。

# 導入

## jestのインストール

```bash
yarn add --dev jest jest-preset-angular @types/jest
```

## jest.config.jsを作成

```js:./jest.config.js
module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  globals: {
    "ts-jest": {
      tsConfigFile: "<rootDir>/tsconfig.test.json"
    },
    "__TRANSFORM_HTML__": true,
  },
  testMatch: [
    "<rootDir>/src/**/+(*.)+(test).+(ts)?(x)"
  ],
  setupTestFrameworkScriptFile: '<rootDir>/jest/setupJest.ts',
  transformIgnorePatterns: [
    "node_modules/(?!@ngrx)"
  ]
};
```

jest起動のための設定ファイルになります。
導入資料と変更している点としては、すでに存在しているkarmaのテストに影響を与えないように、testMatchファイルを`xxx.test.ts`となるようにしている点。
setupFileはtslintの影響を与えないようにするために、新しくjestディレクトリを切った中に入れるようにしました。

## setupJest.tsの作成

```ts:./jest/setupJest.ts
import 'jest-preset-angular';
import './jestGlobalMocks';
```

```ts:./jest/jestGlobalMocks.ts
const mock = () => {
  let storage = {};
  return {
    getItem: (key: any) => key in storage ? storage[key] : null,
    setItem: (key: any, value: any) => storage[key] = value || '',
    removeItem: (key: any) => delete storage[key],
    clear: () => storage = {},
   };
  };
  Object.defineProperty(window, 'localStorage', {value: mock()});
  Object.defineProperty(window, 'sessionStorage', {value: mock()});
  Object.defineProperty(window, 'getComputedStyle', {
  value: () => ['-webkit-appearance']
});
```

ここは資料通りです。setupJest.tsでテスト起動時にimportしたいクラスを指定し、
jestGlobalMocks.tsにjsdomには存在しないブラウザAPIを定義しています。

## webpackの修正

今回新しくtest拡張子を追加したので、それを追加する必要があります。

## tsconfigの修正

```diff
{
  "compilerOptions": {
      :
    "types": [
-     "jasmine",
+     "jest",
      :
    ]
```

## package.json

```diff
"scripts": {
    :
+ "jest": jest,
+ "jest:watch": "jest --watch",
- "test": "karma start",
+ "test": "jest && karma start",
```

# まとめ

ブラウザのjsdomで動いているのでjestは速くていいです。
また今回挙げながったですがwatch機能が便利なのもいいです。
構築当時はkarmaと共存を考えていましたが、現在はkarmaなくしていいと考えているので置き換えの方を進めようとしています。


明日のカレンダーは @kyokoshimizu さんが担当します。よろしくお願いします。
rails 5でajax送信をするform_tagの設定ではまった話

Ruby on Railsで開発中、他の所と同じようにajax通信をする検索ダイアログをform_Tagで作ったところ以下の様なエラーがでて困ったと言う話です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42407/ff8d8468-8849-7a41-f87f-d9964a80c84e.png)

結論から言うと、

* form_tagやform_forの場合、 remoteオプションを使うと、authenticity_tokenのinputが自動で追加されない
* submit_tagとかbutton_tagとかのjavascript処理でauthenticity_tokenをmetaタグがから取ってくるようになっている
* すなわち、自力でjavascriptでsubmitするとauthenticity_tokenが追加される処理が走らない

っぽいです。

以下、rubyonrails.orgより抜粋。

```
Remote forms may omit the embedded authenticity token by setting config.action_view.embed_authenticity_token_in_remote_forms = false. This is helpful when you're fragment-caching the form. Remote forms get the authenticity token from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.
```

ajaxで処理をする様なフォームはfragment-cachingされているという前提のようですね。
確かにその場合、フォームの中にCSRFのタグを持っていると認証が通らなくなるので、html作成時に割り当てられたtokenをheaderのmetatagから取得する必要があると。

## エラーになるコード

```
.d-flex.flex-row
  =form_tag({controller: 'office', action: 'modal_search'}, {remote:true, id:"office_search"}) do
    .px-3
      =text_field_tag 'keyword'
    .px-3
      =button_tag t('cmn_sentence.searchButton',model:Business.model_name.human), class:"btn btn-secondary", onclick:"on_office_search_click()"
    #office_search_message.py-3
      検索後下のリストから選択して下さい
  #office_search_list.d-flex

:javascript
  function on_office_search_click(){
    $('#office_search_message').text("検索中...")
    $('#office_search').submit();
  }
```

## 修正されたコード

```
.d-flex.flex-row
  =form_tag({controller: 'office', action: 'modal_search'}, {remote:true, id:"office_search"}) do
    .px-3
      =text_field_tag 'keyword'
    .px-3
      =button_tag t('cmn_sentence.searchButton',model:Business.model_name.human), class:"btn btn-secondary", onclick:"on_office_search_click()"
    #office_search_message.py-3
      検索後下のリストから選択して下さい
  #office_search_list.d-flex

:javascript
  function on_office_search_click(){
    $('#office_search_message').text("検索中...")
  }
```

...そうなんです。romoteオプションがつけられたformはsubmitしちゃだめ。というだけでした。
【Python】input()からsys.stdin.readline().strip()への変更


# やりたいこと
競プロで処理時間が長すぎた時に，処理部分のコードは変えずに`input()`を`sys.stdin.readline().strip()`に変更する。

# 入力
```input.txt
10
hoge
foo foo
```

# うまくいった方法
```py
def input(): return sys.stdin.readline().strip()
[print(input()) for _ in range(3)]
'''出力
10
hoge
foo foo
'''
```

# うまく行かなかった方法
理由は分かりませんが一行目しか取れませんでした。ご存知の方いたら教えてくださいm(_ _)m

```py
input = sys.stdin.readline().strip
[print(input()) for _ in range(3)]
'''出力
10
10
10
'''
```
s3にCloudFrontからはアクセスさせて、開発拠点、開発VPC以外からアクセスさせないパケットポリシー

s3のバケットに

CloudFrontからはアクセスさせる。
S3への直接アクセスは、開発拠点からのみアクセスできる
S3にアップロードするEC2の所属するVPCからのみアクセスできる
というポリシーが必要になった。

NotPrincipalの存在に気付かなかったので少しハマった。
別途VPCのエンドポイントを作成して、使用するＶＰＣからのアクセスを限定する必要がある。

```ｊｓｏｎ:qiita.rb
{
    "Version": "2012-10-17",
    "Id": "IP-VPC-CloudFront-Policy",
    "Statement": [
        {
            "Sid": "2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E233333eee"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::production-s3/*"
        },
        {
            "Sid": "Allow-from-specific-IP-and-VPC-only",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E233333eee"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::production-s3/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "<IPアドレス>",
                        "<IPアドレス>",
                        "<IPアドレス>",
                        "<IPアドレス>
                    ]
                },
                "StringNotEquals": {
                    "aws:sourceVpc": "vpc-<vpcid>"
                }
            }
        }
    ]
}
```
順列組み合わせ JavaScript(ES2015)

# その1
https://qiita.com/higuma/items/5af4e62bdf4df42ce673
を参考にJavaScript(ES2015)での順列組み合わせ関数を作成したのでメモとして残しておく。

以下の`コードの解説`の再帰処理の流れが参考になった。
https://qiita.com/higuma/items/5af4e62bdf4df42ce673#%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E8%A7%A3%E8%AA%AC

## 実装

```js
// pre: 1st half of array
// post: 2nd half of array
const permutation = ({ result = [], pre = [], post, n = post.length }) => {
  if (n > 0) {
    post.forEach((_, i) => {
      const rest = [...post];
      const elem = rest.splice(i, 1);
      permutation({ result, pre: [...pre, ...elem], post: rest, n: n - 1});
    });
  } else {
    result.push(pre);
  }
  return result;
};

const array = [0, 1, 2, 3];
const results = permutation({ post: array });
console.log(results);

const results2 = permutation({ post: array, n: 2 });
console.log(results2);
```

## 結果
```js
[ [ 0, 1, 2, 3 ],
  [ 0, 1, 3, 2 ],
  [ 0, 2, 1, 3 ],
  [ 0, 2, 3, 1 ],
  [ 0, 3, 1, 2 ],
  [ 0, 3, 2, 1 ],
  [ 1, 0, 2, 3 ],
  [ 1, 0, 3, 2 ],
  [ 1, 2, 0, 3 ],
  [ 1, 2, 3, 0 ],
  [ 1, 3, 0, 2 ],
  [ 1, 3, 2, 0 ],
  [ 2, 0, 1, 3 ],
  [ 2, 0, 3, 1 ],
  [ 2, 1, 0, 3 ],
  [ 2, 1, 3, 0 ],
  [ 2, 3, 0, 1 ],
  [ 2, 3, 1, 0 ],
  [ 3, 0, 1, 2 ],
  [ 3, 0, 2, 1 ],
  [ 3, 1, 0, 2 ],
  [ 3, 1, 2, 0 ],
  [ 3, 2, 0, 1 ],
  [ 3, 2, 1, 0 ] ]
```

```js
[ [ 0, 1 ],
  [ 0, 2 ],
  [ 0, 3 ],
  [ 1, 0 ],
  [ 1, 2 ],
  [ 1, 3 ],
  [ 2, 0 ],
  [ 2, 1 ],
  [ 2, 3 ],
  [ 3, 0 ],
  [ 3, 1 ],
  [ 3, 2 ] ]
```

# その2
その1を実装後に `Generate permutations of JavaScript array` のキーワードで検索していたら、以下の記事を発見した。

Implement All Permutations of a Set in JavaScript – InitJS
https://initjs.org/all-permutations-of-a-set-f1be174c79f8

その1とは処理フローが少し異なるが、上記の記事を参考に別の実装をしてみた。
引数が`array`のみで済んでいる。

## 実装

```js
const permutation = (array) => {
  let result = [];
  if (array.length === 1) {
    result.push(array);
    return result;
  }
  for (let i = 0; i < array.length; i++) {
    const firstElem = array.slice(i, i + 1);
    const restElem = [
      ...array.slice(0, i),
      ...array.slice(i + 1),
    ];
    let innerPermutations = permutation(restElem);
    for (let j = 0; j < innerPermutations.length; j++) {
      result.push([...firstElem, ...innerPermutations[j]]);
    }
  }
  return result;
};

const array = [0, 1, 2, 3];
const results = permutation(array);
console.log(results);
```

## 結果
```js
[ [ 0, 1, 2, 3 ],
  [ 0, 1, 3, 2 ],
  [ 0, 2, 1, 3 ],
  [ 0, 2, 3, 1 ],
  [ 0, 3, 1, 2 ],
  [ 0, 3, 2, 1 ],
  [ 1, 0, 2, 3 ],
  [ 1, 0, 3, 2 ],
  [ 1, 2, 0, 3 ],
  [ 1, 2, 3, 0 ],
  [ 1, 3, 0, 2 ],
  [ 1, 3, 2, 0 ],
  [ 2, 0, 1, 3 ],
  [ 2, 0, 3, 1 ],
  [ 2, 1, 0, 3 ],
  [ 2, 1, 3, 0 ],
  [ 2, 3, 0, 1 ],
  [ 2, 3, 1, 0 ],
  [ 3, 0, 1, 2 ],
  [ 3, 0, 2, 1 ],
  [ 3, 1, 0, 2 ],
  [ 3, 1, 2, 0 ],
  [ 3, 2, 0, 1 ],
  [ 3, 2, 1, 0 ] ]
```

# 参考
https://qiita.com/s-katsumasa/items/7b8ce83df22467f74c51
にも書いてあるが、Rubyの場合 `Array#permutation` があるが、JSでは同等のものはなさそう。
instance method Array#permutation (Ruby 2.5.0)
https://docs.ruby-lang.org/ja/latest/method/Array/i/permutation.html

その2の実装と似ている ↓
Generate permutations of JavaScript array - Stack Overflow
https://stackoverflow.com/questions/37579994/generate-permutations-of-javascript-array/43260158#43260158
Blenderソースコードの歩き方

この記事は[Blender Advent Calendar 2018 - Adventar](https://adventar.org/calendars/2987)に参加しています。本日は19日目。

Blenderのソースコードを読んだり、書いたりするときのTipsです。
ここではgit.blender.orgのblenderブランチを扱います。

また、パッチの送り方とか、ビルドの仕方とか、externとinternの違いとか、DNAとRNAとかの話は公式に書かれていますので、そっち読んでください。

# 使用言語
Blenderの開発をする上で必要なプログラミング言語は、C, C++, pythonの3つです。
私が見たところでは、

- C: ヘッダーファイル（実質C++と同じ）と構造体
- C++: 論理
- python: UI

というように、Cはほとんど使われておらず、C++とpythonをメインに扱うことになりそうです。

# よく使うディレクトリー
よく使うディレクトリーは以下の2つです。

- release/scripts/startup/
- source/blender/

release/scripts/startup/はUIとかをいじる時に使います。中身はpythonです。
source/blender/は論理をいじる場所です。例えば、モディファイアーの実際の処理はこの中のmodifiersというディレクトリーに格納されています。

# ソースコードの位置を突き止める方法

Blenderはかなり大きいソフトなので、どこから手を付けたら良いのかわかりません。一歩目を踏むためのアドバイスを投げていきます。

ファイルを探す際の基本的な流れとしては、pythonUI->rna->dna、という手順を踏むといいでしょう。

1. pythonのUIはedit sourceなどでかんたんに見れますが、実際の演算にはほとんど関係ありません。
2. rnaはpythonとCをつなげる役目をします。
3. dnaは実際のC（C++）で使われるオブジェクトを宣言します

## rnaのファイルを探す
さきほどPythonUIから攻めろと掻きましたが、BlenderのTooltipsを使うと一気にrnaまで迫ることが出来ます。
TooltipsはUIですが、C言語系で書かれており、大抵の場合source/blender/makesrna/intern/にあります。（英語のみ。日本語翻訳は.poとかいうおおよそ翻訳に向いていないのに翻訳に使われているフォーマットに基づいて、どっか別のディレクトリに格納されています）
なので、

1. 自分の必要とする機能と関係のありそうなTooltipsを探す
2. makesrna/intern/内をTooltipsで検索する（特異度高いです）

の手順を踏むと、大体関係のありそうなフォルダーが見つかります。なお、BlenderのUIは結構ぐちゃぐちゃなところがあるので、これで見つからないときも稀によくあります。

```C
static void rna_def_modifier_explode(BlenderRNA *brna)
{
	StructRNA *srna;
	PropertyRNA *prop;

	srna = RNA_def_struct(brna, "ExplodeModifier", "Modifier");
	RNA_def_struct_ui_text(srna, "Explode Modifier", "Explosion effect modifier based on a particle system");
	RNA_def_struct_sdna(srna, "ExplodeModifierData");
	RNA_def_struct_ui_icon(srna, ICON_MOD_EXPLODE);

#(中略)
	prop = RNA_def_property(srna, "particle_uv", PROP_STRING, PROP_NONE);
	RNA_def_property_string_sdna(prop, NULL, "uvname");
	RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME);
	RNA_def_property_ui_text(prop, "Particle UV", "UV map to change with particle age");
	RNA_def_property_update(prop, 0, "rna_Modifier_update");
```

適当に引っ張ってきたこれは、RNAの中でTooltipsが宣言されている様子を示しています。
どうやら`Explode Modifier`上で`"UV map to change with particle age"`をするためのもののようです。
Explode Modifierのこの機能は、ソースコード上、2通りの名前を持ちます。

中略後の1行目の`particle_uv`は、pythonでUIをいじるための名前です。PythonのUIから攻める際はこちらを手がかりに使います。
中略後の2行目の`uvname`は、C言語で論理を扱うための名前です。次のトピックのdnaを探す、ではこちらを使います。

## dnaのファイルを探す
dnaはsource/blender/makesdnaを探すとだいたい出てきます。
dnaの記述は、普通の構造体の宣言と同じです。
構造体の名前は`RNA_def_struct_sdna(srna, "ExplodeModifierData");`とあるように`ExplodeModifierData`です。一方のその構造体のプロパティー名が先程の例で言うところの`uvname`です。
このDNAファイルで宣言されている構造体こそが、その後Cのコードで実際に使われるものです。

## 似たコミットを探す
この構造体を手がかりにして実際の論理ソースコードを探すのも十分現実的ですが、関連のあるコミットを探すほうが見落としが少なくて楽です。先程突き詰めたrnaやdnaのソースコードを`git blame`したり、そのフォルダーへのコミットログで似たものを探したりすると、いいです。

ちなみに私の場合は、似たコミットを上記の手法で探す→とりあえずコピペ→ビルドするか確認する、という手順を踏んでます。

# その他

- 巨大なソースコードを潜るとき、どこか別のディレクトリから関係のあるファイルにだけハードシンボリックリンクを貼るとはかどりました。ハードリンクがおすすめなのは、そのディレクトリ内でgit initすると、本物のところでgit commitしなくても変更を記録できるからです。
- http://www.letworyinteractive.com/blendercode/modules.html ここがBlender内のライブラリ（ベクトル演算とか）を調べる上でめちゃくちゃ便利でした。
- 解決されたバグからコミットログをたどるのも良さそうです。

乱文失礼しました。（想像以上に忙しかったんです……。時間に余裕が出来たら加筆・推敲するかも）
明日はdrmdrさんです。
RXJS scan と filterの違い

# 前提として
Observableに関して学ばなければいけません
https://qiita.com/ryuseikurata/private/6db14969b628e0de1d0c
https://qiita.com/ryuseikurata/private/fa5227a1203af86a19ab
https://qiita.com/ryuseikurata/private/45faa9cd8f50a390b10c

# scan
Operatorの一つです。
**アキュームレータ**とメッセージを使って処理することができます。

**アキュームレータ**とは、蓄積されたものという意味です。
observableのscanでは、処理した返り値をアキュームレータとします。


```typescript
const array = of(1,2,3)

//accがアキュームレータ、curがメッセージです。
//メッセージの1を処理するとき、蓄積がないので、acc は 0となります。
//メッセージの2を処理するとき、蓄積は` 1(0 + 1) `なので、acc は 1となります。
//メッセージの3を処理するとき、蓄積は` 3(1 + 2) なので、acc は 3となります。
const scan = array.pipe(
   scan( (acc, cur) => acc + cur ) 
 );
scan.subscribe(val => console.log(val));
```

```typescript

1
3
6
```

# filter
Operatorの一つです。
メッセージをフィルタリングしてくれます。
filiterのなかで、trueになったもののみを返します。

```typescript
const array = of(1,2,3);

//メッセージが、奇数のものだけを返すようにしています。
const filter = array.pipe(
         filter( num => num % 2 == 1));

filter.subscribe(val => console.log(val));
```

```typescript
1
3
```