OmniAICreator/Qiita-1.07M huggingface dataset:
PMP試験に出てくるProcess groupsを覚えよう！

# Process groupsとは
PMBOKのプロセス群のことである。

## PMBOKのどこに記載があるのか
PMBOKの`23ページ`の`1.2.4.5`に記載されているぞ！

## プロセス群には何があるのか

- Initiating
- Planning
- Executing
- Monitoring and Controlling
- Closing

## プロジェクトフェーズとは別物なので注意
PMBOKの`20ページ`の`1.2.4.2`に記載されている`Project Phase`とは別物！


----

よかったよかった
authorized_keysファイルをチェックするツールを作った話

# はじめに
## 背景
SSHと言えば公開鍵暗号を使った公開鍵認証 ( 参考: [SSHの公開鍵ってなに?](https://qiita.com/angel_p_57/items/19eda15576b3dceb7608#%E8%AA%8D%E8%A8%BC%E9%8D%B5) ) ですが、「鍵をサーバに登録したのにログインできない…」といったトラブルが後を絶ちません。

ということで、ふと次のようなことを思いました。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/405601f9-e765-86b8-dda9-32780a323c82.png)](https://twitter.com/angel_p_57/status/1255649323322232832)

ということで、標題のようにチェックツールを作ってみたので、記事にすることにしました。

## 前提
今回、CentOS用のパッケージに手を入れる形でツールを作成しました。
CentOS 8.1.1911 + OpenSSH 8.0p1 ( openssh-8.0p1-4.el8_1 )

パッチファイルは以下のgithubリポジトリに置いています。
https://github.com/angel-p57/qiita-sample/tree/master/ssh-list-id

# ツールについて
ツールの名称は"ssh-list-id" としました。
**サーバの立場で**authorized\_keysファイルに登録された鍵をリストアップする ( まずいことがあれば報告する ) ということで、openssh-serverパッケージに追加しています。

例えば、次のようにフィンガープリントが確認できるような鍵があったとして、

```shell-session:手元の鍵の確認例
$ ssh-keygen -l -f ~/.ssh/id_ed25519.pub 
256 SHA256:yD3nJEK03pb5kurpxt+Wy35sQifd8vPCF3PTSFx1nfQ angel@cent8 (ED25519)
$ ssh-keygen -l -f ~/.ssh/id_rsa.pub 
4096 SHA256:ryZbBuLbavSaEVEIEbAEuL2dgG/GnIiPyvtcMiXCtwk angel@cent8 (RSA)
```

それをサーバ上の authorized\_keys に登録していれば、次のように一覧が出力されます。

```shell_session:ssh-list-idによる登録されている鍵のリストアップ
$ ssh-list-id
# authorized_keys file /home/angel/.ssh/authorized_keys:
line 1: SHA256:yD3nJEK03pb5kurpxt+Wy35sQifd8vPCF3PTSFx1nfQ
line 2: SHA256:ryZbBuLbavSaEVEIEbAEuL2dgG/GnIiPyvtcMiXCtwk
```

これにより、意図した通りに鍵が登録されているか、サーバ上で確認でき、**実際にログインしてみないと分からない**という不安定な状況を改善できるのではないか、ということです。

なお、ユーザに鍵登録を任せず管理者が行うような場面でも、rootユーザであれば、ユーザ名を指定して実行することができるようになっています。

```shell-session:ユーザ名指定実行
# ssh-list-id -u angel
# authorized_keys file /home/angel/.ssh/authorized_keys:
line 1: SHA256:yD3nJEK03pb5kurpxt+Wy35sQifd8vPCF3PTSFx1nfQ
line 2: SHA256:ryZbBuLbavSaEVEIEbAEuL2dgG/GnIiPyvtcMiXCtwk
```

そして**サーバの立場で**という通り、sshdと同じロジックで、鍵のパーミッションのチェックも行ってくれます。例えば、次のようにファイル自身のパーミッションがまずければ、警告を出してくれます。
ログイン時に原因が分かりづらい**鍵登録時の不備を事前にチェックできる**ということです。

```shell-session:パーミッション不備時
$ ls -l ~/.ssh/authorized_keys   # グループのw権が過剰→パーミッション不備
-rw-rw-r--. 1 angel angel 830  5月  7 23:10 /home/angel/.ssh/authorized_keys
$ ssh-list-id
# authorized_keys file /home/angel/.ssh/authorized_keys:
Authentication refused: bad ownership or modes for file /home/angel/.ssh/authorized_keys
some problems occurred to open file /home/angel/.ssh/authorized_keys
```

その他、**サーバの立場で**ということから、実は内部的にサーバ設定ファイル ( デフォルトで `/etc/ssh/sshd_config` ) を読み込んで解釈してたりします。もしデフォルト以外の場合、`-f`で指定することも可能です。
※以下、undocumentedながら、用意しているオプションの一覧です。

```shell-session:Usage
$ ssh-list-id -h
unknown option -- h
usage: ssh-list-id [-v] [-V] [-B|-E md5|-E sha256] [-u user] [-f sshd_config]
                   [-a authorized_keys] [-C connection_spec]
```

# パッケージ生成
パッケージ生成は、既存のソースRPMファイルにパッチをあてて行うようになっています。
詳しくは [HOWTO.txt](https://github.com/angel-p57/qiita-sample/blob/master/ssh-list-id/HOWTO.txt)をご覧ください。

※念のためですが、作成したパッケージをご利用される場合、くれぐれも自己責任でお願いします。

# おわりに
必要な機能は、既にOpenSSHのソースに一式揃っているので、いかに組み合わせて作るかに集中すれば良く、( ビルドを調整するために気を使う場面はあったものの ) 比較的楽に作ることができたと思います。
OpenSSHが登場してから随分と時間が経っているので、本ツールの機能には今更感もあるのですが、本家でもこういうの作らないのかな? とは思います。
anyenvの環境構築

この記事では個人的にお勧めなanyenvのインストール方法と使い方について簡単に紹介していきたいと思います。

## anyenvのダウンロード

まず、anyenvのソースをGitHubからcloneしてきます。

```sh
git clone https://github.com/anyenv/anyenv ~/.anyenv
```


## pathを通す

コマンドを叩けるようにパスを通しましょう。

- bashの場合

```sh
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
```

- Ubuntu DesktopやWindows Subsystem for Linuxの場合

```sh
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(anyenv init -)"' >> ~/.bashrc
```

- zshの場合

```sh
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(anyenv init -)"' >> ~/.zshrc
```

- Fish shellの場合

```sh
set -Ux fish_user_paths $HOME/.anyenv/bin $fish_user_paths
echo 'eval (anyenv init - | source)' >> ~/.config/fish/config.fish
```


環境によって違いますので、自分の環境に合った方法でpathを通しましょう。

私のおすすめは以下のように通す方法です。

```sh:.zshrc
if [ -e "$HOME/.anyenv" ]
then
    export ANYENV_ROOT="$HOME/.anyenv"
    export PATH="$ANYENV_ROOT/bin:$PATH"
    if command -v anyenv 1>/dev/null 2>&1
    then
        eval "$(anyenv init -)"
    fi
fi
```

上記のように記述しておくと`.bash_profile`や`.zshrc`などを`anyenv`を入れない環境へコピーしたときにもエラーになりませんし、不要なパスを通すこともありません。


## シェルを再起動する

pathを通したらログインシェルを再起動して新しい設定ファイルを読ませましょう。

```sh
exec $SHELL -l
```

コマンドが正しくインストールされているかも確認しましょう。

```sh
anyenv --version
```


## プラグインをインストールする

anyenvで〇〇envをインストールするために`anyenv-install`のプラグインが必要になります。
これは、どこから何を持ってくるのかを示しているプラグインです。
macOSであれば、`~/.config/anyenv/anyenv-install/`にインストールされます。
以下のコマンドを叩いてインストールしましょう。

```sh
anyenv install --init
```

# anyenvの使い方

ここまでの準備ができていれば、anyenvは以下のようにして使うことができます。

## 〇〇envのインストール

```sh
# インストールできる〇〇envを確認する
anyenv install --list

# 必要な〇〇envをインストールする
anyenv install rbenv
anyenv install pyenv
anyenv install nodenv

# シェルを再起動する
# 以前使っていた〇〇envはアンインストールするかpathを通らないようにしておくこと
exec $SHELL -l
```

これで、インストールした〇〇envを使うことができます。


## 〇〇envのアンインストール

〇〇envを消したい場合はuninstallコマンドを使います。

```sh
anyenv uninstall nodenv
```


## anyenvのアップデート

anyenvをアップデートしたい場合は以下のようにします。

```sh
(cd "$(anyenv root)" && git pull)
```

anyenvでインストールできるコマンドのリストをアップデートしたいときは以下のコマンドを実行します。
これを実行してから〇〇envをインストールすることで最新の〇〇envをインストールできます。

```sh
anyenv install --update
```

[anyenv-update](https://github.com/znz/anyenv-update)というプラグインを入れると、`anyenv update`でanyenvと〇〇envを全てまとめてアップデートすることができます。

インストール方法は`plugins`ディレクトリを作って、その中にGitHubからcloneするだけです。

```sh
mkdir -p $(anyenv root)/plugins
git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update

anyenv update
```

## anyenvのアンインストール

`~/.anyenv`のディレクトリを消すだけです。

```sh
rm -rf $(anyenv root)
```

# まとめ

最後まで読んでいただきありがとうございました。
以上でanyenvのインストール・使い方は一通り終了です。
他にもいろいろな機能がありますので、公式のドキュメントを参考にして使っていってください。


# 参考

https://github.com/anyenv/anyenv
seleniumを使用しようとしたら、「"chromedriver"は開発元を検証できないため開けません。」と言われた

## はじめに
掲題通りだが、seleniumを導入し実行しようとしたら、「開発元を検証できないため開けません」と言われてたので、その対応時の備忘録になります。

## 環境
```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.4
BuildVersion:	19E266
```

## 準備
seleniumを使用するために、必要な下記のインストールは[こちら](https://qiita.com/y-agatsuma/items/ea2c9845ee0a931d5c9c)を参考にさせていただいたので、参考ください。
- GoogleChrome
- chromedriver 
- selenium-webdriver(gem)

## 本題
プログラムを実行しようと思ったら、以下のようになった。
![スクリーンショット 2020-05-10 15.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/216379b4-b01a-67ff-9ad8-6c24e1f4a974.png)


## 対応
下記の画面が表示されたら、キャンセルボタンを選択する。
![スクリーンショット 2020-05-10 15.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/bbe14b30-59d1-dc4b-ae4b-d90ef220db87.png)


「システム環境設定」をクリックし、「セキュリティとプライバシー」を選択する。
その際に、このまま許可と画面が表示されるので、そのボタンを選択する
<img width="668" alt="スクリーンショット 2020-05-10 15.40.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/d5b04bf1-fcdc-7a89-f19c-4c52bf91e6db.png">

再度プログラムを実行すると、「開いてもよろしいですか」と聞かれるので、開くを選択
![スクリーンショット 2020-05-10 15.42.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/f11580b6-ba88-c625-b8f1-521097e6fa82.png)

問題がなければ、そのままプログラムが実行される。


## 参考
- [MacにChromeDriverを入れる](https://blog.naichilab.com/entry/mac-chromedriver)
- [[Ruby] seleniumでChromeを使ってWebスクレイピング](https://qiita.com/y-agatsuma/items/ea2c9845ee0a931d5c9c)

こんな簡単なことを解決するのに余計な情報を参考にしてしまい、全然seleniumが実行できず、時間つかってしまった。。。。
resize2fs: Bad magic number in super-blockとなった時の対応方法

- 環境
    - CentOS Linux release 7.8.2003 (Core)

# 事象 : AWSのEBSサイズを変更したからファイルシステムを拡張しようとして`resize2fs`コマンドを使ったら怒られた

```bash
$ sudo resize2fs /dev/xvda1
resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Bad magic number in super-block while trying to open /dev/xvda1
Couldn't find valid filesystem superblock.
$
```

# 原因 : CentOS7からのファイルシステムでは`resize2fs`が使えないから
ファイルシステム？
> ファイルシステムとは、記憶装置に保存されたデータを管理し、操作するために必要な機能です。OSが提供する機能の一つで、ほとんどのOSはファイルシステムでファイルを管理しています。
> [ファイルシステムとは？今さら聞けない基礎知識とOSごとの種類｜発注成功のための知識が身に付く【発注ラウンジ】](https://hnavi.co.jp/knowledge/blog/filesystem/)

そのファイルシステムが、CentOS7からXFSになったそうな。

> RHEL 7では、標準のファイルシステムとしてXFSが採用されました。RHEL 6以前の標準ファイルシステムには長い間ext系ファイルシステムが使われてきましたが、XFSに切り替わったことでファイルシステムの設定、運用の方法などが従来とは異なってきます。
> [今から始めるRHEL 7 第2回 標準ファイルシステムとなったXFS | NTTデータ先端技術株式会社](http://www.intellilink.co.jp/article/column/oss-rh02.html)

そして、XFSでは`resize2fs`ではなく`xfs_growfs`で拡張を行うそうな。

> CentOS 7 からデフォルトになっているXFSではresize2fsは利用できないということ。
> [CentOS 7(XFS)でLVMディスク拡張でハマったこと - Qiita](https://qiita.com/fetaro/items/d7dc74262633ba474bc8)

## 対応 : `xfs_growfs`コマンドを使う
[3.4. XFS ファイルシステムのサイズの拡大 Red Hat Enterprise Linux 7 | Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/storage_administration_guide/xfsgrow)

```bash
$ sudo xfs_growfs /dev/xvda1
meta-data=/dev/xvda1             isize=512    agcount=4, agsize=524224 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=2096896, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2096896 to 4194043
```
PythonでSesami APIをたたく

#やったこと
ラズパイから自宅のスマートロック（Sesami）を制御します。

#参考
[Sesame API Version 3 のチュートリアル](https://qiita.com/mizutoki79/items/63413a977a9f64344587)

#作成部分
tokenは固有のものを使用してください。

##[STEP1] device_idの取得
```python:
# keyを指定してデバイス情報をstrで取得する
# args: device_id, serial, nickname
def get_device_info(key):

    url = "https://api.candyhouse.co/public/sesames"
    headers = {"Authorization": token}

    r = requests.get(url, headers=headers)
    json_data = r.json()

    return json_data[0][key]
```

##[STEP2] 鍵をunlock or lockする
URLがSTEP1と微妙に違うので注意。
STEP1:https://api.candyhouse.co/public/sesames
STEP2:https://api.candyhouse.co/public/sesame

```python
# 鍵の状態がlockならunlock, unlockならlockする
def toggle_device_key(device_id):
    url = "https://api.candyhouse.co/public/sesame/" + device_id
    headers = {"Authorization": token}

    if key_is_locked(device_id) is True:  # locked
        r = requests.post(url, headers=headers, data='{"command":"unlock"}')
    elif key_is_locked(device_id) is False:  # unlocked
        r = requests.post(url, headers=headers, data='{"command":"lock"}')
    else:
        print("error! toggle_device_key")
        return

    json_data = r.json()

    return json_data["task_id"]
```

##[STEP3] 正常にコマンドが実行されたか確認
```python:
# task_idを指定して実行結果をbooleanで返す
def check_task_state(task_id):
    url = "https://api.candyhouse.co/public/action-result?"
    headers = {"Authorization": token}

    # task_idが空なら何もしない
    if task_id is None:
        return

    r = requests.get(url + "task_id=" + task_id, headers=headers)
    json_data = r.json()

    # statusが完了(terminated)になるまで待つ
    while json_data["status"] != "terminated":
        # wait
        time.sleep(3)
        # retry
        r = requests.get(url + "task_id=" + task_id, headers=headers)
        json_data = r.json()
    else:
        # 実行結果のステータスをbooleanで返す
        return json_data["successful"]
```
Ubuntu 18.04 に WINE 最新版(2020/05/10 時点 stable 5.0) apt package をインストールするメモ

https://wiki.winehq.org/Ubuntu

を参考に, apt で stable 5.0(development 5.8)を入れようとすると,

```
The following packages have unmet dependencies:
 winehq-devel : Depends: wine-devel (= 5.8~bionic)
```

というエラーが出ます. 実際には wine-devel が依存している faudio(の最新?) が apt に無いのが原因です.

https://forum.winehq.org/viewtopic.php?t=32192

あたりを参考に, faudio を登録しておきます.

```
$ wget https://download.opensuse.org/repositories/Emulators:/Wine:/Debian/xUbuntu_18.04/Release.key
$ sudo apt-key add Release.key
$ sudo add-apt-repository 'deb https://download.opensuse.org/repositories/Emulators:/Wine:/Debian/xUbuntu_18.04/ ./'
$ sudo apt update
```

これで最新 wine が apt で入ります! :tada:
PMP試験にでてくるRisk Termsを覚えよう！

# Risk Termsとは
リスク用語のこと

## どんな用語があるのか！
- Contingency fund
    - 臨時費。リスク準備金。
- Secondary risks
    - リスク対応によって生まれるリスク
- Residual risks
    - リスク対応によって生まれるが受容可能なレベルのリスク
- Triggers
    - リスク発生の警告サイン。リスク対応のトリガーとなる！
- Positive risk
    - プラス影響のあるリスク
- Negative risks
    - マイナス影響のあるリスク
- Pure risk
    - マイナス影響しかないリスク（火事とか）
- Business risk
    - プラス影響、マイナス影響の両方を持つリスク。プロジェクト投資はビジネスリスク。
- Qualitative analysis
    - 定性分析。主観的！
- Quantitative analysis
    - 定量分析。客観的！
- Utility function
    - 効用関数。リスク許容度のこと。

----

よかったよかった
Docker上でRedmineを立ち上げる方法

# やったこと

こちらのサイトを参考にして、Docker上にredmineを立ち上げた。
https://hub.docker.com/_/redmine?tab=description

## MySQL の 設定
MySQLのDockerイメージを取得

~~~
$ docker pull mysql:5.7.25
$ docker run --name mysql5.7.25 -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7.25
~~~

Redmine用のDataBase作成。

~~~
$ docker exec -it mysql5.7.25 /bin/bash
$ mysql -p
Enter password: password
 
mysql> create database redmine;
mysql> exit;
~~~

## Redmineのインストール
Databaseに先ほど作成したmysql5.7.25を指定する。

~~~
$ docker pull redmine
$ docker run -d --name redmine -p 80:3000 --link mysql5.7.25:mysql -e REDMINE_DB_MYSQL=mysql5.7.25 -e REDMINE_DB_USERNAME=root -e REDMINE_DB_PASSWORD=password redmine
~~~

## Redmineへログイン
ブラウザからアクセスすると、redmineのHome画面が起動する。
初期IDとPWはadmin/adminで、ログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535710/7ca4babf-8e45-8264-406d-66a04009d334.png)


## E-mail 設定
config/configuration.yml にSMTPの設定を記述して、E-mailを使えるようにする。

RedmineのDockerにはeditorが入っていないので、vim をインストールしておく。

~~~
$ docker exec -it redmine /bin/bash

$ apt-get update
$ apt-get install vim
$ cp ./config/configuration.yml.example ./config/configuration.yml
$ chown redmine:redmine ./config/configuration.yml
~~~

./config/configuration.ymlに以下を追加、
enable_starttls_auto: falseを設定しないと、"hostname was not match with the server certificate"というエラーになる。
http://guide.redmine.jp/Email_Configuration/

~~~ config/configuration.yml
production: 
    email_delivery: 
    delivery_method: :smtp 
    smtp_settings: 
        address: "SMTP サーバー" 
        port: 25 
        enable_starttls_auto: false
~~~

普通にsmtpサーバーの設定をするだけだと以下のエラーが出たので、
SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure

このサイトを参考にして、
https://medium.com/@edgar/how-to-resolve-openssl-sslv3-alert-handshake-failures-ruby-2-6-3-buster-cbc594537e7e

openssl のsecurity levelを2 -> 1に変更したら、E-mailの設定もできた。

~~~/usr/lib/ssl/openssl.cnf
CipherString = DEFAULT@SECLEVEL=2
↓
CipherString = DEFAULT@SECLEVEL=1
~~~
#iTerm2 で Mac のポップアップ通知を無効にする

Mac の Settings を変えれば良いっぽい

![image](https://user-images.githubusercontent.com/13635059/81464815-df769500-91ff-11ea-8391-df09ec3f47ec.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3157











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#VsCode rubocop not executable Error 

# Error

`execute path is empty! please check ruby.rubocop.executePath`

![image](https://user-images.githubusercontent.com/13635059/81465055-19e13180-9202-11ea-8d57-18653881fa8a.png)

`/Users/yumainaura/.rbenv/shims/arubocop is not executable`

![image](https://user-images.githubusercontent.com/13635059/81465079-48f7a300-9202-11ea-8a9d-356a9dc3f9bd.png)

# 解決

rubocop を インストールしておく

```
gem install rubocop
```

rubocopのパスを確認

```
$ which rubocop
/Users/yumainaura/.rbenv/shims/rubocop
```

これをVsCodeのrubocop設定に使う
入力するのはディレクトリまで

`/Users/yumainaura/.rbenv/shims/`

![image](https://user-images.githubusercontent.com/13635059/81465025-c5d64d00-9201-11ea-9b7b-fcd0f452996a.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3158











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
15年前の駆け出しエンジニア、2020年の駆け出しエンジニアと交流する（２）

# ▼　駆け出しエンジニアから聞いたプログラミングスクール

　最近、以下のような20代の「駆け出しエンジニア」と話す機会があった。

- ソフトウェアとは異なる業界にいた人
- 同じ業界だけど違う職種にいた人

これらの人は、いずれもプログラミングスクールで学習して、小さい会社にプログラマーとして転職していた。
上記の人達は以下のようなスクールに通っていた。

## タイプA：学費返金なし

- 30万円ぐらいで3ヶ月ぐらい
- 対面
- 仕事を紹介することが前提。
- 紹介に際しては、課題をかならずこなすこと。
- Railsを使ったチュートリアル。AWSへのデプロイなんかも行った。

## タイプB：就職後、学費返金あり

- 30万円ぐらいで3ヶ月ぐらい。
- 対面
- 就職できたら学費は返ってくる。
- Railsを使ったチュートリアル。


タイプBの人のほうが多かったように思う。
ポイントは、「学費が就職後返金される」という点。
スクール側が企業側からキックバックをもらうから、返してもいいという感じなんだろう。
企業の研修と人材紹介を兼ねたスクール。

# ▼　ソフトウェア業界へ転職した理由

 何故、この業界に、または、転職先の職場にきたのかを聞いてみた。簡単には以下の通り。

## 同じ業界だけどプログラマーになりたい

- 大手企業でSI的な仕事をしていたがコーディングをしたことがない。
- 自分が扱う商品について、その中の仕組みが知りたいし、つくってみたい。
- ゆくゆくは独立したい。

## 別の業界から転職した人

- 独立してお金を稼ぎたい
- ソフトウェアについてはあまりしらない。
- 何か作りたいものがあるわけではない。

# ▼ 15年前のプログラミングの学習や職業としてのプログラマー

　上記の20代の転職した駆け出しエンジニアの話をきいてて、時代は変わっていると感じた。
15年前自分がWebプログラマーとして独立したときは、以下のような状況だった。

- プログラミングスクールのようなものはなかった。（専門学校はあった）
- 今ほどオンラインでのプログラム教材はなかった。
- 学習は、書籍か英語の読みにくいリファレンスをみながら、試行錯誤。
- メンターなどもなく基本は、自分で問題解決をした。
- ソフトウェア開発は大変だと言われる職種だった。（花形にはみえなかった）
- 今ほど、言語もツール、サービスもそれほどなかった。（一人でシステムがすべて作れた）

　上記のような感じだったので、今（2020年）はとても恵まれているように見る。
　けれど、プログラム言語、ライブラリ、サービス、IDEが乱立し、習得するのも大変なので、ある意味スクールとかあっても当然かなという気もする。

# ▼ 昔は見なかった昨今の「フリーランス推し」

　転職したエンジニアのいずれもが独立したいということを言っていたので、フリーランスについて少し書いてみる。
　自分は、社会人経験2年で、あとはフリーランスと一人法人として活動しているので、その経験を交えながら。
　
　最近は、動画広告でも、「派遣」ではなく、「フリーランス」を紹介する事業も増えており、「フリーランス」推しが目につく。それは、派遣すらコストが高くなるから、いつでも切り捨てられる「フリーランス」を進めていこうとしているのかなあという邪推さえしてしまうぐらい。

　自分は、2年間ソフトウェアの営業をした後、独立してフリーランスのプログラマーとなった。
　儲かるからなったというよりも、会社が合わないと感じ、自分で思うように仕事を進めたいと思ったから。
　今のように、「年収何千万」とかそういう話はあまり聞いたことがない。ただ、確かにプログラマーの月単価は当時も高かった印象はある。Javaプログラマーで月80万円とかは聞いたことがある。
　
　年収よりは仕事の進め方に不満があったのと、もともと営業していたし、人脈づくりはそれほど苦手ではなかったのも独立した理由かもしれない。

　フリーランスを3年して、年収もある程度の額を超えたので、法人化して、今は一人法人として活動している。
　では、果たして、フリーランスだから儲かったのか？

---

　疲れたので、ここでこの記録は終了。
　気が向いたら、フリーランスプログラマーについて書いてみようと思う。
iPhoneのテザリングの仕様について

#DHCP機能による自動設定
iOS端末のインターネット共有機能を使い接続すると、DHCPにより以下の設定でIPアドレスが降ってきます。

* IPアドレス　172.20.10.*
* サブネットマスク　255.255.255.240
* デフォルトゲートウェイ　172.20.10.1

ここで注目なのはサブネットマスク
/28でサブネットが設定されているためIPアドレス範囲が16個しかありません。
そのため、実質の接続台数は13台が限界となります。
実際の使用ではそれほど同時接続することもなく問題になることはあまりないでしょう。
しかし、実は別の問題が存在します。

#リースタイム
iOSのDHCPのIPリースタイムは、85536秒（約24時間）に設定されています。
そのため、一日に13台以上接続すると、それ以上は最初のIPが解放されるまで接続することができなくなります。
現状では、強制的に解放する方法はありません。また、端末の再起動等では解放されません。


#解決方法
現状根本的な解決方法はありませんが、接続端末側でIPを手動設定してやれば問題なく接続できます。

#詳細
個人ブログにも詳細を掲載しています。

https://blog.nikujiro.com/2019/12/ios-dhcp.html
【初心者向け】関数を使って増税してみた /map,forEach,Math.round

#概要
関数勉強後のoutputとして、商品の値段に消費税の10％を乗せる計算をしてみました。
私と同じ初学者の方に取っては、いいエクササイズになると思うので是非やってみてください。
##流れ
Q.増税後の値段を四捨五入して出す

A.
1.配列で値段を定義する
2.mapで1.1倍する
3.forEachで展開する
4.Math.roundで四捨五入する

慣れれば仕組みがすっと入ってきます！それではやってみよう！

###1.配列で値段を定義する
```javascript:tax.js
const prices = [132, 222, 444];
```
こんな端数が出そうな数字選んでるのはわざとです笑
###2.mapで1.1倍する
```javascript:tax.js
const afterPrices = prices.map((price) => {
    return (price *= 1.1);
});
```
###3-4.forEachで展開しつつ、Math.roundで四捨五入する
```javascript:tax.js
//3.forEachで展開する
afterPrices.forEach((net, i) => {
    //4.Math.roundで四捨五入する
    const fixedPrices = Math.round(net);
    console.log(`増税後は${i + 1}番目の商品が${fixedPrices}円です`);
  });
```
:point_down_tone2:
[consol]
"増税後は1番目の商品が145円です"
"増税後は2番目の商品が244円です"
"増税後は3番目の商品が488円です"

いやあ、自分はこれを０→１で組み立てて完成するまで１時間以上かかってしまいました笑
まだまだ道のりは険しいですね、一緒に頑張りましょう。
GitLab CI で Docker Image をビルドして ECR に push する

元ネタ： [GitLab RunnerとkanikoでDockerイメージをビルドする - GeekFactory](https://int128.hatenablog.com/entry/2019/09/25/204930)

以下のようなジョブを `.gitlab-ci.yml` に記述

```.gitlab-ci.yml
build_image_with_kaniko:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - |
      cat > /kaniko/.docker/config.json <<EOF
      {
        "credsStore": "ecr-login"
      }
      EOF
      /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $ECR_URI:$CI_COMMIT_SHORT_SHA
```

GitLab で Ci/CD　で参照する変数の設定で以下の環境変数を設定

* `AWS_ACCESS_KEY_ID`
* `AWS_SECRET_ACCESS_KEY`
* `ECR_URI`
    * ex) `000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/hoge`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8219/a1e17e9a-d4b9-4fda-fc77-924253a2aea0.png)

GitLabで上記のジョブを実行してみて ECR に Image が登録されれば OK

## ポイント

いくつかポイントがあるので補足しておく

* kaniko の image は `:debug` を使用する。
    * GitLab CI で動作させるためには `sh` が必要らしく、`:debug` のイメージが必要
* `kaniko` の `entrypoint` をオーバーライドする
    * オーバーライドしないと `/kaniko/executor` を直接実行しようとして エラーになる

## 参考

* [Building images with kaniko and GitLab CI/CD | GitLab](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html)
* [GoogleContainerTools/kaniko: Build Container Images In Kubernetes](https://github.com/GoogleContainerTools/kaniko)
* [GitLab RunnerとkanikoでDockerイメージをビルドする - GeekFactory](https://int128.hatenablog.com/entry/2019/09/25/204930)
VBAでダイアログからファイル・フォルダを選択してフルパスを取得する方法

# はじめに

VBAでツールを作るとよくダイアログからファイルやフォルダを選択する処理が出てきます。
ネットで調べるといろいろな方法が出てきますが、私が使っている方法をご紹介します。

# ファイル選択

## メソッド

```vb
'ダイアログからファイルを1つ選択する。
'選択したファイルのフルパスを戻り値とする。
'
'@param(Optional) dialogTitle　ダイアログのタイトル
'@param(Optional) fileFilter ダイアログに表示するファイルの拡張子
'@param(Optional) defaultPath ダイアログのデフォルトパス
'@return openFileFullPaht 選択したファイルのフルパス。キャンセルを選択した時は「False」(String型)。
Function GetSelectFileFullPath(Optional dialogTitle As String = "ファイルを選択してください。", Optional fileFilter As String = "*", Optional defaultPath As String = "") As String

    '現在のカレントディレクトリのバックアップを取得する
    Dim currentFolderPath As String
    currentFolderPath = CurDir
    
    'カレントディレクトリの変更
    '省略又はフォルダが存在しない場合は、マクロのフォルダをデフォルトにする
    If defaultPath = "" Or Not IsExistFolder(defaultPath) Then
        CreateObject("WScript.Shell").CurrentDirectory = ThisWorkbook.path & "\"
    Else
        CreateObject("WScript.Shell").CurrentDirectory = defaultPath
    End If
    
    'フィルタに使用する文字列を作成
    Dim argFileFilter As String
    argFileFilter = ",*." + fileFilter
    
    'ダイアログの表示
    GetSelectFileFullPath = Application.GetOpenFilename(title:=dialogTitle, fileFilter:=argFileFilter)
    
    'カレントディレクトリの戻し
    CreateObject("WScript.Shell").CurrentDirectory = currentFolderPath

End Function
```

## ダイアログの表示

```vb
'ダイアログの表示
GetSelectFileFullPath = Application.GetOpenFilename(title:=dialogTitle, fileFilter:=argFileFilter)
```

「Application.GetOpenFilename」を使用してダイアログ表示して、選択したファイルのフルパスを取得します。
引数でダイアログに表示するタイトル、ダイアログで表示する拡張子を指定できます。

## カレントディレクトリ

ダイアログ表示時の最初のフォルダを変更しています。
選択したいファイルは、マクロを格納しているフォルダの近くにあることが多いのでデフォルトはマクロの格納場所にしています。引数を指定することで変更することができます。

「CreateObject("WScript.Shell").CurrentDirectory」で指定している理由は、現在のカレントディレクトリと異なるドライブやネットワークドライブでも動作するようにするためです。

また、ツールの実行前後でカレントディレクトリが変わらないようにバックアップを取得して、メソッドの最後で元に戻しています。


# フォルダ選択

## メソッド

```vb
'ダイアログからフォルダを選択する。
'選択したフォルダのフルパスを戻り値とする。
'
'@param(Optional) dialogTitle　ダイアログのタイトル
'@return 選択したフォルダのフルパス。
Function GetSelectFolderFullPath(Optional dialogTitle As String = "フォルダを選択してください。") As String

    With Application.FileDialog(msoFileDialogFolderPicker)
        .InitialFileName = ThisWorkbook.path & "\"
        .title = dialogTitle
        If .Show = True Then
            GetSelectFolderFullPath = .SelectedItems(1)
        Else
            GetSelectFolderFullPath = "False"
        End If
    End With
    
End Function
```

ファイル選択時とほとんど同じです。
「Application.FileDialog(msoFileDialogFolderPicker)」を使用してダイアログを表示してフォルダを選択します。

デフォルトのフォルダは、「InitialFileName 」プロパティで指定しています。
Ubuntu14.04 で Postfix エラーを直す

旧い Ubuntu14.04 でまとめて apt upgrade したら Postfix が動かなくなった。


アップグレードの内容は以下の通り。

```

Preparing to unpack .../postfix_2.11.0-1ubuntu1.2_amd64.deb
Unpacking postfix (2.11.0-1ubuntu1.2) over (2.9.6-1~12.04.2) ...

```

2.9.6から2.11.0にアップグレードされたらしいですね。

/var/log/mail.log には以下のようにエラーが出る。


```


May 10 03:56:42 www postfix/smtpd[16290]: fatal: in parameter smtpd_relay_restrictions or smtpd_recipient_restrictions, specify at least one working instance of: reject_unauth_destination, defer_unauth_destination, reject, defer, defer_if_permit or check_relay_domains


```


「Postfix 2.10 から中継制限の設定が変わった (smtpd_recipient_restrictions はダメ)！ - yuumi3のお仕事日記」
http://yuumi3.hatenablog.com/entry/20130916/1379320836

ということらしい。

理由はこちら
「Postfix 2.10 の smtpd_relay_restrictions 新設の背景 - Postfix Advent Calendar 2014 - ダメ出し Blog」
https://fumiyas.github.io/2014/12/05/smtpd_relay_restrictions.postfix-advent-calendar.html

さて、上記資料を読んで、

```
smtpd_relay_restrictions =  permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination


```

を /etc/postfix/main.cf に追加して


```

$ sudo /etc/init.d/postfix reload
```

すると直りました。
PMP試験に出てくるRisk Responsesを覚えよう！

# Risk Responsesとは
リスクに対する対応方法のこと

## どんな種類のリスク対応方法があるのか！

- Avoidance
    - リスクそのものを回避せよ！
- Mitigation
    - リスクのダメージを緩和せよ！
- Acceptance
    - 我慢してリスクのダメージを受け入れろ！
- Transference
    - リスクを第三者に押し付けろ！
- Exploit
    - プラス効果のあるリスクなので活用せよ！
- Share
    - プラス効果のあるリスクなので組織内で共有せよ！
- Enhance
    - リスクがプラス効果になるよう調整がんばれ！

----

よかったよかった
コールバックについて

#コールバックとは
登録や削除といった重要なイベントの前後に任意の処理を呼び出す仕組み。

参照：[Railsのcallbackについて調べた](https://qiita.com/rtoya/items/29cef3e328299781a328)

#コールバックの実装
簡単な実装例を以下に示します。

例）生成されたオブジェクトのname属性にデータが入っていない場合、’名前なし’をname属性にいれる。
(name: nil => name: '名前なし')にする。

```models/task.rb
class Task < ApplicationRecord
   before_validation :set_nameless_name

...

  private

  def set_nameless_name
    self.name = '名前なし' if name.blank?
  end

...
end
```
ここでは`before_validation`を使ったので検証する前に処理が行われています。
IPv6とIPv4を共存させる

# はじめに
https://www.archlinux.site/2018/12/ipv6ipv4.html

こちらのサイトを参考に、自宅のネットワークで`IPv6`と`IPv4`を共存させることができました。
この記事では補足を記載したいと思います。

# 環境
- プロバイダ：楽天ひかり ※2020年4月末にIPv6(IPoE/IPv4 over IPv6)がリリースされた
- 契約プラン：ファミリープラン
- ひかり電話の契約：なし
- IPv6
    - 接続方式：IPoE/IPv4 over IPv6(DS-lite)
    - ルーター：IO DATA WN-DX2033GR/E (このリストをもとに価格を見て決定 https://rmisp.force.com/ispc/s/article/ISPC104)
- IPv4
    - 接続方式：PPPoE
    - ルーター：TP-Link Archer C6（楽天ひかりに加入するときにもらったルーター）
- ハブ：TP-LINK TL-SG105V5.0

※ハブとルーター接続用でLANケーブルを2本購入しました(Jeavdarn CAT8)
※コンセントはONU、ハブ、ルーター✕2なので最低4つ

# ネットワーク構成

https://www.archlinux.site/2018/12/ipv6ipv4.html
より引用および加筆

```
インターネットコンセント
│
終端装置（ONU）
│
ハブ
│ │
│ └IPv4ルーター(192.168.1.1)
│      ├─ IPv4接続したい機器
│      ├─ IPv4接続したい機器
│      └─ ...
│
└─ IPv6ルーター(192.168.2.1)
       ├─ IPv6接続したい機器
       ├─ IPv6接続したい機器
       └─ ...
```

軽く調べたところ本来はルーターの前にハブを置く構成はアンチパターンのようです。
もう少し高めのルーターだと、ルーター同士を直列に接続して`IPｖ４`での通信をパススルーできるようですが、
今回購入したルーターにそのような機能はないため並列に配置しています。

また、ルーター同士で通信する必要はないので

- IPv4ルーター: 192.168.1.1/24
- IPV6ルーター: 192.168.2.1/24

としています。
※この構成だと`IPv4`系列の機器と`IPv6`系列の機器同士で通信できない
※ルーターのデフォルト割当が192.168.0.1/24でぶつかるので必ず変更します

# ルーター設定
## IPv4ルーター
- IPv6の通信オプションを無効にする
- ルーターのIPを192.168.1.1/24とする
    - 接続機器のIP割当設定がある場合は192.168.1.2〜から割り当たるようにする
- 2GHz帯域
    - IPv6ルーターの2GHz帯とかぶらないように無線チャンネルを自動から固定値に変更する(かぶらなければ値はなんでも良い)
- 5GHz帯域
    - IPv6ルーターの5GHz帯とかぶらないように無線チャンネルを自動から固定値に変更する(かぶらなければ値はなんでも良い)



## IPv6ルーター
- ルーターのIPを192.168.2.1/24とする
    - 接続機器のIP割当設定がある場合は192.168.2.2〜から割り当たるようにする
- 2GHz帯域
    - IPv4ルーターの2GHz帯とかぶらないように無線チャンネルを自動から固定値に変更する(かぶらなければ値はなんでも良い)
- 5GHz帯域
    - IPv4ルーターの5GHz帯とかぶらないように無線チャンネルを自動から固定値に変更する(かぶらなければ値はなんでも良い)

# 回線速度

確認したところ朝昼はIPv4、IPv6でほとんど差はないようでした。
混雑する夜間帯に効果を発揮するようです。

## IPv4
<img width="375" alt="IMG_6055.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273970/c12ea573-05f3-1965-e48e-7daa46477f9d.png">

## IPv6
<img width="375" alt="IMG_6054.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273970/7e7933b2-bbb3-8fac-e364-6f67c681c2e3.png">

# さいごに
間違いなどありましたらご指摘ください。

# 蛇足
## IPｖ６だから早いわけじゃない
http://www.kahemicafe.com/ipv4-over-ipv6-point-to-notice

## IPv6とIPｖ４を共存するに至った経緯
楽天ひかりからIPv6(IPoE/IPv4 over IPv6)に対応したというとメールが来たのでネットワークを`IPｖ６`に移行した。
基本的に問題なさそうだったが、ただひとつfire tv stickが「Homeは現在使用できません」というエラーに陥った。

サポートに問い合わせたところ

```
『Fire TV Stick』に関する推奨ネットワーク設定は現在以下のようになっております。
----------------------------------------
・2.4Ghzの場合：1-13（14）chのいずれかに固定

・5Ghzの場合：W52の36/40/44/48chいずれかに固定

・Ipv（インターネット・プロトコル・バージョン）4がAmazonデバイスの接続をサポートしておりますため、
「Ipv6」「Ipv4からIpv6自動変更」の設定の場合、「Ipv4」に固定
----------------------------------------
また恐れいりますが、Wi-Fiルータの操作・設定変更による影響等詳細な情報確認につきましては、
Wi-Fiルーターメーカーの窓口へのご相談をご検討くださますようお願いいたします。
```

という回答が来た。
通信速度が遅いのも困るがfire tv stickが使用できないのも困る。
そして、現在に至る。
Vue.jsでvue createしようとしたらエラー（loglevel error）になったｰ備忘録

プログラミング初心者の備忘録です。

#Vue.jsでvue createしようとしたらエラー（loglevel error）になった
(スクショなくてすみません)

```
ERROR command failed: npm install --loglevel error
```

#キャッシュを消すと良いらしい

何故、エラーなのかはわかりませんが、キャッシュを消すと良いらしい、ということで実施。

```
npm cache clean --force
```

そうすると、

```
npm WARN using --force I sure hope you know what you are doing.
```

その後、もう一度vue createを実施。

```
vue create ***
```
そうすると、

```
? Target directory C:\Users\*** already exists. 
```
との表示が。
どうやら前回のvue createは途中でエラーになったものの一部ファイルは出来上がっていたよう。

どうすれば良いかわからなかったため、ひとまず上書き保存を選択。


```
Pick an action: Overwrite
```

その結果、無事にvue createが出来た模様。

```
.
.
.
�  Successfully created project notepad.
�  Get started with the following commands:

 $ cd notepad
 $ npm run serve
```

#最後に
リンク先を教えてくださった方、またリンク先で記事にしてくださった方、参考にさせていただきました。ありがとうございました。

#参考
https://deep-space.blue/web/1531
時計付き玄関センサーでSlackに通知（ESP32+RaspberryPI）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219051/2f4ecf6e-77e3-f258-3325-8369ce750ae7.jpeg" width=80% border="1">


#概要
 - 時計付きの玄関センサーです。玄関を人が通過するとSlackに通知します。
 - 24時間に1回再起動し、時刻同期を行います。Wifiが切断されている場合も再接続します。
 - ESP32から直接Slackに投稿することが少し難しい（https通信のため）ので、今回は自宅サーバとして使用していたRaspberryPI経由でSlackに投稿しました。ESP32からRaspberryPIにはUDPで通知します。

#全体構成
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219051/8e618f59-0317-3d27-d8b2-31188968f07e.png" width=80% border="1">

#部品
 - [ESP32-DevKitC-32D](http://akizukidenshi.com/catalog/g/gM-13628/)
 - [HC-SR04超音波距離センサー](https://www.amazon.co.jp/Elegoo-JP-EL-SM-001-ELEGOO-Arduino%E7%94%A8-HC-SR04%E8%B6%85%E9%9F%B3%E6%B3%A2%E8%B7%9D%E9%9B%A2%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC5PCS/dp/B071DN2HS7/ref=pd_lpo_147_t_0/356-9545234-3334519?_encoding=UTF8&pd_rd_i=B071DN2HS7&pd_rd_r=7c041259-ac0a-4256-b2b2-39f7f1e3773a&pd_rd_w=ahBs2&pd_rd_wg=r9Mir&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=XXZGKMZNPDXB67D018MH&psc=1&refRID=XXZGKMZNPDXB67D018MH)
 - [0.96" IIC OLED](https://www.amazon.co.jp/HiLetgo-128%C3%9764-LCD%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4SSD1306%E6%B6%B2%E6%99%B6-MSP430-Arduino%E3%81%AB%E5%AF%BE%E5%BF%9C/dp/B071ZPFDWW/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=OLED+0.96&qid=1589088881&s=industrial&sr=1-6)
 - LED
 - 330Ω抵抗

#配線
|HC-SR04|ESP32|
|---|---|
|VCC |5V|
|Trig|12|
|Echo|14|
|GND|GND|

|OLED|ESP32|
|---|---|
|VCC |3.3V|
|GND|GND|
|SCK|22|
|SDA|21|

 - LEDは19ピンに接続します（抵抗は330Ω） 

#ソースコード
　[https://github.com/type89/ESP32_GateKeeper_public]https://github.com/type89/ESP32_GateKeeper_public)
※slack_sdk形式に修正しました（2022/1/8）

 - 「ESP32_new_gatekeeper.ino」：ESP32に書き込みます。
 - 「ent_monitor.service」：RaspberryPIの「/etc/systemd/system」に置きます。
 - 「udp_rev_to_slack.py」：「ent_monitor.service」で指定したパスに置きます。

 
#検知時の状態
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219051/505151c3-9a78-fe94-891f-9bd1e885f999.jpeg" width=80% border="1">
 - OLED画面の表示が変わり、LEDが点灯します。


#工夫したポイント
 - 0.1秒ごとに距離を検出し、90cm以下（壁との距離は1m）の場合に通過の判定にしました。誤検知の対策として、3回連続で20cm以下の場合に通知するロジックとしました。
 - 1回検知した後に30秒待機時間を設けることで、Slackに必要以上に通知しないようにしました。待機中は本体のLEDが点灯します。
 - センサーの前を走り抜けると、距離が大きく測定され、検知しないことがありました。測定結果が1.2m以上の場合は検知対象にすることで、正常に検知できるようになりました。
 - 試作品を運用してみると、2〜3日でWifi接続が切れてしまい、通知できなくなることがわかりました。そこでntpで時刻取得し、指定した時刻に再起動するようにしました。また、玄関に時計がある方が便利なので、OLEDモジュールで時刻表示もしてみました。
 - 検知した場合は画面表示が切り替わります。そのままだと時間がわからない（特に朝は待てない）ので、検知画面は1秒だけ表示し、時刻表示に戻しています。
 - RaspberryPIはsytemctlでサービスを動かしています。サービスが停止しても復旧するように、「always」を指定しました。

#参考にしたサイト
 - [PythonでSlackのIncoming Webhookを試してみる](https://qiita.com/bakira/items/8fa06ab10edf1f42ff97)
 - [Raspberry Pi で systemd を使ってプログラムを自動実行する](https://qiita.com/molchiro/items/ee32a11b81fa1dc2fd8d)
 - [ESP32でUDP通信やってみた（ESP32インストール手順解説あり）](https://qiita.com/Tsukkey/items/247285c703fbbc6c6cd2)
 - [ESP32でOLEDディスプレイ「SSD1306」にHello-world表示してみた](https://wak-tech.com/archives/825)
VirtualBoxのゲスト同士の通信ができない時に時間を溶かした件について vulnhubの構築に手間取ったこと

#vulnhubを解こうとした時のこと。　2020/05/10
https://www.vulnhub.com/entry/kioptrix-level-1-1,22/

このマシンを攻略しようとしてダウンロードしてVMwareの仮想ファイルをVirtualBoxで立ち上げました。
元々、Kali LinuxをVirtualBoxで立ち上げていたためわざわざVMwareで立ち上げませんでした。
そして普通に、マシンを構築して立ち上げることに成功しました。
そこから、マシンを攻略しようとしたのですが、、
###しかし、ここで問題が生じます。
netdiscoverしても何にもマシンが見つからない！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635094/315be98d-32fd-37dd-1f58-ac6f6db46765.png)
####IPアドレスも間違えていないし、何が悪いのかがさっぱりわかりませんでした。。
そこで、VirualBoxのネットワークを設定を見ると、NATになっていました！
これが悪いのだろうと思い、https://qiita.com/pitao/items/0f9475e4c0e230911eb7
上記のサイトを参考にNATネットワークに設定を変更しました！
##でも、まだ見つからないのです。。
そして色々試したのですが、全然見つからない状態で時間溶かしてしまいました。
一番最後にまさかと思い、IPv6サポートにチェックを入れてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635094/24921007-ea60-934b-b9e5-cc653c196b87.png)
そうしたらなんと！！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635094/f962bbda-682d-18a9-b150-c2d058677c35.png)
netdiscoverで出てきました！

あれだけ時間を溶かしたのに、たった一瞬で解決するなんて、、、、
これで攻略できるようになったので一安心です！
もし、同様のことでお困りでしたらぜひ試してみてください。
以上

Twitter:https://twitter.com/1097kai
apacheのssl設定

# 証明書の作成

```sh:RSA秘密鍵の作成
$ openssl genrsa -out server.key 2048
```

```sh:CSRの作成
$ openssl req -new -days 365 -key server.key -out server.csr
```

```sh:証明書の署名
$ openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 365
```

## mkcertで証明書の作成

[mkcert](https://github.com/FiloSottile/mkcert)

```sh:インストール
$ brew install mkcert
$ brew install nss
```

```sh:証明書の作成
$ mkcert -key-file server.key -cert-file server.crt localhost
```

# apacheの設定

apache2.4.41

```conf:httpd.conf
LoadModule ssl_module libexec/apache2/mod_ssl.so
LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so

Include /private/etc/apache2/extra/httpd-ssl.conf
```

```conf:httpd-ssl.conf
SSLCertificateFile "/private/etc/apache2/server.crt"
SSLCertificateKeyFile "/private/etc/apache2/server.key"
```
署名した証明書(`server.crt`)とRSA秘密鍵(`server.key`)を`/private/etc/apache2`以下に配置

## httpをhttpsにリダイレクト

```conf:httpd.conf
LoadModule rewrite_module libexec/apache2/mod_rewrite.so

# Redirect http to https
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
```

# apacheの起動

```sh
$ apachectl configtest
Syntax OK

$ apachectl start
```
getElementsByClassNameとgetElemetByIdの違い

ネイティブJSでのDOM操作を学習中にgetElementsByClassNameとgetElemetByIdで大きな違いがあることを発見したのでメモ書きです。

## やりたいこと
以下のHTMLコードでulタグの子要素の数を把握する。

```html
  <ul class="list">
    <li>apple</li>
    <li>orange</li>
    <li>melon</li>
  </ul>
```

## jQueryで実装すると
```js
$(function(){
  alert($('.list').children().length);
})
```
これで「３」が返ってくる。

## getElemetsByClassNameで実装
```js
const List = document.getElementsByClassName('list');

const num = List.childElementCount;
alert(num);
```
この場合undefindが返ってくる。
console.log（'list'） を確認すると「ul.list」となっている。

```console
HTMLCollection [ul.list]
0: ul.list
length: 1
__proto__: HTMLCollection
```

## getElemetByIdで実装
```js
const List = document.getElementsById('list');

const num = List.childElementCount;
alert(num);
```
この場合は「３」が返ってきて、思い通りに実装できる。
console.log('list')を確認すると次のとおり。

```console
<ul id="list">
  <li>apple</li>
  <li>orange</li>
  <li>melon</li>
</ul>
```

## なぜこのような結果に？
現段階でこのような結果になる理由がわかりません。
もう少し深掘りしてみて、わかったことを追記しようと思います。
Unity入門　Ｑ＆Ａに答えていくよって話


この間、　[Unity講座](https://note.com/zazizuzezo22334/n/n90340339a00c)をリリースしたばかりですが　

それを見てくれている人も多いようで　

質問が　たまっていたので　

色々解答していきたいと思います。　

# Q　Unityは最新ｖｒを使ったほうがいいでしょうか？ 




　Ａ　最新ｖｒだと、　エラーが出ることも多々あるので　

一つか２つ前のｖｒを使った方がいいかと思います。

もしくは　長期サポートのＬＴＳｖｒを使ったほうがいいです　

最低でも、Unityハブに２つ以上のｖｒを入れておくといいでしょう


#  Ｑ　やはり　ゲーミングＰＣじゃないと　きついでしょうか？　



Ａ　はい　きついです。　２Ｄゲームならともかく　

３ＤやＶＲなどをやりたい場合は　ゲーミングＰＣじゃないときついです。　

最低でも、ＧＰＵが　gtx１０６０以上のゲーミングＰＣを

使った方がいいかと思います。　



# Ｑ　初心者です。　最初は何からやればいいか　分かりません。　

Ａ　とりあえず、　公式のチュートリアルをやったり

Standardアセットやプロビルダーで色々遊んでみるといいかと思います。　



# Ｑ　書籍には　Unity用のＣ＃と　普通のＣ＃がありますが　両方とも勉強したほうがいいでしょうか？　

Ａ　はい　両方とも勉強したほうがいいです。

Ｃ＃が分かっていないと、　Unityもできるようにはなれないですからね。



# 　Androidビルドが　うまくできません　

Ａ　ＳＤＫは入っていますか？　入っていない場合は

Unityｈｕｂから　インストール　モジュールを加えるで　

Android　ＳＤＫとＮＤＫを加える必要があります。　



# Ｑ　シーンを間違って上書きをしてしまいました　これはもう直らないのでしょうか？　

Ａ　あるあるですね。　残念ながらもう直りません。　

Windowsのシステム復元を使えば、　一応直せるのですが　

直近のやつは復元できませんからね。　

なので、普段からバックアップはとっておきましょう。　



# 　Unityちゃんを設置したときに　すり抜けてしまいます　

Ａ　コライダーの設定がずれている可能性が高いです。　

　地面に合わせるように微調整してみてください。　

因みに、Unityちゃんは身長　1.5mなので　

コライダーの高さも1.5にしておくといいでしょう。　



# Ｑ　SerializeFieldは　つけたほうがいいのでしょうか？　

Ａ　そうですね。　実際にゲームをリリースする予定なら　

つけたほうがいいですけど。　そうじゃない場合は　

普通にpublicでいいと思います。　



# Ｑ　２Ｄゲームで　コライダーをつけているのに動きません

Ａ　２Ｄ用のコライダーにすれば　直ると思います。　

　　２Ｄと３Ｄで、分かれているので注意しましょう。　



# Ｑ　Unityはグラフィックがしょぼく　ないですか？　

Ａ　昔はしょぼかったですが　今は違います。　

ここ最近　かなりパワーアップしていますからね。

　確かにデフォルトでのグラフィックなら　ＵＥ４の方がいいですが　

Unityでもほとんど同じようなグラフィックにできます。　

Unityの方がちょっとコツがいるって感じですかね。
SafariはBasic認証の結果でAuthorization: Bearerを上書きする

# 最初に結論

Safari で Basic認証 が成功した後、Authorization Header を Basic の認証結果で上書きしてしまう。JWT のアクセストークンを上書きするので、APIアクセスが失敗してしまう。解決策として、アクセストークンは Authorization Header で渡さず、別の方法で渡せば良い ※。

[Safari 12 replaces authorization header - Stack Overflow](https://stackoverflow.com/questions/52456478/safari-12-replaces-authorization-header)

※ OpenID Connect ではクエリパラメータやフォームで渡す方法も定義されている。これらを使えば回避できると考えているが、試せてはいない。

# ある日のこと
アルバイトの方から「検証環境のアクセスが401になります...」と報告があった。彼には開発中 Webアプリケーションの iPhoneデバッグをお願いしていたのだが、どうやら iPhoneでアプリケーションに繋ぐとエラーが発生するらしい。

# アプリケーションの構成

アプリケーションは認証認可に OpenID Connect を使っている。クライアントは、IdP で認証が成功したら JWTのアクセストークン を受け取る。そのアクセストークンを HTTPリクエスト の Authorization Header に設定し、APIサーバと疎通する仕組みだ。

ざっと図にするとこんな感じ。ちょっと端折っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10499/6b426965-aa30-0f5e-50ac-f435cdef37f4.png)


* アプリケーションは SPA で CloudFront + S3 で配信される
* CloudFront は `/api/* は Fargate` と `/* は S3` で参照先を変更している
* 認証はAuth0を使用。クライアントが認証成功するとアクセストークンを取得する
* Fargate からデータ取得するとき、クライアントはアクセストークンをリクエストヘッダに設定して /api/* へ APIリクエストを行う
* Fargate はアクセストークンを検証して、正しいものであればデータを返す。逆に不正なアクセストークンの場合は401エラーを返す

よくあるアーキテクチャ構成かと思う。今回問題となったのは、**検証環境のためBasic認証を導入していた**という点だ。本番環境にはBasic認証はない。

ちなみに上記の図では、CloudFront のところに Lambda@Edge を使用してBasic認証を導入していた。

# 影響範囲を確認

発生当時はすぐ本番環境を確かめたが再現しなかった。よってすぐ検証環境のみで発生していると辺りがついた。モバイルのみで発生？ Android Chrome でアプリを開いたが再現しなかった。なので Safari が怪しいと当たりをつけて調査を行った。

その結果、どうやら MacのSafari と iPhoneのSafari の両方で発生していた。

# リクエストを覗いて見る

バックエンドのレスポンスが401になっていたため、Chrome と Safari のリクエストの差異を調べて見た。（実際にはアルバイトがリクエストを見て報告してくれた🙏）。下記は /api/* へのAPIリクエストの中を覗いたもの。

|  Safari  |  Chrome  |
| ---- | ---- |
|  Authorization: **Basic** abc...  |  Authorization: Bearer xyz...  |

...Basic？

Safari の Authorization Header の値が Basic認証の結果で上書きされている...。まさか、と思いすぐさまググってみると、同事象で困っている人が。この記事だと、旧Edge や IE でも発生するらしい。

* [Safari 12 replaces authorization header - Stack Overflow](https://stackoverflow.com/questions/52456478/safari-12-replaces-authorization-header)
* [How to prevent/override authorization header in Safari? - Stack Overflow](https://stackoverflow.com/questions/36789514/how-to-prevent-override-authorization-header-in-safari)

日本語のハマった記事も見つけました。


* [iOS Safari限定でAjaxリクエストが失敗してハマった話 - らっちゃいブログ](http://racchai.hatenablog.com/entry/2016/05/18/070000)

# 結局 どうしたか
🤷‍♂️

まだ何もしてない...

できればアプリケーションに手を加えず解決したいところ。だって本番影響のない事象で修正をしたくない。検証環境はアクセスを絞り込みしたいため、グローバルIP制限に変更する...とか？

検証環境へのアクセスを絞る別方法、なにか良いアイデアがあれば教えてほしいです。

# 回避策

そもそも CloudFront を使っているのだから、Basic認証ではなく「署名付きCookie」でアクセス制御しようよって話な気がしている。
DDBJのスパコンでGuppyを使ってbasecallしたい

### 自分でロングリードシーケンスをしたくなったのでMinIONを買うことにした
購入の手配は全部代理店に任せる感じでした。MinION Starter Pack-Enhancedがだいたい70万弱でだいぶ高いなと思っていたがNEBのキットも別途購入しないといけないらしく結局いいお値段になってしまった。予定ラン回数を考えると普通に外注でもよかったんじゃないか疑惑が。。。  
MinIONのアカウント設定が若干めんどくさい。事前にソフト類が動くかチェックしたかったが購入前だとインストールすらできないので注意。

----
実際の解析の順番とは前後するが、とりあえず手持ちのfast5をfastqに変換できるか確認。
  
#### Guppyのインストール
Linux GPU版のをダウンロード。そのままDDBJのサーバーにscpであげる。
たぶんもっとスマートなやり方あり。
あとは普通に解凍したらインストールは完了のようだ。
  
```sh
tar -xf ont-guppy_3.6.0_linux64.tar.gz
```
2020.5.10.時点で最新のGuppy 3.6.0をインストールした。
#### fast5をfastqに変換
GPUを使用するためにはログインするときに` -l gpu` オプションをつける必要がある。

```sh
qlogin -l gpu
```
#### base call
よく分からないが以下のコマンドを投げると動いた　　

```shell-session
#!/bin/sh
#$ -S /bin/sh
#$ -cwd
#$ -l gpu -l cuda=2
#$ -l s_vmem=64G -l mem_req=16G -pe def_slot 4
#$ -l d_rt=192:00:00 -l s_rt=192:00:00

module load cuda10.0/toolkit/10.0.130

/path/to/guppy_basecaller \
--input_path /path/to/fast5_reads \
--save_path /path/to/fastq_reads \
--device cuda:0,1:4G \
--num_callers 4 \
--flowcell FLO-PRO002 \
--kit SQK-LSK109
```
  
  

`#$ -l gpu -l cuda=2` 使用するcudaの数(?)を指定
`#$ -l s_vmem=64G -l mem_req=16G -pe def_slot 4` これを指定しないとすぐ止まってしまった。`--num_callers `が4だったから???よく分からん。
`module load cuda10.0/toolkit/10.0.130`でcudaを使えるようにしておく。的な。
あとはガイド通りにinputとoutputのpathを指定する。フローセルのIDとキットも指定された通りに記載。
`--device cuda:0,1:4G` ここもガイドどおりに。2個GPUを使用することにした。なぜか4Gにしたが
https://sc.ddbj.nig.ac.jp/ja/guide/hardware
6Gまでいけるということかしら??

終わったら続きを書きます。
 

#### 201220 Guppy 4.2.2でベースコール
Guppy のバージョンが上がったのでそちらでもやってみる。
よくわからないけど`--device cuda:0,1:4G` の設定では動かず、`--device cuda:0:4G` にすると動いた。
15Gbくらいが一晩くらいで出力された。 

CUDAはdefaultで最新版が使用できる設定になっているので、上でやっているようなmodule loadは必要なかった。

```
#!/bin/sh
#$ -S /bin/sh
#$ -cwd
#$ -l gpu -l cuda=2
#$ -l s_vmem=64G -l mem_req=16G -pe def_slot 4
#$ -l d_rt=192:00:00 -l s_rt=192:00:00

/oath/to/guppy_basecaller \
--input_path /path/to/fast5_dir \
--save_path /path/to/fastq_dir \
--device cuda:0:4G \
--num_callers 4 \
--flowcell FLO-MIN106 \
--kit SQK-LSK109
```


たしかにGuppy3より全体的にQualityが向上している
【git】履歴をきれいにしたい

git を使っていますが、グループで作業しているとき、履歴をきれいにしたいなーと思うことがあります。
そこで、頑張ってみます。ふー。

## ローカルでcommit を一つにまとめる

とりあえず、自分は以下の作戦でできました。

1. 開発開始のときのコミットに戻る
2. 開発開始のコミットで新しいブランチを作り、チェックアウトする
3. 開発で使用したブランチをmerge する
4. リモートレポジトリにpush する or 開発で使用したブランチを削除する

### 実行例

最初にtopic branch dev0 で作業していました。

```git
* 97bc41b (HEAD -> refs/heads/dev0) add3
* 0e4917a add1
* 802e1c2 initial
```

で、最初にチェックアウトして本命topic branch dev1 を作ります。

```
* 97bc41b (refs/heads/dev0) add3
* 0e4917a add1
* 802e1c2 (HEAD -> refs/heads/dev1) initial
```

ここでmerge --squash を実行します。

```
$ git merge --squash dev0
Updating 802e1c2..97bc41b
Fast-forward
Squash commit -- not updating HEAD
 test.txt | 3 +++
 1 file changed, 3 insertions(+)
$ git commit
[dev1 cc1152d] Squashed commit of the following:
 1 file changed, 3 insertions(+)
```

```
* cc1152d (HEAD -> refs/heads/dev1) Squashed commit of the following:
| * 97bc41b (refs/heads/dev0) add3
| * 0e4917a add1
|/
* 802e1c2 initial
```

この状態でpush すればdev0 はremote repository にはpush されません。
また、削除するには以下のコマンドでできます。

```
$ git branch -D dev0
Deleted branch dev0 (was 97bc41b).
```

```
* cc1152d (HEAD -> refs/heads/dev1) Squashed commit of the following:
* 802e1c2 initial
```

リモート・リポジトリにあった開発ブランチの削除はgithub ではＵＩ操作でできました。

なんだかこれで本番も乗り切れそうです。ふー。

https://www.granfairs.com/blog/cto/git-merge-squash
を参考にさせていただきました。ありがとうございました。
(2020/05/10)

### 追記

- [【中上級者お断り】初心者のためのgit利用入門](https://qiita.com/YamaguchiRei/items/82c35c04a524f1af86aa)に同じ内容がよりよく書かれていました。(2020/05/10)
SSH FSでroot権限で編集できるようにする。

Visual Studio Codeで[ssh -fs](https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs)という拡張機能がある。
コレ自体は非常に使いやすいのだが、`sudo `コマンドやroot権限でないとアクセスできないファイルの編集はできなかった。

そこで出来るようにならないかと調べた所、こちらにやり方があった。
[https://github.com/SchoofsKelvin/vscode-sshfs/issues/28](https://github.com/SchoofsKelvin/vscode-sshfs/issues/28)

以下やりかた。

---

前提として**すでにSSH FSにSSH接続するサーバーを登録していること**が必要。


拡張機能の設定を押すと出てくるドロップダウンメニューから【拡張機能の設定】を選ぶ。

![Inkedf61d06b3ec1a8c8389d1b480886e6446_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136336/1baf0f9b-3119-73ab-c308-795def9e4cdd.jpeg)

次にConfigsのSetting.jsonを開く。

![75e8650340b61b2c4663c24c728b1014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136336/72079267-3e7a-0b7e-23f8-8cf678cfff68.png)

最後にサーバーの設定に`"sftpCommand": "sudo /usr/lib/openssh/sftp-server"`を追加する。

![bokashita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136336/e8138cd4-b2c9-53d7-4598-ccac5b49a95f.png)


以上。
【Rails】主要コマンドまとめ 

#参考文献

- [Railsコマンドまとめ(基本~応用)](https://qiita.com/gcyagyu/items/dea818095feed81f66c0)
- [docker-composeでよく使うコマンド(Ruby on Rails)](https://qiita.com/LikeGeohotz/items/0e3cd9dfa67d7ff6ff96)
- [Docker Compose + Railsでイメージ内でbundle installしているはずなのにgemが無いとエラーがでる。](https://qiita.com/hokita222/items/49f4ca54835e08fdd6b2)
- [Capistrano で Rails アプリケーションの自動デプロイ](https://qiita.com/Salinger/items/4ee4f3c5ebd5227196c0)
- [(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/814e0979217b1a25aa3e)
- [ssh-agentを利用して、安全にSSH認証を行う](https://qiita.com/naoki_mochizuki/items/93ee2643a4c6ab0a20f5)
- [scpコマンド](https://qiita.com/chihiro/items/142ebe6980a498b5d4a7)


#Rails編

###gemインストール（path指定）

```
$ bundle install --path vendor/bundle
```

###model作成
```
$ rails g model sample name:text    #name=カラム名（text型）
```


#Docker編

###railsプロジェクト作成
```
$ docker-compose run web bundle exec rails new . --force --skip-bundle
```

###キャッシュを利用したくない場合
```
$ docker-compose build --no-cache   
```

###MySQL利用
```
$ docker-compose run web rails new . --force --database=mysql
```

###DB関連コマンド
```
$ docker-compose exec web bundle exec rake db:drop     #削除
$ docker-compose exec web bundle exec rake db:create　 #作成
$ docker-compose exec web bundle exec rake db:migrate　#マイグレーション
$ docker-compose exec web bundle exec rake db:seed　　 #データ投入
```

###サーバ起動
```
$ docker-compose up -d
```

###exit1が発生する場合
```
$ rm tmp/pids/server.pid
```

#Unicorn編

###起動コマンド
```
$ bundle exec unicorn_rails -E XXXXXXX -c config/unicorn/XXXXXX.rb -D
``` 

###起動確認
```
$ ps -ef | grep unicorn | grep -v grep
```

#Nginx編

###起動コマンド
```
$ sudo systemctl start nginx.service
```

###起動確認
```
$ ps aux | grep nginx
```

#Capistrano編

###database.ymlアップロード
```
$ bundle exec cap XXXXXXX deploy:upload      #環境名(ex: development)
```

###デプロイチェック
```
$ bundle exec cap XXXXXXX deploy:check   #環境名(ex: development)
```

###デプロイ実行
```
$ bundle exec cap XXXXXXX deploy        #環境名(ex: development)
```

#SSH関連コマンド

###公開鍵作成
```
$ ssh-keygen -t rsa
```

###EC2接続
```
$ ssh -i XXXXX.pem ec2-user@XX.XX.XXX.XXX
```

###ssh-agentに鍵の登録
```
$ ssh-add -K ~/.ssh/XXXX_key_rsa
```

###リモートマシン-ローカル間のファイルコピー
```
$ scp XXXXXX.txt ユーザ名@サーバホスト名:/var/www/XXXXX/XXXX
```
【簡潔】Railsで不要ファイルを生成しない方法~Ruby~

###概要

rails gコマンドでファイルを生成するときに不要なファイルを指定して生成しないようにする方法を解説します。
<br><br>

###・方法

まずrails newで作成したアプリを開いて、configの中のapplication.rbを開きます。
<br>
そうすると以下のような画面が出てくると思います↓

```config/application.rb
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)

module PostApp
  class Application < Rails::Application
    config.load_defaults 5.2
  end
end
```

この中の

```
config.load_defaults 5.2
```
の行のconfig.以下`load_defaults 5.2`を削除します。

そうしましたらconfig.後に生成したくないファイルについて記述します。
<br>
以下のように記述してください↓


```config/application.rb
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)

module PostApp
  class Application < Rails::Application  
    config.generators do |g|
      g.javascripts false
      g.helper false
      g.test_framework false
    end
  end
end
```

このように記述すると生成したファイルに対応した
-javascripts
-helper　（ヘルパー）
-test_framework　（アプリをテストするためのファイル）
が生成されなくなります。

<br>
<br>
この記事を読んでいただきありがとうございました。
【初心者】GoogleAppsScriptでWebスクレイピングし、スプレッドシートに保存する

## はじめに
GoogleAppsScriptでWebスクレイピングをし、結果をGoogleスプレッドシートに保存する案件があったため調べてみました。簡単に出来るんだなとわかりました。参考にした以下サイトがわかりやすいです。

## 参考
[Easy data scraping with Google Apps Script in 5 minutes](https://www.kutil.org/2016/01/easy-data-scrapping-with-google-apps.html)
わかりやすい。感謝です。

## コード
GET_DATA.gs：スクレイピングでデータを取得する
SAVE_DATA.gs：スプレッドシートにデータを保存する
の2プログラムを作成

### GET_DATA.gs
``` javascript
function getData() {
    var url = 'https://www.yahoo.co.jp/';
    var fromText = '<title>';
    var toText = '</title>';

    var content = UrlFetchApp.fetch(url).getContentText();
    var scraped = Parser
                    .data(content)
                    .from(fromText)
                    .to(toText)
                    .build(); //文字列
//                    .iterate(); //文字列の配列。結果が複数の場合はこちらを使用

    Logger.log(scraped);
    return scraped;
}
```


### SAVE_DATA.gs
``` javascript
// GET_DATA.gs
function saveData() {
  var spreadsheetId = 'スプレッドシートのID'
  var sheetName = 'シート名'
  var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName); // insert Spreadsheet Id and Sheet name
  sheet.appendRow([ new Date(), getData() ]);  
}
```

スプレッドシートIDの確認方法：[【GAS】GoogleスプレッドシートIDの見方
](http://somen.site/2018/07/06/%E3%80%90gas%E3%80%91google%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88id%E3%81%AE%E8%A6%8B%E6%96%B9/)