OmniAICreator/Qiita-1.07M huggingface dataset:
[ActiveStorage] ファイルのURLにアクセスしたときに routes.rb 末尾の *path にマッチしてしまうのを避ける


`config/routes.rb` の末尾に `*path` などのルーティングがあると、
ActiveStorageのファイルを示すエンドポイント(`/rails/active_storage/...`)[^2]よりも先にマッチしてしまう。

[^2]: 定義はこちら https://github.com/rails/rails/blob/v5.2.4.4/activestorage/config/routes.rb#L4

```config/routes.rb
Rails.application.routes.draw do
  ...

  get "*path" , to: redirect('/')
end
```

これを回避するためには以下のようにする。

```config/routes.rb
Rails.application.routes.draw do
  ...

  get '*path' , to: redirect('/'), constraints: lambda { |req|
    req.path.exclude? 'rails/active_storage'
  }
end
```

これで `rails/active_storage` を含むパスがマッチしないように設定できる。

### `constraints` オプションについて
特定のルーティングに制約(constraints)を与えるためのオプションという解釈。
以下のようにして使う。

```rb
# match `/users/A12345`, but not `/users/893`
get 'users/:id', to: 'users#show', constraints: { id: /[A-Z]\d{5}/ }

# match port 3000 only
get :users, to: 'users#index', constraints: { port: '3000' }
```

上述のようにlambdaを指定することもできる。[^1]

```rb
get "hi", to: redirect("/foo"), constraints: ->(req) { true }
```

[^1]: 厳密には `request` を引数に取る `call` メソッドが呼び出し可能なオブジェクトを指定すればよさそう。リクエスト毎に呼ばれる `call` がtrueを返す場合にのみ、対象のルーティングがマッチするといった動作のよう。本投稿では触れていないが `matches?` でも可。 ( [テストコード](https://github.com/rails/rails/blob/e44b3419d44b5fa6e66305fe703f34bb63932593/actionpack/test/dispatch/routing_test.rb#L118-L131) 、 [実装部分](https://github.com/rails/rails/blob/e44b3419d44b5fa6e66305fe703f34bb63932593/actionpack/lib/action_dispatch/routing/mapper.rb#L41-L42) を参照)

### 参考
- https://qiita.com/NaokiIshimura/items/0f0e56c159c95b59b11f
- https://github.com/rails/rails/issues/31228#issuecomment-352900551
- https://y-yagi.tumblr.com/post/92386974040/rails-routing-constraintsについて
- https://railsguides.jp/routing.html#セグメントを制限する
Xcode12で実機デバッグのRunningが遅い

# 事象
Xcode12にアップデートしてから、実機デバッグ時のRunningに2,3分かかる

# 解決策
`〜/ Library / Developer / Xcode / iOS DeviceSupport`
上記パス内のコンテンツを全て削除すると直りました。
Laravel　[マイグレーションの設定~テーブル作成〜カラム作成]

# マイグレーション設定
モデルは artisan コマンドを使えば良いので php artisan とした後に、 make:model そして モデル名を今回は記事の Model なので Post としてあげましょう。
その後にバージョン管理するためのマイグレーションファイルも作りたいので、 php artisan make:model Post --migration のようなオプションを付けてあげましょう。
![スクリーンショット 2020-10-08 16.00.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/923eda88-9515-89cc-5a22-8daa82364c4e.png)
こうする事でPostモデルとマイグレーションフォルダができます。
# マイグレーションの記述
migration ファイルには up() と down() というメソッドがあるのですが、 up() がこのマイグレーションで行いたい処理、 down() はそれを巻き戻すための処理になります
![スクリーンショット 2020-10-08 16.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/bffcf157-c034-f2b1-ede9-df15acf4fe61.png)
## カラムの追加
column の種類なんですが、 SQL でいうところの varchar は string で設定していくので string('title') 、そして body に関してはテキストで設定したいので text('body') としてあげれば OKです。
![スクリーンショット 2020-10-08 16.18.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/930eb8f0-7c83-65c0-1aac-d58251cfddf3.png)
その後に、
php artisan migrate　とするとdbにテーブルができます。
オレオレ証明書の警告をChromeで表示させないようにする

# 目的
オレオレ証明書の警告をChromeで表示させないようにする。
ドメインは `ore.example.com` とする。

# 手順

## ホスト側の hosts 変更
以下の設定を追加する。※Windows10の場合

```:/C/Windows/System32/drivers/etc/hosts

127.0.0.1 ore.example.com
```

## SSL証明書を作成

### 秘密鍵を作成
```bash
openssl genrsa -out ore.example.com.server.key 2048
```

### 証明書署名要求(CSR Certificate Signing Request)を作成
```bash
openssl req -new -key ore.example.com.server.key -out ore.example.com.server.csr

Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or Your name) []:ore.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

### SAN値を設定
ドメインはワイルドカードにしている。※ore.example.com にすると動かなかった
IPはホストのローカルエリアネットワークのIPアドレスにしている。※適宜変更

```bash
echo "subjectAltName = DNS:*.example.com, IP:192.168.xxx.xxx" > san.txt
```

### サーバ証明書を作成
```bash
openssl x509 \
  -req \
  -sha256 \
  -days 3650 \
  -signkey ore.example.com.server.key \
  -in ore.example.com.server.csr \
  -out ore.example.com.server.crt \
  -extfile san.txt
```

### （オプション）サーバ証明書を確認
```bash
openssl x509 -in ore.example.com.server.crt -text -noout
```

### オレオレ証明書を Chrome に登録する
1. Chrome の`設定`を開く。
2. `プライバシーとセキュリティ`メニューの`セキュリティ`を選択する
3. `証明書の管理`を選択する（設定ボックスが表示される）
4. 設定ボックスで`インポート`をクリックする
5. 説明の画面で`次へ`をクリックする
6. さきほど作成した`ore.example.server.crt`ファイルを選択して`次へ`をクリックする
7. 証明書ストアを `信頼されたルート証明機関` に変更して`次へ`をクリックする
8. 最終確認画面で`完了`をクリックする
9. セキュリティ警告が出る場合は`はい`をクリックする
LEDハーバリウム

小学生の娘がハーバリウム作りにはまっていたので、コラボして夏休みの宿題を作成した。
無接点電源モジュールを使ったハーバリウムを作っている人の記事を見つけたので、それを応用してみることにする。

[ワイヤレス給電で光るハーバリウム (前編)](https://lipoyang.hatenablog.com/entry/20180321/p1)

## 完成形

![IMG_5426.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/2eff74b5-f0f5-fb67-f209-29483f9288ea.jpeg)

## 準備

ちょうどよい瓶を探すためにホームセンター巡り。無接点電源モジュールを使うため、底がフラットで、口も大きなものが必要。保存用500ml広口瓶にした。

## プロトタイプ

まずは、LEDの色と点灯タイミングのテストのために、レギュラーのArduinoとブレットボード、LEDでテスト。
1/fゆらぎアルゴリズムのチューニングもここで。

## 本番用
### 回路
- [ELEGOO Arduino Nano（互換機）](https://www.amazon.co.jp/dp/B072F5NS4X)
- LED(2.8-3.6V) x 6本
- 抵抗（100Ω） x 3本
- [120mA 無接点電源モジュール](https://eleshop.jp/shop/g/gG6A412/)
- 006P用ケース

### ハード
- 瓶
- 箱
- プリザーブドフラワー
- 数珠玉

## 構成

###ハーバリウムボトル

Arduino NanoにLED2本を直列で接続×3セットを立ち上る。
LEDはなるべく存在感をなくしたかったので、LED、LED、抵抗、抵抗の足を使って高さ稼ぎ、を空中配線。
下に無接点電源モジュールを敷く。

![IMG_5399.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/9f24e2ba-ce50-237a-df54-54d7a032311a.jpeg)

それらをUVレジンで固定する。
まわりを数珠玉で埋め、さらにUVレジンを流し込み固定する。

![IMG_5403.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/ffa9d75e-5c08-491d-9c3a-45dd24164bad.jpeg)

まわりに花を配置（ここがハーバリウム的には本番）、最後にシリコンオイルを流し込む。

![make.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/7516e657-624d-2819-e2a4-ba925cc4552a.jpeg)

### 台

乗せる台は当初スタンド的なものなどを想定していたが、ちょうどよい大きさのお菓子の箱があったのでそれを利用。
箱の底に無接点電源モジュールを置き、箱の背に穴を開け、裏の電池ケースとつなぐ（006P）。

位置を合わせたらUVレジンで固定、まわりにプリザーブドフラワーをデコレーション。

![IMG_5444.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/762550bb-1498-be50-2daf-abb908c897db.jpeg)

当初電池ケースとスイッチを別々につなごうとしたが、ちょうどよいスイッチ付き電池ケースが調達できたので、それを背面に仮留め。

![IMG_5489.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54438/9ad2163d-af22-381a-6150-b9f2bc7d4380.jpeg)

## 回路

配線はArduino NanoのD3、D5、D6ポートを使用。電源は、5V端子に接続

## TIPS

Arduino Nano互換ボードをArduino IDEに認識させるために、Arduino Nano USB Driverをインストール。

[ダウンロード](https://www.elegoo.com/download/)

##ソース


    // herbarium 3
    // for haruka summer work
    // 2020/8/26
    
    int yuragi();

    const int LED[] = {3, 5, 6};  // LED pin numbers
    float x1[] = {0.1, 0.2, 0.3}; // default values
    
    int value = 0;

    
    void setup() {
    }
    
    void loop() {
      for (int i = 0; i < 3; i++) {
        value = chaos(i);
        analogWrite(LED[i], value);
      }
      delay(80);
    }

    int chaos(int i) {
    // 1/f yuragi
    
      float x = x1[i];
      if (x < 0.5) {
        x = x + 2 * x * x;
      }
      else {
        x = x - 2 * (1.0 - x) * (1.0 - x);
      }
    
      if (x < 0.08) {
        x = (float)(random(20, 80)) / 256;
      }
      if (x > 0.995) {
        x = (float)(random(128, 253)) / 256;
      }
    
      x1[i] = x;
      x = x * 255;
    
      return (unsigned int)x;
    }
Twitterの新規アカウント作る際の電話番号入力フォームで気づいたこと

請負った仕事で、ツイッターアカウントを作って欲しいと依頼を受けました。
私は、電話認証（SMS認証）ある事を忘れていたので、安請け合いしてしまいました。
依頼主は、電話認証に協力してくれなかったので、認証コードを教えてもらえなかったです。
その挙げ句、自分自身でアカウントを作ったと言われたので、私は、何だったのだろうと悔しいような悲しいような複雑な思いをしました。

そのため、電話認証できる電話番号を作る方法をネット検索してみました。
見つかる情報は、いずれも数年前のもので、今では使えないものばかりでした。

私は、こちらのブログの記事でも書きましたが、textPULSというアプリを使いました。
https://ameblo.jp/atelier-miracle/entry-12630131642.html

https://www.valuer.work/?p=2206

無料で、アメリカのsms送受信出来る電話番号を作ることができるアプリです。
でも、このアプリは、制限があります。
アメリカとカナダの中で発信されるSMSのみ受信できます。
そのため、日本のスマホからtextPLUSの電話番号にSMSを送信しても、受信できません。
Skypeでも、日本の０５０で始まるSkype番号では、textPLUSの電話番号にSMSを送信しても、受信できません。

アメリカのSkype番号を作ってからtextPLUSの電話番号にSMSを送信すると、正常に受信できました。
音声通話は、Skypeの050のSkype番号の状態で試しましたが着信できました。

##さらに工夫
アメリカの国内VPNサーバー経由して、Twitterにアクセスしました。
そして新規登録を選択して、アカウント登録を試みました。

この時、textPLUSの電話番号は、エラーなり入力できませんでした。

ネットで知った記事の中に、Google voiceで作った電話番号ならてTwitterのSMS認証できるとあったので、Google voiceにもアクセスしました。

Google voiceは、日本では利用できないサービスなので、VPNでアメリカ国内からのアクセスして、電話番作りを試みました。
textPLUSの電話番号で認証できると読んだ記事には書いてありましtが、今は対策されているようで、VOIPで作られた電話番号では利用できないようです。

そのため、TwitterのSMS認証できるのか検証できませんでした。

VPNでTwitter.comにアクセスしたのですが、何故か日本語のウェブサイトのままでした。

##発見したこと
電話番号入力していて気がついたのですが、VPNでアメリカ国内からのアクセスとしていたので、電話番号で、日本の携帯電話番号の局番や市外局番を入力すると、正しくないとエラーになりました。
そして、アメリカの電話番号風の数字で入力したら、エラー出ませんでした。

ということは、表示しているページは一つですが、アクセスしてきた国に応じて、入力できる電話番号の形式を切り替えているように思いました。
見た目が日本語だからと思っても、中身は、ちゃんとアメリカのサイトになっていました。

##結論
どうしてもアメリカの電話番号でTwitterアカウントを作る必要がある場合は、アメリカのSIMカードを手に入れて、アメリカの携帯電話番号を使って登録しましょう。

もしくは、メールアドレスを使って、アカウントを作るようにしましょう。

私も、今回の依頼の際に電話認証に拘らずメールアドレスで認証すれば良かったと、後から後悔しています。
【Ruby on Rails】RSpec実行時にgem 'chromedriver-helper'は非推奨ですよって警告を受ける。

## 前書き・編集点
この記事は前回の記事
[【Ruby on Rails】RSpec実行時にgemのバージョン違いで警告を受ける。](https://qiita.com/MasaoSasaki/items/41343771cc85d5161566)
の続きですが、全く別の警告だったので２つに分けました。

2020.10.10
コメントで、私の解釈の違いについてご指摘をいただきましたのでその点修正を行いました。

## 環境
Ruby 2.5.7
Rails 5.2.4

### gem
gem 'rspec-rails', '~> 3.6'

## 経緯
RSpecを使ってテストコードを記述し、実行すると下記のような警告文が出ました。

```
$ rspec spec/models/tag_spec.rb 

2020-10-09 09:13:13 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
```

これはエラーではないのでテストは正常に実行されますが、毎回出るのを放っておくわけにも行かないのでこれも解決していきます。

## 手順
警告文の内容ですが、
`Selenium::WebDriver::Chrome#driver_path= is deprecated.`
Chromeクラスの`driver_path=`メソッドが非推奨であるため、
`Selenium::WebDriver::Chrome::Service#driver_path= instead.`
Serviceクラスの`driver_path=`メソッドを代わりに使うようにというメッセージです。

こちらに書かれている通り、私のGemfileにも`gem 'chromedriver-helper'`がありましたので、まずはこれを削除します。
次に代わりとなる
`gem 'webdrivers'`を記述します。

最後に

```
$ bundle install
```

で解決することができました。

## まとめ
質問や解釈の違い、記述方法に違和感ありましたら、コメント等でご指摘いただけると幸いです。

最後まで読んでいただきありがとうございました。


## 参考サイト
私のGitHubに実際に使っているファイルを公開しているのでそちらも参考にしていただければと思います！
[GitHub - MasaoSasaki/matchi](https://github.com/MasaoSasaki/matchi)

その他
[Qiita - サポートが終了したchromedriver-helperからwebdrivers gemに移行する手順](https://qiita.com/jnchito/items/f9c3be449fd164176efa)
[Qiita - rspec-rails 3.7の新機能！System Specを使ってみた
](https://qiita.com/jnchito/items/c7e6e7abf83598a6516d)
プロセスについて基本知識と操作をまとめてみた

Linuxの基本を学習中、プロセスについての初歩的な知識と、操作方法を知識定着の為まとめてみる。

## プロセス
プロセス：
メモリ上で実行状態にあるプログラムのこと。
プロセスIDという一意のIDで管理されているので、同じコマンドが同時に複数実行されても、
データが混じったりすることはない。

####プロセスの確認方法

```
$ ps
 PID  TTY        TIME  CMD
 3007 pts/0  00:00:00  bash
 3035 pts/0  00:00:00  less
 3040 pts/0  00:00:00  less
 3043 pts/0  00:00:00  ps
```
↑↑　psコマンドで現在実行中のプロセスを表示。
　　　lessが２回実行されてるが、PID(プロセスID)で区別されてる。

プロセスを確認する際によく使われるpsコマンドのオプションが以下↓↓

| オプション| 意味 |
|:-:|:-:|
| x  |psコマンドを実行したユーザーのプロセス全てを表示   |
|  ux|psコマンドを実行したユーザーのプロセス全てを,詳細情報を合わせて表示   |
|   ax|全てのユーザーのプロセスを表示   |
|aux|全てのユーザーのプロセスを詳細情報と合わせて表示|

※これらのオプションは、-（ハイフン）が不要。
####プロセスの終了方法
killコマンドで、PIDを引数に指定。
さっきのpsコマンドの実行結果でPIDを確認した後

```
kill 3040
```
これでさっきのpsコマンドで表示された
上から３つ目のlessコマンドのプロセスが終了。

### ちなみに
killコマンドは、プロセスを終了させるコマンドではなく、正確には`シグナルを送信するコマンド`です。
デフォルトで`TERM`というシグナルを送信している。

```
kill 3040
kill -TERM 3040
kill -15 3040
```
これ↑は全部同じ処理をしている。
どういうことかというと、「3040`（のプロセス）`」を「TERM`(終了させるシグナル)`」で「kill`(送信)`する」と言い換えれる。

３番目の-15は何かというと、kill -lでkillコマンドの利用可能なシグナルの一覧が見れる


```
$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
...省略...
```
（頭にSIGがついています）
TERMが15番目にあるのでオプションを指定する時のように -15を指定するとTERMが指定されます。

killコマンドはデフォルトでシグナルがTERMになっている為、何も指定しなければ、プロセスを終了するシグナルを送信します。

kill -lで表示したリストの中に`KILLのシグナル`も９番目（SIGKILL）にあり、
これもプロセスを終了するシグナルですが、`TERMプロセスを受け付けなくなった、異常なプロセスを終了させるときに使う最終手段`として使うことが多いらしい。

##まとめ

- プロセスとは実行中のプログラムのこと。
- psコマンドで実行中のプロセスを確認できる。
- psコマンドにオプションをつけると、表示されるプロセスの情報を変えられる。
- kill <プロセスID>でプロセス（実行中のプログラム）を終了させることができる。
- killコマンドはシグナルを送信するコマンド。シグナルは複数あり、指定することでプロセスを終了する以外の振る舞いもできる。
ドキュメントを書かないエンジニアがDXを阻害する

# はじめに
　2025年以降も企業が存続するために必要であるというDX（デジタルトランスフォーメーション）は注目されていますが、それを実行するために重要なアクションプラン（行動指針）については語られることは少ないです。
DXには縁がないと思われる人が多いかもしれない地方銀行もコスト削減と地方銀行間で共通のサービスを提供するために[「TSUBASAアライアンス」](https://www.shigagin.com/pdf/topics_190522_1.pdf)というプロジェクトを推進しDXに取り組んでいます。

ではDXの実行のためには具体的にどうすればよいのでしょうか。

以下のレポートを参考にアクションプランを考えていきます。

～ITシステム「2025年の崖」の克服とDXの本格的な展開～
https://www.meti.go.jp/shingikai/mono_info_service/digital_transformation/pdf/20180907_03.pdf

# ドキュメントを書かないエンジニア
７ページ目を読むと「レガシーシステムが足かせと感じる理由」が書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33329/623c985b-3e2f-6225-0e1a-72d08080f4b3.png)

　最も足かせと感じる理由として多いのが「ドキュメントが整備されていないために調査に時間を要する」です。
ようするにコーディングだけはするけれど、「あとはもう知りません」。というエンジニアが多いということかもしれません。そんな人をエンジニアと呼ぶべきかわかりませんが…。

　では、ドキュメントが無いことの何が問題なのでしょうか。それはドキュメントがないのでソースコードを読むしかないということになります。するとエンジニアの稼働がそっちにとられます。

　こういうことを書くとドキュメントを書かなくてもうちの会社ではサービスの稼働はできているという人がいるかもしれません。しかし、会社は組織でやっているので、あなたが病気になったり会社を退職したときには必ずそれを引き継ぐ人がいます。サービスに不具合が起こった時、サービスの改修が必要になった時退職していたら基本的には頼むことは難しいでしょう。したがって、ドキュメントを書く必要があります。
次にドキュメントの書き方について説明します。

## ドキュメントの書き方
ドキュメントの書き方には答えはありませんが、私は以下の内容を書くことが多いです。

・ソフトウェアの概要、目的
・ソフトウェアの利用方法
・クラスの利用方法、メソッドの利用方法
・クラス図とその説明
・ソフトウェアの依存関係
・ソフトウェアを動かすのに必要なライブラリ

必要なことは過不足なく書くことが重要です。

# 最後に

私はソフトウェアをしっかりと開発できていると自信満々に言うのは現状できません。
日本人ですが文章も分かりやすく書けませんし、日本語も正しく読めないことが多いです。
ですが、何が必要か考えて、本を読んで勉強して行動しています。
今回の記事は自分のことを棚に上げて書きました。失敗に気づいて直していくのが大切だと思います。
【Rails】複数モデルのインスタンスを一覧表示する

# 実現させたいこと
YouTubeやFacebookのタイムラインのように、投稿と広告を作成降順に同じ画面に表示する機能が必要になった（通常なら広告は作成順の表示ではないかもしれないが、話を簡単にするために作成順で並べると仮定する）。

上記の状況に限らず、いくつかのモデルパターンを想定して、コントローラーでうまいこと取得し、ビューで並列して処理する方法を考える。

# 前提
## バージョン
- Ruby 2.6.3
- Rails 5.2.3


# ケース１
## 関連のないモデルを作成日順に並べる

```ruby
# 投稿モデルと広告モデルはカラムが異なるとする

# 投稿モデル（Post）
  t.integer "user_id"
  t.string "content"
  t.string "image"
  t.datetime "created_at"
  t.datetime "updated_at"

# 広告モデル（Advertisement）
  t.integer "company_id"
  t.string "content"
  t.string "link_url"
  t.datetime "expired_date"
  t.datetime "created_at"
  t.datetime "updated_at"
```

## 実装方法

```rb:timeline_controller.rb
def index
  posts = Post.all
  ads = Advertisement.all

  # それぞれの複数インスタンスを1つの配列にする
  @instances = posts | ads
  # 作成降順（新しい順）に並び替え
  # 作成昇順の場合は、a.created_at <=> b.created_at }
  @instances.sort!{ |a, b| b.created_at <=> a.created_at }
end
```

```erb:index.html.erb
<% @instances.each do |instance| %>
  <% if instance.class == "Post" %>
    <%# Postの表示 %> 
    <%= instance.user_id %>
    <%= instance.content %>
    <%= instance.image %>
  <% else %>
    <%# Advertisementの表示 %> 
    <%= instance.company_id %>
    <%= instance.content %>
    <%= instance.link_url %>
  <% end %>
<% end %>
```


# ケース２
## 関連のないモデルを異なるDate型カラムで日付順に並べる

```ruby
# ケース１と同じ

# 投稿モデル（Post）
  t.integer "user_id"
  t.string "content"
  t.string "image"
  t.datetime "created_at"  <= これで並び替えたい
  t.datetime "updated_at"

# 広告モデル（Advertisement）
  t.integer "company_id"
  t.string "content"
  t.string "link_url"
  t.datetime "expired_date"  <= これで並び替えたい
  t.datetime "created_at"
  t.datetime "updated_at"
```

## 実装方法

```rb:timeline_controller.rb
def index
  posts = Post.all
  ads = Advertisement.all

  @instances = posts | ads
  # 投稿モデルの場合はcreated_atを、広告モデルの場合はexpired_dateで判定する
  @instances.sort! do |a, b|
    a_created_at = a.class == "Post" ? a.created_at : a.expired_date
    b_created_at = b.class == "Post" ? b.created_at : b.expired_date
    b_created_at <=> a_created_at
  end
```

# ケース３
## 子がある場合は子の最新の作成日、ない場合は親の作成日を見て並べる

```ruby
# トークルームモデル（TalkRoom）
  t.string "name"
  t.datetime "created_at"
  t.datetime "updated_at"

# 投稿モデル（Post）
  t.integer "talk_room_id"
  t.string "content"
  t.string "image"
  t.datetime "created_at"
  t.datetime "updated_at"
```

## 実装方法

```rb:timeline_controller.rb
def index
  @instances = TalkRoom.includes(:posts)
                       .order("posts.created_at DESC")
                       .to_a
  # 子モデルが存在するかを判定し、ある場合は最新の子モデルのcreated_at、ない場合は親のcreated_atで判定する
  @instances.sort! do |a, b|
    a_created_at = a.posts.present? ? a.posts.first.created_at : a.created_at
    b_created_at = b.posts.present? ? b.posts.first.created_at : b.created_at
    b_created_at <=> a_created_at
  end
end
```
点群データをUnityのVFX Graphで使用する

点群データをUnityのVFX Graphから使用できるようにしてみます。

使用したバージョンは以下のとおりです。

- Unity: 2020.1.4f1 Personal
- Universal RP: 8.2.0 
- Visual Effect Graph: 8.2.0 

# Pcxのインポート

[keijiro / Pcx](https://github.com/keijiro/Pcx)というパッケージを使用するので、READMEに従ってUnityにインポートします。

# 点群データの作成

今回は[静岡県ポイントクラウドデータベース](https://pointcloud.pref.shizuoka.jp/)で提供されている点群データを使用させて頂きました。Pcxはbinary形式のplyファイルしか使用できないので、[CloudCompare](danielgm.net/cc/)などのソフトウェアでファイルフォーマットを変換します。その際に、必要であれば点群のマージや間引き、スケールの変更などもしておきます。

# 点群データのインポート
Unityに作成したplyファイルをインポートします。インポートすると最初はContainer TypeがMeshになっているので、Textureに変更してApplyボタンを押します。そうすると、VFX Graphで使用できる点群の位置と色を書き込んだテクスチャがそれぞれPosition Map、Color Mapという名前で生成されます。
![pc-vfx01PNG.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/65810cd3-1b00-2060-fdff-5c042e3d681d.png)

# VFX Graphでの表示

作成されたテクスチャを使用して単純にすべての点を表示するVFX Graphは以下のようになります。Single Burstで点群データに含まれる点の数だけパーティクルを作成して、Set Position from MapとSet Color from Mapで先ほど作成したテクスチャから位置と色をそれぞれ割り当てるようにしています。
![pc-vfx02PNG.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/3f34ee25-fbb7-de8f-2f01-37ebc20cb32f.png)

結果、以下のように点群データをUnityで表示することができました (浜松城です)。
![pc-vfx03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/edbca35a-0024-9ec1-f28d-1a81a2bc7d3c.png)

---

 【出典：静岡県ポイントクラウドデータベース】、[CCライセンス 表示 4.0 国際](https://creativecommons.org/licenses/by/4.0/legalcode.ja)
Arch LinuxでZoomにOBSの映像を配信する

# TL;DR

- Arch Linux上で仮想カメラデバイスを作成します．
- OBSで映像キャプチャや画面キャプチャを1つの映像に合成します．合成映像をOS上の仮想カメラに流します．
- 仮想カメラの映像をZoomのカメラデバイスとして設定し，配信します．
    - Zoomに限らず，DiscordやGoogle Meetなどのカメラ出力をする場合に利用できます．

# 準備

- Arch Linux（ubuntu等の他のディストリビューションでも可能です）
    - Windowsでは手順が異なります．
- OBS Studio
- Zoom（カメラ入力ができればなんでもよい）

# セットアップ

## 仮想カメラのセットアップ

v4l2loopbackを使って仮想カメラをセットアップします．
以下AURヘルパーであるyayを使ってインストール作業を行っています．他のディストリビューションではパッケージ名等が異なる可能性があります．

まず，以下のパッケージをインストールします．

```sh
$ yay -S v4l2loopback-dkms
```

標準カーネルを使っている場合はカーネルヘッダーファイルをインストールして，カーネルモジュールをコンパイルする必要があります．

```sh
$ yay -S linux-headers
```

v4l2loopbackモジュールを読み込みます．`video_nr=42`はデバイス番号を指定します．`exclusive_caps=1`を指定すると，Google Chrome等のブラウザ上で仮想カメラが認識されます．

```sh
sudo modprobe v4l2loopback video_nr=42 devices=1 exclusive_caps=1
```

モジュールが読み込めたら以下の手順で確認します．`video42`が作成されていればOKです．

```sh
$ ls /dev | grep video
video42

$ v4l2-ctl --list-devices
Dummy video device (0x0000) (platform:v4l2loopback-000):
	/dev/video42
```

### 設定の永続化

カーネルモジュールの読み込みを起動時に行いたい場合は設定ファイルに書き込んでおきます．

```conf:/etc/modprobe.d/v4l2loopback.conf
options v4l2loopback video_nr=42 devices=1 exclusive_caps=1
```

```conf:/etc/modules-load.d/modules.conf
v4l2loopback
```

## OBSのセットアップ

OBSをインストールします．また，OBSの映像をv4l2に流し込むためのプラグインもインストールします．
`obs-studio`はcommunity版もありますが，ブラウザ機能がないため，必要があればGit版をインストールします．詳細は[こちらの記事](https://qiita.com/roamer7038/items/b1dd76063a2593aa7cb1)を参照ください．

```sh
$ yay -S obs-studio obs-v4l2sink
```

プラグインがインストールされた状態でOBSを起動すると，メニューのツールタブ下に`v4l2sink`の選択肢が増えています．
設定を開くと以下のスクリーンショットのような画面が表示されるので，**Device Path**に`/dev/video42`を指定して，**Start**をクリックします．

![2020-10-09_152124_667388197.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405311/bc4d1847-ba41-e94c-e375-0bd0221ddce5.png)



## Zoomのセットアップ

Zoomを使って仮想カメラのテストをします．AURからインストールできます．

```sh
$ yay -S zoom
```

Zoomを起動して，適当にミーティングを開始します．
そのまま自分のカメラ映像を設定してもよいですが，今回は画面共有時に仮想カメラを指定して表示してみようと思います．
画面共有のウィンドウを選択する際に，**Advanced**のタブから**Content from 2nd Camera**を選択します．
他のカメラが接続されている場合は，左上に表示される**Switch Camera**をクリックして仮想カメラに切り替えます．

![2020-10-09_152459_389006401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405311/0cfe248b-0634-b9c7-c277-7e7dc1557776.png)

OBSの画面を流せるので，ソースやシーンを活用すれば通常の画面共有よりも高度なことができるようになるかと思います．

# 参考

- [Arch Linux上でZoom用の仮想カメラ/マイクを作る](https://blog.browniealice.net/post/zoom_virtual_cam_and_mic_on_arch/)
- [obs-v4l2sinkを使ってLinux上のOBS Studioで合成した映像をSkypeやZoomに流す](http://www.nofuture.tv/diary/20200413.html)
【Linux】psコマンドでCPU使用率を表示する、ヘッダーを表示する、grepのプロセスを表示しない方法

#概要
OS内部で現在実行されているプロセス一覧を表示するpsコマンドについて、
タイトルの3つの方法を調べたので、備忘の意味でまとめておく

#psコマンドでCPU使用率を表示する
ps　auxコマンドを使用する。%CPUの列の数値がCPU使用率を表示している

```
[oracle@user]$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.0  0.1  19400  1532 ?        Ss   18:37   0:00 /sbin/init
root         2  0.0  0.0      0     0 ?        S    18:37   0:00 [kthreadd]
```

CPU使用率の高い順にソートする場合は　
ps aux --sort -%cpu

```
[oracle@user]$ ps aux --sort -%cpu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      2248  1.2  2.4 113448 24728 tty1     Ss+  18:37   0:02 /usr/bin/Xorg :
oracle    2493  0.4  2.3 543792 23932 ?        S    18:38   0:00 nautilus
root         1  0.3  0.1  19400  1532 ?        Ss   18:37   0:00 /sbin/init
```

#ヘッダーを表示する
psコマンドの結果をgrepでソートすると、ヘッダーが表示されなくなってしまう。
head　-1　を追記することで、ヘッダーを表示する。

```
[oracle@user]$ ps aux | head -1 && ps aux | grep bash
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      2029  0.0  0.0 108212   900 ?        S    18:37   0:00 /bin/bash /usr/sbin/ksmtuned
oracle    2796  0.0  0.1 108352  1936 pts/0    Ss   18:38   0:00 /bin/bash
```

#grepのプロセスを表示しない
grepコマンドを使用したときに、[ ] 角括弧（かくかっこ）を利用して
grep自身がpsコマンドで出力されないようにする

```
#何もしないとgrep自身が表示される
[oracle@user]$ ps aux | grep bash
root      2029  0.0  0.0 108212   900 ?        S    18:37   0:00 /bin/bash /usr/sbin/ksmtuned
oracle    2796  0.0  0.1 108352  1936 pts/0    Ss   18:38   0:00 /bin/bash
oracle    2903  0.0  0.0 107500   892 pts/0    S+   18:48   0:00 grep bash

#角括弧をつけるとgrep自身は表示されなくなる
[oracle@user]$ ps aux | grep [b]ash
root      2029  0.0  0.0 108212   900 ?        S    18:37   0:00 /bin/bash /usr/sbin/ksmtuned
oracle    2796  0.0  0.1 108352  1936 pts/0    Ss   18:38   0:00 /bin/bash
```
【Ruby on Rails】RSpec実行時にgemのバージョン違いで警告を受ける。

## 前書き・編集点
2020.10.10
コメントより修正を行いました。

## 環境
Ruby 2.5.7
Rails 5.2.4

### gem
gem 'rspec-rails', '~> 3.6'

## 経緯
RSpecでテストコードを書いて、いざ実行すると、次のようなエラーが発生しました。

```
$ rspec spec/models/tag_spec.rb

WARN: Unresolved specs during Gem::Specification.reset:
      diff-lcs (< 2.0, >= 1.2.0)
WARN: Clearing out unresolved specs.
Please report a bug if this causes problems.
```

正確にはエラーではなく、同じgemで複数のバージョンがあるからそれの警告を受けているようで、テスト自体は無事に実行されていました。
しかし、放っておくわけにも行かないので、解決していきます。

## 手順
解決策はこちらの記事を参考にさせていただきました。
[Qiita - RubygemでWARN: Clearing out unresolved specs.が出た時の対応](https://qiita.com/seimiyajun/items/cc823452082a115fba07)

まずは問題のgemについて確認していきます。

```
$ diff-lcs (< 2.0, >= 1.2.0)
```

`diff-lcs`というgemのバージョンが複数あるという指摘でしたが、このgemは自分でインストールした覚えはないので、当然ながらGemfileには記載がありません。
となると、何らかのgemをインストールした時にbundlerが依存gemとして自動的にインストールした可能性があるので、`Gemfile.lock`を確認すると、rspecのgemの依存以外のところにも`diff-lcs (1.4.4)`がありました。

rspecでインストールされている依存gemは2箇所あって、どちらも`diff-lcs (>= 1.2.0, < 2.0)`という感じで、バージョンは書かれていないので、このgemのバージョンを次のコマンドで調べていきます。

```
$ gem list -a | grep diff-lcs

diff-lcs (1.4.4, 1.4.2, 1.3)
```

調べた結果、どうやら`(1.4.4, 1.4.2, 1.3)`３つのバージョンがインストールされているようです。
依存していない方の`diff-lsc (1.4.4)`がこの中で一番最新ということで、rspec依存の他二つをこのバージョンに合わせていきます。

ここで一つ注意ですが、bundlerで依存しているgemをインストールした場合、依存gemのバージョンを安易に変更してしまうと、依存関係にある他のgemに不具合が起きる可能性があります。
今回の場合だと、rspec依存の`diff-lcs (< 2.0, >= 1.2.0)`はバージョンが「1.2.0以上、2.0未満」と書かれてあったので(今回の中で)最新の1.4.4ならバージョンアップしても問題ないという結論に至りました。

次に参考サイトにも書かれてあるコマンドを実行していきます。

```
$ gem cleanup
```

そして

```
$ bundle install
```

これで警告文が消えました。

## 手順(依存関係でgemが複数バージョン必要な場合)
こちらコメントより抜粋させていただきます。

```
$ bundle exec rspec (実行ファイル指定)
```

を行うと、bundlerがGemfileに記述されている依存関係を自動的に認識してくれます。

依存関係が複雑になって、どうしても複数バージョンが必要な時は、前述した最新バージョンにまとめることはできないので、この方法しかなくなります。

## まとめ
私の場合は、これ以外にもう一つ警告文が出ていましたので、それについては次の記事をご覧いただければと思いますヽ(；▽；)ノ
[Qiita - 【Ruby on Rails】RSpec実行時にgem 'chromedriver-helper'は非推奨ですよって警告を受ける。](https://qiita.com/MasaoSasaki/items/8ead24ba685acbb3d6c0)

質問や解釈の違い、記述方法に違和感ありましたら、コメント等でご指摘いただけると幸いです。

最後まで読んでいただきありがとうございました。


## 参考サイト
私のGitHubに実際に使っているファイルを公開しているのでそちらも参考にしていただければと思います！
[GitHub - MasaoSasaki/matchi](https://github.com/MasaoSasaki/matchi)

その他
[Qiita - RubygemでWARN: Clearing out unresolved specs.が出た時の対応](https://qiita.com/seimiyajun/items/cc823452082a115fba07)
[YoheiIsokawa - 【Rails】Gemfileのバージョン指定の書き方](https://blog.yuhiisk.com/archive/2017/04/24/specify-the-version-of-gemfile.html)
csvをmongodbへupsertしたい人のためのコマンド

# mongodbへcsvをupsertしたい
そんな私みたいな人が居ると思いますので、コマンドを共有します。

#環境説明
**mondodbの環境は以下の通りです**
-DB名：api
-コレクション名 : macList

**コレクション**

```
{
    "name":"   ",
    "mac" :"   "
}
```

※IDが勝手に入ります。

**ファイル名**
file.csv

#コマンドは以下のとおりです

```
mongoimport --db=api--collection=macList --upsert --upsertFields=mac --type csv --file file.csv --headerline
```

**各オプション解説**
--db DB名
--collection コレクション名

--upsert アップサートでインポート
--upsertFields　アップサートの際に既存にあるか確認するフィールド名

--type 入力ファイル形式
--file 入力ファイル名
--headerline ヘッダ行の無視


よろしくおねがいします。
JODConverter+LibreOfficeの変換が遅いとお嘆きのあなたへ

JODConverter

- Apache OpenOfficeまたはLibreOfficeを利用してOffice系ファイルのフォーマットを変換するライブラリ
- Excel → PDFなど多様な変換が可能
- https://github.com/sbraconnier/jodconverter/wiki

---

　巷で見かけるサンプルコードは、次のような流れが多数となっている。しかし下記の処理を実行すると、外部プロセスとしてLibreOfficeを起動・終了するため、処理に時間がかかる。例えばWebアプリケーションの１リクエストごとに実行する処理としては、適切でない。

```java
OfficeManager officeManager = LocalOfficeManager.make();
officeManager.start();
// ・・・
// フォーマット変換（中略）
// ・・・
officeManager.stop();
```


　公式に推奨された方法としては、単一のOfficeManagerをWebアプリ起動時にstart()して、全リクエストで共有して、Webアプリ終了時にstop()する。
https://github.com/sbraconnier/jodconverter/wiki/Web-Application

---

　ExternalOfficeManagerもそれなりに有効かもしれない。

ExternalOfficeManager (JODConverter Local 4.3.0 API)
https://www.javadoc.io/static/org.jodconverter/jodconverter-local/4.3.0/org/jodconverter/local/office/ExternalOfficeManager.html

[1] 次のように引数を指定してLibreOfficeを起動しておく。

```
soffice.exe -accept="socket,host=127.0.0.1,port=2002;urp;"
```

[2] フォーマット変換時には ExternalOfficeManager を利用して、起動済みのLibreOfficeに接続する。この処理はそれなりに速く実行できる。

```java
OfficeManager officeManager = ExternalOfficeManager.make();
officeManager.start();
// 中略
officeManager.stop();
```

　ただし、Javadocに書いてある通り、LibreOfficeが異常終了しても、JODConverterはLibreOfficeを再起動しない。

> Since this implementation does not manage the Office process, it does not support auto-restarting the process if it exits unexpectedly.
Service Workerの大雑把な概要

サービスワーカーに対して調べたことで大まかに概要が把握できるものをさらっとまとめました。

# 概要
端的に言うとブラウザ上でバックグランドに処理を実行する機能
オフラインアプリの実装、サポートのために作られた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179800/df73d1e9-cd13-8515-0688-b7dc1f4fe644.png)

大まかな構成は上の通りで、
対応表はここを参照
https://caniuse.com/?search=service%20workers

# 状態
サービスワーカーはいくつかの状態を遷移して、対象のページを動作しようとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179800/1a9f54f1-10f8-1667-b136-0c6afb1582e4.png)

googleより引用

## register

serviceWorker のファイルを登録する。

```javascript
 navigator.serviceWorker.register('/service-worker.js');
```

この登録関数にswファイルを指定すると、その階層のページがserviceWorkerの制御対象になる
そして、実際にswのファイルがダウンロードされる。

## install 
クライアント制御のためのリソースを取得したり、キャッシュしたりするイベント
ブラウザはこのinstallのイベントが成功 or 失敗を検知でき、失敗の場合はserviceworkerを破棄する


## activate 
installが終わり、実際にswがページを制御下に置いた状態。これでpush や syncといった処理を扱える様になる。
ただし、初期読み込みの場合はactivateまで行かず、二回目以降の読み込みでactivateまで到達する
activate時にclients.claim()をすれば、１度目のinstallでも制御下における。


## fetch 
[** fetch]
他ページへの遷移やリロードが行われる時に、呼び出されるイベント。
ここで、リクエストを確認して、キャッシュにヒットするものがあればそれを返す。なければfetch結果を返す

## 制約・特徴
* Worker独自のコンテキスト(スコープ)で動く
    * メインスレッド(javascript)とは違うスレッドで動作するのでDOMにアクセスできない
* 完全なノンブロッキング且つ非同期の処理になる
    * 結果としてXHRのような同期処理やLocalStorageは使えない,
        * ただ fetch　関数は使える。

# 活用法
* fetchイベントを活用して、APIのリクエストをキャッシュする。キャッシュが古ければAPIを投げ、新しければキャッシュ内容を活用してページを表示する。
* pushイベントを活用して、push通知を行う。service workerは独自のAPIのエンドポイントのような物を生成し、そのAPIに対してリクエストするとpushイベントが発火、そこで、通知処理(スマホに通知が来たと表示する)をすれば擬似的なpush通知ができる。

# 終わりに
相当、雑にまとめましたが、メインスレッドとは別に独自のライフサイクルで動き、そのライフサイクルで発生するイベントに処理を登録することで、色々できると言うのが大きな強みだと感じました。
【Python】xlsbで保存されているEXCELファイルを、xlsxに変える方法

#これは何か
なぜかEXCELファイルをxlsbという形式で保存しており(しかも3年分とか！)、その形式ではBIツールに読み込ませられたなかったので、「手で一つ一つ形式変えて保存しないといけないの…？」と絶望したので、Pythonでできるか調べました。Qiitaにはあまり情報なかったので、メモします。

#結論
Pyxlsbライブラリで、できました。

#スクリプト
```python
import pandas as pd
import pyxlsb

import_file='sample.xlsb' #読み込みファイルの場所
sheet= 'sheet1' #読み込みファイルのシート名
export_file='sample.xlsx' #ファイルの吐き出し先
df_read = pd.read_excel(import_file,sheet,engine='pyxlsb') #xlsbファイルの読み込み
df_read.to_excel(export_file) #xlsxで保存
```

#参考
[XLSBファイルをPandas Python](https://www.it-swarm-ja.tech/ja/python/xlsb%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92pandas-python/833269674/)
Symbol from NEMのトランザクションをパースする

Symbol from NEM で実装されるアグリゲートトランザクションによって、ブロックチェーンは信用と信用の途切れ目を無くし、さらに複雑な用途に使用できるようになります。


ただ、一つのトランザクションの内部に複数のトランザクションを詰め込むこという設計のため、そのトランザクションを解析するには注意が必要です。

今回は、アグリゲートトランザクションを他の一般のトランザクションと同列に解析する方法を説明します。

#### 事前準備
まず、いつものようにChromeのコンソールをF12で開いてスクリプトを読み込みます。

```js
NODE = 'https://sym-test.opening-line.jp:3001';
GENERATION_HASH = '6C1B92391CCB41C96478471C2634C111D9E989DECD66130C0430B5B8D20117CD';

(script = document.createElement('script')).src = 'https://xembook.github.io/nem2-browserify/symbol-sdk-pack-0.21.0.js';
document.getElementsByTagName('head')[0].appendChild(script);
```

##### 必要なライブラリのインポート

```js
nem = require("/node_modules/symbol-sdk");
rxjs = require("/node_modules/rxjs");

txHttp  = new nem.TransactionHttp(NODE);
```


#### 解析function

これが今回の要となる解析用の関数です。

```js

function parseTxs(txs){

    for(tx of txs){

        //アグリゲートトランザクション判定
        if(tx.type === nem.TransactionType.AGGREGATE_COMPLETE 
        || tx.type === nem.TransactionType.AGGREGATE_BONDED){

            //アグリゲートの場合、内部トランザクションを再取得
            txHttp.getTransaction(

                tx.transactionInfo.hash,
                nem.TransactionGroup.Confirmed

            ).subscribe(tx =>{

                console.log("== aggregateTx ==")
                //この関数を再帰的に呼び出し
                parseTxs(tx.innerTransactions);  //再帰呼び出し
                console.log("-----------------")
            });
        }else {
            //ここに解析する処理を記述します。
            console.log(tx);
        }
    }
}
```

解析ファンクションはトランザクションを配列で受け取ります。
for ループで1件ずつトランザクションを取り出し、処理していきます。
TransactionTypeがアグリゲートトランザクションでなければそのままコンソール出力して次の処理へうつります。
アグリゲートトランザクションだった場合はinnerTransactionsの中をさらに再帰的に同じ関数で処理させます。
ここで注意点としては、REST APIでトランザクションをリストで取得した場合、innerTransactionsの情報が入っていません。なので、リストで一つずつ取り出したトランザクションがアグリゲートトランザクションだった場合は、そのHASH値をキーにinnerTransactions情報も含む全情報を取り直す必要があります。innerTransactionsが取れればその関数の内部から同じ関数を呼び出せば再帰的に処理していくことができます。

#### 呼び出しプログラム

上記解析関数を呼び出すプログラム例です。

```js

txHttp.search({

//  type:[
//      nem.TransactionType.AGGREGATE_COMPLETE,
//      nem.TransactionType.AGGREGATE_BONDED
//  ],
    order:nem.Order.Desc,
    group:nem.TransactionGroup.Confirmed

})
.subscribe(
    page => parseTxs(page.data)
)

```
最新の承認済みトランザクションを新しいもの順に抽出します。
コメントアウトしている部分は検索条件としてアグリゲートトランザクションだけに絞り込みます。
検索結果はページングされているので、parseTxs関数へは内部のdata部分のみを渡します。

これで以下のように、普通のトランザクションとアグリゲートトランザクションを同列に解析することができるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/e98e17a8-5b9e-7a9c-e2b0-8072d4892fab.png)

ぜひ、お試しください。
【JavaScript】ホイスティングとは？

はじめまして！Qiita初投稿になります。
最近JavaScriptの勉強を始めました。
折角なので学習したことをアウトプットしていきたいと思います。
基本的な内容が多いですが、私と同じ初学者方の参考になれば幸いです。

また至らない点がありましたら、ご指摘いただけると嬉しいです。

今回はJavaScriptを勉強中に、**ホイスティング**という耳慣れない用語が登場したので調べて見ました。

#ホイスティングとは
**変数や関数の定義をコードが実行される前にメモリに配置する挙動**のことを指します。
その挙動から「宣言の巻き上げ」とも言われます。

言葉ではイメージしづらいので早速コードを見ていきましょう。

###関数のホイスティング

```js

f(); //f関数を実行

function f(){
    console.log("Hoisting Test"); // Hoisting Test
}
```

こちらのコードですが、一見すると実行文が関数の定義より前にあり、エラーになりそうですが問題なく動作しています。

これはホイスティングによって**コードが実行される前に関数の定義がメモリに配置されているため**、実行することができています。

これがホイスティングによる動きになります。

続いて変数のホイスティングを見てみましょう。

###varを使った場合

```js
console.log(x); // undefined

var x = 0; // 変数xの宣言
```

今度は変数xの宣言よりも前にconsole.logでxの値を取得しています。
こちらも一見エラーになりそうですが、undefinedが出力されます。

変数も関数同様、ホイスティングによってコード実行前に変数xのメモリを確保しているので、console.logで問題なく参照することができています。

注意点としては、行っているのはメモリの確保のみで、値は代入されていないので中身はundefined（未定義）となります。
undefinedは値が未定義の場合に自動で代入されるキーワードになります。

イメージとしては以下になります。

```js
// 事前に変数xのメモリ確保とundefinedの代入を行ってからコードを実行！

console.log(x); // 空の中身を出力。

var x = 0; // 0を代入。
```

var変数ではこういった処理がコード実行前に行われるため、エラーが発生することなく変数の値を出力することができます。


###let、const場合

```js
console.log(x); // ReferenceError

let x = 0;
```

```js
console.log(x); // ReferenceError

const x = 0;
```

let、const変数の場合は、
**[Uncaught ReferenceError: Cannot access 'x' before initialization]**
というエラーメッセージが表示されます。

これは**変数xに値が値が入っていませんよ（初期化されていない）**というエラーです。

どういうことかと言うと、let、constではvarのように自動でundefinedが代入されません。
よって、メモリ確保はされているので参照することはできますが、変数の値を取得しようとしてもエラーが発生することになります。

個人的にエラーがでてくれた方が安心感があります。

ということで、**varとlet、constではホイスティングの挙動が異なるということになります。**

###予期せぬエラー
さて、関数や変数のホイスティングの動きを見てきましたが、この挙動を理解していないと意図していない値の取得、エラーの原因となります。

例えば、以下のコードを見てみましょう。

```js
let x = 10; //グローバルスコープの変数x。

{
    console.log(x); // グローバルスコープの変数xを取得したい。でもエラー
    
    let x = 0; //後からブロックスコープで変数xを宣言。
}
```
**グローバルスコープで宣言した変数xの値をブロックスコープ内で取得したい時**、誤って後から同名の変数xをブロックスコープで宣言してしまうと、ReferenceErrorが発生してしまいます。

ホイスティングはスコープごとに発生するのですが、今回はブロックスコープ内で宣言した変数xがホイスティングにより、中身が無い状態でブロックスコープの最初に定義されるため、参照されるのはブロックスコープの変数xとなります。

そしてletの中身は空なので、値を出力しようとしてもReferenceErrorになるわけです。

**イメージとしては以下になります。**

```js
let x = 10; //グローバルスコープの変数x。

{
    // x 中身が無い変数xがここにある。

    console.log(x); // 上の空のxを参照する。
    
    let x = 0; //ここで初めて値が入る
}
```
この場合、グローバル変数xの値を取得するには、ブロックスコープの変数名を変更してあげれば良いのですが、慣れないうちは予期せずこういったエラーに遭遇するかもしれません。

ホイスティングの動きを理解していれば冷静に対処できそうです。


##まとめ
ホイスティングについて記述しました。ホイスティングによって変数や関数の定義が事前にメモリに配置されるということになります。慣れないうちはホイスティングによる挙動を意識してコードを記述していきたいと思います。

至らない点がありましたら、ご指摘いただけると嬉しいです。


##参考
https://developer.mozilla.org/ja/docs/Glossary/Hoisting
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var
Sequel ProでMySQL8.0へ接続できない方へMySQL Workbenchのススメ

# 概要
　MySQL8.0をインストール後、Sequel Proで接続できない場合の対処法としてMySQL Workbenchを使用する。

# 環境
`macOS` : Catalina 10.15.7
`MySQL` : 8.0.12

# 問題点
Sequel ProでMySQL8.0に接続しようとした場合、認証プラグインの関係でアプリ側が対応しておらず接続できない状況が発生します。
![Screen Shot 2020-10-09 at 17.50.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566213/c2857805-0395-ad98-86bc-94fdbdd67e82.png)
認証プラグイン自体を変更することで従来通りにSequel Proで接続することも可能ですが、それでは安全性が下がってしまいます。

# 解決策
代替案としてMySQL8.0に対応しているアプリ`MySQL Workbench`を使用することで、認証プラグインの変更を回避して接続できます。
macの場合、下記コマンドでインストールできます。
`$ brew cask install mysqlworkbench`

`Sequel Pro`と`MySQL Workbench`のメリット・デメリットについて知りたい方は、[Sequel Pro vs MySQL Workbench vs TablePlus](https://tableplus.com/blog/2018/10/sequel-pro-vs-mysql-workbench-vs-tableplus.html)に詳しくまとめられています。

# まとめ
認証プラグインの変更をしたくない方は、アプリを変えるだけで簡単に接続できるようになるので使用を検討してみてはいかがでしょうか。

# 参考
[Sequel ProでMySQLにログインできない](https://qiita.com/yusuke_dev/items/7f0ca12ced72363f9448)
raid6でデバイスを1個追加してパーティションの拡張を忘れてrebootしたら事故った（解決）

前回↓
https://qiita.com/soybean/items/4ae0da04ae80bda1b0b9

前回raid6で7枚のSSDで組んだが、手狭になったので1台追加した。

前回と同じくmdadm で--addしたまではよかったが、

```
sudo resize2fs /dev/md127
```
をし忘れた。

その後、再起動すると...

```
sudo mdadm -D /dev/md127  
/dev/md127:
           Version : 1.2
        Raid Level : raid0
     Total Devices : 7
       Persistence : Superblock is persistent

             State : inactive
   Working Devices : 7

              Name : wstat000001:127  (local to host wstat000001)
              UUID : dd6b134e:d2c168ca:31070d48:452c4b38
            Events : 33526

    Number   Major   Minor   RaidDevice

       -       8       64        -        /dev/sde
       -       8       32        -        /dev/sdc
       -       8        0        -        /dev/sda
       -       8      112        -        /dev/sdh
       -       8       80        -        /dev/sdf
       -       8       48        -        /dev/sdd
       -       8       96        -        /dev/sdg

```

無事死亡していました。inactiveです。
sdjというのが見当たりませんので、8デバイスのはずが7デバイスにとどまっていて1個足りません。
とりあえず、mdadmを止めます

```
sudo mdadm --stop /dev/md127
```
そして、手動で再構成

```
sudo mdadm --assemble --force /dev/md127 /dev/sda /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh   
```

そうしたら、全てのデバイスが認識されたので、あとは

```
sudo mdadm --add /dev/md127 /dev/sdj
```
として、追加したssdをraidグループに放り込み、リカバリーを開始

```
md127 : active raid6 sdj1[8] sda[0] sdh[7] sdg[6] sdf[5] sde[4] sdd[2](F) sdc[1]
      5860196352 blocks super 1.2 level 6, 512k chunk, algorithm 2 [8/6] [UU_UUUU_]
      [==>..................]  recovery = 12.4% (121730060/976699392) finish=78.4min speed=181585K/sec
      bitmap: 5/8 pages [20KB], 65536KB chunk

unused devices: <none>
```

最後に、忘れずにパーティションの拡張

```
sudo resize2fs /dev/md127
```
【復習】RailsでWebアプリを作っている時にsyntax error, unexpected ')', expecting => ...]}%", "%#{params[:content]}%"]) ...

どうもshirakabaです。

今回はRailsの復習をしていきたいと思います。

以前オンラインスクールで作っていた作品を消してしまったので、もう一度復習も兼ねて作っていこうと思っています。

とはいっても今回書く内容は、アプリを作っていく過程で出たエラーを解決したよっ！ていうことを書いていきたいと思います。

余談なんですが、ずっと別のことに追われていて、自分の大切なことや本来の目的などや楽しかったことなどを忘れていたので、もう一度原点に戻ってそのタスクと、プログラミングの学習並行で行いながらやっていきたいと思います！

もう好き勝手学んでいきますよ！

※注意点
未経験で、今は独学で勉強中の初心者です。
あくまで学習したことをアウトプットする目的で書いております。
ですので、間違いなどがあるかと思いますが、その際は生暖かい目で見ていただければ幸いです。

#解決したこと
##何をしようとしたか？
検索機能を作成しようとしてコントローラーにsearchアクションを作ろうと以下の記述をしたところ下記エラーが出てしまいました。

```
def search
  if params[:content].present?
     @book = Book.where(user_id: current_user.id,['title LIKE ? OR author LIKE ? OR label LIKE ?',"%#{params[:content]}%", "%#{params[:content]}%", "%#{params[:content]}%"])
  else
    @book = Book.none
  end
end
```
##エラー文
URLにアクセスするといつものエラー画面が...
```SyntaxError
syntax error, unexpected ')', expecting => ...]}%", "%#{params[:content]}%"]) ... ^
@book = Book.where(user_id: current_user.id,['title LIKE ? OR author LIKE ? OR label LIKE ?',"%#{params[:content]}%", "%#{params[:content]}%", "%#{params[:content]}%"])
```
ターミナルだと
```SyntaxError (/ファルダ名/フォルダ名/controllers/books_controller.rb:6: syntax error, unexpected ')', expecting =>
...]}%", "%#{params[:content]}%"])
...                              ^
):
```

##解決方法
結論から言うと`where`を二つにしてつなげて書くことで解決しました。

```
@book = Book.where(user_id: current_user.id).where('title LIKE ? OR author LIKE ? OR label LIKE ?',"%#{params[:content]}%", "%#{params[:content]}%", "%#{params[:content]}%")
```
今回記述ミスによりエラーではありましたが、なかなか見つけるに苦労してしまいました...
ちゃんと原因を調べて落ち着いて考えればこんなにも時間がかかることはなかったかもしれないです。

復習とはいえ、まだまだ修行が足りないことを痛感させれられます。
それに、これ自体綺麗な書き方ではないのかもしれないので、もっとちゃんと調べようと思います。

##最後に
今後はどんな些細なことでも、恥ずかしいことでもこうやってアウトプットして行けたらいいなと思っています。
それでは〜
【FileMaker】「げんきかな？チェック」アプリ解説 1  - 概要と画面遷移

4月に作って解説記事を続けて書こうとしていて、その他の仕事などで追われていて、出すのを忘れていた「げんきかな？チェック」アプリの解説シリーズです。
このアプリは、新型コロナウィルスが蔓延し、主要都市に緊急事態宣言が出されてどうにもままならない（私生活が）事態に陥り、コロナ禍前も引きこもって仕事していたのにさらに引きこもっていたのでiPadのサンプルアプリとして作ったものです。

![スクリーンショット 2020-10-09 15.21.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/df3eb16b-8cf1-7737-3829-4bd07b9d6d63.png)


# なんで作ろうとしたのか
何かしら重大なイベントが発生すると、世の中では情報にたどり着けない・自分の状態をどこにも発信できない人が必ず出てきます。
まずは自分の状態をしっかりと記録しておき、いざという時にせめて記録した自分の状態を出せるようにしておければ病院にかかった時もアプリを医師等に見せれば苦しい状況でも状態をわかってもらえるかな？と思いました。
そして、単純に市販のメモ書き程度のアプリに記録してもいいのですが、IT業界の片隅から愛を叫んでみました。

# 要件として何が必要か
・どうせなら巣篭もりしている家族単位で記録できるもの
・ひらがなが読める子であれば操作できるもの
・1人1人の状態を確認できること
・パッと見て自分の症状がどのくらい危険なのかがわかること
・使う人のお金を使わないこと（アプリの課金など無しで）
というお題（要件）を元に作り始めました。

# 必要な画面
以下の３つのカテゴリの画面があれば、要件を満たせそうでした。
・誰の情報を記録するかを登録・設定する画面
・症状を記録する画面
・集計する画面

# 開発期間
最初のβバージョンができるまで、1,2日だったと思います。
その後、FileMakerに精通している方々や近所の友達・子供に声をかけ、アプリを検証してもらいました。
それと、出典元の確認やイラスト使用許諾などの問い合わせを並行して行い、ここまでで3,4日くらいでしょうか。
微調整をして、構想から5日くらいで[guthub](https://github.com/atsukosekiguchi/FileMakerSample/blob/master/COVID19check.fmp12)で公開しました。
twitterなどでもアナウンスしましたが、どうせなら、と自屋号のHPで[紹介の記事](https://guppywebservice.info/?p=273)を書きました。

# 開発環境
開発当時の最新バージョン、[Claris FileMaker Pro](https://www.claris.com/ja/filemaker/) 18 AdvancedをMacOSで開発しています。
検証はiPadの[Claris FileMaker Go](https://www.claris.com/ja/filemaker/go/) 18です。
※この記事を執筆段階のバージョンは、19に上がっています

特に難しい最新技術は使っていませんが、サンプルを使用する際はバージョン18以上でよろしくお願いします。


# 画面遷移
おおよその画面遷移です。
青線：処理進行
赤線：戻る系
![画面遷移図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/b90d79af-0dd7-a2f7-9328-dc418e5fca89.png)

とにかく操作に迷わないように、と思い、余計な機能は極力省きました。
画面は、
チェック前に、チェックする人の情報の設定
↓
症状のチェック
↓
結果の表示
↓
集計リストで複数日の集計を確認
という流れです。

プラス、最初の画面に戻れるようにしました。
途中でやめたい時にやめれて、また最初からできるようになっていると使い勝手がよさそうです。
それと、むやみやたらにアプリ外のホームページなどに飛ばないようにしました。
アプリを離れると、「いったいどこに連れて行かれるんだ？」とドキッとしますよね。

画面遷移図では画面をはめ込んでいますが、最初は四角で構成していました。
手書きでババっと書いてもいいのですが、最近はアイディアを出す段階から、[cacoo](https://cacoo.com)を使っています。

まずは、紹介がてらの、画面遷移でした。
画像フォーマット：EPSをSVGに変換する

## モチベーション

論文等でLaTeXで原稿を書く際、画像ファイルはEPS,JPG,PNGを使うことが多いと思います。特に実験データのグラフなどはベクター画像形式であるEPSを用いることになります。

ところでこのEPSというフォーマットは、HTML中のimgタグでパスを記述してもWebブラウザでは表示できません。Web技術全盛の昨今ではいささか使いにくいと感じます。

個人的にも、LaTeXフォーマットの執筆がやりにくいので、代わりにMarkdownで原稿執筆するエディタを作ったりしました[^1]。レンダリングはHTML+Javascript+CSSで行い、Electronでアプリとして固めました。しかしEPS画像は表示できないのは論文執筆には不便です。

ブラウザで表示させるためにJPGやPNGに変換しても良いですが、ベクター系式ではなくなってしまいます。
変換するならベクター形式であるSVGが良いだろうということで、方法を模索したのでここで紹介します。

## 方法 EPS → PDF → SVG

Latex環境一式とGhost Script(GS)をインストールします[^2]。
場合によりPerlも必要です。私の場合はWindows環境だったのでstrawberryperlをインスコしました。

Latex環境の中に入っている`epstopdf`コマンドを使って、EPSからPDFへ変換します。続いて、`pdftocairo`コマンドを使ってPDFからSVGへ変換します。実際には次のようなコマンドになります

```
epstopdf hoge.eps hoge.pdf
pdftocairo -svg hoge.pdf
```

上手く行けば`hoge.svg`というファイル名でSVGファイルが作成されると思います。


## Note 1
GSは32bitと64bitの設定が混在しているとerrorになります。環境変数のpathでtexのbinとGSのbinが共に64bitになっているか確認しましょう。

## Note 2
他の方法として`pstoedit`も試しましたが、上手く行きませんでした。


[^1]: [NowType](https://atsushi-m-ito.github.io/nowtype/)
webpackのdistとsrcフォルダの違い。dist配下のファイルはいつ作成されるか

webpackのdistとsrcが実際の操作でどう使われるかについて。

webpackで作成したプロジェクトの基本構造は下記。

```
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
  |- main.js
  |- index.html
|- /src
  |- index.js
|- /node_modules
```

distとsrcが存在する。
・distは配信用(distribution)。本番環境で実際にブラウザに表示されるもの。

・srcは編集用(source)。プログラムを記述する。



##serveとbuild
ここからが本題。
一般的にpackage.jsonに以下のような記述がある。

```js:package.json
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "serve": "webpack-dev-server --config webpack.config.js --open"
  },
```

オプションで細かい設定がしてあるのは無視して、buildとserve(またはstart)。

buildをするとファイルをリロードして、serveするとlocalhostのブラウザが立ち上がるんだ〜。程度の軽い理解だったが、もう少し踏み込む必要がある。


###・`npm run serve`
serveを実行すると、localhostが立ち上がる。つまり、**開発環境が立ち上がる**。

この時、ブラウザに表示される画面は**src内のファイルを使用**している。

**distは関係なく。serveを実行しても配信用のファイルを自動生成しない**。


<br>
###・`npm run build`
**buildを実行するとsrcのファイルを元に、dist配下に配信用のファイルを生成する**。

つまり、**buildは本番環境の構築**となる。



<br>
##まとめ

| alias | 内容 | 使用するファイル |
|:-:|:-:|:-:|
| serve(or start)  | 開発環境の起動 | src  |
| build  | 本番環境用ファイルの作成  | src -> dist |
繋がりの多い議員はどんな政策態度を持っている？

James H. Fowler大先生がHarvard Dataverseでデータを公開してくれているので遊んでみました。
論文はこの2つ。
>Legislative Cosponsorship Networks in the U.S. House and Senate, James H. Fowler, Social Networks 28 (4): 454-465 (October 2006) https://doi.org/10.1016/j.socnet.2005.11.003

>Connecting the Congress: A Study of Cosponsorship Networks, James H. Fowler, Political Analysis 14 (4): 456-487 (Fall 2006) https://www.jstor.org/stable/25791871

データは[ここ](https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/JMZS8E)から入手できます。

#何をするかというと
要するに、アメリカ議会に提出される法案の共同提出者名簿を使って、議員同士がどのように「つながっているか」を調べたものです。

このデータセットさんは非常に優秀なので、各議員のNOMINATEスコアが付されていたりします。NOMINATEというのは各議員の持っている政策的立場を二次元にまとめたものと思ってしまった大丈夫だと思います。
このスコアが正の数なら保守的、負の数ならリベラルと言われたりしますね()


今回はこいつらを使って「他の議員よく繋がっている議員はどんな政策的立場をとる傾向にあるか」を調べます。さっそくアメリカ議会下院のNOMINATE第１次元をみてみましょう。


#実際にやってみる

```r
fit.dim1.H.dem <- list()
chmbr <- "H"
for(i in c(93:107)){ #93議会から107議会までの
  con <- i
  net <- NET %>%
  filter(congress==con, chamber==chmbr, party==100) #第i議会下院の民主党議員(party=100)を抽出
  fit.dim1.H.dem[[i-92]] <- lm(ideol1 ~ connectedness, data = net) 
  #NOMINATEスコア第１次元を中心性で単回帰
}
```
要は、アメリカ議会下院で93議会から107議会までの間において、共同提出者になっている回数の増加は政策的立場をどの程度変化させるのかをまとめたリストを作成しています。

これを議会会期毎にプロットしていきます。

```r
df.dem <- matrix(NA, length(fit.dim1.H.dem), ncol(fit.dim1.H.gop))
for (j in c(1:length(fit.dim1.H.dem))) {
  df.dem[j,] <- fit.dim1.H.dem[[j]]$coefficients
}
plot(c(93:107), df.dem[,2], xlab = x, ylab = y, main = ttl)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712546/36a8748e-8f0c-7c37-0d33-356b31602cc9.png)

民主党議員の場合、中心性が高いほどNOMINATE第１次元が負の数になりやすい傾向があることがわかります。Poole & Rsenthal (2006)によれば第１次元は保守/リベラル軸で、数値が-1に近づくほどリベラルなことになっているので中心性が民主党議員で中心性が高い人たちは点呼投票でよりリベラルな政策的立場を取りやすいことがわかります。

共和党議員についても見てみましょう。やってることはさっきと同じです。

```r
fit.dim1.H.gop <- list()
chmbr <- "H" #下院を抜き出す
for(i in c(93:107)){
  con <- i
  net <- NET %>%
  filter(congress==con, chamber==chmbr, party==200)#第i議会下院の共和党議員(party=200)を抽出
  fit.dim1.H.gop[[i-92]] <- lm(ideol1 ~ connectedness, data = net)
}
summary(fit.dim1.H.gop[[1]])

df.gop <- matrix(NA, length(fit.dim1.H.gop), ncol(fit.dim1.H.gop))
for (j in c(1:length(fit.dim1.H.gop))) { #各会期の回帰結果をデータフレームにまとめる
  df.gop[j,] <- fit.dim1.H.gop[[j]]$coefficients
}
colnames(df.gop) <- names(fit.dim1.H.gop[[1]]$coefficients) 
plot(c(93:107), df.gop[,2], xlab = x, ylab = y, main = ttl, type = "l")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712546/f0b1b110-6614-f081-fef1-a8a6b26ad293.png)

共和党議員について見てみるとちょっと面白いことがわかります。
回帰した推定値を議会期の推移で見てみると、中心性が大きくなる場合、政策的立場のスコアを押し下げる効果が見て取れる年が多いのです。推定値0のところに赤線を引っ張って見ましたが、ほとんどの時期でスコアを引き下げる効果が見られます。

データセットがある93議会以降は次第に議会における分極化が進んでいった時期でもあるので、両党のNOMINATEスコアは比較的凝集性が高くなっていっており、民主党議員はスコアが負の数に、共和党議員は正の数になる傾向があります。それでもなお、両党議員においてスコアを引き下げる効果が観測されるとすると、中心性の増加は民主党議員の場合、政策的立場が極端になることを、共和党議員の場合は政策的立場が比較的穏健になることを意味するのかもしれないですね。
integer型がmigrateされないよぉ

#integer型がmigrateされない（devise導入後）


      t.string  :surname ,null: false, default: ""
      t.string  :surname_kana, null: false, default: ""
      t.string  :firstname, null: false, default: ""
      t.string  :firstname_kana, null: false, default: ""      
####下記が入るとマイグレートできない。。（共通点はint型）

      t.integer :gender_id ,null:false,default: ""
      t.integer :age ,null:false,default: ""

##解決法

      t.integer :gender_id 
      t.integer :age 

###null-falseやめました、、
書籍「考える練習帳」まとめ

「[考える練習帳](https://www.amazon.co.jp/dp/4478100977)」を読んで自分なりに腑に落ちたところをまとめてみた。
![考える練習帳](https://rimg.bookwalker.jp/9585172/frDGCemG5kX9EBY8IrbThQ__.jpg)

#なぜ自分の頭で考えることが大切なのか
「自分の頭で考える」ことの対極にあるのが「他人の意見にむやみに従う」ことだからである。なぜ「他人の意見にむやみに従う」ことは良くないのだろうか？理由のひとつ目は、悪意をもって人を騙そうとする人間がいるからである。例えば〇〇詐欺といった類である。「他人の意見にむやみに従う」ことはそういった詐欺にひっかかりやすくなる。理由のふたつ目は、（こちらが最も問題だが） **他人が悪意をもたずに発信している意見・情報** を鵜吞みにしてしまう危険性がある、ということである。では悪意をもたずに発信している意見・情報とはどういった性質のものか、その理解には「無知の知」という概念を知る必要がある。

#「無知の知」とは
哲学の父と呼ばれるソクラテスは「無知の知」という考えかたを基本とした。「無知の知」とは「自分がいかにものを知らないのかを知っている（自覚している）こと」である。これが自分の頭で考えることの第一歩となる。逆に「無知の無知」とは「自分はなんでも知っていると思い込んでいること」である。例えば酔っ払いが「まだまだ酔っていないから運転は大丈夫」というのが「無知の無知」、「もう酔ってしまったので運転なんかできない」というのが「無知の知」である。先ほどの**他人が悪意をもたずに発信している意見・情報**というのも発信者が自分の無知に気づかずに自分の立場や状況による一方的な情報を発信していることが往々にしてある。そのため鵜吞みにせずに自分の頭で考えることが大切となる。

# 自分の頭で考えるヒント
この本には「自分の頭で考える」ヒントがたくさんある。以下に有益そうなのをピックアップした。

+ 意見・情報を鵜呑みにするのではなく、**なぜ？それは何？本当に？**を常に自分に問う。
+ 身の回りの「自己矛盾」をチェックしてみる。（自己矛盾の例：「多様性を認めないのは絶対におかしい」という意見。「他人の意見に左右されるな」というアドバイス。など…）
+ すぐにネットで調べない。まず自分で考えて仮説を立ててからネットで調べてみる。
+ ある常識（意見・情報）が1000年前のアフリカ（なじみの薄いエリアならどこでも）でも通用するか想像してみる。（常識の例として、例えば「知識は"ちしき"と読む」というのは正しいか？これは **日本語でなら** という前提が存在する。）
+ 思考の世界では確実な正解・不正解はない。すべてはグレーですべては「前提条件次第」である、ということを意識する。

# 参考サイト
自分の頭で考える、参考になりそうなサイト。

「自分の頭で考えること」を学ぶ
https://www.ki1tos.com/entry/2020/04/14/174739

自分の頭で「考える」人と「考えない」人
https://bobisummer.com/reading-thinking-training-hosoya-10/