OmniAICreator/Qiita-1.07M huggingface dataset:
M1 macとインテルMac+others で Dockerfileを扱う方法

M1　macとインテルMac、Windows環境が混在した場合に、Dockerが上手く使えなかったので、なんとか作ってみました。重要なのは、コンパイル部分を一つにまとめる事です。

以下の記事を参考にさせていただきました。


https://engineer.blog.lancers.jp/2021/04/docker-m1-mac/

##ソース

```
RUN if [ $(uname -m) = "aarch64" ]; then \
  echo arm64; \ 
  # M1 Mac用
  # インストールしたいパッケージのコマンドが入る
  && ./configure --build=arm \
  && make \
  && make install; \
  else \ 
  echo amd64; \
  # それ以外のOS用
  # インストールしたいパッケージのコマンドが入る
  && ./configure \
  && make \
  && make install; fi
```

これで、今まで課題でGitで管理するのがめんどだった部分が無事解決しました。
M1 macはuname -mでaarch64という環境情報をはいてくれるのでこれを使います。
ASP.NET Core MVC CSV出力

## はじめに
ASP.NET CoreのMVCのアプリケーションでCSV出力機能を実装する機会があったため、メモとして使用したものを残しておきたいと思います。



## CsvHelper
CSV出力で使用する専用のクラスとマッピングするためのクラスを用意。

### CSV用クラス

``` C#
public class StudentInfo
{
    public long ID { get; set; }
    public int Japanese { get; set; }
    public int Mathematics { get; set; }
    public int Science { get; set; }
    public int SocialStudies { get; set; }
    public int English { get; set; }
}
```

### マッピング用クラス

``` C#
public class StudentInfoMap : CsvHelper.Configuration.ClassMap<StudentInfo>
{
    public StudentInfoMap()
    {
        Map(result => result.ID).Index(0);
        Map(result => result.Japanese).Index(1);
        Map(result => result.Mathematics).Index(2);
        Map(result => result.Science).Index(3);
        Map(result => result.SocialStudies).Index(4);
        Map(result => result.English).Index(5);
    }
}

```


## ASP.NET MVC
### View用Model
``` C#
public class StudentSearchModel
{
    public long ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public int Grade { get; set; }
    public string Class { get; set; }
}
```

### Controller
CSVを出力するためのAction(ExportCsv)を用意。
CsvHelperの仕様が一部変わった箇所がある模様。※ここの調査に時間がかかってしまった。。。
この時のCSVは普通のものとは少し違い、区切り線も出力する必要があった。

``` C#
public IActionResult ExportCsv([FromForm] StudentSearchModel model)
{
    //_repositoryはDB操作をするための自作クラスの変数
    //GetStudentInfoでDBから情報を取得してくる ※情報取得部分は割愛
    var results = _repository.GetStudentInfo(model).ToList());
    var bytes_separate = Encoding.GetEncoding("Shift-JIS").GetBytes("-----成績一覧-----\r\n");
    var bytes_results = GetCsvData<StudentInfo, StudentInfoMap>(results);
    return File(
        //byte配列をつなぐ
        bytes_separate
        .Concat(bytes_results)
        .ToArray(),
        "text/csv",
        "sample.csv");
}

private static byte[] GetCsvData<T, TMap>(List<StudentInfo> list) where TMap : ClassMap
{
    var ms = new MemoryStream();
    var sw = new StreamWriter(ms, Encoding.GetEncoding("Shift-JIS"));
    var cw = new CsvWriter(sw, CultureInfo.CurrentCulture);
    //ここの仕様が変わった？ 以前は "cw.Configuration.RegisterClassMap" のようにしていたと思う
    cw.Context.RegisterClassMap<TMap>();
    cw.WriteRecords(list);
    sw.Flush();
    return ms.ToArray();
}
```

## おわりに
CsvHelperの仕様が変わったところでだいぶ時間がかかってしまいましたが、当時は何とか実装できたのでホッとしました。
今後もこのようなメモは残していきたいと思います。
Wordpressで固定ページのURLを変えるには

Wordpressで固定ページのURLを変えるために行う作業は2ステップだけです。

1.管理画面上から固定ページのパーマネントリンクを変更する
2.固定ページのファイル名を変更する
※ベタで記載されているリンクがあればそのリンクも修正

## 管理画面上から固定ページのパーマネントリンクを変更する
![スクリーンショット 2021-08-27 11.42.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467966/e59059c7-25ac-525f-a43c-8a70db0bd705.png)
 
編集から固定ページのURLを変更しましょう。

## 固定ページのファイル名を変更する
![スクリーンショット 2021-08-27 12.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467966/42d3a43d-b0b7-40da-55d1-5f678024cfd1.png)

変更した固定ページのファイル名を変更しましょう。
固定ページはpage-○○.phpになるので、○○の部分を変更後のURLのものに差し替えればOKです。
[Ruby on rails]ゲストログイン機能　ゲストログインは削除、編集されないようにする

<h2>ゲストログインは作っておいた方が良い！</h2>

ゲストログイン押したら、ログインできちゃう便利機能です。
就職、転職活動でポートフォリオを外部の方に見せる場合には、作っておいた方が良いらしいです。
ゲストユーザーを作成せず、これでログインしてくださいとemail,passwordを提示したところで、
少し面倒なので見てもらえない可能性があります。
すぐ実装できるので、ゲストログインは作っておくべきだと思います！！！！
（他の人のポートフォリオ触ってみてもそうですが、
ゲストログインがないと、やっぱりすごく面倒に感じます。）

![スクリーンショット 2021-08-27 11.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/26e66d94-852a-f6dc-d836-a5209c29016b.png)

<h2>とても参考にした記事</h2>

https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104

<h2>気をつけないと、すぐ壊れる！！</h2>
今回ゲストログイン機能を実装しました。実装自体はうまくいったのですが、、
気をつけないとゲストログイン機能は簡単に壊れていきます。

落とし穴としては今のところ以下２点だと認識しています。
①ゲストログインは、退会（削除）ができないようにする！
②ユーザー情報の編集もできないようにする！

私の場合、新規登録時に入力させる情報は以下の通りになっています。

![スクリーンショット 2021-08-27 11.29.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/d73b3154-1322-5f33-759a-47c33dda6b3b.png)


<h2>ルーティングをかく</h2>

```rb
Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  devise_for :users, controllers: {
    registrations: 'users/registrations',
    sessions: 'users/sessions',
  }
#ここ追記しています！！！！！
  devise_scope :user do
    post 'users/guest_sign_in', to: 'users/sessions#guest_sign_in'
  end
  namespace :departments do
    resources :searches, only: :index
  end
省略
```

[devise_scope]は、deviseに新しくルーティングを追加したい場合に使います。(これを使わないとエラーが発生します。）
```rb
devise_scope :users do
  get 'ルーティング情報', to: 'users/registrations#アクション'
end
```

<h2>コントローラー記述</h2>

```rb
def guest_sign_in
    user = User.guest
    sign_in user
    redirect_to posts_path, notice: 'ゲストユーザーとしてログインしました。'
  end
```

<h2>モデルファイル記述</h2>

```rb:user.rb
def self.guest
    find_or_create_by!(name: 'ゲストユーザー',
                       email: 'guestda@example.com',
                       join_year: '新入社員',
                       department_id: 1,
                       is_valid: true) do |user|
      user.password = SecureRandom.urlsafe_base64
    end
  end
```

<h2>ゲストログインボタン</h2>

```erb
<li class="nav-item">
        <%= link_to "ゲストログイン", users_guest_sign_in_path,class:"btn btn-light fas fa-seedling",method: :post %>
    </li>
```

<h5>ひとまず終わり！</h5>
ここまででゲストログインはできなくなったかと思います。

あとは、ゲストログインを削除、編集できないようにします。

<h2>退会させないようにする</h2>

<h2>ルーティング</h2>
devise_for :usersになってる場合は、書き換えてください。


```rb
  devise_for :users, controllers: {
    registrations: 'users/registrations'
  }
```

<h2>削除しようとしたら、トップ画面へリダイレクト</h2>

私は論理削除にしています。

```perl:app/controllers/users_controller.rb
 def destroy_confirm
    @user = current_user
  end

  def destroy_user
    @user = current_user
    if @user.email == 'guestda@example.com'
      reset_session
      redirect_to :root
    else
      @user.update(is_valid: false)
      reset_session
      redirect_to :root
    end
  end
```
もしゲストユーザーが退会処理をしようとしたら、
ログアウトさせトップページにレダイレクトさせます。


<h2>編集させないようにする</h2>

ユーザー情報編集されると、
私の場合、「部署」「クラス（新入社員）」とか変更されると、
ゲストログインが壊れました。
なので、ゲストユーザーの場合には、
編集ページが表示されないようにしました。

```perl:edit.html.erb
<% if @user.email == 'guestda@example.com'%>
      　<p>ゲストユーザーはユーザー情報の編集ができません。</p>
      <% else %>
```
Dataiku：社名の由来とその読み方

たくさんの方々によく聞かれています。
「Dataikuはどういう意味？あと発音は？」

発音の前に、先にDataikuの由来を説明しましょう。

Dataikuは、Motel (Motor+Hotel)やbrunch(Breakfast+Lunch)のように2つの単語の音を混ぜ合わせたり、意味を組み合わせたりした2つの単語の組み合わせです。下記の２つがDataikuの組み合わせとなります。

- <font color="DarkCyan">Data (データ)：情報の一部分</font>
- <font color="DarkCyan">Haiku（俳句）：短く構成された日本の詩</font>

![Dataiku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/d9fe4df9-46bd-dc22-8a2e-ce3379c631cc.png)
データプロジェクトに関わる人や組織にとって、データのモデル完成までのプロセスは、時には長くてややこしいです。データサイエンティストの仕事を支援する複数のツールが、ときには、かえってプロセスを長くしたり、効率を悪くしたりすることもあります。また、データサイエンティストは、この場所でデータを整理し、あの場所で視覚化し、別の場所でモデルを作成してから、最終的には、デプロイや運用の前にすべてをつなぎ合わせる必要があります。

一方、「俳句」は素直さと構造を重視しています。そのシンプルさにも定評があります。Dataikuは、データプロジェクトが組織や人にとってどのようなものであるべきかを考えました。それは、最初から最後まで構造化されたプロセス、単一の流れです。

- あらゆる場所にデータがある
- ビジネスに成果をもたらす必要がある
- Dataikuを使わなければならない！


発音に関しては、Dataikuが創業されたフランス（ヨロッパ）では「ダタハイク」「ダタイク」と読みますが、日本はDataを「データ」と発音するので、「データイク」と読んでいます。

製品自体がエンド・ツー・エンドで俳句のように「単一の流れ」になっているDataikuの製品を、ぜひ一度お試しください!


原文： *[Pronouncing Dataiku](https://blog.dataiku.com/2014/08/07/pronouncing-dataiku)*
[JS]簡単なフォームバリデーション

##この記事について
JavaScriptの学習の記録。
学習している書籍の演習問題をヒントにBMI測定プログラムを作りました。
(掲載のコードは書籍に記載のコードではありません。)
フォームのバリデーションや正規表現について記載しています。

学習書籍
[いちばんやさしいJavaScriptの教本 第2版 ECMAScript 2017（ES8）対応 人気講師が教えるWebプログラミング入門 「いちばんやさしい教本」](https://www.amazon.co.jp/dp/B07RPT6K35/ref=sspa_dk_detail_1?psc=1&pd_rd_i=B07RPT6K35p13NParams&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyTk1QUjdHNFdHTVY1JmVuY3J5cHRlZElkPUExMDE3MDYzMjBZQUFLUURLNDRJWSZlbmNyeXB0ZWRBZElkPUEzOUszUExMMEJXMTVUJndpZGdldE5hbWU9c3BfZGV0YWlsJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)


##作ったもの

[BMI測定](https://codepen.io/Maro1027/pen/QWgbaXq)

機能
・全角入力してもjs側で半角にしてから計算する
・数値以外の文字が入力されていた場合は注意文言を表示

###バリデーションチェック部分JS
文字列の判定は「JS 正規表現 数値」などで検索すると参考サイト出てきます。
記号付きや桁数の指定もできるようです。

```javascript
// 全角→半角変換（数字のみ）
function changeStrHalf(str) {
    return str.replace(/[０-９]/g, function(s) {
        return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
    });
}

// 数値で入力されているかチェック
function isNum(num){
    var pattern = /^[0-9]+$/;
    return pattern.test(num);
}
```

参考サイト：
[[JavaScript] 全角⇔半角の変換を行う（英数字、カタカナ）
](https://www.yoheim.net/blog.php?q=20191101)[正規表現を用いて JavaScript で数値チェックを行う方法](https://webllica.com/javascript-number-check-function/)
EC2に自動でEIPを割り当ててくれるシェルスクリプト

# 概要
普段、Terraformを使用している私にとって、EC2を起動した際などに使用するEIPは
ドメインを割り振る関係上、簡単に変更できないように
Terraformのライフサイクルに含めたくないケースが多い。
そんなときに便利な
EIPを作成し、EC2へそのEIPを自動で割り当ててくれるシェルスクリプトを紹介する。



# 動作環境
- Linux
  - Debian [v10.8]
- Windows
  - WSL の Ubuntu [v20.04]
  - WSLの構築については以下を参照

https://qiita.com/mttk030/items/6fd9821120a5a2218e78



# シェルスクリプト

``` bash
#!/bin/bash
set -eu

create_and_set_eip () {
    # サーバ用Elastic IP作成 and EC2連携
    aws ec2 allocate-address --domain vpc --tag-specifications "ResourceType=elastic-ip,Tags=[{Key=Name,Value=${AWS_PROFILE}}]"
    aws ec2 associate-address \
    --allocation-id `aws ec2 describe-addresses --filter "Name=tag:Name,Values=${AWS_PROFILE}" --query 'Addresses[*].AllocationId[]' --output text` \
    --instance `aws ec2 describe-instances --filter "Name=tag:Name,Values=${AWS_PROFILE}" "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].InstanceId[]' --output text`
}

# [source set_aws_profile.sh] を実行し、デプロイ先を指定しているか確認
if [ ${AWS_PROFILE} = '******(アプリ名など)' ]; then
    create_and_set_eip
    echo '----- Elastic IP作成 and EC2連携完了 -----'
else
    echo '[source set_aws_profile.sh] を実行し、デプロイ先を指定して下さい。'
fi
```

# 説明


## 1. 事前準備
- `AWS CLI` のインストール
- AWSのクレデンシャル情報などを保存する、名前付きプロファイルの名前を  
  EC2のNAMEタグと一致させるようにする。(以下コマンドで設定するやつ)

``` bash
aws configure --profile ******(アプリ名など)
```

- 上記の名前付きプロファイルの名前を環境変数(`AWS_PROFILE`)に設定しておく

``` bash
export AWS_PROFILE=******(アプリ名など)
```


## 2. ポイント解説
- `1. 事前準備` で設定したように、**名前付きプロファイルの名前を  
  EC2のNAMEタグと一致させるようにする**ことで、デプロイ先が変わっても  
  上記シェルスクリプトをそのまま流用することができる
- 間違って操作するとヤバいことになるEIPの操作を自動化できる
- 以前紹介した、私のTerraform運用オペレーションに組み込むことができる

https://qiita.com/mttk030/items/fe11afddce39b9e5e60f



# 参考

[AWS CLIのフィルターとクエリーの使い方についてまとめてみた](https://dev.classmethod.jp/articles/aws-cli-filter-and-query-howto/)
OpenSSL で複数のホスト名に対応した自己署名証明書を作成するには

1 つのホスト名の場合は、`-subj` オプションで `/CN` にホスト名を指定して作成します。

```shell-session
$ openssl req -new -x509 -days 3650 -nodes -text -out test.crt -keyout test.key -subj /CN=$(hostname)
Generating a RSA private key
.................+++++
..................................................................+++++
writing new private key to 'test.key'
-----
```

複数のホスト名の場合は、`req` コマンドで秘密鍵を作成し、`x509` コマンドで自己署名証明書を作成する際、拡張属性を読み込むファイルを `-extfile` オプションで指定し、`v3_ca` セクション内の `subjectAltName` 属性にホスト名は `DNS:`、IP アドレスは `IP:` をつけ、`,` (カンマ) 区切りで指定します。

ここでは、拡張属性を標準入力 `/dev/stdin` から読み込み、最初に標準の設定ファイル `/etc/pki/tls/openssl.cnf` (環境によって異なります) を出力し、それに追加する形で `v3_ca` セクション内の `subjectAltName` 属性にドメインつきのホスト名、ホスト名のみ、IP アドレスの設定を行っています。なお、コマンドの入力は `EOF` までになります。

```shell-session
$ openssl req -new -nodes -text -out test.csr -keyout test.key -subj /CN=$(hostname)
Generating a RSA private key
...............................+++++
.....................................................+++++
writing new private key to 'test.key'
-----
$ openssl x509 -req -in test.csr -text -days 3650 -extfile /dev/stdin -extensions v3_ca -signkey test.key -out test.crt <<EOF
$(cat /etc/pki/tls/openssl.cnf)
[ v3_ca ]
subjectAltName = DNS:$(hostname), DNS:$(hostname -s), IP:$(hostname -i)
EOF
Signature ok
subject=CN = node-1.example.com
Getting Private key
```
Nest-js Headerデコレータのカスタム




###### tags: `nest-js`

```typescript
import { createParamDecorator, ExecutionContext,BadRequestException } from '@nestjs/common'
import * as admin from 'firebase-admin'

export const CustomHeaders =  createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const req = ctx.switchToHttp().getRequest()
    const value = req.headers[data].split('Bearer ')[1]
    
    return admin.auth().verifySessionCookie(value, true).then((decodedClaims) => {
        return decodedClaims.user_id
    }).catch(err => {
        console.log("err:",err)
        throw new BadRequestException('Error:Validation failed. Is the authorization appropriate?');
    })
  }
)

```



```typescript
@Post()
  async sample(@CustomHeaders('authorization') uid) {
    const result = await this.sampleService.sample(uid)
    return result
  }
```



## 解説

firebaseのセッションを受け取って(ヘッダーに添付),userIdを返すPipeを作ろうとしたが、既存のデコレータ(@Header())はPipeに互換性がなかったため、セッションを受け取ってuseridを返すデコレータを作った。

## 参照

https://docs.nestjs.com/custom-decorators
[axios] ファイルダウンロードができない or 空ファイルになってしまう現象の解消

フロント側はReact、サーバーサイドはRailsでファイルダウンロードが
うまくいかないケースがあり、それを解消した記事内容になります。

症状としては、axiosのissueにあったこのケースに当たります。
[Github | axios/axios | Empty response when responseType is blob or arraybuffer.](https://github.com/axios/axios/issues/1392)

サーバーサイドとフロント部分の結合部分なので、
原因の特的ができていなくて引っかかってる人が多そうですね。

私のケースの場合は、railsでheadの記述が不要だったのですが、
それだけじゃよくわからないと思います。
実装をみながら解消方法をみていきましょう。


## フロント側の記述

フロント側は以下のようなコードにしています。

```
$ yarn add file-saver
```

```tsx
import  { saveAs } from 'file-saver';
~~

export const fileDownload = () {
  axios
    .get(url, {
      ~~,
      responseType: 'blob',
    })
    .then((response) => {
      const blob = new Blob([response.data], {
        type: response.data.type,
      });
      saveAs(blob, downoloadFileName);
  });
}

```

(ちなみにaタグにdownload属性をつけるやり方もあります。)

これでフロント側はOKです。
ただ、空ファイルをダウンロードしてしまう場合があります。
const blobの上でブレイクポイントで止めて見ると、以下のような感じです。

![スクリーンショット 2021-08-27 11.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178099/b6a73c83-ad66-a3a8-2f0c-50d60afacbd0.png)

Blobのサイズが0になっていたり、画像やpdfをダウンロードしようとしているのですが、typeがtext/xmlになっています。

こんなときはサーバーサイド側に問題があります。

## サーバーサイド側の記述

私の触ったコードのケースではrailsでsend_data()を使ってfileの実体を送っていました。
記述は以下のような感じにもともとなっていました。

```ruby
def download
  upload_file = UploadFile.find(file_params)
  file = upload_file.file.blob.download  # モデルでhas_one_attached :fileを記述

  if send_data(file, disposition: 'attachment',
    filename: upload_file.file.blob.filename.to_s,
    ~~
    ~~
    head :no_content  # これがあるとうまくいかない。
  else
    ~~
  end
end
```

send_data()の引数自体は問題ないのですが、このコードはうまくいきませんでした。
head :no_contentが不要でした。
head :no_contentを削除すると、フロント側のレスポンスが以下のように変わります。

![スクリーンショット 2021-08-27 11.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178099/ee714aba-26e1-1a32-1060-afc11a7021a7.png)

Blobのsizeやtypeにちゃんと値が入ります。
ダウンロードした画像も表示できました。

![スクリーンショット 2021-08-27 0.54.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178099/da848b72-4ed5-1206-0162-9a5208296674.png)
PowerAutomateDesktopのexcelまとめ記事はpowerhacksさんの所が良い予感……


https://powerhacks.uishare.co/classroom/4983
にサンプル毎ありましたっ

powerhacksさん助かりますっ


私は偉くないので契約可否判断出来ないので
とりあえずQiitaで宣伝します。

それで偉い人が契約してpowerhacksさんにお金が行って
（主に私が要望している）ユーザーフォーラムなど設置して
もっとPowerAutomateDesktopユーザーが増えると良いと思っております。

もちろん案件じゃないヨ(^_^;)

現在解析中……
OKtaの検証用アカウントを取得してみる

検証に触ってみたかったので取ってみる。まずは無料30日アカウント

https://www.okta.com/jp/

![スクリーンショット_2021-08-27_11_07_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/9387520b-5b3f-91bc-c1c9-6afe31753346.png)

無料トライアル

![スクリーンショット 2021-08-27 11.09.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/02258da5-d22f-3491-3401-3e441b931cb4.png)

各項目を記載する。

会社等のメールアドレスを入力すると、ドメインの部分が変更される。
会社ドメインがサブドメインになって入力されてしまうので、既に存在するとエラーになる。

テキストボックスをクリックすると入力が可能になるので、**-xxxxxxxx**みたいに末尾に追加して一意のものにすれば大丈夫。


![スクリーンショット_2021-08-27_11_15_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/3dfdd69c-0243-ecb1-e28a-c14a3136629c.png)

登録すると大事な情報出てくるので忘れないように。
同時にメールが送信されていてテンポラリのパスワードが記載されているのでそれを使ってログインする。

パスワード等の設定をしたら２FAの設定。
モバイルにアプリを入れたら進む

![スクリーンショット 2021-08-27 11.20.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52141/efc62f2b-a854-0158-16fe-00851612c834.png)

設定すれば無事ログイン完了。
30日あればまあ試せる。
Vue.js開発中のエラー対処

##この記事について
Vue.js開発中のエラーについて備忘。

##開発環境

+ Mac OS
+ Node.js v12.13.1
+ npm 6.12.1
+ Vue CLI 3.9.0
+ vue 2.6.2
+ Mac OS

## エラー

```
[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.
```

原因
v-forのkeyに配列やオブジェクトを指定しているために発生するエラー

```html:NG
<div v-for="item in items" :key="item">
  {{item}}
</div>
```
```html:OK
<div v-for="(item, index) in items" :key="index">
  {{item}}
</div>
```
参考サイト：
[vuejs 開発時に遭遇したエラーリスト](https://hapicode.com/javascript/vuejs.html#avoid-using-non-primitive-value-as-key-use-string-number-value-instead-%E3%82%A8%E3%83%A9%E3%83%BC)
AWSのEC2インスタンスでAmazon Correttoを用いてJDK16を導入する

とあるサーバー向けソフトウェアでJava16を必要とする事があった。
すでにAmazon Corretto 8を用いてJDK8がインストールされていたが、
AmazonLinuxならAmazon CorrettoというOpenJDK互換のソフトウェアが簡単にインストールとバージョン切り替えが可能なのでその方法を説明する。
この記事ではAmazon Corretto 16のインストールについて解説するが、Corretto 8については次の記事を参考にしてほしい。→[AWSのEC2インスタンスでAmazon Correttoを用いてJDK8を導入する](https://qiita.com/honahuku/items/e5464bb3b102710b555a)

# 環境
```
AWS EC2 t4g.medium ARM AmazonLinux2
JDK 1.8.0_302 がインストール済み
```
今回はARM版のAmazonLinux2を利用しているが、x86でも手順はほぼ同様だと思われる。

# インストール
今回はyumからインストールを行う。rpmからマニュアルでインストールする方法はこちら→[AWSのマニュアル](https://docs.aws.amazon.com/corretto/latest/corretto-16-ug/generic-linux-install.html#rpm-linux-install-instruct)

Amazon Linux2でyumリポジトリを有効にする。
AWSが用意したAmazon Corretto用のリポジトリの公開鍵をインポートし、リポジトリをシステムに追加する。

```
sudo rpm --import https://yum.corretto.aws/corretto.key 
sudo curl -L -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
```

リポジトリの追加後、以下コマンドでインストールを行う。

```
sudo yum install -y java-16-amazon-corretto-devel
```
Amazon Corretto 8の場合と比較すると今回インストールするのはJDKだと予測できるが、公式ドキュメントにCorretto 16でのJDK,JREについての記載はなくJDKのリンクのみが記載されていた。

Amazon Corretto 16は`/usr/lib/jvm/java-16-amazon-corretto`にインストールされる。
Corretto 8の場合と異なり、ディレクトリ名にCPUアーキテクチャーの記載が無いが、yumのログを見ると

```
Downloading packages:
java-16-amazon-corretto-devel-16.0.2.7-1.aarch64.rpm                                                               | 197 MB  00:00:08     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : 1:java-16-amazon-corretto-devel-16.0.2.7-1.aarch64                                                                     1/1 
  Verifying  : 1:java-16-amazon-corretto-devel-16.0.2.7-1.aarch64                                                                     1/1 
```
となっているのでアーキテクチャーに応じたソフトウェアが適宜インストールされているようだ。

# バージョンの切り替え
環境によってはすでにJavaが入っており、`java --version`で旧バージョンが有効になってしまうことがある。

```
java -version
openjdk version "1.8.0_302"
OpenJDK Runtime Environment Corretto-8.302.08.1 (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM Corretto-8.302.08.1 (build 25.302-b08, mixed mode)
```
これは以下コマンドを利用してJavaの切り替えを行い対応する。

```
sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
 + 1           /usr/lib/jvm/java-1.8.0-amazon-corretto.aarch64/jre/bin/java
*  2           /usr/lib/jvm/java-16-amazon-corretto/bin/java

Enter to keep the current selection[+], or type selection number: 2
```
変更を確認する。

```
java -version
openjdk version "16.0.2" 2021-07-20
OpenJDK Runtime Environment Corretto-16.0.2.7.1 (build 16.0.2+7)
OpenJDK 64-Bit Server VM Corretto-16.0.2.7.1 (build 16.0.2+7, mixed mode, sharing)
```
変更が確認できた。
なお、JDKを使用している場合は以下コマンドも合わせて実行する必要がある場合がある。

```
sudo alternatives --config javac
```

# 参考記事
公式のAmazon Corretto 16インストール記事
https://docs.aws.amazon.com/corretto/latest/corretto-16-ug/generic-linux-install.html#rpm-linux-install-instruct

私が過去に執筆したAmazon Corretto 8についてのQiitaの記事
https://qiita.com/honahuku/items/e5464bb3b102710b555a
QNAPにgitea入れるメモ

# 背景など

QNAP（TS-453D-4G） に Gitサーバーを入れようと思い、GitLab を入れてみたら重すぎて使い物にならなかったので、Gitea を入れた時のメモ。

用途としては、DAW のプロジェクト管理で、LFS を使う前提でセットアップしてます。

今まで CentOS で構築した自宅サーバー上にあった、git リポジトリを移行する形で考えてます。

# 事前準備

QNAP の IP アドレスは固定にしておいた方が楽。

# インストール

インストールは ContainerStation > Create > Create Application から。

![gitea-cs-ca.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84947/e128e835-8056-9170-e002-eb0c96317232.png)

Application name と YAML を入力して Create で作成される。

## YAML

YAML の内容はひとまず下記のサイトの内容を貼り付ければ動くは動きそう。

https://hub.docker.com/r/gitea/gitea

```yaml
version: '2'
services:
  web:
    image: gitea/gitea:1.12.4
    volumes:
      - ./data:/data
    ports:
      - "3000:3000"
      - "22:22"
    depends_on:
      - db
    restart: always
  db:
    image: mariadb:10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=changeme
      - MYSQL_DATABASE=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=changeme
    volumes:
      - ./db/:/var/lib/mysql
```


必要に応じて、下記のサイトを参考に書き換える。

https://docs.gitea.io/en-us/install-with-docker/


### 変更点

同じ書式で version を 3 にしても問題なさそう。

```yaml
version: '3'
```

最新版を使う

```yaml
    image: gitea/gitea:latest
```

日時をJSTにするために `volumes:` に下記の2行を追記

```yaml
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
```

下記の DB 接続系の情報（特にパスワード関連）は書き換えておいた方が良さそう。

```yaml
      - MYSQL_ROOT_PASSWORD=changeme
      - MYSQL_DATABASE=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=changeme
```


# 初期設定

変更する場所

データベース設定 |　　 
-- | --
データベースのタイプ | `MySQL` を選択
ホスト | ホスト名を `localhost` から `db` に変更　（YAML のセクション名？）
パスワード | `MYSQL_ROOT_PASSWORD` に設定したもの。


LFS 使う場合には基本設定で localhost から ホスト名に変えておかないと、LFS 操作時に localhost に接続しようとしてこける。

* SSHサーバーのドメイン
* GiteaのベースURL


## あとから設定変更する場合

app.ini を直接編集するしかないっぽい。

パス

```
/Container/container-station-data/application/gitea/data/gitea/conf
```

app.ini を変更したら再起動



### LFS 関連の処理が localhost に接続しようとしてエラーになる場合

クライアントPC　からの接続時、IPアドレスやホスト名でアクセスしていたとしても、LFS 関連の処理は初期設定で行った下記の設定値を使ってアクセスされてしまう。

* SSHサーバーのドメイン
* GiteaのベースURL

初期値ではこれらの値は `localhost` になっているので、ホスト名などに変更しておく必要があるが、初期設定で行わなかった場合には、app.ini で変更する。

```ini
[server]
DOMAIN           = <host名>
SSH_DOMAIN       = <host名>

ROOT_URL         = http://<host名>:3000/
```



# その他

LFS は最初から有効になっているみたい。


## SourceTree 絡み

pushなどの際にパスワードを聞かれるの避ける

https://qiita.com/YKInoMT/items/a1f730b524aeecf83aaf


# 参考

https://medium.com/@yamasaKit/5-docker-composeを用いた-gitea-でサーバへの接続と日本語の登録-822cb78af40a

https://ytyaru.hatenablog.com/entry/2019/08/14/000000
Vagrant上のDockerでvscode＋xdebugを使いたい

## 気持ち
vagrant上に構築したDockerでLaravel環境の構築はできた。さあ次はデバッグ環境を整えるだけだ。アレ、どう設定したらええんや。

## やりたいこと
vscodeを使ってvagrant環境に接続し、dockerコンテナで実装したlaravel環境のデバッグをxdebugを使って実現する。

### 事前準備
- vscodeからvagrant環境に接続する為の「Remote-SSH」拡張機能をインストールしておく
- vscodeでxdebugを使用する為の「PHP Xdebug」拡張機能をインストールしておく
- vagrant上でdockerをインストールしておく
- dockerでlaravel環境を構築しておく
- コンテナのlaravelのプロジェクトをdockerホストと共有しておく

### 流れ
1. Vagrantfileに仮想マシンのIPアドレスの設定を記入する。
1. phpコンテナ※に接続し、xdebugのインストールを行う。
1. php.iniにxdebugの設定を記入する。
1. vscodeのlaunch.jsonの設定を編集する。

※php:7.4-apacheというイメージから作成したコンテナを使用しています。

### vscode上でvagrant環境にSSH接続する
Windowsであれば/Users/ユーザ名/.ssh/configを開いて、Vagarntの作業ディレクトリ上で`$ vagrant ssh-config`を実行し出力結果を記入する。

```shell
$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile ###ここには＜VirtualBoxの鍵ファイルのパス＞が出力される###
  IdentitiesOnly yes
  LogLevel FATAL
```

Hostは任意の名前でOKです。

```ssh:/Users/ユーザ名/.ssh/config
Host vagrant_env
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile ###＜VirtualBoxの鍵ファイルのパス＞を記入する###
  IdentitiesOnly yes
  LogLevel FATAL
```

あとはvscodeの左側にあるメニューバーから「Remote Explorer」のアイコンをクリックして接続を進めればよい。

## Vagrantfileに仮想マシンのIPアドレスの設定を記入する。
仮想マシンにIPアドレスを割り当てましょう。
以下の内容を追記します。

```ruby:Vagrantfile
config.vm.network "private_network", ip: "192.168.33.66"
```
上記IPアドレスは適当でOKです。

## phpコンテナに接続し、xdebugのインストールを行う

以下のコマンドを実行し、xdebugのインストールをします。

```shell
$ pecl install xdebug
$ docker-php-ext-enable xdebug # このコマンドを実行することでphp.iniファイル内にzend_extension=＜xdebug.soのパス＞を記載しなくて済む
```
私の環境ではxdebugのバージョンは3.0.4がインストールできました。

## php.iniにxdebugの設定を記入する
php.iniのパスは「/usr/local/etc/php/php.ini」になります。
ファイルを開いて以下の内容を追記します。

```ini
[xdebug]
xdebug.mode=debug
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_connect_back=1
xdebug.start_with_request=yes
xdebug.client_host=192.168.33.66 # Vagrantfileで設定した仮想マシンのIPアドレス
xdebug.clent_prot=9003
xdebug.discover_client_host=1
xdebug.idekey="vscode"
```

## vscodeのlaunch.jsonの設定を編集する
まずはdockerホストのlaravelプロジェクトのディレクトリをvscodeで開く。
そして左のメニューバーから「Run And Debug」アイコンをクリックして、「create a launch.json file」をクリックしてlaunch.jsonを作成する。

launch.jsonの内容を以下に書き換える。

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "stopOnEntry": true,
            "serverSourceRoot": "＜コンテナのlaravelプロジェクトのパス＞",
            "localSourceRoot": "${workspaceRoot}" # laravelのコンテナと共有しているdockerホスト側のパス。
        },
    ]
}

```

あとはvscodeのデバッグを実行すればよい。
React 型宣言について

# const

###使用例

```React:Const
const c = 1.23;

c = 5; //エラーが発生
```


### 特徴

* 変数の再代入が禁止されている
* 明らかな定数などには積極的に使用した方がよい


# var と let

### 使用例

```React:varAndLet

if(true){
    var v = 1.23
    let l = 4.56
}

console.log(v) //表示される
console.log(l) //エラーが発生
```
### 特徴

* varとletは変数の再代入が可能
* letはvarに比べてスコープが短い（同じ階層でしか生きられない）
* 出来る限りletを使うことで可読性が高くなる


# まとめ

型宣言にはそれぞれのケースに合わせたものがある。

コードの読み手に変数や定数のニュアンスを伝えるために、適切な型宣言を行う事をを意識したい。
Javaでシリアル通信するためにRXTXライブラリを使ってCOMポートを開いた

###あらまし

先日こんなことがあった

https://qiita.com/Rmecan/questions/066befcf0e7b700b3d42

解決したので報告

まず本プロジェクトの環境周りを
プログラムはほぼ触らずに新しいパソコンへ移植というお仕事

- Windows 7 32bit -> Windows Server 2016 64bit
- Java6 -> Java8
- シリアル通信で外部機械との通信あり、シリアル通信には`RXTX-2.1-7`というライブラリを使っている

次に起きた問題

```Java
// RS232Cポートをオープンする。この処理を実行すると
CommPortIdentifier RSport = CommPortIdentifier.getPortIdentifier("COM1");
```
```Java
// このエラーになる。（ rxtxParallel.dll と rxtxSerial.dll を見つけられませんだって )
> java.lang.NoClassDefFoundError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver 
// Javaが64bitだとこのエラーになる。（ 呼び出した.dllが32bit版だから動かせないよだって）
> java.lang.UnsatisfiedLinkError: C:\Windows\System32\rxtxSerial.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform thrown while loading gnu.io.RXTXCommDriver
```

###やったこと

- Javaの再インストール(64bit版をアンインストールして32bit版をインストールした)

Javaだから環境依存しないでしょ？と何も考えずに64bit版のJavaを入れたのも失敗
上にも書いたけどDLLが32bit版の場合は32bit版のJavaからでないと呼び出せない

ちなみに64bit版ライブラリもあるようだ。こちらだったら64bit版Javaでいいかもしれない。（が今回は32bitで押し通す)

http://memoforalljp.blog.fc2.com/blog-entry-25.html

- `C:\Windows\SysWOW64`に`rxtxParallel.dll`と`rxtxSerial.dll`を配置

以前は32bitOSだからsytem32でよかったけど64bitOSで32bitのライブラリを使うならここに入れる。
なぜならWindowsがリダイレクトするので。

- `RXTXcomm.jar`のパスをきっちりクラスパスに設定する

###試しに書いたサンプルコードを以下に記す

メモ帳で即席で書いたため汚いのはご愛敬で

```bat:run.bat
@echo off
@cd %~dp0

set JAVA_CLASSPATH=%任意のフォルダ%\RXTXcomm.jar

rem =========
rem コンパイル
rem =========
javac -cp "%JAVA_CLASSPATH%" Test.java

@if %errorlevel% equ 0 (cls) else (pause)

rem =========
rem java実行
rem =========
java -cp "%JAVA_CLASSPATH%" Test

pause
```
```Java:Test.java
import gnu.io.CommPortIdentifier;

class Test{

  public static void main(String[] arg){
    showJavaLibrary();
    try{
      // RS232Cポートをオープンする。
      CommPortIdentifier RSport = CommPortIdentifier.getPortIdentifier("COM3");
    }catch(Exception e){
      System.out.println(e.toString());
    }
  }

  public static void showJavaLibrary(){
    System.out.println("パス出力ここから=================");
    for (String str : System.getProperty("java.library.path").split(";")){
      System.out.println(str);
    }
    System.out.println("パス出力ここまで=================");
  }
}
```

さて実環境を直してきますか
AWSのEC2インスタンスでAmazon Correttoを用いてJDK8を導入する

とあるサーバー向けソフトウェアでJava16を必要とする事があった。
AmazonLinuxならAmazon CorrettoというOpenJDK互換のソフトウェアが簡単にインストールとバージョン切り替えが可能なのでその方法を説明する。
この記事ではAmazon Corretto 8のインストールについて解説するが、Corretto 16については次の記事を参考にしてほしい。→[AWSのEC2インスタンスでAmazon Correttoを用いてJDK16を導入する](https://qiita.com/honahuku/items/36e83367f6acac9947c8)

# 環境
```
AWS EC2 t4g.medium ARM AmazonLinux2
Javaは未インストール
```
今回はARM版のAL2を利用しているが、x86でも手順はほぼ同様だと思われる。

# インストール
今回はyumからインストールを行う。rpmからマニュアルでインストールする方法はこちら→[AWSのマニュアル](https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/amazon-linux-install.html#amazon-linux-rpm-install-instruct)

Amazon Linux2でyumリポジトリを有効にする。

```
sudo amazon-linux-extras enable corretto8
```

Amazon Corretto 8は、ランタイム環境（JRE）及び完全開発環境（JDK）の2種類が用意されている。
なお、JDKにはJREが含まれるのでJDKをインストールするならばJREをインストールする必要はない。

### Amazon Corretto 8をJREとしてインストールする場合
```
sudo yum install java-1.8.0-amazon-corretto
```
### Amazon Corretto 8をJDKとしてインストールする場合
```
sudo yum install java-1.8.0-amazon-corretto-devel
```
Amazon Corretto 8は`/usr/lib/jvm/java-1.8.0-amazon-corretto.<cpu_arch>`にインストールされる。

# バージョンの切り替え
環境によってはすでにJavaが入っており、`java --version`で旧バージョンが有効になってしまうことがある。

```
java -version
openjdk version "1.8.0_302"
OpenJDK Runtime Environment Corretto-8.302.08.1 (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM Corretto-8.302.08.1 (build 25.302-b08, mixed mode)
```
これは以下コマンドを利用してJavaの切り替えを行い対応する。

```
sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
 + 1           /usr/lib/jvm/java-1.8.0-amazon-corretto.aarch64/jre/bin/java
*  2           /usr/lib/jvm/java-16-amazon-corretto/bin/java

Enter to keep the current selection[+], or type selection number: 2
```
変更を確認する。

```
java -version
openjdk version "16.0.2" 2021-07-20
OpenJDK Runtime Environment Corretto-16.0.2.7.1 (build 16.0.2+7)
OpenJDK 64-Bit Server VM Corretto-16.0.2.7.1 (build 16.0.2+7, mixed mode, sharing)
```
変更が確認できた。
なお、JDKを使用している場合は以下コマンドも合わせて実行する必要がある場合がある。

```
sudo alternatives --config javac
```
# 参考記事
https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/amazon-linux-install.html
杉並区内の新型コロナウイルス感染者数（日ごと）のPDFをCSV変換

https://www.city.suginami.tokyo.jp/news/kansensho/covid-19/1058987.html

+ camelotは変換できなかったのでpdfplumberで変換
+ 年月が省略

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/edbc4a3a-ee7a-7b48-5537-2593a42e1b0d.png)

# プログラム

```python
import pathlib
import re
from urllib.parse import urljoin

import requests
from bs4 import BeautifulSoup

import pdfplumber
import pandas as pd

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}


def fetch_soup(url, parser="html.parser"):

    r = requests.get(url, headers=headers)
    r.raise_for_status()

    soup = BeautifulSoup(r.content, parser)

    return soup


def fetch_file(url, dir="."):

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    r = requests.get(url)
    r.raise_for_status()

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p


def str2date(s):

    lst = [None, None] + list(map(int, re.findall("\d+", s)))

    return lst[-3:]


url = "https://www.city.suginami.tokyo.jp/news/kansensho/covid-19/1058987.html"

soup = fetch_soup(url)
tag = soup.select_one("ul.objectlink > li.pdf > a")
link = urljoin(url, tag.get("href"))

p = fetch_file(link)

with pdfplumber.open(p) as pdf:

    dfs = []

    for page in pdf.pages:

        for table in page.extract_tables():

            df_tmp = pd.DataFrame(table).set_index(0).T

            if df_tmp.shape[0] > 2:

                # df_tmp.set_axis(["日にち", "感染者数"], axis=1, inplace=True)
                dfs.append(df_tmp)

df0 = pd.concat(dfs).reset_index(drop=True)

df1 = df0[df0["感染者数"].str.endswith("人") & (~df0["日にち"].str.endswith("計"))].copy()

# 日付変換
df_date = (
    df1["日にち"]
    .apply(str2date)
    .apply(pd.Series)
    .rename(columns={0: "year", 1: "month", 2: "day"})
    .fillna(method="ffill")
    .astype(int)
)
df_date["year"] = df_date["year"] + 2018
df1["日にち"] = pd.to_datetime(df_date, errors="coerce")

df1["感染者数"] = df1["感染者数"].str.rstrip("人").str.replace(",", "").astype(int)

df1.to_csv("suginami.csv", encoding="utf_8_sig")
```
SoftEtherで仮想LANカードが作れないエラーが出たとき

# エラー
```
Error occurred. (Error code: 31)
Installation of the Virtual Network Adapter device driver failed.
```

## うまくいった方法
vpnclientをmakeする前に

```shell
sudo ln -s /usr/src/linux-headers-$(uname -r)/ /lib/modules/$(uname -r)/build
```
をしてから、makeして、vpncmdを操作すると仮想LANカードが作れた。

# 参考文献
- [Raspberry Pi3(Ubuntu18.04LTS)でSoftEther VPN - Qiita](https://qiita.com/devzooiiooz/items/44a654b11aa23b5eb2f4)
- [ラズパイに SoftEtherVPN Client をインストール | ミコ-ラボ](https://mikolabo.net/index.php/2020/10/22/rasp-se-client/)
Arduino CLI の使いかた

次のページを参考にしました。
[Arduino CLI Installation](https://arduino.github.io/arduino-cli/latest/installation/)
[arduino-cliの使い方](https://blog.aoirint.com/entry/2020/arduino_cli_usage/)
[RaspberryとArduinoをシリアル通信する](http://soup01.com/ja/2020/08/12/raspberry-arduino-serialcomm/)

Raspberry PI 4 と、ArduinoUNO を使いました。
![IMG_20210827_101442.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6630201d-b0e5-eec5-798c-40eb0237e100.jpeg)


1) ダウンロード

```bash
wget https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_ARMv7.tar.gz
```

2) 解凍

```bash
tar xvfz arduino-cli_latest_Linux_ARMv7.tar.gz
```

次のファイルが出来ました。

```text
27369208 May 14 13:41 arduino-cli
```

このファイルはそのまま実行ができます。

3) バージョンの確認

```text
$ arduino-cli version
arduino-cli alpha Version: 0.18.3 Commit: d710b642 Date: 2021-05-14T12:36:58Z
```

4) ポートの確認

```text
$ ls -al /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 Aug 27 01:50 /dev/ttyACM0
```

5) /dev/ttyACM0 を使えるようにする
   ユーザーが uchida の場合

```bash
sudo adduser uchida dialout
```

6) ボードの確認

```text
$ arduino-cli board list
Port         Type              Board Name  FQBN            Core       
/dev/ttyACM0 Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr
/dev/ttyAMA0 Serial Port       Unknown
```

7) パッケージのインストール

```bash
arduino-cli core install arduino:avr
```

8) Arduino のプログラムの作成

```text:hello_world/hello_world.ino
// ---------------------------------------------------------------
/*
	hello_world.uno

				Aug/27/2021
*/
// ---------------------------------------------------------------
int count = 0;

// ---------------------------------------------------------------
void setup()
{
	Serial.begin(9600);
	Serial.println("*** start ***");
}

// ---------------------------------------------------------------
void display_proc(char msg[])
{
	Serial.print(msg);
	Serial.println(" " + String(count));
	delay(2000);
}

// ---------------------------------------------------------------
void loop()
{
	display_proc("aaaa");
	display_proc("bbbb");
	display_proc("cccc");
	display_proc("dddd");
	display_proc("eeee");

	count++;
}

// ---------------------------------------------------------------
```

9) コンパイル

```bash
arduino-cli compile --fqbn  arduino:avr:uno hello_world
```

10) アップロード

```bash
arduino-cli upload -b arduino:avr:uno -p /dev/ttyACM0 hello_world
```

プログラムはアップロードされるとすぐに実行されます。

11) Raspberry Pi で受信

必要なライブラリーのインストール

```bash
pip3 install pyserial
```

受信プログラム

```py:receive.py
#! /usr/bin/python3
import serial
if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    ser.flush()
    while True:
        if ser.in_waiting > 0:
            line = ser.readline().decode('utf-8').rstrip()
            print(line)
```

実行結果

```text
$ ./receive.py 
*** start ***
aaaa 0
bbbb 0
cccc 0
dddd 0
eeee 0
aaaa 1
bbbb 1
cccc 1
dddd 1
eeee 1
aaaa 2
bbbb 2
```

cu でも受信できます。

インストール

```bash
sudo apt install cu
```

実行結果

```text
$ cu -s 9600 -l /dev/ttyACM0
Connected.
*** start ***
aaaa 0
bbbb 0
cccc 0
dddd 0
eeee 0
aaaa 1
bbbb 1
```
【備忘録】npm run startで missing scriptエラーが出た場合の対処法

npm run startの結果下記エラー発生。
どうやらstartのコマンドがpackage.jsonに記載がないことが原因らしいため、色々調べてみた。

# エラー文

```
1 error generated.
make: *** [Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/●●/project/●●_web_server/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (node:events:394:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Darwin 20.6.0
gyp ERR! command "/usr/local/Cellar/node/16.7.0/bin/node" "/Users/●●/project/●●_web_server/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /Users/●●/project/●●_web_server/node_modules/node-sass
gyp ERR! node -v v16.7.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Build failed with error code: 1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.14.1 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node-sass@4.14.1 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/●●/.npm/_logs/2021-08-27T00_05_44_201Z-debug.log
```

# 解決策

```
rm -rf node_modules
rm -f package-lock.json
npm i
npm run start
```

こちらの記事を参考にさせていただきました。

https://www.fixes.pub/program/505786.html
cssで要素を下から上に表示させる

cssで要素を下から上に表示させる方法になります。
各記述した内容の、解説もしております！
記述を変えれば、表示させる開始時間など変えられます。

##例)コード
太郎を下から上に表示させます。
こちらは
・最初は表示されていない
・1秒後にアニメーション開始
・下から上に0.5秒で表示させる

```perl:HTML
<p class="name">太郎<p>
```


```perl:css
.name {
    opacity:0;
    animation-name:anime;
    animation-duration:0.5s; 
    animation-delay: 1s;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
   }
   @keyframes anime ​{
    ​0% {
     ​opacity: 0;
     ​transform: translateY(30px);
    ​}
      ​100%{
        ​opacity: 1;
         ​transform: translateY(0);
     ​} 
    ​}
```
#解説

```perl:css
name {
   ​opacity:0; #要素の不透明度を設定.0は透明
   ​animation-name:anime;  #@keyframesと同じ名前の必要あり
   ​animation-duration: 0.5s; #アニメーション周期が完了するまでの所要時間を設定します。0.5だと素早くで画面に表示されます。5sだと５秒かけてゆっくり表示されます。
   ​animation-delay: 1ｓ; #アニメーションが起動するまでの時間。5sにすると画面更新5秒後にアニメーションが開始する。
   ​animation-iteration-count: 1; #アニメーションが再生される回数を指定します。
   ​animation-fill-mode: forwards; #アニメーション再生中・再生後のスタイルを指定します。こちらは、再生後、最後のキーフレーム（100%）のスタイルが適用される。
  ​}
  ​@keyframes anime {   #@animation-nameと同じ名前の必要あり、今回は「anime」
    ​0% {              
     ​opacity: 0;
     ​transform: translateY(30px); #0%なので、アニメーション始まった際に、transform: translateY(30px);の場所にアイテムが配置される
    ​}
      ​100%{
        ​opacity: 1;
         ​transform: translateY(0); #100%なので、アニメーション終わった際に、transform: translateY(０0x);の場所にアイテムが配置される
     ​} 
    ​}
```
リモートデスクトップ切断後に自動ログインする方法

# 概要 
通常、Windows10でリモートデスクトップ接続すると、接続を受けた側のローカルPCはログイン画面になります。
そのまま、リモートデスクトップ接続を切断するとローカル側
PCはログイン画面のままになってしまい、ローカル側のPCで一度、ログイン操作をする必要がありました。

# Windowsの再起動

リモートデスクトップ接続の切断後に自動ログインする方法としては、ローカル側のPCで予め自動ログイン設定をしておき、Windowsを再起動させる方法があります。

###自動ログインの設定

1. キーボードのWindowsとRキーを同時に押下し、「control userpasswords2」と入力して実行します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667007/165d9c63-dc2c-8149-8fa5-f0b2a7242be5.png)

2.ユーザーアカウントのダイアログが表示されたら、
「ユーザーがこのコンピュータを使うには、...」のチェックを外して適用ボタンをクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667007/1eb04af7-1345-4523-602c-4a3de25d2592.png)

3.自動サインインのダイアログが表示されたら、パスワードを入力します。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667007/8dc6130e-4824-ade8-bc8a-c3ba48fab31d.png)




Windows7までは、リモートデスクトップ接続状態でスタートメニューから直接、再起動やシャットダウンすることは出来なかったので、
シャットダウンや再起動のバッチファイルを作成しておく必要があったのですが、
Windows10では、スタートメニューで再起動やシャットダウンが出来るようです。

# バッチファイルを使用した自動ログイン
ローカル側のPC上に、バッチファイルを作成し、リモートデスクトップ終了時に実行することをで、ローカル側PCを自動ログインして切断することが出来ます。
(パスワードのパラメータは、ローカル側PCに設定されていない場合は不要)

```bat:rdp_disconnect_auto_login.bat
tscon 1 /dest:console /password:1234
```

ただ、このままバッチファイルを実行してもアクセスエラーとなってしまうので、管理者権限で実行する必要があります。
予めショートカットを作成し、管理者権限で実行するにチェックを入れておくと便利です。

上記のバッチファイルを右クリックして、ショートカットのタブより詳細設定ボタンをクリックします。
詳細プロパティのダイアログが表示されたら、管理者として実行のチェックを入れでOKボタンをクリックします。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667007/20148fc6-4136-8101-17a2-5fc8e000d378.png)

尚、この方法は、バッチファイルにログイン情報を直書きすることになるので、本番環境で使用するのは注意が必要です。
Swift バイナリツリー②

Swift　バイナリツリー②

前回のバイナリツリーに挿入する,検索する関数

```Swift:
//挿入

  public func insert(value: T) {
//小さければ左に行く
    if value < self.value {
//if let構文
      if let left = left {
        left.insert(value: value)
      } else {
//値がなければノードを作成し、親ノードを設定する
        left = BinarySearchTree(value: value)
        left?.parent = self
      }
//右に行く場合
    } else {
//if let 構文
      if let right = right {
        right.insert(value: value)
      } else {
//値がなければノードを作成し、親ノードを設定する
        right = BinarySearchTree(value: value)
        right?.parent = self
      }
    }
  }

//検索
  public func search(value: T) -> BinarySearchTree? {
//左をサーチする再帰処理
    if value < self.value {
      return left?.search(value)
    } else if value > self.value {
//右をサーチする再帰処理
      return right?.search(value)
    } else {
      return self  //発見！
    }
  }
```
【GCP】g-gen関連の記事

https://www.youtube.com/watch?v=ScC2-_Cg0NY
冒頭と17:20～の質問部分で合弁会社設立について触れられている。

https://japan.zdnet.com/article/35175317/
https://japan.techrepublic.com/article/35175329.htm
GCP以外のパートナーを含めたビジネス展開について。

https://g-gen.co.jp/#services
g-genのHP。
t分布を数値実験により求める

#t分布
形状としてはほとんど、正規分布と同じ形をしています。

t分布とは、母分散がわからないとき、不偏分散・母平均で標準化したサンプル平均の確率分布です。

母分散$\sigma^2$・母平均$\mu$として、
サンプルの要素$x_i$は正規分布$N(\mu,\sigma^2)$に従うとします。

仮に、母分散がわかるとき、母分散$\sigma^2$・母平均$\mu$で標準化したサンプル平均値$\bar{x}$(要素数n)の確率分布は$N(\mu,\sigma^2/n)$となります。


**では、母分散がわからず、サンプルの不偏分散・母平均で標準化した場合、サンプル平均値の確率分布はどうなるでしょうか**

###補足
母平均がわかっていると仮定している部分に引っ掛かるかもしれません。
検定問題では、母平均は帰無仮定内で仮定されます。
推定問題では、母平均は変数とし、母平均を推定するためにt分布が使われます。
以上より、t分布においては母平均は確定値として扱ってよいのです。

#数値実験
前述の内容より
サンプル平均値$\bar{x}$(要素数n)の確率分布は

* 母分散$\sigma^2$・母平均$\mu$で標準化　
* サンプルの不偏分散・母平均で標準化

この二つで分布が変わるようです。
試してみましょう

```python
import numpy as np
import matplotlib.pyplot as plt
import math

n_a = 3
sample = 1000000
mu_a = 1
sigma = 1

a = np.random.normal(
    loc   = mu_a,      # 平均
    scale = sigma,      # 標準偏差
    size  = (sample ,n_a),# 出力配列のサイズ
)




"""
不偏分散
"""
hoge = a - np.mean(a,axis=1,keepdims=True)
hoge = np.power(hoge,2)     #要素二乗
unbiased_variance_a = np.sum(hoge,axis =1) / (n_a - 1)  #不偏分散なので n-1　で割る

"""
平均
"""
average_a  =  np.mean(a,axis=1,keepdims=False)

"""
avrage_a　の標準化
"""
normed_average = (average_a - mu_a) / (unbiased_variance_a /math.sqrt(n_a) ) 


"""
母分散で標準化
"""
normed_average_population = (average_a - mu_a) / (sigma/math.sqrt(n_a) ) 


fig, ax = plt.subplots()

ax.hist(normed_average,bins=200,range=(-20,20),alpha = 0.5,label = "unbiased_variance")
ax.hist(normed_average_population,bins=200,range=(-20,20),alpha = 0.5,label = "pupulation_variance")

ax.legend()
ax.set_xlim(-20,20)

plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/88497f4b-889d-0b46-ccda-2bb8cdfa6fd1.png)

不偏分散を使用したほうが横に広がっていることがわかります。
これは、正規分布とt分布を比較した際の特徴です。


標本の要素数を増やすと、どんどん二つは近づいていきます。
###n = 2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/d0ce0c6e-e764-0bc4-fd38-4227a801d418.png)

###n = 3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/e753cf56-5ea6-0337-4475-bec7a858d25e.png)


###n = 5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/440156fb-10f3-7eb4-66a2-9710fb935443.png)

###n = 8
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/c3446035-53dc-cbec-f9fc-3e3465992e7d.png)


###n = 10
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/8bbbcb31-5078-b708-c294-67b6836d2b9f.png)

###n = 20
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/e2f51672-8d97-55ca-821d-2a97e0c31576.png)

###n = 100
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/f3ac0813-1d1d-ce04-d198-b8be5f76cc1e.png)


nが100にもなると完全に一致しています。
【初心者向け】Gradleを使ってSpring BootでWebアプリを作るならとりあえず追加したほうがよい依存関係の設定

#はじめに
Spring初心者がGradleを使ってWebアプリを作ろうとしたとき、
依存関係のエラーがなかなか解決せず試行錯誤した結果、
結局のところGradleのビルド定義ファイル(build.gradle)の依存関係定義の設定漏れだった、ということがよくあります。（体験談）
（プロジェクトの新規作成時に必要な依存関係を追加していればよいのですが、初心者はすっ飛ばしてしまいます。その場合、後から手動で依存関係を追加します。）

そこで、初心者がSpring Bootアプリを作るならまずは追加しておくべき
Gradleのビルド定義ファイルの依存関係をまとめました。


#何も考えずにプロジェクトを作成してしまった・・・
何も考えずにSpring スタータープロジェクトで新規作成した場合、
build.gradleは以下のようになっています。

```gradle
plugins {
	id 'org.springframework.boot' version '2.5.4'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
	useJUnitPlatform()
}
```

この状態で色々なサイトで参考にした情報をもとにソースコードを書いていくと、
依存関係のエラーになることが多々あります。

# build.gradleに依存関係の定義を追加する

ここで、以下のように依存関係の定義を追加します。

```gradle
dependencies {
	implementation('org.springframework.boot:spring-boot-starter-web')
	implementation('org.springframework.boot:spring-boot-starter-validation')
	implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
	implementation('org.springframework.boot:spring-boot-starter-jdbc')
	implementation('com.h2database:h2')
	implementation('org.springframework.boot:spring-boot-devtools')
	
}
```

これで最低限、Spring BootでthymeleafやDBを使ったWebアプリを作ることができます。

# 各設定の補足説明
## spring-boot-starter-web

Spring BootでWebアプリケーションを作るのに必須。

## spring-boot-starter-validation

Spring Bootで@Sizeや@NotNullなどのアノテーションを用いたバリデーション機能を使うのに必要。

参考：https://qiita.com/tatetsujitomorrow/items/a397c311a95d66e4f955

## spring-boot-starter-thymeleaf

「Thymeleaf」はSpring Bootで標準的に使われるテンプレートエンジンの1つ。
普通のHTMLファイルのタグに記述を追加していくだけで使える。
→学習コストが低い、デザイナーとの協業が容易といったメリットがある。

公式サイト：https://www.thymeleaf.org/
引用記事：https://it-kyujin.jp/article/detail/169/

## spring-boot-starter-jdbc
Spring BootでJDBCを使ってRDBにアクセスするために必要。
ライブラリが持つメソッドに引数としてSQL文を渡すことで、DBの検索や更新を行うことが可能。
Spring は、JdbcTemplate と呼ばれるテンプレートクラスを提供し、
SQL リレーショナルデータベースと JDBC を簡単に操作できるようにします。

参考：https://spring.pleiades.io/guides/gs/relational-data-access/
　　　https://spring.pleiades.io/spring-framework/docs/current/reference/html/data-access.html#jdbc-JdbcTemplate


## com.h2database:h2
Spring Bootで「H2 Database Engine」を使うために必要。
H2 Database Engineは、Javaで実装されたRDBの１つ。
インストールの必要がないので、手軽に使える。
DBが必要なWebアプリを作るときにDB周りのテストをしたいときに便利。

参考：https://zenn.dev/developma/articles/548b9652b01131

## spring-boot-devtools
Spring Bootで「Spring Boot DevTools」を使うために必要。
プロジェクトを停止→再起動することなく、ソースコードを反映させることができるため、
ソースコードの修正と動作確認を繰り返し行いながら開発を進めたいときに便利。

参考：https://qiita.com/IsaoTakahashi/items/f99d5f761d1d4190860d
【JavaScript】データ型とは

#はじめに
こんにちは。JavaScriptを学習中の佐藤です。
今日は、データ型についてアウトプットしていきます！

##データ型とは
データの分類のことで、数値型や文字列型などのデータ型がある。

また、JavaScriptは「動的型付け言語」とも呼ばれ、変数に格納された値によってデータ型が定義される。実際のコードでみてみましょう。


```javascript:JavaScript
let width = 'wide'; //文字列型で定義
width = 1200; //数値型に変更される
```

というように、後から代入された値によってデータ型が変更される。
<br>
また、変数の型はtypeof演算子を使って確認できる。

```javascript:JavaScript
let width = 'wide'; 
console.log(typeof width); //string（文字列型）

width = 1200; 
console.log(typeof width); //number（数値型）
```
<br>
一方、「動的型付け言語」とは反対に、1度定義したデータ型を変更できない「静的型付け言語」というものも存在する。それぞれメリット・デメリットがあるので目的に合ったものを使用していきます。

データ型は、今回紹介したもの以外にも複数あるので、ご興味のある方は調べてみてくださいね。

#最後に

ここまでJavaScriptのデータ型について記事にしました。
静的型付け言語についても、学習を進めながら記事にしていきたいと思います！