OmniAICreator/Qiita-1.07M huggingface dataset:
FlutterアプリでRIVE2製アニメーションが動かない！？場合に読む記事

今回は、FlutterアプリのスプラッシュスクリーンにRIVE２を使ってアニメーションを作ってみました。
気づいたことや引っかかったことを簡単にまとめます。
大まかな流れなどは省いて、注意点のみ記載しています。


導入の仕方などは、こちらでOKだと思います。
https://zenn.dev/zumikou/scraps/8f9e1130af58e4
https://qiita.com/kitamuyu/items/13909a2888757b456837


## RIVE2にjpg、pngファイルをインポートできない。
rive2
https://rive.app/index.html

自分の持っている画像を動かそうと思ったが無理でした。
しかし、**svgファイル**はうまくインポートできました。
自分で2Dの絵を作るところから始めるのがめんどくさい方は、svg素材を持っていると楽ですね。

## packageのriveでアニメーションが動かない

以下がそのパッケージ
https://pub.dev/packages/rive

exampleからinitState部分を抜粋。

```dart
@override
  void initState() {
    super.initState();

    // Load the animation file from the bundle, note that you could also
    // download this. The RiveFile just expects a list of bytes.
    rootBundle.load('assets/off_road_car.riv').then(
      (data) async {
        final file = RiveFile();

        // Load the RiveFile from the binary data.
        if (file.import(data)) {
          // The artboard is the root of the animation and gets drawn in the
          // Rive widget.
          final artboard = file.mainArtboard;
          // Add a controller to play back a known animation on the main/default
          // artboard.We store a reference to it so we can toggle playback.
          artboard.addController(_controller = SimpleAnimation('idle'));
          setState(() => _riveArtboard = artboard);
        }
      },
    );
  }
```

僕は、rivファイルの部分のパスを自分のものに置き換えて終了かと思っていました。

しかし、

```dart
artboard.addController(_controller = SimpleAnimation('idle'));
```

'idle'の部分を自分で作ったアニメーションの名前に変更しないとダメでした。
僕の場合は以下の写真のように、名前は「Animation 1」でした。
![スクリーンショット 2021-02-13 8.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634174/8b30f5c6-2df0-eb2c-af0f-8bee87a79002.png)
この２点がつまずいた点でした。
参考にならば幸いです。
ストロングパラメータによるblankErrorの解決例

新規登録画面からユーザー登録をするとNickname can'tbe blankというエラーが生じます。

nicknameの入力フォームに記入できた場合、
入力→保存の間で値が抜けている可能性があります。

今回はdeviseというGemが使用されています。
deviseでは、*ストロングパラメータを直接設定しません。
予め用意されている以外のカラムを保存したい場合は、
特別に追記する必要があるファイルです。

deviseに保存するカラムのストロングパラメータを追記する場所を確認します。
application_controller.rbのconfigure_permitted_parametersというメソッドです。

記述はあったが、許可するカラム名がnameとなっていたのでこの場合、
nicknameに修正して完了になります。

*ストロングパラメータ
WEB上から受け付けたパラメータが安全なデータか検証して取得する仕組みです。
この仕組みを使うことで意図しないデータの登録更新を防ぎます。
manimの作法 その49

#概要

manimの作法、調べてみた。
ComplexPlane使ってみた。

#サンプルコード


```
from manimlib.imports import *

class test(Scene):
	CONFIG = {
		"plane_config": {
			"x_radius": 9,
			"y_radius": 9,
			"stroke_width": 3,
		},
		"background_plane_config": {
			"color": LIGHT_GREY,
			"secondary_color": DARK_GREY,
			"stroke_width": 0.5,
			"stroke_opacity": 0.5,
			"secondary_line_ratio": 0,
		}
	}
	def construct(self):
		self.add_planes()
		z_tuples = [(complex(2, 1), "2 + i", UP), (complex(5, 2), "5 + 2i", LEFT), (complex(-np.sqrt(2) / 2, np.sqrt(2) / 2), "-\\frac{\\sqrt{2}}{2} + \\frac{\\sqrt{2}}{2} i", LEFT, ), (complex(-4, 1.5), "-4 + 1.5i", RIGHT), (complex(3, 0), "3 + 0i", UP), (complex(4, -3), "4 + -3i", UP), ]
		for z, z_tex, label_vect in z_tuples:
			self.show_multiplication(z, z_tex, label_vect)
	def add_planes(self, include_title = True):
		plane = ComplexPlane(**self.plane_config)
		self.plane = plane
		background_plane = ComplexPlane(**self.background_plane_config)
		background_plane.add_coordinates()
		self.background_plane = background_plane
		self.add(background_plane)
		self.add(plane)
		if include_title:
			title = TextMobject("Complex plane")
			title.scale(1.5)
			title.to_corner(UL, buff = MED_LARGE_BUFF)
			title.shift(SMALL_BUFF * UR)
			self.title = title
			self.add_foreground_mobjects(title)
	def show_multiplication(self, z, z_tex, label_vect):
		z_color = WHITE
		plane = self.plane
		new_plane = plane.deepcopy()
		real_tex, imag_tex = z_tex.split("+")
		label = TexMobject("\\text{Multiply by}\\\\", real_tex, "+", imag_tex, alignment = "", )
		label[1].set_color(GREEN)
		label[3].set_color(RED)
		label.scale(1.2)
		h_line = Line(plane.number_to_point(0), plane.number_to_point(z.real), color = GREEN, stroke_width = 5, )
		v_line = Line(plane.number_to_point(z.real), plane.number_to_point(z), color = RED, stroke_width = 5, )
		lines = VGroup(h_line, v_line)
		z_point = plane.number_to_point(z)
		z_dot = Dot(z_point)
		z_dot.set_color(z_color)
		label[1:].next_to(z_dot, label_vect)
		label[0].next_to(label[1:], UP)
		for mob in label:
			label.add_to_back(BackgroundRectangle(mob))
		one_dot = Dot(plane.number_to_point(1))
		one_dot.set_color(YELLOW)
		for dot in z_dot, one_dot:
			dot.save_state()
			dot.scale(5)
			dot.set_fill(opacity = 0)
			dot.set_stroke(width = 1, opacity = 0.5)
		to_fade_out = VGroup(plane, label, lines, z_dot, one_dot)
		self.play(ShowCreation(lines), FadeInFromDown(label), Restore(z_dot), )
		self.play(Restore(one_dot))
		angle = np.log(z).imag
		self.play(one_dot.move_to, z_dot, plane.apply_complex_function, lambda w: z * w, path_arc = angle, run_time = 3)
		self.wait()
		self.play(FadeOut(to_fade_out), FadeIn(new_plane), )
		self.plane = new_plane





```

#生成した動画

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

以上。
【PowerShell】WindowsPCからLinux上のファイルをダウンロードする

### 前置き
今回は Putty を使用して WindowsPC から Linux サーバのファイルを取得するサンプルプログラムを紹介します。
毎日シェルの実行結果をとってくる単純作業を「自動化できたらいいな」と思い、作りました。
PowerShellから他のCLIツールにコマンドの実行について記載しているため、Putty 以外のツールをご利用されている方でも参考になるのではないかと思ってます。

別の記事でLinuxサーバのシェルを実行する記事も書かせていただいております。
一連の流れで「シェルの実行」 → 「実行結果ログのダウンロード」のような場合に使えると思いますので、是非見ていってください。
[【PowerShell】WindowsPCからLinux上のShellファイルを実行する](https://qiita.com/CheatBook/items/2895f374f613a94c7fc0)


### シナリオ

１．ローカルに日付フォルダを作成する
２．PuttyでLinuxサーバにログイン
３．「１」で作成したフォルダに`$TARGET_FILE_PATH`のパターンに該当するファイルをダウンロード

### サンプルプログラム

サンプルプログラムをコピーして、拡張子「.ps1」で保存してください。
下記のサンプルプログラムの`Config`部分に必要な情報を入力してください。
基本的に下記の項目を見直していただきたいと思います。
・`$PUTTY_PATH`
・`$USER_NAME`
・`$IP_ADDRESS`
・`$PASSWORD`
・`$TARGET_FILE_PATH`

```powershell:GetLogFile.ps1

################################## Config ##################################

# 取得したいファイルのパターン用で使用
$NEW_DATE = Get-Date -Format "yyyyMMdd"

# 格納先フォルダ名で利用
$NEW_DATE_TIME = Get-Date -Format "yyyyMMdd_HHmmss"

# PUTTY情報
$PUTTY_PATH = "C:\Tools\PuTTY"
$PSFTP_PATH = Join-Path $PUTTY_PATH "psftp.exe"

# Linux接続情報
$USER_NAME = "user"
$IP_ADDRESS = "XX.XX.XX.XX"
$PASSWORD = "password"

<# 取得先設定
    今回のデフォルトは実行PowerShellと同一のフォルダ配下に
    日付フォルダを作成して、その中に取得したファイルを格納する
#>
$DOWNLOAD_PATH = Join-Path $PSScriptRoot $NEW_DATE_TIME

# 取得したいファイル名パターン
# 今回の例だと「/users/app」配下の「test_20210212_1111.log」などが取得できる
$TARGET_FILE_PATH = "/users/app/test_${NEW_DATE}*.log"

############################################################################

########################## 文字コードをUTF8に変更 ##########################
chcp 65001
############################################################################

############################# ファイル取得処理 #############################

# 格納先フォルダ作成・移動
if (!(Test-Path $DOWNLOAD_PATH)) {
    New-Item $DOWNLOAD_PATH -Type Directory
}
Set-Location $DOWNLOAD_PATH

# Linux上で実行したいコマンドを上から順番に記述
# mgetコマンドにすることでパターンが一致するものを取得できる。
# パターンに該当するファイルが複数存在する場合は全て取得する。
$executionCommadn = @(
    "mget ${TARGET_FILE_PATH}"
    , "exit"
)

# 配列に入っているコマンドを上から順番に実行する
$executionCommadn | & $PSFTP_PATH “${USER_NAME}@${IP_ADDRESS}” -pw $PASSWORD

############################################################################

```

### 終わりに
今回はシェルの実行結果ログファイルをダウンロードする想定で書かせていただきました。
まぁ、使う機会は極めてまれだと思いますが、定例業務の効率化ができるので、よかったら試してみてください。

あと、Linuxサーバからダウンロードするファイルのファイル名に日本語が入っていると文字化けしてダウンロードされます。
すごく調べましが解決策がみつかりませんでした。
もしご存知の方がいらしたらコメントで教えてください！

ここまで読んでいただき、ありがとうございました。
【PowerShell】WindowsPCからLinux上のShellファイルを実行する

### 前置き

今回は Putty を使用して WindowsPC から Linux サーバのシェルをキックするサンプルプログラムを紹介します。
決まった時間にシェルを実行する際はクーロンで事足りますが、手動実行したい時もあり、わざわざログインして実行するのがめんどくさかったため、PowerShellで自動化しました。
PowerShellから他のCLIツールにコマンドの実行について記載しているため、Putty 以外のツールをご利用されている方でも参考になるのではないかと思ってます。

別の記事でLinuxサーバのファイルをダウンロードする記事も書かせていただいております。
一連の流れで「シェルの実行」 → 「実行結果ログのダウンロード」のような場合に使えると思いますので、是非見ていってください。
[【PowerShell】WindowsPCからLinux上のファイルをダウンロードする](https://qiita.com/CheatBook/items/a64cf00be9e0228f51c4)

### シナリオ

１．PuttyでLinuxサーバにログイン
２．`$EXECUT_FILE_PATH`で指定したシェルを実行する

### サンプルプログラム

サンプルプログラムをコピーして、拡張子「.ps1」で保存してください。
下記のサンプルプログラムの`Config`部分に必要な情報を入力してください。
基本的に下記の項目を見直していただきたいと思います。
・`$PUTTY_PATH`
・`$USER_NAME`
・`$IP_ADDRESS`
・`$PASSWORD`
・`$EXECUT_FILE_PATH`

```powershell:ExecutShell.ps1

################################## Config ##################################

# PUTTY情報
$PUTTY_PATH = "C:\Tools\PuTTY"
$PLINK_PATH = Join-Path $PUTTY_PATH "plink.exe"

# Linux接続情報
$USER_NAME = "user"
$IP_ADDRESS = "XX.XX.XX.XX"
$PASSWORD = "password"

# 実行するシェルのパス
$EXECUT_FILE_PATH = "/users/app/test.sh"

############################################################################

########################## 文字コードをUTF8に変更 ##########################
chcp 65001
############################################################################

############################## シェル実行処理 ##############################

# Linux上で実行したいコマンドを上から順番に記述
<#
 ログイン直後はCLI上にゴミが初期値で競ってされており、
 配列[0]にLinuxコマンドを入力した場合、
 「 ﻿sh: コマンドが見つかりませんでした...」と出力された。
 サンプルプログラムでは、配列[0]に空白を入れることで回避している。
   ※ 空白を入れるとEnterを押したときと同じ動きをする
#>
$executionCommadn = @(
    ""
    , "sh ${EXECUT_FILE_PATH}"
    , "exit"
)

# 配列に入っているコマンドを上から順番に実行する
$executionCommadn | & $PLINK_PATH “${USER_NAME}@${IP_ADDRESS}” -pw $PASSWORD

############################################################################

```

### 終わりに
今回は、シェルの実行についてでしたが、もちろん他のLinuxコマンドも利用できるので、是非、応用して使ってみてください。
ここまで読んでいただき、ありがとうございました。
配列の基礎を総復習！

今回は、swiftにおける基礎中の基礎、「配列」の復習をしたいと思います！
この記事を読むと、以下のことがざっとおさらいできます。

- 配列とは、宣言方法
- 空の配列、配列の初期化
- 配列から値を取り出す
- 配列の追加と削除

それではいきましょう！


## 配列とは、宣言方法

配列とは、複数の値を入れられる箱のようなもの。
これを作ることによって、様々なデータを自由に格納したり取り出したりできます。

宣言方法は3通りあります。

```swift
let strings = ["aa", "bb", "cc"]
let strings:[String] = ["aa", "bb", "cc"]
let strings:Array<String> = ["aa", "bb", "cc"]
```

もちろんvarでもOKです。


## 空の配列、配列の初期化

空の配列は、値をなし[]にすればオッケー
また、isEmptyプロパティを使えば空かどうかを判別します。

```swift
var intArray = [1,4,6]
intArray = []
if intArray.isEmpty {
  print("空です")
}

//空です
```

## 配列から値を取り出す

インデックス番号を指定することによって取り出せます。
さらに、スライスすることもできます。

```swift
var intArray = [1,4,6]
let int = intArray.1
print(int)

//4
```




## 配列の追加と削除

配列に追加する場合はappend
挿入する場合はinsert
削除する場合はremoveでできます。

```swift
var colors = ["yellow", "green"]
colors.append("red")
print(colors)
colors.removeFirst //最初を削除できます
print(colors)
colors.insert("blue", at:1)
print(colors)

// "yellow", "green"
// "yellow", "green", "red"
// "green", "red"
// "green", "blue","red"
```


以上です。
他にもソートとかマップとかあるんですけど、やる気が高いときにまた改めて投稿します。笑
Laravelでnpm runしたときのメモ


Vueテンプレートを使って、Laravelの認証画面を作ろうとして詰まった。

- Laravelに laravel/uiを導入
- vueテンプレートを指定
- npｍインストール


この流れでやると失敗した。

こちらの記事の内容も試してみたが、エラーは解決しなかった。
[laravelでnpm run devを実行すると「cross-env: not found」というエラーが出る件対応したった
](https://qiita.com/Yorinton/items/fd9dae33c6748abcdfbc)


`npm install`まではうまくいくが、`npm run dev`でエラーになる

```
npm ERR! code 1
npm ERR! path /var/www/html/larabel
npm ERR! command failed
npm ERR! command sh -c cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-02-12T22_41_21_472Z-debug.log
npm ERR! code 1
npm ERR! path /var/www/html/laravel
npm ERR! command failed
npm ERR! command sh -c npm run development

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-02-12T22_41_21_507Z-debug.log

```


## 1. webpack.mix.jsの修正

```javascript
mix.js('resources/js/app.js', 'public/js')
    .vue() // →　削除
    .sass('resources/sass/app.scss', 'public/css');
```



## npm 再インストール

```
rm -rf node_modules/
rm -rf package-lock.json

npm install
npm run dev
```


これで解決した。


```
98% after emitting SizeLimitsPlugin

 DONE  Compiled successfully in 24793ms                               10:47:18 PM

       Asset      Size   Chunks             Chunk Names
/css/app.css   179 KiB  /js/app  [emitted]  /js/app
  /js/app.js  1.41 MiB  /js/app  [emitted]  /js/app
```
Raspberry Pi などの ARM64 Linux 環境で Flutter が動くようになった

## 初めに

[Raspberry Pi](https://www.raspberrypi.org/) 4 や [Jetson](https://developer.nvidia.com/embedded-computing) などの ARM 64bit Linux 環境で Flutter アプリを動かす方法、そして Flutter アプリ自体を開発する方法を紹介しています。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/1965e9f3-0df8-ddfc-e714-6a215de17b4b.png)

## Flutter が公式に Linux ARM64 ホストをサポート！

遂に Flutter が ARM64 の Linux ホスト OS をサポート完了し、Flutter SDK (開発環境) 自体が Raspberry Pi 4 などの ARM 64bit Linux OS上で動くようになりました。Windows, macOSよりも先に純粋な ARM 64bit CPU 環境に対応しています。

Raspberry Pi 4 だとちょっとパワー不足（メモリも少なくて辛い）感がありますが、これからは Flutter アプリの開発はもちろん、Flutter アプリ (Linux desktop向け) を安価なデバイス上でも動作させることが可能です。

## Flutter SDK のインストール

特別何かをする必要はありません。通常の Windows や macOS, Linux 環境同様に Flutter SDK をインストールして利用するだけです。

ここでは必要最低限の手順のみ説明しますので、必要があれば合わせて[[Flutter] デスクトップアプリ環境構築 for Linux](https://qiita.com/kurun_pan/items/47c25a4b2425725bc199)の記事を参照して下さい。

また、ハードウェアは Raspberry Pi 4, OS は Ubuntu 20.04 64bit版を利用する前提のインストール手順です。

```
$ git clone https://github.com/flutter/flutter
$ sudo mv flutter /opt/
$ export PATH=$PATH:/opt/flutter/bin
$ sudo apt install clang curl pkg-config ninja-build cmake libgtk-3-dev libblkid-dev liblzma-dev unzip
```

## Flutter for Linux アプリを動かす

Flutter SDK をインストール後、以下を任意の場所で実行すれば、Flutter の Linux デスクトップ向けアプリが起動します。

```
$ flutter doctor
$ flutter config --enable-linux-desktop
$ flutter doctor
$ flutter create sample
$ cd sample
$ flutter run -d linux
```

## 注意

ARM64 Linux ホスト上で利用する場合、まだ機能制限があります。

- 64bit CPUのみサポートなので、当然32bit CPU や OS (rasberry pi os 32bitなど) では動作しない
- Android Studio が ARM64 Linux をサポートしておらず、ARM64 Linux 環境では Android 向け Flutter アプリは作れない
Vue.js概要？ #KnockoutJSとの違い

# はじめに
　[本文はこちら](https://qiita.com/asip2k25/items/bd4bdccd5201d542953c)

# KnockoutJSとの違い

Vue.jsと同じく、MVVMを設計基盤とした先発のフレームワークに
KnockoutJSがあります。

Vue.jsに対するKnockoutJSの唯一のアドバンテージはレガシー・ブラウザ
のサポートです。

レガシー・ブラウザにあわせて設計されていることもあり、KnockoutJSの
記法や構文は若干シンプルではありません。

後発のVue.jsのほうが記法や構文を含め、洗練されています。

KnockoutJSはMS勤務の開発者により開発・メンテンスされ、
Visual Studioでも採用されているため、数多くの企業内業務
システムで採用されていると考えられます、企業内業務システム
では稼働しているシステムの動作環境の変更が許可されることは
ないため、レガシー・ブラウザが淘汰されるまでレガシー・
ブラウザのサポートが継続されることはほぼ確実であり、企業内
業務システムの開発エンジニアが保守的傾向が強く変化を好まない
こともあり、構文や記法が今以上にシンプルになることはないと
思われます。

## 設計の違い

### ブラウザー・サポート

KnockoutJSはレガシー・ブラウザをサポートしています。

### Class指向

KnockoutJSはClass指向にふれていますが、オーソドックスなスタイルの
名残が所々にあります。例えば、クラスの設計において何をプロパティとして
扱い何をメソッド(メンバー関数)の引数として扱うかが整理されていないよう
にみえます。

Vue.jsはClass指向で設計されているため、設計はKnockoutJSより
洗練されています。

## 記法の違い

Vue.jsはモダン・ブラウザのみをターゲットにすることにより、
KnockoutJSよりも記法をシンプルにすることに成功しています。

### VMとバインディング

KnockoutJSではプロパティ(変数)は追加時or後、バインディングできる
プロパティであることを用意された関数を呼び出す形で明示する(より正確
にはES5で導入された機能を利用できないためにプロパティにセットする
オブジェクトに対して(値の変更のトラッキング機能と)セッター・ゲッター
を付加する専用の関数を呼び出す)必要があります、Vue.jsではプロパティ
はView Modelに追加するだけでバインディング可能になります。

KnockoutJSではバインディング可能なプロパティに対するアクセサが
専用の関数を呼び出すことにより自動生成されます、モダン・ブラウザの
サポートするES5以降の機能を利用できないためにアクセサは関数と
なっています。

Vue.jsでもプロパティに対する(トラッキング機能と)アクセサは
自動生成されます、ES5の機能を利用して自動生成されたアクセサ
はプロパティへのダイレクト・アクセスのように扱えます。

KnockoutJSでもKnockout-ES5プラグインを導入すれば、プロパティを
追加するだけでバインディング可能、かつ、アクセサをプロパティへの
ダイレクト・アクセスにできますが、Knockout-ES5プラグインはモダン
・ブラウザ用であり、レガシー・ブラウザを切り捨てられない場合は
利用できません。
(Knockout-ES5プラグインはプロパティまわりをES5の機能を用いて
置き換えるだけで、内部構造にはタッチしませんので、導入しても
モダン・ブラウザに導入されたJS(ES5)の他の新機能の恩恵を受けられる
わけではありません。)

Knockout-ES5: a plugin to simplify your syntax
http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax/

### バインディング
KnockoutJSのバインディングに相当する機能をVue.jsでは
ディレクティブとよびます。

KnockoutJSではViewに記述するバインディングの記法も
Vue.jsのディレクティブほどシンプルではなく、種類別の
整理も行なわれていません。

Vue.jsのディレクティブでは種類毎に独自属性が用意され、
KnockoutJSよりも見通しがよくなっています。

KnockoutJSのカスタム・バインディングに相当する機能は
Vue.jsではカスタム・ディレクティブです。

Vue.jsのカスタム・ディレクティブはKnockoutJSの
カスタム・バインディングと機能的には同等ですが、
作成が楽になっています。

### テンプレート
KnockoutJSではtemplateバインディングを用いて、
指定した要素の中身をテンプレートで差し替えることが
できますが、AngularJSのディレクティブに相当する
機能は用意されていません。

Vue.jsには、AngularJSのディレクティブに相当する、
独自タグを定義できる機能、コンポーネント(component)
があります。

## 学習コスト

KnockoutJSは学習コストがAngularJS1.xよりかなり少ないですが、
Vue.js はより少ないです。

学習コストはAngular >> Knockout > Vue.js です。
ずっとFPGA初心者（その３：タイマー&繰り返し）

# 定期的にLEDオンオフの繰り返し
ここでは、１秒おきにLEDのオンオフを繰り返す事例の紹介。用いるボードおよび開発環境は、すべて[その１](https://qiita.com/infinite1oop/items/4b0f03b97ed859fbd954)と同じである。

## ピンアサイン
### ピンの確認
時間を扱うため、用いるボードのクロックピンを確認する。[回路図](https://www.macnica.co.jp/business/semiconductor/macnica_products/max10_board_revb1p04__1.pdf)によると、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/afe5e98c-2627-dc81-4c78-c1637b56a005.png", width=70%>
50MHzのクロックはF13ピンに割り当てられている（LED0はL13ピン）。

### QuartusでのPin Planner
よって、下記のとおりとなる。
![PinPlanner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f3213255-20bb-a947-ea58-31fd562f2142.png)

## VHDLコード
### まずは不適切な例＋α
下記コードは、アルゴリズムとしては問題ない。

```vhdl:ClkLed(NG).vhd
library ieee;
use ieee.std_logic_1164.all;

entity ClkLed is
	port (
		CLK:	in std_logic;
		LED: 	out std_logic);
end ClKLed;

architecture RTL of ClkLed is
constant CYCLE : integer := 50000000; -- ①
signal CNT: integer range 0 to CYCLE-1;
	
begin	
	process (CLK)
	begin
		if (rising_edge(CLK)) then -- ②
			if (CNT = CYCLE-1) then -- ③
				CNT <= 0;
				LED <= '0'; -- 点灯
			else
				CNT <= CNT+1;
				LED <= '1'; -- 消灯
			end if;
		end if;
	end process;
end RTL;
```

不適切な理由を説明する前に、少々コードの説明。
- ①で50MHzの設定、クロック（CLK）50M回の繰り返しで1秒となる。
- ②のrising_edge(CLK)、CLKの立ち上がりを検出している。
- ③で「CYCLE」ではなく「CYCLE-1」で比較している理由は、process内で代入した値は、センシティビティリスト内信号に変化があったとき（次のProcess開始時）に更新されるため。（とどこかに書いてあった。）

で、不適切な理由としては、③のTrue処理は、50M回（1秒間）の内の1回しか行われず、点灯を「目で」確認することができないということである。なので、①のCYCLE数を減らせば確認できるはず。「CYCLE=5」（5Hz）のケースでは、次のような点灯状況であり、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/4a3f5a92-1cdb-8bd2-3ccb-1303e0f4c8cd.png", width=70%>
「CYCLE=100」（100Hz）のケースでは、次のような点灯状況である。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c9185a4e-4927-8e63-29ef-00c1a9e22a05.png", width=70%>

このように、CYCLE数（繰り返し数）が増えると、LED点灯色が薄くなるのがわかる。

### 適切に見える例
内部信号（flag）を設け、それをLED信号と結びつけ、CYCLE数が最大値に達する度（１秒毎）に「flag」を反転させることとした。[その２](https://qiita.com/infinite1oop/items/b4d9b644ac59ed422524)で紹介した、同時処理文と順次処理文とを組み合わせている。

```vhdl:ClkLed.vhd
library ieee;
use ieee.std_logic_1164.all;

entity ClkLed is
	port (
		CLK:	in std_logic;
		LED: 	out std_logic);
end ClKLed;

architecture RTL of ClkLed is
constant CYCLE : integer := 50000000;
signal CNT: integer range 0 to CYCLE-1;
signal flag: std_logic := '0';
	
begin	
	process (CLK) -- ④
	begin
		if (rising_edge(CLK)) then
			if (CNT = CYCLE-1) then
				CNT <= 0;
				flag <= not flag;
			else
				CNT <= CNT+1;
			end if;
		end if;
	end process;

	LED <= flag; -- ⑤

	-- ④と⑤とは同時に処理される
end RTL;
```

これにより、１秒毎にLEDのオンオフが繰り返されているように見える！（自明なので、写真や動画省略）

なお、
- 内部信号CNTへの代入は、同一Process文内で行わないとエラー
のようだ。

別の例ではあるが、例えば
Error (10028): Can't resolve multiple constant drivers for net "TimerFlag" at ClkLedDelay.vhd(28)
のようなエラーで怒られる。[この記事](https://beiznotes.org/201402091391914673-2/)あたりも参考になるかも。

ソフト屋には難しい、、、。だが、少しずつ賢くなっている気がする。でも、ずっと初心者。
Mx MacでCIR115-NTTComを使用する方法

確定申告の時期がやってきましたね。

新しいコンピュータを購入された方も多いと思いますが、M1 Macで今まで使っていたカードリーダー（CIR115-NTTCom）が使えなくなったので、使用する方法を探ってみました。
<b>メーカーサポート外なので、自己責任でお願いします。</b>

- チップ製造メーカーのホームページから、ドライバをダウンロードします。
    - AB Circle製だったので、同じ型番を持つ以下のページから、Mac用のドライバ（USB Mac Installer）をダウンロードします。
    （直近で確認時のドライババージョンはV2.1.7で、Mx Macに対応していることを解凍後のReadme.txtで確認できます）<br>https://www.abcircle.co.jp/jp/product/13/CIR115A/%E6%8E%A5%E8%A7%A6%E5%BC%8Fic%E3%82%AB%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%80%E3%83%A9%E3%82%A4%E3%82%BF/
- 通常通りドライバのzipファイルを解凍し、dmgファイルをダブルクリックして、ドライバをインストールします。
- ドライバインストール完了後、再起動しますので、カードリーダーを接続して、マイナンバーカードが読み取れることを確認します。

ネット上にもあまり情報がなかったようなので、エントリを作成しました。
困っている方の参考になれば幸いです。
Raspberry Pi 3 B (3 B+ではない) で64bit版をUSBブート、初期設定、dockerを使えるまで

RaspberryPi 3 Model `B+`ではUSBブートが出荷時から有効になっているらしいが、
残念ながら手元のはB+ではない。
調べてみるとUSBブートにできるようなので試してみた。


## OSのダウンロード

最近のRaspberryPiは64bit版も準備されているので、そちらを使うこととした。

64bit版ベータをダウンロード（上がGUI有り、下がCUIのみ)

https://downloads.raspberrypi.org/raspios_arm64/images/
https://downloads.raspberrypi.org/raspios_lite_arm64/


### SSHを有効にする

* `ssh`ファイルがないとsshが有効になっていないので注意。

boot のボリュームに `ssh`または`ssh.txt`を作成する。

![ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/d52d3c83-bdf0-686d-d513-b5d4430753ed.png)


## MicroSDで普通に起動

モニターを接続せずにRaspberryPiを探すには以下

```sh
ping -4 raspberrypi
```

```sh
ssh raspberrypi
```

* user : pass = pi : raspberry

## usbブート

MicroSDでbootし、以下確認。

```sh:USBブート無効
$ vcgencmd otp_dump | grep ^17:
17:1020000a
```

上記の場合、USBブートが無効になっている。
config.txtに設定を追記しUSBブートを有効にする。


### 設定追記

```go:/boot/config.txt
program_usb_boot_mode=1
```

* reboot

```sh:USBブート有効
$ vcgencmd otp_dump | grep ^17:
17:3020000a
```

### USBメモリからブート

RaspberryPiの電源をOFFにする。
MicroSDを抜き、
OSが入ったUSBメモリを差し込み電源を入れる。1分くらい待つとbootするのがわかる。



### raspi-config

```sh
sudo raspi-config
```

メモリの空きを確保 (割り当て `913MB` -> `962MB` に増える)

* `7 Advanced Options` -> `A3 Memory Split` -> `16` (初期値は64。)

日本語設定

* `4 Localisation Options`
    * -> `I1 Change Locale` -> `ja_JP.UTF-8 UTF-8`
    * -> `I2 Change Time Zone` -> `Asia/Tokyo`
    * -> `I4 Change WLAN Country` -> `JP Japan`


### ファームウェアのアップデート

```sh
sudo rpi-update
```

![update.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/11f1feb2-8be0-f785-a620-53034f58e461.png)

## TeamViewer

* [TeamViewer builds for aarch64/arm64? — TeamViewer Support](https://community.teamviewer.com/English/discussion/109284/teamviewer-builds-for-aarch64-arm64)

```
apt install -y libxtst6:armhf
```


----

## docker

```
# インストール
curl -sSL https://get.docker.com | sh

# グループに追加
sudo usermod -aG docker pi

sudo apt install -y docker-compose
```

### Docker Hub に push

`docker login`で以下エラーになった場合は、gnupg2とpassを入れる。

> Cannot autolaunch D-Bus without X11 $DISPLAY

```
apt install -y gnupg2 pass
```

```
docker push イメージ名
```


### メモ: x86でarm用ビルド

https://github.com/multiarch/qemu-user-static

* 32bit : `armv7l`
* 64bit : `aarch64`
Greasemonkeyでハマったメモ 変数名の取り扱いに注意する

##### greasemonkeyのスクリプト修正中にハマる
よくわかってないものをよくわからないまま使ってるので結構ハマっちゃいます
ちなみに、tampermonkey(chrome)で確認してます

##### ソース
```javascript
//こんな感じのスクリプトで発生
window.onload = () => {
  createTextArea()
  createButton()
}

createButton = () => {
  var applyBttuon = document.createElement("button")
  applyBttuon.innerHTML = "変更"
  applyBttuon.onclick = function () {
    console.log(input1) //←ココ！
    /*
      input1.valueの変更処理(省略)
    */
  };
  //作成した要素をページに追加
  var mainContainer= document.querySelector("body")
  mainContainer.prepend(applybutton)
}
createTextArea = () => {
  var input1 = document.createElement("textarea") //←ココ！
  input1.id = "input1" //←ココ！
  input1.value = "initial"
  //作成した要素をページに追加
  var mainContainer = document.querySelector("body")
  mainContainer.prepend(input1)
}

/*
 ボタンを押したときの表示 → initial
*/

```
##### 新たにわかったこと
指定した変数が宣言されてなく、かつ同名のidのエレメントがある場合、エレメントにアクセス出来る

##### ハマり内容
applyButton.onclickでglobal変数のinput1に触ったつもりが、input1はglobalではなく、不幸にも(?) id=input1のエレメントがあったためにエレメントのほうにアクセス出来てしまった
更に不幸なことに元々input1をグローバルのつもりで扱っていた関数ではinput1.valueの変更しかしてなかったので見かけ上期待通りに動いていてそのまま通してしまっていた
時を経て、今回id名を変更する形で修正をかけたため、関係ないところでinput1にアクセス出来なくなって、その修正に時間がかかった

##### 感想
idにはハイフンがつくこともあるし、id名そのままでアクセス出来ても使わない気がします
ハイフンがついててもアクセスする方法があるんだろうか
AWSのコストが急に増加したので調査したらNATゲートウェイのデータ転送料金だった



ECS FargateでWebクローラーのバッチ処理を開発しているのですが、新規バッチのデプロイ後にAWSのコストが予想以上に上がったときのことを書きます。

結論としては、ネットワーク設定ミスによって、本来かける必要のないコストがかかってしまっていました。

個人的に気づきにくかったので、AWSのコスト見直しの一つの項目として、確認の手順を書きたいと思います。

#### 気付いたきっかけ

AWS Cost Explorer のホーム画面で日別コストが見れるのですが、ある日から急にコストが高まっていることに気づきました。


![スクリーンショット 2021-02-12 13.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/19bb7cc4-df2b-4c7c-0536-cefcdeca2f46.png)

サービス別のコストを見ると、「EC2 その他」の項目が増加していることが分かりました。

![スクリーンショット 2021-02-12 21.34.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/c1711dd9-4671-8917-bc29-8dc0928502a8.png)

これだけだと原因が分かりにくかったのですが、
「使用タイプグループ」のフィルターでEC2関連を絞り込んでいくことで、原因となっているのが「EC2: NAT Gateway - Data Processed」であることが分かります。


![スクリーンショット 2021-02-12 21.43.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/9544a512-b260-5962-a886-fe35e309c690.png)


AWSのメニューから、VPC > NATゲートウェイ > モニタリング と遷移した画面でも、NATゲートウェイの通信量が増えていることが確認できます。

![スクリーンショット 2021-01-31 17.29.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/b85e360b-1307-45ac-c6f6-03ffe7b839c1.png)


### NATゲートウェイ通信量増加の原因
ECS Fargate でサービスを作成したとき、ネットワーク設定のサブネットの項目にパブリックサブネットではなくプライベートサブネットが指定されていたことが原因でした。



#### そもそも プライベートサブネット ・ パブリックサブネット ・ NATゲートウェイ とは何か

プライベートサブネットはインターネットから接続できないセキュリティ性の高いネットワークで、
パブリックサブネットはインターネットから接続可能なネットワークです。

NATゲートウェイは、プライベートサブネットの内側から外部のインターネットに接続する際に、プライベートIPアドレスをグローバルIPアドレスに変換するためのものです。
※ NATは Network Address Translation の略です。
※ グローバルIPアドレスがないとインターネットに接続できません。

プライベートサブネットには、外部からのアクセスを遮断したいDBサーバなどを配置することが多いです。
今回問題となったバッチ処理のサーバは別に機密情報を持っているわけではないのでプライベートなネットワークに配置する必要はありませんでした。パブリックサブネットに配置することで、NATゲートウェイを通さなくなるので通信コストの増加をなくすことができました。

プライベートサブネットとパブリックサブネットの見分け方は、ルートテーブルの送信先「0.0.0.0/0」がインターネットゲートウェイにつながっているかでどうかで見分けます。
![スクリーンショット 2021-02-13 1.56.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/651bfc3e-e756-bdda-fe18-d7f0703a5556.png)
ターゲットが「igw-」から始まるのがインターネットゲートウェイなので、この場合はパブリックサブネットです。

![スクリーンショット 2021-02-13 1.57.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/79b154a4-b10f-83df-3c57-bc8dc48c268b.png)
「nat-」や「eni-」から始まる文字の場合は、プライベートサブネットとなります。




### 解決方法

ECS Fargateのサービスのネットワーク構成に設定していたサブネットの項目を、プライベートサブネットからパブリックサブネットに設定し直すことで解決しました。

※ ECSクラスターのサービスで実行している場合、ネットワーク構成がサービス作成時にしか設定できないため、サービスを新たに作り直す必要があります。

![スクリーンショット 2021-02-12 22.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234489/d3c10481-93e7-2bed-208a-b04efdfa0930.png)





ちょっとした設定の違いでコストが大きく変わることがあるので、びっくりして心臓に悪いですが今後もエンジニアとして頑張りたいと思います。
Firebaseでメールアドレス、パスワード入力なしで「emailVerified」をtrueにする方法

皆さんこんにちは！

今日は、Firebaseの``emailVerified``について書いていきます。

この``emailVerified``はメール認証を行っているかを示すものです。

これでユーザーの動作やページの制御を行えます。

これを行うには``sendEmailVerification``と言う関数を用いるのですが、通常メールアドレスとパスワードの入力を要求されます。

ユーザーからしたらめんどくさいですよね。

また、``emailVerified``はフロントからは変更を行うことができません。

それをメールに送ったリンクをクリックしたらメール認証完了という感じにしたいと思います。


それではやっていきましょう！

#FirebaseFunctionsの設定#

最初にFirebaseFunctionsで独自の関数を作成していきます。

```functins/index.js
const functions = require('firebase-functions')
const admin = require('firebase-admin')

admin.initializeApp()

// メールアドレス認証（emailVerified）の更新
exports.updateEmailVerified = functions.region('asia-northeast1').https.onCall((data, context) => {
  const uid = context.auth.uid
  if (!uid) {
    return
  }
  admin
    .auth()
    .updateUser(uid, {
      emailVerified: true
    })
    .then()
})
```

この``updateUser``で``emailVerified``を``true``にすることができます。

#メール認証を行うメールの送信#

```
      const actionCodeSettings = {
        url: window.location.origin + '/actionemailverified',
        handleCodeInApp: true
      }
      const user = this.$auth.currentUser
      // メール送信
      await user
        .sendEmailVerification(actionCodeSettings)
        .then(() => {
          //
        })
        .catch((error) => {
          //
        })
```

アクションコードの設定などは、下記の記事に詳しく書いているので是非ご覧ください。

[Firebase初心者向け！Firebaseでパスワードを使わずにメールリンク認証を行う方法](https://qiita.com/akki-memo/items/855e32a8d09035b5b4f7)

#関数の呼び出し#

``sendEmailVerification``で送信したURL先で``functions\index.js``で定義した関数を呼び出します。

```action.js
      const func = this.$function.httpsCallable('updateEmailVerified')
      func()
        .then(() => {
          alert('メール認証が完了しました')
          user.reload()
        })
        .catch((error) => {
          //
        })
```

いかがだったでしょうか？

ちなみにメールアドレスを変更した際は、自動的に``emailVerified``は``false``になりますのでユーザーには再度認証を行ってもらう必要があります。

このようにして``emailVerified``を更新することができます。

あまり情報がなかったので書いておきました。

皆さんのお力になれれば幸いです。

以上、「Firebaseでメールアドレス、パスワード入力なしで「emailVerified」をtrueにする方法」でした！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも毎日初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
都道府県一覧の配列から都道府県名のUnion型を作る

## やりたいこと
```js
const prefectures = ['北海道','青森県','岩手県',..., '沖縄県']
```
という都道府県名の配列から

```ts
type Prefecture = '北海道'| '青森県'| ...| '沖縄県';
```

を意味する型定義を作りたい


## const assertion（`as const`）を使うとできる

```ts
const prefectures = [
  '北海道',
  '青森県',
  '岩手県',
  '宮城県',
  '秋田県',
  '山形県',
  '福島県',
  '茨城県',
  '栃木県',
  '群馬県',
  '埼玉県',
  '千葉県',
  '東京都',
  '神奈川県',
  '新潟県',
  '富山県',
  '石川県',
  '福井県',
  '山梨県',
  '長野県',
  '岐阜県',
  '静岡県',
  '愛知県',
  '三重県',
  '滋賀県',
  '京都府',
  '大阪府',
  '兵庫県',
  '奈良県',
  '和歌山県',
  '鳥取県',
  '島根県',
  '岡山県',
  '広島県',
  '山口県',
  '徳島県',
  '香川県',
  '愛媛県',
  '高知県',
  '福岡県',
  '佐賀県',
  '長崎県',
  '熊本県',
  '大分県',
  '宮崎県',
  '鹿児島県',
  '沖縄県'
] as const;

type Prefecture = typeof prefectures[number];
```
### vscodeでの表示

![ 2021-02-13 at 2.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66521/31ba2077-6519-418a-f418-3c4e3fa38373.png)
Microsoft Certified Azure Fundamentals 認定 (試験 AZ-900 ) を取得しました。

AZ-900 (Microsoft Azure Fundamentals) を受験し、無事合格できたので勉強のやり方などを残しておきます。

本試験に合格すると、Microsoft Certified Azure Fundamentals 認定がもらえます。
これから受験される方のご参考になれば幸いです。

#試験名
AZ-900: Microsoft Azure Fundamentals　日本語

# 概要
試験時間：60分
合格点：700点以上(1,000点満点)
受験料：￥12,500

#出題範囲と出題の割合
公式サイトはこちらです。
https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900

（2020年11月9日更新版）
* Cloudのコンセプトに関する説明（20～25％）
* コアAzureサービスに関する説明（15～20％）
* Azureのコアソリューションと管理ツールに関する説明（10～15％）
* 一般的なセキュリティおよびネットワークセキュリティ機能に関する説明（10～15％）
* ID、ガバナンス、プライバシー、およびコンプライアンス機能に関する説明（20～25％）
* Azureのコスト管理とService Level Agreementsに関する説明（10～15％）



# 勉強方法

私は、トータル15時間ほどかけました。
なお、書籍（合格対策 Microsoft認定 AZ-900:Microsoft Azure Fundamentals）は使いませんでした。

#### 1.Microsoft社が提供する受験対策セミナーの動画受講(無償)【6時間（3時間×2日）】

Microsoft社が受験対策セミナーの動画を無償提供しています。
全体の内容が把握できるため受講をおすすめします。

2日間受講すると、無料受験のクーポンがもらえます。受講後1週間ほどで付与されます。（2021年2月現在）

Microsoft Azure Virtual Training Day: Fundamentals
https://www.microsoft.com/ja-jp/events/top/training-days.aspx

#### 2.Microsoft社が提供するラーニング パス(無償)【3時間】

試験に関して学習ができるeラーニングが用意されています。解説と各カテゴリの最後に設問があります。
また、実際にAzureをつかった実技演習も含まれているため勉強になります（実技も課金不要で無償でできますが、Microsoftのアカウントが必要となります）

受講を進めると、XPという経験値ポイントがどんどんたまっていくため励みになります。

https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900

ラーニング パス

* Azure の基礎 第 1 部:Azure の主要概念に関する説明
* Azure の基礎 第 2 部:Azure の主要サービスに関する説明
* Azure の基礎 第 3 部:Azure のコア ソリューションおよび管理ツールに関する説明
* Azure の基礎 第 4 部:一般的なセキュリティ機能およびネットワーク セキュリティ機能に関する説明
* Azure の基礎 第 5 部:ID、ガバナンス、プライバシー、およびコンプライアンス機能に関する説明
* Azure の基礎 第 6 部:Azure Cost Management およびサービス レベル アグリーメントに関する説明


#### 3.WEB問題集　【2.5時間】

WEBで公開されているWEB問題集を活用しました。
100問近くあります。問題・回答をPDFにまとめて、3回ほど繰り返しました。

Web問題集でAzure試験に合格しよう
https://learn-azure.cafe/

#### 4.WEB問題アプリ【3時間】

問題は4カテゴリに分かれており、「全ての問題」を選択して、3回ほど繰り返しました。

【AZ-900】Microsoft Azure Fundamentals 勉強アプリ
https://simple-was-best.com/az-900

#### おまけ

問題を解く中で、わからないサービス名などは、その場でぱっと調べて覚えていきました。

#まとめ

上記の勉強を行うことで、合格点を100点ほど超えることができ、Microsoft Certified Azure Fundamentals 認定を受けることができました。
yukicoder contest 282 参戦記

# yukicoder contest 282 参戦記

## [A 1389 Clumsy Calculation](https://yukicoder.me/problems/no/1389)

chinerist 君が間違わなかったとすると、S<sub>i</sub> の合計は X * N - (A<sub>1</sub> +  A<sub>2</sub> + ... + A<sub>N</sub>) = X * N - X = X * (N - 1) となる. 間違っているのが S<sub>j</sub> だとすると、S<sub>j</sub> = 2 * (X - A<sub>j</sub>) となり、実際の S<sub>i</sub> の合計は X - A<sub>j</sub> 増えた X * (N - 1) + (X - A<sub>j</sub>) となる. 求めるのは間違えた計算の正しい答え、つまり S<sub>j</sub> の正しい値 X - A<sub>j</sub> なので、実際の S<sub>i</sub> の合計から、正しい S<sub>i</sub> の合計 X * (N - 1) を引けば答えになる.

```python
N, X, *S = map(int, open(0).read().split())

print(sum(S) - X * (N - 1))
```

## [B 1390 Get together](https://yukicoder.me/problems/no/1390)

Union Find を使えば簡単. まず同じ箱にいるスライムを同じ集合に入れる. そして各色ごとに違う箱にいるスライムを統合していって、統合した回数が答え.

```python
from sys import setrecursionlimit, stdin


def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def unite(parent, i, j):
    i = find(parent, i)
    j = find(parent, j)
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j


readline = stdin.readline
setrecursionlimit(10 ** 6)

N, M = map(int, readline().split())

box = {}
color = {}
parent = [-1] * N
for i in range(N):
    b, c = map(int, readline().split())
    box.setdefault(b, [])
    box[b].append(i)
    color.setdefault(c, [])
    color[c].append(i)

for b in box.values():
    i = b[0]
    for j in b[1:]:
        unite(parent, i, j)

result = 0
for c in color.values():
    i = c[0]
    for j in c[1:]:
        if find(parent, i) == find(parent, j):
            continue
        result += 1
        unite(parent, i, j)
print(result)
```
テキスト中のIPythonコンソールのインデックスを自動で振り直す

Qiitaの記事にIPythonコンソールの実行結果を書きたいことがありました。
その際にコピペしたテキストのInオブジェクト、Outオブジェクトのインデックスがバラバラで、手作業で振り直すのが面倒だったのでスクリプトを書きました。

https://github.com/ezotaka/renumber_ipython_inout

以下、README.mdをそのまま抜粋します。

# renumber_ipython_inout.py
テキストに含まれるIPythonコンソールIn、Outオブジェクトのインデックスの再割り当てを行うスクリプトです。

## このスクリプトの使い道
IPythonコンソールの実行結果のコピペを、きれいにして共有したいときなどにお使いください。

例えば、以下のようにインデックスがバラバラなテキストが、

```python
In [2]: index = '  ^100hoge'

In [3]: import re

In [13]: match = re.match(r'^\s*(\^)(\d*).*', index)

In [29]: match.groups()
Out[29]: ('^', '100')
```

スクリプト適用後には以下のようになります。

```python
In [1]: index = '  ^100hoge'

In [2]: import re

In [3]: match = re.match(r'^\s*(\^)(\d*).*', index)

In [4]: match.groups()
Out[4]: ('^', '100')

```

## 使い方
[renumber_ipython_inout.py](https://raw.githubusercontent.com/ezotaka/renumber_ipython_inout/main/renumber_ipython_inout.py)をダウンロードして実行してください。

引数にファイル名を与えるか、標準入力からテキストを入力すると、変換結果を標準出力します。

```
$ python renumber_ipython_inout.py filename

もしくは

$ cat file_name | python renumber_ipython_inout.py 
```

## 仕様
* テキスト中に``In [.*]:``もしくは``Out[.*]:``を見つけたら、インデックス部分の文字列を適切な数値に置換します。
* それ以外の文字列の置換は行いません。
* テキストの先頭から順に、1からの連番になります。
* ``In [^]:``と書くことで、任意の箇所で1に初期化することもできます。
* ``In [^正の整数]:``と書くことで、任意の箇所で任意の数値に初期化することもできます。

## 実行例
スクリプト適用前

```python
In [10]:

In []:  # 空でもいい
Out[何か]:  # 何でもいい

In [^]:  # 1に初期化される

In [40]:
Out[40]:

In [  ^100hoge]: # 先頭の空白や数値以外は無視して、100に初期化される
Out[50]:

# 先頭じゃなくても適用されるので注意 In []: Out[]:

In [60]:
```

スクリプト適用後

```python
In [1]:

In [2]:  # 空でもいい
Out[2]:  # 何でもいい

In [1]:  # 1に初期化される

In [2]:
Out[2]:

In [100]: # 先頭の空白や数値以外は無視して、100に初期化される
Out[100]:

# 先頭じゃなくても適用されるので注意 In [101]: Out[101]:

In [102]:
```
原神やゼルダBoWのあの雰囲気を手っ取り早く出す方法

今更ながら原神を遊び始めました。
クオリティがエグくてビックリ！
グラフィックスがすごいすごいと言われていますが、そこよりも実装されてる仕様の量と質がすごい。
このクオリティを出そうと思ったらいったい何人月必要なのか想像するだけで目眩がします。

いつかこんなゲームが作りたい、でも過酷なデスマーチと、すごい勢いで増えていく開発費を想像したら作りたくない。
そんな人（自分）の為に手っ取り早く、見た目の雰囲気だけ、なんとなく原神やBoWに近づけるアプローチを置いておきます。

↓こんな感じを目指します。
![スクリーンショット 2021-02-13 0.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/a28f5903-1a33-e464-81ab-ff9402328b00.png)

## 1. はじめに
まずはTerrainなどを使ったりアセットストアで買ったりして、木と草が生えてるフィールドを用意します。
この時点ではまだPS2クオリティ。

![スクリーンショット 2021-02-13 0.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/3842c044-e30f-e077-1d95-6548263bb155.png)

## 2. ライトをそれっぽくする

DirectionalLightを黄色っぽくして、intensityを少し上げます。
![スクリーンショット 2021-02-13 0.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/4af4eef3-184e-3bf2-c4f4-b2a314be15ec.png)

![スクリーンショット 2021-02-13 0.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/d7ff97b6-933e-30de-6632-91e438197015.png)

## 3.影をつける
シャドウマップを適用して影をつけます。ソフトシャドウでもハードシャドウでもいいです。

![スクリーンショット 2021-02-13 0.09.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/459be72b-4594-c840-03d2-fd00ef1cfba5.png)

## 4.Ambientを調整

↑の時点では影が真っ暗でいかにも一昔前のPCゲームって感じです。
全体的に柔らかい雰囲気にするため、アンビエントライトの調整をします。
ここでAmbient ColorをHDRにすることで全体的に発光した雰囲気を作ることができます。
![スクリーンショット 2021-02-13 0.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/46eaf033-64e7-abd2-7b98-b4612702c705.png)
![スクリーンショット 2021-02-13 0.11.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/b41b7b6e-3257-0669-3c21-7e8f9edc9981.png)
一気にそれっぽくなりました。

## 5.Fogで遠近感をかもしだす

![スクリーンショット 2021-02-13 0.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/09fa6357-36f2-9b7a-cff0-ca2b426e25ce.png)

![スクリーンショット 2021-02-13 0.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/1e85b736-3287-1594-78d3-0d14ea7ca66b.png)

遠くの木にフォグがかかりました。
静止画だとそんなに差がないですが、実機で動いている状態だとゲーム世界の空気感が変わります。

## 6. ゴッドレイとか置いてみる
雰囲気ものでゴッドレイとか置いてみるとなお良いです。

![スクリーンショット 2021-02-13 0.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/97e70bd2-8942-6bfa-fdd2-1ef3eb39e310.png)

この他、UnityのVolumeでビネットかけてみたり、風のエフェクト（白い線みたいなやつ）を飛ばしてみたり、色々工夫するとより雰囲気が出そうです。
「VPCとは」

<h1>VPCとは</h1>
<p>
VPC:Virtual Private Cloud
<br>日本語で直訳すると、仮想プライベートクラウド。
<br>AWSクラウド内に論理的に分離されたセクションを作り、ユーザーが定義した仮想ネットワークを構築するサービスです。
</p>
<h1>VPCの特徴</h1>
・VPC内で多くのサブネットを構築可能。
・サブネットないでEC2インスタンスを使える。
・サブネットのルーティングテーブルを設定できる。
・VPCにInternet Gatewayを設定し、EC2はそれを利用してインターネットに繋げる。
・一つのVPCは複数のAZに跨がれる。
・一つのサブネットは一つのAZにしか使えない。
・Security Groupはステートフル。
　（ステートフル：行きの通信が許可されれば、戻りの通信も許可される。）
・Network Access Control Listはステートレス。
　（ステートレス：行き通信と戻り通信は別々で配置し、お互いに影響しない。）
・サブネットの設定可能範囲：/16～/28。
<p>

<h1>VPCの設定手順</h1>
![1613146644857.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/1bee027a-68ab-32c0-7c35-ec563fd73f52.jpeg)
RDS for Oracle にEC2から接続する

#はじめに
RDS for Oracleのデータベースに接続を試みました。
すっと接続できなかったので備忘のためのメモと役に立ったリンクを記載。

#背景
社内の踏み台サーバ(Windows Server)からパブリックサブネットに配置したRDS for Oracleに接続を試みたが、なぜか接続できないので色々実施。

とりあえず接続できればよかったので、踏み台→EC2→RDSと間にEC2をはさんで接続を試行。
EC2には問題なくログインできたので、踏み台→AWSのネットワーク的には問題なかったはず。
EC2とRDSは同じVPCのパブリックサブネットに配置。

EC2にSSH接続し、以下のリンクを参照し順番に実行。
必要な部分を置き換えて最終的に無事接続できた。
EC2にOracle ClientをインストールしてRDS(Oracle)に接続する
https://zatoima.github.io/oracle-ec2-oracleclient-install.html

#上記リンク良いところ
他の「RDS sqlplus 接続」系の記事もたくさん見たが、「圧縮ファイルをEC2にアップする」などの手順があったり手間が多かった。
この記事だと、curlとyumで解決するので、怠惰な私にはありがたかった。
→EC2がインターネット出られる状態になっていれば問題なく実施できる。
自分が記事を書く時も、なるべくストレスなく完了できる手順書けるよう意識したい。

#参考
EC2からSQLPLUSでRDSを接続する設定
https://www.flyenginer.com/low/low_db/ec2%E3%81%8B%E3%82%89sqlplus%E3%81%A7rds%E3%82%92%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E8%A8%AD%E5%AE%9A.html#toc7

Oracle DB インスタンスへの接続
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToOracleInstance.html
AWS S3 CSSが反映されないとき

# 初めに
s3にboto3を使ってindex.html, main.js, style.cssをアップロードした。URLを開くとJavascriptが動いていることがわかった。しかしstyle.cssが反映されていなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/3a3f3b34-24cd-fff6-6b3a-216ccf63f303.png)


# メタデータ編集

手順1
style.cssをクリックし、オブジェクトアクションをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/f4b1f0fd-4c2f-19c9-263f-b092f0e516bc.png)

手順2
メタデータの編集をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7e804556-019f-7194-ee00-5abcbd09add4.png)

手順3
以下の"値"が"text/html"になっているので、"text/css"に編集する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/4f534534-24bb-d6ea-8689-bfe98a62bcac.png)

編集後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/ca74b663-de22-52ac-c101-980715453b55.png)

手順4

オレンジ色のメタデータの編集ボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/e854edb8-75f7-5bcb-7a9e-4c262a4e9814.png)

これで反映される！！！
と思いきや反映されませんでした。
なぜ！！！

# キャッシュの削除

キャッシュを削除すると反映された・・・
(･∀･)ｳﾝ!!
設定しなおした後は必ずキャッシュ削除
以下の記事を参考にした

https://hodalog.com/httpd-enablesendfile-off/

# boto3

```upload.py

import boto3


def get_content_type_dict():
    content_dict = {'html': 'text/html',
                    'css': 'text/css',
                    'js': 'text/javascript',
                    'jpeg': 'image/jpeg',
                    'png': 'image/png',
                    'csv': 'text/csv',
                    'json': 'application/json',
                    'pdf': 'application/pdf'}
    return content_dict


def upload(up_file, bucket, object_name, credentials):
    session = boto3.Session(aws_access_key_id=credentials[0],
                            aws_secret_access_key=credentials[1],
                            aws_session_token=credentials[2])
    s3_client = session.client('s3')
    type_dict = get_content_type_dict()
    content_type = type_dict[os.path.splitext(object_name)[1].strip('.')]
    try:
        s3_client.upload_file(up_file, bucket, object_name,
                              ExtraArgs={'ContentType': content_type,
                                         'ACL': 'public-read'})
```

こんな感じで拡張子に応じてアップするときメタデータを設定すると楽かも
Content-Typeは以下の記事を参考にした
https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa

ExtraArgsなるものの存在は以下の記事が参考になった
https://qiita.com/jansnap/items/ecad5f20659cf138419b

# 疑問

main.jsはメタデータがtext/htmlでも動くこと

# 参考文献

ローカル環境でCSSが反映されない時に見直すべきhttpdの設定
https://hodalog.com/httpd-enablesendfile-off/

Content-Typeの一覧
https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa

boto3でS3にアップロードした画像が、ブラウザで表示するとダウンロードされてしまう時
https://hack-le.com/boto3-s3-browser/

Python+boto3でS3に画像をアップロードして公開する
https://qiita.com/jansnap/items/ecad5f20659cf138419b
[Ruby on Rails]編集ページでのエラーメッセージの出し方

自身の失敗を踏まえた備忘録を書いていきます。


###エラーメッセージの読み込みの記述
![スクリーンショット 2021-02-12 23.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/f7a11e38-708c-64a9-d82f-6780f90a6bd4.png)

上記の記述は別のファイルで**エラー文の繰り返し処理**を表した記述になります。
　　
　
記入すべき所が空欄だったりしたら表示される文章を
**エラー文**と言います。

**new.html**と一緒のエラー文を、
**編集ページ**の**edit.html**でも表示させたい時に書く記述を書いていきます。
　

###(例)
編集ページなので**editとupdateアクション**に定義してある
**item**のインスタンス変数を使っていきます。
![スクリーンショット 2021-02-13 0.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/4919ce99-ab76-ef36-036b-4c1cac4082e7.png)


ここで大事なのは**prefix**の
**item_path**を記述した後のメソッドの**patch**です。
<h3>PATCH

**編集をした情報を送信する際に使用するHTTPメソッド**のことです。
　　

editやupdateとややこしい所ですが、
今回の**patch**は地味に大事なことなので自分も忘れないように覚えておこうと思います。
AWS Config とは

## 勉強前イメージ

`$ aws configure` と似たようなもんだと思ったけど、
なんか違う気もする...

## 調査

### AWS Config とは

AWSリソースの設定がモニタリングされ、
設定が変更された際には再評価を行ったり通知を行ってくれます。
また、社内のガイドラインに沿って設定されているかなど確認もでき、
セキュリティ分析・変更管理などができます。

### 特徴

#### 費用について

費用は記録された設定項目の数やconfigルールによる評価数等によって課金がされ、最低利用料金や前払いなどはありません。
ですので、気軽に1つの項目からでも設定を行うことができます。

#### 監査や評価について

社内のガイドラインに沿っているか など継続的に監査または評価されます。
継続的に行われるため、コンプライアンス違反をしているリソースがあれば素早く特定を行い改善をすることができます。

#### 変更管理などのモニタリング

リソースの設定変更を継続的にモニタリングして記録されます。
変更があった際にはAmazon SNS通知を行うことですぐに確認ができます。

## 勉強後イメージ

誰が変更したかわからない！とか、
そもそも社内ガイドラインに沿ってるかわからんし現状どうなってんの！？とかにはすごい良さそう....
一回設定して、どう表示されるか見てみたい

## 参考

- [AWS Configの使い方について](https://www.acrovision.jp/service/aws/?p=2702)
- [AWSリソースの設定変更履歴を管理する「AWS Config」とは？実際に使用してみた](https://business.ntt-east.co.jp/content/cloudsolution/column-try-26.html)
python 変数を日本語で定義


## 環境
Python 3.9.1
win 10

 

## コード

```python 
import random
def 泡(数字: list[int]) -> list[int]:
    数字配列の長さ = len(数字)
    for い in range(数字配列の長さ):
        for ろ in range(数字配列の長さ - 1 - い):
            if 数字[ろ] > 数字[ろ + 1]:
                数字[ろ], 数字[ろ + 1] = 数字[ろ + 1], 数字[ろ]

    return 数字




数字 = [random.randint(0, 1000) for い in range(10)]
print(数字)
print(泡(数字))
```

問題なく実行できてる

```
[947, 894, 661, 501, 138, 85, 518, 352, 297, 557]
[85, 138, 297, 352, 501, 518, 557, 661, 894, 947]
```
英語に慣れてるせいか日本語読みずらい
requestsでAPIコールする際にSSL: CERTIFICATE_VERIFY_FAILEDが出ても、認証を切らない対処法



requestsを使ってhttpsのエンドポイントにAPIコールしたらSSLErrorになった。

```
requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url: /exampleapi (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)'),))
```


あえてHTTPS接続をする必要がないテスト時などは、以下の方法でSSL認証をしないことで回避できる。

```python
requests.get('https://example.com/exampleapi', verify=False)
```

そうできない場合にどうするか。

## 原因

今回接続したいAPIは、Root認証局の証明書と中間認証局の証明書が必要だった。
エラーの原因は、システムがRoot認証局の証明書については持っていたが、中間認証局の証明書を持っていなかったことだった。

## 対策

この場合の対策は、要するに中間認証局の証明書を渡すことだが、２通りある。

### 1. verifyにRoot認証局の証明書と中間認証局の証明書のあるフォルダパスを渡す

Ubuntu/Debianの場合、Root認証局の証明書は`/etc/ssl/certs`以下にある。
ここに中間認証局の証明書を配置する。
中間証明書は、ブラウザのURLバー脇の鍵アイコンをクリックし、証明書を見るとわかる。

今回は認証局としてEntrustを利用しているAPIであったため、[Entrustのサイト](https://www.entrust.com/resources/certificate-solutions/tools/root-certificate-downloads)から中間認証局の証明書を取得した。


その上で、`c_rehash`コマンドで中間証明書を処理しておく。
(なお、手元の中間証明書の拡張子は.cerでなく.crtにしないと`c_rehash`コマンドで処理されなかった。)

```bash
$ c_rehash /etc/ssl/certs
```

この状態で、コードを以下のように修正する。

```python
requests.get('https://example.com/someapi', verify='/etc/ssl/certs')
```
これで、中間認証局の証明書も見てくれるのでSSLErrorがなくなる。

### 2. 中間認証局の証明書を含めた、単一の証明書ファイルを更新する

Ubuntu/Debianの場合、`/etc/ssl/certs/ca-certificates.crt`に、設定済みの証明書をすべてまとめたファイルがある。
これに、中間認証局の証明書を含めることでも対応できる。

中間証明書が`/tmp/intermediate-ca.cer` というパスにあるとして、以下のコマンドで行える。

```bash
$ mkdir /usr/share/ca-certificates/mylocal
$ cp /tmp/intermediate-ca.cer /usr/share/ca-certificates/mylocal
$ echo "mylocal/intermediate-ca.cer" >> /etc/ca-certificates.conf
$ sudo update-ca-certificates
```

これで`/etc/ssl/certs/ca-certificates.crt`に中間認証局の証明書が入るので、1と同様、requestsのverify引数に渡せる。

```python
requests.get('https://example.com/someapi', verify='/etc/ssl/certs/ca-certificates.crt')
```

また、`REQUESTS_CA_BUNDLE`という環境変数にセットすれば、verify引数をセットしなくてもよくなる。
[※requests公式docのSSL Cert Verification](https://requests.kennethreitz.org/en/master/user/advanced/#ssl-cert-verification)

```bash
$ REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt python
>> requests.get('https://example.com/someapi')
```


---

## opensslコマンドでの確認方法

SSLErrorが出る原因を調べる際にopensslのコマンドが役に立った。

```bash
$ openssl s_client -connect example.com:443 -servername example.com

...


    Verify return code: 21 (unable to verify the first certificate)
```
このように、return codeで何が問題かわかる。(この場合は中間証明書かRoot証明書が悪い)

問題ないときは、以下のようなコードが表示される。

```
    Verify return code: 0 (ok)
```


## 参考にしたURL

* requestsのエラーでまず最初に見、ドキュメントの意訳がわかりやすくて助かった。
  * https://qiita.com/sta/items/6d08151fd9b20fa8b319
* .cer, .crt拡張子のファイル種別について
  * https://qiita.com/kunichiko/items/12cbccaadcbf41c72735
* requestsのssl認証に関する公式ドキュメント
  * https://requests.kennethreitz.org/en/master/user/advanced/#ssl-cert-verification
* opensslでのデバッグについて
  * https://kaworu.jpn.org/kaworu/2011-01-28-1.php
  * https://koumei2.com/wiki/1639
  * http://home.att.ne.jp/theta/diatom/verify%281%29.html