OmniAICreator/Qiita-1.07M huggingface dataset:
日経225mini 先物自動取引のためのAPI 利用(板情報取得) - Interactive Brokers

#日経225mini 先物の板情報を取得する
Interactive Brokers 証券株式会社のAPI を利用する自動売買システムを開発しています。新たに板情報を取得するコードを追加しました。自動売買システムに必要な代表的な機能としては、歩み値取得、発注、シグナル発生、資金管理などがあるかと思いますが、これまでは板情報の取得を行っていませんでした。システム全体がまだまだ完成から遠かったのとデータ利用料金が必要となりそうだったためです。
Windows 環境でプログラム言語はPython を主に使用していますが、周辺機能で必要な場合には別の言語やOS も利用しています。

#板情報取得を行う
既にAPI を利用している場合には追加で板情報取得を行うのは簡単で、マーケットデータの利用設定と２つのメソッドを実装してあげるだけです。
<dl>
<dt>Market Data Subscriptionsの設定確認</dt>
<dd>Japan Equities and Derivatives BundleがFee Waived となっているのを確認</dd>
<dt>メソッドのコードを公式文書よりコピー</dt>
<dd>reqMktDepth</dd>
<dd>updateMktDepth</dd>
</dl>
(公式文書の該当コードは、[こちら](https://interactivebrokers.github.io/tws-api/market_depth.html)のPython のタブの箇所に置かれています。)


#板情報更新の動作動画#
板情報を取得してデータベースに格納した後に、コンソールに表示するようにしました。この動画ではAPI から取得したデータの表示とHyper SBI での板表示を重ね合わせて記録しています。値の表示は一瞬で更新が行われるので、動画ではまず最初の1秒間で等倍速度表示し、残りの部分では最初の1秒間をスロー再生し表示しています。
<iframe width="640" height="480" src="https://www.youtube.com/embed/pG3XyoZvIq0" title="Level 2 Market Data" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#使用環境
TWS API (9.76.01)
IB Gateway 978 / 984
Trader Workstaton 978 / 985


#これまでに検討、開発してきた取引環境
これまでにも複数のデータ配信、注文環境を試してきました。残念ながら全データが取得できなかったり、開発途上だったりしたため今のところはInteractive Brokers さんのAPI を利用しています。ただし、この場合には特定口座での取引とならないため、不便さを感じています。
1. 岡三オンライン証券の岡三RSS
2. 楽天証券の楽天RSS
3. kabu STATION API
Python Challenge Level 3

[Python Challenge](http://www.pythonchallenge.com)に挑戦しています。次はLevel3。

#Level 3
タイトルはre

![bodyguard.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62130/48da5d9c-c8cb-5a79-07f7-aecd776dff39.jpeg)

>One small letter, surrounded by EXACTLY three big bodyguards on each of its sides.
文字ひとつが、「正確に」三つの大きな随行員に挟まれている。

ヒントを求めてソースコードを見てみると、

```html:re.html
<html>
<head>
  <title>re</title>
  <link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<center>
<img src="bodyguard.jpg"/><br>
<font color="#ffd000">
One small letter, surrounded by <b>EXACTLY</b> three big bodyguards on 
each of its sides.
</center>
<br><br>
To see the solutions to the previous level, replace pc with pcc, i.e. go
to: http://www.pythonchallenge.com/pcc/def/equality.html

<br><br>
Join us on IRC: irc.freenode.net #pythonchallenge
</body>
</html>
<!--
kAewtloYgcFQaJNhHVGxXDiQmzjfcpYbzxlWrVcqsmUbCunkfxZWDZjUZMiGqhRRiUvGmYmvnJIHEmbT
省略
PBuijeoTSpsVLaOGuLVjMZXkBvVXwUuHfBihziiavGSYofPNeKsTXruMUumRRPQJzvSzJkKbtSipiqBd
-->
```

コメントアウトされた大量のアルファベットの文字列があります。ここから目的のものを見つけ出せばいいようです。

タイトルがreとあるので正規表現（regular expression）を用いれば良さそうです。画像とそのヒントからすると目的の文字は３つの大文字（大きな随行員）に挟まれた小文字であるようです。例えば、"ABCdEFG"というような文字列を探し出せばいいようです。早速プログラムにしてみると、

```python:3.py
#!/usr/bin/env python3

import re
reg = re.compile(r'[A-Z]{3}([a-z])[A-Z]{3}')

coText = """
kAewtloYgcFQaJNhHVGxXDiQmzjfcpYbzxlWrVcqsmUbCunkfxZWDZjUZMiGqhRRiUvGmYmvnJIHEmbT
省略
PBuijeoTSpsVLaOGuLVjMZXkBvVXwUuHfBihziiavGSYofPNeKsTXruMUumRRPQJzvSzJkKbtSipiqBd
"""

ms = reg.findall(coText)
print("".join(ms))
```

で良さそうです。実行してみると、

```
jfeiauzroivgzbmpszazlutnwsdofbiwqdjbzshfrblqgsbydajygcbjwggtdfjeobcmdlzxajvitecgpkcfwqbvkoietpiijanvqjjgtcpadjkgcluaidgumcdskunujfcjfmbzkzsasdxsqqqlaeisjefjfdaoljaywxjthqjknednxnsahxqedoeqsdcmltcsnwakjxtytaalhgabekfmyimwrkffydghiunlriwgkuzqljjbsxguytfsatejmdwkfbzifdknpcqimvehxujszbuyutsompijjojspbwlroefiwmrsjstdjhfwxhnthsoosmoqtufoxvpvpjkgiaqgfrhufxxdnjiwtfqusbkeakunjgknpibklgjounivhgxsnekxgrrbslpuaouvhzbilbirmqqxtktgcnkdljoasnexwtgvwjegurnksokjtrovpmykzgeolwysfidemflmkwmj
```

わけのわからん文字列が出力されてしまった。何が間違いなのか。
##再考
ヒントを改めて読んでみると、『文字ひとつが、「正確に」三つの大きな随行員に挟まれている。』ということだった。「正確に」とはどういうことだろうか。現在の探索方法だと、"AABCdEFGH"みたいに四つの大文字に挟まれているものも探しだしてしまう。ここがまずいのかということで「正確に」三つの大文字に挟まれた小文字を探し出せるようにする。
具体的には

```python:
reg = re.compile(r'[a-z][A-Z]{3}([a-z])[A-Z]{3}[a-z]')
```

というものに置き換えてみる。

### 結果
```
linkedlist
```

が出力され、意味のある単語が出てきた。

# Level 4
linkedlist.html
http://www.pythonchallenge.com/pc/def/linkedlist.html
にアクセスすると、linkedlist.html じゃなくてlinkedlist.php だと変更を求められる。

というわけで次のレベルが開かれた。
http://www.pythonchallenge.com/pc/def/linkedlist.php
.eslintrcのrulesに0とか2とか書かれてるけど、あれは何？

.eslintrcのrulesでプロパティの値に、0とか2とか書いてあるのを見かけたが、
これは何を意味しているか。

```json:.eslintrc
  "rules": {
    "react/prop-types": 0,
    "react/react-in-jsx-scope": 2
  }
```

**結論、off, warn, errorを表している。**
>0 -> "off"
1 -> "warn"
2 -> "error"

なので、以下の書き方と同義

```json:.eslintrc
  "rules": {
    "react/prop-types": "off",
    "react/react-in-jsx-scope": "error"
  }
```

意味は以下の通り
>・off -> 設定オフ。 ルールに沿っていなくても何もしない。
・warn -> 警告モード。 ルールに沿っていなければ、黄色波線付けてくれる。
・error -> エラーモード。 ルールに沿っていなければ、赤波線付けてくれる。


数字わかりにくいし、普通に文字列指定して欲しい（）
Chakra-uiでグローバルなスタイルを設定する方法

#はじめに

CSSフレームワークであるChakra-uiの機能について記事にします。

#グローバルなスタイルを設定する

グローバルなスタイルとは、アプリケーション全体を通して設定する共通のスタイルのことです。
例えば文字の色や背景色などです。

CSSフレームワークであるChakra-uiを使うと、すごく簡単にグローバルスタイルが設定できます。

```
/* Theme.tsx */

import { extendTheme } from "@chakra-ui/react";

export const theme = extendTheme({
  styles: {
    global: {
      body: {
        backgroundColor: "gray.100",
        color: "gray.800"
      }
    }
  }
});
```

chakra-uiには、extendThemeというものがあり、 その中で styles->global->bodyと階層を作り、最終的にbodyの中でグローバルなスタイルに適用したいCSSを記入します。

このextendThemeを、自分で宣言した定数（今回はtheme）に代入し、コンポーネント化します。

```
/*App.tsx*/

import { ChakraProvider } from "@chakra-ui/react";

import { theme } from "./Theme";

export default function App() {
  return (
    <ChakraProvider theme={theme}>
    </ChakraProvider>
  );
}
```

そして、themeをメインのファイル内でインポートし、上記のようにreturnの中身全体を<ChakraProvider>で囲みます。 ChakraProviderもchakra-uiが用意してくれているもので、<ChakraProvider>で囲んだ中で初めてchakra-uiの様々な機能が使えるようになります。
最後に、ChakraProviderのthemeという引数に、インポートしておいたthemeを渡します。

すると、グローバルなスタイルが全体に反映された状態で、後の開発が行えます。
Rubyで逆数の和を算出する方法

　逆数の和を算出する問題を解いたので記録しておきます。

1/1 = 1

1/1 + 1/2 = 1.5

1/1 + 1/2 + 1/3 = 1.8333...

　このような形で1からNまでの整数の逆数の和を出していき、その逆数の和が7を超える最小の値Nを出したいと思います。
　最終的にコードは以下のようになりました。答えは「616」です。

```ruby
num = []
sum = 0
count = 0
while sum < 7
  count += 1
  reciprocal = 1.0/count
  num << reciprocal
  sum = num.sum
end
puts num.length
```

　プログラミング初心者ということもあり、めちゃめちゃ非効率なやり方ではありますが、論理が飛躍しないように地道に複数のやり方を試して答えに辿り着きました。
　というわけで以下の流れで答えに辿り着いたプロセスを紹介したいと思います。

1. 小数を含める
2. とりあえずN=20で試してみた
3. 強引に答えを出してみた
4. もう少し可読性を上げる


##1. 小数を含める
　まずは4までの逆数の和を出そうとしてみました。

```ruby
num = 1/1 + 1/2 + 1/3 + 1/4
puts num
```
　しかし上記のコードでは実行結果は「1」となってしまいました。どうやら小数が切り捨てられてしまうみたいです。そこで「to_f」を使ってみると、実行結果は「2.08333...」となり、小数点も含まれるようになりました。

```ruby
num = 1/1.to_f + 1/2.to_f + 1/3.to_f + 1/4.to_f
puts num
```
　ただこんなことをしなくても「1」を「1.0」に変えるだけでも小数が含まれるようになりました。「整数÷整数=整数」という仕様になっているようなので「.0」をつけるだけで良かったみたいです。

```ruby
num = 1.0/1 + 1.0/2 + 1.0/3 + 1.0/4
puts num
```

##2. とりあえずN=20で試してみた。
　だいたい答えがどれくらい大きな数字になるかというアタリをつける目的で、とりあえず20回繰り返し処理を試してみました。

```ruby
num = 0
20.times do |i|
  num += 1.0/(i + 1)
  puts num
end
```
　そうすると実行結果は以下のようになりました。

```ruby
1.0
1.5
1.8333333333333333
2.083333333333333
2.283333333333333
2.4499999999999997
2.5928571428571425
2.7178571428571425
2.8289682539682537
2.9289682539682538
3.0198773448773446
3.103210678210678
3.180133755133755
3.251562326562327
3.3182289932289937
3.3807289932289937
3.439552522640758
3.4951080781963135
3.547739657143682
3.597739657143682
```
　N=20で逆数の和は「3.597...」ですし、足していく逆数はどんどん小さくなるため、逆数の和が7を超える最小の値はかなり大きな数字になりそうです。勘では当てられそうにありません。

##3. 強引に答えを出してみた
　もちろんここから原始的なやり方で答えを導くことも可能だと言えます。とりあえず1万回繰り返し処理をしてみて、逆数の和が7を超えた時に繰り返し処理をストップさせてみました。また、何回目でストップしたかが分かるようにブロック変数の中身を「timesCount」にしてみました。

```ruby
sum = 0
10000.times do |timesCount|
  count = timesCount + 1
  sum += 1.0/count
  if sum >= 7
   puts sum
   puts count
   return
  end
end
```
　これで実行結果は以下のようになりました。

```ruby
7.001274097134162
616
```
　N = 616の時に初めて逆数の和が7になるという答え自体は導き出せました。

##4. もう少し可読性を上げる
　答えを出すことだけが目的ならば上記のコードでも問題はないですが、とりあえず1万回繰り返し処理をしてみたというのはコードとしては不適切です。そのため、whileを使ってコードを書き直してみました。

```ruby
num = []
sum = 0
count = 0
while sum < 7
  count += 1
  reciprocal = 1.0/count
  num << reciprocal
  sum = num.sum
end
puts num.length
```
　それが最初に紹介したこのコードです。合計が7を超えるまで繰り返し処理を行うようにして、配列に値を追加しながら合計を出すようにしていきました。配列を使っているため、lengthメソッドでNの値を出すようにしています。

　以上です。もっと適切なコードはあるはずですので、ご意見を頂けるとありがたいです。
ZIG SIM で取得した Quaternion でGrasshopperオブジェクトを動かす

#はじめに
ND3M の MEDY さん、consomme さんによる ZIG SIM ハンズオンでスマホのセンサー情報を Grasshopper で取得する方法を教えていただきました。ハンズオンのあとで Quaternion を使って Grasshopper オブジェクトを動かしてみたのでメモ書きです
**@consomme** さんの記事「[**GrasshopperによるZIGSIM連携**](https://qiita.com/consomme/items/f3769ac4153846a1eb4d)」

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/ND3M?src=hash&amp;ref_src=twsrc%5Etfw">#ND3M</a> ハンズオン(6/17_19:00-21:00)ありがとうございました。ZIGSIMを用いてスマホセンサーの値をGrasshopperにインプットし、モデルをインタラクティブに操作するというワークショップを <a href="https://twitter.com/consomme__?ref_src=twsrc%5Etfw">@consomme__</a> さんと企画しました。<br><br>「楽しい～」「すごい簡単にできた！」と言ってもらえてうれしかったです。 <a href="https://t.co/h4SwawtpXA">pic.twitter.com/h4SwawtpXA</a></p>&mdash; MEDY (@408321date) <a href="https://twitter.com/408321date/status/1405508033698963458?ref_src=twsrc%5Etfw">June 17, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#全体像はこんな感じ
「[**GrasshopperによるZIGSIM連携**](https://qiita.com/consomme/items/f3769ac4153846a1eb4d)」を見ながら gHowl の UDP Receiver で ZIGSIM の情報を受け取る。
List Item で Quaternion の数値を取り出し、GhPython Script で回転行列を計算する
Construct Matrix > Inverse Transform > Transform でオブジェクトを動かす
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/5872b94b-aca4-bc90-42ac-5f0f38bffb6a.png)

#Gh Pyhon の準備
インプットを４つに増やして名前を x, y, z, w にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/046084bf-c258-f22c-d7dd-ec9f0f0f8204.png)

x, y, z, w の Type hint を全て float にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/18da072c-78f8-fe82-758d-996917b30e20.png)

#Gh Python の中身
Quaternion を 回転行列に変換するための計算をしてます



```python
a = []

a.append(1 - 2*y**2 - 2*z**2)
a.append(2*x*y + 2*w*z)
a.append(2*z*x - 2*w*y)
a.append(0)

a.append(2*x*y - 2*w*z)
a.append(1 - 2*z**2 - 2*x**2)
a.append(2*y*z + 2*w*x)
a.append(0)

a.append(2*z*x + 2*w*y)
a.append(2*y*z - 2*w*x)
a.append(1 - 2*x**2 - 2*y**2)
a.append(0)

a.append(0)
a.append(0)
a.append(0)
a.append(1)
```

#参考

[GrasshopperによるZIGSIM連携](https://qiita.com/consomme/items/f3769ac4153846a1eb4d)
[クォータニオンからオイラー角を求めてみる](https://qiita.com/edo_m18/items/5db35b60112e281f840e)
UNIXドメインソケット

本日得た知識の1つを記していきます。

## ソケット通信とは

プロセス間通信の方法の一つ。ネットワークを経由することで、データのやりとりなどを行う。その際に通信先を特定する際には、通信先のドメイン名・IPアドレス・ポート番号を基に、通信先のソケットという部分に接続します。**ソケット**とは、通信におけるインターフェースの名前です。

## UNIXドメインソケットとは

プロセス間通信の際に、ネットワークを経由する事なく、通信先と繋げる方法のこと、またはそのインターフェースのことをUNIXドメインソケットと言います。同一のホスト間で行われ、IPアドレスなどを用いて名前解決する必要がない為、高速なプロセス間通信を可能にします。UNIXドメインソケットを用いて接続された機器（webサーバーなど）は、同一のプロセスとして扱う事ができる。

## 参考

https://qiita.com/toshihirock/items/b643ed0edd30e6fd1f14

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

認識違い等ございましたら、ご指摘頂けると幸いです。

### 例：NginxとUnicorn

Dockerの同一コンテナ内で、NginxとUnicornをUNIXドメインソケット接続する。

```
:app/nginx/ドメイン名.conf
user root;
events {
	:
}
http {
	upstream app {
		server unix:/root/tmp/unicorn.sock;
	}
	server {
		:
	}
}

```

```ruby
:app/confing/dev_unicorn.rb
	:
listen  File.expand_path('/root/tmp/unicorn.sock', app_path)
	:
```

IPアドレスとポート番号を指定する代わりに、socketファイルの位置を指定する事で、UNIXドメインソケット通信を実現させています。
ちなみに、こちらの設定ではソケットファイルを`root/`配下の`/tmp`ファイルに設置する事で、コンテナの停止・起動とを同一のタイミングでプロセス同士の接続を行うよう設定している。
残プロ 第-25回 ~Flaskで変数を扱う~

# 簡単なflaskのまとめ

**pythonとhtmlをつなげるやつ**

## pythonからhtml

python側：flask.render_templateでhtmlを指定，変数を渡す
html側：{{ foo }}とすることで変数を利用できる


## htmlからpython

html側：url_forで実行する関数を指定する(routeを設定しておく必要あり)．変数も渡せる
python側：@app.routeでurlと関数を紐づける．/\<string:bar>とすることで変数を受け取れる
AWS Amplify Function でプライベートネットワーク内のRDSに接続する方法


# この記事について
Amplify を用いると簡単にバックエンド環境を揃えられるので、
スピーディ且つスケーラブルなアプリ開発にもってこいですよね。

しかし、アプリがスケールしてきて、応用的な開発をしたいときに、
公式ドキュメントが英語だったり、日本語の記事がまだ豊富でないので詰まったりすることが良くあります。

今回は、Amplify CLI でVPC内のRDSに接続するために、VPCリソースを利用するLambda 関数を作成する手順について解説します。

コンソールからVPCリソースを利用するLambda関数の作成方法は少し調べれば分かりますが、
Apmplify CLI でLambda関数を作成する場合、バックエンドリソースは Cloud Formation で管理されるので、
`<関数名>-cloudformation-template.json` ファイルを手動で編集する必要性があります。

# cloudformation-template.json のプロパティ追加

こちらのGitHubIssueを参考にしました。

Deploy lambda to VPC. #32
https://github.com/aws-amplify/amplify-cli/issues/32

`amplify/backend/function/<関数名>/<関数名>-cloudformation-template.json` を編集します。
追加するプロパティは”VpcConfig"の`SecurityGroupIds`と`SubnetIds`です。

sg-xxx と subnet-xxx をご自身のセキュリティグループとサブネットのIDをセットしてください。

```json
"Resources": {
    "LambdaFunction": {
        "Type": "AWS::Lambda::Function",
        "Metadata": {
            "aws:asset:path": "./src",
            "aws:asset:property": "Code"
        },
        "Properties": {
            "Handler": "index.handler",
              ....
            "VpcConfig": {
                "SecurityGroupIds": [
                    "sg-xxx"
                ],
                "SubnetIds": [
                    "subnet-xxx",
                    "subnet-xxx",
                    "subnet-xxx"
                ]
            }
        },
        "LambdaExecutionRole": {
              ....
        
```

これで`amplify push function`を実行！

しかし、これだけだと EC2 の権限周りらしいというエラーメッセージをだしてデプロイ失敗、、、となります。

`An error occurred (InvalidParameterValueException) when calling the CreateFunction operation: The provided execution role does not have permissions to call CreateNetworkInterface on EC2`

上記エラーの解消法にはこちらの記事が参考になりました。
LambdaのIAMロールにVPCアクセスの権限がないためエラーになっているようです。
`{関数名}-template.json`内のLambdaのIAMロールポリシーに以下を追加すれば解決しました。

```json
"lambdaVPCexecutionpolicy": {
      "DependsOn": [
        "LambdaExecutionRole"
      ],
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": "lambda-vpc-access-execution-policy",
        "Roles": [
          {
            "Ref": "LambdaExecutionRole"
          }
        ],
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface",
                "ec2:AssignPrivateIpAddresses",
                "ec2:UnassignPrivateIpAddresses"
              ],
              "Resource": "*"
            }
          ]
        }
      }
    },
```


どなたか同じ悩みをもった方のご参考になれば幸いです。
descを省略したRakeタスクを一覧に表示させる方法

# Rakeタスクの `desc` について

Rakeタスクを作る際、`desc` にタスクの説明を記述します。
それにより、作成したタスクが `rake -T` コマンドや `rake -D` コマンドで表示されます。
逆に、`desc` を省略したタスクは表示されません。

例として、`desc` のあるタスク `my_task` と無いタスク `my_secret_task` を用意してみました。

```ruby:Rakefile
desc 'This is my task.'
task :my_task do
  puts 'My Task!'
end

# This is my secret task.
task :my_secret_task do
  puts 'My Secret Task!'
end
```

`rake -T` と `rake -D` で確認してみます。

```bash
$ rake -T
rake my_task  # This is my task
$ rake -D
rake my_task
    This is my task.

```

このように、`my_secret_task` は表示されません。

# `desc` を省略したRakeタスクを一覧に表示させる

`-A` オプションで `desc` を省略したタスクも表示することができます。

```bash
$ rake -T -A
rake my_secret_task  # 
rake my_task         # This is my task
$ rake -D -A
rake my_secret_task

rake my_task
    This is my task.

```
 
`desc` を省略したタスクも表示することができました。

また、オプションをまとめて以下のように実行することも可能です。

```bash
$ rake -AT
rake my_secret_task  # 
rake my_task         # This is my task
$ rake -AD
rake my_secret_task

rake my_task
    This is my task.

```

なお、 `-TA` や `-DA` だと何も表示されないので注意。
ナッシュ均衡をわかりやすく説明

# 「ナッシュ均衡」の形式的な説明
>相手の行動が変わらない場合，自分がその行動以外の行動を取ると利得が減ることはあっても増えることはない状態

これ、結局腑に落ちにくいですよね。テストが迫っているので自分なりに直感的な説明で理解してみました。

# ナッシュ均衡の直感的な説明
これは、「背に腹は変えられない」という状況です。

リゾート地に夜についたけどホテル取り忘れた！という状況を考えましょう。


相手はホテルのフロントの方だとしましょう。この方は旅人が来たら泊めることは**合理的**に決定しているとします。(だって、私が入る入らないのいずれにせよ、ホテル側はお金が入ることはあっても減ることはないでしょう？)
今回は相手の戦略はさておき、**自分の選択しうる行動**について注目しましょう。

今、考えられる私の戦略は以下です。

(i)高級ホテルにダメもとで泊まる
(ii)港の公園で野宿する

(i)だとホテルは1万2千円得しますが、私はその分お金を失います。
(ii)だとホテルの利得は0円（変わらない）ですが、私は港の潮風にふかれ、睡眠の質が最悪になり、ダメージを負います。
このダメージは(i)の金銭的なダメージよりも大きいものとします。

この場合、(i)の高級ホテルにダメもとで泊まるという戦略は、ナッシュ均衡です。
なぜでしょうか？

(i)以外の戦略をとる、すなわち(ii)を選ぶと、より大きなダメージを負います。

今、ホテルのフロントの人は「人が来たら受け入れる」という行動を仮定しています。
これは「相手の行動が変わらない」ということに対応しています。


>相手の行動が変わらない場合、自分がその行動以外の行動を取ると、利得が減ることはあっても増えることはない状態

に該当しますよね。すなわち、**背に腹は変えられない**と私たちが渋々納得して選ぶような行動と相手の行動の組がナッシュ均衡というわけです。

なお、ナッシュ均衡は、単一の行動をとりうる場合(AKA 単純戦略)は存在しないこともあります。一方で、確率的にプレーヤーが行動を選ぶとき(AKA 混合戦略)は、必ず存在するそうです。

## 参考
イラストで学ぶ人工知能概論（第二版）　**学校の授業の教科書です。**


## 感想
五島列島の福江島に行ったときにこんな状況になりました。
身近な例を勉強と絡めて考えると、*自己参照効果*により学習の効果が上がるそうです。
また、他人に説明することは学習効果が高く、*想起学習*の要素もあるため、Qiitaに記事を書くことは自分自身にもメリットが大きいですね。
SSM Agentのトラブル対処をした際の話

#はじめに

ユーザーから「WindowsUpdateをしてから、SSM Agentが起動しなくなった」と問い合わせがあり、そのトラブルシューティングを実施した際のことを備忘録として記載したものである。 
OS：Windows Server 2016

#トラブルシューティング

##①調査

下記のコマンドで、イベントログで出力されているSSM Agent関連のメッセージを出力した結果、たしかにSSM Agentが何度も起動を試しているが、うまく起動しないことが分かった。

```
PS C:\Users\Administrator> get-winevent -logname System -FilterXPath '*[EventData[Data[@Name="Param1"] = "Amazon SSM Agent"]]'


   ProviderName: Service Control Manager

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
2021/03/10 16:04:53           7031 エラー           Amazon SSM Agent サービスは予期せぬ原因により終了しました。このサービスの終了は 25 回目です。次の修正操作が 30000 ミリ秒以内に実行されます: サービスの再開。
2021/03/10 16:04:53           7024 エラー           Amazon SSM Agent サービスは、次のサービス固有エラーで終了しました: ...
2021/03/10 16:04:53           7036 情報             Amazon SSM Agent サービスは 停止 状態に移行しました。
/////////////////////////////////////////////////////     略        /////////////////////////////////////////////////////
2021/03/10 13:22:21           7031 エラー           Amazon SSM Agent サービスは予期せぬ原因により終了しました。このサービスの終了は 1 回目です。次の修正操作が 30000 ミリ秒以内に実行されます: サービスの再開。
2021/03/10 13:22:21           7024 エラー           Amazon SSM Agent サービスは、次のサービス固有エラーで終了しました: ...
2021/01/29 14:50:20           7036 情報             Amazon SSM Agent サービスは 実行中 状態に移行しました。
```


次に、SSM Agentのログを確認したら、以下のログが出力されていた。
パスは、Windowsの場合、 **%PROGRAMDATA%\Amazon\SSM\Logs** になる。
参考URL：[SSM エージェントログを表示する](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-agent-logs.html)

```
caused by: Get http://169.254.169.254/latest/meta-data/instance-id: net/http: request canceled (Client.Timeout exceeded while awaiting headers)

ERROR [Execute @ agent_windows.go.180] Failed to start agent. error fetching the instanceID, Failed to fetch instance ID. Data from vault is empty. RequestError: send request failed
```

##②対処

上記のログを確認したら、インスタンスメタデータを取得するために「169.254.169.254」へアクセスしたが、宛先に到達できていないエラーを発見。
Windows Updateをする際にProxyを設定したことにより、「169.254.169.254」への通信ができなくなり、それでSSM Agentの起動が失敗していた。
その為、「169.254.169.254」はProxyを経由しないように設定したら、本事象は解決した。
参考URL：[SSM エージェントが Windows Server インスタンス用にプロキシを使用するように設定する](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-install-ssm-proxy.html)

#最後に

SSM Agentはインスタンスメタデータの情報を使用していたことを知らなかった為、それでトラブル対処に時間がかかってしまった。
今後は、各AWSサービスの特性を理解した上で、トラブル対処を効率的に実施していきたいと思います。
終わり(●´ω｀●)
sympy で定数変数的なのをうまく扱いたい

たとえば

```
z = a x
```

のような式で, a は実数定数で, いろいろ数値が変わって複数の式を定義したい(e.g. 外部ファイルから a の値を読んだりとか).

a, x で変数作り,

```
a = sympy.Symbol('a')
x = sympy.Symbol('x')

def gen_fun(a, x):
  return a * x

z = gen_fun(a, x)

z.subs(a, 0.3)
```

のようにして `0.3 x` の式を作ろうとすると

```
Add/Mul with non-Expr args has been deprecated since SymPy 1.7. Use
Expr args instead. See https://github.com/sympy/sympy/issues/19445 for
more info.

  SymPyDeprecationWarning(
```

という warning がでる. github issue みても `Expr args` で検索してもよくわからない.

## とりあえずの解決

ひとまずは文字列から式を作るでしょうか.

https://docs.sympy.org/dev/modules/parsing.html

```
a = 0.3
z = parse_expr("{} * x".format(a))
```

のような感じで.
## その他

https://stackoverflow.com/questions/39665207/define-a-variable-in-sympy-to-be-a-constant

これでいけるかも?
Flutter TabBarのサンプルその２　スクロールで下のタブが消える

スクロールで下のタブが消えるサンプルの自分用メモ
リストを突っ込みたかったけどエラーでまくって
どう改造すればいいのかわからなかった・・・
下記URLのコードです。
https://stackoverflow.com/questions/50353640/hide-bottom-navigation-bar-on-scroll-in-flutter

ここにはコード書きませんが他にもこんなのがありました。
https://pub.dev/packages/scroll_bottom_navigation_bar/example

```main.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

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

class _MyHomePageState extends State<MyHomePage> {

  bool _isVisible = true;
  ScrollController controller;


  @override
  void initState() {
    super.initState();
    controller = ScrollController();
    controller.addListener(() {
      setState(() {
        _isVisible = controller.position.userScrollDirection == ScrollDirection.forward;
      });
    });
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        controller: controller,
        children: List.generate(200, (index) => Text(("$index"))),
      ),
      bottomNavigationBar: Offstage(
        offstage: !_isVisible,
        child: BottomNavigationBar(
          items: [
            BottomNavigationBarItem(
              title: Text("Hello"),
              icon: Icon(Icons.style)
            ),
            BottomNavigationBarItem(
                title: Text("Hi"),
                icon: Icon(Icons.style)
            ),
            BottomNavigationBarItem(
                title: Text("Hey"),
                icon: Icon(Icons.style)
            )
          ],
        ),
      ),
    );
  }
}
```
【データ視覚化のデザイン】の紹介 （その１）

## この本について

「データ視覚化のデザイン」は、永田ゆかりさんが書かれた本です。

> 永田ゆかり(ながた・ゆかり)
アクセンチュア、楽天、KPMGなどを経て、独立。PATH Data Analytics & Visualization(PATH株式会社)を立ち上げる。日本Tableauユーザー会会長を務める。2019年2月にTableau ZEN MASTER に日本人女性で初めて選ばれる。

本記事は、自分の学習振り返りや共有用としてエッセンスだけをまとめたものです。

- ** ~ なんで「可視化の技術」が大切なのか~   無意味な分析について**
- **プロっぽいチャートにするコツ** (その２で書く予定)

より詳細な内容も沢山乗ってるので、興味ある方はAmazonなどで是非買ってみてください。

## なんで「可視化の技術」が大切なのか

「うちはデータをいつでも表にして出してる」
「別にグラフとか綺麗に作れてるよ」
と思っていらっしゃる方、本当に大丈夫でしょうか？？


**1. 正しい意思決定ができない
2. 認知的負荷がかかる**

上記の項目について、具体的な例を見ながら考えていきたいと思います。

### 1. 正しい意思決定ができない

適切な可視化しないとどうなってしまうのか、具体的な事例を使って考えていきましょう。
以下は、可視化の重要性を解くのによく使われる**「アンスコムの例」**というデータです。
この**「表」**のデータから、どんな傾向があるか読み取ってみてください。

![スクリーンショット 2021-06-26 20.57.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182163/004e019b-476d-1b99-6f10-2038a51d52d4.png)

どうでしょう、何か読み取れたでしょうか？
「表だけで見てもあんまりよくわからない...」という人が多いかと思います。

では、更なる知見を得るために、平均・分散などの**「統計量」**を計算してみましょう。
実は、**Ⅰ・Ⅱ・Ⅲ・Ⅳのどのグループも全く同じ統計量**になります。

|  統計量  |  値  |
| :----: | :----: |
|  Xの平均  |  9  |
|  Xの分散  |  11  |
|  Yの平均  |  7.5  |
|  Yの分散  |  4.12  |
|  XとYの相関係数  |  0.816  |
|  回帰直線 |  y = 3.00 + 0.500x  |


**「なーんだ、全部おんなじ傾向のあるデータか。」**
と思ったそこのあなた。

...本当にそれでいいでしょうか？？

より詳細な分析をするために、**「データの散布図」**を出してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182163/f7c379cd-fb4f-709a-9163-c427bed7c431.png)

実際に可視化してみると、**それぞれ全く異なる分布のデータ**であることがわかりました！
「表を見るだけ」「統計量を見るだけ」ことがいかに危険か、「適切な可視化」がいかにわかりやすいかが見て取れますね。

実際のビジネスの現場では、数字だけしか見ずに意思決定をしてしまうことも珍しくありません。
**適切な意思決定のためには可視化が重要**ということがわかっていただけたかと思います。

### 2.認識的負荷がかかる

データを可視化したとしても、オーディエンスがデータを理解するためには非常に多くのエネルギーを必要とします。

以下のデータのように、見た目が整理されてなかったり情報が多すぎると、理解することが難しく、データからの知見を何も得ようとしてくれなくなります。

![スクリーンショット 2021-06-26 21.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182163/ed4813eb-ec1b-5d4d-efc7-5570d1766b41.png)

色や情報量が多すぎて、どのような意思決定をしたらいいか分かりませんね。


ちょっと修正してみて、注目したいポイント以外の色を消すと非常に分かりやすくなりますね。

![スクリーンショット 2021-06-26 21.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182163/e94ad051-20df-039f-0b7c-2a7c6618f7b6.png)

データから知見をオーディエンスにしっかり共有するには、**認知的不可を下げること**が必要不可欠です。
だからこそ、**「可視化の技術」を学び実践することが重要**です。

## まとめ

データ可視化が如何に重要かを紹介しました。

データ分析は「データを見ておしまい」ではなく、**データを適切に分析できることや、企画推進のため周囲に結果を正しく伝えられること**が大切です。
データドリブンにビジネスを進めていくためにも、「可視化の技術」をしっかり意識していきたいですね！

プロっぽい見せ方にする方法については、次の記事で書きます！
【備忘録】Wordで数式の一部に図形で補足を入れても改行で配置が崩れないようにする設定

#実現したい数式レイアウト
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308853/0fe4c3e9-cca0-4570-6b46-1988427cf424.png" height="120%">

数式の一部に矢印、下線、カッコで補足したいような場面。(上図では $=0$ ($\because$ incompressiblle fluid)が該当）
自分の知っている範囲ではwordの数式機能だけでは実現不能なので、工夫が必要だと思われる。

#環境
Windows 10 Home
Word 2016

#やり方
##1.数式作成

テキストボックス内に数式ブロックを挿入して補足用数式(今回の例では$ =0$ など)を作り、矢印やかっこなどを図形で作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308853/7bdfc16d-2a10-23ca-702d-cd3a8dad7b19.png)
##2.グループ化
それらをマウスで範囲選択する or 一つずつctrl押しながらマウスで選択。その後グループ化しておく(ショートカットキーはctrl+g)。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308853/d8bb8d8c-527f-e59d-c154-6e4f434f5988.png" height="40%">

##3. 希望の位置、かつ配置崩れしないレイアウト設定

文字列の折り返しを”前面”or”背面”かつ”文字列と一緒に移動する”に設定する。（デフォルトの設定でもうなってたらok）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308853/8f2fe29d-3fb2-511c-a878-7c95beb79bc0.png" height="50%">
このようにすると文章の配置を変えてもそれと連動して図形も動くし、好きな場所に数式＆図形を配置できる

#おわりに
Wordのプロではないので、もっといいやり方がありましたら教えていただけるとありがたいです。

以上、Wordで数式の一部に図形で補足を入れても改行で配置が崩れないようにする設定でした。

お読みいただきありがとうございました。
HTML のデータセット属性に無理やり配列を設定する方法

結論から言うと、まず次の HTMLの `data-disabled-dom="windowsVersionInput, WSL2Checkbox, windowsTerminalSoftInput, linuxDistributionInput"` のように、データセット属性にカンマ区切りの文字列を設定します。

```html
<input class="form-check-input" type="radio" name="osName" id="macos" value="MacOS" data-activate-dom="macosVersionInput" data-disabled-dom="windowsVersionInput, WSL2Checkbox, windowsTerminalSoftInput, linuxDistributionInput">
```

それから、`.js` ファイルに次のコードを追加して、`data-disabled-dom` 属性に設定した文字列を配列として取り出します。なお、`data-disabled-dom` 属性に設定した値の取り出し方は、[データ属性の使用 - ウェブ開発を学ぶ \| MDN](https://developer.mozilla.org/ja/docs/Learn/HTML/Howto/Use_data_attributes) を参照してください。

```js
const disabledDomIds = document.getElementById('macos').dataset.disabledDom.replace(/\s/g, '').split(',');
console.log(disabledDomIds);
// -> ["windowsVersionInput","WSL2Checkbox","windowsTerminalSoftInput","linuxDistributionInput"]
```

ちなみに、`replace(/\s/g, '')` でスペースを取り除いていない場合、次のとおり無駄なスペースが含まれてしまいます。

```js
// ["windowsVersionInput"," WSL2Checkbox"," windowsTerminalSoftInput"," linuxDistributionInput"]
```

これで `data-disabled-dom` 属性に設定した配列が `disabledDomIds` 変数に格納されたので、次のコードで順番に取り出して処理することができます。

```js
for(let disabledDomId of disabledDomIds) {
  let disabledDom = document.getElementById(disabledDomId);
  // 何かの処理
}
```
代入 ― J 言語入門

# 変数名

これまでの記事では、`a` や `b` のような文字を変数に使ってきましたが、もちろん 2 文字以上の変数名も使えます。変数名には以下のような決まりがあります。

- 半角英数字 (`A-Z` `a-z` `0-9`) とアンダースコア (`_`) が使える
- 先頭の文字はアルファベット (`A-Z` `a-z`) のみ
- アンダースコアで終わったり、連続するアンダースコアを含んだりしてはならない

J には**予約語がない**ので、`if` や `for` なども変数名に使えます。一方、アンダースコアを使う位置には注意が必要です。

## 命名規則

定数の名前は大文字のスネークケース、それ以外は小文字のスネークケースないしはキャメルケース、とするのが一般的です。

# 代入

代入には `=:` を使います。`=:` は **copula** (繋辞) [^1] に分類されます。copula は noun や verb などとは異なり、それ自体は**値ではありません**。

copula は、`=:` と `=.` の 2 種類です。代入の構文は、`=:` も `=.` も同じです [^2]。

# 左辺

代入式の左辺は、いくつかの書き方ができます。配列の要素を同時に複数の変数に代入することもできます。

- 変数名 (直接)
- 文字列リテラル ― スペース区切りで複数の変数に代入できる
- 括弧で括った式 ― 式の結果が以下のいずれか
  - 1 つ以上の変数名からなる文字列 (スペース区切り)
  - 変数名を格納したボックス (のリストも可)

```j
   one=: 1
   'two'=: 2
   NB. 複数の変数に配列を代入
   three ; four ; five [ 'three four five'=: 3 4 5
┌─┬─┬─┐
│3│4│5│
└─┴─┴─┘
   NB. 変数名 ab を作る
   ab [ ('a' , 'b')=: 'AB'
AB
   NB. 変数名 a と変数名 b をボックスに入れてリストに
   a ; b [ ('a' ; 'b')=: 'AB'
┌─┬─┐
│A│B│
└─┴─┘
```

括弧を使うと、変数を間接的に参照して代入できます。

```j
   name=: 'var'
   (name)=: i.3   NB. var=: i.3 になる
   name ; var
┌───┬─────┐
│var│0 1 2│
└───┴─────┘
```

配列を複数の変数に代入する場合、長さが一致する必要があります。

```j
   'a0 a1 a2'=: 2 3
|length error
|   'a0 a1 a2'    =:2 3
```

# 右辺

変数には、noun に限らず verb, adverb, conjunction も代入することができます。変数に型はないので、極端な話、noun を代入していた変数に verb を代入するようなことも可能です [^3]。

```j
   ]cat=: '😺'
😺
   cat=: ,
   'c' cat 'at'
cat
```

noun 以外を代入する場合、`[` や `]` を一緒に使うと**別の意味になる**ので、気をつけてください。

```j
   ]f=: /
]/
```

---

\[ 前 : [adverb と conjunction](https://qiita.com/unsigned-wrong-wrong-int/items/b61c2f03af3096be044f) \] \[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \] \[ 次 : [フックとフォーク](https://qiita.com/unsigned-wrong-wrong-int/items/03f1b408fd89bdbc18ff) \]

[^1]: 英語の be動詞などに相当する品詞。
[^2]: `=.` については、後々必要になるので、その際に説明します。
[^3]: 余程の理由がない限り、してはいけませんが。
【swift】error: cannot convert value of type 'String' to expected argument type 'String.SubSequence'の解消方法

## 問題
以下のようなコードで文字列をsplitしてString型の変数をapeendしようとするとエラーになる

```swift
let name:String = "qiita"
var ary = name.split(separator: " ")　 //["q","i","i","t","a"]
ary.append(name)
```

## 解決方法
以下のようにsplitした後にmapで明示的に型変換する必要がある。

```swift
let name:String = "qiita"
var ary = name.split(separator: " ").map(String.init)　 //["q","i","i","t","a"]
ary.append(name)
```
Node.js+expressでWEBサイトを構築する際に気をつけたいこと

# はじめに

Google Chromeのデベロッパーツールを使うと、サーバ情報などを分析できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/5a2b25a7-7193-7449-7f69-2d816b8b1a93.png)

図のようにWEBサーバがApacheだと判明できます。
例えば、Apacheの脆弱性が発見された場合に、脆弱性のあるサーバに対して攻撃を受ける可能性があります。
そこで、サーバ情報を隠す方法があります。

# サーバ情報を伏せるためにX-Powerd-Byの設定を変更する。

Node.js＋expressを利用したWEBアプリケーションの場合、
**app.disable("x-powered-by")**を追記しましょう。

```javascript:app.js
var express = require( 'express' ),
    app = express();

app.set( 'view engine', 'ejs' )
app.disable("x-powered-by"); //これを追記する

```

以上です。
Jetson NanoのPython3環境でIllegal instruction (cpre dumped)

# 現象

* ドローンのTelloをプログラムで制御するためのPythonライブラリDJITelloPyをJetson Nano(Ubuntu)にインストールした。
* が、`import Tello`を実行しただけなのに`Illegal instruction (cpre dumped)`でエラーになってしまう。

https://github.com/damiafuentes/DJITelloPy


## 環境
* Jetson Nano
* Ubuntu 18.04 LTS

## エラー内容

こんな感じで、`import Tello`を実行しただけで、`core dumped`になる。

```
$ python3
>>> from djitellopy import Tello
Illegal instruction (core dumped)
```

![Screenshot from 2021-06-25 22-21-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/023d9a17-bcc0-93b1-0abb-23304d58f4f3.png)


`pip3 install`でいろんなバージョンを試したけど解決せず。

一方、Intel Macでは正常に実行できる。

![スクリーンショット 2021-06-25 22.36.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/3fc447df-5eee-be6a-7f77-37c2a63ad4b8.png)


# 解決方法

python3を実行する前に環境変数`OPENBLAS_CORETYPE`に`ARMV8`だよって設定をしとけばよい。
（毎回設定するのが面倒くさいなら.bashrcあたりに書くとかする）

```
$ export OPENBLAS_CORETYPE=ARMV8
```

* ここに解決方法が記載されている。
    * https://forums.developer.nvidia.com/t/illegal-instruction-core-dumped-xavier/166278
    * https://www.programmersought.com/article/46997515059/
* 要するに、Jetson NanoはARM64系なので、そのままだとCPU命令セットの違いで動かないみたい。
    * 特にTello(djitellopy)に限った話ではなく、Jetson NanoでPyhton3実行する際の一般的な問題な訳だ。


OK、解決した！

![Screenshot from 2021-06-25 23-14-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/9709cd05-591a-c8d1-2925-8b7874410af7.png)


落ち着いて調べたら、からあげ先生のまとめにちゃんと書かれてましたね。
さすがです。

* [Jetson Nano関係のTIPSまとめ](https://qiita.com/karaage0703/items/b14c249aa33112669ee4)
TypeScriptでPDF.jsを使う際「The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream`); please use a `legacy`-build instead.'」が出た場合の対処法

#概要

TypeScriptでPDF.jsを使う際にコンパイルは通るが、実行時に致命的な機能がないと言われた時の対処方法です。
調べてもドキュメントが少なかったので、ここに残します。

#環境
Node.js:v14.17.0
@types/pdfjs-dist:2.7.3
pdfjs-dist:2.8.335


#発生事象

処理実行中下記メッセージが出力されてエラーとなる。

>「The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream`); please use a `legacy`-build instead.'」

## エラーとなったコード

```TypeScript:test.ts
import { getDocument } from 'pdfjs-dist';

export class TestClass {
  async getNumPages(file: Express.Multer.File) {

    const pdf = getDocument({
      data: file.buffer
    }).promise;
  
    const page = (await pdf).numPages;

    return page;
  }
}
```

#対処方法

エラーの指示通り、レガシーなモジュール（pdfjs-dist/legacy/build/pdf）を使い、解決しました。

## 修正済のコード

```TypeScript:test.ts
import { getDocument } from 'pdfjs-dist/legacy/build/pdf';

export class TestClass {
  async getNumPages(file: Express.Multer.File) {

    const pdf = getDocument({
      data: file.buffer
    }).promise;
  
    const page = (await pdf).numPages;

    return page;
  }
}
```
Railsで複数のテーブルを一括削除する

Railsで昔に作ったテーブルが複数残ってしまっていたので、
新しいテーブルを作り、migrateした際に、
already exists（既にあるよ）と怒られていた。
たまに削除したくなったりするので、忘れないように投稿します(ｏ'∀')ﾉ

## 流れ
① 空のmigrationファイルを作成

```
$ rails g migration destroy(destroyは任意の名前)
```

② 出来上がったmigrationファイルに

```
class Destroy < ActiveRecord::Migration[6.1]
  def change
    drop_table :不要テーブル名
    drop_table :不要テーブル名
    drop_table :不要テーブル名
  end
end
```

③ migrateする

```
$ rails db:migrate
```

これで不要なテーブルは削除されます。
+αでモデルの削除もした方がよろしいと思いました。


## 参考資料
[Railsでテーブルの削除](https://qiita.com/kanuu/items/a9223712ee0ff8d19d56)
Linux: LSコマンドでファイルのみ・ディレクトリのみを表示する方法

バッチで必要になったので調べたついでにメモしておきます。

###### 実施環境：

```Linux:Linux
[testuser@testhost ~]$ uname -a
Linux testhost 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[testuser@testhost ~]$ echo $SHELL
/bin/bash
```

単にlsコマンドでディレクトリかどうかを判別する場合、"-l"オプションで先頭の文字が"d"であるかを確認すればディレクトリであるかは判別できます。
ただ、更新日時やサイズなど余分な情報も出てきてしまうため、ファイル名部分をバッチで利用する場合はこの方法ですと扱いづらいです。

```Linux:Linux
[testuser@testhost ~]$ ls -l
-r-------- 1 testuser testgrp 0 Jun  6 13:04 test.conf
drwxr-xr-x 2 testuser testgrp 6 Jun  6 13:04 test_dir
--w------- 1 testuser testgrp 0 Jun  6 13:04 test.log
---x------ 1 testuser testgrp 0 Jun  6 13:04 test.sh
```

ではどうするのかというと、"-F"オプションを使用します。

```Linux:Linux
[testuser@testhost ~]$ ls -F
test.conf  test_dir/  test.log  test.sh*
```

"-F"オプションを使用すると、対象のタイプに応じて末尾に記号が付与されます。
通常のファイルでは何も付与されませんが、実行権のあるファイルの場合は"*"が、ディレクトリの場合は"/"が付与されます。
そのため、grepをかけることでファイルのみ、ディレクトリのみの表示が可能となります。

```Linux:Linux
[testuser@testhost ~]$ ls -F | grep -v /
test.conf
test.log
test.sh*
[testuser@testhost ~]$ ls -F | grep /
test_dir/
```

末尾の記号を削除したい場合はsedコマンドを使用します。

```Linux:Linux
[testuser@testhost ~]$ ls -F | grep -v / | sed s/\*$//g
test.conf
test.log
test.sh
[testuser@testhost ~]$ ls -F | grep / | sed s/\\/$//g
test_dir
```
Raspberry Pi 4Bに64-bit Raspberry Pi OSをインストールしてみた記録

#はじめに
Raspberry Pi 4B+に64-bit Raspberry Pi OSをインストールしてみました。
気づいた点があればコメントをお願いします。

#環境
- Raspberry Pi 4B+ 4GB
- SD Card 32GB

#１．64-bit Raspberry Pi OSのイメージファイルをダウンロードする。
以下のサイトから64-bit Raspberry Pi OSのイメージファイルをダウンロードする。
- https://downloads.raspberrypi.org/raspios_arm64/images
私の場合は、
- https://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2021-05-28/2021-05-07-raspios-buster-arm64.zip
をダウンロードしました。

#２．64-bit Raspberry Pi OSをRaspberry Pi Imagerを使ってSDカードに書き込む
まず、https://www.raspberrypi.org/software/ にアクセスしてRaspberry Pi Imagerをダウンロードして起動します。すると次の画面が表示されるので、"CHOOSE OS"をクリックします。
![RaspberryPiImager_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/49d0c0ce-18bb-a2f9-2488-9c3379f669ca.jpeg)

#３．イメージファイルの選択
"CHOOSE OS"をクリックするとドロップダウンメニューが表示されるので、一番下の"Use custom"を選択ます。すると、ファイルエクスプローラーが起動されるので、そこから先ほどダウンロードした64-bit Raspberry Pi OSのイメージファイルを選択します。
![RaspberryPiImager_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/3a904b27-6ca9-13ad-cf03-154cf45cff2f.jpeg)

#４．書き込み先SDカードを指定する。
"Storage"ドロップダウンメニューから64-bit Raspberry Pi OSをインストールするSDカードを選択します。
![RaspberryPiImager_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/1ede1113-b7d9-c92a-1145-98ef79af9a27.jpeg)

#５．64-bit OSのイメージファイルの書き込み
64-bit Raspberry Pi OSのイメージファイルをSDカードに書き込む準備ができたので"WRITE"ボタンをクリックします。
![RaspberryPiImager_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/2d7fd7aa-f600-b44a-738a-b22540eab6c1.jpeg)

#６．起動
64-bit Raspberry Pi OSのイメージファイルの書き込みが終了したら、書き込みが終了したSDカードをRaspberry Pi 4B+ に差し込んで電源を入れます。すると64-bit Raspberry Pi OSで起動されました。初期設定のためのウインドウが表示されるので、初期設定を終わらせたら簡単に確認作業をしてみましょう。
![raspberry-pi-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/ed6ff81a-7599-1763-2b1e-8d86c62521f1.jpeg)

#７．確認
確認作業は、"uname -a"コマンドを使ってカーネルのバージョンを確認して、"gcc -v"でコンパイラーも確認しておきましょう。
![raspberry-pi-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1615141/ae35a952-3931-6964-8c63-ed76d7e075e1.jpeg)

#参考文献
https://qengineering.eu/install-raspberry-64-os.html
Webサーバのファイルをローカル環境にダウンロードする【scpコマンド】

ローカル環境で開発を進めるにあたって「本番環境やステージ環境に置いてあるファイルをローカルでも使いたい」みたいことがあると思います。そんな時に役立つLinuxのscpコマンドを簡単に紹介します。

##やりたいこと
Webサーバーに置いてあるファイルを、ローカル環境(今回はMacBook)にダウンロードしたい。
　→ターミナルからscpコマンドを叩くことで簡単に実現できます。

##scpコマンドとは？
scpコマンドは、リモートマシンとローカルマシンでファイルをコピーするLinuxコマンドです。(もちろんリモート同士でもOK)
この時の通信プロトコルにはsshを使用し、データ転送の通信を暗号化します。

このため前提としてWebサーバに対してssh接続できるようにしておく必要があります。

## 基本的な使い方
```sh
$scp [オプション] コピー元のパス 保存先のパス
```
## 実際にやってみる
ユーザ名@ホスト名でサーバーにssh接続できる前提で、/homeにある対象のディレクトリをコピー(ローカルマシンにダウンロード)してみたいと思います。

```sh
$ scp -i ~/.ssh/id_rsa -r ユーザ名@ホスト名:/home/'ディレクトリ名' ~/Downloads/'ディレクトリ名'
```
これでサーバーの/homeにあったディレクトリを、ローカルの/Downloadsにコピーすることができました。
`-i`オプションで秘密鍵ファイルを渡し、ディレクトリごと再帰的にコピーできるよう`-r`オプションを指定しています。
ファイルをダウンロードする場合は`-r`オプションは付けずに、ディレクトリ名の部分にファイルを指定すればOKです。

その他、使えるオプションもいくつかあって、

|付けるオプション|内容|
|:--|:--|
|-i　秘密鍵ファイル|秘密鍵ファイル(identityファイル)を指定する
|-P　ポート番号|ポート番号を指定する
|-C|通信を圧縮する|
|-p|コピー元の更新時間とモードを維持する
|-r|ディレクトリ内を再帰的にコピーする
|-1|SSHのプロトコルバージョン1を使用する
|-2|SSHのプロトコルバージョン2を使用する
|-4|IPv4を使用する
|-6|IPv6を使用する

などがあります。

個人的にはリモートのDBをdumpして、それをローカル環境での開発でテスト用に使いたいというシーンが多いかなと思いますが、いざというときにスッと使えるように各種オプションも含めて身に付けておきたいものですね。
MySQL+MyBatisでシーケンス(連番)を扱う

MySQLってシーケンスオブジェクトないんですね・・。auto_increment列使えよ〜ということなのかな？
軽くググってみると・・・LAST_INSERT_ID関数を使うとシーケンスっぽいことできるよ〜という記事がちらほら見つかりました。どうやら、この方法は公式のドキュメントでも紹介されている方法のようです。

* https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id

# 検証バージョン

* MySQL 8.0
* MyBatis 3.5.6

# テーブルを作る

```sql
create table sequence (
  name varchar(50) primary key,
  value   bigint
) ENGINE=MyISAM;
```

> **NOTE:**
>
> ENGINE=MyISAMにするとロールバックの影響を受けない（＝ロールバックしても番号が戻らない）ようにすることができる見たいです（MyISAMがトランザクションをサポートしていないからのようです）。

# Mapperを作る

```java
@Mapper
public interface SequenceMapper {

  @Insert("INSERT INTO sequence (name, value) VALUES(#{name}, LAST_INSERT_ID(1)) " +
      "ON DUPLICATE KEY UPDATE value = LAST_INSERT_ID(value + 1)")
  @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "value", before = false, resultType = long.class)
  void incrementAndGet(Sequence sequence);

  default long nextSequence(String name) {
    Sequence sequence = new Sequence();
    sequence.name = name;
    incrementAndGet(sequence);
    return sequence.value;
  }

  class Sequence {
    private String name;
    private long value;
  }

}
```

# シーケンス値を取得する

```java
@SpringBootTest
class MyTest {

  @Autowired
  SequenceMapper sequenceMapper;

  @Test
  void test() {
    Assertions.assertThat(sequenceMapper.nextSequence("file_id")).isEqualTo(1L);
    Assertions.assertThat(sequenceMapper.nextSequence("file_id")).isEqualTo(2L);
    Assertions.assertThat(sequenceMapper.nextSequence("order_id")).isEqualTo(1L);
    Assertions.assertThat(sequenceMapper.nextSequence("order_id")).isEqualTo(2L);
  }

}

```

# 参考サイト

* [MySQLで採番機能（シーケンス）を実装する方法を整理する](https://qiita.com/Nyokki/items/c68dddff2368c557c4bf#%E6%96%B9%E6%B3%95%EF%BC%93%E6%96%B9%E6%B3%95%EF%BC%91%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%92myisam%E3%81%AB%E3%81%99%E3%82%8B)

* https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id
Azure Static Web Appsの使い方 第1回「特徴と使いどころ」

# 連載予定

- [特徴と使いどころ](https://qiita.com/yyukawa/items/09b1f6b9d35d60b30716)
- Reactで作ったページをホスティングする
- GitHubアカウントで認証する
- カスタムドメインを利用する
- Functionsを組み込む
- Application Insightsを組み込む
- [Standard plan]フル機能のFunctionsを組み込む
- [Standard plan]Azure AD B2Cで認証する

# Azure Static Web Appsの特徴と使いどころ

個人が小規模なコンテンツを公開する場合は最強のサービスだと思います。
GA後もFreeプランが残ったというのが一番の特徴で、まずお金がほとんどかかりません。
カスタムドメイン、OpenID Connectに準拠したID Providerとの連携、Functions連携、URLのRewrite、CICDが統合済みになっているなど、手間もかかりません。
私も自分の子供のために作った知育ゲームをホスティングするのに使っています。

https://piyo.mysensei.work/

# Azureで静的コンテンツをホスティングする方法

Azureで静的コンテンツをホスティングする方法はいくつかあります。

| 手段                   | 特徴 | 制限 |
| ---------------------- | ---- | ---- |
| ストレージアカウント   |   大量の静的ファイルを扱う場合は必然的にこの選択肢になると思います。ゾーン冗長やリージョン冗長なども設定一つで実現することができますし、一定期間経過したコンテンツを削除したりすることもできます。   |   ストレージアカウントのみだとGETのリクエストしか受け付けることができず、URLのRewriteもできません。カスタムドメインを設定することもできないです。そのためAzure CDNやFront Door、Application Gatewayなどと組み合わせて使うことになると思います。   |
| Static Web Apps        |  カスタムドメイン、OpenID Connectに準拠したID Providerとの連携、Functions連携、URLのRewriteなど、一つ一つは特化した仕組みを提供しているサービスと比べると見劣りする部分はあるものの充実した機能を提供しています。SSLの証明書を用意する必要がない点も魅力です。小規模なコーポレートサイト、ReactアプリケーションやUnityのWebGLアプリケーションをホスティングするのには適していると思います。    |   配信対象のコンテンツの容量が有料のStandard planでも500MBしかありません。可用性についてもドキュメントが少なく、企業が大規模に使うのは現時点ではまだ早そうです。   |
| VM,VMSS,AKS,AppService |  従来のWebサーバと同じです。自由ですが、設計しなければいけないことが一番多くなります。    |   大規模配信には適さないと思います。コンテンツが少ない場合や流量が少ない場合の選択肢です。  |

# Azure Static Web Appsの制限

かなり厳しい制限があるので確認が必須なのですが、日本語のドキュメント（2021-06-26時点）は最新化されておらず、Previewの頃の情報しか掲載されていません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16609/8bd6187a-b2be-3c67-53e0-6326b79261e0.png)

https://docs.microsoft.com/en-us/azure/static-web-apps/quotas
UserLAnd/Termuxとandroidでファイルコピー

# 概要

- android上でLinux環境を構築するUserLAndやTermux
- これらのLinux環境と母体のandroidでファイルのコピーをする
- 環境はPixel4a 5G(android11)

# 準備

- android標準のファイルマネージャーを使えるようにする
    - Googleが配布しているFiles By Googleとは別物
    - 多くのandroidではデフォルトでは見えないようになっているので見えるようにする
- Google PlayからShortcut Makerをインストールする
    - https://play.google.com/store/apps/details?id=rk.android.app.shortcutmaker
    - 「Shortcut maker for DocumentsUI」というアプリは古いandroid用なので使えなかった
- Shortcut Makerを立ち上げてアクティビティを選ぶ
- 「ファイル」アプリを開いて「com.android.documentsui.files.FilesActivity」を選んで「ショートカットを作成」
- ホーム画面に「ファイル」のショートカットが作成される

# Termuxの場合

- androidからTermuxのホームディレクトリを参照する
    - ファイルのショートカットを立ち上げる
    - 左上の「≡」を開いて、Termuxを選ぶ
    - Linux側のホームディレクトリが表示されるので、ここでファイル操作ができる
- Linux側からandroidのストレージを参照する
    - termux-setup-storageを実行する
    - 権限を与える
    - ~/storage以下に各種ディレクトリへのシンボリックリンクが作られる
    - 公式情報: https://wiki.termux.com/wiki/Termux-setup-storage

# UserLAndの場合

- 公式情報: Importing and exporting files in UserLAnd
    - https://github.com/CypherpunkArmory/UserLAnd/wiki/Importing-and-exporting-files-in-UserLAnd
- ファイルのショートカットを立ち上げる
- 左上の「≡」を開く
- UserLAnd INTERNALが内部ストレージ
    - Linux環境での/storage/internalが見えている
- UserLAnd SDCARDがSDカード
    - Linux環境での/storage/sdcardが見えている
    - android側からもsdcardのAndroid/data/tech.ula/files/storageとして見えている
        - 通常のファイルマネージャーからも見える
bootstrapについて

### Bootstrapについて

HTML、CSS、JavaScriptを集めた巨大なコード(部品)の集まり。
利用することで簡単に整った見た目のページを作成できる。
全ての主要ブラウザに対応している。

### viewportについて
PCやスマートフォンなどの表示領域について横幅を指定することで、デバイスに対応した表示となる。
指定するには head 内の meta で指定する。

```
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">  
  <!-- content="width=device-widthは横幅をデバイスと同じにする
       initial-scale=1は倍率を1倍で表示する --!>
</head>
```

### メディアクエリについて
レスポンシブデザインの基本となる。
特定の表示環境に対してCSSを適用することができる。

```
@media (min-width: 500px) {
  /* ウインドウ幅500px以上の時に適用されるスタイル */
  body {
    background-color: #f00;
  }
}

@media (min-width: 750px) {
  /* ウインドウ幅750px以上の時に適用されるスタイル */
  body {
    background-color: #0f0;
  }
}

/*○○px以下を指定できる　max-width　もある*/
```
### グリッドシステムについて
Bootstrapにあるシステムで、横幅を12カラム(列)として、カラム数を指定することで要素を配置する。
必要に応じて使えばよい。
.container は決められた幅を持っており、表示サイズによって5つの段階を用意されている。
.container-fluid を使うとウィンドウ幅を変えたときに対応できる。

```
 <body>
        <!--　グリッドを使いたい範囲を囲うブロックレベル要素に class="container" を指定 --!>
        <div class="container">
            <!-- その中に class="row"を指定し、その中に要素を配置し、カラム数を指定 --!>
            <div class="row">
　　　　　　　　　<!-- 指定には class="col-画面サイズ-カラム数で指定" --!>
                <div class="col-md-6">col-md-6</div>
                <div class="col-md-6">col-md-6</div>
            </div>

　　　　　　 <div class="row">
                <!-- offset-画面サイズ-カラム数 でカラム数を指定すると空間を配置できる。 --!>
                <div class="col-md-5">col-md-5</div>
                <div class="offset-md-2 col-md-5">offset-md-2 col-md-5</div>
            </div> 
        </div>
    </body>
```
簡単なWebブラウザゲーム

簡単なWebブラウザゲームを作りました。
簡単に出来ますので是非挑戦してみてください。

```HTML
<!-- JavaScriptで当たりBoxを見つける -->
<!-- 新規作成  2021/6/26 -->
<!-- Author   乃木坂好きのITエンジニア -->


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>JavaScript Practice</title>
    <style>
        body {
            display:flex;
            flex-wrap:wrap;
        }
        .box {
            width:100px;
            height:100px;
            background-color:lightcoral;
            cursor:pointer;
            transition: 0.8s;
            margin: 0 8px 8px 0;
            text-align: center;
            line-height: 100px;
            
        }
        .win{
            background:gold;
            border-radius: 50%;
            transform:rotate(360deg);
        }
        .lose{
            transform:scale(0.9);
        }
    </style>
</head>
<body>
        
    <script>
    'use strict';
    
    const num = 7;  
    // 0-7までの数字をランダムに表示する    
    const winner = Math.floor(Math.random() * num);
          
        
        
    for(let i=0;i<num;i++){
        const div = document.createElement('div');
        div.classList.add('box');  
            
        
        div.addEventListener('click',() => {
            if (i === winner){
                div.textContent = 'Win!';
                div.classList.add('win');
            } else {
                div.textContent = 'Lose!';
                div.classList.add('lose');
            }
            
        });
        document.body.appendChild(div);
    }    
    
    </script>
</body>

</html>
```

num変数を変えて数を増やしたり、減らしたりすることもできます。
当たり、外れのメッセージを変えても良いでしょう。
CircleCI から artifact を一気にダウンロードするスクリプト

# 問題

artifact が大量にあるので、1個づつダウンロードするのが面倒くさい。
一気にダウンロードしたい。

# スクリプト

以下のスクリプトを実行するには [Personal API Tokens page](https://app.circleci.com/settings/user/tokens) で作成したトークンを環境変数 `CIRCLECI_TOKEN` に格納しておく必要がある。
  
```bash:download_artifacts.sh
#!/bin/bash
if [ "$1" = "" ]; then
  echo "usage: $0 job_number"
  exit 1
fi

project_slug=gh/{your-name}/{repo}  # ここを自分のリポジトリに合わせて変更する
job_number=$1
work_dir="results/${job_number}"
mkdir -p "${work_dir}"

curl --silent \
  -X GET "https://circleci.com/api/v2/project/${project_slug}/${job_number}/artifacts" \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header "Circle-Token: $CIRCLECI_TOKEN" \
| grep -o 'https://[^"]*' \
| grep 'xml' \
| xargs -P4 -I % wget --header="Circle-Token: $CIRCLECI_TOKEN" --directory-prefix "$work_dir" %
```

実行時にパラメタとして job number を渡す

```
$ sh download_artifacts.sh 99041
```

ダウンロードした結果は `results/` 配下に格納される。

```
$ tree results
results
└── 99041
    ├── rspec.xml
    ├── rspec.xml.1
    ├── rspec.xml.10
    ├── rspec.xml.11
    ├── rspec.xml.12
    ├── rspec.xml.13
    ├── rspec.xml.14
    ├── rspec.xml.15
    ├── rspec.xml.2
    ├── rspec.xml.3
    ├── rspec.xml.4
    ├── rspec.xml.5
    ├── rspec.xml.6
    ├── rspec.xml.7
    ├── rspec.xml.8
    ├── rspec.xml.9
```
Dockerの送信専用メールサーバー（Rocky Linuxのベースイメージ対応）

#はじめに
過去に投稿した「[Dockerの送信専用メールサーバー](https://qiita.com/takeyamajp/items/be4ccc61862de3b121bf)」を Rocky Linux ベースに対応しました。

**送信専用メールサーバー**
https://github.com/takeyamajp/docker-postfix

##特徴
+ メール送信機能だけのシンプルな Docker イメージです。
+ 動作に必要なメモリー量は、わずか 60MB 程度です。
+ アイドル時のCPU使用率は、ほぼゼロ％です。
+ このコンテナはPostfixのTLS暗号化通信をサポートしているため、業務用途にも安心して使えます。
> `ユーザー or 他のコンテナ` — TLS(任意) —> `このコンテナ` — TLS(送信先が対応していたら) —> `送信先メールサーバー`

+ タイムゾーンの設定ができます。（一般的な Docker イメージとは異なり、日本時間で運用できます。）
+ 送信可能な最大メールサイズはデフォルトで１０MBで、設定で変更可能です。
+ メール送信に使用するポート番号は、標準ポート：25、サブミッションポート：587、SMTPS：465 に対応しています。
（ポート 25 はデフォルトで無効になっています。）
+ 構成モジュールの完全な動作ログが Docker Logs に出力されます。

各種システムの通知用SMTPとして最適です。