OmniAICreator/Qiita-1.07M huggingface dataset:
[iOS] SwiftShareBubbles で SNS へシェアする導線を作る



# TL;DR

[SwiftShareBubbles](https://github.com/takecian/SwiftShareBubbles)という SNS へのシェアや Safari を開く導線を簡単に導入するライブラリを作ったので使ってくださいという記事です。

![ShareBubble.gif](https://qiita-image-store.s3.amazonaws.com/0/27210/dfdaa617-42c0-77e5-e37d-1f6093ae0ee3.gif "ShareBubble.gif")

# SwiftShareBubbles

## 使い方

Cocoapods か Carthage でインストールします。

### Cocoapods

```
pod 'SwiftShareBubbles'
```

### Carthage

```
github "takecian/SwiftShareBubbles"
```

シェアをしたい ViewController の viewDidLoad の中でセットアップをします。

```
class ViewController: UIViewController, SwiftShareBubblesDelegate {

    var bubbles: SwiftShareBubbles?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        bubbles = SwiftShareBubbles(point: CGPoint(x: view.frame.width / 2, y: view.frame.height / 2), radius: 100, in: view)
        bubbles?.showBubbleTypes = [Bubble.twitter, Bubble.line, Bubble.safari]
        bubbles?.delegate = self
    }
    
```

ここでは例として Twitter, LINE, Safari への Bubble(導線)を用意しました。
他にも Facebook や Youtube への Bubble も追加できます。サポートしている Bubble を全て追加するとこんな感じになります。

![All.gif](https://github.com/takecian/SwiftShareBubbles/blob/master/Resource/ShareBubbles1.gif?raw=true)

ちょっと radius を大きくしないと入りきらないですね・・。

そして Bubble を選択された時のメソッドを実装します。

```
// SwiftShareBubblesDelegate
    func bubblesTapped(bubbles: SwiftShareBubbles, bubbleId: Int) {
        if let bubble = Bubble(rawValue: bubbleId) {
            print("\(bubble)")
            switch bubble {
            case .safari:
                UIApplication.shared.openURL(URL(string: "SOME_URL"))
            case .twitter:
                if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeTwitter) {
                    guard let composer = SLComposeViewController(forServiceType: SLServiceTypeTwitter) else { return }
                    composer.setInitialText("test test")
                    present(composer, animated: true, completion: nil)
                }
                break
            case .line:
                // TODO
                break
            default:
                break
            }
        } else {
            // custom case
        }
    }
```

簡単ですね。

### 自作の Bubble を使用する

ライブラリで用意されている Bubble だけでなく自作の Bubble を使うこともできます。

ShareAttirbute を使って Bubble を作成し、customBubbleAttributes にセットすれば OK です。

```
let customBubbleId = 100
    
    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        let customAttribute = ShareAttirbute(bubbleId: customBubbleId, icon: UIImage(named: "Custom")!, backgroundColor: UIColor.white)
        bubbles?.customBubbleAttributes = [customAttribute]
        ...
    }
```

SNS 上で拡散してもらってアプリの認知度を広めることは大事なことなので SwiftShareBubbles を使ってシェアしてもらってみてはいかがでしょうか。

[SwiftShareBubbles](https://github.com/takecian/SwiftShareBubbles)
React Native+Flowにおける.flowconfigの設定方法	


## Flowとは
一言で言えば、Javascriptのコードに対して静的な型チェックをしてくれるやつです。
導入に関しては[ここ](https://medium.com/react-native-training/getting-started-with-react-native-and-flow-d40f55746809)とかを参照。

## Flow導入時の問題点
Nuclide(Atom)の設定を済ませて、いざFlowで型チェックを試そうとした時に次の問題が発生しました。

### 問題1: 解析時間が長すぎ&node_module内のファイルでエラーが出る問題
.flowconfig内の`[ignore]`ディレクティブの設定をしていなかったので、node_modulesディレクトリ内のファイルも解析対象になってやたら時間がかかる上に、エラーとなっていました。
そこで、.flowconfigの`[ignore]`ディレクティブに下記を設定。

> [ignore]
.*/node_modules/.*


無事、解析時間は短縮されましたがさらなる問題が発生。

### 問題2: react-nativeのモジュールが見つからない問題
なんと、import文でエラーがでるように...

![スクリーンショット 2017-06-27 17.52.13.png](https://qiita-image-store.s3.amazonaws.com/0/29971/ea780434-0383-e55d-8a94-9749a9bb18e0.png "スクリーンショット 2017-06-27 17.52.13.png")

![スクリーンショット 2017-06-27 17.52.37.png](https://qiita-image-store.s3.amazonaws.com/0/29971/89bafff8-571d-a471-13ae-6ad02eaf4608.png "スクリーンショット 2017-06-27 17.52.37.png")

### やりたいこと
- node_moduleはflowの解析対象から外したい
- 自分で書くソースの中でパッケージのimport文がエラーにならないようにしたい

これだけなんですよね。


## 解決方法
githubやstackoverflowいろいろ調べましたが、「これだ！」というのは無いらしく、各々自分なりの対応を取っているようでした。
そん中、flowのgithubのissue内で[輝くコメント](https://github.com/facebook/flow/issues/869#issuecomment-256643823)を発見。

簡単に対応をまとめると下記の通り

- libdefs.jsを作成し、エラーとなっていたモジュールをdeclareする
- .flowconfigでnode_modules配下を無視するように変更
- .flowocnfigでlibdefsを読み込ませる

## libdefs.jsの作成
このファイルの中で、import文でエラーになったモジュールを記述する。

```libdefs.js
declare module 'react-native' { declare var exports: any; }
```

## .flowconfignの設定(必要な部分のみ抜粋）
```.flowconfig
[ignore]
<PROJECT_ROOT>/node_modules/.*
<PROJECT_ROOT>/libdefs.js
[include]
[libs]
./libdefs.js
[options]
all=true
```

これで快適に型チェックをしながらReact Nativeのコードが書けるように！
Spring-securityでユーザーログイン後とかにリダイレクトさせる方法

ある一定の条件をDBから取得して、条件に一致するならば指定された画面にリダイレクトするような画面が作りたいとする。

そんなとき、Spring-securityを使っているならばカスタムフィルターが使える。フィルターを定義して、そのクラスの中でリダイレクトを実行させればよい。

# Spring-securityで定義されるフィルターの種類

Spring-securityでフィルターを差し込めるタイミングは以下の一覧に載っている。

* [Table 6.1. Standard Filter Aliases and Ordering](http://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#filter-stack)

## 使いそうなもの

* CSRF_FILTER
* LOGOUT_FILTER
* FORM_LOGIN_FILTER
* FILTER_SECURITY_INTERCEPTOR

カスタムで作成したフィルターは、上記の前にも後にも、もしくはそのフィルター自体の代替として定義できる。

```xml:spring-security.xml
<http>
    <!-- 前 -->
    <custom-filter before="FORM_LOGIN_FILTER" ref="myFilter" />
    <!-- それ自体の代わりとして -->
    <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
    <!-- 後 -->
    <custom-filter after="FORM_LOGIN_FILTER" ref="myFilter" />
</http>
```

## フィルター自体の定義方法

* [Writing a Custom Filter in Spring Security](http://www.baeldung.com/spring-security-custom-filter)

Springのフィルターは `GenericFilterBean` を使ったほうがいいようだ。プロジェクトの適当なところに、このクラスを継承したクラスを定義する。

そして、そのクラスの名前空間とSpring上でのidをXMLに設定する。そうすることで、spring-securityで使用するためだ。

```xml:spring-context.xml
<beans:bean id="myFilter" class="org.baeldung.security.filter.CustomFilter"/>
```

## 二重Dispatchを防ぐために

こういうプロジェクト全体的にかかわるフィルターを書くと、Strutsとかでかつてよく見た二重Dispatchのエラーが出る。こんなの：

```text
java.lang.IllegalStateException: Cannot forward after response has been committed
```

要は、行き先が決まっているリクエストをフィルターでもう一度リダイレクトしようとするとこれが起こる。

対処としては、前述の [Table 6.1. Standard Filter Aliases and Ordering](http://docs.spring.io/autorepo/docs/spring-security/current/reference/htmlsingle/#filter-stack) を見て、リクエストの行き先が決まる前に所望のフィルター処理を実行することだ。
Médecine esthétique en Tunisie

La médecine esthétique mini-invasive est depuis plusieurs années une compétence centrale à laquelle nous suivons beaucoup d'amour et engagement les attentes d'une patientèle variée. Des thérapeutes expérimentés disposent d'une formation médicale de beaucoup d'années et participent régulièrement à des formations continues et colloques internationaux. Par l'emploi quotidien et exclusif l'équipe dispose d'experts en médecine esthétique ayant un maximum d'expérience sur ce secteur. Nos collaborateurs motivés se réjouissent de pouvoir vous offrir du début à la fin un soin personnel suivant votre état. On accorde une importance particulière à une consultation détaillée, pour pouvoir accepter individuellement vos demandes visitez https://medecine-esthetique-paris.net/
php で Cloud Front にキャッシュしてもらうようにする




```php
header_remove('Expires');
header_remove('Pragma');
header("Cache-Control: max-age=240, must-revalidate");
```


[CloudFront エッジキャッシュにオブジェクトを保持する時間の指定（有効期限切れ）](
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Expiration.html)

> ビューアからの GET リクエストで HTTP Cache-Control または Pragma ヘッダーフィールドを使用して、オリジンサーバーに戻ってオブジェクトを取得するように CloudFront を設定することはできません。CloudFront は、ビューアからのリクエストにあるそのようなヘッダーフィールドを無視します。

とあったが、`Pragma` を消さないと `X-Cache: Miss from cloudfront` だった。
Splunkコマンド集 その2

[前回](http://qiita.com/kikeyama/items/3a423de39a02ac2380ed)に続いて、Splunkコマンドの紹介です。

# コマンド紹介

## transaction
一番好きなコマンド。
IPアドレスやユーザー名、ID等をキーとして、関連するイベント（ログ行）をまとめるコマンド。
複数のソースタイプもまとめられるので、トラブルシューティングに便利。
ただ、実際はマシンパワーを食うので、 `maxspan` `maxpause` `startswith` `endswith` といったオプションの指定は必須。

例）

```
sourcetype=apache:access OR sourcetype=tomcat:access:log 
| transaction maxspan=3s clientip
```

http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Transaction

ちなみに、`maxspan`は1トランザクション内での最大時間、`maxpause`はトランザクション間の間隔。
セキュリティ用途でも 「3秒間に同一IPアドレスで1,000件以上のアクセス」 を抽出するときにこれをつかうと便利。

語りだすと長くなるので、また別途。

## eventstats
イベントをまたいでの統計を追加するもの。
例えば、`stats`コマンドでIPアドレスごとの件数を取得して、その件数の全体の平均値を計算してその差分をとるときとか。

例）

```
sourcetype=apache:access 
| stats count by clientip 
| eventstats avg(count) as avg_count 
| eval delta = abs(count - avg_count) 
| sort - delta
```

http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Eventstats

## streamstats
2番目に好きなコマンド。
`eventstats` と似ているけど、スライディングウィンドウで累積したり計算したりするもの。

例） 時系列データから標準偏差±2範囲外の異常値を見つける。

```
sourcetype=apache:access 
| timechart span=1h count 
| streamstats window=12 avg(count) as avg stdev(count) as stdev 
| eval lower_bound = avg - stdev * 2 
| eval upper_bound = avg + stdev * 2 
| eval isOutlier = if(count>upper_bound OR count<lower_bound, 1, 0) 
| fields - avg stdev
````
この場合、12時間（1hスパンが12個）のスライディングウィンドウで平均値と標準偏差を計算して、isOutlierの値が1になっているものは異常値とみなす。

http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Streamstats

## bin
範囲にまとめるコマンド。
例えば、HTTPステータスコードを100単位で集計したい時に使ったり、機械学習用にカテゴリ分類するような用途。
`bucket`コマンドと同じ。

例） ステータスコードを200-300、300-400という具合に分類

```
sourcetype=apache:access 
| bin span=100 status 
| stats count by status
```

http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Bin

## autoregress
直前のイベントのフィールドの値をそのイベントに入れる。
`streamstats`でも同じことはできる。

例）

```
sourcetype=apache:access 
| autoregress src_ip as last_src_ip
```

http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Autoregress

## concurrency
マイブームなコマンド。
同時実行を累積していく。 同時アクセスを見るのに便利かも。

例）

```
sourcetype=apache:access 
| transaction maxpause=10m user 
| concurrency duration=duration start=_time 
```

この場合、Apacheアクセスログから（1行目）、10分間ログ出力されていない場合はアクティブではないとみなしてトランザクションにまとめ（2行目）、`transaction`コマンドで出力されるdurationフィールドの間に積み重ねてカウントしていったものがconcurrencyというフィールドに出力される（3行目）。
これを折れ線グラフか棒グラフにするとわかりやすいかも。

ただ、実際ログに吐き出される時間はマチマチなので、間に空白の時間がある場合には`gentimes`コマンドで埋める必要あるかも。
それはまた別途。

# 最後に
何となく思いつくまま自分の好きなコマンドを紹介しました。
実用的に使えるかどうかはアイデア次第でしょう。
実際の出力イメージ含めた詳細な説明は、気が向いたときにでも。

# リンク集
Splunkコマンド集 その1
http://qiita.com/kikeyama/items/3a423de39a02ac2380ed
Ultimaker2 Go と Blender を使って 3D プリントする

　Ultimaker2 Go と Blender を使って 3D プリントするまでの流れを紹介します。
　なお必要なソフトウェアのインストール方法は割愛させて頂きます。

# 環境
　今回確認した環境は以下の通りです。

* Mac OS X 10.11.6
* Blender 2.78c
* Cura 2.6.0
* Ultimaker2 Go

# Blender 
Blender からは STL 形式で出力を行います。

## STL で出力する
　まず出力したいモデルを選択しておきます。それから `File` > `Export` > `Stl(.stl)` としてエクスポートの設定画面に移ります。
 選択したモデルを出力するために `Selection Only` にチェックを入れます。またリアルスケールできちんと作ってある場合は良いですが、そうでなければ適当な値を `Scale` 値に設定します。

<img width="278" alt="スクリーンショット 2017-06-27 15.24.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/13938/d632f341-4d74-a328-9a20-e9cfcdbe5654.png">

　スケール感の参考として、デフォルトキューブをそのまま出すとこんな感じになります。真ん中あたりにある黄色い小さな立方体がそれです。
<img width="427" alt="スクリーンショット 2017-05-09 14.26.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/13938/4f3ce1f3-f09b-b627-fcf0-82633e972df9.png">

# Cura
　Ultimaker2 Go ではスライサーとして "Cura" を推奨しているので、 Cura を使うことにします。次の web サイト(https://ultimaker.com/en/products/cura-software) からダウンロード出来ますので、ダウンロードしてインストールを行いましょう。

## STL ファイルを読み込む
　先ほど Blender から出力した STL ファイルを読み込みます。

## G-code を作成する
　SD カードを PC に挿入した状態で `Save to Removable Drive` ボタンを押します。すると、 SD カードに G−code が書き込まれます。

<img width="451" alt="スクリーンショット 2017-06-27 14.10.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/13938/733341cb-2986-bf0b-3905-e0da4b4a49e9.png">

　無事に書き込まれたメッセージが表示されたら `Eject` ボタンを押して SD カードをアンマウントし、 PC から取り出します。

<img width="392" alt="スクリーンショット 2017-06-27 14.11.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/13938/01cc1ae7-ba49-0bc7-865d-3405fd6c18c0.png">

# Ultimaker2 Go

## 3D プリントする
### 準備
1. G−code を保存した SD カードを Ultimaker2 Go 本体に挿入する
2. プリントベッドに（付属の）スコッチテープを貼る
3. モデルが滑らないように（付属の）スティックのりを塗る

### プリント
　本体のメニューから `PRINT ` を選んで、プリントしたいモデル名を選択するとプリントが開始されます。

### 造形物の取り出し
　プリントが終了すると

```
Printer cooling down
```

と表示されて、冷却が始まるので、冷めるまで待ちましょう。そして

```
Print finished

You can remove
the print
```

と表示されれば、安全に取り出しが出来る状態になります。

### 豆知識
　造形物がプリントベッドやスコッチテープに強力にくっついてしまう事があります。そんな場合はホームセンターなどに売っているシール剥がしスプレーを使うと楽に剥がす事ができます。
SELinuxの無効化


#概要
1.SELinuxを一時的にオフにする方法
2.SELinuxを永続的にオフにする方法

#環境
CentOS7


#現在の状態確認方法
状態一覧
・enforcing ･･･ SELinuxは有効で、アクセス制限も有効。
・permissive ･･･ SELinuxは有効だが、アクセス制限は行わず警告を出力。
・disabled ･･･ SELinux機能は無効。

実行ログ

```
# getenforce
  Enforcing
```

#一時的に無効にする
```
# setenforce 0
```
で、設定が"Permissive"になる。

```
# setenforce 1
```
で、設定がEnforcingになる。

<h1>永続的に無効にする</h1>
上の方法だと、再起動するたびにコマンド打たなきゃいけない。
毎回めんどくさいです。
ということで、設定ファイルを書き換えましょう。

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

enforcingをdisabledに変えましょう。

<h1>サーバ再起動</h1>
変更した設定は再起動しなければ反映されない。

```
# reboot
```

念のため確認しましょ。

```
# getenforce
  Disabled
```

#できた！
これで面倒なSELinuxから解放された...
再起動のたびにエラーが出てきて、試行錯誤した結果、
またSELinux解除を忘れてた！
ってのがしょっちゅうあってとてつもなくイライラしたので。笑
ファイルダウンロードが途中で止まってしまったのでターミナルからダウンロードをする

# ブラウザから重いファイルをダウンロードできない
Mac chromeから重いデータ(2G)をダウンロードしようとしたところ、
しれっとダウンロードできたかと思ったら
ダウンロードファイルを解凍しようとしたところ

>"ダウンロードファイル名"を"ダウンロードファイル名"に展開できません。
>（エラー１ - その操作は許可されていません。）

といったエラー出て不完全でした。

その場合はターミナルで行えばOK


```
wget [option] URL
```
OPTION については
下記サイトのものを自由に入れてOK

[Linuxコマンド集](http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/230995/?rt=nocnt)
Tensorflow API: tf.reverse


https://www.tensorflow.org/api_docs/python/tf/reverse

* 入力のテンソルを反転させる
* TensorFlow 1.0より機能が変更されている。

~~~
reverse(
    tensor,
    axis,
    name=None
)
~~~

* tensor: 入力テンソル
* axis: 反転させる次元を、integerのリストで指定
* name: 出力テンソルの名前

### 使用例

* 実行環境: TensorFlow 1.2.0

~~~python
import tensorflow as tf

# 3次元のテンソルを定義
x = tf.constant([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
                [[11, 12, 13], [14, 15, 16], [17, 18, 19]]])

sess = tf.Session()
x_reverse_0 = tf.reverse(x, [0])
x_reverse_1 = tf.reverse(x, [1])
x_reverse_2 = tf.reverse(x, [2])
x_reverse_0_1 = tf.reverse(x, [0, 1])
x_reverse_0_1_2 = tf.reverse(x, [0, 1, 2])

# 結果の確認
print(str(sess.run(x)) + '\n')

print("tf.reverse(x, [0]):")
print(str(sess.run(x_reverse_0)) + '\n')

print("tf.reverse(x, [1]):")
print(str(sess.run(x_reverse_1)) + '\n')

print("tf.reverse(x, [2]):")
print(str(sess.run(x_reverse_2)) + '\n')

print("tf.reverse(x, [0, 1]):")
print(str(sess.run(x_reverse_0_1)) + '\n')

print("tf.reverse(x, [0, 1, 2]):")
print(str(sess.run(x_reverse_0_1_2)) + '\n')
~~~

~~~python:出力
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]]

 [[11 12 13]
  [14 15 16]
  [17 18 19]]]

tf.reverse(x, [0]):
[[[11 12 13]
  [14 15 16]
  [17 18 19]]

 [[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]]]

tf.reverse(x, [1]):
[[[ 7  8  9]
  [ 4  5  6]
  [ 1  2  3]]

 [[17 18 19]
  [14 15 16]
  [11 12 13]]]

tf.reverse(x, [2]):
[[[ 3  2  1]
  [ 6  5  4]
  [ 9  8  7]]

 [[13 12 11]
  [16 15 14]
  [19 18 17]]]

tf.reverse(x, [0, 1]):
[[[17 18 19]
  [14 15 16]
  [11 12 13]]

 [[ 7  8  9]
  [ 4  5  6]
  [ 1  2  3]]]

tf.reverse(x, [0, 1, 2]):
[[[19 18 17]
  [16 15 14]
  [13 12 11]]

 [[ 9  8  7]
  [ 6  5  4]
  [ 3  2  1]]]
~~~
hdfsに接続するユーザーを指定する

リモートからhdfsに接続するときに接続元のユーザーでアクセスしようとするので、権限がなければ、Permission deniedエラーが出る。以下の例だとhdfsユーザーのディレクトリにdrwtsn64がmkdirをしようとしたが権限がないので怒られている。

```bash
 Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
mkdir: Permission denied: user=drwtsn64, access=WRITE, inode="/user/drwtsn64/demo":hdfs:hdfs:drwxr-xr-x
```
その場合は`HADOOP_USER_NAME`にユーザー名を指定してアクセスすればよい。

```bash
HADOOP_USER_NAME=hdfs hdfs dfs -mkdir -p /user/drwtsn64/demo
```
Nodist を使って、Node.js のバージョン管理を行う方法【 Nodist 導入編 】

# はじめに
Nodistのインストール手順をまとめてみた。 #メモレベル
_インストールする際に、いろんなサイトを見に行くのが面倒なので、
自分が引っかかった箇所を重点的に記載してます！_

# Node.jsのバージョン管理ツール __(nodist, nvm, nodebrew etc)__

__Node.js__には__複数のバージョン管理ツール__ _(nodist, nvm, nvmw, nodebrew)_ があるが、
今回は、__Windows専用のNode.jsバージョン管理ツール<font color="red">「Nodist」</font>__をインストールしてみる。

>__[ Node.js バージョン管理ツール一覧 ]__

><font color="black">__1. nvm__</font>
→ Mac OSX/Linux用のバージョン管理ツール
<font color="black">__2. nodebrew__</font>
→ Mac OSX/Linux用のバージョン管理ツール (Perl製)
<font color="red">__3. Nodist__</font>
→ Windows専用のバージョン管理ツール

# Nodistのインストール方法
#### __1. 下記サイトより、最新のインストーラー__「NodistSetup-v0.8.8.exe」__をインストールする。__
__[Nodist - Releases](https://github.com/marcelklehr/nodist/releases)__

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/b61d6d29-bf89-91ea-51c1-291301c969f4.png" width="720px">

#### __2. インストーラーを実行すると、Nodistのセットアップウィザードが開くので、作業を進める。__

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/0ca7d937-341a-1451-f9b3-c8e294ea5902.png" width="500px">

インストール先は、下記パス指定。

```
C:\Program Files\Nodist
```

_※こちらのパスはお好みでどうぞ！_

インストール作業が完了すると、nodistコマンドのパスが設置されていますが、
PCを再起動しないと有効にならないようなので、一度PCを再起動します。

# Nodistのバージョンを確認

```
C:\Users\User名> nodist -v
0.8.8
```

これで、Nodistのインストール作業は完了です。
_自分の備忘録用にと書きましたが、PC再起動させてシステム環境変数を反映させるところ以外は、詰まらずに進めることができました。_

# __<font color="red">node.jsのバージョンが切り替わるか検証を行う。</font>__

まず、nodistを使ってインストール可能なNode.jsのバージョン一覧を確認します。

```
$ nodist dist
```

と、その前にデフォルトでインストールされているNode.jsのバージョンを確認しておきましょう。

```
$ nodist ls
(x64)
> 7.2.1 (global: v7.2.1)
```

デフォルトでは、Node.js(v7.2.1)がインストールされているので、
今回は、検証用(Nodistを使ってNode.jsのバージョンを切り替えれるかどうか)に、
最新バージョンのNode.js(v8.1.2)をインストールしてみます。

```
$ nodist + v8.1.2
8.1.2 [=====================] 22677/22677 KiB 100% 0.0s
8.1.2
```

たった、10秒足らずでインストールが完了しました。

さて、この状態で、```node -v```を試してみましょう。

この時点では、デフォルトのNode.js(v7.2.1)が実行されます。

続いて、さきほどインストールしたNode.js(v8.2.1)に切り替えます。
切り替えるには、下記コマンドを実行する必要があります。

```
$ nodist v8.2.1
v8.2.1
```

上記にて、実行されるnode.exeのパスが変わります(はず)。

```
$ node -v
```

ドーーーーーーーン！！！

```
v7.2.1
```

変わらない。世の中そんな甘くないですよねーｗ

# コマンドの叩き方が間違っていた??? (汗

__[追記]__
>今試したら、```V```付きでも実行できますね。:frowning2:
もし```v```付きで切り替わらない人は、```v```無しで試してみてください！
(下記手順あり)


すみません、コマンドの叩き方が間違えておりました！

```
誤) $ nodist v〇.〇.〇
```

```
正) $ nodist 〇.〇.〇
```

※バージョンを表す「v」がいらなかった。
ちなみに、こちらのコマンドを実行してもエラーは出ない、
むしろ変更されているかのように「v〇.〇.〇」と出力される。

気を取り直して、下記コマンドを実行！

```
$ nodist 8.1.2
8.1.2
Default global packge update dsuccessful.
```
↑なんか誤字のような気もするが出力結果は上記の通りになる。

nodeのバージョンを確認してみる。

```
$ node -v
```

ドーーーーーン！！！

```
v8.1.2
```

バージョンを切り替えることに成功しました:point_up:

最後に、```nodist ls```コマンドで、global設定になっているnode.jsのバージョンを確認してみると、、

```
$ nodist ls
(x64)
7.2.1
> 8.1.2 (global: 8.1.2)
```

Node.js(v8.1.2)に切り替わっていることが確認できると思います！！！


いやーすっきりしました。

# おわりに
最後までお読みいただき、ありがとうございました。
困ったときは、```nodist --help```を活用しましょうｗ
AWS Lambda & DynamoDBのベストプラクティスを求めて


こんにちはsekitakaです。

serverlessな環境での開発も随分慣れてきましたが、コードの再利用性についてどうしようか悩んでいるので考えたこと&暫定結論を公開します。
ベストプラクティスを模索中なのでコメントでの議論も大歓迎です。

# 前提条件
共通するDynamoDBのテーブル(例:User)を参照する3つのプロジェクトがある。

- プロジェクトP1
- プロジェクトP2
- プロジェクトJ1

以下のような状況になっている。

- プロジェクトP1には既にUserデータのデータを取得する関数がある
- プロジェクトP1,P2はPythonで実装されており、プロジェクトJ1はJavaScriptで実装されている。
- プロジェクトは全てLambda関数郡としてデプロイされる。

# お題
Userテーブルからのデータ取得を各プロジェクトに組み込むにはどんな方法がよいか考える

# 案
## 案1 - 車輪の再発明を恐れない
各プロジェクト内にUserテーブルからのデータ取得用のライブラリをそれぞれ作成する。
この方法は再利用性がプロジェクト内に限定されるかわりに、各プロジェクトで行った修正が他のプロジェクトへ影響しない。
PythonとJavaScriptの両方の言語で実装する必要がある。

## 案2 - Userテーブル専用のLambda関数を作成する
データアクセス専用のLambda関数を作成する。
1種類の言語でのみデータアクセス用のLambda関数を実装すればよい。
ただしデータアクセス関数を変更した場合、全プロジェクトに影響範囲が広がる。
つまりデータアクセス関数を変更した場合に、各プロジェクトのテストを実行する仕組みが必要になる。

## 案3 - Userテーブル専用のAPIを作成する
API Gatewayに専用APIを作る。案2とあまり変わらないが、APIGatewayのバージョン管理が使用できそう。
各プロジェクトからバージョン指定でAPIを実行することで、バージョンアップに伴う影響範囲を小さく出来る。

## 案4 - プロジェクトP1の既存の関数を使用する
案2と似ている。プロジェクトP1の変更がプロジェクトP2,J1に影響するという構造になり混乱が生じやすい気がする。

## 案5 - 各言語のライブラリを作る
案1に似ているがPythonとJavaScriptの2種類のライブラリを汎用で作成する方法もある。
利用するプロジェクトではnpmのプライベートリポジトリなどを利用して依存関係を解決する。
適切にバージョン管理すれば、バージョンアップに伴う影響も最小限に抑えることができる。

# 比較
## コード量
類似コードを記述(コピペ)する量を比較します。
その場のスピードを出すために案1を使いたいこともありますが、プロジェクトが増えることを考えるとあまりよくないかな。
ただAWSのSDKとして既にライブラリ化されているので、それを利用する部分のコードだけと考えると無くもないかな。

| 案 | 倍率 | 
|---|---|
| 案1 | 3(プロジェクトごとに増える) | 
| 案2 | 1 | 
| 案3 | 1 | 
| 案4 | 0(既存なので) | 
| 案5 | 2(言語毎に増える) | 

## 実装規模
新しく開発する必要のある部分の開発工数の比較。

| 案 | 規模 | 
|---|---|
| 案1 | 小 | 
| 案2 | 中 | 
| 案3 | 中 | 
| 案4 | 小 | 
| 案5 | 大 | 

## シンプルさ
全体の構造が分かりやすいほどトラブルが起こりにくいので、シンプルさも大切です。

| 案 | シンプルさ | 
|---|---|
| 案1 | ○ | 
| 案2 | ○ | 
| 案3 | △(案2よりAPI Gateway分複雑) | 
| 案4 | × | 
| 案5 | ○(作るの大変だけど使うのはシンプル) | 

## 点数化
比較したけど何がいいかわからないので点数化してみました。
各要素3点満点にしました。点数が高いほどよい評価です。

| 案 | 倍率 | 規模 | シンプルさ | 合計 |
|---|---|---|---|---|
| 案1 | 1 | 3 | 3 | 7 |
| 案2 | 3 | 2 | 3 | 8 |
| 案3 | 3 | 2 | 2 | 7 |
| 案4 | 3 | 3 | 1 | 7 |
| 案5 | 2 | 1 | 3 | 6 |

ザルみたいな点数化ですが差がつきました。案2がよさそうです。
感覚的にも案2のシンプルなわかりやすさはいい感じに思えます。

# とりあえずの結論
案2がよさそうという結論になりました。
他にも方法がありそうでしたらコメントお願いします！

# まとめ
1つのモノリシックなアプリを作るのでなく、既存のリソースを利用する場合リソースにどう再利用するか悩みどころが多いですね。
今回の結論も絶対ということはなくスピードや移行コストを考えるとまた違う結論になりそうです。

ノウハウ共有というより脳内垂れ流しですが、色々コメントいただけるとありがたいです。
nodeモジュールを作成する

言語は異なっても、プログラムの組み方はなかなか変えられないもの。
自分のパターンのメソッド名でラップして自分のライブラリに置いておきたい。
nodeでクラス化して置いておきたい場合はどうする？
ということで、nodeモジュールの作成方法のメモ。

#環境
Node.js v6.11.0

#参考
[Node.js v6.11.0 Documentation](https://nodejs.org/dist/latest-v6.x/docs/api/)

#仕様
Node.jsでは、ファイルとモジュールは1対1で対応しています（各ファイルは個別のモジュールとして扱われます）。

たとえば、foo.jsという名前のファイルを考えてみましょう。

```node:foo.js
const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
```

最初の行で、foo.jsは、foo.jsと同じディレクトリにあるcircle.jsモジュールをロードします。
circle.jsの内容は次のとおりです。

```node:circle.js
const { PI } = Math;
exports.area = (r) => PI * r * r;
exports.circumference = (r) => 2 * PI * r;
```
モジュールcircle.jsは、関数area()とcircumference（）をexportsしています。
関数とオブジェクトを追加するには、それらをexportsオブジェクトに追加します。

モジュールがNode.jsによって関数にラップされるため、モジュールのローカル変数はプライベートになります。 この例では、変数PIはcircle.jsに対してプライベートです。

モジュールのエクスポートのルートを関数（コンストラクタなど）にする場合や、一度に1つのプロパティを作成するのではなく、1つの割り当てで完全なオブジェクトをエクスポートする場合は、エクスポートの代わりにmodule.exportsに割り当てます 。

以下、bar.jsはコンストラクタをエクスポートするsquareモジュールを使用します。

```node:bar.js
const square = require('./square.js');
const mySquare = square(2);
console.log(`The area of my square is ${mySquare.area()}`);
```
squareモジュールはsquare.jsで定義されています。

```node:square.js
// assigning to exports will not modify module, must use module.exports
module.exports = (width) => {
  return {
    area: () => width * width
  };
};
```
モジュールシステムはrequire（ 'module'）モジュールに実装されています。

#実践
例えば、Slack APIを操作するためのラップされたクラスを用意したいとします。
私のクラス名命名規則は接頭辞にHKを付けているので、クラス名をHKSlackとします。
また、ファイル名とクラス名を一致させてるので、以下の様なファイルになります。
[Slack Web API](https://api.slack.com/methods)

```node:HKSlack.js
/**
 * constructor
 *
 * @return void
 */
var HKSlack = function(token)
{
	this.token = token;
}
/**
 * Set Token
 *
 * @param string $token
 * @return void
 */
HKSlack.prototype.setToken = function(token)
{
	this.token = token;
}
/**
 * Get Token
 *
 * @return string
 */
HKSlack.prototype.getToken = function()
{
	return this.token;
}
/**
 * Post Chat Message
 *
 * @param
 * @return void
 */
HKSlack.prototype.postMessage = function(json)
{
	var Slack = require('slack-node'); // slack-node モジュールを読み込んでいる
	var slack = new Slack(this.getToken());
	slack.api('chat.postMessage', json, function(err, response) {
		console.log(response);
	});
}
module.exports = HKSlack;
```
最後に、作成したクラスをmodule.exportsに割り当てています。
このモジュールを利用する場合、以下の様になります。

```node:post_slack.js
var token = 'xxxxxxxxxxxxxxxxxxxxxxxx';
var HKSlack = require('./HKSlack.js');
var slack = new HKSlack(token);
slack.postMessage({
	'channel': '#mychannel',
	'username': username,
	'text': text
});
```
今回はここまで。
Android StudioでSVGを扱う方法

## はじめに
初歩的なことですが分からないので調べて見ました。公式ドキュメントに詳しく書いてありました。

## 環境
- Android Studio 2.3.3

## 手順
1. プロジェクトウインドウでAndroidビューを選択し、resフォルダを右クリックして[New] > [Vector Asset]を選択します。
	![スクリーンショット 2017-06-27 16.43.17.png](https://qiita-image-store.s3.amazonaws.com/0/185323/ac229c42-47cb-01ed-0f41-67c25d2e8981.png "スクリーンショット 2017-06-27 16.43.17.png")

2. 表示されたVector Asset StudioからAsset Type[Local file (SVG, PSD)]を選択しPathから対象ファイルを選択します。
	![スクリーンショット 2017-06-27 16.43.56.png](https://qiita-image-store.s3.amazonaws.com/0/185323/db78940e-8929-84a8-98ab-59d4a8cf133a.png "スクリーンショット 2017-06-27 16.43.56.png")

Vector Asset Studioのデフォルトだとサイズは24dp*24dpです。Size項目にあるOverrideにチェックすることで対象のSVGファイルのサイズが適用されるようです。また、Asset Type[Material Icon]を選択するとIcon項目から用意されたMaterial Iconが使用できるようです。便利ですね。

![スクリーンショット 2017-06-27 16.56.53.png](https://qiita-image-store.s3.amazonaws.com/0/185323/4f42b9ea-1c46-79da-269b-aaafcebbf00c.png "スクリーンショット 2017-06-27 16.56.53.png")

## 参考
- [さまざまな密度に適用可能なベクター グラフィックの追加 | Android Studio](https://developer.android.com/studio/write/vector-asset-studio.html?hl=ja#importing)
Bluemix の Cloudant に csv ファイルを python でアップロード

こちらで curl で行ったことを、python3 で書いてみました。

[Bluemix の Cloudant に csv ファイルをアップロードする](http://qiita.com/ekzemplaro/items/46458b2e7a2e6437d712)

csv のアップロード

```py3:go_create.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#
import sys
import json
import requests
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
url="https://44b508dd-346a-44c8-85b7-79d184aaf02f-bluemix:b92b6187dfe7c1fcb97c88ea2c0ce5015eee6829c5bb74fbb148e5aa8cfba362@18b508dd-346a-44c8-85b7-79d184aaf02f-bluemix.cloudant.com"
#
url_csv = url + "/csv"
rr=requests.delete(url_csv)
print(rr)
print(str(rr.content,'utf-8'))
#
rr=requests.put(url_csv)
print(rr)
print(str(rr.content,'utf-8'))
#
#
csv_in="cities.csv"
fp_in = open (csv_in,encoding='utf-8')
str_out = fp_in.read ()
fp_in.close ()
#
url_csv_file = url + "/csv/tochigi/cities.csv"
payload = {'send': str_out}
files = {'file': open(csv_in, 'rb')}
headers = {'Content-type': 'text/plain; charset=utf-8'}
rr=requests.put(url_csv_file, files=files,headers=headers)
print(rr)
print(str(rr.content,'utf-8'))
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

CSV　の　ダウンロード

```py3:go_get.py
! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	go_get.py
#
#					Jul/27/2017
import sys
import requests
# --------------------------------------------------------------------
def filter_save(file_out,str_in):
	fp_out = open(file_out,mode='w',encoding='utf-8')
	print("*** filter_save *** start ***")
	lines=str_in.split()
	sys.stderr.write ("len(str_in) = %d\n" % len(str_in))
	sys.stderr.write ("len(lines) = %d\n" % len(lines))
	for line in lines:
		if ',' in line:
#			print(line)
			fp_out.write(line + "\n")
	fp_out.close()
	print("*** filter_save *** end ***")
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
url="https://44b508dd-346a-44c8-85b7-79d184aaf02f-bluemix:b92b6187dfe7c1fcb97c88ea2c0ce5015eee6829c5bb74fbb148e5aa8cfba362@18b508dd-346a-44c8-85b7-79d184aaf02f-bluemix.cloudant.com"
#
file_csv="cities.csv"
#
url_csv = url + "/csv/tochigi/" + file_csv
rr=requests.get(url_csv)
print(rr)
bbx=rr.content
str_aa=str(bbx,'utf-8')
#
filter_save(file_csv,str_aa)
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
Azure Skillsはエンジニアの育成に有効か？

最近AWSとAzureの案件が比率として半々くらいになってきており、社内のメンバーに「両方覚えてね！」と無茶振りする機会が増えてきました。そこで何か良い学習コンテンツがないかな〜と探していたところ、MicrosoftからAzure Skillsという無料のeラーニングコンテンツの案内がきましたので試してみました。

## 結論
とても良かったです。教育コンテンツとして使えると思いました。AWSをある程度触っているエンジニアがAzureをキャッチアップするには現時点で知る限り一番良いコンテツではないでしょうか。

## そもそもAWSとAzureを両方知る必要性はあるのか？
AWSもAzureもカバーしているサービス領域が広いため、単純な比較や良し悪しを語るのは難しいと思います。しかし、お客様と対面するエンジニアは両者の特徴を理解して、使い分け、ユーザからの質問に一次回答できるくらいの基本知識が必要になってきている気がします。

## Azure Skillsとは
マイクロソフトが提供している無料で受講可能なeラーニングです。もともとのコンテンツは英語のようで、2017.6.26時点では11コンテンツが日本語化されています（英語コンテンツは34コンテンツ）。

<img width="1241" alt="スクリーンショット 2017-06-26 16.17.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/38866/9832001a-02b0-4443-c915-07ead20f771a.png">

https://www.microsoft.com/ja-jp/learning/azure-skills-training.aspx

日本語コンテンツの中に「AWS の専門家のための Microsoft Azure」というドンピシャなコンテンツがありましたので、今回はこちらを選択しました。

そこそこコンテンツにボリュームがあり、予想学習時間は16〜24時間となっています。効率的に学習をすすめるには全体をざっと流し、知りたいところを深ぼっていくのがよさそうです。関連リンクがたくさん貼られていますので、ググらなくても詳細情報にたどり着けるます。Azureの前提知識があったため、私が実際にかかった学習時間は8時間程度でした。

## Let's Start！
まず最初に、

* [microsoft learning accountの取得](https://openedx.microsoft.com/register)　
* [無料のAzureアカウントの取得](https://azure.microsoft.com/ja-jp/free/)

の２つが必要となります。それぞれのサイトでユーザ登録が完了するとコースが受講できるようになります。

学習中の画面は左に目次、真ん中にコンテンツが表示されます。

<img width="1203" alt="スクリーンショット 2017-06-27 15.42.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/38866/66b49ed8-fd3d-2351-49e7-adaa9a13242d.png">

学習コンテンツはテキスト、ビデオ、ハンズオンで構成されています。文字ばかり読んでいると眠りの彼方にいってしまいますが、適度なタイミングでビデオ、ハンズオンが刺激を与えてくれます。実際、操作してみるのが一番理解が早いのでハンズオンが随所にあるのはとても嬉しいですね。

## AWSとの比較
タイトル通り、特に前半はAWSと比較してAzureのサービスや特徴が説明されています。用語、料金体系、サブスクリプションなど、最初は理解しづらい内容がAWSとの比較で説明されているのが良いですね！

<img width="706" alt="スクリーンショット 2017-06-27 15.54.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/38866/7df9b845-2d61-abbc-4ce3-b5801c44a339.png">

Azureのネットワーク速度は [azurespeed.com](http://azurespeed.com/) で確認できるんですね。*Test network latency from your IP location to Azure datacenters around the world.* とあるので、アクセスしている端末の近いロケーションから各リージョンへのレーテンシーが計測できるようです。元ネットワークエンジニアとしてはついついこのあたりに興味がわいてしまいます。

## 理解度チェック

最後に最終評価があり、理解度を確認することができます。

<img width="714" alt="スクリーンショット 2017-06-27 16.10.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/38866/9602dfcf-3942-f33c-cc15-7a66c4f13fe3.png">

私のスコアは80%でした。サービスのURLを問われる問題などもあり、なかなか難しかったですがなんとか合格点はクリアできました（ほっ）

## まとめ

* AWSと比較してAzureが説明されているので、AWSが知っている人だったら理解が早い（と思う）
* AzureもAWSも進化が激しいので、情報が陳腐化しないように常にアップデートし続けてほしいです（いくつか古い情報がありましたので今後のアップデートに期待！）
* 英語コンテンツにはBig Data系もいくつかありますので、早く日本語化されるとよいですね
* Azureの強みの一つでもあるAI系、ML系のコンテンツにはまだないですので、このあたりもハンズオン付きでリリースされると嬉しいです
* AWSは知ってるけどAzureってどうなんだろ〜って方は是非やってみてはいかがでしょうか！？
URLの動画を再生する Swift3 

![on.gif](https://qiita-image-store.s3.amazonaws.com/0/135794/3b8ae589-247d-aeff-41cc-bff3d8af2dd7.gif)

# 実装

```swift

import UIKit
import AVFoundation


//クロージャーを多用 }()
class ViewController: UIViewController {

    
    //動画のURLを定義
    var url: URL = {
        var url = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
        return url!
    }()

    
     /*
     下記から動画画面の実装
     */
    
    //AVURLAssetは持ってないから
    //AVAssetResourceLoaderDelegateをしないといけないからextensionする
    lazy var asset: AVURLAsset = {
        var asset: AVURLAsset = AVURLAsset(url: self.url)
        asset.resourceLoader.setDelegate(self, queue: DispatchQueue.main)
        return asset
    }()


    lazy var playerItem: AVPlayerItem = {
        var playerItem: AVPlayerItem = AVPlayerItem(asset: self.asset)
        return playerItem
    }()

    
    lazy var player: AVPlayer = {
        var player: AVPlayer = AVPlayer(playerItem: self.playerItem)
        player.actionAtItemEnd = AVPlayerActionAtItemEnd.none
        return player
    }()

    //動画の画面
    lazy var playerLayer: AVPlayerLayer = {
        var playerLayer: AVPlayerLayer = AVPlayerLayer(player: self.player)
        playerLayer.frame = UIScreen.main.bounds
        playerLayer.backgroundColor = UIColor.clear.cgColor
        return playerLayer
    }()

    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.layer.addSublayer(playerLayer)
        player.play()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

extension ViewController : AVAssetResourceLoaderDelegate {
}
```

# ソース

[GitHub](https://github.com/Ryosuke-Hujisawa/Movie-playback-AVFoundation-Swift3)

[URLの動画を再生する Swift3](http://off.tokyo/blog/2017/06/27/url%E3%81%AE%E5%8B%95%E7%94%BB%E3%82%92%E5%86%8D%E7%94%9F%E3%81%99%E3%82%8B-swift3/)
PyQやってみた

##PyQとは？
株式会社ビープラウドが提供しているPythonを勉強するための有料サービスです(https://pyq.jp/)

###良いところ
作業が全てブラウザ内で完結するので環境設定が必要なく、どのパソコンからでも勉強出来ます。
問題、解答、エディタ、実行結果、ターミナルが全部1画面で見れます。（ターミナルは権限に制限があります。）受講項目は基本的なプログラミングの学習から本格的なWebアプリ制作まで揃っているため、初心者から上級者まで対応しています。
↓作業画面(2017年6月27日時点)
![スクリーンショット 2017-06-21 18.35.02.png](https://qiita-image-store.s3.amazonaws.com/0/187011/d743fb5b-4ad4-78d4-b9b2-161d095beb29.png)



###注意点
逆に環境設定が説明されないので、自分のPCで実行環境を作るのは自力でやるしかありません。
Djangoの項目から説明がわかりにくくなるため公式のドキュメントと合わせて学習する必要があります。https://www.djangoproject.com/

###こんな人に向いている
・がっつりプログラミングの勉強がしたい人
・ECサイトの制作に興味がある人
・業務でPythonを使う人
<br>


<hr>
###使ってみた感想
この手の勉強サービスの中ではかなり親切で使いやすい設定になっていました。
問題数は多いので全部やるには結構な時間はかかりますが、クリアした項目がわかるように表示されるため、達成感はありました。プログラミング経験者なら前半は問題なく解けると思います。後半はDjangoフレームワークを利用した専門的なWebアプリ制作をしますが、前半ほど多く解説がされていないので解くのが難しいと感じました。PyQの応用科目には開設途中のコンテンツも多く、今後はさらにWebプログラミングの学習コンテンツも追加されていくそうです。
Swift3でインジケーター実装

`removeFromSuperview()`でインジケーターを消す


```ViewController.swift

import UIKit

class ViewController: UIViewController {

    //スピナー画面
    lazy var spinnerView: SpinnerView = {
        var spinnerView = SpinnerView()
        spinnerView.frame = UIScreen.main.bounds
        spinnerView.spinner.center = self.view.center
        return spinnerView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(spinnerView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
```


```SpinnerView.swift

//ここはただのスピナー以外の機能はない？

import UIKit

class SpinnerView: UIView {

    //MARK: - Accessors

    lazy var spinner: UIActivityIndicatorView = {
       
        var spinner = UIActivityIndicatorView(activityIndicatorStyle: .white)
        
        spinner.startAnimating()
        
        return spinner
    }()
    
    //MARK - Init
    
    override init(frame: CGRect) {
        
        super.init(frame: frame)
        
        backgroundColor = UIColor.red
        
        addSubview(spinner)
    }
    
    required init?(coder aDecoder: NSCoder) {
        
        super.init(coder: aDecoder)
    }
    
}

```

# ソース

[GitHUb](https://github.com/Ryosuke-Hujisawa/spinnerSwift3)


# 実行


![on.gif](https://qiita-image-store.s3.amazonaws.com/0/135794/1b559eac-38ad-5aef-c276-ec1674b87903.gif)
onamae さんのドメインがある日、「DNSが見つかりませんでした。」と言ってくる

onamae さんで、ドメインをとりまして、Web サイトを運用しておりました。2週間くらいたったら、

**DNS アドレスが見つかりませんでした。**

となりました。

インフラのことがよくわからない僕は以下のようなことをして様子を確認しました。


# dig

```bash
$ dig sample.com
```

本来あるはずの ANSWER SECTION が空です。

```
;; ANSWER SECTION:
sample.com.	792	IN	A	>>空<<
```

# whois

お名前の DNS 設定を確認するとちゃんと入ってる。

```bash
$ whois sample.com


Name Server: ns-cloud-c1.googledomains.com
Name Server: ns-cloud-c2.googledomains.com
Name Server: ns-cloud-c3.googledomains.com
Name Server: ns-cloud-c4.googledomains.com
```

# dig, nslookup with name server

ネームサーバーつけて、dig と nslookup 見てみる

```bash
$ dig @ns-cloud-c1.googledomains.com sample.com
```

あれ、ちゃんとある

```bash
;; ANSWER SECTION:
sample.com.	21600	IN	A	>>正しいIPがある<<
```

```bash
$ nslookup sample.com ns-cloud-c1.googledomains.com

Address: >>正しいIPがある<<
```


:thinking: 

なんだこれは。


# 神様がおしえてくれました


となりの席にいらっしゃいます神様が

「お名前からメールきてるとおもうよ」

確認してみますと...

```
※本メールに心当たりの無い方は、本メールの破棄をお願いいたします。

本メールアドレスは送信専用となります。本メールアドレス宛への返信は受付
できませんのでご了承ください。
────────────────────────────────── 
■メールアドレスの有効性認証■
────────────────────────────────── 

本メールはICANNのWhois情報正確性確認方針に基づき、レジストラより
ドメイン名の登録者（Registrant）にご登録いただいているメールアドレスへ
送信しております。

ドメイン登録者情報のメールアドレスとして情報が正しい場合は、期日までに
以下URLへアクセスしてください。
```

来てた。しかも、ちょうど期限を昨晩で過ぎている。

悲しい。

とりあえず、ダメモトで、URLにアクセスしましたら、その後、数時間で復旧しました。（その旨メールも届きました。）


ありがとうございました。
〜プログラミングとは〜　プログラミング入門(1)

# プログラミングとは
プログラミングとは

コンピュータのプログラミング（英: programming）とは、コンピュータプログラムを作成することにより、人間の意図した処理を行うようにコンピュータに指示を与える行為である。
引用元:wikipedia

あ～なるほど！
そうゆいうことかとおもったあなたはおそらく天才です。
この記事を読むのを今すぐやめましょう笑

たいていの人は
このように説明されてもあまりイメージができないと思います。

では、なんなのか
例えばあなたがテストの平均点を知りたいとしましょう。
どうやって計算しますか？
トータルの点数　÷　教科数　＝　平均点
ですね

え？
この計算式がわからない？？？
残念ながらあなたは、プログラミングを学ぶには向いていないようですね。

逆にこの計算式が出てきたあなたは、プログラミングを簡単に理解できます。

プログラミングとはこのような計算のプログラムをパソコンに対して指示することです。
このパソコンに指示を与えることがプログラミングなのです。

ではどのように指示をあたえるんでしょうか？
人ならば、指示したい人に対してテストの平均点を出して！言えばいいでしょう
同じようにパソコンに対してはプログラミング言語という機械の言葉で話してあげればいいのです。

ではプログラミング入門(2)の[プログラミング言語とは](http://qiita.com/tech-caddiee/items/247df8e2a12cbddac6c0)へ行ってみましょう！
Docker 初心者 | Docker for Mac | コンテナのディレクトリをローカルにマウントする



# 検証コマンド

```
$ docker run -v ~/:/some_mount_dir busybox touch /some_mount_dir/example.txt
```

## 解説

- `docker run`
 - コンテナを走らせる
- `-v ~/:/some_mount_dir`
  - ローカルの `~/` に Dockerコンテナの `/some_mount_dir` をマウントする
- `busybox`
  - てきとうなイメージ
- `touch /example.txt`
  - Docker コンテナにファイルを作成する

# 確認

コマンドを実行すると、コンテナはファイルを作成して終了する。
その後、ローカルにファイルが作成されているのが分かる。

```
$ ls ~/example.txt
~/example.txt
```
# 設定

Preference > File Sharing から、マウント可能ディレクトリの設定が出来る。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/d5dc133e-0828-b82a-6bc7-70a1b9fcf2e9.png)

# 参考

- [Dockerizing a Ruby on Rails Application - Semaphore](https://semaphoreci.com/community/tutorials/dockerizing-a-ruby-on-rails-application)
- [The path /var/lib/kubelet/ is not shared · Issue #14 · vyshane/kid](https://github.com/vyshane/kid/issues/14)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Ethereumのgenesis.jsonファイル

Ethereumを勉強する場合の最初のステップとなる。プライベートネットの構築の際に使用するgenesis.jsonファイルの中身です。
2017年6月27日現在このファイルで送金できることを確認していますが、バージョンアップなどにより正常に動作しなくなることが考えられます。

```genesis.json
{
"config": {
        "chainId": 10,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
          },
"alloc"      : {},
"coinbase"   : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData"  : "",
"gasLimit"   : "0x2fefd8",
"nonce"      : "0x0000000000000042",
"mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp"  : "0x00"
}
```
教科「情報」の専任教員と将来の夢「ITエンジニア・プログラマー」の現状

## はじめに
滋賀県育ち千葉県民としてこれを記事にしないのは無いだろうと思い記事にしました。
IT技術と言えば「言語」とか「資格」とか「IOT」とか着目されがちですが、
今回は教科「情報」という技術の現状と今後について書きます。
## 教科「情報」とは
2003年に新設された教科。
<font color="OrangeRed">2024年度から大学入学希望者学力評価テスト（仮称）の入試科目になる予定です。</font>
なお、教科「情報」は高度情報化社会に対応した人材を育成するために、情報の収集・分析から
発信までを総合的に学ぶ教科であり、単にパソコン操作を教える教科ではありません。
## 将来の夢
2017年4月にネットやニュースで話題になりましたが、男子中学生と男子高校生の
将来の夢の一位は
「ITエンジニア・プログラマー」
です。
IT業界にとって、明るいニュースです。
## 現状
千葉県の担当教員数は327人であり、専任教員率は<font color="OrangeRed">7%</font>。つまり約23人。
滋賀県の担当教員数は174人であり、専任教員率は<font color="OrangeRed">2%</font>。つまり約3人。

これが現状です。
全国だと20%程度です。
兼任教員の方は数学と情報、理科と情報というように授業を行っています。
## 問題
最初に書きます。兼任教員の方は頑張っています。故に責めるのは筋違いです。
ただでさえ常識外れに激務なので、複数の教科に全力を出すのは厳しいと思います。

専任教員でない場合に発生しうる問題は

+ 専門知識の不足
+ 片手間になる

です。

「ITエンジニア・プログラマー」を目指す生徒が多い中、この問題が発生するリスクに対して
対策を打たないのは疑問が生じます。
## 専任教員が少ない理由
おそらくは下記だと推測しています。

+ 情報「しか」できない(やってくれない)教員と情報「も」できる(やってくれる)教員なら後者を採用する
+ 専任の場合、教員の授業数の確保ができない
+ 情報は入試科目ではない
+ 非常勤講師、臨時的採用教員、TAで教科をカバーしている
+ 教科「情報」教員免許取得のカリキュラムが他教科の免許取得を伴う

あくまで推測です。
## 今後
2020年には

+ 大学入学希望者学力評価テスト（仮称）
+ 学習指導要領の改訂

が控えています。
2024年度に入試科目になるにせよならないにせよ
専任教員を増やさざるを得ない状況になりつつあります。

また、大学入学希望者学力評価テスト（仮称）の全貌はまだ見えませんが、
入試科目になるのであれば、それは大きな営業のチャンス（リスク）になる
可能性があります。
中学生や高校生に向けた教科「情報」の教育事業といったことも可能になる
かもしれません。
## さいごに
自分は教科「情報」は優れたIT人材を生み出すためのものだとは思っていません。
教科「情報」は情報格差（デジタル・ディバイド）の差を縮め、
メディア・リテラシーを身につけるものだと思っています。

というのも、「ITエンジニア・プログラマー」を志すのであれば、
最初に情報を理解し制御し活用する力を身につけて欲しいからです。

そのような授業・指導を行えるような教科「情報」になればと思います。
## 参考
<a href="http://techwave.jp/archives/students-future-dream-by-sonylife.html">中高生 将来の夢、男子1位は「ITエンジニア・プログラマー」</a>
<a href="https://mainichi.jp/articles/20161006/k00/00e/040/269000c">高校必修教科「情報科」専任教員は２割</a>
<a href="http://edutmrrw.jp/2017/innovation/0313_2020education">2020年 次期学習指導要領</a>
flexboxで可変要素が親要素ぶち抜いた時の対策

flexboxで2カラムレイアウト実装の際ににつまづいた時の備忘録

## 現象
* flex:1;を指定したflex-itemが親要素のwidth指定を無視して表示される 
* 左のカラムのwidht:200px;の指定が無視される  

![スクリーンショット 2017-06-27 15.20.25.png](https://qiita-image-store.s3.amazonaws.com/0/113074/c1089538-25f5-66af-dea3-87bda16d692a.png)

```html
    <div class="flex">
      <div class="col-1"></div>
      <div class="col-2">
        <p>糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト糞長いテキスト</p>
      </div>
    </div>
```

```css
.flex{
  display: flex;
  width: 1080px;
}

.col-1{
  width: 200px;
  background-color: rgb(42, 152, 138);
  padding: 8px;
  
  flex-shrink: 0;
}

.col-2{
  flex: 1;
  background-color: rgb(236, 161, 48);
  padding: 8px;
}

.col-2 p {
  font-size: 36px;
  color: #fff;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
```

##対策
* 可変要素にmin-width:0;を指定

```css
.col-2{
  flex: 1;
  background-color: rgb(236, 161, 48);
  padding: 8px;
  min-width: 0; //追加
}
```

![スクリーンショット 2017-06-27 15.29.19.png](https://qiita-image-store.s3.amazonaws.com/0/113074/0a79f34b-84c0-c8e9-6ff4-f352ff4dfb23.png)



flexbox便利なんだけど色々落とし穴が・・・主に__IE11__とか__IE11__とか
Pythonistaへの道のり

# **はじめに**
- Python学習に**実際に使用している**サービス、ナレッジ、技術書などをメモしていこうという企みです
- 良いサービス、良い学習方法があれば教えて頂けると幸甚でございます


# **学習に使用しているもの**
- 公式ドキュメント
- Python学習サービス
- Python技術書
- 問題集サイト

# **公式ドキュメント**
## [Python 3.6.1 ドキュメント](http://docs.python.jp/3/index.html)
### [Python チュートリアル](http://docs.python.jp/3/tutorial/index.html)
- Python の言語仕様と仕組みについて、基本的な概念と機能をざっと紹介

### [Python 標準ライブラリ](http://docs.python.jp/3/library/index.html)
- Python とともに配付されている標準ライブラリについての説明

### [Python 言語リファレンス](http://docs.python.jp/3/reference/index.html)
- Python 言語の文法と、 “コアとなるセマンティクス” について説明

### [PEP8](http://pep8-ja.readthedocs.io/ja/latest/)
- Python コードのスタイルガイド

# **Python学習サービス**
## [PyQ](https://pyq.jp/)
- ビープラウドが提供しているPython学習サービス
- 月額2980円から利用可能

# **Python技術書**
## [Pythonチュートリアル 第3版 ](http://amzn.to/2th0EAf)
- [Python 3 エンジニア認定基礎試験](https://www.pythonic-exam.com/exam/basic)の公式教材
- 内容は[Python チュートリアル](http://docs.python.jp/3/tutorial/index.html)と同じ

## [Effective Python ―Pythonプログラムを改良する59項目](http://amzn.to/2th67Hm)
- 入門書の次に読み進めるPython本

# **問題集サイト**
## [HackerRank](https://www.hackerrank.com)
- 色々な問題、アルゴリズムをPythonで解くことができる

## [CheckiO](https://checkio.org/)
- 色々な問題があり、他人の解法も確認できる
- 一部日本語対応している

## [言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)
- 色々な問題があり、また色々な解法がQiita等でも公開されているのでそれらを見るだけでも役に立ちます！
- 特に @segavvy さんは完走されているので見習いたいところです
  - [素人の言語処理100本ノック:まとめ](http://qiita.com/segavvy/items/fb50ba8097d59475f760)
Bluemix の Cloudant に csv ファイルをアップロードする

関連情報
[Bluemix の Cloudant に curl でアクセスする](http://qiita.com/ekzemplaro/items/29b95d5fc8fc449bb554)

 csv のアップロード

```bash
URL="https://44b508dd-346a-44c8-85b7-79d184aaf02f-bluemix:b92b6187dfe7c1fcb97c88ea2c0ce5015eee6829c5bb74fbb148e5aa8cfba362@18b508dd-346a-44c8-85b7-79d184aaf02f-bluemix.cloudant.com"
#
curl -X DELETE $URL/csv
curl -X PUT $URL/csv
curl -X PUT $URL/csv/tochigi/cities.csv --data-binary @cities.csv -H "Content-Type: text/plain; charset=utf-8"
curl -X GET $URL"/_all_dbs"
#
```

Bluemix の　コンソールで見た状況

![cloudant_csv_jun2701.png](https://qiita-image-store.s3.amazonaws.com/0/179446/953278e8-2b61-b390-6496-a1f887ebba8e.png)

CSV　の　ダウンロード

```bash
URL="https://44b508dd-346a-44c8-85b7-79d184aaf02f-bluemix:b92b6187dfe7c1fcb97c88ea2c0ce5015eee6829c5bb74fbb148e5aa8cfba362@18b508dd-346a-44c8-85b7-79d184aaf02f-bluemix.cloudant.com"
#
curl -X GET $URL"/csv/_all_docs"
echo ""
curl -X GET $URL"/csv/tochigi/cities.csv" > cities.csv
```

テストに使った csv

```csv:cities.csv
t1271,千葉,59178,2003-9-21
t1272,勝浦,47215,2003-10-15
t1273,市原,83654,2003-6-14
t1274,流山,74251,2003-9-9
t1275,八千代,42516,2003-8-4
t1276,我孫子,35987,2003-1-21
t1277,鴨川,81256,2003-7-23
t1278,銚子,29374,2003-10-26
t1279,市川,85613,2003-2-17
```
node_modulesの参照とinstanceof

instanceofはプロトタイプを`===`演算子で比較するので、別の`node_modules`を有するディレクトリからimportすると期待通り動かない、という話です。

https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/instanceof



`npm install`で外部のパッケージをインストールすると直下の`node_modules`にダウンロードされその中のものが参照されます。

```
npm install some-package
```

```js:test.js
import SomePackage from 'some-package'

```

ここで、`some-package`自体を一時的に変更したい事案が発生し、`some-package`のソースをPULLしてきて参照先を相対パスに変更しました。

```js:test.js
...
import SomePackage from '../some-package'
```

するとSomePackage内で読み込んでいる別の外部パッケージ（具体的には[selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver)）の中でinstanceofを使っているところがエラーでこけました。

呼び出し元とエラーは下記のような感じです。

```js
return this.driver.wait(until.elementLocated(locator), this.waitElementTimeout)
```

```
Wait condition must be a promise-like object, function, or a Condition object
```

`until.elementLocated(locator)`の返り値は`WebElementCondition`なので本来[この部分](https://github.com/SeleniumHQ/selenium/blob/6907a129a3c02fe2dfc54700137e7f9aa025218a/javascript/node/selenium-webdriver/lib/webdriver.js#L931)でIF文がtrueになるはずですが、同じクラスでも別の参照なので`instanceof`がtrueにならずエラーになっていたようです。

自身のnode_modulesからではなく、独自にnode_modulesを持った'../some-package'からimportすると、'SomePackage'の中でインポートされる`import webdriver from 'selenium-webdriver'`は`../some-package/node_modules`の中を参照するのはなんとなく知っていたのですが、`some-package`側ではwebpackでes6から変換していて、`selenium-webdriver`はwebpackでexternalsに指定してあったので、しばらく気づきませんでした。instanceofがprototypeの同一性を比較してるという話もあまり意識してませんでしたね。

npmに公開してあるライブラリを変更したい時、たまに、この相対パスで外側のライブラリを読む手法を一時的に使っていたのですが、気をつけないといけないですね。
アプリケーションインストール時のエラー“0x8009000b ”

# 概要
Windows 10 にバージョンアップしたPCのドメインユーザーからアプリケーションをインストールしたところ以下のエラーが発生しました。

> Failed to decrypt using provider 'MyUserDataProtectionConfigurationProvider'.
プロバイダからのエラー メッセージ: 指定した状態で使用できない無効なキーです。
(HRESULT からの例外: 0x8009000B)

このアプリケーションはASP.NETによって構築されており、DPAPIによって構成ファイルが暗号化されています。

# 原因

以下のリンクから、データの暗号化に使用したものと異なるアカウントでアプリケーションを実行すると、DPAPI 鍵が保管されているユーザー ストアに ASP.NET からアクセスできないため"0x8009000B"エラーが発生する。

[How To: DPAPI を使用して ASP.NET 2.0 内の構成セクションを暗号化する方法](https://msdn.microsoft.com/ja-jp/library/ff647398.aspx)

# 対策

ローカルユーザーでログインをし直して、再インストール。

以上。
Selenium WebDriverをPythonで動かしているときにファイルの選択のsend_keysでフリーズする【PhantomJS】

# <i class="fa fa-graduation-cap" aria-hidden="true"></i>:checkered_flag: 結論

(少なくとも)
`input`タグの`display`が`none`の場合、うまくファイルを設定できない。

なので、ファイルを指定する前に、styleをいじって可視化してやるとうまくいく。

```py
driver.execute_script("document.getElementsByName('datafile')[0].style.display = '';")
```

# <i class="fa fa-cogs"></i>:gear: 検証環境

* Linux(調べるとよくWindows環境が出てきます)
* Python 2.7.5
* selenium (2.53.6)
* phantomjs 2.1.1


3系じゃないのとかHeadless Chromeじゃないんですかとかは気にしないで。

検証サイトは
[`<INPUT type="file">`－HTMLタグリファレンス]
の`input`を使わせてもらいます。

# :writing_hand: コード

```py:成功するやつ
from selenium import webdriver
from selenium.common.exceptions import TimeoutException

if __name__ == '__main__':
    try:
        driver = webdriver.PhantomJS()
        driver.get('http://www.htmq.com/html/input_file.shtml')
        elm = driver.find_element_by_name("datafile")
        print('get')
        elm.send_keys('./test.jpg')
        print('send')
    except TimeoutException as e:
        print(e)
    finally:
        driver.quit()
```


```py:失敗するやつ
from selenium import webdriver
from selenium.common.exceptions import TimeoutException

if __name__ == '__main__':
    try:
        driver = webdriver.PhantomJS()
        driver.get('http://www.htmq.com/html/input_file.shtml')
        # new!
        driver.execute_script("document.getElementsByName('datafile')[0].style.display = 'none';")
        elm = driver.find_element_by_name("datafile")
        print('get')
        elm.send_keys('./test.jpg')
        print('send')
    except TimeoutException as e:
        print(e)
    finally:
        driver.quit()
```

この例では正常に動くものをわざと動かないようにしている。
翻って、失敗するもの=`style.display = 'none'`なものはこれを取り除かないといけない。


```py
driver.execute_script("document.getElementsByName('datafile')[0].style.display = '';")
```

***

遭遇したサイトは隠したinputを内包したdivでボタンを作っていた。
手動でもSeleniumIDEでも問題なく動いていたので、問題の特定にかなり手間取った…


[`<INPUT type="file">`－HTMLタグリファレンス]:http://www.htmq.com/html/input_file.shtml
gitbook　ページ遷移ができない問題を解決したメモ

$ gitbook ls #gitbookのバージョンを確認
　→ バージョンが3以上だとページ遷移がうまくいかないバグがあるようです。
私は3.2.2で実行したところ、ページ遷移ができず焦りました！

以下のように、3以下のバージョンをfetchして、
buildの際に指定することで無事にページ遷移を確認することができました。

$ gitbook fetch 2.6.7
$ gitbook build --gitbook=2.6.7

参考：
https://github.com/GitbookIO/gitbook/issues/1527