OmniAICreator/Qiita-1.07M huggingface dataset:
Windows 10「ファイル履歴」のエラー原因を検出する

#「ファイル履歴」の致命的な不具合
Windows 10の公式バックアップ「ファイル履歴」には致命的とも言える不具合があります。
同一フォルダに全角と半角、平仮名と片仮名で同名のファイルがあると対象ファイルだけでなくバックアップ全体が停止してしまうんですね。

↓ 例えばこんな組み合わせ

```
HOGE.txt
ＨＯＧＥ．ｔｘｔ

うぬ.jpg
ウヌ.jpg

!.mp4
！.mp4

資料１.doc
資料1.doc
```

細かい事は[日経の記事](https://xtech.nikkei.com/it/atcl/column/16/051000107/051100002/)が参考になります。

バックアップに失敗してもログに簡単なエラーが記録されるだけで特に通知はありません。
具体的な原因は何も教えてくれないのでバックアップ対象の無数のファイル群から自力で原因を探し出さなくてはならず……って普通キレますよね？　僕はガチギレしましたｗ

またパス名が長すぎる場合もやはりバックアップ全体が停止してしまいます。
こちらも特に通知はありませんが原因となったファイル名がログに記録してくれるので若干マシかもしれません。

これらの不具合はシングルバイト言語圏の方々には特に重大な問題ではないらしく、Windows 8の頃から放置されています。Windows 11でも多分直らなさそう。

#「ファイル履歴」のエラーを通知する
「ファイル履歴」は不具合さえ無ければとても便利なツールなんですが、いつの間にか停止しているバックアップなんて怖くて使えないです。
でも逆に言えば次の機能さえあれば実用できるハズです。

- バックアップの失敗を通知する
- 失敗したファイルを特定する

失敗の通知に関してはとても簡単に実現できます。
イベントビューアーで “Microsoft-Windows-FileHistory-Engine/BackupLog” を開き、「このログにタスクを設定」をクリックすると、実行ファイルやスクリプトを設定できるのでこれを利用します。
![event.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258214/7d21c05e-ffb5-7bb0-212f-7107a7415efc.png)
単純にエラーログが書き込まれたタイミングでタスクを起動するだけなので、たとえ未知のエラーでバックアップが停止してもエラー通知が届くハズです。
（ログも吐かずに停止してしまうような不具合が存在しなければですが）

#「ファイル履歴」のエラー原因を検出する
通知だけならスクリプトで十分ですが、エラー原因の検索もしたいので今回はC#(WinForms+.NET Core 3.1)を採用します。
起動したらエラーの原因になりそうなファイルを検索しつつタスクトレイで待機します。

失敗しそうなファイルを検索する処理はこんな感じ。

```C#
var list = new HashSet<string>();

var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var enumerationOptions = new EnumerationOptions();
enumerationOptions.RecurseSubdirectories = true;
var files = Directory.GetFileSystemEntries(path, "*", enumerationOptions);

foreach (var file in files)
{
    var file1 = Strings.StrConv(file, VbStrConv.Wide);
    file1 = Strings.StrConv(file1, VbStrConv.Uppercase);
    file1 = Strings.StrConv(file1, VbStrConv.Hiragana);

    if (list.Contains(file1))
    {
        Invoke(new AddItemDelegate(AddItem), file);
    }
    else
    {
        list.Add(file1);

        if (file.Length >= 250)
        {
            Invoke(new AddItemDelegate(AddItem), file);
        }
    }
}
```

対象フォルダのファイルやフォルダを全角化、大文字化、平仮名化しつつリスト化します。
同名のファイル名や長いファイル名を見つけたらListViewに放り込むだけ。

#「ファイル履歴」の「簡易」チェッカー
というけで作成した成果物は[GitHub](https://github.com/RST38h/CheckFileHistory)にあります。
![checker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258214/d895b2ce-341c-f997-10ab-9ed170f10937.png)
直接起動しても不具合ファイルの検索ツールとして使えますが、イベントビューアーで "Microsoft-Windows-FileHistory-Engine/BackupLog"を開き、「このログにタスクを設定」をクリックして"CheckFileHistory.exe"を設定するとエラー通知が届いていい感じになります。
[ログ]メニューでイベントビューアーの該当ログが開きますので、そこから設定可。

ファイルのリストをダブルクリックすると、エクスプローラーで対象ファイルがあるフォルダが開きますので、名前を修正するなり削除するなりしてください。

「簡易」チェッカーという名称はチェック対象がユーザーフォルダ(C:\Users\[ユーザー名])固定なためです(手抜き)
自分の利用範囲ではこれで十分実用的なので、これ以上の改良は他の方に任せます:-)

"[ユーザーフォルダ]\AppData\Local\Microsoft\Windows\FileHistoryy\Configuration"あたりにファイル履歴の設定ファイルがあるのでここらへんを調べればなんとかなりそう？
……けど何故か設定ファイルが２組あるし？？？ってなって面倒くさくなったｗ
LaravelとBootstrapで作るアプリケーション開発にトライ1

##  はじめに
YouTubeでぽんたさんの動画を発見して、動画が短時間で複数回に渡って解説していたので、こちらを見ながらハンズオン。
おまけに、Zennで解説書も提供されているので、不明点が無いくらい、有料でも良いくらいな資料だと思いました。
見よう見まねですが、手を動かさないことには覚えられませんのでレッツトライ！

##  概要
Laravelを使用したCRUD（登録・表示・更新・削除）機能の開発

##  操作環境
　Windows10 21H1
　Visual Studio Code
　Docker Desktop for Windows

### 使用する言語・フレームワークなど
・PHP 7.4
・Laravel 6
・Bootstrap 4.5
・MySQL 5.7
・Docker
Dockerは入っていなかったので、ダウンロードしてインストール。

### 作業用フォルダ作成
　・Laravel_todo
### ファイル作成
　・docker-compose.yml
　・Dockerfile

### 開発環境立ち上げ
コマンド実行　docker-compose up -d

### 起動確認
C:\Laravel_todo>docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED              STATUS              PORTS                               NAMES
52e1ebd89e01   mysql:5.7          "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:3306->3306/tcp, 33060/tcp   laravel_todo-mysql-1
84109332c1fd   laravel_todo_php   "docker-php-entrypoi…"   About a minute ago   Up About a minute   0.0.0.0:8000->8000/tcp, 9000/tcp    laravel_todo-php-1

## Laravelインストール
docker-compose exec php composer create-project --prefer-dist "laravel/laravel=6.*" .

成功メッセージ

> @php artisan key:generate --ansi
Application key set successfully.

### 開発サーバ起動、トップページへのアクセス確認
docker-compose exec php php artisan serve --host=0.0.0.0 --port=8000

ブラウザからlocalhost:8000でアクセスOK
![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115027/067f9b5b-6a3d-03a5-9152-0f74c20b885d.png)

一度、Ctrl+Cで開発サーバを終了。

## 初期設定
src/.envのLaravelのDB設定をdockerの設定に合わせます。

・DB_CONNECTION=mysql
・DB_HOST=mysql
・DB_PORT=3306
・DB_DATABASE=laravel
・DB_USERNAME=root
・DB_PASSWORD=password

### Laravelのデフォルトのマイグレーションを実行してDBの設定が正しいか確認します。
docker-compose exec php php artisan migrate
・Migration table created successfully.
・Migrating: 2014_10_12_000000_create_users_table
・Migrated:  2014_10_12_000000_create_users_table (0.27 seconds)
・Migrating: 2014_10_12_100000_create_password_resets_table
・Migrated:  2014_10_12_100000_create_password_resets_table (0.17 seconds)
・Migrating: 2019_08_19_000000_create_failed_jobs_table
・Migrated:  2019_08_19_000000_create_failed_jobs_table (0.08 seconds)
デフォルトのマイグレーションが通ったら成功。

Laravelのデフォルトは
タイムゾーンがUTC
LocaleがEN
のためsrc/config/app.phpの
timezoneとlocaleの内容を下記に変更します。
・'timezone' => 'Asia/Tokyo',
・'locale' => 'ja',

ここまでで環境構築が終わり、いざ設計～

躓くことなく進めることができた、色々と進歩していると思いたい。

ぽんたさん、丁寧な解説および資料の提供ありがとうございました！
django.core.exceptions.ImproperlyConfigured: SQLite 3.9.0 or later is required (found 3.7.17).に半日くらい悩まされた話（備忘録）

経緯
-

バックエンド初心者がDjangoプロジェクトをAWS上で動かすべく
[こちらの記事](https://qiita.com/kur/items/fb75354ee53671c79614)を参考にサーバーの設定を行なっていた際に遭遇したエラー
下のコードが実行できず、

```
$ gunicorn your_project.wsgi --bind=0.0.0.0:8000
```


SQLiteのバージョン3.9.0以降が必要です。（3.7.17が見つかりました）というエラーが出る。

```
django.core.exceptions.ImproperlyConfigured: SQLite 3.9.0 or later is required (found 3.7.17).
```


試したこと
-
エラー文でググってヒットしたページを上から順に試して行った

 * [Django2.2で開発サーバー起動時にSQLite3のエラーが出た場合の対応](https://qiita.com/rururu_kenken/items/8202b30b50e3bfa75821)

 * [DjangoをEC2インスタンス上で動かす環境を構築する(その4:「SQLite 3.8.3 or later is required」エラー対応)](https://kamatimaru.hatenablog.com/entry/2020/05/28/014653)

 * [django can't find new sqlite version? (SQLite 3.8.3 or later is required (found 3.7.17))](https://stackoverflow.com/questions/55674176/django-cant-find-new-sqlite-version-sqlite-3-8-3-or-later-is-required-found)

結果
-

対処療法的ではあるが、３つ目の記事 [Djangoのバージョンを下げること]
(https://stackoverflow.com/questions/55674176/django-cant-find-new-sqlite-version-sqlite-3-8-3-or-later-is-required-found)で解消された

下げるというより古いバージョンのDjangoをインストールする形で解決できた

```
$ pip install Django==2.1.*
```
[Swift]新規プロジェクト立ち上げ時`pod init`できない件の対処法

## 投稿の経緯
Xcode13へアップデート後に`Pod init`ができない不具合が発生しました。
対処法を共有させていただきます。

## 環境
Xcode version 13.0
Swift version 5.5

## エラー内容

――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

### Command

```
/usr/local/bin/pod init
```

### Report

* What did you do?

* What did you expect to happen?

* What happened instead?


### Stack

```
   CocoaPods : 1.10.1
        Ruby : ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
    RubyGems : 3.0.3
        Host : macOS 11.6 (20G165)
       Xcode : 12.5.1 (12E507)
         Git : git version 2.30.1 (Apple Git-130)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib
Repositories : trunk - CDN - https://cdn.cocoapods.org/
```

### Plugins

```
cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-trunk       : 1.5.0
cocoapods-try         : 1.2.0
```

### Error

```
RuntimeError - [Xcodeproj] Unknown object version.
/Library/Ruby/Gems/2.6.0/gems/xcodeproj-1.19.0/lib/xcodeproj/project.rb:227:in `initialize_from_file'
/Library/Ruby/Gems/2.6.0/gems/xcodeproj-1.19.0/lib/xcodeproj/project.rb:112:in `open'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/command/init.rb:41:in `validate!'
/Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:333:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.1/lib/cocoapods/command.rb:52:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.1/bin/pod:55:in `<top (required)>'
/usr/local/bin/pod:23:in `load'
/usr/local/bin/pod:23:in `<main>'
```

――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

[!] Oh no, an error occurred.

Search for existing GitHub issues similar to yours:
https://github.com/CocoaPods/CocoaPods/search?q=%5BXcodeproj%5D+Unknown+object+version.&type=Issues

If none exists, create a ticket, with the template displayed above, on:
https://github.com/CocoaPods/CocoaPods/issues/new

Be sure to first read the contributing guide for details on how to properly submit a ticket:
https://github.com/CocoaPods/CocoaPods/blob/master/CONTRIBUTING.md

Don't forget to anonymize any private data!

Looking for related issues on cocoapods/cocoapods...
 - Unknown object version
   https://github.com/CocoaPods/CocoaPods/issues/10973 [closed] [10 comments]
   3 days ago

 - RuntimeError - [Xcodeproj] Unknown object version.
   https://github.com/CocoaPods/CocoaPods/issues/7458 [closed] [20 comments]
   2 weeks ago

 - RuntimeError - [Xcodeproj] Unknown object version.
   https://github.com/CocoaPods/CocoaPods/issues/10746 [closed] [1 comment]
   02 Jul 2021

and 68 more at:
https://github.com/cocoapods/cocoapods/search?q=%5BXcodeproj%5D%20Unknown%20object%20version.&type=Issues&utf8=✓

## 対処法
ルートディレクトリにて下記コマンドを実行し、`Cocoa Pods`をアップデートします。

```
sudo gem update cocoapods
```

これで、改めて対象のディレクトリで`pod init`できるはずです。
参考にしてください！

## お知らせ
現在、iOS開発案件を業務委託で募集中です（副業）。[TwitterDM](https://twitter.com/ken_sasaki2)でご依頼をお待ちしています
本番・ステージング環境（さくらVPS+CentOS7）でDockerを動かす

ローカル開発環境で動いていたdockerコンテナをvpsサーバで動かそうとするとハマったのでメモ。
この環境にはすでに8000番で他のサービスが動いており、全然違うミドルウェアを使うので隔離したかった。

まだ本番特有のセキュリティとかはできていない。
とにかくローカルと同様にブラウザからアクセスできるようにするところまでできたのでメモ。

さくらVPSサーバ固有の設定があったため、他のサーバだとそちらのコンパネなりを調べる必要がありそうです。

# Portを解放する
今回はdocker-compose.yml のwebコンテナで 8081番をしている前提です。

```docker-compose.yml
version: '2'

volumes:
  nextcloud:
  db:

services:
  db:
    image: mariadb
    restart: always
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}  # .envファイルに環境変数を設定
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}  # .envファイルに環境変数を設定
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    image: nextcloud
    ports:
      - 8081:80
    links:
      - db
    volumes:
      - nextcloud:/var/www/html
    restart: always
(END)
```

```.env
ENV_MYSQL_ROOT_PASSWORD=root
ENV_MYSQL_PASSWORD =root
```

## CentOSのfirewallで対象のPortを開く

```
sudo firewall-cmd --permanent --zone=public --add-port=8081/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
```
--list-all でportの行に8081が追加されていたら成功。

が、これでアクセスできるかと思ったらさくらVPSでは以下の手順も必要だった。

## さくらVPSのコントロールパネル　サイトへアクセスする。
サーバを選択して、
タブからグローバルネットワークを選択
パケットフィルタを設定を押下
カスタムで開きたいポートを追加登録する。
ここでは8081

# 初回はdocker本体をインストールする。
確かこの人の言う通りにやったら特につまらずインストールできたので、コピペさせてもらって入れてください。

https://qiita.com/inakadegaebal/items/be9fecce813cebec5986

# ローカル環境で使用したdocker-comopse.ymlなどを任意のフォルダを作って用意する。

```
mkdir NetCloud-Docker
cd NetCloud-Docker
vim docker-compose.yml
vim .env
```
今回のイメージはこれだけで動くものなので、はじめに書いた内容をvimで貼り付ければ動く。
git cloneとかが必要なプロジェクトでもローカルで動いた構成と同じものを用意する。

# 立ち上げる

```
sudo docker-compose up -d
sudo docker ps
```

アプリ側が8081番を待ち受けているか確認

```
netstat -tanp
```

以下のような表示がされていたら8081で待機できている。

```
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      -
```

ブラウザからアクセスする
http://{IPアドレス}:8081
Redmine on Docker にプラグイン導入を簡単に

# やりたいこと

- redmineを公式dockerイメージで簡単に立てたい
- プラグインは入れたい
- **buildはしたくない** ← ここ重要

# やること

- docker-compose.yml で redmine と postgres を設定する
- plugin を解凍して plugins フォルダに入れて起動する

# 手順

## docker-compose.yml

```yaml
version: '3'

services:
    pdb:
        image: postgres:11-alpine
        environment:
            POSTGRES_PASSWORD: postgres
        #ports:
        #    # for debugging
        #    - 5432:5432
        volumes:
            - /opt/server/postgres:/var/lib/postgresql/data
            - /etc/localtime:/etc/localtime:ro
        restart: unless-stopped

    redmine:
        image: redmine:4-alpine
        environment:
            REDMINE_DB_POSTGRES: pdb
            REDMINE_DB_USERNAME: postgres
            REDMINE_DB_PASSWORD: postgres
            REDMINE_PLUGINS_MIGRATE: "true"
        volumes:
            - /opt/redmine/files:/usr/src/redmine/files
            - /opt/redmine/plugins:/usr/src/redmine/plugins
        ports:
            # for debugging
            - 8080:3000
        depends_on:
            - pdb
        restart: unless-stopped
```


### ポイント

```yaml
        volumes:
            - /opt/server/postgres:/var/lib/postgresql/data
```

postgresのデータの永続化のために必要

```yaml
        environment:
            REDMINE_PLUGINS_MIGRATE: "true"
```

pluginsフォルダの中のプラグインに対して `rake redmine:plugins:migrate` を走らせる．一部，なくても動作するプラグインはあるけど，普通は走らせないと500エラーを吐くので必要

```yaml
        volumes:
            - /opt/redmine/files:/usr/src/redmine/files
```

チケット等に添付したファイルはストレージに保存されるので，ここの永続化は必須

```yaml
        volumes:
            - /opt/redmine/plugins:/usr/src/redmine/plugins
```

プラグインフォルダに後からプラグインを追加するために，ここもマウントしておくと便利

redmine がマウントするファイルパスは書き込み権限をつけておく．

```shell
sudo mkdir -p /opt/redmine
sudo chmod 777 /opt/redmine
```

## プラグインの配置

```shell
cd /opt/redmine/plugins
unar hogehoge.zip   # アーカイブはunzipしておく
git clone https://github.com/hogehoge/hogehoge.git  # cloneしたら動くものも沢山ある
```

## 実行

いつも通りに

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

dockerを動かしているマシン (host_addressとする) に対して `http://host_address:8080/` でアクセスするとredmineが見えるはず．
WEBrickが起動するまで接続できないので，焦らないこと．

docker-compose.yml 内で for debugging と書いたところは，フロントエンドにnginxとかを使う場合は不要．
その場合，upstreamにredmine:3000を指定する
pdbのportsは隠蔽しておいた方がいい

# 使っているプラグイン

参考までに

- [Redmine Gantt プラグイン \- Easy Redmine](https://www.easyredmine.jp/redmine-gantt-plugin)
    - ガントチャートをただ表示するだけじゃなくて，ガントチャート上で操作できるようになるので好き
- [のアジャイルプロジェクト管理用Redmineアジャイルプラグイン](https://www.redmineup.com/pages/ja/plugins/agile)
    - チケットをアジャイルボードで進捗管理できるようになる．リスト表示ではチケットの中身が分かりづらいので看板の方が好き
- [sciyoshi/redmine\-slack: Slack notification plugin for Redmine](https://github.com/sciyoshi/redmine-slack)
    - 最近，社内コミュニケーションがslackに移行したのでインストールしてみただけ．今後試してみる予定
Web上で再生する動画の速度変更

##はじめに
昨今、Web上で動画を視聴する機会が増えているのではないでしょうか。

Web上の動画では「速度調節ボタン」が設定されていない場合もあります。

今回は、そんな時に役立つ記事を記載しました。

##方法
ブラウザはGoogle Chromeを使っていることが前提です。

再生したい動画ページにて右クリックします。
「検証」を押すと下図のような画面が表示されます。
![スクリーンショット 2021-10-02 17.29.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1622645/708e1f60-718a-4b5c-7494-403c80df785d.png)

左上にあるボタンをクリックします。
![スクリーンショット 2021-10-02 17.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1622645/51141200-a4fc-054d-64e7-e57c13f37a5b.png)

速度を変更したい動画をクリックします。

その後「Console」をクリックして
![スクリーンショット 2021-10-02 17.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1622645/fd0c8e85-e774-9e69-93d3-808f6f1a820c.png)

下記コードを画面中央の空白のところに貼り付ければ「0.75倍速」で視聴可能です。

```
document.getElementsByTagName('video')[0].playbackRate = 0.75
```

＊「0.75」という数字を変更すれば、任意の速度で再生可能です。速くすることもできます。

##参考記事

https://qiita.com/t15/items/9cf11354a4e6c5ef0616
AngularでHello,world／バインディング

# はじめに
この記事では Angular バインディングについて記載します。
バインディングとは、テンプレートファイル(.htmlファイル)と、コンポーネントファイル(.tsファイル)の間で、変数やイベントを共有する機能です。

例えば、コンポーネントファイルで宣言した変数の内容を、テンプレートファイルで表示するといったことです。
公式リファレンスではさまざまなバインディングが解説されていますが、ここではよく使われるプロパティ、イベントのバインディングについて解説します。
[公式リファレンス Binding syntax](https://angular.io/guide/binding-syntax)


なお、開発環境については、環境準備編を参照してください。
[AngularでHello,world／環境準備](https://qiita.com/shuji-k/items/4c05655c37d08a10a041)

# 1. プロパティへのバインディング
input タグの value や、img タグの src 等の値を動的に変更する場合のバインディングについて解説します。
方法は2つあり、テキスト補完の応用と、バインディングを使うことで実現できます。

1. テキスト補完の応用
    まず、テキスト補完をつかって、input タグの value に値を設定するサンプルを以下に示します。
    [テキスト補完](https://qiita.com/shuji-k/items/f27c774b6d5af41b040e)
    コンポーネントファイルは、上記テキスト補完と同じなので省略します。

    ```html:app.component.html
    <input value="{{message}}">
    ```  

    テキスト入力欄内に「hello, world!」と表示されましたね。
    このようにダブルクォーテーションで囲われた中でも、テキスト補完は有効になります。

1. プロパティへの一方向バインド記号
    次に、input の value など、タグのプロパティへのバインドに使える方法を示します。

    ```html:app.component.html
    <input [value]="message">
    ```

    こちらでも、テキスト入力欄に「hello, world!」と表示されましたね。
    ***Angular のプロパティバインドでは、こちらの記述が一般的です。***


# 2. イベントへのバインディング
さて、ここまで動的な変更が確認できないサンプルコードでしたね。
そこで、動的な変更を確認するために、ボタンを押したら表示が変更されるサンプルを作成してみましょう。
そのために、「ボタンを押した」というイベントに対応するため、イベントへのバインディングを示します。
サンプルコードは以下の通りです。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public title = 'my-app-bind';

  public message = 'hello, world';

  public test() {
    this.message = 'hoge! hoge!';
  }
}
```

```html:app.component.html
<input [value]="message">
<button (click)="test()">テスト</button>
```

「テスト」のボタンを押すと、テキスト入力欄が「hoge! hoge!」に変わりましたね。
このように、テンプレートからコンポーネントへのバインドとして、```()``` でイベント名を囲み、対応する関数を記述すると呼び出すことができます。
イベントのバインディングは複雑なので、おって独自イベント作成の回で深堀りしたいと思います。

---
[メニューに戻る](https://qiita.com/shuji-k/items/3b3cdec4dac3dc48ba43)
今さらSTM8S-DiscoveryのSTM32F103でLチカ



x もどせなくなります。書き込み機として使えないからまーいーか?


![o_con30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f2657e84-1eda-0424-f336-25cc58707618.jpeg)



1.STM32CubeProg.. で　read outプロテクションを外す。

2.STM32 ST-LINK Utiityでライトプロテクションを外す、オールイレース

4.mbedで次のプログラムをコンパイル



```c++



#include "mbed.h"

DigitalOut myled(PA_8);

int main()
{

    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }

}



```


5.STM32 ST-LINK Utiityで書き込み実行

6.赤LEDが光る

7.おわり
Dockerを使用せずにReact(Next.js)+TypeScriptの環境を構築する手順

#なぜこの記事を書いたのか

React(Next.js)とTypeScriptは相性が良いといわれており、この二つを組み合わせて開発する人も多いため、環境構築する方法を記事としてまとめておきたかった。ただし、今回はDockerなしでの構築とする。

#環境構築完了（ゴール）の確認

この記事のゴールは以下のようにReact(Next.js)のページが起動すること。

![スクリーンショット 2021-10-02 16.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758310/0a3e8b26-a7cb-a866-db37-a2fc203b88db.png)

#環境構築の手順

##１．React(Next.js)アプリ作成

まずはターミナルを起動してプロジェクトフォルダを作成したいディレクトリへ移動する。今回は「next-ts-redux」という名前のフォルダを作成し、その直下に「app1」という名前のプロジェクトフォルダを作成することにする。

以下のコマンドを実行する。

```
npx create-next-app app1
```

コマンドを実行すると以下のような構成でフォルダが作成される。

```
コマンド実行したディレクトリ
 └ app1
     └┬ next.config.js
      ┝ node_modules
      ┝ package-lock.json
      ┝ package.json
      ┝ public
      ┝ README.md
      ┝ pages
      |   └┬ _app.js
      |    ┝ index.js
      |    └ api
      |        └ hello.js
      └ styles
          ┝ globals.css
          └ Home.module.css
```

##２．アプリを実行する

ディレクトリを「app1」へ移動して、以下のコマンドを実行するとローカルサーバが立ち上がる。

```
npm run dev
```

:::note info
この実行コマンド”npm run dev”や”npm start”はpackage.jsonが存在するディレクトリで実行する必要がある。
理由はこのコマンドはpackage.jsonのscriptの内容を実行しているため。
:::

上記のコマンドを実行したらブラウザで「 http://localhost:3000 」を起動してみよう。
![スクリーンショット 2021-10-02 16.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758310/0a3e8b26-a7cb-a866-db37-a2fc203b88db.png)

いったん実行中のターミナルで「Control」+「C」キーを同時押しして、実行をキャンセルする。

##３．Reactコンポーネントを格納するフォルダの変更
ターミナルにて以下のコマンドを実行して、Reactコンポーネントを格納するpagesフォルダをsrc直下へ移動する。

```
mkdir src && mv pages src
```

##４．TypeScriptを導入する

以下のコマンドを実行してTypeScriptを導入する。

```
npm install --save-dev typescript @types/react @types/react-dom
```

##５．TypeScript用のファイル名に変更

以下のファイル名の拡張子をJavaScriptからTypeScript用に変更する。

- src/pages/_app.js　→　src/pages/_app.tsx
- src/pages/index.js　→　src/pages/index.tsx
- src/pages/api/hello.ts　→　src/pages/api/hello.ts

それぞれのtsxファイルをVSCODEで開いて、以下の箇所を修正する。これはもともとJavaScriptで書かれていたプログラムをTypeScriptで動くように変更する作業なので必須。

```_app.tsx
// 先頭行に以下を追加
import React from 'react'
import {AppProps} from 'next/app';

// 3行目
// 修正前
import '../styles/globals.css'
// 修正後
import '../../styles/globals.css'

// 5行目
// 修正前
function MyApp({ Component, pageProps }) {
// 修正後
const MyApp = ({Component, pageProps}: AppProps) => {
```

```index.tsx
// 先頭行に以下を追加
import React, {FC} from 'react'

// 3行目
// 修正前
import styles from '../styles/Home.module.css'
// 修正後
import styles from '../../styles/Home.module.css'

// 5行目
// 修正前
export default function Home() {
// 修正後
const Home: FC = () => {

//最終行に以下を追加
export default Home;
```

##６．アプリを実行する

ここでもう一度、ディレクトリを「app1」へ移動して、以下のコマンドを実行する。

```
npm run dev
```

上記のコマンドを実行してブラウザで「 http://localhost:3000 」を起動すると、以下のように確認できるはずだ。
![スクリーンショット 2021-10-02 16.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758310/0a3e8b26-a7cb-a866-db37-a2fc203b88db.png)

ここでtsconfig.jsonが作成されているかを確認しよう。プロジェクトフォルダ「app1」直下にtsconfig.jsonが作成されているはずだ。

これでDockerなしのReact(Next.js)+TypeScriptの環境を構築する手順は以上となる。
QEMU on WindowsでPC Speakerをエミュレートする

`-audiodev` オプションと `-machine` オプションを利用する。

## 具体例

例えば、以下のようにオプションとその値を指定すると、PC Speakerがエミュレートできるようになる。

```diff
- qemu-system-i386 -drive file=./os.img,format=raw,if=floppy
+ qemu-system-i386 -drive file=./os.img,format=raw,if=floppy -audiodev dsound,id=0 -machine pcspk-audiodev=0
```

`-audiodev` オプションにはエミュレートのバックエンドで利用するオーディオを指定する。値には `dsound` (DirectSound)とそれを識別するためのidを指定する。ちなみにidに指定する値は文字列でもOK。

`-machine` にはデバイスとそれに割り当てるidを指定する。値には `pcspk-audiodev=<audiodev id>` を指定する。


## DirectSoundCaptureの初期化エラーが発生する場合の対処

オプションとその値を適切に指定しても、以下のようなエラーが出る場合がある。

```
dsound: Could not initialize DirectSoundCapture
dsound: Reason: No sound driver is available for use, or the given GUID is not a valid DirectSound device ID
```

これはQEMU側の問題ではなく、Windows側の問題である可能性が高い。

例えば、 `設定` アプリの `システム > サウンド > 入力` の入力デバイスを選択するためのドロップダウンリストの値が「入力デバイスが見つかりません」になっているとこのエラーが発生する。

この場合は、なにかしらの音声入力デバイスをPCに接続し、 `サウンドデバイスを管理する > 入力デバイス` に表示されているデバイスを有効にしてあげるとエラーが消える。


## Version

```bash
$ qemu-system-i386 --version
QEMU emulator version 6.1.0 (v6.1.0-11882-g7deea770bf-dirty)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
```

## 参考

https://qemu.readthedocs.io/en/latest/system/qemu-manpage.html
GitHubのリポジトリをクローンする方法

こんにちは！テックアカデミーのWebアプリコースを受講している駆け出し高校生エンジニアの安田駿介です。

今回は、「GitHubのリポジトリをクローンする方法」というテーマで解説していきます。

# GitHubのリポジトリをクローンする手順

##１．GitHubのリポジトリトップページに行く
![a4a519ebfdf5eceac604f8912919a8fe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903726/863a5233-38c1-38bc-b4fd-677ceabbad11.png)

##２．Codeボタンを押して、RemoteのURLを取得
![74fea6251b310b6944bcc35e376961fb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903726/5c116287-130e-f98c-89bc-09ebc800c6ee.png)

URLをコピーしてください。

##３．ターミナルで「git clone コピーしたURL」を実行する
![d738f11ae8b57ab3183314b8eba0ecab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1903726/e04b1172-e959-3d4d-c03f-d2a86088ac31.png)

これで、クローン完了です。

# 開発環境
・AWSのcloud9
・GitHub
Rails ~Rspec環境~

# Rspec

## Install
```
group :development, :test do
  gem 'rspec-rails', '~> 5.0.0'
end
```

`rails generate rspec:install`

## Configuration

### .rspec
```:.rspec
# 全てのファイルでrequireを宣言しなくてもspec_helperがロードされる
--require spec_helper
# 出力を色付け
--color
# 出力形式を詳細に記載
--format documantation
```

`rails_helper.rb`で　`require spec_helper`がされているので、このファイルを　`.rspec`内に記載すれば良いように思えるが`spec_helper.rb`ファイルにコメントアウトされている記述によると、全てのファイルにロードされるものなのでできるだけ軽量な依存にとどめておくのがベターであると。

## Factory bot rails

### Install
```
group :development, :test do
  gem 'factory_bot_rails'
end
```


### Configuration

```:spec/support/factory_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
```

```rails_helper.rb
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

```

上記の設定で、`FactoryBot`のシンタックスがいらなくなる。
(https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#rspec)

```
# before
FactoryBot.build(:user)

# after
build(:user)
```

# Generators
上記の設定で　railsをAPIモードで動かしている時、モデル、コントローラーを生成すると自動で

```:controller
spec/requests/users_spec.rb
````

```:model
spec/models/user_spec.rb

spec/factories/users.rb
```

が生成される。

Factory bot Generators: https://github.com/thoughtbot/factory_bot_rails#generators
【React】namespace を活用したキレイな記述方法

## TL;DR

`export default`と`namespace`を組み合わせて、コンポーネントの名前空間に型定義入れると、情報がまとまってキレイに書けそうです。

```ts
function ChildComponent({ label }: ChildComponent.Props) {
  return <div>...</div>;
}

namespace ChildComponent {
  export interface Props {
    label: string;
  }
}

export default ChildComponent;
```

```ts
import ChildComponent from 'path/to/child_component'

// 1. 定数としてPropsを入れるパターンや
const ITEMS: ChildComponent.Props[] = [
    { label: "hoge" },
]

function ParentComponent() {

    // 2. コンポーネント内で動的に作るならこうだし(変数の命名や以降の擬似コードは適宜読み替えてください!)
    const items = useMemo<ChildComponent.Props[]>(() => [{ label: 'hoge' }], [])

    return (
        <>
            {ITEMS.map(item => (
                <ChildComponent key={item.label} label={item.label}>
            ))}
        </>
    )
}
```

## 内部の挙動

詳細な説明は公式 Docs を参照ください。
https://www.typescriptlang.org/docs/handbook/declaration-merging.html

今回のようなコード例（namespace 内が、interface などの値ではなく型の定義のみ）をトランスパイルすると、js ファイルは当然中身はなく、以下のような型定義ファイル(`d.ts`)のみ生成されます。

```ts
declare namespace ChildComponent {
  interface Props {
    label: string;
  }
}
```

よって、今回のようなコンポーネントの記述方法によってファイルサイズの増大はなさそうです。

## 注意点

### `default export function ChildComponent...`の形ではダメ

こんな感じで怒られます。

```
Merged declaration 'ChildComponent' cannot include a default export declaration. Consider adding a separate 'export default ChildComponent' declaration instead.
```

### `named export`も（多分）ダメ

`namespace`を定義したファイルないであれば問題ないのですが、インポートする側は namespace が見つからないため、難しそうです。（このあたりの仕様についてご存じの方いらっしゃいましたら、コメントいただけると幸いです。）

### `default export`は宗教上の理由で使えないです

ごめんなさい。
もし、import時のTypoがどうしても怖いという場合は、default-import-match-filenameというeslintのルールで、ファイル名と同じ名前でimportするよう制約付けることもできるそうですが、まあこのためにわざわざやるのは見合わないかもですね。

https://github.com/minseoksuh/eslint-plugin-consistent-default-export-name/blob/main/docs/rules/default-import-match-filename.md

### 参考資料

https://www.typescriptlang.org/docs/handbook/namespaces.html
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
ChromebookでLinux環境を構築してQGISを動かすまで

ChromebookのLinux環境でQGISを動かすまでのメモです。

## 環境
[hp Chromebook x360 14c](
https://jp.ext.hp.com/notebooks/personal/chromebook_x360_14c/)

+ CPU：Core5-10210U
+ メモリ：8GB
+ Chrome OS：93.0.4577.95

## 手順
#### Linux環境の構築
[googleのサポートページ](https://support.google.com/chromebook/answer/9145439?p=chromebook_linuxapps&b=hatch-signed-mp-v6keys&visit_id=637687492538380512-188032290&rd=1)を参照して作業。
設定　→　デベロッパー　→　Linux 開発環境　→　オンにする
しばらく待つと、ターミナルが表示されるので、一応Linuxのバージョンを確認

```sh
（アカウント名）@penguin:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
（アカウント名）@penguin:~$ 
```
これでLinux環境の構築は終了。簡単・・・！
#### QGISのインストール
[QGISの公式サイト](https://qgis.org/ja/site/forusers/alldownloads.html#debian-ubuntu)に書かれているコマンドをターミナルに貼り付けて実行するだけ。Linuxターミナルを右クリックすると、コピーしたテキストを貼り付けることができます。
実行したのは、以下の５つです。記事作成時点の内容なので、実行する際は公式ページから最新のものを参照してください。
インストールには割と時間がかりました（私の環境で２０分前後）。

```
sudo apt install gnupg software-properties-common
```
```
wget -qO - https://qgis.org/downloads/qgis-2021.gpg.key | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/qgis-archive.gpg --import
sudo chmod a+r /etc/apt/trusted.gpg.d/qgis-archive.gpg
```
```
sudo add-apt-repository "deb https://qgis.org/ubuntu $(lsb_release -c -s) main"
```
```
sudo apt update
```
```
sudo apt install qgis qgis-plugin-grass
```

一応バージョンの確認をしておきましょう。

```
（アカウント名）@penguin:~$ apt-cache policy qgis
qgis:
  Installed: 1:3.18.3+15buster-1
  Candidate: 1:3.18.3+15buster-1
```
QGIS 3.18が正常にインストールされていることが確認できました。

####QGISの起動
アプリ一覧の「Linux アプリ」からQGISデスクトップを起動します。
![Screenshot 2021-10-02 16.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/d88320be-0bcd-68ca-b327-f8794057c46f.png)

上部メニューのSettings→Options
![qgis-langsetting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/4157d025-63d5-af5f-ebc9-c5995610da2f.png)

General→上部のOverride System Localeにチェック→User interface TranslationとLocaleを日本語に設定→OK
QGISを再起動

#### QGISの動作確認
空間デーテが表示できることを確認していきます。
[国土数値情報の行政区域](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v3_0.html#prefecture28)と[鉄道のライン](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v2_3.html)をダウンロード

LinuxからChromeOSのファイルを参照するためには、ファイルアプリ→フォルダを右クリック→Linuxと共有　とします。
Linuxから　/mnt/chromeos/MyFiles/　以下で参照できるようになります。
![Screenshot 2021-10-02 16.53.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/20d0f372-707a-2a4d-6d14-1e773e2d67f2.png)

ポリゴンとラインが正しく表示できることが確認できました。
![Screenshot 2021-10-02 17.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/060a1a04-fe5d-bace-650e-24764a47fc22.png)
【AWS】EC2インスタンスが正常に稼働してもping疎通が通らない原因と解決策

今回はAWSのEC2インスタンスにおいて、インスタンスは実行中でSSH接続も出来るし、Apacheも正常に動作していて、index.htmlもちゃんと表示されるのにping疎通が通らないといった場合の原因と解決策を解説します。

#前提条件
- Windows10を使用。
- PCはDELLを使用。
- 東京リージョンを使用。

#原因
SSH接続出来てApacheも動いているのに以下のようにpingだけ通らないといったことがよくあると思います。
「0 received, 100% packet loss」と表示されているので応答がないことを確認できます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/02692ddf-f65c-c626-c64d-ee9d11f7e90f.png)

原因は、ネットワークにおけるセキュリティ周りが原因です。
具体的に言うとセキュリティグループの設定に問題があります！

#解決策
セキュリティグループのインバウンドルールを修正する必要があります。
１、IMCPのプロトコルを許可する必要があるので「すべてのICMP - IPv4」を選択します。
２、ICMP許可するIPアドレスを入力する。※今回は自宅のIPアドレスを許可しております。
３、「ルールの保存」をクリックする。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/41afe381-6c91-739b-d4d5-9373bc3bc624.png)

４、セキュリティグループの設定が完了したら再度ping疎通を実施し、以下のように
「4 received, 0% packet loss」と表示されていればping疎通はOKです！
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/735a9c91-2dd1-c4a3-79ed-bbd0f417abf1.png)

#終わりに
今回はAWSのEC2インスタンスにおいて、サーバは正常に動作しているけどping疎通が通らない場合の原因と解決策について解説しました。
少しでも参考になれば幸いです♪
YOLOXのインストール時エラーの対処（ERROR: Command errored out with exit status 1: /opt/conda/bin/python3.7 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '）

# エラーの内容

YOLOXのインストールで次のエラーが出た

```
ERROR: Command errored out with exit status 1: /opt/conda/bin/python3.7 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/home/sagemaker-user/YOLOX/setup.py'"'"'; __file__='"'"'/home/sagemaker-user/YOLOX/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps Check the logs for full command output.
```

# 原因
Pythonのバージョンによるものだと思われます

# 解決方法
Python3.6に切り替えましょう

## バージョンの切り替え
### Windows
Windows版のPython3.3からデフォルトでインストールされるPythonランチャーで簡単に切り替えられます

```bash:実行例
py -3.6 xxx.py
```

参考：[Pythonの複数バージョンの扱い方（Windowsの場合）](https://gammasoft.jp/python/python-version-management/)

### Linux
pyenvがおすすめです
参考：[pyenv | Github](https://github.com/pyenv/pyenv)


# (ついでに) YOLOX-sで推論してみる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">最近話題のYOLOXで推論<br><br>原付に乗っている人までちゃんと認識しているのすごい🏍<a href="https://t.co/fEqk4LAENn">https://t.co/fEqk4LAENn</a>…<a href="https://twitter.com/hashtag/YOLOX?src=hash&amp;ref_src=twsrc%5Etfw">#YOLOX</a> <a href="https://twitter.com/hashtag/AI?src=hash&amp;ref_src=twsrc%5Etfw">#AI</a> <a href="https://twitter.com/hashtag/PyTorch?src=hash&amp;ref_src=twsrc%5Etfw">#PyTorch</a> <br><br>[YOLOX-s] <a href="https://t.co/Pcp1nBrTgz">pic.twitter.com/Pcp1nBrTgz</a></p>&mdash; 宮本 大輝@TechSword CTO (@i7i5) <a href="https://twitter.com/i7i5/status/1443856471653969927?ref_src=twsrc%5Etfw">October 1, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">別の動画で <a href="https://twitter.com/hashtag/YOLOX?src=hash&amp;ref_src=twsrc%5Etfw">#YOLOX</a> 推論<br><br>YOLOはアルゴリズムの性質上、オブジェクトの重なりに弱いと聞いたことがあるが、これをみる限りそうでもない気がしますね<br><br>今度、別々のアルゴリズムを並べて比較してみよ<a href="https://twitter.com/hashtag/AI?src=hash&amp;ref_src=twsrc%5Etfw">#AI</a> <a href="https://twitter.com/hashtag/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92?src=hash&amp;ref_src=twsrc%5Etfw">#機械学習</a> <a href="https://twitter.com/hashtag/%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98?src=hash&amp;ref_src=twsrc%5Etfw">#画像認識</a> <a href="https://twitter.com/hashtag/DeepLearning?src=hash&amp;ref_src=twsrc%5Etfw">#DeepLearning</a> <a href="https://t.co/Bfqr9Qxnwr">pic.twitter.com/Bfqr9Qxnwr</a></p>&mdash; 宮本 大輝@TechSword CTO (@i7i5) <a href="https://twitter.com/i7i5/status/1444202036908621825?ref_src=twsrc%5Etfw">October 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
AWS Lambda プロビジョニング済み同時実行を設定する

# プロビジョニング済み同時実行とは
コールドスタートを防ぐ機能です。コールドスタートとは Lambda 関数の呼び出し時にインスタンスを初期化してから関数を実行することです。プロビジョニング済み同時実行数に 0 より大きな値を設定することで追加料金が発生します。

# 設定手順

「新しいバージョンを発行」をクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/1ea6eb7a-33a1-d93e-f774-d6ba8ae349e4.png)

「発行」をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/fec4f794-71ac-537d-ffe0-6e6a56ace2be.png)

「設定タブ」$\to$「プロビジョニングされた同時実行」$\to$ 「編集」の順にクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/8839e520-184d-2cc3-4dd4-ce9ed15c0d91.png)

同時実行数を入力し、「保存」をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/12eedc4b-1d51-02b1-79b0-56d873a76df8.png)

これで完了です。

このプロビジョニングされた Lambda 関数を API Gateway の REST API で呼び出すには、ステージ変数を使用します。

https://aws.amazon.com/jp/blogs/compute/using-api-gateway-stage-variables-to-manage-lambda-functions/

こちらについても記事を書きました。

https://qiita.com/quryu/items/d72323ba5d5017b16913

# 参考記事

https://aws.amazon.com/jp/blogs/news/new-provisioned-concurrency-for-lambda-functions/
rails g または rails c を実行するとCPU使用率が100%(熱くなる)になる

# 事象
railsコマンドを使っているとPCが非常に熱くなりました。
再起動を行うと解消されますが、railsコマンドを使うと再び熱くなりました。
熱くなるコマンドは以下でした（後で記載しているGemfileでわかりますが、developmentに関わるコマンドが影響あるようです)。

```
* rails c
* rails g ~~
* bundle exec spec ~~
```

熱くなったのでPCの状態を次のようにして確認しました。

```shell:tarminl
% ps aux | head -n 2
USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
username   68581 100.0  2.4  9070972 397040   ??  Rs    2:29PM   5:51.09 ruby -I /Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib -I /Users/username/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/spring-2.1.1/lib -e require 'spring/application/boot'
```

# 対象
現象が発生するのは限定的なようです。ポイントは`M1プロセッサ`のようです。

```
Machine : MacBook Air（M1プロセッサ）
OS      : macOS Big Sur version 11.6
ruby    : ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin20]
rbenv   : rbenv 1.1.2
rails   : Rails 6.0.4.1
```

# 原因
springかlistenというrailsのライブラリに関わる問題だと報告があるようです。
詳細は、参考サイトのページで確認してください。

# 簡易的対策(コマンド)
① アプリケーションのフォルダへ移動する（アプリ名がappの場合）

```
% cd app
```

② springを停止させる

```
% spring stop
Spring stopped.
```

# 簡易的対策(Gem)
① Gemfile の gem 'spring' と  gem 'spring-watcher-listen', '~> 2.0.0' をコメントアウトする

```file:Gemfile
group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  # gem 'spring'
  # gem 'spring-watcher-listen', '~> 2.0.0'
end
```

② bundle install コマンドを実行する

# 恒久的な対策
① Gemfile の `gem 'listen', '>= 3.0.5', '< 3.2'` を `　gem 'listen', '>=3.0.5', '<4.0'` に変更する

```file:Gemfile
group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
　　　　gem 'listen', '>=3.0.5', '<4.0'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end
```

② bundle install コマンドを実行する

# 参考サイト
[Github - rails/spring | Pegging CPU core on Apple M1 processor #636](https://github.com/rails/spring/issues/636)

# その他
私は、どうしても簡易的対策しか打てない環境でした。
そのため、気づくとどうしてもPCが熱くなります。
そのため、CPU使用率が高くなっていることを通知するソースコードを製作してみました。

[ryohei-takasugi/rails-cpu-checker](https://github.com/ryohei-takasugi/rails-cpu-checker)

10秒周期でPSコマンドを実行しています。 PSコマンドのCPU使用率をチェックして、60%以上になっているプロセスを見つけます。 また、それのプロセスが「spring/application/boot」である場合に次の動作をします。

* 現在日時を表示します。
* PSコマンドの取得内容を表示します。
* 音声で確認を促します。

# 追記　
## 2021/10/6
Railsを同じく勉強している方から「Spring」って何？と聞かれました。
そういえば、調べていたのに書いていなかったため、追記したいと思います。
GitHubの説明を読む限り、Railsコマンドを高速に起動するため、必要となるファイルを事前に読むこんでおくライブラリのようです。
そのため、導入しなくても動作は変わらず、起動が遅くなるだけで済みます。

[Github - rails/spring](https://github.com/rails/spring)
flaskのrequest.form[]とrequest.form.get()の違い

#はじめに
今までrequest.form.get()でコードを書いていたが、他の人のコードを見るとrequest.form[]という書き方がちらほら。
これらの違いは何か調べてみた。

#結論
request.form.get()は探しているものがなければエラーが出ないようにデフォルトの値を返すそう
request.form[]はデフォルトの値がないため探しているものがなければエラーをはいてしまう

##例
そう言われてもいまいちわからないので実際に試してみた

```python:app.py
@app.route("/input", methods=['GET', 'POST'])
def input():
    if request.method == "POST":
        #if request.form['name']:
        if request.form.get('name'):
            return "成功！"
        else:
            return "失敗"
    else:
        return render_template("input.html")
```

```html:input.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Input</title>
</head>
<body>
    <form action="/input" method="POST">
        <input type="text" name="name">
        <input type="submit">
    </form>
</body>
</html>
```

### if request.form['name']:の場合
- input type="text" name="name"があれば成功と表示される（正常に動作する）
- input type="text" name="name"がなければエラーになってしまう(ステータスコード400)

- ->　例外処理が必須

### if request.form.get('name'):
- input type="text" name="name"があれば成功と表示される（正常に動作する）
- input type="text" name="name"がなければ失敗と表示される

- ->　例外処理をしなくても良い（？）


##ちなみに
- request.form.get()がデフォルトで返す値はNone

```python:app.py

@app.route("/input", methods=['GET', 'POST'])
def input():
    if request.method == "POST":
        #if request.form['name']:
        if request.form.get('name'):
            return "成功！"
        else:
            test = request.form.get('name')
            return render_template("input.html", test=test)
    else:
        return render_template("input.html")
```

```html:input.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Input</title>
</head>
<body>
    <p>{{ test }}</p>
    <form action="/input" method="POST">
        <input type="text" name="nam">　#ここが間違っている
        <input type="submit">
    </form>
</body>
</html>
```

![スクリーンショット 2021-10-02 16.14.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087368/7e2c0b79-164f-9f3e-7894-05d668a9b962.png)

#おわりに
どちらにもメリット・デメリットがあるので必要に応じて使い分けたい。


##参考
https://stackoverflow.com/questions/39806433/flask-differences-between-request-formxxxxx-request-form-getxxxxxx-and

https://www.reddit.com/r/cs50/comments/5saebt/pset_7_flask_requestform_vs_requestformget/
Let's Encrypt証明書を使ったメールサーバからの送受信がiOSでエラーになる場合の対処方法

# はじめに
無料SSL証明書を発行するLet's Encryptで従来使用されていたDST Root CA X3証明書が2021年9月30日で使用できなくなり、これに伴い、この証明書で運用していた自身のメールサーバ（Postfix, Dovecot）につき、iOSでのメール送受信（SSL）ができなくなったので対応した。

# 結論
1. Let's Encrypt証明書をいったん削除し、certbot コマンドに ```--preferred-chain "ISRG Root X1"``` オプションを追加して証明書を再作成する
1. PostfixおよびDovecotで、証明書として cert.pem ではなく **fullchain.pem** を指定する

# 経緯
- [この記事](https://ssl.sakura.ad.jp/column/letsencrypt-root-certificate/)のように、以前からLet's Encryptで使用されていたDST Root X3のルート証明書は2021年9月30日で使用できなくなることは以前からアナウンスされていた。
- その後はISRG Root X1がルート証明書として利用されるが、かなり古いブラウザではこのルート証明書が使用されないことが懸念されていたものの、新しめのブラウザでは問題なく使用でき、自身の環境でもブラウザでの閲覧では問題が起きなかった。
- しかしiOS（iPhone, iPad）では、Let's Encrypt証明書を使用しているメールサーバにつき送受信時にエラーが出るようになった。

# 上記1.の対応について
- Let's Encryptのルート証明書として**ISRG Root X1**が優先されるように証明書を再作成する（Webサーバとして証明書を発行し、それをメールサーバに転用する運用をしています）

# 上記2.の対応について
- Let's Encrypt証明書をメールサーバ（Postfix, Dovecot）で使用する場合、従来は証明書として cert.pem を指定しても運用できていたが、上記変更以来エラーになったため fullchain.pem に変更することで解決できた。

久しぶりにPostfixでのメールサーバ構築手順の記事をいろいろ調べたところ、Let's EncryptのSSL証明書としては「fullchain.pem を使用すること」とする記事が多かったので、自身がこのメールサーバを構築した際に参照した記事が古かったことが障害の原因と思われます。
【Vue.js】Vue Routerについて

#はじめに
こんにちは。
Vue.jsのVue Routerの実装についてアウトプットしていきます！

##Vue Routerとは
>Vue RouterはVue.js公式ルータです。これは Vue.js のコアと深く深く統合されており、Vue.js でシングルページアプリケーションを構築します。

> 参照：https://router.vuejs.org/ja/



```html:HTML
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-router"></script>
```
まずは、HTMLにCDNで読み込ませます。
※バージョンを指定する場合はURLの語尾に`@3.0.6`（バージョン）というような記述をする。
<br>

##Vue Routerの実装
Vue Routerでページ遷移を行う処理を記述します。

```html:HTML
<div id="app">
  <router-link to="/home">Homeへ</router-link>
  <router-link to="/news">Newsへ</router-link>
  <router-view></router-view>
</div>
```
`router-link to`でページ遷移先のリンクの生成、`router-view`でそれぞれのコンポーネントが描画される。

<br>

```javascript:Vue.js
const Home = { template: '<div>Home</div>' }
const News = { template: '<div>News</div>' }

const router = new VueRouter({
  routes: [
    {
      path: '/home',
      component: Home
    },
    {
      path: '/news',
      component: News
    }
  ]
})

const app = new Vue({
  router
}).$mount('#app')
```
それぞれのページで使用するコンポーネントを定義する。
Routerインスタンス内には、ページの遷移先とtemplateを格納した変数を記述して呼び出す。
Vueインスタンスには、routerを渡して使用できるようにマウントしている。

<img width=“400” src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966101/1511041f-edcf-06d2-3a0d-a2fcb410e8c1.png">

上記のように、ページ全体は更新されずにHomeとNewsが切り替わる処理が実装できました。

<br>


#最後に
ここまでVue Routerについてまとめました。
初めて使ってみたとき、こうやってSPAが作成できるのか！と感動してました笑
色んな気づきが得られるので、ひとつひとつ身につけていこうと思います！
python の TypeVar を最もシンプルな例で理解する

python の型ヒント（アノテーション）については、基本的に [公式ドキュメント](https://docs.python.org/ja/3/library/typing.html) に記述されている。しかし、実用的な範囲でのシンプルな例が記載されているため、理解したいこと以外の情報もあり、やや理解しにくいことがある。そのため今回、実用性は度外視し、 `TypeVar` 自体を理解することだけを目的とした情報を残したく、本記事を作成した。なお、記事中の表現は、筆者独自の表現である場合があることはご了承いただきたい。

python のバージョンは 3.9 を想定している。

## TypeVar とは

`TypeVar` とは、「とある決まった型」を表す場合に用いる型変数である。

## TypeVar の使用例

例えば下記のように、引数をそのまま返す関数の定義に使用する。

```python:use_typevar.py
from typing import TypeVar

T = TypeVar("T")


def get_t_arg(arg: T) -> T:
    return arg
```

上記の `get_t_arg(arg: T) -> T` の型ヒントは、 **「引数 `arg` の型が `T` であるとき、返り値の型が `T` である」** ことを意味する。例えば、 `get_t_arg` の引数として渡した `arg` の型が `int` であるときの返り値の型は `int` であるし、 `arg` の型が `str` であるときの返り値の型は `str` である。

## TypeVar と Any の違い

`Any` とは、制約のない型である。

下記例を用いて `TypeVar` との違いの説明を試みる。

```python:use_any.py
from typing import Any


def get_any_arg(arg: Any) -> Any:
    return arg
```

上記の `get_any_arg(arg: Any) -> Any` の型ヒントは、 **「引数 `arg` に型の制約はなく、返り値にも型の制約はない」** ことを意味する。例えば、 `get_any_arg` の引数として渡した `arg` の型が `int` であるときの返り値の型に制約はなく、返り値の型が `int` や `str` などの可能性がある（当然 `get_any_arg` の実装上、引数と返り値の型が異なることはないが、型ヒントが表すのはそのような意味となる）。

このように、 `TypeVar` と `Any` は全く異なる。

## 許容する型を制限する場合の TypeVar の使用例

`TypeVar` を用いたいが、許容する型を制限したい場合がある（例えば「 `int` または `float` のみを許容する」など）。その際の使用例は下記。

```python:use_int_or_float_typevar.py
from typing import TypeVar

T = TypeVar("T", int, float)


def add_one_to_t_arg(arg: T) -> T:
    return arg + 1
```

上記のように `T = TypeVar("T", int, float)` と宣言した際の `add_one_to_t_arg(arg: T) -> T` の型ヒントは、 **「引数 `arg` の型は `int` または `float` であり、 `arg` の型が `int` のときの返り値の型は `int`、 `arg` の型が `float` のときの返り値の型は `float` である」** ことを意味する。

## 許容する型を制限する場合の TypeVar と Union の違い

`Union` とは、「指定したいずれかの型」を表す型である。

下記例を用いて `TypeVar` との違いの説明を試みる。

```python:use_union.py
from typing import Union


def add_one_to_num(num: Union[int, float]) -> Union[int, float]:
    return num + 1
```

上記の `add_one_to_num(num: Union[int, float]) -> Union[int, float]` の型ヒントは、 **「引数 `num` の型は `int` または `float` であり、返り値の型も `int` または `float` である」** ことを意味する。例えば、 `add_one_to_num` の引数として渡した `num` の型が `int` であるとき、返り値の型は `int` である可能性も `float` である可能性もある。

## 複数の TypeVar を使用する例

```python:use_multi_typevar.py
from typing import TypeVar

T = TypeVar("T")
S = TypeVar("S")


def get_t_and_s_args(t_arg: T, s_arg: S) -> tuple[T, S]:
    return t_arg, s_arg
```

上記の `get_t_and_s_args(t_arg: T, s_arg: S) -> tuple[T, S]` の型ヒントは、 **「第一引数 `t_arg` の型が `T`、第二引数 `s_arg` の方が `S` のとき、返り値の方は `tuple[T, S]` である」** ことを意味する。

以上です。閲覧ありがとうございました！
AWS API Gateway バージョンやエイリアスを指定して Lambda 関数を呼び出す

# 設定の概要

やることは以下の通りです。

- Lamdbda
  - バージョンやエイリアスを作成する
  - API Gateway の呼び出し許可のためにリソースベースのポリシーを作成する
- API Gateway
  - Lambda 関数名に `{stageVariables.version}` や `{stageVariables.alias}` を含める
  - ステージ変数を追加する

# 手順

## Lambda

- バージョンやエイリアスを作成する

ここではバージョンを作成します。

「新しいバージョンを発行」をクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/a1b3ee28-7343-9884-2122-71b70761f039.png)

「発行」をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/efbfaeb5-6d10-b4c8-e324-da2b4bde7471.png)

- API Gateway の呼び出し許可のためにリソースベースのポリシーを作成する

これは次の API Gateway の手順の途中で設定します。API Gateway の ID やステートメント ID という API Gateway が発行する ID が必要であるためです。

## API Gateway

- Lambda 関数名に `{stageVariables.version}` や `{stageVariables.alias}` を含める

メソッドは POST でも GET でも問題ありません。ポップアップが出てきたとき注意してください。Lambda のリソースベースのポリシーに必要な値です。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/a996214d-d3fe-ba96-b392-3f4f824e6817.png)

**ポップアップ**

「OK」は Lambda のリソースベースのポリシーを設定するまで押しません。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/a6f813bf-f73e-c6dd-d9f2-01bf100e2f86.png)

新しいタブで Lambda 関数のアクセス権限を開きます。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/2573b8af-50b5-347c-01a0-d5fe911682fb.png)

上記のポップアップの各値を以下のように設定します。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/026e0e68-afde-a16e-ac30-fa76a9631c7b.png)

その後「OK」をクリックし、ポップアップを閉じます。

- ステージ変数を追加する

CORS を有効化し、API をデプロイします。その後、「ステージ変数」タブでステージ変数を追加します。ここには Lambda 関数のバージョンを入力します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/26e34f94-a2c0-34bf-faa7-0ba04603a048.png)

最後に「設定」タブをクリックし、「変更を保存」をクリックします。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/f41b97bb-7871-fe0b-74e3-5bcb5650d2bd.png)

エイリアスの場合も同じ手順です。

## テスト

以下のコードで動作確認を行いました。

```index.html
<!DOCTYPE html>
<html>
<body>
  <button onclick="myFetch()">click</button>
  <script>
    function myFetch() {
      const raw = JSON.stringify({test: 'hello'});
      const myHeaders = new Headers();
      myHeaders.append('Content-Type', 'application/json');
      const requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        redirect: 'follow'
      };
      fetch('https://API_GATEWAY_ID.execute-api.ap-northeast-1.amazonaws.com/ver', requestOptions)
        .then(response => response.text())
        .then(result => {
          console.log(result);
        })
        .catch(error => {
          console.log(error);
        });
    }
  </script>
</body>
</html>
```

# 参考記事

https://aws.amazon.com/jp/blogs/compute/using-api-gateway-stage-variables-to-manage-lambda-functions/