OmniAICreator/Qiita-1.07M huggingface dataset:
GASによるGmailの日報の自動化

日報ってめんどくさいですよね。

みんなも自動化してると思うけど、してない方のために伝授します。
まあGmail限定です。(Outlookは別の人に託す)

次の3つを使用します。

- GAS(GoogleAppsScript)っていうJavaScriptみたいな言語
- Gmail
- スプレッドシート


ほな、いくで。

##スプレッドシートの作成

まず、スプレッドシートを開く。
Chrome使ってたらアプリってやつ左上くらいにあるので、それ押したら出てくるはず。

スプレットシートはこんな感じで。
ファイル名：日報
シート名：作業内容

![スクリーンショット 2021-01-27 19.54.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/451bfe2e-b4fe-bf22-0e0f-af1a912a2d5c.png)


##スクリプトの作成
次に「ツール→スクリプトエディタ」を開く。
ここでコードを書く。

2つファイル作る。
前者が日報の下書きを作ってくれるやつで、
後者はスプレッドシートでドラフト保存で保存するを選択したら検知して、前者を呼び出してくれるスクリプト。

- createGmailDraft.gs
- checksave.gs

####createGmailDraft.gs
```javascript:createGmailDraft.gs

function createDraft() {
  //日付
  var date  = new Date()
  var today = Utilities.formatDate(date, 'Asia/Tokyo','yyyyMMdd')
  //スプレッドシートの情報
  var ss = SpreadsheetApp.getActive().getSheetByName('作業内容')
  var values = ss.getDataRange().getValues()
  //作業時間
  var start = values[0][1]
  var close = values[1][1]
  var wkHour = values[2][1]
  //作業内容
  var todayTask = values[3][1]
  var tomorrowTask = values[4][1]
  //メール内容
  var to = 'yamadataichou@taicho.com,test@test.com'
  var subject = '日報_田中太郎' + today
  var body = `\
山田隊長\n\n\
お疲れ様です。田中です。\n\n\
下記本日の作業でござる。\n\n\
[作業時間]\n\
開始時間：${start}\n\
終業時間：${close}\n\
稼働時間：${wkHour}\n\
[作業内容]\n\
${todayTask}\n\n\
[作業予定]\n\
${tomorrowTask}\n\n\
以上、ヨロピコ丸。`
  GmailApp.createDraft(to, subject, body)
}

``` 

####checksave.gs
```javascript:checksave.gs
function checkSave() {
  //スプレッドシートの情報
  var ss = SpreadsheetApp.getActive().getSheetByName('作業内容')
  var values = ss.getDataRange().getValues()
  //保存する、しないの部分
  var draftSave = values[5][1]
  
  if (draftSave==='保存する'){
    //メール作成メソッドのお呼び出し
    createDraft()
  }
  //保存しないに変更しとく。
  ss.getRange(6,2).setValue('保存しない')
}

```

すまん。最初に見た人
createDraft()がコメントアウトなってました。

![スクリーンショット 2021-01-27 19.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/c5b6856b-b0ce-37a3-6d1b-cd3432559087.png)

![スクリーンショット 2021-01-27 19.58.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/ec755189-6ad6-2f52-d136-9774a8dd468d.png)

スクリプト完成！

##トリガーの設定
次にトリガーを設定する。
左のバーにカーソル合わせてトリガーをクリック、
![スクリーンショット 2021-01-27 20.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/4d9d4e5b-ecdc-80f8-df7c-aea86c2ca3fa.png)
右下のトリガーを作成をクリック。
![スクリーンショット 2021-01-27 20.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/a98a21c6-5ab7-4da9-2c33-3329d44c89ca.png)

下記を選択する
実行する関数：checkSave
実行するデプロイ：Head
イベントのソース：スプレッドシートから
イベントの種類：変更時
![スクリーンショット 2021-01-27 20.21.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/e20c7182-3a90-e0b3-f9d6-a714af5de89e.png)

##日報作成
スプレッドシートで保存するを選ぶと内容が適用されて下書きが作成される。

![スクリーンショット 2021-01-27 19.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672975/3d60f9dc-7aa3-eda0-f7e7-f29221c83c9c.png)


終わり
初めて作るアプリのアイコンを作成する

##なぜ記事にするのか
本当に無知（アプリ開発初心者）の段階で、どのような考え方、過程でアプリのアイコンを作ったか記録するため

##どんなアプリを作っているのか
以下の記事で説明していますが、台湾中国語および日本語勉強アプリです。アプリのタイトルは「AtaCon」に決めました。
[初めて作るアプリのタイトルを決める](https://qiita.com/atamakonkurii/items/a38281091f5b8e1ed4a5)

##要件
・台湾中国語と日本語が学習できるとわかるようにしたい（国旗をいれるとか）

##作る過程
YouTubeをやっており、動画編集で使うためAdobe Creative Cloudを契約しています。
そのため、Adobe illustratorでアイコン作成をしました。
完成したアイコンはこれです。
<img width="300" alt="アートボード 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/1ca672a7-1fbe-4ad6-1b44-c5e2900d0fce.png">

このデザインにセンスがないといことはわかりますが、どうやってセンスのいいアイコンを作れるのかわかりません、、、
とりあえず要件は満たしたのでよしとしますが、いいアイデアがあれば是非教えてください。

##作る過程(2021/01/28追記)
上のアイコンが少しごちゃごちゃしていて気に入らなかったのですぐに作り替えました。
<img width="300" alt="アートボード 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/693138c2-4ec5-e95b-89cb-fd65ba22ebae.png">
テトラポッドでコンクリートを表現しました。


ホーム画面イメージ
<img width="300" alt="Simulator Screen Shot - iPhone 11 Pro - 2021-01-28 at 07.07.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/de97b3ec-3d6e-b36a-5684-191c6c85528a.png">



##参考URL
【Xcode】アプリアイコンの作成と設定方法
https://qiita.com/digital-creator-masa/items/57ae8e84665205369481

【2021年版】もう配色デザインには迷わない！すごい無料カラーパレットツール72個まとめ
https://photoshopvip.net/72189
lodashの真偽値判定まとめ

### lodashのさまざまな真偽値判定

`lodash`の`isXXXX`を使ったりするのですが、`undefined`のとき`true`だっけ・・・？
と迷うことが多々あったのでまとめてみました。

検証バージョンは`4.17.14`です。


| 引数           | 引数(コード) | _.isEmpty() | _.isNaN() | _.isNil() | _.isNull() | _.isUndefined() | 
|:-:            |:-:            |:-:     |:-:    |:-:    |:-:     |:-:          |
|空文字         | ''            | **true**|false |false  |false    |false       |
|半角スペース    | ' '           | false  |false |false   |false    |false       |
|NaN            | NaN           |**true**|**true**|false |false    |false       |
|null           | null          |**true** |false|**true**|**true** |false       |
|undefined      | undefined     |**true** |false|**true** |false   |**true**   |
|真偽値         | true          |**true** |false |false  |false    |false       |
|数字           | 0             |**true** |false |false  |false    |false       |
|文字           | 'hoge'        | false   |false |false  |false    |false       |
|配列           | [0,1,2]       | false   |false |false  |false    |false       |
|空配列         | []            |**true**|false |false  |false     |false       |
|オブジェクト    | {hoge:'hoge'} |false   |false |false  |false    |false       |
|空のオブジェクト| {}            | **true**|false |false  |false    |false       |

`isEmpty`使用するときは要注意ですね。。

### おまけ

以下で確認しました。

```js
this.checkFuncReturnValue('isEmpty', hoge => _.isEmpty(hoge));
this.checkFuncReturnValue('isNaN', hoge => _.isNaN(hoge));
this.checkFuncReturnValue('isNil', hoge => _.isNil(hoge));
this.checkFuncReturnValue('isNull', hoge => _.isNull(hoge));
this.checkFuncReturnValue('isUndefined', hoge => _.isUndefined(hoge));
```
```js
checkFuncReturnValue(funcName, func) {
  console.log(funcName);
  console.log(' blank =>' + func(''));
  console.log(' halfSpace =>' + _.isEmpty(' '));
  console.log(' fullSpace =>' + _.isEmpty('　'));
  console.log(' NaN =>' + func(NaN));
  console.log(' null =>' + func(null));
  console.log(' undefined =>' + func(undefined));
  console.log(' true =>' + func(true));
  console.log(' number =>' + func(0));
  console.log(' string =>' + func('hoge'));
  console.log(' array =>' + func([0, 1, 2]));
  console.log(' emptyArray =>' + func([]));
  console.log(' object =>' + func({ hoge: 'hoge' }));
  console.log(' emptyObject =>' + func({}));
}
```
Blockchain 基本用語

# ナンス
 - ブロックを生成する時に、マイナー（採掘者）によって生成される``32ビットの数値``
 - ``Number used once``（一度だけ使用される使い捨ての数字）の略

# ECDSA
 - 暗号アルゴリズムのひとつである``楕円曲線暗号``のこと
 - RSAと比較して、``約10分の1のデータ長``での高速処理でありながら同レベルの安全性がある

# マイニング
 - 新たなブロックを生成し、その`報酬`として仮想通貨を手に入れる行為のこと
 - ブロック：``取引``をまとめたもの 

# Proof of Work
 - ``コンセンサスアルゴリズム``の一種
 - ``何が正当な取引情報なのか``を決定・管理するための仕組み
 - P2Pネットワーク：``中心的な管理者``は存在せず、ネットワーク内で情報が縦横無尽に走る

# コンセンサスアルゴリズム
 - 直訳すると、``合意方法``
 - 中央集権的な管理者が存在しない``P2Pネットワーク``における合意方法

# トランザクション
 - ``取引記録``のこと
 - ``価値の移転``を記号化している
 
# ウォレット
 - 自分の``ビットコインアドレス``をまとめたもの
 - ``秘密鍵``を保管する場所

# イーサリアム（Ethereum）
 - 仮想通貨は``イーサ（ETH）``
 - ビットコイン同様に``Proof of Work``を採用している

# ビットコインアドレス
 - ビットコインを利用する際の``口座番号``のようなもの
 - ``公開鍵``から生成される

# ノード
 - ``P2Pネットワーク``に参加するコンピュータまたは参加者のこと
 - データの署名や取引データを検証し、``分散型台帳``と比較することで監視・取引を承認する

# 51%攻撃
 - 特定の個人や団体が``計算処理能力``の51%以上を支配する
 - 51%攻撃が起こると、取引に対する信頼性を失い、市場での``価格が下がる``

# 参考文献
 - [ビットコイン（Bitcoin）用語集](https://bitflyer.com/ja-jp/glossary/mining)
 - [用語集](https://bitwallet.com/ja/support/glossary/ecdsa.html)
 - [Proof of Work（プルーフオブワーク）とは？](https://hedge.guide/cryptocurrency/bitcoin/mechanism/pow)
 - [P2P（ピアツーピア）ネットワークの仕組みと強み・弱み](https://floc.jp/log/basic/1270/)
 - [ブロックチェーンにおけるトランザクションとは](https://qiita.com/nagata03/items/b2a4a2a3d1e5081be28b#:~:text=%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A3%E3%81%A6%E4%BD%95%EF%BC%9F,%E3%81%A7%E3%82%82%E8%A6%8B%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%80%82)
 - [ウォレットとは？仮想通貨を扱う上での利便性と安全性を解説【初心者必見】](https://floc.jp/log/basic/1490/)
 - [51%攻撃](https://zaif.jp/glossary/51attack?lang=ja)
vue-simple-suggestの機能を最小限で実装

#概要
Vue.jsでサジェスト機能を実装したくてやり方を調べていたら、vue-simple-suggestなるライブラリがあることが分かったので使ってみる。

インストール方法は公式参照
公式GitHub→https://github.com/KazanExpress/vue-simple-suggest

#環境
Vue.js 2.5.17
vue-simple-suggest 1.10.3
#実装
##全体
```Form.vue
<template>
    <div class="form-group">
        <vue-simple-suggest
            v-model="selected"
            :list="getSuggestionList"
            :filter-by-query="true">
            <input type="text" name="tag" id="tag" placeholder="タグを入力してください" autocomplete="off">    
        </vue-simple-suggest>
    </div>
</template>
<script>
import VueSimpleSuggest from "vue-simple-suggest";
import 'vue-simple-suggest/dist/styles.css';

export default {
    components: {
        VueSimpleSuggest
    },
    data() {
        return {
            selected: '',
            List:'',
        };
    },
    methods: {
        async getSuggestionList() {
            return await axios.get('/api/tagList')
            .then(res => this.List = res.data )
            .catch((error)=>{
                this.errorMsg = 'Error! Could not reach the API. ' + error
                console.log(this.errorMsg)
            })
        },
    }
}
</script>
```

##ポイント
```form.vue
<vue-simple-suggest
    v-model="selected"         
    :list="getSuggestionList"  
    :filter-by-query="true">
　         <input type="text" name="tag" id="tag" placeholder="入力してください" autocomplete="off">
</vue-simple-suggest>

```
フォームに入力された文字がv-modelに入る
getSuggestionList()APIで引っ張ってきたlistが入る
これがないとうまくサジェストされません
\<vue-simple-suggest>\</vue-simple-suggest>の中に\<input>を実装のもポイント


```form.vue
<script>
import VueSimpleSuggest from "vue-simple-suggest";  //忘れずにインポート
import 'vue-simple-suggest/dist/styles.css';        //忘れずにインポート

export default {
    components: {
        VueSimpleSuggest
    },
    data() {
        return {
            selected: '',  //入力された文字を格納
            List:'',       //getSuggestionList()で引っ張ってきた配列を格納
        };
    },
    methods: {
        async getSuggestionList() {
            return await axios.get('/api/tagList')
            .then(res => this.List = res.data )
            .catch((error)=>{
                this.errorMsg = 'Error! Could not reach the API. ' + error
                console.log(this.errorMsg)
            })
        },
    }
}
</script>
```


#最後に
困ったら公式ドキュメント！
PHP 配列への追加と上書き

簡単にまとめ書き
環境：PHP Version 7.4.13

##まず2次元配列を作ります。

```php

$alphabet = array( "a", array( "b-a", "b-b", "b-c", "b-d"), "c", "d", "e");

var_dump($alphabet);
```

var_dump()関数 に放り込んで配列の構造を表示させます。
（ ↓ ブラウザの画面）

```

array (size=5)
  0 => string 'a' (length=1)
  1 => 
    array (size=4)
      0 => string 'b-a' (length=3)
      1 => string 'b-b' (length=3)
      2 => string 'b-c' (length=3)
      3 => string 'b-d' (length=3)
  2 => string 'c' (length=1)
  3 => string 'd' (length=1)
  4 => string 'e' (length=1)
```

####echoでの表示

`echo $alphabet[4];`　→　`e`
`echo $alphabet[1][2];`　→　`b-c`

`echo $alphabet;`　→　エラー
`echo $alphabet[1];`　→　エラー

配列はechoでは表示されない。


##配列への追加と上書き

イメージしやすいように画像にしました。

![PHP配列への追加と上書き_補完版.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009471/5254e9b9-e0c8-14c2-fdbd-1b970e1d744d.png)





##配列の結合や追加のために用意されている関数

+ array_merge()
+ array_merge_recursive()
+ array_push()

など、結合や追加のために用意されている関数があります。


+ 参考
 +  https://www.php.net/manual/ja/function.var-dump.php
 +  https://qiita.com/shuntaro_tamura/items/784cfd61f355516dfff0
ruby3.0 rails6.1 postgresql + redisなdocker環境を構築する


ruby:latest使ってるので
当然最新rubyになりますが、、、笑

redisはおまけ,
自分はsidekiqに使うので入れておきました。
いらなかったら消してください。

### ディレクトリ構造

```
app
├─ Dockerfile
├─ Gemfile  
├─ Gemfile.lock
└─ docker-compose.yml
   
```

### 各ファイルの中身

```docker:Dockerfile

FROM ruby:latest

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update -qq && apt-get install -y \
  nodejs \
  yarn \
  imagemagick \
  build-essential \
  libpq-dev \
  postgresql-client

WORKDIR /app

COPY Gemfile Gemfile.lock /app/

RUN bundle install

```


```yaml:docker-compose.yml

version: '3'

volumes:
  db-data:
  redis:
  bundle:
  node_modules:

services:
  web:
    build: .
    command: >
      bash -c "rm -f tmp/pids/server.pid &&
               bundle exec rails s -p 3000 -b '0.0.0.0'"
    ports:
      - '3000:3000'
    volumes:
      - '.:/app'
      - 'bundle:/usr/local/bundle:cached'
      - 'node_modules:/app/node_modules'
      - '/app/vendor'
      - '/app/tmp'
      - '/app/log'
      - '/app/.git'
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - db
      - redis
    links:
      - db
  
  db:
    image: postgres
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
    volumes:
      - 'db-data:/var/lib/postgresql/data'
  
  redis:
    image: redis:latest
    command: redis-server
    ports:
      - 6379:6379
    volumes:
      - redis:/data

```

node_modules,vendor,tem,log,.gitはup高速化のためvolumeを作成しました。


```:Gemfile

source 'https://rubygems.org'
gem 'rails', '~> 6.1'

```

```:Gemfile.lock

#　何も書かないでね

```


### アプリ立ち上げ

appディレクトリにて以下のコマンドでapp立ち上げ

rspec使うので skip-testしてますがそこら辺はお好みで！
--forceは強制上書き、
--no-depsはリンクしたサービスを起動しない設定。
--webpackerはwebpacker:installをやってくれます。

```
docker-compose run web rails new . --force --no-deps --database=postgresql --skip-test --webpacker
```

webpackerがインストールできました！
となれば成功です。

次にdatabase.ymlを修正しましょう。

```yaml:database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  user: postgres
  port: 5432
  password: <%= ENV.fetch("DATABASE_PASSWORD") %>
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: product_register_development

test:
  <<: *default
  database: product_register_test

production:
  <<: *default
  database: product_register_production
  username: product_register
  password: <%= ENV['PRODUCT_REGISTER_DATABASE_PASSWORD'] %>

```

修正したら、db:createを実行

```
docker-compose run web rake db:create
```
createできました！
となったら

```
docker-compose up
```
でcontainerとserver立ち上げて成功です！


```
docker-compose exec web bash
```

でコンテナ入って確認してみましょう。
※僕はtest_appという名前でアプリを作成しました。

![スクリーンショット 2021-01-27 19.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/1f1edbe3-9e72-7912-358f-fb4692f2efa1.png)


CMDとかENTRYPOINTとかcommand:とかvolume:とかcontainer_name:とか好きにカスタマイズしてください。

日々精進。
保守性の高いコミットメッセージを書こう


# はじめに
みなさんこんにちは。突然ですが、コミットメッセージを適当な気持ちで書いていませんか？
2,3週間後に過去のコミットのログを見直したときに、何についての変更なのかがわかりづらくて昔の自分を殴りたくなった経験はありませんか？

そんなあなたにとっておきのプラグインを紹介いたします。

# 概要
結論から申し上げますと、[commitizen](https://github.com/commitizen/cz-cli)を使うだけです。

**Commitizenとは?**
CLIを使って対話的にコミットメッセージを作ることができるコマンドラインツールです。


# 導入手順

以下の記事を参考に導入して参ります。

[Commitizenを使ってもうコミットメッセージに迷わない](https://qiita.com/ikedaHi/items/4d205bc950387a1139f2)
[個人開発者のためのコマンドラインGit使いこなし術](https://www.youtube.com/watch?v=1kThUbSdlro&t=803s)



<br>



**①グローバルにインストール**
(ローカルにインストールすることもできますが、今回はグローバルにインストールします。)
以下のコマンド

```zsh
$ npm install commitizen -g
$ npm install -g cz-conventional-changelog
```

**②グローバルのルート直下に.czrcファイルを作成**

```zsh
$ touch .czrc
$ vim .czrc
```

```shell:.czrc
{ "path": "cz-conventional-changelog" }
```

以上です。gitでaddした後に
`$ git cz`
を入力するとcommitizenがスタートし、以下のような対話形式でメッセージを入力する流れとなります。


![スクリーンショット 2021-01-27 18.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612915/819e5534-a786-7157-41eb-2a907552f61d.png)

コミット後に
`$ git log --graph`
を入力すると以下のようにメッセージを含んだlogが表示されます。
![スクリーンショット 2021-01-27 19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612915/32485803-37e9-4c67-8d4a-bca9227c7c0e.png)

# 参考記事

非常にわかりやすかったです。ありがとうございました。

[【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話](https://qiita.com/numanomanu/items/45dd285b286a1f7280ed)
[僕が考える最強のコミットメッセージの書き方
](https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e)

<br>
`[Question] SyntaxError: Parsing JSON at <path> for commitizen config failed:`に対するエラーは以下のissueで議論されていました。
[[Question] SyntaxError: Parsing JSON at <path> for commitizen config failed:](https://github.com/commitizen/cz-cli/issues/465)
緯度経度の情報でポリゴン生成し、GeoJsonに変換してみよう! (Go言語)

# はじめに
この記事では、特定の4箇所の緯度経度からポリゴンを生成し、GeoJsonを作成する方法をまとめたものです。
また、使用言語はGoになります。

# GeoJsonとは？
GeoJSONとは、JSONを基としたGISデータを記述するためのフォーマットです。
Google mapやOpen street mapなどの地図サービスも対応しているため、読み込ませるだけで、エリアを可視化できたり、ポイントの表示が可能となります。

[参考: GIS実習オープン教材](https://gis-oer.github.io/gitbook/book/materials/web_gis/GeoJSON/GeoJSON.html)


# 実装
## orbライブラリ
今回はGoで実装を行なっていったのですが、緯度経度の情報からポリゴンを作成し、GeoJson形式にしてくれるライブラリがあります。
それが[orbライブラリ](https://github.com/paulmach/orb)です。
このライブラリ、[Strava](https://www.strava.com/?hl=ja-jp)でも使われたライブラリのようです。

### ポリゴン
ちなみにポリゴンなのですが、GISのポリゴンというのは、ベクトルデータ(すなわち、座標値を持った点のデータ)で**面**を表現したものを指します。

そのため、ポリゴンを作成する際は、最低でも3つの点を必要とします。

また、注意しなければならないのは、下記のコードのように最初のポイントの緯度経度を最後にポイントとして指定しなければなりません。こうすることで、面を表現できる。

```
p := orb.Polygon{{{Lng1, Lat1}, {Lng2, Lat2}, {Lng3, Lat3}, {Lng4, Lat4},{Lng1, Lat1}}}
```

```main.go
package main

import (
	"github.com/paulmach/orb"
	"github.com/paulmach/orb/geojson"
)

func main() {
	convertGeojeson(35.681, 139.77496, 35.68563, 139.76234,35.67681, 139.76002,35.6751, 139.77165)
}

func convertGeojeson(Lat1 float64, Lng1 float64, Lat2 float64, Lng2 float64,  Lat3 float64, Lng3 float64,  Lat4 float64, Lng4 float64) {

	name := "エリア"
	// ポリゴンの作成
	p := orb.Polygon{{{Lng1, Lat1}, {Lng2, Lat2}, {Lng3, Lat3}, {Lng4, Lat4},{Lng1, Lat1}}}

	// geojsonの作成
	c := geojson.NewFeatureCollection()
	gp := geojson.NewFeature(p)
	gp.Properties["name"] = name

	c = c.Append(gp)
	b, _ := c.MarshalJSON()
	println(string(b))
}
```


```実行結果.geojson
{
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            139.77496,
                            35.681
                        ],
                        [
                            139.76234,
                            35.68563
                        ],
                        [
                            139.76002,
                            35.67681
                        ],
                        [
                            139.77165,
                            35.6751
                        ],
                        [
                            139.77496,
                            35.681
                        ]
                    ]
                ]
            },
            "properties": {
                "name": "エリア"
            }
        }
    ],
    "type": "FeatureCollection"
}
```

## mapに食わせてみる
結果が得られたので、このGeoJsonをmapに出力してみたいと思います。
その時に便利なのが[こちら](http://geojson.io)のサイトです。
GeoJsonを食わせるだけで、mapに表示してくれます。

![スクリーンショット 2021-01-27 13.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/b084f86c-c431-fe8e-7ea7-7b78af2075a9.png)
MPCNC作成のためのお話（その２）-パーツ作成-

##３Dプリンタの用意
MPCNCを作るには３Dプリンタが必要です。
もちろん木材を使って似た形状を作成しても、強度が保てれば大丈夫です。
木製の自作CNCを作っている方もいますので、３Dプリンタの購入意欲が無い方は
検索して参考にしてみても良いと思います。

最近ではそこそこ大きめの３Dプリンタでもかなり安く購入できます。
20x20x20cm程度であれば2〜3万円台程度で購入できると思います。
必ずフィラメントを溶解させて積層するFDM方式のものを使用してください。

３Dプリンタはホームセンターで時間貸ししてたりもしますが、
必ず出力を失敗するので3万円ぐらいのものを購入したほうが安上がりです。


##今回使用した３Dプリンタ
（というかこれしかもって無いです…）

|デアゴスティーニidbox!<br><img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79204/ff414a6f-2fcd-38f5-011d-da68ea9980e1.jpeg" alt="idbox!改" title="idbox!改" itemprop="image" width="画像の幅" align="right"/>|
|:--|
| （以下に換装）<br>・E3D HEMERA エクストルーダー<br>・Voron Design Mobius Extruder (2つ目のエクストルーダー)<br>・E3D Chimera+<br>・BonsaiLabo BS-01ヒートベット<br>・E3D Hardened Steel Nozzle|

デュアルノズルに改造してあり、2つ目の
エクストルーダーもついていますが使用していません。
idbox!は現在は販売されていませんが、
ヤフオクなどで完成品がが意外と安く売ってたりします。
ヤフオクで競り落とす場合は、デアゴスティーニの
冊子部分が付属していることを必ず確認してください。

この冊子は３Dプリンタの仕組みを理解する上でかなりの情報量がありますので、
落札品が壊れていたとしても、この冊子があるだけで自分で直せます。
それとできればヒートベット化されている方が良いです。

##3Dプリンタを使用する上での注意
僕はidbox!を使用しましたが、この３Dプリンタは
ArduinoとRAMPS1.4というコントローラーで出来ています。

このRAMPS1.4けっこう壊れやすく、
RAMPS1.5かRAMPS1.6あたりをAmazonかaliexpress、
banggoodなどで予備を購入しておくことをおすすめします。
休みなく沢山出力するのと、idbox!の排熱の甘さでヤられます。

他の3Dプリンタを購入された方はおそらく大丈夫だと思いますので
一応安心してもらって大丈夫だと思います。
そもそもボードが違ったりします。

|<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79204/1cab5c6c-0b2d-f13c-e508-24de48759656.jpeg" alt="idbox!改" title="idbox!改" itemprop="image" width="画像の幅" align="right"/> |
|:--:|
|未使用のRAMPS1.5とぶっ壊れたRAMPS1.4(赤)とRAMPS1.6<br>そしてそう、もう一つあるのです…今載ってるヤツが…|

idbox!のコントローラボードがヤられたときの不具合としては以下になりやすいです。
・ステッピングモーターのどれかが回らなくなる
・ヒートベットかサーミスタの温度がわからなくなる
・ヒートベットかサーミスタの温度が上がらなくなる

##使用したフィラメント
フィラメントはすべてPETGを使用してました。
・Prusament Prusa Orange PETG
・サインスマート PETG （色々カラー違い）
・RepRapper PETG （色々カラー違い）

※PETGは熱耐性も強く、積層時に反りにくく剛性もあり粘度もありABSとPLAの良いとこ取りをしたような素材ですので、マシン全体が治具のようなCNCを作るにはもってこいです。

##MPCNCデータ
※ここの情報はオリジナルサイトからの引用で日本ローカライズしています。

今回作るburlyのリンク先です
https://docs.v1engineering.com/mpcnc/burly/
MPCNCはthingiverseという有名な３Dデータの共有サイトで配信されています。
https://www.thingiverse.com/


種類としてはスチールパイプのサイズに合わせてC,F,Jの3種類存在します。
ダウンロード - [パイプサイズ23.5mm (“C”) パーツファイル](https://www.thingiverse.com/thing:724999)
ダウンロード - [パイプサイズ25mm (“F”) パーツファイル](https://www.thingiverse.com/thing:790533)
ダウンロード - [パイプサイズ25.4mm (“J”) パーツファイル](https://www.thingiverse.com/thing:1671517)

 **強化パーツ**
以下の強化パーツにはじめから換装させました
ダウンロード - [Fタイプ フットパーツ](https://www.thingiverse.com/thing:3468440)
ダウンロード - [強化パーツ](https://www.thingiverse.com/thing:2531659)　←こちらは「RollerPlate.stl」のみ使用しています。



僕は25mmパイプを使用したのでFを選びました。手に入りやすいスチールパイプを選んでください。
たわみの少ないもののほうが精度が上がりますので、強化パイプや同サイズのシャフトでも良いですが、値段はそれなりに上がります。
またシャフトや内部の梁に隙間の無い強化パイプを使うと、パイプと違い配線を内部に通せないので、線を上に釣ったりと余計な作業や出費も必要になります。

３Dプリンタで作成するパーツは必ず必要なので、スチールパイプやボルト、ベアリングなどの金物類を揃える前に作ってしまって大丈夫です。
その上で実際に作りたいMPCNCのサイズを決めて金物類を購入しましょう。

次回は金物類の調達になります。

次回　[金物類の調達](https://qiita.com/nyos/items/f4c3d646480c9f0d0b5c)
衛星画像ファイルをNumpy Arrayの形で保存する方法(Python)

##概要
こんにちは。
　衛星リモートセンシングの分野では大量の画像を扱うことがありますが、GeoTiffなどの位置情報付きのものは専用のソフト（QGIS)などで扱うことが主だと思います。数十枚までならば気合で処理することもできますが、数百～数千枚になると非常に険しいのでPython等で自動化したい気持ちが湧いてきます。特にNumpy arrayの形は統計手法や機械学習手法を用いる際のベースとなるので、この形で取り込めると便利ですね。また衛星画像解析では時系列の情報も大切になりますが、変数に逐一"~_2019"と付けるのも大変です。
　以上を踏まえて、画像が格納されているフォルダから画像ファイルをNumpy arrayの形で読み込み、それを辞書型配列に画像の取得年と一緒に格納するコードを書いたので、ご紹介したいと思います。

##環境と前提条件
1. Google Colabで実行 (記事執筆時点でのバージョンはpython 3.6.9)
2. ファイル名は"~YYYYMMDD~.geotiff"の様に取得年を含む形になっていることが前提条件です
3. ファイルパス等についてはご自分の環境に合わせて変えて頂ければ（多分）動くと思います。Google Colabは個人的にとても便利だと感じているので、是非この機会に手を出されてみるのもオススメです！<br>

[Colab入門編](https://qiita.com/shoji9x9/items/0ff0f6f603df18d631ab "Google Colabの使い方まとめ") <br>


##コード
最初に必要なモノをインポートしましょう。<br>

```python:import.py
from osgeo import gdal
import numpy as np
import glob
import os
import pandas as pd
```
ファイル名を取得して年ごとに辞書型配列にしまっておきます。例では2001年から2020年までのMODIS衛星のプロダクト画像を使う準備をしています。ここを変えれば違う年についても大丈夫だと思われます。ソートをかけているのは、これが無いとファイル順がカオスになってしまうからです。ワイルドカードで特定の年に合うファイル名を探しつつ、forループでぐるぐる回しています。"/content/drive/My Drive/Colab Notebooks"はColabからDriveのファイルを使う際に特有の書き方なので、ここを変えればColab以外でも動くのではないでしょうか。<br>

```python:filename.py
for y in range(2001,2021):
  filenames=[os.path.basename(p) for p in \
sorted(glob.glob(f'/content/drive/My Drive/Colab Notebooks/satellite_data/MODIS.2001-2020.FRP.Buryat/L3/MODIS.{y}*.geotiff', recursive=True)) \
if os.path.isfile(p)]
  list_of_filenames[f"{y}"]=filenames
```

画像をnumpy行列へ格納していきます。画像が重かったり、沢山ある場合にはそこそこ時間がかかると思います。gdalでファイルを開いて、Arrayとして読み込んでいきます。グレースケール画像を使っていたのでバンドを一つしか読んでいません。前段階でソートをかけているので、日時についてはfor文で頭から順番に読んでいきます。途中でコメントアウトしてあるprint(FName)を使うことでファイル名が書かれていくと思うので、これによって順番通りに処理されているか確認されても良いかもしれません。

```python:array.py
database_array={}
for year in list_of_filenames.keys():
  ArrayList=[]
  for day in range(len(list_of_filenames[f"{year}"])):
    FName=list_of_filenames[f"{year}"][day]
    #print(FName)
    File=gdal.Open(f'/content/drive/My Drive/Colab Notebooks/satellite_data/MODIS.2001-2020.FRP.Buryat/L3/{FName}')
    FileAsArray=File.GetRasterBand(1).ReadAsArray()
    ArrayList.append(FileAsArray)
  database_array[f"{year}"]=ArrayList
```

処理が終わると、辞書型配列として画像が格納されているかと思います。
配列の格納にはそこそこ時間がかかるので、以下の様にpickleとして保存しておいてもいいかもしれません。

```python:save.py
pd.to_pickle(database_array,'/content/drive/My Drive/Colab Notebooks/outputs/pickle/database_array.pkl')
#再度の読み込みも簡単
#database_array=pd.read_pickle('/content/drive/My Drive/Colab Notebooks/outputs/pickle/database_array.pkl')
```

以上が記事の内容です。初投稿なので色々と至らなかった点も多いと思いますが、今までお世話になったQiitaコミュニティへと少しでも貢献できていたら幸いです。
Mockeryでクロージャを実行する関数を使っているメソッドをテストする

例えばLaravelのトランザクションみたいなやつ

```php
return $this->dbManager->transaction(function () {
  return some;
});
```

こういうコードがあるメソッドに対して、`dbManager`を[Mockery](https://github.com/mockery/mockery)で差し込んだとします。
その場合以下のように書くとモックできる

```php
$mockDbManager = Mockery::mock(DatabaseManager::class);
$mockDbManager->shouldReceive('transaction')
    ->andReturnUsing(function($closure) {
        return $closure();
    });
```

Facade使ってたらそもそもモックの必要もないのだが、依存しているものはなるべくコンストラクタから注入したいよね！
ではまた。
Rubyでバイナリーリサーチ（二分探索）の実装

※2022年から技術系の記事は[個人ブログ](https://yamaday0u.net/category/programmer/)に投稿しております。ぜひこちらもご覧ください→[yamaday0u Blog](https://yamaday0u.net/category/programmer/)

スクールのドリルでだいぶ苦戦したのでバイナリーリサーチの実装方法について整理します。

```rb
def binary_search(array, right, target)
  left = 0
  while left <= right
    # 要素の左端と右端を足して二分した値をcenterへ代入
    center = (left + right) / 2
    if array[center] == target
      # centerで指定した位置の配列の数字と検索したい数字が一致すれば
      # centerを返す
      return center
    elsif array[center] < target
      # centerで指定した位置の配列の数字より検索したい数字が大きい場合、
      # centerに１を足した数値を左端の位置を表すleftに代入
      left = center + 1
    else
      # centerで指定した位置の配列の数字より検索したい数字が大きい場合、
      # centerから１を引いた数値を右端の位置を表すrightに代入
      right = center - 1
    end
  end
  # 検索したい数字が配列の中の数字と一致しなかった場合、-1を返す
  return -1
end

array=[1,3,5,6,9,10,13,20,26,31]
number_of_elements = array.count

puts "検索したい数字を入力してください"
target = gets.to_i

result = binary_search(array, number_of_elements, target)

if result == -1
  puts "#{target}は配列内に存在しません"
else
  puts "#{target}は配列の#{result}番目に存在します"
end
```

たとえば26を検索したい場合、以下の動きをします。

```rb
# whileの1回目のループ
center = ( 0 + 9 ) / 2 = 4 # 計算結果の小数点以下は切り捨てられる
array[4] = 9 < 26
left = 4 + 1 = 5

# whileの2回目のループ
center = ( 4 + 9 ) / 2 = 6
array[6] = 13 < 26
left = 6 + 1 = 7

# whileの3回目のループ
center = ( 6 + 9 ) / 2 = 7
array[7] = 20 < 26
left = 7 + 1 = 8

# whileの4回目のループ
center = ( 8 + 9 ) / 2 = 8
array[8] = 26 == 26
return 8

# 実行結果=>"26は配列の８番目に存在します。"
```
脆弱性対応の管理ポイント

私の現場では、脆弱性対応に関するフローや対応策が確立できていません。
気づいた人ベースで発信され、深刻度合いで対応するかしないかをお客様が決定します。

この、「気づいた人ベース」をしっかり運用フローに乗せることを考えて行きたいと思います。

# そもそも脆弱性対応をする意義

脆弱性をついたサイバー攻撃により、企業の重要な情報が外部に漏洩することや、サイト停止に伴う売上や信頼の低下を防ぐことだと思います。

攻撃側を考えると、脆弱性発生後に脆弱性の内容を元に、攻撃プログラムが作成されるため、一定の期間は要します。
この間に、攻撃を未然に防ぐことが重要になります。なので、脆弱性情報の収集は必須となってきます。

統計的には、実際に攻撃までに繋がる脆弱性は2%にも満たず、攻撃プログラムが公開されるまでの日数は、２週間以内が50%を占めているそうです。
なので、全ての脆弱性を対応するのは非効率であって、深刻な脆弱性を見極めて対応していくこと重要となってきます。

# パッチマネジメント

システム構成を把握している前提で、構成要素ごとに関連する脆弱性情報を早く検知し、影響範囲の特定とリスクの分析によって適用の緊急性と対応用ひを判断し、判断結果を元に対応する一連の流れ。

❶検知
ベンダ、有識者、業界団体などから発信される脆弱性情報を収集し、システム構成要素に対する影響を評価

❷判断
脆弱性に起因するリスクの大きさと攻撃手法の容易性を分析し、対応の緊急度と対応要否を決定する

❸対応
対策方法と実施時期を確定し、攻撃を受ける前に、脆弱性によるリスクを下げる。

# 対策
## 検知
検知の部分に関しては、ベンダ（AWS）の[脆弱性情報サイト](https://alas.aws.amazon.com)があるのでそちらで、通知機能をSlack通知で検知できるようにしている。
その他は、Twitterの有識者やベンダのフォローをして、自主収集する形をとっている。

このSlackへ全員を招待させることで、検知に関しては解決すると思っている。
全員に通知する必要はないかもしれないが、セキュリティ担当が確立されていないので、一旦全員に通知。


## 判断
判断に関しては、緊急性判断は、CVSSを用いた考えが一般的。
CVSSとは、脆弱性に対するオープンで汎用的な評価手法、及び指標を指します。
1.0〜10.0の数値指標となっていて、7.0以上が緊急度：Highに値します。
緊急度：Highであり、他社でも被害が出ている状況であると、即座に対応が必須な状況であります。

だが、大体的に報道される脆弱性の悪用は、直接的被害に留まらず風評被害などのに二次的な被害につながりやすいです。

### 実際にあった脆弱性
#### sudo
https://access.redhat.com/security/cve/CVE-2021-3156

`CVSS 7.0 High`
他社影響はなしだけど、ベンダから情報発表はあり

要確認の脆弱性となる。

## 対応
対応策としては、パッチ適用、ワークアラウンド（設定変更やWAFによる通信遮断）、一時的なサービス停止などがあります。
これらを比較して、最良な選択をすることが大事になってくる。

それでも対応結果が追跡しきれず、時間がかかってしまう場合は、システムごとの対応状況の一元管理が必要となってきます。
資産管理台帳をもとに、脆弱性対応の指示や報告を実施して、常に最新情報を集約できるようにしておくこと。

情報集約度、情報鮮度、検索容易性の観点から管理や統制パターンが分かれるそうです。

・情報集約度
システムの構成情報が集中管理されているか

・情報鮮度
構成情報が常に最新の状態が保たれているか

・検索容易性
脆弱性を検知後、迅速に対象となるシステムを一覧化できるか

# 踏まえて
現状、脆弱性の集約から判断や対応に関しては有識者の方で、なんとか実施できているが。
いない時を考えると恐ろしいので、運用フローには乗せて行きたい。
メインシステムは、WAFの導入をしているので大半は大丈夫である気がするが、抜け道もある気がする。
情報集約度の観点からすると、システム構成の集中管理はできていない状況なため、大規模な脆弱性が起きた場合に、迅速に対応する体制はできていない。

まず、手をつけるとしたら、この「システム構成の集中管理」が第一優先だと思いました。
Bootstrapの基礎①

#デイトラWeb制作コース初級編DAY10の学び

# 【この記事に書いてあること】
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">プログラミング学習10,11日目⏩<br><br>Web制作コース　初級編DAY10　💻<br><br>学習時間:25分⏳<br><br>学習内容:Bootstrapの基本を学ぶ✏<br><br>学び📚<br>・BootstrapはHTMLのclass名に書くだけで、CSSが反映される<br>・Bootstrapを使用するには、専用のスタイルシートを読み込む必要がある<a href="https://twitter.com/hashtag/%E3%83%87%E3%82%A4%E3%83%88%E3%83%A9?src=hash&amp;ref_src=twsrc%5Etfw">#デイトラ</a><a href="https://twitter.com/hashtag/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%88%9D%E5%BF%83%E8%80%85?src=hash&amp;ref_src=twsrc%5Etfw">#プログラミング初心者</a> <a href="https://t.co/EyymHvD6cp">pic.twitter.com/EyymHvD6cp</a></p>&mdash; ふりっく💻トリプルゼロの（これから）フリーランス (@FuRiC_twi) <a href="https://twitter.com/FuRiC_twi/status/1353807120341282817?ref_src=twsrc%5Etfw">January 25, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#　【学習時間】

25分

#　【学び】

1　Bootstrapの使い方
Bootstrapを使用するには、専用のスタイルシートを読み込む必要がある

```index.html
<!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
```

2 よく使うBootstrapのclass名

・文字の色を変える（青）：```text-primary```

・文字を中央に置く：```text-center```

・文字を左右に置く（右）：```text-right```

・文字を太くする：```font-weight-bold```

・文字を細くする：```font-weight-light```

・文字の背景に色を付ける（青）：```bg-primary```

・フォントをサイズを変更する(一番大きい)：```display-1```

## ↓

![スクリーンショット 2021-01-27 18.40.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1028584/e85ba47e-d282-dfd7-b9fc-698e3d6b84bd.png)



3 Bootstrapのclass名は公式サイトのドキュメントに掲載してある
参考サイト: [Bootstrapドキュメント](https://getbootstrap.jp/docs/5.0/getting-started/introduction/)

https://getbootstrap.jp/docs/5.0/getting-started/introduction/
laravel 認証機能でログイン後のリダイレクト先を変更する

#はじめに
laravelで認証機能をmake:authで作成する際にリダイレクト先が設定されています。また、`middlewareでログインしないと任意のページに遷移できないように設定済`です。
今後新たなwebアプリケーションを作成する可能性が高いので任意のページを変更してみたいと思います。

#やってみること
ログインすると任意のページにリダイレクトを設定する

###投稿者の環境
MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
macOS Big Sur バージョン11.0.1
PHP 7.3.23
Laravel Framework 6.20.7

#リダイレクト先を変更してみよう
###ステップ1
HTTP->Middleware->RedirectIfAuthenticated.phpを編集する。
フォルダの構成はこのようになっている。![“スクリーンショット” 2021-01-27 18.12.25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/9cf7c1ad-a2b1-797b-5b35-0e72533ba96a.jpeg)


```RedirectIfAuthenticated.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/home'); //こちらを変更する
        }

        return $next($request);
    }
}

```
###コードの編集
```RedirectIfAuthenticated.php
return redirect('/home');
//以下のように変更する
return redirect('online_reviews/hospital_list/index');

```

###ステップ2
Authフォルダ->LoginController.phpを編集する。

```LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';//ここを編集する。

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

```
###コードの編集
```LoginController.php
protected $redirectTo = '/home';
//以下のように変更する
protected $redirectTo = 'online_reviews/hospital_list/index';
```
以上でコードの編集は終了です。無事にリダレクト先が変更されましたか?

#解説
ルーティングの設定で`web.php`を見てみます。一番上に記述している`group``'prefix'`をしているため`'online_reviews'`を記述する必要がありません。`その反面、リダイレクト先を設定するにはこの記述を記述しないとエラーが発生します。`
groupとprefixに関しては[こちらのページ](https://qiita.com/ntm718/items/95eee03f5294d0c351b0)を参考にして下さい。


```web.php
Route::group(['prefix' => 'online_reviews','middleware' => 'auth'], function(){
  Route::get('hospital_list/index','OnlineReviewsController@index')->name('online_reviews.hospital_list'); 
 //以下省略
```
#最後に
初めての試みだったので試行錯誤の連続・・・
認証機能は自動で作成できる反面、カスタマイズが難しい・・・
ログイン機能をもっと充実させるようにがんばります!!
[TypeScript]配列とタプルの違い

タプルとは・・・
　=>　複数の型の集合（KotlinのPairのようなイメージ） 

```typescript
type Array = {
    hoge1: string,
    hoge2: number,
}[];

type Tuple = [{
    hoge1: string,
    hoge2: number,
}];

```
ググって出てきた正規表現がさっぱり理解できない時に使えるハック


ググって出てきた正規表現がさっぱり理解できない時に使えるハックです。
正規表現のみたこともないやつ、たくさんあると思います。

例えばとある接頭語から”始まらない”バリデーションを書きたいとする。

以下のようにググりました。
`check not start with prefix regexp`

このstack overflowが最初に出てきました。
https://stackoverflow.com/questions/2116328/regexp-matching-string-not-starting-with-my

どうやら
`^(?!my)\w+$`
この表現が使えそうです。

`?!`の表現なんてみたことないです。

ここで活躍するのがこのサイト => https://regex101.com/
正規表現書いたことある人は絶対ブックマークに入れたほうがいいです。


どうやら意図通りに動きそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/7d0bc6cb-59e3-1ecc-e082-62f8e3f3bf4e.png)


でも裏を取らないと、本当に意図としてあっているのか不安です。
実は右のほうに、その表現がどういう名前で呼ばれているか書かれています。

![貼り付けた画像_2021_01_27_18_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/de8cd995-01d2-2aea-71eb-db3d696d26a9.png)


なので、`Negative Lookahead`で改めてググると、以下の解説サイトが出てきました。
https://ja.javascript.info/regexp-lookahead-lookbehind

めでたしめでたし。
WindowsPC内のJavaのバージョン変更

仕事の関係でJava12が入っていたPCにJava8を入れることになったので、作業備忘録。

##ダウンロードとインストール
　これは分かりやすい記事がたくさんあるので、他の記事を参考にしてください。
　<font color="red">必ずJDKとJREの両方をダウンロードしてください</font>
##JREとJDKのシステム環境変数登録
　【ユーザーの環境変数】に以下の内容を登録。
　　変数：JAVA_HOME
　　　値：JDKのディレクトリ
　　　　　→下の図の例だと「C:\Program Files\Java\jdk1.8.0_281」
　　　<font color="red">※変更前のものは変数から消すか上記を上書きしてください</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/bb7b1eda-901b-47d9-f431-28edacf762b4.png)
 【システム環境変数】の【Path】内にJREのbinディレクトリのパス
　　→下の図の例だと「C:\Program Files\Java\jre1.8.0_281\bin」を登録
　<font color="red">※変更前のものは消すか上記を上書きしてください</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/e2e5f75b-f087-a976-3a40-3df81f2c439b.png)
##正しく変更されているかの確認
　・「ウィンドウズキー」＋「R」を押して「cmd」と打ってコマンドプロンプトを立ち上げる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/91598643-8b87-f8e3-a3d1-c30df80aa0c5.png)
　・コマンドで「java -version」と「javac -version」と打って表示されるバージョンが今回ダウンロードしたバージョンと同じだったらOK！
　　<font color="red">※「java -version」ではPCが採用しているJREバージョン、「javac -version」ではPCが採用しているJDKバージョンが表示されます。</font>
　　<font color="red">※もしこれらが正しく表示されていない場合は、環境変数でのディレクトリ指定に誤りが無いか確認してください。</font>

以上、自分では滅多にやらないJavaのバージョン変更に関する備忘録でした。
【Python】create_sheetメソッドの引数で、作成されるシートの位置を変更する。

Pythonのライブラリであるopenpyxlを使用してExcelのシートを増やす場合
create_sheetメソッドを使用しますが
作成されるシートはブックの末尾に作成されてしまうようです。
任意の場所に作成したい場合
create_sheetメソッドのindex引数を使用します。

```python:例
from openpyxl import Workbook

count = input('全シート数: ')

wb = Workbook()
ws = wb.active
ws.title = '概要_1'

for i in range(2, int(count) + 1):
    wb.create_sheet(title=f'概要_{i}')

wb.save('資料.xlsx')
```
こちらを

```python:ブックの先頭に作成したい場合
    wb.create_sheet(title=f'概要_{i}', index=0)
```

```python:2番目に作成したい場合
    wb.create_sheet(title=f'概要_{i}', index=1)
```

こちらのように変更します。
地味ですが、覚えておくと後々便利だなと思えました。
AWS Cognitoのユーザープールにて発行・使用されるトークンに関して調べてみた

# 調査結果

以下はOAuth2.0にて定義されている。
- アクセストークン
- リフレッシュ(更新)トークン

以下はOpen ID Connectにて定義されている。
- IDトークン

# 調査した経緯

AWS Cognitoで認証を行うアプリを作成する機会があったのだが、使用しているトークンがCognito特有のものなのか、一般的に定義されている仕様なのかがわからなかった。
これによって、実装時のクラス(インターフェース)分けに影響が出る可能性もあると考え、調査を行った。

# 調査した内容

AWS Cognitoのユーザープールで使用するトークンに関して調べて見ると、以下のサイトにたどり着いた。
このサイトを読んで、Open ID Connectに準じていることが判明。
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html

次にOpen ID Connectについて、AWSのサイトに記載されているリンクから仕様を確認。
https://openid.net/specs/openid-connect-core-1_0.html

仕様からOAuth2.0を拡張したものということが判明。

最後にOAuthについて以下のサイトで勉強し、調査結果にたどり着いた。
https://openid-foundation-japan.github.io/rfc6749.ja.html
https://murashun.jp/article/programming/oauth2.html
bulletml.jsの研究 その7

#概要

bulletml.jsの研究です。
技を調査。

#全方位


```
<bulletml>
	<action label="top">
		<repeat>
			<times>22</times>
			<action>
 				<fire>
  				<direction type="aim">-30</direction>
	  			<bullet>
						<action>
 							<changeDirection>
  							<direction type="sequence">0</direction>
  							<term>0</term>
 							</changeDirection>
						</action>
					</bullet>
 				</fire>
				<repeat>
					<times>35</times>
					<action>
 						<fire>
  						<direction type="sequence">10</direction>
	  					<bullet>
								<action>
 									<changeDirection>
  									<direction type="sequence">0</direction>
  									<term>0</term>
 									</changeDirection>
								</action>
							</bullet>
 						</fire>
 						<wait>0</wait>
					</action>
				</repeat> 
 				<wait>120</wait>
			</action>
		</repeat>
	</action>
</bulletml>


```


n-wayの派生型で、全周に向けて一斉に発射する攻撃です。

#成果物

https://embed.plnkr.co/plunk/xXUfQnSvcRNBfeTd


以上。
pug内のパスをnodeの開発環境で切り替える


テスト環境/本番環境でディレクトリ階層が違というプロジェクトがあり、pugの変数をビルドのたびに手動で切り替えるようにしていました。
「nodeでビルドするんだからnodeの環境開発で切り替えれるっしょ！！」
と思ってやってみたらやっぱり出来たので、備忘録として書き残しておきます。

## 環境
- pug ^3.0.0
- html-webpack-plugin ^4.5.1
- pug-loader ^2.4.0

pugは、`pug-loader`。`html-webpack-plugin`を用いてwebpack内でビルドしています。
ここでのミッションは、**webpack経由でどうやってpugに環境変数を埋め込むか？**です。
（下記の方法はpug出なくても素のhtmlでも可能です。）



## pug内に環境変数を埋め込む

```js
  plugins: [
    new HtmlWebpackPlugin({
      title: 'My App',
      filename: 'assets/admin.html'
    })
  ]
```

これを


```js
  plugins: [
    new HtmlWebpackPlugin({
      title: 'My App',
      filename: 'assets/admin.html',
      environment: process.env.NODE_ENV
    })
  ]
```

こうですね。environmentはドキュメントなどにある提供されているプロパティではなく勝手につけたプロパティのようです。
つまり `foo` でも `test` でもなんでもOKです。

```pug
- var appEnv = htmlWebpackPlugin.options.environment;
```
pug内で上記のよう先ほど追加したプロパティ経由で `process.env.NODE_ENV` にアクセスすれば、dev/proでpugを分岐出来ます。

もちろん、コマンドを叩くときはNODE_ENVのセットを忘れずに。

```package.json
"dev": "NODE_ENV=development webpack --mode production",
"build": "NODE_ENV=production webpack --mode production"
```

### 追記
ちなみに modeを指定した場合、コマンドで指定した `NODE_ENV`は無視されて
mode production ではprocess.env.NODE_ENVに`production`が、
mode developmentではprocess.env.NODE_ENVに`production`が入ってしまいます。
これをやめたい場合、webpackにoptimizationの`nodeEnv`をfalseにし、
DefinePlugin経由でNODE_ENVを渡してあげるといいです。

```js:webpack
optimization: {
 nodeEnv: false,
},
```
```js:webpack
plugins: [
  new webpack.DefinePlugin({
     NODE_ENV: JSON.stringify(process.env.NODE_ENV),
  }),
],
```

```js:js
console.log(`node_env: ${NODE_ENV}`) // NODE_ENV=test とコマンドで叩くと testが取得できる
```


## おまけ HTMLでは？

```html

<body class="<%= htmlWebpackPlugin.options.environment %>">
```

## 参考サイト
https://stackoverflow.com/questions/39902197/how-can-i-pass-webpack-environment-variables-in-html
LinuC level1の学習

LinuCレベル1の受験にあたって勉強について、私は以下の講座を受講したので紹介していこうと思います！

Linuxサーバー構築入門（LinuCレベル１ ver. 10対応）
https://www.udemy.com/course/linuc_level1/

まず、私はあまりLinuxの知識が少なく、LinuCの参考書から買おうかと思いましたが、
未だそんなに参考書の種類がないということと、動画で初歩から学んだ方が抵抗が少ない
かなという理由でこちらを受講しました。

ある程度Linuxの知識がある方には新規で学べる内容は少ないかもしれませんが、
私のような初心者には内容的にはちょうどよかったかなと思います。

cd, ls, chmodなど基本中の基本のコマンドから一つ一つ丁寧に実際にコマンドを
打って動作を確認しながらの講義だったので、大分イメージはしやすかったです。

講義で解説される環境はCentOSとUbuntuです。
その他、RedhatやAWSについて簡単な紹介があります。

講義の動画は6時間ほどです。
私は現在一通り、視聴したので、次はpingTの無料のLinuCの模擬試験を何回か回して、
また復習がてら動画を視聴しようかなと考えてます。

まずLinuxの勉強で何をしたらいいのか分からない人にはちょうどいいものではないかと思います！
ネストが深くなるWidgeを視覚的に見れる「FlutterのDevTools」の開き方

#はじめに
**FlutterはとにかくWidgetが深くなりすぎて、どこで何をしているのかわからない！！**という状態がよくあるかと。。。

そんな時はWidgeの階層を視覚的に見れる「DevTools」を使いましょう。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ネストが深くなりがちなFlutterのWidgetを、視覚的にわかりやすく見れるだけでDevToolsの価値はある！ <a href="https://t.co/mLpg2aZgao">pic.twitter.com/mLpg2aZgao</a></p>&mdash; 高卒プログラマーげんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1354352882850533377?ref_src=twsrc%5Etfw">January 27, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#前提
エディタはVSCode
・ [Dart extension](https://marketplace.visualstudio.com/items?itemName=Dart-Code.dart-code)
・ [Flutter extension](https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter)
上記２つがVSCodeにインストール済み

#DevToolsの開き方


##デバッグモードで起動
![スクリーンショット 2021-01-27 17.30.03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/c10b054f-f40a-9d27-883b-8625ebaaad84.jpeg)


下がオレンジ色になればOK
![スクリーンショット 2021-01-27 17.44.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/edad8ca8-85dd-7fee-16d6-2f706a81bc15.jpeg)



##「dart dev」で検索
VSCodeのショートカットキーの設定がデフォルトならば（macの場合）`command + p`でファイル検索のタブが出現します。
![スクリーンショット 2021-01-27 17.45.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/eb36a708-4919-e69c-3701-331d54a46b1d.jpeg)

DevToolsを選択

何を開くか？を聞かれるので、適当に選ぶ。
（おすすめはWeb Browserです。VSCodeの画面内だと小さい・・）
![スクリーンショット 2021-01-27 17.45.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/2e013c25-7516-6234-c05a-88423781841a.jpeg)

##「Select Widget Mode」を有効にする
![スクリーンショット 2021-01-27 17.54.33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/20778466-2955-4dfa-095b-5c152a899e4b.jpeg)
これでどのWidgeがどんな状態か？を視覚的に把握することができます！:thumbsup:




#参考
https://nekodeki.com/flutterのdevtoolsを使ってみた/

公式はこちら:point_down:
https://flutter.dev/docs/development/tools/devtools/vscode
React.js + sqlite3 + Material-ui でSPAを作るプロジェクトの準備（構築）

# はじめに
限られたLAN内で動作するSPAを作りたかったので、[サーバーをセットアップ](https://qiita.com/tomofu74/items/831b05849ed60c5c569f)し、ReactでSPAを開発してみる。ちなみに筆者は初Reactだ。いつもならVue.jsで作ろうかって話になるんだけど、今はVue3が出たばかりでUIライブラリが整ってない。今後長く使うSPAになりそうだから、息の長そうな開発環境に手を出してみたのだ。

# 準備
今回は、Raspberry pi zero W をサーバーにする。Swapは大きくしておこう。

　　参考：　Raspberry Pi のスワップ領域拡張
　　https://qiita.com/nyas/items/f4d0675061ee8cdcc3e7

/etc/dphys-swapfile の CONF_SWAPSIZE はデフォルトで100となっている。1024ぐらいにしておこう。それから、nodeのバージョンは、10か12の偶数のもので。eslint-typescriptがインストールできるように（[create-react-appでReact環境構築について](https://teratail.com/questions/312103)）。npm や yarn が動いたときに、インターネット上から関連するモジュールを取得するみたいなので、インターネットに接続されていることが前提。

sshでサーバーにログインし、任意のプロジェクトフォルダを作ってそこにアプリを構築。srcファイルを書き換えて作っていこう。プロジェクトではsqlite3を使ってデータ管理できるようにしよう。あと、UIはオーソドックスでもいいからきれいなやつを使いたいな・・・、ということで今回はMaterial-UIを使う。・・・というようなざっくりとした構想でスタート。


### プロジェクトの構築
公式の説明を参照。「新しいシングルページアプリケーションを作成するのに最も良い方法です。」という [Create React App](https://ja.reactjs.org/docs/create-a-new-react-app.html#create-react-app)に従う。

```
# 任意のフォルダに移動（プロジェクトフォルダの親フォルダ）

$ npx create-react-app myapp
```

しばらく待つ。私の環境では２０分ぐらいかかったが、マシンによってはあっという間なんだろうな・・・。

### パッケージの追加
さて、プロジェクトフォルダが用意できたところで、似たようなことをすでに行っている先達の手順を参照、確認させていただく。何事も先達はあらまほしきことなり。今回の先輩はこちら。

　　Raspberry Pi Zero WでNode.js＋SQLite3を動かしてみた
　　https://qiita.com/s-suefusa/items/6f4b1df1781c82999816

私の環境では、nodebrewのインストールは不要なのでそこは省略。あくまで参考。丸パクリではない。

とりあえず、プロジェクトフォルダに入る。

```
$ cd myapp
```

#### sqlite3
sqlite3を使えるようにしていこう。

```
$ npm install sqlite3 --save
```

-gオプションでグローバルにインストールするか、とも悩んだが、サーバーの故障や拡張のときにプロジェクトのバックアップからのリストアを行いやすいように、--saveでプロジェクトに含める形でセットアップすることにした。

ちなみに、Raspberry Pi OS lite だったため、sqlite3 をソースからビルドしてくれて、インストールに小一時間ほどかかる。

#### Material-ui
アプリ開発でUI構築はラクしたい～。ポピュラーらしい Material-UI を使ってみよう。

　　ポピュラーなReact UIフレームワーク（Material-UI）
　　https://material-ui.com/ja/

　　material-uiを使ってかっこいいuiのreactアプリケーションを作ってみた
　　https://blog.takanabe.tokyo/2015/12/material-uiを使ってかっこいいuiのreactアプリケーションを作ってみた/

　　React入門 ～Material UI編～
　　https://zenn.dev/h_yoshikawa0724/articles/2020-09-24-react-material-ui

```
$ yarn add @material-ui/core
```
これもまた小一時間ほどかかる。

#### Reactアプリのディレクトリルート/package.jsonに下記の一文を追加する。
忘れないうちにやっとこう・・・。参考情報は次の通り。

　　create-react-appで作成したReactアプリをWebサーバにデプロイする手順
　　https://qiita.com/matoruru/items/04dc2a325c317e9c50ae

## 開発環境
開発環境としては、このサーバー上のnodejs react プロジェクトを、リモートのVSCODEで開くとかしていじっていこうと思う。

# おわりに
Raspberry pi zero W では、React + sqlite3 + Material-ui のプロジェクトを準備するだけで、３時間弱の時間がかかった。Raspberry pi zero W が、今回作るWEBアプリサーバーとして実働負荷に耐えうるかどうかテストもかねて進めているプロジェクトだが・・・。気長にやろう・・・。
互換性のないドライバを削除する

# 経緯
Sysprepでマスタ配信後、ドライバをインストールするとエラーのある項目がある。
よくよく見てみると、どうやら互換性のないデバイスドライバが当たっているらしい。
適切なデバイスドライバを当てるために、ドライバを削除する。

# デバイス マネージャでの操作
ドライバの更新をしたらなんか解決した。
あとデバイスをアンインストールしてリロードしたらなんか解決した。

# 自動化する
マスタ展開したPC1台1台にデバイスマネージャでポチポチするのは地獄なので自動化する。
ドライバの更新はオンラインが前提であるため、後者のデバイスのアンインストールを行う方針で行く。
devcon.exeを利用する。

# 複数のドライバが当たっている際の考慮
確認したところ、ドライバが2種類当たっており、互換性のないバージョンのドライバが適用されているように見えた。
適切なドライバは確保しているため、ドライバは全部抹消して良い前提とする。

# 手順
### ハードウェアIDを調べる
デバイスマネージャで調べます

### デバイスドライバのファイルを調べる
なんかよくわからないが削除時には`oem{enum}.inf`って指定するらしい。それを特定します。

```
.\devcon driverfiles {HardWareID}
```

### デバイスを削除する
先にデバイスを削除しないとドライバを消せないっぽい。(一応forceオプションもあります)

```
.\devcon remove {HardWareID}
```

### デバイスドライバのファイルを削除する
```
.\devcon dp_delete {DriverFile}
```


##Powershell
```powershell:delete_drivers.ps1
$HWID  = "ACPI\VEN_XXXX&DEV_XXXX"
$targ  = .\devcon driverfiles $HWID

.\devcon remove $HWID

$reg   = new-object regex("oem.*?\.inf")
$reg.Matches($targ) | %{.\devcon dp_delete $_.value}
```

# 最後に
適切なドライバをインストールする。エラーが無くなってHappy。
【rails】忘れがち！！localhostサーバーのプロセスが切れない時！！

今回はターミナルでローカルサーバーを起動した時に出るトラブルを対処した時のお話です。

たまになるのですが忘れるのでメモメモ！！

```ruby:ターミナル
rails s
```

とした時に！！

```ruby:ターミナル
Run rails server --help` for more startup options
```

と出た時のお話ですね(*´∇｀*)

結論的にはkillコマンドなのですが、毎回その番号がどこにあったかを忘れてしまいます(アルツ？)

どこだったかな？とゴソゴソしていましたが見つけましたw

```ruby:tmp>pids>server.pid
<ここに出てきるプロセス番号！！>
````

このプロセス番号にkillコマンド！！

```ruby:ターミナル
kill -9 プロセス番号
```

これでrails sをすると再起動ですね(*´∇｀*)
git push -u origin main の実行でエラー

Winodows 1p Pro (64bit)
Vagrant 2.2.14
Ubuntu 16.04.6 LTS
Docker 18.09.7
ruby:ruby 2.7.2p137 
GitHubにファイルをプッシュしたら以下のエラーが発生。

`````
git push -u origin main
Warning: Permanently added the RSA host key for IP address '52.69.186.44' to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists
`````

そこで、以下のコマンドを実行した。


````
root@vagrant:/home/vagrant/rails_docker#  sudo ls -al ~/.ssh
total 20
drwx------ 2 root root 4096 Jan 27 08:30 .
drwx------ 8 root root 4096 Jan 27 07:13 ..
-rw------- 1 root root 1679 Jan 26 13:27 id_rsa
-rw-r--r-- 1 root root  394 Jan 26 13:27 id_rsa.pub
-rw-r--r-- 1 root root 1768 Jan 27 08:34 known_hosts
````
.sshに実行権限を与えた。
````
root@vagrant:/home/vagrant/rails_docker# sudo chmod 700 ~/.ssh
````


そして再度 git push -u origin mainを実行


````
root@vagrant:/home/vagrant/rails_docker# git push -u origin main
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
````
エラーが変わった。
ググって
[gitでPlease make sure you have the correct access rights and the repository exists. が出た時の対処法]("https://qiita.com/GakuNaitou/items/81dbbd3ea6211af71648")
という記事を発見。これを参考にして再度、プッシュして成功しました。