OmniAICreator/Qiita-1.07M huggingface dataset:
AWS公式資料で挑むSCS認定(25)-こんな時どうする(全分野その2)

##### [前回] [AWS公式資料で挑むSCS認定(24)-こんな時どうする(全分野その1)](https://qiita.com/mingchun_zhao/items/d4e6cf1651d52523fe65)

## はじめに

AWS資格11冠制覇の名人(同僚)の[ブログ記事](https://qiita.com/Sunameri_Beluga/items/1559d33eb44b7a790a8f)から、
「公式ドキュメント(理論)とハンズオン(実践)のクイックな往復こそ最も有効な試験対策」

自分のやり方あっていたようです。よっしゃ、試験準備続けよう。
引き続き、AWS公式資料を参考に「こんな時どうする」の追記です。

## 分野1: インシデント対応

- 外部からIAMアクセスキーを悪用した不正アクセス発生、どのような操作が行われたか特定したい
    - AWS CloudTrailを使用し、IAMアクセスキーと関連付けされたユーザの操作履歴を確認
    - AWS CloudTrailは、インフラストラクチャ全体のアカウントアクティビティをモニタリング/記録し、保存、分析、修復アクションをコントロールできる

## 分野2: ログとモニタリング(監視)

- CloudTrailログへの不正アクセスと改ざんを防止したい
    - CloudTrail設定で、ログファイルの整合性を有効に
    - 一元化された専用S3バケットにログ保存
    - S3ライフサイクルを設定し、古いログファイルをS3 Glacierにアーカイブしてから削除
    - KMS管理キーを使用したサーバー側の暗号化(SSE-KMS)

- 組織複数アカウントのCloudTrailログをS3バケットで一元管理しているが、一部アカウントの証跡がS3バケットに保存されない
    - バケットポリシーで、問題アカウントのCloudTrailからのアクセスが許可されているか確認
    - マスターアカウントのCloudTrail設定で、ストレージがS3バケットに指定されているか確認
    - CloudTrailコンソールで、ログファイルをS3バケットへ配信するための証跡が有効か確認

- S3バケット設定に対する変更を記録/監視し、SNS通知したい
    - バケットポリシーで、AWS Configがバケット設定変更を記録できるように許可
    - AWS管理ポリシーの`AWSConfigRole`をAWS ConfigのIAMロールにアタッチ

## 分野3: インフラストラクチャのセキュリティ

- EC2インスタンスの侵入テスト(ペネトレーション)を行いたい
    - AWSの事前承認について
        - 許可されたサービス(8つ)は事前承認不要(https://aws.amazon.com/jp/security/penetration-testing/)
        - その他シミュレートされたイベントは、事前承認要
    - AWSユーザーの責任
        - セキュリティ評価に使用するツールとサービスが、禁止されたDoS攻撃などを使用せず正常動作できるように適切に設定し事前検証を行う
        - サードパーティに依頼する場合も、侵入テストポリシーに違反しない方法でセキュリティ評価を実施することを保証
    - 禁止された行為
        - Amazon Route 53ホストゾーン経由のDNSゾーンウォーキング
        - サービス妨害(DoS)、分散サービス妨害 (DDoS)、シミュレートされたDoS、シミュレートされたDDoS
        - ポートフラッディング
        - プロトコルフラッディング
        - リクエストフラッディング(ログインリクエストフラッディング、APIリクエストフラッディング)

- コンプライアンス要件に従って、EC2インスタンスの脆弱性リストを取得したい
    - Amazon Inspectorを使用
    - Amazon Inspectorは、ソフトウェアの脆弱性や意図しないネットワーク露出がないか継続的にAWSワークロードをスキャンする自動脆弱性管理サービス

## 分野4: アイデンティティ(ID)及びアクセス管理

- EC2操作に対し、MFAによる認証を強制したい
    - MFA以外の認証を拒否するIAMポリシーを作成
        - `"Effect": "Deny"`
        - `"Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": false}}`
- AWS CLI使用時、MFAによる認証を強制したい
    - IAMロールを作成、ロール信頼ポリシーでMFA以外の認証を拒否する
        - ポリシーの"NotAction"に"sts:AssumeRole"を追加 
    - Role権限を引き受けるため、CLIコマンド`aws sts assume-role`を実行、下記パラメータを指定、
        - `--role-arn`: 上記ロール
        - `--serial-number`: MFAデバイスのARN
        - `--token-code`: MFAで発行されるトークン

## 分野5: データ保護

- AWS Secrets ManagerでAmazon RDSのシークレット(パスワードなど)を自動的にローテーションさせたい
    - VPCのプライベートサブネットにRDSインスタンスとAWS Lamda関数を配置
    - Secrets Managerからプライベートサブネットへ接続
        - 方法1: VPCエンドポイントを使用
        - 方法2: NATゲートウェイを使用
    - Lamda関数でシークレットのローテーションをスケジュール

- ELB配下のEC2に構築したアプリケーションのトラフィックに対し、暗号化を強制したい
    - ELBのHTTPSリスナー(ポート番号443)を有効に設定
    - ELBのHTTPSリスナーからEC2インスタンスへのリクエストはHTTPS送信(送信先ポート番号443)

## おわりに

試験対象の各分野における「こんな時どうする」追記でした。
次回も続きます、お楽しみに。

##### [次回] [AWS公式資料で挑むSCS認定(26)-こんな時どうする(全分野その3)](https://qiita.com/mingchun_zhao/items/feaf1d3d5bff8d0dd954)
プロジェクト単位のブックマークをファイルとして管理する

# 作ったもの

```
// 1. Makefileのコマンドリストを開く
$ m

// 2. boって打ったらbookmarkだけがヒット
QUERY> bo
open-bookmark  ブックマーク

// 3. 遷移先を選択
QUERY>
repository  https://github.com/hogehoge
project https://github.com/orgs/hogehoge/projects/1
```

するとデフォルトブラウザでリンクが開く
というのを作ってみた。

# 背景
プロジェクト固有のGitHubのリンクとか課題管理へのリンクをブラウザのブックマークに紐づけてると、
プロジェクトが増えるごとに掛け算で増えていくのでちらかる。

そこでブックマークもリポジトリにいれちゃえば楽なのでは？ということで作ってみた。

# 前提
[Makefileのコマンドを「m」で選択実行できるようにする](https://qiita.com/Teach/items/12b3ee7410b31388e063)

# 手順

まずブックマークファイルを作成。パスはプロジェクト内で適当に配置。

```config/bookmark.txt
repository https://github.com/hogehoge
project https://github.com/orgs/hogehoge/projects/1
```

Makefileに以下を追加

```Makefile
.PHONY: open-bookmark
#: ブックマーク
open-bookmark: select-bookmark
	@open $(BOOKMARK)

.PHONY: select-bookmark
select-bookmark:
	$(eval BOOKMARK := $(shell cat config/bookmark.txt | peco | awk '{print $$2}'))
```

pecoで選択したものをBOOKMARKという変数に保存し、
openで移動


以上！
Unityでアセットをインストールしたらエラーが...

<h2> 1. はじめに </h2>
Unityのアセットを導入する際エラーが出てしまい、うまくインポートできなかったのですが解決ができたので備忘録として本記事を作成しました。
同じエラーが出てる人にとって参考になれば幸いです。

<h2> 2. エラーコード </h2>
<p>[Package Manager Window] Error while getting auth code: System.InvalidOperationException: Failed to call Unity ID to get auth code.
UnityEditor.AsyncHTTPClient:Done (UnityEditor.AsyncHTTPClient/State,int) (at /Users/bokken/buildslave/unity/build/Editor/Mono/AsyncHTTPClient.cs:248) </p>
<br>
<p> エラーコードを感じだとUnity IDがうまく取得できなかった、といった感じでしょうか？

<h2> 解決方法 </h2>
<p>結論から言うと、Unityを再起動したうまく読み込んでくれました。笑
<br>
<p>たまたまUnity IDがうまく読み込まれてなくて再起動する必要があったと言うことなのだろうか？わからない...ただもしこれを読んでくれている人も同じエラーが出ているのであれば一度試してみるのもいいかもしれません。</p>
<p>拙い文ですが、最後まで読んでくださりありがとうございました。</p>
cscの作法 その88

# 概要
cscの作法、調べてみた。
xml使ってみた。

# 参考にしたページ

https://uchukamen.com/Programming1/DataGrid/index.htm

# test.xml

```
<MyDataSet>
<PersonalInfoTable ID="1">
<Name>taro yamada</Name>
<Height>180</Height>
</PersonalInfoTable>
</MyDataSet>

```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1b447106-29fe-7cdd-ee5f-d4076c6933c0.png)

以上。
selenium用のよく使うコードをクラス化してみました！

<h1>概要</h1>
<p>
seleniumをでよく使うコードをモジュール化して制御させました。</p>
<p>
ネットに落ちている情報を参考にしながら作ったので、冗長な記述になっていると思いますが、動作確認はできております！
現状最低限動かせるメソッドしか用意できていませんが、実用性を重視してXpathだけでなくCSSセレクタからの要素の取得も行えるよう改良していきます。
</p>
<h1>ソース</h1>

<h2>クラス</h2>

```python
from pickle import NONE
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import WebDriverException
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

import time


class SeleniumOperationBase:
    def __init__(self, *, headless=True):
        self.log=NONE

        options = Options()
        options.add_argument('--window-size=1024,768')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-setuid-sandbox')
        options.add_argument('--disable-gpu')
        options.add_argument('--headless') if headless else None
        self.driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)

        self.wait = WebDriverWait(self.driver, 30)
        self.driver.set_page_load_timeout(15)
        self.driver.implicitly_wait(15)
        self.driver.set_script_timeout(15)

    #指定したURLにアクセス
    def driver_get(self, url):
        self.driver.get(url)

    #指定した要素が表示されるまで待機する
    def wait_WebElement_Visibility(self,webElement):
        try:
            self.wait.until(EC.visibility_of_element_located((By.XPATH,webElement)))
        except SystemError:
            self.log.error('要素待機失敗:'+webElement)
            raise

    #指定した要素を返すelementsの状態で返す
    def get_WebElements(self,webElement):
        try:
            elements = self.wait.until(EC.visibility_of_all_elements_located((By.XPATH, webElement)))
        except:
            self.log.error('要素待機失敗:'+webElement)
            raise
        return elements
    
    #画面要素をクリックする(WebElement形式)
    def webElement_Click(self,webElement):
        try:
            webElement.click()
        except SystemError:
            self.log.error('画面要素押下失敗')
            raise

    #テキストを送る(WebElement形式)
    def sendText(self,webElement,sendTexts):
        try:
            webElement.clear()
            webElement.send_keys(sendTexts)
        except SystemError:
            self.log.error('テキスト送信失敗:'+sendTexts)
            raise
```

<h2>使用例です;;</h2>

```python
class ExampleCrawler(SeleniumOperationBase):
    def __init__(self,):
        super().__init__(**args)


crawler = ExampleCrawler(headless=False)
```
cscの作法 その87

# 概要
cscの作法、調べてみた。
menu使ってみた。

# 参考にしたページ

https://uchukamen.com/Programming1/Menu/index.htm

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e5a8c3cc-2cfc-b33b-4193-20b7895ea842.png)

以上。
cscの作法 その86

# 概要
cscの作法、調べてみた。
tabcontrol使ってみた。

# 参考にしたページ

https://uchukamen.com/Programming1/TabControl/index.htm


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3c6cb621-dcb1-bca7-d64e-62112fde7c8e.png)

以上。
Flutter初心者が知っておきたいpackageまとめ

# Flutter package
 
## はじめに

Flutterを触れ始めて間もない状態を対象としたドキュメントです。
実装を進めていくにあたって頻出するライブラリ（パッケージ）についてご参考ください。

### pubspec.yaml

記述方法は[こちら](https://qiita.com/kurun_pan/items/76e13bfd03fd3dec1e27)を参考にさせていただきます。
はじめは構造のルール、記述するセクション、バージョンの指定方法を抑えておくと良さそうです。

https://pub.dev/

```yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  get: ^4.6.1
  http: ^0.13.4
  intl: ^0.17.0
  sprintf: ^6.0.0
```

## パッケージ

要求に即したパッケージについてまとめています。

### GetX

- 値を画面間で共有したい
- 値が更新されたら画面を再描画したい
- 画面遷移を簡単に実装したい

```dart:
import 'package:get/get.dart';
```

画面遷移や変数の状態管理に便利なパッケージ。
変数が更新されたら画面を再描画したいといったシーンは多く、導入・実装すると便利です。

#### 例

1. 状態を管理するコントローラーを作成
1. main()でインスタンス化
1. 必要箇所でインスタンスを取得、参照

```dart:game_controller.dart
class GameController extends GetxController {
  final score = 0.obs;
}
```

```dart:main.dart
void main() {
  final GameController gc = Get.put(GameController());
  runApp(MyApp());
}
```

```dart:home.dart
// 取得
final GameController gc = Get.find();
// 代入
gc.score.value = 1234; // gc.score(1234);
// 参照
Text('score: ' + gc.score.toString()); // score: 1234
```

https://pub.dev/packages/get

### http

- サーバにデータを送信したい 
- APIからJSONデータを取得して使用したい

```dart:
import 'package:http/http.dart' as http;
```

APIからJSONを取得するなど、非同期のFuture(asymc/await), FutureBuilderといったキーワードと組み合わせてよく利用されます。

https://pub.dev/packages/http

### intl

- カンマ区切りにしたい
- 日時をフォーマットしたい
- 通貨単位を付加したい

```dart:
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';　// initializeDateFormatting('ja');でローケルを初期化する場合
```

カンマ区切りのフォーマットでよく利用されます。

```dart:
var price = 1000;

var f1 = NumberFormat("#,###");
Text(f1.format(price) + '円'); // 1,000円

var f2 = NumberFormat.simpleCurrency(locale: 'ja');
Text(f2.format(price)); // ¥1,000
```

DateFormatの方法はいろいろアプローチがあるので一例です。

```dart:
DateTime now = DateTime.parse('2022-04-01');
DateFormat df = DateFormat('yyyy年MM月dd日'); // 月日を0埋めする
Text(df.format(now)); // 2022年04月01日
```

https://pub.dev/packages/intl

### sprintf

- 文字列をフォーマットしたい

```
import 'package:sprintf/sprintf.dart';
```

日付をフォーマットする。

```dart:
String now = '2022-04-01';
String formatDate = sprintf('%s年%s月%s日', now.split('-'));
Text(formatDate);
```

https://pub.dev/packages/sprintf

各パッケージの以下ページを一読し、インストールや実装について概要把握することをおすすめします。

- Readme
- Example
- Installing

## 最後に

アプリ開発で共通的によく利用されるパッケージについて、今後も引き続きまとめていきます。
🚧元組み込みC++エンジニアがWebアプリを作ってみる

🚧まだまだ作成中です、ゆっくり作るので期待しないでくださいね🚧

# はじめに
どうです、みなさん、Webアプリをフルスクラッチで作ったことはありますか？**私はないです。**
というわけで作り始めてみました。

# 作者について
- 元組み込みC++エンジニア(5年半くらい)です
    - Linux: 装置間通信とか
    - Windows: MFCでアプリとか
- 現職はWeb界隈のQAエンジニアをしたりしなかったりしています
    - E2Eテストを作ってみたりしました
    - ソースは読み書きしていましたが、**「Webエンジニアです」と宣言するには引け目があります**

# (想定している)対象読者
- 組み込みなどWeb界隈じゃないところのエンジニアのみなさん
- プログラミング勉強してみたけど、何作っていいかわからないみなさん
- その他Webアプリをフルスクラッチで作ってみたいみなさん

# 作るもの
- お店の情報をユーザーが登録して閲覧できるようにするサイト
    - ぐるなびとかそういう感じです
    - 「お店」は各自飲食店だったりバイク屋さんだったり病院だったり、好きなお店に読み替えてください
- ↑に付随する、情報交換用掲示板

# 🔰必要なスキル
- 基本的なターミナル操作
    - `mkdir`とか`ls`とかが叩けて、「何かコマンド入力すれば動くんだな〜」くらいでOKです
    - `ls ~`や`cd $HOME`など、たまに環境変数などその他一般的にわかりそうなものは使います
- 基本的なプログラミングの理解
    - 関数とか変数とかくらいがわかればOKです
- (最重要)何か起きた時に検索するスキルと心の準備
    - 開発はエラーとの戦いです、首を傾げながら検索しましょう
    - わからないことはバシバシ検索していきましょう

# 使おうと思っている技術
- フロントエンド
    - HTML・CSS(Sass)
    - JavaScript・TypeScript
    - Vue.js(Vuex)
- バックエンド
    - Go(Gin)
    - RDB(MySQLなど、未選定)

> ※なぜGo？
モダンな言語に触れたい + ビルドして実行バイナリを吐く言語がいい、という観点です。
Ruby(ROR)やPHP(Laravel)などスクリプト言語&バックエンドF/Wでもよかったんですが、私がF/Wのバージョン差異などに明るくないので、外しました。
またJavaやC#は同様に私がJava VMやCLRに明るくないので外しました。


# やらないこと
- バージョン管理
    - GitだったりSVNだったり、お好みで好きなタイミングでご使用ください

# 環境
こちらはMacです。
Windowsでもできると思いますが、手元にないのでわかりません！
(WSLとかでなんとかなるんじゃないでしょうか)

# 本編リンク集
https://qiita.com/dashi-no-ajiwai/items/0a1ade1a7365a2c0b123

🚧 追記します
CloudFront functionで複数ユーザーのBasic認証を使えるようにする



```javascript
function handler(event) {
  var request = event.request;
  var headers = request.headers;

  // echo -n user:pass | base64
  var authStrings = ["Basic dXNlcjE6cGFzc3dvcmQ=","Basic dXNlcjpwYXNz"]

  if (
    typeof headers.authorization === "undefined" ||
    !authStrings.includes(headers.authorization.value)
  ) {
    return {
      statusCode: 401,
      statusDescription: "Unauthorized",
      headers: { "www-authenticate": { value: "Basic" } }
    };
  }

  return request;
}
```

## 参考
https://dev.classmethod.jp/articles/apply-basic-authentication-password-with-cloudfront-functions/
高圧縮画像フォーマット webp と avif の両方に対応する .htaccess

# はじめに

でかい画像で入稿されて悲しいの。

# webp と avif は？

いずれも後進の高圧縮画像フォーマットです。

webpは瞬間で圧縮できるのが特徴ですが、
avifは圧縮するのに非常に時間がかかります。

# webp と avifの対応ブラウザは？
Can I use より
https://caniuse.com/avif
Firefox93以降、Chrome85以降、Opera71以降


https://caniuse.com/webp
Edge18以降、Firefox65以降、Chrome32以降、Opera19以降
Safari(iOS)14以降


# webp と avif の圧縮率は？

具体的な圧縮率は申し上げにくいものの、
webpの圧縮率(pngロスレス→webpロス)がおおむね1/10～1/1.2
avifの圧縮率(pngロスレス→avifロス)がおおむね1/10～1/1.5 程度で
平均的にはavifのが圧縮率が高いのですが、
ファイルによってはavifよりwebpのがサイズが小さいことがあります。

avifのがファイルサイズが大きい場合、圧縮した avif ファイルを削除すれば、webpで問題なく配信できます。

:::note info
更に場合によっては、webpやavifよりもpngのがサイズが小さいことがあります。
SDGSの透過画像がそれにあたることを確認していますが、webpもavifファイルも削除すれば、問題なくpngで配信できます。
:::

### ちなみに、データ速報を出してみました。

以下の条件の画像を圧縮した際の平均データとなります。

おおむね4KのJPEG画像（デジカメもしくはスキャナ）からImage::Magickで
・横解像度(normal) 450
・横解像度(normal800) 800
・横解像度(big) 1600
・横×縦(mini)　 70

に自動加工・リサイズしたものをソースファイルとする

これをmozjpeg、guetzli、webp、avifで圧縮すると
733ファイルの
オリジナル平均容量：865502byte
mozjpeg平均容量：271144byte (31.32%)
guetzli平均容量（有効ファイルのみ）204075byte (23.57%)
webp平均容量：99257byte (11.46%)
avif平均容量：66925byte (7.73%)

になりました。

## コマンドラインで一括圧縮する

```avif.sh
for loop in `ls *.png`
do
avifenc -j 16 -s 0 $loop $loop.avif
done

for loop in `ls *.jpg`
do
avifenc -j 16 -s 0 $loop $loop.avif
done
```

-j 16 の数字は、論理CPUの数に合わせて下さい。
かなり時間がかかりますのでご注意ください。

-s 0 は 最も低速で高圧縮するオプションとお考え下さい。
テスト目的以外で、この数値をあげる理由はまずありません。

```webp.sh
for loop in `ls *.png`
do
cwebp -q 80 $loop -o $loop.webp
done

for loop in `ls *.jpg`
do
cwebp -q 80 $loop -o $loop.webp
done

```

## たぶん、ここが一番みんなが知りたい .htaccess の設定

これで http:// 環境のWordpressで動作していますので、提示してみます。

なお、これは、/wp-content/themes/テーマ名/.htaccess に
設置して動作しています。

```.htaccess
<IfModule mod_rewrite.c>
	RewriteEngine On

	RewriteCond %{HTTP_ACCEPT} image/avif
	RewriteCond %{REQUEST_URI} (?i)(.*)(\.jpe?g|\.png|\.gif)$
	RewriteCond %{DOCUMENT_ROOT}%1%2.avif -f
	RewriteRule (?i)(.*)(\.jpe?g|\.png|\.gif)$ %1$2\.avif [L,T=image/avif,R]

	RewriteCond %{HTTP_ACCEPT} image/webp
	RewriteCond %{REQUEST_URI} (?i)(.*)(\.jpe?g|\.png|\.gif)$
	RewriteCond %{DOCUMENT_ROOT}%1%2.webp -f
	RewriteRule (?i)(.*)(\.jpe?g|\.png|\.gif)$ %1$2\.webp [L,T=image/webp,R]

</IfModule>

<IfModule mod_mime.c>
	AddType	image/webp	.webp
	AddType	image/avif	.avif
</IfModule>

<IfModule mod_headers.c>
	Header append Vary Accept env=REDIRECT_accept
</IfModule>

```

先にavifファイルが表示可能であることを処理してから、次にwebpファイルの処理を行います。

もし先にwebpファイルの処理を行うと、webp非対応でavif対応のブラウザはまずないと思いますので、webpだけで配信されてしまいます。


ちなみに、HTMLは旧来の画像のURLを指定します。

```test.html
<img src="test.png">
<img src="test.jpg">
```

:::note info
Wordpressのプラグインの中に、Webpに自動圧縮するプラグインがありますが、
/wp-content/themes/テーマ名/ 以下に .htaccess を記述するものでなければ、
こちらの .htaccessが優先され、avifも利用可能となります。
:::


## きちんと対応しているか確認する

一般的にはデベロッパーコンソールで確認するのですが、

もっとも簡単な方法としては
最新バージョンのブラウザ、（もしくは適度に古いブラウザ）で
画像を右クリックして、ダウンロードしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149448/4d37957e-75bf-ee5c-1253-d2f774e75d40.png)


webp もしくは avif 画像のいずれかでダウンロードされようとします。
「理科系の作文技術」を読んだので、その要点

「理科系の作文技術」。以下である。
[理科系の作文技術 (中公新書 624) | 木下 是雄 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4121006240)
初版は1981年に書かれた本。開発や技術者が文章を書く上では「バイブル」などと表現されることもあるが、知っておくべきポイントはそれほど多くはないと思う。

<img src="https://images-na.ssl-images-amazon.com/images/I/31818M220JL._SX298_BO1,204,203,200_.jpg"  width=30% />

## 理科系に求められる作文技術とは

- 実用文を書く技術。
- 読む前と読んだ後で読者にどのように変化することを求めるのかを理解させ、行動させる技術。
- 事実と意見を分ける。
    - 「ジョージ・ワシントンは米国の最も偉大な大統領であった」
    - 「ジョージ・ワシントンは米国の初代の大統領であった」
        - 前者は意見。後者が事実。

## チャーチルのメモ

この本の肝であり、要約だと考える。

> 1940年、潰滅の危機に瀕した英国の宰相の座についたウィンストン・チャーチルは、政府各部局の長に次のようなメモを送った。

> われわれの職務を遂行するには大量の書類を読まねばならぬ。その書類のほとんどすべてが長すぎる。時間が無駄だし、要点をみつけるのに手間がかかる。同僚諸兄とその部下の方々に、報告書をもっと短くするようにご配意ねがいたい。
> （ⅰ）報告書は、要点をそれぞれ短い、歯切れのいいパラグラフにまとめて書け。
> （ⅱ）複雑な要因の分析にもとづく報告や、統計にもとづく報告では、要因の分析や統計は付録とせよ。
> （ⅲ）正式の報告書でなく見出しだけを並べたメモを用意し,必要に応じて口頭でおぎなったほうがいい場合が多い。
> （ⅳ）次のような言い方はやめよう　
> 「次の諸点を心に留めておくことも重要である」
> 「…… を実行する可能性も考慮すべきである」。
> この種のもってまわった言い廻しは埋草にすぎない。省くか、一語で言い切れ。
> 思い切って、短い、パッと意味の通じる言い方を使え。くだけすぎた言い方でもかまわない。
> 私のいうように書いた報告書は、一見、官庁用語をならべ立てた文書とくらべて荒っぽいかもしれない。しかし、時間はうんと節約できるし、真の要点だけを簡潔に述べる訓練は考えを明確にするにも役立つ。

## 「もってまわった言い廻し」

[「することができる」は有害と考えられる - Qiita](https://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0#%E7%90%86%E7%A7%91%E7%B3%BB%E3%81%AE%E4%BD%9C%E6%96%87%E6%8A%80%E8%A1%93%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B)
[「対応」という言葉を使うのはやめよう - Qiita](https://qiita.com/e99h2121/items/13936c52eaf94ebeb4e1)
[「事実」と「意見」を見分けよう - Qiita](https://qiita.com/e99h2121/items/a9fc183556302c6c48e3)
[Designとデザインと設計 - Qiita](https://qiita.com/e99h2121/items/7b352a6bf4acfac8b2fa)
[ユーザーなのか、ユーザなのか](https://zenn.dev/iwamasa/articles/069f72be5f5a5f)

など、つい雰囲気で使ってしまう言葉ありますね…。


## 参考記事

[正確に伝わる文章を書くために「理科系の作文技術」を修得する｜Dr. Kano｜note](https://note.com/dr_kano/n/n9f7f9d0c89c8)

チャーチルのメモが言うようにいかに要点だけを簡潔に書くかが開発者としても、社会人としても大事だぞという本。以上です～
conoha vps 初期設定

https://support.conoha.jp/v/macssh/

https://weblabo.oscasierra.net/openssh-keygen-macos/

https://s10i.me/whitenote/post/42

https://qiita.com/kanuma1984/items/a278528b92762a869287

https://create-it-myself.com/know-how/set-domain-in-conoha-vps/

https://pointsandlines.jp/server-infra/conoha-vps-domain-setting

https://manual.sakura.ad.jp/vps/support/security/firstsecurity.html

https://weblabo.oscasierra.net/openssh-sshd-centos7-change-port/

https://qiita.com/kenokada/items/105007df710adec237db

https://gadgelaun.com/?p=32873

https://www.linuxcapable.com/ja/CentOS9%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%81%ABApache%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/

https://kawairi.jp/weblog/vita/2016040220277

https://qiita.com/koara-local/items/35b999631b6ab41fdc9f

https://ramendelicious.com/2021/06/16/post-834/

https://qiita.com/hondy12345/items/427c7124c41d23bb87ad

https://www.spankyjpn.com/ssl-using-letsencrypt-2-ubuntu/

https://qiita.com/cherubim1111/items/b259493a39e36f5d524b

https://pandanote.info/?p=1225
UbuntuでAppImageを使用する方法

## 環境

```
  Operating System: Ubuntu 20.04.4 LTS
            Kernel: Linux 5.13.0-37-generic
      Architecture: x86-64
```

## 1. AppImageLauncherを使用する方法
https://github.com/TheAssassin/AppImageLauncher/releases


[最新版のパッケージ](https://github.com/TheAssassin/AppImageLauncher/releases)(記事作成時点では`v2.2.0`)を選択してダウンロード。

ダウンロードした`xxx.bionic_amd64.deb`ファイルをクリックしてインストール。

### セットアップ

1. `xxx.appimage`ファイルを右クリックして「AppImageLauncherで開く」を選択
<img width="400" alt="Screenshot from 2022-04-02 05-29-38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658122/3f212d78-c427-df0c-ef55-58e8514e98ef.png">

2.ダイアログが出るので「Integrate and run」を選択する
<img width="400" alt="dialog.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658122/b999c100-74c4-3c7e-8677-61f2c94f8e13.png">

以上でランチャーから起動できるようになります。
実行ファイル自体は`~/Applications`に配置されます。


### アイコンが設定されないとき
`~/.local/share/applications`に`.desktop`ファイルがあるので`Icon`の値を任意のアイコン画像のパスに書き換えます。

```sh:~/.local/share/applications/xxx.desktop
[Desktop Entry]
Name=Joplin (2.7.15)
Exec=/home/username/Applications/Joplin-2.7.15_87e7a8488e8f7c91c18759ff4a5addea.AppImage --no-sandbox %U
Terminal=false
Type=Application
# 任意のアイコン画像のパスを設定する
Icon=/home/username/xxx.icon
StartupWMClass=Joplin
X-AppImage-Version=2.7.15
MimeType=x-scheme-handler/joplin;
Comment=Joplin for Desktop
Categories=Office;

TryExec=/home/username/Applications/Joplin-2.7.15_87e7a8488e8f7c91c18759ff4a5addea.AppImage
X-AppImage-Old-Icon=joplin
X-AppImage-Old-Name=Joplin
X-AppImage-Identifier=4cc8af6459fca417a643050faf2c543f
Actions=Remove;
X-AppImageLauncher-Version=2.2.0 (git commit 0f91801), built on 2020-09-29 21:36:15 UTC

[Desktop Action Remove]
Name=Remove AppImage from system
Icon=AppImageLauncher
Exec=/usr/lib/x86_64-linux-gnu/appimagelauncher/remove "/home/username/Applications/Joplin-2.7.15_87e7a8488e8f7c91c18759ff4a5addea.AppImage"
Name[ast]=Desaniciar AppImage del sistema
Name[cs]=Odebrat AppImage ze systému
Name[de]=AppImage vom System entfernen
Name[en]=Remove AppImage from system
Name[es]=Eliminar Appimage del Sistema
Name[fr]=Supprimer l'AppImage du système
Name[it]=Rimuovi AppImage dal sistema
Name[nl]=AppImage deïnstalleren
Name[pl]=Usuń AppImage z systemu
Name[pt]=Remover AppImage do sistema
Name[pt_PT]=Remover AppImage do sistema
Name[ru]=Удалить AppImage из системы
Name[zh_Hans]=从系统中移除 AppImage

```

## 2. `.desktop`ファイルを作成して自分で配置する方法

AppImageLauncherを使用しない場合は、`~/.local/share/applications`に`.desktop`ファイルを作成して設定するだけでもOKです。

```sh:~/.local/share/applications/xxx.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Joplin
Comment=Joplin for Desktop
# AppImageのファイルパス
Exec=/home/username/.joplin/Joplin.AppImage
Icon=joplin
StartupWMClass=Joplin
Type=Application
Categories=Office;
```
UnityのTextを豆腐にしない、Font.HasCharacter

# 概要
Unityのテキスト表示で、顔文字とか、なんかよくわからない難しい漢字を表示しようとすると、Text表示でエラーが出たり、TextMeshProが通称"豆腐"になったりします。（下図は、アルファベットしか対応してないフォントで「TextMeshぷろ」と入力したときの表示）
![TMP_Tofu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2356775/6263850f-e68a-aca0-8d3d-7f90224f37ba.png)
新しくリリースされたソシャゲなどでユーザー名を入力する際に、表示対応してなさそうな様々な文字を入力してアプリをクラッシュさせる遊びを皆さん嗜んでおられると思いますが、自分のゲームでやられると嫌なのでしっかり対策しましょう。
様々方針はあると思いますが、文字の扱いって歴史が深くてできれば関わりたくないので、Unityが用意してくれてるAPIを利用してみます。

# フォントに文字が含まれてるか返すメソッド
## UnityEngine.Font.HasCharacter
UnityEngine.UI.Textを使用する際に使えます。
`char`を引数に渡して、それがフォントに含まれる文字かどうかの`bool`を返してくれます。

```cs
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    [SerializeField] private Text text;
    
    private void Start()
    {
        // なんかすごい難しそうな漢字
        var userInputChar = '亹';
        // この文字は表示できる？
        var canRender = text.font.HasCharacter(userInputChar);
    }
}
```
フォントに含まれてるなら表示できるし、含まれてないなら表示できないっていうのが一番素直なので、特定の文字はどうしても使わせたくないとか特別な事情が無いならこれで十分かなと思います。
## TMPro.TMP_FontAsset.HasCharacter
TextMeshProを使用する際にも同様のメソッドを使用できます。プロパティ名は`font`と、前述のTextと同じですが型は違います。
なお、オプション引数として、「フォールバックのフォントも検索するか」、「フォントアセットに動的に文字を追加するか」を選べます（デフォルトfalse）。
```cs
using UnityEngine;
using TMPro;

public class Test : MonoBehaviour
{
    [SerializeField] private TextMeshPro tpm;
    
    private void Start()
    {
        // なんかすごい難しそうな漢字
        var userInputChar = '亹';
        // この文字は表示できる？
        var canRender = tmp.font.HasCharacter(userInputChar);
    }
}
```
TMPro版はさらに`string`を渡して文字列を一括で判定してくれる、`HasCharacters`もあります。
```cs
using UnityEngine;
using TMPro;

public class Test : MonoBehaviour
{
    [SerializeField] private TextMeshPro tpm;
    
    private void Start()
    {
        // なんかすごい難しそうな文字列
        var userInputString = "齷齪";
        // この文字列は表示できる？（1つでも表示できない文字があればfalse。そうでなければtrue）
        var canRender = tmp.font.HasCharacters(userInputString);
    }
}
```
# おわり
こういうメソッドをUnityサイドが文字表示するために用意してるのは考えてみれば当たり前の話ですが、実はpublicで公開されてるので我々Unityユーザーも使えるんですね。文字表示に限らず、もしかしてUnityに元からあるんじゃね？と思える処理なら、一度Unityが公開しているソースコードを調べてみるのは悪くないと思います。
とはいえ調べた結果internalで宣言されてるのを見つけて悲しい気持ちになる可能性はなくはないです。
単純な線形回帰モデルの回帰係数を3つの言語で推定した結果

# やったこと
- 線形回帰モデルの原理について、よさそうな記事を資料中で紹介した。
- 線形回帰モデルによる回帰係数を、`python`、`R`、`Julia`の3言語で推定した。
  - データセットはおなじみいつもの安心と信頼と実績の`iris`を使った。
- 推定方法は各言語でよく用いられているライブラリやパッケージによるもののほかに、行列計算用ライブラリを用いた数値計算によるスクラッチ版がある。
- 記述には`.Rmd`を用い、ソースを`github`にあげるほか`RPubs`で公開した。

# 参考文献

1.は`Julia`の行列計算についてわかりやすい記載をされていました。2.は、線形回帰モデルについてよい記載をしているサイトのひとつです。参考になる記事をありがとうございました。

1. https://zenn.dev/hyrodium/articles/3fa3882e4bca04#2%E3%81%A4%E3%81%AE%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E3%81%AE%E7%A9%8D
2. https://qiita.com/fujiisoup/items/e7f703fc57e2dfc441ad

# 関連サイト

1.は筆者による、今回作った`.Rmd`ファイルとなっています。2.は、1.を`RPubs`でみられるようにしたものです。

1. https://github.com/yaminabeworks/qiitakiji/blob/main/ols.Rmd

2. https://rpubs.com/yaminabeworks/ols

# 感想
- 各言語によるデータの取り出し方は筆者が忘れていることもあり、思いのほか時間をとられた気がする。
- さすがに線形回帰モデルだけだと寂しいので、よりこじらせた線形モデルや加法モデルくらいはまとめておきたい。

# 次にやる、この記事に関連すること

- まずは一般化線形モデルについてスクラッチ実装をしたい。
- Rの数値計算に関する本でスクラッチ実装をしていた気がするので、それを参考にする予定です。

# 次にやる、必ずしもこの記事と関連しないこと
- ベイズ統計学
  - ちょっと時間かかりそうです。
- 情報検索分野
  - 今`bm25`の計算等をまとめているので時間かかりそうです。
【インフラ構築】MENTAにてフォローしていただいた事を振り返ります

## 背景
Laravelで作成したポートフォリオのAWSデプロイに苦労していた時、**MENTAにて@adachin0817さん**よりお声がけいただき、インフラ構築のフォローをしていただきました。

以下のプランよりフォローしていただきました。

https://menta.work/plan/442/5218

https://speakerdeck.com/rvirus0817/menta-sabaenziniajiao-yu-nituite?slide=22

## 構築過程
まず最初に開発環境構築に使用すたDockerの設定があまりよろしくなかったので、
開発環境の再構築から始めました。
(本番環境と設定を合わせる目的もあります)

### 開発環境

**開発環境にはDockerを使用しています**

- **Docker 20.10.12**
- **Docker Compose v2.2.3**
  - **Docker image**
    - **laravel-app(appコンテナ)**
      - **php7.4-fpm-alpine(nginx,php-fpm,supervisor)**
      - **Laravel 6.20.34**
    - **laravel-db(mysqlコンテナ)**
      - **MySQL 8.0.27**

**以下構成図です。**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/ae65265c-6dbc-9062-3107-d5f113fdae9b.png">

**具体的な構成、構築内容は以下の記事にまとめました。**

**[【Docker+Laravel6】開発環境構築についてまとめてみました](https://qiita.com/yuuichimizuta/private/85015a63a8e53c058cb2)**

https://qiita.com/yuuichimizuta/private/85015a63a8e53c058cb2

### 本番環境

**本番環境はAWSを使用し、CircleCIで自動デプロイを可能にしています**

- **AWS：EC2, RDS, VPC, Route 53, ALB, ACM, S3, CloudWatch**
**EC2 : nginx, php-fpm**
**RDS : mysql 8.0.27**
- **CircleCI**
**deploy job : git pullデプロイ自動化**
**slack orb : Slackデプロイ結果通知**
　
**以下構成図です。**

![スクリーンショット 2022-04-01 17.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/91ba199a-c0f4-f8a4-4dfc-d41f00777f87.png)

**具体的な構成、構築内容は以下の記事にまとめました。**

**[【AWS＋Laravel】本番環境構築についてまとめてみました](https://qiita.com/yuuichimizuta/items/899251a9cb2dd61dabb0)**

https://qiita.com/yuuichimizuta/items/899251a9cb2dd61dabb0

## 身についたこと

- Docker, AWSのインフラの構造とCircleCIの設定・操作の理解
- 構成を理解し構成図として表記できる能力
- 公式ドキュメントを軸に、あらゆる記事を読み、最適な実装方法を導き出せる能力
- 自走力

## 実装中に意識したこと

- 後で見返してもわかりやすいように、タグや説明をその都度付け加える。
- 各サービス同士の繋がりを意識しながら構築していく。
- とにかく諦めないこと。

## 振り返り

ちょうど1ヶ月でのデプロイ完了でした。技術力のみならず質問力も鍛えられました。
まだまだ理解不足なところもあるので、普段の学習と実務経験で、もっと対応できる幅を広げていきたいです。

## 最後に
**@adachin0817さんのMENTAプランについて紹介します。**

初学者が一番悩むであろう構築までのロードマップを速攻で作っていただき、構築完成まで手厚いサポートをしていただきました。
とにかく質問への回答が早く、問題を素早く解決できます。
また、実務レベルのフォローで、メンティー自身が解決までたどり着けるよう導いてくださるので、自走力爆上がりすると思います！
初学者にとっては決して甘くはないですが、インフラの知識のみならずエンジニアとしての心得を学ぶにおいて、**@adachin0817さんのサポートは最高です。**

<font color="Red">**おすすめです！！**</font>

https://menta.work/user/1162
【SwiftUI・KeyboardShortcut】外部キーボードの入力検知一覧

# KeyboardShortcut
外部キーボードの検知を伝えるには　**.keyboardShortcut(, modifiers: [])**　を使用して、Buttonなどに通知することができます。
```swift
Button {
// ボタン押下時の処理
} label: {
// ラベル（ButtonにするView）を記述
}.keyboardShortcut(押下するボタン, modifiers: [])
```

# KeyboardShortcutの一覧
SwiftUIで外部キーボードのボタンごとの入力の検知をまとめてみました。
#### 文字
```swift
.keyboardShortcut("J" , modifiers: [])
.keyboardShortcut("6" , modifiers: [])
```
#### 文字が変数に含まれている場合
```swift
var character = "J"
var array = ["A","B","C"]
///////////////////////
.keyboardShortcut(KeyEquivalent(Character(character)), modifiers: [])
///////////////////////
.keyboardShortcut(KeyEquivalent(Character(array[0])), modifiers: [])
```
#### upArrow
```swift
.keyboardShortcut(.upArrow , modifiers: [])
```
#### downArrow
```swift
.keyboardShortcut(.downArrow , modifiers: [])
```
#### leftArrow
```swift
.keyboardShortcut(.leftArrow , modifiers: [])
```
#### rightArrow
```swift
.keyboardShortcut(.rightArrow , modifiers: [])
```
#### clear
```swift
.keyboardShortcut(.clear , modifiers: [])
```
#### delete
```swift
.keyboardShortcut(.delete , modifiers: [])
```
#### deleteForward
```swift
.keyboardShortcut(.deleteForward , modifiers: [])
```
#### end
```swift
.keyboardShortcut(.end , modifiers: [])
```
#### escape
```swift
.keyboardShortcut(.escape , modifiers: [])
```
#### home
```swift
.keyboardShortcut(.home , modifiers: [])
```
#### pageDown
```swift
.keyboardShortcut(.pageDown , modifiers: [])
```
#### pageUp
```swift
.keyboardShortcut(.pageUp, modifiers: [])
```
#### return
```swift
.keyboardShortcut(.return , modifiers: [])
```
#### space
```swift
.keyboardShortcut(.space, modifiers: [])
```
#### tab
```swift
.keyboardShortcut(.tab, modifiers: [])
```

# 参考
https://developer.apple.com/documentation/swiftui/keyequivalent
https://stackoverflow.com/questions/64916392/how-to-enable-the-delete-key-shortcut-in-the-edit-menu-of-a-swiftui-app-on-macos
segment tree

```c++
template< typename Monoid >
struct SegmentTree {
    using F = function< Monoid(Monoid, Monoid) >; //max, minなど

    int sz; //一番下の段以外
    vector< Monoid > seg; //値が入る

    const F f; //関数
    const Monoid M1; //int_max

    //size、 関数、 int_max
    SegmentTree(int n, const F f, const Monoid& M1) : f(f), M1(M1) {//f,M1を(private関数)に
        sz = 1;    
        while (sz < n) sz <<= 1; //木の大きさ
        seg.assign(2 * sz, M1); //M1で初期化
    }

    void set(int k, const Monoid& x) {//k番目にxを代入
        seg[k + sz] = x; //値をセット
    }

    void build() { //値をセットした後準備
        for (int k = sz - 1; k > 0; k--) {
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    void update(int k, const Monoid& x) {//k番目にxを更新
        k += sz;
        seg[k] = x;//セット
        while (k >>= 1) {//更新
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    Monoid query(int a, int b) { //[a,b)の最小値
        Monoid L = M1, R = M1; //INFをセット
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) L = f(L, seg[a++]);//上に遡る
            if (b & 1) R = f(seg[--b], R);
        }
        return f(L, R);
    }

    Monoid operator[](const int& k) const {
        return seg[k + sz];//値を返す
    }
};
```

```c++
int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);
  SegmentTree< int > seg(N, [](int a, int b) { return min(a, b); }, INT_MAX);
  while(Q--) {
    int T, X, Y;
    scanf("%d %d %d", &T, &X, &Y);
    if(T == 0) seg.update(X, Y);
    else printf("%d\n", seg.query(X, Y + 1));
  }
}
```

```c++
//sum
SegmentTree< int > seg(N, [](int a, int b){ return a + b; }, 0);

```
[参考](https://ei1333.github.io/algorithm/segment-tree.html)
【AWS＋Laravel＋CircleCI】本番環境構築についてまとめてみました

## 背景

Laravelを使用して開発したポートフォリオのデプロイをする目的で、AWSで本番環境を構築しました。
AWSを使用した理由は、インフラの構造をしっかりと理解したかったからと、
実務に入るとプログラミングだけではなく、サーバーやネットワークについての知識も必要だろうと考えたからです。

(CircleCIについての記事は執筆中です。)

- **開発環境構築(Docker＋Laravel6)については以下にまとめました**
**[【Docker+Laravel6メモ】開発環境構築についてまとめてみました](https://qiita.com/yuuichimizuta/items/85015a63a8e53c058cb2)**

## 本番環境について

- **AWS：EC2, RDS, VPC, Route 53, ALB, ACM, S3, CloudWatch**
**EC2 : nginx, php-fpm**
**RDS : mysql 8.0.27**
- **CircleCI**
**deploy job : git pullデプロイ自動化**
**slack orb : Slackデプロイ結果通知**

### 本番環境構成図

![スクリーンショット 2022-04-01 17.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/891391/efae1491-5676-bc3e-999c-7d246eacb123.png)

## 構築ロードマップ

|順番|手順|
|---|---|
|1|お名前.comで独自ドメイン取得する|
|2|お名前.comで取得したドメインをRoute53に登録する|
|3|VPCを作成する|
|4|セキュリティーグループを作成する|
|5|EC2インスタンスを作成する|
|6|ACMでSSL証明書を発行する|
|7|ELBを作成する|
|8|Route53でAレコードのエイリアスを作成する|
|9|RDSを作成する|
|10|EC2インスタンスにLaravel環境を構築してアプリのデプロイをする|
|11|CircleCIを使用した自動デプロイ(執筆中)|
|12|AWS S3を使用した画像アップロード(執筆中)|

## 構築手順(記事)

### 1.お名前.comで独自ドメイン取得する

https://qiita.com/yuuichimizuta/items/d56608a21891e4bbc296

### 2.お名前.comで取得したドメインをRoute53に登録する

https://qiita.com/yuuichimizuta/items/bd335c9af518560ca3d4

### 3.VPCを作成する

https://qiita.com/yuuichimizuta/items/cee204b9e2776056b863

### 4.セキュリティーグループを作成する

https://qiita.com/yuuichimizuta/items/5d3b9e4872ad8ae1db4f

### 5.EC2インスタンスを作成する

https://qiita.com/yuuichimizuta/items/279bef2573c30b4175a5

### 6.ACMでSSL証明書を発行する

https://qiita.com/yuuichimizuta/items/61f22085342430a69a32

### 7.ELBを作成する

https://qiita.com/yuuichimizuta/items/d7dabc1b4b21de0e7e60

### 8.Route53でAレコードのエイリアスを作成する

https://qiita.com/yuuichimizuta/items/23ed28b7518cdd9a7801

### 9.RDSを作成する

https://qiita.com/yuuichimizuta/items/ac43d5e2be0c1d8f1bc2

### 10.EC2インスタンスにLaravel環境を構築してアプリのデプロイをする

https://qiita.com/yuuichimizuta/items/300672663b991b3a971e

### 11.CircleCIを使用した自動デプロイ(執筆中)

**....**

### 12.AWS S3を使用した画像アップロード(執筆中)

**....**

## 振り返り

今回の**AWS**の**環境構築**を通して、Webサービスがどのように運用されているのかを知るキッカケになりました。
**インフラ周り**の知識を理解するのに、**AWS**は最適だ思います!!

自分が構築した環境は、コストを考えたシンプルな構造となっているため、おそらく基本の域だと思います。
実務でも通用する技術を身につけるためには、更に深く学んでいく必要があります。
なので、これからも**AWS**を通じて**インフラ周り**の知識を磨いていこうと思います！！

難しいけど、がんばります(笑)
Pytorch-ONNXを量子化して高速化する

変換前に量子化することで高速化できます。

# AnimeGANを量子化

```Python
import torch
model = torch.hub.load("bryandlee/animegan2-pytorch:main", "generator", pretrained="celeba_distill").eval()
model_int8 = torch.quantization.convert(model)

dummy_input = torch.randn(1, 3, 512, 512)
input_names = [ "input" ]
output_names = [ "var_444" ]

torch.onnx.export(model_int8z, dummy_input, "animegan2_celeba_distill.onnx", verbose=True, input_names=input_names, output_names=output_names, opset_version=11)
```

ColabのGPUランタイムで試すと、これで推論が倍高速になりました。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
dbt(CLI)をセットアップしてみる(BigQuery)

# dbtとは
公式Docによると、
ELTのTをしてくれるツール。

select文を書くだけでWHのデータを変換できる。
dbtはselect文をテーブルやビューに変換する処理をする。

テストとかもできるらしい。


要するに、テンプレート化したSQLをコンパイル、DWHへ問い合わせ、反映（テーブル、ビューの作成）、またそのテストができる。


プロジェクトファイルとしてymlファイル、モデルとしてSQLファイルの準備が必要とのこと。

https://docs.getdbt.com/

# インストール
- 環境 : Windows10 , bash

Web版は有料みたいなので、CLI版を使用する。
事前準備としては、
- BigQuery(PostgreSQL等の方も読み替えても問題ないです)
- Git
- Python(pipを使用するため)

下記でdbt-coreとdbt-bigqueryがインストールできる。
```
pip install dbt-bigquery
```

```bash
$ dbt --version
installed version: 1.0.4
   latest version: 1.0.4

Up to date!

Plugins:
  - bigquery: 1.0.0
```
Macでhomebrewを使う方、Dockerイメージ、ソースから使いたい方は公式Docへ

https://docs.getdbt.com/dbt-cli/install/overview


# profileの構成
「~/.dbt」に「profiles.yml」を作成する。(dbt initの際に対話形式でも作成できる)

```yml:~/.dbt/profiles.yml
my-bigquery-db:
  target: dev
  outputs:
    dev:
      type: bigquery
      method: service-account
      project: [GCP project id]
      dataset: [the name of your dbt dataset]
      threads: [1 or more]
      keyfile: [/path/to/bigquery/keyfile.json]
      <optional_config>: <value>
```

また、サービスアカウントにジョブユーザーのロール(roles/bigquery.jobUser、roles/bigquery.user、roles/bigquery.dataEditor)を与えておく必要があるので、下記参照
※roles/bigquery.jobUserだけだと、その後のdbt runとかでテーブル作れないため、要確認。

https://cloud.google.com/docs/authentication/getting-started?hl=ja#create-service-account-gcloud

https://cloud.google.com/bigquery/docs/access-control?hl=ja


BigQueryのprofileは下記参照


https://docs.getdbt.com/reference/warehouse-profiles/bigquery-profile


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

dbt init [プロジェクト名]で作成できる。
※また、profiles.ymlが未作成の場合、ここで対話的に聞かれるので、そこで答えることでprofiles.ymlが作成される。
```
$ dbt init dbt_test
```

https://docs.getdbt.com/docs/building-a-dbt-project/projects

# デバッグ

```powershell
$ dbt debug
08:45:52  Running with dbt=1.0.4
dbt version: 1.0.4
python version: 3.9.9
python path: C:\Users\user\AppData\Local\Programs\Python\Python39\python.exe
os info: Windows-10-10.0.19044-SP0
Using profiles.yml file at C:\Users\user\.dbt\profiles.yml
Using dbt_project.yml file at C:\Users\user\Desktop\abcd\dbt_test\dbt_project.yml

Configuration:
  profiles.yml file [OK found and valid]
  dbt_project.yml file [OK found and valid]

Required dependencies:
 - git [OK found]

Connection:
  method: service-account
  database: test1234
  schema: test_test
  location: None
  priority: None
  timeout_seconds: 300
  maximum_bytes_billed: None
  execution_project: test1234
  Connection test: [OK connection ok]

All checks passed!
```
これで接続が確認できた。

# 続き

https://qiita.com/yasu_25/items/a8ecdac5175df2f03e67
【トリビアのDelta Lake】#3 Pysparkで全行とも同じ値が入った列を新設したい

# Pysparkで、同じ値だけを各行に入れた列を新設したい
今回は少しマイナーなTipsかもしれませんが、意外と「あれどうやるんだっけ？」となることが多いので書いてみます。

今回も例によってサンプルデータを用意します。
```
sample_data = [{'name': 'Alice',"age": '2',}, 
               {'name': 'Bob',"age": '50'},
               {'name': 'Matilda',"age": '12'}]

df = spark.createDataFrame(sample_data)
df.show()

【結果】
+---+-------+
|age|   name|
+---+-------+
|  2|  Alice|
| 50|    Bob|
| 12|Matilda|
+---+-------+
```
ここに、birthplace（出身地）という列を新設しようと思います。
値となる地名は何でもいいですが、せっかく名前にマチルダを追加したのでここでは映画『レオン』に則って「NewYork」としましょうか。
3人とも、全員ニューヨーク出身として、NewYorkという値が各行に入った列を追加します。

# litで値を囲むのがミソ
結論、こんな感じで書くことが出来ます！
```
from pyspark.sql.functions import lit
df_add_birthplace = (
    df
    .withColumn("birthplace",lit("NewYork"))
)
df_add_birthplace.show()

【結果】
+---+-------+----------+
|age|   name|birthplace|
+---+-------+----------+
|  2|  Alice|   NewYork|
| 50|    Bob|   NewYork|
| 12|Matilda|   NewYork|
+---+-------+----------+
```

列を追加するコマンドとして.withColumnがある、というのは割と有名ですよね。
ここでは
```
df.withColumn("新設するカラム名",lit("新設列に入れる値"))
```
といった文法になります。

# 想定されるユースケース：名前からメアドを生成
といっても、Pysparkで行うETL作業の中で、元データから必要なものだけに削ぐことはあっても追加する、ってことは経験上あまりないのかなと思っています。

そのなかでも、想定されるユースケースとしては、例えば「**メールアドレスの生成**」があるかなと思います！
```
sample_data = [{'name': 'Alice',"age": '2',}, 
               {'name': 'Bob',"age": '50'},
               {'name': 'Matilda',"age": '12'}]
df = spark.createDataFrame(sample_data)

#「mail_domain」列を追加する
from pyspark.sql.functions import lit
df_add_mail_domain = (
    df
    .withColumn("mail_domain",lit("@amail.com"))
)
df_add_mail_domain.show()

【結果】
+---+-------+-----------+
|age|   name|mail_domain|
+---+-------+-----------+
|  2|  Alice| @amail.com|
| 50|    Bob| @amail.com|
| 12|Matilda| @amail.com|
+---+-------+-----------+
```

そして、nameとmail_domainをconcatで結合すると、晴れてメールアドレスの出来上がりです！
（今回は架空ドメインの「@amail.com」を使うことにします）

```
from pyspark.sql.functions import col,concat
df_add_mail_address = (
    df_add_mail_domain
    .withColumn("mail_address",concat(col("name"),col("mail_domain"))
    )
)
df_add_mail_address.show()

【結果】
+---+-------+-----------+-----------------+
|age|   name|mail_domain|     mail_address|
+---+-------+-----------+-----------------+
|  2|  Alice| @amail.com|  Alice@amail.com|
| 50|    Bob| @amail.com|    Bob@amail.com|
| 12|Matilda| @amail.com|Matilda@amail.com|
+---+-------+-----------+-----------------+
```
ちなみに文法はこんな感じ。
```
(データフレーム).withColumn("新設するカラム名",concat(col("結合列①"),col("結合列②"))
```

いかがでしょうか？
この他にも「この列の値に特定の値を付与したいよね」というニーズには、上記のような「litで新列作る」→「concatで結合」の流れを踏むことで応えられる気がします。

あ、マチルダにメールは送らないでくださいね笑

# このシリーズの目的
クラウドストレージに蓄積された生データ（CSV,JSON等）を加工するのに必要なPysparkの知識を溜めていく、まさに「Pysparkに関するトリビアのDalta Lake」を目指しています。
Pysparkに関する記事はまだ海外のものが多く、このシリーズが私のような国内の駆け出しデータエンジニアの一助になることを願っています。
Javaでメール受信

# 概要

[Apache James](https://james.apache.org/)を使うサンプル。Jamesはかなり高機能なようですが、今回はメール受信して独自に処理する必要があったので、受信してログ出すだけの最小サンプル。

# Apache James

Javaで実装されているメールサーバ。SMTPやIMAPなどに対応しているようです。「Mailet」を実装することでメールの独自処理を行うことができます。

# 実装

javaコマンドの引数に`-Dworking.directory=(confディレクトリを置いたディレクトリへのパス)`を指定して実行してください。

[https://github.com/YasunoriHigashiyama/custom-james-assembly-sample](https://github.com/YasunoriHigashiyama/custom-james-assembly-sample)
【合格体験記】Pythonエンジニア認定試験（基礎、データ分析）

# はじめに

ちょっと息抜き。本稿は趣向を変えて、お届けします。

筆者、Pythonエンジニア認定試験を直近の約半年のうちに２つ受験し、合格しました。
というわけで、合格を記念して、合格体験記を綴ることにしました。

（Pythonエンジニア育成推進協会に投稿しろよ、って話ですが恥ずかしい。）

# 受験結果

- Python3エンジニア認定基礎試験

:::note info
合格評価得点：700／筆者の評価得点：850／結果：合格
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/95673ca8-4290-4abf-775f-b3905ec047b5.png)

- Python3エンジニア認定データ分析試験

:::note info
合格評価得点：700／筆者の評価得点：975／結果：合格
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/95ade77e-9c15-cf8b-e5c5-55672aeae675.png)

# 筆者のこれまで

- 理系脳なはず
  - 高校の頃は、国語の授業数を減らしたい（現代文やら小説やら興味ない）という想いから理系を選択
  - 大学・大学院は、ソフトウェアの世界で生きてくための知識スキルを身に着けたいという考えで情報系を専攻
- Pythonが大好きだけど、仕事ではあまり利用していない
  - 性能目標、周辺システムとの連携、実装に必要なライブラリの実績・サポートなどで制約がなければPythonを選定
  - 共通フォルダのTree情報を引っこ抜くためにPythonをひっそり使ってたり

# 体験記

## Q1：Python経歴年数とPythonに出会った際の第一印象についてお教えください。
学生時代に３年間どっぷり、就職後は趣味（日曜プログラマー）で業務でも触れていた時間は２年に満たないレベル。
出会ったときは、**スッキリしてて美しいな**、と思いました。C／C＋＋／C＃／Javaを普段使いしていたところに、ある意味でよい衝撃。

初めてのPythonは、当時ｖ２．５の頃でPyGameでライフゲーム作ってたｗ

## Q2：Pythonエンジニア認定試験を受けたきっかけと勉強方法についてお教えください。
仕事ではWindows／Linuxは当然、AIやクラウドの知識スキルが求められる立場。
いつ会社が潰れてもすぐ働き口を見つけられるように、**AIないしクラウドに関する認定資格**が欲しいな、がきっかけ。

勉強方法ですが、ベースは**日曜プログラマー**です。
試験概要を下調べしている過程で見つけた以下の２サービスの模擬試験を**試験前日にTry**、というスタンス。（限りなく一夜漬け）

:::note warn
メールで届く模擬試験の結果をきちんと把握し、得点率の低い出題範囲を炙り出して対策を打つことが重要です。
:::

https://study.prime-strategy.co.jp/

https://diver.diveintocode.jp/dive_into_exam/lp

### 基礎試験は２サービスを併用
基礎試験は、Pythonの仕様とか根幹思想とかただプログラム書いてるだけでは深く意識しない部分も出題範囲だったので、各サービスで模擬試験を１回ずつ。

で、とりあえず得点率はいずれの８０％を超えたので、打ち止め。

### データ分析試験は１サービス（PRIME STUDY）のみ利用。
データ分析試験は、正直慣れと推測。
というわけで、Kaggle分析だったり株価予測だったりで、データ分析で利用するPythonライブラリ群（pandas/numpy/matplotlib/scikit-learn）に一通り触れるようにしてきた。

https://qiita.com/Blaster36/items/0875960a028ecc5c43c0

https://qiita.com/Blaster36/items/9bdf777f35fda3335f6a

https://qiita.com/Blaster36/items/d0a99f9d4f6b12a2dd83

統計や行列演算については、高校や大学で基本を学んでいたはずで、その記憶も多少役立っていたかと。

で、総復習という位置づけで、模擬試験（全３回）を各々１回ずつTry。

## Q3：Pythonエンジニア認定試験を受けて満足していますでしょうか？
**大満足。**

以下、各々の試験に対する筆者の所感。
- 基礎試験は、Pythonの仕様とか根幹思想とかを改めて体系化して知識として蓄えられた。
- データ分析試験は、会社での業務にも通ずるものがあり、データ分析をLiteではあるものの実体験できた。

## Q4：会社からの受験補助や資格手当がありましたでしょうか？
**一切なし。**

これらのサポートが受けられる企業で働けるとありがたいな、と思うこの頃。

## Q5：Pythonエンジニアとして大事にしていることはなんですか？
**シンプルに、そして美しく。**

スパゲッティコードだとせっかくのPythonの良さが活きないので、上記を意識して可読性の高いコードになるよう努めてます。

## Q6：「Pythonic」について、一言お願いします。
**素敵な思想。今後も意識し、追い求めたい。**

> Beautiful is better than ugly.

・・・ワンライナーを考えて使うのは楽しい、一方で可読性を気にして仕事では積極的には使えてないのが少し残念。
Python3.8で**セイウチ演算子**が導入されたりとかもあるけれど、チーム開発となると可読性はある程度必要かな、と。

## Q7：Pythonエンジニアとしての今後の計画・夢・目標についてお教えください。
データ分析は当然、LiteめなWebシステムやサーバの夜間処理、地味な事務処理の自動化はこれまで同様に取り組む。
**データサイエンティスト（データから価値を作り出す側）とデータ分析エンジニア（データ分析の環境を仕立てる側）の両視点をバランスよく**持つことを目指してく。

夢は、**株取引で儲ける**こと。（実現したら、誰にも言わず、ひっそりと儲け続けてやる。）

（現実的な）目標は、**自然言語処理**を極めたい。word2vec、BERT、GPTや感情分析を使いまわせるようになること。
そして、音声認識（Speech2Text）や音声合成（Text2Speech）を利用したアプリをあといくつか作りたい。
いろいろな時代のいろいろな人に使ってもらえる**サービスの開発に携わってゆけるPythonエンジニア人材**になりたい。

# おわりに
タイトルこそ合格体験記だが、、、ほとんど雑談めいた日記。
最後までご覧いただいた方、ありがとうございます。
GAS - Googleフォームからアップロードした画像を自動でLINE NOTIFYに投稿

Google フォームからアップロードした画像をLINE NOTIFYに投稿する手順のメモ


LINE NOTIFY API公式ドキュメント

https://notify-bot.line.me/doc/ja/




・Googleドライブにアップロードされたファイルのパーミッションを公開に設定しないと、LINEのAPIが画像を読み込めない。 
パーミッションの設定を変えるには [setSharing](https://developers.google.com/apps-script/reference/drive/file?hl=en#setsharingaccesstype,-permissiontype) 関数を使う。
```js
file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
```

:::note warn
注意：LINE NOTIFYにはJPEG画像かPNG画像しかアップロードできない。フォームでは画像や文書など種類は制限できるが、画像フォーマットまでは制限できないため、画像フォーマットを判別して変換する等の対応が必要になるか。（下記では未対応）
:::


# 準備

+ フォームのコンテナバインドスクリプトとして記述（スプレッドシートではない）
+ トリガーでフォーム送信時に下記 postImage 関数が実行されるように設定しておく。
+ フォームに画像アップロードの設問を１つ作り、タイトルを「画像アップロード」にしておく。

# 参考コード
```js
const LINE_NOTIFY_TOKEN = '*******';

function postImage(e) {
  let blob = null;
  const itemResponses = e.response.getItemResponses();
  itemResponses.forEach(item => {
    const title = item.getItem().getTitle();
    const response = item.getResponse();

    if (title === "画像アップロード") {
      const fileImage = DriveApp.getFileById(response);
      fileImage.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
      blob = fileImage.getBlob();
    } else {
      // その他の設問の場合の処理
    }
  });

  const body = "メッセージ";
  sendLine(body, blob);
}

function sendLine(body, blob) {
  const options = {
    "method": "post",
    "payload": {
      "message": body,
      "imageFile" : blob,
    },
    "headers": { "Authorization": "Bearer " + LINE_NOTIFY_TOKEN }
  };

  UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
```
インフラエンジニア基礎入門 #1

ウズウズカレッジさんが出しているネットワーク基礎の動画を視聴したので、その内容をまとめてみました。
↓動画のリンク
https://www.youtube.com/watch?v=aYbUDGn61cU&list=PLXXalsdlzX-J7AUuw2zSHit5nRUZ3eDdz&index=6&ab_channel=%E3%82%A6%E3%82%BA%E3%82%A6%E3%82%BA%E3%82%AB%E3%83%AC%E3%83%83%E3%82%B8l%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%EF%BC%88IT%E3%83%BBDX%EF%BC%89%E5%88%86%E9%87%8E%E3%81%AE%E3%83%AA%E3%82%B9%E3%82%AD%E3%83%AA%E3%83%B3%E3%82%B0%E5%B0%B1%E8%81%B7


###### イントラネット
TCP/IP を用いて作られた社内ネットワーク
使用を限定されたアプリや情報の共有可能
###### エクストラネット
イントラネットとイントラネットを結んだもの

###### アプリケーション
ある機能を持ったソフトウェア

###### サーバ
アプリケーションを提供するコンピュータ

###### クライアント
他が保有するアプリケーションを利用するコンピュータ

###### ネットワークユーザアプリケーション
ネットワークを利用したアプリケーション

###### バッチアプリケーション
ユーザの実行やあらかじめ設定されたタイミングで自動実行＆終了
###### インタラクティブアプリケーション
クライアント⇔サーバでデータ通信が発生
###### リアルタイムアプリケーション
クライアント⇔クライアントでデータ通信が発生

###### 2進数
コンピュータはどんな情報も2進数（バイナリ）データに変換して扱う
2進数を送信する際は電気信号に変換
人間がわかる情報→2進数データ→電気信号→2進数データ→人間にわかる情報

###### エンコード/デコード
エンコード：情報をバイナリデータに変換すること
デコード：エンコードの逆

###### 文字コード
世に存在する様々な文字に対して、１つずつ対応する番号を付けたもの

###### 文字化け
送信側と受信側で文字コードが食い違っていて、受信側で複号化に失敗

###### バイナリデータを電気信号に変換
０→OFF １→ON

###### 帯域幅
一秒間にどれだけの情報を送ることができるか
≒通信速度　bps(bits per second)

###### 輻輳
大量データ通信などによりネットワークが混雑し、データ通信が困難になること
###### ジッタ
信号が想定より早いor遅く宛先に到着すること

###### ノード
コンピュータ、ルータなどの機器
###### リンク
ケーブルや電話など、ノード間のデータの通り道

###### トポロジ
ノードのつなぎ方

###### バス型トポロジ
一本の同軸ケーブルに複数ノードを接続
電気信号の販社によるノイズを防ぐターミネータ取り付けられている
一か所の断線で機能しなくなるため、現在は使われてない

###### スター型トポロジ（ハブアンドスポーク）
集線装置（ハブ）を中心にノードを接続する
現在もっとも一般的

###### リング型トポロジ
喉同士をリング型につなげたトポロジ
トークンという周回している信号を受け取ったノードのみがデータ送信可能
データの衝突発生しない

###### メッシュ型トポロジ
複数のノードを網目状に接続するトポロジ
フルメッシュ：全ノードつなぐ
パーシャルメッシュ：重要なノードに絞ったもの
コストはかかるが、高い冗長性を持つ

###### 通信の種類
ユニキャスト：1:1
ブロードキャスト：1:全て
マルチキャスト：1:特定のグループ
ROS2 tutorials 

# ビルド方法


```
colcon build --symlink-install
```

# 以下ROS2 多様するコマンド一覧
手始めにコマンドの確認
```
ros2 -h
```
ROS１の頃には見かけなかったコマンドもあるようだが

```
Commands:
  action     Various action related sub-commands
  bag        Various rosbag related sub-commands
  component  Various component related sub-commands
  daemon     Various daemon related sub-commands
  doctor     Check ROS setup and other potential issues
  interface  Show information about ROS interfaces
  launch     Run a launch file
  lifecycle  Various lifecycle related sub-commands
  multicast  Various multicast related sub-commands
  node       Various node related sub-commands
  param      Various param related sub-commands
  pkg        Various package related sub-commands
  run        Run a package specific executable
  security   Various security related sub-commands
  service    Various service related sub-commands
  topic      Various topic related sub-commands
  wtf        Use `wtf` as alias to `doctor`

```



# トピック一覧の表示
```
ros2 topic list 
```

# トピック情報の表示
```
ros2 topic echo /tf
```

# ノード一覧の表示
```
ros2 node list 
```

# トピック一覧の表示
```
ros2 topic list 
```

# メッセージ一覧の表示
```
ros2 interface list 
```

# メッセージの構造を表示
```
ros2 interface show nav2_msgs/action/FollowPath

``````

# nodeに属するparameterを表示
``````
ros2 param list
``````
モバイルデバイスでタップした時に擬似的に発生する :hover ステートを CSS 上で効かなくする

レスポンシブな HTML + CSS を書いている時、デスクトップでだけマウスカーソルのホバー時にツールチップを出したいとかあると思うんです。

こんな感じで。

```html
<a class="link">ちょっと見て！<span class="tooltip">やっぱ見ちゃダメ</span></a>
```

```css
.tooltip {
    display: none;
}
.link:hover .tooltip {
    display: block;
    /* 位置合わせする */
}
```

で、モバイルデバイスには :hover ステートが無いのでツールチップは表示されません。…と思うじゃないですか。ところが、モバイルデバイスには :hover ステートは無いものの、タップ時に擬似的に :hover が発生して、他の場所をタップするまで発生したままになるんですね。なので、このままだとタップした時にツールチップが表示されそのままになっちゃうんです。ちょっと嫌ですね。

これ、簡単に抑制できます。

```css
.tooltip {
    display: none;
}
@media (hover: hover) {
    .link:hover .tooltip {
        display: block;
        /* 位置合わせする */
    }
}
```

[メディアクエリ](https://developer.mozilla.org/ja/docs/Web/CSS/Media_Queries/Using_media_queries)の [hover](https://developer.mozilla.org/ja/docs/Web/CSS/@media/hover) 特性を使って、実際に :hover ステートをサポートするデバイスでのみ CSS が有効なようにすればいいんですね。

分かってしまえば簡単な話なんですが、すぐに忘れそうなので自分用の備忘録に残しておきます。
カイ二乗分布と適合度検定

# はじめに
下記について解説し、例題を用いてPythonで実装する。
・カイ二乗分布
・適合度検定


# カイ二乗分布について
確率変数 $Z_{1}$, $Z_{2}$,..,$Z_{n}$が互いに独立で、標準正規分布に従うとき
次の式から導かれる統計量$χ^2$ が従う確率分布のこと（確率密度関数は割愛します）

$χ^2 = Z_{1}^2 + Z_{2}^2 + Z_3^2 $+ .. + $Z_{k}^2$  (自由度k)

# 適合度の検定
理論上の確率分布(度数に関する分布)に対して、標本から求めた度数(観測度数)が適合しているかを検定すること。
例えば、理論上の確率分布がばらつきに偏りのないもの(一様分布)だった場合、観測度数も偏りがないはずであるということ。
観測度数が確率分布に適合している仮説の下で、近似的に下記が成立することを元に検定を行う。

$\sum_{i=1}^k(x_{i} - np_{i})^2 / np_{i} $　～$χ^2$ (自由度k-1)

※ x:観測度数、np:期待度数


例）
1～5の数字が書かれたくじを20回選んでもらった。特定の数字が多く出ているか検定せよ。

```
import pandas as pd

# 標本のdf
df = pd.DataFrame(
    {"選択した回数(観測度数)": [12, 15, 12, 10, 1], "期待度数": [10, 10, 10, 10, 10]},
    index=[1, 2, 3, 4, 5]
)
print(df)
```
出力結果
![カイ二乗 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1018986/a447e8b9-06b3-3a7f-c117-9dbf6a91fc44.png)

検定統計量$χ^2$を計算する。
```
result = 0
for row1, row2 in zip(df["選択した回数(観測度数)"], df["期待度数"]):
    result += (row1 - row2)**2 / row2
print(result)

>>> 11.399999999999999
```
自由度4のカイ二乗分布の5%水準の統計量は、9.49。
したがって、5%水準で有意差あり。
理論上の確率分布に従っているという仮定に無理があったと言える。
※今回の場合の理論上の確率分布は、1～5がすべて確率$\frac{1}{10}$ という一様分布のこと。