OmniAICreator/Qiita-1.07M huggingface dataset:
ECS Exec

#概要#
https://dev.classmethod.jp/articles/ecs-exec/#toc-6

実行中のコンテナに乗り込んでコマンドを実行できる機能「ECS Exec」が利用可能になりました。

- これまで
 - EC2 : SSH でログインした後に docker exec コマンドを実行。
 - Fargate : そもそもできない。

- 仕組み
 - セッションマネージャーの仕組みを利用しており、これには、ECS Exec に対応済みの特定バージョン以降を利用している必要がある。⬇️

- ECS Exec に対応済みの特定バージョン
 - EC2 : ECS-optimized AMIの 2021年1月20日以降にリリースされたバージョン。
 - Fargate : Fargate のプラットフォームバージョン 1.4.0以降。

- AWS CLI （現時点では、CLIからしか行えません。）
 - AWS CLI v1 : バージョン 1.19.28 またはそれ以降
 - AWS CLI v2 ： バージョン 2.1.31 またはそれ以降

AWS CLI に加えて、Session Manager plugin をインストールする必要があります。⬇️

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html


#ECSタスクロール#

ECSタスクロールを新規作成して、下記で作成したIAMポリシーをアタッチします。

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssmmessages:CreateControlChannel",
        "ssmmessages:CreateDataChannel",
        "ssmmessages:OpenControlChannel",
        "ssmmessages:OpenDataChannel"
      ],
      "Resource": "*"
    }
  ]
}
```

#--enable-execute-command#

##サービスを新規に作成する場合##

aws ecs create-service を実行する際に `--enable-execute-command` を付与して、ECS Exec機能を有効にする必要があります。

今回は、既存のサービスを変更するので、⬇︎の通り行なってみました。

##既存のサービスを変更する場合##

```
$ aws ecs update-service \
> --cluster ecs-cluster \
> --service ecs-service \
> --enable-execute-command
        "enableExecuteCommand": true
```

なお、ECS Exec機能を無効にする場合は、`--disable-execute-command` です。

#タスクを起動する#

ECS Exec機能は `--enable-execute-command` で有効にした後に起動したタスクでのみ利用可能です。

現在起動中の既存のタスクは、⬇︎の通り、ECS Exec機能は無効（`enableExecuteCommand": false`）になっています。

```
$ aws ecs describe-tasks \
> --cluster ecs-cluster \
> --tasks 31ebca28dd044e46a6d253550e38f2b2

            "enableExecuteCommand": false,
```

--desired-count 2 にしタスクをもう一つ起動すると、新しく起動したタスクは、ECS Exec機能が有効（`enableExecuteCommand": true`） となっていることがわかります。

```
$ aws ecs update-service \
> --cluster ecs-cluster \
> --service ecs-service \
> --desired-count 2

        "desiredCount": 2,

            "enableExecuteCommand": true,
```

#execute-command#

`execute-command` で、bin/sh などを実行してみましょう。

```
$ aws ecs execute-command \
> --cluster ecs-cluster \
> --task b243e1cda7ba4212b71637ade1124c48 \
> --container ecs-conntener \
> --interactive \
> --command "bin/sh"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-0aa48e585657edbd0
```


#リンク#
[Amazon ECS](https://qiita.com/leomaro7/items/deb114e5ec209a044e5d)
【Cloud9】クラウドIDEでターミナルが動かなくなった時の対処法【AWS】

<h2>症状</h2>
Railsチュートリアルで容量が足りず、EBSボリュームを増やし、インスタンスを再起動するも、ターミナルが反応しない事象が発生しました。
ボタンを押したり、Ctrl+qなどのボタンを押しても全く反応がありませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/12ceee53-fdf4-d21a-4d6a-4020aca1b0ec.png)

<h2>解決策</h2>
変更途中で更新できず保存できなかったファイルがあり、それを保存せずにタブを閉じて、ターミナルを開きなおしたら解決しました。
容量が重くなりすぎたせいなので、ファイルのバックアップを取り、ファイルを削除するなど容量不足を一時的に解消するなどすることで解決するようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/2d7773ae-cf3f-c66e-b599-8ae6f1bea15d.png)
Vue.js~ToDoリスト~

今回はToDoリストを作っていきたいと思います。

```script.js
new Vue({
  el: '#app',
  data: {
    todo:  [
      'task1',
      'task2',
      'task3'
    ]
  }
});
```
script側からはデータというオブジェクトの中に今回繰り返すタスクを記入します。
ここで注意していただきたいのは、入れ子の構造になっているところです。また、new Vueのカッコの外のセミコロンをお忘れなく👍


```index.html
<!DOCTYPE html>
<html lang="en">
<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">
  <link rel="stylesheet" href="css/style.css">
  <title>ToDo-App</title>
</head>
<body>
  <div id="app" class="container">
    <h1>ToDo-App</h1>
    <ul>
      <li v-for="todo in todo">{{ todo }}</li>
    </ul>
    <div class="inputs">
      <input type="text">
      <input type="submit" value="UP">
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
  <script src="script/script.js"></script>
</body>
</html>
```
index.htmlに追加されているv-forですがこれは配列などのデータを繰り返して表示させたい場合に使います。

では実際にToDoを追加する実装を行っていきたいと思います。
AWS Congnito をALBで設定する方法 - リスナーのルール編集部分

## AWS Cognito をALBのリスナールールに追加する場合
AWS Cognitoを使って実装をする際に、
Cognitoのユーザープールに設定方法について解説する記事はいくつかみたのですが、
アプリケーションロードバランサーのリスナールールと連携する部分について解説する記事がないので、
記録としてあげておきたいと思います。

参考にしたもの
[Youtube User Authentication with AWS Application Load Balancer and Cognito] (https://www.youtube.com/watch?v=cAEtjMI1KcQ)
こちらはほぼ唯一のAWS CognitoとALBを使ったハンズオンの動画(英語)です。
ゼロからVPNの設定からCognitoの設定までをすべてカバーしています。


前提:
先にAWS Congnitoのユーザープールの作成、アプリクライアントの作成を行う
ネットワークの設定を行う(VPN,サブネット等)

1.EC2>ロードバランサ
- 
- ロードバランサのリスナータブを開く
- Cognitoで認証をしたいリスナーのルール>ルールの表示/編集を押下
![スクリーンショット 2021-03-23 15.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/31c046ca-bb0e-3d15-c69d-5e7d9ebdb531.png)

2． ルールの編集
- 
- IF でパスなどのターゲットの設定を行う
- THEN で"認証"を選択する ※事前にCognitoの設定をしなければ選択できない
![スクリーンショット 2021-03-23 12.12.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/f20421a0-14d9-69ff-90e4-f9717f7f2fb9.png)

2．1 パスの設定とアプリクライアント
-
- 1つのユーザープールにつき、複数のアプリクライアントを設定することができる。
- パスごとに同じユーザープール、別々のアプリクライアントを設定することで、そのパスがアクセスできる属性情報をコントロールすることもできる。
- Cognitoが提供しているログインページもアプリクライアント単位に作成されるので、パスごとに別々のログインページを設定することも可能
 

構築時に参考になった記事
-
- [ALB + Cognito認証で付与されるユーザー情報をEC2サイドから眺めてみる](https://dev.classmethod.jp/articles/http-headers-added-by-alb-and-cognito-are-explained/)

これは認証のデータがサーバーとCognitoのユーザープールでどうやりとりされているかの解説
仕組みを知りたい方向け

- [インフラエンジニアが一切コードを書かずにWebサーバーに認証機能を実装した話](https://dev.classmethod.jp/articles/alb-cognito-user-pool/)

こちらは実際にAWS CognitoとALBの設定をするのにとても参考にさせてもらった記事です。
ALBの設定は、パスによってターゲットを変更したい時/パスによってCognitoのアプリクライアントを分けたい時は「ALB>リスナー>編集」ではなく、上記こちらの記事で解説している設定が必要です。
AWS Lambda (Python 3.8)からWrikeのAPIを叩いてみる

#この記事の概要
AWS API Gatewayでリクエスト受けてLambdaを実行するという記事は結構あるのですが、逆にLambdaから他の外部APIを叩くのにサンプルがほしかったのでLabmda & Python 3.8（＆標準ライブラリ）からWrikeのAPIを叩いてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/90aaf978-d6da-eee8-9124-ee2025c738d6.png)
bearerトークンが使えるAPIが公開されているWeb serviceなら他のサービスでも流用できると思います。

#本記事の投稿者
Python＆Lambda初心者（両方とも初めて書いてみた）のでとりあえず動けばいいというレベルです。
#大まかな手順
Wrikeで永続トークンを生成し、LabmdaでPythonの関数つくって実行。

#Wrike公式APIリファレンス（英語）
https://developers.wrike.com/

#永続アクセストークンの取得
こちらの記事参照
https://note.com/katoiek/n/nf7342fd84add

#AWS Lambdaで関数の作成
今回は1から関数を作るのでAWSコンソールからLabmdaのコンソールへ移動し、新規作成をクリックし、一から作成を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/00b763cc-3d27-1488-24f1-dd5b29d3b80e.png)
アクセスロールは下記の2個を選択したものを作成もしくは既存のものを使用。1つ目はLabmdaへのアクセス、2つ目はCloud watchへのアクセス（ログ出力など）らしいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/b9631910-7490-3df5-7685-1969fd2febb1.png)
関数を作成したらタイムアウト3秒だと足りないので60秒くらいにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/35101552-897d-1d1c-5c4d-a8c1ca332a35.png)
コードをクリックして下記のコードを入力します。

```python:lambda_fucntion.py
import json
import urllib.request
from pprint import pprint

permanent_token='ここに永続トークンを入力します'
url = 'https://www.wrike.com/api/v4/tasks'
header ={ 'Authorization': 'bearer '+ permanent_token}

#HTTP methodはすべて大文字 GET, POST, PUT, DELETE
method = 'GET'

def lambda_handler(event, context):
    req=urllib.request.Request(url, headers=header,method=method)
    
    with urllib.request.urlopen(req) as res:
    # resは http.client.HTTPResponse
        body = json.loads(res.read().decode('utf8')) # レスポンスボディ
        headers = res.getheaders() # ヘッダー(dict)
        status = res.getcode() # ステータスコード
        pprint(header)
        pprint(status)
        pprint(body)
```
永続トークンのところは書き換えてください。
#Lambdaからの実行
Deployし、Testをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/aa348fed-13fe-2b07-3638-a80d685bec1f.png)
イベント名を入力（必須ですが、名前は任意）単純にGetを叩くだけなのでデータをすべて削除して作成をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/33f712ce-9c52-52dc-03c5-d81e782d8c05.png)
再度Testをクリックすると実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/eab9a867-7c2f-a463-af04-6153caa55a7f.png)
こんな感じでレスポンスがあればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/16704586-e04f-9217-8e83-6ba90d8c6888.png)
今回はシンプルにGetでデータをクエリを行いましたが、Jsonをパースしたりキャストしたりして他のSAASのAPI経由で連携といったこともできると思います。

Cronのように定期的にトリガーを引きたい場合はEventBridgeをトリガーに設定することでスケジューリングなどができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2671/a245599d-68f6-c74d-8276-d6cd7f7af0e0.png)
Lambdaは無料枠もかなり大きいですしサーバーレスの名の通り実行環境を構築しなくていいという点でAPIの運用にも便利な環境と思います。
GitHub Actionsで長いコマンドの分割にバックスラッシュは使えない

長いコマンドオプションを分割するときは、バックスラッシュではなくYAMLのfolded styleを使いましょう。

## ダメなパターン
シェルスクリプトでやるように、バックスラッシュ`\`で区切るとうまくいきません。

```yaml
steps:
  - name: Deploy
    run: rsync -avzr \
      -e "ssh -i ssh_id -p $SSH_PORT -o UserKnownHostsFile=known_hosts" \
      --delete \
      ./public/ \
      ${SSH_USER}@${SSH_HOST}:${PUBLIC_DIR}
```

ちなみに、この場合だと

```
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.3]
Error: Process completed with exit code 255.
```

のエラーが出ます。

## 動くパターン
`>`を利用したfolded styleで記述します。末尾以外の改行がスペースと解釈されます。

```yaml
steps:
  - name: Deploy
    run: >
      rsync -avzr
      -e "ssh -i ssh_id -p $SSH_PORT -o UserKnownHostsFile=known_hosts"
      --delete
      ./public/
      ${SSH_USER}@${SSH_HOST}:${PUBLIC_DIR}
```

GitHub Actions関連の記事ではバックスラッシュで区切っているものがあり、かつてはバックスラッシュの区切りでも動作していたようです。しかし、現在は有効な記法ではありません。

## 参考文献
- [yaml - Github Action: Split Long Command into Multiple Lines - Stack Overflow](https://stackoverflow.com/questions/59954185/github-action-split-long-command-into-multiple-lines)
- [YAML Multiline Strings](https://yaml-multiline.info/)
- [syntax - How do I break a string in YAML over multiple lines? - Stack Overflow](https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines)
カラム型とRubyクラス

*カラム型とRubyクラス

|migrationの型|Rubyのクラス|MySQL|PostgreSQL|
|:--|:--|:--|:--|
|integer|FixedNum|int(11)|integer|
|decimal|BigDecimal|decimal(10,0)|decimal|
|float|Float|float|float|
|boolean|TrueClass/FalseClass|tinyint(1)|boolean|
|string|String|varchar(255)|character varying|
|text|String|text|text|
|date|Date|date|date|
|datetime|ActiveSupport::TimeWithZone|datetime|timestamp|
|time|Time|time|time|
|timestamp|ActiveSupport::TimeWithZone|timestamp|timestamp|
|binary|String|blob|bytea|
Java 変数修飾子についての　簡単な説明　と　自分なりの解釈

#普段からよく目にするJavaの変数修飾子
* **public**
* **private**
* **static**
* **final**

上記4つのみ対象にしています



##public
* **簡単な説明**
どこからでもアクセス可能な変数

* **自分なりの解釈**
基本的には明示されていないもの
メンバ変数(フィールド変数)で変数宣言時に外部から参照できる理由は
省略されて見えないだけ

```java:publicについて
public class Main {	
	//明示してないがpublic
	int a;
	
	//明示してpublic
	public int b;
	
	public static void main (String[] args) {	
	}
}
```
##private
* **簡単な説明**
同一クラスからのアクセスのみ許可

* **自分なりの解釈**
**簡単な説明**の通り、同一クラスからのアクセスのみ許可するもの
外部クラスから参照したい場合は、メソッド経由(getter or setter)で参照が可能

```java:privateについて
public class Main {

	//private変数
	//メソッドを経由して外部からアクセスする
	private int privateVariable;

	//public変数
	//外部からアクセス可能
	public int publicVariable;

	public static void main (String[] args) {
	}

	//setterメソッド
	public void setPrivateVariable(int privateVariable) {
		this.privateVariable = privateVariable;
	}

	//getterメソッド
	public int gettPrivateVariable() {
		return privateVariable;
	}
```
##static
* **簡単な説明**
静的変数

* **自分なりの解釈**
クラスをインスタンス化せずに参照可能な変数。クラス名.変数名で参照可能
また、static変数に値を代入した値は他のインスタンス間でも共有できる

```java:staticについて（Subクラス）
public class Sub {

	//非スタティック変数（インスタンス変数とも呼ばれる）
	int sampleVariableA = 0;

	//スタティック変数（クラス変数とも呼ばれる）
	static int sampleVariableB = 0;

}
```
```java:staticについて（Mainクラス）
public class Main {

	public static void main (String[] args) {

		//Subクラスをインスタンス化
		Sub subA = new Sub();
		Sub subB = new Sub();

		//subAのsampleVariableA（非スタティック変数に　＋1）
		subA.sampleVariableA =subA.sampleVariableA+1;

		//1を表示
		System.out.println(subA.sampleVariableA);

		//subBのsampleVariableAには +1 していない為
		//0を表示
		System.out.println(subB.sampleVariableA);

		//sampleVariableBはインスタンス化していない
		//sampleVariableB（スタティック変数）に　＋1
		Sub.sampleVariableB = Sub.sampleVariableB+1;

		//スタティック変数は共有しているので下記の3つは全て同じく１と表示する
		System.out.println(Sub.sampleVariableB);
		System.out.println(subA.sampleVariableB);
		System.out.println(subB.sampleVariableB);
	}
```
##final
* **簡単な説明**
値の変更ができない変数

* **自分なりの解釈**
finalで宣言された変数に対しては一度だけしか値を代入することができない為、
定数として扱われる。
また、Javaの命名規則により
　すべて大文字
　複合文字の場合は区切りをアンダースコア "_" で結合。（スネークケース記法）
で宣言する

```java:finalについて
public class Main {

	public static void main (String[] args) {
		
		//定数として宣言
		final  int SAMPLE_CONSTANT_A = 1;
		
		//一度だけしか値を代入することができない為
		//↓下記はコンパイルエラーとなります!!
		SAMPLE_CONSTANT_A = 2;
		

		//定数として宣言
		final int SAMPLE_CONSTANT_B;
		
		//後から値を代入することもできる
		SAMPLE_CONSTANT_B = 1;
	}
}
```


##最後に

* protected　同一クラス、同一パッケージ、サブクラスからのアクセスを許可
* transient	オブジェクトがSirialization時には情報として含まない

そのほかにも上記、が変数修飾子としてそんざいしますが、自分がこれまでに触れる機会が少なかったので、自分なりの解釈は一旦今回は省きます。
excelにウェブページを表示する

# やり方


以前はセルやActiveXコントロールにブラウザを貼ることができたようですが、現在はセキュリティ上の理由でVBAからのみ実行できるようになったようです。


# 手順


デフォルトのユーザーフォームツールボックスにはWebBrowser(下の画像の地球儀マーク)が表示されていませんので、右クリック➔その他のコントロール➔「Microsoft Web Browser」にチェック➔OK で表示してやります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/7ad11ef1-95f5-5e4f-c4c8-472998ed46ae.png" width=50%>
フォームにWebBrowserを貼ります
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/086eeda6-a7eb-5e66-1b2c-16ffdfc41b84.png" width=50%>
WebBrowser1.Navigateを実行するとそのページを開いてくれますので、UserForm_Initialize()に書いておけばuserformが開いた時に指定のURLを開いてくれます


```vb:userform1
Private Sub UserForm_Initialize()
    WebBrowser1.Navigate "https://www.google.co.jp/"
End Sub
```


あとは適当なマクロからユーザーフォームを表示してやるだけです


```vb:VBA
Sub show_form()
    UserForm1.Show
End Sub
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/8dcd9868-5697-080d-23e9-3f98057f0b93.png" width=50%>
できました


# 実用できるか


Excelにどっぷり浸かっている職場で、Excelとブラウザで行ったり来たりする作業をExcel上でまとめて出来ないかと思って試してみたんですが、ちょっとJavaScriptが貼ってあるだけでエラーを吐きまくってページが開けなくなってしまい、今回の用途には使えないという結論になりました。

うーん残念
【Kotlin 初心者】font-familyで余白が入った場合の対処方法

## font-familyで余白が入った場合の対処方法
font-familyを指定した際に意図しない余白があり困ったので、この記事を書きました:point_up_tone2:

結論から言うと下記のプロパティを書くと解決します。

```
android:includeFontPadding="false"
```

fontによっては初期でandroid:includeFontPaddingがtrueになっているみたいです。
ざっくりとですが、android:includeFontPaddingの初期値がtrue,falseのfont一覧を書きました

|  true  |  false  |
| ---- | ---- |
|  noto_sans_cjk_jp_medium  |  hiragino_kaku_gothic_pro_n_w_3  |
|  -  |  yu_gothic_bold  |
|  -  |  roboto_medium  |
StoryBookでCanvasタブを表示したくない場合

今回はDocsタブだけ表示したいのでCanvasタブを隠す。

```.storybook/preview.js

~~省略~~

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  previewTabs: {
    docs: {
      hidden: false,
    },
    canvas: {
      //この部分
      hidden: true,
    },
  },
};

~~省略~~
```
BindingAdapterで「Caused by: java.lang.IllegalStateException: Required DataBindingComponent is null」

DataBindingでBindingAdapterを使っていると、以下のエラーが発生することがあります。

```kotlin
Caused by: java.lang.IllegalStateException: Required DataBindingComponent is null in class ActivityMainBindingImpl. 
A BindingAdapter in com.example.sample.BindingAdapter is not static and requires an object to use, retrieved from the DataBindingComponent. 
If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
```

これは`@JvmStatic`がないことによるエラーなので、BindingAdapterに追加すると解決します。

```kotlin
object BindingAdapter {

    @BindingAdapter("method")
    // 追加
    @JvmStatic
    fun TextView.method(text: String) {
        this.text = text
    }
}
```
Cloud Pubsubの非同期pullでサブスクライバーのフロー制御とスレッド数を制御する

# 背景
pubsubの非同期pullでpollingするjobをAirflowのDAGとして数分毎に実行するようなシステムを想定する。この時、pubsubへのpublishが高頻度で続くと、非同期pullをし続けてしまいDAGが終了しなくなっていまう問題がある。FlowControlを使って、数分ごとのDAGが被りなく実行されるように、適切に非同期pullを制御したい。また、非同期pullのcallback処理を複数並列で行えるようにcallbackを並列化させる。

# やり方

### 非同期pullの制御
メッセージのフロー制御を行う。サブスクライバーがメッセージをpullするスピードや量を制御することができる。

https://cloud.google.com/pubsub/docs/pull?hl=ja#config


### callbackの並列化
schedulerを指定してスレッド数を制御できる

https://googleapis.dev/python/pubsub/1.3.1/subscriber/api/scheduler.html#google.cloud.pubsub_v1.subscriber.scheduler.ThreadScheduler



# 実装

```py:polling.py
from google.cloud import pubsub_v1
from google.cloud.pubsub_v1.subscriber.scheduler import ThreadScheduler
import concurrent.futures.thread

project_id = "your_project"
subscription_id = "my-sub"
timeout = 10

def callback(message):
    print(f"Received {message}.")
    message.ack()

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_id)
# flow_controlで30以上のメッセージは受け取らないようにする
flow_control = pubsub_v1.types.FlowControl(max_messages=30)
# schedulerのdefaultのスレッド数が10なので30に変更する
scheduler = ThreadScheduler(concurrent.futures.thread.ThreadPoolExecutor(30))
streaming_pull_future = subscriber.subscribe(
    subscription_path,
    callback=callback,
    flow_control=flow_control,
    scheduler=scheduler
)

with subscriber:
    try:
        streaming_pull_future.result(timeout=timeout)
    except TimeoutError:
        streaming_pull_future.cancel()
```

# 参考
- [フロー制御を使用したサブスクライブ](https://cloud.google.com/pubsub/docs/samples/pubsub-subscriber-flow-settings)
- [github#python-pubsub#FlowControl](https://github.com/googleapis/python-pubsub/blob/2e03ba090ea938f19821622ebf6a87391dede0f5/google/cloud/pubsub_v1/types.py#L124)
- [github#python-pubsub#Scheduler](https://github.com/googleapis/python-pubsub/blob/16bf58823020c6b20e03a21b8b1de46eda3a2340/google/cloud/pubsub_v1/subscriber/scheduler.py#L76)
Laravel　Docker開発環境　使用したコマンド

#①Laravelのインストール
```zsh
$ docker-compose exec app composer create-project 'laravel/laravel=7.*' --prefer-dist [プロジェクト名]
```
Laravelのバージョンを指定したい場合は、上記のように
'laravel/laravel=7.*'
と書く。
#②ライブラリのインストール
```zsh
$ composer update
```
composer.jsonに使いたいライブラリ（
今回は、
"laravelcollective/html": "^6.2",
"scssphp/scssphp": "^1.4.1",
"twbs/bootstrap": "5.0.0-beta1"）
を記入後、上記のコマンドを実行

#③.envファイルの変更、　キャッシュの削除
```zsh
$ vi .env
```
docker-compose.ymlで設定したenvデータを上記コマンドで入力、変更する。

```zsh
$ php artisan cache:clear
```
一応キャッシュをクリアにしておく。

#④MySQLのユーザ認証方式を mysql_native_password に変更
```zsh
$ docker-compose exec ｄｂ bash　#①
$ mysql -u root -p #②
```
```sql
# SELECT user, host, plugin from mysql.user; #③
# ALTER user 'ユーザー名'@'ホスト名' identified with mysql_native_password by '新規パスワード'; #④
```
MySQL8以上は認証方式がcaching_sha2_passwordに変わっている。
現在（2021年3月）のPHPではサポートされておらず、エラーが発生する。
参照：https://www.php.net/manual/ja/mysqli.requirements.php
https://teffs.jp/2019/10/mysql-8-0-mysql-native-password-laradock-on-ubuntu/

①まずｄｂコンテナに入り、
②ルートユーザーでログインする。
③user, host, pluginを確認し、
④上記のように実行する。

#⑤モデルの作成
```zsh
$ php artisan make:model Article -m -c -r
$ php artisan migrate
```

```zsh
$ composer require doctrine/dbal
$ php artisan make:migration add_column_username --table=articles
$ php artisan migrate:fresh
```
カラム変更がしたい場合は上記のdoctrine/dbalをインストールする。

テーブルがすでに存在しているよというエラーが出た場合は、
migrate:freshで一度テーブルを作り直すと上手くいく  。

#⑥Bootstrapの組み込み
```scss:プロジェクト名/public/scss/app.scss
@import 'プロジェクト名/vendor/twbs/bootstrap/scss/bootstrap.scss';
```
指定したいスタイルがある場合は、app.scssに追記していく。

```zsh
プロジェクト名/vendor/scssphp/scssphp/bin/pscss < プロジェクト名/public/scss/app.scss > プロジェクト名/public/css/styles.css
```
追加したら、その都度上記のコマンドを実行する。
Heroku ActiveModel::UnknownAttributeError (unknown attribute 'カラム名' for テーブル名.): 解決例

DBでカラムの追加削除を行い、Herokuで投稿を行うと下記のエラーが表示されました。
ActiveModel::UnknownAttributeError (unknown attribute 'title' for Tweet.):
app/controllers/tweets_controller.rb:13:in `create'

```
2021-03-23T07:07:05.028419+00:00 app[web.1]: F, [2021-03-23T07:07:05.028321 #4] FATAL -- : [9942ded6-643a-4701-848b-9326668c790b]
2021-03-23T07:07:05.028421+00:00 app[web.1]: [9942ded6-643a-4701-848b-9326668c790b] ActiveModel::UnknownAttributeError (unknown attribute 'title' for Tweet.):
2021-03-23T07:07:05.028422+00:00 app[web.1]: [9942ded6-643a-4701-848b-9326668c790b]
2021-03-23T07:07:05.028422+00:00 app[web.1]: [9942ded6-643a-4701-848b-9326668c790b] app/controllers/tweets_controller.rb:13:in `create'
2021-03-23T07:07:05.032386+00:00 heroku[router]: at=info method=POST path="/tweets" host=original-2-app.herokuapp.com request_id=9942ded6-643a-4701-848b-9326668c790b fwd="111.239.163.211" dyno=web.1 connect=1ms service=34ms status=500 bytes=1827 protocol=https
^C
```
createから投稿がDBに保存される際にエラーが発生していることが予想できます。
ローカル上では投稿機能に問題はないがHerokuでは投稿できない状態なので
ターミナルで下記のコマンドでローカルのDBを削除して再作成します。

```
./bin/rails db:migrate:reset
```
その後、下記のコマンドで再作成されたDBをHerokuへ反映させることで解決できました。

```
git push heroku master
```
【謎すぎ】SwiftUI encountered an issue when pushing aNavigationLink エラー

# 謎すぎる「SwiftUI encountered an issue when pushing aNavigationLink」

以下のバグにだいぶ苦しみました。

一応画面遷移はちゃんとできるし、一見問題なさそうだけどエラーログ出ているのが気持ち悪かったので対応した。どうせアプリリースの時にappleさんから指摘されそうだしね。

```
SwiftUI encountered an issue when pushing aNavigationLink. Please file a bug.
```

解決策ググっても全然出てこなかったので、かなり解消に時間がかかりました。。
備忘として雑に残します。

ちなみに本バグは数々のロジックのバグを総称して上記のようなアラートを出しています。
あくまで参考程度に見ていただければ幸いです。

# 解決策
## 結論：NavigationLinkをForEachまたListから出してください。

Before:ForEachの中にNavigationLinkを配置していた。

```
ForEach(self.Memoes.data){i in
   VStack(alignment: .leading, spacing:5){
      NavigationLink(destination: ReadMemoView(data: self.data),isActive:self.$viewControllerModel.ReadMemoViewPushed) {
      Button(action: {
          self.data = i
          self.viewControllerModel.ReadMemoViewPushed.toggle()
      }) {
           Text("テキスト")
          }
      }
   }
}
```

After：ForEachの外にNavigationLinkを配置する

```
NavigationLink(destination: ReadMemoView(data: self.data), isActive: self.$viewControllerModel.ReadMemoViewPushed) {
       EmptyView()
}

ForEach(self.Memoes.data){i in
   VStack(alignment: .leading, spacing:5){
      Button(action: {
          self.data = i
          self.viewControllerModel.ReadMemoViewPushed.toggle()
      }) {
           Text("テキスト")
          }
   }
}
```

ForEachの中でNavigationLinkを行うと繰り返し処理された「isActive」のどれをアクティブ処理するべきか分からなくなってしまうみたい。
git mv で expressアプリケーションのディレクトリを移動しようとしたらpermission deniedでつまづいた話

## 問題
expressアプリケーションのディレクトリ構成を変更するため、
`git mv`でディレクトリを移動しようしたが
`permission denied`により移動できなかった。
パーミッションを確認したが問題はなかった。

## 解決方法
node_modulesを含むディレクトリを`git mv`で移動しようとすると
`permission denied`エラーになるため、
一度node_modulesを削除してから`git mv`で移動する。
最後に`yarn install`でnode_modulesを復元する。

## くわしく

```
.
├── express_nextjs
│   └── app
│        ├── express
│        │     ├── node_modules
│        │     └── その他 
│        └── Dockerfile
│
└── その他
```
を

```
.
├─ app
│   ├── express
│   │     ├── node_modules
│   │     └── その他 
│   └── Dockerfile
│
└── その他
```
にするためアプリケーションルートにて

```shell
$ git mv ./express_nextjs/app ./app
```
を試みたが`permission denied`

```shell
$ mv ./express_nextjs/app ./app
```
も`permission denied`

`ls -l`でパーミッションを確認したが問題なし。


`node_modules`を一旦削除する

```
git rm -rf ./express_nextjs/app/express/node_modules
```

再度

```shell
$ git mv ./express_nextjs/app ./app
```
でディレクトリを移動することに成功した。

最後に`yarn install`で`node_modules`を復元した。
SteamVRを起動するとディスプレイが暗くなる現象を直す

# SteamVRを起動するとディスプレイが暗くなる現象を直す

いつからか、SteamVRを起動すると、ディスプレイが暗くなるようになりました。

ディスプレイの電源を入れ直せば、元の明るさに戻るので、それで騙し騙しやってきたのですが、さすがに面倒になってきたため、解決法を探してみました。



## 原因はNVIDIAコントロールパネルの設定

どうやら以下の人たちと同じ症状のようです。

- [Main monitor brightness gets really dark after starting SteamVR?](https://www.reddit.com/r/SteamVR/comments/hplnk8/main_monitor_brightness_gets_really_dark_after/)

こちらの記事によると、NVIDIAコントロールパネルの `ディスプレイ > デスクトップ カラー設定の調整 > 2. カラーの設定方法を選択します。`  が `他のアプリケーションによってカラー設定をコントロールする` になっていると、よくないようです。



## NVIDIAコントロールパネルの設定を変更で解決

NVIDIAコントロールパネルの `ディスプレイ > デスクトップ カラー設定の調整 > 2. カラーの設定方法を選択します。`  を `NVIDIA の設定を使用する` に変更したところ、症状が出なくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/ecc8ff8a-66d4-dd33-eee3-4e5f872b8d5a.png)



# さいごに

本記事作成にあたり、以下の記事を参考にさせていただきました。ありがとうございました。

- [Main monitor brightness gets really dark after starting SteamVR?](https://www.reddit.com/r/SteamVR/comments/hplnk8/main_monitor_brightness_gets_really_dark_after/)
金子研の新人研修用プログラミング課題全部倒す Part.1  

## はじめに
##### "金子研の新人研修用プログラミング課題"とは？
[これ](https://datachemeng.com/pythonassignment/)です。
説明もリンク先の説明を読んでいただけると幸いです。
##### "全部倒す"とは？
全部解くということです。強い意志の表れです。

## 解いてみる
前半の問題1~12をGoogle Colab上で解いてみました。
<https://colab.research.google.com/drive/19lHSO9Na23G25QnpLJscf62A3_8wpNdk?usp=sharing>

## 解説
特に解説することがなかったので解説はないです。
後半はまた気が向いたら解いて記事を書きます。
セキュリティに関する知識

#本記事ついて
プログラミング初心者がセキュリティに関する知識を学んだので、その備忘録として載せております。

どうかお手柔らかにお願いいたしますm (- -)(_ _)ペコリ

##脆弱性
アプリケーション上で悪意のある者に攻撃を仕掛けられる際の弱点

##被害の想定をすることは重要
脆弱性を作り出さないために開発時にセキュリティを考慮した実装が必要
→未然に対策をしておく

##JavaScriptによるセキュリティ攻撃
JavaScriptはクライアント側で動くプログラミンング言語なので、ユーザーがwebアプリケーションに悪意のあるJavaScriptのプログラムを埋め込めば、そのプログラムを実行されてしまう恐れがある。

##XSS（クロスサイトスクリプティング）
JavaScriptを利用した攻撃方法。
悪意のあるJavaScriptプログラムを埋め込みそのサイトの利用者を攻撃する。

##スクリプト
「コードを書く　→　すぐに動かす 」ことができるプログラム
書いてすぐに実行できるプログラム

##スクリプティング
XSSのうち、スクリプトを埋め込んで実行させること

##攻撃する多い理由
ユーザーの個人情報などを悪意のある人のサーバーなどへ送付するようにスクリプトが埋め込まれていることが多い。

##反射型XSS（URLをクリックしレスポンスがあると即座位にスクリプトが実行）
ユーザーが悪意のあるURLをクリックすると脆弱性のあるwebアプリケーション上でスクリプトが実行されるようにする方法。

①ユーザーにURLをクリックさせる
②ユーザーがクリックするとアプリケーション上でスクリプトが動く
③スクリプトが発火すると攻撃者のサーバーへ個人情報が送られる
→ユーザーがクリックすると攻撃者が仕込んだスクリプトが動き、攻撃者のサーバーへ個人情報が送られる

##格納型XSS
悪意のあるスクリプトを脆弱性のあるwebアプリケーションの投稿などに埋め込み、ユーザーがそのwebアプリケーションに訪れた際にスクリプトが動作する方法

①攻撃者がwebアプリケーション上で、フォームからスクリプト付きの投稿をする
②ユーザーがスクリプトの埋め込まれた投稿のあるページを訪れるとスクリプトが発火
　または画像にマウスを合わせると発火
③スクリプトが発火すると攻撃者のサーバーへユーザーの個人情報が送られる。

反射型
検索欄に入力するだけ実行される

格納型
投稿に入力するだけで実行される

##XSSでの被害が多くの割合を占める
XSSへの対処は最優先で考える

##XSSが発生する主要因
フォームから入力されたスクリプトタグ（<script>…</script>）などがスクリプトとしてそのままブラウザに反映されてしまうことが挙げられる。

##文字参照
・ブラウザ上で表示できない特殊文字を表記する際に用いられる記法

・特殊文字はブラウザで表示できず特殊文字には変換できないので、特殊文字を文字参照にして表示すれば外部から埋め込まれたスクリプトが実行されることはない。

・特殊文字を文字列としてブラウザ上に表示するには文字参照を用いる。

##Ruby on Railsでの主要な対処方法
・ビューファイルにおけるヘルパーメソッド<%= %>。ヘルパーメソッドを用いることでXSSの対策を行うことができる。
（フォームを送信する際にヘルパーメソッドを使うがXSS対策がなされている）

・ヘルパーメソッドは特殊文字をエスケープできる。

・非同期投稿で表示する際にはヘルパーメソッドを用いないのでエスケープできないので
文字列として表示できない。しかし、リロードすることで特殊文字はエスケープされて反映されている。
→他のユーザーのブラウザ上で影響を及ぼすことはない。

##サニタイジング
非同期投稿を実装しているJavaScriptファイルでエスケープできる
Windows PC上のVMwareにMacOS 11 Big Surを構築する方法

Macを買ってみたいが、その前にMacOSを試してみたい！と思われるプログラマもいると思います。パフォーマンスはともかくとして、とにかくMacOSを体験してみたいのなら、仮想環境を構築することは一つの選択肢といえます。

macOS Big SurをVmWare Workstation Player上に構築する方法をブログに公開しています。よかったら、参照ください。

[Windows PC上のVMwareにMacOS 11 Big Surをインストールする方法](https://daimaohsx.dip.jp/wordpress/2020/12/09/how-to-install-macos-11-big-sur-on-vmware-on-windows-pc/?preview_id=647&preview_nonce=2d7b46eaba&preview=true)
[WordPress] WordPress 非ログイン時に wp-content/uploads/ へのアクセスを拒否する

WordPress のメディアファイルは静的ファイルなので、WordPress のログイン・非ログインにより表示・非表示を制御するということができません。
ただ会員制サイトとかだと、ログインしてない時に直接アクセスさせたくないとかって要望もあるので、対応できるようにしてみました。

まず、WordPress がインストールされてるディレクトリに以下のファイルを作成します。

```php:uploads-files.php
<?php
require __DIR__.'/wp-load.php';
if ( is_user_logged_in() ) {
    $file = realpath( ABSPATH . sanitize_text_field($_GET['file']) );

    // アップロードディレクトリ以下のファイルのみを対象にする
    $upload_dir = wp_get_upload_dir();
    if ( $file && strpos( $file, $upload_dir['basedir'] ) == 0 ) {
        $mime_type = mime_content_type( $file );

        // アップロードが許可されている mime type のファイルのみを対象にする
        $allowed_mime_types = get_allowed_mime_types();
        if ( in_array( $mime_type, $allowed_mime_types, true ) ) {
            if ( $mime_type === 'image/svg' ) {
                $mime_type = 'image/svg+xml';
            }
            header( 'Expires: 0' );
            header( 'Cache-Control: must-revalidate' );
            header( 'Pragma: public' );
            header( 'Content-Length: ' . filesize( $file ) );
            header( 'Content-Type: ' . $mime_type );
            header( 'X-Content-Type-Options: nosniff' );
            while ( ob_get_level() ) { ob_end_clean(); }
            readfile( $file );
            exit;
        } else {
            wp_die(
                '403 Forbidden',
                get_bloginfo('name').' - Forbidden',
                ['response' => 403]
            );
        }
    } else {
        wp_die(
            '404 Not Found',
            get_bloginfo('name').' - Not Found',
            ['response' => 404]
        );
    }
} else {
    wp_die(
        '401 Unauthorized',
        get_bloginfo('name').' - Unauthorized',
        ['response' => 401]
    );
}
```

そんで、Nginx の設定ファイルに以下の rewrite ルールを追加。
合わせて `/uploads-files.php` に対して直接アクセスされないように internal に設定しておきましょうかね。

```conf:nginx.conf
rewrite ^(/wp-content/uploads/.*)$ /uploads-files.php?file=$1 last;
location = /uploads-files.php {
    internal;

    expires        off;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_index index.php;
    include       fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
}
```

これで `/wp-content/uploads/` 以下へのリクエストがくると `/uploads-files.php` で処理されるようになります。
`/uploads-files.php` の中で WordPress にログインしているか( `is_user_logged_in()` )をチェックしているので安心ですね。
Cでポモドーロタイマーを作りました

## 初めに

ポモドーロタイマーは一般的に「25分＋5分」ですが、自分にはちょっと短いかなと思っていました。そこで「30分＋10分」のものを自作してみました。

「もっとこうしたらいいんじゃない」というところがあったらぜひ教えてください。

## コード

- OSはmacOSです
- 音源は主に[こちらから](https://soundeffect-lab.info/sound/voice/)ダウンロードしました
- `afplay`というコマンドを使うと、mp3ファイルをコマンドラインで再生できるので、これを使いました

```c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

/*
    A "pomodoro" is a set of a working session and a short break.
    And we define a "tomato" as a set of several pomodoros. We put a long break between two tomatoes.
    But we don't put a short break at the end of a tomato.
*/

void work(double t /* min */)
{
    system("afplay ~/Downloads/「開始します」.mp3 && afplay ~/Downloads/「がんばりましょう」.mp3");
    printf("work start\n");
    sleep(t * 60 /* seconds */);
    printf("work end\n");
    system("afplay ~/Downloads/warning1.mp3 && afplay ~/Downloads/「そこまで」.mp3");
}

void short_break(double t /* min */)
{
    system("afplay ~/Downloads/「これより10分間の休憩となります」.mp3");
    printf("short break start\n");
    usleep(t * 3 / 4 * 60 * 1000000 /* micro s */);
    system("afplay ~/Downloads/「始まるよ～」.mp3");
    usleep(t * 1 / 4 * 60 * 1000000 /* micro s */);
    printf("short break end\n");
}

void long_break(double t /* min */)
{
    system("afplay ~/Downloads/「頑張ったね」.mp3");
    printf("long break start\n");
    usleep(t * 3 / 4 * 60 * 1000000 /* micro s */);
    system("afplay ~/Downloads/「始まるよ～」.mp3");
    usleep(t * 1 / 4 * 60 * 1000000 /* micro s */);
    printf("long brek end\n");
}

int main()
{
    int n_pomodoro = 3; // in one tomato
    int n_tomato = 3;
    double t_work = 30;        // min
    double t_short_break = 10; // min
    double t_long_break = 30;  // min

    for (int i = 1; i <= n_tomato; i++)
    {
        for (int j = 1; j <= n_pomodoro; j++)
        {
            printf("%d-th tomato, %d-th pomodoro\n", i, j);
            if (j == n_pomodoro)
            { // if the pomodoro is the last one in a tomato
                work(t_work);
            }
            else
            {
                work(t_work);
                short_break(t_short_break);
            }
        }
        long_break(t_long_break);
    }
    return 0;
}

```
＜python＞プログラミング実行中の記録を残す→logging

### 参考リンク
https://docs.python.org/ja/3.8/howto/logging.html

###  やりたいこと
機械学習モデルのパラメータやら、特徴量エンジニアリングの試行実験結果を、
excelによる手打ち記録から、自動ファイル出力へとステップアップする

### この記事の対象者
- python始めたばかり
- モデルのパラメータを保存したい
- 実験結果を残したい

### コード

import logging　＃ インポート

logger = logging.getLogger('aaa')　# オブジェクト
logger.setLevel(logging.DEBUG)　# 表示（出力）するlogレベルをdebugに変更する（デフォルトはwarning）

log_file = logging.FileHandler(filename='test.log', mode='w')　# 出力するファイルを指定
logger.addHandler(log_file)　

logger.debug('debug')
【Rails】バリデーションの設定〜エラーメッセージ表示までの手順

# バリデーションとは
dbへデータを保存する際に、そのデータが意図したものかどうか検証する仕組み。
例）何かを投稿するときに名前を入力必須にする、パスワードの文字数は4文字以上、等々。

# 目標
インスタのような画像投稿SNSで、画像を投稿する際、未入力項目があれば、エラーメッセージを表示できるようにする。
モデルとカラムは以下の前提。
- モデル：PostImage
- カラム：shop_name、image

# 設定手順
＜おおまかな流れ＞
1. モデルで、バリデーションの条件を設定
2. コントローラで、エラー時の処理を設定
3. Viewで、エラーメッセージを表示

### 1. モデルでバリデーションの条件を設定
`validates :カラム名, 条件`
条件には色んなオプションがあります（後述）。
今回は未入力かどうかを検証するため、`presence :true`を条件に設定。

```ruby
class PostImage < ApplicationRecord
# 中略  
  validates :shop_name, presence: true
  validates :image, presence: true
end

```
> このとき、同時にマイグレーションファイルでも`null: false`を設定した方が良い。
理由は、モデルに定義しただけだとRails側で保存させないだけ。つまり、投稿フォーム経由での保存はできなくなるが、SQLから実行するとデータは保存できてしまうため。

#### ＜参考＞ よく使う条件
###### - 未入力
```ruby
presence: true
```
##### - 文字数
```ruby
length: { maximun: 20 }  # 最大
length: { minimum: 10}  # 最小
length: { in: 2..30 }  # 範囲
```
###### - 一意（重複不可）
```ruby
uniquness: true
```
###### - 特定のフォーマット
```ruby
format: { with: 正規表現 }
```

### 2. コントローラで、エラー時の処理を設定

```ruby
  def create
    @post_image = PostImage.new(post_image_params)
    if @post_image.save
      redirect_to post_images_path
    else
      render :new
    end
  end
```
バリデーションに引っかかると（今回は未入力なら）、saveメソッドでfalseが返る。
従い、saveメソッド自体を条件としてif文にし、elseでエラー時の処理を設定。

`render :アクション名`　で、同じコントローラ内のViewを表示可能
`render 'コントローラ名/アクション名'`　で、別コントローラのviewも表示可能

*renderとredirect_toの違い・使い分けについては、こちらの記事が分かりやすかったです

https://qiita.com/morikuma709/items/e9146465df2d8a094d78

### 3. Viewで、エラーメッセージを表示

```ruby:views/post_images/new.html.erb
<% if @post_image.errors.any? %>   # バリデーションエラーが発生したら以下を表示
  <%= @post_image.errors.count %>件のエラーが発生しました
  <% @post_image.errors.full_messages.each do |message| %>
    <%= message %>
  <% end %>
<% end %>
```
errorsは、バリデーションによるエラー内容を確認するメソッド。
any?でエラーの発生有無を判定し、full_messagesでエラー内容を出力。
*full_messagesは配列で保存されるため、eachを使用

# 最後に
フラッシュメッセージでも同様に、エラー時（＋処理成功時も）にメッセージを表示することが可能。

今のところ、
- バリデーション：検証条件の定義＆エラーメッセージ表示
- フラッシュメッセージ：成功時メッセージ表示
と認識しているが、いまいち使い分けが分かっておらず。

理解できたら更新するか別記事で上げます。
【Selenium】webdriversで「Bad CPU type in executable」エラー

### 環境
MacOS Catalina

* capybara
* rspec
* selenium-webdriver
* webdrivers

# Problem

久しぶりにseleniumを動かそうと実行すると以下のエラーが発生しました。

```
Errno::EBADARCH:
       Bad CPU type in executable - /Users/xxx/.webdrivers/chromedriver
```

Catalinaから32ビット版は使用できなくなりましたので、おそらくその影響でしょう。

# Solve

64ビット版を使うためにGemをアップデートします。
今回は全てのGemをまとめて更新したいので、Gemfile.lockを削除しました。
再び「bundle install」することで全てのGemが最新版で入りました。

```:Gemfile
gem 'capybara'
gem 'rspec'
gem 'selenium-webdriver'
gem 'webdrivers'
```

```shell
$ rm Gemfile.lock
$ bundle install
```

これでエラーなくSeleniumを動かすことが出来ました。
Fastlaneのactionにパラメータを渡す

Fastlaneのactionにパラメータを渡す方法を備忘録メモ

# 渡し方

```
fastlane dp update:false version_code:1
```

# 受け取り方

適当にスラックにログを送ってみる

```
lane :dp do |options|
  # ...
  if options[:update]
      slack(
        message: "version code #{options[:version_code]}",
      )
  end
end
```
Replace Autoprefixer browsers option to Browserslist config.

```
  Replace Autoprefixer browsers option to Browserslist config.
  Use browserslist key in package.json or .browserslistrc file.

  Using browsers option can cause errors. Browserslist config 
  can be used for Babel, Autoprefixer, postcss-normalize and other tools.

  If you really need to use option, rename it to overrideBrowserslist.

  Learn more at:
  https://github.com/browserslist/browserslist#readme
  https://twitter.com/browserslist
```

## 対応
gulp設定の置き換え

```
  autoprefixer({
    browsers: ['> 1%', 'last 5 versions']
  })
↓
  autoprefixer()
```

### .browserslistrc を プロジェクトルートに作成
```.browserslistrc
> 1%
last 5 versions
```
Rails ActionController::InvalidAuthenticityTokenが出た理由

## 結論
application.html.erbファイルのリファクタリング時に、tokenの埋め込みコードだと知らずにあやまって消してしていた。

間違え

```ruby:application.html.erb
- <%= csrf_meta_tags %>
- <%= csp_meta_tag %>
```

正しい

```ruby:application.html.erb
+ <%= csrf_meta_tags %>
+ <%= csp_meta_tag %>
```

##　最後に
あの2行のコードが、トークンに関するコードだという事がわかった。

参考
https://github.com/rails/rails/blob/main/actionpack/lib/action_controller/metal/request_forgery_protection.rb#L14
https://makicamel.hatenablog.com/entry/2019/03/06/230344
https://stackoverflow.com/questions/42795288/rails-how-to-implement-protect-from-forgery-in-rails-api-mode
NEM Symbol ノードの https化対応

NEM Symbol ノードは基本httpだけで稼働しますが、昨今のhttps化推進の流れもありますしhttps化対応をぜひしちゃいましょう。
https化をするには、my-preset.yml に下記を追加する必要があります。
```
httpsProxies:
    - excludeDockerService: false
```
参考
https://docs.symbol.dev/ja/guides/network/using-symbol-bootstrap.html

もし、公式が用意しているLet's Encryptを利用してのhttps化ではなく、その機能のアイデア元となったうにやさんのhttps-portalを利用してのhttps化をしたい場合は、以下をご参照下さい。

- 2021/03/24 と、うにやさんがタイミングよく新しい記事を投下してくださいました。神。

参考
~~https://nemlog.nem.social/blog/31033~~
https://nemlog.nem.social/blog/58808

参考までに下記画像はさくらVPSですが、https化の際は、80番ポートと 3001番ポートを追加で解放してください。

80番ポートは Let's Encrypt の定期的な証明書の更新時に使用されます。また、3001番ポートはsymbolのhttps通信の際に利用されます。

![sakura_vps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50227/d63af1ab-5320-48db-f59c-0d40c468aa71.png)



タヌソンスラック道場
https://tanuson.slack.com/
RHELを無償で利用する方法とは

# CentOSの終焉

業界標準といわれるRHEL（Red Hat Enterprise Linux）互換OSのCentOSが終了します。このニュースはシステムの構築屋（システムエンジニア）だけではなく、プログラマも衝撃を受けたと思います。

# プログラマの選択肢とは

CentOSの終了に伴い、代替えとなるディストリビューションの決定は悩みどころです。その選択肢のひとつとなるのが、「無償でRHELを使い倒す」です。
今までRHELが無償で使えるのは開発用途のものだけでした。それも、1アカウントで１台しか利用できませんでした。
それに対し、１アカウントで最大16台までの導入を可能とすると発表されました。さらに個人用途に限り、本稼働システムにも利用可能になりました。これは、CentOSが終了することに対する反響の大きさが、Red Hat社にそうさせたのかもしれません。

# RHELを無償で利用しよう

無償のRHELを使用してみたいという方向けに、開発用途のRHELをダウンロードする方法を紹介したブログを公開しました。
よければ、参考にしてください。

[RHELを無償で利用する方法とは](https://daimaohsx.dip.jp/wordpress/2021/03/10/how-to-get-and-use-rhel-for-free/?preview_id=1132&preview_nonce=7233f9c083&preview=true)
MacからWindows10へアクセス（ファイル共有）する時にうまくいかなかった時の別の手段

この辺り↓を試してみましたが「接続できません」とはねられたりそもそも表示されなかったりと困ったので備忘録です。

https://support.apple.com/ja-jp/guide/mac-help/mchlp1660/mac

https://u-ful.com/5903

※この記事はMac上で「ネットワーク」上に接続したいWindowsPCの名前が出てくるのに接続できないヒト向けの記事です

## 接続までの手順

### WindowsのIPを調べる
まずは同じネットワーク上にあるWindowsのIPを調べます。

https://faq.ricoh.jp/app/answers/detail/a_id/55/~/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E3%81%AEip%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%EF%BC%88standard-tcp%2Fip%EF%BC%89/session/L2F2LzEvdGltZS8xNjE2NDgyNTY0L2dlbi8xNjE2NDgyNTY0L3NpZC9mVUpOR0RMZEwwNEtBbGdxY1VqVDRaVWZldURISDc2cENZbEtZWWU4THUzdk1RNHZZUGRQWEtZbUlqbmVIcVpZRXFMWUlJb05uSmk5U0ZTaFJOa0R5NkZ5YjI4NVFEc2lxNlhUYWZoOGc2Q3Rlc3FoeVNQQnB6MkElMjElMjE=

ここで出てきたIPアドレスをメモしておきます。

### MacでWindowsに接続をする
MacのFinderのメニュー上で「移動」→「サーバーへ接続…」を選択します。

入力画面が出てくるので、先ほど調べたWindowsのIPアドレスを入力し「接続」を押します。

### Windowsのユーザー名とパスワードを入力する
普段WindowsにログインするときはPINコードを使用していたので、いきなりユーザー名とパスワードを求められ焦りましたが
Microsoftに登録してあるメールアドレスをユーザー名に、パスワードもMicrosoftに登録してあるパスワードで無事に通りました。
初期値のユーザー名が別のものが出る場合があるので注意しましょう。

### 接続完了
Finder上に接続したIPアドレスがでれば無事接続完了です。
MacからWindowsの中身がみられるようになります。

## まとめ
Windowsで共有フォルダを作ったりMacのシステム環境設定をしたり諸々試してもできなかった時にお試しください。
Rubyでカレンダーを書く

## はじめに
この記事はRubyの初心者がアウトプットの練習をするために書いたものです。
後続の人が見て分かりやすいよう初心者なりに丁寧に解説しながら書いています。

参考元を以下に記します。
[アウトプットのネタに困ったらこれ！？Ruby初心者向けのプログラミング問題を集めてみた（全10問）]
(https://blog.jnito.com/entry/2019/05/03/121235)

## 問題
[上記参考元](https://blog.jnito.com/entry/2019/05/03/121235)より引用。

>Date クラスを使って、今月の１日と月末の日付と曜日を求め、次のような形式でカレンダーを表示させてください

>```
      April 2013
 Su Mo Tu We Th Fr Sa
     1  2  3  4  5  6
  7  8  9 10 11 12 13
 14 15 16 17 18 19 20
 21 22 23 24 25 26 27
 28 29 30
```

## 方針
表示させたい日付は入力できるようにします。その日付が含まれるカレンダーを表示させるメソッドを用意してあげます。

```ruby
def calender(year,mon,day)
  #ここに処理を書く
end

puts "日付を入力してください(年,月,日)"
year = gets.to_i
mon = gets.to_i
day = gets.to_i
calender(year,mon,day)  #取得した年,月,日をcalenderメソッドに渡す
```

目標の表示は、上から年月の部分、曜日の部分、日にちの部分の3つに分けられそうです。それぞれ表示させていけば題意を満たせそうです。

## 年月の部分
取得した日付にstrftimeメソッドを用いることで表示させます。

```ruby
top = Date.new(year,mon,day).strftime("%B %Y")
puts top
```

## 曜日の部分
配列でSu~Saを用意し、表示させれば良いです。

```ruby
wday = %w(Su Mo Tu We Th Fr Sa)
puts wday.join(" ")
```

## 日にちの部分
ここは少し複雑ですので、順番に考えましょう。
まず、表示させるカレンダーの1日目が何曜日か把握する必要があります。また、最後の日付も把握する必要があります。問題にもこの２つを求めるよう指示がされています。この２つの情報がないとカレンダーを正しく表示させることができません。

```ruby
  firstday_wday = Date.new(year,mon,1).wday  #1日目が何曜日か
  lastday = Date.new(year,mon,-1).day  #その月の最後の日付
```

次に1日目を表示させる位置を考えます。これは、1日目が何曜日かがわかっていれば、その曜日分まで空白を記述させることで実現しましょう。

```ruby

print "   " * firstday_wday
```
　* firstday_wdayと記述することで、空白をfirstday_wdayの値分記述することができます。
 例えば今注目している1日目が日曜日なら、firstday_wdayの値は0,空白はなし。月曜日ならその値は1で空白も１つ。と言う具合です。


次に考えるのは日にちを実際に表示させることです。1日目をスタートさせる位置は分かりました。ですので、今度は何日分の表示をすれば良いか考えます。そのために、注目している日付の最後の日にちを取得します。

```ruby
lastday = Date.new(year,mon,-1).day
```

最後に日付を表示するコードを記述します。このとき、7日に一回（wdayが日曜日、つまり7の倍数になるたびに）改行することに留意しましょう。

```ruby
firstday_wday = Date.new(year,mon,1).wday  
wday = firstday_wday
  (1..lastday).each do |date|
    print date.to_s.rjust(2) + " "
    wday += 1
    if wday % 7 == 0
      print "\n"
    end
  end
```
目標とする表示が右詰になっているので、日にちはrjustで右に詰めて表示させます。
毎日wdayの値を1増加させ、7の倍数になる(=日曜日)ときには改行させましょう。

## 感想、まとめ
これまでバラバラに書いていたコードを修正しながら掲示します。

```ruby

def calender(year,mon,day)
  require "date"

  top = Date.new(year,mon,day).strftime("%B %Y")
  firstday_wday = Date.new(year,mon,1).wday
  lastday = Date.new(year,mon,-1).day
  wday = %w(Su Mo Tu We Th Fr Sa)

  puts top.center(20)  #目標とする表示が真ん中似合わせるようになっているので
  puts wday.join(" ")

  print "   " * firstday_wday
  wday = firstday_wday
  (1..lastday).each do |date|
    print date.to_s.rjust(2) + " "
    wday += 1
    if wday % 7 == 0
      print "\n"
    end
  end
  if wday % 7 != 0  #表示が土曜日以外で終わった際に改行させる
    print "\n"
  end
end


puts "今日の日付を入力してください(年,月,日)"
year = gets.to_i
mon = gets.to_i
day = gets.to_i
calender(year,mon,day)

```

新しい記述をしたもののみ注意書きをしておきましたが、概ねはまとめまでに書いた内容が理解できればカレンダーをかけると思います。
CDKで"Argument of type 'this' is not assignable to parameter of type 'Construct'."

# なんでや
ドキュメント通りに書いてもエラー出たりした。

```ts

const ec2Instance = new ec2.CfnInstance(
  this, //ここで Argument of type 'this' is not assignable to parameter of type 'Construct'.
  'ec2Instance',
  {
    imageId:  'ami-xxxx',
    instanceType: 't3.medium',
    ...
  }
);
```

# moduleのバージョンが違ってるのが原因
```json
"dependencies": {
  "@aws-cdk/aws-ec2": "^1.94.1", // これと
  "@aws-cdk/core": "1.86.0", // これのバージョンが違ってるから出るっぽい
  "source-map-support": "^0.5.16"
}
```

`@aws-cdk/core`のバージョンに合わせると幸せになれる。

```json
"dependencies": {
  "@aws-cdk/aws-ec2": "1.86.0",
  "@aws-cdk/core": "1.86.0",
  "source-map-support": "^0.5.16"
}
```

インストール時にバージョンしておけば上記の問題起こらないです

```shell
npm i @aws-cdk/aws-ec2@1.86.0
```

以上
GPT-3 APIの利用申請から承認まで

# はじめに
近年、Deep Learningの自然言語処理分野への応用もかなり活発になっていますが、その中で特に話題となっているOpen AIのGPT-3を試してみました。今回は申請してから承認されるまでの流れを紹介したいと思います。

# Open AI サイト
以下のページから申請は始まります。
https://beta.openai.com/
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/9cb4ecf0-ce78-1e94-899f-be02449c1d44.png)



# API試用申請
Join the waitlist ボタンを押すと以下のページに移ります。
まずは、基本情報として、Email、氏名などに回答します。
![clip-20210219142729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/8fe4683d-41ce-3849-3c2a-506fbbc1716e.png)


# APIの用途について
次に、APIをアプリケーションに使うつもりかどうかについて訊かれます。さらに新規商品か既存商品に使うのか、あるいは研究用途のみかプレイグラウンドというOpen AI提供のお試し場で試してみるのかを回答します。ちなみに私の場合は研究用途ですのでConduct researchにチェックを入れました。さらに分野についても回答する必要があります。
![clip-20210219142243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/7826ca43-b7f2-b460-e153-ec03947a1cfd.png)


# 用途の詳細について
GPT-3はあまりに高性能なため、悪用される危険性があるとして、OpenAIはどう使われるかについて慎重になっていますので、ある程度詳しく書く必要があるようです。私の場合は、所属するラボの概要、直近の研究の方向性も入れて書きました。
![clip-20210219142619.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/6f18df34-25d2-4c2a-5eac-0db8dfe7e32e.png)


# 所属する組織の情報
会社などの組織に所属するのであれば、組織名や従業員数などについて記入します。
![clip-20210219142632.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/767f7d0a-24e3-1913-c891-1d77b07496b1.png)


# メディア関係者かどうか等
最後にジャーナリストかソーシャルメディアクリエイターか独立出版者か、年齢について回答し、書いた内容が正しいと保証する旨チェックするようになっています。

![clip-20210219143126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185839/b6824b35-2b31-837e-eb54-5e0ff3d19812.png)


# 承認
私の場合、申請してから1週間程度でOpenAI事務局から承認メールが届きました。
メールにはGPT-3のSlackコミュニティへ招待する旨が書かれてあり、そこではほぼ毎日のように投稿があり活発に活動されています。
（さらに、メールには念押しで5人以上にAPIのアウトプットを供する場合は製品レビューリクエストを事務局に提出し、承認を得る必要があると記載されていました。）

# おわりに
今回はGPT-3の申請から承認までについて記事にしました。次は、APIの試用について書きたいと思います。
「『クロージャ(closure)』は何をcloseしているんだろうか」の解決

※クロージャ自体のことは（なんとなく）わかることを前提としている。
※「クロージャとは」でググるとJavaScriptが関係しているページが多いので、以降JavaScriptを例に用いる。

# 前提となる言葉の説明
### "束縛変数"・"自由変数"
**あるプログラム断片に着目**したときに、その断片中に出てくる変数（仮に `x` とする）について、 `x` が断片中で宣言されているなら `x` は **束縛変数** であり、断片中で宣言されてないなら `x` は **自由変数** である[^1]。

[^1]: 実用的なプログラミング言語での束縛変数・自由変数の説明、難しい。大抵のサイトでは「関数中の仮引数とローカル変数が束縛変数である」となっている気がする。

「あるプログラム断片に着目する」のが重要で、着目する断片によって自由変数か束縛変数かは変わってくる。例えば、以下のプログラム断片では、

```javascript
function(a) {
    return function(b) {
        return [a, b, c, d];
    }
}
```

`a` , `b` は引数として宣言されているため束縛変数であり、`c` , `d` は自由変数である。

一方、同プログラムの内側の関数のみに着目すると、

```javascript
function(b) {
    return [a, b, c, d];
}
```

`b` のみが束縛変数で、 `a` , `c` , `d` が自由変数である。

### "閉じている"（"closed"）
自由変数を含まないプログラム断片は、**閉じている**（**closed**）という。

例えば、次の断片は閉じた断片である（`a` は束縛変数）。

```javascript
function(a) {return a;}
```
一方、次の断片は閉じていない（開いた）断片である（`b` は自由変数）。

```javascript
function(a) {return b;}
```

閉じていない断片は、断片内で宣言されていない変数を含むため、その断片単体では実行できない。


# 本題

以下のコードを例に。

```javascript
function getClosure() {
    const x = 123;
    return function(a) {
        return x + a;
    };
}

// 動作例
const myClosure = getClosure();
myClosure(0); // -> 123
```

このとき、クロージャ `myClosure` は

```javascript
function(a) {
    return x + a;
}
```

である。ところが、この関数は**閉じていない**（変数 `x` が自由変数だから）。そのため、この関数単体では使えない。
そこで、`myClosure` は、`x` の値が何であるかの情報（JavaScript風に書くと `{x: 123}` のようなイメージ）を保持しておく必要がある。この情報を **環境** と呼ぶ。
この環境を先ほどの関数とセットで見ることで、あたかも `x` が束縛変数になり関数が**閉じた**状態になるように見える。

このようにあたかも**閉じた**（**closed**）状態になった「関数と環境のセット」を、「**クロージャ**（**closure**）」と呼ぶのである。

# まとめ
「クロージャ（closure）」という名前の由来は、自由変数を含む関数が、環境とセットになって「閉じた（closed）」状態になったから[^2]。

[^2]: 「クロージャとして扱われる関数とそうでない関数がある」ようなニュアンスで書いたが、（少なくとも）JavaScriptでは、関数は常にクロージャである（[クロージャ - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures)）。

# 参考
[Closure (computer programming) - Wikipedia # History_and_etymology]
(https://en.wikipedia.org/wiki/Closure_(computer_programming)#History_and_etymology)
コメントアウトがめんどくさいと感じたら

成果物を提出する際にコメントアウトを追加するってなって関数のパラメーターとリターンがあるか確認して書いていくみたいなときにいちいち確認して書いていくってだるいなって思った。

それでなんかたまたまJavadoc的な何かを導入する際にあるコマンドを打つと関数のところのパラメーターとかリターンとか自動で作ってくれる物を発見したので共有。

やり方はこれだけ

関数のところに　|　←これを合わせる

あとはコマンド+オプション+/

これを押すだけ

そうすると関数のパラメーターとかリターンとかコメントアウトを自動で作ってくれる

例えばパラメーター一つとリターンの場合はこんな感じ

    /// Description
    /// - Parameter パラメーター名: <#パラメーター名 description#>
    /// - Returns: <#description#>

結構コメントアウトって忘れてしまうし、いちいちだるいななんて思って書くのを忘れることが多いので、このコマンドを最後に打てばできるんで割と簡単にできるななんて思ったので、もしこの記事を見つけた方は使えるタイミングがあれば使ってみて欲しい。

これはXCodeだけなのかはわからない。

試すのは誰でもできるので、この記事を見つけたら機会があればやってみてもらえればと思う

追記

変数のところで行っても///とコメントアウト表示されることが確認できた
Homebrewの「brew doctor」でエラーになった。

Homebrewをインストールして、「brew doctor」するとエラーが出たので、対処法を記す

エラーの内容

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

Warning: Unbrewed header files were found in /usr/local/include.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.

Unexpected header files:
  /usr/local/include/node/cppgc/allocation.h
  /usr/local/include/node/cppgc/common.h　
.
.
.
```
これらの全てのファイルを消すといいということだったので消した。


```
cd ~/../../usr/local/include/
open .
```
ファイルの場所までとび、開けて、エラー内で記されているファイルを消す。

私は選ぶのが面倒だったため、一度全てを消去し、その後Homebrewもアンインストールして、再度インストールを行った。