OmniAICreator/Qiita-1.07M huggingface dataset:
itamae | itamae運用に関する備忘録

itamae運用に関する備忘録、本来はドニュメント等にあるはずの事に過ぎないが、必要な時に探すのが面倒なので、自分用にまとめておく。

# 実行に関して

## レシピが実行されるのは、未適用の時

 説明は不要だと思うが、itamaeを向けて実行した時に、レシピが未適用だったら問答無用に適用される

## 適用済みのレシピを再度適用させるのは、レシピの内容が変更された時

 一度適用されたレシピを、再度itamaeを向けて実行しても、レシピの内容に変更がなければ、適用されない。つまり、何度実行しても、勝手にアップデートがかかるような適用はされない。

## レシピの内容が変更されていなくても、関連ファイルの内容が変更されれば、適用される

 レシピの中で、template等を使用してファイルを配置する場合などでは、レシピが全く変更されていなくても、そのsourceファイルが変更されていれば、適用される。

## 通常のレシピ適用ではパッケージアップデートはされない

 RedHat系のみで確認していないが、新しいパッケージがある状態でレシピを適用させても、インストール済みのパッケージがバージョンアップされることはない。但し、明確にversionでversion指定するとアップデートされる(or アンインストールして再適用してもアップデート可能)。

# テクニックに関して

## packageはパッケージ管理ツールでインストール可能な安定版の最新バージョンがインストールされる

 RedHat系に関して、YUMでインストールされるパッケージの安定版の最新バージョンがインストールされるので、特定のバージョンをインストールしたい場合には、package resourceでversionオプションを使用すること

## Redhat系でリポジトリの有効/無効を切り替えてインストールする方法

 Redhat系でリポジトリを通常enabled=0にしておいて、yum --enablerepo=xxxでインストールするのを、itamaeのレシピで実現するのはpackage resourceで optionsオプションを使用し、 options "--enablerepo=xxx"と記載する

## service resource の:startは開始であって、restartではない

 phpなど、apache(httpd)の関連サービスの起動が必要なものではaction :startとする必要がある。そのphpの場合、例えばphp.iniを変更した場合には、apache(httpd)の再起動の必要があるが、action :startでは、起動中のapacheプロセスは再起動されない。また、起動してない場合に action :stopしても不具合は起こらない。そのため変更後に再起動が必要なサービスは、イデオムとしてaction [:stop, :enable, :start]とすると良い

## ポートフォワーディングとitamaeのpオプションを組み合わすと、直接グローバルIPで接続できないサーバーに対してもプロビジョニングが可能

Server1(itamae実行サーバー): 192.168.56.101
Server2(踏み台サーバー): 192.168.56.108 | 10.0.0.11
Server3(プロビジョニング先サーバー): 10.0.0.12

![img2.jpg](https://qiita-image-store.s3.amazonaws.com/0/137052/09554a9c-dfe5-6e1c-36dd-ef44a7e9e883.jpeg)



#### Server2でポートフォワーディング

```shell-session
# 踏み台サーバーでポートフォワーディング実行
ssh -i xxxx -L 192.168.56.108:20022:10.0.0.12:22 xxx@10.0.0.12
```

#### Server1でitamaeの実行

```shell-session
# itamae実行
itamae ssh -i xxxx -u xxx -h 192.168.56.108 -p 20022 recipe.rb
```

## レシピの記載ポリシーについて

1つのサーバーのプロビジョニングをすべてまとめて1つのレシピを作成し実行していくやり方もあるが、そうするとレシピがそのサーバー用にカスタマイズされ過ぎて再利用性が乏しいレシピになってしまう。
![all1.jpg](https://qiita-image-store.s3.amazonaws.com/0/137052/e55d9fad-8270-b344-24ce-be0cd377ab96.jpeg)


再利用性を重視し、サービス単位でのレシピを作成し、手動のitamaeコマンドで実行していくやり方では、Infrastructure as Code が台無しになってしまう。
![manu1.jpg](https://qiita-image-store.s3.amazonaws.com/0/137052/cdcb8dd0-eca5-aa23-40c3-497874b5b36e.jpeg)


関連サービス単位でのレシピを作成し、itamaeコマンドの実行に関してはサーバー単位でまとめた実行シェルスクリプトを作成し実行するのが、Infrastructure as Codeという観点や、レシピの再利用にも良いと思う。
![shell1.jpg](https://qiita-image-store.s3.amazonaws.com/0/137052/a47b165f-81df-a468-b218-71dd039fc1b1.jpeg)
数値Double型の誤差が発生する原因について ~ 2進数の小数って面倒いねって話 ~

# 背景

先日、同僚からdoubleをBigDecimalに変換するとき適当にやると誤差がでますよね
と言われ ???? となってしまいました😇

恐れながら、BigDecimal ついてちゃんと理解しておらず、何も考えずにdoubleをBigDecimalに変換し、数値の誤差をだして、計算がずれるというのを今後やらかしそうだったので、
なぜ、doubleをBigDecimalに変換すると誤差が発生するのかについて調べたり確認したことをまとめておこうと思います😅

[Oracle BigDecimal 公式リファレンス](https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html)

# どのような状況で誤差が発生するのか

小数が含まれる時に発生する可能性があります。

```java:誤差が発生しない例
double tmp = 0.5;
System.out.println( new BigDecimal(tmp) ); 
// 出力結果 0.5
```

```java:誤差が発生する例
double tmp = 0.3;
System.out.println( new BigDecimal(tmp) ); 
// 出力結果 0.299999999999999988897769753748434595763683319091796875
```

「0.5」、「0.3」と同じような値でもこのように誤差がでたりでなかったりします。

# なぜ、誤差が発生するのか

原因としては、
[Double 公式リファレンス](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Double.html)
で記載があるように、Double型は、IEEE754 に準拠しているためです。

どういうことかと言いますと、プログラムとして、doubleを記述する際には10進数で表現していますが、ソフトウェア内部での数値は2進数で扱われます。
つまり、10進数で表記したものが、内部では2進数に変換し保持され、コンソールなどに出力される際に、２進数から10進数に変換されるということになります。
10進数 -> 2進数 -> 10進数
といった流れとはなり、誤差が発生します。


## 具体的に先ほどの誤差が発生した時と発生しなかった時の例で見てみると

__誤差が発生しない例__
10進数「0.5」　を ２進数に変換すると、「0.1」となります。
2進数「0.1」を 10進数に変換すると、「0.5」となり、完全に元の値に復元が行えました。

__誤差が発生する例__
10進数「0.3」　を ２進数に変換すると、「0.010011001100...」となり、
2進数「0.010011001100」を 10進数に変換すると、「0.2998046875」となります。


___0x0.1は、有限小数に対して、0b0.010011001100は、循環節が「1100」の循環小数となります。___

___double型の桁数は有限であるため、無限小数は必ず丸め込みが発生し、誤差が出てします。___

# では、誤差がでないようにするにはどうするのか

[___BigDecimal___](https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html) を使用しましょう!!!
BigDecimalは、内部的に 

```math
unscaledValue×10^{-scale}
```
というように小数を整数として保持するため、誤差が発生しないようにしています。
整数は、小数と異なり、どんな10進数の値でも、綺麗に2進数で表現することができます。
10進数 -> 2進数 -> 10進数
と変換を続けても誤差は発生しません。

__例とし、10進数「0.3」　を保持する場合について考えてみる__

0.3 は、

```math
3 × 10^{-1}
```

と表現でき、整数部「３」は、
2進数「0011」となります。 
2進数「00111」を10進数に変換しても「３」と綺麗に元の値に復元が行えます。

このように、小数を整数として扱うようにすることで、BigDecimalは、小数でも誤差がでないようにしています。


我々は普段10進数を使用し物事を考え表現していますが、ソフトウェアは2進数で動くということを改めて考えさせらますね。。。

## BigDecimalを使用する際の注意

小数を引数としたBigDecimalのコンストラクタを利用する際には、注意が必要となります。
上で書いた例のように

```java:誤差が発生する例
double tmp = 0.3;
System.out.println( new BigDecimal(tmp) ); 
// 出力結果 0.299999999999999988897769753748434595763683319091796875
```

になることがあるため、小数をBidDecimalに変換する場合は、引数を「数値型」ではなく、「文字列」で初期化をするようにします。

```java:文字列をBidDecimalに
System.out.println( new BigDecimal( "0.3" ) ); 
// 出力結果 0.3
```

のように、誤差が発生しなくなります。
BigDecimal.valueOf()　などは、引数が数値型でも内部で、文字列に変換しキャストすることで、誤差が発生しないようにしているようです。

BigDecimalを使用しても誤差が出る場合はありますので、用法用量を守り正しくお使いください。


# おわりに

金額計算を行うなら、BigDecimalを使用すると、Javaを勉強し始めで教えられるかと思います。
ただ、なぜ、BigDecimalを使用しなければいけないのかという理由まで理解していなければ、冒頭で書いたように、

>先日、同僚からdoubleをBigDecimalに変換するとき適当にやると誤差がでますよね
と言われ ???? となってしまいました😇

となってしまします。
無知ってのは怖いですね(笑)

言語の仕様について、普段はブラックボックスとして見ない部分も、本当に理解をするためにはやはり、奥深くまで潜らなければ理解することはできないってことを改めて実感させられました💦
houndを自前で運用するときに課金を促されないようにする方法

アカツキではコード品質を高めるためにhoundciを運用しています。(独自に改良も加えています。その時の記事は[こちら](http://hackerslab.aktsk.jp/technology/%25e4%25ba%25ba%25e3%2581%258c%25e3%2582%25b3%25e3%2583%25bc%25e3%2583%2589%25e3%2583%25ac%25e3%2583%2593%25e3%2583%25a5%25e3%2583%25bc%25e3%2581%2599%25e3%2582%258b%25e6%2599%2582%25e4%25bb)です)3年前の古いバージョンから新しいバージョンへと切り替えようと、githubにある[リポジトリ](https://github.com/houndci/hound)をそのままデプロイしてみたのですが、

<img width="990" alt="スクリーンショット 2017-04-01 0.37.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/23392/818329ae-2933-ada9-cfb6-ac62f33be786.png">

自前のサーバーで運用しているのに課金を促されるようになりましたorz課金処理を通らないとリポジトリが登録できないようになっていますので、この処理を外すことにします。

課金されているかどうかのチェックは[subscriptions_controller.rb](https://github.com/houndci/hound/blob/master/app/controllers/subscriptions_controller.rb#L7-L17)の

```ruby
  def create
    if Tier.new(current_user).full? # リポジトリがTierの上限に達したら課金ページへ飛ぶ
      render json: {}, status: :payment_required
    elsif activator.activate && create_subscription # リポジトリをactivateしたらsubscriptionを追加する
      render json: repo, status: :created
    else
      activator.deactivate

      head 502
    end
  end
```

この辺でやってます。これを

```ruby
  def create
    if activator.activate
      render json: repo, status: :created
    else
      activator.deactivate

      head 502
    end
  end
```

こう書き換えますと課金処理をスキップしてリポジトリの登録が行なえます。
tableタグのcolspan、rowspan属性が '%' で指定できたけど、実際はそんなうまい話はなかった件

# 事の発端
いくらCSS3のflex-boxレイアウトが一般的になったとはいえ、いまだに現役バリバリあちこちで使われているtableレイアウト。
そんな中、つぎのようなやるせなさを感じたことはありませんか？

> tableタグの `colspan` で行ぶち抜きのレイアウトをしたいんだけど、列が何個あるのか数えるのめんどくさいし、列が増減するたびに `colspan` の値も増やすのは正直しんどいわ`

# 理解しやすい具体例
なんでもいいですが、検索すると条件に一致した結果の一覧が表示されるようなWebサービスを運用しているとします。

<table>
  <th>No</th><th>product  id</th><th>product name</th><th>made in</th></tr>
  <tr><td>1</td><td>A0001</td><td>Peppar</td><td>Japan</td></tr>
  <tr><td>2</td><td>A0002</td><td>Watson</td><td>U.S.</td></tr>
  <tr><td>3</td><td>A0003</td><td>先行者</td><td>China</td></tr>
</table>

検索結果が0件だった場合、それらしいメッセージを表示したいですよね
こんなかんじで

<table>
  <th>No</th><th>product  id</th><th>product  name</th><th>made in</th></tr>
  <tr><td colspan='4'>該当するデータはありませんでした</td></tr>
</table>

マークアップはこうなるのが一般的でしょうね

```html
  <tr><td colspan='4'>該当するデータはありませんでした</td></tr>
```

でもこれ・・・
カラムが増えたら `colspan` の指定も変えなきゃダメじゃん・・・
tableの特性上、実際のカラム数より大きい数を指定しとけばちゃんと動くのはわかるけど、 `colspan='100'` とか何かキモいし・・・

# そんなときには

```html
  <tr><td colspan='100%'>該当するデータはありませんでした</td></tr>
```

これでいい

<table>
  <th>No</th><th>product  id</th><th>product  name</th><th>made in</th></tr>
  <tr><td colspan='100%'>該当するデータはありませんでした</td></tr>
</table>

# 結果、ベテランたちにフルボッコにされました
実際は `%` が無視されて、 `colspan='100'` として解釈されているみたいです・・・
浅はかな自分に絶望し、再び歩き出そうと思います
コメントくれた先輩方、ありがとうございました！
netmikoでネットワーク機器の種類を自動検出してコマンドを実行する

# netmiko とは
[netmiko](https://github.com/ktbyers/netmiko) とは、ネットワーク機器にSSHでログインして操作するのを助けてくれるPythonのライブラリです。現在Cisco IOS、Juniper JunOS、Palo Alto PAN-OSなどに対応しています。ログイン、コンフィグモード移行、ログアウトなどがメソッドとして抽象化されていて、個別のコマンドは直接コマンドを指定するタイプのライブラリです。この点ではNAPALMより抽象度は低いです。 `pip intall netmiko` 等でインストール可能です。

- GitHubリポジトリ
    - 
[ktbyers/netmiko: Multi-vendor library to simplify Paramiko SSH connections to network devices](https://github.com/ktbyers/netmiko)

# 自動検出機能
netmikoでは通常、コネクションオブジェクトを生成する際に、 `device_type` というパラメータを設定する必要があり、Cisco IOSであれば、"cisco_ios" のように指定していました。


```py:device_typeを明示的に指定する場合
remote_device = {'device_type': 'cisco_ios',
                 'host': '192.168.0.254',
                 'username': 'user',
                 'password': 'passwordpassword'}
```

最近リリースされた version 1.3.0 では「 SSH autodetect」という`device_type`を自動検出する機能が追加されました。

 - [Netmiko 1.3.0 Release](https://github.com/ktbyers/netmiko/releases/tag/v1.3.0)

[auto_detect.py](https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_autodetect.py) を読む限り、自動検出できる機種は本来netmikoがサポートしている機種よりも限られているようですが、今回はひとまずCisco IOSを検出できるか確かめてみました。
（ほとんど上記ソース内のコメントにある例そのままです）

# コード例
```py:自動検出
from netmiko.ssh_autodetect import SSHDetect
from netmiko.ssh_dispatcher import ConnectHandler

# パラメータの設定 device_typeはここでは autodetect にしておく
remote_device = {'device_type': 'autodetect',
                 'host': '192.168.0.254',
                 'username': 'user',
                 'password': 'passwordpassword'}

# 自動検出
guesser = SSHDetect(**remote_device)
best_match = guesser.autodetect()

# 検出結果のデバッグ出力
print("device_type: " + best_match)

# 自動検出した device_type を再設定する
remote_device['device_type'] = best_match
connection = ConnectHandler(**remote_device)

# コマンド実行結果の出力
print(connection.send_command('show version'))

# 切断
connection.disconnect()
```

# 出力例
```text:出力例

device_type: cisco_ios   ←検出したdevice_type

Cisco IOS Software, C181X Software (C181X-ADVENTERPRISEK9-M), Version 15.1(4)M4, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2012 by Cisco Systems, Inc.
Compiled Tue 20-Mar-12 23:34 by prod_rel_team

　　~略~

-------------------------------------------------
Device#	  PID			SN
-------------------------------------------------
*0  	  CISCO1812-J/K9        ***********     
Configuration register is 0x2102

```
自動検出がうまくいき、無事に show version の結果も表示されました。

# 参考
 - netmiko の一般的なチュートリアル
    - https://pynet.twb-tech.com/blog/automation/netmiko.html
Androidでタッチイベントを取得する

Androidに対しての画面入力時のイベントを取得する方法についてまとめます。

以下の3通りに分けてまとめていきたいと思います。

* 同一アプリ内から取得する方法
* 別アプリから取得する方法
* Systemから取得する方法

## アプリ内から取得する方法
Android Frameworkの場合、例えば以下のような順番でTouchEventが処理されていきます。

1. Activity.dispatchTouchEvent()
2. ViewGroup.dispatchTouchEvent()
3. View.dispatchTouchEvent()
4. View.onTouchEvent()
5. ViewGroup.onTouchEvent()
6. Activity.onTouchEvent()

いずれかの処理でタッチイベントが消費された時（return true）、それ以降のタッチイベントは処理されない仕組みになっています。
よって、対象をActivityとした場合、そのActivityのdispatchTouchEvent()をOverrideし、falseを返せば、タッチ処理時に処理を挟むことができます。

## 別アプリから取得する方法
### Overlay Dummy Window
透明なFull ScreenのDummy Windowをスクリーン一番手前に生成してTouchEventを拾う方法です。
TouchEventが下のレイヤーのアプリに伝わらないので使えませんでした。

### Zero Size Dummy Window
サイズ0のWindowを一番手前に作成します。
その際にFLAG_WATCH_OUTSIDE_TOUCHというフラグを与えると、Window外のTouchEventを消費することなく拾うことができます。
ただし、注意点が2つあります。

* Dummy Windowと検証用の画面は同一のセキュリティポリシーであること  
（詳細は[Android Security Policy](Android-Security-Policy)をご覧くださいをご覧ください。）
* FLAG_WATCH_OUTSIDE_TOUCHフラグはタッチ開始時のEventしか拾うことができない  
（スワイプや離す時のイベントは拾えない）

```
> https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_WATCH_OUTSIDE_TOUCH

FLAG_WATCH_OUTSIDE_TOUCH
 
Window flag: if you have set FLAG_NOT_TOUCH_MODAL, you can set this flag to receive a single special MotionEvent with the action
MotionEvent.ACTION_OUTSIDE for touches that occur outside of your window.
```


## Systemから直接取得する方法
### Linux Input Subsystem
Linux Kernelは入力デバイスのInput APIをInput Subsystemで提供しています。
AndroidはこのInput Subsystemを使って入力デバイスを制御しています。
Input SubsystemはLinuxデバイスファイルから制御することができ、デバイス毎に /dev/input/XXX に存在します。

利用する際はlinux/input.hのプロトコルに従って制御することができます。
アクセスするためには、ADBのユーザ権限が必要です。

Reference: https://source.android.com/devices/input/overview.html

### geteventコマンド
Android内のコマンドとして、geteventコマンドが存在します。
このコマンドは上記のLinux Input Subsystemを利用して実装されています。

Reference: https://source.android.com/devices/input/getevent.html


## Android Security Policy
AndroidアプリケーションはSandboxによってアプリケーションを分離しています。
AndroidのSandboxはLinux user-base Protectionによって動作しており、Linux Kernelが提供している以下の機能を利用しています。

* ユーザベースの権限モデル
* プロセス分離
* IPC
* SELinux

よって、Aユーザ - Bユーザ（アプリA - アプリB）間では、
ファイル、メモリ、CPUリソース、デバイス情報等には一切アクセスすることはできません。

通常、アプリケーションがインストールされる段階で一意のユーザIDが割り当てられます。
割り当てられるユーザIDはManifestファイル内のandroid:sharedUserId属性で指定することも可能です。
同じユーザIDで起動した複数アプリケーションは同じセキュリティポリシーとなるので、アプリケーション間のリソースに自由にアクセスすることができます。

## 最後に
今後のAndroidのバージョン、セキュリティポリシーによってこれらの方法が使えなくなる可能性がありますのでご留意ください。
react-modalのzIndex設定により透過効果を実現

# React Modalで作ったポップアップ画面の透過効果
　Modalを表示する場合、デフォルトは元画面が暗くなり、透過的な効果で薄く見えるようになる。Modal画面を閉じると、元の状態に回復する。
　ヘッダ、コンテンツ部のサブヘッダなどが存在するなど複雑の画面構成の場合、Modalを表示しても、ヘッダ部が暗くならないケースがある。
　その理由はz-indexの値がヘッダのz-indexより小さいからです。Modalのインラインスタイルでoverlay部にzIndexを大きい値を設定すれば解決になる。

```
<Modal
  isOpen={true}
  contentLabel="hello react model"
  shouldCloseOnOverlayClick={false}
  style={{
    overlay: {
      zIndex: 100
    },
    content: {
      border: 'none'
    }
  }}
>
  <p>Hello, React Modal</p>
</Modal>
```

# ModalのDOM構成
Modalコンポーネントで生成されたDOMが次のような構成である。

- modelルートdiv
 - overlayのdiv
       - contentのdiv
SQLのORDER BY で任意のソート順を設定する

※追記
変換ツールを作りました。
https://yuyabu.github.io/OrderByWithCaseExpressionGenerator/



SQLのORDER BYでは昇順・降順で特定のカラム(単独or 組み合わせ)の並びを指定できるが、CASE式を組み合わせて、任意のソート順を指定出来ることを最近知った。
(SQL内だけでこういうことが実現できるのが衝撃的)


```SQL:前提となる一次テーブル
WITH students as(
SELECT 1 AS sid, '高橋太郎'   AS sname FROM DUAL 
UNION ALL
SELECT 2 AS sid, '山田幸助'   AS sname FROM DUAL
UNION ALL
SELECT 3 AS sid, '鈴木美恵子' AS sname FROM DUAL
UNION ALL
SELECT 4 AS sid, '織田信長'   AS sname FROM DUAL
)
SELECT * FROM students ORDER BY sid
```

| SID | SNAME | 
|-----|-------| 
| 1   | 高橋太郎  | 
| 2   | 山田幸助  | 
| 3   | 鈴木美恵子 | 
| 4   | 織田信長  | 




例えば上記のようなテーブルの場合
sidが

 - 1→2→3→4
 - 4→3→2→1

の並びで並び替えることはorder by にascまたはdescを指定することで
実現できるのは常識だが、CASE式をORDER BYの中で使うことで

 - 4→2→3→1

のような順番でソートすることができる。


```SQL:CASE式で任意のソート順を指定する
SELECT * FROM students 
ORDER BY
  CASE sid WHEN  4  THEN 1 ELSE 2 END,
  CASE sid WHEN  2  THEN 1 ELSE 2 END,
  CASE sid WHEN  3  THEN 1 ELSE 2 END,
  CASE sid WHEN  1  THEN 1 ELSE 2 END,
sid
```

```:結果
SID     SNAME
4       織田信長
2       山田幸助
3       鈴木美恵子
1       高橋太郎
```



# 用途
 - オリジナルのソート順を作る(S → M → L等)
 - 特定の要素を先頭に表示する(国コードの列挙で日本を先頭に表示等)
 - 過去のエビデンスなどの資料に記載されている、特に規則のない順序に合わせたソートを実現する


# 補足
 - パフォーマンスがあまり良くないのでアプリケーションで使うSQLに採用するときは注意してください。
 - アプリで使う場合はソート順を定義した別テーブルを作成し、結合後にソート順を定義した列でソートしてください


参考：https://www.greenwich.co.jp/blog-archives/p/937
特定のセルデータの内容によって処理を分岐する方法

![内容による条件分岐.png](https://qiita-image-store.s3.amazonaws.com/0/160563/c6ce9239-2ffd-bda8-1194-5f2bae92c057.png)


#利用シチュエーション

* 特定のセルに情報が記載されているかされていないかで処理を変更したい場合


#記述方法
##特定の文字列があるか確認
`=IF(COUNTIF(A2,"*/*"),"色表記あり","色表記なし")`

> **前提条件**
> A列に果物情報
> ![Excel.png](https://qiita-image-store.s3.amazonaws.com/0/160563/8149f69c-63d3-e8a5-8b88-29f62e6bf035.png)

---

> **抽出結果**
> ![Excel_2.png](https://qiita-image-store.s3.amazonaws.com/0/160563/e206d57b-5402-b455-5bb6-723d797b6ab7.png)


---

> **解説**

> * COUNTIF関数で指定した条件があるかないかを確認
> * IF関数で条件に一致していれば「色表記あり」、一致しなければ「色表記なし」

> ####個々の関数の説明####
> COUNTIF関数は指定された条件に一致した要素の個数を返す

> |         | 書き方                            | 利用例             |
> |:--------|:---------------------------------|:------------------|
> | 書式    | COUNTIF(範囲, 検索条件)             | COUNTIF(A2,"*/*") |
> | 引数1   | カウントする範囲(数値)を指定          | A2                |
> | 引数2   | カウントする条件を指定               | */*               |

> IF関数は論理式が真であれば真の値を返し、偽であれば偽の値を返す

> |         | 書き方                            | 利用例                    |
> |:--------|:---------------------------------|:-------------------------|
> | 書式    | IF（論理式, 真の場合, 偽の場合）      | IF(A1=A2,"色あり","色なし") |
> | 引数1   | 論理式が真の場合に返す値              | "色あり"                 |
> | 引数2   | 論理式が負の場合に返す値     　　　　　　| "色なし"                |

#サンプル
[Google スプレッドシート](https://goo.gl/OsQDPw)
【webpack】source mapに指定されるdomainやpathを変更する

webpackのトランスパイル等でjsを生成するときsource mapを出力することができますが、
source mapで指定されるdomainやpathを変更する方法を知ったので記事書きます。

設定方法はドキュメントがありました。
https://github.com/webpack/docs/wiki/configuration#outputdevtoolmodulefilenametemplate


# やりたいこと
`webpack://`となってしまうのを変更したい。
### 例えばこうなるのを
![image](https://qiita-image-store.s3.amazonaws.com/0/84259/b343acef-2687-4ead-4edc-fb25085c0cd1.png)

### こんな感じにしたい
![image](https://qiita-image-store.s3.amazonaws.com/0/84259/e0928fb2-9a62-435f-4668-d424ff16086d.png)

# 設定方法

`webpack.config.js`で`output.devtoolModuleFilenameTemplate`を設定します。
今回は以下のように設定しました。

```js
	output: {
		//・・・
		devtoolModuleFilenameTemplate: 'src/[resource-path]',
	},
```

自由に変更したい場合は、以下のページを参考に `src` と書いたあたりを自由に変更するといいです。

参考：
https://github.com/webpack/docs/wiki/configuration#outputdevtoolmodulefilenametemplate

# sourceMap抜粋

```json:設定なし
{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap aa8079d35e035494576e","webpack:///./sub.js","webpack:///./main.js"],・・・
```

```json:設定後
{"version":3,"sources":["src/webpack/universalModuleDefinition","src/webpack/bootstrap c0cbd02b78933164b9eb","src/./sub.js","src/./main.js"],・・・
```

# サンプルプロジェクト

は、こちら
https://github.com/ota-meshi/webpack-devtool-module-filename-template-sample

# 何がうれしいの？

別に`webpack://`でいいじゃん。何が困るの？って感じですが、
私は`remap-istanbul`がうまくreportが出なくて、この方法を探しました。
`remap-istanbul`が何なのか？この方法がどう使えるのかはまた別で記事書きます。
WN-G300UA(IO DATA)をubuntu 16.04に挿したらハングした話

可動式アンテナ付きのUSB Wifi子機が欲しかったので、適当にググッてUbuntu 16.04で実績のある[WN-G300UA(IO DATA)](https://www.amazon.co.jp/Wi-Fi-%E7%84%A1%E7%B7%9ALAN-300Mbps-%E3%82%A2%E3%83%B3%E3%83%86%E3%83%8A%E5%9E%8B-WN-G300UA/dp/B009GQNMQ8
)を購入した。

標準ドライバで対応してるチップ(Realtek RTL8192CU)だから、挿すだけで認識するということで早速挿入！
すぐにアクセスポイントを検出！さすが！
SSIDを選択してパスワードを入力すると…
なんとハングした。

認識しないぐらいは覚悟してたけど、まさかハングするとは。

改めてぐぐったところ、このチップ（Realtek RTL8192CU）、linuxと相性がよくないらしい（購入前に見た実績はなんだったんだorz）。
下記サイトで紹介されている手順で修正済みドライバを入れることで回避。

[Infamous RTL8192cu](https://adamscheller.com/systems-administration/rtl8192cu-fix-wifi/)
Smart Custom Fields のチェックボックスのキーに数値が設定できない

# Smart Custom Fields のチェックボックスのキーに数値が設定できない


![image](https://qiita-image-store.s3.amazonaws.com/0/177083/a8fa2130-e5a4-a5b4-9ced-c5476f09b772.png)

キーに数値を指定した場合は無視されてしまい、このカスタムフィールドを表示したページでは以下のように表示される。

\<label>\<input type="checkbox" name="smart-custom-fields[item_type][0][]" value="aaa"/> aaa\</label>
Cuda 付きで OpenCV をインストール（OSX 10.11）

こんにちは。
OSX 10.11 で Cuda 付きで OpenCV (3.2) をインストールしました。必要な [Xcode721](https://developer.apple.com/download/more/) [^1]はダウンロードして入手しました。

[^1]: "[System Requirements](http://docs.nvidia.com/cuda/cuda-installation-guide-mac-os-x/index.html#system-requirements)" （NVIDIA CUDA Installation Guide for Mac OS X）の説明を参考

```console
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.11.6
BuildVersion:	15G1421
$ sudo xcode-select --switch /Applications/Xcode721.app/Contents/Developer/
$ xcodebuild -version
Xcode 7.2.1
Build version 7C1002
$ xcode-select -print-path
/Applications/Xcode721.app/Contents/Developer
$ export SDKROOT=/Applications/Xcode721.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
$ brew install python python3
$ python --version
Python 2.7.13
$ python3 --version
Python 3.6.1
$ brew tap caskroom/cask homebrew/science
$ brew cask install cuda 
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:46_CST_2017
Cuda compilation tools, release 8.0, V8.0.61
$ brew install opencv3 --with-cuda --with-python3
$ python -c "import cv2; print cv2.__version__"
3.2.0
```
PHP7インストール



```bash
yum install libxml2-devel


cd /usr/local/src
wget --content-disposition "http://jp2.php.net/get/php-7.1.4.tar.gz/from/this/mirror"
tar zxvf php-7.1.4.tar.gz 
cd php-7.1.4/
./configure --prefix=/opt/php7 --with-apxs2=/opt/apache/2.4.25/bin/apxs 
make
make install 

cp -i php.ini-development /opt/php7/lib/php.ini
```
Python でハートを描く

# 概要

[Pythonからはじめる数学入門](https://www.amazon.co.jp/Python%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%95%B0%E5%AD%A6%E5%85%A5%E9%96%80-Amit-Saha/dp/4873117682) という書籍を買いました。せっかくなので「2 章 データをグラフで可視化する」を参考にしながら、何かグラフを描画してみようと思い立ちました。かわいい図形がよかったので :heart: を描画してみることにしました。

まず前準備として [matplotlib](https://matplotlib.org/) の設定ファイルを作成します。macOS の環境でグラフを表示するために `backend`、そしてグラフのタイトルに日本語を使うために `font.family` の指定が必要でした。

```~/.matplotlib/matplotlibrc
backend : TkAgg
font.family : Ricty Diminished
```

では本題の :heart: の描画に移ります。[Heart Curve](http://mathworld.wolfram.com/HeartCurve.html) というページに載っている数式を利用しました。

$x = 16sin^3(t)$
$y = 13cos(t)-5cos(2t)-2cos(3t)-cos(4t)$

```draw_heart.py
from matplotlib import pyplot as plt
from math import pi, sin, cos


def draw_graph(x, y, title, color):
  plt.title(title)
  plt.plot(x, y, color=color)
  plt.show()


# range() 関数の浮動小数点数バージョン
# (参考) Pythonからはじめる数学入門 2.4.2.1 等間隔浮動小数点数の生成
def frange(start, final, increment=0.01):
  numbers = []

  while start < final:
    numbers.append(start)
    start = start + increment

  return numbers


def draw_heart():
  intervals = frange(0, 2 * pi)
  x = []
  y = []

  for t in intervals:
    x.append(16 * sin(t) ** 3)
    y.append(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

  draw_graph(x, y, title='ハート', color='#FF6597')


if __name__ == '__main__':
  try:
    draw_heart()
  except KeyboardInterrupt:
    # control + C で終了する。
    pass
```

この Python スクリプトを実行すると、美しい :heart: のグラフが描画されます。かわいい :relaxed:

![figure_1.png](https://qiita-image-store.s3.amazonaws.com/0/6697/8fc0b39c-1b90-1f3f-0d86-efb82c56fc86.png)

# おまけ

前述のスクリプトで実装した frange 関数は NumPy の [arange](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html) 関数に置き換えることができました。NumPy には `pi` や `sin`, `cos` などの関数も備わっているので、このモジュールを使う場合は `math` モジュールも不要ですね。

```draw_heart.py
from matplotlib import pyplot as plt
from numpy import arange, pi, sin, cos


def draw_graph(x, y, title, color):
  plt.title(title)
  plt.plot(x, y, color=color)
  plt.show()


def draw_heart():
  intervals = arange(0, 2 * pi, 0.01)
  x = []
  y = []

  for t in intervals:
    x.append(16 * sin(t) ** 3)
    y.append(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

  draw_graph(x, y, title='ハート', color='#FF6597')


if __name__ == '__main__':
  try:
    draw_heart()
  except KeyboardInterrupt:
    pass
```
railsアプリ fetchを使ったajax通信のエラーハンドリングで気をつけること

RailsとReact.jsを使ってアプリ開発時に、fetchを使ったajax通信のエラーハンドリングで気づきがあったのでメモします。

---

railsアプリにおいて、以下のように```request.xhr?```で条件分岐をし、ajax通信時とそれ以外という形でエラーハンドリングをすることは良くあるかと思います。

```application_controller.rb
 rescue_from ActionController::RoutingError,   with: :_render_404
 
 private

 def _render_404(e = nil)
   logger.info "Rendering 404 with exception: #{e.message}" if e
   if request.xhr?
     render json: { error: '404 error' }, status: :not_found, layout: false
   else
    render template: 'errors/error_404', status: 404, layout: 'application'
  end
```

Railsの```xhr?```メソッドは
```request.xhr? #=> 0 or nil```
```@env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" ```の結果を返しています。
しかし、fetchを使った場合のrequest.headerには```'X-Requested-With': 'XMLHttpRequest'```が含まれないのでそれがajax通信なのかどうかは判断出来ないようです。

なので、fetchを使用する時は、headerに以下を追加してあげることで、jQueryの$.ajaxなどと同じようにRailsのxhr?でajax通信かどうかを判断出来るようになります。

```
headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken,
      'X-Requested-With': 'XMLHttpRequest',
    },
```

---

### 参考
[Fetch API - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API)
[github/fetch#17](https://github.com/github/fetch/issues/17)
[http://stackoverflow.com/questions/33662318/how-do-i-detect-requests-initiated-by-the-new-fetch-standard-how-should-i-detec](http://stackoverflow.com/questions/33662318/how-do-i-detect-requests-initiated-by-the-new-fetch-standard-how-should-i-detec)
Rantly(property based testing tool)でテストデータ生成 - float

Rantly#float でランダムに浮動小数点数のデータを作ります

## <i class='fa fa-question-circle'></i> 関連記事
[tbpgr の rantly 関連記事](http://qiita.com/search?utf8=%E2%9C%93&q=user%3Atbpgr%20tag%3Arantly)

## <i class='fa fa-flask'></i> サンプル

```ruby
Rantly(3){float}
# => [0.8244445374569535, 0.6365100379174634, 0.3248653262563964]
Rantly(3){float}
# => [0.06616341355233324, 0.502312989860315, 0.7295971014341072]
```

## <i class='fa fa-code'></i> 実装
Rantly#float の実装をみたら `rand` だけだった

[Rantly#float の実装](https://github.com/rantly-rb/rantly/blob/5d5c766251acebe1f5305473532359b35a32701c/lib/rantly/generator.rb#L144-L146)

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [abargnesi/rantly](https://github.com/abargnesi/rantly)
AndroidIntentにリファラ情報を入れる

Androidのディープリンクで、「アプリをインストール済みの場合はそのアプリを起動、未インストールの場合はPlayStoreページを表示」というような動作をさせたい。

以前はiframeのsrc属性にアプリ独自のカスタムスキーマをセットして、そのスキーマに反応しなかった場合はjavascriptでPlayStoreへ飛ばし、反応した場合はそのままアプリを立ち上げるという方法をとって上記のディープリンク的な動作を実現していた。が、2017年現在、iframeのsrc属性にカスタムスキーマをセットしてもアプリは立ち上がることはないので、この方法は使うことができない。

そのため現在はAndroidIntentを使うことがGoogleから推薦されている。

https://developer.chrome.com/multidevice/android/intents

```html
<a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end"> Take a QR code </a>
```

intentで始まるのがこのAndroidIntent。intentスキーマをもったリンクをhrefにセットすれば利用できる。上のhtmlの場合、以下のアプリが入ってたらそのアプリを起動し、入っていなかったら以下のページをPlayStoreアプリで開くことになる。

https://play.google.com/store/apps/details?id=com.google.zxing.client.android

## intentの記法

```
intent:
   HOST/URI-path // Optional host 
   #Intent; 
      package=[string]; 
      action=[string]; 
      category=[string]; 
      component=[string]; 
      scheme=[string]; 
   end; 
```

intentから始まるやつの記法はこの通り。Host(上のzxingの例で言うと「scan」の部分)とその後に続くパスはオプション。#Intent;以降はpackageでアプリのパッケージ名を、actionやcategory,schemeなどはAndroidManifest.xml内のIntentFilterの該当部分のものを書けば望んだ動作が得られることになる。

## Referrerを取得するには

```html
<a href="https://play.google.com/store/apps/details?id=com.google.zxing.client.android&referrer=param1">QR code app</a>
```

AndroidはPlayStoreにアクセスした時のリファラをとれる。と言ってもリファラは上のリンクのようにURLパラメータで指定したものだけど。これを複数サイトの「アプリをインストール！」みたいなボタンにそれぞれセットしておけば、どのサイトからインストールしたのかという情報がわかるようになる。このリファラの値はBroadcastReceiverから取得することができる。

で、問題はこのリファラの値をAndroidIntentでどう指定するか。ドキュメントページには何も書いていないが、以下の方法で指定することが出来る。

```
intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;S.market_referrer=param1;end
```

`S.market_referrer`にリファラの値を入れればOK。

https://bugs.chromium.org/p/chromium/issues/detail?id=459711
ラングレーの問題をだいたいsympyを使って解く

(参考)ラングレーの問題
https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%BC%E3%81%AE%E5%95%8F%E9%A1%8C
(参考)Langley’s Adventitious Angles
https://en.m.wikipedia.org/wiki/Langley’s_Adventitious_Angles


```python
#実行時間は、2分ぐらいかかります
from sympy import *
var('x')
x=100
B=Point(0,0)
A=Point(x*cos(pi/180*80),x*sin(pi/180*80))
C=Point(x*cos(pi/180*80)*2,0)
D2=C.rotate(pi/180*60)
E2=B.rotate(pi/180*(-50), C)
ans1=Line(C,A).intersection(Line(B,D2))
ans2=Line(B,A).intersection(Line(C,E2))
D=Point(ans1[0].x,ans1[0].y)
E=Point(ans2[0].x,ans2[0].y)
print("#角度BDE=",float(mpmath.degrees(Polygon(B,D,E).angles[D])))
#角度BDE= 30.0

#①xに値を入力しないと、以下のエラーがでます
#ValueError: Can't determine orientation
#②mpmath.radians関数を使うと
#角度BDE= 30.000000000000068
```

CADを使ったほうが早いかも。
npm initからのプログラム作成までに必要なコマンド殴り書き

# npm init
パッケージ名にはキャメルケースは使えない。大文字小文字は違いを識別しないっぽい。
テストコマンドにはmochaもしくはgulpを指定しておこう。
# npm i -D gulp gulp-mocha mocha should
テストに必要なライブラリをdevDependenciesとして導入する。
gulpを入れるのはIntellijがタスクランナーとして認識してくれる。テストがやりやすい。Ctrl+F5。
# touch gulpfile.js
一から作成するのは大変なので
https://github.com/gulpjs/gulp/tree/master/docs/recipes
https://github.com/gulpjs/gulp/blob/master/docs/recipes/mocha-test-runner-with-gulp.md
このあたりからコピペ。
# gibo Node JetBrains > .gitignore
.gitignore生成ツール。gibo。
http://qiita.com/tmknom/items/c4bcebe17d25381fa45d
# git init
必要に応じてバージョン管理。
# npm i -S 好きなパッケージ
https://www.npmjs.com/
やりたいことが大概パッケージとして実装されてる。Statsを見て人気度、安定度を自己判断。自己責任で利用。

# ひたすらテスト
コードを書いたらテスト。むしろTDDでテストファーストでやってやろうかっていうぐらいテスト。特に不人気なパッケージを使うときとか、複雑なことをする時は。
テストを書かないと、やりたいことと利用するパッケージの挙動を理解することがごっちゃになって破綻する。
テストを書くと、テストできないコード≒凝集度の高いコードを書かなくて済む。コードが読みやすくなる。
フレームワーククラスの規模のパッケージを使うときはyeomanのgeneratorを探す。
vimのquickfixでPythonのエラーメッセージにジャンプできるようにする

これをvimrcに追加する。
なんか日付文字列とかあるとErrorFormatと五人されることがあるので、autocmdでpythonファイルが実行されたときだけに限定する。

```vim
augroup ErrorFormat
    autocmd BufNewFile,BufRead *.py
        \ set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
augroup END
```
「オフラインリアルタイムどう書くF04の問題」の解答

「オフラインリアルタイムどう書くF04の問題 - 正八角形の分割」の解答
http://nabetani.sakura.ne.jp/hena/ordf04octsp/

今回は会場で実施
全部Successまで40分でした。
その後手直し実施

指摘は以下
1. 最初のテーブルが残念
2. "/2"の結果が浮動小数点か整数かがPythonのバージョンにより異なる(現場では2.7で実行)
 ↓ 2.について試してみた


```
Python 2.7.13 (default, Apr 12 2017, 21:12:30) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.41)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0
>>> 
```

```
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0.5
>>>
```

ちなみに以下ならPythonのバージョンにかかわらず意図通りの動作となる。
floor division もしくは integer division と呼ばれる

```
>>> 1//2
0
```


以下現場での解答

```python:main.py
polygon_table = {}
polygon_table[0] = ''
polygon_table[1] = '3'
polygon_table[2] = '4'
polygon_table[3] = '5'
polygon_table[4] = '5'
polygon_table[5] = '7'
polygon_table[6] = '8'
polygon_table[7] = '9'

def get_startline(data):
    start = 128
    while True:
        if data >= start:
            return start
        else:
            start /= 2

def detect_poly(data):
    start = get_startline(data)
    triangle_count = []
    count = 0

    while start != 0:
        if data >= start:
            data -= start
            triangle_count.append(count)
            count = 0
        else:
            start /= 2
            count += 1

    polys = []
    for t in triangle_count:
        polys.append(polygon_table[t])

    remaining = 8 - sum(triangle_count)
    if remaining > 0:
        polys.append(polygon_table[remaining])

    polys.sort()
    return ''.join(polys)

## test logic
class Result:
    def __init__(self):
        self.success = 0
        self.fail = 0

RESULT = Result()
RESULT.success = RESULT.fail = 0

def test(data, expect):
#    print("actual:" + detect_poly(int(data)) + " expected:" + expect)
    if detect_poly(int(data)) == expect:
        RESULT.success += 1
    else:
        RESULT.fail += 1

## ---- tests ----

test("165", "3445" )
test("80", "48" )
test("255", "33333333" )
test("68", "55" )
test("200", "355" )
test("82", "455" )
test("164", "455" )
test("73", "455" )
test("146", "455" )
test("37", "455" )
test("74", "455" )
test("148", "455" )
test("41", "455" )
test("38", "355" )
test("76", "355" )
test("152", "355" )
test("49", "355" )
test("98", "355" )
test("196", "355" )
test("137", "355" )
test("19", "355" )
test("20", "48" )
test("9", "57" )
test("209", "3345" )
test("121", "33345" )
test("239", "3333334" )
test("26", "347" )
test("111", "333344" )
test("95", "333344" )
test("85", "4444" )
test("24", "39" )
test("97", "347" )
test("234", "33444" )
test("59", "33345" )
test("187", "333344" )
test("34", "55" )
test("249", "333335" )
test("43", "3445" )
test("143", "33335" )
test("28", "338" )
test("79", "33345" )
test("173", "33444" )
test("55", "33345" )
test("77", "3445" )
test("35", "355" )
test("153", "3355" )
test("30", "3337" )
test("228", "3355" )
test("177", "3345" )
test("162", "445" )
test("184", "3345" )

## --------------

print("Success: {0.success}, Fail: {0.fail}".format(RESULT))
```
pyenv + anaconda + python3

python3が使いたい。しかし、Linuxではpython2は様々な場面で利用されておりシステムワイドにpython3を[デフォルトにしてしまう](http://qiita.com/skoyama427/items/b1b23bac0771fb6ef9fd)と不都合が生じる。例えばlinux用のDropboxのクライアントがpython2系で書かれているようで、update-alternativesを使うやり方ではエラーメッセージが頻発する。pyenvをインストールし、その上にanacondaをインストールして利用する([参考](http://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c))。

```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv install -l | grep ana #最新のパッケージを検索
pyenv install anaconda3-4.3.1
pyenv rehash
pyenv global anaconda3-4.3.1
echo 'export PATH="$PYENV_ROOT/versions/anaconda3-4.3.1/bin/:$PATH"' >> ~/.bashrc
source ~/.bashrc
conda update conda
```

これだけでとりあえずrootの環境ができる。さらにパッケージの依存環境などを調整した仮想環境を作ることができる。基本的には仮想環境を作業用に作成して開発を行うほうが良いようだ。

仮想環境を作る、numpy, scipy, pandas, jupyterを同時にインストールする

```
conda create -n py3 python=3.4 numpy scipy pandas jupyter
```

仮想環境に入る

```
source activate py3
```

仮想環境から出る

```
source deactivate
```

パッケージはそれぞれの環境(rootを含め)にインストールされる。基本的にはconda installを使えばよいが、condaのレポジトリにないパッケージもある。このときはpipも使える。

```
conda install numpy scipy
conda uninstall numpy
conda install -n py3 numpy scipy
conda uninstall -n py3 numpy
conda update numpy
conda update -n py3 numpy
pip install numpy
```

例えば、Intel distribution for pythonをインストールするには

```
conda update conda
conda config --add channels intel
conda create -n idp intelpython3_core python=3
source activate idp
activate idp
```
マストドンの画像URL仕様

なにげに地雷体質のえふしんです。
他のインスタンスでは問題ないのに、うちだけリモートフォローしたアカウントのアイコンがうまく表示されてないのに気がついたので調査中メモ（2017/4/21時点の情報です）

これがアイコンのURL
https://s3-ap-northeast-1.amazonaws.com/mstdn-fm-image/accounts/avatars/000/000/194/original/7c6f3433b2115421.png?1492614141

accountsテーブルに入ってる該当ユーザーの情報

```
mastodon=# select id,username,domain,created_at, display_name,avatar_file_name,avatar_content_type,avatar_file_size,avatar_updated_at from accounts where id = 194;
```
 id  | username |  domain   |         created_at         | display_name |   avatar_file_name   | avatar_content_type | avatar_file_size |     avatar_updated_at      
-----+----------+-----------+----------------------------+--------------+----------------------+---------------------+------------------+----------------------------
 194 | ****  | pawoo.net | 2017-04-19 15:02:21.665211 |              | 7c6f3433b2115421.png | image/png           |             2645 | 2017-04-19 15:02:21.793892

まぁ見れば、何が対応してるのか大体予測つきますよね。

https://github.com/tootsuite/mastodon/blob/66b39ccaedd86030e0f1299b52b6daab43560b18/config/initializers/paperclip.rb

```
/:class/:attachment/:id_partition/:style/:filename
```
id_partitionとは、paperclipの仕様で、`12 would be converted to 000000012`という処理をされて３桁ずつ分けたのがパスになるようです。

マストドンはリモートフォローすると、アイコン画像をローカルにダウンロードしてるんですね。avatar_updated_atってのがあるので、おそらく一定周期で最新データを拾ってくれる、、のかな。（ソースコード読みましょうね）

ということでアイコンが表示されないのは、S3へのアイコンのコピーが失敗しているようですね。ファイルサイズは把握してるわけだから、アップロードに失敗しているらしい。何故だ...（続く）


つづき　１：

画像をアップするところは、ここらへんかな？
https://github.com/tootsuite/mastodon/blob/b155e6ccf55bbd0e2b07d6e06349849dd1f06f0a/app/models/account.rb
```
  # Avatar upload
  has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' }
  validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES
  validates_attachment_size :avatar, less_than: 2.megabytes
```

すごいなー。これでPaperclip経由でファイルがアップロードされちゃうんだー。Railsすごいな。

つづき　２：
fetch_remote_account_service.rbを改造して、irb経由で、無理やりアカウント情報を更新してアイコンを更新してました。

で、思ったんだけど、ここ間違ってると思うんですよね。

https://github.com/tootsuite/mastodon/blob/master/app/services/fetch_remote_account_service.rb#L36

```ruby:fetch_remote_account_service.rb
UpdateRemoteProfileService.new.call(xml, account) unless account.nil?
```
ではなくて、

```ruby:fetch_remote_account_service.rb
UpdateRemoteProfileService.new.call(body, account) unless account.nil?
```

じゃないと、うまくいかない。

このパスでリモートフォローしにいったらプロフィールの取得に失敗するんじゃないかなぁ。ちゃんと調べてないから問題があるのかまではわからないのだけど。とりあえずプログラム上は間違っている。

別口で、sidekiq経由でUpdateRemoteProfileServiceが呼び出されるパスがあって、そっちが動けばアイコン画像は更新される。どういうきっかけで動くのかまではよくわからない。
https://github.com/tootsuite/mastodon/blob/master/app/workers/remote_profile_update_worker.rb

ただissueとしては、「画像URLわかってるけどS3へのアップロードが失敗している」だからちょっと違うか。まぁ仮にネットワークやサーバ負荷の問題だったらS3アップロード失敗を検知して、次回の何かで更新させて欲しいですね。もう少ししつこく動いてもいいかな。

アイコンの更新は、accountテーブルにavatar_updated_at があるから時間経過で行うつもりなのかなぁ。
ぱっと検索する限り、該当処理が見つからないのが謎。

この辺に深掘りできる方がいらっしゃいましたらpull requestなど投げていただけるとありがたいです。他人任せですいませんw

p.s. ローカルからS3に画像を移したい場合は、この辺のメソッドを再度実行するようなバッチがあれば、一気に更新出来るような気がしますね。
コマンドラインからSSH経由でSQL文を実行して結果をCSVで得る

教わったとおりにやったらできました。

とにかく結果だけ手元にほしい時なんかに。

# 支度

[こんな感じで](http://qiita.com/nozma/items/87f876a1a842504045f4)準備がしてあるとする。

# コマンドラインからSQLを実行する

`psql -c`でコマンドラインからSQL文を渡して実行結果を得ることができる。sshのパラメータとしてコマンドを渡すとそのコマンドだけ実行して結果だけ得ることができるので、このようなことができる。

```
% ssh pi@192.168.11.11 psql -c '"select * from actor limit 10;" -U pi -d dvdrental'
pi@192.168.11.11's password:
 actor_id | first_name |  last_name   |      last_update
----------+------------+--------------+------------------------
        1 | Penelope   | Guiness      | 2013-05-26 14:47:57.62
        2 | Nick       | Wahlberg     | 2013-05-26 14:47:57.62
        3 | Ed         | Chase        | 2013-05-26 14:47:57.62
        4 | Jennifer   | Davis        | 2013-05-26 14:47:57.62
        5 | Johnny     | Lollobrigida | 2013-05-26 14:47:57.62
        6 | Bette      | Nicholson    | 2013-05-26 14:47:57.62
        7 | Grace      | Mostel       | 2013-05-26 14:47:57.62
        8 | Matthew    | Johansson    | 2013-05-26 14:47:57.62
        9 | Joe        | Swank        | 2013-05-26 14:47:57.62
       10 | Christian  | Gable        | 2013-05-26 14:47:57.62
(10 行)
```

# カンマ区切りで出力

`COPY`を使うと出力をファイルや標準出力に送ってくれるうえ、ついでにCSV出力してくれたりする。

```
% ssh pi@192.168.11.11 psql -c '"copy (select * from actor limit 10) to stdout csv header;" -U pi -d dvdrental'
pi@192.168.11.11's password:
actor_id,first_name,last_name,last_update
1,Penelope,Guiness,2013-05-26 14:47:57.62
2,Nick,Wahlberg,2013-05-26 14:47:57.62
3,Ed,Chase,2013-05-26 14:47:57.62
4,Jennifer,Davis,2013-05-26 14:47:57.62
5,Johnny,Lollobrigida,2013-05-26 14:47:57.62
6,Bette,Nicholson,2013-05-26 14:47:57.62
7,Grace,Mostel,2013-05-26 14:47:57.62
8,Matthew,Johansson,2013-05-26 14:47:57.62
9,Joe,Swank,2013-05-26 14:47:57.62
10,Christian,Gable,2013-05-26 14:47:57.62
```

あとは手元のcsvファイルにリダイレクトするなり煮るなり焼くなり。

# 参考
- [PostgreSQL備忘録 - Qiita](http://qiita.com/nobuyuki-ishii/items/dfd1f0e447f495bf5aac)
- [bash - PostgreSQL export result as CSV from remote server - Stack Overflow](http://stackoverflow.com/questions/28840918/postgresql-export-result-as-csv-from-remote-server)
- [ssh コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/ssh.html)
certutilでNSS DBを操作する方法

#はじめに
certutilとは、nss-toolsパッケージに含まれ、証明書と鍵データベースを管理できるものです。
mozillaが提供しているNSSセキュリティツールのひとつです。

certutilを使って信頼性フラグを立てた自己署名証明書を作る必要があったのでその手順を投稿します。

#実行環境
* OS：CentOS 6.5
* nss-tools：3.16.1

#手順
## DBの作成
まず、NSSの証明書DBと鍵DBが必要です。
httpdのmod_nssをインストールしている場合には、インストール時に自動で作られると思います。

DBがない場合にはcertutilの-Nオプションで作成できます。
作成するディレクトリを指定する場合には-dオプションで作成先を指定します。
　```$ certutil -N -d ＜DBを作成するディレクトリ＞```
DBアクセス時のパスワード不要な時はenterキー連打で大丈夫です。

指定したディレクトリに次の3つのファイルができます。

* cert8.db
* key3.db
* secmod.db

##自己署名証明書の作成
certutilの-Sオプションで作成します。

* -n：ニックネームを指定
* -s：証明書の所有者を特定する情報を指定
* -v：証明書の有効期間を月単位で指定
* -x：自己署名であることを指定
* -t：証明書の信頼性を指定
* -d：作成先

例えば、以下のように入力します。
```$ certutil -S -n SelfSignedCertificate -s "C=XX" -v 12 -x -t "Pu,Pu,Pu" -d ＜DBを作成したディレクトリ＞```

　"Continue typing until the progress meter is full:"
　という文字列が表示されたらキーボードでランダムに文字入力をする。
　（鍵を生成するためのランダムな文字列）

　enterキー押下で下記の文字が表示されたら作成完了
　"Generating key.  This may take a few cemoments..."

##作成した証明書の確認
certutilの-Lオプションで確認できます。
```$ certutil -L -d ＜DBを作成したディレクトリ＞```

##証明書の削除
certutilの-Dオプションで削除できます。
```$ certutil -D -n ＜ニックネーム＞ -d ＜DBを作成したディレクトリ＞```

#参考
下記のサイトが参考になりました。
http://www.nina.jp/server/redhat/certutil/certutil.html
仕事世界で評価されるのは「ファッション同条件同結果意識行動」だと思った

# 同じ条件なら同じ結果が出るという信念が共有されている
斉一性ってやつですね。
仕事という場では、斉一性が共同信念（あるいは共同幻想）として存在している。

# 人に同じ質問を２回するのは無能という風潮はこの共同幻想のためだ
同条件では同結果が出るという考えが当たり前のものとしてあるので、同じ質問をすることは、問題が発生した状況の条件を把握しておらず、その条件からどのような結果が導き出されるのかということも把握できていないから無能と判断される。

# 同条件同結果を重視する割に条件の精緻化ができていない感じがする
PDCAなんてその代表ですね。
斉一性を採用するならそれはそれでいい。
ただそれならもっと結果を引き起こす条件は何なのかということを厳密に測定しろよと思ってしまう。
何か問題が起こりました→はい！PDCA回して解決してね！
そんな簡単に原因の発生条件を特定してそれを証明するために妥当性を測れるわけないだろ！
ファッションPDCAですね。

# 同じ失敗を何度も繰り返すことでたどり着ける結果もあるはずだ！
と思って仕事をしたいですね。
Raspberry Pi上に練習用データベースを作成する

忘れないうちにメモ。

# Raspberry PiにPostgreSQLをインストール

事前にサンプルデータベースをダウンロードしておく。

- [PostgreSQL Sample Database](http://www.postgresqltutorial.com/postgresql-sample-database/)

```
sudo apt-get install postgresql
sudo passwd postgres 
su - postgres 
createuser -P pi
psql 
```

```postgres 
CREATE DATABASE dvdrental;
\q
```

ダウンロードしたサンプルデータベースのzipファイルがあるディレクトリで

```
unzip dvdrental.zip
pg_restore -U pi -d dvdrental ./dvdrental.tar
psql dvdrental
```

```postgres 
\dt
```

テーブル一覧が表示されればOK。

# ログインテスト

Raspberry Pi側で

- 設定 > Raspberry Piの設定 > インターフェイス > SSH > 有効

としておいた上でMacから


```
% ssh pi@192.168.11.11
pi@192.168.11.11's password:

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Apr 20 21:07:41 2017 from 192.168.11.2
pi@raspberrypi:~ $ psql dvdrental
psql (9.4.10)
"help" でヘルプを表示します.
```

# 参考

- [[PostgreSQL] サンプルのデータベースを用意する ｜ Developers.IO](http://dev.classmethod.jp/etc/postgresql-create-sample-database/)
- [PostgreSQLの導入（データベースの利用） | Raspberry Pi用ソケットサーバーフレームワーク「HAL」 | Feijoa.jp](http://www.feijoa.jp/work/hal/postgres/)
[Swift]Bool型

## ``Bool``型

- 真理値を表す
  - ある命題が真であるか偽であるか

## 真理値リテラル

- 真理値を表すリテラル
  - ``true``: 真
  - ``false``: 偽
- 真理値リテラルの代入先の型は``Bool``型

## 論理演算

- 否定
- 論理積
- 論理和

### Swiftの演算子の配置位置

- 前置演算子
  - ``-a``
- 中置演算子
  - ``a + b``
- 後置演算子
  - ``a!``

### 否定

- 真理値の真偽を逆にする
- 前置演算子 ``!``

```Swift:否定
let a = true    // true
let b = !a      // false
```

### 論理積

- 与えられた複数の真理値が**いずれも真であれば真**
- 中置演算子 ``&&``
- 両辺に``Bool``型を取る

```Swift:論理積
let a = false && false  // false
let b = false && true   // false
let c = true && false   // false
let d = true && true    // true
```

### 論理和

- 与えられた複数の真理値の**少なくともどれか1つが真であれば真**
- 中置演算子 ``||``
- 両辺に``Bool``型を取る

```Swift:論理和
let a = false || false  // false
let b = false || true   // true
let c = true || false   // true
let d = true || true    // true
```
Library not loaded: /usr/local/lib/libmysqlclient.18.dylibにはまったとき

# MySQLを謝って削除してしまった… 

MySQLを入れ直す。
```
brew install mysql
```

そしてrails sでサーバーを起動しようとすると、

```
Library not loaded: /usr/local/lib/libmysqlclient.18.dylib
```

というエラーメッセージが発生。


エラーメッセージでぐぐると、下のポストを発見。
http://qiita.com/wktk/items/a1df946b64b7adbcb346

紹介されている対策をすべて試してみる。
ときにエラーメッセージが変わるが、最後には

```
Library not loaded: /usr/local/lib/libmysqlclient.18.dylib
```

に舞い戻る。


mysql@5.6を諦め、5.7を入れ直した。

ごちゃごちゃやってみたが、最終的に

```
sudo ln -s /usr/local/lib/libmysqlclient.20.dylib /usr/local/lib/libmysqlclient.18.dylib
```
で解決。


/usr/local/lib/libmysqlclient.18.dylibというファイルはなかったので、代わりに鎮座していたlibmysqlclient.20.dylibを実行するようにしたら治った。
プログラミングを始めてから 1 カ月

侍エンジニア塾のブログに出会ってプログラミングを開始。
あの日から 1 ヶ月くらい経ちました。

この 1 ヶ月間で学習したことやその流れをざっとまとめていきたいと思います。



## :pencil2: 進捗状況 

- HTML/CSS,JavaScript,jQuery →　Bootstrap
- PHP →　(MySQL、cakePHP)
- Ruby → (Ruby on Rails)


☆カッコ内は、始めたばかりでこれから学習するところ
・Python , Java , Command Line は Progate で少し触れた程度


## :pencil2: 学習した流れ　

### 1 . プログラミングってこんな感じなんだ

　まず最初に、**学習サイトで簡単に雰囲気を掴む**ところから始めました。
勉強という意識はほとんど無かったと思います。



オススメ学習サイト:exclamation:
**[Progate](http://prog-8.com)**

　**ゲーム感覚でプログラミングを楽しく学べる**のがポイント！
学べる範囲がそれほど広くないのが難点ですが、「入門」としては十分といえるかもしれません。

　Progate にあるプログラミング言語を一通りサクサクっとやってみました。
分からないところは軽くメモを取る程度にとどめておいてます。
一週間後に有料会員へ。

　※　なにから始めればいいのか分からない場合
　　　[Progate の学習ガイド](http://prog-8.com/tracks#1)を参考にしてみてください
　　　


### 2.　フレームワークというのがあるらしい

jQuery（厳密にはライブラリ） 、Bootstrap 、cakePHP 、Angular JS


　プログラミングを学び始めて少し経った後、よく「フレームワーク」という単語が登場していました。「これをメインに学習した方が効率が良さそうだな」ということで、なるべく早めに基本を押さえてフレームワークを学習しようと意識し始めました。

（プログラミング言語：フレームワーク＝2：8　くらいがいいらしいです）

この頃から基礎定着を図るため、学習してきたプログラミング言語の書籍を買い始めました。


### 3.　基礎の強化

　Progate の道場コースで実践するものの、自分でいざ書こうとするとほとんど全く書けないという壁に当たりました。

　そこで、Progate のほかに paiza ラーニング 、CODEPREP　の二つの学習サイトに会員登録して、復習したり、簡単なコードを素早く書く練習をしたり。とにかく、繰り返して定着させることを重点に置きました。



## :pencil2:学習して思ったこと

###プログラミングってスポーツ？

　何となくですが、プログラミングはスポーツに似ているなと思いました。
効率よく学習するには、**頭だけでなく実際にプログラムを打ち込んで体に染み込ませる**ことも必要かと思います。

###基本概念はもしかして一緒？

　Progate で JavaScript、PHP、Ruby、Python、Java をやってみたのですが、共通する部分がいくつかありました。

　- 演算子
　- 条件分岐
　- 配列
　- 繰り返し
　…
　
　各言語における記述の違いはあるものの、こういった基本的な概念は共通していると感じました。**一つの概念で二度・三度オイシイ…？**


## :pencil2:　次回

1. 各種フレームワークの使用法、連携の仕方
2. 簡単なアプリの開発
3. 配列の理解補完

##:pencil2: 気になる単語（キニタン）

1. オブジェクト指向（クラス・インスタンス）
2. Ajax (JavaScript)
3.  DOM (PHP)

## :star: 最後に

　自分の学習の記録と、初心を忘れないという意図を込めて 1 ヶ月やってみたことをまとめました。初学者ということもあってまだ分からないことがたくさんありますが、一日でも早く上達できるように頑張りたいと思います。

　また、プログラミングをどのように始めたらいいのか分からないという方にも自分の投稿した記事が参考になれば幸いです。
ノートパソコンでLinuxを使うときに、キー入力中のタッチパッドの誤動作を止める

ZenbookというWindowsのパソコンに、Ubuntu 16.04をインストールしてるんですが、
このノートパソコンでキーボードを入力していると、タッチパッドに指が触れるたびに、タッチ判定でクリックされてしまってカーソルがどっかに飛んでいってしまうみたいなことが多発したので、対策を見つけ出しました。

キーボードを打っている間は、タッチパッドのタッチ判定を受け付けないようにします。

```
syndaemon -i 1.0 -t -K -d
```

これをどこか、起動時に実行できるところに書いてください。
たとえば `$HOME/.bash_profile` とか...

`man syndaemon` ってやってもらうとまあ、使い方はわかると思うんですが、オプションとして、
`-i` はキー入力後の無視する時間。好みでもっと長くしてもいいかも。
`-t` をつけないと、タッチパッドでの移動まで、無視されてしまいます。
`-K` は、修飾キー(Ctrl)とかの入力があっても気にしないという設定です。
`-d` で、デーモン化します。

これだけでかなり、文章を打つのが捗ると思います。
集合論の「濃度」について

カントールの集合論
カントールは無限個にも，もっと細かい量の区分を入れられると考えた．
無限個の要素を持つ2つの集合に1対1の関係が成り立つとき，その「**濃度**(要素の数のこと)」は等しいと決めた．
自然数，平方数，偶数，奇数，整数，有理数は**可付番集合**で濃度 $\aleph_{0}$(アレフ・ゼロ)
実数は可付番集合では無い

線も面も立体も存在する点の濃度は皆同じ
そういう集合を**連続体**といい，カントールは連続の濃度を$0$のつかない $\aleph$ とした．
$\aleph_{0}\lt\aleph$
また無限集合の濃度には $\aleph_{0}$ から始まり，$\aleph_{1},\ \aleph_{2},\ \aleph_{3},\ldots$ と無限に大きい濃度があることもわかった．
***
#### 参考文献
1) 『[マンガおはなし数学史](http://amzn.to/2ounDRw)』(pp.227-238)
2) 『[マンガ・数学小事典](http://amzn.to/2opXrIo)』(p.42)
C#でfile_put_contentsしたかった

Azureの[AppService](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-value-prop-what-is)上でファイルを追記したいだけの人生だった。

```csharp
	using System.IO;

	/**
	* file_put_contents(FILE_APPEND)
	* @param string ファイル名
	* @param string 書き込み内容
	*/
	public static void file_put_contents(string FileName, string SaveText){
		// 実際はフォーマットとか追加があるけど本質的な違いは無いので略
		File.AppendAllText(FileName, SaveText);
	}
```

という素晴らしく手抜きな関数を使っていたところ、リクエストが重なったときに競合であっさり死亡。

```csharp
	// わりと頻繁に発生
	System.IO.IOException: The process cannot access the file 'hoge.txt' because it is being used by another process.
```

PHP脳はマルチスレッドに弱いのだ。

で、これをどうにかしたいと思ったのだが、キューに投げておけば後で勝手に書き込んでくれる、みたいな機能はどうやら用意されていないみたいだ。
ちなみにAppendAllTextのサンプルは、そもそもcatchすらしてないものが大半だった。

しかたないので`TextWriter.Synchronized()`を使うことにする。

```csharp
	public static void file_put_contents(string FileName, string SaveText){
		using(StreamWriter writer = new StreamWriter(FileName, true)){
			// まだ何も書いてない
		}
	}
```

```csharp
	// 希に発生
	System.IO.IOException: The process cannot access the file 'hoge.txt' because it is being used by another process.
```

どうやらファイルをStreamWriterで開くだけで死ぬらしい。
Synchronizedとかする以前の問題だった。
[ドキュメント](https://msdn.microsoft.com/ja-jp/library/36b035cb.aspx)には「ファイル名、ディレクトリ名が正しくないときに出る」としか書いてないのだが、どう見てもロック失敗である。

えっこれどうすんの？
newしただけでExceptionとか聞いてないよ。
WriteをcatchするとかSynchronizedするとかのソリューションはよく見かけるけど、実は解決になっていないということがわかった。

その後もなんか色々調べたりしたんだけどそのあたりは省略して、最終的にできあがったのがこんな。

```csharp
	public static void file_put_contents(string FileName, string SaveText){
		using(FileStream fs = new FileStream(FileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)){
			using(StreamWriter sw = new StreamWriter(fs)){
				using(TextWriter tw = TextWriter.Synchronized(sw)){
					tw.Write(SaveText);
					tw.Flush();
				}
			}
		}
	}
```

例外は発生せず、動作も安定しているように見えるのだが、本当にこれで合ってるのか？？？