OmniAICreator/Qiita-1.07M huggingface dataset:
Python Djangoで写真のExif情報を取得する方法

Python Djangoで写真のExif情報を取得する方法は
下記のサイトで詳しく記載されている。

この二つのサイトを参考にすれば
GPSの情報を無事に引き出せるようになります。

https://github.com/tody411/PyIntroduction/blob/master/lib/pil_exif.md

https://www.lifewithpython.com/2014/12/python-extract-exif-data-like-data-from-images.html
GitHubで refs から辿れなくなったコミットは消えているのか

# まとめ

パスワードとか入ったファイルをコミットしちゃった時の対処で「git rm じゃ駄目、git filter-branch 使え」という記事を何度か目にしてる。わかってる人はわかってると思うけど補足。

* git rm して commit しても履歴には残ってる
* git filter-branch でローカルのrefsから辿れる履歴から消すことはできる
  * ローカルリポジトリには commit は残ってるので reflog から辿って戻せる
* push してたら force push してもリモートリポジトリには残ってる
  * force push するまでに他の人が fetch してなかったとしても取り出せる可能性がある

セキュリティの観点では最後のが気になると思うので、リモートが GitHub の場合に実験してみる。

# 準備

## 「パスワード」が入ったファイルをプッシュする

```
$ echo "secret password" > password.txt
$ git add password.txt
$ git commit -m "add password.txt"
[master 661598e] add password.txt
 1 file changed, 1 insertion(+)
 create mode 100644 password.txt
$ git rev-parse HEAD
661598e05d5e5faef7c1fc75a4f3c5a2c88368a1
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 305 bytes | 305.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:yoichi/test_fetch_sha1.git
   43fe66d..661598e  master -> master
```

## filter-branch して force-push

```
$ git filter-branch --tree-filter "rm -f password.txt"
Rewrite 661598e05d5e5faef7c1fc75a4f3c5a2c88368a1 (2/2) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten
$ git push origin master --force
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 196 bytes | 196.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:yoichi/test_fetch_sha1.git
 + 661598e...7568dd0 master -> master (forced update)
```

# clone し直して checkout

clone し直した時、 refs から辿れないコミットは取得されない。でもこれはリモートで消えていることの根拠にはならない。

```
$ git clone git@github.com:yoichi/test_fetch_sha1.git
Cloning into 'test_fetch_sha1'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 1), reused 3 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
Resolving deltas: 100% (1/1), done.
$ git checkout 661598e05d5e5faef7c1fc75a4f3c5a2c88368a1
fatal: reference is not a tree: 661598e05d5e5faef7c1fc75a4f3c5a2c88368a1
```

# fetch sha1

git fetch で SHA1 の値を与えても弾かれる。でもこれはリモートで消えていることの根拠にはならない。

```
$ git fetch origin 661598e05d5e5faef7c1fc75a4f3c5a2c88368a1
error: Server does not allow request for unadvertised object 661598e05d5e5faef7c1fc75a4f3c5a2c88368a1
```

# GitHub の commit のページを開く

あ、見えた

https://github.com/yoichi/test_fetch_sha1/commit/661598e05d5e5faef7c1fc75a4f3c5a2c88368a1

![スクリーンショット 2019-03-03 14.23.15.png](https://qiita-image-store.s3.amazonaws.com/0/64323/f8a76d84-d95b-b0e6-7470-9f1d2d64330d.png)

# じゃあどうすればいいの？

履歴から消すことは二の次で、誤ってプッシュしてしまった情報自体を使えないものにする（パスワード変更するとか）のが第一です。
以下のヘルプの「Warning」のところも参照のこと
https://help.github.com/en/articles/removing-sensitive-data-from-a-repository
[ruby] 戻り値が配列の場合の挙動

# 背景

戻り値が配列の場合、その取得部分ではどのように挙動するのか。
とても単純で基礎的なことですが、「あれ、実際にどう挙動するんだろう」と一瞬わからなくなったので、覚書として残しておく。

# サンプルコード

```test.rb
def test
  [1, 2, 3]
end

a, b, c = test

d = test

puts "a = #{a}"
puts "b = #{b}"
puts "c = #{c}"
puts "d = #{d}"
```

# 実行結果

```
a = 1
b = 2
c = 3
d = [1, 2, 3]
```
Rustを3時間勉強したらわかること

僕が先に3時間分くらい勉強しときました。大体こんな感じっていうのと、読んでよかった記事のリンクを貼っとくので、3時間分くらいショートカットしましょう！

## どんなもの？
速いし、並行性もいい感じだし、安全なものが作れる。安全じゃない書き方をすると、コンパイラがちゃんと怒ってくれて、さらに親切なアドバイスをくれる。

- [まえがき - The Rust Programming Language](https://doc.rust-jp.rs/book/second-edition/)
    - Rustの日本語のドキュメント。これがあれば英語が苦手な僕でも勉強できそう！無料で！
- [Rustは何が新しいのか（基本的な言語機能の紹介） - いもす研 (imos laboratory)](https://imoz.jp/note/rust-functions.html)
    - Rustのメモリ管理までの歴史やRustの特徴的な言語仕様を説明してくれてる。難しい。


### エラーの例

```shell
⋊> cargo run
   Compiling variables v0.1.0 (/Users/yujiroarai/Projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: make this binding mutable: `mut x`
3 |     println!("The value of x is: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable
```

## 何ができるの？
コマンドラインツールもwebアプリもWebAssemblyもラズパイで動くものも作れる。なんでもできる。

- [RustでシンプルなWebサーバー | Then go talk to a wall](https://www.yo1000.com/rust%E3%81%A7%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA-web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC)
    - HyperっていうのがWebアプリを作るときのデファクト？(2019.01.14の記事)
- [RustでCLIツールを作り始めてみた](https://blog.mamansoft.net/2018/08/06/rust-clitool-create/)
    - Goみたいにシングルバイナリを作ってくれるから、コマンドを配布した先にRustの環境がなくてもOK！



## こんなとこでつかってる

- npm: レジストリサービス内のCで書いたボトルネックになってるとこを書き換えてる
- Cloudflare
- VOYAGE GROUP: ログ収集ツール
- Figma: real-time multiplayer syncing server
- Mozilla: Servo browser engine, 
    - [Users - Rust programming language](https://www.rust-lang.org/production/users)
- Dropbox
    - [[翻訳] Rustの正式リリースから１年を振り返って（米Rust公式ブログより、DropboxやFirefoxの事例、開発状況やコミュニティの動向など） - Qiita](https://qiita.com/tatsuya6502/items/00612dbc26442e43783d)


## 0からhello worldまで

```shell

# インストール（rustupをインストールする）
$ curl https://sh.rustup.rs -sSf | sh
$ source $HOME/.cargo/env # パスを読み込み

# インストールできてるか確認（バージョンが表示されればOK！）
$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

# ソースコード作成
$ vi main.rs
fn main() {
    println!("Hello, world!");
}

# コンパイル
$ rustc main.rs

# 実行
$ ./main
Hello, world!
```

## 周辺ツールはどんな感じ？

デフォルトで色々揃えてくれてる！モダンな開発環境がデフォルト。

- Cargo： 依存関係の管理・ビルドツール
- Rustfmt： コードフォーマッター
- Rust Language Server： IDEでエラー表示とコード補完ができるようにする
- rustup： Rubyのrbenvとか、nodejsのnみたいなRustのバージョンと関連するツールを管理するツール

## Rustが好きになる記事

- [RustとDNSの1年 | POSTD](https://postd.cc/a-year-of-rust-and-dns/)
    - 愛されてるなー

## Goと比較してる記事もよく見る

- [Rust なのか Go なのか | Mastering Python](https://python.ms/sub/misc/rust-or-go/#%E5%9E%8B)
- [Go言語がダメな理由 | POSTD](https://postd.cc/why-go-is-not-good/)

## 終わり

もうちょっと勉強したら、もっと良い記事書きます！
【Python】参照先の移り変わりを頑張って理解したい【LeetCode】

#はじめに
最近LeetCodeというサイトでプログラミングの問題を解き始めました。
しかしながら、さっそく2番目の単純リストを用いた足し算問題でつまずいてしまう始末。
きちんと理解するためにQiitaで自分なりに考えたことをアウトプットしとこう。と思った次第です。
[問題へのリンクはこちら](https://leetcode.com/problems/add-two-numbers/)

#本題
##答えを見ながら作った回答

```python:Solution.py
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        dummyHead = ListNode(0)
        current = dummyHead
        carry = 0
        while(l1 is not None or l2 is not None):
            x = l1.val if l1 is not None else 0
            y = l2.val if l2 is not None else 0
            
            #足し算の結果と繰り上がりを求める
            total = carry + x + y
            carry = int(total/10)
            
            #currentを更新
            current.next = ListNode(total%10)
            current = current.next

            #次の位へ移動
            if l1 is not None:
                l1 = l1.next
            if l2 is not None:
                l2 = l2.next
        #最後の計算で繰り上がりがあればそれも反映させる
        if(carry > 0):
            current.next = ListNode(carry)
        return dummyHead.next #なぜdummyHead.nextを返したら答えが求められる？？
```
##頑張って理解する
上記のように書いて提出してみたところ、とりあえず正しく動くプログラムと判定されました。
引っかかったのは、なぜ、dummyHeadは途中で触っていないのに最後に返り値として使えるのか？というところ。
基本的にPythonは参照の代入をするはず。ということは、なにやらオブジェクト同士の参照関係が理解できていない気がする...
動作を理解すべく、順を追って考えてみます。
なお、今回は足し算のところがメインではないので、足し算についての考察はせず、画像内の7,2,8という数値は適当に入れました。ご了承ください。

```python
dummyHead = ListNode(0)
current = dummyHead
```
まず、この部分。先述したように、Pythonは基本的に参照の代入をします。
そのため、この時点でdummyHeadとcurrentが指し示しているものは同じです。
![図8.png](https://qiita-image-store.s3.amazonaws.com/0/271991/2d547bbf-876b-29ec-9d8f-0ec62ddf45ad.png)

三項演算、足し算と繰り上がりを求めている部分は特筆すべきことはありません。
続いて以下の部分に注目。

```python
#currentを更新
current.next = ListNode(total%10)
current = current.next
```
current.nextはNoneでしたが、ここでListNodeが代入されました。
続くcurrent = current.next は、やはり参照の代入です。この部分の関係性としては次のようになります。
![図9.png](https://qiita-image-store.s3.amazonaws.com/0/271991/9d9f95f2-5762-08ab-cd68-18d7fd5fd63d.png)

dummyHeadは外側のListNodeオブジェクトを指したままであり、current = current.next によって currentの参照先が一段内側のnextに変わります。
このようにcurrentの参照先を変えていきながら、dummyHeadが指し示しているオブジェクトをどんどん改造していくことができます。
最終的に、次のようになります。
![図5.png](https://qiita-image-store.s3.amazonaws.com/0/271991/2d1c249c-ee13-f361-d643-d9365e4f4687.png)

この結果、一番外側のlistNodeを指しているdummyHeadを最後にreturnしてやれば、計算結果が格納されたオブジェクトを返すことが可能になります。

#おわりに
グラフ形式で作図しようと思ったのですが、ListNodeクラスの入れ子構造を表現できるブロックを使って作図してみました。
アルゴリズム自体は簡単だったのに、私の想像力の欠如によって詰まってしまった問題でした。
精進せねば。。。
gem のversion指定 `~>` と `>=` の差

`~>`と`>=`、ともに後方互換性を指定する記号。
# 差分
## `~> x.x.x`： version`x.x.x` 以上、`x.x+1.0`未満
例：下記の場合、1.3.6以上、1.4.0

```Gemfile.
gem 'sqlite3', '~> 1.3.6'
```


```Gemfile.
gem 'sqlite3', '>= 1.3.6', '<1.4.0'
```

または

## `>= x.x.x`：version`x.x.x`以降で最新のもの
例：下記の場合、`0.8.5`以上の最新version、`0.9.x`代があれば、それらも対象になる。

```Gemfile.
gem "cucumber", ">= 0.8.5"
```


# 参考
[What is the difference between ~> and >= when specifying rubygem in Gemfile?](https://stackoverflow.com/questions/4292905/what-is-the-difference-between-and-when-specifying-rubygem-in-gemfile)
Windows10でのSublimeText3の日本語化をなるべく楽にやった


SublimeText3をインストールして日本語化させるのが割と面倒だったので自分の思いつく限りでの楽なやり方を書きます。
# ダウンロード
SublimeText3自体のダウンロードは下記リンクから
<a href="https://www.sublimetext.com/3" target="_blank">https://www.sublimetext.com/3</a>

Chocolateyを使っている方なら下記コマンドでインストールできます。

```powershell:cmd.exe(管理者として実行)
 choco install sublimetext3 
```

# Package Controlのインストール
日本語プラグインをインストールするためにPackage Controlを導入します。
下記リンクからSublimeText3のスクリプトコードをコピーします。
<a href="https://packagecontrol.io/installation" target="_blank">https://packagecontrol.io/installation</a>
![sublime3.jpg](https://qiita-image-store.s3.amazonaws.com/0/320157/b7dcc8de-e5cc-4aac-d44f-7d1a48a8d8af.jpeg)
次にSublimeText3の画面で`View > Show Console`に進み、コピーした内容を貼り付けます。![SublimeScript.jpg](https://qiita-image-store.s3.amazonaws.com/0/320157/96cedf8b-b4b1-f847-326a-cb2769a5a334.jpeg)

`Enter`キーを押して`Preferences`メニューに`Package Control`が追加されていればインストール成功です。

次に`Ctrl + Shift + P`で`Package Control`を開いて`Install`と入力
![install.JPG](https://qiita-image-store.s3.amazonaws.com/0/320157/7382ad6f-7e87-7086-9cad-ca8dd88b1343.jpeg)

`Install Package`から`Japanize`と入力して`Enter`
![japanize.JPG](https://qiita-image-store.s3.amazonaws.com/0/320157/0b635384-d946-aa65-5ba6-ddf4dec466db.jpeg)

# 表示テキスト通りにファイルを移動させる

```text:install.txt
Package Control Messages 
========================

Japanize: 
——–

Japanese menu for Sublime Text 3

Sublime Text 3の日本語化プラグインです。 
[ゆーがいぶろぐ](http://blog.huwy.org/article/292827228.html)さんの日本語化ファイルがベースです。

適用手順 
１．C:\Users\ユーザー名\AppData\Roaming\Sublime Text 3\Packages\Japanizeにインストールされている*.jpファイルを、 
C:\Users\ユーザー名\AppData\Roaming\Sublime Text 3\Packages\Default 
にコピーします。※Defaultフォルダがない場合は作成してください。 
２．コピーしたファイルをオリジナルのファイル（.jpが付かないファイル）と置き換えます。（念のため、オリジナルのファイルが有る場合は.orgなどを付けて保管しておきましょう。） 
３．C:\Users\ユーザー名\AppData\Roaming\Sublime Text 3\Packages\Japanize\Main.sublime-menu（.jpが付かない方）を、 
C:\Users\ユーザー名\AppData\Roaming\Sublime Text 3\Packages\User 
にコピーします。すると、他のプラグインで上書きされてしまっているトップメニューも日本語化されます。 
以上です。
```

これが結構めんどくさいので`powershell`でなんとかします。

```powershell:powershell
cd ~\AppData\Roaming\'Sublime Text 3'\Packages\
mkdir .\Default
cp .\Japanize\*.jp .\Default\
dir .\Default\ | rename-item -newname { $_.name -replace '\.jp','' }
```

以上でメニュー、サブメニューの日本語化終了です。
FlowTypeでオブジェクトを渡すときのプロパティの書き方まとめ

FlowTypeでオブジェクトを渡すときのプロパティの書き方による違い。

```javascript
// @flow

// a はないといけないけど、undefinedやnullでもOK
function hoge(x: { a: ?number }) {}
hoge({a:1});
hoge({a:1, b:1});
hoge({}); // bug?
// hoge({b:1});   // error
hoge({a: undefined});
hoge({a: null});

// aはあってもなくてもよい
function hoge2(x: { a?: number }) {}
hoge2({a:1});
hoge2({a:1, b:1});
hoge2({});
hoge2({b: 1});
hoge2({a: undefined}); // undefined はないのと同じ扱い
// hoge2({a: null}); // error aというプロパティがある以上numberでないといけない。

// aはないといけない
function hoge3(x: { a: number }) {}
hoge3({a:1});
hoge3({a: 1, b:1});
hoge3({}); // bug?
// hoge3({b:1}); // error
// hoge3({a: undefined}); // error aがある以上numberないといけない
// hoge3({a: null}); // error
 
// nullをゆるしちゃうぞ
function hoge4(x: { a: number | null }) {}
hoge4({a:1});
hoge4({a: 1, b:1});
hoge4({});  // bug?
// hoge4({a: undefined}); // error
hoge4({a: null}); // nullを許容することができる

// 他のがあったらだめ
function hoge5(x: {| a: number |}) {}
hoge5({a:1});
// hoge5({a: 1, b:1}); // error
// hoge5({}); // error 
// hoge5({a: undefined}); // error
// hoge5({a: null}); // error
```

`{}`が渡せちゃうのはバグっぽいけどどうなんだろうか。
実際にこまることはめったにななさそうだけど。
go-taskでサーバーのライブリロードを実現する

[go-task](https://github.com/go-task/task)の`-w`オプションを使って、HTTPサーバーでライブリロードをやろうとしたら、ちょっと工夫が必要だった。

# go-taskの-wオプション
Golang用のタスクランナー[go-task](https://github.com/go-task/task)には、[Watch](https://taskfile.org/#/usage?id=watch-tasks)機能があり、ファイルを監視して変更があったらタスクを自動実行する機能がある。

```
  foo:
    cmds:
      - go run cmd/foo/main.go
    sources:
      - internal/**/*
 ```

こんな風に書いておいて、

```
task foo -w
```
`-w`オプションをつけた状態でタスクを実行すると、`sources`に指定されたファイルに変更があった時に自動的に`go run cmd/foo/main.go`が実行される。

この機能は、「ただ指定されたコマンドを実行するだけ」で、実行中だったコマンドを終了してくれる訳ではないので、サーバーのように起動し続けるタイプのコマンドの場合は、新しくコマンドが実行される前に古いコマンドのプロセスを終了させないとプロセスが多重に起動して(あるいは起動に失敗して)おかしなことになってしまう。

# 先に起動していたプロセスを終了する
新しいコマンドを実行する直前に、プロセスを終了するようにしたい。

```
  foo:
    cmds:
      - ここで以前のプロセスが生きていたら終了したい
      - go run cmd/foo/main.go
 ```

プロセスを終了するには、`kill`コマンドを実行すれば良いが、そのためには先に実行されたコマンドのプロセスIDを知っておく必要がある。

# 起動時にプロセスIDを保存しておくようにする
コマンド実行時に、プロセスIDを保存するようにプログラム側を拡張する。保存先をコマンドライン引数で指定できるようにしておき、`go-task`以外で起動した時に問題がおきないようにする。

```golang
func main() {
	var pidFile = flag.String("pid-file", "", "Path to pid file")
	flag.Parse()

	if len(*pidFile) > 0 {
		if err := ioutil.WriteFile(*pidFile, []byte(fmt.Sprintf("%d", os.Getpid())), 0664); err != nil {
			log.Printf("[WARNING] Failed to write pid file. %v\n", err)
		}
		defer func() { // 終了時にPIDファイルをちゃんと消すようにする
			if err := os.Remove(*pidFile); err != nil {
				log.Printf("[WARNING] Failed to delete pid file. %v\n", err)
			}
		}()
	}

	// プログラムのメイン...
	...
}
```

実行中のプロセスIDは`os.Getpid`で取得することができるので、これを`--pid-file`で指定されたファイルに書き込む。書き込もうとした先にすでにファイルが存在する場合は異常な状態なので、本来はそのチェックをするべきだが、プログラムが読みにくくなるので上のコードでは省略した。deferを使って、プログラムが終了する時にPIDを書き込んだファイルを削除するようにしている。(異常終了した場合にはファイルが残る)

タスク実行時のコマンドに`--pid-file`オプションを加えれば、タスク実行時にプロセスIDがファイルに出力されるようになる。

```yaml
  foo:
    cmds:
      - go run cmd/foo/main.go --pid-file=dev.pid
```

試しに実行してみて、`cat`コマンドでpidを確認できれば成功。

```
cat dev.pid
```

これで、実行中のプロセスをKILLしたい場合は下記のコマンドでKILLできるようになった。

```
kill -TERM `cat dev.pid`
```

# 実行前にプロセスをKILLする
上の仕組みを使って、新しいプロセスを立ち上げる前に実行中のプロセスがあれば終了するようにする。

```yaml
  foo:
    cmds:
      - kill -TERM `cat dev.pid`
      - go run cmd/foo/main.go --pid-file=dev.pid
```

ただし、これだけだと初回起動時など`dev.pid`がない場合にエラーが発生してしまう。

```yaml
  foo:
    cmds:
      - cmd: kill -TERM `cat dev.pid`
        ignore_error: true 
      - go run cmd/foo/main.go --pid-file=dev.pid
```

このような記法に変更して、`ignore_error: true`を指定すると`dev.pid`が存在せずエラーになった場合でもコマンドを続行できるようになる。これでも十分なのだが、画面にエラーが出力されてしまうので、コマンドの標準出力/エラー出力の内容を`/dev/null`にリダイレクトするように設定する。

```yaml
  foo:
    cmds:
      - cmd: kill -TERM `cat dev.pid` > /dev/null 2>&1
        ignore_error: true 
      - go run cmd/foo/main.go --pid-file=dev.pid
```

これで、コマンドを連続して叩いた場合には古いプロセスを終了して新しいプロセスを立ち上げられるようになった。

# 監視対象のファイルを指定する
最後に、Watchの対象となるファイルを`sources`で指定する。

```yaml
  foo:
    cmds:
      - cmd: kill -TERM `cat dev.pid` > /dev/null 2>&1
        ignore_error: true 
      - go run cmd/foo/main.go --pid-file=dev.pid
    sources:
      - internal/**/*
```

単純に全てのファイルにしてしまうとログや`pid`ファイルなども監視対象となってしまいおかしなことになる可能性があるので注意する。

# -wオプションをつけてタスクを実行する

```
task foo -w
```

以上で、ファイルを変更すると自動的にサーバーがリロードされるようになった。
Pythonでスマホ用のページのwebスクレイピングを試してみる

# まえがき
とあるアニメの人気投票（総選挙）的な企画が始まり
ランキングをいい感じに自動取得できないかな～、という思いから
pythonでのwebスクレイピングを試してみよう！という感じで始めました。
あくまで個人的にランキング情報を見るために使用しています。

# 環境
OS: CentOS 7
Python: 3.6.7

python の BeautifulSoup というライブラリを使用して作業していきます。

# 準備
### python のインストール

```
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
# yum install -y python36u python36u-libs python36u-devel python36u-pip
# python3.6 --version
Python 3.6.7
```

### BeautifulSoup のインストール

```
# pip3.6 install beautifulsoup4
```

# html要素の取得

```
URL = "取得したいURL"
headers = {
        "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) > > AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
        }
request = urllib.request.Request(url=URL, headers=headers)
response = urllib.request.urlopen(request)
html = response.read().decode('utf-8')
```

今回はスマホ用のページの取得がしたかったので
header部分に iPhone と iOS11 のユーザーエージェントを設定しました。

requestにURLとheaderを設定し、urllib.request.urlopenでURLを開きます。

# BeautifulSoupオブジェクト生成
先ほど取得したhtmlから生成します。

```
bs = BeautifulSoup(html, "html.parser")
```

# tableタグ情報取得
ランキングをいい感じに取得します。

```
table = bs.findAll("table",{"class":"ranking_tile"})[0]
rows = table.findAll("tr")
```

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all

findAllでtableタグとclass名を設定してそれに一致するtableの情報をまるっと取得します。
さらにそこからtrタグで列ごとの情報を取得します。

# ランキングの順位取得

```
for row in rows:
     for cell in row.findAll(['td', 'th']):
          rank = cell.get_text().splitlines()
          print(rank[3] + ' : ' + rank[8])
```

列ごとにループし、カラムごとの情報を取得します。
そのままカラムを表示しようとしたら改行のせいでうまいこと表示できなかったので
改行で分割して配列に格納してから、順位とキャラクター名が入ってる要素をprintで表示しました。

# 結果
```
# python3.6 bs_test.py
1位 : ? 神○美月
2位 : ? 藤○ユリカ
3位 : ? 星○いちご
4位 : ? 大○あかり
4位 : ? 冴○きい
6位 : ? 紫○ 蘭
7位 : ? 霧○あおい
8位 : ? 有○川おとめ
9位 : ? 氷○スミレ
```

おけおけおっけ～！

# おわりに
情報解析目的ならスクレイピングでこういったランキングを取得すること自体は問題なさそうですが
最近は著作権うんぬんな話が多いので使用する場合は注意が必要かもしれません。
この辺に関して無知なので今後勉強したいと思います。

ほんとうはこのスクリプトを1日1回実行→ twitter or LINE で通知する、的なことを
やりたかったのですが、サーバーを用意する必要がありそうで手間がかかるため諦めました。
この記事書いてて思ったけど、定期的にランキング情報取得して最終的にどういう推移をしたか
調べるのも面白いかもしれません。（多分やらない）

もっといいやり方あるよ！とかここちょっと駄目なんじゃない的なご指摘等ありましたら
コメントに書いていただけると助かります。
RubyOnRailsでのCSVをDBへ読み込む方法

#RubyでのCSVのDBへの挿入の方法



今回始めてCSVを扱う機会がありましたので、情報のアウトプットと、同じような境遇の方のために書きます。


データベースへの書き込みということで、今回はseedsを使って挿入します。


###1.モデルを作成する
まず、CSVファイルに対応するカラムを持ったモデルを作ります。

###2.Seedsの作成

書式としてはこんな感じなります

**seeds.rb**


```
require 'csv'

CSV.foreach('ファイルパス') do |hoge|   # hogeは配列クラス
  モデル名.create!(DBのカラム名1:    hoge['対応するCSVのカラム名'],
                 DBのカラム名2:     hoge['対応するCSVのカラム名'],
                 ....
                 )
end

```

create!と「!」を付けているのは、書き込み途中にエラーが発生した時に、例外処理が発生するのでエラー内容が把握しやすいからです。「！」がないと単にfalseを返すだけなので、エラーが把握しにくいです。


###3.データベースへの挿入

```
$ rails db:migrate:reset
$ rails db:seed
```

以上で完了です!
初心者にオススメのNode.jsインストール方法(MacOS/Linux)

## 概要

初めて[Node.js](https://nodejs.org/ja/)を触る時、どのようにインストールするのがいいのかわからなかった記憶があるため、クリーンなPC環境から、どのように[Node.js](https://nodejs.org/ja/)をインストールするのがいいのかを順を追って書いておきます。

今回は、node v10.15.1をインストールする手順を紹介するのですが、今後エンジニアとして成長していく過程でいろんなバージョンを使うことになると思います。  
ですので、[Node.js](https://nodejs.org/ja/)のバージョンを簡単に変更できるように[nodenv](https://github.com/nodenv/nodenv)というバージョンマネージャをインストールし、[nodenv](https://github.com/nodenv/nodenv)経由で対象の[Node.js](https://nodejs.org/ja/)をインストールする手順を紹介します。

## 手順（MacOS）

1. [Homebrew](https://brew.sh/index_ja)のインストール
2. [nodenv](https://github.com/nodenv/nodenv)のインストール
3. [Node.js](https://nodejs.org/ja/)のインストール

ターミナルで実行するコマンドだけをまとめると以下のようになります。

1. `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
2. `brew install nodenv`
3. `echo "export PATH=~/.nodenv/shims:\$PATH" >> ~/.bash_profile`
4. `source ~/.bash_profile`
5. `nodenv install 10.15.1`
6. `nodenv global 10.15.1`

確認: `node --version` -> `v10.15.1` と表示されたら成功

これらについて知りたい方は下の説明とリンクしてある公式ドキュメントを参照してください。

### [Homebrew](https://brew.sh/index_ja)のインストール

[Homebrew](https://brew.sh/index_ja)は、MacOS向けのパッケージマネージャというもので、いろんなライブラリや便利なツールを以下のように簡単にインストール・アンインストールすることができるもので、多くのユーザーがいます。

`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`

### [nodenv](https://github.com/nodenv/nodenv)のインストール

[nodenv](https://github.com/nodenv/nodenv)は、Node.jsのバージョンマネージャです。Node.jsはバージョンによる差が大きいので、適宜変更できるようにしておくために[nodenv](https://github.com/nodenv/nodenv)のようなツールが存在します。

`brew install nodenv`

そして、この状態だと `node` コマンドや `npm` `npx` コマンドがまだターミナルから使える状態になっていないため、下の[Node.js](https://nodejs.org/ja/)のインストール手順を踏んでも肝心の `node` コマンドなどを実行することができません。ですので、これらを使えるようにするために、[nodenv#Understanding Shims](https://github.com/nodenv/nodenv#understanding-shims)のようにコマンドにパスを通す必要があります。

MacOSの場合、 `~/.bash_profile` ファイルのどこでもいいので、`export PATH=~/.nodenv/shims:$PATH` の1行を新しく追加し、ターミナルを再起動するか `source ~/.bash_profile` を実行します。

### [Node.js](https://nodejs.org/ja/)のインストール

`nodenv install 10.15.1` を実行してNode.jsのバージョン10.15.1をインストールします。インストールしただけでは使用するnodeのバージョンが設定されないため、 `nodenv global 10.15.1` を実行してターミナル全体でnodeの10.15.1が実行できるようにしましょう。 

`node --version` を実行したら `v10.15.1` の1行が表示されたら手順は完了です。

## 補足(Linux向け)

Linuxだと[Linuxbrew](http://linuxbrew.sh/)というHomebrewと同じようなインターフェースのパッケージマネージャが存在するので、リンク先を参照してLinuxbrewをインストールすれば、それ以降の手順はLinuxでも同様のコマンドでインストールが可能です。
3次元の散布図を補間

2次元の散布図を補間する例はたくさんあるけれど、3次元にはあまりないので。

3つの軸のどれかをX軸に選ぶのがおそらく一番簡単。

```python
import numpy as np
import scipy.interpolate as itpl
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

def show_points(points):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    for i in points:
        x, y, z = i
        ax.scatter(x, y, z, marker='o')

    ax.set_xlabel('X')
    ax.set_xlim(0, 1)
    ax.set_ylabel('Y')
    ax.set_ylim(0, 1)
    ax.set_zlabel('Z')
    ax.set_zlim(0, 1)

    plt.show()


def gen_curve(n_point):
    x = np.linspace(0, 1, n_point)
    points = np.array([x, np.sin(x * np.pi / 2), np.cos(x * np.pi / 2)]).transpose((1, 0))
    return points

def main():
    points = gen_curve(10)
    show_points(points)
    f = itpl.interp1d(points[:,0], points[:,1:3], axis=0, kind='cubic')
    x = np.linspace(0, 1, 20)
    y = f(x)
    points2 = np.hstack((x.reshape(-1, 1), y))
    show_points(points2)

if __name__=='__main__':
    main()
```
お手軽Laravel環境構築(Virtualbox-Vagrant)(CentOS7+php7.2+mysql+apache)#1

この記事ではCentOSを導入します。

[(続き記事)お手軽Laravel環境構築#2](https://qiita.com/hekizi/items/e2a8e35a7eb3c531ec78)

## ◆VirtualBoxとVagrantのインストール
VirtualBox 自分のPC上に仮想環境を作成できる
Vagrant VirtualBoxの操作を簡単にしてくれる・環境を配布できる・別の環境でも同じ設定で簡単に作れる

## ◆vagrantを利用していく
てきとうにそれ用のディレクトリを作成する

```Python:コマンドプロンプト
\MyVagrant>mkdir MyVagrant
```

今後いくつか作りたいときようにMyVagrant配下で

```Python:コマンドプロンプト
\MyVagrant>mkdir CentOS7
```

box OSのイメージ群・そのOSを元に色々設定した一つのパッケージ

vagrant init 実行したディレクトリをVagrant環境として初期化(設定ファイル作成)

### box自動追加パターン
今回はvagrantFileを作るときに、box指定がある設定ファイルを使う。

```Python:コマンドプロンプト
\MyVagrant\CentOS7>vagrant init centos/7
```

(Vagrant 公式ドキュメント参照)
こうしておくことで、起動したときに自動でboxを追加してくれた。

### 共通
```Python:コマンドプロンプト
\MyVagrant\CentOS7>vagrant up
```

```Python:コマンドプロンプト
An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.
```

こんな感じのエラーがでたら、box追加がうまくいってないっぽい。

vagrant up　最初の仮想環境を作成してくれる。

```Python:コマンドプロンプト
\MyVagrant\CentOS7>vagrant ssh
```

仮想環境にログイン完了

次は色々インストールして、いろいろ試してみたいです。
## 続き記事
[お手軽Laravel環境構築#2](https://qiita.com/hekizi/items/e2a8e35a7eb3c531ec78)
Git自分メモ

#Github備忘録
github自分用メモ
①githubでリモートリポジトリを作成する
②払い出されるリポジトリのurlをターミナルで入力

```
$ git clone 払い出されたURL
```

③クーロンで作成されたディレクトリに管理したファイルやディレクトリを入れる
④下記コマンドでステージングにあげる

```
$ git add 対象ファイルまたはディレクトリ
```
addコマンド後に↓

```
$ git commit -m 'コミットメッセージ'
```

⑤マスターにプッシュする

```
$ git push origin master
```

#その他

```
$ git log 
 # コミット履歴確認

$ git status
# ファイルの追加を確認

$ git reset
# ステージングを取り消す 

$ git checkout -b 新しいブランチ名
# ブランチを作成する

$ git push -u origin <ローカルのブランチ名>
#ローカルで作成したブランチをリモートに登録する

$ git -a
# ブランチ一覧確認

$ git branch -m '新しいブランチ名'
# ブランチ名変更
```


#所感
手順通りの作業ではあるものの、やっぱりうまく行くと嬉しいです。
vue.js 勉強のために簡単なものを書いてみた

## ボタンを押して数をプラス
```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
</head>

<body>
    <div id="app">
        <button v-on:click="doAdd">プラス</button>
        <ul>
            <li v-for="item in list">
            No.{{ item.number }} 
            </li>
        </ul>
    </div>

    <!-- Vue.js読み込み -->
    <script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
    <script>
        new Vue({
        el: '#app',
        data: {
            list: [
            { number: 1 },
            ]
        },
        methods: {
            // ボタンをクリックしたときのハンドラ
            doAdd: function () {
            // リスト内で1番大きいナンバーを取得
            var max = this.list.reduce(function (a, b) {
                return a > b.number ? a : b.number
            }, 0)
            // ナンバーをリストに追加
            this.list.push({
                number: max + 1
            })
            }
        }
        })
    </script>
</body>
</html>
```

## テキストエリアに入力したテキストを出す
```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
</head>

<body>
    <div id="app">
        <textarea v-model="textarea"></textarea>
        <button v-on:click="Replacement">テキストを入力</button>
        <p>入力されている内容： {{ textarea }}</p>
        <p>ボタンで入力された内容： {{ text }}</p>
    </div>

    <!-- Vue.js読み込み -->
    <script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
    <script>
        new Vue({
        el: '#app',
        data: {
            textarea: '',
            text: "ここにテキストが入ります"
        },
        methods: {
            // ボタンをクリックしたときのハンドラ
            Replacement: function () {
            this.text = this.textarea
            }
        }
        })
    </script>

</body>
</html>
```
Codeceptionをサーバー上で安定して可動させるためのメモ

# 概要
Codeceptionがサーバー上で中々安定して可動しなかったので備忘録として

## 要素が見つからない
- waitForElementを使う
要素が見つかるまで待機してみる。

```php
    $I->waitForElement('.hoge', 5);
```

## 要素がクリックできない
- waitForElementClickableを使う
- scrollToを使う

要素がクリックできるまで待機してみる。一旦スクロールさせて表示位置まで移動してみる。

```php
    $I->scrollTo('.hoge', 0, 0);
    $I->waitForElementClickable('.hoge', 5);
```

上記の操作を行うだけでもサーバー上でだいぶ安定して可動するようになりました。

## 参考

[seleniumにてButtonがクリックできない時の対処法](https://qiita.com/DNA1980/items/528ff6269986b262acdc)
ExpoのErrorRecoveryモジュールについて

Expoの[ErrorRecevoryモジュール](https://docs.expo.io/versions/v32.0.0/sdk/error-recovery/)について、ネットで調べても大して情報が載っていなかったのでその調べたメモ。

# どういうモジュールなのか

説明を読むと、

----


> Set arbitrary error recovery props. If your project crashes in production as a result of a fatal JS error, Expo will reload your project. If you've set these props, they'll be passed to your reloaded project's initial props under `exp.errorRecovery`. 

（適当訳）

任意のエラー回復プロパティを設定する。プロダクションモードで、JSの致命的エラーでクラッシュすると、Expoはプロジェクトをリロードする。もしエラー回復プロパティが設定されていたら、リロードされたプロジェクトの初期プロパティ`exp.errorRecovery`の下に、エラー回復プロパティが渡される。

----

となっていて、調べた感じ実際この通りの動作になっているようです。

デモプロジェクト: https://github.com/mk2/expo-error-handler-demo

※プロダクションビルドでしか動かない（それ以外だとRNの赤画面が出てくる）ので、確認する場合はExpoでのビルドが必要だと思われます。

※Apple Developerアカウントは持っていないので、Androidのみ確認。

# 使い所

調べていて気づいたのですがErrorRecoveryを使わなくても`exp.lastError`にクラッシュ時のエラーが入っています。なので、エラー自体の情報を設定するというよりは再起動した際になんらかの方法で処理を回復・継続させるための情報の保存に使うと有効？かもしれません。
Laravelで「Cannot declare class UpdateUsersTable」ほか

## Cannot declare class UpdateUsersTable

Laravel 5.5で`make:auth`を使い、テーブルのカラムの変更を2回行った。
別の端末でセットアップし、`php artisan migrate`を実行したところ、

```
In 2019_03_01_183512_update_users_table.php line 29:
Cannot declare class UpdateUsersTable, because the name is already in use
```

というエラーメッセージが表示され、マイグレートが行われない。

```
2014_10_12_000000_create_users_table.php
2019_03_01_163803_update_users_table.php
2019_03_01_183512_update_users_table.php
```

で、エラーが起こっているのは最後のファイルである。
エラー行の29行目はファイルの最終行であり、`class UpdateUsersTable extends Migration {`対応の閉じ括弧の行だ。

すでに`UpdateUsersTable`というクラスはあるので宣言はできない、という感じだが……何か釈然としないまま、

1. 最後のファイルのリネームを行う（.bakを付ける）
2. migrateを実行（問題なし）
3. リネームしたファイルを元に戻す
4. migrateを実行（最後のファイルのみ実行される。問題なし）

とした。自動でカブらないクラス名にして貰えないものなんですかね…？

## Please provide a valid cache path.

「cache」って書いてあるので、cacheディレクトリだけが足りないのか！と思ってしまいますが、同階層のviewsディレクトリがなくても同じエラーが出ます。

```
storage/framework/sessions
storage/framework/cache
storage/framework/views
```

上記のディレクトリはプロジェクト作成時に作成され、その後は自動的には作成されずエラーになるので、注意が必要です。
VS CodeのExplorerでVim風に移動する

VS Codeは多機能で大変便利なのですが、Vimにある程度なれると移動に↑↓←→キーを使うのが億劫になります。

特にFile Explorerでディレクトリ構造を見ながらファイルを開きたいというときにキーボードのホームポジションを崩して↑↓←→キーで移動するのが辛くてどうにかできないか調べたのでその備忘録です。

VSCode version:  1.31.1

## とりあえず結論
- VSCodeVim Extension を入れる
- setting.jsonで`"workbench.list.keyboardNavigation": "simple"`にする

## 実は既にVSCodeVim Extensionでサポートされている

Googleで適当に「vscode explorer vim binding」で調べた結果、以下のIssueを見つけました。

Using j,k,l,i to navigate inside explorer list #754
https://github.com/VSCodeVim/Vim/issues/754

それによると2017年の6月の時点でVSCodeVim Extensionを入れていればExplorerでもVim風な移動ができるみたいです！

VSCodeVim Extensionは入れていたので早速試してみました！

<img width="243" alt="Screen Shot 2019-03-03 at 12.33.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/282900/99473d70-af0c-5db0-13c7-6a92b767752b.png">

どうやらVSCodeの別の機能にキーを奪われてVim風な移動ができなくなっているみたいです。。。

## Listのハイライト表示機能をOffにする

とりあえずまたGoogleで適当に「vscode explorer search」で調べて適当にIssueを漁っていたら以下のコメントを見つけました。

https://github.com/Microsoft/vscode/issues/10026#issuecomment-462312727

`List Keyboard Navigation`というそれっぽい機能があるようなのでさっそく確認してみたところ、

<img width="978" alt="Screen Shot 2019-03-03 at 12.41.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/282900/26d4ae00-6873-4c84-f44a-030a92953dfe.png">

- highlight(私の環境だとデフォルト)
- filter
- simple

があり、`simple`に変えてみたところ、無事にjkキーでリストの移動ができました🎉

## Keybinding
2019/3月現在、VSCodeVim Extensionを入れるとリストで以下の操作が有効になるみたいです。

| キー | コマンド |
|----|----|
| h | list.collapse |
| j | list.focusDown |
| k | list.focusUp |
| l | list.select |
| o | list.toggleExpand |
| / | list.toggleKeyboardNavigation |
| ctrl+d | list.focusPageDown |
| ctrl+u | list.focusPageUp |
| g g | list.focusFirst |
| G | list.focusLast |

ただ、いくつかの挙動が怪しくて`/`とか動作しているのかいまいちわかりませんでした。

## まとめ
VSCodeのExplorerでVim風に移動するやり方を紹介しました。
個人的にhjklで操作するだけでVSCodeがさらに快適になり、よかったです。
また、`keybinding.json`にキーバインディングの設定を書くときに`"when": "listFocus && !inputFocus"`を付け加えることでオリジナルのリスト操作中のキーバインディングを自作することができそうなので色々いじってみたいと思います！
php.ini の場所をワンライナーで確認する

# 結論
コンソールで以下コマンドを実施する
`php -r "phpinfo();" | grep php.ini | less`

##背景
php.iniの場所忘れがちなんです。
`phpinfo()` だけ実行するファイル作ってそれをサーバーから参照するというやり方しか見つからずそれすらも面倒だったのでもっと簡単な方法がないかと探して見つけたのでメモがてら共有します。

##説明
- `php -r "PHPコマンド"` でcui上でPHPのコマンドが実行できるので、それで`phpinfo()`を実行します。([参考](https://www.softel.co.jp/blogs/tech/archives/2077)
)
- `grep "文字列"`　で文字列を検索できるので`php.ini` を抽出します。
- less コマンドで見やすくしますが、今回は1行しか出力がないのでなくてもそんなに見づらいとかないです。


簡単ですが以上です。
gcc/clang の -save-temps オプションでプリプロセッサ出力とアセンブラコードを確認する

## C/C++ コンパイルの流れ

```
$ gcc test.c
```
のように C のソースファイルから実行ファイルを作るとき、ざっくり言うと以下のような流れで処理されています。

1. プリプロセッサ処理 (`#ifdef` や  `#define` マクロの展開) 
2. 1 の結果からアセンブラコードを出力 (狭義のコンパイル)
3. 2 の結果からアセンブラが機械語コードを出力 (`*.o`)
4. 3 の結果を複数集めてリンク

たいていのプログラムは複数のソースコードで構成されるので、3. の出力である `*.o` は目にする機会が多いと思いますが、 1-3 は `gcc` コマンドが内部的に処理してしまうので、 1 や 2 の結果は気にすることは少ないと思います。

この 1  や 2 の結果をファイルとして出力させるのが `-save-temps` オプションです。

## -save-temps オプション

https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-save-temps

> Store the usual “temporary” intermediate files permanently; place them in the current directory and name them based on the source file. Thus, compiling foo.c with -c -save-temps produces files foo.i and foo.s, as well as foo.o. This creates a preprocessed foo.i output file even though the compiler now normally uses an integrated preprocessor.

このオプションをつけてコンパイルすると、例えば `foo.c` (`foo.cc`) というソースファイルに対して

- プリプロセッサ出力:  `foo.i` (C の場合) / `foo.ii` (C++ の場合)
- アセンブリコード: `foo.s`

を出力します。

マクロが実際にはどのように展開されているか見たい場合や、最適化の結果どのようなアセンブラコードが吐かれているのかをみたいときなどに役立ちます。

なお、 それぞれ `gcc -E` や `gcc -S` でも出力できますが、これらは `*.o` を作らないので、大きなビルドの中に組み込むのは不便です。  `-save-temps` なら、ビルド自体は通常通り行いつつ中間成果物を確認することができます。

### -save-temps=obj

単に `-save-temps` だと `foo.i` / `foo.s` はカレントディレクトリに生成されますが、
`-save-temps=obj` とすると `foo.o` と同じディレクトリに生成されます。


## ビルドシステムへの組み込み

このオプションを簡単に有効にできるよう、プロジェクトのビルドシステムに組み込んでおくとよいでしょう。
(オーバーヘッドはあるはずなので常に有効にしておくようなものではないかなと)

例えば make なら

```Makefile
ifneq ($(SAVETEMPS),)
CFLAGS += -save-temps=obj
endif
```

としておいて有効にしたいときには

```
$ make SAVETEMPS=1
```

とする、みたいな話です。

## warning が変わる (ことがある)

`-save-temps` を付けるとコンパイル時の warning の出方が変わる場合があります(`-save-temps` をつけると warning が増える、またその逆)。

これは、gcc は通常はプリプロセス・コンパイルを一気に行うのに対して、 `--save-temps` をつけると2段階で行うようになるためです。これについては別途書こうと思います。
Cognitoユーザープールのグループを組織（テナント）管理に使おうとした時の留意点

Cognitoユーザープールでは、グループを作成してユーザーをまとめることができます。

「ユーザーを組織（テナント）ごとに管理したい」という要求があったので、このグループを利用すれば簡単にできるかなと思ったのですが、期待していたものとは少し異なっていたので、調べて判ったことをまとめておきます。

# グループは後から追加された機能

まずこのグループは、後から追加された機能みたいです。

[新機能 – Amazon Cognito グループ、およびきめ細かなロールベースのアクセス制御](https://aws.amazon.com/jp/blogs/news/new-amazon-cognito-groups-and-fine-grained-role-based-access-control-2/)

ざっと読んだどころ、グループはロールベースアクセス制御（RBAC）を行うための概念のようです。

- IAMロールを設定することができる
- **ユーザーは複数のグループに属することができる**

グループを組織として扱う場合、複数グループに所属できる点はちょっとイメージに合いませんが、まあ単一のグループに属するようにすれば大丈夫そうです。

# ユーザー情報にはグループは（直接）含まれない

`list_users`や`get_user`（`admin_get_user`も含む）でユーザー情報を取得できますが、これにグループ情報は含まれません。

```json:get_userのレスポンス
{
    'Username': 'string',
    'UserAttributes': [
        {
            'Name': 'string',
            'Value': 'string'
        },
    ],
    'MFAOptions': [
        {
            'DeliveryMedium': 'SMS'|'EMAIL',
            'AttributeName': 'string'
        },
    ],
    'PreferredMfaSetting': 'string',
    'UserMFASettingList': [
        'string',
    ]
}
```

ユーザーが属するグループを取得するには、`admin_list_groups_for_user`を使う必要があります。つまり、「この組織のこのユーザーを直接取得する」ということはできなさそうです。

# グループに関するメソッド

groupで検索したら以下がありました。これらをうまく組み合わせて組織に関する操作を行う必要があります。

- 単純なCRUD
  - `create_group()`
  - `get_group()`
  - `list_groups()`
  - `update_group()`
  - `delete_group()`
- グループへの追加と削除
  - `admin_add_user_to_group()`
  - `admin_remove_user_from_group()`
- ユーザーが属するグループの一覧の取得
  - `admin_list_groups_for_user()`
- グループに属するユーザーの一覧の取得
  - `list_users_in_group()`

# ひとまずの結論

- ユーザーは複数のグループに属することができる
- ユーザーが属するグループを取得するにはひと手間必要
Hover Effects

仕事に役に立つかもしれないボタンのHoverをいくつか紹介したいと思います

#Hover 1（作者：Noel Delgado）
<p class="codepen" data-height="621" data-theme-id="dark" data-default-tab="result" data-user="noeldelgado" data-slug-hash="pGwFx" style="height: 621px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Direction-aware 3D hover effect (Concept)">
  <span>See the Pen <a href="https://codepen.io/noeldelgado/pen/pGwFx/">
  Direction-aware 3D hover effect (Concept)</a> by Noel Delgado (<a href="https://codepen.io/noeldelgado">@noeldelgado</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#Hover 2 (作者：Gabrielle Wee）
<p class="codepen" data-height="391" data-theme-id="dark" data-default-tab="result" data-user="gabriellewee" data-slug-hash="Qdpgwx" style="height: 391px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="CSS-Only Direction-Aware Cube Links">
  <span>See the Pen <a href="https://codepen.io/gabriellewee/pen/Qdpgwx/">
  CSS-Only Direction-Aware Cube Links</a> by Gabrielle Wee ✨ (<a href="https://codepen.io/gabriellewee">@gabriellewee</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#Hover 3
<p class="codepen" data-height="405" data-theme-id="dark" data-default-tab="result" data-user="muadong200474" data-slug-hash="WmwLWj" style="height: 405px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="WmwLWj">
  <span>See the Pen <a href="https://codepen.io/muadong200474/pen/WmwLWj/">
  WmwLWj</a> by Lampt (<a href="https://codepen.io/muadong200474">@muadong200474</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#Hover 4
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="result" data-user="muadong200474" data-slug-hash="gErZJr" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="gErZJr">
  <span>See the Pen <a href="https://codepen.io/muadong200474/pen/gErZJr/">
  gErZJr</a> by Lampt (<a href="https://codepen.io/muadong200474">@muadong200474</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
BeagleBoneGreenでGPSを受信する01

BeagleBoneGreenにGPSモジュールを接続してGPSを受信できるようにします。

#材料

使用したGPSモジュールはスイッチサイエンスのESPr® Developer用GPSシールド
u-bloxのアンテナ一体型モジュールSAM-M8Qを搭載しています。
https://www.switch-science.com/catalog/3480/

![DSC_0024.jpg](https://qiita-image-store.s3.amazonaws.com/0/366164/87d27095-5a2f-4f63-9de9-d8d26bd665ae.jpeg)
旧世代の6シリーズモジュール搭載基板は安価でいくつかありますが、最新M8シリーズはあまり見つかりませんでした。
u-blox最新モジュールを使いたい場合はEVKを購入する手がありますが、2万円位します。
このSAM-M8Qモジュール搭載シールドであれば別途アンテナを用意する必要が無くコンパクトに収まります。


ホットスタート&ウォームスタートができるようにコイン電池ものせられるようにします。
スイッチ付きですのでコールドスタートの実験もやりやすいです。
20mmコイン電池・ピッチ変換基板(スイッチ付き)
https://www.switch-science.com/catalog/1778/
https://www.adafruit.com/product/1871
![DSC_0025.jpg](https://qiita-image-store.s3.amazonaws.com/0/366164/73ed7d00-e5d1-1c21-4598-ae058da38560.jpeg)


BeagleBone用のユニバーサル基板に実装します。
BeagleBone Black用　ユニバーサル基板23　スタック-きばん本舗
https://www.amazon.co.jp/gp/product/B00NM2NSO8/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
http://kibanhonpo.shop-pro.jp/?pid=80216183
![DSC_0027.jpg](https://qiita-image-store.s3.amazonaws.com/0/366164/f9fd7046-7866-751b-8ba5-d90a43d58b51.jpeg)


回路図、データシートは各リンク先から参照して下さい。
BeagleBoneGreenの端子はメーカーwikiで確認できます。
http://wiki.seeedstudio.com/BeagleBone_Green/

#組立
以下を接続します。
-GPSシールドのJP2-3pin IO4 と ユニバーサル基板の J19(J9)-26pin
-GPSシールドのJP2-6pin IO6 と ユニバーサル基板の J19(J9)-24pin
-GPSシールドのJP1-10pin +3V3 と ユニバーサル基板の 3.3V
-GPSシールドのJP2-10pin GND と ユニバーサル基板の GND
-GPSシールドのJ1-1pin BACKUP と コイン電池基板のSW
-コイン電池基板の GND とニバーサル基板の GND

BeagleBoneGreenのUART1のTX,RXに接続するようにしました。
UART2はGrove Interfaceコネクタと共用になっています。電気的にもつながっていますのでUART2を使う場合は注意が必要です。
GPSシールドのTXD,RXD端子はデフォルトではSAM-M8Qに接続されていません。IO4とIO6に接続されいます。
GPSシールドのRESET端子は接続しなくても大丈夫です。モジュール内部で11kΩでプルアップされています。
RESET端子を接続する場合、出力端子はオープンドレイン出力に設定する必要があります。SAM-M8Q Hardware Integration Manualの2.1 Pin descriptionにH電圧を印加しないよう注意書きがあります。

![DSC_0029.jpg](https://qiita-image-store.s3.amazonaws.com/0/366164/99290810-6c34-8a9e-a19a-8d92c9b1c58c.jpeg)
実装後の写真。余っていたOSコン(16V47uF)とセラコン(50V0.1uF)もつけました。

![DSC_0030.jpg](https://qiita-image-store.s3.amazonaws.com/0/366164/b5a4a028-7bb3-cf89-1759-73ac048a8fc5.jpeg)
BeagleBoneGreenに載せた状態。ケースに収まらないので底板以外は外しました。



#設定

BeagleBoneGreenはデフォルトではUART端子が有効になっていませんので設定を変更します。

```
$ config-pin p9.24 uart
$ config-pin p9.26 uart
```
cat でシリアル通信の受信を確認します。

```
$ cat /dev/ttyS1
```
NMEAの電文が表示されれば成功です。デフォルトの9600bpsで表示されるはずです。測位に成功するとNMEAに位置情報が出力され、GPSシールドの1SEC LEDが点滅します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/366164/bdbc431e-2d01-dd8f-e890-073fba7c5f3e.png)

続き
[BeagleBoneGreenでGPSを受信する02](https://qiita.com/pata128/items/77516d81db2aa9bf835e)
色の違うオブジェクトを交互に表示させてみる。

###はじめに
このテーマで作成した目的は、配列をUnityで活用するにはどうすればいいのかわからなかったので、作ってみました。
自分は初心者という立ち位置ですが、プログラミングの書籍の写経を何度もしてわかったことは。小さくてもいいので、この動きをどうすればいいのか思い浮かべ、調べてトライ&エラーを繰り返すことが一番最適なのではないかと思います。

###配列の基本型

~~~C#
int[] a = new int[3];   //型[] 変数　= new 型[配列数]
~~~


###Game Objectに色を付ける。
3D_objectsを作成する(2個以上作成し色分けも行う）。
↓
ProjectのAsset欄で右クリック　→　Create　→　Materialを選択する。
![QiitaMaterial.png](https://qiita-image-store.s3.amazonaws.com/0/307841/b963106c-e37e-96cd-a519-95cf5862ad88.png)

Albedoの赤い部分を選択　→　ここから色を選択する

![materialselect.png](https://qiita-image-store.s3.amazonaws.com/0/307841/e2e73f68-3d59-c7d5-92c8-bf5cc334970b.png)

###GameObjectのスクリプト
ファイル名はEnemyにしました。これを3Dオブジェクトにアタッチする。
内容は0.5f経過したらGameObjectが消失します。

~~~C#
public class Enemy : MonoBehaviour {
    float time = 0;
	// Update is called once per frame
	void Update () {
        time += Time.deltaTime;

        if(time >= 0.5f)
        {
            Destroy(gameObject);
        }

    }
}
~~~

###EmptyGameObject・クリプトを作成
空のGameObjectを作成してここに3D_GameObjectが出現できるようにします。

・スクリプト（名前はenemy2にしました）

~~~C#
public class Enemy2 : MonoBehaviour {
    [SerializeField] GameObject cube1;   //GameObjectを配置

    [SerializeField] GameObject cube2;   //GameObjectを配置

    float time = 0;    //float型でtimeを0秒に設定する。

    GameObject enemy;  //GameObject型をenemyで宣言する。

    GameObject[] spaners = new GameObject[2];  //配列GameObject型で配列2つ作成する。

	// Use this for initialization
	void Start () {
        spaners[0] = cube1;  //配列0をCube1に指定
        spaners[1] = cube2;  //配列1をCube2に指定
	}
	// Update is called once per frame
	void Update () {

        var v = Random.Range(0, spaners.Length);  //Var型を宣言し乱数を生成。spanersは配列が2つなので最大値が2になる。
        
        time += Time.deltaTime;  //timeを加算し続ける。


        //enemyが無くかつtimeが1.2f以上の場合はenemyにクローンを生成する。
        if (enemy == null && time >= 1.2f)
        {
            enemy = Instantiate(spaners[v], transform.position, transform.rotation);   
        }

        //enemyがある場合timeを0にする。
        if(enemy == true)
        {
            time = 0;
        }
        
        //時間経過を見るためコンソールに時間を表示させる。
        print(time);
	}
}
~~~

スクリプトをEnptyEnemyにアタッチする。

###結果
![movie (1).gif](https://qiita-image-store.s3.amazonaws.com/0/307841/39bd6d50-4708-43ae-3742-114c95b33f60.gif)


今回はGameObjectをオレンジと緑に設定しました。

###最後に
配列は写経だけではあまり使わないと思っていたが、実際に使ってみると乱数との相性がとても良く、Unityでも使えるかと不安だったか杞憂でした。
[TIPS]「別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません」と出たときの対処方法


# 「別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません」と出たときの対処方法

Windowsでフォルダーやファイルを操作しようとすると、このようなダイアログがでることがあるので、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/15b931c3-0086-be7b-8d26-c2325567eebe.png)

**別のプログラム**とやらを特定して、対策をする。

Windows+R または コマンドプロンプトを開いて

```shell
perfmon.exe /res
```

または

```
resmon.exe
```

と入力する。

するとリソースモニターが開く。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/1d7a4c8b-32c0-304c-c118-04053246a304.png)

**関連づけられたバンドル**にあるテキストボックスに、操作しようとするフォルダー名 or ファイル名を入力してエンター。

すると、どのプログラムが該当フォルダー（ファイル）を開いているかわかるので、それを閉じるなりして対策できる。
Github ssh setting cheatcheet

# Overview
Cheetsheet of How to set up for ssh to github comfortably.
(macbook買い直した時などgithubを爆速で設定する方法)

## Make ssh keys
$ `ssh-keygen -t rsa -b 4096 -C "your email(registerd at github)"`

Enter a file name and a passphrase

when a file name is as follows

`~/.ssh/github_rsa`

## Register pub key with github
$ `pbcopy < ~/.ssh/github_rsa.pub`

in github.com
at `Setting` > `SSH and GPG keys` > `New SSH key`
paste pub key and name it

## Avoid `Enter passphrase for key`
### Add ssh config
$ `vim ~/.ssh/config`

```
Host *
  UseKeychain yes

Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/github_rsa
  User git
```

### Add ssh key with 
$ `ssh-add -K ~/.ssh/github_rsa`
※ -K Store passphrases in your keychain.

### Check
$ `ssh -T git@github.com`

## 参考
- [お前らのSSH Keysの作り方は間違っている](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)
- [macOS 10.12 Sierra で SSH のパスフレーズを憶えてくれない問題への workaround](https://qiita.com/shao1555/items/9e7a368f495228332a03)
[EC2]サーバのリソース監視入門


# ■概要
- AWSでEC2を使う際に、見ておく必要があるであろう項目を、洗い出して監視を実践する。

# ■取っておきたいメトリクスについて

### ◆EC2を建てると標準で取得されるメトリクス一覧

「[(公式)インスタンスの利用可能な CloudWatch メトリクスのリスト表示](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html)」に詳細が書いてあるが、一般的なアプリケーション監視に使う項目が標準ですべてとれるわけではない。

※自分が運用/監視で標準メトリクスから使っている項目は下記くらい。

~~~
　1. CPU使用率
　2. ディスクのRead/Write
　3. ネットワークのIn/Out
~~~


### ◆追加で必要であろうリソース情報

~~~
　1. CPU使用率の詳細(user/system/iowait/idle)
　　※nice,irq,softは特に気にしていない
　2. メモリ使用量の詳細(swpd/free/buff/cache)
　3. ロードアベレージ
　4. ディスク使用率
~~~

### ◆Webアプリケーションなら取っておきたい情報(Cloudfront/ELBなどを使うと標準で取れる)

~~~
　1. 総リクエスト数
　2. 5xx系のエラーレート
　3. 5xxのエラーリクエスト数
　4. レスポンスタイム
　5. ミドルウェアのプロセス/スレッド数(psコマンドで取得)
　6. サーバ間のTCP接続数(netstatコマンドで取得)
~~~

# ■サーバからメトリクスをどうやってcloudwatchメトリクスに送るか
サーバ上のリソース情報をどうやってCloudwatchメトリクスに登録するかという事だが、[fluentd(td-agent)](https://docs.fluentd.org/v1.0/articles/quickstart)を使うのが吉。
自身の環境に合わせて何秒に一回上記の情報をメトリクスに登録するか、検討するのが良い。　
Cloudwatch以外のSaasサービスを利用する際にも同じように実装が可能である。

> ※fluentd(td-agent)の実装例を記事化する要望があれば乗せるのでご要望を寄せていただけるとありがたいです。

# ■取得したメトリクスを便利に見る方法

結論、CloudWatchのダッシュボードにまとめるのが一番良い。

 - 下記のようなメリットがある。

~~~
　1. 一つのダッシュボードに上手くまとめればコスパが最高
　2. 見たい時間へのスケールがとても楽ちん
　3. グラフにカーソルを合わせると他のグラフ上にも線が出るので相関が見やすい
　4. 編集もポチポチで簡単
~~~

# ■最後に
「[入門　監視(O'REILLY)](https://www.oreilly.co.jp/books/9784873118642/)」にも書いてありますが、今の時代オンプレミスのサーバに監視基盤を作る時代は過ぎたと思います。(当然堅牢性など仕方ない場合はありますが。)
監視の為の監視に大切な人的コストを浪費し、本来の仕事が出来ていない状況にあるのであれば、是非Saasサービス(CloudWatchがおすすめ)を検討しましょう。

　*以上、フィードバックやご指摘等いただけると大変ありがたいです!!よろしくお願いいたします!!*
【RxJS入門】エラー時に一定時間後リトライする(retry、retryWhen)

こんにちはムラびとです。
最近スクレイピングの依頼が増えたのですがその最中でソケットが上がったり、リクエスト数が多すぎて一時停止することがよくあります。
そこでエラー時にその処理を繰り返せるretry、retryWhen関数の登場です。
そこで今回は、Observableがエラーを返してきた時にある回数まで一定時間後にリトライ、一定回数後にエラーを返すプログラムを作っていきます。

- retry関数とは
- retryWhen関数を使って一定時間後リトライ
- リクエストエラーのステータスコードによる分岐

## retry関数
RxJSは非同期処理に強く、エラー処理が簡単に書くことができます。
例えば、リクエストを送る時、サーバーの都合でリクエストが失敗することはよくあります。
そんな時に最初から処理を繰り返すことができるようにするのが`retry関数`です。

```JavaScript
import { from,of,throwError } from 'rxjs'; 
import { flatMap ,retry} from 'rxjs/operators';


const source = from([2,4,6,8])
  .pipe(
    flatMap(n=>(n>4)?throwError(n):of(n)),
    retry(5)
  )

source.subscribe(
  x => console.log(x),
  err=>console.error(err)
);
```
などのように使い、リトライの最大回数を設定することができます。

## retryWhen関数を使って一定時間後リトライ
リクエストを送って失敗したら数秒後にリトライして欲しい、という時にはretryWhen関数を使います。
retryWhen関数を使うことで、送られたエラーを変換してretryすることできます。
これを使うと例えばエラーが起きたら１０秒後にリトライさせることができます。

```typescript
import { throwError, of } from 'rxjs'
import { delay, retryWhen, take, tap, concat, flatMap } from 'rxjs/operators'
export const retryWithDelay = (ms: number, count: number) =>
  retryWhen(errors => errors.pipe(
    flatMap((err, i) =>
      (i >= count))) ?
        throwError(err) :
        of(err)
    ),
    tap(err => console.log(`err:${JSON.stringify(err)}, retrying...`)),
    delay(ms),
    concat(throwError('retried too much...'))
  ))
```

使い方としては以下のようにします。

```typescript

const source = from([2,4,6,8])
  .pipe(
    flatMap(n=>(n>4)?throwError(n):of(n)),
    retryWithDelay(1000,10)// 1s間隔で10回までリトライ
  )
```

またこれを使うとスクレイピングなどでアクセス制限をされないようランダムにウェイトをかけることもできます。

```typescript

export const retryWithRandomDelay = (min: number, max: number, count: number) =>
  retryWithDelay(Math.random() * (max - min) + min, count)
```

## リクエストエラーのステータスコードによる分岐

リクエストで、404（Not Found）エラーがきた場合、何度送っても意味がありません。そこで、エラーのステータスコードによってリトライするかどうかを判断するようにプログラムを書いていきます。

```typescript
export const retryWithDelay = (ms: number, count: number, excludedError: (string)[] = []) =>
  retryWhen(errors => errors.pipe(
    flatMap((err, i) =>
      (i >= count || excludedError.find(e => e == (err.statusCode || ''))) ?
        throwError(err) :
        of(err)
    ),
    tap(err => console.log(`err:${JSON.stringify(err)}, retrying...`)),
    delay(ms),
    concat(throwError('retried too much...'))
  ))
```

exculdedErrorにステータスコードの配列を入れてそれらのステータスコードが来たらリトライをせずエラーをそのまま返す、ということができます。

## 終わりに

ここまで見ていただきまことにありがとうございます。
他にもいくつかRxJSについて記事を書いていますのでよろしければご参照ください。

## 出典

[公式サイト](https://www.learnrxjs.io/operators/error_handling/retrywhen.html)