OmniAICreator/Qiita-1.07M huggingface dataset:
vscodeにblackを導入したけど、自動フォーマットされない

#はじめに
全然効かないblack。
何でだろう？
#チェックポイント
1. pythonは3.6以降ですか？
2. [適切な設定をしていますか？](https://qiita.com/tsu_0514/items/2d52c7bf79cd62d4af4a)
3. オプションの付け方が間違っていませんか？

私は3番にハマりました。
いきなり色々変更するのはやっぱりよくないですね...

```settings.json
    "[python]": {
        "editor.tabSize": 4,
        "editor.detectIndentation": false,
        "editor.formatOnSave": true,
    },
    "python.linting.enabled":true,
    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "python.linting.lintOnSave":true,
    "python.formatting.provider": "black",
    "python.linting.flake8Args": [
        "--max-line-length=120",
        "--ignore=E203,W503,W504"
      ],
    "python.formatting.blackArgs": [
        "--line-length=120"
      ],

```

自動フォーマットが効かない問題は、１行における最大文字数の指定方法でした。
- flake8→ `max-line-length`
- black →  `line-length`
まじか
以上。
名簿に載っている人がテーブルの中に何人いるかを調べる

##はじめに
タイトルがわかりにくいのですが、下のイメージのように、掃除当番表のようなテーブルがあり、月曜はグループ1の人が何人、グループ2の人が何人で、火曜は・・・ということを知りたいなと思い、VBAの関数を作成しました。

![countMember.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507401/6560396f-938b-f4c7-a711-99f7425ce242.png)


##コード

さっそくコードを書きます。

```vb

Function CountMember(member_list_rng As Range, target_rng As Range) As Long

Dim members As Variant
members = member_list_rng

Dim rng As Range

Dim i, n As Long
n = 0

For Each rng In target_rng
    For i = 1 To UBound(members, 1)
        If StrComp(rng.Value, members(i, 1)) = 0 Then
            n = n + 1
        End If
    Next i
Next

CountMember = n

End Function

```

##処理の流れ
続いて、処理の流れを説明します。

第一引数(member_list_rng)は、グループのメンバー一覧が記載されたRangeオブジェクト、第二引数(target_rng)は、調べたい対象のRangeオブジェクトとします。

まず、Variant型の変数(members)に第一引数のRangeオブジェクトを格納すると、グループのメンバーが配列となってmembersに格納されます。

この配列は二次元の配列になり、また、インデックスは0からではなく、1から始まることに注意が必要です。
例えば、以下のようなA1〜C5のセル範囲をmembersに格納すると、members(1 To 5, 1 To 3)となります。一次元目が行数、二次元目が列数ですね。今回の関数では、第一引数のセル範囲として列数＝1での処理を想定しています。

![5x3Rng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507401/9118e896-e847-1497-173b-70cbba83429e.png)

あとは、target_rng内のそれぞれのセルに対し、memmbersの全ての要素と値が一致しているか照らし合わせていきます(StrComp)。そして、値が一致している場合は、nに1を加えます。

最後にnを返しておしまいです。
正規表現で大文字から始まる文字列を取り出す(Ruby)

## 今回やる事
タイトル通り、正規表現で大文字から始まる文字列を取り出します。

## コード
今回書いたコードは以下の通り

```ruby

# 配列から大文字から始まる文字列を抜き出すメソッド
def upperstr(array)

  # 配列の添字として使用する変数
  count = 0

  # 大文字から始まる文字列を格納する配列
  upper = []

  # eachメソッドで配列に含まれている要素を全て取り出す
  array.each{|arraystr|

    # 正規表現で先頭が大文字から始まりる文字列を抽出し、配列(upper)に格納する
    upper[count] = arraystr.slice(/^[A-Z].*/)

    # 配列の添字に1を加算する
    count += 1
  }
  
  # 文字列の先頭が小文字だった場合は配列にnilが格納されるため、deleteメソッドでnilを削除する。
  upper.delete(nil)

  # メソッドの返り値として、大文字から始まる文字列を格納した配列を変えす。
  return upper

end


# ユーザー用のガイド
p "文字列を半角スペースで区切って入力してください"

# コンソールから入力した文字列を変数に代入
str = gets

# 入力された文字列を半角スペースで区切って配列に代入
ary = str.split(" ")

# upperstrメソッドの返り値を変数に代入
# (upperstrメソッドは大文字から始まる文字列を取り出すメソッド)
upperary = upperstr(ary)

# ユーザー用のガイド
p "大文字から始まる文字列を取り出しました"

# eachメソッドで配列に含まれている要素を全て取り出す
upperary.each{|ustr|
  # 配列の中身を表示
  p ustr
}
```

## 正規表現
※各メソッドや処理についてはコメントに書いたので説明は割愛。
今回はupperstrメソッド内で使用しているsliceメソッドで正規表現を使っております。
噛み砕きまくって説明しますと、以下の通りです。

①コード
upper[count] = arraystr.slice(/^[A-Z].*/)

②/
/　と　/　で囲まれた範囲が正規表現パターンの範囲となる

③^
^の直後の文字が先頭の文字であることを表しています

④[A-Z]
AからZという意味であり、大文字であることを表しています。
^[A-Z] とすることで先頭が大文字である文字列を検索する事ができます。
小文字にしたい場合は[a-z]です。

⑤.
.　は任意の1文字です。

⑥*
*　は直前の文字列が0回以上繰り返すことを意味します。
.*　と書くことで、「任意の文字列が0回以上繰り返す」ということになります。
なんかわかりづらいと思いますが、「先頭の文字以外はどうでもいいよ」っていうことです。

## 動作確認
実際にプログラムを動かした結果を書いておきます。
入力値は「aaa AAA B b CC cc DDDDD ddddd」です。
大文字から始まる文字列を取り出すので、想定される結果は「AAA B CC DDDDD」となります。

```
% ruby regex.rb 
"文字列を半角スペースで区切って入力してください"
aaa AAA B b CC cc DDDDD ddddd
"大文字から始まる文字列を取り出しました"
"AAA"
"B"
"CC"
"DDDDD"
```
想定通りの結果が出ました！今回の記事は以上です！
[Java]配列

#配列の定義
`データ型[]　配列名 = {};`

```java

String[] names = {"tanaka" , "sato" , "suzuki"};
System.out.println(names[0]);
```

#配列のfor文
配列の中身を全部出力する。

**通常のfor文**

```java

String[] names = {"tanaka" , "sato" , "suzuki"};

for(int i = 0; i < names.length; i++) {
  System.out.println(names[i]);
}
```

**拡張for文**
`for(データ型　変数:配列名){}`

```java

String[] names = {"tanaka" , "sato" , "suzuki"};

for(String name:names) {
  System.out.println(name);
}
```
firebase送信可能なメールアドレスで認証する方法(認証時コード追記)

#sendEmailVarification()で認証メールを送信する
####はじめに
通知やメルマガでユーザーのアドレスを使用する場合や会員認証が可能。
今回はVue Typescript(javascript)のプロジェクトで実装。
※[sendSignInLinkToEmail()](https://firebase.google.com/docs/auth/web/email-link-auth?hl=ja)でもアドレス取得が可能だが、emailLinkを要求するため、2回目以降も毎回リンク付きメールからログインしなければならない。
##①SDKを追加してFirebaseを初期化する
以下記事参照
[FirebaseにJavascriptのプロジェクトを追加する](https://qiita.com/hinokichi77/items/26fb33a7b5c9101fbf61)
[公式](https://firebase.google.com/docs/web/setup?hl=ja)
##②sendEmailVerification()で認証メール送信
###②-1 createUserWithEmailAndPassword()でアカウントを作成
認証メールはログイン状態でないと送信できないため、先にアカウントを作成する
※この時点でコンソールにはアカウントが作成されるが、まだ認証済みではない。
![6231.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/7b992d12-e1d7-92c6-14e6-65881f09f314.png)
###②-2 sendEmailVerification()で認証メール送信
![6.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/5b7f45f5-7e16-3d26-6e18-d3e224790cc5.png)
※actionCodeSettingsはURL付きメールの設定　[公式を参照](https://firebase.google.com/docs/auth/web/passing-state-in-email-actions?hl=ja)
認証メールが送れなかったらuser.delete()で消去する
##③emailVerifiedでログインを承認する。
②で送信された認証メールのURLを開くをfirebase.User.emailVerifiedが付与される
onAuthStateChanged()でユーザーの状態を取得してemailVerifiedであればログインさせる。
![6232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/bc9bdee1-4e90-cc5e-66c1-83b0a885bc9e.png)

一度サインアウトしてもユーザーのemailVerified状態は保存される。
2回目以降のサインイン↓
![6233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651029/437ef938-749d-0215-bfc9-a0111305f50a.png)
apt-get時にgcrypto20が原因でHash Sum mismatchになる話

# はじめに

Virtual Box 上の Kali 2020.2 で apt-get update をしたら `Hash Sum mismatch` が出てハマってしまいました。
解決策として試したのは以下の3つの方法ですが、どれも同じようにハッシュのエラーが出てしまい、解決に至れませんでしたが、とある方法で試したところ、解決できたので備忘録として残しておきます。

試してダメだったのは以下の方法です。

### 解決策①

```
$ sudo apt-get update --fix-missing
```

### 解決策②

```
$ sudo apt-get clean または sudo rm -rf /var/lib/apt/lists/*
$ sudo apt-get update
```

### 解決策③

`/etc/apt/sources.list`の設定ファイルを編集して、レポジトリのURLを
`http://mirrors.ocf.berkeley.edu/kali kali-rolling main non-free contrib`
に変更してから`apt-get update`


# 解決策

では最終的になにが原因だったのかというと、ヒントはHash値がMD5Sumのみが一致しているところにありました。

```
$ sudo apt-get update
Get:1 http://linux3.yz.yamagata-u.ac.jp/pub/linux/kali kali-rolling InRelease [30.5 kB]
Get:2 http://linux3.yz.yamagata-u.ac.jp/pub/linux/kali kali-rolling/main amd64 Packages [16.6 MB]
Err:2 http://linux3.yz.yamagata-u.ac.jp/pub/linux/kali kali-rolling/main amd64 Packages                     
  Hash Sum mismatch
  Hashes of expected file:
   - Filesize:16590427 [weak]
   - SHA256:00ccf318db598c4ddcd7094d28442cdb30088ab7de8cff6c0294de484a102146
   - SHA1:12776612134b22e45ffd84538bcc493c87e881a4 [weak]
   - MD5Sum:b9db76fb5ce9653b1d721068963a1787 [weak]
  Hashes of received file:
   - SHA256:4d733b1f1ead1ce850dbd4ff906a1eb959380b181afb6eba0b9898652f58a2a1
   - SHA1:b14761cbb2748365e608bbd57db3f1c41be04a53 [weak]
   - MD5Sum:b9db76fb5ce9653b1d721068963a1787 [weak]
   - Filesize:16590427 [weak]
  Last modification reported: Tue, 23 Jun 2020 12:03:38 +0000
  Release file created at: Tue, 23 Jun 2020 12:04:33 +0000

```

どうやら新しいLinuxで使用されている`gcrypto20`が原因でSHA256やSHA1のハッシュ値が異なってしまうようです。
参考に載せたサイトをもとに以下の手順で解決することができました。（心から感謝です、、、！）

```
$ sudo bash
# mkdir /etc/gcrypt
# echo all >> /etc/gcrypt/hwf.deny
```

この設定を施した後に

```
$ sudo apt-get update
```
でいけました！！

# 参考
- https://github.com/ktkr3d/ktkr3d.github.io/issues/1
- [apt - “Hash sum mismatch” error due to identical SHA1 and MD5 but different SHA256](https://askubuntu.com/questions/1235914/hash-sum-mismatch-error-due-to-identical-sha1-and-md5-but-different-sha256/1242739#1242739)
Next.jsを使って医師国家試験の勉強ノートを公開するブログを作った話

# Next.jsを使って医師国家試験の勉強ノートを公開するブログを作った話

表題の通りです。まずは完成品とレポジトリのURLをどうぞ。

サイト：https://chilvary-beta.vercel.app

GitHub：https://github.com/yokonao/chilvary-beta

## 作ったきっかけ

next.jsの公式チュートリアル(URLは以下)をやったら、構築の容易さとSPAのページ遷移の速さに感動したので。これで自分のブログ作ったら超便利じゃない？と思いました。単純なページ公開だけならバックエンドなしでも可能です。
https://nextjs.org/learn/basics/create-nextjs-app?utm_source=next-site&utm_medium=homepage-cta&utm_campaign=next-website
## アーキテクチャ

アーキテクチャっていうのは大げさすぎるかもしれません。

1. ローカルPCで書いたMarkdownファイルを作成
2. Markdownファイルを**AWS S3**にアップロード
3. S3のデータを引っ張ってきて、静的サイトとしてビルド

Next.jsとは全く関係ありませんが、Markdownファイルのバージョン管理とアップロードは完全自動化しています。作業終了後Alfredをちょっと立ち上げてAppleScriptを起動すればアップロードが完了するようにしました。（AppleScriptでgit pushしてgithub actionsでS3にアップロード）。この話はまた別でしたい。

## メリット

-  SPAなのでページ遷移はほぼ０秒
-  超優秀なMarkdownエディタ**Typora**の力を借りることができる

参考：https://qiita.com/4_mio_11/items/223326c3289f6b2c2a07

## 実際の記事にはどんなこと書いてんの？
クエスチョンバンク(QB)を解きながら、疑問に思った点を調べてMarkdownファイルにまとめる。国試の勉強は長期戦なので、１年後の自分に向けて書いてます。

スタイルに関しては、Typoraのテーマで使用されているcssファイルとBulmaを併用してます。記事をローカルで作成した時とほぼ同じ見た目で公開しつつ、ヘッダーなどを作る際はBulmaのコンポーネントを利用できるになっています。

## チュートリアルから進化している点

S3のディレクトリ構成が完成品のブログにそのまま反映されています。説明が難しいですがサイトを一度巡回していただければ、意図が伝わるはず...

本当に手元で作成したフォルダがそのままwebサイトになるイメージです。

## Next.jsのすごいところ

このwebサイト、markdownファイルの中身をNext.jsに渡してあげれば成立するので以下のような拡張もできると思います。

- データの置き場所をS3からデータベースにする

- Markdown形式で記事をアップロードできるwebアプリを作成してS3を介してつなぐ

メディアサイトのようなものを作成しようとすると、認証機能など難しい点も出てくるでしょう。しかし、ローカルで作成した文書をSPAとして公開できるサイトをこれだけ簡単に自分で１から作れてしまうのは、Next.js様様かな、と感じます。もちろんGitHub Pagesなどもっと楽な選択肢もありますが、SPAや自由にカスタマイズできるというメリットは十分あると思います。

個人的には自分で見返す際もページ遷移に時間をとられないのでストレスフリーで気持ちいいです。普段やる気にならない勉強も記事作成という遊び感覚でできるようになりましたし。

## 今後

現在は、ビルド時に全てのページを静的に作成しているので、記事を追加・変更する際は**再ビルド**が必要になります。

しかし最近、Next.jsは静的なwebサイトに動的なページ更新機能を搭載できるようになりました。*Incremental Static Regeneration*というやつです。この機能を使いたかったのですが、現在はバグが存在するようなので実現できませんでした。

Next.jsのレポジトリではこのバグに関するissueに最優先事項のラベルがつけられていたので、修正がきたら導入したいと思っています。これさえ導入できれば、Markdownファイルの保存から公開までがほぼ自動化できる...

## 補足

Incremental Static Regenerationについては以下のサイトの説明が超わかりやすいです。（英語ですけど...）

https://arunoda.me/blog/what-is-nextjs-issg

件のバグのissue

https://github.com/vercel/next.js/issues/12851

https://github.com/vercel/next.js/issues/14382
人生短いかもだが、なにか残せたらと

yacc bisonなんて使わなくてもいい
コンパイラーコンパイラーもいらん。
もっと簡単でいい。
抽象レベルを、組合せたぐらいのテキスト形式の言語を作成したいかな
それは、いまのハードが速いので、tcltkレベルのweb版をつくりたい。
それも、google firebase系をメインとしたラッパー言語をつくりたい。

javascriptは、もともと根本から狂ってる言語だった。いまでも継ぎ接ぎだらけの
いまだに、破壊的レベルの変革があってもいいのかとおもってるのだが。。

まあいいや、kotlinはあまりにnullに対してのこだわりがありすぎる。まあ大事なのだが。。
golangは、いまだにポインタを一部的にしか適応しないようなレベルだな
あと、宣言にこだわりすぎ。複数の方法で書けるのはどうかとおもう。
pythonは、もう3でいいだろ。2.7とか捨ててもいいと思う。


いちばんいいたいのは、web世界で、とおる言語がhtmlとjavascriptってことだ。
まあ、asm系も動いているが、どうなってるんだ？
typescriptぐらいふつうに通せよとかｗ
service crond statusでunrecognized serviceされる

crontabが動かん。下のコマンドを使って、crondが動いているのか確認するとunrecognized serviceと怒られる。

```
service crond status
```

結果、以下のコマンドでやったらうまくいった。

まず、crontabを起動する。

```
crontab -e
```

所望の処理を書いてエディタを閉じる。次にcronを以下のコマンドで再起動する。

```
sudo /etc/init.d/cron restart
```

これで動いた。
【AWS;Lambda入門】第二弾；jsonファイルから文章抽出してS3保存♬

[前回](https://qiita.com/MuAuan/items/49cbc0a18dcf6c6406bb)は、以下のコードでs3://バケットに配置されたmp3ファイルをtranscribeしてテキストに変換して、jsonファイルをOutputBucketNameのS3;バケットに配置した。
今回は、このjsonファイルを呼び出して、テキスト変換された文章を抽出しようと思います。わざわざ前回コードを出したのは、今回もコードが似ているからです。

```py
s3 = boto3.client('s3')
transcribe = boto3.client('transcribe')
def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        transcribe.start_transcription_job(
            TranscriptionJobName= datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '_Transcription',
            LanguageCode='ja-JP',
            Media={
                'MediaFileUri': 'https://s3.ap-northeast-1.amazonaws.com/' + bucket + '/' + key
            },
            OutputBucketName='lamoutput'
        )
．．．
        raise e
```
ということで、以下のコードで実施できました。
S3；バケットに保存する方法は参考のとおりにしています。
【参考】
①[【AWS Lambdaの基本コードその2】 S3へのファイル保存](https://recipe.kc-cloud.jp/archives/10058)
②[Boto3 で S3 のオブジェクトを操作する（高レベルAPIと低レベルAPI）](https://qiita.com/sokutou-metsu/items/5ba7531117224ee5e8af)
参考①のコメントを残しています。ほぼまんまなコードで動きました。
異なるのは、[先日のjsonファイルの取り扱い方](https://qiita.com/MuAuan/items/45bc563a068d9fc87600)を取り入れている部分です。
まず、Libは以下のとおり、

```py
# ①ライブラリのimport
import boto3
import urllib.parse
from datetime import datetime
import json
```
以下は、参考②から真似してclientを定義しています。

```py
print('Loading function')      # ②Functionのロードをログに出力
s3 = boto3.resource('s3')      # ③S3オブジェクトを取得
client = s3.meta.client
```
lambda_handlerの入りのbucket, keyの取得は、上記のtranscribeのコードと全く同一です（当然ですが。。）。

```py
# ④Lambdaのメイン関数
def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
```
以下は、参考②と同じコードでjsonファイルから、response['Body']を読込ます。
ところが、ここで躓きました。
つまり、このbody.decode('utf-8')とすれば日本語の文章が表れると思っておりました。が、現実は結構なjson likeな（文字列）が出現。
当初は、これは文字列と気づかず、jsonファイルだと思いました。
ということで、文字列と気づき、さらにjson.loadsでjsonファイルに変換できることが分かり、．．．やっと以下のコードにたどり着きました。
つまり、bodyは文字列です。

```py
    response = client.get_object(Bucket=bucket, Key=key)
    body = response['Body'].read()
```
文字列をjsonファイルに変換します。

```py
    dec = json.loads(body)
```
そして、jsonファイルなるがゆえに以下のように日本語文章が簡単に抽出できました。

```py
    con_el=dec["results"]["transcripts"][0]["transcript"]
    print('contents=',con_el)
```
`contents= こんにちは 東京 横浜 も 少し 曇り です 声 は 水木 さん です`
最後に以下のように指定したs3;バケットにkeyのような時刻入りの.txtとして保存できます。

```py
    bucket = 'muauanpub'    # ⑤バケット名を指定
    key = 'test_' + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') + '.txt'  # ⑥オブジェクトのキー情報を指定
    file_contents = con_el # 'Lambda test'  # ⑦ファイルの内容
    obj = s3.Object(bucket,key)     # ⑧バケット名とパスを指定
    obj.put( Body=file_contents )   # ⑨バケットにファイルを出力
    return
```

###まとめ
・音声ファイルを変換したjsonファイルから文章抽出してs3バケットに保管できた
・これで二段階になっていますが、mp3ファイルをs3バケットに置くと、自動的にそのテキスト変換された文章そのものがs3バケットに保存されるようになりました。
・一応、Teraterm→ec2→s3バケット転送．．．s3バケットからダウンロード⇒表示は出来ました

・あと、このs3バケットに音声ファイルを転送するアプリとs3バケットのテキストファイルを表示するアプリが出来るとより使いやすい音声ファイル-テキスト変換アプリが出来そうです（Web化）
・変換時間が長くともどちらのLambda関数も非同期起動なので、お金にも時間にも優しいアプリになりそうです
[Java]出力、変数

#標準出力
`System.out.println()`

```java
System.out.println("Hello World");
```

#変数
**変数定義**
`データ型　変数名;`

```java
String hello;
hello = "Hello World";
System.out.println(hello);
```
こちらでも意味は一緒

```java
String hello = "Hello World";
System.out.println(hello);
```
#型変換
**強制型変換(キャスト)**
出力の時に型を強制的に変換する

例：int型同士の計算結果を小数点で出したい(本来は小数点はでない)

```java
int num1 = 10;
int num2 = 4;
System.out.println((double)num1 / num2);
```
プロダクトバックログの優先付けに関して

プロダクトバックログの優先付けの為に、難易度とビジネス価値で評価するのが一般的だと思います。この評価の結果どれを一番最初グループへ配置するでしょうか？
- 難易度高＆ビジネス価値高をA
- 難易度低＆ビジネス価値高をB
- 難易度高＆ビジネス価値低をC
- 難易度低＆ビジネス価値低をD
とするとA>B>D>Cの順番で組むようにと現場へはアドバイスしています。

昨年、ある現場支援した時にBを一番先に開発した方が良いという方がいました。意見を伺うと、Aを一番最初に選んだ場合、開発チームが実装できなくて自信を無くすから、という理由でした。さらに、何故そのように考えたのかと質問すると、開発チームが宣言したバックログ常に構築できていないと自信だけでなくチーム崩壊の危機が訪れると説明しました。
はたして、この姿勢は良いのでしょうか？

何事も失敗してはダメだという心理が働いていると思います。

失敗は真摯に受け止め、改善策を考え・実行して良くなることで、チームは自信を持って成長していきます。

アジャイル開発の初段では様々なリスクを顕在化させることがとても大切です。これがリスクマネジメントの基本だからです。

一番最初に難易度の高いプロダクトバックログを実装することで、現時点での開発チームの力量が判ります。

上手くできなかった場合には、その理由を明確にして、関係者全員でそれを共有して、対応策を考え・実施するように誘導することが成功への第一歩となります。

もう一つ、私の体験をお話しします。
あるアジャイル開発プロジェクトでプロダクト・オーナー（PO）と開発チームの距離（心理的も含めて）が近い現場を支援したことがありました。

このチームは従来のW/Fでの開発経験は十分に持っていました。ただ、POも含めてアジャイル開発は初挑戦でした。

まず初めに、POはシステムの全体像を開発チームと一緒に描き、さらに、その全体像上にプロダクトバックログに相当する業務シナリオの流れを太線で書いていき、それぞれにルート〇〇とIDをつけていきました。

その後、POはこのルートをユーザー部門が一番誘いに乗りやすい（興味を持ち易い）グループに分類していきました。
この時点で、プロダクトバックログはユーザーの興味順に尚且つ、それぞれが一つの業務シナリオとして完結し独立するように整理できたのです。

『ここまで整ってきたので、ユーザーレビューへ向けた各イテレーションでの開発順位は開発チームにアイデアを出してもらいましょう。』とPOに話して、実装するための優先順位を開発チームに立ててもらうようにしました。

この時、開発チームは自分たちの技術的リスクも考慮して、自分達の自信が持てるプランを提示してきました。

これを基にPOはユーザーとの折衝も重ね、開発チームの提案通りの優先順位で、このプロジェクトをスタートさせました。

このプロジェクトは一回目のリリースで一部の積み残しはあったものの絶大な信頼を得て、その後のイテレーションもステークホルダーがONE Teamとなり成功を収めました。

アジャイル開発ではPOがプロダクトバックログについて責任を持ち、優先順位や見積もりを行うと一般には定義されていますが、実際に成功させる為には開発チームと常に会話できる状態を保ち、開発チームの意見を尊重することが大切なのです。

プロダクトバックログの優先順位付けの正解な決め方は無いという事です。ステークホルダーを含めONE Teamになっていないとダメなのです。発注者側のマネジメントが従来型で、単なるアジャイル開発のプラクティスだけを導入しても成功しないのは、この例から推測できると思います。
zipline Beginner Tutorial

#1.この記事は

ziplineのBeginner Tutorial([リンクはこちら](https://www.zipline.io/beginner-tutorial))に載っているバックテストを動かすまでの手順を説明します。

#2.内容

#2-1 準備
下記リンク記事の2-1,2-2,2-3を終わらせてください。

2-1 [python3.5をjupyter仮想環境上にインストールする。](https://qiita.com/NT1123/items/6ca9ee2d2c586371bcaf#2-1-python35%E3%82%92jupyter%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E4%B8%8A%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)
2-2 [仮想環境上にziplineをインストールする。](https://qiita.com/NT1123/items/6ca9ee2d2c586371bcaf#2-1-python35%E3%82%92jupyter%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E4%B8%8A%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)
2-3 [benchmarks.pyとloaders.pyの修正](https://qiita.com/NT1123/items/6ca9ee2d2c586371bcaf#2-1-python35%E3%82%92jupyter%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E4%B8%8A%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)

#2-2 銘柄データの取得

Quandle APIを使って株価データを取得します。(無料アカウントの場合2018年以降のデータは取得できないようです。) 使用するには、[https://www.quandl.com/](https://www.quandl.com/)にアクセスし、APIキーの取得をまず行ってください。

(0)[https://www.quandl.com/](https://www.quandl.com/)よりAPIキーを入手する。
入手したキーを"xxx123"とします。

(1)anaconda3プロンプトを立ち上げます。

(2)QUANDLのAPIキーをセットします。
windowsの場合は下記のとおりset ***でAPIキーをセットする必要があります。

```console:
(python355) C:\Users\***\anaconda3>set QUANDL_API_KEY=xxx123
```

(3)QUANDLから株価データを入手します。

```console:
(python355) C:\Users\***\anaconda3>zipline ingest
```

(4)データセット「quandl」が作成されていることが確認できます。

```console:
(python355) C:\Users\fdfpy\anaconda3>zipline bundles
quandl 2020-06-23 11:59:39.478449
```



#2-3 Beginner Tutorialの実行(コンソールで実行)

コンソールで実行する場合、C:/Users/fdfpy/anaconda3/envs/python355/Lib/site-packages/zipline/examples/buyapple.py を実行します。

(1)anaconda3プロンプトを立ち上げます。

(2)C:/Users/fdfpy/anaconda3/envs/python355/Lib/site-packages/zipline/examples/に移動します。

(3)buyapple.pyを実行し、バックテストを行います。

```console:
(python355) C:\Users\fdfpy\anaconda3\envs\python355\Lib\site-packages\zipline\examples>zipline run -f buyapple.py --start 2016-1-1 --end 2018-1-1 -o buyapple_out.pickle
```


(4)実行結果が表示されます。
<img width="754" alt="85.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/9d0140a7-d64a-48c0-c420-77101255ee59.jpeg">

#2-4 Beginner Tutorialの実行(Jupyter上で実行)

jupyter上で下記コードを実行してください。

```console:
%load_ext zipline
```
```console:
from zipline.api import symbol, order, record

def initialize(context):
    pass

def handle_data(context, data):
    order(symbol('AAPL'), 10)
    record(AAPL=data[symbol('AAPL')].price)
```

```console:
%zipline --bundle quandl --start 2016-1-1 --end 2017-1-1 -o start.pickle
```

下記が出力結果です。バックテストの結果が出力されます。
<img width="602" alt="86.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/3647eac0-d406-3143-1c99-0eef0241cbd2.jpeg">
Railsチュートリアル(第4版)メモ 第6章

Railsチュートリアル(第4版)の個人メモ
気になった部分、忘れそうな部分を記述。

- Ruby 2.6.1
- Rails 5.1.6

前章の最後 (5.4) でUsersコントローラを作成した。そのつづき。
6〜12章にかけて、ユーザ認証の各機能について作成していく。
6章ではこのうち、ユーザのデータモデル、保存について扱われている。

※ おわび
ナレッジになりきれていないメモをQiitaに上げるのが違うような気がしてきたが、
記事として所感を上げれば、それなりに反応があり、勉強にもなったため、お目汚しにはなりますが何卒ご容赦を。
そして最近Rails書いてないのだが下書が埋まってきたので放流。

# 6章 ユーザーのモデルを作成する
Railsでは認証を実装するための仕組みが既に整っているが、サービスごとに認証には多くのカスタムが必要になる。
このため、車輪の再発明にはなるが、方法を知っていればサードパーティ製の認証も実装しやすくなるので、Railsチュートリアルでは車輪を再発明している。

## 6.1 Userモデル
Railsは、データモデルとして扱うデフォルトのデータ構造を `Model` (MVCのM) と呼ぶ。
このModelとのやり取りにはRailsデフォルトでは `Active Record` というものが使われる。
これはSQLを意識せずにCRUDや構築を行ってくれるもの。

### 6.1.1 データベースの移行
データベースを永続化するためにUserモデルを作成。
Usersコントローラ作成時と同様、 `$ rails g` する。

注意として、
コントローラは **複数形** `Users`
モデルは **単数形** `User`

とするのが慣習。

```
$ rails g model User name:string email:string
```

DBで使う属性(DBでいうカラム名)と、型を `:` を挟んで渡す。

諸々生成されるが、 `db/migrate/` には `タイムスタンプ_create_モデル名s.rb`というファイルができる。
ここでDB作成のための情報が定義される。

```ruby:db/migrate/タイムスタンプ_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```

idとタイムスタンプについては、特に指定なしでも自動で用意される。
クラス名の部分を見ると、 `ActiveRecord::Migration[5.0]` を継承しているらしい。
(Railsチュートでは5.0だが、小生の環境は5.1の表記)
`timestamps` は、タイムスタンプに係る2つのカラム [ `created_at`, `updated_at` ] を作成してくれる。

mysqlだとこんなかんじだろうか。

```sql:mysql
CREATE DATABASE User;
USE Users;
CREATE TABLE users(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(300),
  email VARCHAR(300),
  created_at TIMESTAMP NOT NULL CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
);
```

sql書くたびに大文字or小文字 許さないおじさんが発生しそうだな、とビクビクしながら書いている(前職にもいた)。
正直、今の御時世、すべて小文字でも問題ないんだとおもっている。
~~ちなみに前職では日付はvarchar()で書いてうわなにをするやめろ~~

マイグレーションを適用。
友人曰く、複数人開発で特に気を遣わんと爆死するコマンドだから、と念を押された。気をつけよう。
DB側はバージョン管理されてるわけではない。

```shell
$ rails db:migrate
```

### 6.1.2 modelファイル
**演習**
Railsコンソールで `User.new` をし、どのような継承関係に有るのか確認した。

`Userクラス` < `ApplicationRecord` < `ActiveRecord::Base` < `Object` < `BaseObject`

### 6.1.3 ユーザーオブジェクトを作成する
#### railsコンソールのサンドボックスオプション
を使うと、DBへの変更を終了時にすべてロールバックしてくれる。

```shell
$ rails console --sandbox
```

この中での実験。
モデルを生成した際にuserクラスが生成され( `app/model/` )、これが `ActiveRecord` から継承されている。

以下使ったメソッド
`valid?` : 有効性(Validity)の確認
`save` : 保存
保存した際、 `create_at` , `update_at` にタイムスタンプが押される。
戻り値に、保存ができたかどうかのbool値が帰ってくる。

`create` : User.new ではメモリ内に生成するだけだったが、生成と同時に保存する。

**演習**
User.create
user.name
ActiceSupport::timeWithZone

## 6.2 ユーザーを検証する
### 6.2.1 有効性を検証する

要はSQLでのカラム型指定みたいな話
`:email` に対して、 `Double` とか `Boolean` は入らんとか。
以下4点

- 存在性 (presence)
- 長さ (length)
- フォーマット (format)
- 一意性 (uniqueness)

# 所感
- usersテーブルに削除フラグって要るような気がする。後で追加するのか？
- dbのmigrateファイル、いっつも書くidとかをよしなにやってくれるのもだし、varcharとかで文字数指定しなくて良いのだけでも楽。
- dbのmigrateファイル、変更が時系列で残ってくれるのがとても安心感ある。前職ではDBに変更掛けたときのSQLすら遺してなかった。
prometheusとgrafanaをdocker(podman)で10分で構築してみた。

#環境
ubuntu 18.04.4 LTS
podman 1.9.2
podman-compose 0.1.5
#参考サイト
- https://qiita.com/ryuichi1208/items/caf2d32b7a49ce5a39b1

#podmanインストール  
[podman](https://qiita.com/nyapori/items/1a7eb07beba32fd99435)インストールはリンクを参照

#手順

##1.prometheus.ymlを作成

```shell
$ mkdir prometheus-data
```

prometheus-dataの配下に以下を作成

```prometheus.yml
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s

    static_configs:
      - targets: ['localhost:9090']
      
```




##2.docker-compose.ymlを作成

prometheusもgrafanaもイメージが公開されているので構築は楽ちんです。

```docker-compose.yml
version: '2'
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus-data/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - '9091:9090'
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
```


作成後、upする。

```shell
sudo podman-compose up -d
```

以下に接続する

http://localhost:3000/

こんな感じの画面が表示されます。
<img width="1440" alt="スクリーンショット 2020-06-23 21.48.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501815/1ddfcdc6-a074-e5c7-428a-14836049eadf.png">

どんなもんか試していきたいと思います。

## お礼
@ryuichi1208さんのサイトを参考にさせていただきました。ありがとうございました。
Dockerをnginxのリバースプロキシで制御する

# 概要　
一つのレンタルサーバーに複数のWebサイトをURLで制御する必要性があり、Dockerとnginxを用いて組んでみたという話

# 環境
レンタルサーバー : さくらのVPS(1GBプラン)
os : CentOS7
Docker version 19.03.12, build 48a66213fe
nginx version: nginx/1.16.1

# Dockerの環境構築
Dockerを使ったこともない人が付け焼刃でDockerを組んでみたら意外と組めるものであったが...
数点はまったので書いておく  

- systemctlが使えない
まず、普通にCentosのDockerをたてたが、systemctlが認識されない.....
なんと、起動時に指定しないといけないらしい....(知らなかった....)
ということで、Docker runするときに以下のコマンドを追加

```
--tmpfs /tmp --tmpfs /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro --stop-signal SIGRTMIN+3
```  

- portがかぶって複数のコンテナがたたない  
docker container runをするときに ipオプションで ホスト:コンテナの順で、指定する

# Dockerをnginxのリバースプロキシで制御する
ここからは本題のDockerをnginxのリバースプロキシで制御したという話
今回の最終目標は以下の図のようにすることである
![nginx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371782/4f118e80-1765-a800-514a-c5185467d7fa.jpeg)

図の説明をすると、URLを基にDocker1~Docker4のどれかに接続する
今回はSSLについては記述しない
nginxの設定は/etc/nginx/conf.d以下に記述する
接続したいDocckerのコンテナ名でconfファイルを生成する
そこに以下を記述する

```
server{
    listen 80;
    server_name         <接続したいURL>;
    location / {
        proxy_pass    <DockerのIP>;
    }
}
```
この記述ができ次第nginxを再起動する
Reactの問い合わせフォームの作成

# プログラミングの勉強日記
2020年6月23日　Progate Lv.146
React Ⅳ

##問い合わせフォームの作成
　今回はContactFormというコンポーネントを作成して作る。

<img width="571" alt="React7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/cb9f0e94-9981-e94f-769a-f392c30c1f9c.png"><img width="325" alt="React8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/d17038b6-0419-6aba-d1ff-c08e1806a8ae.png">


　フォームのJSXはHTMLとは違う書き方をするので気を付ける。フォーム全体は`<form>`タグで囲む。inputタグは`<input />`、textareaタグは`<textarea />`と書く。送信ボタンHTML同様にinputタグを使い、`type='subimit'`を指定する。表示名を変えたい場合には`value='表示名'`とする。

```jsx:例
<form>
  <textarea />
  <input type='submit' />
</form>
```

##送信完了メッセージの作成
　フォームが送信されたかどうかはstateで管理する。そのためにisSubmittedという真偽値型のstateを用意する。falseのときはフォームをtrueのときは送信完了メッセージを表示する。なので、初期値はfalseである。

```react:ContactForm.js
constructor(props){
  super(props);
  this.state={isSubmitted:false};
}
...

render(){
  let contactForm;
  if(this.state.isSubmitted){
    contactForm= //送信完了メッセージのJSX（※()で囲む）
  }else{
    contactForm= //フォームのJSX
  }
  ...
  return(
    <div>{contactForm}</div>
  );
  ...
```

##onSubmitイベント
　フォームが送信されたときに処理を実行するには、formのタグに対してonSubmitイベントを指定する。

```jsx
<form onSubmit = [()=>{処理}}> ... </form>
```

　stateの値を更新するメソッドを作成して、フォームの送信時に呼び出す。

```react:ContactForm.js
//1.stateの値を更新するメソッドの定義
handleSubmit(){
  this.setState({isSubmitted:true});
}
...
render(){
  //2.フォーム送信時にメソッドを呼び出す
  <form onSubmit={()=>{this.handleSubmit()}}>
  ...
```

##問い合わせフォームを作成する

```react:ContactForm.js
import React from 'react';

class ContactForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isSubmitted: false,
    };
  }

  handleSubmit(){
    this.setState({isSubmitted:true})
  }

  render() {
    let contactForm;
    if (this.state.isSubmitted) {
      contactForm = (
        <div className='contact-submit-message'>
          送信完了
        </div>
      );
    } else {
      contactForm = (
        <form  onSubmit={()=>{this.handleSubmit()}} >
          <p>メールアドレス（必須）</p>
          <input />
          <p>お問い合わせ内容（必須）</p>
          <textarea />
          <input
            type='submit'
            value='送信'
          />
        </form>
      );
    }
    
    return (
      <div className='contact-form'>
        {contactForm}
      </div>
    );
  }
}

export default ContactForm;
```
Gitで上流ブランチを取得する第3の方法

## 概要

`git pull` した時にマージされるブランチ、いわゆる「上流ブランチ」が何かを知りたい時、`git status -sb` の出力を読んだり、ファイル `.git/config` の中身を読めばわかるのですが、そんなことしなくても、

```
$ git rev-parse --abbrev-ref @{u}
```

すれば、わかるんです。

# `git status -sb`

`-s` はshort formatで出力するためのオプション、`-b` はshort formatにおいてブランチ情報を出力するためのオプションで、出力の一行目にブランチの情報が現れます。

上流ブランチが設定されてない場合にはローカルブランチ名だけが出力されます。

```
$ git status -sb | head -1
## master
```

上流ブランチが設定されている場合にはローカルブランチ名の後に"..."、そのあとに上流ブランチ名が出力されます。

```
$ git status -sb
## master...origin/master
```

上流ブランチと同期されてない場合には、上流ブランチ名の後に、ローカルブランチと上流ブランチがコミットいくつ分離れているかが出力されます。上流ブランチより遅れている場合は

```
$ git status -sb
## master...origin/master [behind 7]
```

のように出力され、この状態で `git pull` すると origin/master のコミット7つがfast-forwardでマージできます。

```
$ git log --oneline master...origin/master|wc -l
       7
```

逆に手元のブランチの方が進んでいる場合は

```
$ git status -sb
## master...origin/master [ahead 1]
```

と出力され、この場合は git push するとローカルブランチと上流ブランチが同期されます。

一方、ローカルブランチと上流ブランチが分岐している場合、つまり `git pull --ff-only` が失敗し、`git pull` でマージコミットが生成される状況では

```
$ git status -sb
## master...origin/master [ahead 1, behind 7]
```

のように、ローカルブランチと上流ブランチの、共通の祖先を経由した距離が出力されます。

```
$ git log --oneline master...origin/master|wc -l
       8
```

また、設定された上流ブランチが削除されるなどして存在しなくなった場合には、

```
$ git status -sb
## feature...origin/feature [gone]
```

のようにgoneと出力されます。

## `.git/config`

master の上流ブランチが origin/master である場合、`.git/config` には以下の内容が記載されています。

```
[branch "master"]
        remote = origin
        merge = refs/heads/master
```

この値は以下のようにしても読み出せます。

```
$ git config branch.master.remote
origin
$ git config branch.master.merge
refs/heads/master
```

ここで branch.master.merge の値 refs/heads/master はリモートリポジトリでの表現であり、ローカルリポジトリでは refs/remotes/origin/master で表現されることに注意が必要です。

## `@{u}`


[gitrevisions(7)](https://git-scm.com/docs/gitrevisions) に説明があるように、`@{u}` もしくは `@{upstream}` で上流ブランチを参照できます。

```
$ git rev-parse --abbrev-ref @{u}
origin/master
$ git rev-parse --abbrev-ref @{upstream}
origin/master
```

先に説明した二つの方法では上流ブランチの表現を得るには出力を加工する必要がありましたが、この方法だとそのまま出力してくれるので簡単です。
PHP基礎＜PHPの書き方・表示方法＞



#前書き
PHPを基礎から学習しています。
積み重ねのアウトプットとして更新していきます。

#PHPの書き方

```index.php

<?php // 開始タグ
   echo ('cat');    
   echo ('<br>'); //改行
   echo ('こんにちは');  // プログラム
   echo (123);


```

- 開始タグ<?phpと終了タグ?>を書き、その間にプログラムを記述する
- PHP ファイルの拡張子は .php とする
- '○○'シングルクオーテーションは必ず必要
- echoの場合は（　　）が無くても可
- ;　(セミコロン）は必ず付ける
- コメントアウトは//から改行までか/* から */の範囲に記述する

#ブラウザにPHPを表示する
- MAMPを使ってPHPを表示する

http://localhost:8888/(PHPプロジェクトのフォルダ名)/(PHPファイル名).php
と入力すればブラウザで表示が確認ができる。

#おまけ
PHPコードのみの場合は、ファイルの最後の終了タグ ?> を省略することが公式サイトでも推奨されているそうです。
ご指摘ありがとうございました。
勉強になりました。

#あとがき

初回は基本の書き方のみまとめました。
次回は変数について、初心者の勉強のまとめをしていきたいと思います！
SwiftのKeyPathは結構遅いから気を付けろ

# 実験
SwiftのKeyPathは普通のプロパティアクセスの100倍遅い。

両方を100万回実行して確認。


```swift
var a: Int = 0
class Person {
    var name: String { didSet { a += 1 } }
    init(name: String) { self.name = name }
}

// ドットアクセス
let bobName = "Bob"
let bob = Person(name: bobName)
let start1 = Date()
for _ in 0..<1000000 {
    bob.name = bobName
}
print(Date().timeIntervalSince(start1), "s")

// KeyPathアクセス
let start2 = Date()
let nameKeyPath = \Person.name
for _ in 0..<1000000 {
    bob[keyPath: nameKeyPath] = bobName
}
print(Date().timeIntervalSince(start2), "s")

print(a) // 20000
```
# 結果

|普通のアクセス|KeyPath|
|-----|-----|
|0.0066s|0.6208s|


KeyPathあまり使わないようにしよう...


PlayGroundでは何故か逆になります。
多分Debug表示の関係でプロパティアクセスに特殊な処理がされてる。
wasm-pack + WebWorker + react-scripts

# 前提

- 重い計算を Rust + WebAssembly でやる
- WebAssembly のパッケージは wasm-pack でビルドする
- WebAssembly は WebWorker で動かす
- アプリは React で書く
- アプリの設定を頑張りたくないので react-scripts （create-react-app） を使う

# react-app-rewired

react-scripts では、WebWorker と WebAssembly のロードができないので設定する必要がある。
react-scripts で eject せずに設定を追加するために [react-app-rewired](https://github.com/timarney/react-app-rewired) を使う。

[worker-loader](https://github.com/webpack-contrib/worker-loader) では WebWorker から WebAssembly を import できなかったので、[workerize-loader](https://github.com/developit/workerize-loader) を使う。

こんな感じで `config-overrides.js` を書く。

```config-overrides.js
const path = require("path");

module.exports = function override(config, env) {
  config.module.rules.push({
    test: /\.worker\.js$/,
    use: { loader: "workerize-loader" },
  });

  const wasmExtensionRegExp = /\.wasm$/;

  config.resolve.extensions.push(".wasm");

  config.module.rules.forEach((rule) => {
    (rule.oneOf || []).forEach((oneOf) => {
      if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
        // Make file-loader ignore WASM files
        oneOf.exclude.push(wasmExtensionRegExp);
      }
    });
  });

  // Add a dedicated loader for WASM
  config.module.rules.push({
    test: wasmExtensionRegExp,
    include: path.resolve(__dirname, "src"),
    use: [{ loader: require.resolve("wasm-loader"), options: {} }],
  });

  return config;
};
```

これで拡張子が `.worker.js` のファイルを WebWorker として読み込めるようになる。

`package.json` の `scripts` を以下のように書いておく。

```package.json
  "scripts": {
    "build": "react-app-rewired build",
    "start": "react-app-rewired start"
  },
```



# WebWorker の実装

こんな感じで WebWorker を実装する。

```example.worker.js
export const twice = async (v) => {
  const { twice } = await import("example");
  return twice(v);
};

```

`example` は wasm-pack で作られたパッケージで、dynamic import で読み込む。

workerize-loader では、WebWorkerで呼び出せる関数を named export する。
async/await が使える。

# アプリの実装

いい感じにアプリ側を実装する。
workerize-loader で import したモジュールは関数になっていて、呼び出すと関数を取り出すことができる。
関数は Promise を返すようになっている。

```App.js
import React, { useState } from "react";
import worker from "./hoge.worker";

const { twice } = worker();

const App = () => {
  const [value, setValue] = useState(1);
  return (
    <div>
      <button
        onClick={() => {
          twice(value).then((result) => {
            setValue(result);
          });
        }}
      >
        click me
      </button>
      <p>{value}</p>
    </div>
  );
};

export default App;
```

# 実用例

凸包を計算して描画するプログラムを書いてみた。

https://likr-sandbox.github.io/convex-hull/
【FuelPHP,エラー対処法】Incorrect string value: '\xF0\x9F\x8C\xB8\xE3\x80...'


#はじめに

MacOS
フレームワーク：FuelPHP
環境ソフト：MAMP

#エラー内容

DBに値を入れていたところ下記エラー発生。

```
Incorrect string value: '\xF0\x9F\x8C\xB8\xE3\x80...'...
```

今まで普通に値が入っていたので、入れようとしてる文字が悪いのかなと推測。
よく見ると、🌸の絵文字が笑

ググってみると、文字コードをutf8ではなく、utf8mb4にしないといけないとのこと
[utf8とutf8mb4の違いはこのサイトがわかりやすかったです。](https://tmtms.hatenablog.com/entry/2016/09/06/mysql-utf8)

でも、データベースとテーブルの設定はutf8mb4になっているのになんでかなーと悩んで1時間くらい経った後に気付きました。

#解決法 ： 'charset' => 'utf8mb4'に変更

```:fuel/app/config/db.php
'charset'      => 'utf8mb4',     //変更後
'charset'      => 'utf8',　　　　 //変更前
```
db.phpがutf8のままになってました笑
完全に存在を忘れていました。。。

変更後、問題なくDBに入るようになりました。

ご参考になれば幸いです。
ゼロから始めるLeetCode Day65「560. Subarray Sum Equals K」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day64「287. Find the Duplicate Number」](https://qiita.com/KueharX/items/17081ff496e370e303e2)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！


# 問題
[560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/)
難易度はMedium。
Top 100 Liked Questionsからの抜粋です。

整数の配列と整数 k が与えられたとき，和が k に等しい連続部分配列の総数を求めよ、という問題です。

>Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
 
>Constraints:

>The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

# 解法

```python
import collections

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        dic = defaultdict(int)
        dic[0] = 1
        count = calc = 0
        for n in nums:
            calc += n
            dic[calc],count = dic[calc] + 1,count + dic[calc-k],
        return count
# Runtime: 144 ms, faster than 44.41% of Python3 online submissions for Subarray Sum Equals K.
# Memory Usage: 17.9 MB, less than 10.96% of Python3 online submissions for Subarray Sum Equals K.
```

`defaultdict`を使って書きました。

制約についてはそこまで意識せず、ひとまず解くにはどうやったら良いかを考えました。
calcで累積和を保持し、辞書を使ってkeyの部分で値を保持し、valueの部分で連続で同値が出現した回数を保存し、そして和に遭遇した回数も差し引いたもの`dic[calc-k]`で保持することにより、`count`に要求に沿った値が加算されていく、というものです。

ヒントをSolutionからもらって書きましたがすごくしっくりきますね。


そういえば専門的なアルゴリズムの講義を受けたことがないのですが、思えば他の人がどうやってアルゴリズムを書いているのかをよく知らないんですよね。

僕の考え方は

```
一旦プログラミングのことを考えずにどうやって書くかをぼんやり考える
↓
良さそうな考え方がつかめたら適当に紙とかに書いてちゃんと正しいフローになっているかを考える
↓
Pythonでそのフローを実現するために良さげなライブラリや組み込み関数があるか調べて書く
↓
完成
```

という流れです。
上手くいかない場合はフローを見直して手直ししたりざっくり新しいパターンを書いたり、といった風にしていて、僕の課題はフローを考えるところにあるのかなぁと思ったりしています。（もちろん典型的なアルゴリズムやデータ構造に関してもまだまだ勉強不足ですが）
高校生の時に真剣に受験数学というものに取り組んでこなかったですし、整数や確率、場合の数などについて聞かれると面食らう場合が多いんですよね。

割とそこについての課題を克服するために数学の問題をコツコツ解いたりしているのですが、やはりやりたいことがあってその過程で学ぶ数学はやってて楽しいものがありますね。
学生時代は数学で何かをやりたいと思っていなかったので新鮮な気持ちで取り組めています。

では今回はここまで、お疲れ様でした。
[2020Q2] Docker コンテナでの sshd 起動まとめ w/o init

# はじめに

いくつかのディストリビューションにおいて sshd を起動するミニマムと思しき手順をまとめます。
今回想定しているのは init を使わないで直接 sshd を起動するケースです。

・・・っていう出だしなんですが、どちらかと言うと、鍵を誰が作っているのか、鍵が無かったらどうなるのか、イメージ配布するのに鍵を消したいけど自動的に再生成されるのか、みたいなことがポイントになってます。

対象ディストリビューション：

- CentOS 8
- Ubuntu 20.04 LTS (Focal Fossa)

CentOS 6 と 7 それから Ubuntu 16.04 LTS (Xenial Xerus) と 18.04 (Bionic Beaver) については、[古い投稿](https://qiita.com/teruo-oshida/items/502e0202ac66cd7433f4)にて扱っています。


# そろそろみんな systemd けれど少しずつ微妙に違う

CentOS 8 も Focal も sshd は systemd が管理しています。例えば sshd の起動は下記で共通です。

```
# systemctl start sshd
```


## CentOS はオンデマンドで鍵を生成する

伝統的に CentOS は sshd 起動時に自動的に鍵が生成されます。
もしイメージから鍵ファイルを消しておいたとすると、次回起動時に改めて生成されるということです。イメージ流用の観点からは、この方式は便利です。サンクス。

CentOS 7 と 8 では鍵生成用の systemd unit ファイルが独立して存在し、sshd.service に依存関係が設定されています。ただちょっと 7 と 8 では unit ファイル構成が違っています。


### CentOS 7 はシンプル

```/lib/systemd/system/sshd-keygen.service:
[Unit]
Description=OpenSSH Server Key Generation
ConditionFileNotEmpty=|!/etc/ssh/ssh_host_rsa_key
ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ecdsa_key
ConditionFileNotEmpty=|!/etc/ssh/ssh_host_ed25519_key
PartOf=sshd.service sshd.socket

[Service]
ExecStart=/usr/sbin/sshd-keygen
Type=oneshot
RemainAfterExit=yes
```


### CentOS 8 は target を活用

```/lib/systemd/system/sshd-keygen@.service:
[Unit]
Description=OpenSSH %i Server Key Generation
ConditionFileNotEmpty=|!/etc/ssh/ssh_host_%i_key

[Service]
Type=oneshot
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/libexec/openssh/sshd-keygen %i

[Install]
WantedBy=sshd-keygen.target
```

```/lib/systemd/system/sshd-keygen.target: 
[Unit]
Wants=sshd-keygen@rsa.service
Wants=sshd-keygen@ecdsa.service
Wants=sshd-keygen@ed25519.service
PartOf=sshd.service
```

ふーん、て感じですｗ


## Ubuntu は１回だけ鍵を生成する

伝統的に Ubuntu では openssh-server パッケージの postinst スクリプトが鍵を生成しています。

```
# dpkg-reconfigure openssh-server
```


もしイメージから鍵ファイルを消しておいたとすると、次回起動時に sshd は正常に動きません。イメージ流用の観点からは、この方式は不便です。ざんねん。

そして、鍵が無いとき、sshd の挙動が Bionic と Focal で異なります。Bionic も Focal も `sshd.service` の `ExecStartPre` で `sshd -t` しているのですが・・・


### Bionic は諦めない

Bionic は鍵が無くても `sshd -t` が成功扱い（$? が 0）で、sshd が起動します。しかし鍵が無いと ssh クライアントから接続できません。
ここで sshd を起動したまま鍵を生成すると、ssh クライアントから接続できるようになります。なんだか強い子っぽい。


### Focal は潔い

Focal は鍵が無いと `sshd -t` が失敗し、sshd は起動しません。
個人的には Focal の挙動が好きです。


### ところで

Ubuntu では伝統的に sshd.service は ssh.service へのシンボリックリンクです。


### 実は

`dpkg-reconfigure openssh-server` では dsa 鍵が生成されません。なんでだろ。
ちょっとキモいけど今は無視します。
DakotaをWSLにインストールしましたよ

Dakotaについて

米国サンディア国立研究所で開発されたオープンソースの最適化システムです。
私はこれから勉強するので何も分かってません^^;。

本家
https://dakota.sandia.gov/

2. インストール環境
・Windows 10 Pro （Homeでも問題ないでしょう）
・WSL
・Ubuntu 18.0.4 LTS
（他のバージョンのUbuntuは途中でBoost関連のエラーが出て駄目でした）
※グラフィックは必要なかったので動作を確認してません。
　ごめんなさい。

3. Dakotaソースの入手
本家から、Unix用の最新バージョン「dakota-6.12-release-public.src.tar.gz」を入手します。

4. インストール方法
・下記コマンドを順に実行
・インストール先は、「/usr/local」としました。
・ワークディレクトリは、ユーザーディレクトリ直下の「dakota_install」です。
　ダウンロードしたソースはここに保存しておいてください。
・Linux側のファルダにエクスプローラでアクセスするには「explorer.exe .」と打ち込めば良いみたいです。

以下、インストールのためのコマンド

sudo apt-get update

sudo apt-get upgrade

mkdir -p  dakota_install

cd dakota_install

tar zxf  dakota-6.12-release-public.src.tar.gz

sudo apt-get install gcc g++ gfortran cmake cmake-curses-gui libboost-dev libboost-all-dev libblas-dev liblapack-dev libopenmpi-dev openmpi-bin openmpi-doc xorg-dev libmotif-dev

export DAK_SRC=\$HOME/dakota_install/dakota-6.12.0.src

export DAK_BUILD=/usr/local

cp  \$HOME/dakota_install/dakota-6.12.0.src/cmake/BuildDakotaTemplate.cmake  \$HOME/dakota_install/dakota-6.12.0.src/cmake/BuildDakotaCustom.cmake

ccmake -C \$HOME/dakota_install/dakota-6.12.0.src/cmake/BuildDakotaCustom.cmake \$DAK_SRC -DCMAKE_INSTALL_PREFIX=\$DAK_BUILD

（cmakeでは最初に「c」を押して、次に「g」を押す）

make -j2

sudo make install

make clean

以上です。
iOS14 WidgetKitを触ってみる

# Apple公式ドキュメント
https://developer.apple.com/widgets/

# 環境
Xcode 12.0 beta

# Widget
https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
↑のリンクの手順に沿って作ってみる。

まず、WidgetTestというプロジェクトを作成。
<img width="1392" alt="スクリーンショット 2020-06-23 20.56.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/b4773fc8-8ca0-31de-aee9-934c9ebeab80.png">

Xcode > File > Target... を選択。
<img width="666" alt="スクリーンショット 2020-06-23 20.57.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/6021a243-363b-7582-e105-fa89a8eb74ab.png">

WidgetExtensionを選択して、Next。
<img width="724" alt="スクリーンショット 2020-06-23 20.57.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/6bdf381f-28ef-44c2-5e55-27826ebaf1f9.png">

TimeLineWidgetと名前をつける。(Include Configuration Intent にチェックをつけると、[intentconfiguration](https://developer.apple.com/documentation/widgetkit/intentconfiguration)のWidgetが作れる。)
<img width="718" alt="スクリーンショット 2020-06-23 20.59.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/88b60b65-192e-82f3-4954-bd19d3364f0f.png">

Activateするか聞かれたので、とりあえずActivateする！
<img width="424" alt="スクリーンショット 2020-06-23 21.00.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/04fee2a9-4c68-14f6-4ceb-2a75f235fb2f.png">

TimeLineWidgetのフォルダが追加されて、
TimeLineWidget.swiftにはHello Worldのようにデフォルトのコードが書かれている。
<img width="273" alt="スクリーンショット 2020-06-23 21.09.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/77bb57b6-1959-93a5-b50a-4664000ce617.png">

<img width="680" alt="スクリーンショット 2020-06-23 21.04.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/660799d8-0fe2-3af2-f24c-33637ea6ccfb.png">

この状態で実行してみると、
<img width="401" alt="スクリーンショット 2020-06-23 21.03.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/58042527-5a71-81b7-cdd4-557c88883673.png">

Widgetが追加された🎉
<img width="347" alt="スクリーンショット 2020-06-23 21.05.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156708/e9b3a7c5-ea7c-2524-f1f3-268f9b65e183.png">
メディアクエリの使い方

#メディアクエリの使い方

個人アプリでレスポンシブ対応が必要だったので、その使い方を記事にまとめました。



```php:index.blade.php
<div class = "content">
    @foreach($posts as $post)
      <img src="/storage/{{$post->image}}" class="image" width=293px height=293px>
    @endforeach
  </div>
```

```index.css
@media (max-width: 1420px) {
  .content {
    margin: 90px 218px 0;
  }
 }

 @media (max-width: 1420px) {
  .image {
    width: 280px;
    height: 280px;
  }
 }

 @media (max-width: 1340px) {
  .content {
    margin: 90px 200px 0;
  }
 }

 @media (max-width: 1340px) {
  .image {
    width: 260px;
    height: 260px;
  }
 }

 @media (max-width: 1260px) {
  .content {
    margin: 90px 180px 0;
  }
 }

 @media (max-width: 1260px) {
  .image {
    width: 240px;
    height: 240px;
  }
 }

```

こんな感じで要素の幅によって中身のサイズを調整してあげる。
検証機能を使えば、幅が簡単にわかるので、それを見ながら調整していけば、
自然にビューのレスポンシブができるようになります！
AzureADドキュメントSAML2.0の要求・応答フローの英語説明をDeepLで日本語にした

# はじめに
AzureADを使用してシングルサインオン(SSO)をする要件があり、
その時に調べた、認証方式のSAML2.0の認証要求と応答についてのまとめ。

Azureドキュメントに、認証要求と応答のフローがあったのでそれで学習しました。
[シングル サインオンの SAML プロトコル](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/single-sign-on-saml-protocol)

フローの説明が英語でしたので、日本語にしたく、話題のDeepLを使用して日本語訳にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/364aa432-e6c1-330a-0408-2b8d721a67bf.png)



# 英語・日本語対応表
| No | 英語 | 日本語 |
|:---|:---|:---|
| 1 | User tries to access the application | ユーザーがアプリケーションにアクセスしようとする |
| 2 | Application finds the identity provider to authenticate the user | アプリケーションは、ユーザーを認証するためのIDプロバイダを見つけます |
| 3 | Application generates a SAML2.0 AuthnRequest  and redirects the user’s browser to the Azure AD SAML single sign-on URL | アプリケーションは、SAML2.0のAuthnRequestを生成し、ユーザーのブラウザをAzure ADのSAMLシングルサインオンURLにリダイレクトする |
| 4 | If the user is not signed in, Azure AD authenticates the user and generates a SAML token | ユーザーがサインインしていない場合、Azure AD はユーザーを認証し、SAML トークンを生成します |
| 5 | Azure AD posts the SAML response to the application via the user’s browser | Azure AD は、ユーザーのブラウザを介してアプリケーションに SAML レスポンスを投稿します |
| 6 | Application verifies the SAML Response | アプリケーションがSAML レスポンスを検証する |
| 7 | Application completes user sign-in | アプリケーションはユーザーのサインインを完了します |

# 作成した図
![AzureAD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/57805e53-452d-d30a-9966-7389a01d422e.png)


# 参考
* [シングル サインオンの SAML プロトコル](https://docs.microsoft.com/ja-jp/azure/active-directory/develop/single-sign-on-saml-protocol)
* [DeepL翻訳](https://www.deepl.com/translator)
*
WSL を使って Let's Encrypt で使い捨てのワイルドカード証明書を取る

#やったこと
Windows Subsystem for Linux (WSL) を使って Let's Encrypt で使い捨ての証明書を取ってみたメモ。
Azure WAF にカスタムドメインを当てて SSL を有効化する実験用途で使いました。
（自分用備忘録なので、ちょっと雑なところもありますが…。）

#手順
##まずは certbot をインストール
```
sudo apt install certbot
```

##certbot で証明書を取得
```
sudo certbot certonly --manual --preferred-challenges dns -d *.ドメイン名 --server https://acme-v02.api.letsencrypt.org/directory --register-unsafely-without-email
```

証明書一式は **/etc/letsencrypt/live/ドメイン名** 配下のディレクトリにできるはず。
このディレクトリ、root 権限でないとアクセスできないので注意。

##pem ファイルを pfx ファイルにする
```
openssl pkcs12 -export -inkey privkey.pem -in cert.pem -out servercert.pfx
```
※パスは適宜設定ください

##pfx ファイルのアクセス権変更
※たぶん root の所有物になってるので

```
sudo chown ユーザー名:グループ名 servercert.pfx
```

##Windows 側のエクスプローラーから WSL のディレクトリにアクセスしてキーを取り出し
**\\\\wsl$** にエクスプローラーからアクセスすると、WSL のディレクトリが読める。
ユーザー権限のファイルでないと読めないので、必要なファイルは chown しておくこと。

#まとめ
あとは pfx ファイルを Azure の WAF とか WebApps とかの証明書に使えば色々実験できる。
【Rails】CSVエクスポート機能の実装

# 目標

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/ac716827-b50d-3400-693e-fc52c1c3f3de.gif)

# 開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# 前提

下記実装済み。

・[Slim導入](https://qiita.com/matsubishi5/items/b639ffddecc626856039)
・[Bootstrap3導入](https://qiita.com/matsubishi5/items/b117c95f4dd71340cc80)
・[投稿機能実装](https://qiita.com/matsubishi5/items/1a5aeab651b5822d1f2c)

# 実装

## 1.`application.rb`を編集

```ruby:application.rb
require_relative 'boot'

require 'rails/all'
require 'csv' # 追記

Bundler.require(*Rails.groups)

module Bookers2Debug
  class Application < Rails::Application
    config.load_defaults 5.2
  end
end
```

## 2.コントローラーを編集

```ruby:books_controller.rb
def index
  @book = Book.new
  @books = Book.all
  # 追記
  respond_to do |format|
    format.html
    format.csv do |csv|
      send_users_csv(@books)
    end
  end
end

# 追記
def send_users_csv(books)
  csv_data = CSV.generate do |csv|
    header = %w(ID 登録日 投稿者 タイトル)
    csv << header
    books.each do |book|
      values = [book.id, book.created_at, book.user.name, book.title]
      csv << values
    end
  end
  send_data(csv_data, filename: '本一覧情報')
end
```

### ① CSVファイルのヘッダーを設定する。

```ruby
header = %w(ID 登録日 投稿者 タイトル)
csv << header
```

### ② CSVファイルの内容を設定する。

```ruby
books.each do |book|
  values = [book.id, book.created_at, book.user.name, book.title]
  csv << values
end
```

### ③ CSVファイル名を設定する。

```ruby
filename: '本一覧情報'
```

## 3.ビューを編集する。

```slim:books/index.html.slim
/ 追記
= link_to 'CSVエクスポート', books_path(format: :csv), class: 'btn btn-success'
```
#programming　#csharp　クラス内に定義したクラスの正式名(qualified name)

「+」で連結されるっぽい。

```c#
using System;

namespace qualified_name
{
    class Program
    {
        public class SubClass
        {
            public SubClass()
            {
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine(typeof(SubClass).ToString());
        }
    }
}
```

```plaintext
>qualified_name.exe
qualified_name.Program+SubClass

>
```
Bootstrapでoutlineなalertの作り方

## 環境

- Bootstrap4

## 出来上がり

![bootstrap-outline-alert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100766/a28debce-53b9-4097-85cc-dd263194fd7f.png)


## コード

```html
<div class="alert alert-primary bg-white text-primary">outlineなprimaryアラート</div>
<div class="alert alert-secondary bg-white text-secondary">outlineなsecondaryアラート</div>
<div class="alert alert-success bg-white text-success">outlineなsuccessアラート</div>
<div class="alert alert-danger bg-white text-danger">outlineなdangerアラート</div>
<div class="alert alert-warning bg-white text-warning">outlineなwarningアラート</div>
<div class="alert alert-info bg-white text-info">outlineなinfoアラート</div>
<div class="alert alert-dark bg-white text-dark">outlineなdarkアラート</div>
```

alertをoutlineな感じにするには、通常のalertの要素に`bg-white text-primary`を追加します。