OmniAICreator/Qiita-1.07M huggingface dataset:
vistaでstm32duino その19

#概要

vistaでstm32duinoやってみた。
freertos、やってみた。

#サンプルコード

```
#include "STM32FreeRTOS.h"

const uint8_t LED_PIN = LED_BUILTIN;
volatile uint32_t count = 0;
TaskHandle_t blink;

static void vLEDFlashTask(void * pvParameters) {
	pinMode(LED_PIN, OUTPUT);
	for (;;) 
	{
		digitalWrite(LED_PIN, HIGH);
		vTaskDelay((50L * configTICK_RATE_HZ) / 1000L);
		digitalWrite(LED_PIN, LOW);
		vTaskDelay((150L * configTICK_RATE_HZ) / 1000L);
	}
}
static void vPrintTask(void * pvParameters) {
	while (1)  
	{
		vTaskDelay(configTICK_RATE_HZ);
		Serial.print(F("Count: "));
		Serial.print(count);
		Serial.print(F(", Unused Stack: "));
		Serial.print(uxTaskGetStackHighWaterMark(blink));
		Serial.print(' ');
		Serial.print(uxTaskGetStackHighWaterMark(0));
		Serial.print(' ');
		Serial.println(uxTaskGetStackHighWaterMark(xTaskGetIdleTaskHandle()));
		count = 0;
	}
}
void setup() {
	Serial.begin(9600);
	while(!Serial) {}
	xTaskCreate(vLEDFlashTask, "Task1", configMINIMAL_STACK_SIZE + 50, NULL, tskIDLE_PRIORITY + 2, &blink);
	xTaskCreate(vPrintTask, "Task2", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 1, NULL);
	vTaskStartScheduler();
	Serial.println(F("Die"));
	while(1);
}
void loop() {
	while(1) 
	{
		noInterrupts();
		count++;
		interrupts();
	}
}





```

#結果

```
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108
Count: 9307985, Unused Stack: 163 194 108



```


以上。
vistaでstm32duino その18

#概要

vistaでstm32duinoやってみた。
i2c master、やってみた。

#サンプルコード

```
#include <Wire.h> 
#include "Lcd8574.h"

Lcd8574 lcd;
int i = 0;

void setup() {
	pinMode(PC13, OUTPUT);
	lcd = Lcd8574();
	lcd.begin(16, 2);
	lcd.print("012hello, world!");
}
void loop() {
	i++;
	lcd.setCursor(1, 0);
	lcd.print(i);
	digitalWrite(PC13, HIGH);
	delay(1000);
	digitalWrite(PC13, LOW);
	delay(1000);
}





```

以上。
vistaでstm32duino その17

#概要

vistaでstm32duinoやってみた。
i2c scanner、やってみた。

#写真

![DSCN0549.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a29e5550-d7f1-824f-f66a-c320afbc41bd.jpeg)


#サンプルコード

```
#include <Wire.h>

void setup() {
	Serial.begin(9600);
	Wire.begin();
	Serial.println("\nI2C Scanner");
}

void loop() {
	byte error, 
		address;
	int nDevices;
	Serial.println("Scanning...");
	nDevices = 0;
	for (address = 1; address < 127; address++) 
	{
		Wire.beginTransmission(address);
		error = Wire.endTransmission();
		if (error == 0) 
		{
			Serial.print("I2C device found at address 0x");
			if (address < 16) 
				Serial.print("0");
			Serial.println(address, HEX);
			nDevices++;
		}
		else if (error == 4) 
		{
			Serial.print("Unknown error at address 0x");
			if (address < 16) 
				Serial.print("0");
			Serial.println(address, HEX);
		}
	}
	if (nDevices == 0)
		Serial.println("No I2C devices found");
	else
		Serial.println("done");
	delay(5000);
}





```

#結果

```
Scanning...
I2C device found at address 0x27
done
Scanning...
I2C device found at address 0x27
done
Scanning...
I2C device found at address 0x27
done


```

以上。
RDSのMySQLでクエリキャッシュを有効化する

AWS RDSのMySQLではクエリキャッシュがデフォルトでオフになっています。
当初はてっきりオンなのかと思っていましたがオフのようです。

しばらく前からクエリキャッシュ自体をやめたほうが良いのではという記事を見かけていましたが、RDSでは実際にオフになっているようです。

https://yakst.com/ja/posts/4612

ただ経験上、一般公開されているWebサーバであればクエリキャッシュはかなり効果的だと思っています。
特にselectの比率が高い場合（90%以上）には有用かと思います。

まずクエリキャッシュの状況確認のため、各種パラメタの調整にも有用なのでphpMyAdminで接続して確認しておきます。

https://qiita.com/yousan/items/649e554c1099c1e06ae5

上記記事を参考にphpMyAdminに接続し、「状態＞アドバイザ」を進みます。

クエリキャッシュがオフであることが確認できました。

![Screen Shot 2021-10-20 at 10.04.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/20365d58-acb3-df6c-1d82-7708f6d68bc9.png)


## キャッシュの設定

RDSの場合には設定を「パラメタグループ」という項目で設定します。
RDSのコンソールよりパラメタグループを開き新規作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/522c81bd-bc01-748f-5655-6eebb197a06e.png)

作成されたらパラメータとRDSインスタンスを関連付けします。
インスタンスの「編集」を開きパラメタグループの指定部分を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/99c4515f-a9bb-4e9c-7baa-8399d9d487bf.png)

保存します。

「パラメータ」の「変更」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/2b07690b-be9a-3847-9dda-e550bd3d115d.png)

`query_cache_type` を１に設定します。[^qtype]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/536fb41b-bac0-73cd-bcc0-7aabc2862453.png)

[^qtype]: 0,1,2 が指定可能ですが、2はオンデマンド方式になります。 https://dev.mysql.com/doc/refman/5.7/ja/query-cache-configuration.html

パラメタグループのタイプの適用には「Dynamic」と「Static」があります。[^awsrds]

| 種別 | 説明 |
| --- | ---|
| Static （静的） | 再起動するまで反映されない。 |
| Dynamic （動的） | 再起動なしで反映される。ただし多少のタイムラグがある。 |


[^awsrds]: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Troubleshooting.html#CHAP_Troubleshooting.Parameters

今回は `Static` ですので設定後にRDSを再起動します。

その他、キャッシュ用に確保されるメモリの容量と、キャッシュされる最大値の設定もしておきます。

設定名 | 値
---|---
query_cache_type | 1
query_cache_size | 104857600 (100MB)
query_cache_limit | 104857600 (100MB)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/4b8acf1c-7ea8-c0b9-d6c0-5869dcb2bd7c.png)


設定が終わったらRDSを再起動してしばらく待ちます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/eb06dd58-b3cc-f438-bbe0-3409c3cba866.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/eaafd5fe-bb72-3df6-db5e-a607729db860.png)


再起動が終わったらphpMyAdminから確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47327/1c4b2f62-63d4-b184-3e9d-0e7b4740bbc2.png)

キャッシュのヒット率が少ない問問題が表示されていますが、これでキャッシュ自体は有効化されていることが確認されました。
再起動直後のためサーバの起動時間が少なく、ヒット率も低くなってしまいます。しばらく起動を続けてヒット率が上がることを確認します。

またいくつかクエリを投げて結果が早いことを確認しておくと良いでしょう。
AWS AppSync の Cognito UserPools 認証を行ったユーザーで GraphQL API を実行する

# はじめに

GraphQL API を実行する場合、API_KEY を使う場合は　API Key 認証として具体的なリクエスト方法が示されている。

```bash
$ $ curl -XPOST -H "Content-Type:application/graphql" -H "x-api-key:ABC123" -d '{ "query": "query { movies { id } }" }' https://YOURAPPSYNCENDPOINT/graphql
```

https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/security-authz.html#api-key-authorization

一方、Cognito UserPools で認証を行っている場合は、どのような情報が必要かの具体例が少なかったので、本記事で説明する。


# 回答

手順の概要は以下の通り。

- ログイン可能な Cognito UserPools を作成する (この用途であれば Cognito フェデレーティットアイデンティティは不要)
- GraphQL API と作成した Cognito UserPools を紐づける
- Cognito UserPools にログインして ID トークンを取得する
- GraphQL API にアクセスする際の Authorization ヘッダに ID トークンを載せてアクセスする。
    - 公式の説明では [Authorization ヘッダには Amazon Cognito ユーザープールによって提供される OIDC トークンが使用されます、と説明されている](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/security-authz.html#amazon-cognito-user-pools-authorization) が、Cognito UserPools を利用する場合は ID トークンが OIDC トークンに該当する
- Cognito に保存されているユーザー情報による制御を行いたい場合、Resolver 内で ID トークンの内容が参照できるため、これを使って解決する

デフォルトの認証モードとして Cognito UserPools を紐づける場合、マネジメントコンソールであれば 設定 > デフォルトの認証モードから設定できる。

![SnapCrab_NoName_2021-10-20_9-58-29_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/ec929d76-7feb-bd55-977d-5a5239aa8415.png)

Cognito UserPools にログインして以下の結果が得られたとする（これは `cognito-idp admin_initiate_auth` を実行して得られた結果）。 この記事では Cognito UserPools の設定やログイン方法については説明しない。

```json
{
  "ChallengeParameters": {},
  "AuthenticationResult": {
    "AccessToken": "eyJraWQiOiJpSlp........",
    "ExpiresIn": 3600,
    "TokenType": "Bearer",
    "RefreshToken": "eyJjdHkiOiJKV1QiLCJlbm......",
    "IdToken": "eyJraWQiOiJ3RU9......"
  },
  "ResponseMetadata": {
    "RequestId": "ed5aaa19-92a4-439f-b686-8a0525818e99",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "date": "Wed, 20 Oct 2021 00:26:58 GMT",
      "content-type": "application/x-amz-json-1.1",
      "content-length": "4098",
      "connection": "keep-alive",
      "x-amzn-requestid": "ed5aaa19-92a4-439f-b686-8a0525818e99"
    },
    "RetryAttempts": 0
  }
}
```

この時、得られた `AuthenticationResult.IdToken` をリクエスト時の Authorization ヘッダに設定してアクセスする。 具体的には以下の通り。

```bash
$ curl -s -X POST -H "Context-Type: application/graphql" -d '{"query": "{ hello }"}' -H "Authorization: eyJraWQiOiJ3RU9......" https://********.appsync-api.ap-northeast-1.amazonaws.com/graphql

# {"data":{"hello":"This is a fixed string!"}}
```

初期設定では Cognito にログインして正常な ID トークンさえ持っていればアクセスが可能だが、ユーザー毎にアクセスを制限したい場合、リゾルバー内で `$context.identity` としてアクセスして ID トークンに含まれる情報を取得し、利用できる。

例えば、`$context.identity.claims.get("cognito:groups")` によって、ユーザーが所属しているグループ一覧が取得できるため、これを使って「Administratorグループに属していれば PutItem が可能」と言ったリゾルバーマッピングテンプレートを記載できる。

より詳細なユースケースは以下を参照。

https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/security-authorization-use-cases.html
githubをアクセストークンを使ってログインする

Githubへのアクセスで、2021年8月にパスワード認証が終了し、代わりにアクセストークンを使用しなければならなくなりました。
当時は調べて対応しましたが、8月に設定したトークンの使用期限を迎えたのに気づかず、右往左往してしまったので自分への戒めで書きました。（テンパりすぎて数日分の作業を誤って消してしまいました...）

下記ページでアクセストークン設定方法がありますが、初心者向けに細かく書きます。

https://docs.github.com

##環境
- Mac

#GitHubでのトークン生成方法

- GitHubトップページにアクセス（ https://github.com/ ）
- 右上アイコンクリック
- 『Setting』にアクセス
- 左側メニューの下方の『Developer settings』にアクセス
- 左側メニューの下方の『Personal access tokens』にアクセス
- 『Generate new token(新しいトークンを生成する)』をクリック
- 各項目を入力
 - Note：トークンの名称。どのスコープを使用するか、作成した日付等がいいかも
 - Expiration：有効期限。有効期限なしもあるけど...GitHubさんに設定することを強くお勧めされるので90日に設定しました...
 - Select scopes：スコープを選択。　とりあえずリポジトリが使えるように『repo』のみチェック
 - 『Generate token』クリック
- 『ghp_』からはじまるアクセストークンが表示されるので<font color="Red">コピーすることを忘れずに！</font>（二度と表示されなくなります。）

#Macでのトークン再設定方法
- キーチェーンアクセスを開く（見つからない場合はSpotlightで検索）
- 『git』を検索
<img width="100%" alt="keychain" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221058/03eee505-0af4-ab3a-1f0c-428d547875eb.png">
- 『＠github.com』を選択
- 『パスワード表示』にチェックし、PCのパスワードを入力
- 　以前入力しているはずのアクセストークンが表示されるので、削除して先ほど生成した新アクセストークンを入力
- 『変更内容を保存』



これにて設定完了です。
私と同じように右往左往している方のお役に立てれば幸いです。
WindowsServer2016にOpenSSHをインストールしてみた。sshd_configファイルの中身

sshd_configファイルの中身はこんな感じだった。

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# GSSAPI options
#GSSAPIAuthentication no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem	sftp	sftp-server.exe

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
オイラ、オイラーの等式が書きたかったんだッ！(パート２）

##前書き

以前、  [オイラ、オイラーの等式が書きたかったんだッ！](https://qiita.com/takeC74/items/ef3a0d2f047bd11e2a55)を投稿したときに教えてもらった `math` 表記をつかってみたいと思った記事である。

##本題

先ずは前回同様、htmlで書いてみる。


```html:Euler.html
e<sup>iπ</sup>+1＝0
```


e<sup>iπ</sup>+1＝0

次に、`math` で書いてみる。

```mathematica:Euler.math
e^{iπ} + 1 = 0 
```


```math
e^{iπ} + 1 = 0 
```


**おおお～っ美しい！！**


##後書き

参考にした記事はコチラ。Markdownって楽しいですね。

https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada


https://qiita.com/Qiita/items/c686397e4a0f4f11683d


へぇ、こんな書き方もあるんだ。

:::note info
インフォメーション
infoは省略可能です。
:::

:::note warn
警告
○○に注意してください。
:::

:::note alert
より強い警告
○○しないでください。
:::

以上、皆様の参考になれば幸いです。
linuxサーバ上に簡易httpsサーバをたてる

先日、javascriptのgetUserMediaメソッドの調査のため以下のようなhtmlをcentos7上で作成し、pythonのhttp.serverモジュールで起動した簡易httpサーバー経由でアクセスしてみたのですが、「navigator.mediaDevices is undefined」エラーが出て正常に動作しません。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <!-- マイクの入力をそのまま返すだけのプログラム -->
  <script>
    navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => {
      const audioelm = document.createElement('audio');
      audioelm.autoplay = true;
      audioelm.srcObject = stream;
    });
  </script>
</body>
</html>
```

結局、[こちら](https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia#privacy_and_security)に書かれている通り、

- プロトコルがhttps
- hostがlocalhost
- htmlファイルをブラウザで直接開く

のいずれかでなければgetUserMediaが使えないということが原因でした。
htmlファイルを直接ブラウザで開いて作業続行でも事足りたのですが、せっかくの機会なので簡単な簡易httpsサーバーのたてかたを調べて簡易httpsサーバー経由でアクセスするようにしてみました。

# 私が考える一番簡単な簡易httpsサーバーのたてかた

## 必要なもの

- opensslコマンド


## 手順

簡易httpsサーバー用のオレオレ証明書を作成後、オレオレ証明書を使ってサーバー起動という流れになります。

### 1. オレオレ証明書の作成

```bash:1.1オレオレ証明書用秘密鍵の作成
[ssh_admin@localhost audio]$ openssl genrsa -out oreore-private.key 2048
Generating RSA private key, 2048 bit long modulus
...............+++
........................................................+++
e is 65537 (0x10001)
```

```bash:1.2オレオレ証明書用CSR(証明書署名要求)の作成
$ openssl req -new -key oreore-private.key -out oreore.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Hokkaido
Locality Name (eg, city) [Default City]:Sapporo
Organization Name (eg, company) [Default Company Ltd]:bitstar Inc.
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:oreore.server
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

```bash:1.3オレオレ証明書の作成
$ openssl x509 -req -days 3650 -in oreore.csr -signkey oreore-private.key -out oreore.crt
Signature ok
subject=/C=JP/ST=Hokkaido/L=Sapporo/O=bitstar Inc./CN=oreore.server
Getting Private key
```

### 2. オレオレ証明書を使って8443ポートでhttpsサーバー起動

```bash:簡易httpsサーバー起動
$ openssl s_server -cert oreore.crt -key oreore-private.key -accept 8443 -WWW
Using default temp DH parameters
ACCEPT
```

簡易httpsサーバーなので、アクセス時はindex.htmlファイルでも

> https\://oreore.server:8443/index.html

と明示する必要があります。

これより簡単な方法をご存じの方はぜひ教えてください。

今回、いろいろ調べていた中で、@kunichikoさんの[こちら](https://qiita.com/kunichiko/items/12cbccaadcbf41c72735)の記事に出会ったのですが、SSL証明書関連のファイルについてわかりやすく書かれていてとてもためになりました。
SSL証明書関連の業務に携わるかたでお読みになっていない方にはご一読をおすすめします。
AWS リファレンスメモ

# 背景・目的
いつも、探せなくなるのでメモします。

# 一覧
## 権限など
- [サービス認証リファレンス](https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html)

# 最後に
随時更新します。
Mozilla とは

## 勉強前イメージ

httpのアクセスログとかでよく見るイメージ・・・

## 調査

### Mozilla とは

Netscape Communications社がブラウザの大手だった時代の資産を受け継いで
オープンソースのwebブラウザの開発などを行うアメリカの非営利団体、Mozilla Foundationを指すことが多く、
Mozillaの商標の管理や Mozilla Firefox、Mozilla Thunderbird などのオープンソースのソフトウェアの
開発プロジェクトの統括を行っている。

### 歴史

元々は、MozillaというNetscape社がwebブラウザを発売する前に開発コード名にしたもので、
Netscape社のマスコットとゴジラをかけ合わせたものであるとの発言があった。

Netscape社のブラウザは Netscape Navigator という名称で発売されたが、
名残としてUserAgentに Mozilla/5.0 という文字列が残っており、
互換性のためほとんどのwebブラウザのUserAgentに Mozilla が含まれている。

IEとの競争に負けブラウザ事業から撤退の後、非営利団体のMozilla Organization にソフトウェア資産を移管。
プログラムのソースコードは独自のライセンスの元でオープンソースとして公開されており、現在はボランティアの開発者によって開発が続けられている。
その開発されているのが、ブラウザのFirefoxや メールクライアントの サンダーバード になります。

## 勉強後イメージ

Mozillaよく見るし、localに立てたテキトーなwebサーバのアクセスログ見ても
`"Mozilla/5.0` ってあるの、あれ互換性のためだったのね？
てかfirefoxってそういう経緯で出来てるのも知らなかったし、
firefoxとサンダーバードって同じ団体のアプリケーションなのも知らなかった
別に知ったからといってなにかあるわけではないけど、なんかスッキリしたw

## 参考

- [Mozilla](https://e-words.jp/w/Mozilla.html)
3-3.1 HTML演習

# 1. HTMLの基本形

1. 下記のHTMLの基本形をコピペせず、打ち込んでみてください。
2. 1.同様に打ち込みますが、1行1行どういうタグなのか考えながら打ち込んでみてください。(分からない箇所は調べてみてください。)

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>タイトル</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div>ボディー部です。</div>
  </body>
</html>
```

# 2. radio

以下をHTMLで表現してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/44994615-da73-126c-a0b1-d4f11fbce0b2.png)

# 3.table

以下をHTMLで表現してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1888749/a61debac-90e4-290b-5f24-055f30783399.png)

<!--
```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>タイトル</title>
  </head>
  <body>
    <h1>演習２</h1>
    <p>
      お問い合わせは？
      <input type="radio" name="rdo" value="はじめて" />はじめて
      <input type="radio" name="rdo" value="２回目" />２回目
      <input type="radio" name="rdo" value="３回以上" />３回以上
    </p>
    <hr />
    <h1>演習３</h1>
    <br />
    <table border="1">
      <tr>
        <th>都道府県</th>
        <th>面積</th>
        <th>人口</th>
      </tr>
      <tr>
        <td>東京都</td>
        <td>2,193km2</td>
        <td>13,742,906人</td>
      </tr>
      <tr>
        <td>大阪府</td>
        <td>1,905km2</td>
        <td>8,831,642人</td>
      </tr>
    </table>
  </body>
</html>
```
-->
compose.service.BuildError: (<Service: db>, {'message': 'Cannot locate specified Dockerfile: Dockerfile'}) の対処法

#背景
Docker-compose を使用してコンテナ環境を作成しようとしていました。

ディレクトリ構造は以下の通りです。

```
tree
.
├── Gemfile
├── Gemfile.lock
├── entrypoint.sh
├── docker-compose.yml
├── rails
|   └── Dockerfile
├── mysql
└── nginx				
		
```


#問題
docker-compose run app rails new . --force --database=mysql --skip-bundle を実行したところ以下のエラーが発生しました。


```
Creating network "docker_rails_default" with the default driver
Building db

Traceback (most recent call last):
  File "compose/cli/main.py", line 81, in main
  File "compose/cli/main.py", line 202, in perform_command
  File "compose/metrics/decorator.py", line 18, in wrapper
  File "compose/cli/main.py", line 967, in run
  File "compose/cli/main.py", line 1428, in run_one_off_container
  File "compose/project.py", line 671, in up
  File "compose/service.py", line 365, in ensure_image_exists
  File "compose/service.py", line 1171, in build
compose.service.BuildError: (<Service: db>, {'message': 'Cannot locate specified Dockerfile: Dockerfile'})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 92, in main
TypeError: can only concatenate str (not "dict") to str
[25377] Failed to execute script docker-compose
```

#原因
Cannot locate specified Dockerfile　とエラー文に記載があるので、Dockerfile がないことが原因のようです。
mysql nginx ディレクトリ以下にDockerfile がありません。

#対処法
mysql nginx ディレクトリ以下にDockerfile をそれぞれ作成しました。
その後、再度 docker-compose run app rails new . --force --database=mysql --skip-bundle を実行したところうまくできました。
【JavaScript】関数とオブジェクト⑤　bindとthis


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/e8798dbf47ddf02c7577

#目的

* 関数とオブジェクトについての理解を深める

#本題
###1.前回のおさらい

````javascript
window.name = 'John';

const person = {
    name: 'Tom',
    hello: function() {
        console.log('Hello ' + this.name);
    }
}

person.hello();


function fn(ref){
    ref();
}
// personのhelloメソッドをコールバック関数として渡した際に
// refを実行した際のthisのオブジェクト先がwindowオブジェクトになった
fn(person.hello); 

// personのhelloの参照先がrefに格納されているためrefでは関数が実行されているとみなされる
// => グローバルオブジェクトを参照する
``````

###2.bind

**this**や**引数**を固定した新しい関数を作成できる。
=> bindによるthisの束縛

####例1

上記のrefの実行により,Hello Tomを出力するにはどうすればいいのか

````javascript
window.name = 'John';

const person = {
    name: 'Tom',
    hello: function() {
        console.log('Hello ' + this.name);
    }
}

// 変数helloTomを定義する
// bindの第一引数で渡したオブジェクト(person)を
// helloの中で実行されるthisの参照先として設定し,
// その設定をhelloTomに入れる
const helloTom = person.hello.bind(person);
// 第一引数で指定したオブジェクトをthisの参照先に限定、縛る

function fn(ref){
    ref();
}
// コールバック関数として実行
fn(helloTom);
``````

####例2
より簡単な例

````javascript
const person = {
    name: 'Tom',
    hello: function() {
        console.log('Hello ' + this.name);
    }
}

function a(){
    console.log("hello " + this.name);
}
// bindの第一引数をaのオブジェクト内のthisに限定し、bに返却
const b = a.bind({name: "太郎"});
// これもいけた
const c = a.bind(person);
// 実行
b();
c();
`````
####例3

bindではthisだけでなく引数も固定することができる

`````javascript
const person = {
    name: 'Tom',
    hello: function() {
        console.log('Hello ' + this.name);
    }
}
// 引数にnameを入れる（中身のthisを削除した）
function a(name){
    console.log("hello " + name);
}
// 関数内でthisが使用されていないので,第一引数は必要ない => nullとしておく
// 第２引数として関数の引数を渡すことでbindをかけられる
const b = a.bind(null, "次郎");
// 「hello 次郎」と出力
b();
// もし、bに引数を渡したとしてもbindが優先される
b("三郎");
``````
`````実行結果.
hello 次郎
hello 次郎
``````






今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
psqlコマンドメモ

# 背景と目的
忘れがちなのでpsqlコマンドをメモします。

# コマンド
## 接続
```
psql -h XXXX -p 5432 -d hogehoge -U fugafuga12345
```

- -h エンドポイント
- -p ポート番号
- -U ユーザID


# 最後に
都度、更新する予定です。
HTTPS の証明書を削除する

HTTPS の証明書をなくしてあるツールの HTTPS の証明書確認プロセスが失敗する方法を検証する必要があったときのメモです
検証には `git` を使っています

# 環境

+ Linux(AmazonLinux2)
+ Windows(Windows Server2019)

# Linux(AmazonLinux2)

[SSL Certificate Location on UNIX/Linux](https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux)

上記を参考に、以下を削除

```
rm  /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
rm  /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
```

これで `git` が失敗する。

```
$git clone https://github.com/toshihirock/node-elb-log-parser.git
Cloning into 'node-elb-log-parser'...
fatal: unable to access 'https://github.com/toshihirock/node-elb-log-parser.git/': error setting certificate verify locations:  CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none
```

`/etc/pki/tls/certs/ca-bundle.crt` がないとのことで失敗。
OK。

`git config --global http.sslVerify false` コマンドを実行して SSL verify しないようにして再度実施。

```
$git config --global http.sslVerify false
$git clone https://github.com/toshihirock/node-elb-log-parser.git
Cloning into 'node-elb-log-parser'...
remote: Enumerating objects: 55, done.
remote: Total 55 (delta 0), reused 0 (delta 0), pack-reused 55
Receiving objects: 100% (55/55), 8.87 KiB | 4.43 MiB/s, done.
Resolving deltas: 100% (26/26), done.
```

この設定をすれば `git clone` は成功

# Windows(Windows Server2019)

以下を参考に `certmgr.msc` の証明書をすべて削除したが、だめだった

[Windows PCに追加した証明書の削除 (Windows Tips)](https://www.ipentec.com/document/windows-delete-certification)

今回検証したいのが `git` だったため、`git` 配下にあるファイルを削除した。
より具体的には ` C:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt` をリネームした。

「Linux(AmazonLinux2)」と同じようにデフォルトでは失敗し、`git config --global http.sslVerify false` によってクローンできた。
Flutter: 子widgetに親widgetの関数を渡す方法

##今回のトピック
今回はStatefullWidget(PageまたScreen)でvoid関数を自分で作った子のwidgetに渡す方法を紹介します。

##関数を渡したいケース
以下を子のwidgetで使った場合
e.g
- inkwell
- GestureDirection

###子のwidget（カスタムボタン）
```dart
class CustomButton extends StatelessWidget {
  const CustomButton({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: (){
           //ここで親の関数を呼びたい
        },
        child: Container(
      child: Text("CustomButton",),)
    );
  }
}
```

###親のwidget(スクリーンまたページ)
```dart
class CustomButtonScreen extends StatefulWidget {
  const CustomButtonScreen({Key? key}) : super(key: key);

  @override
  _CustomButtonScreenState createState() => _CustomButtonScreenState();
}

class _CustomButtonScreenState extends State<CustomButtonScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomButton(
          //ここでCustomButtonのGestureDetectorのonTapを使いたい
        )
      ),
    );
  }
}

```

##解決策(VoidCallback)
解決策はVoidCallBackを子のwidgetのフィールドに持ってくる

```dart

class CustomButton extends StatelessWidget {
  final VoidCallback onTap;//ここにVoidCallback
  const CustomButton({Key? key, required this.onTap}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,//ここで親のwidget(Screen)の関数が呼ばれる
        child: Container(
      child: Text("CustomButton",),)
    );
  }
}

```
###親のwidgetからこのwidgetに関数を渡す

```dart

class CustomButtonScreen extends StatefulWidget {
  const CustomButtonScreen({Key? key}) : super(key: key);

  @override
  _CustomButtonScreenState createState() => _CustomButtonScreenState();
}

class _CustomButtonScreenState extends State<CustomButtonScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomButton(
          onTap: () {
            print("Hit");//子のonTapにこのvoid関数が渡される
          },
        )
      ),
    );
  }
}

```
脱ExcelしたいMarkdownテンプレート目次

「Markdownテンプレート」シリーズの目次です。

## Markdownで全ての社内文書

https://qiita.com/e99h2121/items/28fd575b18bdf41b60dd


### GitHub Flavored Markdown推し

https://qiita.com/tk0miya/items/6b81e0e4563199037018

https://qiita.com/zr_tex8r/items/0c02ee2cba92c635c7c5

### 段落

https://qiita.com/zr_tex8r/items/95822fb19bee698c0f17

https://qiita.com/zr_tex8r/items/511662d8d79e9afabe86


## Markdownで設計

https://qiita.com/e99h2121/items/d690ea1fb7e9f9eb9ad4

https://qiita.com/e99h2121/items/d1b15b54719da76ffad1

https://qiita.com/e99h2121/items/2700337c9750568fec0a

https://qiita.com/e99h2121/items/f508ef4c9743b8fc9f5b

https://qiita.com/e99h2121/items/7016aecc131299d481e6

https://qiita.com/e99h2121/items/eaca084ae7b0488ab686

## Markdownでリリースノート

https://qiita.com/e99h2121/items/bd26841072627957c199

## Markdownで報告書

https://qiita.com/e99h2121/items/468495374cf4a10e595a

## Markdownで職務経歴書

https://qiita.com/e99h2121/items/a3763dc9fd3a4e530684

## Markdownでスライド

https://qiita.com/e99h2121/items/de4a7aa2409b54e42817

https://qiita.com/e99h2121/items/79db6b7375ccbf3d3977

https://qiita.com/e99h2121/items/a115f8865a0dc21bb462

https://qiita.com/e99h2121/items/826a46dbf8464f435eee

https://qiita.com/e99h2121/items/aa3c41b2e180f8468cbe


## Markdownで会議

https://qiita.com/e99h2121/items/190de25a79701baa4122

## Markdownで校正

https://qiita.com/e99h2121/items/2b7aaa1625db2785d3bd

## 終わりに  

https://qiita.com/e99h2121/items/ef194c4fec579ec2c11c

以上、各記事が参考になれば幸いです。
[ECS] ecs-cli基本

## インストール

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_CLI_installation.html

```bash
sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
```

```
ecs-cli --version
ecs-cli version 1.21.0 (bb0b8f0)
```

## 基礎

### cluster-config設定

```bash
ecs-cli configure --cluster ec2-tutorial --default-launch-type EC2 --config-name ec2-tutorial --region ap-northeast-1
```

`~/.ecs/config`に保存される

### ecs profileの設定

```bash
ecs-cli configure profile --access-key xxxx --secret-key xxxxx --profile-name <ecs_profile名>
```

`~/.ecs/credentials`に保存される

### Up

クラスタ作成

```bash
ecs-cli up --keypair id_rsa --capability-iam --size 1 --instance-type t2.medium --cluster-config ec2-tutorial --ecs-profile <ecs_profile>
```

### Down

クラスタ削除

```bash
ecs-cli down --force --cluster-config ec2-tutorial --ecs-profile <aws_profile>
INFO[0000] Waiting for your cluster resources to be deleted... 
INFO[0000] Cloudformation stack status                   stackStatus=DELETE_IN_PROGRESS
INFO[0031] Deleted cluster                               cluster=ec2-tutorial
```

## Up コマンド詳細

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/cmd-ecs-cli-up.html

```bash
ecs-cli up [--capability-iam | --instance-role instance-profile-name] [--keypair keypair_name] [--size n] [--azs availability_zone_1,availability_zone_2] [--security-group security_group_id[,security_group_id[,...]]] [--cidr ip_range] [--port port_number] [--subnets subnet_1,subnet_2] [--vpc vpc_id] [--extra-user-data string] [--instance-type instance_type] [--image-id ami_id] [--launch-type launch_type] [--no-associate-public-ip-address] [--force] [--tags key1=value1,key2=value2] [--cluster cluster_name] [--region region] [--empty] [--verbose] [--help]
```

### 例

- vpc指定
- 3つaz指定
- 3つのsubnet指定


```bash
ecs-cli up \
  --capability-iam \
  --size 1 \
  --tags Environment=dev,Name=dev-ecs
  --instance-type t2.medium \
  --cluster-config ec2-tutorial \
  --vpc vpc-xxx \
  --subnets subnet-xxxx,subnet-xxx,subnet-xxx \
  --ecs-profile <profile>
```
Linuxのプロセスの管理

Linuxは、多数のプロセスを同時に動作させる事が出来るマルチタスク環境を実現してる。
psコマンドやtopコマンドを実行しプロセスのリストを取得すると多数のプロセスが実行中である事がわかる。 
これらのプロセス全てが同時に平行して動作しているように見える。 

しかしながら、１つのプロセッサは同時に複数のプログラムを実行する事が出来ない。

マルチタスクをサポートするOSでは複数のプロセスを非常に短い時間ずつ切り替えながら実行する事で、あたかも同時に実行されているかのようなふるまいを見せている。
実際には、1つのプログラムしか実行されていない。



https://syuu1228.github.io/process_management_and_process_schedule/process_management_and_process_schedule.html
DB設計の基本

概念設計、論理設計、物理設計と順を追って行っていく。

概念設計

主にどのようなデータ（エンティティ）が必要になるのかなど、インタビューをしながら明らかにしていきながら、エンティティの関係を決める。
その時に用いられるのがER図（Entity Relation Diagram）

主な作業

* エンティティの抽出
* 属性の抽出
* 識別子の検討
* リレーションシップの検討
* 正規化
* 重要項目、導出項目の扱いを決める
* ドメインを考える
SQLServer: インデックスチューニングの効果検証をprd環境で事前に試す方法

#背景
クエリチューニングのためにインデックスを新規作成することは定期的にあるかと思いますが、スペックおよびデータ量が同等のdev/stg環境が無い限り、ある程度は「リリースしてみないと効果が分からない」を受け入れざるを得ないと思います。
そんな時に、prd環境でインデックスチューニングの効果検証をリリース前に実施する方法をご紹介します。
なお、完璧な精度で事前検証できるわけではありません。

###チューニング対象クエリ

以下のクエリが重く、table1のcol1にインデックスを作成すれば良いのでは、と考えているとします。

```sql
select *
from table1 a
join table2 b on a.pk = b.fk
where a.col1 = 1
```

#検証方法
tempdbを使います。

インデックスを作成したいテーブル（table1）と同じ内容のテーブルをtempdbに作成します。

```sql
create table #table1 (pk bigint primary key colustered, col1 int)

insert into #table1
select pk, col1 from #table1
```

そして一時テーブルにインデックスを作成します。

```sql
create index ix_#table1 on #table1 (col1)
```

あとは元のクエリのテーブルを一時テーブルに置き換えてパフォーマンス検証します。

```sql
select *
from #table1 a
join table2 b on a.pk = b.fk
where a.col1 = 1
```

###メリット
db_datareaderロールにしか所属していなくても（＝読み取りしかできなくても）、一時テーブルの作成と、一時テーブルへのインデックス作成は可能なので、prd環境でありながらユーザーDBのデータファイルに一切変化を加えることなくある程度確度の高い事前検証を実施できます。

###注意事項
tempdbのサイズと、作ろうとしているテーブルのサイズを事前に把握したうえで、tempdbサイズに余裕があることを確認してから実施します。

以上、小技的なテクニックですがインデックスチューニングの効果検証を事前に実施する方法をご紹介しました。
チューニング対象クエリが複雑でインデックス作成による効果が予測し辛い場合に、特に効果を発揮すると思います。
【ちょっと楽】Linuxコマンド集

#Linuxコマンド入力をちょっと楽にする
プログラミング学習をしていく中で、Linuxコマンドを扱うことは必須です。
事あるごとに入力をしていきます。
「同じ入力億劫だな。。」「ターミナルが文字だらけだからすっきりさせたい！」などと思ったことが何度もありました。
特に個人的には、フォルダ・ファイル移動の際に、「はて？なんてファイル名だっけ？？」というド忘れ現象が多々起こりました。
今回は、私が教えていただいて便利だった入力方法をご紹介することで初学者の方に便利に使っていただけたら嬉しく思います。

##それでは本題

####「↑」ボタン
過去に実行したコマンドが新しい順に出てきます。行きすぎたら「 ↓　」押してください。
ローカルホストの再起動のとき、「 control + C 」からの「 ↑ 」がめちゃ便利です！

####clear
表示されている文字を一掃してくれます！（今までの処理は消えない）
カーソルが上段に移動してさっぱりします！

####cd Tabキー
cdコマンドの後にTabキーを押すことで、次に行けるフォルダやファイルを選ぶことができます。Tabキーを押すごとに１つずつ移動できます。
ちなみに頭文字を入力してTabキーを押すと該当するものに絞れます！

####cd ..
１つ前の階層に戻れます。

####control + A
コマンドラインの先頭に移動します。
コピペしたコマンドをちょっと変更したいときなど便利です。

####control + E
コマンドラインの最後に移動します。

##おまけ
railsにおいての開発で、「localhost:3000」だけでは足りないとき（複数開発を行なっているとき）
####rails s -p 3100
localhost:3100で使えます。数字の部分はポート番号といいます。
ポート番号は、3001でも3200などでも大丈夫です！
こちらは、重複して学習しているときや、見本サイトの挙動確認をしながらコードを書きたいときに便利でした。


以上となります。
私は、上記を使うだけでもだいぶターミナル操作が楽になりました。
ありがとうございました！
python で Pillow（PIL）を扱う実行ファイルを作る際のエラーについて

#はじめに
Pillow を利用した実行ファイルを生成する際に出たエラーとその対処法について書いておこうと思います．

#やりたいこと
Pillow を利用したコードについて，Pyinstaller を用いて実行ファイルを生成します．

#問題点
import PIL を行い PIL.Image 関数を利用しようとすると，開発環境上では上手く実行できたのですが，Pyinstaller を利用して生成した実行ファイルを使うと プログラムが停止します．
新しいバージョンの Python だと Pillow はデフォルトで入っているようですが， Pyinstaller と Numpy の互換性の問題があり，Pyinstaller やその他のモジュールは古いバージョンを利用しているため手動で入れる必要があります．

#流れ
そこで私の行った対処についてまとめておきます．内容はあまりまとまっていないですし，細かな検証も行っていません．私の行った対処と動いた環境だけまとめておきます．
まず，普段通り pyinstaller (ファイル名).py --clean --noconsole --onefile によって生成した実行ファイルを起動すると，途中でプログラムが停止しました．
そこで，エラー内容を確認するためにコンソール表示するため， pyinstaller (ファイル名).py --onefile を実行しました．すると，AttributeError: module 'PIL' has no attribute 'Image' というエラーが出ました．（エラーの内容はもう少し長い）
もしかしたら Pillow のバージョンの問題かなと思い，他のモジュールと同時期辺りに利用されていたバージョンにダウングレードしましたが，上手く動きませんでした．
そこで，今度はモジュールのインポート文を import PIL.Image という書き方にかえ，内容も import PIL.Image as PillowImage へ変更しました．しかし，今度も開発環境では上手くいくのですが，Pyinstaller によるファイル生成時に Cannot find existing PyQt5 plugin directories というエラーが出ました．
そこで，下記リンクを参考にディレクトリを作り，pyinstaller (ファイル名).py --clean --noconsole --onefile --hidden-import="PIL.Image" のコマンドを利用して実行ファイルを生成したところ正しく動作するようになりました．
https://qiita.com/tatsuruM/items/cd657f25022c93d0284f


#環境

pillow は anaconda で提供されていないので pip install を利用する必要があります．

#利用したPython
```
Python = 3.7.10
```

#パッケージの管理
```
pip install Pyinstaller==3.4 (記事作成時の最新版は 4.3)
pip install pytoshop (記事作成時の最新版は 1.2.1)
pip install opencv-python==4.0.1.24 (記事作成時の最新版は 4.5.2.54)
pip install mkl==2018.0.0 (記事作成時の最新版は 2021.3.0)
pip install six (記事作成時の最新版は 1.16.0)
pip install pytoshop (記事作成時の最新版は 1.2.1)
pip install pillow==7.2.0 (記事作成時の最新版は 8.4.0)
```
これ以外に含まれているモジュールは，全て以前書いた記事と同様です．
https://qiita.com/bellvine/items/d42b05c3cbdd823dc77a
phpのインターフェースとは

#phpのインターフェースとは
インターフェースとは、クラスがメソッド持っていることを定義するオブジェクト指向の仕組み。
インターフェース ≒ 抽象クラスである

##抽象クラスと具象クラス
***具象クラス***
具象という単語が意味する通り処理を記述したメソッドの集まり。
・<font color="LimeGreen">メソッド</font>の中身が記述されている
・<font color="LimeGreen">インスタンス化</font>して使用できるクラス

***抽象クラス***
インターフェースと通常のクラスの中間のようなクラスで、処理の記述がないメソッドを１つ以上持つクラスのこと。
抽象クラスだけでは意味を持たず、サブクラスに継承されることで初めて機能する。
・<font color="LimeGreen">メソッド</font>の中身が記述されていない
・直接<font color="LimeGreen">インスタンス化</font>できない
・多重継承できない
・<font color="LimeGreen">インスタンス化</font>するには、抽象クラスを継承した具象クラスですべての抽象クラスを<font color="LimeGreen">オーバーライド</font>する必要がある
・サブクラスで<font color="LimeGreen">コンストラクタ</font>を記述しなければならない


##インターフェースのメリット
最大のメリットは、継承関係に縛られることなく、複数のクラスに共通の仕様と資格（似たような処理を一つのグループにまとめる）を与えることができる点。
→インターフェースを実装したクラスには定義してある抽象メソッドに対して実装されたメソッドが必ず存在する
→どんなクラスなのか、ソースを追う必要がなくなる。

***→クラスではなく、インターフェースを依存させることで、インターフェースを継承したクラスならどれでも依存させることができる。（呼び出す際に使いたいクラスを呼び出す必要あり）***
→クラス通しが疎結合になる

##インターフェースの定義
・定義可能なのは抽象メソッド（処理の技術がない）だけ
・アクセス修飾子には「public」しか指定できない
・直接インスタンスの生成は不可能
M1 MacによるDocker開発環境構築エラー

# 前提環境
- macOS BigSur v11.6
- MacBook Pro(Apple M1)
- docker compose v3.7

# 概要
- M1 MacBook 環境でdockerの起動を行なったところ`no matching manifest for linux/arm64/v8 in the manifest list entries
`が発生した
- 原因はdockerのimageがまだARMプロセッサに対応していないことだった
- dockerのデフォルト設定では起動したPC環境を踏襲した仮想環境を構築してしまう。
- つまり、M1 MacBookの環境で作られる仮想環境はARMで動くことになってしまう。

# 解決策
- dockerのplatform設定にて、**linux/amd64**を明示的に指定する
- これによりintelx86-64プロセッサの環境で動くこととなる

# 現象

- 実案件とは全く違うqiita用の記述ですが、docker-compose.ymlにてmysql環境を構築する記述を作成しました。
- 下記定義をM1 MacBookでビルドすると、仮想環境もARMプロセッサとして構築されます。

```yml
version: '3.7'
services:
  test_mysql:
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_DATABASE: test
      MYSQL_ROOT_PASSWORD: password
      TZ: 'Asia/Tokyo'
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    ports:
      - 3306:3306
```
- こちらのファイルでdocker compose up実行すると下記のようなエラーが発生します。
- これはどうやら、mysql5.7のdockerイメージがARMプロセッサに対応していないためのようです。

```
no matching manifest for linux/arm64/v8 in the manifest list entries
```

# 対応
- 下記のように`platform: 'linux/amd64'`という定義を追加しただけです。
- これによりPCの環境によらず、仮想環境では`intelx86-64`でビルドすることができます。
- この記述でdocker compose upをすると、正常に起動できるはずです。

```yml
version: '3.7'
services:
  test_mysql:
    platform: 'linux/amd64'
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_DATABASE: test
      MYSQL_ROOT_PASSWORD: password
      TZ: 'Asia/Tokyo'
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    ports:
      - 3306:3306
```

# 余談
- 今回はdokcer-compose.ymlの場合でしたが、Dockerfileを使った仮想環境構築でも同様の事象が発生します。
- その場合は`docker build --platform linux/amd64`というようにオプションをつけてビルドすることで明示的にプロセッサの指定を行うことができます。
【Python】XMLのデータを読む

# はじめに

今日はXMLのデータをpython script で読むためのメモです。本当にただのメモ。

# 内容

標準ライブラリを使ってできます。

https://docs.python.org/ja/3/library/xml.etree.elementtree.html

なのですが、とりあえず動かしてみたメモを。

## 例

全くXMLを分かっていないのですが、```xml.etree.ElementTree``` というのを使えばできるようです。

- 木構造のデータを fromstring で読み込める。
- root も child もtag と attribute を持っていて、.tag, .attrib でアクセスできる
- 値？は .text で参照できる。

iterator でアクセスする場合もあるけれど、今回は下記の単純なサンプルなので必要なった。

```Python
xml_string = \
"""<?xml version="1.0" encoding="UTF-8"?>
<calibration>
  <projection>frame</projection>
  <width>5456</width>
  <height>3632</height>
  <f>3683.29</f>
  <cx>-5.730</cx>
  <cy>-38.810</cy>
  <date>2010-01-01T12:23:12Z</date>
</calibration>
"""

import xml.etree.ElementTree as ET
root = ET.fromstring(xml_string)
print( f"root={root}")
print(f"root.tag={root.tag} .attrib={root.attrib} .text={root.text}")

for child in root:
    print(f"child.tag={child.tag} .attrib={child.attrib} .text={child.text}")

```

実行結果

```
$ python3 test_xml_string_parse.py 
root=<Element 'calibration' at 0x7f326cb487c0>
root.tag=calibration .attrib={} .text=

child.tag=projection .attrib={} .text=frame
child.tag=width .attrib={} .text=5456
child.tag=height .attrib={} .text=3632
child.tag=f .attrib={} .text=3683.29
child.tag=cx .attrib={} .text=-5.730
child.tag=cy .attrib={} .text=-38.810
child.tag=date .attrib={} .text=2010-01-01T12:23:12Z
```

何の面白味もないが、読み込めたのは確認できた。
root からiterate 可能な要素として読んでいるので、番号のインデックスでもアクセスできます。

```
In [10]: root[1].text
Out[10]: '5456'
```

また、ファイルから直接に読むこともできます。

```xml:mydata.xml
<?xml version="1.0" encoding="UTF-8"?>
<calibration>
  <projection>frame</projection>
  <width>5456</width>
  <height>3632</height>
  <f>3683.29</f>
  <cx>-5.730</cx>
  <cy>-38.810</cy>
  <date>2010-01-01T12:23:12Z</date>
</calibration>
```
というファイルを、

```Python
tree = ET.parse('mydata.xml')
root = tree.getroot()
```

と読みます。

# まとめ

今回、ただ読めただけなのだが、それ以上なし。
何かあればメモを足していきます。明日の仕事もこれでできそうな気がしています。
javascript演習　5日目/３０日

覚えたこと

cssのflex
flex-grow:伸びる率（デフォルト0）
flex-shrink:縮む率（デフォルト1）

```css
displat:flex;
/*  flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;
```


いつものようにスクリプトでクラスをつけて動かす

```javascript
function toggleActive(e){
  if(e.propertyName.includes('flex')){
    this.classList.toggle('open-active');
  }
}

panels.forEach(panel => panel.addEventListener('transitionend' , toggleActive))

```
windows10 HomeとRyzen5でDocker Desktopを入れた話

何も考えず普通に入れたらエラーが出たので忘備録として残します。
過不足や問題等あるかもしれません。

# スペック
OS: Windows 10
CPU: Ryzen5 3500
M/B: X570S Torpedo Max
Docker Desktopのバージョン: 4.1.1

# やったこと
##公式よりインストーラをダウンロードしてインストール
すると
`hardware assisted virtualization and data execution protection must be enabled in the bios.`
なるエラーが発生する

###解決のためにやったこと
下記の2つを実行
1. 'Windowsの機能の有効化または無効化'より、'Windowsハイパーバイザープラットフォーム'を有効化して再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2194329/e99f0c71-43d0-d219-fffb-00497be147ff.png)
2. BIOS画面より、'SVM Mode'を有効化する
![MSI_SnapShot_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2194329/79443e45-7d10-c132-fafa-9a4f2ef2a963.png)
![MSI_SnapShot_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2194329/dd6ac65c-6101-b3d4-3d97-c6acf8739951.png)
ここを有効にした

##そうするとまた別のエラーが発生する
`WSL 2 installation is incomplete`
なるエラーが発生する

###解決にためにやったこと
https://docs.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package
上記リンクの'x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ'をクリックして実行
そのままインストールして再起動

##Docker Desktopを起動
正常に起動できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2194329/3bc548d0-81dd-9f16-f02a-381f65977843.png)

参考になれば幸いです。
HTTPメソッドまとめ

#はじめに
HTTPメソッドについて、以下の書籍を参考に学習したことをメモしました。

https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042

#そもそもHTTP(HypertextTransferProtocol)とは
クライアントとサーバでリソース(textや画像ファイルなど)のやり取りをする上でのプロトコル(約束事)
クライアントからHTTPに従ってリクエストを送信し、サーバからレスポンスが返ってくる

#HTTPメソッドとは
httpリクエストを送信する際に記述される
どのメソッドを使うかは、サーバのリソースをどうしたいかによって変わる

##主な6つのHTTPメソッド
①GET・・・リソース取得
②POST・・・小リソース作成、リソースへデータ追加
③DELETE・・・リソース削除
④PUT・・・リソース変更、リソース作成
⑤HEAD・・・リソースヘッダ取得
⑥OPTIONS・・・リソースのサポートメソッド取得

### ①GET
![get.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/638c45ab-2123-e6f4-8bd7-3027c0a4c801.jpeg)

### ②POST
![post.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/9551d116-f20d-8c48-f921-45bbffbf579a.jpeg)

### ③DELETE
![delete.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/a450b001-8901-14f9-4736-c4cbb8f99617.jpeg)

### ④PUT
![put.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/3654be97-7560-ca85-8e92-829df765eb25.jpeg)

### ⑤HEAD
![head.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/9479ee19-2607-9ea9-b1b1-df28c3523f0a.jpeg)

### ⑥OPTION
![option.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599988/25abf73a-c42f-9a77-5975-95ace609aea1.jpeg)

# POSTとPUTの使い分けは？
POSTメソッドを使用した場合、URI(URL)をサーバが指定し、PUTの場合はクライアントが指定する。
クライアントがURIを指定する場合、プログラマがURIに対して文字制限などのチェック処理を施したり、内部構造を熟知する必要があるため、基本的にリソースの作成はPOSTで行いURIもサーバが指定するのが良い。
docker-composeでNuxt.js環境構築

Nuxt.jsはローカルにNode.jsを入れてあげれば動かすことができますが、
ローカルをできるだけ汚したくないので、***docker-compose***で動かします。

## 構成  
- Vue.js v2.6.14
- Nuxtjs v2.15.7
- コンポーネント設計
  - compositionApi
  - Nuxt.js用のプラグイン(@nuxtjs/composition-api)を使用
- TypeScript
- Vuetify(UIフレームワーク)

## 環境構築手順
### コンテナでNode.jsのバージョン確認まで
- nodeのイメージを使用する
- 作成したnodeのイメージに、yarnを用いて使用するモジュールをインストールしていく


```Dockerfile
FROM node:lts

EXPOSE 3000
ENV HOST 0.0.0.0

RUN apt-get update && \
    apt-get upgrade -y && \
    yarn global add @vue/cli && \
    yarn global add @vue/cli-init
```

```docker-compose.yml
version: '3'
  services:
    nuxt-app:
      build: .  # Dockerfileの場所
      working_dir: /src  # ホストOSとコンテナ内でソースコードを共有する
      volumes:
        - .:/src
      ports:
        - 5000:3000   # コンテナ内部の3000を外部から5000でアクセスする
      tty: true   # コンテナ起動後、StatusがExitにならないようttyの設定
```


ビルド実行

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

コンテナを起動。バックグランドで起動します。

```
docker-compose build
```

起動したコンテナにアタッチ。Node.jsのバージョンを確認

```
docker-compose exec nuxt-app bash
$ node -v
$ yarn -v
```


### Nuxt.jsの導入
Nuxt.jsの導入については、[公式]([https://nuxtjs.org/ja/docs/get-started/installation)を参考に実行しました。
yarn / npm / npxのそれぞれでプロジェクトを開始する方法が記載されています。  
今回は、yarnを使用します。  

```
yarn create nuxt-app <project-name>
```

nuxtのプロジェクト作成が始まり、何を導入するのか（packageやモジュールなど）質問されるので、必要なものを選択します。
この段階でモジュールのインストールを選択しなかったものについても、プロジェクト作成後に追加できます。
質問されるモジュールの内容と今回私が導入したものを紹介します。  

```
　・Project name
　　任意

　・package manager
　　・npm
　　・yarnを選択

　・Programing language
　　・TypeScriptを選択
　　・JavaScript

　・UI Framework
　　・Vuetify.jsを選択
　　・Tailwind　CSS
　　・その他UIフレームワーク

　・Nuxt.js modules
　　・Axios 選択
　　・Progressive Web App(PWA) 選択
　　・content(Git based headless CMS)

　・Linting tools
　　・ESLint 選択
　　・Prettier　選択
　　・StyleLint　選択

　・Testing Framework
　　・Jestを選択
　　・AVA
　　・WebdriverIO
　　・Nightwatch

　・Rendering mode
　　・Universal(SSR/SSG)を選択
　　・Single Page App(SPA)

　・Deploy target
　　・Server(Node.js hosting)
　　・Static(Static/Jamstack hosting)を選択

　・Development tool
　　・jsconfig.jsonを選択

　・Continuous integration
　　　・GitHub Actionsを選択
　　　・TravisCI
　　　・CircleCI

　・Github Name

　・Vergion controll system
　　・Gitを選択

```

### ローカルサーバを立ち上げる
Nuxtプロジェクトの作成が終了すると（結構時間がかかります。15分ほどかかった気がする）、
ローカル上でプロジェクト作成の動作確認を行います。  

```
($コンテナ内) cd <project>
($コンテナ内) yarn dev
```

### yarn devでエラーが発生
下記のエラーが発生。
今回、UIフレームワークにVuetifyを導入したのですが、Vuetifyで使用するモジュールが一部不足していたようです。  
![20210727_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2172312/abe58a26-d789-b76a-b78d-4ea009194f2e.png)


コンテナ内で

```
vue add vuetify
```

を実行し、再度

```
yarn dev
```

localhost:5000にアクセスし、以下のような画面が表示されていればプロジェクトの作成は完了です。

![20210727_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2172312/5d359850-ec15-0432-b0fd-f1b6b01e66af.png)

### @nuxtjs/composition-apiの導入
vue2系でcompositionAPIを使用するため、@nuxtjs/composition-apiモジュールの追加を行います。

```
yarn add @nuxtjs/composition-api
```
[Composition APIについて]([https://v3.ja.vuejs.org/guide/composition-api-introduction.html#composition-api-%E3%81%AE%E5%9F%BA%E6%9C%AC)

### 最後に
Docker環境が準備できれば、Nuxtを導入するときにいろんなモジュールを試せたりできそうですね。 
(この記事を書くにあたって、数回環境作りなおしましたw)
Apache Kafkaをdocker-composeで試してみる

走らせるだけで意外と調べることが多かったので、メモです。

## 参考

https://qiita.com/dublog/items/4b7f0d41a4075f794bd8

https://qiita.com/tily/items/ea212a7fe68d62e34644

## 環境

- Macbook Pro 16inch (Intel)
- Mac OS Big Sur

## 前提

- docker-composeが入っている
- dockerが入っている

## コード

まず、自分のデバイスに割り当てられたIPアドレスを取得しましょう。

```
$ ipconfig getifaddr en0
192.168.11.17
```

これを以下のdocker-compose.ymlに貼り付けます。

```
version: '3'

services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    ports:
      - "9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 192.168.11.17 # must be your IP, run `ipconfig getifaddr en0`
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

```

## 走らせてみる

```
docker-compose up
```

別のディレクトリでトピック登録

```
$ docker-compose exec kafka /opt/kafka/bin/kafka-topics.sh \
--create --zookeeper zookeeper:2181 --replication-factor 1 \
--partitions 1 --topic test
Created topic test.
```

トピックの確認

```
$ docker-compose exec kafka \
/opt/kafka/bin/kafka-topics.sh --list --zookeeper zookeeper:2181
test
```

メッセージを送信してみる

```
docker-compose exec kafka \
/opt/kafka/bin/kafka-console-producer.sh \
--broker-list kafka:9092 --topic test
>lol
>haha
```

メッセージの受信

```
docker-compose exec kafka \
/opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server kafka:9092 --topic test --from-beginning
lol
haha
```
[メモ] GitHub CLI と direnv で GitHub の複数アカウント使い分けをちょっと楽にした

## 前置き

[GitHub](https://github.com) に2つの個人アカウントを持っているのですが、これらを使い分けることにしたので忘れないうちに何をしたかをメモします。
2つ持っている経緯は忘れましたが、せっかくなので活用してやろうというのが動機です。

## Prerequisites

- GitHub CLI
    - https://github.com/cli/cli
- direnv
    - https://github.com/direnv/direnv

## 具体的に何をしたか

あるディレクトリ（ここでは `~/Directory` とします）以下でのみ別アカウントを利用することにしました。

### 別ユーザとして振る舞う

Git を利用する際、普段は `${XDG_CONFIG_HOME}/git/config` 辺りにグローバルな設定を書いていると思います。

ユーザ情報に関わる部分は `user.name` や `user.email` 辺りですね。

これらは環境変数で上書きすることができるようです。[参考](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables)

- `GIT_AUTHOR_NAME`
- `GIT_AUTHOR_EMAIL`
- `GIT_COMMITTER_NAME`
- `GIT_COMMITTER_EMAIL`

これらを `direnv` で設定してやれば、そのディレクトリ配下ではそのユーザとして振る舞うことができそうです（多分）。

### GitHub CLI で利用する別のトークンを用意する

これも GitHub CLI が読む環境変数を上書きしてやることで実現します。[参考](https://cli.github.com/manual/gh_help_environment)

- `GH_CONFIG_DIR`

これを他のアカウントで利用しているものと別の場所を見るように変更してやります。今回は `~/Directory/.gh` としました。

### 手順

1. `~/Directory` に次の `.envrc` を用意しました（適宜読み替えてください）。
1. `direnv allow`、`gh auth login` を実行し、このディレクトリ以下で利用するアカウントの認証を通しました（preferred protocol は HTTPS としました。SSH だと考えることが増えそうなのでパスです）。
1. あとは GitHub からの clone は `gh repo clone` をする感じで利用していきます。

```sh:~/Directory/.envrc
export GIT_AUTHOR_NAME=<name>
export GIT_AUTHOR_EMAIL=<e-mail>
export GIT_COMMITTER_NAME=<name>
export GIT_COMMITTER_EMAIL=<e-mail>

export GH_CONFIG_DIR=~/Directory/.gh
```

## 最後に

初め `COMMITTER` のスペルを間違えていました。MもTも2つなんですね。