OmniAICreator/Qiita-1.07M huggingface dataset:
SQLの基本的な操作

# プログラミングの勉強日記
2020年6月14日　Progate Lv.102
SQLⅠ

##データベースとは
　テキストや数値などのデータを保存するためのツール。データベースは表でデータを管理している。表のことを<font color=orange>テーブル</font>、縦の列のことを<font color=orange>カラム</font>、横の列のことを<font color=orange>レコード</font>という。必要に応じて複数のテーブルを作成できる。

##クエリとは
　（データベースからデータを取得するために）データベースに送る命令のこと。SQLはクエリを書くための言語である。

##SELECT
　データベースからデータを取得するために用いる。どのカラムのデータを取得するか選ぶ。

##FROM
　SELECTで選んだカラムがどのテーブルのカラムかを指定する。）データベースには複数のテーブルが存在する場合がある）
　クエリは`;`（ダブルクォーテーション）を加えて完成する。<font color=blue>SQLは大文字と小文字を区別しない。</font>

```sql
SELECT name
FROM puechases;
```
　複数のカラムを選択する場合は、カラム名を`,`（コンマ）で区切る。すべてのカラムからデータを取得するときには`*`を用いる。

```sql
SELECT name, price FROM purchases;
SELECT * FROM purchase;
```

##WHERE
　特定のデータを取得するために用いる。どのレコードを取得するかを特定する。`=`や比較演算子を用いて定義する。データにはデータ型と呼ばれるルールに従う。

###データ型
　データベースに保存されているデータに適用されているルール。データ型はテキストデータや数値データ、日付データといったデータの種類を示すもの。データベースではカラムごとにデータ型を決める。

　テキストデータ：クォーテーションで囲む必要がある。
　数値データ：クォーテーションで囲んではいけない。
　日付データ：クォーテーションで囲む必要がある。

###LIKE演算子
　ある文字列を含むデータを取得したいときに使う。`WHERE name LIKE 文字列`のように使う。
　どんな文字列にも一致することを指す記号である<font color=orange>ワイルドカード</font>を使うこともある。`%`をワイルドカードとして使う。ワイルドカードは文字列の前後どちらかのみに置くこともできる。　
　「〇〇%」とすると前方一致と呼ばれ、〇〇以降はどんな文字列にも一致するという意味であり、〇〇から始まる文字列を検索をできる。
　「%〇〇」とすると後方一致と呼ばれ、〇〇以前はどんな文字列にも一致するという意味であり、〇〇で終わる文字列を検索できる。

```sql
SELECT * FROM purchases WHERE name LIKE "%田中%"; 
SELECT * FROM purchases WHERE name LIKE "田中%";  //田中で始まるデータを取得
SELECT * FROM purchases WHERE name LIKE "%田中";  //田中で終わるデータを取得
```

###NOT演算子
　「〇〇」を含まないデータや「〇〇に一致しないデータ」のような条件でデータを取得したいときに使う。その条件を満たさないデータを取得できる。

```sql
WHERE NOT price > 1000; 
WHERE NOT name LIKE "%田中%";
```

###NULL
　中身がわからない、何のデータも保存されていないことを示す。NULLのデータを取得するためには、「～がNULLである」という意味になる`IS  NULL`を使う。NULLでないデータを取得するためには、「～がNULLでない」という意味になる`IS NOT NULL`を使う。<font color=blue>`=`は使用できない。</font>

```sql
WHERE price IS NULL;
WHERE price IS NOT NULL;
```

###AND演算子
　WHEREに複数の条件を指定できる。`WHERE 条件1 AND 条件2`として、条件1と条件2をともに満たすデータ検索できる。

###OR演算子
　WHEREに複数の条件を指定できる。`WHERE 条件1 OR 条件2`として、条件1または条件2のどちらかを満たすデータ検索できる。

##ORDER BY
　データを並び替えるために使う。（「～順に並べる」という意味）
　`ORDER BY 並べたいカラム名 並べ方;`として使う。

　小さい数から大きい数へ向かう順序である昇順か、大きい数から小さい数へ向かう順序である降順かを指定する。SQLでは昇順は`ASC`、降順は`DESC`と指定する。
　<font color=blue>クエリの末尾に記述することで取得結果を並び替える。</font>（WHEREと併用できる）

```sql
ORDER BY price DESC;
```

##LIMIT
　最大で何件取得するか指定するために使う。データの件数を指定する。<font color=blue>クエリの末尾に記述することで取得結果を並び替える。</font>（WHEREと併用できる）
　<font color=blue>ORDER BYとも併用できるが、その場合はLIMITを末尾にする</font>

```sql
LIMIT 5;
```
プロセス間通信に便利なDistributedNotificationCenterが、Pure Swiftな型のuserInfoしか扱えない話

# はじめに

`DistributedNotificationCenter` (https://developer.apple.com/documentation/foundation/distributednotificationcenter)
はmacOSのアプリでプロセス間通信を行う際にとても便利だが、userInfoにはPure swiftな型 (StringとかIntとか) しか含めることができないらしい。

# やったこと
Notificationの送信側と受信側2つのアプリを用意し、↓ のように実装する。
送信側のSandboxがonになっているとuserInfoを含めることができないので、Sandboxはoffにしておく。

```swift:送信側
import Cocoa

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let dnc = DistributedNotificationCenter.default()
        // userInfoにstringを含める
        dnc.postNotificationName(NSNotification.Name("StringUserInfo"), object: nil, userInfo: ["value": "hogehoge"], deliverImmediately: true)

        // userInfoにURLを含める
        dnc.postNotificationName(NSNotification.Name("URLUserInfo"), object: nil, userInfo: ["value": URL(string: "https://www.google.com")!], deliverImmediately: true)

    }
}

```


```swift:受信側
import Cocoa

class ViewController: NSViewController {

    private var observers = [NSObjectProtocol]()
    override func viewDidLoad() {
        super.viewDidLoad()

        let dnc = DistributedNotificationCenter.default()
        let o1 = dnc.addObserver(forName: NSNotification.Name("StringUserInfo"), object: nil, queue: OperationQueue.main) { n in
            print("Can receive")
            print(n)
        }
        observers.append(o1)

        let o2 = dnc.addObserver(forName: NSNotification.Name("URLUserInfo"), object: nil, queue: OperationQueue.main) { n in
            print("Cannot receive")
            print(n)
        }
        observers.append(o2)
    }
}

```


上記の実装で実行してみると、 `StringUserInfo` の方は正しく受信できるが `URLUserInfo` の方は受信できない。
これでちょっとハマった。

# 考えたこと

冷静になってみると、受け取った側でどんな型かわからん状況が容易に想像できるので、安全のために絶対に型がわかるuserInfoしか送れないようになっているんだと思う。
Objective-Cでどうなるかは試していない。

# 終わりに
Primitiveな型しか扱えなかったりuserInfoを渡すにはSandboxがoffになっていないといけなかったり何かと制約は多いが、プロセス間通信したい場合にはとても便利なので積極的に使っていこう。

なお、今回の挙動はこちらで試せる。
https://github.com/yamazaki-sensei/distributed_notification_sample.git
【プログラミング初心者】Swift練習問題~クイックソート~

# クイックソート
## クイックソートについて
クイックソートはソートアルゴリズムの１つです。

過去の投稿で一度ソートの実装問題を出していますが、回答例ではバブルソートと呼ばれるソートアルゴリズムで実装をしています。
バブルソート:https://qiita.com/euJcIKfcqwnzDui/items/306979a03fc813615720

ソートアルゴリズムにはバブルソート、マージソート、クイックソートなど複数のアルゴリズムがあります。
なぜ複数あるのかというと計算量の違いです。
この計算量の違いにより、処理速度に差が出てしまうためより早いソートアルゴリズムが求められています。

その中で最も早いと言われているのが**クイックソート**と呼ばれるアルゴリズムです。
(データの並びによって変わるため必ずしも最速となるわけではありません)

N個の配列の場合、バブルソートでは要素数に対して二重ループを回しているため計算量はN^2程度です。
一方でクイックソートの場合の計算量はNlogNとなり、大幅に改善されます。
※計算量はOという記号で表され、O(N^2)、O(NlogN)と記載されます。(オーダーと呼びます)

クイックソートの計算量に興味が有る方は調べてみると多くの解説があります。

## クイックソートの考え方
クイックソートの考え方について紹介します。

以下のような配列が与えられているとします。
<img width="576" alt="クイックソート１.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326173/43231327-4be4-53af-d936-4673b36ace28.png">
クイックソートではまず**ピボット**と呼ばれる軸となる数値を配列の中から１つ決めます。
決め方は何でも構いません。
今回は配列の先頭をピボットとします。
<img width="576" alt="クイックソート２.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326173/49ffb7b2-1642-bb3d-c3d2-5ee755734128.png">
ピボットを決めたら各要素に対し前から順に比較を行ない、大きいグループ、小さいグループに分割します。
<img width="654" alt="クイックソート３.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326173/c57c3f68-8bb3-29f7-e382-0f41d3b1a093.png">
これでピボットから見て左は大きいグループ、右は小さいグループと大雑把なソートができています。
つまり当然ですが[大きいグループの値]>[右は小さいグループの値]となるため、今後大きいグループの値はピボットより右に、小さいグループの値はピボットより左にくることはあり得ません。
そのため次からは各グループ内でのみ並べ替えを行えばよくなります。

次の処理では各グループ内でそれぞれ新しくピボットを決めます。
それぞれ決めたピボットに対しその中でさらに大きいグループ、小さいグループに振り分けます。
<img width="821" alt="クイックソート４.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326173/28f0f8db-edf8-7ca2-3b5f-55cee6b93138.png">
これを分割したグループに要素が存在する限り続けます。
<img width="1098" alt="クイックソート５.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326173/0a119468-f0fd-aa78-ae2e-a4861d3e1430.png">
このように最後まで並べ替え続けるとソート完了となります。

## 問題
降順ソートを行う関数をクイックソートを用いて作成してください。

回答例は[こちら](https://qiita.com/euJcIKfcqwnzDui/items/bb2168f2b8bd2165bd15)

#最後に
別の問題は以下に掲載しています。
また本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載も以下にまとめていますのでそちらも是非もご覧ください。
http://naoyalog.com/
cypressを5分だけ触ってほしい

# はじめに

cypressがどんなものか知っていただきたくて、ざっくり触ってもらうための記事です。
実際に実行するコマンドも記載していますが、コピペで動くレベルなので全部で5分かからないと思います。

# cypressとは

E2Eテストフレームワークです。Puppeteer や Selenium の類似です。
導入の設定が簡単で、テスト結果のスクリーンショットや動画も記録できます。

## サポートブラウザ

- Chrome
- Edge
- Firefox

課題になっていたクロスブラウザもバージョン4から対応しています。[詳細は公式を参照](https://docs.cypress.io/guides/guides/launching-browsers.html#Browsers)

# ざっくり触ってみる

[公式のチュートリアル](https://docs.cypress.io/examples/examples/tutorials.html)のリポジトリを動かしてみます。（本当に簡単なのでぜひ触ってほしいです！）
※リポジトリのcypressはバージョン3なのでクロスブラウザ対応していません。

## システム起動

リポジトリをcloneしてからシステムを起動します。

```bash
# 任意のディレクトリへ移動
# cd workspace/cypress/
git clone https://github.com/cypress-io/cypress-tutorial-build-todo.git
cd cypress-tutorial-build-todo/

# パッケージをインストール
yarn

# システム起動
yarn dev
```

## GUI実行

```bash
yarn cypress
```

赤枠のRun all specsをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/8eec5190-e649-5b11-212f-0e3cc390ff2e.png)

Chromeが起動して全テストが実行されました。（凄く早いですよね！？）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/450a0679-b062-339c-b61c-832e378624e2.png)

## CLI実行

cypressをCLI実行します。

```bash
yarn cypress:all
```

CLI実行結果⇣
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/43ae60ee-a99c-ef86-ca36-ae8c100bc1cf.png)

先程のテストの動画が保存されています。

```bash
ls cypress/videos
> app-init.spec.js.mp4	input-form.spec.js.mp4	smoke-tests.spec.js.mp4
> footer.spec.js.mp4	list-items.spec.js.mp4
```

# ざっくりcypressのフォルダ構成を説明

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/80241a3f-da73-ce2a-2a1e-4b6b69b0d860.png)

- fixtures
    - テストデータを保存しておきます。
- integration
    - テストシナリオを保存しておきます。
- plugins
    - cypressのイベントをフックしたり、使用するconfigを動的に切り替える設定をします。
- support
    - 使い回すテストシナリオをコマンドとして設定します。
- videos
    - 実行したテストの動画が保存されます。（CLI実行のときだけ？）

# おわりに

動画のチュートリアルが分かりやすくてオススメです！
1.2５倍速くらいでみれば 1 時間程度で全部みれますよ！
https://docs.cypress.io/examples/examples/tutorials.html

他のE2Eテストフレームワークは触ったことないのですが、cypressを初めて触ってみて、
直感的にテストが書けることや、記述ミスのエラーメッセージがすごく親切なところが
凄く開発者のことを分かってくれてる感じがして好きです。
JavaScriptでjoin()を使おうとして起こったエラーについて

 はじめまして, 「つゆ」と申します。
Qiitaではじめての投稿となります。作法のなっていないところ、投稿内容について知識が不十分なところ多々あると思いますがどうぞよろしくお願いいたします。


#はじめに 
 本記事では、javascript 初学者である私が学習中に出会ったエラーの中で、個人的に気になったエラーが起こったので、そのエラーについて調べたことを書かせていただきます。

#開発環境
 この記事ではwin10 HomeにインストールしたVS codeを使用。
htmlファイルの実行には、Google Cromeを使用。

#エラー内容
エラーが起こった経緯ですが、文字列に関する命令について学習している際、

```main.js
'use strict'

const d = [2020, 06, 14];
console.log(d.join('/'));
```
とエディタに記述して実行したところ、ブラウザのConsoleにおいて以下のエラーメッセージが出力されました。

```error
Uncaught SyntaxError: Octal literals are not allowed in strict mode.
```

 ただ配列に記述した日付を'/'で区切って出力しようとしただけなのに謎のエラーが起こり戸惑いました(笑)。

 とりあえずエラーメッセージを訳してみたところ、
「捉えられなかった SyntaxError。厳密なモードでは八進数リテラルは許可されません。」

 なんのこっちゃいと思い、いろいろ調べてみたところ、どうやらjavascriptでは先頭に0がつく数値は8進数として処理されてしまうみたいです。つまり、今回私が配列の要素として'06'と指定しまったことが原因でエラーが起こってしまいました。

数値が8進数として処理されてしまうことの何が問題かというと、もし配列に'011'と代入したい場合（こんな場合があるか今の自分には分かりませんが..）、本当は10進数の 11 という数値を代入したかったにもかかわらずjavascript上では、代入された数値は'9'として処理されてしまいます。

#そんな時のために
　ですが、上記のような本人の意図しない処理を防ぐために、javascriptを知る皆さんならよくご存知の、javascript内における厳密なエラーをチェックしてくれる

```
'use strict'
```

さんが活躍してくれます。　初学者故なんのためにコードの1列目に書いていたかちゃんと理解していませんでしたが、今回のような数値を扱うシチュエーションにおいて、Strictモードの宣言をしていなかった場合、処理が通ってしまい、エラーは発生していないが挙動がおかしくどこを直したらいいんだという状況になってしまうことがないよう、エラーを返してくれます。

#最後に
　以上で、「JavaScriptでjoin()を使おうとして起こったエラーについて」を締めくくらせていただきます。はじめての投稿である上、javascriptの知識も不十分であるため、記事の内容について不正確なところが見受けられるかもしれませんが、どうかコメント等で精いっぱいのやさしさをもって指摘していただけると幸いです。

誤字脱字、文章構成（文のノリがうっとうしいなど）についても同様にご指摘下さると助かります。

最後となりますが、本記事を最後までお読みいただきありがとうございました。

##参考文献

-[JavaScriptの数値型完全理解](https://qiita.com/uhyo/items/f9abb94bcc0374d7ed23)
-[JavaScriptのStrict（厳格）モードまとめ | てらこや.work](https://www.terakoya.work/javascript-strict-mode/)
チームメンバー全員が自動デプロイできるようにする方法

# 問題
プログラミングスクールのチーム開発で、最初に自分が自動デプロイ担当になって、チームの中で自分しかcapistranoでの自動デプロイができなかった。

他のメンバーが自動デプロイしようとすると、

```ruby
Net::SSH::AuthenticationFailed: Authentication failed for user ec2-user@xx.xxx.xxx.xxx
```
というエラーが出てしまう。


この問題を今日チームで解決できたので、備忘録を書いておこうと思う。

# 解決方法
1. 自動デプロイできるメンバーがpemファイルを他のチームメンバーに共有
2. pemファイルを受け取ったチームメンバーが、pemファイルを~/.sshディレクトリに配置する

## 1. pemファイルをチームメンバーと共有する
このやり方がわからなくて、チームmtgでもみんなで頭を抱えた。
「pemファイルの共有ってどうやるんだ？」
メンバーのうちの１人がこの記事を見つけてくれた。
https://pc-karuma.net/mac-finder-show-all-files/

最初、pemファイルは、チームのEC2インスタンスを作る時にAWSを操作した自分の「ダウンロード」フォルダに入ってるのかと思ったが、実際はpemファイル隠しファイルに配置されていて見れなくなっていた。
この記事には隠しファイルを表示させるコマンドが書いてあります。
https://pc-karuma.net/mac-finder-show-all-files/

```:ターミナル
隠しファイルを表示させるコマンド
$ defaults write com.apple.finder AppleShowAllFiles TRUE

設定を反映させるために「Finder」プロセスを終了させる必要があるらしい
$ killall Finder
```
この２つの操作で隠しファイルにあったpemファイルを見れるようにしてから、メールにpemファイルを添付してメンバーに送った。


### pemファイルとは？
pemファイルはいつどの段階で作ったかというと、AWSのEC2インスタンスを作成した時に、「キーペアをダウンロードする」という工程があったと思うが、その時ダウンロードしたファイルこそがpemファイルだ。
キーペアはEC2インスタンスにSSHでログインする際に必要となる「秘密鍵」のこと。

## 2. 各チームメンバーが、pemファイルを、~/.sshディレクトリに配置する
メールを受け取ったメンバーは送られてきたpemファイルを~/.sshディレクトリに配置した。

その状態で次の自動デプロイのコマンドを実行したら問題なく自動デプロイできた。

```
# アプリケーションのディレクトリで実行する
$ bundle exec cap production deploy
```

# 参考記事
MacのFinderで隠しファイル・隠しフォルダを表示する方法
https://pc-karuma.net/mac-finder-show-all-files/
自作したライブラリのDemoプロジェクトが実機でビルドできない件

タイトルの通り、iOSのライブラリを自作したがDemoプロジェクトがシュミレータではビルドできるが実機ではビルドできなかった。
構成はこんな感じ

<img width="266" alt="スクリーンショット 2020-06-14 23.13.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97817/c25ed890-16a5-dd99-4f69-5aee46a8699b.png">

## 原因
frameworkがシュミレータしか対応しておらず、Build PhasesのCopy File phaseからframeworkを実機用にコピーする必要があった。（正直あんまわかってない）

## 対応
Demoの`Build Phases`から`Copy File phase`を選択。
<img width="752" alt="スクリーンショット_2020-06-14_23_20_10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97817/cdb0a935-0efd-6312-250a-7d9a5f24b585.png">

追加した`Copy File phase`を`Compile Sources`の上に移動
<img width="979" alt="スクリーンショット 2020-06-14 23.22.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97817/3f89ab6b-fd37-c41c-a356-8326e83fdb5f.png">

Destinatioをframeworksに指定して、対象のframeworkを追加
<img width="963" alt="スクリーンショット 2020-06-14 23.23.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97817/fd4a7fa0-3dba-3944-7147-962983d3adff.png">

で無事にできた！

## 参考
https://stackoverflow.com/questions/58144104/xcode11-dyld-library-not-loaded-reason-image-not-found
PHPで組み合わせの全パターンを取得する

# 何をするのか

配列の中から取り得るすべての組み合わせを取得します。

例えば，配列の要素が3つなら，1, 2, 3 いずれかの要素数を持つ組み合わせを作ります。

# PHPで実装

```php
/**
 * すべての組み合わせを返す
 *
 * @param array $arr 選ぶ元となる配列
 * @return array
 */
function getAllCombinations(array $arr): array
{
    $arr = array_unique($arr);
    $results = [[]];

    foreach ($arr as $item){
        foreach ($results as $result){ 
            $results[] = [$item, ...$result];
            // PHP7.4 未満
            // $results[] = array_merge([$item], $result);
        }
    }
    array_shift($results);
    return array_values($results);
}
```

使い方

```php
// 3C3 + 3C2 + 3C1 = 7（組）
$arr = ['A', 'B', 'C'];
print_r(getAllCombinations($arr));
```

結果

```
Array
(
    [0] => Array
        (
            [0] => A
        )

    [1] => Array
        (
            [0] => B
        )

    [2] => Array
        (
            [0] => B
            [1] => A
        )

    [3] => Array
        (
            [0] => C
        )

    [4] => Array
        (
            [0] => C
            [1] => A
        )

    [5] => Array
        (
            [0] => C
            [1] => B
        )

    [6] => Array
        (
            [0] => C
            [1] => B
            [2] => A
        )

)
```

# 解説

外側の foreach を回す毎に，$results の中身がどう変化しているのかを見ればわかります。

配列 [A,B,C] があります。（クオーテーションは省略します）

初期時↓

```
[]
```

1回目のループ（A）終了時↓

```
[], @ [[A]]
```

2回目のループ（B）終了時↓

```
[], [[A]], @ [[B]], [[B],[A]]
```

3回目のループ（C）終了時↓

```
[], [[A]], [[B]], [[B],[A]], @ [[C]], [[C],[A]], [[C],[B]], [[C],[B],[A]]
```

@ 以降がそのループで追加された要素です。

ループの度に，現時点の \$results の各要素と \$item を結合した配列を \$results に追加していきます。

\$item 単体の組み合わせを作る為に，初期値の空配列が必要なのです。

# 参考

[Finding All Element Combinations of an Array](https://www.oreilly.com/library/view/php-cookbook/1565926811/ch04s25.html)
2020/06/13〜14 プログラミング(フロントエンド)学習14〜15日目 メモ

# 2日間の学習範囲
### たにぐち まことのともすたチャンネル(YouTube)
https://www.youtube.com/user/tomostajp
Bootstrap 4入門 #03〜#09
（学習時間：5時間）
## Bootstrap学習メモ
### tableタグ(HTML)
`<table></table>`
表を作成する
### trタグ(HTML)
`<tr></tr>`
表の一行を定義する
table rowの略
table要素内に記述する
### thタグ(HTML)
`<th></th>`
見出しとなるセルを作成する
table headerの略
tr要素内に記述する
### tdタグ(HTML)
`<td></td>`
データとなるセルを作成する
table dataの略
tr要素内に記述する
### table要素にBootstrapのスタイルを適用する方法
`<table class="table">`
### theadタグ(HTML)
`<thead></thead>`
表のヘッダ行を定義する
table要素内に記述する
### tbodyタグ(HTML)
`<tbody></tbody>`
表のボディ部分を定義する
table要素内に記述する
### codeタグ(HTML)
`<code></code>`
プログラムのソースコードであることを示す
### preタグ(HTML)
`<pre></pre>`
半角スペースや改行をそのまま表示する
ソースコードとして表示する場合、codeタグと組み合わせて使う
`<pre><code>コード</code></pre>`
### kbdタグ(HTML)
`<kbd></kbd>`
キーボード入力される文字であることを示す
### Lorem Picsum
https://picsum.photos/
`<img src="https://picsum.photos/px数/px数">`
とすると、画像が指定されたサイズでランダムに表示される
サンプル画像として利用できるサービス
### .img-fluid
`<img src="..." class="img-fluid>"`
画像をレスポンシブにする
### .img-thumbnail
`<img src="..." class="img-thumbnail>"`
画像に丸みのある境界線(1ピクセル分)が表示される
`<img src="..." class="rounded>"`
四つの角が丸みのある画像になる
### ナビゲーション
サイト内の他ページへのリンクやページ内リンクなどのこと
### navタグ(HTML)
`<nav></nav>`
ナビゲーションであることを示す
### .nav
`<ul class="nav">`もしくは`<nav class="nav">`
ナビゲーションバーを作成する
※.navコンポーネントではアクティブは適用されない
### .nav-tabs
`class="nav nav-tabs"`
タブ付きのナビゲーションバーを作成する
### .nav-item
`<li class="nav-item">`
ul要素でナビゲーションバーを作成する際、liタグに記述する
### .nav-link
`<a class="nav-link">`
ナビゲーションバーを作成する際、aタグに記述する
### .jumbotron
`<div class="jumbotron">`
ヒーローユニットスタイルのコンテンツを表示する
### buttonタグ(HTML)
`<button></button>`
ボタンを生成する
### 以下は後で記載(とりあえずメモ)
btn btn-
javascript
jquery
popper.js
script
modal
modal fade
data-dismiss
data-toggle
class=" border"
class=" shadow"
bg-
embed-responsive
embed-responsive-item
d-none
float
sr-only
flex-wrap
justify-content
:first-child
align-content
flex-direction
style="order: 数字"
style="flex-grow: 数字"
align-self
flex-flow
flex
d-flex
flex-row-reverse
justify-content-center
align-items-center
flex-fill
form
 method
label
form-group
form-control
form-control-lg
readonly
form-control-plaintext
form-check
form-check-input
form-check-label
form-check-inline
Validation
required
novalidate
invalid-feedback
valid-feedback
is-invalid
## その他
今回の動画ではJavaScriptを利用しているものも出てきたので、
先日の模写コーディングをBootstrapを利用して改めて書き直したのち、
改めて動画を見直して理解したい。
Amazon Linux / RHEL 系向け Xymon クライアント インストール

# はじめに
監視ツールXymonのクライアント(エージェント)の最新版(執筆時は4.3.30)をAmazon Linux もしくはRHEL(7以降)系にインストールする方法です。
非公式のパッケージは使わず、ソースからビルドします。

Amazon Linux 2023, Amazon Linux 2 と RHEL 8 で動作確認しました。

# 事前準備
```
# yum install pcre-devel gcc libtirpc-devel
```

```
# useradd xymon
```

```
# passwd xymon
```

# インストール

任意のユーザとディレクトリで。

Sourceforgeから最新をダウンロード

```
wget https://sourceforge.net/projects/xymon/files/latest/download/xymon.tar.gz
```

サーバでダウンロードしたファイルを展開

```
$ tar xvfz xymon.tar.gz
```

展開されたディレクトリに入る。

```
$ cd xymon-?.?.??/
```

クライアントとしてconfigure

```
$ ./configure.client
```


```
Server side client configuration, or client side [server] ?
client
```
clientと入力しエンター


色々と聞いてきますが、下記の1つの質問は答えます。それ以外はエンターキーでデフォルトで良いです。

```
What is the IP-address of your Xymon server [127.0.0.1] ?
実際のXymonサーバのIPアドレス
```

make

```
$ make -s
```

警告はたくさん出ますが

```

Build complete.

#####################################################################
IMPORTANT: If upgrading from 4.2.x, see the docs/upgrade-to-430.txt
           file for instructions. You must run build/upgrade430.sh
           before installing the new version.
#####################################################################

Now run 'make install' as root
```
と出ればmake完了。

以降はrootで

```
$ sudo su -
```
もしくは
```
$ su -
```

makeしたディレクトリに移動して

```
# cd 先程までのディレクトリ
```

インストール

```
# make install
```

下記が出れば完了。
```
Installation complete.

To start the Xymon client, as the xymon user run '/home/xymon/runclient.sh start'
```

# 起動用の設定

```
# vi /etc/systemd/system/xymonclient.service
```

以下をコピペ

```config:/etc/systemd/system/xymonclient.service
[Unit]
Description=XymonClient
After=network-online.target

[Service]
Type=forking
ExecStart=/home/xymon/runclient.sh start
ExecStop=/home/xymon/runclient.sh stop
User=xymon
Group=xymon

[Install]
WantedBy=network-online.target
```

OS 起動時に Xymonクライアント も自動起動

```console:
# systemctl enable xymonclient
```

起動

```console:
# systemctl start xymonclient
```

# 動作確認

サーバ側の server/etc/hosts.cfg にはクライアントの情報を追加しておく。

ブラウザでXymonを確認し、クライアントの情報もCPUやディスクやメモリなどのアイコンが表示されたらOK。

## 表示されない場合

### 名前が異なる

ブラウザのXYmonトップページにあるxymondの緑のアイコン(下図)

![スクリーンショット 2023-12-03 11.14.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70113/730cb416-c11c-abac-da1e-f6945c832f5a.jpeg)
をクリックすると、下の方に、

```
Ghost reports:
  xxx.xxx.xxx.xxx   reported host xxxxxxx
```

のように、表示されることがあります。
これは、hosts.cfgにある監視対象名と、実際に監視対象からxymonサーバに送られてくる監視対象名が異なる場合に表示されます。
Xymonクライアントから送信される情報がXymonサーバに到達していますが、該当するホスト情報がないために表示できないとの状態です。
Xymonクライアントのホスト名を変更するか、Xymonサーバ側のhosts.cfgのホスト名を変更するかして、一致させると正常に表示されます。

### ポートが空いていない

監視対象からXymonサーバへの通信はport 1984/TCP を使います。ポートを開けておく必要があります。
Zoom LINE GoogleカレンダーAPI BOT

# はじめに
昨今のコロナウイルスの影響で外出すること減り、オンラインで会議や飲み会、キャバクラまで行われています。

そんな中でよく使われているのがZoomだと思います。
僕も友達とよく使いますし認知度としてはかなり高いものだと思います。

Zoomでミーティングを予約する時ZoomでURLを発行して、その予定をGoogleカレンダーに行って予定を入れてURLを貼り付けるという作業をしていたのですが、面倒だなと思ってました。

こういう無駄な工数を勉強しているプログラミングで解決できるんだということで、
生活の中で身近なLINEを使って予約するLINEbotを作ってみました。

この記事はあくまで参考にした記事をまとめたもので、参考記事を見ることで形にできると思います。
個人的に躓いたポイントを記述しています。

## 概要
LINEで「会議」と送ることで日時選択が可能となり、Zommを予約したい時間を指定する。
時間を指定すると、Zoomがその時間に予約され、同時にGoogle カレンダーにも予定を追加する。
日時指定後、ZoomのミーティングURLとGoogleカレンダーのURLをメッセージとして返す。
予定を確認する際は、「予定」と送ることで直近5件のスケジュールを返す。

録画動画：https://youtu.be/_YBavI3peLw


## Zoom API
zoomのAPIキーとシークレットキーを使ってzoomのミーティングを作成する際のJWT（json web token）を生成する。
`PHP-JWT`というライブラリを使ってJWTを生成する。

```
use \Firebase\JWT\JWT;
```
これを記述することで`PHP-JWT`を利用することができ、`JWT::encode()`でtokenを生成してくれる。
生成したJWTをHeaderに記述する。
※content-typeは`application/json`を指定する
`POSTFIELDS`にミーティングの詳細を記述する。
`topic` `type` `start_time` `timezone` `settings` etc.
今回はミーティングURLを返したかったため、`join_url`をreturn

### 参考記事
[公式ドキュメントCreate a Meeting](https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate)
[Help with api create meeting with php](https://devforum.zoom.us/t/help-with-api-create-meeting-with-php/5189)
[JWT With Zoom](https://marketplace.zoom.us/docs/guides/auth/jwt)
[PHP & JWT - Basic instructions](https://devforum.zoom.us/t/php-jwt-basic-instructions/15879)
[firebase/php-jwt](https://github.com/firebase/php-jwt)
[What’s the difference between join_url and start_url](https://devforum.zoom.us/t/whats-the-difference-between-join-url-and-start-url/1183)

## LINE Messaging API
条件分岐によってミーティングを作成するのか取得するのかを分ける。
メッセージテンプレレートで日時を指定するか選択する
日時指定を選択すると日時選択アクションによって日時を選択する。
指定あれた日時がポストバックイベントとして返ってくるのでその日時をzoomの開始日時に入れる。
※zoomの`start_time`のフォーマットは決まっているためその形にして渡す必要がある

```
YYYY-mm-ddTHH:ii:ss
```
今回は`date`関数で下記のようにした。

```
$post_time = date('Y-m-d\TH:i:s', strtotime(datetime);
// '\'を入れることで本来[JST]と返ってくるものを[T]だけにできる
```

### 参考記事
[日時選択アクション](https://developers.line.biz/ja/reference/messaging-api/#datetime-picker-action)
[ポストバックイベント](https://developers.line.biz/ja/reference/messaging-api/#postback-event)
[LINE Messaging APIをPHPで使ってみる](https://blitzgate.co.jp/blog/2089/)
[PHP×LINE Messaging APIで作るチャットボット](https://qiita.com/ryo_hisano/items/da85ee205fb6c8fd3fee)

## Googleカレンダー API
Googleカレンダーで色々と設定する必要がある。
※参考記事**【Google Calendar API と PHP で 予定の取得と追加をしてみるよ（準備編）】**参照
【作成】
LINEから送られてきた日時を`Google_Service_Calendar_Event`の引数の開始時間に渡す。
今回終了時間については開始から1時間とした。
※`date`関数と`strtotime`関数によって開始時間から1時間足した時間を渡す
descriptionにzoomのURLを記述することでカレンダーからでもzoomに飛ぶことができる。

```
予定を追加する時はGoogle_Service_Calendar::CALENDAR_EVENTS
```
【取得】
LINEから予定と送られた時にそのときの日時から直近の予定を返す。
$optParamsに件数などを指定する。
foreachで回して返ってきた結果をLINEからに返す。

```
予定を取得する時はGoogle_Service_Calendar::CALENDAR_READONLY
```
### 参考記事
[Create Events](https://developers.google.com/calendar/create-events)
[Events: insert](https://developers.google.com/calendar/v3/reference/events/insert)
[Events: get](https://developers.google.com/calendar/v3/reference/events/get)
[Google Calendar API と PHP で 予定の取得と追加をしてみるよ（準備編）](https://liginc.co.jp/472637)
[Google Calendar API と PHP で 予定の取得と追加をしてみるよ（PHP編）](https://liginc.co.jp/474321)
Microsoft ExcelでCSVファイル（UTF-8）を開くと文字化けが発生する問題

###背景
**UTF-8**にて作成されたCSVファイルを、Microsoft Excel を使用して開くと、日本語が化けてしまっていることを経験されたことも多いかと思います。
私も、忘れた頃に、この問題に直面することがあるため、備忘録として、一度整理することにしました。

###なぜ化けるのか

- Microsoft Excelの仕様として、デフォルトでは、入力ファイルを**SJISと解釈して開く**ようです。（というような記事を多く見かけるため、このように理解しています）
- また、Microsoft Excelは、入力ファイルについて、UTF-8 も解釈できるようですが、厳密には、ファイルの先頭に、***BOM（byte order mark）***といった、3文字（0xEF 0xBB 0xBF）が付いているファイルのみ、解釈するようです。
- ちなみに、BOMが無いファイルは、**UTF-8N**という名称で区別されることがあります。
- そして、ブラウザーからダウンロードしたCSVファイルには、UTF-8Nであることも多く、このため、Excelで開くと、文字化けしてしまうことがあります。
- また、Pythonにて、UTF-8で書き出しているにも関わらず、BOMを付けてないことで、Excelで開くと、文字化けしてしまうことがあります。（これは、よくあるケースかと思います）

###ではどうするのか

1）何かしらのプログラミング言語で出力している場合には、CSVファイルを出力する際に、BOMをつけてしまうことです。
たとえば、Pythonなら、以下のように、***encoding="utf_8_sig"*** を付けることで対応できます。

```with open(path, 'w', encoding="utf_8_sig") as f
```
詳細は、関連記事の2．を参考にしてみてください。

2）エディタを使う場合
サクラエディタには、BOMの有無を指定できるので、一度、ファイルを開き、BOMを指定して保存することで、BOMを付与できます。


##関連記事
1. [BOMの地雷を踏み抜かない正しい文字コードとの接し方](https://alaki.co.jp/blog/?p=1236)
2. [PythonでUTF-8 with BOMのCSVファイルを出力する](https://qiita.com/kino15/items/c9c06bdfc8e4a6ad34e3)
3. [UTF-8 BOM付き・BOM無しでハマった](https://qiita.com/JINr/items/255429d6174fad76b9b7)
【AWS VPC】依存関係エラーが発生した場合のデタッチ・削除の仕方

#エラーが発生
VPCを削除しようとしたが、下記の画像のようにエラーが発生した。依存関係の影響で削除できないらしい。エラー内容に基づいて削除しようとしても、どのように依存しているかわからず削除に手こずった。

<img width="965" alt="スクリーンショット 2020-06-14 18.11.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/a5c87ece-b4b7-b03c-5176-acee8b3b583f.png">

#説明
[AWSの記事]
(https://aws.amazon.com/jp/premiumsupport/knowledge-center/troubleshoot-dependency-error-delete-vpc/)に説明および解決方法が載っていた。

要するに
インスタンス、サブネット、カスタムセキュリティグループ・カスタムルートテーブル、インターネットゲートウェイ・仮想プライベートゲートウェイ
が残っていると削除ができないとのこと。

#解決方法
エラーに応じて削除する対象が変わる。

<h2>「VPC に 1 つ以上のインスタンスが含まれており、それらのインスタンスが終了されるまで削除できません。」のエラーの場合</h2>
該当のEC2インスタンスを削除すればOK。

<h2>「VPC には使用中のネットワークインターフェイスが 1 つ以上含まれており、それらのネットワークインターフェイスが削除されるまで削除できません。」のエラーの場合</h2>
1.Amazon EC2 コンソールを開きます。

2.Amazon VPC があるリージョンを選択します。

3.ナビゲーションペインの [ネットワークインターフェイス] で、削除している Amazon VPC の VPC ID を検索します。
<img width="1260" alt="スクリーンショット 2020-06-14 22.36.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/d68361c6-572d-6dba-f78d-5e0155d8446c.png">

4.Elastic Network Interfaceを選択して、[詳細] タブをクリックします。
<img width="1250" alt="スクリーンショット 2020-06-14 22.41.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/60ce85de-e470-f11e-22b6-e355d11b086c.png">


5.[説明] で、インターフェイスがアタッチされているリソースを確認します。

6.関連付けられたリソースを削除します。
今回の場合ELB appが紐付けられているとのことで、該当の物を削除する。
<img width="949" alt="スクリーンショット 2020-06-14 22.46.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/b6948f16-f36a-840e-4f69-39e36bf91036.png">

<h2>「ネットワークにはいくつかのマッピングされたパブリックアドレスがあります。ゲートウェイをデタッチする前に、これらのパブリックアドレスのマッピングを解除してください。」

「VPC には 1 つ以上のインターネットゲートウェイまたは仮想プライベートゲートウェイがアタッチされており、デタッチまたは削除されるまで削除できません。」 のエラーの場合</h2>

1.Amazon VPC コンソールを開きます。

2.Amazon VPC があるリージョンを選択します。

3.ナビゲーションペインで、NAT ゲートウェイまたは 仮想プライベートゲートウェイを選択します。

4.NAT ゲートウェイまたは仮想プライベートゲートウェイを選択します。
<img width="1023" alt="スクリーンショット 2020-06-14 22.53.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/feb23273-6482-d4fd-8d8e-44068a5e6aca.png">
5.[説明] で、インターフェイスがアタッチされているリソースを確認します。

6.Actions で、 Delete NAT Gateway (インターネットゲートウェイの場合) または Detach from VPC (仮想プライベートゲートウェイの場合) を選択します。
<img width="1017" alt="スクリーンショット 2020-06-14 23.04.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/c2bcc2c9-464d-72ee-7f73-f06a7fc1d5b9.png">

上記のようにして依存関係を全て削除し、Amazon VPC の削除を再試行を行う。


参照
https://www.cloudn-service.com/faq/3696
chat-spaceの応用実装

# はじめに

この記事は、某プログラミングスクールに登場する、通称chat-spaceの応用実装についてまとめたものです。スクールを卒業した際に、応用実装があったことを思い出したので記事にしてみました。

早速ですが、応用実装とはどんなものかというと、グループに追加したユーザーを検索してもでないようにするというものです。
![画面収録 2020-06-14 22.54.10.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616088/d9e40190-f2a5-e105-f9e2-8acbe9eb821d.gif)

この機能の動作の流れといたしましては。
#### ①　キーワード（input）を入力する。
#### ②　イベントが発生した際に、チャットメンバーに表示されているユーザーのidを配列（ids）で取得
#### ③　あとは、Ajax通信の際にinputとidsを渡し、idsを含まないユーザを検索するだけです。

以上のことをソースコードで記述すると、次の通りになります（変更した部分だけ表示）。

``` javascript
 let input = $("#user-search-field").val();
    let ids = [];
    $.each( $(".chat-group-user").find("input"), function(key,value){
      ids.push(  $(value).attr("value") );
    })
    $.ajax({
      type: "GET",
      url: "/users",
      data: { keyword: input,ids: ids },
      dataType: "json"
    })
```

``` ruby
 def index
    @users = User.search(params[:keyword], params[:ids])
    respond_to do |format|
      format.html
      format.json
    end
end
```
``` ruby
  def self.search(input, ids)
    return nil if input == ""
    User.where(['name LIKE ?', "%#{input}%"] ).where.not(id: ids).limit(10)
  end
```
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～CSS第1の1回～

# アジェンダ
* CSSとは
* CSSの書き方
    * CSSを書くのに必要な情報
    * CSSを記述する場所
* CSSの適応優先順位
* 用語
* CSSのバージョンについて

# CSSとは
CSSとは、文書の見た目を決めるためのもの。

# CSSの書き方
## CSSを書くのに必要な情報
「どこの」「なにを」「どうするか」という3つの情報が必要になる。

## CSSを記述する場所
* 使用率高 ： 外部のCSSファイルに記載する。
* 使用率中 ： HTMLファイルの、headタグの中(styleタグを使用する)
* 使用率低 ： HTMLファイルの、各タグの中(style属性を使用する)

### 外部ファイルに記載するメリット
CSSに変更を加える際、修正する箇所が少なく済むメリットがある。

外部ファイルに記載したCSSは、(基本的には)全てのWebページに反映される。
HTMLに記載した場合、そのWebページにしか反映されないので、全てのWebページのHTMLファイルに同じ内容を記載することになる。

# CSSの適応優先順位
同じ箇所に複数のスタイルが指摘された際、最も優先順位の高いスタイルが適応される。
優先順位は以下のルールで決められる。

* !importantを付けたものが優先される。(※最優先)
* 後に書かれたものが優先される。
* セレクタの書き方
 1. 要素を特定したidセレクタ(HTMLのタグとid属性を指定)
 2. 要素を特定しないidセレクタ(id属性を指定)
 3. 要素を特定したclassセレクタ(HTMLのタグとclass属性を指定)
 4. 要素を特定しないclassセレクタ(class属性を指定)
 5. タイプセレクタ(HTMLのタグを指定)
 6. 全称セレクタ(*を使用して全体を指定)
* スタイルを指定する媒体
 1. Webページ製作者が指定したCSS
 2. Webページを閲覧するユーザが指定したCSS
 3. Webブラウザ独自のCSS

# 用語
## セレクタ
「どこの」を指定するためのもの。

## プロパティ
「なにを」を指定するためのもの。

## 値
「どうする」を指定するためのもの。

# CSSのバージョンについて
CSSの最新バージョンは、まだ策定中であっても、Webブラウザによっては先行搭載している機能もある。
先行搭載された機能を使用する場合は、プレフィックスを記述する必要がある。

# おわりに
今回は、CSSの基礎知識についての内容だった。
まだわからない内容があるが、実際にCSSを書いたら理解できると思うので、とりあえず進む！

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/b534c478374af0b1f4cb)

## 参考
[1-1 CSSとは何か？（はじめてのCSS）](https://www.youtube.com/watch?v=bfKDnLSCxeE&list=PLjw-30bsJNVVa4PuUseJ5YPN1K2dJr041&index=2&t=0s)
[1-2 CSSの書き方（はじめてのCSS）](https://www.youtube.com/watch?v=sELiQ-U8ibU&list=PLjw-30bsJNVVa4PuUseJ5YPN1K2dJr041&index=2)
動画から直線を検出した覚書



    import numpy as np
    import cv2
    import time

    cam = cv2.VideoCapture('ファイルパス/sample.mp4')
    #動画を取り込み
    while(cam.isOpened()):# 動画終了まで繰り返し
        t = time.time()
        #時間測定
        ret, img = cam.read()
        #動画を画像に切り取り

        if not ret:
            break #動画が最後なら終了



        img = cv2.resize(img, (640, 380))
        #画像のリサイズ
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        #グレイスケール変換
        dst = cv2.Canny(gray, 150, 200)
        #輪郭検出(画像、外れ許容値（これ以上ならつなげる）、しきい値)

        if cv2.waitKey(1) & 0xFF == ord('q'): break
        #「ｑ」が押されたら終了

        lines = cv2.HoughLinesP(dst, rho=1, theta=np.pi/360, threshold=30, minLineLength=20, maxLineGap=8)
        #輪郭画像から直線を検出　HoughLinesPは確率的探索
        #HoughLinesP(画像, rho=1, 検出角度, しきい値, 最小ライン長, 検出幅)
        for line in lines:
            x1, y1, x2, y2 = line[0]
            lines_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 2)
            #検出した線をimgに書き込み
        cv2.imshow("Frame", lines_img)
        cv2.imshow("Frame2", dst)
        print(time.time() - t, len(lines))

    cv2.imwrite('lined_img.png', lines_img)
    print(len(lines))
    print(time.time() - t)
    cam.release() #後処理
    cv2.destroyAllWindows() #後処理

処理フレームレート30dpsくらい
ひとりGit　リポジトリ構成編

#プロローグ
[前回](https://qiita.com/roku28632/items/8392bda65acfce12702b)の続き。
今回はリポジトリを作って状態を記録複製できるか確認してみる。

#実行

はじめの状態

```bash
C:\work\git_practice\work>tree
フォルダー パスの一覧:  ボリューム Local Disk
ボリューム シリアル番号は FAFC-01FC です
C:.
├─local_r
└─remote_r.git

```

remoteリポジトリ作る

```bash
C:\work\git_practice\work\remote_r.git>git init --bare --shared
Initialized empty shared Git repository in C:/work/git_practice/work/remote_r.git/
```

クローンする

```bash
C:\work\git_practice\work>git clone remote_r.git local_r
Cloning into 'local_r'...
warning: You appear to have cloned an empty repository.
done.
```

ファイル作ってaddしてcommitしてpushする

```bash
C:\work\git_practice\work\local_r>copy nul test.txt
        1 個のファイルをコピーしました。

C:\work\git_practice\work\local_r>git add test.txt

C:\work\git_practice\work\local_r>git commit -m "test"
[master (root-commit) a226526] test
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.txt

C:\work\git_practice\work\local_r>git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 198 bytes | 99.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To C:/work/git_practice/work/remote_r.git
 * [new branch]      master -> master

```

記録できたか確認する

```bash
C:\work\git_practice\work>mkdir local_r2
C:\work\git_practice\work>git clone remote_r.git local_r2
Cloning into 'local_r2'...
done.
C:\work\git_practice\work>cd local_r2
C:\work\git_practice\work\local_r2>dir
 ドライブ C のボリューム ラベルは Local Disk です
 ボリューム シリアル番号は FAFC-01FC です
 C:\work\git_practice\work\local_r2 のディレクトリ

2020/06/14  22:45    <DIR>          .
2020/06/14  22:45    <DIR>          ..
2020/06/14  22:45                 0 test.txt
               1 個のファイル                   0 バイト
               2 個のディレクトリ   2,364,313,600 バイトの空き領域
```

#エピローグ
次はブランチ作って、mergeとかrebaseとかやっていく
GASで生徒の質問対応をする教師

## 質問対応にGoogleフォームを使用

高校で教員をしています。
学校が臨時休校になったとき，教員と生徒にGoogleアカウントが割り当てられ，Classroomなどを使えるようになりました。
生徒からの質問対応にGmailを使いたかったのですが使用不可に設定されており，生徒との個人的なメールアドレスでのやり取りも禁止されているため，以下の方法で質問を受けることにしました。

1. Googleフォームで名前，質問内容，参考画像(あれば)を回答してもらう
2. 生徒個人へGoogle Classroomで質問を作成し，質問内容に返事を，回答には選択肢「既読」のみを用意して送信する

理系科目のため，数式や図を紙に書いて写真で送信できるよう，このような方法にしています。

## フォームへの回答内容をメール通知

フォームをこまめにチェックするのが面倒なので，回答をメール通知してもらうためのGoogleAppsScriptを作りました。
フォーム本体からの通知だと，参考画像が送られてきたときにGoogle Drive上のURLが取得できなかったため，フォームに紐付けられているスプレッドシートから通知するようにしました。

このようなシートになっていて，回答があるたびに最新行に内容が追加されていくようです。
![ex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632954/a67ccc48-a4eb-450e-407f-9c30bfdddfda.png)

「ツール」→「スクリプトエディタ」を開き，以下のようなGoogle Apps Scriptを作りました。

```javascript
function sendNotification() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();//スプレッドシートを取得
  const sheet = ss.getSheets()[0];//シートを指定
  const cell = sheet.getLastRow();//最新行を取得
  
//最新行のB列の値を取得（アカウント）
  const account = sheet.getRange('B'+ cell).getValue();
  
//最新行のC列の値を取得（氏名）
  const name = sheet.getRange('C'+ cell).getValue();

//最新行のD列の値を取得（質問内容）
  const question = sheet.getRange('D'+ cell).getValue();

//最新行のE列の値を取得（画像URL）
  const image = sheet.getRange('E'+ cell).getValue();
  
//メールの本文を指定
  const msg = account + '\n氏名:' + name + '\n質問:' + question + '\n' + image;
  
//メールを送る(メールアドレスは自分のものに変更します)
  MailApp.sendEmail('example@gmail.com', '質問がきました', msg);
};
```

トリガーをこのように設定しました。
![ex2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632954/377c0743-5434-c0cc-31a1-af915ac491e7.png)

## 使用してみて
生徒からの質問があると，以下のようなメールが届きます。

> 質問がきました
> 
> <生徒アカウント>
> 氏名:<氏名>
> 質問:<質問内容>
> <画像URL>

フォーム自体の設定での通知や，Zapierを利用しての通知なども試してみましたが，スマホのメールで素早く確認する場合にはこの方法が最も便利そうです。


## 生徒への返信方法は？
Classroomでその生徒に向けた選択肢型の質問を作成し，返信をしています。
選択肢は一択で「既読」とすることで，生徒の既読確認に使っています。


## 別の使い方
同じようにして，担任クラスの生徒に大学入試の合否発表をさせています。
メール通知が来るのでリアルタイムで報告が見られて便利です。
NextCloudの手前にnginxを挟んだときにログイン時のリダイレクトが非SSLで失敗する

NextCloud 18などで、nginxを手前に挟んで通信させている際に、ログインなどのリダイレクト処理のリダイレクト先が `http://nextcloud.domain.example` などとなり、リダイレクトに失敗してログインに失敗する場合がある。

ブラウザでの利用であれば、再読込させるとログイン後の画面が表示されるため、回避は行えるが、Androidアプリなどのアプリでは失敗した状態でフリーズしてしまい、アプリとして利用できなくなるため、以下のような処理が必要となる。

※）この処理は 80 から 443 へのリダイレクトをnginxに追加したとしても失敗します。

NextCloudの `config.php` を以下の行を追記します。追記場所は以下の記述の下がわかりやすいのでオススメです。

```
'overwrite.cli.url' => 'http//localhost',
```

記述するオプションは以下となります。

```
'overwriteprotocol' => 'https',
```

これで、リダイレクト時の問題を回避できます。
今日は何のごみの日かを教えてくれるシステム(Trash_day_notification)1/3

# 今日は何のごみの日かを教えてくれるシステム(Trash_day_notification)

## 困っていること

ごみの日がどうしても覚えられない、、
私の家には、庭があって、ごみを一時的にためておくことができるために、ごみをいつでも捨てれるのは素晴らしいのですが、
ごみの日を覚えられないため、基本的に朝の用事があるときに、周りを見て、今日何のごみの日かを確認している。
-> これが非常に面倒くさい、、

ということで、通知してくれるシステムを作ろう！


## 機能
* 毎朝8時30分にごみの日をLINEに通知する

## 使用するもの
* GAS (Google Apps Script)
* LINE Notify 

## 設計

シンプルに
GAS(トリガー機能) -> LINE Notify -> LINE


## 1. 設定とコーディング1

まずは、午前8時にLINE Notifyを使って、LINEに通知する仕組みを作成する。


### LINE Notify設定

[LINE Notifyのwebhook登録ページ](https://notify-bot.line.me/my/)でトークルームを選択して、トークンを取得する。


![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192308/642acef7-f23d-86a0-8b0b-24e5e1401289.png)


自分だけのトークグループを作成し、LINE Noticeをメンバーに招待する。
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192308/3d52362c-b0e6-1654-2a90-744e0a0f3ae7.png)


### GASでコーディング
GASに次のコードを記載して、実行する。

```
function requestPost(message){
  var token = '{LINE Notifyトークン}';
  var options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}

   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}

function myFunction(){
  var message="今日は〇〇のごみの日です。" ;
  requestPost(message);
}

```

### GASでトリガーの設定
毎朝8時くらいに送られてほしいので、次のように設定する。

![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192308/2b0ba2a2-6970-c27f-e1a6-4c1878f497b5.png)

![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192308/e35ea5cc-5111-5254-851d-e3927f6e8eb0.png)

![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192308/149bffcb-6a85-2ac8-89dd-fc6718c74ad1.png)


## 2. 設定とコーディング2

ゴミの日は曜日ごとに決まっているので、それに従って違うメッセージを送信する。
もし、ごみの日でなかったら送ってきません。

```
function requestPost(message){
  let token = '{LINE Notifyトークン}';
  let options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}

   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}

function myFunction(){
  let day_of_week = get_day_of_week();
  let trash_dict = {
    'Mon': '紙・布類(段ボール)',
    'Tue': '燃やすごみ',
    'Fri': '燃やすごみ',
    'Sat': 'ビン・缶・ペットボトル類',
  }
  
  let trash_str = trash_dict[day_of_week];
  
  if (trash_str != undefined){
    let message='今日は'+ trash_str +'のごみの日です。' ;
    requestPost(message);
  }
  
}

function get_day_of_week(){
//  曜日を取得する
  let arr_day = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
  let day_num = new Date().getDay();
  console.log(arr_day[day_num]);
  return arr_day[day_num]
}

```
## 次回の記事
[今日は何のごみの日かを教えてくれるシステム(Trash_day_notification)2/3](https://qiita.com/kurikurisan/items/84456334082b72892985#2-設定とコーディング2)


## まとめ

これで、GAS, LINE Notify, LINE を使用して、ごみの日に何のごみを捨てればいいのかLINEに通知することができました。
しかし、ここまでなら、カレンダーの通知機能で大丈夫です。
この機能に、amazonダッシュボタンを使ってごみがどのくらいたまっているか、
その数によって、通知をきめるような処理を入れていきます。
AtCoder 生活　77日目

[前回](https://qiita.com/flandrescarlet237/items/27edbd8fa9d70515e2a0)

#77日目
今回はABC170に参加しました。
![スクリーンショット 2020-06-14 22.43.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606053/375956f9-8bb8-9361-12f1-16a50a12febc.png)


##[ABC170](https://atcoder.jp/contests/abc170)

###A

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    vector<int> a(5);
    rep(i,5) cin >> a[i];
    rep(i,5){
        if(a[i] == 0) cout << i + 1 << endl;
    }
}

```

###B

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int x,y;
    cin >> x >> y;
    rep(i,x+1){
        if((i*2 + (x-i)*4) == y){
            cout << "Yes" << endl;
            return 0;
        }
    }
    cout << "No" << endl;
}

```

###C

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int x,n;
    cin >> x >> n;
    if(n == 0){
        cout << x << endl;
        return 0;
    }
    if(n == 100){
        cout << 101 << endl;
        return 0;
    }
    vector<int> p(n);
    rep(i,n) cin >> p[i];
    sort(p.begin(),p.end());
    queue<int> que;
    int j = 0;
    rep(i,100){
        if(i + 1 == p[j]) j++;
        else que.push(i + 1);
    }
    int s = que.front();
    que.pop();
  	if(que.empty()){
      	cout << s << endl;
      	return 0;
    }
  	int ans = 2e9;
  	int res = 2e9;
    while(!que.empty()){
        int t = que.front();
        que.pop();
        int a = abs(s - x);
        int b = abs(t - x);
        if(a <= b){
            if(res > a){
                res = a;
                ans = s;
            }
        }
        else{
            if(res > b){
                res = a;
                ans = t;
            }
        }
        s = t;
    }
    cout << ans << endl;
}

```
感想：最後まで解けなかった

###最後に
C問題がこれでなんで通らなかったのかを、教えてくれると嬉しいです。

###追記
PDF見たらqueに０と１０１を入れれば多分通ったんじゃないかと気づいてしまった…
cssで真ん中に配置する

# 真ん中に配置する
自分用に真ん中に配置する方法についてまとめて見ました!


# 私が使うやつ
- marginを使う
- text-alignを使う

要素を真ん中に配置するのはmarginをよく使います
margin: 0 auto;
とか言う形で使うことが多いですね！
文字を真ん中に配置したいときは
text-align: center;
とすることが多いです！
BotFrameworkComposerをAzureにデプロイしたらエラーが出た話

[Bot Framework Composer](https://github.com/microsoft/BotFramework-Composer) が GA されたので使ってみたら、[Azure Bot Service](https://azure.microsoft.com/ja-jp/services/bot-service) へのデプロイで躓いたという話。

<font color="red">【2020/6/18 追記】</font>
https://qiita.com/tfukumori/items/6090dbaf3f79b7682516 に対処方法があります。
@tfukumoriさん、ありがとうございました。

# 環境

|ツール |バージョン |
|:-----|:-----:|
|Bot Framework Composer **※** |1.0.1 |
|Azure CLI    |2.7.0 |
|.NET Core    |3.1   |

**※** Web版とデスクトップ版の両方で試しました。

# Azureでプロビジョニング
Bot Framework Composer には、Azureでプロビジョニングするためのスクリプトが含まれており、その使い方は https://docs.microsoft.com/en-us/composer/how-to-publish-bot に記載がある。BOTプロジェクトのフォルダにあるREADMEファイルを見ろとも書いてあるので、先ずは従いましょう。

```:プロビジョニングのスクリプトを実行
cd C:\Users\UserName\Documents\Composer\BotName\scripts
npm install
node provisionComposer.js --subscriptionId=<AzureサブスクリプションID> --name=<リソースグループ名> --appPassword=<アプリのパスワード> --environment=<環境名>
```

|項目 |値 |
|:-----|:-----|
|AzureサブスクリプションID |AzureリソースにあるサブスクリプションIDを確認 |
|リソースグループ名   |任意の名前で |
|アプリのパスワード   |英数字と特殊文字を含む16文字以上 |
|環境名   |省略するとdevを仮定。リソースグループ名のサフィックスになる |

```:実行例
node provisionComposer.js --subscriptionId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --name=CHATBOT --appPassword=yyyyyyyyyyyyyyyy --environment=DEV
Login to Azure:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ZZZZZZZZZ to authenticate.
```

続いて、表示された9桁のコードを https://microsoft.com/devicelogin に入力して認証を完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/eef5577f-91f5-e0f0-a0ab-7e4f1d9dd210.png)

```:実行結果
> Using Tenant ID: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
> Creating App Registration ...
User was not found.
** Provision failed **
```

ところが、ユーザが見つからないと言われて失敗します。
調べてみると、気になる投稿をいくつか見つけました。

- https://github.com/microsoft/BotFramework-Composer/issues/3324
- https://github.com/Azure/azure-sdk-for-node/issues/1821

記事中に出てくる Live ID とか Hotmail ID は個人アカウントで、今の Microsoftアカウントのことです。
そして、今回使ったのも Microsoftアカウントでした。
言及されているテナント情報ですが、MicrosoftアカウントはMicrosoftが管理し、Azure ADアカウント（組織アカウント）は組織が管理するという違いがあります。

そこで試しに、会社が契約するAzure ADアカウントのサブスクリプションIDを指定したところ、あっさり上手くいきました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/4b2b3d83-50ea-9c70-224a-6f5eaf9d103d.png)
テナントに問題があったのか理由は定かではありませんが、今回はAzure ADアカウントで開発を続けることにします。
競技プログラミング練習記 No.10【ABC170参加】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC170](https://atcoder.jp/contests/abc170)に参加しました。
4完です。


|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  1min |-|4ms|
| B |  4min |-|4ms|
| C |  7min |-|6ms|
| D | 40min |エラトステネスの篩|39ms|



## A
```c++
	int a, b, c, d, e;
	cin >> a >> b >> c >>d >> e;
	cout << 15 - (a + b + c + d + e);
```
本番で、早く解けた方がいいので変数名を`a,b,c,d,e`にしました。
それぞれ問題文では`x1,x2,x3,x4,x5`ですね。
`x1,x2,x3,x4,x5`のどれかが`0`に書き換えられているとのことなので、
`x1 + x2 + x3 + x4 + x5 = 15`より式変形をして
`15 - x1 + x2 + x3 + x4 + x5` が答えになります。

## B
``` c++
	int x, y;
	cin >> x >> y;
	cout << (((y <= x * 4) && ((y & 1) == 0) && (x * 2 <= y))  ? "Yes" : "No");
```
3つの`if`文が1行に入っているので少し複雑ですね。
・足の数が`x`の2倍以上
・足の数が`x`の4倍以下
・`y`が偶数である
の3つを判定しています。

## C
``` c++
	int x, n;
	cin >> x >> n;
	vector<bool> p(105, true);
	int input;
	for(int i = 0; i < n; ++i)
	{
		cin >> input;
		p[input] = false;
	}

	if (p[x])
	{
		cout << x;
		return;
	}

	for(int i = 1; i < 100; ++i)
	{
		if (x - i < 0 || p[x - i])
		{
			cout << x - i;
			return;
		}
		if (x + i > 100 || p[x + i])
		{
			cout << x + i;
			return;
		}
	}
```
`x`を中心として絶対値が1ずつ増えるように探索して、数値が数列の中になければそれが答えになります。

## D


``` c++
	const ll MAX_SIZE = 1000005;

	bool num[MAX_SIZE];
	for(int i = 0; i < MAX_SIZE; ++i)
	{
		num[i] = false;
	}

	int n;
	cin >> n;
	vector<ll> a(n);
	for(int i = 0; i < n; ++i)
	{
		cin >> a[i];
	}
	sort(a.begin(), a.end());

	int ans = 0;
	for(int i = 0; i < n; ++i)
	{
		if(num[a[i]] == true)
		{
			continue;
		}

		// 重複がなければ
		if (!(i < n - 1 && a[i] == a[i + 1]))
		{
			ans++;
		}

		ll prime = 0;
		while(prime += a[i], prime < MAX_SIZE)
		{
			num[prime] = true;
		}
	}
	cout << ans;
```
[エラトステネスのふるい](https://www.google.com/search?q=%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9&oq=%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9)を利用します。
メモ化により高速で素数を求めるアルゴリズムですね。
一度見たものは2回目以降は見る必要はありません。この枝刈りをしないとTLEになります。
`if(num[v] == true)` 
の部分です。

小さい数からみる必要があるためソートをします。
重複したときに表を埋める処理を忘れてWAを増やしてしまいました。反省。
リファクタしました。


以上です。ありがとうございました。
Nuxt.js（Vue.js）のdata()オブジェクトに型を設定する方法【TypeScript】

TypeScriptを導入して、Nuxt.js（Vue.js）のdata()オブジェクトに型を設定する方法です。
下記は例ですが、interfaceを用いて型定義できます。

```vue
<script lang="ts">
import Vue from "vue";

interface UserInfo {
  id: number
  name: string
  email: string
  text: string
  modal: boolean
}

export default Vue.extend({
  data(): UserInfo {
    return {
      id: 22,
      name: "ken",
      email: "abc@gmail.com",
      text: "Lorem ipsum dolor sit amet, consectetur adip",
      modal: false
    }
  }
});
</script>
```
[Rails] jQueryを利用する

##はじめに
**1.gemの追加**

```ruby:Gemfile
gem "jquery-rails"
```
bundle installを行いましょう

**2.application.jsファイルに追記する**

```ruby:app/assets/javascripts/application.js
//= require jquery  // ←ここを追加
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require_tree .
```

これで、jQueryを使う準備が整いました。
##【イベントの記述】
セレクタ名にはclass,idの=の後が入ることが多い
.はclass名の前に　#はid名の前につく

```ruby:
$('.セレクタ名').イベント名(function(){
        　イベント発生時に行われる処理
});
```
**イベントの一覧**

| click | 指定した要素で左クリックしたときに処理がおこなわれる。 |
|:--|:--|
| dblclick | 指定した要素でダブルクリックときに処理がおこなわれる。 |
| contextmenu | 指定した要素で右クリックしたときに処理がおこなわれる。 |
| mousedown | 指定した要素で左もしくは右クリックしたときに処理がおこなわれる。 |
| mouseup | 指定した要素で左もしくは右ボタンが押してから離れたときに処理がおこなわれる。 |
| mouseout | 指定した要素からマウスが離れるときに処理がおこなわれる。 |
| mouseover | 指定した要素にマウスがオーバーしたときに処理がおこなわれる。 |
| mousemove | 指定した要素にマウスカーソルが動いたときに処理がおこなわれる。 |
| scroll | 画面がスクロールしたときに処理がおこなわれる。 |
| resize | ウィンドウの幅が変更したときに処理がおこなわれる。 |
| blur | 要素がフォーカスを失った時に発生 |
| focus | 要素がフォーカスを得た時に発生 |
| load | ドキュメント内の全リソースの読み込みが完了したときに発生 |
| change | 要素がフォーカスを得て値の修正が完了した時に発生 |
| select | type属性値が”text”のinput要素、textarea要素のテキストが選択された時に発生 |
| submit | フォームが送信された時に発生 |
| keydown | キーが押し下げられた時に発生 |
| keypress | キーが押された時に発生 |
| keyup | キーが上がった時に発生 |
| error | javascriptのエラーが発生した時に発生 |

##jQueryで要素にクラスを追加する
要素にclassを追加する.addClass()
$(".セレクタ名").addClass("追加するclass名");

要素からclassを削除する.removeClass()
 $(".セレクタ名").removeClass("追加するclass名"); 

クラスを追加・削除する.toggleClass()
toggleClass()は、指定した要素に指定したclassがない場合は追加、すでにある場合は削除するメソッドです。
$(".セレクタ名").on("click", function(){
  $(".セレクタ名").toggleClass("追加、削除するclass名");
});
##animate()とは？
特定のHTML要素のCSSプロパティを連続して変化させることでアニメーションを実現してくれます。

```ruby:
対象要素.animate( CSSプロパティ, duration, easing, 関数 )
```

「duration」は、ミリ秒で指定するようになっており、アニメーションが完了するまでの時間を設定できます。
「easing」は、アニメーションの挙動を指定可能で、「linear」と「swing」の2種類を文字列で設定します。

例

```ruby:
$('h1').animate({
    'fontSize': '200px'
}, 3000);
```
実行すると、現在の文字サイズから指定した200pxまでアニメーションしながら変化していき、3秒かけてサイズが変化します。

##用語
**var**: 変数を宣言して、任意で指定した値を初期化します。

```ruby:
var 変数名 = 値;
```
**attr()**: 　要素の値を取得することができます。
**IDセレクタ**：　HTML要素のid属性で指定し、取得したいid属性の値に#を付けたセレクタのことです。
**クラスセレクタ**：　HTML要素のclass属性で指定し、取得したいclass属性の値に.を付けたセレクタのことです。
**要素セレクタ**：　h1やpのようなHTML要素を対象とし、取得したい要素名をそのままセレクタとして利用します。
**属性セレクタ**：　HTMLのタグの属性値を指定したい場合、$("[ 属性 = '値' ]")で属性セレクタを取得できます。

#まとめ
 ・jQueryを使うと任意のhtmlを取得、追加、削除
classの追加削除
・アニメーションで任意の動きをさせたりすることができる。