OmniAICreator/Qiita-1.07M huggingface dataset:
Herokuでデプロイ

# Herokuを初めて使う場合

・Heroku CLIのインストール

```
brew tap heroku/brew && brew install heroku
```

・バージョン確認

```
heroku --version
```

・Herokuにログイン

```
heroku login --interactive
```

・Heroku上にアプリケーションを作成

```
heroku create　アプリケーションの名前
```

### データベースの設定

Herokuでは、使用するデータベースの設定が、デフォルトでPostgreSQL
MySQLを使用するためには、ClearDBアドオンを追加することによって設定できます。

ClearDBアドオンとは、ClearDBというデータベースサービスが提供しているアドオンで、これを追加すると、HerokuでMySQLを使用できます。

・ClearDBの追加

```
heroku addons:add cleardb
```

#### Ruby on Railsを使うときの設定

Ruby on Railsを使う場合は、MySQLに対応するGemについての設定が必要です。

・ClearDBデータベースのURLを変数heroku_cleardbに格納

```
heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`
```

・データベースのURLを再設定(mysql2というGemを使用している時)

```
heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

またデプロイする際は、サーバーのアクセスキーやAPIキーなど暗号化する必要があります。

#### credentials.yml.encファイル

Railsで、外部に漏らしたくない情報を扱うファイルです。
通常時は、英数字の文字列で構成された暗号文で何が書かれているのか分かりません。
このcredentials.yml.encと対になるmaster.keyが存在する場合、credentials.yml.encの暗号文を復号し、ファイル内の記述を確認できます。

#### master.keyファイル

credentials.yml.encの暗号文を復号する、鍵の役割を持ったファイルです。
特定のcredentials.yml.encと対になっているため、その他のcredentials.yml.encへは、効果を発揮しません。
master.keyは重要なファイルなので、.gitignoreに記述されており、Gitで管理されない仕組みになっています。


・credentials.yml.encの中身を確認

```
EDITOR="vi" bin/rails credentials:edit
```

確認後は、「escキー」→「:」→「q」と入力、「enterキー」を押して credentials.yml.encを閉じる。

このままではただの暗号文なので、Heroku上に環境変数としてmaster.keyの値を設置します。

・Heroku上に環境変数の設定

```
heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```

・環境変数一覧の表示

```
heroku config
```

デプロイをする前に、Herokuで利用する環境を指定します。
Rubyのバージョン2.6.5は、Heroku-20では使用できないため、動作するStackを指定します。

・Stackを指定

```
heroku stack:set heroku-18 -a　アプリケーションの名前
```

#### Herokuへアプリケーションの追加

Herokuでデプロイするには、Gitを使用します。
Gitで管理しているリポジトリをHerokuへ反映することで、Heroku上で該当するアプリケーションの操作ができます。

・Gitで管理しているリポジトリをHerokuに反映

```
git push heroku master
```

・Heroku上でマイグレーションを実行
※runを付けないと上手く実行されません

```
heroku run rails db:migrate
```

・Herokuにデプロイされたアプリケーションの情報を確認

```
heroku apps:info
```

・Herokunoログを確認(--tailと付けると最後から10行のログを確認)

```
heroku logs --tail --app アプリケーションの名前
```

# 手順のまとめ

### はじめてデプロイをする場合

1. Herokuにアカウント登録
1. Heroku CLIをインストール
1. masterブランチへcommit
1. Heroku上にアプリケーション作成
1. MySQLを使用できるように設定
1. master.keyを環境変数として設定
1. Herokuへアプリケーションの情報をpush
1. Heroku上でマイグレーションを実行


デプロイ済みのアプリケーションに変更を加えた場合

1. 変更修正をcommitする
1. ブランチを作成していた場合は、masterブランチへマージする
1. Heroku上にpushする
1. テーブルに変更を加えた場合は、Heroku上でマイグレーションを実行する
google colaboratoryでmecabを使うまで

メモメモ

#1.ローカルでの準備
ローカルで色々と準備しないと動かなかった

```bash:mac
$ brew install mecab
$ brew install mecab-ipadic
#or
$ brew install mecab mecab-ipadic git curl xz
```

#2.colaboratory側で
```python:colab
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!pip install mecab-python3
```

```python:colab
!git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
!echo yes | mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n

!ln -s /etc/mecabrc /usr/local/etc/mecabrc
```
あとは`import MeCab`して使えるかを確認
Pythonウェブページのデータを取得

# Pythonウェブページのデータを取得
Pythonにライブラリrequests、解析ライブラリBeautifulSoupを介して情報を取得します、ここではYahoo（https://www.yahoo.com/）を例にします、ホームページTrending Nowの内容を取得します。

1）まずはライブラリrequests、BeautifulSoupをインポート
2）requests.get(url)を使ってウェブページのすべてのコンテンツを取得
```java
  requests.get(url)
```
3）取得したウェブページのコンテンツをBeautifulSoupタイプに変換
```java 
  bs = BeautifulSoup(result, 'html.parser')
```
4）解析Yahoo（https://www.yahoo.com/）のTrending Nowエリア、探し出す他の内容との違い、分析し発見するclass属性は唯一です。この属性を使って値を取得します。
find_all(class_='XXX')方法を使って値を取得します。
※classがpythonのキーワード、だからclass_を使用します。
その他ラベル、属性は直接使用できます。
例：
```python
  find_all('a')
  find_all(id='link2')
  find_all(["a", "span"])
```
など。
イメージ：
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209998/881e242f-b845-400d-5cd8-b753cf602406.png)


#### ソースコード

```python
# ライブラリ
import requests
# 解析ライブラリ
from bs4 import BeautifulSoup

# ウェブページurl
r = requests.get("https://www.yahoo.com/")
# タイプ
result = r.text
# BeautifulSoupタイプに変換
bs = BeautifulSoup(result, 'html.parser')
print("データ：")
# class属性を使って値を取得します
data1 = bs.find_all(class_='Mstart(-2px) C($c-fuji-grape-jelly):h C($c-fuji-inkwell) Fz(12px) Fw(600)')
# ループ出力
for i in data1:
    print(i.text)
```

#### 実行結果

```shell
C:\>"C:\Program Files\Python37\python.exe" D:/WeChat_Robot/CatchData/catchdata.py
データ：
 Carey Mulligan
 Hideki Matsuyama
 Kid Cudi
 Prince Phillip
 Biglietti da visita
 Antivirus Kaspersky
 Forni elettrici
 Camicie uomo
 Mascherine online
 Spesa online

Process finished with exit code 0
```
WindowsServerでio.netty.channel.abstractchannelエラーが発生したときの対処法(備忘録)

Minecraftサーバーをwindows server2019で建てようとした際にファイアウォールに阻まれて接続できなかった。

Windowsの設定→更新とセキュリティ→Windowsセキュリティ→ファイアウォールとネットワークの保護→ファイアウォールによるアプリケーションの許可→別のアプリの許可で
`C:\Program Files (x86)\Common Files\Oracle\Java\javapath_target_774203`のjavaを選択するとエラーが発生しなくなった。
Gitコマンド　基本的なコマンド

##Gitコマンドを忘れてしまった時の見直し　~> その2

####記載コマンドの種類一覧
`checkout` 変更を取り消したり、ブランチの切り替えを行う。
`reset` ステージへ上げた変更を取り消すコマンド
`--amend` **取扱注意のコマンド**
- - -

###変更をやり直したい時に使うコマンド
```ruby:checkout
git checkout -- <ファイル名>
git checkout -- <ディレクトリ名>

git checkout -- .
#現在いるディレクトリ以下の変更を全てを取り消す
```
”--”と付いてるのは、ブランチ名とファイル名が被ってしまった時に
gitがどっちを指しているのかが分かる様にするためにつけられている。
このコマンドで重要なのは、ステージにあげる前の変更に対して
変更を取り消しているということ
__つまり、`git add`した後の取り消しはまた別のコマンドが必要__


```ruby:reset
git reset HEAD <ファイル名>
git reset HEAD <ディレクトリ名>

git resetHEAD .
#全部の変更を取り消す
```

__指定した変更をステージから取り消すだけなので、
ワークツリーにあるファイルには影響を与えない__
つまり自分のローカルの中身は変更がないので、
もし、こちらも変更をしたいのであれば
`git checkout`をしないとワークツリーには反映されない


```ruby:amend
git commit --amend
#リモートリポジトリにpushしたコミットはやり直すと大変なことになる...
```
**本当に注意しないといけないのはあくまで`push`したコミットは
決してやり直してはいけない**
このコマンドの裏側で何を行っているのかというと、、、
ステージに上がっている変更を元にリポジトリの内容を
上書きするということをやっているため
最悪の場合は、マージができなくなる事もあるので
決してpushしたコミットに関して`--amend`コマンドは使わないこと
もし、コミットした内容を変更したい時は
新しくコミットして変更すること

ちなみに、`git --amend`コマンドの内容を確認する際は
`git log`などを使う事が多いと思うが小ネタとして

```ruby:log
git log -p -n 1 
#この様に打つと直前のコミットの内容が見れる
```
logに入っている最中は
"j＂を打つと下にスクロール、
"p"を打つと上に移動する。
抜けたい時は"q"を打てばいい
【Vue.js】Vueインスタンスのライフサイクル

## はじめに
仕事で使う事になったので1からVue.jsについて学んだ。
ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。

## Vueインスタンスのライフサイクル
Vueインスタンスにはライフサイクルという概念があり、以下のようなライフサイクル（フェーズ）がある。
これが分かっていると、DOMの描画後に...などの柔軟な実装ができるようになる。
![Vueインスタンスのライフサイクル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/e33972a2-82d6-b14c-6cda-2560b50c6fb5.png)
上記の図中の`状態(プロパティ)名`と書かれている部分がVueインスタンスが持つフェーズである。
各フェーズでconsole.log()を出力させるようにすると、以下の動画のように各フェーズに到達してconsole.log()が出力されているのが分かる。
![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/389e5b86-a266-9392-43f9-c47c63978f91.gif)
動画のソースコードは以下。

```html:sample.html
<body>
    <div id="app">
        <h1>こんにちは、{{name}}</h1>
        <button @click="name = '田中 太郎'">名前を変更</button>
        <button @click="destroy">インスタンスを破壊</button>
    </div>

    <script src=" https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script><script src="./vue.js"></script>
    <script>
        const vm = new Vue({
            // el: '#app',
            data: {
                name: '山田 花子'
            },
            beforeCreate: function () {
                console.log('beforeCreate');
            },
            created: function () {
                console.log('created');
            },
            beforeMount: function () {
                console.log('beforeMount');
            },
            mounted: function () {
                console.log('mounted');
            },
            beforeUpdate: function () {
                console.log('beforeUpdate');
            },
            updated: function () {
                console.log('updated');
            },
            beforeDestroy: function () {
                console.log('beforeDestroy');
            },
            destroyed: function () {
                console.log('destroyed');
            },
            methods: {
                destroy: function () {
                    this.$destroy();
                }
            }
        })

        setTimeout(() => {
            vm.$mount('#app')
        }, 3000);
    </script>
</body>
```

※`destroy`の動きについて
destroyはVueインスタンスを破壊するものであるが、実際にdestroyを行うと以下の動画のようにVueの機能（ここではクリックイベントを発火し`name`を書き換え、それがリアクティブに反映される）が動かない事が確認できる。
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/84725750-4f9b-2d70-0abe-8acb9af319c5.gif)

## Vue.jsの勉強メモ一覧記事へのリンク
Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。

- https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
PHP5上級試験/準上級試験の上級合格に挑戦(23) 上級落ちました その３

# 今日の結果

ご無沙汰してしまった。
[前回の記事](https://qiita.com/Atsulabo/items/0d64c97c4c1aba2ebfd3)から、投稿してなかったが、
その間ずっと勉強していた。
で、今日、再度試験を受けた、その結果。

落ちた。

しかも７５０点という中上級合格点ギリギリで。

序盤で難しい問題にあたってしまい、そこで精神が折れたのか、
ど忘れしたりとかそういうケアレスミスを連発し、こういう結果に。

もう一回やり直しかぁ。。。

#　各カテゴリごとの得点
| セクション | 正解率 | 前回 | 判定 |
|:-:|:-:|:-:|:-:|
| 関数  | 50%  | 50%  | - |
| 文字列 | 50%  | 50%  | - |
| 配列 | 67%  |67%  | - |
| オブジェクト | 17%  | 50% | ↓ |
| ウェブに関するテクニック | 75%  | 88% | ↓ |
| データベース | 40%  | 100% | ↓ |
| グラフィックス | 50%  | 50% | - |
| PDF | 100%  | 100% | - |
| XML | 25%  | 75% | ↓ |
| セキュリティ | 57%  | 57% | - |
| アプリケーションに関するテクニック | 60%  | 40%| ↑ |
| PHPの拡張 | 50%  | 0% | ↑ |
| WindowsでのPHP | 100%  | 0% | ↑ |
| SPL日付クラスPEAR | 0%  | 50% | ↓ |
| 名前空間　クロージャー　リフレクション　遅延静的束縛 | 0%  | 0% | - |
| JSON | 0%  | 100% | ↓ |
| PDOとmysqlndドライバ | 100%  | 0% | ↑ |
| 正規表現 | 100%  | 0% | ↑ |
| APD/xdebug memcache | 0%  | 100% | ↓ |
| フィルター | 100%  | 0% | ↑ |

点をとっていなければならないところで多く下回った。
ひとまずコスパがいいところと、点数が必要なところからがんばっていきたい。

# 勉強方法の振り返り

勉強方法を振り返ってみると、
弱点補強というより、ずっと、全体をまんべんなくやってたので、
深いところまでできていなかったのが敗因なのだろうなぁと思う。

ただ、まんべんなくやらないと頭の悪い俺の頭だと、
すっかり忘れてしまいそうで怖かったのだと思う。

そのせいで、新たな知識を得るというところまでいけてなかった。
ガッデム。

テストを受けたあと、カフェでテストの問題を思い出しながら、
黒本の各章を振り返ってみると
（問題は転載禁止なので、法に触れない範囲で）

たいてい、
・各章で出されると嫌なところ（メモでは具体的なところまで書いてるけど、書けないので、
　うーん、、、自分が出題者だとしたら、どこを出題するか考えてみるとよいかも。）
・黒本では文章だけでしか言及しておらず、コードもないところでコード出される。
　たいてい、章の程よく進んだところが多い。
・あんまり実務では使わなさそうな章。
・黒本には書いていないけど、もしこういうふうにしたらどうなる問題
・各章のリストや、似たようなところや、使えるようになったバージョン、関数の引数の並び方などは要チェック。

→記事を書かなくなったのは、実は具体的な問題を書いてしまいそうだから。
 
# 今後

・各章で、自分で出題者になったつもりで問題を作成し、コードも書き、実際にどうなるか確かめておく。
・各章で、文章だけしか言及していないところをコードを書いてみて、実際にどうなるか確かめておく。
　→その後、ノートにもコードと出力を赤ペンで書いていつでもクイズで確認できるようにする。
・各章のコードを穴埋め問題にして、作ってみるのもあり
・実務で使わなさそうな章は、復習をしっかり。
・各章のリスト・使えるようになったバージョン・関数の引数の並び方など。
・学んだことを使って、もしこうなったらどうなるかコードを書いてみて知っておくのも有効か


# うーん

落ちたのは実は５回目。書き始めたのは２回目ぐらい？からなので。
まあこう連続で落ちると、モチベも下がるのだけど、勉強方法が悪かったと思ってがんばるしかないなぁ。
ただ、試験を受けるたびに、毎回答えられなかったところをマスターしていっているので、今後の対策も建てられたことなので、頑張っていきたい。

できれば、廃止になる９月までには合格したい。いや、してみせる。

今後、Wordpressを使ったPHPの仕事が本格的になるので、学んだことを実践できるようにがんばりたいところ。
仕事をしながらも勉強も並行して進められるように計画立ててすすめていきたい。
 
PHPerになるんや！　バックエンドエンジニアとして食べていくんやあああああ！！！！

と、さけんでおく。
WebViewでWebページを表示する機能の実装まとめ(Xcode/Storyboard)

WKWebViewを使ってWebページの表示の基本的な実装の仕方を記事にしました。

#環境
・Mac Book Pro(macOS:BigSur)
・Xcode(ver:12.5)

#実装例
![Unknown-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864623/e7b2bcda-9e0c-15ce-655a-a1fd3c370b78.gif)

#コード例
```ruby:ViewController.swift

import UIKit
import WebKit

class ViewController: UIViewController,WKNavigationDelegate {
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var indicator: UIActivityIndicatorView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.navigationDelegate = self
        
        let request = URLRequest(url:URL(string: "https://www.google.co.jp/")!)
        
        webView.load(request)
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        indicator.startAnimating()
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
      
        indicator.stopAnimating()
        indicator.isHidden = true
    
    }
 
}
```

Webページが表示される前に、indicatorのアニメーションをつけることで表示待ちを表現できます。
$refs を使って親コンポーネントから子コンポーネント内の関数を触る

エンジニア見習いとして働き始め（2021年3月1日〜）て2ヶ月半が経ちました。

親コンポーネントでの操作をする際に、同時に子コンポーネント内の関数を呼びたいケースが業務でありまして。
具体的には親コンポーネントにあるプルダウンメニュー内の値を選択すると同時に、
子コンポーネントにあるフォームに入力された内容を自動で保存させる（子コンポーネントにフォーム内容を保存する処理があったのでそれを呼ぶ）ようにしたかったんです。

$refsを使って子コンポーネント内の関数を呼ぶことができました。

###①ref属性を使い、子コンポーネントにリファレンスIDを割り当てる
```vue:親コンポーネント
<template>
  <child-Component ref="child"></child-Component>
  ・
  ・
  ・
</template>
```
refとはreference（参照）の略。
まずは子コンポーネントにアクセスするためのIDをrefという属性を使って割り当てます。
ID名は自由です。

###②$refsを使って親コンポーネントから子コンポーネントにアクセス
```vue:親コンポーネント
<script>
  // saveCommentは子コンポーネント内の関数
  this.$refs.child.saveComment()

</script>
```
this.$refs.[参照ID].[参照先の関数] 
とすることで親から子の関数を実行させることができました。

## 参考
[Vue.js 特別な問題に対処する](https://jp.vuejs.org/v2/guide/components-edge-cases.html)
SpringBootの環境構築

# SpringBoot環境構築

## はじめに
SpringBootでWebアプリケーションを作ってみたかったので[公式リファレンス](https://spring.pleiades.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started)を見ながら環境構築をやっていきます。
自分の記録用なので環境構築をしたい方は公式リファレンスを見ながらやったほうがいいと思います。。
ちなみにJavaでフレームワークを使うのは初めて。サーブレットとJSPで簡単なものを作ったことあるぐらいのレベル。

## 開発環境

```
mac osx 10.15.7
java 16.0.1
maven 3.8.2
```
インストールの説明割愛。

## Spring Boot CLIのインストール
Homebrewを使用してるので以下でインストールしました。

```
$ brew tap spring-io/tap
$ brew install spring-boot
```

## POMの作成
VScodeを開きディレクトリを作成、そこに`pom.xml`を作成。

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <description/>
    <developers>
        <developer/>
    </developers>
    <licenses>
        <license/>
    </licenses>
    <scm>
        <url/>
    </scm>
    <url/>

    <!-- Additional lines to be added here... -->

</project>
```

`pom.xml`はMavenコマンドを実行する際にプロジェクトを管理するビルドファイル。
(POMはProject Object Modelの略)


## コードの作成
Mavenは`src/main/java`からソースをコンパイルを行う。
したがって以下のファイルを`src/main/java/Example.java`に作成した。

```java:Example.java
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Example.class, args);
    }

}
```

`@EnableAutoConfiguration`がよくわかりませんでした。
`main`メソッドは、引数に`Example.class`と`args`配列を渡して、`SpringApplication`クラスの`run`メソッドを呼び出してます。
これにより自動構成されたTomcatWebサーバが起動するそうです。

## 実行
以下を実行

```
$ mvn spring-boot:run 
```
http://localhost:8080/ にアクセスして`Hello World!`と表示されればOK

##よくわからんかった
- `@EnableAutoConfiguration` アノテーション
- jarの依存関係とか
M5StackとMH-Z19Cで部屋のCO2濃度を測定してみた

室内のCO2濃度が1000ppmになると、思考力、集中力が減少するとのことで
室内のCO2濃度を測定してみました。
使ったのはM5StackとMH-Z19Cです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483586/2655d94d-23bf-f4c3-a31c-815ffdd9f941.png" width=50%>

MH-Z19Cは2秒/回程度、赤ランプが点灯しますが、見つめてなければ気にならない程度です。
また、MH-Z19Cでは温度も取得できるようですが、精度良くなさそうです。
(写真撮影時に温度が28℃あったとは思えないです。)
取得方法間違えていたらスミマセン。

* 環境
    * M5Stack Basic
    * MH-Z19C
    * Windows 10 (作業用PC)

* 事前準備
    * 作業用PCにArduino IDEとCP210X Driverをインストールしてください。
        * 詳細は[過去記事](https://qiita.com/Yukitaku/items/cb10e6b71604cd48a84c)を参考にしてください。
    * [mh_z19](https://github.com/nara256/mhz19_uart)ライブラリをインポートしてください。
        * zipをダウンロードし、Arduino IDEにインポートしてください。
        * ソースコードから参照するため、MHZ19_uart.hを参照可能な箇所に保存してください。
        * 詳細は[こちら](https://qiita.com/nara256/items/a3cecc5fbf043b2d042c)をご参照ください。

* 接続
    * M5Stack BasicとMH-Z19Cの接続も[こちら](https://qiita.com/nara256/items/a3cecc5fbf043b2d042c)を参考にしました。

| M5Stack側 | MH-Z19C側 |
|--|--|
| "G"    | "GND" |
| "5V"   | "Vin" |
| "16"   | "Tx"  |
| "17"   | "Rx"  |


* ソースコード
ほぼ[参考元](https://qiita.com/nara256/items/a3cecc5fbf043b2d042c)のコピペで作成しました。

```
#include <M5Stack.h>
#include "MHZ19_uart.h"

#define RX 16
#define TX 17
#define INTERVAL 1  // 毎秒表示

MHZ19_uart myMHZ19;

void setup(){

  M5.begin();
  M5.Power.begin();
  M5.Lcd.setTextSize(5);
  M5.Lcd.print("start");

  delay(100);
  myMHZ19.begin(RX, TX);
  myMHZ19.setAutoCalibration(false);
}

void displayCo2(int co2, int temp) {
  M5.Lcd.clear(); 
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("CO2 ppm");
  M5.Lcd.println(co2);
  M5.Lcd.println("Temperture");
  M5.Lcd.print(temp);
}

int count = 0;
int co2 = 0;
int temp = 0;
void loop()
{
  if ((count % INTERVAL) == 0 ) {
    co2 = myMHZ19.getCO2PPM();
    temp = myMHZ19.getTemperature();
    displayCo2( co2, temp );
  } else {
     M5.Lcd.print(".");
  }
  count++;
  delay(1000);
}
```

Arduino IDEで上記ソースコードを保存します。
その後、コンパイルとマイコンボードへの書き込みを実施すると
M5Stackの画面に冒頭のCO2濃度(ppm)と温度が表示されました。

* 参考元
    * [ESP32(M5Stack)で作る、安価なCO2モニタ【秋月でCO2センサ取扱開始 記念】](https://qiita.com/nara256/items/a3cecc5fbf043b2d042c)


## おまけ
作業中、次のコンパイルエラーが発生しました。

```
「WiFi.h」に対して複数のライブラリが見つかりました
使用済：C:\Users\hogehoge\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi
未使用：C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\WiFi
「SD.h」に対して複数のライブラリが見つかりました
使用済：C:\Users\hogehoge\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.6\libraries\SD
未使用：C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\libraries\SD
```

使用済のフォルダは削除可能でしたが、削除して再コンパイルすると次のエラーが発生したため、削除差し戻し。

```
"Architecture or board not supported"
```

未使用のフォルダは削除できなかったため、Arduino IDEをアンインストール。
そしてArduino IDEを再インストールするとエラーは解消しました。
IntelliJ IDEA 2021.1で自動保存を無効化する設定

`IntelliJ 自動保存`とかでググった結果が、2021.1に設定画面と一致しない記事が多く、どこかのバージョンアップのタイミングで設定画面が変わってしまったのかも…なので、設定画面をまとめる

（IntelliJ、デフォルトで自動保存される設定になっていますが、その度コンパイル走ってしまったりするので個人的には微妙に思ってしまいます）

# 自動保存の設定画面
公式：https://pleiades.io/help/idea/system-settings.html

![スクリーンショット 2021-05-16 21.53.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110469/614234fc-fd90-0496-cf9c-dd7ff0dd8bd5.png)

- Save files if the IDE is idle for xx seconds： IntelliJで編集中に自動保存していくかという設定。オンにした場合はアイドル状態の秒数を指定する。逆にこれをオフにしている限りは、IntelliJ起動中に自動保存されることはないという設定のようだ
- Save files when switching to a different application： IntelliJ以外のアプリケーションに切り替えるときに保存。編集→ブラウザ確認、とかのサイクルを回している場合はタイミングとしては良いかも
- Back up files before saving： 文字通りバックアップの設定。保存せず編集していてIntelliJが落ちてもバックアップから復帰させられるというもの
- Synchronize external changes when switching to the IDE window or opening an editor tab：　別のアプリケーションからIntelliJに切り替えるときに、外部で変更されたファイルを再ロードする。IntelliJで開いているファイルを他のアプリケーションからも変更する使い方をしているときには便利？

ちなみに上2つをオフにすれば自動保存されなくなるような気もするのだが
> これらのオプションを無効にして自動保存を完全に無効にすることはできません。詳細については、ソースコードの作成と編集セクションを参照してください。

とか書いてあって、以下のページを参照と言われる。

https://pleiades.io/help/idea/working-with-source-code.html#auto_save

> IntelliJ IDEA は自動的にあなたのファイルに加える変更を保存します。保存は、コンパイル、実行、デバッグ、バージョン管理操作の実行、ファイルやプロジェクトのクローズ、IDE の終了など、さまざまなイベントによって引き起こされます。

要するにIntelliJがやったことでファイルに変更が入るならそれは自動で保存されるよ！ということみたいですね。
このあたりはふわっと書いてあるので実際に使ってみないとちょっとわからないですね。

# 未保存の変更があるファイルにマークをつける
一般的なエディタでありがちな未保存の場合のマークを設定もできます。

https://pleiades.io/help/idea/working-with-source-code.html#cc30e07a
【jq】bashでjson配列をループさせる

`jq`の`-c`オプションを使うことで、シンプルにループ処理が可能。

> --compact-output / -c:
> By default, jq pretty-prints JSON output. Using this option will result in more compact output by instead putting each JSON object on a single line.

```array.json
$ JSON='
[
    {
        "name": "JSON",
        "good": true
    },
    {
        "name": "XML",
        "good": false
    }
]
'
```

```sh
IFS=$'\n'; for item in $(echo $JSON | jq -c '.[]'); do
  echo $item | jq .name
done

# "JSON"
# "XML"
```

## 参考
- [jq Manual (development version)](https://stedolan.github.io/jq/manual/)
- [looping through JSON array in shell script · GitHub](https://gist.github.com/OlegGorj/43ce94d8447d31da335db822b8682de9#formatting-the-result)
- [bash - How to read complete line in 'for' loop with spaces - Ask Ubuntu](https://askubuntu.com/questions/344407/how-to-read-complete-line-in-for-loop-with-spaces)
MacでiPhoneが接続されているかをterminal上で確認するにはsystem_profiler SPUSBDataTypeを使おう

なんか動作がおかしいiPhoneがったのでUSBに接続して中身を見たかったのだけど、どのレベルで認識されていないのか調べたのでついでにこれもやってみた。

terminal上で確認したい場合`system_profiler SPUSBDataType`で確認する。

(linux系ではlsusbコマンドで表示されるが、Macだと独自コマンドらしい) 

出力例:

```console 
 
$ system_profiler SPUSBDataType  
                                                                    
2021-05-16 21:40:22.748 system_profiler[2972:64012] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
USB:

    USB 3.1 Bus:

      Host Controller Driver: AppleUSBXHCIAR
      PCI Device ID: 0x15d4 
      PCI Revision ID: 0x0002 
      PCI Vendor ID: 0x8086 
      Bus Number: 0x01 

    USB 3.1 Bus:

      Host Controller Driver: AppleUSBXHCIAR
      PCI Device ID: 0x15d4 
      PCI Revision ID: 0x0002 
      PCI Vendor ID: 0x8086 
      Bus Number: 0x00 

    USB 3.0 Bus:

      Host Controller Driver: AppleUSBXHCISPTLP
      PCI Device ID: 0x9d2f 
      PCI Revision ID: 0x0021 
      PCI Vendor ID: 0x8086 

        iPhone:

          Product ID: 0xXXXX
          Vendor ID: 0x05ac (Apple Inc.)
          Version: 11.06
          Serial Number: XXXXXXXXXXXXXXXXXXXX
          Speed: Up to 480 Mb/s
          Manufacturer: Apple Inc.
          Location ID: 0x14500000 / 5
          Current Available (mA): 500
          Current Required (mA): 500
          Extra Operating Current (mA): 1900
          Sleep current (mA): 2400

        Apple T1 Controller:

          Product ID: 0xXXXX
          Vendor ID: 0x05ac (Apple Inc.)
          Version: 1.01
          Manufacturer: Apple Inc.
          Location ID: 0x14100000

```
モーダルで表示するYouTube動画をボタンごとに切り替え

#はじめに
　今回[なでしこジャパン応援団体eAstBlueのHP](https://eastblue-nadeshiko.com/)を作る際に調べて出てこなかった内容を書き留めたものです。この記事を見た方にとって参考になっていましたら幸いです。

#モーダルでYouTubeの表示
　今までHTML埋め込みの形ではやっていました。同様の方法でモーダルにそのまま埋め込んだ場合に起こった問題。__モーダルを閉じても動画が止まらない__ことがわかりました。[YouTube公式のマニュアル](https://developers.google.com/youtube/player_parameters?hl=ja)を参考に実装しました。

```HTML:YouTube埋め込み部分のタグ
<div id="ytplayer"></div>
```


```JavaScript:使用するスクリプト
// iframeへのYouTubeAPI埋め込み
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      
// 'ytplayer' に <iframe> を置き換える処理
var player;
function onYouTubePlayerAPIReady() {
  player = new YT.Player('ytplayer', {
           height: '100%',
           width: '100%',
           videoId: 'oEcY98MFRR8'
  });
}

// モーダルを閉じる処理の中で入れるコード
player.stopVideo();
```

これによってモーダルを閉じると同時に動画も止まるようになりました。
しかし、これだけでは足りません。ボタンごとに表示される動画が切り替わる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955604/ea76b490-112c-0c17-3816-63d5bf8936b1.png)

#切り替え制御の実装
　それでは今回の本題です。まず埋め込む要素を必要数用意し、パラメーターを定義する変数を配列にします。

```HTML:YouTube埋め込み部分のタグ
<div id="ytplayer-call-nippon"></div>
<div id="ytplayer-chant-vamosnippon"></div>
<!-- 埋め込む数だけ定義 -->
```


```JavaScript:パラメータ部分の変更
var player = [];
function onYouTubePlayerAPIReady() {
  player[0] = new YT.Player('ytplayer-call-nippon', {
           height: '100%',
           width: '100%',
           videoId: 'JHrh_MX69T0'
  });
  player[1] = new YT.Player('ytplayer-chant-vamosnippon', {
           height: '100%',
           width: '100%',
           videoId: '9jSQvqjgNCc'
  });
  // 埋め込む数だけ定義
}
```

このままにすると全ての動画が表示されてしまいますのでCSSでコントロールします。
ボタンが押された際に全体からshowクラスを削除し、ボタンに対応する部分にshowクラスを付与します。

```CSS:CSS
[id^="ytplayer"]{
  display: none;
}
[id^="ytplayer"].show{
  display: block;
}
```

#さいごに
　今回紹介した方法が最適でないかもしれません。理由としてはこちらphpを使ったCMS化を考えていましてphpでコードを生成しやすい構造を考えたからです。「もっといい方法があるよ！」ということでしたら是非コメントにて教えてください！他にもプログラミングやデザインでアドバイスくださるととても嬉しいです！
flexのこと理解してる？？説明できる？？((煽

まず、flexには
・flex container（親）
・flex item（子)
の二種類が存在します.（両者はコード上ではどちらもflexと表記します。）
この二つは親子の関係にあり、flex item(子)の中に新たなflex item（子）を書いた場合はこの二つも親子の関係になります。すなわち、flex item(子)はflex container(親)にもなり得るわけです。
次のコードを見てみましょう。

```react:App.js（２階層、つまり親子の関係のみ）
<View style={{flex: 1}}> #親
  <View style={{flex: 1}}> </View> #子
  <View style={{flex: 2}}> </View> #子
  <View style={{flex: 3}}> </View> #子
</View>
```

![名称未設定のノート-2 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505731/43d3a757-fb23-cd22-8319-c52e3b98be62.jpeg)


このコードでは親子関係のみです。つまり第一階層がflex container、第二階層がflex itemに当たります。

```react:App.js（３階層、つまり親子孫の関係、または親子の関係が二つ）
<View style={{flex: 1}}> #親
  <View style={{flex: 1}}> #子(一個下の階層との関係ではflex containerつまり親にもなり得る）
    <View style={{flex: 1}}> </View> #孫
    <View style={{flex: 2}}> </View> #孫
    <View style={{flex: 3}}> </View> #孫
  </View>
  <View style={{flex: 2}}> </View> #子
  <View style={{flex: 3}}> </View> #子
</View>
```

![名称未設定のノート-3 3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505731/a4a397b6-5d50-94a4-6095-110f229fd59e.jpeg)




このコードでは親子孫の関係があります。第一階層は親、第二階層は子（または親とも見なせる）、第三階層は子（第一階層からすれば孫）です。


そしてここが一番重要な部分ですが、

・同階層にflexを持つ’<View>‘などが"複数"ある場合は、そのflexの数の比率で画面を分割します。
例えば最初の例では全画面が（デフォルトでは上から1:2:3)に分割されます。
また、二つ目の例では全画面が1:2:3に分割された後、３分割のうち一番上の領域がさらに1:2:3に分割されます。なので領域は全部で５つ生じます（サイズ比は1:2:3:12:18)になります。

・同階層にflexを持つ’<View>‘などが"一つだけ"ある場合は、そのflexの数字自体には何の意味もありません。どんな数字でもいいので入れておけばオッケーです。（逆にflexを与えないと画面が真っ白になってしまいます。）
その後同階層に二つ目以降の<View>などを付け加えた時に初めて、画面をその比率で分割するという意味を持つようになります。

説明は以上です。最後まで読んでいただいてありがとうございました。少しでも参考になれば幸いです！
【kotlinx-metadata】KmClass(KClass)がsealed classか判定する

# TL;DR
- `Flag.IS_SEALED(KmClass.flags)`で判定できる
- エッジケースの考えると`KmClass.sealedSubclasses`が空か否かで判定した方がいいかもしれない

# 本文
`org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.3.0`で検証しています。

## やること
`kotlin-reflect`無しで[^isSealed]、以下の3クラスについて、それぞれ`sealed class`か否かを判定します。

[^isSealed]: `kotlin-reflect`有りなら`KClass.isSealed`/`KClass..sealedSubclasses`で今回やっている内容は実現できます。

```kotlin:判定対象
package com.wrongwrong

// 子持ちsealed class
sealed class HasChild {
    object Child1 : HasChild()
    object Child2 : HasChild()
}

// 子無しsealed class
sealed class NoChild {}

// sealed classじゃない
object NotSealed
```

## やり方
判定対象が`sealed class`かは`Flag.IS_SEALED(KmClass.flags)`で判定できます。
ただし、例に含めた通り、`sealed class`かつ子無しというエッジケースが有りうるため、実用時には`KmClass.sealedSubclasses`が空か否かで判定した方がいいかもしれません。

```kotlin:サンプルコード（※KmClassの取得方法は補足に掲載）
import kotlinx.metadata.Flag
import kotlinx.metadata.KmClass

val hasChildKmClass: KmClass = getClassMetadata<HasChild>().toKmClass()
println(Flag.IS_SEALED(hasChildKmClass.flags)) // -> true
println(hasChildKmClass.sealedSubclasses) // -> [com/wrongwrong/HasChild.Child1, com/wrongwrong/HasChild.Child2]

val noChildKmClass: KmClass = getClassMetadata<NoChild>().toKmClass()
println(Flag.IS_SEALED(noChildKmClass.flags)) // -> true
println(noChildKmClass.sealedSubclasses) // -> []

val notSealedKmClass: KmClass = getClassMetadata<NotSealed>().toKmClass()
println(Flag.IS_SEALED(notSealedKmClass.flags)) // -> false
println(notSealedKmClass.sealedSubclasses) // -> []
```

### 補足
サンプルコードで省略した`KmClass`の取得コードです。

```kotlin
import kotlinx.metadata.jvm.KotlinClassHeader
import kotlinx.metadata.jvm.KotlinClassMetadata

fun Metadata.toKotlinClassHeader() = KotlinClassHeader(
    this.kind,
    this.metadataVersion,
    this.data1,
    this.data2,
    this.extraString,
    this.packageName,
    this.extraInt
)
// KClass -> metadataの変換
inline fun <reified T : Any> getClassMetadata() = (T::class.java.annotations.first { it is Metadata } as Metadata)
    .toKotlinClassHeader()
    .let { KotlinClassMetadata.read(it) as KotlinClassMetadata.Class }
```
MapperクラスのSQLで不等号を使いたい（MyBatis） 


## 困ったこと
MapperのSQLをXMLに記載するとき、不等号（大なり、小なり　など）を使用すると、
「要素のコンテンツは、整形式の文字データまたはマークアップから成るものでなければなりません。」
のエラーになってしまう。

## 解決方法
`<![CDATA[`と`]]>`で囲むと良い.
以下の2つがあるが、1がおすすめ。


### 1. 該当箇所を囲む

```.Java
  <select id="methodName" parameterType="EntityClass" resultType="Integer">
    SELECT 
        id
    FROM
        test
    WHERE
         <![CDATA[ 
         start_date <= NOW()
         and
         end_date > NOW() 
         ]]>
  </select>
```

### 2. SQL文全体を囲む
この方が可読性が良いが、動的SQLを記載しても反映されない。

```.Java
  <select id="methodName" parameterType="EntityClass" resultType="Integer">
    <![CDATA[
    SELECT 
        id
    FROM
        test
    WHERE
         start_date <= NOW()
         and
         end_date > NOW())
    ]]>
  </select>
```
Vuetify Vue 確認ダイアログ

## 作りたいもの
「開く」ボタンをクリックすると以下のようなダイアログを出す。
「閉じる」ボタンでダイアログを消し、
確認ボタンを押すとメソッドを実行する。

![スクリーンショット 2021-05-16 21.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147821/f8f93d37-6d64-ada9-df39-38d0caeba469.png)

## サンプル

my_dialogを初期はfalseにしておき、
「開く」ボタンをクリックすると、`@click="my_dialog = true"`でtrueになりダイアログを出す。

```.vue
<template>
  <v-app>
    <v-btn @click="my_dialog = true">開く</v-btn>
    <v-dialog v-model="my_dialog" max-width="400">
      <v-card>
        <v-card-title>
          <div>タイトル</div>
        </v-card-title>
        <v-card-text>
          <p>本文</p>
        </v-card-text>

        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn @click="my_dialog = false">閉じる</v-btn>
          <v-btn @click="confirm">確認</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-app>
</template>
<script>
export default {
  data() {
    return {
      my_dialog: false,
    }
  },
  methods: {
    confirm() {
      alert('確認しました')
      this.my_dialog = false
    },
  },
}
</script>
```
CircleCIの基礎オブ基礎

#はじめに
明日からCirckeCIを使用してCI/CDパイプラインの構築をしていくので、本日はそもそも「CircleCI」ってなんなの？という基礎オブ基礎ところから簡単に自分の言葉でまとめてみました

#CircleCIとは

まず大前提に、CircleCIとはなんなのか。それは、クラウド型のCI/CDツールです。
はい、まず初心者でこの一文を理解できた方はこの後の記事は読む価値ありませんのでここでやめましょう笑

かつて私も、最初この一文をみて1ミリも理解できませんでした。
そもそも、CI、CDの説明から必要ですね。

###CI（継続的インティグレーション）
CIとは、CIとはテストや静的コード解析などの作業を自動化し、継続的に実行する手法です。
これにより、開発者は早期に問題を発見でき、ソフトウェア品質の維持・向上が容易できるようになります。

###CD（継続的デリバリー）
CDとは各環境へのデプロイ作業を自動化し、継続的に実行する手法です。

以上を踏まえると、CircleCIではテスト、ビルド、デプロイを自動化するツールであることがわかります。
ちなみに、最近はGithubActionも流行りみたいです

#CircleCIの必要性
近年のプログラミング言語やフレームワークのバージョンアップはすさまじい勢いで更新されます。そのため、逐一テストを書いていては追いつくことはできません。また、テストの種類も単体テスト、E2Eテストなどなど様々なものがあり、コーディング量も膨大になります。また、デプロイに関しても操作ミス等の可能性を考慮すると自動化にした方がいいことは言うまでもありません。
だから、テスト・ビルド・デプロイの自動化は実務では当然必須となるわけです。


#私がポートフォリオに組み込む理由
私が転職用になぜCircleCIを取り入れようと思ったのかも記しておきます。

まず以下2つの理由があります。

- テストを自動でやってくれるので開発効率が上がるから
- 実務でよく使われているため

1つめの開発効率が上がるという点については、毎回自身が開発を進めるたびにいちいちテストを実行するのがめんどくさいなと単純に思っていたので、CircleCIのようなツールがあるのであれば入れてみようと考えました。

2つめの、実務で使われているからと言うのは、未経験の私でも実務で少しでも役に立ちたいと思い、せめて多くの現場で使われているようなツールは自分で勉強したいなと思ったからです。一部のスクールでは教えてもらうことが当然みたいで、ある種CircleCIが未経験市場では当たり前の実装になってきているとうこともありますが、基本的には「できることは自分でやってから転職したい」と言う思いがあり、今回実装することにしました。

#おわりに
明日からいよいよ取り組むわけですが、またしてもエラーとの戦いになりそうで楽しみです笑
Laravel6.x  Font Awesomeの使い方。

FontAwesomをしようするとwebアイコンフォトを簡単に使用することができます。

##実装環境
* PHP7.3
* Laravel 6.20.26


##前提条件
Font Awesomeをインストールするのに`npm`をしようするので`npm`はインストールしていることを前提としています。
ターミナルで`npm -v`とするとインストールされていたらバージョンが出るので確認してみてください。


##実装手順
1. FontAwesomをsインストール
2. インストールしたFont awesomeが使えるよう必要なデータをインポートする



##1.FontAwesomをインストール
ターミナルに移動して` npm install --save-dev @fortawesome/fontawesome-free`を実行することでパッケージをインストールすることができます。

```
$npm install --save-dev @fortawesome/fontawesome-free
```

##2. インストールしたFont awesomeが使えるよう必要なデータをインポートする
`resources/js`配下にfontawesome.jsファイルを作成して必要なデータをインポートする。

```PHP:fontawesome.js
1 import "@fortawesome/fontawesome-free/js/fontawesome";                                                                                                    
2 import "@fortawesome/fontawesome-free/js/brands";
3 import "@fortawesome/fontawesome-free/js/solid";
4 import "@fortawesome/fontawesome-free/js/regular";
```

`fontawesome.js`ファイルにデータを入れたら次は`resources/js`配下`app.js`があるのでそちらに下記を記入する。

```js:app.js
require("./fontawesome");
```

`app.js`に記入しておくと`resources/views/layouts/app.blade.php`に下記のような記述があるので読み込んでくれる

```js:app.blade.php
 <script src="{{ asset('js/app.js') }}" defer></script>
```
これで準備は完了です。


##使用方法
下記のようにすると簡単にwebアイコンフォトを使用することができます。

```HTML
<i class="fas fa-camera fa-3x"></i>
```
今回はカメラのアイコンフォトを使用しました。
![スクリーンショット 2021-05-16 20.53.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1477510/7d83b268-b426-8a76-7df2-c5a3d52bae22.png)


今回は`JavaScrip`でパッケージを読み込んだのですが`CSS`でも読み込むことができます。
httpd start できない  (2)No such file or directory: AH02291: Cannot access directory '/etc/httpd/logs' for main error logというエラーが出る

#httpd start できない

Apacheを起動させようとすると、下記のようなエラーがでました。

```ターミナル.
$ sudo service httpd start

(2)No such file or directory: AH02291: Cannot access directory '/etc/httpd/logs' for main error log
AF00014: Configuration check failed

```


### 参照画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602083/0ab53d67-cac1-8298-4688-22a0d960e774.png)


エラーを見ると、'/etc/httpd/logs'というディレクトリが存在しないということのようです。

###/etc/httpd/logsディレクトリを作成しようとしてもできない

```ターミナル.
$ sudo mkdir /etc/httpd/logs/
mkdir: cannot create directory ‘/etc/httpd/logs/’: File exists

```

すでにそういったファイル(ディレクトリ?)が存在していて作れないよというエラーっぽいです。


本当にあるのか？？ということでディレクトリを移動して調べてみました。

![スクリーンショット 2021-05-16 19.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602083/783438fd-258f-9843-b170-0a71c62b768c.png)

赤く表示されています。謎です。

調べたところ、こちらリンクファイル(シンボルクリック)と呼ばれるもののようです。
リンクファイル(シンボルクリック)とは実態は別にあるファイルのことだそうです。


では本体がどこにあるのか調べてみます。 ls コマンドに -l　オプションを付けるとファイルの詳細も確認できます。

![スクリーンショット 2021-05-16 19.43.37 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602083/35787695-6f45-b59b-3bde-0242fd18ab1b.png)



すると、一番右に実態の正体が表示されました。

そして、/var/log/httpdディレクトリを探しに行くと、こちらのディレクトリが存在しなかったので、
作成しました。

```ターミナル.

$ sudo mkdir /var/log/httpd

```

その後、``$ sudo service httpd start``をすると、問題なくApacheを立ち上げることができました。


##整理
 /var/log/httpdは、Apacheのログが保存されるディレクトリです。
このディレクトリがなかったために、Apacheを起動できなかったようです。

エラーででていた、/etc/httpd/logs/は/var/log/httpdへのシンボルクリックでした。
 /var/log/httpdへアクセスするためのリンクのようなものと解釈。
【検証】PostgreSQLをインストールする

今回はGitLabサーバーで利用するDBサーバー(PostgreSQL)を別のサーバーから参照するために、その準備としてPostgreSQLをインストールします。

#PostgreSQL インストール
まずは以下のコマンドを実行し、パッケージの取得を行います。

```
yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
```

続いて以下のコマンドでPostgreSQLサーバーをインストールします。

```
yum -y install postgresqlXX-server #XXにはバージョンを指定（最新verは13の模様）
※以降、バージョン13として記載する
```

インストール完了後、以下コマンドで初回起動を実行します。
注意点として、root等の特権ユーザーでは実行出来ないため、コマンド実行前に`postgres`ユーザーにスイッチします。

```
su postgres
/usr/pgsql-13/bin/initdb -D <データベースのディレクトリ>　#データベースの格納先のデフォルトは「/var/lib/pgsql/13/data/」
※ちなみに過去のバージョンだとデータベースの格納ディレクトリは/var/lib/pgsql/data/だったようです
```

上記コマンド実行後、`Success`と表示されれば成功です。
続いて以下のコマンドでサービスの起動を行います。

```
systemctl start postgresql-13.service
```

サービス起動後、`psql -l`コマンドを実行して以下のような結果が出力されれば実行出来ています。

```
psql -l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileg
es
-----------+----------+----------+-------------+-------------+------------------
-----
 postgres  | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 |
 template0 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres
    +
           |          |          |             |             | postgres=CTc/post
gres
 template1 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres
    +
           |          |          |             |             | postgres=CTc/post
gres
(3 rows)
```

#PostgreSQL 色々な設定
インストール完了後、デフォルトで作成される`postgres`ユーザーのパスワードを設定します。
パスワードを変更するために一度rootまたはroot権限のあるユーザーへスイッチします。

```
su -
passwd postgres
新しいパスワードを設定する
```

続いて、外部からアクセスするために最低限必要なセキュリティ設定を行います。
内容としては、特定のアドレスからパスワード認証でアクセスするというものです。

```
vi /var/lib/pgsql/13/data/pg_hba.conf
※最下行に以下の形式で追加する
host    all             all             <クライアントネットワークアドレス>/<プレフィックス長>           md5
```

次にPostgreSQLに接続を許可するため、PostgreSQLのポート番号`5432`でリッスンするアドレスを変更します。
`/var/lib/pgsql/13/data/postgresql.conf`ファイルのlisten_addressesの値を変更します。
デフォルトではコメントアウトされているので、listen_addressesの行の先頭の#を外します。

```
vi /var/lib/pgsql/13/data/postgresql.conf
※listen_addressesの行を検索し、「localhost」から「*」に変更する
listen_addresses = '*'
```

次に接続テスト用のDB作成と、`postgres`ユーザーのパスワードを設定します。

```
createdb <DB名>
psql -d <DB名>
alter user postgres with password '<設定したいパスワード>';
\q
```

設定が完了しましたら、`systemctl restart postgresql-13.service`を実行します。
次にPostgreSQLに外部サーバーからアクセスするためにFirewallを許可します。

```
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload
```

上記設定完了後、クライアントにて以下のコマンドを実行して接続テストします。

```
psql -d <DB名> -h <ホスト名/IPアドレス> -p 5432 -U postgres
ユーザ postgres のパスワード:<設定したパスワード>
※「<DB名>=#」といったプロンプトが返ってくれば接続成功
```

以上で今回の検証兼事前準備は終了です。
jsCoqのインストール

# 1. はじめに

ローカル環境でjsCoqが使えるようにする。
jsCoqについては以下のページを参照。

https://jscoq.github.io/

# 2. 準備

以下の手順を踏む。

1. Node.jsをインストール
1. npmでhttp-serverをグローバルモードでインストール
1. npmでjscoqをローカルにインストール

## 2-1. Windows10

### 2-1-1. Node.jsをインストール

以下のページからインストーラをダウンロードする。
[Node.js](https://nodejs.org/en/)
この記事を書いている段階の推奨版は14.17.0 LTSなので、そちらを選択する。

インストーラを実行し、デフォルトで進めていく。
ただし、Tools for Native Modulesは **”Automatically install the necessary tools..."**はチェックを入れておく。

PowerShellなどターミナルを開き、以下のコマンドを実行してバージョンが表示されていれば、インストールは成功している。

```
> node --version
v14.17.0
```

### 2-1-2. npmでhttp-serverをインストール

ターミナルから以下コマンドを実行する。

```
> npm install -g http-server
```

Windowsの場合、スクリプトの実行が有効になっている必要がある。
以下のコマンドを実行し、結果がこのようになっている場合はスクリプト実行が無効になっている。

```
> Get-ExecutionPolicy
Restricted
```

スクリプト実行を有効にするには、以下のコマンドを実行する。

```
> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
> Get-ExecutionPolicy
RemoteSigned
```

### 2-1-3. jsCoqのインストールと起動

以下のように、適当な作業ディレクトリに移動し、jsCoqをインストールしてhttp-serverを起動する。

```
> mkdir jscoq
> cd jscoq
> npm install jscoq
> cp .\node_modules\jscoq\examples\npm-template.html .\index.html
> http-server
```

終了する場合はCtrl-C。

## 2-2. macOS

Homebrewでインストールすることを前提とする。

あらかじめアップデートしておく。

```
$ brew update
$ brew upgrade
```

### 2-2-1. nodebrewのインストール

nodebrewは、Node.jsのバージョン管理ツール。
ターミナルから以下のコマンドを実行する。

```
$ brew install nodebrew
$ mkdir -p ~/.nodebrew/src
```

さらに`~/.bash_profile`の最後尾に以下のスクリプトを追加する。

```
# nodebrew
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

`. ~/.bash_profile`を実行しておく。

### 2-2-2. Node.jsのインストール

本家webページに記載されている推奨版14.17.0をインストールする。

```
$ nodebrew install v14.17.0
$ nodebrew use v14.17.0
```
### 2-2-3. npmでhttp-serverをインストール

ターミナルから以下コマンドを実行する。

```
$ npm install -g http-server
```

### 2-2-4. jsCoqのインストールと起動

以下のように、適当な作業ディレクトリに移動し、jsCoqをインストールしてhttp-serverを起動する。

```
$ mkdir jscoq
$ cd jscoq
$ npm install jscoq
$ cp ./node_modules/jscoq/examples/npm-template.html ./index.html
$ http-server
```

終了する場合はCtrl-C。

## 2-3. Ubuntu

### 2-3-1. Node.jsとnpmをインストール

ターミナルから以下のコマンドを実行する。

```
$ sudo apt install -y nodejs npm
```

以下のコマンドを実行してバージョンが表示されていれば、インストールは成功している。

```
$ node --version
v10.19.0
```

### 2-3-2. npmでhttp-serverをインストール

ターミナルから以下コマンドを実行する。

```
$ sudo npm install -g http-server
```

### 2-3-3. jsCoqのインストールと起動

以下のように、適当な作業ディレクトリに移動し、jsCoqをインストールしてhttp-serverを起動する。

```
$ mkdir jscoq
$ cd jscoq
$ npm install jscoq
$ cp ./node_modules/jscoq/examples/npm-template.html ./index.html
$ http-server
```


# 3. jsCoqを使う

## 3-1. ブラウザ起動

http-serverはデフォルトで8080を使用しているので、ブラウザから以下のURLで使用することができる。

http://localhost:8080

## 3-2. キーボードショートカット
GAS × Line Messaging Api のデバッグ

# 本記事の作成背景
5分で読めます！

GASでLine Messaging API を使い、Line Bot を作る場合、`console.log()`を使っても、ログが表示されないため、デバッグが難しいです。
※デバッグ・・・コードに含まれるエラーを調べること

そこで、
　<strong>google スプレッドシートにログを吐き出すことで、デバッグがしやすくなる方法</strong>
をご紹介します！

# 完成イメージ
写真のように、 ログが書き溜められていくようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772803/b9a260c2-caf9-547b-764f-1dc80ae566d0.png)

# 実装
### ソースコード
```Code.gs
function doPost(e) {
  //中身省略
}

//doPost(e)の外に書く
function debug(value='デバッグテスト') {
  const sheet = SpreadsheetApp.openById('スプレッドシートID');
  const ss = sheet.getSheetByName('logs');
  const date = new Date();
  const targetRow = ss.getLastRow() + 1;
  ss.getRange('A' + targetRow).setValue(date);
  ss.getRange('B' + targetRow).setValue(value);
}
```
### テスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772803/96831c2a-0de1-e062-4633-abaff44992fb.png)
画像のように、'Debug'の右隣が <strong>'debug▼'  </strong> となっていることを確認し <strong> '▷Run（実行）' </strong>をクリック
(`function debug()`を選択し、実行しています）

以下の写真のように表示されたら成功です
※スプシのA列の書式を時間にしておく必要があります
（デフォルトでは日付のみが表示されているはずです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772803/df8f3a48-d792-8b3d-b28c-c585b958e572.png)

# 使い方
実際のコードの必要なところに'debug( )'を書いて使いましょう！
※このコードは一部抜粋なので、不完全です

```Code.gs
function doPost(e) {
    var event = JSON.parse(e.postData.contents).events[0];
    debug(event); //eventの中身をスプレッドシートで確認する

    if(event.type == 'message') {
      //ifを通ったことを確認する。
      debug('メッセージをを確認しました')
```

このようなコードを書くと、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772803/da2ea2c0-b427-e5e8-a22d-621f17b347a2.png)
スプレッドシートに`event`の中身と、`「メッセージを確認しました」`という文章が現れました！

#おしまい
GAS × Line Messaging API での開発が少しでも楽になれば嬉しいです！
FTS（全文検索）について調べたので、KotlinでNgram法の文字列分割を実装してみた

AndroidのSearchViewを使った検索機能について調べていると、出くわす「FTS(全文検索）」という単語。
この単語についてあまり理解していなかったので、調べてみました。

先人の方々が詳しくまとめてくれていました。特に参考になったのは、以下の記事です。
・[Wikipedia「全文検索」](https://ja.wikipedia.org/wiki/%E5%85%A8%E6%96%87%E6%A4%9C%E7%B4%A2
)

上記のページを見れば、全文検索の概要は把握することができます。ありがたい限りです。

## FTS(全文検索）とは
「Full text search」の頭文字を取った語。
複数の文書にまたがって、文書に含まれる単語の検索を行う。
FTS（全文検索）はLIKEのようなパターンベースの検索とは異なり、単語ベースの検索を行う。

## 全文検索技術の分類
大きく「grep型」と「索引型」の２つの方法に分かれるようです。

### grep型
複数のテキストファイルの内容を順次走査していくことで、検索対象となる文字列を探し出す方法。
この方法は事前にインデックスを作成しないため、検索対象が多くなるほど検索速度が低下する。

### 索引型
上記のgrep型に対して、こちらは予め検索対象にインデックスを作成しておくことで、検索速度の向上を図る。
AndroidでSQLiteによる全文検索を行う場合、こちらの方法を使用する。

索引文字列の抽出方法としては、「形態素解析」や「N-Gram」という方法がよく使われるようです。

#### N-Gram法とは
検索対象を単語単位ではなく文字単位で分解し、後続の N-1 文字を含めた状態で出現頻度を求める方法を[N-Gram法](https://ja.wikipedia.org/wiki/%E5%85%A8%E6%96%87%E6%A4%9C%E7%B4%A2)という。
たとえば、Nの値が２の時、「私は太郎です。」という文字列は「私は」 「は太」 「太郎」 「郎で」 「です」 「す。」と分割されます。

形態素解析を実施するには、文脈や単語の解析をするための辞書が必要なため、お手軽に試すのは難しそうですが、N-Gram法であれば、一定の規則で文字列を分割するだけなのでお手軽に試せそうです。

ということで、今回はこのN-Gram法による文字列分割をKotlinで実装してみました。
以下がその実装です。

## ソースコード

```Kotlin
object FtsUtils {
    const val DEFAULT_SEPARATOR: String = " "
    const val DEFAULT_GRAM: Int = 2

    fun ngram(src: String, n: Int = DEFAULT_GRAM) : List<String> {
        return if (n <= src.length) {
            listOf(src.take(n)) + ngram(src.drop(1), n)
        } else {
            emptyList()
        }
    }

    fun toNgramText(src: String, n: Int = DEFAULT_GRAM, separatedBy: String = DEFAULT_SEPARATOR) : String =
        ngram(src, n).foldRight(initial = "", operation = {s, acc -> s + separatedBy + acc })
}

fun main() {
    println(FtsUtils.toNgramText("私は太郎です。"))
}

```

上記のコードを実行した結果は以下です。

```Kotlin:実行結果
私は は太 太郎 郎で です す。 
```

ちゃんと動いていそうです。
また、時間のあるときにAndroidアプリでFTSを使った検索機能を実装してみようと思います。
機械が言うと角が立たない4

# 背景
[前回](https://qiita.com/goichiya/items/e095a6e1d0e88f1cb9eb#%E8%83%8C%E6%99%AF)からの続き
Jetson Nano 2GBに作ったモデルを載せて喋らせる

# 何をする
これも[前回](https://qiita.com/goichiya/items/e095a6e1d0e88f1cb9eb#%E4%BD%95%E3%82%92%E3%81%99%E3%82%8B)からの続き

# 組み上げてゆくもの
- [Jetson nano 2GB](https://amzn.to/2SQLoZ1)
    - 「画像といえばGPU」とばかりに調達してしまった。
- [Wifiドングル TL-WN725N](https://amzn.to/3hmFGIw)
    - 単独でAzureと崇信できる必要がある。Jetsonは周辺機器をかなり選ぶみたいで、普通に手持ちの物は認識してくれなかった。同梱されているものもあるみたい。最初にこの[記事](https://qiita.com/akinko/items/c01ed6b891f2117f5ed9)を確認しておけばよかった、、
- [USBカメラ Logitech c270](https://amzn.to/3hqxyXt)
    - Raspiのカメラも試したが安定しなかったので素直にNVIDIAお勧めの機種を調達。運用の為に小さい筐体が必要な場合は何とかしてラズパイカメラを安定させる方法を考える
- [USB サウンドカード(waveshare usb to audio)](https://amzn.to/33MGYEs)
    - ラズパイを使っていればいらなかった、、
- [スピーカ](https://amzn.to/3ffrFtv)
    - ラズパイならダイソーのスピーカでよかったのに、、ノリだけでJetson使うから、、
- [音読さん](https://ondoku3.com/ja/)
- [convertio](https://convertio.co/ja/wav-mp3/)
    - 再生する音声ファイルを作成し、wavファイルに変換
- [3Dプリンタ　X-Maker](https://amzn.to/2RTUZxu)
    - コロナ対策の名目で導入したものが役に立った。フィラメントに初めてPETGを使用したら、糸引きが厄介だった。
- [3D モデル](https://kitto-yakudatsu.com/archives/6058)
    - フリーの物を利用。きれいなモデルを公開頂きありがとうございます。

# 組み上げてゆく
## ネットワークの接続
USBポートに挿して、ネットワークの接続をする。
ドングルは何もせずに認識してれた。
ネットワークの設定はモニタが断然便利。
この設定ができるとssh接続でjetsonを操作できる

## python3関連のインストール
jetson nano用のSDカードを作成するときに使用したイメージのバージョンによっては不要かもしれない。
`sudo apt install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev`
` sudo apt install python3-pip`
`sudo pip3 install -U pip`
numpyを19.4にダウングレードしておくのが色々な不具合を避けるのに手っ取り早い

## tfliteのランタイムインストール
lobeからエクスポートした際に作成されるrequirementに記載されている通り
`pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp36-cp36m-linux_aarch64.whl`

## azure関連のインストール
azureのチュートリアルに記載されている通りに実行
`pip3 install --upgrade azure-cognitiveservices-vision-face`

## soundcardの接続
つなぐだけで動き始めた
音が出ない時にの確認にはモニタがあると便利。

## 筐体の印刷
フリーで頂いたstlファイルから３Dプリンター用のファイルを出力
PETGだと充填率を下げた際に糸引きがすごくて、途中でダマのようになり上手く出力されなかったので、充填率を80％ぐらいに上げて印刷。
それでもバリがすごいでた
一連の作業で一番長く働いていたのは３Dプリンターだった

## 出来上がり

jetson nano 2GBの筐体
![IMG_20210512_012039.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/f890c27c-f78c-1a42-d9a2-a9bcf3f4bd00.jpeg)

スピーカとカメラの筐体
![IMG_20210511_194917.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/d9028637-8ab4-41b8-4ba4-4409009f19f1.jpeg)

# 確認
- sshでコマンドを実行するとカメラが動いて（ランプが一瞬つく）、判定結果に応じた音声ファイルを再生する。
- モデル構築時に使用していない人の顔でも期待通りに判定してくれる。
- 鼻が出ている場合でも「マスク着用」と判定されるが、これはモデル構築時のラベルの付け方やデータ数の調整をして検証する必要あり。

# 所感
- 思いつきで初めて思ったところまでたどり着けた。
- dockerで構築すれば環境差異も吸収できて、環境に依らずでも実行可能にできそうと思ったが、Lobeは同じモデルで異なる環境用にエクスポートできるので、そのあたりは気にする必要はなさそう。
- 判定した理由や部分を返してくれる用になると安心感が増す。
- 角が立たないようにするにはもっと間抜けでかわいい筐体が良い気がする
! [rejected] Heroku に Push できなかった問題

```
git heroku push
 ```
すると
こんなエラー

```
To https://git.heroku.com/~~.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://git.heroku.com/~~.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
しらべたところ

heroku 側のcommit履歴？とローカル側の履歴が違うためだったとすいそく

```
git rebase heroku/master 
```

して　Heroku のブランチの先端？をローカルの先端に置き換えた？

そして

```
git push heroku
```
で無事pushできた。

リモートリポジトリとローカルがべつのものに変わった？ぽいので

git pull したがエラー

```
fatal: refusing to merge unrelated histories
```
これで解決？した

```
git merge --allow-unrelated-histories origin/master
```

この後,heroku run rails db:migrateなどして

ブラウザからアプリに接続、、、できない！

原因は、アプリいったん止めるコマンドかと思い

```
heroku restart
```

しかし変わらず
今度は
https://qiita.com/rebi/items/efd1c36f0a9e46222d80
を参考に

```
heroku ps:scale web=1
```
でいけた！
【Nuxt.js】ビルドのプロパティとコマンドまとめ

# 概要

Nuxt.jsでSPA（SSR・SSG）を制作するときの`ssr` / `target`プロパティや、ビルドコマンドあたりの理解がふわふわしていたので整理します。
現在では非推奨となった`mode`プロパティについては特に記述しません。


# 環境

- Nuxt.js v2.15.6


# `ssr` / `target`プロパティ

```nuxt.config.js
export default {
  ssr: true, // デフォルト
  target: 'server' // デフォルト
}
```

- `ssr`：サーバーサイドレンダリングを有効にするかどうか
- `target`：サーバーホスティングにするか静的ホスティングにするか


# `build` / `generate`コマンド

```package.json
{
  "scripts": {
    "build": "nuxt build",
    "generate": "nuxt generate",
  }
}
```

- `build`：`target: 'server'`のときに使用
  - `.nuxt`ディレクトリに出力されます。
- `generate`：`target: 'static'`のときに使用
  - `dist`ディレクトリに出力されます。


# まとめ

### SSRでつくるとき
- プロパティの設定
    - `ssr: true` ・ `target: 'server'`
- 使用するコマンド
    - `nuxt build`
        - `.nuxt`ディレクトリに出力されます。

### SSGでつくるとき
- プロパティの設定
    - `ssr: true` ・ `target: 'static'`
- 使用するコマンド
    - `nuxt generate`
        - `dist`ディレクトリに出力されます。

### SPAでつくるとき
- プロパティの設定
    - `ssr: false` ・ `target: 'static'`
    - `ssr: false` ・ `target: 'server'`
        - `ssr: false`に設定しているとビルド時に`target`が`static`に変換されます。
- 使用するコマンド
    - `nuxt generate`
        - `dist`ディレクトリに出力されます。


# 参考URL

- ssr プロパティ - NuxtJS
  https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-ssr/

- target プロパティ - NuxtJS
  https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-target/

- デプロイターゲット - NuxtJS
  https://ja.nuxtjs.org/docs/2.x/features/deployment-targets/