OmniAICreator/Qiita-1.07M huggingface dataset:
スイスに新しいAWSリージョンがオープンしたらしい。

2022年11月8日(投稿ちょっと遅れた)に、スイスの都市(チューリッヒ)にAWSリージョンが開設されたらしいです！

僕は北欧の国が好きなので記事にしました。笑

↓Source:
[AWSニュースブログ　新しいAWSリージョンがスイスにオープン](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)

# 概要
|NO.|コード|場所|AZ数|
|:---:|:---:|:---:|:---:|
|28個目|eu-central-2|スイス(チューリッヒ)|3個|

>この新しいリージョンには、チューリッヒの近くにある 3 つの完全に冗長なアベイラビリティーゾーンがあります。データ常駐要件を満たしながら、アプリケーションへの低遅延アクセスを顧客に提供します。

今回のチューリッヒリージョンが追加されたことで、ヨーロッパでは８個のリージョンを有しています。(スイスのリージョンが開設されてから数日後にスペインリージョンが開設されました。後日記事出します。)

ちなみに欧州での最初のリージョンは、アイルランドリージョンで2007年に開設されています。

AWSがスイスに関与したのは、AWSが立ち上げられて以来、協力関係があり、2016年にはAWSのオフィスが置かれ、現地のチームができていたようです。

リージョンは今回(2022)でしたが、すでにエッジロケーションは2017年次に、CloudFrontエッジロケーションとDirect Conectロケーションが開始されていました。

# サービス
>ワークロードは、 C5、 C5d、 I3、 I3en、 M5、 M5d、 M6gd、 R5、 R5d、およびT3インスタンスを使用でき、AWS サービスの長いリストを使用できます。 Amazon API Gateway、  AWS AppConfig、  AWS Application Auto Scaling、  Amazon Aurora、  Amazon EC2 Auto Scaling、  AWS Config、  AWS Certificate Manager、  AWS CloudFormationを 、  AWS CloudTrail、  Amazon CloudWatch、Amazon CloudWatch Events、Amazon CloudWatch Logs、  AWS CodeDeploy、  AWS Database Migration Service (AWS DMS)、AWS Direct Connect、  Amazon DynamoDB、  Amazon Elastic Block Store (Amazon EBS)、Amazon Elastic Compute Cloud (Amazon EC2 )、  Amazon Elastic Container Registry (Amazon ECR)、  Amazon Elastic Container Service (Amazon ECS)、AWS Fargate、  Amazon ElastiCache、  Amazon EMR、  Amazon OpenSearch Service、 Elastic Load Balancing、Elastic Load Balancing – Network (NLB)、Amazon EventBridge、Amazon Simple Storage Service Glacier、  AWS Identity and Access Management (IAM)、  Amazon Kinesis Data Streams、  AWS Key Management Service (AWS KMS)、  AWS Lambda、AWS Marketplace、  AWS Health Dashboard、  Amazon Relational Database Service (Amazon RDS)、  Aurora PostgreSQL、Amazon Redshift、  Amazon Route 53、  Amazon Virtual Private Cloud (Amazon VPC)、  AWS Secrets Manager、  Amazon Simple Storage Service (Amazon S3)、  Amazon Simple Notification Service (Amazon SNS)、  Amazon Simple Queue Service (Amazon SQS)、  AWS Step Functions、  AWS サポート API、  Amazon Simple Workflow Service (Amazon SWF)、AWS Systems Manager、AWS Trusted Advisor、  VM Import/Export、  AWS VPN、および AWS X-Ray。



これからもAWSの進展が楽しみです！
JavaScript参考サイト

https://www.youtube.com/watch?v=HeLnMQ-R86M


https://www.youtube.com/watch?v=ig3GosWuKF0&t=6214s



https://www.youtube.com/watch?v=gs0l4rsQCGM&t=2904s



https://www.youtube.com/watch?v=E08jeQBa1D0


https://www.youtube.com/watch?v=pnsieVYy72M&list=PLwM1-TnN_NN7-zdRV8YsGUB82VVhfYiWW


https://ja.savefrom.net/1-youtube-video-downloader-144.html

https://www.youtube.com/watch?v=IlOhmnCrMog

https://www.youtube.com/watch?v=f38nYM_Z-Eo

https://www.youtube.com/watch?v=ZCt06tXxtFg&list=RDCMUCHxqQ8bUg5F2GW79D_DvSjQ&index=2

https://www.youtube.com/watch?v=Uqm642_O52U

https://qiita.com/hari64/items/47568790dc92100e4e77

https://atmarkit.itmedia.co.jp/ait/articles/2301/16/news032.html#_ga=2.117102979.469114552.1674393383-1763075561.1647833802
SourceTreeからコミットを試みるとHuskyのpre-commitでエラーになる（husky - pre-commit hook exited with code 127） 

SourceTreeからコミットを試みるとHuskyのpre-commitでエラーになる（husky - pre-commit hook exited with code 127） 

Huskyでpre-commitが設定してあるプロジェクトに対し、SourceTreeからコミットを行った際、
```
.husky/pre-commit: line 4: yarn: command not found
husky - pre-commit hook exited with code 127 (error)
```
というエラーが出てコミットできませんでした。

pre-commitを確認してみると、
```
yarn lint
```
という箇所があり、 yarn が見つからないことが原因のよう

### 対策
https://community.atlassian.com/t5/Bitbucket-questions/SourceTree-Hook-failing-because-paths-don-t-seem-to-be-set/qaq-p/274792

```
open /Applications/SourceTree.app/Contents/MacOS/SourceTree
```
で、SourceTreeを起動することによってyarnのパスを通しています。

ただし、毎回コマンドを打ち込むのも面倒なので、
```
source-tree.command
#!/bin/sh
open /Applications/SourceTree.app/Contents/MacOS/SourceTree
```
という形でバッチファイルを作成し、権限を与え、このファイルをダブルクリックすることでSourceTreeを起動

### 参考サイト
https://blog.kimizuka.org/entry/2022/05/02/130441
【IT基本用語】カーネル、シェル、デーモン

# カーネル
OSの中核となるソフトウェア。**ハードウェアとソフトウェアの仲たち**をしてくれるメモリやCPUに仕事をするように指示をだしてくれていたり、メモリやCPUの順番を調整してくれたりしている。
# シェル
外部からの入力をコンピューターに伝えるプログラムのこと。**人間とコンピューターの仲たち**をしてくれる。カーネルとのやり取りはシェルを通しいて送られる。

#### シェルの種類

- sh系
    - .bash .ksh .sh
- csh系
    - .csh .tcsh
- 両方に属さず
    -  .zsh


# デーモン

いろんなことをしてくれる常駐プログラム。メモリ上で動いている。デーモンの名前は最後に「d」がついている(httpd, ftpd, syslogd)。
MySQLの数値型は最大値が決まっている、(数値)は最大桁数ではない

よくやらかすので備忘録として残しておきます。

MySQLのテーブル定義には、INTEGERなど整数型・文字型などで()に桁数がつくパターンとつかないものがあります。
数値型に関しては、`（）`の中身が最大桁数を示すものではないので、Oracleの知識などで考えるとミスを起こすことがあります。

例えば以下のようなテーブルを考えてみます。
```
CREATE TABLE `column_max_size` (
  `id` int NOT NULL AUTO_INCREMENT,
  `column_int` int(11) unsigned zerofill DEFAULT NULL,
  `column_tinyInt` tinyint(1) DEFAULT NULL,
  `column_varchar` varchar(255) DEFAULT NULL,
  `column_int_2` int(8) unsigned zerofill DEFAULT NULL,
  `column_int_default` int DEFAULT NULL,
  `column_tinyInt_default` tinyint DEFAULT NULL,
  PRIMARY KEY (`id`)
) 
```

これの最大値を入れると以下のようなデータになります。
少なくともtinyintだったら最大が「1桁」ではないですね。
※varcharは見切れていますが、255文字入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/6f89798e-935e-ae7e-4063-1cb6d6c59d83.png)

## MySQLのINTやtinyIntの桁数は決まっている
Oracleユーザーであれば、後ろの`(10)`などを見ると「最大桁数」と捉えてしまいがちですが、
MySQLでは必ず最大桁数、というわけではなく違う意味を持ちます。
http://dbinfo.sakura.ne.jp/?contents_id=102

**INTやtinyintなどの整数型は最大桁数が決まっています。**
MySQLではINTやtinyIntは以下のように、最大値・最小値が決まっています。
というものの、整数型によって確保するバイト領域が決まっているため、その範囲が最小～最大となります。
https://dev.mysql.com/doc/refman/5.6/ja/integer-types.html

では、後ろの`(10)`は何を示すのか？

### ()の中身の意味はそれぞれで異なる。
INTなどの()は桁数ですが、この桁数部分は表示桁数です。

例えば、以下のような定義に関して、データの1を登録した場合は`00000001`という表示になります。
なぜなら、`zerofill`オプションが付いているので、`(8)`で定義された8桁目までは0で埋められます。
逆にMAX値を入れた場合は、`4294967295`の値になります。
```
  `column_int_2` int(8) unsigned zerofill DEFAULT NULL
```

### tinyint(1)とはなにか？
「tinyint(1)ってなんだよ！！最大値127で（1）って桁数じゃないじゃん！！！」
ということがありますが、これの(1)というのは別です。

どうやら、MYSQLにはBOOLEAN型が存在せず、tinyint型に内包されています。
そのBOOLEAN型を示すのが`tinyint(1)`らしいのです。

https://blog.s-giken.net/29.html

ややこしい(;^ω^)。

### ちなみにvarcharなどの文字列は…
**これは桁数を示しています。**
ごっちゃになりがちなので、MySQLに関しては型の最大値は調べてやった方がいいかもしれません。
contabo VPSにVNCパスワードを設定してみた

VNCで接続しようとしたところサーバーのパスワードではログインできなかった。
調べるとVNC用のパスワードを設定する必要があることが分かった。

# パスワードを設定する
 VPS controlを開く

- Manageをクリックする

- VNCパスワードをクリックする

 <img width="400" alt="vncpass" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/b1ae6f3c-bfdd-c83f-82c3-a883446d363b.png">


- パスワードを入力する

<img width="400" alt="vncpass2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/6a55a382-2bb6-5fa4-903a-af697ea9f98d.png">

# VNCで接続する
- サーバーIPアドレスを入力
<img width="400" alt="vnc1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/42f456ca-2f54-fdea-fa9d-e1fe584029ce.png">

- VNCパスワードを入力
<img width="400" alt="vnc2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/ba188faa-6724-f769-28c6-fb893f7c7e82.png">

- 無事接続できた
- サーバーアカウントを入力

<img width="400" alt="vnc3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/3fb08593-679a-6d50-a8b8-0b9291817c50.png">

- ターミナルソフトでログインしたときと同じ表示がされた

<img width="400" alt="vnc4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/fa656f30-3f04-2876-8c23-517dcd8cdd54.png">
1年間社内LTを続けて学んだこと


つい先日社内LTを始めて1年が経過したので、記録として感想や良かったことなどをまとめました。

# 前提
- 会社規模
    - エンジニアが20人弱

- LTについて
    - 毎週実施（ただし、発表者がいなかったら中止）
    - 業務時間に実施（ただし、準備などは業務外で行う）
    - 時間は10分/1人
    - 途中からLTの発表が人事評価で＋に評価されるように

# 継続するためにしたこと

### 自分が一番多く発表する
LTがないと実施自体がなくなってしまい、また、その状態が続くとLT自体が廃れてしまうと思ったので、参加者が少ない時は可能な限りで自分が発表側に回るようにし、LTが実施されていることが普通の状態になることを目指しました。

昔読んだwebの記事に書いてあったことですが、「自分以外のモチベーション管理は非常に難しいので、場を提供し続けることが大事」という考えを非常に参考にしています。やはり、やる気になるタイミングや取れる時間には、人それぞれ差があります。他の人も同じモチベーションでやってくれるはずと勝手に期待してしまうと、自分も相手も不幸になってしまいます。
そのため、周りのモチベーションを高めて、LTの参加・発表人数を増やす作戦は今回はあまりしませんでした。どちらかというと、それぞれのモチベーションが高い時に発表できる環境を作ることを意識して、LTの会がなるべく途切れないように、LTの発表を続けました。

(実は3年ほど前に同じようなLTを行なっていましたが、なかなか発表者が集まらず自然消滅していった歴史もあります...)

### LTネタをみんなに共有する
業務で気づいたことやQiitaなどで得た情報でLTネタになりそうなものは積極的に共有しました。

自分が多く発表するために、アンテナを広くしていろんな情報を見るようにしていました。いろんな情報を探す中で、LTに使えそうなももあれば、興味を惹かれないものや今の自分の能力的には難しいなと思うものもあります。ただし、自分がそんなにでも、誰かの琴線に触れることはあります。なので、気になったものや面白そうなものは、誰かの強みや興味に引っ掛かればいいなと思い、情報の共有をしていました。

たまに、自分のネタがなくなることもあったのですが、それは気合いで乗り越えました...!

**LTネタを探すところ**
- Qiita
- はてブ
- 他社の技術ブログ
- Twitter
- conpassで面白そうなイベントを探して参加
- AWSのイベントに参加

# LTを実施して良かったこと

### 勉強する習慣がついた
毎月2回程度の発表を意識していたので、そのためのネタ探し、発表のための調査、資料作成などで勉強する習慣がつきました。
ネタ探しについては、今までだと目が滑っていた記事などについても、これはどういう原理なんだろうか、社内で役に立てられないかのような視点で見られるようになったので、考える力もついたと思います。

また、資料作成のために、様々な環境で検証・動作確認については、全てDockerで環境を構築して行いました。（Dockerはローカルを汚さずに検証できるのがいいですね）
こういった小さい検証を環境を作って、PDCAを回していくことは業務でも活きる機会が多かったので、LTで練習・習慣化できたのは良かったと思います。

### 発表する練習になる
自社ではなかなか会議などはなく、決まったフォーマットで発表するなどの機会はほとんどありませんでした。通常の業務においてはこれは非常に良いことなんですが、たまに発表をするとなると、緊張してどもってしまったり、うまく説明できないこともありました。
LTは1回10分という短い場ですが、発表の練習ができて良かったです。
最初はたどたどしい発表でしたが、最近では割とスムーズな発表ができていると感じています。

### 新しいことを学ぶことができる
いろんな人のLTを聞くことで今まで知らなかったことを知ることができました。
LTのルールとしては、内容は技術に関するものというざっくりしたものだけだったので、割となんでもありでした。
そのため、聞いたことあるけどまだ勉強してなかったみたいなものから、全く聞いたことのない技術まで、いろんなことを発表で聞くことができました。
自分で行う情報収集は、どうしても自分の興味のある範囲に偏りがちなので、他の人の発表に聞くことはとても勉強になりました。

また、チームメンバーの今まで知らなかった強みや興味などを知る良い機会になりました。

# 今後やりたいこと
ここは個人の目標です

### LTの質の向上
LTの時間が短いこともあり、内容がどうしても導入部分が中心になったり、初学者向けになったりしていました。
わかる人はどうしても減ってしまいますが、特定の人に刺さるような踏み込んだ内容の発表やガッツリ調査した内容の発表も今後はしていきたいなと思っています。

### 外部イベントへの挑戦
社内LTで発表に慣れてきたので、社外のイベントにも挑戦したいと思っています。
自分の能力のなさを言い訳に参加を躊躇してしたんですが、今後のキャリアにとってはプラスにしかならないので、来年の早いうちに参加できるようにしたいです。
(悩めば悩むほど自分の中のハードルが上がっていくことを感じてます...)
[Java Script] jQueryを用いてinput, textareaの編集中にエンターでイベントを発生させる


# Code
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/3f6607ef-a422-45d1-76c6-502604e75b47.png)
このように編集する内容があると仮定、
`form`を用いておらず、ajax通信をしているので`input`や`textarea`でEnterキーを押しても何も反応しない。
より直感的に操作できるようにしたいので、`input`上でEnterキーを押したらボタンを押すようにしたい
## jQuery
```html:jQuery
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

```

## inputでEnter
```javascript:input
$("input[type=text]").on('keyup', function(e){
    if(e.key==='Enter'||e.keyCode===13){
        $('#submit').trigger('click');
    }
})
```
`input`を編集している状態で、Enterキーを押すことによって`id=submit`をもつ要素、ここではボタン、をクリックするようにした。
## textareaでEnter
```javascript:textarea
$("textarea").on('keyup', function(e){
    if(e.key=='Enter'||e.keyCode===13){
      $('#submit').trigger('click');
    }
})
```
同様に`textarea`もEnterキーを押すことでボタンクリック
## 発生させたbuttonの内容
```javascript:submit button
      $("#submit").click(function () {
        var title = $("#title").val();
        var user_id = $("#user-id").val();
        var purpose_text = $("#purpose-text").val();

        $.ajax({
          method: "POST",
          url: "/works/mode/edit/write",
          data: { work_id:this.dataset.id,  user_id: user_id, title: title, purpose_text: purpose_text },
        }).done(function (result) {
          location.href = document.referrer;
        });
      });

```
Alma Linux9にRailsアプリケーションの最低限の動作環境を構築する際の個人的備忘録

# はじめに
本記事はAlma Linux9で最低限のRailsアプリケーションを動作させるための手順を記したものです。
前提は以下となります。
* RailsアプリケーションはGitクローンしてくる
* Rubyのバージョンは3.1.2とする
* gemはvendor配下にbundle installする

# 手順

1. アップデートを行う
    ```bash
    $ dnf update -y
    ```
1. `git` をインストールする
    ```bash
    $ dnf install git -y
    ```
1. `vim` をインストールする
    ```bash
    $ dnf install vim-enhanced -y
    ```
1. 開発者用ツールをインストールする(Todo: Cコンパイラだけでいいかもしれない)
    ```bash
    $ dnf group install "Development Tools" -y
    ```
1. `mysql` or `postgresql` に必要なパッケージをインストールする
    ```bash
    # MySQLの場合
    $ dnf install mysql-devel -y
    # PostgreSQLの場合
    $ dnf install postgresql-devel -y
    ```
1. `rbenv` のビルドに必要なパッケージをインストールする
    ```bash
    $ dnf install openssl-devel -y
    $ dnf install readline-devel -y
    $ dnf install libyaml-devel -y
    ```
1. `rbenv` をインストールする
    ```bash
    $ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
    ```

1. `bash_profile` を開く
    ```bash
    $ vim ~/.bash_profile
    ```

1. 以下の内容を `bash_profile` の最後尾に追加して保存する
    ```bash
    # set PATH so it includes rbenv bin if it exists
    if [ -d "$HOME/.rbenv/bin" ] ; then
        PATH="$HOME/.rbenv/bin:$PATH"
    fi
    ```
1. `bash_profile` の内容を反映する
    ```bash
    $ source ~/.bash_profile
    ```
1. `rbenv init` を実行する
    ```bash
    $ rbenv init
    ```
1. `bash_profile` を開く
    ```bash
    $ vim ~/.bash_profile
    ```
1. 以下の内容を `bash_profile` の最後尾に追加して保存する
    ```bash
    eval "$(rbenv init -)"
    ```
1. `bash_profile` の内容を反映する
    ```bash
    $ source ~/.bash_profile
    ```
1. 以下のコマンドを実行して、正しく `rbenv` がインストールできたかを確認する
    ```bash
    $ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor | bash 
    ```
1. `ruby` の3.1系をインストールする
    ```bash
    $ rbenv install 3.1.2
    ```
1. システム全体で使う `ruby` のバージョンを3.1.2に設定する
    ```bash
    $ rbenv global 3.1.2
    ```
1. `ruby` のインストールを確認する
    ```bash
    $ ruby -v
    ```
1. `bundler` をインストールする
    ```bash
    $ rbenv exec gem install bundler
    ```
1. `bundler` のインストールを確認する
    ```bash
    $ bundler -v
    ```
1. 個々のアプリケーションをクローンしてきてbundle install~起動を行う

# 終わりに
アプリケーションで使用するgemによっては追加の依存パッケージが必要な場合があるので、その辺は個々で調べて対応ください。
当方Linuxについての知見は浅いので間違っている箇所があればご指摘くださいませ。
napariで連番付きtif画像を開きたい

# やりたいこと
ディレクトリに含まれる連番付きのtif画像をまとめて開いてnapariで見たい。Image Jで言うところの「Open Image Sequence」。

# コード
```visualize_tif_sequence.py
import glob
import napari
import numpy as np

from skimage import io


dir_name = "./data"
file_names = glob.glob(dir_name + "/*.tif")
stack = np.array([io.imread(file_name) for file_name in file_names])

viewer = napari.view_image(stack)
napari.run()
```

# ポイント
## 連番付きの画像ファイルをnumpy配列に格納する
```python
stack = np.array([io.imread(file_name) for file_name in file_names])
```
rbenvでRubyのバージョン管理

# 環境

- macOS Monterey 12.1
- Homebrew 3.6.12

# rbenv

rbenvを使用してRubyのバージョン管理をする。

https://github.com/rbenv/rbenv

# rbenvの準備

Homebrewをアップデートして、rbenvのインストール

```shell
$ brew update
$ brew install rbenv
$ rbenv -v
rbenv 1.2.0
```

デフォルトのRubyのバージョン参照先がrbenvの参照先に変えるためPATHの追記。
また、PC起動時にrbenvが自動で使用できるようにするための設定も記述。

```shell
$ vi ~/.zshrc

eval "$(rbenv init -)"
PATH="$HOME/.rbenv/bin:$PATH"

$ source ~/.zshrc
```

# Rubyのインストール

インストール可能なRubyのバージョンを確認

```shell
// 下記どちらでもOK
$ rbenv install --list
$ rbenv install -l
```

上記コマンドの応答末尾にも記載があると思いますが、一応過去のイントール可能バージョンも見れます。

```shell
$ rbenv instlal --list-all
```

インストールしたいバージョンを指定してインストール

```shell
$ rbenv install 0.0.0

$ rbenv versions
* ststem
  0.0.0
```

バージョンの変更

```shell
$ rbenv global 0.0.0

$ rbenv versions
  system
* 0.0.0

$ ruby -v
ruby 0.0.0
```

# 参照

- [rbenvでのRuby管理](https://qiita.com/payreikit/items/414ad190a60bde323509)
- [Rubyのバージョン切り替え方法！（Mac用）](https://info-wcn.com/ruby-changeversion-mac/)
リスクベース認証 とは

## 勉強前イメージ

リスクを承知で認証する？
そんなことないか

## 調査

### リスクベース認証 とは

英語では Adaptive Authentication と書き、なりすましによる不正アクセス対策に有効とされている認証方法になります。

通常のログインはIDとパスワードで認証されるのが一般的です。
しかし、どちらも流出する可能性がありその際には他の第三者がログイン可能になってしまいます。
その際にも不正にログインされないようになりすまし対策として強化するの手段の一つとしてリスクベース認証があります。

リスクベース認証では、認証時にヘッダやクッキーなどの情報を取得し、いつもと違う環境からのアクセスだと追加の認証をユーザに提示します。
イメージでは以下になります。
通常では国内からアクセスされてるが、今回は海外からアクセスされた際には別途他の認証方法(ワンタイムパスワード等)での認証も行います。

![12022-11-26 # リスクベース認証 とは - diagrams.net - Google C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/804b0895-9a8a-2a4a-c9eb-4a7b52f8bfbc.png)


### リスクベースでの認証の要素

- IPアドレス
- 位置情報
- 時間帯
- 登録しているデバイス
- 過去認証に成功したデバイス
- 不可能な移動
- OS・ブラウザの種類

上記のような要素で追加での認証を行うかを決めます。
特に不可能な移動というのが、前回アクセスした時刻と場所から不可能な移動を検知した際には追加での認証をする場合があります。

### リスクベース認証のメリデメ

- メリット
	- なりすましの防御 : 悪意のある第三者にログインされそうな際は別の認証方法を用いて不正ログインを回避させられる
	- ユーザの負担が少ない : 通常と同様のログインであればユーザは他の認証方法を行う必要がない
- デメリット
	- 導入コストがかかる : 別で認証を行う判断をする情報を取得・管理する必要があるためよりセキュアにはなりますがコストがかかります。
	
## 勉強後イメージ

ネットバンキングとかよりセキュアな環境が求められるシステムに導入が多いらしい

## 参考

- [リスクベース認証とは？仕組みやメリット、注意点について徹底解説](https://cybersecurity-jp.com/column/35310)
- [「リスクベース認証」とは？～仕組みやメリット・デメリットを紹介～](https://www.trustbind.jp/column/risk-based-authentication-20211105.html)
ゲストログイン機能

# はじめに
ポートフォリオ（Webサイト）を作成するにあたって、ボタン一つですぐにログインできるようにするため、ゲストログイン機能を追加しました。
新規登録やログイン機能はdeviseを使用しています。
アウトプットのため記録します。

# ルーティング
```ruby:config/routes.rb
 devise_scope :user do
    post "users/guest_sign_in", to: "public/sessions#guest_sign_in"
  end
```
deviseに新しくルーティングを追加します

# コントローラー
```ruby:app/controllers/users/sessions_controller.rb
 def guest_sign_in
    user = User.guest
    sign_in user
    redirect_to user_path(user), notice: "ゲストユーザーとしてログインしました。"
 end
```
sign_in userでゲストユーザーをログイン状態にします。
その後、ゲストユーザーの詳細ページへと遷移させます。
# モデル
```ruby:app/models/user.rb
 def self.guest
    find_or_create_by!(name: 'guestuser', email: 'guest@example.com') do |user|
      user.password = SecureRandom.urlsafe_base64
      user.name = 'guestuser'
 end
```
`find_or_create_by`:データを自動的に検索し、条件に該当するデータがあればそれを返し、なければ新規作成するRailsのメソッド
`SecureRandom.urlsafe_base64`:ランダムな文字列を生成するRubyのメソッド
## ゲストログインボタンを追加
トップページにゲストログインボタンを追加しました
```html:app/views/top.html.erb
<%= link_to 'ゲストログイン', users_guest_sign_in_path, method: :post, class: "btn btn-outline-info" %>
```
※ボタンはBootstrapを利用してます

# 参考記事

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

# 最後に
今回、ゲストログイン機能をアウトプット目的で投稿しました。
機能実装はできましたが、ここからゲストユーザーの削除・編集ができないようにする設定が必要だと思います。
情報に間違いがありましたら、コメント頂けますと幸いです。
エンジニアあるある

あるある書いていきます。予告なく編集したり追加したり削除したりします。
コメント欄であるある募集します。

### ネットワーク構築するなら仕様書くらい作れ
仕様書も設計書もないって言われたときは正気を疑った、、、
商用やぞおまえら、、、、
何がやばいって、それをあっけらかんと言ってたのが何よりヤバい

### 飯屋行くとバグ探しを始める
最近、結構な割合で席の端末から注文するようになってると思いますが、
ボタンの境目を押してみたり普通の一般客が操作しない手順で中身のデータを想像しながら操作してみたりする。
それでヒットしたら、チョコボールの銀のエンゼル当たったくらいの幸福感を味わえる。
非エンジニア諸君よ、性格が悪いと突っ込むことなかれ。いじわるじゃなくて職業病か本能です。

### 横文字と略語多すぎる。
ITって横文字多すぎんか。あと英字大文字の略語の数。
全く同じ言葉が全く違う意味でつかわれてたりする。
オフィシャルじゃなくてプロジェクト内のローカル言語も山のようにある。
これからエンジニアになりたい皆様、ご安心ください。全部理解できてる変態狂人エンジニアなんていません。

### リリース後の仕様変更
リリースして納品も完了した後に「仕様変更おねが～い」。
ざっけんな。ぶっとばしたろか。
サーバ止めてアプリも再配布になるけどリリース直後のサービスでそれやるんかおまいら。
なんとかしろ？てめえらでなんとかしろ。
CSVをgrepできるようにするコマンドを作った

この記事はGo Advent Calendar 2022の5日目の記事です。

CSVをgrepできるようにするコマンドを作ってみました。
CSVを検索するコマンドではありません。
grepと連携するコマンドです。

## 経緯

CSVのセルには改行文字が含まれ得ます。
改行文字の含まれるCSVをgrepすると、CSVのセルが壊れます。

具体的には、以下のようなCSVをgrepすると壊れます。

```bash
$ cat testdata/sample1.csv
Language,Word,Note
English,"Hello
World",note
Japanese,"こんにちは
こんばんは",メモ
English,"John
Rose",
Japanese,"太郎
花子",

$ grep Japan a.csv
Japanese,"こんにちは
Japanese,"太郎
```

grepで検索した文字列にマッチする行を抽出しつつ、
CSVフォーマットとして壊れないようにgrepしたかったわけです。

CSVを検索するツールとかは探せばあるんですけれど、grepの検索機能をそのまま使いたい。
かといって自分でgrepと同等の検索処理を実装するのは難しい。
ということで、grepに食わせる橋渡しをするツールを作りました。

## 成果物

gsv というコマンドです。

https://github.com/jiro4989/gsv

これは[gron](https://github.com/tomnomnom/gron)というコマンドのアイデアを参考にしました。

gsvに対してCSVを食わせると、改行文字が含まれるセルを1行の文字列に変換して出力します。
この文字列をgrepで検索し、再度gsvに噛ませることでCSVに復元します。

## 使い方

以下のように使います。
見ての通り、CSV行がJSON形式の文字列配列に変換されて出力されます。

```bash
$ cat testdata/sample1.csv
Language,Word,Note
English,"Hello
World",note
Japanese,"こんにちは
こんばんは",メモ
English,"John
Rose",
Japanese,"太郎
花子",

$ cat testdata/sample1.csv | ./gsv
["Language","Word","Note"]
["English","Hello\nWorld","note"]
["Japanese","こんにちは\nこんばんは","メモ"]
["English","John\nRose",""]
["Japanese","太郎\n花子",""]

$ cat testdata/sample1.csv | ./gsv | grep Japan
["Japanese","こんにちは\nこんばんは","メモ"]
["Japanese","太郎\n花子",""]

$ cat testdata/sample1.csv | ./gsv | grep Japan | ./gsv -u
Japanese,"こんにちは
こんばんは",メモ
Japanese,"太郎
花子",
```

## 実装

Go言語は標準でCSV、JSON用のライブラリを備えています。
このライブラリを使ってCSVを読み取り、読み取った文字列スライスをJSONフォーマットにエンコードします。

CSVを1行のJSONに変換する処理は以下のようになっています。

```go
func (a *App) readFoldAndWrite(r io.Reader, w io.Writer) error {
	c := csv.NewReader(r)
	for {
		row, err := c.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
		result, err := Fold(row)
		result += "\n"
		b := []byte(result)
		if _, err := w.Write(b); err != nil {
			return err
		}
	}
	return nil
}

func Fold(row []string) (string, error) {
	b, err := json.Marshal(row)
	if err != nil {
		return "", err
	}
	s := string(b)
	return s, nil
}
```

そして変換したJSONをCSVに戻す処理は以下のようになっています。

```go
func (a *App) readUnfoldAndWrite(r io.Reader, w io.Writer) error {
	br := bufio.NewReader(r)
	cw := csv.NewWriter(w)
	cw.UseCRLF = a.param.LF == "crlf"
	for {
		line, _, err := br.ReadLine()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		row, err := Unfold(string(line))
		if err != nil {
			return err
		}

		if err := cw.Write(row); err != nil {
			return err
		}
		cw.Flush()
	}
	return nil
}

func Unfold(row string) ([]string, error) {
	b := []byte(row)
	var s []string
	if err := json.Unmarshal(b, &s); err != nil {
		return nil, err
	}
	return s, nil
}
```

中間フォーマットとしてJSONを採用したのは、エンコード、デコード処理を自前で実装したくなかったからです。

改行文字をエスケープして、アンエスケープできるフォーマットなら何でも良かったので、
Go言語の標準ライブラリで備わっているJSONを採用しました。

## まとめ

以下の話をしました。

1. CSVをgrepできるようにするコマンドを作った
1. CSVを1行のJSONに変換してgrepに食わせて使う

以上。
更新日時が最新のファイルを取得する

# はじめに
特定のフォルダ内に格納されている更新日時が最新のファイルを取得するのを
仕事で使ったのでメモとして残します。
この記事は、UiPath Advent Calendar (produced with UiPath Friends) Advent Calendar 2022の3日目の記事です。

https://qiita.com/advent-calendar/2022/uipath

# 結論
GetFileでフォルダ内のファイル名を配列で取得後Listに変換（変換しているのはFirstプロパティを使いたかったからです）、更新日時（LastWriteTime）で降順（Descending）で並べ替えて、その最初（First）のFileNameを出力しています。
~~~
Path.GetFileName( (Directory.GetFiles(FolderPath,"*.txt").OrderByDescending(Function(x) New FileInfo(x).LastWriteTime)).toList.First)
~~~

# 今回の例
今回は例として、こんな感じのファイルたちの中から、最新のファイルを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/a20e7428-ea04-a4bc-f719-3c3046daf6ec.png)

なんだこのファイル管理！？という感じですが、あくまでも例としてみてください。
今回とってきたいのは、14：42更新の「テキスト（最新）.txt」です。
(画像内赤線部分)
# 今回の実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/caf175a7-74d7-36f1-e13b-3a974923dba1.png)

実装は非常にシンプルです。
ファイル名のログ出すだけ。

## メッセージの中身
くどいですがもう一度載せます。
~~~
Path.GetFileName( (Directory.GetFiles(FolderPath,"*.txt").OrderByDescending(Function(x) New FileInfo(x).LastWriteTime)).toList.First)
~~~

## 実行結果
意図したファイル名（更新日時が最新である）ファイル名を取得できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/71815e04-c4b9-2476-5122-9d2d61488f3d.png)

# おわりに
ファイル名だけでなくファイルのフルパスを取得したい場合はGetFileNameを外せばフルパスが取得できます。
また、今回は例としてテキストファイル（.txt）で実施しましたが、拡張子指定部分を変更すればExcelやPDFなども指定可能です。
ツイートのurlを書くだけで記事内への埋め込みができるようになりました！

## ※ 「Markdownで本文を見る」メニューを選択して、ツイートのurlしか本文に書いてないことをご確認くださいませ。

以下のようにツイートを埋め込んでいますが・・・それはできることは知ってたんですが・・・

https://twitter.com/Pixel_Outlaw/status/1595997371376115712

これは・・・
`https://twitter.com/Pixel_Outlaw/status/1595997371376115712` という文字列を記事内にリンクを書くつもりで挿入したら、twitter の記事が埋め込まれたｗ (冒頭のツイート埋め込み)
以前は埋め込み用のコードをとってこないといけなかったはずですが・・・

**Qiita の新機能かな?**
wiggler.el 変な Lisp コード

Twitter で「#Emacs」を見てたら変な Lisp コードを発見しました。

https://twitter.com/Pixel_Outlaw/status/1595997371376115712

早速打ち込んで実行してみました。

```elisp:wiggler.el
(defun coffee-break ()
  "Move the mouse in random 1 pixel directions until user presses C-g in buffer"
  (interactive)
  (cl-loop
   (let* ((mouse-pos (mouse-absolute-pixel-position))
          (next-x (+ (car mouse-pos)
                     (* (expt (- 1) (random 2)))))
          (next-y (+ (cdr mouse-pos)
                     (* (expt (- 1) (random 2))))))
     (sleep-for 1)
     (set-mouse-absolute-pixel-position next-x next-y))))
```

M-x coffee-break RET とすると：

* マウスカーソルを動かした方向の反対方向のランダムなポイントにマウスカーソルが勝手にジャンプします。
* C-g で終了します。(無限ループのプログラムのため)

mouse-absolute-pixel-position とか set-mouse-absolute-pixel-position を使ってなんか他におもしろいことできませんかねｗ

実用性のない(内容の薄い)記事でした～！

ちなみに、

> [英語「wiggler」の意味・使い方・読み方 | Weblio英和辞書](https://ejje.weblio.jp/content/wiggler)

によると wiggler は「揺り動かす人[もの]」または「【昆虫】 ボウフラ」だそうです。

### 蛇足

`https://twitter.com/Pixel_Outlaw/status/1595997371376115712` という文字列を記事内にリンクを書くつもりで挿入したら、twitter の記事が埋め込まれたｗ (冒頭のツイート埋め込み)
Qiita の新機能かな?
【Homebrew】brew doctorのWarning対応パターン別4選

brewでrbenvのバージョンをupdateしようとした時に、気になるWarningが出ていたので、`brew doctor`を実行し、`Homebrew`の点検を行った。この時に出ていたWarningそれぞれの対応記録を残しておく。
# Warning: Some installed formulae are deprecated or disabled.
非推奨、又は無効になっているライブラリの指摘です。

```
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: Some installed formulae are deprecated or disabled.
You should find replacements for the following formulae:
  mysql@5.6

```
不要である場合は削除してしまいましょう。

```
$ brew uninstall mysql@5.6
```

# Warning: No developer tools installed.
こちら結論、指示通り`xcode-select`をインストールすれば解決する。（環境によっては結構時間かかるかもです）

```console
Warning: No developer tools installed.
Install the Command Line Tools:
  xcode-select --install
```
参考：[brew upgrade でのエラー対処からCommand Line Toolsについてまとめてみる](
https://techracho.bpsinc.jp/wingdoor/2021_04_09/104821)

# Warning: You have unlinked kegs in your Cellar.
シンボリックリンク切れを教えてくれています。

```console
Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-trouble and cause formulae that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
  gettext
```

シンボリックリンク作成で解決するがここでエラーが出た場合、別途対応が必要。
```
$ brew link gettext
Linking /usr/local/Cellar/gettext/0.20.1... 181 symlinks created.
```

# Warning: Broken symlinks were found. Remove them with 'brew cleanup'
壊れたシンボリックリンクを`brew cleanup`コマンドで綺麗にしてね、と言う内容です。

```console
Warning: Broken symlinks were found. Remove them with `brew cleanup`:
  /usr/local/bin/notary
  /usr/local/share/man/man1/brew-cask.1
  /usr/local/share/zsh/site-functions/_brew_cask
```

指示通りコマンドを打てばOKです。
```
$ brew cleanup
```

# Your system is ready to brew.
全て解消できれば、気分もスッキリですね。
```
$ brew doctor
Your system is ready to brew.
```
KotlinでAtcoderをしていて「1000000007で割った余り」を出力したいとき

こんにちは。
[bitFlyerのAdvent Calendar](https://qiita.com/advent-calendar/2022/bitflyer) 9日目の記事です。

初めまして、私はbitFlyerでAndroidエンジニアをしています。
私が担当しているアプリ開発においてはパフォーマンスが非常に重要で、高速化のためのアルゴリズムが用いられている箇所もあり、勉強中です。

ところで皆さんは`10^9 + 7`という文字列を見たことがありますでしょうか。

私は、AtCoderをやっていて初めて見ました。
この文字列を見るときは大抵問題が難しいので「この表記がある問題が出てきたら捨てよう」とアレルギー反応が出ていましたが、問題自体は大した難易度ではないものが度々混じっているので非常にもったいないです。
いつかは越えねばならぬ壁なので色々調べましたが、Kotlinで書かれたサンプルコードが全然見つからなかったのでこの記事を書くに至りました。（以前Pythonでやっていた頃、Pythonなら豊富にあったのですが・・・）

### この記事に書くこと
- `10^9 + 7`の余りを出力する問題を解く際の四則計算の方法
- 繰り返し二乗法の仕組み

### 対象読者
- 競プロのビギナー（Atcoderでいうと茶色〜緑色）
- `10^9 + 7`という文字列を見るとアレルギー反応が出てしまう人
- 細かい理屈はともかく、`10^9 + 7`を打破したい人


では早速、まずは四則計算から

# 足し算
これに関しては特筆すべき点はありません。
```kotlin
const val MOD = 1000000007L
a += b % MOD
a %= MOD
```

こまめにMODの余りに変換しておきましょう。


# 引き算
```kotlin
const val MOD = 1000000007L
a -= b % MOD 
a += MOD
a %= MOD
```

負になってしまわないようにMODを足しています。

# 掛け算
この手の問題だと`1<= a <= 10^9` `1<= b <= 10^9` といった条件がついているかと思います。
10^9までならLong型同士で掛け算すればせいぜい10^18なのでオーバーフローしないはずです。
```kotlin
const val MOD = 1000000007L
a *= b % MOD
a %= MOD
```

特にこれに関しても特筆すべき点はなく、オーバーフローしないように計算後にちゃんと割りましょうということくらいです。

難しいのは割り算です。


# 割り算

```kotlin
const val MOD = 1000000007L
a /= b // NG
a %= MOD
```

これはNGです。
`a(mod 1000000007L)`を`b(mod 1000000007L)`で割るのはNGです。
ではどうすれば良いのかというと、まず結論から書くと

```kotlin
const val MOD = 1000000007L

fun main(args: Array<String>) {
    a *= b.modPow(MOD - 2)
} 

fun Long.modPow(n: Long, mod: Long = 1000000007L): Long {
    assert(n >= 0)
    if (n == 0L) return 1L
    if (n == 1L) return this
    if (n % 2L != 0L) return (this * modPow(n - 1, mod)) % mod
    val t = modPow(n.shr(1), mod) // n.shr(1)は、2で割っているだけです（右に一つビットシフト）
    return (t * t) % mod
}
```

何をしているのかというと、「aをbで割る」の部分を「aにb^(1000000007L - 2)を掛ける」というコードに書き換えています。（※この変形ができる理由を私は理解していないので「フェルマーの小定理」や「逆元」でググってみてください。）

`aをbで割る`の計算部分を`aにb^(1000000007L - 2)を掛ける`という計算に置き換えられることはここでは自明として扱って先に進みます。
`b^(1000000007L - 2)`を計算するにあたっていくつか注意点があります。

1. オーバーフローしないように掛け算の都度`1000000007L`で割ること
1. 単純に`1000000007L - 2`回の掛け算をしたらTLE待ったなしなので、効率的に計算すること（繰り返し二乗法を用いる）

以上をクリアするLongの拡張メソッドが

```kotlin
fun Long.modPow(n: Long, mod: Long = 1000000007L): Long {
    assert(n >= 0)
    if (n == 0L) return 1L
    if (n == 1L) return this
    if (n % 2L != 0L) return (this * modPow(n - 1, mod)) % mod
    val t = modPow(n / 2, mod)
    return (t * t) % mod
}
```

こちらになります。
この拡張メソッドのアルゴリズムはシンプルで
1. nが2で割り切れるときは、x^n * x^nの形にしてしまおう
1. nが2で割り切れないときは、割り切れる形にしよう

ポイントはこの二点だけです。

例えば`x^66`をこのアルゴリズムに当てはめてみると
```
x^66
= x^33 * x^33

x^33
= x * x^32

x^32
= x^16 * x^16

x^16
= x^8 * x^8

・・・
```

n乗するときの計算量のオーダーは、`O(log N)`かと思います。

これを用いると高速で逆元を求められることがわかりました。



# 終わりに

Kotlinで競プロをやっている人はあまりいないかもしれませんが、Intellijという強力なIDEを使えますし、急いで書いても予期せぬ型が入ってこないので手戻りが少なくて非常に書きやすいです。
おすすめです！

最後に、弊社bitFlyerでは[Androidエンジニアを募集](https://www.green-japan.com/company/3509/job/167514)しています。ご興味のある方はぜひご応募ください！
【CSS】transition-timing-functionの同時比較

### 概要
CSSのtransitionにて
`transition-timing-function`に
設定した値(linear, ease系, step）によって、
実際にどういった違いが出るのかを
同時に動かして比較してみました。

---
### 比較結果
タイトル部分にカーソルを乗せてみてください。

<p class="codepen" data-height="750" data-default-tab="result" data-slug-hash="ExRRxmZ" data-user="ymdarudy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ymdarudy/pen/ExRRxmZ">
  transition-timing-function</a> by ymdarudy (<a href="https://codepen.io/ymdarudy">@ymdarudy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※`transition-duration` (動作間隔・変化速度）は
すべて2s（2秒）で設定

---
### 補足
transitionの変化を「**同時比較**」してる記事を
自分で見つけることができず、執筆してみました。

詳しい使い分けや解説、他に使える値などは、
下記参考記事に譲ります。

---
### 参考にさせていただいた記事
https://ics.media/entry/18730/

https://qiita.com/s-kato/items/d5d1ceee9e2a28e02e6e

https://www.flapism.jp/html/416/
Xserverドメインで取得した独自ドメインをKAGOYA CLOUD VPSに設定する方法

この記事は[上智大学エレラボ Advent Calendar 2022](https://adventar.org/calendars/7664)第2日目の記事です。

# はじめに
私は、個人開発したアプリケーションを公開したいと思い、つい先日、初めてVPSを契約しました。
それまでインフラ周りの経験はほとんどなく、かなり苦労をしたので備忘録の意味も込めて、学んだことを少しずつQiitaにアウトプットしていこうと思います。

さて、今回は「**Xserverドメインで取得した独自ドメインをKAGOYA CLOUD VPSに設定する方法**」の備忘録です。

# 前提
- KAGOYA CLOUD VPSにおいて、とあるWebアプリケーションを公開しているとします。
- 現在、そのWebアプリケーションのページを表示する手段としては、インスタンスのIPアドレスにアクセスするのみという状態です。
![スクリーンショット 2022-11-26 17.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726756/c6e03030-0cfc-73a2-4f66-20496b075cdc.png)
- 今回のゴールは、**このWebアプリケーションのページを、Xserverドメインで取得したドメインでアクセスして表示できるようにすること**です。

# ネームサーバの設定
まず、ドメイン->IPアドレスの名前解決を行うネームサーバの設定を行います。
1. KAGOYA CLOUD VPSのコントロールパネルから、`その他＞ドメイン＞ドメインの追加・申請＞他社管理ドメイン登録`の順にアクセスします。そうすると、**他社管理ドメイン登録**の画面に飛び、`ns0.kagoya.net`と`ns1.kagoya.net`のようにネームサーバの情報が表示されます。
![スクリーンショット 2022-11-26 17.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726756/e9d60443-2178-ebb7-6b8d-e24b5a6cc1dc.png)

2. 別のタブでXserverドメインのコントロールパネルから、`ネームサーバー設定`を開き、`その他のサービスで利用する`を選択します。そして、1.で確認した`ns0.kagoya.net`と`ns1.kagoya.net`などのネームサーバの情報を入力します。そして、「確認画面へ進む」⇨「設定を変更する」を押すことでXserverドメイン側での設定は完了です。
![スクリーンショット 2022-11-26 17.48.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726756/68ca1283-6500-c521-bc2c-e74a383f1ff8.png)

3. KAGOYA CLOUD VPSの、**他社管理ドメイン登録**の画面に戻り、「追加」ボタンを押して、Xserverドメインで取得したドメインを入力し、「登録」を押してください。これでKAGOYA CLOUD VPSにXserverドメインで取得したドメインを追加できました。

# DNSレコードの設定
1. KAGOYA CLOUD VPSのコントロールパネルの**インスタンス一覧**画面に戻ります。そして、対象のWebアプリケーションが設置されているインスタンスのインスタンス名をクリックします。そして、「正引き設定」の＋ボタンをクリックして、ドメインを追加します。
![スクリーンショット 2022-11-26 17.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726756/1b6fc070-586b-9532-1518-088132827c44.png)
「選択してください」をクリックすると、先ほど登録したドメインが表示されるので、選択します。サブドメイン(一番左側の入力欄)は任意です。その後、右側の「設定」ボタンを押下することで設定完了です。
![スクリーンショット 2022-11-26 17.58.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726756/4b916545-b63d-130d-8040-4d1bdab93480.png)

2. 最大15分ほど待ち、アクセスして確認します。[KAGOYA CLOUD VPSの公式サイト](https://support.kagoya.jp/vps/manual/index.php?action=artikel&cat=35&id=37&artlang=ja)には

>
>※ 当社ネームサーバーは、15分間隔(毎時0分, 15分, 30分, 45分)で更新をしております。
>

と書かれているため、毎時0分, 15分, 30分, 45分にならないと、反映されません。

# さいごに
いかがでしたか。
何かご不明な点やご指摘等ございましたら、お気軽にコメントをいただけると幸いです。
今後も、学んだことを少しずつQiitaにアウトプットしていこうと思っているのでぜひ、ご覧ください。

また、[上智大学エレラボ Advent Calendar 2022](https://adventar.org/calendars/7664)には、
私の所属する上智大学エレクトロニクス研究部の部員をはじめとする様々な方が面白い記事を投稿してくれている(はず)ので、是非一度、ご覧ください！！

# 参考
- [マニュアル - KAGOYA CLOUD VPS サポートサイト - はじめに](https://support.kagoya.jp/vps/manual/index.php?action=artikel&cat=35&id=37&artlang=ja)
- [【IIS】さくらのVPS(WindowsServer)にエックスサーバーの独自ドメインを設定してみた](https://pentan.net/sakuravps-xdomain-windows/)
自己紹介

# はじめに
Qiita初投稿です。
ギリギリと言われる年齢ですが、完全未経験からPGへの転職を目指して勉強中です。







# 自己紹介
* 学習意欲強め（過去に占い師から「武者修行のような人生」と言われる）
* 現在、基本情報技術者試験の勉強中
* 現職は部品管理を主とした事務仕事に従事
* インフラエンジニアを目指す高専生の息子と二人暮らし





# プログラマーを目指すきっかけ
コロナ禍で在宅ワークに興味を持ち、いろいろ調べた結果辿り着いたのがプログラマーでした。
これまで主に事務仕事を行なっていたこともあり、パソコン作業が好きということと、
息子が巣立つまでに私も手に職をつけたい、という思いから学習をはじめました。






# スクールでのオンライン学習
2021年秋頃より、スクールのオンラインでプログラミング学習を開始。

* Python
* Django
* Git(SouceTree)
* MariaDB






# おわりに
スクールで受講したものの身についているのか不安があります。
備忘録とアウトプットのため投稿していきたいと考えています。
よろしくお願いします。
日本株のバックテスト用データ取得

日本株のバックテスト用データはどうしていますか。
いろんな銘柄でバックテストしたいと思うのですが、これまでなかなかいいデータが見つかりませんでした。

* 日足用
* 全銘柄
* 修正株価

このあたりの要件を満たすデータを探していたら、やっと見つかりました。[Stooq](https://stooq.com)のデータです。
APIで一つの銘柄のデータを取得する方法はよく紹介されていますが、今回は一度で全銘柄のデータを取得する方法です。

実はこのStooqは時系列データを[ここ](https://stooq.com/db/h/)で公開しています。
JapanのASCIIデータ(200MBくらい)を選択すると、画面に表示される文字列を入力するウィンドウがでます。正しく入力できると、ダウンロードできるようになります。
今回は日々自動でデータを取得することが目的ではないので、問題なしです。

これだけではただのデータ紹介になるので、ZIPデータを開いてbacktesting.pyでグラフ化します。

まずデータをpandasで読み込む関数を作ります。backtesting.pyに渡せるように、カラム名を変えています。

```python
import zipfile
from pathlib import Path

import pandas as pd


def read_data(price_path):
    stooq_zip = Path('d_jp_txt.zip')
    use_cols = {
	'<DATE>': 'Date',
	'<OPEN>': 'Open',
	'<HIGH>': 'High',
	'<LOW>': 'Low',
	'<CLOSE>': 'Close',
	'<VOL>': 'Volume',
	}

    with zipfile.ZipFile(stooq_zip) as zip_dir:
        with zip_dir.open(price_path) as f:
            data = pd.read_csv(f, usecols=use_cols.keys())

    data['<DATE>'] = pd.to_datetime(data['<DATE>'], format='%Y%m%d')
    data = data.rename(columns=use_cols)
    data = data.set_index('Date')

    return data
```

ZIP内でデータは株価、ETF、指標のデータなどがフォルダーで分けられており、株価は更に1と2のフォルダーに分けられています。

以下の例ではトヨタ自動車の株価を取得します。
トヨタ自動車(7203)は2のフォルダーに入っていますが、ZIP内でのパスをハードコードします。

株価を取得したら、backtesting.pyのクラスに渡してグラフ化します。


```python
from backtesting import Strategy, Backtest

class MyStrategy(Strategy):

    def init(self):
        pass

    def next(self):
        pass


def main():
    price_path = rf'data/daily/jp/tse stocks/2/7203.jp.txt'
    toyota = read_data(price_path=price_path)
    bt = Backtest(toyota, MyStrategy)
    bt.run()
    bt.plot()


if __name__ == '__main__':
    main()
```

![7203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591762/df2e0ded-bf0b-d16c-9313-af1255ef1c4d.png)

1999年4月からのデータが入っているようですね。
これでシストレの練習が捗りそうです。
DI（依存性の注入）はただ引数でインスタンスを渡せば良いってもんじゃない

## この記事は何
DI（依存性の注入）を実施する際に、コードとしてはDIになっているけど上手く活用できていないパターンを見かけることがあります。
この記事では、DIをする際にこういう運用はしない方が良いよ、というところをまとめていきます。

## DI（依存性の注入）とは
依存性の注入とは、上位レイヤーのオブジェクトを下位のレイヤーのオブジェクトから利用をする必要がある場合でも、
上位のレイヤーから下位のレイヤーを参照するような依存関係を作り上げるためのテクニックです。
依存関係は上位レイヤーから下位レイヤーへの一方通行にする、というのは保守性を高めるためにも非常に重要な考え方です。

一番わかりやすい例だと、データの永続化をするようなユースケースを実現する際に、ユースケース層より上位レイヤーであるインフラ層に属するDBクライアントなどを利用する必要がある、等の場合に活用できます。
DBクライアントに依存させないようにすることで、実行環境ごとの差分などを下位のレイヤーに意識させないで実装を行なっていくことができます。

DIとは、具体的に以下のようなことを実施します。

- 下位のレイヤー（参照したい側）で、上位のレイヤーのオブジェクトのインターフェースを定義する
- 上位のレイヤーのオブジェクトを呼び出したいクラスのコンストラクタで、引数として定義したインターフェースの値を受け取る
- コンストラクタで受け取ったオブジェクトを利用して処理を実装する

こちらの記事には具体的なコードも記載されているので、ぜひ参考にしてください。

https://qiita.com/saeki4n/items/22a276dcac9ef537ee25

DIについての概念は以下の記事にも記載していますので、一読いただければと思います。

https://qiita.com/getty104/items/dc0ba5a3b10c4f5121e4

## DIをするときによくある間違った運用方法

DI自体は今日からでも使えるシンプルなテクニックなのですが、目的を忘れてしまうと本来の役割全うしていないようなDIになっていることがあります。その例を紹介しながら、それぞれどのような考え方をしていくと良いかを紹介します。

### 1. 上位レイヤーのオブジェクトの事情で下位レイヤーで実装したインターフェースを変更する
上位レイヤーのオブジェクトの更新をするために、下位レイヤーで定義したインターフェースを変更する対応ををしている方をたまに見かけます。
前項でも説明した通り、DIは依存の流れを上位レイヤーから下位レイヤーへとするためのテクニックです。
基本的に依存の関係は、依存されている側はしている側の事情によって実装の内容を変えるなどの対応は行いません。
何か上位レイヤーのオブジェクトに変更が加わった場合は、下位レイヤーのオブジェクトのコンストラクタに値を渡すタイミングで、定義されているインターフェースに合うような形に修正する対応を行うか、そもそもインターフェースで定義されている範疇を超えない範囲でできるだけ上位レイヤーのオブジェクトの実装を行うようにしましょう。
ちなみに下位のレイヤーのオブジェクトで必要なインターフェースが変わった際は、インターフェースを変え、上レイヤーのオブジェクトの変更を行うのは全く問題ありません。

### 2. 下位レイヤーに定義したいインターフェースの事情で、上位レイヤーのオブジェクトのインターフェースを変える
逆に定義したインターフェースの内容によって、上位レイヤーのオブジェクトにメソッドを追加する方もいます。
これもあまり良くないアプローチである場合があります。
このパターンは依存性の流れに対して何かを違反しているわけではないですが、このような対応をするときは、「インターフェースに依存している別のオブジェクトと処理を揃えるために変更を加える」パターンが多いと感じています。
この場合は、そもそも同じインターフェースを参照するべきなのかが怪しい場合があるので、その場合は、コンストラクタで渡す値を分割し、インターフェースは最小の構成にできないかを検討した方が良いと考えています。

```csharp:Bad
public interface IUserRepository {
    int getDBId();
    void save();
    ...
}

public class UserRepository: IUserRepository   {
    public int getDBId() {
    ... 
    }

    public void save() {
    ...
    }
}

public class InMemoryUserRepository: IUserRepository {
    public int getDBId() {
      0 // 本来は必要のないメソッドをインターフェースに合わせるために追加している
    }

    public void save() {
    ...
    }
}

public class UserRegistrationService {
    public void register() {
        IUserRepository repository = new UserRepository()
        RegisterUser registerUser = new RegisterUser(repository)
        registerUser.call()
    }
}
```

```csharp:Good
public interface IUserRepository {
    void save();
    ...
}

public class UserRepository: IUserRepository   {
    public int getDBId() {
    ... // 何かしらの処理
    }

    public void save() {
    ...
    }
}

public class InMemoryUserRepository: IUserRepository {
    public void save() {
    ...
    }
}

public class UserRegistrationService {
    public void register() {
        IUserRepository repository = new UserRepository()
        RegisterUser registerUser = new RegisterUser(repository, repository.getDBId())
        registerUser.call()
    }
}
```

## 最後に
最後までお読みいただきありがとうございました。
Devトークも公開しているので、もし直接話してみたい、と感じていただけた方はぜひDevトークの方も「話したい」を押していただけると嬉しいです！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/27
System.ArgumentException: ''IBM437' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. Arg_ParamName_Name'

System.ArgumentException: ''IBM437' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. Arg_ParamName_Name'

'IBM437' はサポートされているエンコーディング名ではありません。カスタムエンコーディングの定義については、Encoding.RegisterProvider メソッドのドキュメントを参照してください。


`.NET6`の開発でExcelライブラリの`EPPlus`の`v4`を使用したところ、Excelをバイト配列に書き出す時点でエラーが発生した

## 原因
`.NET Core`以降では`IBM437`エンコーディングがネイティブでサポートされていない
`.NET Framework`までと`.NET Core`以降の差異によるもの

## 解決方法

nugetで`System.Text.Encoding.CodePages`を追加

```
dotnet add package System.Text.Encoding.CodePages --version 7.0.0
```

`Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)`の記述を追加

```cs
using OfficeOpenXml;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

using (var package = new ExcelPackage())
{
　// do something
}
```

## Reference

https://github.com/PowerShell/PowerShell/issues/18537

https://www.nuget.org/packages/System.Text.Encoding.CodePages/
Bogon とは

## 勉強前イメージ

なんかの攻撃の名前？
そもそもなんて読むんやろ

## 調査

### Bogon とは

ボーゴンと読み、本来インターネット上で使われることのないIPアドレスのことを指します。
どんなIPアドレスかというと以下のようなものになります。

- 割り振りがされていないIPアドレス
- 予約済みIPアドレス
	- プライベートIPアドレス
	- ネットワークアドレス・ブロードキャストアドレス・ループバックアプアドレス...
	- ... etc

なんでBogonがあるかというと
上記のようなアドレスが偽装されてDDoS攻撃などに使用されないようにISPのルータやサーバなどでフィルターをされています。
IPv4,IPv6それぞれに存在します。
また、しばしば変わるそうなのでフィルターの見直しが必要になってきます。

## 勉強後イメージ

IPアドレスが悪用されるってことか

## 参考

- [【初心者向け】IPアドレスについての理解を深める](https://dev.classmethod.jp/articles/concepts-not-understood-after-acquiring-aws-clf-is-ipaddress/)
- [IPv4アドレスの素性](https://livra.geolocation.co.jp/iplearning/855/)
- [bogonとは【用語集詳細】](https://www.sompocybersecurity.com/column/glossary/bogon)
Next.jsの始め方

Reactを触ったことはある私なのですが、Next.jsは名前しか聞いたことがない。
大人の事情でNext.jsをインストールすることになりました。
# Next.jsとは
ReactベースのJavaScriptのフレームワーク。サーバーサイドレンダリングができる。
Reactにはサーバー機能がないため、単体では動かせないが、Next.jsは単体でWebアプリを動かすことができる。
## ざっくり特徴
一応書くけど、他のサイトが詳しいのでそちらを参照していただきたい。
+ **SSR（Server Side Rendering）**
レア度の話ではない。
ブラウザではなくサーバーでレンダリングして、クライアント側で描画する方式
ReactはSPAでパスによってブラウザが、表示するDOMを変える＝レンダリング。Next.jsはサーバーでどのDOMを返すかを判断する。
+ **SSG（Static Site Generator）**
サーバー側で事前にビルドして、HTMLを構築しておく方式。
+ **ISR（Incremental Static Regeneration）**
SSGと基本は一緒。SSGは事前にビルドしているため、表示される情報が更新されにくいという課題があるが、ISRはバックグラウンドで一定期間ごとに再ビルドをする仕組みなので、更新頻度が高いページには効果的。
+ **ファイルベースルーティング機能**
ルールに従ってファイルを配置→**自動的にURLのパスが生成**されアクセス可能になる機能。
デフォでPagesフォルダが生成されている。Pagesフォルダ内にファイルを配置するだけで、そのページへの遷移が可能になる。

その他にもちろんたくさんある。
上記の中でまだ実際にどういうものか分かっているものは少ないけど、ファイルベースルーティング機能は便利。Reactだと、ページ表示させるだけで色々書く必要があったね。。。

### 似たような名前ものにNuxt.jsやNode.jsがある。
**Nuxt.js**はVue.jsでサーバーサイドレンダリングをするときに使う。
**Node.js**は本来ブラウザで動くJavascriptをPCのターミナルで動かせるようにするソフトウェア。

関係ないけど、N〇〇.jsばかりで混乱する。jsはNに弱みでも握られているのでしょうか。

# Next.jsをインストールする
npmでインストールする。Next.jsを始めたいディレクトリで下記コマンドを打つ。
`npx create-next-app@latest`
:raised_hand:コマンドはちょいちょい変わる事があるので、最新のものは公式サイトを見てね。
[Next.js公式](https://nextjs.org/docs/getting-started)

途中でプロジェクトの名前と、Typescript使う？ESLint使う？と聞かれるので、好きに選ぶ。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416489/2d2ae4c7-78b4-80c5-6b09-c95783579f8c.png)

終わったらSuccess！と出てくるので、しばらく待つ。

# 最後に
間違ったことを書いていましたら、それとなくコメントしていただけるとありがたいです。
Golang 新規プロジェクトのセットアップ

# やりたいこと
滅多にやらないプロジェクトのセットアップ方法の備忘録
とりあえずHello world!を表示するサンプルプロジェクトを立ち上げる
## 環境
- macOS Monterey 12.2.1
- VSCode
- go 1.18
  ```sh
  $ go version
  go version go1.18 darwin/arm64
  ```
# プロジェクト作成
## 作業ディレクトの作成
作業用ディレクトリ作成して、移動
```sh
mkdir sample-project
cd sample-project
```
## パッケージ管理の初期化
Golangでは基本的に[Go Modules](https://github.com/golang/go/wiki/Modules#quick-start-example)を使用してパッケージを管理する。（Node.jsのnpmやPythonのpipのようなものです。）以前はGOPATHでパッケージ管理していたみたいですが、今はGo Modulesで管理。

モジュールの初期化。
下記コマンドを実行したディレクトリがプロジェクト(リポジトリ)のルートディレクトリになる。
```sh
go mod init {プロジェクト名}
```
プロジェクト名は、下記の命名規則に従う
- GitHubなどで公開する場合: `github.com/{GitHubユーザー名}/sample-project`
- Localのみ: `sample-project`

実行すると、`go.mod`がプロジェクトのルートに作られているはずです。このファイルでこのリポジトリのパッケージを管理します。

### 参照するパッケージ追加/削除
* パッケージの追加
（参照するパッケージを`go.mod`に追加しているだけで、インストールはしていないらしい）
  ```sh
  go get {パッケージ名}
  ```
  グローバルインストールする場合は`go install`を使うらしいが、リポジトリ内だけの操作であれば不要だと思う。 （Go 1.18~ `go get`削除されたのではなく、`go get`を使ってインストールができなくなっただけっぽい）

* パッケージの更新や削除
  ```sh
  go mod tidy
  ```
  使われていないパッケージが`go.mod`にあれば削除してくれる。  ちなみに`go get`しなくても`import`に新規パッケージが記述されていれば、このコマンドで`go.mod`に追加される


# サンプルコード作成
エディタで下記をリポジトリのルートに作成。
（ちなみにVSCodeのGoの拡張機能を入れるコードのフォーマットを自動でやってくれます）
```main.go
package main

import (
   "fmt"
)

func main() {
   fmt.Println("Hello World!")
}
```

実行
```sh
$ go run main.go
Hello world!
```

## 補足
- ファイルが分かれていても同一ディレクトリ内であれば同一パッケージになり、同一パッケージであれば別ファイルの関数や変数でもprivateなものとして呼び出すことができます。
- ディレクトリが異なる場合は別のパッケージになり、呼び出しには`{パッケージ名}.{関数名}`と記述する必要があります。また呼び出せるのはPublicで宣言されているものだけです。

```hello_jp.go
package main

import (
   "fmt"
)

func helloJp() {
   fmt.Println("Hello Japan!")
}
```
```us/hello_us.go
package us

import (
   "fmt"
)

func HelloUs() {
   fmt.Println("Hello US!")
}
```
```main.go
package main

import (
   "fmt"
)

func main() {
   fmt.Println("Hello World!")
   helloJp()     // 同じディレクトリの別ファイルのprivate関数の呼び出し
   us.HelloUs()  // 異なるディレクトリのPublic関数の呼び出し
}
```

これを踏まえて、プロジェクトのディレクトリ構造を決める

# ビルド
goはコンパイラ言語なので実行にはビルドする必要がある。(`go run`はコンパイル+実行）
コンパイルした後のビルドファイルはGoの環境がなくても実行できるバイナリなので、デプロイする場合はビルドファイルを使用する。

ビルドファイルの作成
```sh
go build {コンパイル後のファイル名} {コンパイルするgoファイル名}
```
何も指定しない`go build`だけの場合はmain.goがコンパイルされ、リポジトリ名のビルドファイルがリポジトリのルートに作成される。

ビルドファイルの実行
```sh
$ ./{ビルドファイル名}
Hello world!
```

# 終わり
以上が新規でプロジェクトを始めるときのセットアップ方法

# 参考
- https://dev.classmethod.jp/articles/go-setup-and-sample/
- https://zenn.dev/optimisuke/articles/105feac3f8e726830f8c
RedisというDB

以下の特徴がある。
・非リレーショナルDB。Key-value型。
・メモリで処理される。揮発するので、スナップショットとして保存するRDBと、コマンドを記録するAOFによって、データを永続的に保存する仕組みあり。
・マスター・スレーブ型レプリケーション機能
UE5 Landscapeメモ


# ゲームの枠を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/9e24fa9e-ae03-976c-6d1d-2d69113ca93a.png)

Foliage Mode

ゲームの枠を作成
BrushSize：120
PaintDensity：0.3

枠用のFoliageのみをActivate
その他は全選択をしてDeactiveにしておく

# その他のオブジェクトを配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/4964b248-a61f-a2aa-1bc4-8beb5f174a03.png)

BrushSize：8192
PaintDensity：0.0004

いい感じに配置されるサイズで配置しておく


# Paintで道を作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/2a9a0cc7-1aa3-0609-77df-5a2df279b827.png)
【初心者向け🔰】最低限のWebアプリ開発の環境構築、全手順

## 概要
最低限の Web アプリの開発環境構築の全手順を記載します。
VScodeの導入、VScodeの日本語化、デベロッパーツール（開発者ツール）について触れます。

この記事は、[初心者向けWebアプリ開発環境構築の解説動画](https://youtu.be/962hCkKG2iE)のまとめ記事です。
より詳細な説明を聞きたい方は動画をご覧ください。

### 前提

- PC： Macbook Pro（Intel CPU）
（※ Windowsの方は、適宜、読み替えてください）

## アプリ開発必須ツール、「エディタ」とは

Editor ＝ Edit（編集）＋ er/or（〜するもの）
とは、「編集ツール」のこと。
今回でいうと、コーディング作業を行うためのソフトウェアのこと。

### PCに標準搭載のエディタとの違い

PCには、標準搭載のエディタ「テキストエディット（Mac）」「メモ帳（Windows）」があるが、開発作業は可能だが、かなり厳しい（現実的に開発に向いていない）。
開発作業をするには、開発専用のエディタ（または「統合開発環境」と呼ばれるソフト）を必ず使用する。

|エディタ|できること|
|:---:|:---|
|PC標準搭載エディタ|テキスト（文字）を書ける|
|開発用エディタ|テキスト（文字）を書ける<br>入力候補表示など補完機能がある<br>ファイル・フォルダの新規作成・削除などの操作が、エディタ内でできる<br>プログラムを動かしてみたりできる<br>拡張機能を追加して、エディタをカスタマイズできる|

## 初心者におすすめのエディタは？
Visual Studio Code（通称：VScode）がおすすめ。
![Web開発環境構築_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/e24fba15-fc16-8dc2-952f-6d9158d7db8d.png)


## 導入手順

### ダウンロード・インストール

[公式サイト](https://code.visualstudio.com/) から無料でダウンロード（Mac/Windows 対応）
![スクリーンショット 2022-11-26 15.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/ca807dc2-93c1-c7a5-0bfc-64437d946063.png)

#### Macの場合
ダウンロードしたZIPファイルを解凍し、ソフトウェアを「アプリケーション」フォルダに格納する。
![開発環境_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/5b225cce-a73f-7361-0b71-c79248b015ce.png)

![開発環境_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/a9da66db-8de1-44ba-f18b-b31b3a10f129.png)

「アプリケーション」フォルダに移動すると、アプリ選択画面に表示されて、いつでも選べるようになる。
![開発環境_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/982cfe80-12c5-e79f-f17d-bea0cf8cfecd.png)

#### Windows の場合
`〜.exe` というインストール用の実行ファイルがダウンロードされるので、これを起動する。

起動すると、「セットアップウィザード」という画面が立ち上がるので、基本はデフォルト（初期設定）の状態で「次へ」「インストール」などのボタンを押していけばインストールが完了する。

これで、開発環境の構築は完了。いつでもWebアプリの開発を始められる状態になった。

### 日本語化

デフォルトでは英語になっている事があるので、日本語化したい場合は、以下の手順を実施

VScodeを起動して、左の機能拡張アイコンを選択
![開発環境_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/5893e3d7-3e34-d4f6-e8b7-f1637bce041a.png)

左上のキーワード入力エリアに「japanese」と入力し、Enter キーで検索。
すぐ下の検索結果エリアに候補が表示される。おそらく一番上に `Japanese Language Pack for Visual Studio Code` というパッケージが表示されるので、それを選択
![開発環境_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/08c5b139-5f9b-6b42-a53d-b9422aeb3a58.png)

選択すると、右側に詳細情報が表示されるので、「install（インストール）」というボタンを押す
![開発環境_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/5b437281-4c1c-1b34-d72e-13a4c99bbb3d.png)

下図のように表示されていれば、インストール完了（必要に応じて、VScodeを再起動する）
![開発環境_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787582/ffe1ff04-c785-6e8a-9e41-41fa91be3dcb.png)

これで、日本語化は完了。

---
### 参考
この記事は、以下の動画のまとめ記事です。詳細は動画をご覧ください。

https://youtu.be/962hCkKG2iE
Emacs の message 関数で出力が流れてしまうのをなんとかする！

## ※ この記事で記載している xmessage(マクロ) を利用するには以下の過去記事内の xprint.el というファイルを Emacs にロードしておく必要があります。

> [Emacs Lisp でプリントデバッグをする (5) - Qiita](https://qiita.com/javacommons/items/50b2ac5e84143308c2cc)

----

Emacs Lisp の message 関数…便利ですよね。ミニバッファ以外のバッファ(ウィンドウ)を乱すことなく(デバッグ)メッセージを出力(確認)できますから。
でも、連続して message を呼ぶと再表示されずに、最後に読んだ message だけ出力されるように見えます(途中経過が視覚的に確認できない)

以下の例を見てください。xprint.el をロード後、messageの代わりにxmessageを同じようによんでも代り映えはありません。
しかし、`(xmessage 200 "i=%d" i)` のように第一引数に整数の定数またはシンボル(変数)を指定すると出力後にディレイがかかります。
これで途中経過を見ながらデバッグできます。

```
;; ミニバッファにいきなり「i=49」とだけ表示される
(dotimes (i 50)
  (message "i=%d" i))


;; xmessageマクロも第一引数に整数(スリープするミリ秒)を指定しないと、やはりミニバッファにいきなり「i=49」とだけ表示される
(dotimes (i 50)
  (xmessage "i=%d" i))

;; 「i=0」から「i=49」まで、200ミリ秒(0.2秒)ずつ再表示およびスリープしながらカウントアップが見れる(第一引数に整数定数を指定)
(dotimes (i 50)
  (xmessage 200 "i=%d" i))
```

### xsleep を開発・デバッグに使うときのシナリオ

デバッグしないときに、全ての xmessage の第一引数を削除したり、ディレイの時間をデバッグしたい時だけ指定できたら便利ですよね。
そこで、第一引数にシンボル(変数)を指定できるようにしました。以下のサンプルと説明をお読みください。

```elisp:my-sleep-test.el
(defcustom *my-sleep* nil "スリープする時間")

(defun my-test ()
  (interactive)
  (dotimes (i 50)
    (xmessage *my-sleep* "i=%d" i)))
```

`*my-sleep*` という変数を定義することでデバッグしたい時だけディレイをかけることができます：

* defcustom でスリープを制御する変数 `*my-sleep*` を nil として定義(第三引数のコメントも必須)
* xmessage の第一引数に `*my-sleep*` を指定しておく
* M-x my-test でマクロを実行 ⇒ ミニバッファにいきなり「i=49」とだけ表示される
* M-x set-variable を実行し、「`*my-sleep*`」 と入力後「200」を入力。
* 再度 M-x my-test でマクロを実行 ⇒ ミニバッファのメッセージがディレイ付きでカウントアップするのが確認できる
* デバッグが終わったら M-x set-variable を実行し、「`*my-sleep*`」 と入力後「nil」を入力。⇒ディレイがなくなる

# 最後に

> [Emacs Lisp でプリントデバッグをする (5) - Qiita](https://qiita.com/javacommons/items/50b2ac5e84143308c2cc)

には、xprint, xdump という関数/マクロがあり、デバッグ時のメッセージ出力に革命をもたらします。
message関数しか使ったことのない方も是非一度おためしください。

何かお気づきの点がございましたら、コメント等で教えていただけると助かります。