OmniAICreator/Qiita-1.07M huggingface dataset:
[Django]テンプレートタグから直接JavaScriptの変数に値を渡す方法

# Background

`TemplateView`の`context_data`からhtmlにそのまま表示させたい時、下記の通りでタグをセットすると表示することができます。

```Python:views.py
from django.views.generic import TemplateView

class SampleTemplateView(TemplateView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['areas'] = ["japan","tokyo","osaka","nagoya","sapporo","sendai","fukuoka"]
        return context
```

```html:index.html
...
    <ul>
    {% for item in areas %}
        <li> {{ item }} </li>
    {% endif %}
    </ul>
...
```

- japan
- tokyo
- osaka
- nagoya
- sapporo
- sendai
- fukuoka

と表示。

しかし、Javascriptのライブラリを使って描画させたい時に直接値を渡したい場合があります。
ここでは渡す方法を紹介します。

# Failure

そのまま渡すと、、、

```html
<script type="text/javascript">
    var areas = "{{ areas }}";
    console.log(areas);
</script>
```

```text
[&#x27;japan&#x27;, &#x27;tokyo&#x27;, &#x27;osaka&#x27;, &#x27;nagoya&#x27;, &#x27;sapporo&#x27;, &#x27;sendai&#x27;, &#x27;fukuoka&#x27;]
```
となってシングルクオテーション、"<"、">"などが自動で変換されます。
文字列型なので正規表現で置換した後に `JSON.parse` でdict化でいいかなと思ったのですがうまくできず。

で、調べた結果二つの方法を見つけました。

# Method 1
泥臭いですが、各要素を呼び出してjavascriptコードに書き込む方法です。

```django
var areas = [
{% for area in areas %}
{% with index=forloop.counter0 %}
{% if 0 < index%},{% endif %}
{% endwith %}
"{{area.name}}"
{% endfor %}
];
console.log(areas);
```

# Method 2

もう一つは、`autoescape`で⾃動エスケープ制御をoffにする方法です。

```Django
{% autoescape off %}
var areas = {{ areas }};
{% endautoescape %}
console.log(areas);
```

こっちの方がラクです。

# Reference

- [Django 公式ページ 組み込みタグとフィルタ](https://docs.djangoproject.com/ja/3.0/ref/templates/builtins/#autoescape)
- [Django Template(テンプレート) HTMLタグをエスケープしないで表示する](https://opendata-web.site/blog/entry/3/)
- [Django Template Variables and Javascript](https://stackoverflow.com/questions/298772/django-template-variables-and-javascript)
- [現場で使える Django の教科書《基礎編》 7.4.8 autoescape （⾃動エスケープ制御） p77](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81/dp/4802094744)
AtCoderでRuby学習10【第一回アルゴリズム実技検定 DoubleCamelCase Sort】

## はじめに
Ruby学習の一環として「アルゴリズム実技検定」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「第一回アルゴリズム実技検定」の六問目（DoubleCamelCase Sort）より。
[第一回アルゴリズム実技検定 過去問](https://atcoder.jp/contests/past201912-open/tasks/past201912_f)

今回は、参考になった解答をもとに学ぶことが出来た内容をまとめていきたいと思います。


## 問題
文字列 S が与えられる。
これは、1 つ以上の単語を (間に空白などを挟まずに) 連結したものである。
ここで、各単語は 2 文字以上であり、最初の文字と最後の文字のみが英大文字、それ以外の文字は全て英小文字である。

制約
・S は長さ 2 以上 100,000 以下の文字列である。
・S の各文字は英大文字または英小文字である。
・S は問題文で述べたような単語の連結である。

入力は以下の形で与えられる。

```ruby
S

入力例
FisHDoGCaTAAAaAAbCAC
```

```ruby
出力例
=> AAAaAAbCACCaTDoGFisH
```

## 解答
今回参考にさせて頂く解答はこちらです。

```ruby
puts gets.scan(/[A-Z][a-z]*[A-Z]/).sort_by(&:upcase).join
```
受け取った文字列に対して、単語ごとに要素としてまとめて配列化。
sort_byメソッドを使って並び替えた後、joinメソッドを使って配列の要素全てを連結して出力という流れ。

それぞれのメソッドについてや、正規表現での表現について以下にまとめていきます。

### scanメソッド
オブジェクトに対し、()内に指定したパターンを繰り返しマッチし、マッチした部分文字列を配列として返します。

```ruby
p "test".scan(/../)
#=> ["te", "st"]
p "test".scan("t")
#=> ["t"]
p "testet".scan(/te./)
#=> ["tes", "tet"]
```
大文字で始まり、大文字で終わる単語を取り扱う今回のようなケースでは最適なメソッドですね。

### 正規表現部分
今回取り扱う単語を正規表現で表現すると以下のようになります。

```ruby
/[A-Z][a-z]*[A-Z]/
```

**/ /**
//で囲むことで正規表現オブジェクトを生成することが出来ます。
つまり、「//で囲まれたものが正規表現だよ」という宣言になります。

**[ ]**
角括弧[ ]で挟まれた部分を文字クラスと言います。
1個以上の文字を列挙したもので、いずれかの1文字にマッチします(上記では0から9のうち1文字)。

**[A-Z]**
1文字の大文字英字を表しています。

**[a-z]**
1文字の小文字英字を表しています。

*
直前の表現を0回以上繰り返すという意味のメタ文字になります。
今回の場合は小文字英字が0回以上繰り返されるという意味になり、
3文字以上の英単語が示される際、大文字の間に挟まれるのは必ず小文字、という意味になります。

これで、問題の指定に沿った単語にマッチ出来るようになりました。
                    
### sort_byメソッド
配列の中身を比較して並び替え、並び替えた状態の配列を新たに作ってくれます。
()内にて、正しく比較をするためにupcaseメソッドを各要素に当て、全て大文字にしてから比較しています。
※そのままだとabcという順番よりも、大文字ABC...小文字abc...という順番で並び替えてしまうため。

```ruby
p ["AA", "AC", "AaA"].sort_by(&:upcase)
#=>["AA", "AaA", "AC"]
```

### joinメソッド
配列の要素を括弧()内に指定した区切り文字を挟んで連結した文字列を返します。
()を記述しなかった場合は、区切り文字なしで連結されます。

```ruby
p ["AA", "AaA", "AC"].join(",")
#=>AA,AaA,AC
p ["AA", "AaA", "AC"].join
#=>AAAaAAC
```


## 最後に
以上、「第一回アルゴリズム実技検定」の六問目（DoubleCamelCase Sort）で学んだメソッドについてまとめました。
正規表現や様々なメソッドを使って、今回参考にさせて頂いた解答のように簡潔で分かりやすい解答が出来るようにしていきたいものです。

もし間違いなどございましたら、ご指摘いただけると嬉しいです。
【コピペでできる】PythonでWebスクレイピング

#はじめに
この記事はプログラミングを始めて1ヶ月ほどの初心者でもできた内容となっているので上級者の方には少しつまらなく感じてしまうかもしれませんがご了承ください。
※プラス初投稿なのでお手柔らかに

#Webスクレイピングとは

Webスクレイピングとは、WebサイトのHTMLから必要な情報を抽出するコンピューターソフトウェア技術です。

データを抽出するにあたって、Webスクレイピングが規約に反してしまうサイトもあるのでちゅういしてください。

ex ) TwitterはAPIの利用が必須なので無断で使用すると法的に罰せられる可能性があります。


#使用したもの
<ul>
<li><strong>Python</strong></li>
<li><strong>Requests</strong></li>
<li><strong>Beautiful Soup</strong></li>
<li><strong>Jupyter Notebook</strong></li>
</ul>

言語はPythonを使用しました。

ただ、今回の内容は特にPythonを覚えたりはしなくてもコピペでできるので初心者の方でも安心してご覧ください。
※Jupyter Notebookはインストールしてあるものとします。インストールできていない方は先にインストールしておきましょう。

>Requestsは、Apache License 2.0の下でリリースされたPython HTTPライブラリです。-Wikipedia


>Beautiful Soupは、HTMLおよびXMLドキュメントを解析するためのPythonパッケージです。-Wikipedia

説明をしていても何も始まらないので早速作業に入っていきましょう。

なお、この記事は[https://www.sejuku.net/blog/51241](https://www.sejuku.net/blog/51241)を参考にしています。

#早速やってみよう

まずはRequestsとBeautiful Soupをインストールします。

Windowsならコマンドプロンプトに、macならターミナルに次のコードを入れます。

※pipでインストールします。

```

pip3 install requests
```
Enterでインストールが始まります。

```
pip3 install beautifulsoup4
```
Enterでインストールが始まります。

インストールが終わったらJupyter Notebookを開きます。

Pythonでファイルを作成し、以下のコードをコピペします。

```python
import requests
from bs4 import BeautifulSoup
	
r = requests.get("https://news.yahoo.co.jp/")
	
soup = BeautifulSoup(r.content, "html.parser")
	
#ニュース一覧のテキストのみ抽出
print(soup.find("ul", "newsFeed_list").text)
```

このコードでは先ほどインストールしたRequestsによってヤフーニュースの情報を取得してBeautiful Soupで要素を抽出しています。

このコードを動かしてみるとHTMLが返ってきます。

"ul" の "newsFeed_list" の部分だけ返ってきていると思います。

さて、そのコードを別のHTMLファイルに貼り付けて開いてみましょう。

ヤフーニュースの「おすすめ記事」のコードを取得できているはずです。

実際のページと見比べてみるのも面白いです。

#まとめ

今回は初心者向けにコピペでできるWebスクレイピングの方法を書いてみました。

Qiita自体始めて使用したので記事作成にかなり時間を費やしてしまいましたがこれからも学んだことをアウトプットしていこうと思います。

気になる方はぜひフォローをお願いします。。

最後までご覧いただきありがとうございました。
AWS EC2インスタンスにtermiusから接続する

スマホでEC2入れたら便利じゃね？的な

# 前提

- Termiusがスマホに入ってる
- AWS EC2インスタンスが立ち上がってる

[Termius](https://termius.com/android)はスマホでターミナルがいじれるアプリだよ

# 1. pemファイルをスマホに送る

インスタンスを作るときにpemファイルをダウンロードしたと思います（してなかったらインスタンスを作り直そう、pemファイルは一回しかダウンロードさせてくれないので）
これを、スマホにbluetoothなりslackの自分宛てのDMなりで送ります

# 2. TermiusにKeychainを追加

Termiusのアプリの、右のメニューを開いてKeychainを選択
+ボタンを押して、Import Keyを選択 
:arrow_right: さっきスマホに転送したpemファイルを選択

ファイルの中身を見ると`---BEGIN RSA PRIVATE KEY---`とかも入るけど、これは**消さないでそのままでok**
（消しちゃうと`Invalid RSA Key`とか怒られる）

# 3. Termiusに新しいHostを追加

Hostsのタブを開いて、New Hostを選択
以下の項目を設定していきます

## Alias

Hostのあだ名
「AWS EC2」でも「ほげ太郎」でも自分がわかればok

## Host name or IP Address

これはIP Addressの方を入力する
EC2のダッシュボードにいって、IPV4 PublicのとこにあるIPを入力する

## Username

`ec2-user`を入れる
基本的にこれでいけるはずだけど、設定を自分でいじった人は違うかも

## Key

2で追加したKeychainを選択
（入力するとこをタップすると、Select keyという画面になるので、そこでさっきのファイルをタップすればok）

## その他の項目

:arrow_up: 以外のところは何も入力しない


# 4. 接続してみる

Hostsの画面で、今つくったHostをタップして、黒い画面が出ればok
おめしゃす :tada:
npm listを見やすく（yarn listライクにする）

# `npm list --depth=0`を使おう！

```shell
npm list --depth=0

npm list -g --depth=0
```

## `yarn list`は見やすい

```
$ yarn global list                                                                                                     17:22:38
yarn global v1.22.4
info "create-react-app@3.2.0" has binaries:
   - create-react-app
info "flow-typed@2.5.1" has binaries:
   - flow-typed
info "gitmoji-c@0.2.1" has binaries:
   - gitmoji
info "nodemon@1.18.10" has binaries:
   - nodemon
info "now@18.0.0" has binaries:
   - now
info "pm2@3.5.1" has binaries:
   - pm2
   - pm2-dev
   - pm2-docker
   - pm2-runtime
info "prettier-eslint-cli@5.0.0" has binaries:
   - prettier-eslint
info "react-native@0.61.5" has binaries:
   - react-native
info "typescript@3.9.2" has binaries:
   - tsc
   - tsserver
info "wml@0.0.83" has binaries:
```

## `npm list`は見にくい
依存関係がでてしまう。

```shell
$ npm -g list                                                                     
/Users/user2/.anyenv/envs/nodenv/versions/12.16.1/lib
└─┬ npm@6.13.4
  ├── abbrev@1.1.1
  ├── ansicolors@0.3.2
  ├── ansistyles@0.1.3
  ├── aproba@2.0.0
  ├── archy@1.0.0
  ├─┬ bin-links@1.1.6
  │ ├── bluebird@3.5.5 deduped
  │ ├── cmd-shim@3.0.3 deduped
  │ ├── gentle-fs@2.3.0 deduped
  │ ├── graceful-fs@4.2.3 deduped
  │ ├── npm-normalize-package-bin@1.0.1
  │ └── write-file-atomic@2.4.3 deduped
...
```

* * * 

それをoption `--depth=0` でネスト表示（依存関係表示）の階層を0にする
Safariの文字入力でハマった

# シングルクォーテーションだけ入力チェックが正しく動かない

inputタグへの入力文字の制御を行なっていて、PCブラウザやAndroidでは上手くいくのに、iOSだけシングルクォーテーションがうまくいかずハマりました。

## keydownイベントでは問題ない

keydownイベントのevent.keyを確認しましたが文字コード0x27「'」で問題なく処理されます。

## inputイベントに問題あり

event.target.valueをログ出ししていて、文字コードが0x27「'」でないことに気付きました。
入力の一文字目は\u2018「‘」、二文字目以降は\u2019「’」に勝手に変換されるようです。

下記のコードで変換かけてあげて回避できました。
```
event.target.value = event.target.value.replace(/[\u2018\u2019]/g, '\'');
```
AngularFire 6とAngular 9では、AngularFireAuthが少し変わったよ！

#はじめに
Angularを使ってる人たちにはお馴染みの[AngularFire](https://www.npmjs.com/package/@angular/fire) 

こいつが**Angular 9**にアップグレードされたのに合わせて、最新バージョンが**AngularFire 6**となりました（2020年5月現在）

それによって変わった点を１つ紹介（たくさんあると思うので、詳しくは[こちら](https://github.com/angular/angularfire/blob/master/CHANGELOG.md)を見てね:thumbsup:）

#よく使うであろうAngularFireAuthが変わった
**Before Version 6**

```typescript
export class UserService {

  constructor(public afAuth: AngularFireAuth) {}

  signIn(): Promise<auth.UserCredential> {
    return this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
  }
  signout(): Promise<void> {
    return this.afAuth.auth.signOut();
  }
}
```
**In Version 6**
`this.afAuth.signInWithPopup`のように、`auth`が無くなった！！

```typescript
export class UserService {

  constructor(public afAuth: AngularFireAuth) {}

  signIn(): Promise<auth.UserCredential> {
    return this.afAuth.signInWithPopup(new auth.GoogleAuthProvider());
  }
  signout(): Promise<void> {
    return this.afAuth.signOut();
  }
}
```

`currentUser`も同じように変わったようです。

**Before Version 6**

```typescript
sendEmailVerificationLink(): Promise<void> {
    return this.afAuth.auth.currentUser.sendEmailVerification();
  }
}
```
**In Version 6**

```typescript
sendEmailVerificationLink(): Promise<void> {
    return this.afAuth.currentUser.then((user) => {
      return user.sendEmailVerification();
    });
  }
```
QiitaでLGTMした記事・ストックした記事の一覧はどこ？（2021.05〜）

# LGTMした記事の一覧（2021年5月現在）
マイページ下、タブ切り替えのなかにあります。
![スクリーンショット 2021-05-09 2.01.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/0f46efc2-502b-6bd5-1cfa-d4fcf7f7148d.png)

# ストックの一覧
右上のアイコンから開いたメニューのなかにあります。
![スクリーンショット 2021-05-09 2.03.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410392/6501e911-c4ab-8de4-a7bf-f54a43619024.png)


# さいごに
いつのまにか場所が変わっていて、またしても探してしまったのでアップデートしておきます。
エラー”DHT12' has no member named 'readTemperature'でつまづいた話


## 概要
M5StickCでENV HAT（DHT12搭載)を使用しようと、ArduinoIDEで公式ドキュメントを参考に基本コードを書こうとしたら、”DHT12' has no member named 'readTemperature' のエラーでつまづいた話。

## 訂正前コード（公式ドキュメント参考）

```ruby:envhat.ino
#include <M5StickC.h>
#include <DHT12.h>
#include "Adafruit_Sensor.h"

DHT12 dht12;
float tmp;
float hum;

void setup() {
  M5.begin();
}

void loop() {
float tmp = dht12.readTemperature(); 
    float hum = dht12.readHumidity(); 
    M5.Lcd.setCursor(0, 20, 2); 
    M5.Lcd.printf("Temp: %2.1f Humi: %2.0f%%", tmp, hum); 


省略
}
```

そうすると、>> DHT12' has no member named 'readTemperature' ENVのエラーがかえってきます。

## 問題点

直接DHT12のライブラリを参照してみると、readTemperatureではなく、getTemperatureになっていました。

## 訂正後

````ruby:envhat.ino
float tmp = dht12.getTemperature(); 
    float hum = dht12.getHumidity(); 
    M5.Lcd.setCursor(0, 20, 2); 
    M5.Lcd.printf("Temp: %2.1f Humi: %2.0f%%", tmp, hum); 
````

## 参考

ENV HAT
https://www.switch-science.com/catalog/list/?keyword=ENV+HAT

Git HUB公式ドキュメント
https://github.com/m5stack/M5StickC/tree/master/examples/Hat/ENV
【Xamarin.Forms&Prism入門】ボタンの配置とタップされたときの処理を書く（コードビハインド編）

# はじめに
Xamarin.Forms&Prism入門2回目です。
（前回：https://qiita.com/ats_y/items/8ac1123505840f9de818）

今回は画面にボタンを配置してタップされたときの処理を作ります。

タイトルに【Xamarin.Forms&Prism入門】とありますが、今回はPrismはなしです。

*本記事にでてくるプログラムはアプリ名を「XamarinBasic」として[Prism Template Packを使わないでXamarin.FormsソリューションにPrismを適用する](https://qiita.com/ats_y/items/f76098612786b3e9cf4a)の手順で作成したものをベースに説明します。*

# 画面にボタンを配置する

MainPage画面にボタンを配置します。
PCLプロジェクトのMainPage.xamlにボタンの定義を追加します。
<img width="1302" alt="スクリーンショット_2020-05-24_15_07_45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/c6f37d4e-1175-f282-1085-a96ba6436005.png">


```XML
<Button
  Text="ぼたん"/>
```

赤枠線で囲んだ内容を追加しました。
右側に表示しているプレビュー画面にも追加したボタンが表示されます。

xamlファイルはXMLです。XML要素の親子関係が画面部品の親子関係になります。
今回は[StackLayout要素](https://docs.microsoft.com/ja-jp/dotnet/api/xamarin.forms.stacklayout?view=xamarin-forms)の小要素として[Button要素](https://docs.microsoft.com/ja-jp/dotnet/api/xamarin.forms.button?view=xamarin-forms)を追加したので、StackLayoutの中にButtonを配置したことになります。
StackLayoutが見えていないのでわかりづらいですが、以下のような構成になっています。
![ボタンの配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/81f067d0-8a22-4da4-259d-79869dbb2e3a.png)

# ボタンがタップされたときの処理を定義する

追加したButton要素に`Clicked="Button_Clicked"`属性を追加して[Clickedイベント](https://docs.microsoft.com/ja-jp/dotnet/api/xamarin.forms.button.clicked?view=xamarin-forms)を定義します。

```XML:MainPage.xaml
<Button
  Text="ぼたん"
  Clicked="Button_Clicked"/>
```

次にMainPage.xamlのコードビハインドであるMainPage.xaml.csにClickedイベントのイベントハンドラ（イベントが発生した時に動かす処理）となるメソッドを作成しますが、[ボタンのClickedイベント](https://docs.microsoft.com/ja-jp/dotnet/api/xamarin.forms.button.clicked?view=xamarin-forms)は[EventHandler型](https://docs.microsoft.com/ja-jp/dotnet/api/system.eventhandler?view=netstandard-2.0)なので、メソッドの戻り値・引数はEventHandler型に合わせます。
メソッド内にはボタンがタップされたときに動かしたい処理を書きます。
今回はとりあえずデバッグ出力処理を書きました。

```cs:MainPage.xaml.cs
private void Button_Clicked(object sender, EventArgs args)
{
    Debug.WriteLine("ぼたんがクリックされた");
}
```

# 動かしてみる

`Debug.WriteLine("ぼたんがクリックされた");`の行にブレークポイントを設定してデバッグ実行してみましょう。
<img width="1368" alt="スクリーンショット_2020-05-24_16_07_16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/00561db2-8695-9d46-e3c1-c1f52ee7f684.png">

エミュレータが起動したら追加したボタンをタップしてみます。
<img width="554" alt="スクリーンショット 2020-05-24 16.12.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/c00899f4-4927-2bcd-f85e-e3ff0ac8ba0a.png">
設定したブレークポイントでプログラムが一時停止します。
ボタンをタップしたらイベントハンドラが動いた証拠ですね。
<img width="1048" alt="スクリーンショット_2020-05-24_16_16_17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/e02895a7-b1b7-7de3-fb02-8ef1ea35fede.png">

ローカルウィンドウで引数senderの中身をみてみるとタップしたボタンのオブジェクトが格納されていることがわかります。

# まとめ

Xamarin.Formsでは画面レイアウトはXamlファイル（{画面名}.xaml）に記載し、イベントハンドラなどの画面に関連する処理はコードビハインド（{画面名}.xaml.cs）に定義します。
文系エンジニアが量子コンピュータの勉強をする方法

#この記事の目的
　高校でまともに理系科目を学習していなかった自分が、量子コンピュータのプログラミングをするために実践している勉強法の整理と共有。

#想定する読者
　文系だけど量子コンピュータに興味があって勉強をしたいSE

#必要となる数学・物理学の知識
- 大学レベル
 - 量子力学
 - 線形代数
- 高校レベル
 - 高校数学全般
 - 高校物理全般 

どこまで含めるかは人によると思います。特に高校レベルの数学、物理は必要な単元のみ学習する感じで良いと思います。

私の場合、初めは量子力学と線形代数だけで学習すれば良いかと思っていましたが、高校レベルの数学・物理の知識がないと、いろいろと理解できないことが出てきたので、結局のところ高校レベルも全般的に学習しています。

複素数やネイピア数などが当然のように出てくるので、「複素共役って何？」とかそういうレベルだと厳しい。

#学習教材
以下、私が勉強に利用させていただいている教材を紹介します。
書籍以外は全て無料です。

##予備校のノリで学ぶ「大学の数学・物理」（Youtubeチャンネル）
講師：たくみさん
URL：https://www.youtube.com/channel/UCqmWJJolqAgjIdLqK3zD1QQ
チャンネル概要：大学レベルの数学や物理学の講義を予備校のクオリティで提供することを目指すチャンネル。前提として高校レベルの数学や物理の知識が必要となることも多いが、とてもわかりやすくて助かっています。

・量子力学入門 全10講
https://www.youtube.com/playlist?list=PLDJfzGjtVLHlY9nsj_zhgWhyOHnitF4xK

・線形代数入門 全14講＋α
https://www.youtube.com/playlist?list=PLDJfzGjtVLHnc1vTpBaCNKMUl6HauQv1a

##とある男が授業してみた（Youtubeチャンネル）
講師：葉一（はいち）さん
URL：https://www.youtube.com/user/toaruotokohaichi
チャンネル概要：中学生から高校生向けに大量の授業動画が投稿されている。高校レベルの数学を勉強し直したい場合に非常に助かる。

##映像授業 Try It
URL：https://www.youtube.com/channel/UCcj-cHmS0uD91MLjtdiN89Q
チャンネル概要：家庭教師で有名なTryが無料で公開している授業動画。無料だが出し惜しみはなく、とても分かりやすい。

・高校物理 運動と力
https://www.youtube.com/playlist?list=PLfOJcbz0N8NBSdyJQbvU_I8k173txhuTw
・高校物理 波動
https://www.youtube.com/playlist?list=PLloBnmWZfFUWwiooyavUjwGEEVvuj6t2g
・高校物理 電磁気
https://www.youtube.com/playlist?list=PLloBnmWZfFUW0QdfgaGiq6jWHw2xZ_MjI

##書籍
・いちばんやさしい量子コンピューターの教本
ビジネスマン向けに量子コンピュータを解説した本。量子コンピュータの現状や既存のコンピュータとの違い、ビジネスへの応用などについて書かれている。概要を理解したければこれ。
https://www.amazon.co.jp/dp/4295006076/ref=cm_sw_r_cp_awdb_c_cAFYEbG1WFBSG

・みんなの量子コンピュータ
より詳しい原理や回路について書かれている本。本格的に勉強するならこれ。
https://www.amazon.co.jp/dp/4798163570/ref=cm_sw_r_sms_awdb_c_ayFYEb1QAZNRS

##WEB
・Blueqat
https://blueqat.com/?hl=ja
Pythonで量子プログラミングをはじめられるプラットフォーム。Blueqatというオープンソースライブラリを公開しており、チュートリアルも充実している。量子コンピュータのプログラミングを実際にやりはじめるならここ。

・Quantum Native Dojo
https://dojo.qulacs.org/ja/latest/index.html
 有志（？）が作った量子コンピュータの自習用教材。ちゃんと数式を交えた解説が書かれている。足りない数学の知識は上記のYoutubeチャンネル等で補完する。

#最後に
当面の目標は、blueqatでプログラミングをしながら量子コンピュータを理解していきたいと思っていますが、知識不足でチュートリアルなど理解できない部分にぶち当たるので、今後も基礎学習を続けます。
Python速度比較 regex vs startswith vs str[:word_length]

# Python速度比較 regex vs startswith vs str[:num]
## はじめに
Ptyhonである文字列の前方一致を判定する方法はいくつかある。
その中で代表的な以下の3つの速度比較を行う。

- 正規表現
- startswith
- str[:word_length] == word

## 測定方法
### 環境
以下の実行環境で実施する

| 項目 | 値 |
| --- | --- |
| Python Version | 3.8.2 |
| OS | Ubuntu 20.04 |

### プログラム

以下のプログラムを基準にして動作を確認する。なお各変数と各関数の役割は以下の通りである。
計測したい特性に応じて変数を変化させる。

| 変数/関数 | 説明 |
| --- | --- |
| time_logging | 時間を計測するためのデコレータ |
| compare_regex | 引数の文字列のリストのそれぞれを正規表現で比較する |
| compare_startswith | 引数の文字列のリストのそれぞれを`startswith`メソッドで比較する |
| compare_str | 引数の文字列のリストのそれぞれの最初の文字列が`target_word`と等しいかを比較する |
| target_word | 比較対象となる文字列 |
| match_word | `target_word`とマッチする文字列のプレフィックス |
| not_match_word | `target_word`とマッチしない文字列のプレフィックス |
| compare_word_num | 比較する文字列を総数 |
| compare_func | 測定する関数 |
| main | 呼び出される関数 |


```python
import re
import time


def time_logging(func):
    def deco(*args, **kwargs):
        stime = time.time()
        res = func(*args, **kwargs)
        etime = time.time()
        print(f'Finish {func.__name__}. Takes {round(etime - stime, 3)}s.', flush=True)
        return res

    return deco


@time_logging
def compare_regex(compare_words):
    pattern = re.compile(f'^{target_word}')
    for word in compare_words:
        if pattern.match(word):
            pass


@time_logging
def compare_startswith(compare_words):
    for word in compare_words:
        if word.startswith(target_word):
            pass


@time_logging
def compare_str(compare_words):
    length = len(target_word)
    for word in compare_words:
        if word[:length] == target_word:
            pass


target_word = f'foo'
match_word = f'{target_word}'
not_match_word = f'bar'
compare_word_num = 100_000_000
match_rate = 50
compare_func = compare_regex


def main():
    compare_words = []
    for index in range(compare_word_num):
        if index % 100 <= match_rate:
            compare_words.append(f'{match_word}_{index}')
        else:
            compare_words.append(f'{not_match_word}_{index}')

    compare_func(compare_words)


if __name__ == '__main__':
    main()

```

### パラメータ
比較対象の文字列の長さで実行速度の傾向が変わる可能性があるため、
`target_word`を5文字, 10文字, 50文字, 100文字, 500文字と変化させたときの`compare_regex`, `compare_startswith`, `compare_str`の実行速度をそれぞれ計測する。




## 測定

単位(秒)

|関数\文字数|5|10|50|100|500|
|:-:|:-:|:-:|:-:|:-:|:-:|
|compare_regex|11.617|12.044|16.126|18.837|66.463|
|compare_startswith|6.647|6.401|6.241|6.297|6.931|
|compare_str|5.941|5.993|4.87|5.449|8.875|

![chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235240/2d8d3a59-36a6-65d2-ccef-a91b76ad8c77.png)

## 考察
速度的には、あらゆる文字数で`startswith`または、`str[:word_length]`で実装すべきである。比較対象の文字列の影響をもっとも受けない`startswith`がもっともおすすめ。
また可読性という観点でも一番好き。
AWS Lambda で遅延情報を通知してくれる Slack bot を書いてみた

# はじめに
- 以前AWS Lambdaを用いて作成したSlack Botについてまとめる機会があり、せっかくなので備忘録含めQiitaにも投稿しようと思いました。
- 作成当時の記憶はだいぶ薄れておりますが、覚えている範囲で引っかかったところなどどなたかの参考になれば幸いです。

※ 本記事のbotを作成したのは約2年前なので、現在の仕様と乖離する部分もありますがご了承ください。 
※ 作成したbotそのもののソースは以下となります。
  https://github.com/spinrock/delayTrainBot

# そもそもSlack bot作成に至った経緯
- 筆者の家は、複数路線の駅に挟まれた立地にあり、駅から別の駅への移動が大変でした。
    - 駅に到着後に遅延に気付いても別の路線に乗る(駅を移動する)、という選択肢をとることが難しい状況でした。
- 起床時に自分で路線情報を確認できればいいのだが、朝の時間帯はバタバタしていることが多く、見逃す日も多分にありました。
    - 普段から確認するツール(LINEやSlack)に通知が来て教えてくれると便利なのにと感じておりました。
- Lambda(を含むFaaSやSaaS)で何かを作ることに純粋に興味があり、この際なので自作してみようと思いました。
- (当時の職業柄コーディングをしないため、久々にプログラミングしたくなったのも理由の一つです。)

# やりたいこと
- 朝起きてから電車に乗る手前くらいの間で、電車が遅延したら自動で通知して欲しい。
    - 月~金の朝7~9時くらいの間
    - 通知先はSlackの指定したチャネル

# 構成図と処理イメージ
- draw.io (https://www.draw.io/) で書いてみました。
- 使っていた言語はPython3.x系です。
<img width="889" alt="スクリーンショット 2020-05-24 15.54.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142830/88a0c6b4-7722-9980-f404-cd56c5811a68.png">

# 利用した技術の簡単なご紹介
- AWS Lambda : イベント駆動(何か(=イベント)をきっかけにして動く)のアプリケーションを実行できるAWSのサービス
    - https://aws.amazon.com/jp/lambda/
- Amazon CloudWatch : リソースとアプリケーションの監視/管理サービス
    - 今回はその中のCloudWatch Event(特定のルールを基にターゲット(Lambdaなど)へイベントを振り分ける機能)を利用しました。
    - https://aws.amazon.com/jp/cloudwatch/
- スクレイピング : Webサイトから取得した情報からHTMLタグを利用して情報を抽出する技術
    - 今回はPythonのスクレイピングライブラリの一つである「Beautiul Soup」を利用しました。
    - https://www.crummy.com/software/BeautifulSoup/bs4/doc/
- Slack Incoming Webhooks : HTTPリクエストを利用して特定のチャネルに指定したメッセージを投稿するアドオン(のようなもの)
    - 作成していた当時と仕様が変わり、作成したSlack アプリケーションに対してIncoming Webhookを付与できるようです。
    - https://api.slack.com/messaging/webhooks

# できたもの(Slack 画面)
- ↓の画像のようになりました。(10分おきに確認して通知してくれます。)
![スクリーンショット 2020-05-24 14.20.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142830/13952f25-4c73-7884-442d-fea3ad605cfb.png)

# 実際にしばらく使ってみて思ったこと
- 最初困っていたことは無事解決できました。
    - 朝通知が来ることで遅延していない路線(駅)を選べるようになりました。
- 遅延が解消した時に通知してくれるといいな、と思いはじめました。
    - 現状は通知が来なくなることで遅延が解消したことを判断する仕様となっています。
- これ以外にもいろいろBot化させたら便利だろうなと感じました。
    - 買い物メモとか、今日の予定(荷物の到着など)とか...

# (最後に)引っかかったことなどなど
- 通知のタイミングがおかしいなと思ったら、時刻指定がUTCでした。
  - 日本時間に直すために+9:00する必要がありました。
- 情報取得&スクレイピング処理に時間がかかっていた結果、Lambdaがタイムアウトしていました。
  - Lambdaのデフォルトタイムアウトが3秒なので、必要に応じて変更する必要がありそうです。(後からでもGUIで変更可能でした。)
Windows で .tar.zst を解凍する

近頃、`.tar.zst` 形式のファイルを目にする機会が急に増えたように思います。
Facebook が開発した圧縮アルゴリズム [Zstandard](https://facebook.github.io/zstd/) (zstd) を使って圧縮されたファイルですね。

最近の Linux に入っている [GNU Tar](https://www.gnu.org/software/tar/) は zstd を標準でサポートしていて、`-a` で勝手になんとかしてくれます。
しかし、Windows に標準で入っている bsdtar では zstd はサポートされていません。

Chocolatey などで zstd をインストールして、下記のコマンドで解凍できます。

```sh
zstd -dc ANYFILE.tar.zst | tar -xf -
```

普通にパイプを通して標準入出力で渡してやるだけです。簡単だね。
標準入力として `-` を使うのは Windows では見かけたことがなかったので、ちょっと手こずりました。

`tar -xf ANYFILE.tar.zst --use-compress-program="zstd -d"` でもできそうな感じですが、私の環境ではうまくいきませんでした。

おわり
Shell Script （変数編）

#はじめに
こちらではShellScriptの変数について紹介していきたいと思います。

#基本
まずは基本的なところから

```sh:test.sh
#!/bin/sh

VAR="test"

#よみとり専用
readonly VAR2="test2"

echo $VAR
VAR2="test"
```
実行結果

```
$./test.sh 
test
./test.sh: 9: ./test.sh: VAR2: is read only
```

#そのほか格納できるもの
コマンド結果など

```sh:test.sh
#!/bin/sh

#結果を格納する場合``で囲う
VAR=`ls`

#こう言った書き方も（ネストしたりなど柔軟にかける）
VAR２=$(ls)

echo $VAR
echo $VAR2
```

結果

```
$./test.sh 
test.sh
test.sh
```

標準エラーを格納

```sh:test.sh
#!/bin/sh

#">/dev/null"でもとの標準出力をすてる
#※"2>&1"で標準エラーを標準出力へとリダイレクト 
VAR=`ls hoge 2>&1 >/dev/null`

echo $VAR
```

実行結果

```
$ ./test.sh 
ls: cannot access 'hoge': No such file or directory
```

補足:入出力にはそれぞれ番号が振られています（※の部分）
今回は２>&1なので標準エラー>標準出力とさせていただいてます


0: 標準入力
1: 標準出力
2: 標準エラー出力

#参照

まず基本から

```sh:test.sh
#!/bin/sh


VAR="Hallo"
VAR2="World"

#基本的な出力
echo $VAR
echo $VAR2

#結合
echo ${VAR}${VAR2}

#変数の内容を格納
VAR3="$VAR"

#変数の内容を結合して格納
VAR4="${VAR} ${VAR2}"

echo $VAR3
echo $VAR4
```

##特殊な参照(NULLや未使用チェックに)

```sh

#＄VARが未使用   =>   $VARへ文字列「hoge」を代入し文字列「hoge」を返す
#使用していれば＄VARの内容を返す
${VAR:=hoge}

#$VARが「未使用」or「NULL」   =>   $VARへ文字列「hoge」を代入し文字列「hoge」を返す。
#使用していれば＄VARの内容を返す
${VAR=hoge}

#$VARが未使用   =>   変数に代入は行わず文字列「hoge」を返す
#$VARが「NULL」を含み既に使用されている   =>   $VARの値を返す
${VAR-hoge}

#$VARが「未使用」or「NULL」   =>   変数に代入は行わず文字列「hoge」を返す
#$VARが「NULL」以外の値で既に使用されている   =>   $VARの値を返す。
${VAR:-hoge}

#$VARが「NULL」も含み既に使用されてる   =>   変数に代入は行わず文字列「hoge」を返す
#$VARが「未使用」   =>   NULL 値を返す
${VAR+hoge} 

#$VARが「NULL」以外で既に使用されている   =>   変数に代入は行わず文字列「hoge」を返す
#$VARが「NULL」もしくは「未使用」   =>   NULLを返す
${VAR:+hoge} 
```

##特殊変数
```sh
#直前に実行されたコマンドのステータス
$?

#バックグラウンドで実行されたコマンドのプロセスID 
$!

#コマンド自身の PID (プロセスID)
$$

#実行時の引数の数（値ではなくあくまで個数）
$#
```

#まとめ
いかがだったでしょうかまだまだありますか。
量が多いのでよく使いそうな部分だけをピックアップしました。
また使用頻度が高い物があれば出していきたいとおもいます。
実写をアニメ風に変換してくれるWhite-box Cartoonizationやーる（Windows10、Python3.6）

# はじめに
実写をアニメ風に変換してくれるWhite-box-Cartoonizationをやってみました

# システム環境
- Windows10（RTX2080 Max-Q、i7-8750H、RAM16GB）
- Anaconda 2020.02
- Python 3.6

# 導入
[White-box Cartoonization](https://github.com/SystemErrorWang/White-box-Cartoonization)をクローンします。

White-box Cartoonization用の環境を作成します。

~~~
$ conda create -n wbc python=3.6
$ conda activate wbc
$ cd White-box-Cartoonization-master
$ pip install tensorflow-gpu==1.12.0
$ pip install scikit-image==0.14.5
$ pip install opencv-python
$ pip install tqdm
~~~


テスト画像を/test_code/test_imagesに置きます。

/test_code/cartoonize.pyを実行します。

~~~
$ cd test_code
$ python cartoonize.py
100%|██████████████████████████████████████████████████████████████████████████████████| 11/11 [00:12<00:00,  1.12s/it]
~~~

<!--
GPUが複数ある場合、cartoonize.pyの34行目のconfig = tf.ConfigProto()にdevice_countを指定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/6287566e-2bb3-5a3f-d346-c0f1d0b42c3d.png)

~~~python
config = tf.ConfigProto(device_count={'GPU': 1})
~~~
-->

結果は/test_code/cartoonized_imagesに保存されます。

## before 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/45594f9c-b18f-58d6-3107-c708f4b2bf21.png)

## after 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a978262c-da21-5330-1783-3e235046d903.png)

お疲れ様でした。
hamlで、ui-viewやng-controllerなどのハイフンのついた属性はどうやって指定するのか

webサイトの検証データを見ていると、定義してる属性の中にハイフンの混ざったものがあるが、これをhamlで定義しようとすると、ハイフンのせいでエラーが出てしまうんですよ〜。


#h1 しかし、terarailで質問して30分くらいで解決w
hamlで{ }この括弧をしようしていたんですけど、( )これで指定できました！

お騒がせしてすみません。
hashとeach文

理解不足の部分を潰していく強化週間！
ということで、１週間では足りなそうです。

# hashの理解不足（涙
hashに値（value)を代入するところまでは分かっていましたが
問題はその後。

分析していきましょう。

# ハッシュとeach文
<img width="507" alt="スクリーンショット 2020-05-24 16.18.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591023/1eb37f78-8d10-64da-f9f7-d78d5974c892.png">

- １〜５行目でhashにvalueを代入しています。
　※[:name] の部分はkey、= の右辺はvalue
- ６行目のeach文でハッシュの要素を出力する。ココは詳しく解説を残します。

## each文
### ●hash.each do |key, value| 

　・each do の記述により、ハッシュの要素の数だけ処理が繰り返される。
　　今回の場合は、name,height,weight,BMIの４回。
　・４回の処理が繰り返し実行された後、ブロックから抜け出し処理が終了する。

### ●each文のメリット
　変数の初期化や終了判定の処理がない分 eachメソッドを使用した方がより簡潔に記述できる。

　また、オブジェクトの範囲以上に処理が実行されないことが保証されている。繰り返される範囲が決まっているので、エラーの心配が少ない。

#出力結果
ターミナルにこれが出力されたら成功です。
<img width="104" alt="スクリーンショット 2020-05-24 16.37.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591023/1de7a131-311b-6af8-f6a0-951acbba1216.png">

それぞれのvalueが出力され、４回繰り返されて処理が終わっています。


## さいごに
理解力が不足しているので、こんな内容も調べてから腹落ちするまで１時間以上かかる訳です。
アウトプットすることで理解が深まる。ありがたいことです。

せっかく理解したものは、忘れないように！
pythonでつくるオセロ（GUIもどき）

# この記事の注意点
- 初心者が手探りで作っただけです。
- この記事は勉強には向いていません。

# 目次
[1. この記事の注意点](#この記事の注意点)
[2. 目次](#目次)
[3. 記事の内容](#記事の内容)
[4. コード](#コード)
[5. 参考](#参考)
[6. 本題](#本題)

# 記事の内容
python、tkinterを用いてオセロを作りました。
目的は「何かをつくる」以上でも以下でもなく、出来が悪いです。
こちらの方のコメント欄の解説が分かりやすいと思います。（後で見ました）
https://qiita.com/chi-na/items/8794c4bedb8edea03b70
# コード
- https://github.com/Masaaki61081/Othello






# 参考
*https://ruby-de-free.net/wp/how-to-make-othello-program-using-python-0/
*https://tech.pjin.jp/blog/2018/04/03/minesweeper_1/
*https://qiita.com/sensuikan1973/items/459b3e11d91f3cb37e43

# 本題
## 仕様
- 対戦モードは人対人と人対CPUの二種類。色は固定。
- CPUはランダムのみ
- 演算はビットボード
- 表示はtkinter

## スクリーンショット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436016/47d9324a-9fdb-1442-6c3c-ed3aab293685.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436016/ddfc18ff-340e-4c24-b83a-2bd23028da0b.png)
ArduinoのdigitalWrite()

この記事は、2020-05-24に書きました。
***
#概略
`digitalWrite()`は、デジタルピンにHIGHまたはLOWを書き込みます。ピンを5Vにする／0Vにする、と言い換えてもよいでしょう。
コードを実行すると、LEDが点灯して5秒後に消えます。

#環境・部品
PC：Windows 10 Professional
開発環境：Arduino IDE 1.8.12
本体：Arduino UNO Rev3
LED：赤色LED
抵抗：220Ω

#回路図
<img width="320" alt="Arduinoの13番ピンに抵抗とLEDを繋ぐ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635194/db274a55-042c-91d5-1387-fa6a3c7af5e9.png">

<img width="320" alt="Arduinoの13番ピンに抵抗とLEDを繋ぐ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635194/f4b5d6b5-f6b3-45cf-5195-4ffd01885c79.png">

#コード

```cpp:digitalWrite.ino
const int outputPin = 13;

void setup() {
    pinMode(outputPin, OUTPUT); 
    digitalWrite(outputPin, HIGH);
    delay(5000);
    digitalWrite(outputPin, LOW);
}

void loop() {

}
```

#解説
`digitalWrite()`は、デジタルピンにHIGHまたはLOWを書き込みます。
書き込む前に、`pinMode()`でピンモードを`OUTPUT`にします。

```
pinMode(ピン番号, OUTPUT); 
```



ピンモードが`OUTPUT`のピンに対して、`digitalWrite()`で5Vまたは0Vにします。


```
digitalWrite(ピン番号, HIGH); // 5Vにする
digitalWrite(ピン番号, LOW);  // 0Vにする
```

使えるピンは、デジタルピンの0番～13番までです。0番と1番は、シリアル通信に使われるので、デジタル入出力ピンとしては使わない方が無難です。13番ピンは基板上のLEDと繋がっているので、13番ピンのHIGH/LOWの状態に応じて基板上のLEDが点灯／消灯します。

実は、アナログピンA0～A5も同じ使い方ができますが、混乱するのでやらない方が無難です。

公式のリファレンスによると、ピンモードが`INPUT`のピンに対して`digitalWrite`を使うと、内臓プルアップ抵抗をON/OFFできるらしいですが、面倒くさいので試していません。もちろん、そんなことせずに`pinMode(INPUT_PULLUP)`を使えと書かれていますが……


#参考
[digitalWrite()](https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/)（公式、英語）
[pinMode()](https://www.arduino.cc/reference/en/language/functions/digital-io/pinmode/)（公式、英語）
Cognito UserPoolsのAuthorizerをGoでデコードする

# 概要
* AWSのAPI Gatewayの認証にCognito UserPoolsのAuthorizerを用いるときに、API側でもユーザーの一意性を保つために認証します
* その際Cognitoから取得できるJWTのデコードが必要になるのでGo言語でのデコード方法についてまとめました
* クライアント側でAmplifyやリダイレクト後のURLなどを用いてCognitoからIDトークンを取得する方法については既知とします

# Amazon Cognito ユーザープール認証
* Cognitoを用いたログインをクライアントから行うと、ユーザープールからJWT（JSON Web Token)が返されます
* JWTは**Base64**でエンコードされたJSON文字列であり、ユーザーに関する情報（クレーム）が含まれています
    * （このBase64でエンコードされていると言う情報によりかなり苦しむことになりました...）
* エンコードされた文字列は`***.***.***`のように`ドット(.)`で3つのセクションに分けられています
* 3つのセクションはヘッダー、ペイロード、署名で構成されています

ヘッダーは以下のような情報があります
（キーID("kid")と、トークンの署名に使用されるアルゴリズム("alg")が含まれています)

```json
{
  "kid": "abcdefghijklmnopqrsexample=",
  "alg": "RS256"
}
```

ペイロードには以下のような情報があります
（ユーザーに関する情報と、トークンの作成および有効期限のタイムスタンプが含まれています）

```json
{
  "sub": "aaaaaaaa-bbbb-cccc-dddd-example",
  "aud": "xxxxxxxxxxxxexample",
  "email_verified": true,
  "token_use": "id",
  "auth_time": 1500009400,
  "iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example",
  "cognito:username": "example",
  "exp": 1500013000,
  "given_name": "Example",
  "iat": 1500009400,
  "email": "example@example.com"
}
```

署名には、ヘッダーとペイロードの組み合わせをハッシュして暗号化したものが入ります

# ヘッダーとペイロードのデコード
署名の認証周りは一旦なしにして、JWTをデコードしてトークンに含まれるヘッダとペイロードを取得する方法を説明します

Base64でエンコードされているとのことだったのでBase64でデコードすればいいやと思い、デコードしていたのですが、たまにデコードできない現象が発生してしまい、かなり苦しみました...

最終的な結論としては**Base64URL**でデコードすれば間違いがありません

## Base64とBase64URLの違い
Base64エンコードはデータを印字可能な64種類のデータで表現するエンコード方式です

しかし、URLの一部として利用する場合は「+」や「/」とと言ったURLセーフではない文字列が含まれるのでURLセーフにエンコードしなければなりません

そこで用いられるのがBase64URLのようです

おそらくAmplifyなどで直接JWTを取得する場合は問題ないと思いますが、リダイレクト後のURLなどからJWTをゲットした場合にURLセーフにエンコードされているのでBase64ではデコードできなかったものと考えられます

どちらにせよBase64URLでデコードすれば、ヘッダーとペイロードの値を取得できます

## コーディング例
base64urlのデコーディングには`github.com/dvsekhvalnov/jose2go/base64url`をimportして用います
（そのほかには`"strings"`や`"fmt"`や`"encoding/json"`のimportが必要です）

```go
jwt := "***.***.***" // Cognitoユーザープールから取得したJWT
// // API GatewayでLambda Proxyを用いてる場合、AuthorizationヘッダにJWTを付与するので、以下で取得可能
// jwt := events.APIGatewayProxyRequest.Headers["Authorization"]

// ドットで文字列を分割して配列にして、エンコーディングされたヘッダとペイロードを取得
headerEnc := strings.Split(jwt, ".")[0]
payloadEnc := strings.Split(jwt, ".")[1]

// base64urlを用いてヘッダーとペイロードをデコードします
headerDec, _ := base64url.Decode(headerEnc) // 第二戻り値のエラーは無視しています
payloadDec, _ := base64url.Decode(payloadEnc) // 同様

// 文字列として出力
fmt.Println(string(headerDec))
fmt.Println(string(payloadDec))

// デコードされた戻り値は[]byte型なので、以下のように構造体に入れたり、マップに入れ込んだりできます
type Header struct {
    KeyID     string `json:"kid"`
    Algorithm string `json:"alg"`
}
headerStruct := Header{}
json.Unmarshal(headerDec, &headerStruct)

headerMap := map[string]string{}
json.Unmarshal(headerDec, &headerMap)
```

以上のようにデコード自体は難しくないのですが、あまり載っていなかったので苦労しました
クロック周波数とランダムアクセスメモリの性質について

#はじめに

[コンピュータシステムの理論と実装](https://www.oreilly.co.jp/books/9784873117126/)の3章において
CPUのクロック周波数とランダムアクセスメモリの性質について「なるほどな。」って思ったことがあったので共有します。

#ラムダムアクセスメモリ
**RAM(Random Access Memory)**
ランダムアクセスメモリってランダムにメモリにアクセスするわけではないんですよね。
初めて聞いたときは適当なアドレスに不規則でアクセスしまくるものかと思ってました。

[コンピュータシステムの理論と実装](https://www.oreilly.co.jp/books/9784873117126/)には
>ランダムに選ばれたワードに対して、そのワードが位置する場所に制限を受けることなく、書き込み/読み込みができる、ということからきている。つまりメモリ中のすえてのワードは-その物理的に存在する場所に関係なく-同じ時間で直接アクセスできなければならない

という記載があります。

つまりメモリのアドレスが先頭の[0x00]のものでも、終端の[0xFF]ものでも**アクセス時間が等しい**ということを表しています。
ちなみに、このワードというのはレジスタを表していると考えてください。
メモリは複数個のレジスタを組み合わせることで構成されています。

# レジスタの実装について
レジスタがどのように実装されているかというと、下図のように**マルチプレクサ**と**D-フリップフロップ**にて構成されています。
![register_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137041/89b942e3-cafc-ddb1-0160-54d876ad58e3.jpeg)

このマルチプレクサ[^1]のセレクタの値が`true`の場合には`Input`の値を出力するようになり、セレクタの値が`false`の場合には前回の出力`Output(t-1)`をそのまま出力することになります。
この判定はクロックカウンタ毎に行われ、**セレクタの値を`false`にし続けることにより、データがメモリ上に保存される**ということを実現しています。

[^1]: マルチプレクサについては前回記事参照：[CPUの演算処理を司るALUの仕組み](https://qiita.com/satodayo/items/755672aa44acdec1e66e)

#組み合わせ回路と順序回路
この時ポイントとなるのが、マルチプレクサは**組み合わせ回路**であり、D-フリップフロップは**順序回路**であるということです。

何が違うかというと、組み合わせ回路はInputに対して瞬時にOutputが切り替わります。
一方、順序回路はクロックカウンタ[^2]のタイミングによってOutputが切り替わります。

[^2]: クロックカウンタというのはCPUのクロック周波数に依存するものであり、よくCPUのスペックに〇〇GHzとかいてあるあれの値に依存します。

これを踏まえ、レジスタの値をあるアドレスのメモリの値で書き換える場合を考えます。

case1：最寄りのアドレス[0x00]番地のメモリの値で書き換える
case2：一番遠いアドレス[0xFF]番地のメモリの値で書き換える

を考えたときに、アドレスによって値を参照する時間が若干異なるものとします。(電気的な都合上)
例えばアドレス[0x00]の値を取得するには`100n[s]`必要で、アドレス[0xFF]の値を取得するには`130n[s]`必要であるとした場合
マルチプレクサは**組み合わせ回路**であり、Inputに対して即座にOutputが切り替わるため、case1のほうが早くOutputが切り替わります。
これでは上で示したランダムアクセスメモリの性質に反します。

この時これを帳尻合わせしてくれるのが**D-フリップフロップ**です。
D-フリップフロップは**順序回路**であり、クロックカウンタのタイミングでOutputを切り替えます。

そのため、例えばクロックカウンタの周期を`150n[s]`としてあげると、[0x00]のメモリにアクセスした場合に`100n[s]`のタイミングでマルチプレクサのOutputが変化した場合でも、D-フリップフロップのOutputは変化しません。

一番時間のかかるケースの時間にクロックカウンタの周期を設定することで、どのメモリにアクセスしても同じ時間でOutputが得ることができます。
このような仕組みによってランダムアクセスメモリの性質が実現されています。

#まとめ
- ランダムアクセスメモリの性質が実現できているのは順序回路のおかげ
- クロックカウンタの設定が大事
Flutterで導入しているCodecovで genhtml: command not foundと出た時の対処

ジョインさせていただいているチームでFlutterアプリを開発しているんですが Codecov を導入していて、ローカルCLI上でコマンド叩いてカバレッジレポートを生成しようとすると `genhtml: command not found` と出て色々調べてもあまり何も出てこなかったのでメモ！

```
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
```
とやると

```
genhtml: command not found
```
と出たので最初$PATHが通っていないのかな？と思っていたのですが、そもそも `lcov` が入っていないことがわかったので早速インストール
HomebrewでインストールするのでHomebrewが入っていない場合は下記のコマンドを実行してください。

- Homebrewインストール

```
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
```

画面でパスワードの入力を求められた場合は、Macのユーザーパスワードを入力して続行してください。そして、コマンドが完了するまで待ちます。

完了したら、lcovをHomebrewでインストール

```
brew install lcov
```
以上で完了なので下記を実行するとカバレッジレポートがブラウザ(Chrome.app)で表示されます。
※Chrome.app以外をお使いの場合は `/Applications/Google Chrome.app` の部分を書き換えてください。

```
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
open -a '/Applications/Google Chrome.app' coverage/html/index.html 
```
## 開発環境
Mac OS Catelina 10.15.4

## 参考文献
- [Flutter でも Codecov を導入して test モチベを上げよう!](https://qiita.com/sensuikan1973/items/551572dc8ec92cc90fdb)
- [Install lcov on Mac OSX](http://macappstore.org/lcov/)
rtl_fm使ってみた。

FreeBSD 12.1の元祖amd64なマシンにrtl-sdrとsoxをインストールしてFMラジオを聞いてみました。

元祖amd64なマシンにはONKYOのPCIカードのSE-80PCIが入っています。

このカードはESS社のmaestro3が使われていて、ソフトウエアライセンの関係でloader.conf以下を設定してあります。

```
snd_maestro3_load="YES"
```

長いこと欲しかったのもなのですが、2年くらい前に秋葉原のHardOffで見つけて324円で手に入れたものです。DACはWolfsonのWM8716が使われています。

このカードを使うためにはBIOSでマザーボードのsound機能をOffにする必要がありました。

USBの蟹さんモジュールはこんなのを使いました。これもHardOffで入手したものでまだ消費税が5%の頃に315円で入手したものだったと思います。

![写真（2020-05-24 17.13）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/af5857c4-e46f-b16f-7eb7-37427c6950d1.jpeg)

このモジュールは[dump1090](https://qiita.com/yamori813/items/87ec7cc7f2de5c421c3c)では使えませんでしたが、rtl_fmは使えました。

```
% sudo rtl_fm -g 50 -f 82.2M -M wfm -s 180k -E deemp | play -r 180k -t raw -e s -b 16 -c 1 -V1 - lowpass 16k
```

我が家はケーブルテレビのJCOMに加入していて、FMの電波が周波数をずらして、アンテナに入っているのでそこに接続しました。

ノイズはなくクリアに聞けますが、ちょっとナローな気がします。

[rtl_fmとffmpegの面白そうなネタ](https://lansley.com/2014/09/27/using-rtl_fm-and-ffmpeg-to-stream-radio-audio-over-network/)があったのでpkgでffmpegをインストールしてみました。

```
% ffmpeg

******************************************************************
* FATAL ERROR:                                                   *
* This OpenCV build doesn't support current CPU/HW configuration *
*                                                                *
* Use OPENCV_DUMP_CONFIG=1 environment variable for details      *
******************************************************************

Required baseline features:
SSE - OK
SSE2 - OK
SSE3 - NOT AVAILABLE
OpenCV(3.4.1) Error: Assertion failed (Missing support for required CPU baseline features. Check OpenCV build configuration and required CPU/HW setup.) in initialize, file /wrkdirs/usr/ports/graphics/opencv-core/work/opencv-3.4.1/modules/core/src/system.cpp, line 487
Abort (core dumped)
```

もう元祖amd64はサポートされていないようです。少し前までは動いていたと思うのですが、なんでopencvなんか入ったパッケージにしちゃってるんですかね。

portsでopencv抜いてビルドを試してみたのですが、依存が多く終わりそうになかったので諦めました。

元祖amd64はファンがうるさく実用には向きません。

我が家には超高音質なFPGA-FMチューナx2があるので、特に必要はないのですが、使えるのか確認してみました。

また単三電池で使えるラジオも時々使っていて、100Wも使ってFMラジオを聞く必要はありません。

本当はMIPS(Atheros)のモジュールで使いたかったのですが、USBが遅いのか音が途切れ途切れになってしまいます。
tf.print() を使う時に f-string 内だとテンソルの中身が表示できない

# 概要

タイトルの通りです。
`tf.print()` で `f-string` は使わないほうが良いでしょう。

実際に、以下のコードを動かして出力を比較しましょう。

```python
import numpy as np
import tensorflow as tf

@tf.function
def add_a_b(a, b):
    c = tf.add(a, b)
    print("(1):", c)
    tf.print("(2):", f"{c}")
    tf.print("(3):", c)
    return c

a = tf.constant(np.asarray([[1, 2], [3, 4]]), dtype=tf.float32)
b = tf.constant(np.asarray([[4, 3], [2, 1]]), dtype=tf.float32)

c = add_a_b(a, b)
```

出力はこのようになります。
(2) が `f-string` ですが、`tf.print()` の恩恵を受けられていないことが分かります。

```
(1): Tensor("Add:0", shape=(2, 2), dtype=float32)
(2): Tensor("Add:0", shape=(2, 2), dtype=float32)
(3): [[5 5]
 [5 5]]
```
【OpenFOAM】ポスト処理チートシート（随時更新）

#はじめに
この記事ではOpenFOAMのポスト処理をいろいろまとめています．

OpenFOAMの作業ディレクトリをcaseDirとします．

#各時間の物理量の場を取得する(postProcess)
postProcessはメッシュや物理量について，様々な情報を出力することができるユーティリティです．シミュレーション中も後も使用可能ですが，この記事ではシミュレーション後の使用を想定してまとめます．

###Q（速度勾配テンソルの第2不変量）
実行には速度の計算結果が必要です．

```
caseDir$ postProcess -func Q
```

時間ディレクトリ内にQという名前でファイル出力されます．

###y+
wallパッチ上のy+分布を出力します．pimpleFoamで計算したケースなら

```
caseDir$ pimpleFoam -postProcess -func yPlus
```

時間ディレクトリ内にyPlusという名前でファイル出力されます．

###流量
指定したパッチを通過する流量の合計値を出力します．実行には計算結果が必要です．inletという名前のパッチなら

```
caseDir$ postProcess -func 'patchIntegrate(name=inlet, phi)'
caseDir$ postProcess -func 'patchIntegrate(name=inlet, phi)' -latestTime　　　//最新結果のみ出力
```

非圧縮計算の場合，phiはセルのフェイスを通過する体積流量のことです．実行後，postProcessingというディレクトリが作成され，'patchIntegrate(name=inlet, phi)'が出力されます．全パッチの流量を出してどれぐらい質量保存を満たしているかをチェックするのに使えます．


#特定の点の時系列データを取得する(probe)
probeはユーザーが選んだ座標の物理量の時系列データを取得できるユーティリティです．実行には取得したい物理量の計算結果と，systems内にprobesというディクショナリファイルを用意する必要があります．中身は

```C++:probes
/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  7
     \\/     M anipulation  |
-------------------------------------------------------------------------------
Description
    Writes out values of fields from cells nearest to specified locations.

\*---------------------------------------------------------------------------*/

#includeEtc "caseDicts/postProcessing/probes/probes.cfg"

fields (U);    //括弧内に取得したい物理量を入力．複数の場合は半角スペースで区切る (U p ...) 
probeLocations
(
    (0.12 0.01 0.05)    // 取得したい点の座標(x, y, z)
    (0.2 0 -0.5)
);

// ************************************************************************* //
```

実行

```
caseDir$ postProcess -func probes
```
caseDirにpostProcessingというディレクトリが生成され，中に時系列データのファイルが出力されます．


#残差を確認する(foamLog)
foamLogは計算の残差等を時系列データとして出力することができるユーティリティです．計算中の出力内容をファイルに出力しておく必要があります．logという名前のファイルに出力していた場合

```
caseDir$ foamLog log
```

と実行するとlogsというディレクトリが作成され，中に残差等の時系列データが出力されます．
Google Chrome のリモートデスクトップのキー設定を変える

#ChromeデスクトップのWindowsキー使いづらくないですか？
リモート元とリモート先のPCが同じWindowsキーで反応するから不便
ー＞キー設定を変えよう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/7578f7ab-d4d7-0b52-b7b8-1a26ff7a99eb.png)

1. 「キーマッピングを設定」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/b03622f1-8efc-5a82-508a-3e368fd823ed.png)

2．「新しいマッピング」をクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/1adbad82-0311-f273-b891-7f048dc24431.png)

こんな感じでリモート元で押しているキーとリモート先で押しているキーの変更設定ができます

3．今回は例として左Ctrlキーを押すと左Windowsキーを押したことになるように設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/114c2ac0-10eb-e05e-8a7c-24c724df0a3c.png)
チェックを忘れずに～
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/9f65b498-3581-640b-22e6-25afde37efdd.png)
これでキー設定は完成です！
完了ボタンを押して動作確認を行ってみましょう

4．ほかのキーを設定したいときは？
ほかのキーの設定は，2．で出てきていた「このコードの詳細」といったページをクリックすることで行ける(https://www.w3.org/TR/DOM-Level-3-Events-code/#index-defined-here)に載っています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/a86ffb77-6698-5745-1c11-40a5641a30fb.png)
例：左Altキーを押したらEnterキーを押したことになってほしい
ⅰ. 表の右側(Notes(Non-normative))の列から四角で囲まれたAltを探す
ⅱ. その行の左端のピンク色のコードを確認して「””」のなかに書かれている文字をマッピング元のキーに打ち込む
ⅲ. 同様にEnterに対応するコードを探してマッピング先のキーに打ち込む

正しく打ち込めていたらちゃんと動くはずです

5．おさらい
現在のコードでも十分使えますが，Windowsキーを押すとリモート元も先も両方が反応してしまいます
そこでリモート元でWindowsキーを押してもリモート先では反応しないように設定しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/d9b9f441-c372-bb23-e800-8ce6ab6615ca.png)
Typescriptのオーバーロードまとめ

typescriptを書いててC#やKotlinと同じ感覚でオーバーロードを書いたらエラーを吐かれたため
typescriptのオーバーロードの書き方をまとめました。

# functionのオーバーロード

```typescript
function test(a: string, b: string):number // 宣言
function test(a: number): number // 宣言

function test(a: number | string, b?: string): number { // 実装
    if (typeof (a) === "string") {
        return Number(a) + Number(b)
    }
    if(typeof(a) === "number"){
      return a;
    }
    return 0
}
```

ご覧の通りtypescriptはオーバーロード時の関数の宣言だけをして、最後に全てのケースの型を受け取る前提の関数を定義して
実装します。
なので、引数として与えられないケースがある場合は optionalにする
１引数に複数の型が与えられる可能性がある場合は | で繋いでずべてのケースを書く必要があります。

# constructorのオーバロード
クラスのコンストラクターのオーバーロードも同様です。

```typescript
class Test {
    #value1: number = 1;
    #value2: number = 1;

    constructor(value1:number)
    constructor(value1?:number, value2?: number )
    constructor(value1:number, value2:number)

    constructor(value1?: number, value2?: number) {
        if (value1 && value2) {
            this.#value1 = value1;
            this.#value2 = value2;
            return;
        }
        if (value1) {
            this.#value1 = value1;
            return;
        }
        if (value2) {
            this.#value2 = value2;
            return;
        }
    }



    get sum():number {
        return this.#value1 + this.#value2;
    }
}

const test1 = new Test(2);
const test2 = new Test(undefined, 3);
const test3 = new Test(4, undefined);
const test4 = new Test(3,3)

console.log(test1.sum) //3 
console.log(test2.sum) //4 
console.log(test3.sum) //5
console.log(test4.sum) //6
```

なおtsの仕様上 
```typescript

constructor(){}
```
のような意味のないコンストラクタを定義することはできないので、それを除いた形でオーバーロードします。

# class method のオーバーロード
クラスメソッドも同様

```typescript
class Test {
    #value1: number = 1;
    #value2: number = 1;

    constructor(value1: number, value2: number) {
            this.#value1 = value1;
            this.#value2 = value2;
    }

    add():number
    add(a:number):number

    add(a?:number): number {
        if(!a){
            return this.#value1 + this.#value2;
        }
        return this.#value1 + this.#value2 + a;
    }
}
```

# さいごに
残念なことに、typescript は別のJavaなどと違って、オーバーロード解決(もらった引数の型などからオーバーロードされたパターンの内、一致制が高いものを自動的に算出する機構)をもっていないようなので、自前ですべてのパターンを実装する必要があります。

なので、むやみにオーバーロードすると、可読性や保守性を犠牲にしそうなので、注意しないといけないようです。
AndroidStudioでKotlinのvalとvarの違いを知る

#Kotlinの変数定義
Kotlinの変数の定義には**var**と**val**があります。

```kotlin.kt
var iVar : Int = 0
val iVal : Int = 0
```

##varとvalの違い
varとvalは、このように大きく異なります。

```kotlin.kt
var iVar : Int = 0
val iVal : Int = 0
iVar = 1 // OK
iVal = 1 // NG
```

| 定義方法 | 内容 |
|:--:|:---:|
| val | 値の変更が出来ない |
| var | 値の変更が出来る |

値の変更が出来ないのは致命的な変数（定数なのか？）のように思われますが、Kotlinではvarよりvalの方が出番が多くなります。
たとえば

##valに多い役割

```
  val tvMain = findViewById<TextView>(R.id.tvMain)
```

レイアウトのIDを検索して代入するこの定義には必ずvalが使われます。レイアウトのIDは固定なので代わることがありませんし、間違って代入されてしまうことを防ぐ働きもあります。

**var**と**val**は**Kotlin**を学ぶ上で必ず覚える必要があります。

##varで起こしがちの初歩ミス
varは値の変更が可能なので特にミスは起こらなさそうですが、複数回使用するときに注意する必要がありま
す。

```sample.kt
var str = "代入1回目"
strToData(str)
```
これを何回か使おうとコピーするとエラーになります。

```sample.kt
var str = "代入1回目"  // OK
strToData(str)
var str = "代入2回目"  // NG
strToData(str)
var str = "代入3回目"  // NG
strToData(str)
```

2回目以降は定義ではないので

```sample.kt
var str = "代入1回目"  // OK
strToData(str)
str = "代入2回目"  // OK
strToData(str)
str = "代入3回目"  // OK
strToData(str)
```

このようにします。
【Java】計算式を入力して、結果を出力するプログラム

例えば、コンソール画面で、「23+53」と入力すると、「76」と結果が出力されるようなプログラムを作りたいです。
入力する式は、四則演算が可能で、入力する数値の数の限りもないような仕様が望ましいです。
お手数ですが、どなたか教えていただけませんでしょうか。
Python って日本語わかるんだ！

# 算譜
```
import numpy as 算術
円周率 = 算術.pi
範囲, 尺, 字にする, 印刷せよ, 整数, つぶせ = \
  range, len, str, print, int, hash
真, 偽, 全て真なれば真, いずれか真ならば真, 最大値, 最小値 = \
  True, False, all, any, max, min
真偽 = {真:"真", 偽:"偽", "地動説":"真", "天動説":"偽"}
掛け算 = lambda 甲, 乙 : 甲 * 乙

単数字 =  ["零壱弐参四五六七八九"[回] for 回 in 範囲(10)]

# 函数定義
def 漢(仮引数):
  答 = ''
  for 字 in 字にする(仮引数):
    try:
      答 += 単数字[整数(字)]
    except ValueError:
      答 += 字
  return 答

def 自乗(数):
  return 掛け算(数, 数)

# 組定義
class 図形:
  # 方法定義
  def __init__(self, 色 = "黒"):
    自分 = self
    自分.色 = 色

  def 何色(自分):
    return 自分.色 + "色"

# 組継承
class 円(図形):
  # 方法定義
  def __init__(self, 半径, 色 = "黒"):
    自分, 上位 = self, super
    上位で初期化 = 上位().__init__
    自分.半径 = 半径
    上位で初期化(色)

  def 面積(self):
     自分 = self
     return 掛け算(円周率, 自乗(自分.半径))

# 算譜本體
for 回 in 範囲(1,5):
  印刷せよ(' 現在', 漢(回), end='')
印刷せよ()
配列 = [真, 真, 偽]
印刷せよ("配列の尺は", 漢(尺(配列)))
印刷せよ("偽あらば",真偽[全て真なれば真(配列)])
印刷せよ("地動説は",真偽["地動説"],"と心得る")
印刷せよ(漢([5,9,6,3]),"の最大値は",漢(最大値([5,9,6,3])))
印刷せよ('円周率は', 漢数字(円周率))
月 = 円(半径 = 2, 色 = "黄")
印刷せよ('月の色は', 月.何色())
印刷せよ('月の半径が', 漢(月.半径), '尺なれば、其の面積は', 漢(月.面積()), "尺平方也")
```

# 實行顛末
```
 現在 壱 現在 弐 現在 参 現在 四
配列の尺は 参
偽あらば 偽
地動説は 真 と心得る
[五, 九, 六, 参] の最大値は 九
円周率は 参.壱四壱五九弐六五参五八九七九参
月の色は 黄色
月の半径が 弐 尺なれば、其の面積は 壱弐.五六六参七零六壱四参五九壱七弐 尺平方也
```
Pythonの実行時のパッケージと開発環境のパッケージをPoetryで管理する

PyPIパッケージの管理に、Poetryを使うとrequirements.txtを使うよりも、以下の点で便利そうだった。

- 開発/本番環境で使うパッケージの管理を別に行うことができる（npmのdevdependenciesのような感じ）
- 直接プロダクトが依存しているパッケージのみを管理することができる
- 依存パッケージに依存しているパッケージのバージョンは poetry.lock で管理され、いつの間にか依存パッケージのバージョンが上がって動かなくなることはない（npmの、package-lock.json、yarn.lockのような感じ）
- 依存パッケージのバージョンアップも1コマンドでできる
- virtualenv.in-project trueを設定しておくと、venvを使用して.venvディレクトリにパッケージをインストールする（.venvディレクトリはVSCodeでも自動で認識するので便利）

自分で使いそうなコマンドをまとめました。

## Poetryのインストール

```
pip install --user poetry
```

## 環境の分離に使うvenvを使い、.venvディレクトリを自動で作成して使うように設定する

```
poetry config virtualenvs.in-project true
```

## 開発でのみ使うパッケージのインストール

```
poetry add -D black
```

## アプリケーションから依存しているパッケージのインストール

```
poetry add flask
```

## 別のマシンで、開発環境を構築する場合

```
# 分離環境の作成
python -m venv .venv

# パッケージのインストール
poetry install
```

## プログラムの実行

.venv下にパッケージはインストールされているので、.venvで実行する

```
.venv/bin/python api.py
```

もしくは、Poetry経由で実行する

```
poetry run python api.py
```

## パッケージのアップデート

```
poetry update
```

## コンテナ化

コンテナの中では.venvを用いず、Poetryの環境分離機能を使う（VSCodeと共有せず、特に.venvディレクトリである必要はないため）

```
FROM python:3.8.2

# Poetryのインストール
RUN pip install poetry==1.0.5

WORKDIR /app

# 依存パッケージのインストール
COPY poetry.lock pyproject.toml ./
# devは除く
RUN poetry install --no-dev

# アプリケーションの格納
COPY api.py ./
# ...

# Poetry経由で実行する
CMD ["poetry", "run", "python", "api.py"]
```