OmniAICreator/Qiita-1.07M huggingface dataset:
Connecting to Beagle Bone Black with USB on Windows10 in 2020

初カキコ…ども…

俺みたいな2020年にもなってBBBで機体制御する腐れ野郎、他に、いますかっていねーか、はは

︙

Beagle Bone Blackは2013年に発売された俗にいうシングルボードコンピュータ。
みんなは普通にラズパイを使うのでしょう実際そっちのほうが性能いいし安いし文献いっぱいあるし。
でもGPIOがいっぱいあっていいやつなんですよ、こいつ。

前話はともかく現状Windows10でこいつにUSBでつなごうとするとLAN over USBドライバが必要なんだけどデフォでついてくるドライバは署名がされていないので入れられない。
ブートオプションで署名なしドライバでもインストールするようにすることで回避できるが、今回は別の回避法を見つけたので紹介する。


# デバイスドライバでRNDISデバイスを探しドライバをインストール
章タイトルの通りデバイスドライバを開き、ドライバが当たっていない`RNDIS`となっているデバイスを探す。
そしてドライバの更新ボタンを押し、`コンピュータを参照～`をクリック。下の画像のタイトルが違うのはインストール後に撮影したから。
![スクリーンショット 2020-10-09 000003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703910/5c6b25e8-37c5-9822-6301-790a8036d975.png)

1. `コンピュータ上の～`ボタンをクリック
2. 製造元`Microsoft`、モデル`リモートNDIS互換デバイス`で`次へ`をクリック。
![スクリーンショット 2020-10-09 000322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703910/c03ca4e1-18c7-8f8f-079f-61dc4db28544.png)

3.「不安定になる～」というような警告が出るが、無視する。

4.Finish!!!192.168.7.2で接続できるはずでしょう！！！


# 参考文献
[[BBG]BeagleBone GreenのWindows10 RNDISドライバ](https://hiro99ma.blogspot.com/2018/03/bbgbeaglebone-greenwindows10-rndis.html) - hiro99ma blog

[How to install Microsoft RNDIS driver for Windows 7](https://developer.toradex.com/knowledge-base/how-to-install-microsoft-rndis-driver-for-windows-7) - Toradex
【Azure移行】PostgreSQL マイグレーション フローチャート

#はじめに
オンプレミス環境上の PostgreSQL を使用したシステムを Azure へ移行することを検討する場合、Azure上で選択可能な PostgreSQL 関連リソースの種類が多く、どのデータベース リソースを選択すべきか、悩まれる方がいるのではないかと思います。
今回、ありそうであまり見かけない、Azure移行に向けた**「PostgreSQL マイグレーション フローチャート」**を作成してみました。

#目次
[1. Azureで選択可能なデータベース](#1-azureで選択可能なデータベース)
[2. PostgreSQL マイグレーション フローチャート](#2-postgresql-マイグレーション-フローチャート)
[3. 最後に](#3-最後に)
[4. 参考情報](#4-参考情報)

#1. Azureで選択可能なデータベース

Azureで選択可能な PostgreSQL 関連リソース一覧をまとめてみます。
※ 本記事は、オンプレミス環境で PostgreSQL を使用している想定で記載しています。

|種類|デプロイ モード|サービスレベル|簡易説明|
|:-:|:-:|:-:|:--|
|PostgreSQL on Azure 仮想マシン|-|-|Azure 仮想マシン上に PostgreSQL をインストールする構成。ゾーン冗長を考慮した構成にするためには、PostgreSQLがインストールされたAzure 仮想マシンを各アベイラビリティ ゾーンに配置し、各PostgreSQL間で **ストリーミング レプリケーション**を構成する必要があります。また、障害発生時のリカバリプランをオンプレミス環境と同様に考慮する必要がある。|
|Azure Database for PostgreSQL|単一データベース|仮想コア|使用可能なCPUリソースを予約。価格レベルとして「**Basic**」,「**汎用目的**」,「**メモリ最適化**」を選択することが可能。サービスエンドポイント、プライベートリンクを経由したプライベート通信によるアプリケーションからのアクセスを実施する必要がある場合は、「**汎用目的**」もしくは「**メモリ最適化**」を選択する必要がある。|
|Azure Database for PostgreSQL|フレキシブル サーバー(プレビュー)|仮想コア|現時点にてプレビュー機能であるが、Azure Database for PostgreSQLで唯一ゾーン冗長を構成することが可能。価格レベルでは「**汎用**」,「**メモリ最適化**」の他に、「**バースト可能**」が用意され、選択可能な仮想コアは最大2個しか選択することができないが、継続的に最大のCPUリソースを必要としない場合、突発的なトラフィック増加に対応しつつコストを削減することが可能。また、一時的な**停止機能** (最大停止期間 : 7日間) により、ストレージ以外の課金の発生を抑え、コストを削減することが可能。|
|Azure Database for PostgreSQL|ハイパースケール (Citus)|仮想コア|シャーディングを使用して複数のマシン間でクエリを水平にスケーリングすることが可能。大規模データベースに対する応答を迅速化するため、サーバー間でクエリを並列で実行するなど、**リアルタイム分析**や**高スループットのトランザクション ワークロード**に最適なデプロイモード。
※ **Azure Database for PostgreSQL フレキシブル サーバー／ハイパースケール (Citus)** の両デプロイモデルでは、**Azure Database for PostgreSQL 単一サーバー (汎用目的／メモリ最適化)** と同様に、サービスエンドポイント、プライベートリンク、VNET統合などを使用したプライベート通信によるアプリケーションからのアクセスが可能になっている。

#2. PostgreSQL マイグレーション フローチャート
![Azure_Migration_SQL2-フローチャート-20201005-PostgreSQL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752487/01e427f4-264e-2842-0473-48747cf64f7a.png)


#3. 最後に
今回、PostgreSQL マイグレーション フローチャート を作成してみました。
このフローチャートは完璧なものではないと思いますので、アドバイスをいただければ、ブラッシュアップしていこうと思います。



#4. 参考情報
・[サービス レベル アグリーメント](https://azure.microsoft.com/ja-jp/support/legal/sla/)
・[Azure Database for PostgreSQL - Single Server](https://docs.microsoft.com/ja-jp/azure/postgresql/concepts-servers)
・[Azure Database for PostgreSQL - フレキシブル サーバー](https://docs.microsoft.com/ja-jp/azure/postgresql/flexible-server/overview)
・[Azure Database for PostgreSQL - Hyperscale (Citus) とは](https://docs.microsoft.com/ja-jp/azure/postgresql/hyperscale-overview)
【Go 1.13】unexpected directory layout:がでた時の対処

---
### 追記
コメントにて指摘いただきました。`go mod`コマンドを用いると、`go mod init モジュール名`で指定したモジュールからインポートできることが確認できました。

```go
$ go mod init hoge

---main.go
package main

import "hoge/sample"
|
（省略）
---
```

これで動くと思います。

---

 Goにて開発をしていて、ファイルを用いてパッケージを分けようとしたら起きたエラー。
とりあえず解決したので、すぐさまメモ。。。


## 環境

```
バージョン
go version go1.13.14 linux/amd64
centos 7

ディレクトリ構造
./
 |
 |--sample/
 |       |
 |       |--sample.go
 |
 |--main.go

```

## 実際のコード

```go:main.go
package main

import "./sample"

func main() {
	a := sample.Foo("test")
	sample.PrintFoo(a)
}
```

```go:sample.go
package sample

import "fmt"

func Foo(s string) string {
	return "aaa " + s + " bbb"
}

func PrintFoo(s string) {
	fmt.Println(s)
}
```

```
[root@marny ---]# go build -o practice
unexpected directory layout:
        import path: _/develop/go/src/test/marny/sample
        root: /develop/go/src
        dir: /develop/go/src/test/marny/sample
        expand root: /develop/go
        expand dir: /develop/go/src/test/marny/sample
        separator: /
```

## どういったエラーなのか
`unexpected directory layout:`というエラーは、どうやらimportしているパッケージのパスの指定がダメですよーというエラーらしい。

僕自身、centos7(vbox)にsambaでwindowsとつなげて編集していたので、ソースコード上でのエラーはありませんでした、、、、


## 解決
僕の場合、**$GOPATH**を`/develop/go`と指定しています。GOPATHの仕様で、binやらsrcやらを生成して、Goの開発をするのですが、ここでエラーが起きている。

どうすれば解決するか、というと、main.goのimport`./sample`を`$GOPATH/src`から見た相対パスに変更すれば、解決します。


よって、

```go:main.go
package main

import "test/marny/sample"

func main() {
	a := sample.Foo("test")
	sample.PrintFoo(a)
}
```

これで、解決すると思います。

GOPATHめんどくさいね。
flexレイアウト `display: flex`で、サクっとボタンを中央寄せする

「きれいに（かつ、ラクに）レイアウトしたいときは`flex`を覚えるといいよ。」と教わってまずはじめに覚えたやつです。

```sass:sass
.center
  display: flex
  justify-content: center
```

```haml:haml
.center
  = f.button :submit, '送信'
```
digでネームサーバの設定を確認する

```bash
% dig yoneapp.com ns

; <<>> DiG 9.10.6 <<>> yoneapp.com ns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37750
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;yoneapp.com.			IN	NS

;; ANSWER SECTION:
yoneapp.com.		3488	IN	NS	dns1.p01.nsone.net.
yoneapp.com.		3488	IN	NS	dns2.p01.nsone.net.
yoneapp.com.		3488	IN	NS	dns3.p01.nsone.net.
yoneapp.com.		3488	IN	NS	dns4.p01.nsone.net.

;; Query time: 5 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Oct 09 00:03:26 JST 2020
;; MSG SIZE  rcvd: 129
```
【k8s】pod間通信をやってみた！

# はじめに

現在、様々なサービスのマイクロサービス化が進んでいる。その際、重要になってくるの部分の一つとして、サービス間の通信が挙げられる。
また、マイクロサービスを導入していく場合、kubernetesを用いた開発がよく採用されている。

そこで、今回は、サービス間の通信の一手法として、kuberntesの最小リソースであるpod間の通信方法についてみてみる。

> サービス間の通信方法については、pod間通信の他にも,
gRPCなどの通信方法がある。


# 今回作るもの
今回はすごく簡易的なものとして、k8sのdeploymentで作成されたhttpd サーバーのpodとnginxのpodを通信してみる

### httpd

```yml:httpd_deployment.yml
apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
spec:
  selector:
    app: httpd
  ports:
  - port: 8090
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2-alpine
        ports:
        - containerPort: 80

```

### nginx

```yml:nginx_deployment.yml

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - port: 8080
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18-alpine
        ports:
        - containerPort: 80

```

# とりあえず、通信してみる
- 上でつくったdeploymentたちを起動

```
$ kubectl apply -f httd_deployment.yml -f nginx_deployment.yml 
```
- ちゃんと立ち上がったか確認

```
$ kubectl get po 

NAME                    READY   STATUS    RESTARTS   AGE
httpd-7f8bd9884-jptwt   1/1     Running   0          4m26s
nginx-d69ddfd76-r4lhq   1/1     Running   0          4m26s
```
statusが両方ともRunningになっていればok

## httpd→nginx

- httpdのpodに入る

```
$ kubectl exec -it httpd-7f8bd9884-jptwt sh
/ # 
```
- httpdのpod内からnginxのpodにアクセスしてみる

```
/ # curl http://nginx-svc:8080

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
 
```

## nginx→httpd
- nginxのpodにはいる

```
$ kubectl exec -it nginx-d69ddfd76-r4lhq sh
```
- nginxのpod内からhttpdのpodにアクセスしてみる

```
/ # curl http://httpd-svc:8090
<html><body><h1>It works!</h1></body></html>
```

アクセスできたのが確認できた。
[Laravel] seedとページネーション

## 概要

本投稿では、Laravelのseed機能とページネイトを使用し、一度に表示するデータの数の制限かけます。

## 前提条件

以下記事を参考に、CRUDの一覧画面の作成が完了していること。
https://qiita.com/Hiroto10/items/4723b96b491b1ce88278

## seed

seedとは、Laravelに標準で備わっているテストデータの自動生成を行う機能のことです。
`php artisan make:seeder`コマンドで作成することが可能です。

```
$ php artisan make:seeder TasksTableSeeder
Seeder created successfully.
```

コマンド実行後、以下ファイルが作成されていると思うので、run()メソッドにデータを挿入する処理を入れます。
今回はテーブルに100件のデータを格納します。

```database/seeds/TasksTableseeder.php
    public function run()
    {
        for ($i = 1; $i <= 100; $i++) {
            DB::table('tasks')->insert([
                'task' => 'task' . $i
            ]);
        }
    }
```

次に、`DatabaseSeeder.php`を編集し処理の呼び出しを行います。

```database/seeds/DatabaseSeeder.php
    public function run()
    {
        $this->call([
            TasksTableSeeder::class,
        ]);
    }
```

上記が完了後、以下コマンドを実行しデータの格納を行います。

```
$ php artisan db:seed --class=TasksTableSeeder
Database seeding completed successfully.
```

既存のデータも全て消去し格納する場合は以下コマンドを実行します。

```
$ php artisan migrate:refresh --seed
```

無事100件のデータが格納されていたら完了です。

## ページネーション

次に、一覧画面にページネーションの処理を加えます。
現在は以下のように100件のデータが全て表示されています。
ページネーションを加え、1ページに25件まで表示するよう修正します。

![スクリーンショット 2020-10-07 22.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497547/3289f6a1-bb4b-51c5-db2a-8f5f4a6242b8.png)


```app/Http/Controllers/TasksController.php
    public function index()
    {
        $tasks = Task::paginate(25);

        return view('tasks.index', [
            'tasks' => $tasks,
        ]);
    }
```
一覧画面に以下処理を加えることでページネーションすることが可能です。
ボタンが表示されたらページごとにデータが変わるか確認してください。


```resources/views/tasks/index.blade.php
{{ $tasks->links() }}
```

![スクリーンショット 2020-10-07 22.12.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497547/ab699dfd-b04e-4431-34bf-5cca2f98d5a9.png)

データを降順で表示したい場合は、コントローラを以下のように編集してください。

```app/Http/Controllers/TasksController.php
    public function index()
    {
        $tasks = Task::orderBy('id', 'desc')->paginate(25);

        return view('tasks.index', [
            'tasks' => $tasks,
        ]);
    }
```

---
Raspberry Pi（ラズベリーパイ）とは何か？

#Raspberry Pi（ラズベリーパイ）とは？

- イギリスのラズベリーパイ財団（Raspberry Pi Foundation）が開発する名刺ほどの小さなコンピュータ（シングルボードコンピュータ）のこと。

- もともとは教育目的で開発されたものだが、非常に軽量で安価な為、組み込みシステムにも利用されている。

- データの保存場所には主にSDカードなどの外部記憶装置を使い、OSは外部記憶装置にインストールする。

- Rasberry Piには公式のOSとして**`Raspbian（ラズビアン）`**が提供さている。RaspbianはRaspberry Pi上で動作するOSで、**Debian**をベースに作られている。（名前の「bian」の部分はDebianからきていると思われる。）

- Raspberry Pi自体には最初からOSはインストールされていない。その為、配布されているRaspbianを事前にSDカードなどの外部記憶装置へ保存した状態でRaspberry Piを起動し、必要な設定を行うことで利用できるようになる。
####※ 2020年5月に、ラズベリー財団はOSの名称を「Raspbian」から**`「Raspberry Pi OS」`**へと変更した。
【docker】データベースに接続中のセッションを強制切断する方法【Postgres】

Rails db:migrate:resetしようとしたら見たこともないエラーが出てきて少し詰まったので、ここで解決方法を共有したいと思います。

```bash:ERROR!
ERROR:  database "hoge_development" is being accessed by other users
DETAIL:  There are 1 other sessions using the database.
```

どうしてこうなったのかはググっても正直よくわからなかったのですが、どうやら他のユーザーで接続しっぱなしになってしまい、dbコンテナにアクセスできない状態になってしまったようです。

コンテナの中に入り、PostgreSQLに接続し、接続を強制削除する必要があります。

【環境】

- Rails 6.0.3
- Ruby 2.7.1
- PostgreSQL 13.0
- Node.js 10.21.0
- Yarn 1.22.5
- Bundler 2.1.4
- Redis 6.0.8
- Docker for window
- windows10 Pro

##解決手順
まず、dbコンテナに入ります。

```bash

$ docker exec -it hoge_db_1 bash
root@xxxxxaf78adb:/#
```
コンテナに入ったら、PostgreSQLに接続します。

```bash

root@xxxxxaf78adb:/# psql -U postgres
```
PostgreSQLに接続したら、接続中のユーザのpidを以下のコマンドで表示します。

```bash

postgres=# SELECT pid FROM pg_stat_activity where pid <> pg_backend_pid();

  pid  
-------
144
29
28
27
(4 rows)
```
↑で4つ出てきたので、以下のコマンドを順番に一個づつ実行して全て切断します。

```bash

SELECT pg_terminate_backend(144);
 pg_terminate_backend 
----------------------
 t
(1 row)

SELECT pg_terminate_backend(29);
 pg_terminate_backend 
----------------------
 t
(1 row)

(省略)
```

これを行い、コンテナから出て```docker-compose exec web rails db:migrate:reset``` したら無事通りました！

しかし、調べても何故他のユーザーが接続中になってしまったのか不明なので、もしわかる方いましたらコメントいただけますと幸いです！！

##最後まで読んでいただきありがとうございます！
ほぼ毎日、個人開発する中で詰まったことをアウトプットしています。ご指摘などあればコメントいただけますと嬉しいです！
ローカルでCircleCI CLIをつかってみる

# はじめに
CircleCIの動作確認を毎回Web上でポチポチ確認していましたが，ローカルで実行やバリデーションが出来ないのか気になり，調べたところ，CircleCI CLIがありました．
[公式doc](https://circleci.com/docs/ja/2.0/local-cli/)によると，
>CircleCI CLI は、CircleCI の高度で便利なツールの多くを、使い慣れた端末から利用できるコマンドライン インターフェイスです。 CircleCI CLI を使用すると、以下のような作業が行えます。
* CI の設定ファイルのデバッグとバリデーション
* ローカルでのジョブの実行
* CircleCI API のクエリ
* Orbs の作成、パブリッシュ、表示、管理

とのことで，なんか良さそうです．


# インストール

[公式doc](https://circleci.com/docs/ja/2.0/local-cli/#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)をみて入れます．Dockerなりご自由に使って環境を用意してください．curl,homebrew,Snapを用いてインストールができます．

本記事の作者は以下のバージョンで行っています．

```zsh

❯ circleci version 
0.1.10656+c7c1710 
```

インストールができたら，CircleCI の [API トークンを生成します](https://app.circleci.com/settings/user/tokens)． トークンを取得したら、以下を実行して CLI を構成します.

```bash
❯ circleci setup
```

APIトークンをペーストしましょう．

# やってみる
テスト用に以下のymlファイルを作成しました．実行するとgolangのversionを示す簡単なものです．

```yml:config.yml
version: 2.1
jobs:
  build:
    docker:
      - image: circleci/golang:1.15
    steps:
      - run:
          name: echo go version
          command: go version

```

## バリデーション
コマンドは`circleci config validate` 使用します．

* 構文が正しい場合

```zsh
❯ circleci config validate
Config file at .circleci/config.yml is valid.
```

* 構文が不正な場合

```zsh
❯ circleci config validate
Error: Unable to parse YAML
mapping values are not allowed here
 in 'string', line 9, column 18:
              command: go version
                     ^
```

## ジョブの実行


`circleci local execute --job JOB_NAME` でジョブ実行できます．


```bash
❯ circleci local execute

(いろいろ省略)

go version
go version go1.15 linux/amd64
Success!
```

## 注意点(2020/10現在)

circleciを使用してジョブをローカルで実行できるのは非常に便利ですが，[いくつかの制限事項があります](https://circleci.com/docs/ja/2.0/local-cli/#%E3%83%9E%E3%82%B7%E3%83%B3%E4%B8%8A%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%86%85%E3%81%A7%E3%81%AE%E3%82%B8%E3%83%A7%E3%83%96%E3%81%AE%E5%AE%9F%E8%A1%8C)


* ローカル ジョブでは Machine Executor を使用できない．

* add_ssh_keysを使用してSSHキーを追加できない．

* workflowが使えない
CLI ツールでは、ワークフローの実行がサポートされていません。 基本的にワークフローは、複数のマシンで行うビルドの並列実行を活用することによって、高速で複雑なビルドを可能にします。 CLI はユーザーのマシンでのみ動作するため、単一の jobs (ワークフローを構成する一要素) しか実行できません。

* キャッシュが使えない
現在、ローカル ジョブではキャッシュがサポートされていません。 設定ファイルに save_cache ステップまたは restore_cache ステップが含まれている場合、circleci では該当のステップがスキップされ、警告が表示されます。

* checkoutのリポジトリ
Web上でジョブの実行をするとgithubのリポジトリから取得するが，CLIではローカルにあるリポジトリから取得してくる．

* Web上で設定していた環境変数は使えないので引数で与える
セキュリティ上の理由から、UI で構成した暗号化環境変数は、ローカルのビルドにはインポートされません。 代わりに、-e フラグを使用して CLI に環境変数を指定できます。 (例: circleci build -e VAR1=FOO -e VAR2=BAR)


# おわりに

Web版に比べて，いくつか制限がありますが，簡単なジョブの実行やバリデーションチェックは手軽に行えることが分かりました．キャッチアップや検証環境のためには使えるのではないでしょうか．
個人的にはworkflowはサポートして欲しかったですが，言われてみればローカルマシン上では厳しいのでしょうね...
python3 manage.py makemigrations　にて　No changes detected　と表示される場合

マイグレーションを行う際以下のコマンドを使用するが

```
python3 manage.py makemigrations
```
このコマンドを使用すると失敗する

```
hoge@:huga/project$ python3 manage.py makemigrations
No changes detected
```


一番親のプロジェクトにあるsettings.pyに子のプロジェクトを追加したことを知らせていない事が原因でした。

```python:settings.py
INSTALLED_APPS = [
  'django.contrib.admin',
  'マイグレーションフォルダがある作成したプロジェクト名を追加'
]
```

上記追加することで無事にinitial.pyが作成されました。
初歩的な事で、調べても中々出てきませんでした。
エラー内容も表示されないのでわかりにくかったですね。
if文と論理演算子を組み合わせたときに気をつけたいこと

##はじめに
　if文と論理演算子を組み合わせたときに、気をつけるべき点があったので、まとめておく。

##基本的な記述

```ruby
if 条件式
 #条件式がtrueのときの処理
else
 #条件式がfalseのときの処理
end
```
##論理演算子

＆＆→かつ
||→または

##if文と論理演算子の組み合わせ

```ruby
if 条件式１ && 条件式２
 #条件式１と条件式２がtrueのときの処理
else
 #条件式の一つでもfalseがあるときの処理
end
```

細かくみると、条件式１がfalseの場合、条件式２のコードはそもそも読まれない。
具体的には、

```ruby

<% if user_signed_in? && @message.user.id == current_user.id %>
<% if @message.user.id == current_user.id && user_signed_in? %>
```

deviseを用いて、ログイン状態と非ログイン状態で表示を分ける場合、
ログインしていれば、どちらのコードでもエラーは起きない。
しかし、非ログイン状態の場合、
上のコードでは、エラーは起きないが、下のコードだと、エラーになってしまう。

その原因は、`@message.user.id`と`current_user.id`はログインしている状態でないと、値が入らず、そもそも`==`で等しいかどうか、判別することができない。
一方、上の式では、`user_signed_in?`の時点で、非ログイン状態だと、`false`が返るので、`&&`以降のコードを判別に使わずに済む。
getElementsByClassNameとaddEventListener について

今の自分の理解が浅いため、再度同じミスを犯すかもしれない。
その時に見返して確認ができるように記録として残しておく。

#経緯
railsで削除機能実装中、削除を行う前に確認ダイアログを表示させたいと思い、Javascriptファイルに記述を行う。

```ruby:html.erb
 <%= link_to '削除', hoge_path(hoge.id), class: 'delete-btn', method: :delete %>
```

```javascript:javascript

function check() {
  const btn = document.getElementsByClassName('delete-btn');
    btn.addEventListener('click', () => {
    window.confirm('削除を実行します')
  })
 };
```

削除ボタンをクリックしてみるがダイアログが表示されることはなく、削除が実行される。リロードして再チャレンジするがやはり何もなく削除される。

# 結論
htmlファイルの記述を以下のように変更

```ruby:html.erb
 <%= link_to '削除', hoge_path(hoge.id), class: 'delete-btn', method: :delete, data: { confirm: '削除を実行します。よろしければOKをクリックしてください。' } %>
```

 調べたところ```data: { confirm: "表示させる言葉" }```を``link_to``に記述すればダイアログが表示されるとのこと。ダイアログの表示に関しては解決。

#本題
では、もしJavaScriptファイルで```addEventListener```を使いたい時はどうすればいいか。
1. 取得する要素が１つだけならばidを付与して```getElementById```で取得する。
2. ```querySelectorAll```で要素を取得→取得した要素に対して``forEach``関数を用いる

``foreach``関数はNodeListオブジェクトのメソッドであり、NodeListは``querySelectorAll``の戻り値である。そのため、```getElementsByClassName```ではなく``querySelectorAll``を利用して要素を取得する。<br>
ちなみに```getElementsByClassName```の戻り値は```HTMLCollection```。

### 感想
まだまだ理解が浅く、とりあえず調べたことを繋げて書いているため、自分でも理解できていない部分が多い。
もっと理解を深めていけるよう勉強していかねばと感じた。

### 参考記事
- https://developer.mozilla.org/ja/docs/Web/API/HTMLCollection
- https://develop.logical-studio.com/web/20191213-js-class-addeventlistener/
- https://qiita.com/777mountain/items/b2ad9bef1542caa20498
AWS AppSyncについてまとめてみた

# AWS AppSyncとは

- マネージド型のGraphQLサービス
- リアルタイム機能、オフライン機能が簡単に実装可能
- NoSQLデータストア、RDB、HTTP API、AWS Lambdaを使用したアプリケーションの構築

**特徴**

- GraphQLを使用して情報を取得できる。
- Amazon Cognitoと連携することで認可制御が容易に実現できる。
- パイプラインリゾルバーを利用することで、複数のオペレーションを組み合わせて実行できる。
- マッピングテンプレートに処理を記載することで、リソースへアクセスする前後に処理を挟むことができる。


## リゾルバー
AWS AppSyncは、クライアントからGraphQLリクエストを受け取ると、リゾルバーと呼ばれる関数にGraphQLリクエストをマッピングする。

ここでいう関数とは、

- リクエストマッピングテンプレート
- レスポンスマッピングテンプレート
- データソース名
- バージョン

で構成されており、 データソースへの1つのオペレーションを定義している。

開発者はそれぞれリクエスト・レスポンスに対する処理をVTL(Apache Velocity Template Language)と呼ばれるフォーマットでマッピングテンプレートに自由に記述できる。


**リクエストマッピングテンプレート**
文字数チェックなど、リクエストデータのスキーマ定義より細かいバリデーションを行うことができる。
DBへ新規登録する際に、フロントエンドからきたリクエストデータに固定値(バージョン)を加えることができる。


**レスポンスマッピングテンプレート**
ユーザに応じて返却する情報を絞ることができる。
複数リソースから得た結果を1つのオブジェクトに整形することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308386/ce29c296-9d32-1319-7700-a32ad7928e14.png)


## ユースケース
**リアルタイム**
・最新情報をウォッチするダッシュボード
・ほぼリアルタイムでデータを更新

**コラボレーション**
・複数ユーザーが共同編集を行うアプリケーション
・ドキュメント、画像、テキストメッセージなど、さまざまなコンテンツタイプを自動更新

**ソーシャルメディア**
・ソーシャルメディアやチャット
・複数ユーザー間でのメッセージング管理をサポート
・オフライン時でもアプリケーションを操作でき、再接続時に自動Sync


# GraphQLとは

- Facebookが開発
- アプリケーションがサーバーからデータを取得できるように開発されたデータ言語 
- Query(取得)、 Mutation(変更)、Subscription(購読)
- GraphQL クエリでは、クライアントがレスポンスの形式を指定する。 これにより、クライアントは必要なデータのみを必要な形式で照会することが可能。

## GraphQLの実際の動き

### Query
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308386/7e56f8d0-85e3-4b20-5317-7b6d608f7731.png)

サーバー側で定義されたスキーマに沿って、クライアント側で指定したデータのみを取得することができる。
※REST APIでは、返却値が決まっているため不必要なデータも取得される場合がある。

### Mutation
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308386/cf104bec-5b8a-3c77-3df6-a2108f25fe28.png)

### Subscription
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308386/990a6368-c588-e1c1-105a-b8b5f8ce08aa.png)

## GraphQLとREST
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308386/087e8ce6-b2ed-7463-d314-090d0523703b.png)

GraphQLとREST APIのどちらを採用するかで開発フローに違いが出てくる。

**GraphQLの開発フロー**
1. 画面仕様（デザイン）を作成
2. 画面仕様からデータソース（DynamoDB）を作成
3. データアクセスの GraphQL 及びマッピングテンプレートを作成
4. テスト

**RestAPIの開発フロー**
1. 機能仕様書からデータベース設計
2. データベースへアクセスするための API設計
3. APIのプログラミング
4. テスト
AWS CodePipelineでパイプラインとブランチを紐づけるときの権限回り

1. pipelineと新しく作ったブランチを紐づける
2. 権限の境界を削除する
3. templateで定義しているロールの名前を変更する
4. パイプラインでcloudformationスタックの名前を変更する
5. Worker-RoleのpassroleにExecution-Roleを追加する
変数のスコープについて。。。

flaskを使ってローカルサーバを立ち上げ、
ToDoタスクのwebアプリケーションを出力する。

その後、テンプレをアレンジしてflask runを実行したところ以下のエラーが発生。

```python:app.py
UnboundLocalError: local variable 'count' referenced before assignment
```

以下、エラーになった部分を抜粋

```python:app.py
count = 0
@app.route("/updatedone/<int:item_id>")
def update_todoitemdone(item_id):
    todolist.update(item_id)
    count = count + 1
    return render_template("showtodo.html", todolist=todolist.get_all(), result=count)
```

関数外で宣言された変数countを
関数内でも使用する場合、グローバル宣言する必要があった。


以下、修正後。

```python:app.py(修正後)
count = 0
@app.route("/updatedone/<int:item_id>")
def update_todoitemdone(item_id):
    todolist.update(item_id)
    global count
    count = count + 1
    return render_template("showtodo.html", todolist=todolist.get_all(), result=count)
```

doneを押すたびに数値が加算されるようになった！(('ω')ノ


****
↓参考記事↓
[VS CodeとFlaskで作成するToDoリストアプリ](https://www.atmarkit.co.jp/ait/articles/1807/31/news042.html)
***
GraphQLのエラーをSentryに送信

## はじめに

今回はGraphQLのエラーを[Sentry](https://github.com/getsentry/sentry)に送信する際の設定まわりのメモです。

## Apollo ServerからSentryへ送信
[Apollo Server](https://github.com/apollographql/apollo-server)でSentryを使うにはまず[@sentry/node](https://www.npmjs.com/package/@sentry/node)をインストールします。

リゾルバ内での実行時エラーは`ApolloError`としてフロントに返却されSentryはこれをエラーとして認識しないため、何もしないとApolloServerからSentryにエラーは送信されません。Sentryは[公式の記事](https://blog.sentry.io/2020/07/22/handling-graphql-errors-using-sentry)でApollo Serverのライフサイクルイベントである[didEncounterErrors](https://www.apollographql.com/docs/apollo-server/integrations/plugins/#didencountererrors)を活用して、以下のように実装することを推奨しています。

```typescript
didEncounterErrors(ctx) {
  // If we couldn't parse the operation, don't
  // do anything here
  if (!ctx.operation) {
    return;
  }
  for (const err of ctx.errors) {
    // Only report internal server errors,
    // all errors extending ApolloError should be user-facing
    if (err instanceof ApolloError) {
      continue;
    }
    // Add scoped report details and send to Sentry
    Sentry.withScope(scope => {
      // Annotate whether failing operation was query/mutation/subscription
      scope.setTag("kind", ctx.operation.operation);
      // Log query and variables as extras
      // (make sure to strip out sensitive data!)
      scope.setExtra("query", ctx.request.query);
      scope.setExtra("variables", ctx.request.variables);
      if (err.path) {
        // We can also add the path as breadcrumb
        scope.addBreadcrumb({
          category: "query-path",
          message: err.path.join(" > "),
          level: Sentry.Severity.Debug
        });
      }
      Sentry.captureException(err);
    });
  }
}
```

## Apollo ClientからSentryへ送信

[Apollo Client](https://www.npmjs.com/package/@apollo/client)でSentryを使うには[@sentry/react](https://www.npmjs.com/package/@sentry/react)をインストールします。

GraphQLのエラーを送信する際は[apollo-link-error](https://www.apollographql.com/docs/link/links/error/)を活用すると便利です。

```ts
import { onError } from "@apollo/client/link/error";

const link = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
    graphQLErrors.map(({ message, locations, path }) =>
      // Sentryの`captureMessage`などのメソッドで`message`をSentryに送信
    );
  if (networkError) {
    // Sentryの`captureMessage`などのメソッドで`networkError`をSentryに送信
  };
});
```

## まとめ

以上、GraphQLのエラーをSenryに送信する際の設定まわりでした。
Haskell開発環境構築 for Mac

# Haskellの環境構築

## はじめに
以前、途中で挫折したHaskellを真剣にやってみようということで、初歩的なところから始めまする

## 開発環境

・ MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
・ プロセッサ : 2GHz クアッドコアIntel Core i5
・ メモリ : 16GB
・ MacOS Catalina (10.15.4)

## 環境構築
Haskellの環境構築するなら、stackを利用するのが良さそう。
[公式ドキュメンント](https://docs.haskellstack.org/en/stable/install_and_upgrade/)
### stackとは
**下記のような機能を兼ね備えたツール**
・ Haskellコンパイラをインストールできる
・ Haskellで開発する為のプロジェクトを新規作成できる
・ 作成したプロジェクトをビルドできる

### やってみた

・まず、stackをインストール
Homebrewでいけそう。

```
brew install stack 
```

・stackを使用して、コンパイラ(GHC)や基本のパッケージをインストールする

```
stack setup 
```

・GHCのバージョンを表示してみる

```
stack ghc -- --version
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/920615af-a3af-8b5d-51ee-490b2fca8adb.png" width="600px">

stack setupでダウンロード/インストールしたものは、~/.stackディレクトリ配下に格納されているっぽい

・プロジェクトを作成してみる

```
stack new hello-world
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/39314d0b-7650-c005-aa81-5375ed667bf4.png" width="600px">

いい感じです。
これにより、Defaultのプロジェクトファイル一式が作成される。
また、プロジェクトを作成すると、ディレクトリ内にstack.yamlという設定ファイルが作成されている

```
❯ tree .
.
├── ChangeLog.md
├── LICENSE
├── README.md
├── Setup.hs
├── app
│   └── Main.hs
├── hello-world.cabal
├── package.yaml
├── src
│   └── Lib.hs
├── stack.yaml
├── stack.yaml.lock
└── test
    └── Spec.hs

3 directories, 11 files
```

・Hello Worldを出力したい
src/Lib.hs　の中身を書き換える

```Lib.hs
module Lib
    ( someFunc
    ) where

someFunc :: IO ()
someFunc = putStrLn "Hello, world." 
```

・ビルドしてみる

```
stack build
```

・ 実行してみる

```
stack exec hello-world-exe
```

いい感じ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/20d00b45-f182-7624-6bae-6e53a00b6de4.png" width="300px">


### Stackの主なコマンド

・テンプレートからプロジェクトを新規作成する

```
stack new
```
・プロジェクトを新規作成 (テンプレート無し版)する

```
stack init
```
・指定されたバージョンのコンパイラ / 基本パッケージをインストールする

```
stack setup
```
・ビルドする

```
stack build
```
・ビルドしてlocal-binにインストール

```
stack install
```


## おわり
目標 : Haskell使ってWeb APIを作ってみる

## 参考
[参考元](https://qiita.com/usamik26/items/672ed3c4451402bfc275)
RFC2396　とは

#1.目的
「RFC2396　とは」に対して簡単な回答を記事にまとめます。
#2.動機
現場でRFC2396の非予約文字を調べる機会があったので覚書代わりに記事にしようと思いました。

#3.RFC2396　とは
RFC2396ですが、簡単に表現すると”URLで利用できる文字”です。
※RFC3986ってのもいますが今回は説明しません。
RFC2396では以下の文字が使用可能です。
・アルファベット A-Z a-z
・数字 0-9

#4.予約文字と非予約文字
予約文字
区切り文字などの特定目的で用いるために予約されている文字で、その目的以外ではURIに使用できません。
ただし、URLエンコードを使用すれば表現することが可能です。
URLエンコードは16進数で表した2桁の文字コードを「%」に続けた形式で記述します。
例：()をURLで使用したいときは以下のURLエンコードを利用すると使用できます。
・%28=(　　
・%29=)
http://e-words.jp/w/%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%87%E3%82%B8%E3%83%83%E3%83%88.html
↑実際にURLエンコードが使われているものです。（前回記事にしたものの参考記事）

非予約文字とは自由にURIに使用できる文字です。
以下の記号のことを指します。
・ mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
https://tools.ietf.org/html/rfc2396
↑RFC2396の仕様が書かれているものから引っ張ってきているのですが、仕様通りに非予約文字が利用できるかはアプリケーションの実装で同一性が担保されていないと使用できないこともあります。

#5.まとめ
RFC2396ではアルファベット A-Z a-z、数字 0-9、記号 "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"が使用可能です。
それ以外のものはURLエンコードを使って%○○で表現できます。
mergeメソッド

mergeメソッドとは、ハッシュを結合させることができる、Rubyのメソッドである

```ruby

post = { name: "さとう", text: "こんにちは"}
uid = { user_id: "1" }
post.merge(uid)
#=> {:name=>"さとう", :text=>"こんにちは", :user_id=>"1"}

```
備忘録 Javascript callback関数

# callback関数 省略しないパターン

```
function arrayWalk(data, f) {
  //② dataにはarray fにはshowElementが格納
  for(var key in data) {
    //③引数で受け取ったshoElement関数を呼ぶ
    f(data[key], key);
  }
}

function showElement(value, key) {
  //④
  console.log(key + ':' + value);
}

var array = [1, 2, 3, 4, 5];
//①
arrayWalk(array, showElement);

```

# callback　匿名関数
showElementを定義しない。

```
function arrayWalk(data, f) {
  for(var key in data) {
    f(data[key], key);
  }
}

var array = [1, 2, 3, 4, 5];
arrayWalk(array, function(value, key){
  console.log(key + ':' + value);
})
```

# callback関数 ラムダ式
```
function arrayWalk(data, f) {
  for(var key in data) {
    f(data[key], key);
  }
}

var array = [1, 2, 3, 4, 5];
arrayWalk(array, (value, key) => {
  console.log(key + ':' + value);
})
```

# 動作結果
```
//0:1
//1:2
//2:3
//3:4
//4:5
```

## 参考
改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで
https://gihyo.jp/book/2016/978-4-7741-8411-1
本日の『railsチュートリアル』で詰まったところ(2020/10/08)

#詰まったところ


#2.1 アプリケーションの計画
･事象: `$heroku create`でherokuコマンドが認識されない
･解決方法: toy_app内にて、『1.5.1 Herokuのセットアップ』のherokuインストールからやり直した。
･留意点: アプリ毎にインストールする必要があるのか？要確認



#本日のまとめ
･進捗: 2章 2.1.1〜2.2.1読了

･感想:terminalにコマンドを打つ際、カレントディレクトリが重要なので常に意識する必要がある。
OpenMediaVault 4系から5系へのアップグレード

# 概要

OpenMediaVault 4系から5系にアップグレードしようとしたときの手順メモです。

結論としては、アップグレード用スクリプトを実行していくつかのコマンドを打てばメジャーバージョンアップできます。

# 作業環境

更新作業の前後でバージョンは下記のようになりました。

||OpenMediaVault|Kernel|備考|
|---|---|---|---|
|更新前|4.1.36-1|4.19.0-0|Debian 9系の Kernel は 4.9.0 らしいのだけれども、何かの理由で backports を使って Kernel のバージョンを上げていたっぽい。。。|
|更新後|5.5.12-1|4.19.0-11||

# 手順

## 1. Debian 10系へアップグレード

まずは手始めに次のコマンドを実行します。手始めとは言っても、いきなり OS のメジャーバージョンアップになりますが。。。

```shell-session
$ wget -O - https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/upgrade4to5 | sudo bash
(略)
Reboot now.

Then run:
  apt-get purge openmediavault-omvextrasorg resolvconf
  wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | bash
  apt-get update
  apt-get dist-upgrade

  omv-salt deploy run nginx
  omv-salt deploy run phpfpm

https://forum.openmediavault.org/index.php?thread/27909-omv-5-0-finally-out/&postID=219830#post219830
```

ファイル名が `upgrade4to5` となっている割には、このスクリプトでは OpenMediaVault 5系へのアップグレードはまだされていないっぽいです。たぶん次のことをやっている感じ。

*   OpenMediaVault 5系で廃止された(リネームされた？)パッケージの削除
*   Debian を9系(stretch)から10系(buster)にアップグレード

スクリプトが正常に終了したら、ここで必ず OS を再起動します。

```shell-session
$ sudo reboot
```

## 2. OpenMediaVault 5系へアップグレード

OS が再起動したら次のコマンドを実行します。

```shell-session
$ sudo apt-get purge openmediavault-omvextrasorg resolvconf
$ wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | sudo bash
```

このスクリプトで OpenMediaVault 5系がインストールされます。
(どうやら動作している Debian が stretch なら4系、 buster なら5系が自動的にインストールされるようです。)

パッケージも最新化します。

```shell-session
$ sudo apt-get update
$ sudo apt-get dist-upgrade
```

## 3. Web インターフェースのファイルを更新

次のコマンドを打って Web インターフェースを使えるようにします。

```shell-session
$ sudo omv-salt deploy run nginx
$ sudo omv-salt deploy run phpfpm
```

サクッと終わるはずです。

## 4. その他

なんかやっておいた方が良さそうなのでやっておきます。

```shell-session
$ sudo apt-get install usrmerge
$ sudo omv-confdbadm migrate conf 5.0.0
```

OpenMediaVault 4系の設定を5系にマイグレーションしているのでしょうか。

バージョンを確認してみると、こんな感じで5系になっていることを確認できます。

```shell-session
$ omv-sysinfo omv-version
================================================================================
= openmediavault information
================================================================================
Release: 5.5.12-1
Codename: Usul
```

これで更新作業は完了です。 OpenMediaVault の Web インターフェースにアクセスできますが、その際は **忘れずにブラウザのキャッシュをクリアしてください**。

# FYI

*   [OMV 5.0 - finally out! :-) - General - openmediavaulto](https://forum.openmediavault.org/index.php?thread/27909-omv-5-0-finally-out/&postID=219830#post219830)
*   [What OMV-SALT to deploy after installation on Debian 10? - General - openmediavault](https://forum.openmediavault.org/index.php?thread/30294-what-omv-salt-to-deploy-after-installation-on-debian-10/)
【VBA】Outlookで自動メール送信

>参考
https://www.fastclassinfo.com/entry/vba_outlook_sendmail#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%AB%E3%83%83%E3%82%AF%E6%93%8D%E4%BD%9C%E3%83%87%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/1dc50fc6-e60b-b078-4693-1111025043cf.png)

```vb

Option Explicit
Sub sendMail() '

'---コード1｜outlookを起動する
    Dim toaddress, ccaddress, bccaddress As String  '変数設定：To宛先、cc宛先、bcc宛先
    Dim subject, header, mailBody, mailBody_head, mailBody_middle, mailBody_tail, credit As String '変数設定：件名、メール本文、クレジット、添付
    Dim outlookObj As Outlook.Application    'Outlookで使用するオブジェクト生成
    Dim mailItemObj As Outlook.mailItem      'Outlookで使用するオブジェクト生成
    Dim i As Long

    Dim objOutlooksheet As Worksheet
    Set objOutlooksheet = ThisWorkbook.Worksheets("Mail")
    
'---コード2｜差出人、本文、署名を取得する---
    toaddress = objOutlooksheet.Range("B2").Value   'To宛先
    ccaddress = objOutlooksheet.Range("B3").Value   'cc宛先
    bccaddress = objOutlooksheet.Range("B4").Value  'bcc宛先
    subject = objOutlooksheet.Range("B5").Value     '定型
    header = objOutlooksheet.Range("B6").Value     '件名
    mailBody_head = objOutlooksheet.Range("B7").Value    'メール本文頭
'    mailBody_middle = objOutlooksheet.Range("B8").Value    'メール本文中
    mailBody_tail = objOutlooksheet.Range("B9").Value    'メール本文末
    credit = objOutlooksheet.Range("B10").Value      'クレジット

'---コード3｜メールを作成して、差出人、本文、署名を入れ込む---
    Set outlookObj = CreateObject("Outlook.Application")
    Set mailItemObj = outlookObj.CreateItem(olMailItem)
    mailItemObj.BodyFormat = 3      'リッチテキストに変更
    mailItemObj.To = toaddress      'to宛先をセット
    mailItemObj.cc = ccaddress      'cc宛先をセット
    mailItemObj.BCC = bccaddress    'bcc宛先をセット
    mailItemObj.subject = subject   '件名をセット
    
'---コード4｜メール本文を改行する
'    i = 2
'    With Worksheets("Sheet2")
'        Do While .Cells(i, 1) = "○"
'            mailBody_middle = mailBody_middle & .Cells(i, 2) & "/" & .Cells(i, 3) & ":" & .Cells(i, 5) & vbCrLf
'            i = i + 1
'        Loop
'    End With

    mailBody = mailBody_head & vbCrLf & mailBody_middle & vbCrLf & mailBody_tail
    mailItemObj.Body = header & vbCrLf & vbCrLf & mailBody & vbCrLf & vbCrLf & credit   'メール本文 改行 改行 クレジット
    
'---コード5｜自動で添付ファイルを付ける---
'    Dim attached As String
'    Dim myattachments As Outlook.Attachments 'Outlookで使用するオブジェクト生成
'    Set myattachments = mailItemObj.Attachments
'    attached = objOutlooksheet.Range("B9").Value     '添付ファイル
'    If attached <> "" Then myattachments.Add attached

'---コード6｜メールを送信する---
    'mailItemObj.Save   '下書き保存
    mailItemObj.Display  'メール表示(ここでは誤送信を防ぐために表示だけにして、メール送信はしない)
    'mailItemObj.Send    'メール送信

'---コード7｜outlookを閉じる(オブジェクトの解放)---
    Set outlookObj = Nothing
    Set mailItemObj = Nothing

End Sub
```
`rails generate migration` コマンドで長さ制限付きのstring型カラムを追加したいとき


`string{n}` のようにすればよい。

```sh
$ rails g migration AddNameToUsers name:string{30}
```

生成されるマイグレーションファイルは以下のようになる

```rb
class AddNameToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :name, :string, limit: 30
  end
end
```

他にuniqやindexも使えるのだが `limit` だけ何故か忘れてしまうのでメモ

### 参考
- https://github.com/rails/rails/blob/11738e82cdcfb48f7740a2da01ad2716d9bcfbb6/railties/test/generators/migration_generator_test.rb#L194
vim内のヤンクをクリップボードと連携させるには

##目的
vimとクリップボードを連携させる。
具体的にはvim内のコマンドのヤンク(y, dなど)によってコピーされる文字列をvimのレジスタではなくOS側のクリップボードに保存するよう設定する。

##設定変更かあるいは環境構築か
そもそも今の環境で設定変更だけでリンクが可能かどうか調べる必要がある。不可能なら新しいプログラムなどのインストールが必要になる。terminalを開き、

```bash
$ vim --version | grep clipboard
```
で左上が`+clipboard`なら設定変更で可能、`-clipboard`なら不可能

### 不可能であった場合
もとから可能であったならこの項は飛ばして構わない。
```bash
$ sudo brew install vim
```
で最新のHugeバージョンのvim [^1] をインストール
最初と同様にして確認、それでもまだ不可能ならソースコードからビルドすることになる。まずtarファイルを`wget`でダウンロードする。ここではバージョンとしてはvim-8.1を扱っているが適宜置き換えるように。

```bash
$ wget ftp://ftp.vim.org/pub/vim/unix/vim-8.1.tar.bz2
$ tar xvf vim-8.1.tar.bz2
```
tarファイルの取得および解凍はどのディレクトリでも可
解凍したらvim81という名前のディレクトリが作られるのでそこに移動

```bash
./configure --enable-gui=yes --enable-multibyte --with-features=huge --disable-selinux --prefix=/usr/local --enable-rubyinterp --enable-xim --enable-fontset|grep gui
```
を実行する。少し長いが1行にまとめるように。最後に

```bash
$ make
$ sudo make install
```
をして完了
一旦ターミナルを閉じて再度確認し、`+clipboard`になっていたらOK　可能であった場合に進む。

### 可能であった場合

```vim

set clipboard&
set clipboard^=unnamedplus
```
をvimrcに追加することで実際に使える。vimrcは大抵ホームディレクトリに`.vimrc`として存在するが、なければ新規作成すればよい。


## まとめ
備忘録として書いたはいいものの、おそらく二度と使わない気がする。
`dd`を多用する人間なので非常に高頻度でクリップボードが汚染される。
不便で仕方なくて連携させたのに別の不便が増えて嫌な気持ちに...
なんで？　なんでだろうね

##参考
https://gist.github.com/nkurosawa/e74117241f43e7b4b6f1
https://pocke.hatenablog.com/entry/2014/10/26/145646


[^1]: Hugeバージョン未満のものだと機能が制限されている。バージョンごとの大きさがそのまま形容詞の意味につながる
@angular/cliのインストールからAngularプロジェクト作成まで

#はじめに
今回は@angular/cliのインストールをしてから実際にAngularプロジェクトを実行するまでを書いていきます！
Node.jsがインストールされている必要があるので、
まだインストールできていない人は[Node.jsのインストール方法（Windows）](https://qiita.com/masangular/items/2046f0b91c4c8cc9ada3)を見てね！

#目次
1. @angular/cliのインストール
2. ng new コマンドでAngularプロジェクトの作成
3. 実際にブラウザで確認してみよう！

#1. @angular/cliのインストール
* 「npm install -g @angular/cli」を実行するだけです

```
$ npm install -g @angular/cli
```
* インストールされているかを確認するには「ng --version」を実行し、下図のように表示されていれば成功！

```
$ ng --version
```
![angularcli_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748651/b163935b-ea82-aff6-c378-1a4ef79ee766.png)

#2. ng new コマンドでAngularプロジェクトの作成
* 「ng new project-name」を実行すると作成されます(project-nameは自分の好きな名前で作れます)

```
$ ng new sample
```

* 下図のようにproject-name（今回はsample）のフォルダが作成されて、その中にAngularのプロジェクトが出来上がります

![angularcli_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748651/5befd3d5-a0ca-8b10-c60e-33310e685260.png)

#3. 実際にブラウザで確認してみよう！

* 作成されたプロジェクトフォルダに移動し「ng serve」を実行！

```
$ cd sample
```
```
$ ng serve
```

* 下図のように「Compiled successfully」と表示されていればOK!

![angularcli_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748651/05675aca-a910-3ccb-32ee-8e5d0864b80c.png)

* ブラウザを開いて「[http://localhost:4200](http://localhost:4200)」にアクセスし下図のような画面が表示されていれば成功！

![angularcli_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748651/fee5d476-790e-e29f-a5c6-01b3f498d743.png)
Pythonでバブルソート

### ・実行環境
|名前|バージョン|
|---|---|
|Python|3.7.1|


ソースコードは以下になります。

```python 
src = [3, 5, 1, 8, 5, 9]
print(src)

for i in range(len(src)-1):
    for j in range(len(src)-1-i):
        if src[j] > src[j+1]:
            tmp = src[j]
            src[j] = src[j+1]
            src[j+1] = tmp

print(src)
```

実行結果は以下のようになります。

```console
[3, 5, 1, 8, 5, 9]
[1, 3, 5, 5, 8, 9]
```

最後まで読んでいただきありがとうございました。
またお会いしましょう。
正規表現 完全一致で置換



`¥bHOGE¥b`のように`¥b`で文字を囲うと、その文字に完全一致する正規表現になります。`¥b`は単語境界にマッチするメタ文字です。ここで単語とは`a-z`, `A-Z`, `0-9`, `_`から構成されます(英数字とアンダーバー)。

# 変換前
```
sky
->sky
blue->sky[0]
blue.sky[0]

blue_sky
```

# コマンド

上記のskyをmoonに変えたい場合、正規表現を`s/\bsky\b/moon/g`のようにすると、単語の`sky`のみにマッチします。ちなみに`s/sky/moon/g`にすると`blue_sky`まで変換されてしまいます。

```sh
perl -wpln -e 's/\bsky\b/moon/g' ./tp.txt > tp_rep.txt 
```

# 変換後
```
moon
->moon
blue->moon[0]
blue.moon[0]

blue_sky
```
意図通り変換されています。
Gitコマンドの備忘録

いまさらながら改めて。
もちろん他にもたくさんあるけど、
自分の使用頻度が高いやつを備忘録として。

**設定**

```bash
# ユーザー設定
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"

# 差分の日本語文字化け対策
git config --global core.pager "LESSCHARSET=utf-8 less"

# ファイル名の日本語文字化け対策
git config --global core.quotepath false

#　改行文字の自動変換対策
git config --global core.autocrlf false

# ファイルモードの変更無視
git config core.filemode false

# 設定確認
git config --global -l

# 直接編集
git config --global -e
```

**操作**

```bash

# 変更の確認
git status

# 差分確認
git diff ファイル名

# ステージング
git add ファイル名

# ステージング取消
git reset HEAD

# コミット
git commit -m "メッセージ"

# ブランチ一覧
git branch -a

# リモートのブランチ取得
git checkout -b {ローカルブランチ名} origin/{リモートブランチ名}

# ブランチ切替
git checkout ブランチ名

# ファイルの変更の破棄
git checkout ファイル名

# developブランチからの取り込み
git merge develop

# branch作成
git branch ブランチ名

# ブランチの削除
git branch -d ブランチ名

# ブランチ名の変更
git branch -m 変更前ブランチ名 変更後ブランチ名
```
(Jest) asyncのfunctionで「regeneratorRuntime is not defined」と出た場合の対処

## asyncのfunctionで「ReferenceError: regeneratorRuntime is not defined」と表示される。


```
ReferenceError: regeneratorRuntime is not defined

       6 | export default{
       7 |     
    >  8 |     get: async function(){
         |            ^

```

## 対処：@babel/plugin-transform-runtimeをtest実行時に呼び出す設定を加える
https://stackoverflow.com/questions/62139063/jest-error-in-async-method-referenceerror-regeneratorruntime-is-not-defined

@babel/plugin-transform-runtimeは、generatorやasyncといった構文をtranspile時に解決してくれるpluginのようです。
https://babeljs.io/docs/en/babel-plugin-transform-runtime

jestで実行する時にだけ使用するように設定を変更します。

```bash
npm install @babel/plugin-transform-runtime --save-dev
```

```/.babelrc
{
  "env": {
      "test": {
        "plugins": ["@babel/plugin-transform-runtime"]
      }
  }
}
```

これでasyncのfunctionのテストが通りました。

以上です。
【ハッカソンで使える！】AzureやAWSなどの仮想マシン上にFlaskサーバーをデプロイする

# こんなあなたに
- PythonでWebサーバーを構築して公開したい
- 深層学習を使用したAPIサーバーを作りたい

ハッカソンでFlaskを使ってAPIサーバーを構築するために色々調べてやったので，イチからまとめました．

## 前提
- Azure, AWS, GCPなどで，仮想マシンを作成済み
- ssh接続ができている
- 80番ポートが開放されている
- OSはUbuntu18.04

## 環境
- AWS EC2インスタンス
- Ubuntu18.04

## 本編
### 1. 必要なパッケージのインストール
```console
# apache2のインストール #
$ sudo apt install apache2 apache2-dev

# Pythonのインストール #
$ curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
# 最後に表示される設定を~/.bashrcに記述

# インストール可能なanacondaのバージョンを表示
$ pyenv install -l | grep anaconda
# anacondaをインストール
$ pyenv install anaconda3-5.3.1
# anacondaを有効化
$ pyenv global anaconda3-5.3.1

# anacondaの環境を作成
$ conda create -n <hoge> python=3.6
$ conda activate <hoge>
# flask, mod_wsgiのインストール
$ conda install flask
$ pip install mod_wsgi
```

### 2. flaskを使ったアプリケーションを作成
`/var/www/`以下に`flask_app`ディレクトリを作成し，以下のファイルを配置する．

```/var/www/flask_app/app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, Flask!"

if __name__ == "__main__":
    app.run(host='0.0.0.0')
```
```/var/www/flask_app/adapter.wsgi
import sys
sys.path.insert(0, '/var/www/flask_app')

from app import app as application
```

### 3. apache2の設定ファイルを追加する

```/etc/apache2/conf-available/flask.conf
LoadModule wsgi_module /home/<user>/.pyenv/versions/anaconda3-5.3.1/envs/<hoge>/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
WSGIPythonHome /home/<user>/.pyenv/versions/anaconda3-5.3.1/envs/<hoge>/
<VirtualHost *:80>
  ServerName <server-ip>:80
  DocumentRoot /var/www/flask_app
  WSGIDaemonProcess flask_app user=<user> group=<user> threads=5
  WSGIScriptAlias / /var/www/flask_app/adapter.wsgi
  <Directory "/var/www/flask_app/">
    WSGIProcessGroup flask_app
    WSGIApplicationGroup %{GLOBAL}
    WSGIScriptReloading On
    Require all granted
  </Directory>
</VirtualHost>
```
上記はあくまで一例です．
`<user>`や`<hoge>`, `<server-ip>`の部分はそれぞれ，ログインユーザー，anacondaの環境名，サーバーのIPアドレス（ドメイン）に適宜補完してください．
また，`LoadModule`と`WSGIPythonHome`も環境によって異なることがあります．

#### LoadModuleの求め方
flaskをインストールした環境を有効にした上で以下のコマンドを実行するとパッケージがインストールされているディレクトリが出てくる．

```console
$ python -c "import sys; print(sys.path)"
```

その中から，mod_wsgiを探し，パスを確認する．タブ補完していくと間違わない

```console
$ ls /home/<user/.pyenv/versions/anaconda3-5.3.1/envs/<hoge>/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
```

### 4. 追加した設定ファイルを有効化する
```console
$ sudo a2enconf flask
```

### 5. apache2の再起動
```console
$ sudo systemctl restart apache2.service
```

### 接続確認
ブラウザで，`http://<server-ip>`にアクセス．(httpsではないので注意）
`Hello, Flask!`と表示されれば成功です．

### 接続できない・エラーが発生するときは．
- 仮想マシンの80番ポートが開放されているかを確認する
    - サーバーのコンソールから設定できるはず
- internal errorとかが出たらとりあえず以下を確認してみる．

```console
$ sudo systemctl status apache2.service

$ sudo tail /var/log/apache2/error.log
```


## Future work
- SSL対応
じゃんけんアプリをFlutterに移植してみた

# はじめに
[iPhoneアプリ開発集中講座](https://amzn.to/30MZV95)にあるじゃんけんアプリをFlutterでもしも作ったらというお題で移植してみました。
なるべく同じアプリになるようにしました。

# 解説
コードは[github](https://github.com/FromF/flutter_janken)に公開してあります。
一部紹介させていただきます。

## じゃんけん画像
[iPhoneアプリ開発集中講座](https://amzn.to/30MZV95)内ではImageViewのimageプロパティーが初期はnilでじゃんけんをすると画像がセットされる作りでしたが、それをうまくできなかったのでWidgetを作って対応しました。

```Dart
Widget image(String image) {
  if (image.isEmpty) {
    // 画像のファイル名がない場合には、Container()を返して何も表示しない
    return Container();
  } else {
    // 指定された画像ファイル名を表示する
    return Image.asset(
      image,
    );
  }
}
```

## 変数
3つの変数を作りました。

| 変数名       | 概要                                                         |
| ------------ | ------------------------------------------------------------ |
| answerNumber | じゃんけんの結果を保持している変数<br />これで同じ結果が連続して表示されないようにしている |
| jankenText   | じゃんけんの結果（文字）を保持している変数<br />初期値は、「これからじゃんけんをします！」として初期タイトルとなるようにした |
| jankenImage  | じゃんけんの結果（画像）の画像ファイル名を保持している変数<br />初期値は空文字にすることによって先ほど作成したWidgetで何も表示しないようにしている |

```Dart
  int answerNumber = 4;
  String jankenText = 'これからじゃんけんします';
  String jankenImage = '';
```

## じゃんけんの乱数処理
repeat文だったのがdo 〜 while文に変わっている以外はあまり変化ありません。

```Dart
                  // 新しいじゃんけんの結果を一時的に格納する変数を設ける
                  int newAnswerNumber = 0;
                  // ランダムに結果を出すが、前回の結果と異なる場合のみ採用
                  // do {} while は繰り返しを意味する
                  do {
                    // 0,1,2の数値をランダムに算出（乱数）
                    newAnswerNumber = math.Random().nextInt(3);
                    // 前回と同じ結果のときは、再度、ランダムに数値を出す
                    // 異なる結果のときは、while を抜ける
                  } while (answerNumber == newAnswerNumber);
                  // 新しいじゃんけんの結果を格納
                  answerNumber = newAnswerNumber;
                  setState(() {
                    if (answerNumber == 0) {
                      // じゃんけんの数字が0だったら、グー画像を指定
                      jankenImage = 'images/gu.png';
                      jankenText = 'グー';
                    } else if (answerNumber == 1) {
                      // じゃんけんの数字が1だったら、チョキ画像を指定
                      jankenImage = 'images/choki.png';
                      jankenText = 'チョキ';
                    } else if (answerNumber == 2) {
                      // じゃんけんの数字が2だったら、パー画像を指定
                      jankenImage = 'images/pa.png';
                      jankenText = 'パー';
                    }
                  });
```

## 画像が大きくて画面に収まらない

スクリーンショットのように画像が縦長だったりして大きいと画面からはみ出てしまいエラーとなってしまいました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/0c75406d-fa68-91a7-04f3-c7e72dc47728.png" width=300>

そこで、`Expanded()`を使い調整しました。

```Dart
            Expanded(
                child: image(jankenImage)
            ),
```


# 最後に
まだまだFlutterに挑戦し始めたばかりで適切じゃないコードもあると思います。
ただ、FlutterはSwiftUIに近い感じで作れてこれでiOS/Android両方のアプリが作れるのでいいと思いました。
またこれからもこのシリーズ続けていきたいと思います。
VSCodeでclojure-lspを使う方法

VSCodeにはClojure用の拡張機能である`Calva`がありますが、LSPに関するサポートは十分ではないようです。
また、Market Placeを見てもそれらしき拡張機能が見当たりません。

ただ、`clojure-lsp`のリポジトリ内には、VSCode用の拡張機能が入ったディレクトリがあるのでそれを使ってみます

## clojure-lspインストール
[公式サイト](https://github.com/snoe/clojure-lsp)に従ってインストールします。
自分はArchLinuxなのでAURからインストールしました。

```
$ yay -S clojure-lsp-bin
```

## 拡張機能をvsixにビルド
`vsix`はVSCodeの拡張機能用のファイル形式です。
Market Placeにある拡張機能も実態は`vsix`です。

手順は以下のとおりです。ビルドには、nodejsとnpmが必要です

```bash
# 1. clojure-lspのリポジトリをクローンする
git clone https://github.com/snoe/clojure-lsp.git
# 2. vsceをインストール（vsixファイルの作成に使う）
npm install -g vsce
# 3. VSCode用の拡張ディレクトリに移動
cd clojure-lsp/client-vscode
# 4. 依存関係インストール
npm install
# 5. vsix作成
vsce package
```

最後に`client-vscode`ディレクトリ内にvsixファイルができているはずです。
自分は、`clojure-lsp-0.0.1.vsix `という名前で生成されていました。

## VSCodeにインストール
コマンドからインストールできます

```bash
# 生成されたvsixファイルを指定する
code --install-extension clojure-lsp-0.0.1.vsix  
```

GUIでやる場合は、コマンドパレットで`Install from VSIX`を入力して実行します。
vsixと入力すればでてくるはず。
そうするとファイル選択ダイアログになるので、生成されたvsixファイルを選択します。

## 動作確認
動かしてみましょう！！
MVCモデルのいろいろ

###MVCは何ですか？？？
MVCは、ユーザーインタフェースをもつアプリケーションソフトウェアを実装するためのデザインパターンである。

(Ref：https://bit.ly/2GQbO6V)

M（Model)：入力や表示に関連しない処理、システムのビジネスロジックを処理する
V（VIEW）：入力や表示に関連する処理
C（Controller）：モデルとビューの橋渡して制御する

###具体の例
Model：データの処理する。（DBからデータの取得、DBへの保存）
View:ユーザーが実際に見る画面を示す。
Controller：Viewからリクエストを受け取り、Modelへ処理の命令を出す。（Modelから処理の結果を受け取り、レスポンスとしてViewへ返す）

###メリット
各機能が分割されている為、変更・修正があった場合にその影響を受けにくい。