OmniAICreator/Qiita-1.07M huggingface dataset:
よく使うRails関連コマンド集

プロトタイプ速く作成したい用手順メモ
最適解ではないので逐次更新

## 作成
シンプルなscaffoldだと不要そうなファイルも生成してしまうため、必要なファイルをできるだけまとめて生成する組み合わせで使用

### model × migration × test(model)
テーブルを追加する時

```
rails g model モデル名(s付けない) カラム名(idは自動生成されるので定義しない):型 × カラム数分
```

### controller × route × test(controller)
CRUD単位でAPIを作成する時

- viewはvueを使用するので作成しない
- helperそんなに作らないので作成しない

```
rails g scaffold_controller コントローラー名(s付けない) --skip-template-engine --skip-helper
```

## serializer
APIのレスポンスを作る時(active_model_serializersのgem)

```
rails generate serializer コントローラ名(s付けない)
```

## 削除
rails gのgをdにして、モデル名またはコントローラ名だけを指定する

## マイグレーション実行
テーブル構造に変更が入る時(テーブル名にはsが勝手に付く)

```
rake db:migrate
```

## マイグレーション状態確認
dbへの反映を確認したい時

```
rake db:migrate:status
```

## マイグレーション状態確認
dbへの反映を確認したい時

```
rake db:migrate:status
```

## Gemfileの更新
Gem追加した時

```
bundle install
```

## railsコンソール開く
インタラクティブに小さく動作確認したい時

```
rails c
```

## dbコンソール開く
```
rails db
```
axiosでBearerトークンを簡単に設定したい。

小ネタです。

# AxiosはBearer認証がめんどくさい
`axios` でAPIを呼ぶときの認証にBearerトークンを指定する場合、下のような書き方をすると思いますが、

```javascript
axios.get('https://api.example.com/api/v1/foo', {
  headers: {
    Authorization: `Bearer ${token}`,
  }
})
```

毎回こう書くのは面倒くさい。

Basicであれば認証なら

```javascript
axios.get('https://api.example.com/api/v1/foo', {
  auth: { username: user, password: pass }
})
```

と書けるのだから、

```javascript
axios.get('https://api.example.com/api/v1/foo', {
  auth: token
})
```

と書きたいわけですよ。
（ `auth` が文字列の場合はBearer認証、オブジェクトの場合はBasic認証とする。）

# axios のミドルウェアを書いて解決する

そう思う人は他にもいるみたいで[PR](https://github.com/axios/axios/pull/810)まで上がっているのですが、これ以上複雑にしたくないということであっさり却下されてしまっています。


でも、なんとかしたい。そこで [axios-middleware](https://emileber.github.io/axios-middleware/) の登場です。


名前の通り aixos のミドルウェアを作るためのモジュールで、リクエスト前、リクエスト後に自前のフィルタを挟むことができるようになります。

これでリクエスト前のパラメータを修正して、 `auth` が文字列の場合は、`Authorization: Bearer` ヘッダに変換して差し込めばやりたいことが実現できますね。

```javascript
import axios from 'axios'

import { Service } from 'axios-middleware'
const service = new Service(axios)

service.register({
  onRequest(config) {
    if(typeof config.auth == 'string'){
      config.headers['Authorization'] = `Bearer ${config.auth}`
      delete config.auth
    }

    return config
  }
})
```

自分がよく使うヘッダ指定やデータ変換を登録しておくと axios の使い勝手が更に向上しますね。
ISUCON過去問環境構築

# 概要
友達とISUCON過去問のAMIで過去問もくもく会やろうとしたら何箇所かで詰まったので自戒の念を込めて書いた。

# EC2インスタンスの起動
AWSアカウントの作成は省略。

## ISUCON AMIの検索
AWSサービス一覧から[EC2]を選択、画面左にある[AMI]へ遷移後、イメージの検索からISUCONと検索するとたくさん出てくるので適当に選ぶ。
<img width="1647" alt="スクリーンショット 2019-04-08 10.53.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/246199/e1693c72-f2b5-ad5a-cc2f-60483a321838.png">
現時点(2019/4/5)では何故かpixiv社内isuconのAMIがベンチしかない。悲しい。

## インスタンスタイプの選択
[起動]するとAMIのインスタンスタイプの選択画面に移る。
AWSアカウント登録から12ヶ月間は毎月750時間までt2.microインスタンスを無料で利用できる。性能はCPUコア,メモリ1GBだがISUCON本番も多分同じ構成だと思う。ありがたみ。
<img width="1646" alt="スクリーンショット 2019-04-08 10.53.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/246199/a26ebc54-9e02-3406-50db-da6e7526d86e.png">


## キーペアの作成
[確認と作成]→[起動]と進んでいくとキーペア作成画面に入る。
[新しいキーペアの作成]を選択して好きな名前で作成。
ダウンロードしたpemファイルを無くさないように.sshに移動。

```
$ cp hoge.pem ~/.ssh
```

[ここ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html)にあるように自分だけが読めるよう権限の変更を行う。

```
$ chmod 400 hoge.pem
```

## セキュリティグループの設定
このままSSHで入るとアプリは立ち上がっているがブラウザからアクセスできない。
インスタンス一覧の[説明]中にある[セキュリティグループ]の[launch-wizard]を押すと下の様な画面が出てくる。
[アクション]から[インバウンドのルールの編集]を押すと設定画面へ。
<img width="1646" alt="スクリーンショット 2019-04-05 1.01.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/246199/8647f592-a1bc-61db-0c03-825c20f60f08.png">

設定の追加はSSH(22Port)とHTTP(80Port)があればとりあえず動くと思う。
<img width="1126" alt="スクリーンショット 2019-04-05 1.13.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/246199/0fb5355a-e9c5-451a-5f61-b31738bb2d86.png">

設定を追加後、再度ブラウザ上からアクセスすると成功した。

あとは適当なユーザー名でsshする。

```
$ ssh -i hoge.pem root@[IPv4 パブリック IP]
```

終わり。

本番ならメンバーの公開鍵を登録して公開鍵認証した方がいいのかもしれないと思ったけど本題ではないので省略した。











#
laravel非同期処理(キュー)をお手軽に使ってみた

## ◆キュー

```:イメージ
                   --------------キュー--------------               
実行(ディスパッチ) ->        |タスク1| タスク2|         ->handleメソッド
                   ----------------------------------
```

イベントを発火するとキューにため込んで登録された順番に従って、実行される。

##◆使いどころ
大量のメール送信や大容量のファイルを扱う処理は、時間がかかり、ユーザーのストレスになる可能性がある。
キューを使うと、処理結果をレスポンスにすることはできないが、通常のwebアプリの流れであるリクエスト・レスポンスとは別のタスク(ジョブ)として実行することができ、時間がかかる処理をユーザーが待機する必要がなくなる。

##◆作成してみる
ジョブ(タスク)をため込むためのQueueとして、データベース・SQS・Redisなどを利用できるが、前回に続き、Redisを使用する。
[前回記事]https://qiita.com/hekizi/items/5d17e50c912614f28344#%E9%9D%9E%E5%90%8C%E6%9C%9F%E3%83%AA%E3%82%B9%E3%83%8A%E3%83%BC%E3%82%92%E5%AE%9F%E8%A3%85

<b>今回作成する機能：前回と同じアクセス時に、アクセスIPをLogに記述する</b>

```:jobクラス作成コマンド
php artisan make:job AccessIpRecordJob
```

```
class AccessIpRecordJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
    public function __construct()
    {
        //
    }
    
    public function handle()
    {
        //
    }
}
```

前回非同期用リスナーを作成したが、その実装(implements)するクラスやトレイトがもともと用意されている感じのクラスがJobs配下に作成されました。

```
class AccessIpRecordJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
    private $ip;
    
    public function __construct($ip)
    {
        $this->ip = $ip;
    }

    public function handle()
    {
        Log::info($this->ip);
    }
}
```

コンストラクタでIP受け取り、イベント発火時に保存という形にした。

```
class SampleController extends Controller
{
	public function sampleQueue(Request $request)
	{
	    $this->dispatch(new AccessIpRecordJob($request->ip()));
	}
}
```

```:ルート
Route::get('/sampleQueue', 'SampleController@sampleQueue');
```

コントローラーとこれにアクセスするルートを用意

```:コマンド
php artisan queue:work
[2019-04-07 00:00:00][○○] Processing: App\Jobs\AccessIpRecordJob
[2019-04-07 00:00:00][○○] Processed:  App\Jobs\AccessIpRecordJob
```

php artisan queue:workでキューを監視(非同期用)して、アクセスすると実行されていることがわかる

```:Log
[2019-04-07 00:00:00] local.INFO: 192.168.99.1 
```

ちゃんと記述されている。完了
[参考にさせていただいた記事]
https://www.ritolab.com/entry/36
オリジナル翻訳ツールでJavaScriptの限界に挑戦

翻訳といえばMySQL等の高速RDBでマッチングしたり
NoSQL等のオンメモリ処理や今流行の機械学習で実行するのが定石ですが
昨今はブラウザの処理速度も高速ですのでCSVに単語登録し
処理はブラウザのリソース上で行う翻訳ツールを作成してみました。

普通の文章を入力すると、アニメ「ケムリクサ」のキャラクターの特徴的なセリフっぽく変換してくれます。
![[HorribleSubs] Kemurikusa - 11 [720p].mkv_snapshot_11.00_[2019.03.21_10.54.10].jpg](https://qiita-image-store.s3.amazonaws.com/0/275132/78fb819c-10ac-b8b3-09b4-284947145d9e.jpeg)

KEMURIsh Translater Tool
http://j.gmobb.jp/3star/ 

GitHub
https://github.com/team3star/kemurishTranslaterTool

例えば上記の文章を翻訳すると以下の様になります。

翻訳といえばMySQL等の高速RDBでマッチングしたり
NoSQL等のオンメモリ処理や今流行の機械学習で実行するのが定石ニャが
昨今はブラウザの処理速度も高速ニャのでCSVに単語登録し
処理はブラウザのリソース上で行う翻訳ツールを作成してみました。

普通の文章を入力すると、アニメ「ケムリクサ」のキャラクターの特徴的なセリフっぽく変換してくれニャ。
Three.jsとシェーダー　〜attributeとuniformとvaryings〜

前回Three.jsでは勝手に渡される変数があることがわかったのですが、GLSLでの変数にはjsのものとは違う３つの属性が付加されているみたいです。なのでまずはそこをまとめます。


## attribute
頂点ごとに異なる値を持つような変数(座標とか、色とか)をattributeと呼びます。
これは頂点シェーダのみから参照可能です。

## uniform
全体で一つの値を共有するような変数です。時間とか。これは頂点シェーダからもフラグメントシェーダからも参照可能なようです。

## varyings
頂点シェーダからフラグメントシェーダに値を渡したいときに使う変数です。

## 組み込み変数
**Three.jsは賢いので、本来宣言して結構がんばって渡して来なくちゃいけないような変数の一部を宣言無しで自動的に渡して来ます**(この組み込み変数を渡さないようにするクラスもあるみたいです)。

以下のuniform及びattributeは宣言も何もすることもなく使うことができます。

```.js
// = object.matrixWorld
uniform mat4 modelMatrix;

// = camera.matrixWorldInverse * object.matrixWorld
uniform mat4 modelViewMatrix;

// = camera.projectionMatrix
uniform mat4 projectionMatrix;

// = camera.matrixWorldInverse
uniform mat4 viewMatrix;

// = inverse transpose of modelViewMatrix
uniform mat3 normalMatrix;

// = camera position in world space
uniform vec3 cameraPosition;

// default vertex attributes provided by Geometry and BufferGeometry
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
```

https://threejs.org/docs/#api/en/renderers/webgl/WebGLProgram よりコピペ
なので、変換行列等々は苦労して呼ぶ必要がないということです。

すごい
Chromeでフルスクリーン時にタブが見えないとき

#タブの表示切り替えのショートカット
「⇧+⌘+F」でタブの表示切り替えできます。
「⌃+⌘+F」がフルスクリーンモードへの切り替えなので間違って押しやすいですね。
VMWare Player : Device/Gredential Guard には互換性がありません　とはなんぞや


Win10で

「VMWare Player : Device/Gredential Guard には互換性がありません」

と突然。

いみふめい。

解決策を調べた。

スタートメニューで「　gpedit.msc　」と入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/31eb53dc-a4f4-4391-b6e5-66e01d0dac10.png)

Device Guardを探します。　仮想化ベースの云々をダブルクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/4568f48f-ac92-9b76-8ceb-581ea32e69b9.png)

無効＆適用
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/95caa330-8208-428f-811d-5fa967eea59c.png)

これでおしまい。再起動すればなおったはず。



#Ref 
https://yoshidastyle.net/Blogs/2016/11/04/vmware-player_devicecredential-guard
https://ameblo.jp/rhnmtym/entry-12384351675.html
一致がなかったら一致するまでずらす回数をカウントする方法-PHP

表題の通りです。
文字列を右一方向にずらす方法になります。

####文字列の一致がなかったら一致するまでずらす回数をカウントする方法

```php
// 定数定義
$str_len = 5; //文字数
$str_key = "qiita"; //検索したい文字
$str_search = "taqii"; //検索対象

// 変数
$cnt = 0; //keyとsearchが一致するまでに何回ずらす必要があるのか（最小）
$str_tmp = "";

// 文字を一文字ずつ取り出して一致を探す
for($i=0; $i < $str_len; $i++){
    // 検索文字を作成（1文字ずつ検索していくと同じ文字列があった時に前方にヒットしてしまうのを防止）
    $str_tmp .= $str_key[$i];

    // 検索文字に対してどこまで一致してるかを確認
    $key = stripos($str_search, $str_tmp);

    // 一致していない場合
    if($key != 0){
        // 一致した分ずらす
        for($n=0; $n < $key;$n++){
            // 削除する文字（一文字目）を確保
            $str_srip = $str_search[0];
            // 削除する文字（一文字目）以降を取得
            $str_search = substr($str_search, 1, strlen($str_search));
            // 削除した文字を一番最後に付与
            $str_search .= $str_srip;
        }
        // ずらした分カウントを増やす
        $cnt +=$key;
    }
}
echo $str_search; // "qiita"
echo "\n";
echo $cnt; // 2
echo "\n"; 
```
*** 
####余談 
同じ考え方で配列もずらせます。（いくつかの関数は配列用にしないといけないですが）

####文字列の一致がなかったら一致するまで配列をずらす回数をカウントする方法
```php
// 定数定義
$str_len = 5; //配列
$str_key = array("q", "i", "i", "t", "a"); //検索したい文字
$str_search = array("t", "a", "q", "i", "i"); //検索対象

// 変数
$cnt = 0; //keyとsearchが一致するまでに何回ずらす必要があるのか（最小）
$str_tmp = "";

// 文字を一文字ずつ取り出して一致を探す
for($i=0; $i < $str_len; $i++){
    // 検索文字を作成（1文字ずつ検索していくと同じ文字列があった時に前方にヒットしてしまうのを防止）
    $str_tmp .= $str_key[$i];

    // 検索文字に対してどこまで一致してるかを確認
    //$key = stripos($str_search, $str_tmp);
    $key = array_search($str_tmp, $str_search);

    // 一致していない場合
    if($key != 0){
        // 一致した分ずらす
        for($n=0; $n < $key;$n++){
            // 削除する文字（一文字目）を確保
            $str_srip = $str_search[0];
            // 削除する文字（一文字目）以降を取得
            //$str_search = substr($str_search, 1, strlen($str_search));
            $str_search = array_slice($str_search , 1);
            // 削除した文字を一番最後に付与
            //$str_search .= $str_srip;
            array_push($str_search, $str_srip);
        }
        // ずらした分カウントを増やす
        $cnt +=$key;
    }
}
echo implode($str_search); // "qiita"
echo "\n";
echo $cnt; // 2
echo "\n";

```
pythonでimport requestsが使えなくなった→対処

こちらの記事を参考にビットコインのシステムトレードを編集してました。

https://ryota-trade.com/

もっとも初歩的なこちらのコードを書きました

```py
import requests
response = requests.get("https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1514764800")
data = response.json()
print(data)
```
しかし、説明にあったように、ターミナルでファイルを実行しようとしたら、エラーが出ました。

```
$ python test.py
```
↓

```
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    import requests
ImportError: No module named requests
```

ちなみにrequestsはインストールしており、jupyter notebookだと上記のコードで実行できます。
![スクリーンショット 2019-04-07 14.08.10.png](https://qiita-image-store.s3.amazonaws.com/0/321960/3844edfb-98c9-e81f-6541-d5b3e686b42d.png)

もくもく会の人に見てもらいまして、python3をつけることで実行できることがわかりました。

```
$ python3 test.py
```
あとpipについても、今はpipではエラーが出てpip3だと動きます。



なぜ、以前は"3"をつけずとも実行できたのか、どこで変化が生じたのか不明ですが、とりあえずこれで動くようになったので、もし同様の困りごとの初心者おられれば参考になれば幸いです。
redirect_toでaction指定して、かつnoticeも設定しようとしたら、引数にハッシュを渡す云々で詰まった

# ケース
- よくある作成処理で、画面遷移後にメッセージを表示したい。

# 結論
- メソッド引数に複数のハッシュを渡す場合は、最後の引数以外は{}で囲う必要があります。
- メソッドの第1引数にハッシュを渡す場合は、必ず()を付けてメソッドを呼び出す必要があります。

```games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to({action: :index}, notice: '試合情報の作成に成功しました。')
    else
      render :new
    end
  end
```
※redirect_toと()の間にはスペースは入れられません。

# 失敗例

``` games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to action: :index, notice: '試合情報の作成に成功しました。'
    else
      render :new
    end
  end
```
実際に画面操作してみると、遷移後の画面にメッセージが表示されず（noticeを受けるように記述しているのに）、しかもURLが以下のようになっていました。

```
http://localhost:3000/games?notice=試合情報の作成に成功しました。
```

# 原因
ググりながら解決方法を見つけ、問題なく動くようになったのですが、原因はRubyの文法にありました。
[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/dp/4774193976/ref=cm_sw_em_r_mt_dp_U_oQxQCbN06P698)によると、メソッド引数にハッシュを渡す時のルールについて記載されていました。
> Rubyでは「最後の引数がハッシュであればハッシュリテラルの{}を省略できる」というルールがあります。

失敗例のコードでは、{}を書いていなかったため、`action: :index, notice: '試合情報の作成に成功しました。'` の部分でひとつのハッシュと見なされてしまいます。
今回、redirect_toには「アクション」と「notice」のふたつのハッシュを渡す必要があるため、そこで上手くいっていなかったということです。

# さらに

解決はしたのですが、そこで私は
「じゃあこう書いたらどうなる？メソッド呼び出しの()って省略できるんじゃなかったっけ？」
と、以下のコードを書きました。

``` games_controller.rb
  def create
    @game = Game.new(game_params)
    if @game.save
      redirect_to {action: :index}, notice: '試合情報の作成に成功しました。'
    else
      render :new
    end
  end
```
すると、画面操作する前にRubyMineに怒られました（Eclipseでいうコンパイルエラーみたいな感じで赤くなる）。
そのまま画面操作するとエラーになるようです。

[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/dp/4774193976/ref=cm_sw_em_r_mt_dp_U_oQxQCbN06P698)を読み進めると、次のページに同じケースについて書いてありました（著者の方に先を読まれているw）。
> おや、エラーが発生してしまいました。（少し中略）実はこれは、ハッシュリテラルの{}がブロックの{}だとRubyに解釈されたためです。
（中略）
というわけで、このようにメソッドの第1引数にハッシュを渡そうとする場合は必ず()を付けてメソッドを呼び出す必要があります。

なるほどですね。。。
ということでやはり、上述のあの書き方でないとダメということですね。勉強になります！

# 参考
- [redirect_to にcontroller,action,id指定しつつflashを追加](http://taremimi.hatenablog.jp/entry/2018/03/24/040305)
- [Railsのredirect_toでちょっとだけはまる](https://blog.piyo.tech/posts/2014-07-01-203000/)
- [Ruby初学者が戸惑いやすい文法を、例を交えて噛み砕いてみる](https://qiita.com/shinkuFencer/items/045ae58d2192ee3b1406)
- [プロを目指す人のためのRuby入門](https://www.amazon.co.jp/dp/4774193976/ref=cm_sw_em_r_mt_dp_U_oQxQCbN06P698)
RubyMine: rails sとwebpack-dev-serverをワンクリックで実行 (IntelliJ IDEA with Ruby Plugin)

よく `foreman` gemを使って `Procfile` を実行する方法が紹介されていますが、RubyMine/IntelliJ IDEAを使って表題の事を行う方法を紹介します。

### 動作確認環境

* macOS 10.14.4
* Ruby 2.5.3
* Ruby on Rails 5.2.2
* Webpack ~> 4.x
* Vue ^2.6.10

前提として、WebpackとVueをRailsプロジェクトで使える状態になっていればOKです。

### 設定

ここから設定します

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/738099e8-2af6-d00d-c0a1-fbe29748d4ee.png)

Railsの `Development` と `Production` はRubyMineでOpenすると自動的に作られますが、無ければ手動で作ってもOK。この設定をVCSで管理したい場合は `Share` にチェックを入れる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/bcd6f80d-1ba8-31ce-4dfc-dc7bf7ced03c.png)

`./bin/webpack-dev-server` の実行を追加します。 `Bash` が出てこない場合は `BashSupport` pluginをインストール。この設定をVCSで管理したい場合は `Share` にチェックを入れる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/e7336ae6-7270-1342-8d0c-dcdd9477cc9e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/5a2675d8-3328-ab85-a53c-4825785ddeb5.png)


一度 `Apply` をクリックして設定を保存。（そうしないと `＋` をクリックしても一覧に出てこない）

`Compound` を作成し、こんな感じに設定します。この設定をVCSで管理したい場合は `Share` にチェックを入れる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/3cef244a-deef-c4cf-db41-0e0229e993c0.png)

OKをクリックして、三角マークの Run ボタンを押す（ショートカットがお好きな方は `Cmd+Alt+R` ※設定に依存）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/72f35801-8c09-0b18-15e2-65d18d75ff80.png)

`app.vue` を少し変更して（↓ `!` の数を増やしてみました） 自動的にブラウザの表示がリフレッシュされている事が確認できたら、設定完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/b856b135-53d3-a2cf-e7ed-24e79b269cd2.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/a692ca2c-2692-143c-976b-acfdf1d33311.png)

## 設定内容をVCSで管理する場合

以下のように `1: Project` で `Project Files` を選択すると隠しファイルも表示されます。 `Share` した設定は、 `runConfigurations` に表示されるので、これらをVCSで管理します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37334/51eb88ea-cddd-aaac-3fd9-0b00a33a8007.png)

私が使っている `.gitignore` はこちらで公開中です（できればそのまま使わず、参考程度に。）

https://gist.github.com/dyanagi/d1ad9717f9af365a3fa9124d07c3da76
CodilityのCyclicRotationを競プロ未経験が解いてみた

[前回](https://qiita.com/shotastage/items/fe996e6f08a25a7ed39b)に引き続き、Codilityを解いてみました。今回はArrayの章のCyclicRotationです。
CyclicRotationとは簡単に言うと、配列を輪に見立てた時に反時計周りにN要素分移動しなさいと言う問題です。例えば、`[1, 5, 2, 8, 1, 4, 7]`と言う配列を３回ローテーションすると`[1, 4, 7, 1, 5, 2, 8]`となります。


<img src="https://qiita-image-store.s3.amazonaws.com/0/44018/cc1d5f82-6f75-fb7e-806f-ecc9e8c46309.jpeg" alt="CyclicRotation" width="320px"/>



今回はこのCyclicRotationをPythonとJavaで組んで見ました。
いずれのコードも100%の判定を貰うことができました。しかし、さらに効率のいいやり方があるかもしれません。特にJavaはあまり慣れていないので自信はありませんでした。

# アルゴリズム

今回はPythonとJavaで書きましたが、アルゴリズムは基本的に同一です。

**与えられた配列の最後の要素を、先頭に移動する**作業をK回繰り返すだけです。


## Python

Pythonの配列の実態はリストであり、固定長ではなく要素の削除や追加が自由にできるので比較的簡単に実装することができました。

```python
def solution(A, K):
    
    array = A
    
    # Aが空ならそのまま返す
    if array == []:
        return A
    # 最後の要素を先頭に移動する作業をK回行う
    for _ in range(K):
        cache = A[-1]
        array.pop(-1)
        array.insert(0, cache)
        
    return array
```

## Java

基本的にはPythonと全く同じです。しかし、Javaの配列は固定長です。あらかじめ要素数を指定する必要があり、要素の削除や追加が行えません。
従って、事前にリストに変換する必要があります。また、返り値は`int[]`なのでリストを再び配列に変換しています。

```java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public int[] solution(int[] A, int K) {
        
        // 与えられた配列Aが空だった場合はそのままAを返す
        if (A.length == 0) {
            return A;
        }

        // JavaのArrayをListに変換
        List<Integer> list = new ArrayList<Integer>();

        for (int i = 0; i < A.length; i++) {
            list.add(A[i]);
        }

        // Listの最後の要素を削除し先頭に追加する処理をK回繰り返す
        for  (int i = 0; i < K; i++) {
            int cache = list.get(list.size() - 1);
            list.remove(list.size() - 1);
            list.add(0, cache);
        }

        // ListをArrayに変換
        int[] array = new int[list.size()];

        for (int i = 0; i < list.size(); i++) {
            array[i] = list.get(i);
        }

        return array;
    }
}
```


# まとめ

今回はJavaとPythonの２言語で実装しました。Pythonだけを書いていると`[-1]`で最後の要素が取れたりと普段は意識していませんでしたが、改めて便利さを実感しました。今後は次の章にも取り組みたいと思います。
logrageを使う

Railsのログをjson化するためにlogrageを使う

```ruby:Gemfile
gem 'lograge'
gem 'logstash-event' # json化するために必要
```

```config/initializers/lograge.rb
Rails.application.configure do
  config.lograge.enabled = true

  # If you're using Rails 5's API-only mode and inherit from ActionController::API, you must define it as the controller base class which lograge will patch:
  # config.lograge.base_controller_class = 'ActionController::API'

  # JSON(logstash形式)で出力
  config.lograge.formatter = Lograge::Formatters::Logstash.new

  # オリジナルのlogを残す
  config.lograge.keep_original_rails_log = true

  # logrageのlogを別ファイルに保存
  config.lograge.logger = ActiveSupport::Logger.new "#{Rails.root}/log/lograge_#{Rails.env}.log"

  # 独自パラメータを取得 (controllerが落ちてくる)
  config.lograge.custom_payload do |controller|
    params = controller.request.params.except(* %w[controller action])

    {
      request_id: controller.request.request_id,
      user_id: controller.try(:current_user).try(:id), # 例) 確定してるなら&.のほうが良い
      params: params
    }
  end

  # 独自パラメータを設定 (ActiveSupport::Notifications::Event name='process_action.action_controller' が落ちてくる)
  config.lograge.custom_options = lambda do |event|
    ret = {
      request_ip: event.payload[:request_ip],
      error_message: nil,
      error_stacktrace: nil
    }

    if (eo = event.payload[:exception_object])
      ret.merge!(
        error_message: eo.message,
        error_stacktrace: eo.backtrace.join("\n")
      )
    end

    ret
  end
end
```

こんなログが出力される

```json:#{Rails.root}/log/lograge_#{Rails.env}.log
正常時
{"method":"GET","path":"/api/workflows","format":"html","controller":"Api::WorkflowsController","action":"index","status":200,"duration":58.42,"view":11.2,"db":40.94,"request_ip":null,"exception":null,"exception_object":null,"error_message":null,"error_stacktrace":null,"request_id":"4dbf2f3c-ff83-422e-b16d-d8584cbdcf6e","user_id":null,"params":{},"@timestamp":"2019-04-07T04:51:39.978Z","@version":"1","message":"[200] GET /api/workflows (Api::WorkflowsController#index)"}

例外時
{"method":"GET","path":"/api/workflows","format":"html","controller":"Api::WorkflowsController","action":"index","status":500,"error":"RuntimeError: ","duration":0.63,"view":0.0,"db":0.0,"request_ip":null,"exception":null,"exception_object":null,"error_message":"","error_stacktrace":"<<<ここにスタックトレースが出力>>>","request_id":"b680ad4a-9eea-4392-9084-2df09d0ab850","user_id":null,"params":{},"@timestamp":"2019-04-07T04:55:13.013Z","@version":"1","message":"[500] GET /api/workflows (Api::WorkflowsController#index)"}
```


参考:
https://github.com/roidrage/lograge

custom_optionsで落ちてくるeventは 'process_action.action_controller'
https://edgeguides.rubyonrails.org/active_support_instrumentation.html#process-action-action-controller
プログラム初心者のためのC#入門 #4 条件分岐

# #4 条件分岐
プログラミングでは，もし条件を満たせばこの動作，そうでなければこの動作，というように条件によって動作を変えるための構文があります．

##if文

```
if (条件式1)
{
    条件式1がtrueの時実行される．
}
else if (条件式2)
{
    条件式1がfalse，且つ条件式2がtrueの時実行される．
}
else if (条件式3)
{
    条件式1，条件式2がfalse，且つ条件式3がtrueの時実行される．
}
else
{
    すべての条件式がfalseの時実行される．
}
```

if文は上のようにして条件分岐します，`else if`はいくつも書けますが，あまりに多すぎるとコンパイラから怒られることもあります．また，実行する文が一つの場合は波括弧を省略することもできます．
次は具体例を見てみましょう．

```ConditionalBranchSample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConditionalBranchSample
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 2;
            
            if (num == 0)
            {
                Console.WriteLine("numは0です．");
            }
            else if (num == 1 || num == 2)
            {
                Console.WriteLine("numは1か2です．");
            }
            else
            {
                Console.WriteLine("numは0，1，2以外です．");
            }
        }
    }
}
```
```:出力結果
numは1か2です．
```

##switch-case文

```
switch (変数)
{
    case 値1:
        変数が値1の時実行される．
        break;
    case 値2:
        変数が値2の時実行される．
        break;
    default:
        変数が値1でも値2でもない時実行される．
        break;
}
```

switch-case文はラベルが定数でなければならないなど少々使い勝手が良くないため，if文が好んで使われる傾向がありますが，上から条件を判定していくif文と比べるとより早いと言われています．

```ConditionalBranchSample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConditionalBranchSample
{
    class Program
    {
        static void Main(string[] args)
        {
            double num = 3;

            switch (num)
            {
                case 0:
                    Console.WriteLine("numは0です．");
                    break;
                case 1:
                    Console.WriteLine("numは1です．");
                    break;
                default:
                    Console.WriteLine("numは0，1以外です．");
                    break;
            }
        }
    }
}
```

次回は[ループ処理](https://qiita.com/17t7037t/items/506c065e6fc16345604b)について説明します．
##練習問題
int型の変数yearを定義して，西暦年をyearに代入すると平成何年か画面に出力するコードを書いてください．

<details><summary>解答例</summary><div>
元年と表示するのが個人的こだわりポイントです．

```ConditionalBranchSample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConditionalBranchSample
{
    class Program
    {
        static void Main(string[] args)
        {
            int year = 1998;

            if (year == 1989)
                Console.WriteLine("平成元年です．");
            else if (year > 1989 && year <= 2019)
                Console.WriteLine("平成" + (year - 1988) + "年です．");
            else
                Console.WriteLine("平成ではありません．");
        }
    }
}
```

</div></details>
基本情報技術者過去問題 平成30年秋期 午後問8 について

#はじめに
タイトルにもある通り、基本情報技術者過去問題 平成30年秋期 午後問8 についての記事なんだけど、<a href="https://www.fe-siken.com/kakomon/30_aki/pm08.html">このサイト</a>に書かれていた解説のある一文がずっと理解できない、って事態に陥った。
備忘録のために何が理解できなかったのかをここに書き残しておく。

#理解できなかった箇所
理解できなかった箇所は、下記の<font color="red">赤文字部分</font>である。
><font color="red">priHigh=2、priLow=1 以外なら何でも良い</font>のですが、ここでは priHigh=3、priLow=2 とします。

#何故理解できなかったのか
<font color="red">赤文字部分</font>を読んだとき、僕は必死に priHigh=2、priLow=1 がダメな理由を考えたんだけど、ぱっとは思いつかなかった。
a に<font color="red">2以上</font>が当てはまるのは理解できたけど、それは priHigh、priLow には関係ない。
なぜなら、<font color="red">2以上</font>でなければならないのはあくまで<font color="red">括弧の内部にある演算子に対して加算する値</font>のことで、<font color="red">加減算と乗除算とで加算する値のこと</font>ではないからだ

#結論
で、なぜ「<font color="red">priHigh=2、priLow=1 以外なら何でも良い</font>」のかというと、ア と エ で被ってしまうからだ。
選択肢をみてみよう。
>ア：priHigh以上
イ：priHigh＋1以上
ウ：priHigh－priLow以上
エ：priHigh－priLow＋1以上

仮に、<font color="red">priHigh=2、priLow=1</font>にしてみると、アは 2、エは 2 - 1 + 1 = 2、で被ってしまうことが分かる。
これを、解説と同様に priHigh=3、priLow=2 とすると、アは 3、エは 3 - 2 + 1 = 2、でしっかり差分が出ることが分かる。
だから、問題として<font color="red">priHigh=2、priLow=1</font>と定義することが<font color="red">禁止されているわけではなく</font>、ただ<font color="red">効率的に悪い</font>よって話。
JSで要素を比較する

JavaScriptで要素が同じか比較する関数があったのでメモ

#結論
```javascript
const elm = document.body,
   target = new DOMParser().parseFromString(document.body.outerHTML, "text/html").head
elm.isEqualNode(target) // => true
```

#つまずき
`==`や`===`で比較すると同じオブジェクト以外trueにならない。
たぶん`Symbol`あたりの関係? (調べてない)

そしてMDNを見るとそれっぽいのを発見
> https://developer.mozilla.org/ja/docs/Web/API/Node/isEqualNode
>
> 概要
> ふたつのノードが同一ノードの場合は true を、異なる場合は false を返します。

で、試して見るとできた。
調べてもなかなか出てこなかった。。。

#わかったこと
記事を書いている時に`head.outerHTML`はスタイルを展開しちゃうということがわかった。
そのままを手に入れたいときはどうすんだろ。
vue.js で グローバルipアドレスを取得する ウルテク

こんな感じでipアドレスを取得できるがね。
素晴らしいがね。

```

axios.post('https://ipinfo.io/').then(e => {
    console.log(e.data.ip);
    console.log("成功");
        }).catch((error) => {
    console.log("エラー");
});

```


# 日本語対応ブラウザのみ

上記の ipinfo は関係なく使える。
日本語に対応したブラウザのみ対応させたい場合。

```

if((navigator.browserLanguage || navigator.language || navigator.userLanguage).substr(0,2) === 'ja') {
    console.log("多分日本語ブラウザ");
}

```
[PHP]浮動小数点数の乗算でハマった話


初投稿です。
C#からPHPにメイン言語を転換して一ヶ月、初めて見る事象が起きたので備忘録も兼ねて残しておきます。

# 1. 発生した事象
業務で税込みの金額を出力する場面があったので計算ロジックを組んでいたところ、下記の事象が発生しました。

```php:tax.php
    //価格
    $price = 1800;
    //消費税
    $tax = 1.08;
    
    //小数点以下切り上げ
    ceil($price * $tax);//1945
```

1945か〜うんうん

…！？
1944じゃないの！？？

試しにceilで切り上げない素の値を出力してみると

```php:tax2.php
    var_dump($price * $tax); //float(1944)
```

小数点以下無いやん…

これは不味いと思い調査してみると、どうやら浮動小数点数の精度が影響してしまっているようでした。


# 2. 浮動小数点数とは
「浮動小数点数とは」
2進数を扱うコンピュータにおいて小数を表現するために用いられる表現方法です。
極端に桁数が大きい数値や、小数を扱う際に2進数で表現出来るようにするための方法ですね。

浮動小数点数についての詳しい説明は各々わかりやすいサイトや書籍を参考にしていただければと思いますが、では今回PHPの計算では何故このような誤差が発生してしまうのでしょう。

このあたりについては公式リファレンスにて説明されています。
https://www.php.net/manual/ja/language.types.float.php

> 浮動小数点数の精度は有限です。 システムに依存しますが、PHP は通常 IEEE 754 倍精度フォーマットを使います。 この形式は、1.11e-16 のオーダーでの丸め処理で誤差が発生します。 複雑な算術演算をすると、誤差はさらに大きくなるでしょう。そしてもちろん、 いくつかの演算を組み合わせる場合にも誤差を考慮しなければなりません。

> さらに、十進数では正確な小数で表せる有理数、たとえば 0.1 や 0.7 は、 二進数の浮動小数点数としては正確に表現できません。 これは、仮数部をいくら大きくしても同じです。 したがって、それを内部的な二進数表現に変換する際には、どうしても多少精度が落ちてしまいます。 その結果、不思議な結果を引き起こすことがあります。たとえば、 floor((0.1+0.7)*10) の結果はたいてい 7 となるでしょう。おそらくは 8 を想定していらっしゃるでしょうが、そのようにはなりません。 これは、(この計算結果の) 内部的な値が 7.9999999999999991118... のようになっているからです。

簡単に説明するとPHPにおいて浮動小数点数(float型)をそのまま計算に用いた場合、
2進数が扱える桁数(PHPの場合倍精度のため64bit)を超えてしまう場合があります。
よって変換の過程で扱いきれない数値がIEEE754倍精度で規定されたルールに従って最も近い数値に丸められてしまい、結果誤差が発生してしまうということでした。

先ほどceilで切り上げていない素の数値が整数で表示されていたのは、計算結果に小数点以下があるにも関わらず、近似値1944に丸められてしまっていたからかと思われます。(本来ならありがたい仕様のはずだけど、今回は厄介すぎる…)

試しに表示する計算結果を小数点以下40桁まで広げて表示してみます。

```php:tax3.php
    var_dump(sprintf('%.40f', $price * $tax));
    //string(45) "1944.0000000000002273736754432320594787597656"
```
なるほど、この内部的な値が切り上げられてしまうことで想定されない計算結果が出力されてしまうわけですね。


#3. 解決法
公式リファレンスによると、浮動小数点数をそのまま計算に用いるのは推奨されないということでした。
ではどうすれば良いかというと、「任意精度数学関数(BC Math)またはgmp関数を代わりに使用してください。」とのことでした。

私の環境ではgmpは別途インストールが必要だったため、既にインストールされていたBC Mathを選択することにしました。
下記実行結果です。

```php:tax4.php
ceil(bcmul($price, $tax, 1)); //1944
```
bcmul関数の第一引数と第二引数に乗算の対象、第三引数で乗算時の有効桁数を指定してやることでようやく目的の数値を出力することが出来ました。

もしお手持ちの環境にBC Mathがインストールされていない場合、下記のコマンドでPHPにインストールしてあげる必要があるかと思いますので、別途インストールしてください。

```
# yum install php-bcmath
```

###※補足

```
var_dump(ceil((string)($price * $tax))); //float(1944)

var_dump(ceil(sprintf('%.3f', $price * $tax))); //float(1944)
```

他にも上記のようにstring型へのキャスト時に小数点以下に0が続く部分を自動で丸める性質を利用した方法や、sprintfで小数点以下の桁数を指定してしまう方法があったのですが、公式リファレンスで推奨はされていなかったために不採用としました。

任意精度数学関数(BC Math)またはgmp関数に対して環境にインストールが不要ではあり「こっちの方がいいよ」という方もいらっしゃると思うので、もしご意見があればコメントをいただけると有り難いです。

#4. まとめ

以前メインで使っていたC#では小数計算の際、金融系や財務で用いられるdecimal型という精度の高いデータ型を用いており、decimalでは今回のようなケースに出くわしませんでした。
PHPは型の定義の必要がないためコーディングの自由度が増すのは大きな利点だと思いますが、その分自分が書くコードは必ずしも正しくない、という意識をより一層持つ必要があるのかもしれません。

今回は偶然にも計算ミスに気がつくことができましたが、言語毎の違いは正確にキャッチアップしていく必要があるという教訓を得ることができました。
Laravelで簡単Redis利用

##◆redisとは
http://post.simplie.jp/posts/116

##◆導入
前回書いた記事を参考にする(非同期リスナー導入部分)
[https://qiita.com/hekizi/items/5d17e50c912614f28344]

```:env
REDIS_HOST=redis
```

```:コマンド
//設定を変えたので、設定のキャッシュをクリア
php artisan config:cache
//Redisを使うために導入する。
composer require predis/predis
```

僕はdocker-toolboxを使用しているため、

```:docker-compose.yml
redis: 
    image: redis
    container_name: redis
    ports: 
      - "6379:6379"
```
  
```:コマンド
docker-compose up -d
```

これで使用可能になった。

##◆使ってみる

```
class SampleController extends Controller
{
    public function sampleOperateRedis()
    {
        $data = [
            'number' => 1,
            'name'   => '山田'
        ];

        Redis::command('SET', [$data['number'], json_encode($data)]);

        $getData = Redis::command('GET', [$data['number']]);

        dd(json_decode($getData));
    }
}
```

Redisファサードには、それぞれのmagicメソッドと汎用的なCommandメソッドが用意されている。
(magicメソッドを使用するなら、Redis::set(\$data['number'], json_encode(\$data));)

<b>Redisには、文字列やハッシュやセットなどいろいろ保存できるらしい。</b>
今回は、文字列でセットして、取り出すことをした。

```:結果
{#226 ▼
  +"number": 1
  +"name": "山田"
}
```

完了
[参考にさせていただいた記事]
https://www.ritolab.com/entry/76
pythonでAtCoder -ABC008-

# 対象
- AtCoder初心者（緑よりもランクが下の人、ABCのCD問題が解けない人）
- pythonがそれなりにかける人
- 数学やプログラミングに対する深い理解を持っていない人
    - Ex) DP, 深さ優先探索, メモ化再帰の実装ができない

# 動機
AtCoderは全ての問題に対して解説が存在しますが
ざっくり説明を読んでわかった気になっても独力で実装ができないといった経験が多くありました。
参考のために他人の提出を見ても解説と綺麗にリンクした解答が簡単には見つからず
理解を実装に落とすことに苦労しました。

そこで、公式の解答とある程度リンクした実装を見ながら
アルゴリズムや数学的な理解とソースコードを紐付けたいと思ったことが本記事を寄稿した動機です。

いるかわかりませんが同様の苦労をしている人のためにも何らかの参考になればと思い
私の回答とそれに対する簡単なコメントを付与したコードを記載します。

# 実行環境
- python3

## 実装
### 凡例
実装時の事前情報を記します。
何も見ずに実装しているものは、コーディングが理想的でない可能性、アルゴリズムが理想的ではない可能性があります。
解説から実装しているものは、コーディングが理想的でない可能性があります。

### 実装
AB → 何も見ずに実装
CD → 解説を見て実装

# A
```python:A.py
S, T = map(int, input().split(' '))
print(T - S + 1)
```
# B
```python:B.py
from collections import defaultdict
N = int(input())
S = defaultdict(int)
for _ in range(N):
    S[input()] += 1
print(max(S, key=S.get))
```

# C
```python:C.py
N = int(input())
C = [int(input()) for _ in range(N)]

p = 0
# 各コインに対し
for i in range(N):
    # 自身の約数となっているコインの枚数を求める(自身のコインは除く)
    S = [C[j] for j in range(N) if i != j and C[i] % C[j] == 0]
    s = len(S)
    # 自身のコインが、奇数枚目になる確率を求める
    p += (s + 2) / (2 * s + 2) if s % 2 == 0 else 0.5
print(p)
```
期待値の特性を利用した解法です。
各コインの出現確率を求めていく発想にたどり着くことが難しいように感じます。

# D
```python:D.py
def calc(i, j, k, l):
    if (i, j, k, l) in memo:
        return memo[(i, j, k, l)]
    res = 0
    for X, Y in M:
        # 計算したい領域に入っている機械のみを対象にする
        if i < X <= k and j < Y <= l:
            # この機械が取れる金塊
            tmp = (k-i) + (l-j) - 1
            # 左上、右上、左下、右下の領域で取れる金塊
            tmp += calc(i, j, X-1, Y-1)
            tmp += calc(X, j, k, Y-1)
            tmp += calc(i, Y, X-1, l)
            tmp += calc(X, Y, k, l)
            res = max(res, tmp)
    memo[(i, j, k, l)] = res
    return res


W, H = map(int, input().split(' '))
N = int(input())
M = [tuple(map(int, input().split(' '))) for _ in range(N)]
memo = {}
print(calc(0, 0, W, H))
```
メモ化再帰を利用した解法を実装しています。

## 終わりに
今回はD問題はおろかC問題も解けませんでした。
体系的に学ぶために本買うべきですかね。。

以上です。
新社会人になりました。

## はじめに
　今年の3月に大学を卒業して、4月1日から新たに社会人となりました。怒涛の1週間が終わり今日は日曜でお休みな訳ですが、社会人になった感想を淡々と書きたいと思います。なんで書くかっていうと、新社会人って人生において1回だけじゃないですか。**これから社会人を迎える方**を含めた多くの人にシェアできたらなと。（何年後かに自分が見返しても面白いかも）

　業種は「**IT**」ってことだけをお伝えしておきます。何故これだけかというと、**社会人は発言に責任を持つ必要がある**からです。会社の情報をベラベラ喋ってしまったら当然いけないわけです。この点は大学時代と比べると注意しなければならない点の1つだと感じます。私も最善の注意を払って記事にしてみます。業種は違えど、基本的な新社会人の心情はそう大きく違わないと思うので、誰にも当てはまるものだと思っています。

## 社会人として最初の1週間が終わりました...
　あっという間でした。入社式から新人研修まで。研修はこれからも続くわけですが、とりあえず最初の1週間が終わってホッと一息しています。思い返すと、入社式から今日まででたったの1週間だなんて密度濃すぎです。大学生だったら1ヶ月分に相当するレベルです。その密度の大半が「**不安**」によるものであったと考えています。
　私がこの1週間で最も気をつけたことは、とにかく「**社会人らしく振舞う**」ということです。これには次の内容が含まれています。

- **遅刻**をしない
 - ある意味最も頑張った点。スマホのアラームは5分起きにセット
- **言葉遣い**に気をつける
 - (例)「〜じゃないですか。」→「〜ではありませんか。」
- **身だしなみ**をしっかり
 - ネクタイ曲がってないかが気になってしょうがない
- **挨拶**は超大事。
 - (出社時)「おはようございます。」(すれ違い時)「お疲れ様です。」(退勤時)「お先に失礼します。」など
- **メモ**を取る
 - 先輩の言うことはとても大事。できる限りメモる
- **5~10分前行動**を心がける
 - お昼休みギリギリまでダラダラしてはいけない。5~10分前にはもう次の準備をする
- 何事も率先して動く
 - (例)先輩から配布物がある場合はそれを自分から取りに行くなど積極的に
- 先輩の名前を1回で覚える
 - 一度紹介された名前は覚えなきゃ失礼だからしっかり覚える
- その他たくさん

　...... 最も気をつけたことだけを挙げるつもりで書いたのに沢山書いてしまいました。というくらい、新社会人は**不安**だらけというわけなのでしょうね。大学生の時は全然気にならなかったことばかりです。心が落ち着いている日曜日に自分を客観的に見てみると、こんな自分に気がつきました。

## これからもきっと「不安」だらけ...
　上記のリストアップしたことに気をつけていても、いつも不安でしょうがないです。割と常に怒られるんじゃないかっていう心情が何処かにあるせいです。それくらい先輩の方の顔色を伺ってしまいます。そしてこの心情はこれからもずっと持ち続けていくことになると思っています。なぜかって、新人研修が終わるとまた環境がガラッと変わります。環境が変わる度に接する先輩も変わっていくからです。まだ1週間だからなんとか頑張れていますが、この先もずっとと考えると少し憂鬱にもなります。

## だけど頑張りたいなって思う！
　ここまでずっと**ネガティブ**思考の話をずっとしてきましたが、やっぱり社会人になったわけだし、お給料も貰えるんだから一社会人として頑張りたいと言う**ポジティブ**な心情があるのも事実です。（この考えに至らない人もいますが...）　なので、これからを頑張るためにもなんかプラス思考になるようなことを書きたいと思います！

#### １．お給料がもらえるぞ！
　当然ですが、お給料がもらえます！　わぁ！やったあ！！嬉しい！！！　最初のお給料を何に使うかを考えると結構楽しいです！ちなみに私は**PS4**が欲しいです。

#### ２．研修がタダで受けられる！
　現在進行形中で受けている新人研修ですが、当然タダで受けていますよね？今受けているその研修は、会社が新人教育研修費として当然ながら出費しています。学生の頃、タダでもらえるものって大体嬉しくなかったですか？そう考えると、今研修を受けられていること自体が幸せだな〜ってちょっと思えます。「**人の金で焼肉を食べると美味しい**」理論ですね。

#### ３．新しい同僚や先輩ができる！
　一般的に**人間関係**というのは人を悩ませるタネになりがちです。しかし、これは裏を返せば楽しいタネになります！
　当然ながら、**同僚**は嬉しいものです。既に飲み会に行ったよ〜！とか言う方もいらっしゃるのではないでしょうか？何年経っても同僚は同僚です。大事にしたいですね。
　**先輩**は入社してすぐだとなかなか話しかけづらいですよね。でも素敵な先輩も沢山いるはずです。この先輩とのみにいったら楽しそうだな〜とか思っていると自ずと親近感が湧くのでオススメです！

#### ４．どんな先輩も最初は新入社員だった
　あの先輩ちょっと怖いな〜っていう方が必ず一人はいますよね。厳しい声をかける先輩ですが、「そんな先輩にも**新入社員だった時期があった**んだよな」と思うと少しほっこりしたような気分になれます！意外とオススメの方法です！

#### ５．自分は会社に認められている！
　自分は**会社に認められた一人**と考えるとちょっと気分が上がります。具体的に言えば、なんで新人でまるで使えない自分を会社はリスクをおかしてまで社員にしたのかということです。リスクというのは、会社の内部（社会秘）情報を漏らしたりなどです。少し前に**バイトテロ**と呼ばれるニュースが多かったですね。そんな可能性もあるのになぜ？　会社が自分を社員にしてくれたのだろうと考えると少しだけ嬉しくなります。


　これらは、あくまでポジティブな気持ちになるための方法の一つです。当然これを見て「は？wwwこいつ年そこそこいった社員だろwww」とか思った方もいると思います。だけどそんな考えだといつまでも**悪循環**な気がしませんか...？どこかで割り切ってこんな気持ちになってみると、どこかスッキリするかもです。自然と頑張れるような気がしてきます。

## おわりに
　この記事を作成した理由には、何年後かに自分が見て「あんときあういう風だったな〜」って懐かしむというのもありますが、**もし近い将来に後輩ができたとしたらこの記事を読ませてあげたい**というのも一つです。後輩には是非この記事を読んでもらって、先輩も社会人1年目の時はこうだったんだというのを教えてあげたいです。なので未来の後輩くんに向けて、先輩の今の思いを書きます。未来の後輩くんに伝わるといいな！

`〜未来の後輩くんへ〜
「これからも研修をしっかりと受けて、新社会人1年目として頑張りたいと思います！」
（先輩より　2019年4月7日）`

　
　最後に一言を述べて、終わりにしたいと思います。


> 満 員 電 車 が つ ら い 。


　ここまで読んでいただき誠にありがとうございました。質問や感想などがありましたら、気軽にコメントいただけますと幸いです。できる限り全員にご返答したいと思っております。
プロジェクトマネジメント 応用情報技術者試験 対策日記@18

##プロジェクトタイムマネジメント
プロジェクトの**WBS(Work BreakdownStructure)**で定義されたワークパッケージを、より小さく要素分解したものが**アクティビティ**。全てのアクティビティに対してマイルストーンを特定する。

###スケジュールの作成方法
####クリティカルパス法
アクティビティの順序関係を表したアローダイアグラムをもとに、まずプロジェクト完了までにかかる最長の経路であるクリティカルパスを計算する(**フォワードパス**)。次に、所要時間から逆算して復路の時間を計算する(バックワードパス)。フォワードパスにより、全てのアクティビティの最早開始日と最早終了日、バックワードパスにより最遅開始日と最遅終了日がわかる。

####クリティカルチェーン法
クリティカルパスを資源の制限から修正していく方法。

####クラッシング
コストとスケジュールのトレードオフを考え、最小の追加コストで最大の期間短縮を追求するスケジュール短縮方法。

####ファスト・トラッキング
順を追って実行するアクティビティを並行して実行することによるスケジュール短縮方法。

##プロジェクトコストマネジメント
###コスト見積もり方法
####ファンクションポイント法
ソフトウェアの各機能について、五種類のファンクションタイプに分け、それぞれの難易度を評価して基準値を求める。次に、複雑さをそれぞれ評価し、調整値を求める。基準値と調整値をもとにファンクションポイントを計算し、かかるコストを概算する。
####三点見積もり法
Cm=もっとも起こりそうな値
Co=最良の値
Cp=最悪の値
4Cm + Co + Cp / 6　を計算する。
####LOC法
Lines Of Codeを概算し、プログラムの規模を見積もる。
####COCOMO(Constructive Cost Model)
ソースコードの行数の予想に、エンジニアの能力や要求の信頼性などによる補正係数を掛け合わせ、予想コストを計算する。
開発工数(人月) = 3.0 * (開発規模(コードの行数))^1.12　と計算する。
###EVM(Earned Value Management)
PV(Planed Value),EV(Earned Value),AC(Actual Cost)から
CPI(Cost Performance Index) = EV/AC
SPI(Schedule Performance Index) = EV/PV
を計算し、1以上かどうかで各値を評価する。

------
[ホームへ](https://qiita.com/k-y/items/dc2c9a3a8425712253e8)
Ruby on Rails で sqlite3 から mysql に切り替えたい

#目的
Ruby on Rails で sqlite3 を使ってるけど、mysql に切り替えたい

# やり方

### Gemfileの編集
Gemfile に以下を追記する
ついでに sqlite3 は使用しないのでコメントアウトしておく

```Gemfile
#gem 'sqlite3', '~> 1.3.6'
gem 'mysql2'
```

### bundle install 実行

```
[root@localhost work]# bundle install --path=vendor/bundle
```

なんかエラーが出た

```
An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds ```
before bundling.
```


エラーの通りのコマンド実行してからinstallしても同じエラーになる

```
[root@localhost work]# gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'
```

こちらのサイトを参照して下記コマンド実行してからで installできました
https://qiita.com/tktcorporation/items/0ef8c930fc18ce72c301

```
[root@localhost work]# bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl/include"
```

### rails側の設定ファイル変更
sqlite3 の部分をコメントアウトして、mysql用の設定を追記する
database や user などは適宜書き換える

```config/database.yml
...
default: &default
#  adapter: sqlite3
#  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
#  timeout: 5000
  adapter: mysql2
  database: table_name
  username: user
  password: password
  host: 127.0.0.1
  encoding: utf8

development:
  <<: *default
#  database: db/development.sqlite3

test:
  <<: *default
#  database: db/test.sqlite3

production:
  <<: *default
#  database: db/production.sqlite3

...
```

### migrate実行
上で記述したデータベースは作成済みの前提

```
[root@localhost work]# bundle exec rake db:migrate
== 20190331035940 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0100s
== 20190331035940 CreatePosts: migrated (0.0100s) =============================
```

いい感じにマイグレできたっぽいです

### アプリケーションを実行して問題ないか確認
```
[root@localhost work]# rails s -b 0.0.0.0
```

→ http://localhost:3000/ にアクセスして表示できればOK
ただレコードの移行などはできていない状態です

### 最初からこうしておけばよかったのに
rails new コマンド実行時にデータベース指定できるようです

```
rails new application_name --database=mysql
```

# 参考にしたサイト
https://www.oiax.jp/rails3book/setup_mysql.html
https://www.sendai-freelance.com/entry/2017/05/10/232516
matplotlibの描画においてエラーが出る時の対処法

#はじめに
matplotlibを使った描画において、設定ファイルの変更等をしていないとエラーが出ることがあるので、そのことについて説明します。

#開発環境
OS：macOS Mojave(10.14.4)
Python 3.7.2

まずはじめに対話型のpythonを開きます。

```python
$ python
```
適当にx軸price、y軸countのサンプルグラフを作ります。

```python
>>> import matplotlib.pyplot as plt
>>> price = [80, 100, 150, 250, 400]
>>> count = [17, 42, 53, 36, 13]
>>> plt.plot(price,count)
>>> plt.show()
```
matplotlibをimportしたタイミングで以下のエラーが出ました。

```
>>> import matplotlib.pyplot as plt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/user/.pyenv/versions/3.7.2/lib/python3.7/site-packages/matplotlib/pyplot.py", line 2372, in <module>
    switch_backend(rcParams["backend"])
  File "/Users/user/.pyenv/versions/3.7.2/lib/python3.7/site-packages/matplotlib/pyplot.py", line 207, in switch_backend
    backend_mod = importlib.import_module(backend_name)
  File "/Users/user/.pyenv/versions/3.7.2/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/Users/user/.pyenv/versions/3.7.2/lib/python3.7/site-packages/matplotlib/backends/backend_macosx.py", line 14, in <module>
    from matplotlib.backends import _macosx
ImportError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are using (Ana)Conda please install python.app and replace the use of 'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more information.
```
これはmatplotlibrcという設定ファイルの記述の
`backend : macosx`
という箇所を以下のように変更すると解決するみたいです。
`backend : Tkagg`

matplotlibrcの場所は、以下のコマンドで確認できます。

```python
$ python -c "import matplotlib;print(matplotlib.matplotlib_fname())"
/Users/user/.pyenv/versions/3.7.2/lib/python3.7/site-packages/matplotlib/mpl-data/matplotlibrc
```
ファイルの場所を確認できたら、Finderでファイルまでたどり着き上記のように変更してあげましょう。

無事サンプルグラフ作成のコマンドが通り、グラフが作成できたかと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/259323/0de79a35-2f1e-6e18-1919-8d12f031d636.png)

#参考記事
[pyenvとvirtualenvで環境構築した時にmatplotlib.pyplotが使えなかった時の対処法](https://qiita.com/Kodaira_/items/1a3b801c7a5a41c9ce49)
ISOLATION LEVEL -DBSP勉強備忘録-

DBSPの勉強中にきちんと理解できてなかったのでメモ
引用元は[情報処理教科書 データベーススペシャリスト 2019年版](https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AA%E3%82%B9%E3%83%88-2019%E5%B9%B4%E7%89%88-%E4%B8%89%E5%A5%BD-%E5%BA%B7%E4%B9%8B/dp/4798157945/ref=zg_bs_2157079051_1?_encoding=UTF8&psc=1&refRID=KTJ4TCA51MD20NWWE1AN)です

# ISOLATION LEVEL

ISOLATION LEVEL (隔離性水準)はトランザクションの独立性、分離性のレベルのこと
独立性阻害要因を認めるかどうかによって4つのレベルに分類される

## READ UNCOMMITTED
>もっとも分離レベルが低いため、トランザクションのスループットは上がるものの、他のトランザクションで変更されたコミット前のデータを読み込むこんでしまうことがある。

発生する独立性阻害要因
 - ダーティリード
 - ノンリピータブルリード
 - ファントムリード

## READ COMMITTED
>コミットされたデータだけ読み取る。他のトランザクションで変更されたデータでも、コミットされるまでは読み取ることができなくなるので、ダーティリードは抑止できる。

発生する独立性阻害要因
 - ノンリピータブルリード
 - ファントムリード

## REPEATABLE READ
>繰り返し同じデータを読み取っても、同じ内容であることを保証する。つまり、あるトランザクションで読み取ったデータは、別のトランザクションで更新できない

発生する独立性阻害要因
 - ファントムリード
 
## SERIALIZABLE
>複数のトランザクションをいくら実行させても、その影響を受けずに一つずつ実行したのと同じ結果を保証する。ダーティリード、ノンリピータブルリード、ファントムリードのいずれも発生しない。つまり、あるトランザクションが参照したテーブルには、追加、更新、削除のいずれもできなくなる。もっとも強力な隔離レベルだが、排他待ちが起きやすくなるためトランザクションのスループットは一番悪くなる。

排他待ち：他のプロセスによる資源の独占が解放されるのを待っている状態

# 独立性阻害要因
## ダーティリード
>他のトランザクションで更新された”コミット前”のデータを読み込んでしまうことをダーティリードという。そのままコミットされればいいが、その更新が取り消されると”取り消された更新”を処理することになって不整合が発生する。

例
1. トランザクションT1がレコードを挿入
2. トランザクションT2がトランザクションT1が挿入したレコードを読み込む
3. トランザクションT1がロールバックを行うと、トランザクションT2は取り消されたデータを
　読み込んで処理を続けることになり、不整合が起こる可能性がある

## ノンリピータブルリード
>同じでデータを２回リードした時に値が異なる可能性のある読み方のことをいう。ファジーリードともいう。

例
1. トランザクションT1がテーブル１を読み込む
2. トランザクションT2がテーブル１を更新する
3. 再びトランザクションT1がテーブル１を読み込んだ時、前回読み込んだデータと
　　内容が変わってしまっている

##　ファントムリード
>１回目と２回目のリードの間に、他のトランザクションによってデータが追加されてしまう読み方をファントムリードという。１回目にはなかった”幻＝ファントムのデータ”が発生し、不整合になる可能性がある。

例
1. トランザクションT1がテーブル１にレコード１を挿入する
2. トランザクションT2がテーブル１を検索するとトランザクションT1は
　　コミットされていないためレコード１は検索されない
3. トランザクションT1が挿入したレコード１をコミットする
4. 再びトランザクションT2がテーブル１を検索すると今度はレコード１が検索される
　　(１回目にはなかった幻のデータが発生している)
KUSANAGI on Vagrant

# KUSANAGI を Vagrant 上で動かしてみる

## ここです

[piwikjapan/kusanagi-vagrant](https://github.com/piwikjapan/kusanagi-vagrant)

プライムストラテジー社公式の [KUSANAGI for Vagrant](https://kusanagi.tokyo/cloud/kusanagi-for-vagrant/) もあるんですが、[当方のは](https://github.com/piwikjapan/kusanagi-vagrant)素の CentOS からインストールしていきます。
 
# きっかけ

サーバーは [kusanagi](https://kusanagi.tokyo/) を使用していますので WordPress のコンテンツ作成は kusanagi 上で動くことを確認してくださいってコンテンツ屋さんには伝えるんです、でも

* kusanagi ってなに
* kusanagi はわかった。で、環境構築どうやってやるの

っていう質問がくるのはめにみえていて、ここみて、的なものが欲しかったのです。

# 特徴

[bento/centos-7.6](https://app.vagrantup.com/bento/boxes/centos-7.6) から、kusanagi 必要パッケージとかファイルをスクリプトで追加していきます。スクリプト見れば、素の CentOS から何を追加すれば kusanagi サーバーになるのかがよくわかると思います。
プライムストラテジー社公式 [KUSANAGI for Vagrant](https://kusanagi.tokyo/cloud/kusanagi-for-vagrant/)  も同じようなことができるのですが、こちらはあらかじめ全部インストールされているイメージをダウンロードするだけです。

## kusanagi 環境が VM イメージ提供だけな理由を考えてみる

なんで yum レポジトリの設定 → yum install で kusanagi コア rpm パッケージを入れる → kusanagi init という流れではなく、すべてインストールされた VM イメージなんでしょうか。営業的な理由で VM イメージ限定にしているのかはわかりませんが、VM イメージを見てみると、ああ、なるほどと、浮かび上がる問題として:

* 他のパッケージで作られるユーザーとかグループ（httpd, postgres）がある前提となっているが、kusanagi rpm パッケージでこれらユーザーがないと警告はしない。また、先行する rpm パッケージとして定義もされていない
* kusanagi rpm パッケージでしか使わないユーザー（kusanagi, apache）、グループ（www）を rpm パッケージで作成しない
* 独自の設定ファイル（/root/.my.cnf など）、または既存の設定の上書き（/etc/my.cnf.d/server.cnf など）がちりばめられているけど、kusanagi rpm パッケージで面倒は見ない。最悪 kusanagi init でエラーとなって初めて気づく

このへん rpm のインストール時に実行されるスクリプトで解決できると思いますので、kusanagi が VM イメージの提供のみの理由として kusanagi rpm の作りが粗いってことに帰結しそうです。
と、上記にあるように営業的な理由ですね（2019/4/9 追記）。
Reduce of empty array with no initial value

demo https://codepen.io/gnjo/pen/XQjrqX?editors=1010

```js
let a=[],b=['xxx'],c=['ee'],d=void 0
;
let ret=[].reduce((a,b)=>a.concat(b),[]) //safe
console.log(ret)
let ret2=[].reduce((a,b)=>a.concat(b)) //Reduce of empty array with no initial value
console.log(ret2)
let ret3=[a,b,c,d].reduce((a,b)=>a.concat(b))
console.log(ret3)
;//

```
Bashで=で区切られたファイルを変数の設定ファイルとして読み込む

例えば下記のファイルがあるときに

```bash:.env
DB_CONNECTION=mysql
DB_HOST=mysql.test
DB_PORT=3306
DB_DATABASE=mysql
DB_USERNAME=root
DB_PASSWORD=example
```

```bash
echo $DB_HOST  # mysql.test と出力させたい
```

をさせたい。

# シェルスクリプト

`.`でファイルを読み込ませる事ができる。[参考](https://orebibou.com/2014/11/%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%E5%A4%96%E9%83%A8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E8%A8%98%E8%BF%B0%E3%81%95%E3%82%8C%E3%81%9F%E5%A4%89/)

```bash:hoge.sh
#!/usr/bin/env bash

. .env

echo $DB_HOST # mysql.testが出力される
```

# コマンドライン
`source`で読み込ませることができる。

```bash
$ source .env
$ echo $DB_HOST # mysql.test が出力される
```


# 何をさせたかったか
Laravelの環境ファイル`.env`を読み込んで、DBのバックアップ（ダンプ）を取得したかったです。


```bash:.env
# 抜粋です

DB_CONNECTION=mysql
DB_HOST=shiba_office.test
DB_PORT=3306
DB_DATABASE=shiba_office
DB_USERNAME=root
DB_PASSWORD=example
```


```bash:backup.sh
#!/usr/bin/env bash
# .envファイルを元にDBのバックアップを作成する

set -xe # 環境変数の展開しつつコマンドの表示、エラー時に表示 => 環境変数のパスワードがttyに表示されるので注意

# 相対呼び出しに対応するためこのスクリプトファイルが置いている場所に移動
# cd -- "$(dirname "$BASH_SOURCE")"
# cd ../
# そこからLaravelのルートに移動
# cd lara_app

# .envファイルの読み出し
. .env

NOW=$(date +%Y%m%d%H%M%S) # 現在時刻を取得

# 圧縮あり ファイル名は backup_dbname_20190407080030.sql.gz といった名前になる
mysqldump  -h${DB_HOST} -u${DB_USERNAME} -p${DB_PASSWORD} ${DB_DATABASE} \
  | gzip - > backup_${DB_DATABASE}_${NOW}.sql.gz

# 圧縮なし ファイル名は backup_dbname_20190407080030.sql といった名前になる
# mysqldump  -h${DB_HOST} -u${DB_USERNAME} -p${DB_PASSWORD} ${DB_DATABASE} \
#  > backup_${DB_DATABASE}_${NOW}.sql
```

ということで、お手軽にバックアップが作成できます。
pyenvにより、pythonのバージョンを変更する

#はじめに
pythonではpyenvというツールを使うことで、複数バージョンのpython環境を簡単に切り替えることができるようになります。2系列と３系列との切り替えにおいて重宝します。では、早速pyenvによる、pythonのバージョンを変更の仕方を説明します。

#開発環境
OS:macOS Mojave(10.14.4)

#インストール可能なpythonのバージョンを確認する
```python
$ pyenv install --list
```
ここでpyenvがインストールできていない人はHomebrewを使ってインストールしましょう。

```python
$ brew install pyenv
```
#それぞれのバージョンのpythonをインストールする

```python
$ pyenv install 3.7.2
```
```python
$ pyenv install 2.7.10
```
#変更可能なpythonのバージョンを確認する
```python
$ pyenv versions
  system
* 3.7.2 (set by /Users/user/.pyenv/version)
```
#現在のpythonのバージョンを確認する
```python
$ python --version 
Python 2.7.10
``` 
#pythonのバージョンを変更可能なバージョンに変更する
```python
$ pyenv global 3.7.2
$ python --version
Python 2.7.10
```
ここでpythonのバージョンが適切に変更されていませんね。次のコマンドを入力してください。（以下記事が参考になります。）
[pyenvがバージョンを切り替える仕組みを理解する](https://akamist.com/blog/archives/2610)

```python
$ eval "$(pyenv init -)"
```
再度、pythonのバージョンを確認してみましょう。

```python
$ python --version
Python 3.7.2
```
きちんと変更できましたね。

>仕組みとしてはeval "$(pyenv init -)"で環境変数PATHに.pyenv/shimsを追加し、pyenv globalやpyenv localで該当バージョンのpythonを.pyenv/shimsにコピーしているようです。

（[pyenvがバージョンを切り替える仕組みを理解する](https://akamist.com/blog/archives/2610)より引用）

#参考記事
[pyenvがバージョンを切り替える仕組みを理解する](https://akamist.com/blog/archives/2610)
[pyenvを使って、pythonバージョンの変更](https://qiita.com/twipg/items/75fc9428e4c33ed429c0)