OmniAICreator/Qiita-1.07M huggingface dataset:
Gatsby 2.24.2 が何故か動かない

# 内容まとめ

`gatsby develop`で以下のエラーが出て動かない

```bash
Error: EBADF: bad file descriptor, uv_pipe_open
    at Object._forkChild (child_process.js:122:5)
    at setupChildProcessIpcChannel (internal/bootstrap/pre_execution.js:329:30)
    at prepareMainThreadExecution (internal/bootstrap/pre_execution.js:54:3)
    at internal/main/run_main_module.js:7:1 {
  errno: -4083,
  code: 'EBADF',
  syscall: 'uv_pipe_open'
}

```

# 環境

- win10
- node 14.4.0
- npm 6.14.5

# gatsby-cliのインストール

```bash

$ npm i -g gatsby-cli
```

バージョンの確認

```bash
$ gatsby --version
Gatsby CLI version: 2.12.60
```


# 新規サイトの作成

```bash
$ gatsby new gatsby-site
```

# ローカルサーバーの立ち上げ

以下のエラーでストップする

```bash
$ cd ./gatsby-site
$ gatsby develop

child_process.js:122
  p.open(fd);
    ^

Error: EBADF: bad file descriptor, uv_pipe_open
    at Object._forkChild (child_process.js:122:5)
    at setupChildProcessIpcChannel (internal/bootstrap/pre_execution.js:329:30)
    at prepareMainThreadExecution (internal/bootstrap/pre_execution.js:54:3)
    at internal/main/run_main_module.js:7:1 {
  errno: -4083,
  code: 'EBADF',
  syscall: 'uv_pipe_open'
}
```

BuildコマンドやServeコマンドは実行可能

```bash
$ gatsby build
$ gatsby serve
```

# 解決方法

- 直接の原因が分からなかった
- 同じPCで動いている別のGatsbyサイトがあった

上記から、ひとまずパッケージのバージョンを合わせることで解決

```json
...
"dependencies": {
    "gatsby": "^2.24.2", -> "^2.20.12"
    "react": "^16.13.1", -> "^16.12.0"
    "react-dom": "^16.13.1" -> "^16.12.0"
},
"devDependencies": {
    "prettier": "2.0.5" -> "2.0.4"
},
...
```
アクセスが多いテーブルのカラムを安全に変更（削除やリネーム）する方法【Rails,heroku】

# 概要

これはアクセスの多いテーブルのカラムを変更したときに、
カラムを新しく変更したはずなのに、なぜかコードは（すでに存在しない）古いカラムを参照してしまい、エラーが発生してしまう問題を解決するための方法を記したものです。


# ２０２４/０２/２９ 追記、結論「ignored columnを使う」

ごめんなさい。こっちを参照してください。

https://tech.prog-8.com/entry/2020/12/08/093310


## 前提条件
Rails 5.1
heroku

## 解決策１「heroku restart」

先日、自分のカラム の英語の命名ミスに気づき、
AnswerHistoryテーブルのweekly_continuationというカラムを、continuation_all_weekに変更しました。

その後、カラム変更に伴うコードも変更してデプロイし、
`heroku run rails db:migrate`したのですが、その後しばらくSentryより、以下の報告を繰り返し繰り返し受け続けました。

>PG::UndefinedColumn: ERROR:  column answer_histories.weekly_continuation does not exist

つまり、**DBのカラム名はきちんと変更されているにも関わらず、コードは古いカラム名を参照し続けている**ということです。

僕は最初この警告を、一時的な不具合だとばかり思っており、無視していました。
「ユーザーがページを遷移したり更新すれば直るやろ」と。
しかし、自分の端末でも同じ問題が起こり、かつページを遷移しても更新しても解決しなかったとき、これがサービス運営者が解決すべき障害だと気づきました。
（それもこの障害は、自分のサービスの中でももっともアクセスが多いページで起きていました....無念....）

結局このときは、**heroku restart**を行うことで障害を解決することができました。

「なぜheroku restartで障害を解決できたのか？」
解決しておきながら、自分はその理由がわかりませんでした。

よりベテランの開発者の方にこのことを聞くと、
どうやら、`heroku run rails db:migrate` する直前にデプロイされたとき、Railsのアプリケーションサーバーがschema informationのキャッシュを持ってしまっていたがために、アプリケーションサーバーを再起動してキャッシュを消す必要がありました。
heroku restartすることでdynoが再起動したので、アプリケーションサーバーのschema informationも新しくなり障害が解決したということでした。

なので、もし教科書的に、
`git push heroku` 
`heroku run rails db:migrate`
を行いカラムを変更する場合には、
追加で`heroku restart` もしておくことで、
heroku のdynoと一緒に、アプリケーションサーバーも再起動されるおかげで、schema informationのキャッシュもクリアされるので、コードがきちんと新しいカラムを参照してくれるようになります。


## 解決策２「Procfileからリリース時にdb:migrateを行う」

今回の障害で初めて知ったのですが、
herokuではProcfileなるものを設定することで、
`heroku run rails db:migrate` のようなコマンドをリリース時に自動で実行してくれるようになります。
参照： https://devcenter.heroku.com/articles/release-phase

このProcfileでdb:migrateを行うメリットとしては、「デプロイした後」ではなく**「デプロイ直前」にdb:migrateしてくれる**という点です。
herokuではデプロイ時に、自動で真新しい別のDynoを立ててくれます。
そして真新しいDynoはheroku restartされた状態と同じなため、
新しいDynoにあるアプリケーションサーバーはschema informationのキャッシュをもつこともなく、結果として、heroku restartせずとも、カラムの変更によるアプリケーションのエラーに見舞われることがないそうです。

ただしエラーが起きないのは、新しいDynoにアクセスしてきたユーザーのみで、古いDynoにアクセスしていたユーザーは、エラーに見舞われます。

Procfileからデプロイ直前に自動でdb:migrateまで行うには、次のように設定します。

```ruby:Procfile
release: bin/rails db:migrate
```


## 解決策３『段階的にデプロイする』

より安全にカラムを変更するときに、実務においては段階的にデプロイする手法が採用されているそうです。

db:migrateを伴うリリースだけ先にデプロイし、本番環境でdb:migrateを行ってから、
別のタイミングで、変更したカラムを利用するソースコードをリリースするという形です。

たとえば今回のように、AnswerHistoryのweekly_continuationをcontinuation_all_weekにリネームする場合には、次のように３回のデプロイします。


>1, continuation_all_weekカラムを新しく追加するmigrationファイルを作成。
>2, デプロイ＆db:migrate。
>3, weekly_continuationカラムではなく、continuation_all_weekカラムを参照するように、コードを変更する
>4, デプロイ＆weekly_continuationのデータをcontinuation_all_weekにコピー。
>5, weekly_continuationがコードから呼ばれていない状態にする。
>6, weekly_continuationカラムを削除するmigrationファイルを作成。
>7, デプロイ＆db:migrate。

端的にまとめると、
テーブルへのアクセスが多い場合は、古いカラムをリネームするのではなく、新しいカラムを追加して、コードが古いカラムを参照しない状態をつくった後に、古いカラムを削除することで「リネームしたように見せること」が良い、ということらしいです。
　
面倒かもしれませんが、いちばん安全な方法ですね。
　
呼ばれる頻度の低いテーブルのカラムなら、これほど気を使わなくても良いかもしれませんが、
今回僕が障害を発生させたAnswerHistoryテーブルは、1日に1万件以上も生成されるほど利用頻度の高いものだったので、以降、カラムのリネームなどを行う場合は、こちらの段階的なデプロイを採用したいと思います。


以上となります！
僕は恐ろしく無知なので、他にもアドバイスなどございましたら、ぜひ教えてください。



### 宣伝
障害を起こしてしまった弊英単語学習サービスです。

https://www.diqt.net/
[WinForms(unsafe)] USBカメラの列挙

```CS
public unsafe void ListDevices()
{
    AVFormatContext* camera;
    AVDictionary* option = null;

    ffmpeg.av_log_set_level(ffmpeg.AV_LOG_VERBOSE);
    av_log_set_callback_callback logCallback = (p0, level, format, vl) =>
    {
        if (level > ffmpeg.av_log_get_level()) return;

        var lineSize = 1024;
        var lineBuffer = stackalloc byte[lineSize];
        var printPrefix = 1;
        ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix);
        var line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer);
        Console.Write(line);
    };
    ffmpeg.av_log_set_callback(logCallback);

    ffmpeg.avdevice_register_all();
    ffmpeg.av_dict_set(&option, "list_devices", "true", 0);
    ffmpeg.avformat_open_input(&camera, null, ffmpeg.av_find_input_format("dshow"), &option);
}
```

[FFmpeg.AutoGen @Ruslan-B](https://github.com/Ruslan-B/FFmpeg.AutoGen)
mariaDBが起動しなくなった　～　からの復帰の記録

＜環境＞
Windows ServerにmariaDBをインストールしてあり、イントラネット（Wifi）でつないだ数台のクライアントPCで運用している
mariaDBのバージョンは10.4
Windows Serverのバージョンは2020年3月時点で最新のもの

＜状況＞
週末の豪雨の際に停電があったらしい
（サーバーは電源ＯＮのまま、ただし、特に作業はしておらず、単につけっぱなしだった）
週明けにクライアントPCを起動したら「サーバーに接続できない」のエラーが出た

サーバーPC上でサービスを見ると、mariaDBは停止している
起動を試みても起動できない

ネットでいろいろ調べたところ「ログファイルを見よ」「.errファイルを見よ」「mariaDBを再インストールせよ」など、いくつか見つかりましたが、具体的にそのまま同じ解決法になりそうなものは見つからなかったので（再インストールは避けたかった）、ログファイル、.errファイルを探しました。

mariaDBのフォルダを見ていたら、"mariaDB"フォルダの直下に"サーバー名.err"というファイルがあったので、これをメモ帳で開いて見てみました。

で、下の方、当日の記録を探したら、

↑　前日のログ
Cannot find checkpoint record at LSN (1,0x7464)
2020-07-14  7:43:58 0 [ERROR] mysqld: Aria recovery failed. Please run aria_chk -r on all Aria tables and delete all aria_log.######## files
2020-07-14  7:43:58 0 [ERROR] Plugin 'Aria' init function returned error.
2020-07-14  7:43:58 0 [ERROR] Plugin 'Aria' registration as a STORAGE ENGINE failed.

<中略・・・この部分は[ERROR]ではなく、全て[Note]＞

2020-07-14  7:44:05 0 [ERROR] Could not open mysql.plugin table. Some plugins may be not loaded
2020-07-14  7:44:05 0 [ERROR] Failed to initialize plugins.
2020-07-14  7:44:05 0 [ERROR] Aborting
↓　以後、同じことの繰り返し（何回も起動チャレンジしたから）

こんな感じの部分を発見
（7月14日がトラブル発生の当日です）

[ERROR]の1行目に"aria_chk -r"を実行して下さいとありますので、同ファイルを探して、コマンドプロンプトでファイルがあるフォルダに移動してから実行

それと、おなじ行の続きで"aria_log.########"を消すように指示されていましたので、これを探して（サーバー名.errと同じくmariaDB直下にありました）、一つだけだけ見つけたので（"aria_log.00000001"でした）それを削除

それで、無事に復帰できました。



というわけで、まとめ
"mariaDB直下のサーバー名.errというファイルをメモ帳で開いて読んで、言われた通りにしたら復帰できました"

次に停電になったときのための覚書として、こちらに残しておきます
「母数」という単語の誤用と由来、他の漢字文化圏について

> ぼ すう ［2］【母数】
①推計学で、母集団の特性を表す値。
②歩合算で、元金をいう語。
③媒介変数のこと。助変数。パラメーター。
出典： 三省堂 大辞林 第三版
https://www.weblio.jp/content/%E6%AF%8D%E6%95%B0


「母数」という単語は、よく「集団の総数（サンプルサイズ）」や「分母」の意味で使われますが、この使い方は誤用とされています。
母数とは、統計学等での「母集団の特性を表す値」のことです。

<details>
例えば[正規分布](https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E5%88%86%E5%B8%83)においては
![スクリーンショット 2020-07-15 15.59.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54305/c72a3116-e10c-5e76-7468-2ad285f41d61.png)
の $\mu$や$\sigma^2$の部分のことを母数といいます。
_このあたりについて、詳しくは[Wikipedia](https://ja.wikipedia.org/wiki/%E6%AF%8D%E6%95%B0)を参考にしてもらうことにしてあまり突っ込んだ説明をしないことにします。_

</details>

[この記事](https://taroyabuki.github.io/2018/01/15/misuse-of-the-word-parameter/)によれば、一部の古い国語辞典でも母数の説明が「分母のこと」「統計学で，母集団の数」のように間違った説明になっているものもあるそうで、母数の誤用問題が相当根深いことがわかります。



自分も間違えて使っていました……
![63021ca2-6d8f-4f0d-b78a-76f05e44615a-960x261r.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54305/a21bf486-df36-b135-d0c7-f439fc482497.png)


---

母数は英語でいうと `parameter` で、 `para-` は「〜の側の」を表す接頭辞、 `meter` は「測定」を表す接尾語であり、すなわち 「（数式の）外側から与えられる数」というのが `parameter` の語源です。

Wiktionaryによる解説：

- https://ja.wiktionary.org/wiki/para-
- https://ja.wiktionary.org/wiki/-meter

Googleによる解説：

![e9b330de-5e96-4128-ad2d-3c7055f5f3ea-960x757r.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54305/12709f3e-c104-db6c-f746-4ba65a7809d2.png)


母数の「母」の部分は英語の `para-` の部分から来ているようで、「外側から与えられた」の意味だったようなのですが、日本語で「母」という漢字を見ると「分母」や「母集団」といった「全体」を表す単語に見えてしまい、「集団の総数（サンプルサイズ）」や「分母」のような誤用が広まってしまったようです。

---

他の漢字文化圏でも同様の問題が起こっていないか、見てみます。

中国語では「参数(cānshù)」と書くようです。こちらのほうが100倍わかりやすいですね。

- 
https://zh.wikipedia.org/wiki/%E5%8F%82%E6%95%B0%E7%BB%9F%E8%AE%A1
- https://cjjc.weblio.jp/content/%E5%8F%82%E6%95%B0

日本語も、いまからでもparameterのことを「参数」と呼べば、誤用のない平和な世界が訪れそうな気がします。

- 「さんすう」と読むと「算数」と同音なので、読むときは「まいりすう」とでも読めば良さそう。

---

韓国語では「모수」(mosu, モス)、漢字表記だと「母数」で日本語と全く同じです。
日韓で同じ漢字表記なので、どちらかがどちらかの表現を借用したっぽい感じがします。（調べてない）
韓国だと日本と同様に「サンプルサイズ」の意味で「모수」が誤用されていたりするのでしょうか？

- 韓国語の모수は「母数」と、「[毛遂](https://ja.wikipedia.org/wiki/%E6%AF%9B%E9%81%82)（中国史に登場する人物）」の同音異義語のため、「모수 유래(母数 由来)」でググると毛遂の情報しか出てこない。
- namu.wiki では「모집단(population)의 수（母集団の数）」となっており、日本語と同じ誤用が説明されている気がする。
  - https://namu.wiki/w/%EB%AA%A8%EC%88%98
      - でもその下の「통계학에서 모 평균, 모 표준 편차, 모 분산 등 모집단의 데이터를 말한다.」は正しい説明になってるな……
  - 「표본조사」（標本調査）のページでは、日本語の母数(parameter)と同じ定義で正しく모수が使われている。
    - https://namu.wiki/w/%ED%91%9C%EB%B3%B8%EC%A1%B0%EC%82%AC

---

昨今は master/slave => primary/replica とか blacklist/whitelist => allowlist/blocklist 等の[ポリティカルコレクトネス言い換えが流行っており](https://gigazine.net/news/20200615-replace-master-slave-blacklist/)、母数も「母」というジェンダーみのある漢字が入っていることから、ポリコレの波に飲まれて言い換えが必要にならないか心配になってきました。
いや、もっとわかりやすい語が当たるならそれでもいいんですが……



---

というわけで、「母数」と「分母、サンプルサイズ」は正しく使い分けていきましょう。
また、同僚が母数を誤用しているのを見つけても「分母、サンプルサイズ」の意味だと察してあげるようにしましょう。
🍰【CakePHP2】Controllerで動的に一時テーブルを作成し使用する方法

## 環境
PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27

## やりたいこと

テンポラリテーブルを使いたい

## やったこと

ModelをuseTable = falseで用意してControllerでテーブル作成しセット

### Model
```TemporaryTable.php
<?php

App::uses('AppModel', 'Model');

class TemporaryTable extends AppModel
{
    public $useTable    = false;
    public $primaryKey  = '';
    public $useDbConfig = '';

    function setSource($tableName) {
        $this->setDataSource($this->useDbConfig);
        $db = ConnectionManager::getDataSource($this->useDbConfig);
        $db->cacheSources = ($this->cacheSources && $db->cacheSources);

        $this->table = $this->useTable = $tableName;
        $this->tableToModel[$this->table] = $this->alias;
        $this->schema();
    }
}

```

### Controller
```HogeController.php
<?php

class HogeController extends AppController {
    public function index() {
        // TEMPORARY TABLE名
        $tempTableName = 'temporary_table';
        // database.phpのDBconfigをModelに設定
        $this->TemporaryTable->useDbConfig = 'admin';
        // TEMPORARY TABLEを作成
        $this->TemporaryTable->query('CREATE TEMPORARY TABLE ' . $tempTableName . ' (id INT(11), name VARCHAR(256));');
        // 作成したTEMPORARY TABLE名をModelに設定
        $this->TemporaryTable->useTable = $tempTableName;

        // 先ずfindしてみる -> result:array(0)
        $data = $this->TemporaryTable->find('all');

        // テストデータをsaveする
        $testData = [
            'id'   => '1',
            'name' => '_test',
        ];
        $this->TemporaryTable->create();
        $this->TemporaryTable->save($testData);
        // テストデータ2をsaveする
        $testData2 = [
            'id'   => '2',
            'name' => 'test_test',
        ];
        $this->TemporaryTable->create();
        $this->TemporaryTable->save($testData2);
        // 再度find -> result:array(2)
        $data = $this->TemporaryTable->find('all');
        var_dump($data);
        /* find結果
            Array
            (
                [0] => Array
                    (
                        [TemporaryTable] => Array
                            (
                                [id] => 1
                                [name] => _test
                            )
                    )
                [1] => Array
                    (
                        [TemporaryTable] => Array
                            (
                                [id] => 2
                                [name] => test_test
                            )
                    )
            )
        */
    }
}
```
CircleCi expected type: String, found: Mapping エラー workflow でハマったときの対処方法

circleci の設定で4時間溶かしたので供養。

## エラー内容

```bash
Error: ERROR IN CONFIG FILE:
[#/workflows/dev_workflow] only 1 subschema matches out of 2
1. [#/workflows/dev_workflow/jobs/1] 0 subschemas matched instead of one
|   1. [#/workflows/dev_workflow/jobs/1] expected type: String, found: Mapping
|   |   SCHEMA:
|   |     type: string
|   |   INPUT:
|   |     e2e: null
|   |     requires:
|   |     - build_front
|   2. [#/workflows/dev_workflow/jobs/1/requires] expected type: Mapping, found: Sequence
|   |   SCHEMA:
|   |     type: object
|   |   INPUT:
|   |     - build_front

```

## 対処方法
job名の後のインデントは 2タブ（4スペース）
解決のヒントになったのは [yaml to json](https://onlineyamltools.com/convert-yaml-to-json) でJSONの形が想定の値になっているか確認することができます。
頭の中で想定した構造と実際のオブジェクト構造の差分で問題が解消しました。

```yaml
version: 2.1
jobs:
  # 割愛
workflows:
  version: 2
  dev_workflow:
    jobs:
      - build_front
      - e2e:
          requires: # ← ここのインデントはジョブ名に2回インデント(4スペース)
            - build_front

    # - e2e: # error case
    #   requires:
    #     - build_front

```
MavenでKotlinPluginを作ろう！

はいどうもこんにちは～
メックです。
今日は私のGradleがばちこーん逝かれてしまったのでMavenでKotlinPluginを作るべく自分の備忘録＆これからMavenで書きたいという人のために手順などを書いていこうかなと思います。

#いつものごとくプロジェクト作成からいくよん
ちゅーわけで早速作っていこう！
**これは基本中の基本なのでしっかり覚えておくように！**
テストにでるよ！！！（※でません。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/7c530363-ef22-060e-6c1b-c4c82a97d148.png)
最近はPaperServerが主要になってきてるので今回からPaperPluginを作っていきますよ～！https://papermc.io/downloads
ちなみにPaperServerのjarファイルはここで配布されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/e1e150ae-9f2d-763f-c5cb-4845701b967b.png)
ここは上の写真のように設定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/10db1f02-ca6b-5920-d2c0-260361c8b2ae.png)
いつものごとくここは設定しなくていいよん

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/4b862e6d-adc4-5342-3bb3-ed8da09ce722.png)
まあこんな感じにしてね。
何回か作っていくと徐々に理解していくから今のうちは慎重に調べながらやっていこう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/e221dda9-b9f0-b25d-36f5-c3588134d592.png)
はい。プロジェクトはできましたね！
、、、、、、　え？　これJavaじゃね？
( ´ﾟдﾟ｀)ｴｰ　ま～じ～？？？　Kotlinで作るって言ったのにJavaじゃねえかよ！詐欺ったなこのMECのクソ野郎！！！
って思ったそこのあなた。　ちょっとまったぁぁぁ！！！
ここからKotlinで書くためにpom.xmlというファイルを書き換えるのです。

でぇ～は早速やっていこう！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/764fc5eb-6181-c46d-b390-72ea9a17c223.png)
まずはpom.xmlを開いてね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/2547a011-9d39-6f1b-5cbc-408069e99297.png)
そしたらわけのわからん長ったらしい文字の羅列が出てくるけど大丈夫！
コピペをするだけでいいからね！！！

https://github.com/Chiharu-Hagihara/MavenKotlinTemplate
このgithubのリポジトリのなかからpom.xmlを開いてね。
そしたら14行目に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/2cd14b77-c750-a08a-820b-8bca783724c5.png)
こんなことが書かれてると思うんだ。
その通りにその下の行から一番下までをコピーしてね。
ちなみにショートカットキーはCtrl + C

じゃ次はIntelliJに戻って・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/5b6923a9-1edc-925a-5a39-482158c64f21.png)
14行目から下までを選択してペーストしてね。

そしたらPaperHelloWorld.javaに戻って、
Ctrl + Alt + Shift + Kを押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/b099feff-334b-94de-1aa3-972463775378.png)
こうなって
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/eb252e5c-d9a8-f5dc-234b-67cb06ea5077.png)
「はい」を押してね。
するとなんということでしょうぅぅぅ！！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545700/584a4c7a-4186-1af7-1798-c670323b0700.png)
なんかJavaのコードとは一味違う感じになりました！！

これでKotlinを書くための設定は完了です。

あとは自分の思い通りに書いていきましょう。

ちなみに
https://github.com/Chiharu-Hagihara/MavenKotlinTemplate
このリポジトリにはテンプレとなるようなコードが乗ってるのでまずはこれを実行できるように頑張ってみるのもありかもしれません。
ぜひ頑張ってみてください！

今回はここまで！
今回はネタ要素を結構盛り込んだので楽しんで読んでいただけると幸いです。
次はなににしようかな・・・

(T_T)/~~~　（ばいばい～）
sedで特殊な記号を置換・削除

ディレクトリを変更したのでファイル内の環境変数もすべて変更したい。

```test.sh
../../${dir}/file1.txt
../../${dir}/file2.txt
../../${dir}/file3.txt
../../${dir}/file4.txt
../../${dir}/file5.txt
```

↓

```test.sh
../file1.txt
../file2.txt
../file3.txt
../file4.txt
../file5.txt
```
こうしたい

つまり
**../${dir}/**
の部分を削除したい時。



成功したものが以下のコマンド

```sh:

sed -i s@'../${dir}/'@@g test.sh
```

<BR>
<BR>
---

**解説**


検索するとよく出てくるsedの構文は以下の通り
（これがあとあと苦労する原因）

```sh:
sed 's/置換したい文字列/置換後の文字列/g' 入力ファイル名
```
gは入力ファイル中の文字列すべてを置換という意味。


<BR>

オプションを追加

```sh:
sed -i 's/置換したい文字列/置換後の文字列/g' 入力ファイル名
```

-iオプションを使うことでパイプ＆catをしなくてもファイルを上書きできる。

今回は何度も失敗したので-iオプションの後に".org"を追加。

```sh:
sed -i".org" 's/置換したい文字列/置換後の文字列/g' 入力ファイル名
```
これでtest.sh.orgが作成され、バックアップが取れる。

<BR>

さて、本題の特殊記号の置換だ。
とりあえず以下を実行してみた。

```sh:
sed -i".org" 's/../${dir}///g' test.sh
```
>sed: -e expression #1, char 13: unknown option to `s'

エラーが出る。
スラッシュが問題のようだ。

ならば置換したい文字列を''で囲ってみる。

```sh:
sed -i".org" 's/'../${dir}/'//g' test.sh
```
>sed: -e expression #1, char 7: unknown option to `s'

調べてみると、文字列中に「/（スラッシュ）」がある場合は
sedのスラッシュを違う記号に変えるとよいらしい。
今回は「@」を使用したが、「:」や「*」、「#」など、
文字列中に使用していない記号なら何でもよいらしい。

```sh:
sed -i".org" 's@'../${dir}/'@@g' test.sh
```


<BR>
エラーが出てこなかったのでviで確認すると

```test.sh
${difile1.txt
${difile2.txt
${difile3.txt
${difile4.txt
${difile5.txt
```
なんじゃこりゃ・・・

```test.sh.org
../../${dir}/file1.txt
../../${dir}/file2.txt
../../${dir}/file3.txt
../../${dir}/file4.txt
../../${dir}/file5.txt
```
バックアップを取っておいてよかった。

```
mv test.sh.org test.sh
```

<BR>

色々試すも、全部だめ

```sh:
sed -i".org" "s@'../${dir}/'@@g" test.sh
sed -i".org" "s@../${dir}/@@g" test.sh
```


試行錯誤したが、どうやらsedコマンド自体のスラッシュがいらない模様。

```sh:
sed -i".org" s@../${dir}/@@g test.sh
```

文字列はちゃんと囲めってことか
<BR><BR>

```sh:
sed -i".org" s@'../${dir}/'@@g test.sh
```

成功しました。
<BR>
クォーテーションの意味をちゃんと考えなくてはと思った一件でした。
Laravel バージョン確認コマンド

#はじめに
これは初心者エンジニアがフルスタックエンジニアを目指すための備忘録である

#Laravelバージョン確認コマンド

```
php artisan --version
```
または

```
php artisan -V
```
のどちらかです。

```
php artisan -v

// これが出たらOK！

Laravel Framework 5.8.38 

//←投稿者：現在のバージョン
```

以上です。
ターミナルでrailsサーバーを切らずに起こった「A server is already running...」の対処法

ローカルのVisual Studio Codeのターミナルをいじっていた時、PCの不具合で強制終了しました。

その後もう一度Railsサーバーを立ち上げたところ、

` A server is already running. `

と出てきました。


サーバーが稼働時の正常なシャットダウンは「ctrl + C」でOKですが、このケースだとこのコマンドを実行しても何も反応が有りませんでした。


ここでの対処法は２つあり、

1.`kill -9 $(lsof -i tcp:3000 -t)`を実行
2.PCを再起動


私は1.を選択して、とりあえずサーバー接続を白紙にすることが出来ました。



##　補足（localhost:3000にアクセスできない問題）

「あぁとりあえず安心」と思って再度サーバーを接続したら、


yuichi kanban % rails s
=> Booting Puma
=> Rails 5.2.4.3 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.6 (ruby 2.6.6-p146), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

と出てくるものの、ブラウザで`localhost:3000`を検索しても読み込まれませんでした。


こういった場合は上記の対処法に似ていますが、Visual Studio Codeを一旦閉じて再度起こしたら、無事にYay!You're on Rails!が表示されました。


詰まったときには再起動すれば解決することが多いと思うので試してみてください。（適当）
機械学習を用いた株価予測 [データ入手編]

# はじめに
どうにか工夫して、Deep Learningを使った株価予測をやってみたいと考えてこの記事を書くことにしました。
この記事では、株価予測に使うデータを「yahoo finance」からプログラムでダウンロードしてくることを目的に書いています。

ちなみに、どういったモデルで株価を予測するのかについてはまだ未定で、これから考えて行きたいと思っています。いいアイディアがやオススメの手法がある方は教えていただけるとありがたいです。

では、やっていきたいと思います。

# 対象データ
今回の入手先は、「yahoo finance」です。
対象は、[カブサポ](https://kabusapo.com/stock-data/stock-list/)から上場銘柄一覧のcsvファイルがダウンロードできるので、その中の東証一部に絞ってデータを取ってきたいと思います。

ダウンロードできる期間は、2010〜現在までです。

# コード
```stock_data.py
import requests
import io
import re
import pandas as pd

cols = ['Id', 'Date', 'Open', 'High', 'Low', 'Close', 'Adj_Close', 'Volume']
stock_data = pd.DataFrame(columns=cols)

code_list = pd.read_csv('stock_code_list.csv') # カブサポから入手したファイル
code_list = code_list[code_list['市場名'] == '東証1部']['銘柄コード']

for code in code_list:
    url = 'https://query1.finance.yahoo.com/v7/finance/download/{}.T?period1=1262304000&period2=1589241600&interval=1d&events=history'.format(code)
    res = requests.get(url)
    
    if res.status_code != 200:
        print('NotFound:', code)
        
    else:
        stock = pd.read_csv(io.StringIO(res.text))
        stock['Id'] = code
        stock_data = pd.concat([stock_data, stock], ignore_index=True, sort=False, keys=cols)
        print('OK:', code)
```

これで、ダウンロードできました。
データサイズは約500万行ありました。

# おわりに
これでデータを入手できたので、次は予測アプローチを考えて行きたいと思います。
個人的には、ただ翌日の株価が上がるか下がるかとかではなく、もっと個人投資家向けに
上昇トレンドや下降トレンドを検知するようなプログラムができたらなと考えています。
また、定性データも加えられたら精度も上がるかもと考えています。

いいアイディアがあればください、、、

こんな感じで、ちょこちょこ書いていきたいと思います。

[次回記事：機械学習を用いた株価予測 [システム概要編]](https://qiita.com/askl4267/items/22de400efd361ce82dba)
Railsで学ぶXSS脆弱性

webセキュリティについて勉強中なので、学習内容を公開します
スカスカ記事ですがお許しください

#演習環境
- Ubuntu 18.04.4
- Ruby (2.6.6)
- Rails (5.2.4.3)
    - database adapter mysql2 (0.5.3)
- mysql (5.7.30)

記事投稿、コメント投稿、ブックマークなどが出来る演習用アプリ「TARGET」
GitHubリポジトリ https://github.com/Fumitaka1/target

#XSS脆弱性とは
XSSには反射型、持続型、DOMベースの３タイプに分類され、単にXSSというと反射型XSSを指すことが多いようです。

上記の３タイプに共通する性質として「外部からのパラメータを用いてwebページを出力しているアプリケーションにおいて、任意のhtml要素や属性が挿入出来てしまう」所がXSS脆弱性の肝です。

挿入されたスクリプトによってセッションや入力データが流出したり、有害な操作やリダイレクトが可能になるなど多くの被害が発生します。

例　演習用アプリでは投稿にコメントする機能があります
![正規のコメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496557/ebc94266-c95a-aabd-b475-abc3940e75f3.png)

スクリプトタグを含む不正なコメントを投稿すると、ブラウザはスクリプトタグとして解釈します。
![悪意のコメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496557/74a3c72f-d71e-af4c-e002-9b4d86072aec.png)
![攻撃成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496557/d1ac7095-b048-8382-4716-e60bc0c8397f.png)
演習用アプリではRailsの機能によりcookieのHttponly属性が付与されているので、Javascriptでセッションを取得することはできません。
しかし任意のページにリダイレクトしたり、不正なフォームをもとのページに重ねて表示することが出来ます。

#なぜ発生するのか
上記の例では外部からのパラメータを用いてHTML要素内容を出力する際に、特殊文字[" ' & < >]をエスケープしていないことが原因。
等号記号が２つのERB式```<%== @comment.content %>```で意図的にエスケープを回避している。

XSS脆弱性が発生しうる箇所には①HTML属性値②HTML要素内容③リンク④イベントハンドラなどがあり、それぞれエスケープの方法が異なるので場所にあったエスケープを行う必要がある。
各々のエスケープ方法については後日記事にします。
The GET method is not supported for this route. Supported methods: POST.のエラー

忘れっぽすぎるのでメモるぞ。

#####createからconfirmに遷移する時にこのエラーが出るぽよぴえん；；

```
The GET method is not supported for this route. Supported methods: POST.
```

バリデーションに引っかかって、内部でエラーを返すときにGET送信されているから
このエラーが出る！バリデーションに引っかからないようにしような〜〜！
PHP『include()』と『require()』違い

##『include()』と『require()』の違い
ファイルの読み込みに失敗した場合の処理に違いがあって、
『include()』の場合はファイルの読み込みに失敗しても『include()』の
処理部分だけ中止してその先に続く記述は処理が実行される。

逆に『require()』ではファイルの読み込みに失敗した場合はその場ですぐエラーとなり、
その先の記述を含めて処理が停止される。
MacportsでEmacs25を入れる

# MacportsのEmacsをEmacs25にする

``macports``では、採用される``emacs``のバージョンが26になってからか日本語のインライン入力の挙動が変わってしまい、強烈に違和感があり耐えられなかったので、inlineパッチのあたった最後のバージョン(Emacs25)に戻して使っているののでその手順メモ。

```tcsh:作業手順
% mkdir ~/tmp/build/macports_work
% cd ~/tmp/build/macports_work/
% git clone --single-branch https://github.com/macports/macports-ports.git
% cd macports-ports/
% git checkout fa86a353853f961712db15f64457a0f28320853a
% cd editors/emacs
% port -v install subport=emacs-app +imagemagick +multicolor_font +rsvg
```

``git checkout``で指定するバージョンは、ログで調べた。
【Rails】本番環境でも開発環境と同じようにエラー画面を確認する方法【デプロイ】


#### 【経緯】
本番環境だと、ローカル環境のようなエラー画面が出ないため、エラーが特定しにくいものです。と思っていたのですが、本番環境でもエラー画面を出力する方法がありました。この方法を行うことでエラー解決がグッと近くなります！


#### 【バージョンやら環境】
Rails 5.2.4.3
Ruby 2.5.1
macOS Catalina 10.15.4
Capistrano 3.14.1 


#### 【前提】
Capistranoが動く（Capistranoの自動デプロイが成功している）


#### 【解決法】




```ruby:config/environments/production.rb
config.consider_all_requests_local = false
```

を

```ruby:config/environments/production.rb
config.consider_all_requests_local = true
```

にしましょう。こうすると、本番環境でも開発環境（ローカル）と同じエラー画面が出ます。

おなじみのこいつです。（参考画像）
<img width="812" alt="error.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603198/65489110-e20c-3933-4738-e6194fb899ac.png">

（ただし、最終的にfalseに戻すのを忘れないようにしましょう。
一般の方や企業の方が本番環境を見た時にエラー画面が出たら変ですからね💦）


<br>
この後、

①Githubのプッシュ（最新の状態に）

②デプロイを行う。（ローカルで直してもデプロイしないと意味がないので！）

```ruby:ターミナル（アプリのディレクトリにて）

bundle exec cap production deploy
```
#### 【一部参考にしたサイト】
[Railsガイド：Rails アプリケーションを設定する](https://railsguides.jp/configuring.html)

#### 【あとがき】

デプロイの作業は地道ですね。
成功した時の喜びはかなり大きい。
がんばれデプロイ担当者（いつもいってる）
babel-polyfillと@babel/polyfillの違いってなんだ？備忘録

### 背景
Bugsnagで`オブジェクトは 'finally' プロパティまたはメソッドをサポートしていません`とエラーが吐かれることから調査をしていた。どうやら`new Promise.finally()`がIE非対応なことに起因しているようである。[MDN - Promise.prototype.finally()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally)

そこで、package.jsonを確認してみると、以下のようになっていた。
<img width="523" alt="スクリーンショット_2020-07-15_14_47_25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252687/42e36940-57cd-8383-f387-6c13ba3bc50e.png">
 
 - babel-polyfillは入っているじゃないか
 - 最後のアップデートは3年前って化石プロジェクトか？w

普段あまり関わらないプロジェクトなので、たまに触りにくると、こういうものを見つけたりする。


さて、ここである疑問が浮かんだ。

`babel-polyfill`と`@babel/polyfill`の違いってなんだ？

### 調べて見た

`babel-polyfill`とググっても、結果としてヒットするのは`@babel/polyfill`のほうだ。

同じものなのか？と思って、`yarn upgrade babel-polyfill --latest`とやってみるも、更新されない。（*後から考えるとそりゃそうだってツッコミたくなるが、スルーしてください）

[Babelのバージョン一覧](https://babeljs.io/versions)を確認してみる
<img width="197" alt="スクリーンショット 2020-07-15 15.11.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252687/7993db93-7149-3e22-3791-5f0d893871f5.png">

どうやら同じである。ということは、メジャーアップデートの際に何かしら変更があったのか？

ということで、[Babel 7 Released](
https://babeljs.io/blog/2018/08/27/7.0.0)を記事を読んでみた。そして下の方にスクロールすると...

あった。これか

[Major Breaking Change](https://babeljs.io/blog/2018/08/27/7.0.0#major-breaking-changes)
>Move us to the @babel namespace by switching to using "scoped" packages (details). This helps differentiate official packages, so babel-core becomes @babel/core (and no squatting)


なるほど、バージョンが7.0.0になった時に、名前空間が変わったようだ。これが影響して、`--latest`をつけただけでは単純にパッケージが`@babel/polyfill`に切り替わらなかったのである。

### 結論
 - 同じパッケージであるが、バージョン7.0.0をきっかけに名前空間が変わっている
 - パッケージの更新をするには、改めて`yarn add -D @babel/polyfill`をしたのち、`yarn remove babel-polyfill`となる。

*ただし、Babel7.4.0から@babel/polyfillは非推奨になっているので、ご了承ください
=> [Babel7.4で非推奨になったbabel/polyfillの代替手段と設定方法](https://aloerina01.github.io/blog/2019-06-21-1)
【Rails】Capybaraを使った統合テスト（導入〜簡単なテスト実行まで）

## はじめに
統合テストとはアプリ上で意図したとおりの動作をしてくれるかを確認するテストのことです。
ブラウザ上で自分で行なっても良いですが、テストコードを書くことで大きなメリットがあるのでできれば書いておくと良いかと思います。

**メリット**
**・一度コードを書いてしまえばテストが簡単にできる**
（テストコードがないとフォームの入力やリンクの移動など毎回行なう必要がある）
**・思考を整理できる**
　書き下ろすことで自分の思考を客観視でき、抜け漏れに気付きやすくなる
**・記録として残せる**
　アプリの動作を自分がどこまで想定しているか見返すことができる
　また、第３者がテスト内容を用意に確認できる

今回は以下のGIFファイルのように、投稿する動作がうまく行くかどうか確認してみようと思います。
![e02d69df1a47ecac2b896cfeb09626d2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/d5587de7-853a-f8e0-837d-4e1f4d1a316f.gif)


## Capybara導入
まずはCapybaraというgemを導入します。

```rb:Gemfile
group :test, :development do
  # （省略）
  gem 'capybara'
end
```
※ このときtest環境の中にcapybaraが既に入っている可能性があるので、そのときはコメントアウトしておきましょう。rails5.2.3では入ってました。

```:ターミナル
$ bundle install
```

```rb:spec/rails_helper.rb
# 以下の記述を追加
require 'capybara/rspec'
```

次に作業ファイルを用意します。
`spec/features`ディレクトリを作成しましょう。
その中にテスト用のファイルを作成します。
今回は`post_spec.rb`とします。


## テストコード
`post_spec.rb`に記述していきます。

```rb:spec/features/post_spec.rb
require 'rails_helper'

feature 'post', type: :feature do
  scenario '投稿ができること' do
    # 投稿ボタンが存在する
    visit root_path
    expect(page).to have_content('投稿')

    # 投稿処理が動作する
    expect {
      click_link('投稿')
      expect(current_path).to eq new_post_path
      fill_in 'post_content', with: 'こんにちは'
      fill_in 'post_tags_attributes_0_content', with: 'タグ'
      find('input[type="submit"]').click
    }.to change(Post, :count).by(1)

    # トップページにリダイレクトされる
    expect(current_path).to eq root_path

    # 投稿内容がトップページに表示されている
    expect(page).to have_content('こんにちは')
  end
end
```
一連の動作を`senario do 〜　end`の間に記述します。

今回は投稿のリンクが表示されていることを確認し、投稿処理確認、リダイレクトの確認、投稿内容の表示確認を順番に行なっています。
visitで指定のパスへ移動、fill_inでフォームに入力、findやclickで投稿など各処理の詳細はここでは説明しませんが、調べると出てくるので自分がやりたい処理があれば探してみましょう。

[こちらのチートシート](https://qiita.com/morrr/items/0e24251c049180218db4)にcapybaraで使えるものが一通り書かれているので参考にしてみると良いかもしれません。

## テスト実行
テストの実行は以下のようにファイルを指定して実行すると良いです。

```:ターミナル
$ bundle exec rspec spec/features/post_spec.rb
```
spec以下で実行したいファイルを指定します。
今回はfeaturesディレクトリのpost_spec.rbにテストコードを書いたので上のようになります。

では実行してみます。

<img width="444" alt="12172459f80a1f0c542410796c6829fe.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/db2497d0-5aad-83c5-44d7-356d87f4d70a.png">
上のように表示されれば無事クリアしています。
Google Apps ScriptでGoogle Formsの回答を取得する方法

## はじめに

GASでGoogle Formsのフォームに紐づいていないスクリプトで回答を取得するのに詰まったのでメモ。

なお、フォームに紐づいているスクリプトで回答を取得するのは[こちらのページ](https://memordm.com/googleform/)が参考になる。

## トリガー設定
[Google Formsのトリガー設定(公式ドキュメント)](https://developers.google.com/apps-script/reference/script/trigger-builder?hl=ja#forformkey)に書いてある通り、
下記スクリプトを、紐づけたい関数があるプロジェクトで実行すれば良い。


```javascript
ScriptApp.newTrigger('<関数名>')
  .forForm('<フォームID>')
  .onFormSubmit()
  .create();
```

* `関数名` はフォームの回答があった時に実行したい関数の名前
* `フォームID` はフォームのID
    * フォームの編集画面のURLは `https://docs.google.com/forms/d/<フォームID>/edit` となっている


## 回答取得

2パターンあるが、どっちを使用すべきなのか分からないので両方試してほしい。

### パターン1

```javascript
function onSubmit(e){
  Logger.log(e.namedValues['フォームの項目名1'][0]);
  Logger.log(e.namedValues['フォームの項目名2'][0]);
}
```

のようにする。

### パターン2

```javascript
function onSubmit(e){
  let items = e.response.getItemResponses();
  for (i in items){
    Logger.log("title=%s, response=%s", items[i].getItem().getTitle(), items[i].getResponse());
  }
}
```

のようにする。


## 参考
1. [How to get form values in the submit event handler? (stack overflow)](https://stackoverflow.com/questions/43429161/how-to-get-form-values-in-the-submit-event-handler)
2. https://memordm.com/googleform/
3. [Google Formsのトリガー設定(公式ドキュメント)](https://developers.google.com/apps-script/reference/script/trigger-builder?hl=ja#forformkey)
Pythonのmatplotlibで一刻も早く画像を並べて表示したいという人へ

#ソースコード

```python
import matplotlib.pyplot as plt
import cv2
import os

root = "./data" #画像があるフォルダ。適宜変えてください
lsdir = os.listdir(root)

imgs = []
for l in lsdir:
    target = os.path.join(root,l)
    img = cv2.imread(target)
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #pyplotで表示するために色変換
    imgs.append(img)

shownumber = 10 #画像を並べる数
showaxis = 1

while(showaxis*showaxis < shownumber):
    showaxis += 1

cnt = 0
while(1):
    #limit = 30
    #if cnt >= limit:
    #    break
    fig,axs = plt.subplots(showaxis,showaxis)
    ar = axs.ravel()
    for i in range(showaxis*showaxis):
        ar[i].axis('off')
        if i < shownumber:
            ar[i].imshow(imgs[cnt])
            cnt += 1
    plt.show()
```

#表示結果

```python
shownumber = 9
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/63abe7f7-557d-7438-2c3a-d52f5d637aed.png)

```python
shownumber = 10
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/21439706-36ef-3d19-bf80-9c2ea5968888.png)

#なぜこの記事を書いたか

- 画像表示をする度に`matplotlib`についてぐぐっている気がするので、自分の中の定石を定めたかった
- rowとcolumnを指定するのが微妙にめんどくさいため、表示数を指定するだけで動作するコードにしたかった
- そのようなソースコードがすぐにヒットするページを作りたかった

#コードの説明

- フォルダを指定して`cv2.imread`で読み込み、`imgs`という配列にする。
- OpenCVはBGR形式で読み込むため、`cv2.cvtColor`でRGB形式に変換
- 表示数`shownumber`を指定したら、それを満たす最小の二乗数を求めて、1辺を`showaxis`とする。

```python
while(showaxis*showaxis < shownumber):
    showaxis += 1
```

- `plt.subplots`で行と列がそれぞれ`showaxis`の数だけあるグラフを用意
- `axs`は縦位置と横位置を指定するのがめんどくさいため、`axs.ravel()`で一連の配列にする
- 1ループごとに`shownumber`の数だけ、`imshow`と`axis('off')`で画像表示
- `imgs`が尽きるまでループを回し続ける

　コードの構成上、最終的には確実に範囲外参照エラーを起こすので注意。一応脱出処理をコメントで書いてます。
[データ配布] Laravel + Reactのアーキテクチャ設計

# Laravel + React シンプルなTodoアプリ(アーキテクチャ設計)

## 構成
- Laravel: CRUD API（updateは未実装）
- React: フォーム送信機能

## Laravel環境構築
- Laravel 5.8
- React
- VirtialBox
- Vagrant
- Macの場合、Xcode、Homeblue必須

[Laravel環境構築 チートシート](https://qiita.com/dai_designing/items/6fe5f678bf5a05e27c05)
この記事内の`vagrant@homestead:~$ cd code`までおこなってください。
Laravelデータは作成した方を入れるのでデフォルトデータはクローンしなくて大丈夫です。

## GitHubデータをクローン
どこでもいいのでデータクローン。
使うのは中身のファイルです。

```bash
# 別ウィンドウでターミナルを立ち上げて(コマンド+T)
$ cd Desktop
$ git clone https://github.com/dai-570415/laravel-react-example.git
```

クローンできたら
中身のファイル一式を「/Laravelファイル名/code/」ディレクトリに直接移動

```bash
# Laravelプロジェクト側

# 依存関係インストール
vagrant@homestead:~$ npm install
# テーブル生成
vagrant@homestead:~$ php artisan migrate
# React監視
vagrant@homestead:~$ npm run watch-poll
```

こちらで無事表示できたかと思います。

中身の説明はGit Hubにまとめましたので、そちらからみてください。
[Git Hub](https://github.com/dai-570415/laravel-react-example)
Wordress「Twenty Twenty」テーマにあるインラインCSSを削除する方法


適当なテンプレートが見当たらなかったため、デフォルトで入っているTwenty Twentyを親として子テーマを作成。親のCSSを読み込まないようにしたものの、インラインでCSSが設定されていて、これがちょっと全体を邪魔する曲者。

```head.html
<style id=’twentytwenty-style-inline-css’>
```

functions.phpにwp_dequeue_styleを使ってみても読み込まれる。

```funcions.php
function wp_delete_inline_css() {
	wp_dequeue_style('twentytwenty-style-inline');
}
add_action( 'wp_enqueue_scripts', 'wp_delete_inline_css' );
```

いろいろ調べてみると、wp_enqueue_style()で使って登録されたCSSを解除する方法とのこと。
参考URL：https://samurai-project.com/articles/3372

で、どうしたらいいのか

```funcions.php
add_action( 'wp_enqueue_scripts', function() {
	$styles = wp_styles();
	$styles->add_data( 'twentytwenty-style', 'after', array() );
}, 20 );
```
で、解決。

Worpdress本家のTwenty Twentyのサポートに書いておりました。
https://wordpress.org/support/topic/remove-inline-styles-5/


でも、なんでこれで解決出来るのか・・・これから解読しようと思います。
Flutterもう一度触ってみた Day1

# 背景
ネイティブアプリが必要になりそうなので、Flutterもう一度触り始めた。

# TODO

南アフリカにいた時に700円ぐらいで購入したコースをもう一度やっていきます。
The Complete 2020 Flutter Development Bootcamp with Dart


学んだアウトプットをQiitaに書いていこうと思います。

# 以前から気になっていたこと
このAngelaって人は、どういうモチベーションでSwiftやFlutter系のコースを作っているのか以前から気になっていたけど、自分には関係なく、素晴らしいコーズをありがとうって言っとこ。

![スクリーンショット 2020-07-15 14.59.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378998/63bc1d38-8698-9c1c-c8bf-eac262f32837.png)

あ、教えるのがPassionなんだ。
12歳で、スペースインベーダーゲーム作りたくてプログラム書き出したのか。
今日から17日間お世話になります。

Flutterを学んでいる人
友達になりましょう😎
【N+1問題】

##N+1問題とは
アソシエーションでモデル同士を関連づけている場合に起こる問題のこと。

例えばツイッターのようなアプリでユーザーと投稿が紐付いている場合に
トップページで投稿を一覧表示させる時に各投稿ごとに紐付いているユーザーを検索するために毎回毎回データベースにアクセスしているとアプリのパフォーマンスが下がってしまう。

1万投稿ある場合は1万回データベースにアクセスしなければいけないということ。

この問題のことをN+1問題という。

この問題を解決するためのメソッドが

###includeメソッド
と言われるメソッド。

このメソッドは毎回毎回データベースにアクセスして紐づくデータを検索していたところを、
一回で全データを取得してくれる。

そのため1万投稿あるとしてもデータベースへのアクセス「は一度で済む。

<img width="655" alt="n+1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673286/0f530e25-d7a8-d991-6e78-1b32be61bab0.png">

上の画像のようにindexアクションの処理内容の箇所にincludes(:紐づくモデル)とすれば使用できる。

これでツイートなどを一覧表示する際に投稿がいくら増えたとしてもパフォーマンスを下げずに済む。
JavaはPPTドキュメントを最終状態としてマークします

PPTドキュメントを設計および作成した後、ドキュメントが最終的な設計状態に達したことを示し、内部のコンテンツを誰も編集および変更したくない場合は、PPTドキュメントを最終状態としてマークできます。この記事では、Free Spire.Presentation for Javaを使用してPPTプレゼンテーションを最終版としてマークする方法について説明します。

**JARパッケージのインポート**
方法1：[Free Spire.Presentation for Java](https://www.e-iceblue.com/Download/presentation-for-java-free.html)をダウンロードして解凍し、jarパッケージをlibフォルダーに依存関係としてJavaアプリケーションに直接インポートします。 

方法2：Mavenリポジトリからjarパッケージをインストールし、pom.xmlファイルのコードを次のように構成します。

```java
<repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.presentation.free</artifactId>
        <version>2.6.1</version>
    </dependency>
</dependencies>
```

**Javaコード**

```java
import com.spire.presentation.FileFormat;
import com.spire.presentation.Presentation;

public class MarkAsFinal {
    public static void main(String[] args) throws Exception {

        //サンプルドキュメントをロード
        Presentation presentation = new Presentation();
        presentation.loadFromFile("test.pptx");

        //ドキュメントプロパティMarkAsFinalをtrueに設定します
        presentation.getDocumentProperty().set("_MarkAsFinal", true);

        //文書を保存します
        presentation.saveToFile("MarkasFinal.pptx", FileFormat.PPTX_2010);
    }
}
```

![ja.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/b0f27ebd-6f1d-e7f8-e23c-ff43b4f17c57.png)
Tkinterのボタンが呼び出す関数を変更する

`config()`を利用すると、ボタンのいろいろを変更できるらしい。
押下時に呼び出される関数も変更できるので、便利かもしれない。
と思ったけど、実は`["command"]=`を利用すればいいだけだとも気づいた。

参考：http://effbot.org/tkinterbook/pythondoc-tkinter-button.htm

```Python
import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.hi_there = tk.Button(self)
        self.hi_there["text"] = "Hello World\n(click me)"
        self.hi_there["command"] = self.say_hi #ボタンに関数を設定する方法１
        self.hi_there.pack(side="top")
        self.quit = tk.Button(self, text="QUIT", fg="red", command=self.master.destroy) #ボタンに関数を設定する方法２
        self.quit.pack(side="bottom")

    def say_hi(self):
        print("hi there, from Application!")


def say_hi():
    print("hi there!")

def main():
    root = tk.Tk()
    app = Application(master=root)
    app.hi_there.config(command=say_hi) # configを利用した変更
    app.quit["command"] = app.say_hi # 実はそのまま変更できる
    app.mainloop()

if __name__ == "__main__":
    main()
```
Laravel npm installを実行しようとしたらエラーが出た話 超簡易版

# 目的

- Laravelアプリに必要なJSパッケージをインストールするためにnpm installを実行したがエラーが出た話をまとめる

# 問題までの経緯

1. Laravelアプリ名ディレクトリの一つ上の階層で下記コマンドを実行した。

    ```terminal
    $ npm install
    ```

# 問題

1. 下記エラーが発生しコマンドが正常実行されない。

    ```
    npm WARN saveError ENOENT: no such file or directory, open '/usr/share/nginx/html/package.json'
    npm WARN enoent ENOENT: no such file or directory, open '/usr/share/nginx/html/package.json'
    npm WARN html No description
    npm WARN html No repository field.
    npm WARN html No README data
    npm WARN html No license field.

    audited 15 packages in 0.511s

    3 packages are looking for funding
      run `npm fund` for details

    found 0 vulnerabilities
    ```

# 問題解決までの経緯

1. `$ npm install`を実行するディレクトリを間違えていた。
1. Laravelアプリ名ディレクトリに移動して`$ npm install`を実行したところ正常に実行された。
【産休中にProgate】1週目:HTML & CSS、SQL

育休開始から1年が経ち、ちょいとここらでProgateデビュー。

とっても飽き性なのでどこまで続けられるかわかりませんが、せっかくなのでメモっていこうと思います。

##今週の進捗
- HTML & CSS の学習編完了
- SQL途中
![1週目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674636/1d16c2ae-b729-1f40-921c-f51e86593c93.png)

朝はパソコンでWEB版を使ってアウトプット、夜はアプリを使ってインプットのスタイルが私には合ってるみたいです。

##今週の一言
また4日目だけど、とても楽しい。有難く課金させて頂きました。
早速githubに登録して、ページ公開してみた（超初心者ですからお許しください）

https://cherubmachiko.github.io/

とりあえず飽きるまでたくさんあるコンテンツやりたい〜！
LPWAをMQTT-SNで使用してみた (0)

## はじめに
話題は先行しているもののLPWAは使いにくいと感じていた。　wifiのように自由にテストできる環境がないことがその理由だ。　誰でも無料で使える周波数だから試してみようと思ってもSigfoxやLoRaWANの事業者のサービスを使う必要がある。　sigfoxは各国で一社だけがサービス提供できる独占体系だし、全国でサービス提供されていても自分にとって使いたいのは数キロメートルだけで十分なのだ。この課題を解決するためにMQTT-SNにLPWAを追加して。　上手く通信できることが確認できたので記事を書いてみた。
![LoRaMQTT-SN_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41752/9dc45fbe-565d-aefb-b49b-a549711a206b.png)
## LoRaを使ったMQTT-SNゲートウェイ
ゲートウェイには全二重通信が必要だがLoRaは半二重通信なので上りCHと下りCHを分けてそれぞれにLoRaデバイスを用意することにした。　
LoRa物理層上にのせるネットワーク層用としてLoRaLinkと名付けたプロトコルを作った。　このプロトコルはZigBeeと同様にPanIDとデバイスアドレスでデバイスを識別する。PanID毎に暗号化キーを共有することでデータを保護している。　データ改ざん防止用としてLoRaWAN同様のMICを採用している。　また、PanID毎にLoRaのsyncwordを変えることで他のPanの通信を受信しないようにした。　
![LoRaLinkMQTT-SN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41752/41587cce-eb13-a745-f3bb-71f35cf29ed1.png)　
## 使用したデバイス
デバイスは村田製作所のCMWX1ZZABZをゲートウェイの送受信とクライアント用に使用している。　このデバイスはSTM32L082　mcuとSEMTECHのSX1276を使用したもので技適が取得されている。　
このデバイスの開発ボードがSTマイクロから販売されている。(型式 B-L072Z-LRWAN1)　
今回はこのボートの他に、同じデバイスを使って省スペースで省電力になるように設計したモジュールLoRaEzでも試した。
![LoRaEz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41752/663cfe30-9f26-ae12-24d7-5a1bb78a1556.png)
## 開発したソフトウェア
**1. ゲートウェイ**
MQTT-SNゲートウェイはpahoのゲートウェイを使用。　pahoのMQTT-SN用のgithubにexperimentブランチを作ってLoRaLink用のセンサーネットワーククラスを追加したゲートウェイを用意した。　https://github.com/eclipse/paho.mqtt-sn.embedded-c/tree/experiment
**2. クライアントデバイス**
一般的なLPWAのデバイスは通信と制御用にMCUを2つ使用するが、クライアントデバイス用のファームウェアにはクライアント用のアプリケーションフレームワークも組み込まれている。CMWX1ZZABZだけでコスト的にも省電力的にも優れたセンサーデバイスを作ることが出来る。
ゲートウェイとクライアントデバイスのファームウェア用のSDKもgithubで公開している。
https://github.com/ty4tw/LoRaMQTT-SN

**今後ファームウェアの使い方などについて記事を追加していく予定です。**
任意の番号のORAエラーを発生させる方法

# 対象DBMSバージョン、エディション
動作確認はOracle Autonomous Transaction Processing Cloud Service(バージョン19.5)で実施していますが、エディションは問いません。また、マニュアルを机上確認する限り、Oracle7以降にて対応しています。

#はじめに
障害テストなどのためにわざとORAエラーを発生させたい場合があります。制約違反や参照先テーブルがないテストパターンなどは比較的楽に実装できますが、例えばORA-600とかORA-7445といった内部エラーを故意に発生させるにはどうすればいいでしょうか？
実はPL/SQLを使用すると、任意の番号のORAエラーを発生させることが可能です。
ただし、欠点もないわけではないので、注意点含め解説したいと思います。
大きくは以下の2つの方法があります。

# 1. RAISE_APPLICATION_ERRORプロシージャ
対応エラーコード範囲が限定されるので、掲題の趣旨とは少し異なりますが、RAISE_APPLICATION_ERRORプロシージャを用いると、お手軽に特定の番号のORAエラーを発生させることが可能です。対応ししているエラー番号の範囲は、-20000～-20999となります。

RAISE_APPLICATION_ERRORプロシージャには、以下の3つの引数が存在します。

1. エラー番号：-20000～-20999の範囲内で指定
2. エラーメッセージ：2048バイト以内の文字列
3. エラー表示形式：FALSE(デフォルト)はエラースタックを本プロシージャによるエラーに置換、TRUEはエラースタックの最上位に本プロシージャによるエラーを配置

使い方は、以下のように簡単です。例だと雑なIF文ですが、何らかのチェックを行ってアプリケーション上問題となる場合にRAISE_APPLICATION_ERRORプロシージャを呼び出すのが典型的な利用方法となります。

```SQL:
SQL> BEGIN
  2    IF 1 < 2 THEN
  3      RAISE_APPLICATION_ERROR(-20000, 'エラー発生');
  4    END IF;
  5  END;
  6  /
BEGIN
*
行1でエラーが発生しました。:
ORA-20000: エラー発生
ORA-06512: 行3
```

# 2. ユーザー定義例外
RAISE_APPLICATION_ERRORプロシージャは簡便に利用できる半面、意図的にORA-942やORA-600といった、Oracle Database自身が利用するエラー番号のエラーを発生させることはできません。しかし、以下のようにユーザー定義例外を利用すると、自前で任意の番号のORAエラーを発生させることが可能です。

```SQL:
SQL> DECLARE
  2    E942 EXCEPTION;
  3    PRAGMA EXCEPTION_INIT(E942, -942);
  4  BEGIN
  5     RAISE E942;
  6  END;
  7  /
DECLARE
*
行1でエラーが発生しました。:
ORA-00942: 表またはビューが存在しません。 ORA-06512: 行5
```

まず、2行目でユーザー定義例外(EXCEPTION)を定義しています。この例だと、「E942」が例外の名称となります。
3行目は、2行目のユーザー定義例外と、実際のORAエラー番号(エラー番号はマイナスです)を紐づけるプラグマを定義しています。
5行目で、2行目で定義した例外を呼び出すと、3行目で定義したエラー番号で例外が発生します。
上記の例のような、固定のエラーメッセージはこれで問題ないのですが、例えばORA-1のような、エラー対象のオブジェクト名がエラーメッセージに含まれるエラーの場合、エラーとなったオブジェクトが実際には存在しないので、該当箇所が空白となります。ですので、エラーとなったオブジェクト名を拾いたい場合にはこの方法は利用できず、エラーが発生する状況を実直に作り出すしかありません。以下の例では、意図したエラー番号でエラーを発生させることはできているのですが、「スキーマ名.制約名」の部分が、スキーマ名と制約名を分ける「.」だけになってしまっています。

```SQL:
SQL> DECLARE
  2    E1 EXCEPTION;
  3    PRAGMA EXCEPTION_INIT(E1, -1);
  4  BEGIN
  5     RAISE E1;
  6  END;
  7  /
DECLARE
*
行1でエラーが発生しました。:
ORA-00001: 一意制約(.)に反しています ORA-06512:
行5
```

ORA-600のような内部エラーも、ORA-600自体は発生させられますが、エラーメッセージ内の内部番号欄は空になります。トレースファイルも出力はされますが、実際に内部エラーが発生しているわけではないので、内容はほぼヘッダーのみとなります。

```SQL:
SQL> DECLARE
  2    FATAL_ERROR EXCEPTION;
  3    PRAGMA EXCEPTION_INIT(FATAL_ERROR, -600);
  4  BEGIN
  5     RAISE FATAL_ERROR;
  6  END;
  7  /
DECLARE
*
行1でエラーが発生しました。:
ORA-00600: 内部エラー・コード, 引数: [600], [], [], [], [], [], [], [], [], [], [], []
ORA-06512: 行5
```
Chromeで複数Googleアカウントを使い分けるベストプラクティス

# 悩み
Googleアカウントを複数作成して、使い分ける時代がやってきました・・。
会社用、個人用、事業用、ちょっと使う用、Youtube用などなど・・・。
僕個人でいくと今5つのアカウントを使い分けているわけですが、

デフォルトアカウントという設定によって、
Google DriveやGoogle Calenderを開いた時、**デフォルトアカウントで最初ログインしてしまう現象**に
悩まされていました。

![Group 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/3b538f6f-71fa-4abe-012a-90e252f2886e.png)

そう、この**デフォルトアカウント**ですね。
例えば今一番上のアカウントでログインしているわけですが、
この状態で、Google Driveのマイドライブを開くと

![Group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/43c7a400-88b1-3392-0ab4-f0ce476093a4.png)

おいおい、そいつじゃないんだよ。
っていって、毎回上の画面からアカウントを切り替えていましたが、正直かなり面倒でした。。


# 解決方法

解決方法はとても簡単でした。

Chromeにはアカウントごとに、Windowを作る機能がありました！
これを使うと、他のアカウントに切り替える手間がなくなるので、かなり作業効率が上がった気がします。

![Group 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/03e9b6e9-f3d8-6d53-a7d9-542c4b29fb34.png)

![Group 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/60576eeb-28a0-3539-db5d-7c7f2e2a486e.png)

ユーザー名は適当で大丈夫です。
※あとでログインしたら自動的にアカウント名になるので。

<img width="798" alt="スクリーンショット 2020-07-15 14.16.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/ed53db07-9e01-d06d-c2e9-fad4eabb1a34.png">

**追加**をクリック

<img width="1791" alt="スクリーンショット 2020-07-15 14.16.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/3461d8d0-5767-774e-bc01-9c7037f8d59a.png">

**Chromeをすでにご利用の場合はログイン**をクリック

<img width="1792" alt="スクリーンショット 2020-07-15 14.17.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/55e92681-002f-9d78-1af0-862324d135d6.png">

あとは使い分けたいGoogleアカウントでログインします。

この作業を自分の使い分けたいGoogleアカウントの数だけ行い、
作成を行うと・・・。

![Group 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/3fe80652-19ca-8258-2b1f-58729cae3d4e.png)

こうなります！
あとは作業したいアカウントの部分をクリックすれば、専用のwindowが作られるので
存分に作業するだけです！！！


# 個人的なおすすめの使い方

上記でアカウントごとにWindowを分けたことによって、使いやすさと心理的なストレスが軽減されたのもそうですが、
もうひとつオススメの使い方があります。

アカウントごとにWindowが分かれたので、ツールバーもアカウントごとに設定できます！

![Group 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/30a8c80d-a6cd-d692-257c-02d05efdacb3.png)

ここをアカウントごとに使い分けると、さらに作業効率が爆上がりします！
※上記はYoutubeで使ってるアカウントなので、各媒体にアクセスしやすいようにしています。

複数アカウントを一つのWindowでやってた時はツールバーが肥大化して、めちゃめちゃグループ分けとかしてたので
それもストレスでした・・。


# 最後に

正直めちゃめちゃ今更感もあるかもしれないですが、僕みたいにあまりChromeを使いこなせていない方に
届けばいいと思い書きました。

もっと良い使い方がある方は是非教えてください！
プロジェクトマネジメントを引き継いだ話

# はじめに
2020年5月に転職し、6月から自社アプリのPMを引き継いだのですがその時の話を。
筆者はwebエンジニアとして受託という形で関わっていたのですが、5月に正式に会社にjoinした感じです。

## 従来の状態
転職した会社はスタートアップで社員も20名弱。
チームメンバーは3つのプロダクトを兼任しながら10名弱。

ディレクターが２名ほどおり、そこで策定された施策や機能などがエンジニアに降りてくる典型のウォータフォールでした。
しかし、問題としてそこから

開発側が調査・工数見積もり→
問題が発生→
ディレクター側に要件定義の戻りが発生→
再度要件定義→
開発側が調査・工数見積もり→
問題が発生→
・・・・以下loop

ということも少なくありませんでした。

私は前職で要件定義からテストまでをおこなっていたので、そのノウハウを組み込むことができればと思いました。

## 開発手法の転向
まず問題としてアプリの最終ゴールがないことが問題でした。
KPIを決めてそれに向かって走っているのですが、結局ゴールがないままに短期的なプロットを追っている感じでした。

そこでサービスとしてのOKR(googleとかでやってる目標管理指標ですね)の策定と、アプリの最終形を定義しました。
こうすることで常に自分がおこなっていることが間違っていないかどうかの指針しようと思いました。

そして、施策や機能要件を開発者が提案・定義するようなフローとしました。
アプリの最終形があるのでそれに向かっての機能要件などはもうできるようになっているので、それを開発者にしてもらうようにしたのです。

これにより、ざっくりとした工数や技術課題などが初期段階で判明するので、いつものようなディレクターに戻るようなことが発生しない仕組みとしました。

## メリット
先に述べたように手戻りがないので無駄がないことと、開発者がユーザ視点で開発できること、開発者全員がPMになれるよう育つことができると思います。

### 手戻りがない
先述した通り。

### 開発者がユーザ視点になれる
今までディレクターから降りてくる内容をただ開発しているだけだったのが、要件から入ることでよりユーザを意識した開発ができるようになる。

### みんなPM
要件から入り、開発し、効果測定し、改善案を考えて開発する。というサイクルを回せることでPM開発者全員が数値を意識して動けるようになります。
みんなPMの何がいいかというと、PMに依存せずにプロジェクトを進めることができるメリットがあります。
(PMなんてほんとはいなくていいと思ってる)

## ディレクターは？
ディレクターはお払い箱？ではなく、マーケティングなどに注力してサービスの拡大施策に集中できることが良いのです。
※会社によっていろんな体制があるのでなんとも言えませんがうちはこういう感じです。

## 最後に
開発者が一番サービスの内容を理解している(コードレベルで)のでそういったところまでどんどん入っていければ人材としての市場価値も上がるしいいことばっかりではないか？というように思っている次第でした。
走り始めたばかりなので今後どうなるかわかりませんが・・・。
Google SpreadSheetのQueryでWhere節にセルの参照を入れたい

#前回の続き

前回、Query関数を使うと便利と書いたのだけど、条件節にセルの中身を使いたくなって調べました
ちなみに直値の場合
文字列はシングルコーテーションで囲み、数値はダイレクトに記載します
> =Query(A1:D10,"WHERE A='横浜'")

> =Query(A1:D10,"WHERE A=100")


#文字列比較の場合
####シングル→ダブル→アンパーサント→セル番地→アンパーサント→ダブル→シングル

呪文のようになりました

> =Query(A1:D10,"WHERE A='"&E2&"'")


閉じる部分は、アンパーサント→ダブル→シングル。こうなるようです。

#数値比較の場合

####ダブル→アンパーサント→セル番地→アンパーサント→ダブル

シングルコーテーションが不要になります。

> =Query(A1:D10,"WHERE A="&E2&"")

文字列比較と数値比較で考えるとすっきりしますね（しませんw）

#まとめ

|    |  文字列  |  数値  |
| ---- | ---- |---- |
|  直値  |  '文字列'  | 数値  |
|  セル  |  '"&セル番地&"'  |  "&セル番地&"  |
Laravelの最短ページ作成流れ

LaravelのMVCモデルの構造上、以下３つを作れば最低限のページ作成ができる。
細かい繋ぎ込みは省く。

新しく何かを使え加えるときは、以下順に記入していく。


##①routes                /web.phpにルーティングを記入　
('/アドレス名','使いたいコントローラー＠メソッドの名前')
　<img width="468" alt="スクリーンショット 2020-07-14 23.41.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664335/8299c744-d94d-1ffc-2adb-cc1507f761e1.png">


##②app/Http/Controllers  /コントローラー名Controller.phpにメソッドを記入
例：public function 名前(){
     return view('表示したいviewsの名前')
}
![スクリーンショット 2020-07-14 23.50.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664335/87e24f76-5f9b-4cbf-14a4-4cd6d1e12f6b.png)


##③resources/views       /ページ名.blade.phpにhtml文を記入
　


イメージ画像　https://miyabi-lab.space/blog/22
Mac nodebrew installを実行した時にエラーが出た話 超簡易版

# 目的

- 問題の解決方法を簡単にまとめる。

# 問題までの経緯

1. 下記コマンドを実行してNode.jsをインストールしようとした。

    ```terminal
    $ nodebrew install v8.9.4
    ```

# 問題

1. 下記のエラーが発生した。

    ```
    $ nodebrew install v8.9.4
    Fetching: https://nodejs.org/dist/v8.9.4/node-v8.9.4-darwin-x64.tar.gz
    Warning: Failed to create the file 
    Warning: /Users/okawashun/.nodebrew/src/v8.9.4/node-v8.9.4-darwin-x64.tar.gz: 
    Warning: No such file or directory

    curl: (23) Failed writing body (0 != 979)
    download failed: https://nodejs.org/dist/v8.9.4/node-v8.9.4-darwin-x64.tar.gz
    ```

# 問題解決までの経緯

1. 下記コマンドを実行してnodebrew用のディレクトリを作成した。

    ```terminal
    $ mkdir -p ~/.nodebrew/src
    ```
1. 下記コマンドを実行して再度インストールを行ったところ問題は解決した。

    ```terminal
    $ nodebrew install v8.9.4
    ```