OmniAICreator/Qiita-1.07M huggingface dataset:
AZ-900(Azure Fundamentals)について

#AZ-900とは
Azureの初心者を対応にしている資格試験です。

Azure Fundamentals 試験は、クラウドの概念、 Azure サービス、 Azure ワークロード、 Azure のセキュリティとプライバシー、 Azure の価格とサポートに関する知識を証明する機会です。受験者は、ネットワーキング、ストレージ、コンピューティング、アプリケーション サポート、アプリケーション開発の概念を含む一般的なテクノロジの概念に精通している必要があります。
引用 https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900

#試験範囲
クラウドの概念について説明する (15-20%)
Azure のコアサービスについて説明する (30-35%)
セキュリティ、プライバシー、コンプライアンス、信頼について説明する (25-30%)
Azure の価格サービス レベル アグリーメントとライフサイクルについて説明する(20-25%)
引用 https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900

#試験対策
Azure基礎
https://docs.microsoft.com/ja-jp/learn/paths/az-900-describe-cloud-concepts/
Azureの主要サービスがどんな物か理解できれば十分に合格できると思います。

#最後に
Azureの入門資格として必須だと思います。定期的に無料バウチャーが貰えるセミナーが開催されているので、ぜひ受講して無料で取得してみてください。AZ-900が取得出来たら、次の中級者資格にチャレンジしてください！
![IMG_4568.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629294/f9721433-3988-88ac-2182-b589dcb900d4.png)
【GitHub】リポジトリをクローン後に行うコマンド

# 前提・状況

- Ruby on Rails 6
- GitHubを使ってクローンした時
- 他の人がマイグレーションファイルを修正した時
- 他の人がGemのインストールを行った時 

# コマンド

ローカルリポジトリで作業する際、VSコードに書かれている文字そのものは、クローンした時やプルした時に反映されるが、それを取り巻くデータベースや、Gemfile・JavaScriptの依存関係は、コマンド実行しないとエラー出ることを学んだので覚書。

##### （１）自分のデータベースへ取り込み

```terminal:terminal
% rails db:create
``` 

##### （２）マイグレーションファイルを元に、テーブル作成

```terminal:terminal
% rails db:migrate
``` 

##### （３）Gemfile.lockに書かれた内容をインストール

- 自身が作っているRailsに入れたGemのバージョンとクローンのバージョンを合わせている。
- bundle install後にエラーが出る場合は、Gemfile.lockファイルを削除してから再度実行。

```terminal:terminal
% bundle install
```

##### （４）yarn.lockに書かれた内容をインストール

- 自身が作っているyarnファイルとクローンしたバージョンを合わせている。

- jsファイルとcssファイルなどを依存関係を考慮した関係で`yarn.lock`に書かれている内容をインストールしている。

- yarn install後にエラーが出る場合には、`yarn upgrade`を行い、最新のバージョンに更新する。 


```terminal:terminal
% yarn install
```
Docker Machine のコマンドメモ

#DockerMachineのコマンド
|項目|バージョン|
|---|---|
|docker-machine|v0.12.2|
|VirtualBox|6.1.4|

##DockerMachineの作成から停止まで

###作成
作成するマシン名は「test-box」とする。

```
$ docker-machine create --driver virtualbox test-box
```

###一覧確認

```
$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM                DOCKER      ERRORS 
test-box      -        virtualbox   Running   tcp://192.168.99.110:2376                        v19.03.12       
```

###アクティブにする

```
$ eval $(docker-machine env test-box)
$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM                DOCKER      ERRORS 
test-box      *        virtualbox   Running   tcp://192.168.99.110:2376                        v19.03.12      
```

###SSHで接続してexitでログアウト

```
$ docker-machine ssh test-box
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@test-box:~$ exit
logout
```

###IPアドレス確認
```
$ docker-machine ip test-box
192.168.99.110
```

###アクティブを解除
```
$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM                DOCKER      ERRORS 
test-box      *        virtualbox   Running   tcp://192.168.99.110:2376                        v19.03.12 
$ eval $(docker-machine env -u)
$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM                DOCKER      ERRORS 
test-box      -        virtualbox   Running   tcp://192.168.99.110:2376                        v19.03.12 
```

###Dockerマシンを停止
```
$ docker-machine stop test-box
Stopping "test-box"...
Machine "test-box" was stopped.
```

##DockerMachine上でコンテナを実行

###DockerMachine上でdockerコマンドを実行
DockerMachineがアクティブな状態でdockerコマンドを実行すると、そのコマンドはアクティブなDockerMachineのホスト上で実行していることになる。
以下はアクティブなtest-boxというDockerMachineホスト上で、nginxコンテナを実行している。
実行後に、test-boxホストのIPアドレスのポート番号8000にブラウザからアクセスする(192.168.99.110:8000)と「Welcome to nginx!」の画面が表示される。

```
$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM                DOCKER      ERRORS 
test-box      *        virtualbox   Running   tcp://192.168.99.110:2376                        v19.03.12 
$ docker run -d -p 8000:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
852e50cd189d: Pull complete 
a29b129f4109: Pull complete 
b3ddf1fa5595: Pull complete 
c5df295936d3: Pull complete 
232bf38931fc: Pull complete 
Digest: sha256:c3a1592d2b6d275bef4087573355827b200b00ffc2d9849890a4f3aa2128c4ae
Status: Downloaded newer image for nginx:latest
054e2f9af619f68c12dfa964772dcb9902ebfeed9c5805122dd4a967b87b88f7
```

###作成したコンテナの確認


```
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
054e2f9af619        nginx               "/docker-entrypoint.…"   2 hours ago         Up 9 minutes        0.0.0.0:8000->80/tcp   boring_chatelet
```

###DockerMachineホスト上のコンテナのシェルに入る


```
$ docker exec -it 054e2f9af619 bash                              
root@054e2f9af619:/# 
```
（JSメモ）IE用にXmlHttpRequestを用いた、async/await・Promise未使用の順序保証複数GET/POST用関数

作るに至った経緯は以下の記事に纏めています。
> [IEなどにおけるXMLHttpRequestで、複数リクエストをawaitするPromise.all的な処理を行いたい。](https://qiita.com/777_happ/items/19df2d5003fe46c8167d)

#本体
```js
function REQUEST_ALL(c, p) {
    var r = p.map(function(u) {
        var x = new XMLHttpRequest;
        x.addEventListener('loadend', function() {
            r.length == 1 + (p++) && c(r.map(function(v) {
                return {
                    url: v.responseURL,
                    status: v.status,
                    data: {
                        text: v.responseText || null,
                        json: (function(t) {
                            try {
                                return JSON.parse(t)
                            } catch (z) {
                                return null
                            }
                        }
                        )(v.responseText)
                    }
                }
            }))
        }),
        x.open(u.type, u.path, true, u.user, u.password),
        x.send(u.type !== 'GET' ? (function(y) {
            var f = new FormData;
            Object.keys(y).forEach(function(k) {
                Array.isArray(y[k]) ? y[k].forEach(function(v) {
                    f.append(k + '[]', String(v))
                }) : f.append(k, String(y[k]))
            });
            return f
        }
        )(u.param || {}) : null);
        return x
    })
      , p = 0
}
```

##縮小版
```js
function REQUEST_ALL(c,p){var r=p.map(function(u){var x=new XMLHttpRequest;x.addEventListener('loadend',function(){r.length==1+(p++)&&c(r.map(function(v){return{url:v.responseURL,status:v.status,data:{text:v.responseText||null,json:(function(t){try{return JSON.parse(t)}catch(z){return null}})(v.responseText)}}}))}),x.open(u.type,u.path,!0,u.user,u.password),x.send(u.type!=='GET'?(function(y){var f=new FormData;Object.keys(y).forEach(function(k){Array.isArray(y[k])?y[k].forEach(function(v){f.append(k+'[]',String(v))}):f.append(k,String(y[k]))});return f})(u.param||{}):null);return x}),p=0}
```

#使い方
第一引数がコールバック関数、第二引数がリクエスト情報の配列です。

```js
REQUEST_ALL(function(a) {
    console.log(a);
}, [
    {type: 'GET', path: 'a.json'},
    {type: 'GET', path: 'b.json', user: 'guest_user', password: 'guest_credential'},
    {type: 'POST', path: 'x.php', param: {a: 1, b: [1, 2, 3]}}
])
```

----

なお、コールバック関数の返り値は以下のようになっています。

```
[{...}, {...}, {...}]
```
↓↓↓

```json-doc
[
    {
        data: {
            text: "<responseText>",
            json: {...}// responseTextがJSONでパースできないならnull
        },
        status: 200,//400系などの時も
        url: "http://<...>/a.json"
    },
    {...},
    {...}
]
```
GOでPostgresqlへ接続する

## DockerでPostgreを起動する

```docker-compose.yml
version: "3"
services:
  postgres:
    image: postgres
    container_name: postgres
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=password
    tty: true
    restart: always
    user: root
    volumes:
      - ./init:/docker-entrypoint-initdb.d
      - /etc/localtime:/etc/localtime:ro
  pgweb:
    image: sosedoff/pgweb
    container_name: pgweb
    ports: 
      - "8081:8081"
    environment:
      - DATABASE_URL=postgres://root:password@postgres:5432/testdb?sslmode=disable
    links: 
      - postgres:postgres
    restart: always
    depends_on:
      - postgres
```

### 起動

```
docker-compose up -d
```

## Goから接続
```main.go
package main

import (
    "database/sql"
    "fmt"
    _ "github.com/lib/pq"
)

const (
    // Initialize connection constants.
    HOST     = "127.0.0.1"
    DATABASE = "testdb"
    USER     = "root"
    PASSWORD = "password"
)

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {
    // Initialize connection string.
    var connectionString string = fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", HOST, USER, PASSWORD, DATABASE)

    // Initialize connection object.
    db, err := sql.Open("postgres", connectionString)
    checkError(err)

    err = db.Ping()
    checkError(err)
    fmt.Println("Successfully created connection to database")

    // Drop previous table of same name if one exists.
    _, err = db.Exec("DROP TABLE IF EXISTS inventory;")
    checkError(err)
    fmt.Println("Finished dropping table (if existed)")

    // Create table.
    _, err = db.Exec("CREATE TABLE inventory (id serial PRIMARY KEY, name VARCHAR(50), quantity INTEGER);")
    checkError(err)
    fmt.Println("Finished creating table")

    // Insert some data into table.
    sql_statement := "INSERT INTO inventory (name, quantity) VALUES ($1, $2);"
    _, err = db.Exec(sql_statement, "banana", 150)
    checkError(err)
    _, err = db.Exec(sql_statement, "orange", 154)
    checkError(err)
    _, err = db.Exec(sql_statement, "apple", 100)
    checkError(err)
    fmt.Println("Inserted 3 rows of data")
}
```

```
go run main.go
```

## psqlで接続

### シェルから接続
```
psql -h localhost -U root -d postgres -p 5432
```

### DB一覧表示
```
\l
```

### 対象DBへ接続
```
\c testdb
```

### カレントDBを確認
```
select current_database();
```

### データが入っているか確認
```
testdb=# select * from inventory;
 id |  name  | quantity 
----+--------+----------
  1 | banana |      150
  2 | orange |      154
  3 | apple  |      100
```

## 参考
https://qiita.com/hiro9/items/e6e41ec822a7077c3568
https://docs.microsoft.com/ja-jp/azure/postgresql/connect-go
【超入門】GitHubでブランチを切る

こんにちは、むんです:grinning:
今度GitHubを使うことになったのですが、しばらくSVNですっかり忘れてしまい。。
復習がてら、まとめました。

##やること
GitHub上のリポジトリにブランチを切る。
（今回マージはしない）

##目次

①developをクローン
②ブランチを切る
③ソースを改修
④ローカルリポジトリにadd
⑤ローカルリポジトリにcommit
⑥リモートリポジトリにpush

流れとしてはこんな感じ。
それでは詳しく説明していきます。

###①developをクローンしてくる

```
$git clone {url}　
$cd {cloneで出来たディレクトリ名}
```

###②ブランチを切る
まず、現在のブランチの状態を確認。

```
$git branch
$*develop
```

developが出来ているのを確認。
ブランチを切リましょう。

```
$git branch {ブランチ名}
```
ブランチが切られているか、確認。

 ```
$git branch
$*develop
${作成されたブランチ名}
```
ブランチが作成されている。
ブランチに移動。

```
$git checkout {ブランチ名}
```
ブランチに移動出来ているか、確認する。

```
$git branch
$develop
$*{作成されたブランチ名}
```
ブランチに移動出来ている。

###③ソースを改修する
cloneしてきたフォルダ配下で改修する。

###④ローカルリポジトリにコミットするファイルをadd

```
$git add {コミットするファイル名}
```

ステータスを確認する。

```
$git status
On branch {ブランチ名}
Changes to be committed:
 (use "git restore --staged <file>..." to unstage)
	new file:   src/index.html
	new file:   src/img/header.jpeg
	new file:   src/img/sub1.jpeg
	new file:   src/img/sub2.jpeg
	new file:   src/img/sub3.jpeg
```
意図した通り（今回は新規で追加したファイルが）出力される。

###⑤ローカルリポジトリにファイルをcommit

```
$git commit -m "{コミット時のメッセージ}"
```

ログを確認する。

```
$git log
commit 40fd69c7634357748e31b817c91d12cbf1143f64 (HEAD -> {ブランチ名})
Author: Mun Hogehoge <mun.hogehoge@company.co.jp>
Date:   Sun Nov 22 11:01:34 2020 +0900

    Docker入門の記事を書きました //コミット時のメッセージ

```
###⑥リモートリポジトリにpush

```
$git push origin {branch名}
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 431 bytes | 215.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/sample/sample.git
   1abcde2..123456f  {ブランチ名} -> src

```

GitHubを確認してみる。
意図した通りブランチが追加されているはず。
ブランチが追加出来ていなければ、何か手順に漏れがないか確認する。

##まとめ
以上、リポジトリにブランチを切る手順でした。
次回はマージする手順を書きたいと思います。
【PHP】PaizaのDランク問題(辞書式ソート)で躓いた話

##はじめに
アルゴリズムの基礎を学ぶため、現在[Paizaラーニング](https://paiza.jp/works/mondai/c_rank_level_up_problems/problem_index?language_uid=php)の問題集に取り組んでいます。こちらのリンク先の問題はCランク(forループなどの基礎的な問題が解ける程度の水準)達成に向けた問題集ですので基本的に難易度は低いはずですが、躓いた問題があったので投稿しておきます。

###ソート問題 STEP:3 辞書式ソート
難易度は堂々のDランクです。ぐぬぬ。
PHPではソート用の関数として`sort()`や`rsort()`といった関数が用意されていますが、文字列の場合でもこれが適用できますよ、ということを初学者向けに紹介するというのがコンセプトとなった問題な気がします。気がするのですが・・・

####問題概要
こちらから。
[https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_sort_step3?language_uid=php](https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_sort_step3?language_uid=php)
ユーザー登録が必要ですが、問題は無料でチャレンジすることができます。

```
----入力例----
3
1 3
3 5
3 4

----出力例----
3 5
3 4
1 3
```

ざっくり問題を紹介しますと、まずはじめの入力値として整数nが与えられ、スペースで区切られたペアの数字列(a_b)が入力値分n個与えられます。

1.ふたつのペアの数が異なる場合、aの数が多い方が偉い（この際bは関係ない）
2.aが同じである場合、bが多い方が偉い

上記の条件を踏まえて、偉い順にソートして値を出力しましょうという問題です。

####解いてみる

はじめに下記のようなコードで入力サンプルをクリア。

```php
<?php
    //出力をループする回数
    $input_line = fgets(STDIN);
    
    //残り入力される分だけ配列$array[]に入れる
    while ($input = fgets(STDIN)) {
        $array[] = trim($input);
    }

    //関数で大きい順(降順)にソートする
    rsort($array);
    
    //改行して値を出力
    for ($i=0; $i < $input_line; $i++) {
        echo $array[$i]."\n";
    }
    
?>
```

```
----入力値----
3
3 5
1 3
3 4

----出力値----
3 5
3 4
1 3

```

しかしこのコードでは、以下のような入力の場合に上手くソートされておらずNG判定となりました。

```
----入力値----
7
10 5
1 3
2 1
20 10
3 4
20 1
20 5

----出力値----
3 4
20 5
20 10
20 1
2 1
10 5
1 3

```

入力した値に半角スペースが含まれているため文字列として格納されていますので、数字の3と20を比較した時に、初めの3と2が比較され、3の方が高い値であるとみなされてしまっています。

paiza公式(Python3の場合)の解説を見ると、「入力値を保持した配列をそのままソート関数に渡して降順に並べるだけで良い」と記載があります。PHPの解法は載っていなかったため別言語の解法を確認したのですが、あまり上手くいかず。どうしたものか・・・

1時間くらい悩みましたが、以下のステップを踏むことで解決しました。

1.入力値を配列に格納する
2.`explode()`関数で値を分割する
3.配列の値を`sprintf()`関数を用いて、書式を整える(1という値を01表記にする)
4.`rsort()`関数でソート(書式を整えて03とした値なら20と比較した場合でもソートできるはず)
5.`explode()`で再分割。`sprintf()`関数で元の書式に戻してやり、改めて配列に格納
6.整えた配列を出力


sprintf関数については、個人的にこちらのページが分かりやすかったです。
[https://wp.tech-style.info/archives/582](https://wp.tech-style.info/archives/582)

最終的に以下のコードとなりました。

```php

<?php

$inputNum = trim(fgets(STDIN));

//1.入力値を配列に格納する
while ($input = fgets(STDIN)) {
    $array[] = trim($input);
}

for ($i=0; $i<$inputNum; $i++) {
    //2.explode()関数で値を分割する
    $test = explode(" ", $array[$i]); 

    //3.配列の値をsprintf()関数を用いて、書式を整える(1という値を01表記にする)
    $test[0] = sprintf('%02d', $test[0]);
    $test[1] = sprintf('%02d', $test[1]);
    $sort_array[] = $test[0] . " " . $test[1];
}

//4.rsort()関数でソート
rsort($sort_array);

for ($i=0; $i<$inputNum; $i++) {
    //5.explodeで再分割。sprintfで元の書式に戻してやり、改めて配列に格納
    $answer = explode(" ", $sort_array[$i]);
    $answer[0] = sprintf('%01d', $answer[0]);
    $answer[1] = sprintf('%01d', $answer[1]);
    $answer_array[] = $answer[0] . " " . $answer[1];
}

//6.整えた配列を出力
for ($i=0; $i < $inputNum; $i++) {
    echo $answer_array[$i] . "\n";
}
    
?>

```

無事出力できました。

```
----入力値----
7
10 5
1 3
2 1
20 10
3 4
20 1
20 5

----出力値----
20 10
20 5
20 1
10 5
3 4
2 1
1 3
```

###おわりに
冗長なコードである感じもありますが、備忘録も兼ねて記載させて頂きました。
まだまだ勉強不足ですので、PHPでももっと楽に出力させられるよ、こんな考え方でもソートできるよ、などの意見がありましたらご教示いただければとても嬉しいです。

閲覧ありがとうございました！
VSCode で LaTeX をビルドできるようにする

#環境
Windows 10 Home
Visual Studio Code バージョン 1.51.1
LaTeX Workshop v8.14.0

#発生した問題
Visual Studio CodeにLaTeX Workshopを入れてビルドしようと思ったら、以下のようなエラーが出た。
![20201122120304.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815574/a9f058d0-dd28-34c8-e06a-fddae5b15023.jpeg)
そこで、Open compiler logをクリックして出力を見てみると、以下のような表示が。

```
No pages of output.
Transcript written on c:/Users/ユーザー名/Desktop/textest/1.log.
Latexmk: Log file says no output from latex
Latexmk: For rule 'pdflatex', no output was made
Collected error summary (may duplicate other messages):
  pdflatex: Command for 'pdflatex' gave return code 1
      Refer to 'c:/Users/ユーザー名/Desktop/textest/1.log' for details
Latexmk: Use the -f option to force complete processing,
 unless error was exceeding maximum runs, or warnings treated as errors.
=== TeX engine is 'pdfTeX'
Latexmk: Errors, so I did not complete making targets
```
どうやら、Latexmkからpdflatexが呼び出されている。TeXworksを使っていた時に、pdflatexは日本語を扱えないという制約があったことを思い出し、その時と同様にptex2pdfを使うように変更した。

#解決法
以下を```settings.json```に記述する。

```settings.json
{
    "latex-workshop.latex.recipes": [
        {
            "name": "ptex2pdf",
            "tools": [
                "ptex2pdf"
            ]
        }
    ],
    "latex-workshop.latex.tools": [
        {
            "name": "ptex2pdf",
            "command": "ptex2pdf",
            "args": [
                "-l",
                "-ot",
                "-kanji=utf8 -synctex=1",
                "%DOC%"
            ]
        }
    ],
    "latex-workshop.view.pdf.viewer": "tab",
}
```
これで、Visual Studio Code上でビルドができるようになり、PDFのプレビューもできるようになった。

#参考
[TeXworks/設定](https://texwiki.texjp.org/?TeXworks%2F%E8%A8%AD%E5%AE%9A)
[VSCodeプラグイン「LaTeX Workshop」の設定](https://qiita.com/arailly/items/5bfdfaf786f6ac0c9808)
Raspberry Piとhostapdでローカルサーバに接続する

#やりたいこと
Raspberry Pi内臓のWi-Fiをアクセスポイントとして使い、他のデバイス（スマホやPC）で接続することでRaspberry Piで構築したサーバに接続する。

#使ったもの
* Raspberry Pi3 Model B
 * 3B以上のモデルだとWi-Fiを内蔵しているのでこれだけでいい。

#やり方
###インストール（hostapd, dnsmasq, Node.js）
Node.jsが入ってるかを確認

```
$ node -v
```
入ってなかったら、入れる。
こちらの記事を参考にされると良いと思います。
[ラズベリーパイ4にNode.jsをインストールするまで](https://qiita.com/gdate/items/f87af2e8491c6cc3c19e)

```
$ sudo apt-get install hostapd dnsmasq
```

###hostapdの設定
/etc/hostapd/hostapd.confを以下の内容で生成。
ssidとwpa_passphraseは自由に設定。

``` /etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=test-hostapd
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=test1234
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
```
この設定を読み出すように、/etc/default/hostapdの以下を変更。

``` /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```

###DHCPの設定
isc-dhcp-serverでも同じことができるようだが、うまくいかなかったのでdnsmasqを使用。
/etc/dnsmasq.confに以下を追記。

``` /etc/dnsmasq.conf
interface=wlan0
dhcp-range=192.168.2.2,192.168.2.50,255.255.255.0,24h
```

###ネットワーク設定
/etc/dhcpcd.confに以下を追記。
IPアドレスを固定。

``` /etc/dhcpcd.conf
interface wlan0
    static ip_address=192.168.2.1/24
    nohook wpa_supplicant
```

###起動

```
$ sudo systemctl restart dhcpcd
$ sudo systemctl start dnsmasq
$ sudo systemctl enable dnsmasq
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl start hostapd
```

再起動。

```
$ sudo reboot
```

###簡単なWebサーバを構築
以下のソースでtest.jsを生成。

``` test.js
var http = require('http');
var server = http.createServer();

server.on('request', function(req, res) {
    res.writeHead(200, {'Content-Type' : 'text/plain'});
    res.write('hello world');
    res.end();
});

server.listen(3000, '0.0.0.0');
```
以下で実行。

```
$ node test.js
```

###接続
PC等で自分でつけたssid（例：test-hostapd）のWi-Fiに接続。
http://192.168.2.1:3000 にアクセスし、hello Worldと出てくれば成功。
【Windows10】VSCodeからGitHubを使う

VSCodeからGithubを使えるように設定しました。
特殊なことが必要なわけではありませんが。。。

##ローカル環境
| 項目 | バージョン |
|:-----------|:------------|
| OS | Window10 2004 |
| Editor | VSCode:1.51.1 |

##事前準備
####1.GitHubにアカウントを作成します。
https://github.co.jp/

##VSCodeからGitHubのRepositoryをClone
####1.【ローカル環境】git for windowsをダウンロードし、インストールします。
https://git-scm.com/

####2.【GitHub】Repositoryを作成します。
#####2-1．右上の「⁺」ボタンを押下するとメニューが表示されるので、「New Repository」を選択します。

![menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/0d5bf610-232c-2723-456c-5d2734940329.png)

#####2-2．【GitHub】「Repository name」項目を入力します。「Public/Private」、及び「Initialize this repository with:」の各項目は必要に応じて設定してください。

![CreateNewRepo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/3de95c73-afd1-09bf-7c12-720bcb68cef9.png)

#####2-3．【GitHub】（HTTPSを前提としています）作成したRepositoryのURLをコピーします。

![RepoURL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/518434a9-6fce-e2f2-7c22-b38085609f0c.png)

#####3．【ローカル環境】VSCodeからGitHubのRepositoryを開きます。
#####3-1．【ローカル環境】VSCodeのExploereで「Clone Repository」を選択します。
VSCode-GitHub連携でGitHubのログインを求められます。

![CloneRepo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/600b7a18-0372-02b0-34ec-ae83877869e8.png)

#####3-2．【ローカル環境】GitHubのRepositoryのURLを入力します。

![InputRepoURL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/b530e010-0367-665f-7a29-2c179bf788db.png)

#####3-3．【ローカル環境】「フォルダー選択」でLocal Repositoryを選択します。必要に応じてLocal Repositoryのフォルダを作成してください。

![SelectRepoFolder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/dcdfcb5f-12ec-9df1-4fc0-3e692ad81446.png)

#####4．【ローカル環境】Exploereで開ければ完了です。

##VSCode上でcommit/push
####1.【ローカル環境】ファイルに新規・変更・削除がされるとサイドバーの「Source Control」に対象ファイル数が表示されます。

![update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/64dbd33e-0201-0793-e9ef-43ff0d7ecee6.png)

####2.【ローカル環境】「Source Control」でcommitやpushなどが可能です。

![GitOpe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/6c9fc349-ed6e-90c7-941f-65de39f4f742.png)

####3.【GitHub】commit/pushを実行し、GitHub上で対象のファイルが確認できれば完了です。

![RepoDirectory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/da5f628c-746f-889e-5feb-621128dd75a9.png)

##開発では、、、
* チーム開発だとBranchをきったり、Pull Requestによる開発となりますので、VSCodeのExtensionsから「Git History」をinstallしておくと便利です。

![GitHistory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679829/388990a2-9508-8145-69a9-30316711bb21.png)

* それ以外には「GitHub Pull Requests and Issues」なども。
【ジョーク】Ubuntu 20.04でMixxxを使う時にInvalid sample rateになった時の対処法

#環境
- Xubuntu 20.04 (amd64)
- Mixxx 2.2.3
- Numark MixTrack Pro2

#発生した事象

- USB midiデバイスとしては正常に動作するが、MixTrack Pro 2のヘッドホン端子から音が出ない
- MixTrack Pro2のヘッドホン端子からMixxx以外のアプリケーションの音も出ない
- サウンドデバイス設定でMixTrack Pro2のヘッドホン端子から音を出そうとするとInvalid sample rateエラーが発生する

```
Error opening "MixTrack Pro 2: USB Audio (hw:1,0)"
Invalid sample rate 
```

#試した事

- lsusbでMixTrack Pro2を認識しているか確認する
- lsmodでsnd-usb-audioがロードされていない場合、手動でロード ([ここまでの出典](https://www.linuxquestions.org/questions/linux-hardware-18/usb-soundcard-numark-mixtrack-pro-2-does-not-work-4175612190/))
- ALSAのHWを使用せず、plughwを使用するように環境変数を変えた上でmixxxを起動 ([出典](https://github.com/mixxxdj/mixxx/wiki/troubleshooting#mixxx_says_my_sound_card_does_not_support_the_sample_format))

```
$ sudo modprobe snd-usb-audio
$ export PA_ALSA_PLUGHW=1
$ pasuspeder mixxx  #pasuspenderはMixxxの実行中にPulseAudioを一時的に止める
```

#永続化

- /etc/modulesに、```snd-usb-audio```を追加して起動時にカーネルモジュールのロード
- ~/.bashrcに、```alias mixxx='export PA_ALSA_PLUGHW=1 && pasuspender mixxx' ``` の追記
- ~/.local/share/applications/mixxx.desktopの"Exec="の行を ```sh -c'export PA_ALSA_PLUGHW=1 && pasuspender mixxx' ```に変更
[Rails]dry_validationでドライなバリデーションを構築

# dry-validationて？

railsでのバリデーションをdryにやってくれるgemです。
備忘録として残しておきます。
https://dry-rb.org/gems/dry-validation/1.5/schemas/

# 導入

```:Gemfile
gem 'dry-validation'
gem 'dry-struct'
```

# 設定

```
class ApplicationContract < Dry::Validation::Contract
  config.messages.default_locale = :ja
  config.messages.backend = :yaml
  config.messages.load_paths << 'config/errors.yml'
end
```

# バリデーションエラー時のメッセージ
キーとバリューはyamlに記載します。

```:config/errors.yml
ja:
  dry_validation:
    errors:
      str?: '文字列ではない'
      int?: '数字ではない'
      array?: '配列ではない'
      filled?: '空です'
      rules:
        name:
          hogehoge: 'ホゲホゲ'
        カラム名:
          ...
```


# バリデーションルール

```
class HogeContract < ApplicationContract
  params do
   required(:name).filled(:string)
   optional(:email).filled(:string)
   required(:age).maybe(:integer)
  end

  rule(:name) do
    key.failure(:hogehoge) if ~
  end
end
```

`required`：パラメータが存在しているかチェック
`optional`：パラメータの存在は任意
`filled`：型のチェック
`maybe`:型のチェック、nilの時は発火しない

ruleでバリデーション対象のカラムを指定し、その中にバリデーションルールを記述します。


# 呼び出し

```
HogeContract.new.call(
name: params[:name],
email: params[:email],
age: params[:age]
).errors.to_h
```

バリデーションルールを記述したクラスを生成し、callで呼び出します。
引数にはparamsで使うものを全て渡すようにします。
終わりです。


なんか記事もドライになったな、、、
【 Python】InvalidSchema: No connection adapters were found for[画像URL]の対処方法

自分用のメモに記載しているので、文章はかなり雑です。

```python.py
import requests as req

#まずは1枚の画像を取得するところから
test_url="https://papimo.jp/h/00031715/hit/view/605"
soup = BeautifulSoup(html, "html.parser")

img_url=[]
img_tags=soup.find("table",attrs={"class":"graph-some"}).find_all("img")[-1]
img_tag=img_tags.get("src")
img_url.append(img_tag)

reqData1 = req.get(img_url)
with open('/content/gdrive/MyDrive/Colab Notebooks/iland_img/605.png', 'wb') as file:
  file.write(reqData1.content)
```

テスト用でとりあえず1つダウンロードしたかっただけなので、for文で回す必要がないと思っていたけども。
実際実行してみると

```python.py
InvalidSchema: No connection adapters were found for[画像URL]
```

というエラーが発生。
問題だったのはreq.getにリストをそのまま渡してしまっていたこと。
普通にfor文で回したら、解決

```python.py
import requests as req

#まずは1枚の画像を取得するところから
test_url="https://papimo.jp/h/00031715/hit/view/605"
soup = BeautifulSoup(html, "html.parser")

img_url=[]
img_tags=soup.find("table",attrs={"class":"graph-some"}).find_all("img")[-1]
img_tag=img_tags.get("src")
img_url.append(img_tag)

for i_url in img_url:
  reqData1 = req.get(i_url)
  with open('/content/gdrive/MyDrive/Colab Notebooks/iland_img/605.png', 'wb') as file:
      file.write(reqData1.content)
```
【VScode】「！」でVue.js用のデフォルト設定・スニペット【Vue.js】

## HTMLファイル上で「!」を打った際に表示させたいコードスニペット
VScodeエディタ上でHTMLファイル上でvue.jsのCDNを読み込んでコーディングすることを想定した環境です。

### 操作手順
>shift+command+pで検索窓を表示⇨「基本設定：ユーザースニペットの構成」⇨「html」で検索⇨「html.json」を選択

```json:html.json
{
	"html5": {
		"prefix": "!",
		"body": "<!DOCTYPE html>\n<html lang=\"ja\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>${1:Document}</title>\n  <link rel=\"stylesheet\" href=\"${2:./css/style.css}\">\n</head>\n<body>\n  <div id=\"app\">\n\n  </div>\n  <script src=\"https://unpkg.com/vue@next\"></script>  \n  <script src=\"app.js\"></script>\n$0</body>\n</html>"
  }
}
```

## 出力されるコード
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Document</title>
  <link rel="stylesheet" href="../style.css">
</head>
<body>
  <div id="app">

  </div>
  <script src="https://unpkg.com/vue@next"></script>  
  <script src="app.js"></script>
</body>
</html>
```
RaspberryPiでhlsストリーミングする(ための準備)

# 結論
とりあえず最終版のシェルスクリプト。
※ご存知かとは思いますが、念のため。パスの通った場所へ。
私は~/usr/binにぶち込んであります。

```shell:hls_streaming
#! /bin/bash
CACHE_DIR=/tmp/hls_cache

if [ ! -e $CACHE_DIR ];
then
    mkdir $CACHE_DIR
fi

ffmpeg -f alsa -thread_queue_size 16384 -i hw:1,0 \
    -f v4l2 -thread_queue_size 16384 -s 640x480 -r 30 -vsync 2 -i /dev/video0 \
    -c:v h264_omx -b:v 1000k -bufsize 1000k -g 60 \
    -c:a aac \
    -flags +cgop+global_header \
    -f hls \
    -hls_wrap 10 \
    -hls_time 2 \
    -hls_list_size 3 \
    -hls_allow_cache 0 \
    -hls_segment_filename $CACHE_DIR/stream_%06d.ts \
    -hls_base_url stream/ \
    $CACHE_DIR/playlist.m3u8
```

# 動機
　会社から自宅が遠いこともあり昨今のリモートワークブーム(？)の影響で極力自宅で仕事がしたいという思いが日に日に増してきている今日この頃です。ただ、担当が下回りFWの開発で実機を触らないと開発が進まないということもあり、リモートでタッチパネルを操作できるロボット(中華プロッタ)を購入して日曜プログラミングで絶賛構築中です。
　しかしロボットで操作したはいいけど実機がロボットによってどんな状態になってるか分からん！と思うと不安で寝れなくなることは:fire:を見るより明らかです。

はい、ということで前置きが長くなりましたが、要はストリーミングを行うということです:fearful:

# 構成
* RaspberryPi3 or 4
* カメラ：ロジクールC920

```shell-session:shell
$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12

HD Pro Webcam C920 (usb-0000:01:00.0-1.2):
        /dev/video0
        /dev/video1
$
$ arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 1: C920 [HD Pro Webcam C920], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
```

# 参考記事
ほぼ丸パクリです。。。@fujino-fpuさんありがとうございます:pray:
[参考記事へのリンク](https://qiita.com/fujino-fpu/items/2356fa41660d0696d216)

# 少し改造させていただきました
## tsファイルの保存先の変更
よほどRAMにキャッシュされると思うので大丈夫かとは思いますが、保存先をRAMディスクへ。
将来的にはWebサーバーのキャッシュディレクトリに移動させます(もちろんその場合もRAMディスクへ)が、とりあえず/tmpへ

## オーディオ系のエラー対策
```shell-session
[alsa @ 0x1b8d3f0] cannot set channel count to 1 (Invalid argument)
```
と怒られた。[ffmpegのドキュメント](https://ffmpeg.org/ffmpeg.html)にはオーディオのチャンネルを指定せいと書いてあり、問題なさそうですが…
よーわからんけどオプションごと無かった事としてこそっと削除したら動作したので良しとします。

## 生成されるtsファイルに制限を設ける
無尽蔵にtsファイルが生成されるので「-hls_wrap」オプションを付与。
ここでは10を指定して10ファイルごとにリングされるようにしています。
ご自身の環境に合わせて調整してください。
#4 【python】関数の初歩

#はじめに
この記事はプログラミングを勉強し始めて２ヶ月ほどの駆け出しエンジニアがアウトプット目的に書いている記事です。
ruby、jsをかじったのちトレンドであるpythonに興味を持ったので学習を始めました。
今回はpythonの関数定義について記事を書いていこうと思います。
拙い記事になりますが、気になる点があればご指摘いただけるとありがたいです！
なお本記事は、macOSにpython3およびanacondaの導入をしていることが前提となっております。

#1 そもそも関数って何
関数とは定められた処理を実行しその結果を返す命令のことです
行いたい処理に名前を付けることで、その名前で処理を呼び出すことができます。
言葉だけではわからないので実際にコードをみていきます。

#2 関数定義
関数定義はこのような形で行います。

```
def 関数名():
 行いたい処理
```
実例

```python:sample.py
def aisatu(): 
  print("hello")   #print("hello")とい処理にaisatuという名前を付けている

aisatu()  #名前で処理を呼び出す

```
ターミナルでの実行結果

```
python sample.py
hello
```

このように処理に名前をつけることで、簡単に処理を呼び出すことができます。
今回はhelloを出力するだけだったのでわかりにくいですが、なんども行う必要がある処理の場合は、
コードを省略できたり、コードが読みやすくなるというメリットがあります。


#3 引数
引数とは関数呼び出しの際に与える値のことです。
ある二つの数字を足し算する関数を例にしてみてみましょう。

```python:sample.py
def tashizan(a,b):
 print(a + b)

tashizan(1,3)
```
ある二つの数字を足し算するとき、数字は二つ必要になります。
(a,b)の部分はaとb二つの数字が必要なことを表しており、関数を呼び出す際に(1,3)で二つの数字を与えているということです。
関数名の後の（）内はその関数を呼び出すのに必要な値を示しているということです。



#終わりに
今回の記事は以上で終了です。
関数の部分は理解していても言語化して伝えるのは難しいと感じました。
言語化しようと努力することで知識の定着に繋がるので今後も頑張っていきたいです。

前の記事→https://qiita.com/shin12032123/items/89ecbff9257833eceff3
次の記事→https://qiita.com/shin12032123/items/5f7d3db23962957d2bb3
自己相関係数の計算の方法

#1 この記事は

自己相関係数をpythonで計算する方法を説明する。


#2 方法

3日周期が存在するデータの自己相関係数を自動計算する。(plot_acfを使う)


```python:sample.py
#dataを定義する。
from statsmodels.graphics.tsaplots import plot_acf
import pandas as pd
import numpy as np

dat = [
    ['07-01',1],
    ['07-02',10],
    ['07-03',20],
    ['07-04',2],
    ['07-05',11],
    ['07-06',21],
    ['07-07',3],
    ['07-08',22],
    ['07-09',32],
    ['07-10',4],
    ['07-11',23],
    ['07-12',33],
]

#datをDataFrame型変数dfに格納する。
df = pd.DataFrame(dat,columns=["A","B"])

print("dfを表示する","\n",df)

fig, ax = plt.subplots(ncols=2, figsize=(15, 4))
sns.lineplot(x="A", y="B", data=df,ax=ax[0])
plot_acf(df["B"].dropna(), lags=10, zero=False,ax=ax[1]) #自己相関算出時、NAがあると正しく計算できない。
```

![147.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/8283e7d9-62c2-7cb0-6972-8881228dcc5f.jpeg)
Qiitaの記載方法まとめ（テスト記事）

#はじめに
初投稿です。テスト記事として、QiitaのMarkdown方式での書き方をまとめてみます。

#目次
1. エスケープ文字
2. 引用
3. 見出し
4. 改行
5. 文字修飾
6. コードの挿入
7. リンク

#エスケープ文字
エスケープ文字は"\"（バックスラッシュ）
Markdown方式での特殊文字（"#"など）を
通常の文字として扱う際に使う。

\\#鬼滅の刃

と書くと

\#鬼滅の刃

と表示される。

#引用
文の先頭に">"をつけると引用になる。

\>私が引用です

と書くと

>私が引用です

と表示される。
<br>

\>私が引用です
\>>私が引用の引用です

と書くことで、引用in引用も可能

>私が引用です
>>私が引用の引用です

#見出し
文の先頭に"#"をつけると見出しになる。

\#見出しだよ

と書くと

>#見出しだよ

と表示される。

"#"の数で、見出しの大きさを調整できる。
"#"が多いほど小さくなる。

\#見出しだよ
\##見出しだよ
\###見出しだよ

と書くと
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

>#見出しだよ
>##見出しだよ
>###見出しだよ

<br>


ちなみに引用と合わせて

\>#見出しだよ

と書いている。

#改行
\<br>を書くことで、改行できる。
行末に半角スペース2つでもできるが、
可読性が落ちる。

line1
\<br>
line3
\<br>
\<br>
line6

と書くと

line1
<br>
line3
<br>
<br>
line6

と表示される。

#文字修飾
文字を"_"（アンダースコア） or "*"で括ると
イタリック体になる。

文字を"__"（アンダースコア2つ） or "**"で括ると
太字になる。


\*itaric*
↓
*itaric*

\**太字**
↓
**太字**


#コードの挿入
コードを"```"（バッククォート3つ）で括ると、
コードが挿入できる。

\```
\# hostname
host01
\#

\```

と書くと、

```
# hostname
host01
#
```

と表示される。
ここで、#は特殊文字として扱われないので
エスケープ（\）は不要

#リンク
あとは下記のリンクから随時確認。

>[Qiita公式Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
【Azure】Azure LearnのWordPress Web サイトを作成するをやってみた

#はじめに
執筆者は元々AWSを勉強していたのだが、諸事情でAzureを勉強する必要が出て来た。Azureに関する記事がAWSより少ないと思うので、Azure Learnでやったことをスクリーンショット共に備忘録として残したい。

#手順
[Azure の基礎 第 1 部:Azure の主要概念に関する説明 >Azure アーキテクチャのコア コンポーネントを説明する>演習 - Azure でホストされる Web サイトを作成する](https://docs.microsoft.com/ja-jp/learn/modules/azure-architecture-fundamentals/exercise-create-website)を今回教材として使用した。
リソースの作成を選択する。
![スクリーンショット 2020-11-22 10.44.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/7c95e56a-71b1-b084-2be9-42be76590330.png)
検索ボックスにWordPressを入力する。
![スクリーンショット 2020-11-22 10.12.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/4349bc01-f2ab-00b4-c8b8-16dc154d702f.png)
WordPressの画面に移ったら、作成を選択する。
![スクリーンショット 2020-11-22 10.13.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/8371e5ab-48c2-9a31-88d9-13d8328282b6.png)
今回は構成を以下のようにする。
データベース プロバイダー : [MySQL in App] とする。
その後、App Serviceプラン/場所を選択する。
![スクリーンショット 2020-11-22 10.16.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/7afc1c4d-d07d-f850-27b5-27499caaef6a.png)
App Serviceプランに自動で移るので、新規作成を選択する。
![スクリーンショット 2020-11-22 10.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/64b38b6f-eab2-0668-2b48-bf3396840050.png)
新しいApp Serviceプランに好きな名前を入力する。
場所を適宜設定する。
価格レベルを押下する。
![スクリーンショット 2020-11-22 10.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/5c26a712-8d63-af7d-cb85-5a1cc5c6edc8.png)
スペックの選択画面に移るので、開発/テストを選択する。
![スクリーンショット 2020-11-22 10.19.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/308ee639-b9eb-2bb6-82a2-034a1a85f98d.png)
F1レベルを選択し、適用を選択する。
![スクリーンショット 2020-11-22 10.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/0b5533a8-1bc3-c10d-cf3c-3d752ed5251f.png)
新しいApp Serviceプランに自動で戻るため、OKを選択する。
![スクリーンショット 2020-11-22 10.21.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/bd1b891d-38eb-666a-ecd3-825e9820b636.png)
自動で作成画面に戻るので作成を選択する。
![スクリーンショット 2020-11-22 10.22.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/bd133892-161a-ae3f-f142-d717d57c9b3e.png)
展開が成功したらリソースに移動を選択する。
![スクリーンショット 2020-11-22 10.32.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/998fc0d3-59e8-7b06-ff04-fd88c3135a7b.png)
リソースに移動を選択する。
![スクリーンショット 2020-11-22 10.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/e85f179f-27c7-345f-336e-aaf4994d9e44.png)
URLを押下する。
![スクリーンショット 2020-11-22 10.33.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/a98c0523-83bb-cfc0-9957-5f78670d37be.png)
WordPressサイトが表示されていることを確認する。
![スクリーンショット 2020-11-22 11.20.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/b855ac57-0f6d-3619-db45-5e9bb6489453.png)
AWS Amplifyで環境変数を設定し、Reactアプリで読み込む

GitHubなどからWebアプリのCI/CDができるAWS Amplifyですが、
今回は環境変数の設定方法と、AmplifyでホストしているReactアプリから読み込む方法を備忘録として残しておきます。
（あと以外と日本語のドキュメントがなかった）

ReactなどのWebアプリでは.envファイルなどに環境変数を定義しておいて、
`process.env.{任意の名前}`で読み込むことがあると思いますが、
認証情報などを記載している場合はソース管理には載せられませんし、Amplifyで環境変数を設定して読み込む必要があります。

ちなみにAmplifyではバックエンドの構築も可能ですが、環境変数の利用はフロントエンドのみのアプリでもできます。
ちょっとしたフロントエンドだけのアプリ作って環境変数の読み込みだけしたい場合、Amplify CLIを使ったバックエンドの構築などはせずに環境変数の設定、利用が可能です。

# 環境変数の設定
### 環境変数の登録
Amplifyで環境変数を定義するにはまずAWS ConsoleでAmplifyのページに飛び、
サイドメニューから「環境変数」を選択します。
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/b3ba146e-4cff-45c4-8a1a-790323e6b9c4.png)

環境変数のメニューが開くので「変数の管理」から変数の登録・編集ができます。
今回はReactアプリで読み込むので`REACT_APP_`を変数名にプレフィックスとしてつけておきます。
また、複数ブランチをホストしている場合には、ブランチごとに変数を設定することが可能です。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/9247b00f-85ee-6cb6-e047-5ff7d6b1b38e.png)

### ビルドの設定
続いてメニューから「ビルドの設定」を選択し、以下の画面を開きます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/2e948b99-8ab3-2229-ded1-b4379bf075a9.png)
ここではデプロイ時のビルドの設定をyaml形式で定義することができるので、ここで環境変数のエクスポートをします。
buildのcommandsに↓こんな感じで書いておきます。
出力するパスはアプリに応じて変更します。今回はルートに書きだしています。

```
echo "REACT_APP_HOGE=$REACT_APP_HOGE" >> .env
```

### アプリからの読み込み
あとはアプリから

```
process.env.REACT_APP_HOGE
```
で読み込めば完了です。


# 参考
[Environment variables - AWS Amplify](https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html)
M5StickVの環境作成

Win10のWSLの環境で作成します

「ファームウエアビルド環境」と「学習データファイルの作成環境」の２つの環境を作成します
（同じ、WSLの環境では動作しなかったので、別のWSL環境を作成します）

WSLは通常同じディストリビューションは１つの環境しか作れませんが、２つ作成してそれぞれ別に環境作成します


# WSLのインストール
Cドライブにインストールしたくないので、Microsoft Storeを使わず、下記のページを参考にUbuntu 18.04をダウンロード

[Windows Subsystem for Linux (WSL) を好きな場所でインストールする](https://phst.hateblo.jp/entry/2020/01/18/000000)

# ２つのWSL環境を作成
下記ページを参考にしました

[【WSL 2】1つのディストロから複数のインスタンスを作成する方法](https://laboradian.com/multi-instances-from-distro-on-wsl2/)

作成したUbuntu-18.04の環境をエクスポートして、インポートを２回行うことで、環境を２つ作成します。
最後に元の環境を削除します

```
wsl --export Ubuntu d:\Ubuntu-18.04.tar
ws --import M5StickV-FW D:\Ubuntu-18.04\M5StickV-FW D:\Ubuntu-18.04.tar
wsl --import M5StickV-LRN D:\Ubuntu-18.04\M5StickV-LRN D:\Ubuntu-18.04.tar
wsl --unregister Ubuntu-18.04
```

WSLの起動は、下記のコマンドです

```
wsl -d M5StickV-FW -u ユーザ名
```

```
wsl -d M5StickV-LRN -u ユーザ名
```


# ファームウエアビルド環境作成
下記のページを参照
[M5StickVのファームウェアビルド手順](https://raspberrypi.mongonta.com/howto-build-firmware-of-m5stickv/)

WSL環境からWin環境へのファイルコピーは
> /mnt/{ドライブ名}からアクセスできます。cドライブの場合は、/mnt/cです

# 学習データファイルの作成環境作成
下記のページを参照
> メモ
・WSLのシャットダウンは「wsl --shutdown」（複数WSL起動していると全部シャットダウンされます）
・condaのインストール後「source ~/.bashrc」を行う
・学習前に「pip install 'h5py<3.0.0'」を行う

[M5StickVやUnitVで使えるkmodelファイルをローカル環境で作成する。](https://raspberrypi.mongonta.com/howto-make-kmodel-on-ubuntu/)

このページも参照
[#M5StickV でお顔認証する手順](https://qiita.com/nnn112358/items/ef3435d113c03d44d574)


# Jupyter Notebookの環境作成
環境作成

```
mkdir ~/jupyter
cd jupyter
conda create -n "jupyter" python=3.7
conda activate jupyter

conda install jupyter
conda install tensorflow
conda install keras

conda install Pillow
conda install matplotlib
conda install scikit-learn
conda install pytz
conda install seaborn
```

Noteブックの起動

```
jupyter notebook --no-browser --port=8080 --ip=0.0.0.0
```
Mendeley 上の論文読者数をPythonで取得する

# はじめに
研究者の方々は、目にした/書いた学術論文の引用数が気になることがあると思います。
引用数はGoogle scholar 等で簡単に確認することができます。
引用数の前駆的な指標として、文献管理ソフトMendeley における読者数というものもあります。
こちらは少なくとも、Mendeleyを開かなければわからないように思えます。
そこで、スクレイピングの練習がてら、Mendeley reader 数を取得するスクリプトを作成してみました。

# 参考にした記事
[1] [pythonでwebスクレイピング](https://qiita.com/pontyo4/items/264b03d1f718fb55eb08)
[2] [Webスクレイピングの注意事項一覧](https://qiita.com/nezuq/items/c5e827e1827e7cb29011)

# 環境
Windows 
Python 3

# スクリプト

全文は以下の通りです。
以下解説が続きます。

```a.py
# Modules
import requests

# Constants
Mendeley = 'https://www.mendeley.com/catalogue/'
PaperID = []
PaperID.append("5a856ac7-0d75-3560-8824-9f9061f3eb50/")

# Functions
def SandwitchedText(text_source,text_1, text_2):
    return text_source.split(text_1)[1].split(text_2)[0]


for a in PaperID:
    r = requests.get(Mendeley + a)
    text = r.text

    print("Title : " + SandwitchedText(text, "\"title\":\"", "\",\"detail"))
    print("readers : " + SandwitchedText(text, "readers:", ":"))
    print("citations : " + SandwitchedText(text, "citations:", ":"))
```
- requests はスクレイピングに使えるパッケージです[1]。使用時はスクレイピングのルールに注意しましょう[2]。
- データを取得したい論文の情報として対応するURLを与えます。本記事では、有名な[高温超伝導の論文](https://www.mendeley.com/catalogue/5a856ac7-0d75-3560-8824-9f9061f3eb50)を題材とします。スクリプト中変数Mendeleyの部分は固定で、URLのうち論文ごとに異なる部分をPaperIDのリストに与えてゆきます。
- SandwitchedTextとして、与えられた文字列text_sourceからtext_1, text_2で挟まれた部分を返す関数を定義しています。
- requests.get(_url_).text でURL に対応するページのソースを得ることができます。スクリプトでは、textの中にソースが文字列として格納されます。
- 最後に、ページのソースから、論文のタイトル、mendeley reader 数、引用数を取得、コンソールに出力します。ここで、ページのソースとにらめっこして、ソース中どこに必要な情報があるかを探し、SandwitchedText関数を使って情報を取得します。

# 終わりに
リスト内の論文の数を増やしていけば、いくつかの論文の情報をまとめて得られます。
論文のURLではなく、タイトルを与えられるともう少しスマートだと思います。
【Java】変更に強いコード追加編 - Validation 機能


#もっと！変更に強いコードを目指す
* 前回の
[【Java】変更に強いコード実践編 - 値オブジェクト2（Value Object）](https://qiita.com/suema0331/items/4ea28b7dde8d736c0c2e)
では、<br>**Valueオブジェクトを使ってタイポがない、凡ミスがないコードにしよう**o(^^)o
* ということで、建物の緯度経度を表すBuildeingクラスを作りました
* Valueオブジェクトで型を指定することで、Buildingに渡す引数の順番間違え（Latitude、Longitudeの順番）を防止できました👍

##Validation機能追加
* さらに堅牢なコードを目指し、LatitudeにLongitudeの値(139.761102f)を入れてしまうことを防ぎたい。。。
* 値オブジェクトの初期化時に間違った実値を渡してしまう事を抑止するのは**Validation機能**で行うことができます

```java
new Latitude(139.761102f),
new Longitude(35.663114f)
```

* Latitudeクラスを以下のように変更したら、**範囲外の値を入力した時に実行時例外を出す**ことができるので、**さらに堅牢なコード**になりますね⭐️o(^o^)o
* 構成は以下のようになっています

```
Project Root
└─src
    └─ main
        └─ java  
            └─ Main
        └─ values
            └─ Building
            └─ Building2
            └─ BuildingName
            └─ Longitude
            └─ Latitude
            └─ Main
```

* 他の全コードは前回の<br>
[【Java】変更に強いコード実践編 - 値オブジェクト2（Value Object）](https://qiita.com/suema0331/items/4ea28b7dde8d736c0c2e)<br>
参考にしてください

```Latitude.java
package values;

public class Latitude {
    private float value;
    public Latitude(float value) throws Exception {
        if(value < -90 || 90 < value ){
            throw new Exception("Out of Range");
        }
        this.value = value;
    }

    public float getValue() {
        return value;
    }
}
```


```Main.java
package values;

public class Main {

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

        Building mitaka = new Building(
                new BuildingName ("三鷹の森"),
                //fつけないとリテラルとして認識されない
                new Latitude(35.6962303f),
                new Longitude(139.5704895f)
        );

        /*緯度と経度の値を逆にしてしまった場合にValidationが効いて実行時エラー
           Exception in thread "main" java.lang.Exception: Out of Range
         */ 
        Building totoro = new Building(  
                new BuildingName ("トトロの森"),
                new Latitude(139.4219994f), 
                new Longitude(35.7818004f)
        );

        /*緯度と経度の引数順を間違えてしまった場合はコンパイルエラー
        Building totoro = new Building(
                new BuildingName ("トトロの森"),
                new Longitude(139.4219994f),
                new Latitude(35.7818004f)
        );
         */

        /*コンパイルエラーにならない例
        Building2 totoro2 = new Building2(
                "トトロの森",
                139.4219994f,
                35.7818004f
        );
         */

        System.out.println("pause");
    }
}

```

実行時エラーでミスを未然に防げますね〜
![実行時.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/2e7b1f2c-9598-04dc-f859-191e91f901c4.png)
本番環境のコマンドを開発環境で実行してしまった場合の対処

#はじめに
今回は本番環境で行うコマンドを間違って開発環境で実行してしまいエラーが発生してしまったのでそうなってしまった理由や原因を調べていきます。

##やってしまったこと
AWSでEC2のサーバーを立ち上げるために以下のコードを誤って開発環境で実行してしまった...

```
$ bundle install --path vendor/bundle --without test development
```

そこから`bundle install`やサーバーを立ち上げようとするとエラーが発生するようになりました。

bundle installで`Nokogiri`がインストールできないエラー

```
Gem files will remain installed in
/home/vagrant/work/SMB/vendor/bundle/ruby/2.5.0/gems/nokogiri-1.10.9 for inspection.
Results logged to
/home/vagrant/work/SMB/vendor/bundle/ruby/2.5.0/extensions/x86_64-linux/2.5.0/nokogiri-1.10.9/gem_make.out

An error occurred while installing nokogiri (1.10.9), and Bundler cannot
continue.
Make sure that `gem install nokogiri -v '1.10.9' --source 'https://rubygems.org/'`
succeeds before bundling.

```

# 何が行われてしまったのか？

```
$ bundle install --path vendor/bundle --without test development
```

このコマンドで`bundle install`でオプションを付けている

* `--path`でインストール先をいつものパスではなくて指定したパスのディレクトリにインストールをしている(`vendor/bundle`)
rubyは`rbenv`ファイルにインストールをしなければいけないのに`vendor/bundle`にインストールをしてしまっている

*  `--without`(意味：除外します/抜きにする）
今回だと`test development`を除外します
development(開発）環境なのにインストールしないのはマズい...



`bundle install`に一回でもオプションをつけると`bundle`ファイルがずっと覚えていてくれるのでずっとそのオプションになってしまう


####原因！
`bundle install`にオプションを付けてしまったのが原因

#解決策

###bundleファイルの中身を修正

![スクリーンショット 2020-11-22 10.50.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752006/e570ad1a-dffb-5331-dd24-5502b8761f29.png)

`.bundle/config`ファイルの中が先ほど`bundle install`した際のオプションが入っているのでそこを修正。

修正前

```
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_WITHOUT: "test:development:production"
```

修正後

```
---
BUNDLE_WITHOUT: "production"
```

これでまたうまく動くようになりました！

# 最後に
エラーが出た時はかなり焦りましたがしっかりしてしまったことを理解することが大事だと思いました。

またコマンド一つ一つが何をしているのか把握していくのが大事だと改めて知る機会になりました。
node.jsで簡易ftpサーバーを立てる(Qemu用)

## 概要

Qemuではフォルダ共有機能が実質存在しないので、ゲストOSからホストのファイルにアクセスするためのftpサーバーをnode.jsでサクッと構築する。

## パッケージのインストール

```
npm install ftpd
```

## ソース

```ftpd.js
var ftpd = require('ftpd');
var fs = require('fs');
var path = require('path');

//コマンドライン引数からポートとルートになるフォルダの設定
var port = process.argv[2] || 10021;
var root = process.argv[3] || process.cwd();

//サーバーの設定
var server = new ftpd.FtpServer('127.0.0.1', {
  //接続後の初期ディレクトリ
  getInitialCwd: function() {
    return '/';
  },
  //ルートとなるフォルダの設定
  getRoot: function() {
    return root;
  },
  pasvPortRangeStart: 1025,
  pasvPortRangeEnd: 1050,
  tlsOptions: null,
  allowUnauthorizedTls: true,
});

//エラー
server.on('error', function(error) {
  console.log('FTP Server error:', error);
});

//クライアントが接続してきたら認証(してるフリ)
server.on('client:connected', function(connection) {
  var username = null;
  connection.on('command:user', function(user, success, failure) {
    if (user) {
      username = user;
      success();
    } else {
      failure();
    }
  });

  connection.on('command:pass', function(pass, success, failure) {
    if (pass) {
      success(username);
    } else {
      failure();
    }
  });
});

//コンソールへの出力を最低限に
server.debugging = 0;

//指定したポートでサーバー起動
server.listen(port);
console.log('Listening on port ' + port);
```

## 起動

```
node ftpd.js 10020 x:\Documents
```

## Qemuからアクセス

(特に設定をしていなければ)IPアドレス```10.0.2.2```でqemuのゲストからホストのサーバーにアクセスできるようです。
ssh,scpコマンドについて

<h1>sshについて</h1>

暗号化された通信でリモート接続するLinuxコマンド
SSHはSecure Shellの略。

コマンド使い方→ ssh [オプション] ホスト名(IP) 又は　ssh ユーザID@ホスト名
 

<h4>サンプルコード</h4>

```
$ ssh 111.222.333.444(IPアドレス)
$ shh sample.com(ホスト名)
```


<h1>scpについて</h1>

sshと同じく、暗号化された状態でリモート接続をし、コピーができるLinuxのコマンド。

コマンド使い方→ scp [オプション] コピー元　コピー先

基本的にはLinuxのcpコマンドと同じような使い方になります。


<h4>サンプルコード</h4>
```
$ scp copy.txt(コピー元) username@copy.file.com:/remote/directory(コピー先ディレクトリー)
```
Steinを使って名前マスタから情報を取得するメモ

名前の登録があれば設定、なければ登録を促す処理
ユーザIDをもとにユーザ名を取り出す処理。

```javascript
function getUserName(userId){
    let userName ; 
    userName = store.read("name_master", { search: { user_id: userId } }).then(data => {
        console.log(data);
        let uName;
        console.log(data.length);
        if(data.length === 0 ){
            uName = "";
        }else{
            uName = data[0].user_name;
        }
        console.log(uName);
        //1行しか取れないので1つ目のユーザ名を指定
        return uName;
    
    });
    return userName;
}
```
FlutterをVSCodeで使う際のシミュレータまわりのメモ

![スクリーンショット 2020-11-21 21.56.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242610/4c49c7cf-8b4e-8cdc-27cb-3bfbd67e3222.png)

右下は`Chrome (web-javascript)`, 左上は`Dart & Flutter`.

Web Server というデバイスは本番環境用のビルドで使う？

`fn`+`F5`でRunするのと、TERMINALで`flutter run -d chrome`するのは別行為

`flutter run`だけするのもまた違う行為。`Multiple devices found`となるのは`-d`を指定していないから。

```terminal
$ flutter run
Multiple devices found:
Web Server (web) • web-server • web-javascript • Flutter Tools
Chrome (web)     • chrome     • web-javascript • Google Chrome 87.0.4280.67
[0]: Web Server (web-server)
[1]: Chrome (chrome)
Please choose one (To quit, press "q/Q"): 
```

ブラウジングで使うChromeとシミュレーターとして起動するChromeは別物にできる
【JavaScript】JavaScrpitにおけるAND条件とOR条件について


##JavaScriptにおけるfalsyな値

falsyな値とは、Booleanで変換した際にfalseが返る値


- false
- null
- 0
- 0n(bigint)
- ""
- undefined
- NaN

```ex.js
let a = 0;
console.log(Boolean(a));

//false
```

##JavaScriptにおけるtruthyな値

truthyな値とは、Booleanで変換した際にtrueが返る値

- falsy以外


##変数に値が設定するか確認する場合。

```.js
if (a) {
  console.log("set")
  }
```
この場合、変数aがnullや""の場合、setが出力されないため判定できる。
ただし、0 が格納されていた場合は、falseと判定されるので、setは出力されない。

##AND条件の動き
左の式から判定していき、falsyな値が出現した場合、返す。(以後の式は実行されない）
全てtruthyな場合は最後の式を返す。

```.js
const a = 1;
const b = 2;
const c = 0;

console.log(a === 1 && b === 3);
//a === 1 => true
//b === 0 => false
//出力：false
console.log(a === 1 && b === 2);
//a === 1 => true
//b === 2 => true
//出力：true
console.log(a && b);
//a  => true
//b  => true
//出力：2
console.log(a && c && b);
//a  => true
//c  => falsyな値
//出力：0
```

##OR条件の動き
AND条件と逆。
左の式から判定していき、truthyな値が出現した場合、返す(以後の式は実行されない）。
全てfalsyな場合は最後の式を返す。

```.js
const a = 1;
const b = 2;
const c = 0;

console.log(a === 1 || b === 3);
//a === 1 => true
//出力：true
console.log(a === 5 || b === 5);
//a === 1 => false
//b === 2 => false
//出力：false
console.log(a || b);
//a  => truthy
//出力：1
console.log(c || a || b);
//c  => falsy
//a  => truthy
//出力：1
```

ちなみに

```.js
let a = "a";

a && console.log("b");

//bが出力される。

let a = 0;

a && console.log("b");

//bは出力されない。（aがfalsyであるため、console.logは実行されない。)
```
Mac ターミナルからコマンドでファイルをzip化する

# 目的

- Macのターミナルでファイルをzip化するコマンドをメモ的にまとめる。

# 前提情報

- 筆者のMacはシェルをbashに切り替えている

# 詳細

1. ファイルをzip化するときは下記コマンドを実行する。

    ```terminal
    $ zip zip化したファイルの設置場所とzipファイル名 zip化するファイル
    ```
1. ディレクトリをzip化するときは下記のコマンドを実行する。

    ```terminal
    $ zip -r zip化したディレクトリの設置場所とzipファイル名 zip化するディレクトリ
    ```