OmniAICreator/Qiita-1.07M huggingface dataset:
【Ruby】Dateクラスを使わずに月の0を取り除く

# 背景
RubyとSeleniumを使って、DBから持ってきた値を自動で入力する処理を作っているのですが、月を入力する場面で、月がDBには0埋めで保存されていたので、0を取り除く必要がありました。
フレームワークは使っておらず、このためだけにDateクラスを持ってくるのは何か変だなと思ったため、Dateクラスを使わずにやってみました。

# 結論
gsub!を使う。

# 検証
使ってみる。

```ruby:test.rb
month = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']

month.each do |m|
  m.gsub!(/^0/, '') # 先頭の0を空文字に置き換える
end

p month
```

```title:出力
["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
```
できました。

# 参考
- [gsub, gsub! (String) - Rubyリファレンス](https://ref.xaio.jp/ruby/classes/string/gsub)
- [正規表現一覧](http://gimite.net/help/devas-ja/all_regex.html)
Stack練習

```c++
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<n; i++)
using namespace std;

int main(){
    stack<int> S;
    int a,b,x;
    string s;
    
    while(cin >> s){
        if (s[0]=='+'){
            a=S.top(); S.pop();
            b=S.top(); S.pop();
            S.push(a+b);
        }else if(s[0]=='-'){
            b=S.top();S.pop();
            a=S.top();S.pop();
            S.push(a-b);
        }else if(s[0]=='*'){
            a=S.top();S.pop();
            b=S.top();S.pop();
            S.push(a*b);
        }else{
            S.push(atoi(s.c_str()));//c_str()はstring型→char型にする関数
        }
    }
    cout << S.top() << endl;
}
```

#atoi関数
**char型の文字**を**int型の数値**に変換する関数
Djangoのmigrateでerrno: 150 "Foreign key constraint is incorrectly formed"

# TL; DR


- DBがmigrate以外の方法でMODIFYされていてテーブルの型の不一致により外部キーが張れなかった
- 型の不一致は `desc table_name` では判断できないので注意
- あくまで今回当たった事象であり、同様のエラーがでる問題はたくさんある


# はじめに

開発環境では普通にうまくいっていた Django の migrate が本番適用時にコケる。 
幸いテーブルの追加のみのマイグレートだったため影響は最小限だったが、なかなか解決までに時間がかかったのでメモ。

なお、Pythonは3.6.7、Djangoは2.1系だが、バージョンに関わらず発生する内容だと思う。


## 調査

開発環境で事前実施した通り `python manage.py migrate` にてマイグレーションを実施。
……すると、`errno: 150 "Foreign key constraint is incorrectly formed"` としてエラーメッセージが表示される。

正直、ローカルと本番でDBのマイナーバージョンまでそろえてやっているのでこの時点で「面倒なことになった…」と思っていましたが、まずは落ち着いてグーグル先生にメッセージをコピペ。

調べてみると

- 外部キー制約がユニークでない場合
- テーブルのエンジンが異なる場合
- データの型が異なる場合
- etc, etc...

など、様々な場合でこの errno: 150 が発生するらしい。
まずは詳細エラー内容を確認していってみると、

[こちら](http://hogepiyo.hatenablog.jp/entry/2013/09/21/160249) を参考にして `SHOW ENGINE INNODB STATUS; ` 内の `LATEST FOREIGN KEY ERROR` を確認。

すると、

> Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.

というエラーメッセージで型が違う、と言われてしまった。
もちろんこれについては先に `desc table` でお互いの型が `char(32)` であり、型・バイト数まで同じことを確認していたので、やっぱり混乱した。

紆余曲折（20分ぐらい）色々やってみて、型を別の方法で確認しようとして外部キーを貼る先に `SHOW CREATE TABLE` を打ってみたときのこと、

```sql
...
`user_id` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
...
```

…んん！？

文字コードも違えば COLLATE されている設定も違う！
これが「型」として違うと認識されているらしいので、この部分を併せてやる必要がある。

外部キーを貼る元のカラムを `SHOW CREATE TABLE` で見てみると、

```sql
 `owner_id` char(32) NOT NULL,
```

となっているので、ここに COLLATE を指定して型を合わせる。
その後に外部キーを貼ればテーブル上の整合性はOK。

```sql
ALTER TABLE table_name MODIFY COLUMN owner_id char(32) COLLATE 'utf8mb4_unicode_ci';
ALTER TABLE table_name ADD FOREIGN KEY(owner_id) REFERENCES user(user_id);
```

最後に、今回のDjangoマイグレーションを強制的に進めて状態を正として終了。

```bash
# 最新のマイグレーションバージョン 00XX まで適用したことをDjangoに認識させる
python manage.py migrate app 00XX --fake
```

## 原因

Djangoの管理外でDB構造を修正したか、あるいは、既存のDBをDjangoのプロジェクトとして利用し始めた事だと思う（実際のところは歴史的経緯により闇の中）。
ローカル開発環境では全てDjangoのマイグレーションで作成したため問題は発生しなかったが、何らかの理由でDBにマイグレーション以外の方法で手を加えている場合にこういったことが起こることがある。


# 終わりに

管理ツールを使っている場合、極力管理ツールで操作するようにしましょう。
あと、型の詳細を知るには `desc` だけでは不十分でした。
RDKitでフラグメント除去をやってみる

#はじめに
molファイルやsmilesの中に複数の化合物(フラグメント)が含まれていると、その後の記述子計算などに支障がでるため、一般的には前処理においてこれらを除去し、1つの化合物のみにすることが行われる。今回、これをやってみようと思う。

#環境
- Python3.6
- RDKit 2019.03.3.0

#塩を除去する
まず、よくあるパターンとして"Cl"や"Br"等の塩が含まれている場合の除外方法について述べる。
コード例は以下のとおりである。

```python
from rdkit import Chem
from rdkit.Chem.SaltRemover import SaltRemover

smis = ("CN(C)C.Cl", "CN(Br)Cl.Cl", "CC(=O)O.[Na]", "CN(C)C.Cl.Br")

#-------------------------------------------------------
# 脱塩処理
#-------------------------------------------------------

remover = SaltRemover(defnData="[Cl,Br]")
for smi in smis:
    mol = Chem.MolFromSmiles(smi)
    mol2 = remover.StripMol(mol)
    smi2 = Chem.MolToSmiles(mol2)
    print(smi + "->" + smi2)

```

結果は以下のとおりである。

```
Before: CN(C)C.Cl -> After: CN(C)C
Before: CN(Br)Cl.Cl -> After: CN(Cl)Br
Before: CC(=O)O.[Na] -> After: CC(=O)O.[Na]
Before: CN(C)C.Cl.Br -> After: CN(C)C
```

3番目以外は正しく除去されている。3番目の化合物では、"Na"が除去されていないが、これはSalt RemoverのdefnDataのところでNaを定義していなかったためである。ここを"Na"も指定すると正しく除去される。

#一番大きなフラグメントを残して他を除去する
次に、塩以外にも複数の化合物が含まれているmolファイルやsmilesがある場合について述べる。この場合、一番大きいサイズのフラグメントのみを残すという処理がよく行われる。

コード例は以下のとおりである。

```python
from rdkit import Chem
from rdkit.Chem import MolStandardize

lfc = MolStandardize.fragment.LargestFragmentChooser()
smis = ("CN(C)C.Cl", "CN(Br)Cl.Cl", "CC(=O)O.[Na]", "CN(C)C.Cl.Br", "CCC.CCCC")
for smi in smis:
    mol = Chem.MolFromSmiles(smi)
    mol2 = lfc.choose(mol)
    smi2 = Chem.MolToSmiles(mol2)
    print("Before: " + smi + "-> After: " + smi2)
```

結果は以下のとおりである。5番目は塩でないが、小さいフラグメント(CCC)が除去されていることが分かる。

```
Before: CN(C)C.Cl -> After: CN(C)C
Before: CN(Br)Cl.Cl -> After: CN(Cl)Br
Before: CC(=O)O.[Na] -> After: CC(=O)O
Before: CN(C)C.Cl.Br -> After: CN(C)C
Before: CCC.CCCC -> After: CCCC
```

#おわりに
一般的な手法や、RDKitの仕様を調べるのに時間をかかってしまった。次は電荷の処理について書いてみたい。
git,github 初心備忘録

[参考]
基本
https://qiita.com/mikansei-lab/items/dff17ba65b28fc82b1e1
入門
https://qiita.com/ay3/items/8d758ebde41d256a32dc

[dotinstall]
(https://dotinstall.com/lessons/basic_git)

[環境]
mac os mojave
proxy有り
git version 2.23.0

---
git : バージョン管理ツール
github : gitのwebサービス版

---
#初期設定(アカウント登録〜ssh登録)

・アカウント登録
https://github.com/

・gitインストール

```
$brew update
$brew install git
$git --version
```

・SSHkey登録

```
$ls -al ~/.ssh
$ssh-keygen -t rsa #enter
$ls -al ~/.ssh
$cat ~/.ssh/id_rsa.pub
→id_rsa.pubをコピー
https://github.com/settings/keys に登録
```

・ユーザーの追加

```
ユーザーの名前を指定
$ git config --global user.name [name]
ユーザーのメールアドレスを指定
$ git config --global user.mail [mail]
設定を確認
$ git config --global --list
user.name=[name]
user.mail=[mail]
```

・リポジトリを作成
GitHubへログイン→画面左側のRepositoriesの「New」ボタンからリポジトリを作成
Repository name：なんでも


#共有リポジトリへファイルをpush

```
プッシュしたいソースのあるフォルダに移動
$ cd なんちゃらかんちゃら
gitの初期化
$ git init
カレントディレクトリのファイル全てをバージョン管理に追加
$ git add .
ソースのコミット
$ git commit -m "first commit"
```

リポジトリを追加

```
$ git remote add origin <URL>
＊url先のリポジトリを共有リポジトリとしてoriginというあだ名をつける
リポジトリの確認
$ git remote -v
origin  https://github.com/~ (fetch)
origin  https://github.com/~ (push)

共有リポジトリ orijin=url に反映
$ git push -u origin master
```

＊masterとは開発する際のリリース版や安定板のようなもの．個人利用ではこのままでok
master はブランチ（枝分かれ）の名前。ちなみに master は大事なブランチなので、チームでの場合はmasterには通常pushしないので注意
＊「-u」オプションについて
省略の呪文。git push -u origin master とすると、次回から git push だけで引数に指定した origin master で勝手に push してくれる。

#その他(originの変更,branchの確認)
originの変更

```
$git remote set-url origin {new url}
$git remote -v
```

branchの確認

```
$git branch
* master
  hoge

branchの切り替え
$git checkout ブランチ名
```

clone

```
$git clone {url}
```
Azure Maps を使ってみる

今回は Azure Maps を使ってみようと思います。これまで Google Maps API は何度かつかったことがありますが、Azure Maps API は初めてなので使用感含め確認してみたいと思います。

#Azure Portal から Azure Maps リソースをデプロイする
まずは、Azure Maps を使用した地図を表示する WebApp をデプロイします。今回の Runtime Stack は php を使います。(なんでも大丈夫です)

次に、Azure Portal から Azure Maps をデプロイします。あとで一括で削除できるように WebApp と同じリソースグループに纏めておくと良いですね。デプロイが完了したら、Azure Maps に接続するための Key が発行されていますので、そちらをメモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/21b8e4ed-0040-a3a8-423b-20d1be5c19f0.png)

#Azure Maps で地図を表示するためのコードを書く
先ほどデプロイした WebApp に Javascript で地図を表示する コードを書いていきます。
コードは以下の Microsoft が GitHub に公開しているサンプルがあります。
https://github.com/Azure-Samples/AzureMapsCodeSamples/blob/master/AzureMapsCodeSamples/Tutorials/interactiveSearch.html

この中の以下の部分を書き換えます。先ほどメモした Key を入力します。

```javascript
authOptions: {
                    authType: 'subscriptionKey',
                    subscriptionKey: '<Your Azure Maps Key>'
                }
```

書き換え完了したら WebApp にブラウザからアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/83840e32-de99-51ea-597e-618a654abe66.png)

サンプルコードを張り付けるだけで、位置情報の名前から地図の位置を検索することができます。このサンプルはロサンゼルスが中心になっているので、この中心を大井町駅にしてみましょう。地図の中心座標は以下で指定しています。

```Javascript
map = new atlas.Map('myMap', {
                center: [-118.270293, 34.039737],
                zoom: 14,
                view: 'Auto',
				//Add your Azure Maps subscription key to the map SDK. Get an Azure Maps key at https://azure.com/maps
                authOptions: {
                    authType: 'subscriptionKey',
                    subscriptionKey: '<Your Azure Maps Key>'
                }
            });
```

ここの Center を大井町駅の座標 [139.734978, 35.607452] に書き換えます。 
ここで少し注意が必要ですが、順番は、経度、緯度の順番になっています。 Google Maps API は逆なので、Google Maps API になじみのある人はちょっと抵抗があるかもしれません。（実際僕がそうでした。。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/2976b2a8-1df5-089c-105a-b9c8b0c0bf49.png)


な、なんだこれ！？
なんと Azure Maps には日本の地図情報はまだ大きな道路だけのようです。（まじで使えない、、、）はやく色々な地域に対応してもらって、IoT アプリとかいろいろなサービスと掛け合わせて使いたいです。

#参考情報
Azure Maps とは
https://docs.microsoft.com/ja-jp/azure/azure-maps/about-azure-maps

Azure Maps Blog
https://azure.microsoft.com/en-us/blog/topics/azure-maps/
Amazon Linux2で/var/runが初期化される問題


# 最初に
`Amazon Linux`から`Amazon Linux2`に移行した時に発生した/var/run問題を書き残しておきます。
躓いているどなたかの参考になれば幸いです。


# 技術参考
- AWS EC2
- Amazon Linux
- Amazon Linux2

# 事象
OSを再起動またはAutoScalingで新規起動する時に**/var/runに配置したディレクトリが削除されている**事象を発見。Amazon Linuxでは特に意識せずに/var/runを利用できていたが、Amazon Linux2では/var/runが初期化される事象が発生した。

この事象が発生したシステムではOS設定済みのAMIを元にEC2に立ち上げる方式にしていたため、EBSやEFSが原因かと思っていたが、調査した結果/var/runがそもそも初期化されているのではないか。にたどり着いた。

# 原因
Amazon Linux1ではRHEL５/6ベースで構築されていたものが、
Amazon Linux2ではRHEL7ベースに変更されている。
（参考： [Amazon Linux2とAmazon Linuxの違いについて（メモ）](https://qiita.com/akira345/items/2a09c4d06d2e3415bc8d)）


↓↓↓ [Red Hat公式 - ファイルシステム2.3.3](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/migration_planning_guide/sect-red_hat_enterprise_linux-migration_planning_guide-file_system_layout)より ↓↓↓

> Red Hat Enterprise Linux の前のバージョンでは、一部のプログラムで、起動初期に /var ディレクトリーをマウントする前に、実行時データを /dev ディレクトリーに格納できました。 主な Linux ディストリビューションでは、/dev ディレクトリーはデバイスノードにのみ使用し、/run を代わりに使用することが推奨されています。

> したがって、Red Hat Enterprise Linux 7 では、/run ディレクトリーは、/var/run ディレクトリーをバインドマウントする一時ファイルストレージシステム (tmpfs) です。同様に、/run/lock ディレクトリーは /var/lock ディレクトリーをバインドマウントするようになりました。/run と /run/lock に格納されたファイルは、永続的ではなくなり、再起動後に保持されません。つまり、アプリケーションは、インストール時ではなく、起動時に独自のファイルとディレクトリーを再作成する必要があります

公式によるとRHEL7では/var/runが一時ディレクトリ扱いとなっており、再起動後にファイル情報が保持されない仕様と明記してある。これが原因でAmazon Linuxでは/var/runに配置していたシステムが移行した後に動かなく現象が発生した。

# 対処1 - /var/runに配置しない
/var/runにec2-userがアクセスできるようにディレクトリを作成しているシステムの場合は、/var/runや/tmpなどの一時ディレクトリ以外にsocketファイル等を配置しないようにすると対処できる。

# 対処2 - 起動時にディレクトリを自動生成するようにする
`/usr/lib/tmpfiles.d`ディレクトリにconfファイルを作成して配置しておくことで起動時に/var/runへディレクトリを作成することができる。

```/usr/lib/tmpfiles.d/user_service.conf
# Type  Path            Mode    UID             GID             Age     Argument
d       /var/run/xxxxx  0755    ec2-user        ec2-user        -
```

# まとめ
Amazon Linux2に移行する時はAmazon Linuxの仕様だけではなくRHELの仕様も抑えておく必要があるので注意が必要です。

楽しくインフラ構築していきましょう！！！


# 参考
[/var/run 直下に作ったディレクトリが消えないようにする](https://server.etutsplus.com/centos-7-tmpfiles-d-deleted-outdate-files/)
[お前らもさっさとハマって泣くべきCentOS7の落とし穴4つ](https://qiita.com/suemoc/items/e29285e8e67263298f35#%E8%90%BD%E3%81%A8%E3%81%97%E7%A9%B43-%E6%B6%88%E3%81%88%E3%82%8B-varrun)
【Rails】ランダムな文字列をPrimary keyとして使う

# Abstract
Ruby on Railsでは、モデルを作成するときデフォルトでInteger型の`id`をprimary keyとして付与してくれる。
一方で、このQiitaの記事のURLのように、ランダムな文字列をprimary keyに用いたいケースもある。
この記事では、デフォルトで作成されるInteger型のidの代わりに、String型でランダムな文字列のidをprimary keyとする実装手順をメモする。

# Environments
- ruby: 2.6.5
- rails: 6.0.0

# 0. Userモデルを作成する。
今回はサンプルとして、Userモデルをscaffoldで作成する。

```
$ rails g scaffold User name:string
```

# 1. migrationでidの型を指定する
まずはmigrationファイルをいじり、idをString型にします。

```ruby:db/XXXXXXXXXXXXXX_create_user.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users, id: :string do |t|
      t.string :name

      t.timestamps
    end
  end
end
```
`create_table`で`id: :string`と指定することでidの型をデフォルトのIntegerからStringに変更することができます。

# 2. Modelでcreate時にランダムな文字列のidを設定する
idをstring形式に変更したことで、Model.create時に自動でidに数字が付与されなくなります。
そのため、Model側でcreate時にランダムかつユニークな文字列を生成してセットする必要があります。

```app/models/user.rb
class User < ApplicationRecord
  # create前にset_idメソッドを呼び出す
  before_create :set_id
  
  private
    def set_id
      # id未設定、または、すでに同じidのレコードが存在する場合はループに入る
      while self.id.blank? || User.find_by(id: self.id).present? do
        # ランダムな20文字をidに設定し、whileの条件検証に戻る
        self.id = SecureRandom.alphanumeric(20)
      end
    end
end
```

まずプライベートメソッドとして、`set_id`メソッドを作成します。
`while`の条件として、`self.id.blank? || User.find_by(id: self.id).present?`を定義していますが、つまり「idがまだ設定されていない、または、すでに同じidのレコードが存在する」場合にループに入るようになっています。
`while`のループの中では`self.id`に`SecureRandom.alphanumeric(20)`を用いて20文字のランダムな文字列（大文字小文字アルファベット+数字）を生成し、また`while`の条件式と検証します。
SecureRandomはrubyのライブラリです。他にも16進数からランダムに文字列を作る`SecureRandom.hex()`やUUID version4を作成する`SecureRandom.uuid`などがあるので用途に合わせて設定するといいです。--> [module SecureRandom (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html)

このメソッドを`before_create`コールバックで呼び出します。
`before_create`コールバックはモデルのcreate直前に呼び出され、updateの場合は呼び出されません。
updateの度にidが変わってしまってはいけないので`before_create`コールバック時に`set_id`メソッドを呼び出します。

# (additional)作成順に取得する
今のままだと`User.all`でレコードを取得しようとした時に`updated_at`の昇順で並んでいます。
例えば、`created_at`の降順で取得できるようにするためにはモデルファイルに以下のように設定を追加することで実装できます。

```app/models/user.rb
class User < ApplicationRecord

  # User.allで取得するときに、レコード作成日の降順で取得する
  default_scope -> { order(created_at: :desc) }

end
```

# Reference
- [Active Record マイグレーション - Rails ガイド](https://railsguides.jp/active_record_migrations.html)
- [module SecureRandom (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html)
【初心者】CSS　レスポンシブデザイン／レイアウト崩れ防止etc【備忘録５】

##8/16～8/18 勉強したこと

- レスポンシブデザイン→PC／タブレット／スマホの画面上でそれぞれ違うように表示させる方法。基本的にブレイクポイントが670px/100pxで設定されることがほとんど。
- フォントのサイズ／アイコンなどの配置（％）／メニュー表記などのレイアウト変更が可能。
- ＊{ box-sizing:border-box;}でレイアウト崩れを防止
- floatを使用していると、レイアウトなどを変えたときに背景（親要素）から浮いてしまうので、htmlで<div class="clear"></div>を書いてCSSで.clear{clear:left;}と書くことでfloatを解除する必要がある。
- display:none;→メニューアイコンの非表示にするためなどに使う
- display:block;→スマホのレイアウトの際には表示させる・・・などの際に使う。

##振り返り

自分で理解していることが、間違えている可能性もあるので、どこかで書いたものを見てもらう必要もあるのかなと思った。しっかり他人にも伝えれるようにしっかり自分のものにしていきたい。
次は自分自身で考えながら、初級と同じく中級／上級のページも作成する。
gem deviseをインストールする手順と理由

Ruby on Railsでのアプリケーション作成時にgemのdeviseを使って、サインアップやログイン、ログアウトなどのユーザー管理を導入する。
その時の手順と、その手順の意味をメモ。

## 前提：gemを新しく追加する時の流れ
1. Gemfileを更新
2. bundle installを実行
3. Gemfile.lockが自動的に更新される

## 本題：gem deviseインストールの流れ
### 1.Gemfileに `devise` を追記

```ruby:Gemfile
gem 'devise' #ファイルの一番下に追記
```

理由：
Gemをインストールする際に参照するため。
GemfileとはRailsアプリで利用するgemが記述されているファイル。
gemをインストールするときに `bundle install` というコマンドを実行するが
そのときにbundlerがGemfileを参照し、 **Gemfileに記載されているgemの中でインストールされていないものを見つけてインストールを実行する。**


### 2.ターミナルで `bundle install`

```bash:ターミナル

$ bundle install
```
理由：
Gemをインストールするため。
Gemをインストールする際のコマンドは `bundle install`

### 3.Gemfile.lockで `devise` を確認

理由：
インストールされたかを念のため確認するため。
Gemfile.lockは **Gemfileを元に実際にインストールされたgemに加え、依存関係にあるgemが記述されたファイル。**

## deviseのセットアップ

インストールが終わったらセットアップを行う。

### 4.ターミナルで `rails g devise:install`

```bash:ターミナル
$ rails g devise:install
```
理由：
deviseの設定ファイルをrailsアプリケーションにインストールするため。

### 5.ターミナルで `rails g devise User`

```bash:ターミナル
$ rails g devise user
```
理由：
deviseで認証するためのモデルを作成するため。
Userモデルを作成するためUserにしているが、他のモデルを使用したいときはそのモデル名で作成。

### 6.ターミナルで `rake db:migrate`

```bash:ターミナル
$ rake db:migrate
```

理由：
5.でつくったモデルを元にデータベースをつくるため。
これを行わないとデータベースにUsersテーブルが作成されない。

### 7.ターミナルで `rails g devise:views`

```bash:ターミナル
$ rails g devise:views
```

理由：
deviseの用のビューを作るため


おわり。
tmuxのsessionをfzfで選択できるようにする。

# 概要
各リポジトリをtmuxのsessionで管理しているのだが、数が多くなってきて`prefix + s`で毎回上下キーで選択するのが大変（数字で選択するのも）なので、fzfで曖昧検索で選択できるようにしました。ただshellでコマンドを打つのはvimの操作中や何かのダウンロード中はできない（一手間いる）ので、tmuxのキー操作（prefix + なにか）から呼び出せるようにしました。

**※追記**
tmuxのプラグイン作りました！
https://github.com/hokita/tmux-session-fzf

# やったこと
- tmuxのsessionをfzf（詳しくはfzf-tmux）で選択できるようにするshell scriptを作成する。
- tmuxのキーバインドにshell scriptを割り当てる。

# 作業
## 事前作業
作成したshell scriptをどこでも呼べるようにしたいので、スクリプトを置くディレクトリを作成し、パスを通しておきます。※既にあるかたは読み飛ばしてください。

```shell
# 今回はHOME配下にbinディレクトリを作成
$ mkdir ~/bin
```
下記をお使いのshellの設定ファイル（.bashrcもしくは.zshrcなど）に追加。　

```shell
export PATH=$HOME/bin:$PATH
```

設定ファイルを再読込

```shell
# .zshrcの場合
$ source ~/.zshrc
```


## shell script作成
PATHの通ったディレクトリに下記を作成する。

```shell:~/bin/tmux-session-fzf
#!/bin/bash

if [ -n "$TMUX" ]; then
  SELECTED="$(tmux list-sessions | fzf-tmux | cut -d : -f 1)"
  if [ -n "$SELECTED" ]; then
    tmux switch -t $SELECTED
  fi
fi
```

実行権限を付与する。

```shell
$ chmod 755 ~/bin/tmux-session-fzf
```

実行できるか確認

```shell
$ tmux-session-fzf
```

新しいウィンドウにfzfでのsession選択画面が表示されるようになったかと思います。
### ポイント
`fzf-tmux`を使用しましたが、`fzf`もしくは`peco`でもshellコマンド上だと動きます。が、tmuxのキーバインドからだと動作しないので`fzf-tmux`を使用しております。

## tmuxのキーバインドにスクリプトを登録
※追記：tmux3.0以上では`run`だけだとフリーズするようになったので、`-b`のオプションを付与する

```shell:~/.tmux.conf
# 今回はprefix + y に登録。
bind y run -b tmux-session-fzf
```

以上です。`prefix + y`でsession選択のfzf画面を呼べるかと思います。

### 参考サイト
- [tmux/tmux](https://github.com/tmux/tmux)
- [junegunn/fzf](https://github.com/junegunn/fzf)
- [tmux session peco](https://pocke.hatenablog.com/entry/2017/06/22/142419)
【Python】トレード用にも必須のTimer を作る






```Python:timer.py
import time
import datetime

def start_timer():
    # Start time set
    start_time = datetime.time(17, 47, 0)
    while True:
        todaydetail = datetime.datetime.today()
        hour = todaydetail.hour
        minute = todaydetail.minute
        second = todaydetail.second
 
        current_time = datetime.time(hour, minute, second)
        print(current_time)
         
        if start_time <= current_time:
            print(current_time)
            break
        else:
            print('wait')
            
        time.sleep(10)

start_timer()
```


```Python:stop_timer.py
def stop_timer():
    # Set Stop TIme 20:23:00
    stop_time = datetime.time(20, 23, 0)

    todaydetail = datetime.datetime.today()
    hour = todaydetail.hour
    minute = todaydetail.minute
    second = todaydetail.second

    current_time = datetime.time(hour, minute, second)

    if stop_time <= current_time:
        #print(current_time)
        gonogo =1
        return gonogo
    else:
        gonogo =0
        return gonogo
```


```Python:
stop_timer()  # 0: before,  1: after

```
Rails6サーバー起動時webpackerエラー(Node.jsアップデート, yarnインストール)

# 内容
- VagrantでRails6の環境構築をして、サーバー起動したときにwebpackerをインストールしろというエラーが発生したのでその対応
- Rails6からwebpackerが標準となり、yarnのインストールが必要になったためエラーが発生した模様
- 結論: webpackerをインストールしようとするとNodejsが古いと指摘を受けアップデート、yarnも必要となりインストール、その後webpackerインストールしたら解決できた


# 環境

- macOS Mojave 10.14.6
- VirtualBox 6.0.10
- Vagrant 2.2.5
- centos/7 (virtualbox, 1905.1)
- rbenv 1.1.2-4-g577f046
- ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
- Rails 6.0.0
- psql (PostgreSQL) 12.0
- nodejs v12.12.0
- Bundler version 2.0.2



# エラー内容

```sh
# エラーを発生させたコマンド
$ bin/rails s -b 0.0.0.0 -p 2000



# エラー内容
=> Booting Puma
=> Rails 6.0.0 application starting in development 
=> Run `rails server --help` for more startup options
RAILS_ENV=development environment is not defined in config/webpacker.yml, falling back to production environment
Exiting
Traceback (most recent call last):
...
略
...
/home/vagrant/share/vendor/bundle/ruby/2.6.0/gems/webpacker-4.0.7/lib/webpacker/configuration.rb:91:in `rescue in load': Webpacker configuration file not found /share/sample_app/config/webpacker.yml. Please run rails webpacker:install Error: No such file or directory @ rb_sysopen - /share/sample_app/config/webpacker.yml (RuntimeError)
```


# やったこと

## webpackerインストール
エラー文が長々とありましたが、最後の方に`Please run rails webpacker:install`とあるので素直に従う

```sh
$ rails webpacker:install
Webpacker requires Node.js >= 6.14.4 and you are using 4.9.1
Please upgrade Node.js https://nodejs.org/en/download/
```

どうやらNode.jsが古いとのこと

## Node.jsアップデート
Node.jsが古いと指摘が会ったのでアップデート
Node.jsのバージョン管理ツールnvmを使用してインストールする

```sh
# 現在のバージョン確認
$ node -v
v4.9.1

# Node.jsのバージョン管理ツールnvmをclone
$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ echo . ~/.nvm/nvm.sh >> ~/.bashrc
$ . ~/.bashrc

# nvmバージョン確認
$ nvm --version
0.35.0

# インストールできるNode.jsの確認
$ nvm ls-remote

# 最新の安定版をインストール
$ nvm install stable

# バージョン確認
$ node -v
v12.12.0
```

アップデート完了したので再度webpackerインストール

```
$ rails webpacker:install 
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
```

今度はyarnが必要とのこと


## yarnインストール
yarnインストールのエラーが発生したので従う

```sh
# yarn最新版を取ってくる
$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
[yarn]
name=Yarn Repository
baseurl=https://dl.yarnpkg.com/rpm/
enabled=1
gpgcheck=1
gpgkey=https://dl.yarnpkg.com/rpm/pubkey.gpg


# yarnをインストール
$ sudo yum -y install yarn

# バージョン確認
$ yarn -v
1.19.1

# package.jsonリスト化されている全ての依存関係をインストール
# railsのプロジェクトの中で次のコマンド実行
$ yarn install
```

yarnインストールが完了したので再々度webpackerインストール

```sh
$ rails webpacker:install
Webpacker successfully installed 🎉 🍰
```

インストール完了したら再度サーバー起動

```sh
$ bin/rails s -b 0.0.0.0 -p 2000
```

![スクリーンショット 2019-10-19 17.14.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449626/6a73ca28-917e-14f0-11e9-58cd8376229a.png)




(参考)
https://tako1192.hatenablog.com/entry/2016/05/07/054522
FreeBSDのarmの実装

当初FreeBSDのkernelのarmの実装はNetBSDのコードをベースに作られていました。NetBSDのコードはRiscBSDという古いプロジェクトから受け継がれたもののようです。

armは同じチップがarmv6と言われたりarm11x6と言われたりしてとっても混乱します。

FreeBSDでは2014年くらいにarmv6(11x6)からNetBSDの実装から離れて独自実装に切り替えました。そのためv5以前のサポートコードはlocore-v4.Sのようになりv6以降はlocore-v6.Sのようになりました。

![arm-ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/a5d41716-8046-a129-cb5a-bd75ac3bfcff.png)

いろいろ調べていたら、当初はNetBSDのコードをベースにv6のサポートを入れていたようです。これを消して独自実装に切り替えたようです。

https://lists.freebsd.org/pipermail/svn-src-head/2012-December/043491.html

この判断は今となってみると、失敗だったと思われます。

というのは現在FreeBSDはarm.arm,arm.armv6,arm.armv7と三つのアーキテクチャになってしまってます。arm.armv6はv7(CORTEXA)よりもv5に近くv7以降で変更を加えるのが正解だったと思われます。

NetBSDのコードをみるとv6以前とv7で分かれているようです。

NetBSDのソースは取得方法は[こちら](https://qiita.com/furandon_pig/items/0ea880efca245c5beb6d)に記述がありましたが、curlを入れてないので、直接下記のコマンドを叩きました。

```
% fetch "http://ftp.jaist.ac.jp/pub/NetBSD/NetBSD-8.1/source/sets/syssrc.tgz"
```

NetBSDのarmのコードのありかはusr/src/sys/arch/arm/armです。

NetBSDから受け継がれたコードはcpufunc_asm_armv5_ec.Sのようにarmのバージョン毎のファイルが定義されていました。

FreeBSDで新しく実装されたファイルはマクロでCPUの設定を行うようになっています。

```locore-v6.S
	mcr	CP15_TLBIALL		/* Flush TLB */
```

は

```include/sysreg.h
#define	CP15_TLBIALLIS		p15, 0, r0, c8, c3, 0 /*Invalidate entire unified TLB IS */
```

のように定義されています。

cp15_ifsr_get()は

```include/cpu-v6.h
_RF0(cp15_ifsr_get, CP15_IFSR(%0))
```

のように定義されていて、

```include/cpu-v6.h
#define _RF0(fname, aname...)                                           \
static __inline uint32_t                                                \
fname(void)                                                             \
{                                                                       \
        uint32_t reg;                                                   \
        __asm __volatile("mrc\t" _FX(aname): "=r" (reg));               \
        return(reg);                                                    \
}
```

となり、

```include/sysreg.h
#define CP15_IFSR(rr)           p15, 0, rr, c5, c0,  1 /* Instruction Fault Status Register */
```

となります。

cpu_asm-v6.Sにあるarmv6のアセンブラで、

```
#if __ARM_ARCH == 6
```

のような条件があるのですが、そもそもファイル名がv6なので、デフォルトはv6でそれ以外の場合(v7)の条件式にすべきではないでしょうか。

あとcpu_asm-v6.Sの中はマクロだったり直書きだったりして、統一感がまったくありません。

armv6の1136r0には無い(armv6kになるr1にはあるようです)clrex命令がFreeBSDでは直に書かれてしまっていますが、NetBSDではarmv6では使わないような条件が入っています。1176にはあるようなんですが。ここら辺をみるとFreeBSDの実装者がNetBSDの実装者より劣っているのがわかります。とりあえずラズパイの1176で動けばいいというつもりで書いたのではないでしょうか。

v6以外とは現状v7とv8の32Bit版(aarch32)になるようです。armの32Bitは、ほぼこれで終わりと思われます。

v6というのであればまず1136で動くようにするのがOSのサポートの正しい姿勢だと思います。

どうもFreeBSDのv6対応の実装ははやちゃくちゃない（庄内弁）感じがします。

1136なComcerto 1000のために調べているのですが、現状のFreeBSDのコードはNetBSDから受け継がれたarmv5サポートより、1136(v6)の方が怪しい(動かない)状態になっているとようです。

いろいろ考えてみるとFreeBSD側の問題もありますが、armが複雑な製品構成なことも要因な気がします。

armv6をarmv4系に寄せるのが正解な気がしますが、おそらくFreeBSDにはもう力がないので、最終的に両方消すという判断になってしまいそうです。とっても残念です。
Ruby(rails) エラーについて

#Ruby エラー問題
Ruby(rails)を学んでいく中で、様々なエラーに直面しており、
その都度確認していたので、備忘録としてこちらにまとめておきます。
＊記載に誤りなどございましたら、ご指摘いただけますと幸いです。
＊適宜、追記していきます。

##エラー文
###syntax error:構文（文法）エラー　
→該当の構文を見直しましょう。

###unexpected end-of-input, expecting keyword_end
endの数が不一致
→構文全体を改めて見直し、endが抜けている場所を見つけましょう。

###wrong number of arguments
引数の数が不一致　
→該当しているメソッドとそれに関連する引数（変数）の数を確認しましょう。　
*エラー文内　（A for B) (given = A, expected=B) :引数はA個のはずなのに、B個ある。

###unexpected tCONSTANT
閉じタグが無いことが原因で起こることが圧倒的に多いエラー。
→""の閉じ忘れがないかチェックしましょう。
*VS codeではタグが閉じられていなかったりする場合、色が変わってますので、その部分の前後をよく見ると、解決に導きやすくなると思われます。

###undefined local variable or method '~' for main:Object (NameError)
変数名に誤り
→変数名を確認しましょう。スペルミスなどのケアレスミスの可能性も視野にいれて確認しましょう。

###for nil:NilClass 
定義していない変数（クラス）を使用しています。
→該当レシーバー(メソッドを呼んだオブジェクト)の状態を確かめましょう。レシーバーがnilになってしまっている可能性が非常に高いです。

##エラー解決の際に使えるメソッド
###Pメソッド
puts同様、自身の右に書かれたインスタンスに関する出力をしますが、
putsメソッドが返り値を出力するのに対し、pメソッドはそのままの形で出力します。
→どこでエラーが発生しているのか特定しやすくなります。

以上となります。最後までご覧いただき、ありがとうございました！
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします！
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。
初学者のVPSサーバー構築手順書(2)

#VPSにログイン

SSHクライアントソフトのインストールサーバーへssh接続が必要になるのでTerminalから以下を打ち込む

☆Winならクライアントが必要で[Putty](http://hp.vector.co.jp/authors/VA024651/PuTTYkj.html )☆

##やった事

まずはrootに入るため

```
$ ssh root@[IPアドレス]
```
を打ち込めば

```
The authenticity of host 'IPアドレス (IPアドレス)' can't be established.
ECDSA key fingerprint is SHA256:[鍵パスが生成]
//接続するのでyes
Are you sure you want to continue connecting (yes/no)?
```
しかし注意喚起が・・・

```
Warning: Permanently added the ECDSA host key for IP address 'XXX.XXX.XXX.XXX' to the list of known hosts.
```

これは初めて接続したノードがある場合や、以前接続したことのあるホストの証明書が変更された場合に出力されるもので、known_hostというSSHサーバ証明書リストにIPアドレスXXX.XXX.XXX.XXXの証明書を追加したというメッセージだそうで。

これは正常な動作であり、計算結果には影響しないため無視して構いませんとの事で無視。

しかしその下にも・・・

```
ssh_dispatch_run_fatal: Connection to [IPアドレス] port 22: Broken pipe
```

つまり切断されたので再度

```
$ ssh root@[IPアドレス]
root@[IPアドレス]'s password:[鍵じゃなく1で作成したPASS]

SAKURA Internet [Virtual Private Server SERVICE]

[root@tk0-000-00000 ~]#  
```

要するに初めて接続した場合は一度切断されるのか？
意図がよくわかりませんが・・・
rootでのアクセスは成功！

##OsUpdate
最初にやっておいた方が良い？
のかはわかりませんが・・

```
$ yum update
```
走らせて

```
Is this ok [y/d/N]:y
```

選択は何度かあります。
なのでだいたいyで最後に完了しました!と出たら終了。

##セキュリティ強化

次にrootによるログインや操作を許可しない方針にした方が良いため

・ 一般ユーザの作成
・ 公開鍵認証の設定
・ sudo 設定
・ SSH 接続時、root でのログインを禁止
・ SSH 接続時、パスワード認証を禁止

を3で進めていきます。
自分しか触らないのでいい気もしますが・・勉強のため
Xcode11にアップデートをしたらRealmが動かなくなった

開発中のアプリをXcode11にアップデートをしたらビルドは通るが起動時にエラーが発生してクラッシュするようになった

例外にブレークポイントを貼りエラーを調べてみると

```
Primary key property 'name' does not exist on object 'RealmSwiftPermissionRole'
```

このようなエラーが

*ちなみに例外にブレークポイントを貼る方法はこちら*
https://qiita.com/mono0926/items/bf70c7ef15db046ee163

エラーを調べてみるとどうやらXcode11に対応するには**RealmSwiftのバージョンが3.19.0以上**なければならないとのこと

Podファイルに以下を追加してpod install

```
pod 'RealmSwift', '~> 3.19.0'
```

CreanBuledをして起動するとエラーが発生しなくなった
macOS Catalinaでサブセットフォントメーカーが使えなくなったのでPythonで日本語のWEBフォントを作成する

## はじめに
macOS Catalinaで、日本語のフォントをサブセット化する人気No.1ツール、[サブセットフォントメーカー](https://opentype.jp/subsetfontmk.htm)が使えなくなりました。サブセット化したフォントをwoff、woff2に変換するツール、[WOFFコンバータ](https://opentype.jp/woffconv.htm)も同様に使えなくなっています。ツールのアップデートを待ちつつ、Pythonのライブラリを使って日本語のWEBフォントを作ってみようと思います。

## 環境の確認
### Pythonが入っているか確認
```
$ which python
/usr/local/bin/python
```

### pipが入っているか確認
```
$ which pip
/usr/local/bin/pip

# ついでにpipをアップデート
$ pip install --upgrade pip
```

### お好きな日本語フォントを準備
今回は、[Hannari.otf](https://typingart.net/?p=44) （はんなり明朝）。

# インストール

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

```
$ pip install fonttools
```


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

```
$ pip install brotli
```

## 変換コマンド
フォントをサブセット化しつつ、woffとwoff2をそれぞれ作成します。

```
pyftsubset Hannari.otf --text-file=web-font.txt --layout-features='*' --flavor=woff --output-file=public/stylesheets/Hannari.woff
pyftsubset Hannari.otf --text-file=web-font.txt --layout-features='*' --flavor=woff2 --output-file=public/stylesheets/Hannari.woff2

```
最初の引数: オリジナルのフォント
--text-file: WEBフォントに格納したい文字を書いたテキストファイル
--layout-features: '*'（すべて）
--flavor: woffかwoff2
--output-file: 出力ファイル名

上記のコマンドを.shファイルなどに書くことで、次回からは一発で日本語フォントのサブセット化、およびwoff、woff2の作成をすることができますね。

## 参考URL
- [Noto Serif CJK（源ノ明朝）の font-feature-settings:palt 対応サブセットフォントを作る](https://qiita.com/sygnas/items/89e4a3a8dee79e6159c6)
【powershell】 文字のコードポイントを取得する

# 関数
コードポイント → 文字

```powershell
function unicode ([string]$codepoint) {
    return [Convert]::ToChar([Convert]::ToInt32($codepoint, 16))
}
```
文字 → コードポイント

```powershell
function codepoint ([string]$s) {
    return [Convert]::ToInt32($s -as [char]).ToString("x")
}
```

# 動作

```
PS > unicode 72ac
犬

PS > codepoint 犬
72ac
```

文字を厳密に指定するときに使えるかもです。
【Ruby】クラス・モジュールに定数が定義されているか確認する

そんなに使う機会は無いと思うけど備忘録。

# サンプルコード

`#const_defined?`を使えばいい

```ruby
# frozen_string_literal: true

# == クラス ==
class Foo
  SOME_CONSTANT = 'hoge'
end

class Bar
end

puts Foo.const_defined?(:SOME_CONSTANT) # => true
puts Bar.const_defined?(:SOME_CONSTANT) # => false

# == モジュール ==
module Hoge
  SOME_CONSTANT = 'hoge'
end

module Piyo
end

puts Hoge.const_defined?(:SOME_CONSTANT) # => true
puts Piyo.const_defined?(:SOME_CONSTANT) # => false
```
自己紹介

はじめまして！
現在関西に在住している２０歳後半のエンジニアです。
ずっとインプット専門だったQiitaにアウトプットして、より理解を深めるために、
これから記事を投稿していこうと思いました。
今回は、初めての投稿なので、自己紹介記事を投稿しました。

<h2>仕事</h2>
現在（2019年10月19日）SES事業に携わっており、
お客様の現場に駆り出され、稼働時間の関係で休むことのハードルが爆あがりしている会社に所属しています。
これまでアサインした案件はどれもWeb開発を行なっており、開発、テストを担当し、経験を積んでまいりました。

<h2>自己研鑽</h2>
Ruby、Ruby on Railsを勉強しています。

Androidアプリのポートフォリオ作成して、実際にリリースした際、すごく充実感を感じたので、Webの勉強とは別に、Firebaseを用いたアプリを現在開発しています。

Qiitaでは、勉強したことをアウトプットし、より知識を深めたいと考えています。

<h2>実務経験</h2>
【バックエンド】
Java、Spring、Spring Boot

【フロントエンド】
HTML、CSS、JavaScript、Angular2、Angular JS

【RDBMS】
MySQL、PostgreSQL、Oracle
SwiftでYouTubeの特定の動画を再生するアプリを作成した時の気づきについて

この記事では、「SwiftでYouTubeの特定の動画を再生するアプリを作成した時の気づきについて」記載します。

＜作成環境＞
■PC:MacBook Air (11-inch, Mid 2012)
■macOS:10.14.4
■Xcode:10.2.1
■使用言語:Swift 4

＜事前準備＞
・CocoaPodsのインストール
(参考URL:https://qiita.com/ume1126/items/9ec378c02ca1b06287e9)

＜参考URL＞
https://dev.classmethod.jp/smartphone/youtube-player-ios-helper/

＜気づき＞
●「youtube-player-ios-helper」のバージョンについて、GitHubで確認して、Podfileに記述する
こと(2019/10/19現在　Version: 0.1.6)

●再生したいYouTubeの動画ページの中にある「共有」から「埋め込む」選択し、その中にある文字列の中の「src="https://www.youtube.com/embed/-ssjsjsjsjsj」から
最後の/から続く文字列を控えること（例：-ssjsjsjsjsj）
この文字列をコード内の「withVideoId: "-ssjsjsjsjsj"」に記述する

●動画をループで再生したい場合は、
「playerVars: ["playsinline":1, "loop":1]」
と記載すること
（参考URL:https://developers.google.com/youtube/player_parameters?hl=ja）

●停止ボタンを押した際、ラベルのステータスが変化しないので、下記２行をswitch文に記載
case YTPlayerState.unknown:
    stateLabel.text = ""
case YTPlayerState.queued:
    stateLabel.text = ""

下記がコードになります。

```swift:ViewController.swift
import UIKit
import youtube_ios_player_helper

class ViewController: UIViewController, YTPlayerViewDelegate {
    
    @IBOutlet weak var playerView: YTPlayerView!
    
    @IBAction func tapPlay(_ sender: Any) {
        self.playerView.playVideo()
    }
    
    @IBAction func tapPause(_ sender: Any) {
        self.playerView.pauseVideo()
    }
    
    @IBAction func tapStop(_ sender: Any) {
        self.playerView.stopVideo()
    }
    
    @IBOutlet weak var stateLabel: UILabel!
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        playerView.delegate = self;
        self.playerView.load(withVideoId: "-ssjsjsjsjsj", playerVars: ["playsinline":1, "loop":1])
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    func playerView(_ playerView: YTPlayerView, didChangeTo state: YTPlayerState) {

        switch (state) {
        case YTPlayerState.unstarted:
            stateLabel.text = "停止中"
        case YTPlayerState.playing:
            stateLabel.text = "再生中"
        case YTPlayerState.paused:
            stateLabel.text = "一時停止中"
        case YTPlayerState.buffering:
            stateLabel.text = "バッファリング中"
        case YTPlayerState.ended:
            stateLabel.text = "再生終了"
        case YTPlayerState.unknown:
            stateLabel.text = ""
        case YTPlayerState.queued:
            stateLabel.text = ""
        default:
            break
        }
    }

}
```
【Rails】RSpecでアプリの挙動をテストする

#はじめに
RSpecのfeatureのテストします。
featureのテストとはぽちぽち手動でやるテストをプログラムで自動でやるって感じです
何か文字列を投稿する時を例に説明すると以下のような手順になります。
1. 投稿できるページにアクセスする
２. 入力フォームに入力する
３. 投稿ボタンをクリックする
４. リダイレクト先を確認する

実装時に手動でテストを行うとこんな感じでテストを進めると思います
この操作をRSpecを使うと自動でテストできます。

**では実際にやっていきましょう！！**
 
#テストコード
今回はRSpecの公式ページのコード(ちょっと編集済)を使って説明していきたいと思います。

```ruby:spec/features/widget_management_spec.rb
require "rails_helper"

RSpec.feature "Widget management", :type => :feature do
  scenario "User creates a new widget" do
    visit "/widgets/new"

    fill_in "name", :with => "My Widget"
    click_button "Create Widget"

    expect(page).to have_text("Widget was successfully created.")
  end
end
```

* `scenario`
 * モデル、コントローラーのテストとは違って、`describe`、`context`、`it`は使用しません。`feature`、`scenario`を使います
 * （`describe`、`context`） = `feature`
 * `it` = `scenario`だと思って使って行けばだいたいOKです
* `visit "/widgets/new"`
 * URL`/widgets/new`にアクセスします
* `fill_in "name", :with => "My Widget"`
 * id名が`name`のフォームに`My Widget`を記入します
* `click_button "Create Widget"`
 * `Create Widget`と表示されているボタンをクリックする
* `expect(page).to have_text("Widget was successfully created.")`
 * リダイレクトした先の`page`に`Widget was successfully created.`というテキストが含まれているかどうかをテストする

以上が挙動のテストです

**気になるところ、疑問などあれば質問、コメントよろしくお願いいたします！！！**
RawRepresentableを知る

#はじめに

以前こんな記事を投稿しました

[UITableviewにCaseiterableとCustomStringConvertibleを使ってみる](https://qiita.com/Mott/items/5dad583789930d526468)

そこでRawRepresentableに出会ったのですが、RawRepresentableがなんなのかぼんやりとしか知らなかったので調べてみようと思いました。

#RawRepresentableとは

###定義

```swift:
protocol RawRepresentable
```



> For any enumeration with a string, integer, or floating-point raw type, the Swift compiler automatically adds RawRepresentable conformance. 

RawRepresentableはEnumにString,Int,Floatを実装した場合デフォルトで追加されている。

```swift:
var rawValue: Self.RawValue
```

Swiftのenumで自然に使っている、Hoge.hoge.rawValueのrawValueはRawRepresentableからきていて、RawRepresentableを実装していることによって値を持たせることができる

String,Int,Float以外でも、RawRepresentableを実装することによって値を持たせてあげることが可能になります。


## 値にアクセスする

### rawValue

String,Int,Float以外でも実装すれば、値を持たせたり呼び出しに使うことが可能です

```swift:
//RawRepresentableに対応していないためErrorになる
enum Color: UIColor {
    case red = UIColor.red
}
```

RawRepresentableを実装してあげることにより

```swift:
enum Color {
	case red
}

extension Color: RawRepresentable {
	typealias RawValue = UIColor
	
	init?(rawValue: RawValue) {
        switch rawValue {
        case UIColor.red: self = .red
        default: return nil
        }
    }

    var rawValue: RawValue {
        switch self {
        case .red: return UIColor.red
        }
    }
}
```

`Color.red.rawValue`として、UIColorをrawValueで使うことが可能になります


### 値を作成する

CustomStringConvertibleなどと組み合わせると

```swift:
class ViewController: UITableViewController {
	
	enum IndexText: Int, CustomStringConvertible {
		case title1
		case title2
        case title3

		var description: String {
			switch self {
			case .title1: return "cat"
                        case .title2: return "dog"
                        case .title3: return "rabbit"
			}
		}
	}

	override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
		let cell = UITableViewCell()
        //正しくない値が入った場合nilを返す
		cell.textLabel?.text = IndexText(rawValue: indexPath.row)?.description
		return cell
	}
}

```
`RawRepresentable`の`init?(rawValue: Self.RawValue)`を使うことにより、indexPath.rowで新しいインスタンスを作成し、とてもスッキリ書くことができます。



#まとめ

・RawRepresentableはString,Int,Floatにデフォルトで実装されている
・Hoge.hoge.rawValueやinit?(rawValeu:)を使いインスタンス生成など様々な使い方ができる。



#さらに詳しく

[RawRepresentable](https://developer.apple.com/documentation/swift/rawrepresentable)

[The RawRepresentable Protocol in Swift](https://oleb.net/blog/2016/11/rawrepresentable/)
【エラー対処】PyCharmでモジュール読み込みエラーが発生する


# はじめに

PyCharm便利ですよね
VSCodeだと色々と設定がいりますが、IntelliJは大体の設定をいい感じに使用しているので、普段使いしやすいないようになっています。

最近PyCharmで開発をしているとPythonのモジュール読み込みエラーが発生するため、それの解決方法をまとめます。

# ファイル構成

今いるフォルダが`python_how_to_module`というフォルダで、このフォルダに対して「プロジェクトを開く」をしています。
その中のディレクトリ構成は以下です。

```
.
├── README.md
└── calc
    ├── __pycache__
    │   ├── add.cpython-36.pyc
    │   └── add.cpython-37.pyc
    ├── add.py
    └── print.py

```

画像で貼ると以下のようになります。

<img width="695" alt="スクリーンショット 2019-10-19 16.35.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/a31d9976-234e-82cf-3474-e0864bc897cf.png">


# 問題

モジュール化・パッケージ化を学ぶためにこの`python_how_to_module`を作り
calcというフォルダを作って、その中にadd.pyとprint.pyを作りました。
        
add.pyは以下のようにします。

```python
def add(x, y):
    return x + y


if __name__ == "__main__":
    print(add(10, 20))

```

上記のファイルをprint.pyから呼び出して、add.pyをモジュールとして利用するわけです。

そこで、**PyCharmの表記上エラーが出ないように**print.pyを書くと以下のようになりました。

```python
from . import add

print(add.add(2,3))
```

これはおかしいですね･･･。
モジュール化なら、別にカレントディレクトリを示す「.」などはいらないはずです。
通常なら

```
import add

print(add.add(2,3))
```
のようになるはずです。


この

```python

from . import add
```

では、PyCharmの表記上はエラーが出ません。
<img width="1024" alt="スクリーンショット 2019-10-19 16.41.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/833150a5-e394-3063-483a-1101d5008e95.png">


しかし、Control＋Rで実行すると以下のようなエラーが発生します。

```bash
/Users/ganariya/.pyenv/versions/3.7.3/bin/python /Users/ganariya/Desktop/python_how_to_module/calc/print.py
Traceback (most recent call last):
  File "/Users/ganariya/Desktop/python_how_to_module/calc/print.py", line 1, in <module>
    from . import add
ImportError: cannot import name 'add' from '__main__' (/Users/ganariya/Desktop/python_how_to_module/calc/print.py)
```

<img width="1023" alt="スクリーンショット 2019-10-19 16.42.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/b3e405a7-9831-03f0-751a-89b89229dbb5.png">

---

次に、通常通り、普通ならうまく動くはずのファイルの書き方をしてみます。

```py
import add

print(add.add(2,3))
```

上記はPyCharm上では赤線、つまりエラー判定され、インテリセンスも効かなくなってしまいます。

<img width="1024" alt="スクリーンショット 2019-10-19 16.44.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/72ca2d11-3e0d-d4ab-e8ab-63ef1015f308.png">

ただ、PyCharm上ではエラー判定されますが、実行はうまく行きます。
どうやらPyCharmの問題のようです。

# ソースルートの指定

このような問題が起こる原因はどうやら

- PyCharmがデフォルトでフォルダを作成すると、パッケージであるとして判断する
- ソースコードのすべてのルートが`python_how_to_module`である、というのがデフォルトになっている。

というのが原因のようです。
そのため、PyCharmの表記エラーを防ぐためには`from .`のようにカレントディレクトリ指定をする必要があり、実行時はエラーが出るようです（当然実行時はカレントディレクトリ指定がいらないため（モジュールであるため））

そこで、ソースルートを指定します。
今回使用したいフォルダ`calc`を右クリックしてソースルートを選択します。

<img width="626" alt="スクリーンショット 2019-10-19 16.47.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/f406519f-467d-ee70-6337-aa3e3f46bf99.png">

以上の操作を行うことで通常の書き方

```python
import add

print(add.add(2,3))
```

でエラーが出ず、なおかつインテリセンスが効くようになります。


# 最後に

PyCharm特有のエラーの解決方法についてまとめました。
しかし、問題の内容の原因理解には至っていません。
もし、分かる方がいらっしゃったら教えていただけるとありがたいです。

Pythonを雰囲気で使っているため、きちんと理解して使用していきたいと思います！
仙台CTF 2017 [Tri03] ニックネーム 50

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/9a3882ea-6b34-90c9-ef58-6ec5778dee55.png)

#解いてみた

「FBI行動分析課」で検索。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c3da6edb-f636-30f2-6963-1b60b4a03673.png)

クリミナルマインドですか。
見たことないです。

wikipediaを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/3197c50d-6600-fcf3-dbd5-271e2519d211.png)

ペネロープ・ガルシアさんですか。
wikipediaにはニックネーム書いてなかったです。

「ペネロープ・ガルシア ニックネーム」で検索。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/e01d0688-7f71-de58-966e-6b38dd1239f1.png)

プロフェット（prophet）が答え？と思ったら違いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c89b484d-8cb2-b56e-df1b-f032747684fa.png)

プロフェットはこの人でした。

他のWebページを見てるとありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/191d49a7-715a-73e9-61f5-091103e57ffa.png)

これを英語に直したものが答え。
パスワードを自動生成Linux/MAC

# 情報は漏れる。パスワードはそれぞれ自動生成で保存しておくのが良いかも。

---
故意かどうかわかりませんが、保存したパスワードが平文で保存されていたり、投稿サイトにアップされたり、倒産した会社のユーザー、パスワードのセットが販売されたり、、、、大変な時代です。パスワードは自動保存される機能が各ブラウザにあるので、それぞれ自動で生成するのが良いと思います。ランダムな列にしておけば、パスワードに含まれる個人情報が漏れる可能性は低くなる気がします。

信用できないを前提に。

---

## linuxの場合 $ mkpasswd
ubuntuの人
$ sudo apt-get install expect

centos, redhatなどの場合。expectをインストールすると使えます。
\# yum install expect
$ mkpasswd

## macOSの場合 $ pwgen
macportsの人
$ sudo port install pwgen

mabbrewの人
$ brew install pwgen
Swift TableViewからの画面遷移

Tableviewcellでセルごとに処理を変えるにはどうするか。TableViewの各セルがタップされると、UITableViewDelegateProtocolから以下のメソッドが呼ばれる。

```swift:qiita.rb
tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
```
そして、TableView上のどのセルがタップされたかは、引数のindexPathによって判別することができる。それによって処理を分岐させます。今回はif indexPath.row == 0として、TableView上の最上位のセルを画面遷移の対象とした。

![ezgif.com-resize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172095/6a1d86ed-078a-220a-e76b-b08932f50371.gif)

具体的なコードは以下としました。

```swift:qiita.swift

import UIKit
import FirebaseFirestore

class ProductsVC: UIViewController, ProductCellDelegate {
    
    let data:Array<String> = ["iPhone", "iPad", "iPod", "MacBook", "tv", "WATCH"]


    // Outlets

    @IBOutlet weak var tableView: UITableView!

以下省略
    
```
```swift:qiita.swift
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0{
            let targetViewController = self.storyboard!.instantiateViewController(withIdentifier: "ToFirstViewController")
            self.present(targetViewController, animated: true, completion: nil)

```

かなり時間がかかったのでメモ書きです。
仮想ファイルサーバでNFSデータストア時のディスク性能

# 背景

開発や実験用として、自宅にVMWare ESXiサーバを導入している。
サーバにはM.2接続の高速だが容量の少ないSSDと、大容量だが低速な普通のHDDを接続している。SSDはESXiのデータストアとし、VMのルートディレクトリのvmdkの格納に使用している。
HDDは１台のVMにダイレクトに接続し、NFS/sambaによるファイルサーバとして利用している。データストアとしてESXiに接続するよりも高速に利用できる。
ダイレクト接続については[こちら](https://qiita.com/yamato225/items/32761c2c5ea44cc8670c)を参照。

また、このファイルサーバをさらにESXiのデータストアとし、実験用のVMのvmdkを配置している。
これはファイルサーバの容量を最大限有効活用したいため。

図にするとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189186/1be29c2c-c59a-0596-b104-8ab6bd5d6e51.png)

DataStore_NFS上のVMは、データストアとNFSを介してやっとHDDのデータを読み書きするわけなので、相当遅くなっていると思われるが、体感ではVMの起動時間などの面で差異は感じられない。

実際どの程度の差があるのか、測定してみることにした。

# 測定方法

ddコマンドで1GBのファイルを書き込む際の時間を測定する。
つまりシーケンシャルライト。
ハード構成については[こちら](https://qiita.com/yamato225/items/32761c2c5ea44cc8670c)に記載。

以下の２通り試した。


対象
(1) FileServerVM上からHDDに直接
(2) DataStore_NFS上のVMで

条件
(a) 1GBファイル
(b) 8GBファイル

VM構成
(1)CPU=4 Mem=16GB OS=CentOS7
(2)CPU=4 Mem=8GB OS=Ubuntu18


# 測定結果

(1) (a) 6.5秒(181MB/s)
(2) (a) 3.6秒(298MB/s) 
(1) (b) 30.8秒(279MB/s)
(2) (b) 4分43秒(30.4MB/s)

# 考察

1GB書き込み時では、NFSファイルサーバのほうが高速という結果であった。Linuxのファイルキャッシュが機能しているとすると、(1)(2)で差が生じるのはおかしい。NFSデータストアについて、ESXi側で何らかのキャッシュが働いているのではないだろうか。
Railsサーバー起動時PostgreSQLのConnectionエラー対応(PGSQL.5432)

# 内容
- VagrantでRails＋PostgreSQLの開発環境を整えていた際、`bin/rails server`でエラーが発生したときの対応をまとめました
- 結論を言うと最新版をインストールし直しました
    - 古いPostgreSQLを削除して最新版をインストールする方法は[こちら](https://qiita.com/KZ-taran/items/56c1d39dbbdd26df6faf#29-postgresqlインストール)


# 環境
- macOS Mojave 10.14.6
- VirtualBox 6.0.10
- Vagrant 2.2.5
- centos/7 (virtualbox, 1905.1)
- rbenv 1.1.2-4-g577f046
- ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
- Rails 6.0.0
- psql (PostgreSQL) 9.3



# エラー内容
サーバー起動時に次のエラーが発生

```sh
# サーバー起動
$ bin/rails s -b 0.0.0.0 -p 2000



# エラー内容
PG::ConnectionBad (could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
):
```

![スクリーンショット 2019-10-19 7.16.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449626/3c56dc75-91f6-42c8-f6fc-ad5a9f2e53de.png)



# やってみたけど効果なかった対応

## PostgreSQL起動
起動されてないから上記のエラーが出るという情報が多かったため、明らかに起動済みだけど従ってみる

```
# 起動
$ sudo systemctl start postgresql-9.3
# 確認
$ sudo systemctl status postgresql-9.3
```

効果なし

## initdbで初期化

初期化してみる

```sh
# 初期化前に削除
$ sudo rm -rf /var/lib/pgsql/9.3
# 初期化
$ sudo /usr/pgsql-9.3/bin/postgresql93-setup initdb
# 起動
$ sudo systemctl start postgresql-9.3
# 確認
$ sudo systemctl status postgresql-9.3
```

効果なし


# 解決した対応
postgresql-9.3を再度インストールしたりしてみましたが結局効果が得られなかったので、この機会に最新版をインストールし直したら解決
PostgreSQL9.3を削除してPostgreSQL12をインストールし直しました
古いPostgreSQLを削除して最新版をインストールする方法[こちら](https://qiita.com/KZ-taran/items/56c1d39dbbdd26df6faf#29-postgresqlインストール)
初学者のVPSサーバー構築手順書(1)

先生がVPSは面白いよーって言ってたのでWEBを作るタイミングで雑魚が挑戦してみる事にしました。

##まず登録してから起動してosインストールまで

osは大まかにLinux系とBSD系に分類されるようで

![標準OSインストール 名称未設定  - さくらのVPSコントロールパネル (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503961/e4caa375-178c-9597-1ce0-ea0d2e1facd7.png)

使用メモリを少しでも減らしたい方には、CentOS6 32bit版がおすすめらしいが2019年10月現在は
CentOS 6 64bit版かCentOS7 64bit版しかなかったのでこちらに。

##osメリット企業向け製品版であるRed Hat Enterprise Linux(RHEL) のクローンであること

なんといっても企業向け製品版のクローンという点は大きいです。
アップデートも間違いが少ないですし、何か問題があった時の対応も早いです。 基本的にRHELの最新版がリリースされれば、その都度、CentOSもリリースされますから、アップデートさえ行っておけば、安定版を常に利用することができるらしいです。

##パスワード

[Password Generator](https://www.graviness.com/temp/pw_creator/)
でセキュリティー度が高い物を生成

![パスワード自動生成  Automated Password Generator .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503961/3b05b960-8139-e916-1a50-6f992d3c9e69.png)

##パケットフィルタ
[WISESIPSさん](http://www.wisesips.com/service/staff_column/207.html)を参考に便利そうだったので全部にチェック！

インストールが始まり2に続く
仙台CTF 2017 [Tri02] 電子メール詐欺 50

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/287f9cbb-402c-4193-280d-d3575cc4d484.png)

#解いてみた

「ソーシャルエンジニアリング　企業メール」で検索。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d58f3841-e12a-1fd2-3be6-45853a767965.png)

これが答え。
仙台CTF 2017 [Tri01] NSAの攻撃ツール 50

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/c6d76ab7-9712-3861-f05f-8dd4aa5ff0f8.png)

#解いてみた

「WannaCry NSA」でgoogle検索。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7bd8b57d-f025-7dbe-a70a-e1bbd25417d3.png)

これが答え。
仙台CTF 2017 [Lab04] ダウンローダーの通信先 100

#問題

http://ctf.sectanlab.jp/2017/challenges

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f398881c-90d5-3e3a-570a-016d11ec6a4f.png)

#解いてみた

プロキシログを開いて、通信先に.exeがないか確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/75ba3009-e711-9ba5-09d9-e10c983bf8d7.png)

ひとつだけありました。
これが答えです。