OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで複数の処理や関数の処理速度を計り自動でまとめる

今回のプログラムの出力
3秒かかる処理、1.5秒かかる処理、10秒かかる処理をそれぞれ計測し時間を記録、json形式でtxtファイルに保存しています。
プログラム全体の処理速度のボトルネックの可視化に便利ではないでしょうか。
```
{"3 seconds": 3.0122451782226562, "1.5 seconds?": 1.5078651905059814, "10 seconds?": 10.014142513275146}
```

Pythonプログラムの関数毎に処理速度を計りたい。でもプログラム自体はなるべく改変したくない。普通ならprintで出力して確認すれば済みますが中規模や大規模なプログラムになるとprintは情報の掃きだめになっていたりprintしても出力されなかったり、もしかするとprint禁止というのもありえるかと思います。ログも流れが速すぎて追えない。リモート接続でCUI操作しているときはログの検索も面倒？かもしれません。
誰かの助けになるかはわかりませんが、数行程度挿入するだけでその行間の処理速度を計ってログを取ってくれるプログラムを作りました。
```time_record.py
import time 
import json 
import os 
import datetime
from typing import Any, Dict, List, Tuple


class TimeRecorder:
    def __init__(self,path:str) -> None:
        self.path = path 
        self.start = time.time() 
        self.folder_name = "process_time_records"
        self.folder_init()
        self.records = [] 
        self.speeds = {}

    def get_time_stamp(self) -> None:
        today = datetime.datetime.now()
        return today.strftime('%y%m%d%M%S')

    def folder_init(self) -> None:
        os.makedirs(os.path.join(self.path, self.folder_name),exist_ok= True)

    def time_record_handler(self, section_name: str ) -> None :
        result_so_far = time.time() - self.start
        if len(self.speeds) == 0:
            result = result_so_far
        else:
            result = result_so_far - self.records[-1]
        self.speeds[section_name] = result
        self.records.append(result_so_far)

    def generate_result(self) -> None:
        destination_path = os.path.join(self.path, self.folder_name, "speeds_at_{}.txt".format(self.get_time_stamp()))
        with open(destination_path, 'w') as file:
            file.write(str(json.dumps(self.speeds)))
    
```

使い方
```usage.py
from time_record import TimeRecorder
import time 

def test():
    """
    時間を計りたい関数や処理をインスタンス作成もしくは TimeRecorder().time_record_handler(str)で挟みこむ

    最後にTimeRecorder().generate_result()でpathで指定した場所の下に記録フォルダーを作りそこに結果を保存する。
    """
    path = "" #ログを残したいパスを指定する。 このパスの下にprocess_time_recordsというフォルダを自動で作って実行速度のログを保存していく。
    time_recorder = TimeRecorder(path)
    time.sleep(3)
    time_recorder.time_record_handler("3 seconds?")
    time.sleep(1.5)
    time_recorder.time_record_handler("1.5 seconds?")
    time.sleep(10)
    time_recorder.time_record_handler("10 seconds?")
    time_recorder.generate_result() #os.path.join(path, process_time_records) 以下のtxtファイルに結果を保存する

if __name__ == "__main__":
    test()
```

出力結果
冒頭で出しましたが再度
```
{"3 seconds?": 3.0122451782226562, "1.5 seconds?": 1.5078651905059814, "10 seconds?": 10.014142513275146}
```
それぞれ3秒かかる処理,1.5秒かかる処理、そして10秒かかる処理の時間をおおよそ正しく測定できました。
プログラム全体の高速化を行いたい時にボトルネックになっている処理を数字で確認できるため改善するべき関数にあたりを付けられるほか、json形式で保存されるのでそのままチームで共有することもできるかと思います。
1週目SpringBoot 簡単整理

Springはフレームワーク
Springはオープンソース
SpringはIoCコンテナを持つ=オブジェクトをheap空間に上げれば私が管理するのではなく、スプリングが管理する。
SpringはDiを持つ＝依存性注入が必要なところにメソッドからオブジェクトを注入する時、メモリから持ってきて使用することができる。
Springはかなりのフィルターを持っている
検閲機能をするのがフィルターですが、
フィルター機能をするのがweb.xmlである。スプリングコンテナが持っているフィルターはintercepterと呼ばれ、このインターセプターから入ってくる時、
権限チェック後、入出力をする。 これらすべての作業をフィルターという。

Springは非常に多くのアノテーションを持っている。
アノテーション·リフレクション·コンパイル等
アノテーションとは？ 注釈なのにコンパイラが無視するのではなく、ヒントを与える注釈に行って来なさい。
@Componentクラスメモリにロード
@Autowiredローディングされたオブジェクトを該当変数に入れる。

アノテーションは注釈+ヒントリフレクションは、該当クラスがどのようなものかを分析する技法

Springはメッセージコンバータを有し、既定値はJsonである
メッセージコンバータはジャワオブジェクトを誰かに転送しようとする時Jsonでコンバーティングするのがメッセージコンバータだ
スプリングはBuffedReader、BufferdWriterを簡単に使用可能

JPAとは？
永続性データを生成したプログラムが終了しても消えないデータの特性を意味する。
Javaにある一つのデータを永久的に記録できる環境を提供するAPIという意味。
API
A=アプリケーション
P=プログラミング方法
I=インターフェースでプログラミングをし、この時に作られたプログラム

JavaはORM技術だ オブジェクトを連呼する方法論
ORMは私の奴隷みたいなもの
JPAのインターフェースのルールを守れば、JavaをオブジェクトのDBTableを作ることができる これをJPAのORMと言う。
JPAは繰り返しCRUD作業を省略する。
JPAは、零送性コンテキストを持つすべての情報が保存される。
JPAはDBとOOPの不一致性を解決するための方法論を提供
JPA OOPの観点からモデリングできるようにサポートする。

スプリングブート動作原理
内蔵のトケを持つ
トムキャットを別途設置する必要がなく、すぐに実行可能

トムケットの仕事はJavaコードをコンパイルして.html文書にする役割をする。
web.xmlは大きな城の門番だと考えればいい。
web.xmlのファイルを見てこすりが仕事をする。
Servet/JSPマッピング時(web.xmlに直接マッピングor@WebServletアノテーション使用)にすべてのクラスにマッピングを適用させるにはコードが複雑すぎてFrontControllerパターンを使用
Railsで使用するコマンド

Railsで使用する基本的なコマンドについてまとめた記事です。

# プロジェクトの作成
```:#プロジェクトの作成
rails new アプリケーション名 [オプション]
```
```:#オプション(一部)
# ファイルが存在する場合に上書き
--fまたは -–force	

# データベースの種類(MySQL)
--d=mysql または -–database=mysql

# データベースの種類(PostgreSQL)
--d=postgresql または --database=postgresql

# V（ビュー）を生成しない
--api
```
# Controllerの作成・削除
```:#コントローラの作成
rails g controller コントローラー名 メソッド名1 メソッド名2 ...
```

```:#コントローラの削除
rails d controller コントローラー名
```
# Modelの作成・削除
```:#モデルの作成
rails g model モデル名 カラム名1:カラムの型 カラム名2:カラムの型 ...
```
```:#モデルの作成時に使用できるカラムの型
# 文字列型
string

# テキスト（不定長文字列）型
text 

# 整数型
integer 

# 浮動小数点数型
float 

# 固定長整数型
decimal

# 日時型
datetime

# タイムスタンプ型
timestamp

# 時刻型
time

# 日付型
date 

# バイナリ文字列型
binary 

# 真偽値型
boolean 

# 他のテーブルへの外部キーの定義、_id が付いた整数
references 
```

```:#モデルの削除
rails d model モデル名
```

# DB関係
```:#マイグレーションファイルの実行
rails db:migrate
```
```:#データベースを全て削除
rails db:reset
```
```:#データベースを全て削除し、マイグレーションファイルを古い順に全て実行
rails db:migrate:reset
```
```:#seed.rbの実行
rails db:seed
```
# その他
```:#routeの確認
rails routes
```
```:Gemfileにgemを追加した場合
bundle install
```
1週目Java 基礎

第1週目
Java基礎文法
intを利用した変数指定入力
long、int、short、byteなどがあり、
float,double

boolean等の真の嘘のif文作成
文字は「」
文字列は";

小さいタイプのキャスティングに大きいのを入れる時
inti=(int)30L;こんな風にしなければならない

\n=改行を入れること
フォーマットを作って使うともっと楽だ

mathクラスmax(10,30)=30
min等

文字列数字相互変換
int i = Integer.parseInt(str);

String str2 = String.valurOf(i);
このように相互変換可能

ランダム値を受け取る
Random random = new Randon();
int rand = random.nextInt(bound4) + 5 //5
4までは走る
 
Javaで文字列を入力される場合
Scanner scan = new Scanner(System.in);

String str = scanner.next();
int i = scanner.nextInt();



if文
int i = 10;
if ( i<5 ){
System.out.println("力");
}else {
System.out.println("偽り");
}

このように最初のブロックを実行し、または2番目のブロックに移動
そうでなければelifで先に送ってelseで送る方法もある。


三項演算

boolean inMarried = true;
boolean isMan = false ;

String str;

str=isMarred?"結婚した"結婚してない";

if (isMarried) {
str=「結婚した」
}else{

str="結婚してない";

switch (str) {
case"結婚した":
System.out.println(“O”);
break;
case"結婚してない。 “ :
System.out.println(“X”);

defalut:
System.out.println(“?”);

}

System.out.println(“str”);


反復文
forムーン

for(int i = 0; i < 0 ; i++){

System.out.println(“i”);

while
int i = 0;
while (i<10){
System.out.println(“i”);
i++;
}

do while
int i = 0;
do {
System.out.println(i);
i++;
}while (i< 10); }

break;止めて
continue;空振り


配列[]
{
int[] score = {10, 20, 30, 40 50};
int count = score.length;
System.out.println(score[score.length - 1]);
}

= 20


String[] names = new String[2];
ArrayList<Integer> scoreList = new ArrayList<>();
scoreList.add(10);
scoreList.add(20);
scoreList.add(30);
scoreList.add(40);
scoreList.add(50);
System.out.println(scoreLsit);

マーサード

メインメソッド
System.out.println(add 50, 10, 30)

Public static int add(int x , int y, int z){
return x + y + z;
;

メインメソッド
System.out.println(add(1,2,3,4,5)); = 10
Public static int add(int … numbers){
int sum = 0;
for(int i = 0 ;i < numbers.length; i++)
sum = sum + 1;

return sum ;
;

こうやって作っておけば、呼び出して使用可能。
生成子


gettersetter作り


main
Person person = new Person();
personperson1=newPerson(name:"ホン·ギルドン,age:19);




class person{
private String name;
private int age ;

public Person(){

}

public person(String name , int age){
this.name = name ;
this.age = age ;

Public String getName(){
return name;

}
Public String setName(String name){
this.name = name

}
Public String getAge(){
return age;

}

Public String setAge(int age){
this.age = age

}

toStringに変換しなければならない。
@override


Javaは基本的に他のパッケージにあるものを使うにはインポートをしなければならない。

public他のパッケージでもアクセスできるか

相続 extendsPerson

public boolean isFlying(){
return isFlying;
} <飛ばし機能の追加

public void setFlying(){
isFlying = flying;
}

public void attack(Hero hero){

System.out.println(hero.getName()+"と喧嘩をした";


抽象
マーサードabstractvoid(Herohero);
@オーバーライドして相続した未完成クラスを使用するためにオーバーライドをしなければならない

抽象クラスはニューができない

インターフェース抽象クラスと同じ機能を持つ。

Javaは相続を単一支援だが相続のように指定も可能多重相続も可能

ジェネリック
ArrayList<>の中に入ってくるもの
どんなタイプでも中に入れるようにしてくれる

スレッド

ジャバは基本的にメインゴミとして使用される。
時間差で出力可能
For文などの応用が可能である


ラムダ式
抽象メソッドが一つしかない時に使うもの
UIStackViewをViewBuilderで初期化できるVStackViewとHStackViewを作る

```swift
let stackView = VStackView {
  UserProfileView(imageURL)
  UserNameView(name)
}
```

UIStackViewを便利に使うために、ViewBuilderを作って初期化できるようにしてみます。

```swift
import UIKit

@resultBuilder
public struct ArrangedSubviewBuilder {
    public static func buildBlock(_ components: UIView...) -> [UIView] {
        components
    }
}

public class HStackView: UIStackView {
    public convenience init(
        spacing: CGFloat = UIStackView.spacingUseSystem,
        @ArrangedSubviewBuilder arrangedSubviews: () -> [UIView]
    ) {
        self.init(frame: .null)
        self.spacing = spacing
        
        self.axis = .horizontal
        for view in arrangedSubviews() {
            addArrangedSubview(view)
        }
    }
}

public class VStackView: UIStackView {
    public convenience init(
        spacing: CGFloat = UIStackView.spacingUseSystem,
        @ArrangedSubviewBuilder arrangedSubviews: () -> [UIView]
    ) {
        self.init(frame: .null)
        self.spacing = spacing
        
        self.axis = .vertical
        for view in arrangedSubviews() {
            addArrangedSubview(view)
        }
    }
}
```
Teachable Machineで感じた可能性-初めてAIに触れた感じがした

# TeachableMachineでできること

　デジタルツールを業務改善に生かすことを考えて1か月ほど勉強してきた。AIの世界は自分とは関係ない世界と思って過ごしてきたが、Teachable Machineを動かしてみた時、実は**身近なところにある技術**であることを感じた。
　簡単に説明すると複数のオブジェクトに対し、何枚も写真を撮って、判別させ結果を返す、そんなツールだ。これを使えば、自分では名前が分からない、何に使うか分からない、他との違いについてわからない、いろいろな分からないを教えてあげることが可能になる。
　今回は初歩として、職場の課題に対してどのようにTeachable Machineを活用できるかプロトタイプを作ってみた。
　


![2022-05-18_02h14_22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620988/f0ef2b8c-7e17-f848-ccba-be8a5eb58822.gif)



# 扱う什器や資材の名前や管理場所が分からない

　GMSといわれる総合スーパーでは、さまざまなものがいろいろな売り方で販売されており、そのため売場の担当者はさまざまな資材や部材を使う。そうした事情もあり、いつも使っている資材がそもそも何という名前なのかわからないことも多い。「えっと、透明の…あの挟むやつ…」そう言われても分からず、あれこれ話して結局売場に戻って同じものを確認して初めて理解する、そんなこともよくあることだ。それで写真に撮って判別してもらい、それをどこに取りに行くのか、どこに返すのか、それが分かるとよいと思い、**Teachable MachineをNodeREDに組み込み、Makeと連携させてそれぞれのスマホにLINEで送る**イメージでプロトとタイプを作成してみた。

![ファッションクリップ2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620988/3c8ec285-d62f-2f6f-bd81-5dae009c2eea.jpeg)




# Teachable Machineで課題の解決に向けてアプリ作成

- まずTeachable Machineで3つの什器を読み込ませて判別させる
- 冒頭の動画にあるようにノードを作成し連携させる。TeachableMachineのノードもパレットという機能で追加して判別した什器の名前をhttpリクエストのノードに送る仕組みを作る。
- 次にMakeの画面でWebhookのモジュールとLINENotifyのモジュールを連携させて、Webhookから受けた結果をLINEに送る仕組みを作る。
-  WebhookのURLは最後に'?=shizai' のように要素を付け加えるのが大事。
-  連携が完了したらNode-REDにもどり、Teachable Machineの結果をWebhookに送る。
-  Run onceにしてから撮影すると、その什器の名前がラインに通知される。


![スクリーンショット 2022-05-18 022246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620988/905dd9e0-9bcb-ee4a-8a34-8f90a0a82dbc.png)





　
# 実際に試した結果と課題

　今回は、動画等で勉強した基本的な手順で作成した。資材の名前のみ反映される形になり、実際は、保管場所などの情報も反映させることができたらよかった。Teachable Machineで読み込む**名前の後に、資材庫Aと付けたら、名前と同時に場所も通知される**ので、そうした工夫も取り入れたい。また課題としては撮影するカメラがPCに接続しているWEBカメラだったので、実装に当たっては、什器を事務所に持ってこなければならず、この課題を超えて作成したい。
　**LINEに画像を投稿し、それを送るノードを見つけた**のだが、なかなかうまくいかず、挑戦し続けている。
　今回はwebhookとは何なのか、少し理解が深まり、Node-REDなどのツールも勉強できて、興味深く学ぶ機会ともなった。

<details><summary>使用したツール</summary>

-  node-RED
-  Teachable Machine
-  Make
-  LINE
</details>　



:::note info
Node-REDには、デスクトップ版とWEB版があるようだ。今回作成に使ったのはデスクトップ版になる。

:::
【概要】秘密計算を調べてみた

# 背景・目的
Techplayの「[映像データ解析によるDX協業実例と画像解析AIの未来](https://techplay.jp/event/856909)」というイベントで秘密計算というワードを聞き、興味を持ったので簡単に調べてみました。

# まとめ
- データを暗号化したまま計算できる技術。
- 準同型暗号方式と、秘密分散方式の2つの方式がある。

# 概要
NRIさんの[ページ](https://www.nri.com/jp/knowledge/glossary/lst/ha/secure_computation#:~:text=%E3%83%87%E3%83%BC%E3%82%BFに%E3%82%92%E6%9A%97%E5%8F%B7%E5%8C%96%E3%81%97%E3%81%9F,%E3%81%A8%E6%9C%9F%E5%BE%85%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82)と、EAGLYSさんの[ページ]((https://www.eaglys.co.jp/news/column/secure-computing/international-trends))に解説がありましたので、こちらを元に整理します。ありがとうございます。

## 秘密計算とは

- データを暗号化したまま計算できる技術の総称とのこと。
- 秘匿計算とも呼ばれる。
- データ分析でプライバシー保護を強化する技術の一つ。
- 暗号化したままデータ分析可能なため、組織間のデータ共有などアナリティクスの高度化につながると考えられている。

## 背景
- データを取り扱うプレイヤーが増えてきており、安全に分析する技術が注目されている。
- 今後のデータセキュリティ・データ保護の市場規模
    - 国内の情報ガバナンス / コンプライアンス市場は2019〜2024年までに年平均2.5%で成長し、市場規模が440億円（2019年）から498億円（2024年）にまで拡大する（[2020/11/11 IDC発表](https://www.idc.com/getdoc.jsp?containerId=prJPJ46994020)）
    - 世界のデータ保護市場は628億2000万米ドル（2018年）から年平均15.55%で成長し、2026年には1985億9000万米ドルにまで達する。（[Data Resources, Inc「Global Data Protection Market」> Summary](https://www.dri.co.jp/auto/report/vmr/vmrgldataprotection.html#summary)）

- 市場拡大の背景
    - プライバシー保護に対する危機意識
        - 大規模な情報漏えい事件
        - 法規制強化
    - リモートワーク普及に伴う、データ保護の必要性
    - クラウドコンピューティングの採用によるデータ管理への懸念
    - データ利活用にともなう、セキュリティ対策
    - 機密情報の管理体制の強化
    - 顧客情報等のプライバシー保護の対策

## 方式
準同型暗号方式と、秘密分散方式の2つがある。

### 準同型暗号方式
- 複雑な暗号関数を作る。
- 代表的な技術として、「Gentryの制限付き準同型暗号方式」がある。
- 倍数と偶数ノイズを利用することで暗号化する。
- 暗号化と復号
    - 暗号化には秘密鍵pとランダムな偶数のノイズを加えて、データmを暗号化する。
    - 秘密鍵を持つものは、秘密鍵pの倍数と2で割った余りをみるだけでデータの内容を判定可能。
- 暗号化の強度
    - pの倍数、偶数のランダムノイズを非常に大きな値にすることでデータの解読が難しくなる。
- 課題
    - 暗号化したデータが巨大になり、計算や通信に必要なコストが元データの何倍にも多くなる。


### 秘密分散方式
- データをシェアと呼ばれる暗号化された情報に分割する。
- シェアを複数のサーバに分散して配置する。
- n次多項式がn+1個のデータ点があれば特定できることを利用して情報を分割する。
- 一定数以上のシェアが集まらない限り情報の処理や復元できないように分割する。
- シェアのまま計算する。
- 比較的計算時間は短く済む。
- 課題
    - シェアを分割配布するために複数のサーバが必要でシステム全体として複雑になる。設計や管理コストが増える。

## 研究と今後の活用
- 複雑なモデリングを扱う機械学習や深層学習の領域では、実用化に向けた研究が盛んに行われているとのこと。
- 秘密計算の技術は、データ分析を高度化することに加えて、情報銀行やブロックチェーン上での情報の授受など、プライバシー保護のための次世代の基礎技術として広く活用が想定されているそうです。
- 医学研究への応用を見据えた検証
- 生体認証の仕組みや異種混合学習などの分析技術とのかけ合わせ

# 考察
今回は、秘密計算の概要について学びました。
データは増え続ける中で、個人情報の保護などプライバシー保護を強化される流れは止まらないと考えます。また、データに触れる利用者も増え続け、漏洩などのリスクは大きくなる一方です。
そんな中で暗号化されたまま計算や分析ができるという技術は、今後必須の技術になる可能性があると感じました。
今回は概要のため、深く知ることが出来ていません。今後は動向の確認や、実装など理解していきたいと思います。

# 参考
https://www.nri.com/jp/knowledge/glossary/lst/ha/secure_computation#:~:text=%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%9A%97%E5%8F%B7%E5%8C%96%E3%81%97%E3%81%9F,%E3%81%A8%E6%9C%9F%E5%BE%85%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82

https://www.eaglys.co.jp/news/column/secure-computing/international-trends
ScalaでComputedな値（算出プロパティ）を実装する

jsフレームワークのVueには算出プロパティという便利機能がありまして、
こんな感じの機能をScalaでも使いたかったので実装してみました。

Scalaは雰囲気で使ってるのでよくわかりません。

Vueの算出プロパティって一般的な計算機用語でなんていうんですかね？
スマートゲッターとかメモ化ゲッターじゃなさそう？

以下本体。

```scala:Computed.scala
import scala.collection.mutable

class Computed[T](private var func: Option[Computed[_]] => T) {
  private var cache: Option[T] = None
  private var value: Option[T] = None
  private val parents = new mutable.WeakHashMap[Computed[_], Boolean]
  private var listeners = Seq.empty[Unit => Unit]

  def get(implicit computed: Option[Computed[_]]): T = {
    computed.foreach(parents(_) = true)
    if (needsUpdate) {
      cache = Some(func(Some(this)))
    }
    cache.get
  }

  def :=(func: Option[Computed[_]] => T): Unit = {
    if (func != this.func) {
      value = None
      this.func = func
      modified()
    }
  }

  def ::=(value: T): Unit = {
    val optional = Option(value)
    if (optional != this.value) {
      this.value = optional
      :=(_ => value)
    }
  }

  def needsUpdate: Boolean = cache.isEmpty

  def modified(): Seq[Unit => Unit] = {
    cache = None
    val list = mutable.ListBuffer.empty[Unit => Unit]
    list ++= listeners
    parents.keys.foreach(list ++= _.modified())

    parents.clear()
    list
  }

  def addOnChangeListener(listener: Unit => Unit): Unit = {
    listeners :+= listener
    listeners = listeners.distinct
  }
  def clearListener(): Unit = {
    listeners = Seq()
  }
}

object Computed {
  def apply[T](func: Option[Computed[_]] => T): Computed[T] = new Computed(func)
  def value[T](value: T): Computed[T] = {
    val computed = new Computed(_ => value)
    computed.value = Option(value)
    computed
  }
}

```

以下便利ImplicitConversion。

```scala:Extensions.scala
import scala.language.implicitConversions

object Extensions {
  implicit def computedToValue[R](computed: Computed[R])(implicit parent: Option[Computed[_]] = None): R = computed.get
  implicit def $v[T](value: T): Computed[T] = Computed.value(value)
}
```

以下使い方。

```scala
import test.{Computed => $}
import test.Extensions._

......

val value = $v("最初の値")
var count = 0
var deepCount = 0
val computed = $ { implicit c =>
  count += 1
  value + "です"
}
val deepComputed = $ { implicit c =>
  deepCount += 1
  computed + "だよ"
}

println(count)              // 0
println(computed.get(None)) // 最初の値です
println(count)              // 1
println(computed.get(None)) // 最初の値です
println(count)              // 1

value ::= "次の値"

println(deepCount)              // 0
println(deepComputed.get(None)) // 次の値ですだよ
println(deepCount)              // 1
println(deepComputed.get(None)) // 次の値ですだよ
println(deepCount)              // 1

println(count)              // 2
println(computed.get(None)) // 次の値です
println(count)              // 2
```

最初と更新が入って必要なときだけ計算し、それ以外はキャッシュを返してそうですね。
Scala + libGDXでスマホゲームを作っていて、画面レイアウトを計算するのに便利そうだったので作りました。
【Python】ガウス過程と機械学習- 第0章

# ガウス過程と機械学習0章のノート
- [ガウス過程と機械学習](https://www.kspub.co.jp/book/detail/1529267.html)を読んだ自分用のノートです
- 後で見返す用なので、細かすぎることは書かずあらすじ程度の内容
- 詳しいことは本を買って読んでみてください
- 誤字脱字、間違いなどが有りましたらコメントよろしくおねがいします。
- ベイズ系の話を理解するときに自分が引っかかった部分を丁寧に書いたつもりです。ステップ3だけでも読むと他でも活きるかもしれないです


0章の内容は本当の初学者に対して5つのステップでガウス過程へ導く

## ステップ1
機械学習における学習とは観測されたデータ$(x,y)$から入力$x$を入れることで$y$を予言する関数$f(x)$を何らかの方法で得ること。

## ステップ2
特に入力と出力のセットが与えられているデータを教師ありと呼び、$y$が連続変数の場合は回帰と呼ばれる。

```math
\begin{align}
y &= f(x) + \epsilon\\
f(x) &= w_{1}x + w_{2}
\end{align}
```
という線形回帰をここでは扱っている. ただし, ここで $\epsilon$ は確率的に与えられる誤差.



## ステップ3(確率モデリングとベイズ推定)
- $ y = f(x) + \epsilon $による回帰は$w$というパラメータの値が一つ定まると決まる関数となっている。
- $\epsilon$は確率的に定まる変数. つまり確率変数であるため $y$ は自動的に確率変数になってしまう。　　
この2つの事実から $y$ は $w$ というパラメータによって条件付けられた条件付き確率 $p(y|w)$ に従う確率変数となる。 ここで注意してほしいのは$w$は確率変数ではないということである。条件付き確率における条件は常に確定している値であり、確率変数ではない。

ここから確率モデルをベイズモデルに格上げする。
ベイズモデルではモデルにおける未知のパラメータを確立変数に格上げすることを起点とする.
今の場合だと $w$ を $p(w)$ に従う確率変数であると仮定する。つまり、回帰モデルのパラメータをサイコロ(乱数)振って決めてしまうような状況を考えている.
このような過程を **標本化** もしくは **サンプリング** と呼ぶ。おそらく標本理論における呼び方を踏襲しているのだろう。
- $p(w)$ を事前分布
- $p(w|y)$ を事後分布
と呼んでいる。


イメージを掴む。はじめはどのようなパラメータを用いれば予測がうまくいくのか全く前提知識がない状態で、これが事前分布である。 そこから得られたデータ $(x,y)$ をもとに学習を行っていくことで、良い予測を建てられる $f(x)$ のパラメータ $w$ がどのような値を取るのかを確率的に推定していく。これが学習後に得られる事後分布である。
学習が進むに連れ**良いパラメータ**を発生させる確率が高まっていくのである。



## ステップ4 
ガウス分布(正規分布)は最も基本的な連続変数の確率変数に対する確率分布である。
平均と分散を与えることでその分布を特徴づける事ができる。


## ステップ5(ガウス過程とガウス過程回帰)
- ガウス過程とは関数 $f(x)$ を確率変数と見立てた確率分布である。
- ガウス過程回帰とは得られたデータから $f(x)$ の確率分布をガウス過程の形で求める方法である。

最終的に得られるのは確率生成モデルと呼ばれるものである。
つまり、様々な入力 $x_{1},x_{2},\cdots $ に対してその出力 $f(x_{1}),f(x_{2}),\cdots$ が学習によって得られた事後分布 $p(w|y)$ に従う確率分布に従った確率変数として得られる状態である。
注意してほしいことはこれら１つ1つの入力変数が異なれば全く異なる確率分布に従った確率変数であるということである。(おそらくテキストでは省略されているが、ここでの事後確率分布 $p(w|y)$ は正確に表すと $p(w|y(x))$ という形をしているはず。)
一応注意しておくと、 $f(x)$ に対して同じ値を入力してもその出力はガウス分布に従って確率的に定まるので、基本的には毎回異なる。普通の関数との違いはここにある。

一般に関数 $f(x)$ への入力は無限回行ってもよく、無限個の入力に対して無限個の出力が得られる。これらすべてがガウス分布に従うため、 $f(x_{1}),f(x_{2}),\cdots$ をまとめて、無限次元のガウス分布に従うと言っている。



## 参考文献
- [ガウス過程と機械学習](https://www.kspub.co.jp/book/detail/1529267.html)
Rails6でシステムスペック（capybara 導入）

## はじめに
先日、Rails6 でシステムスペックのテスト実行の際に Capybara が導入されておらずエラーが発生してしまいました。
Rails6 では Capybara はデフォルトでインストールされているはずなのに何故かエラーとなってしまう...。
その原因としていくつか勘違いしていた事がありましたので、まとめたいと思います。
  
### 開発環境
- Rails 6.1.4
- ruby 2.7.3
- rspec-rails 5.1.2

## Capybara の設定
spec_hepler.rb に capybara の設定を追加します
```spec_hepler.rb
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration

require 'capybara/rspec'

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :selenium_chrome_headless
  end
end
```
上記の設定は、実行するタスクによって使うドライバを分けます。JavaScript を使ったテストを実行する場合は Chrome を使うように、そうでない場合はデフォルトの Rack::Test ドライバを使うように設定します。
  
参考:

[公式](https://github.com/teamcapybara/capybara)
  
[Capybaraチートシート](https://qiita.com/morrr/items/0e24251c049180218db4)
  
[rspec-rails 3.7の新機能！System Specを使ってみた](https://qiita.com/jnchito/items/c7e6e7abf83598a6516d)
  
## エラー原因の調査
Capybara の設定をしてシステムスペックでのテストを実行してみるとエラーが発生。Capybara が読み込めていないためメソッドが使えず example で失敗してしまいます。Rails5.1 以降ではデフォルトでインストールされているはずなのになぜありませんと怒られてしまうのか。

**(注)↓ここからは私が踏んだ手順であって本来はこのようなことはしません。かなり遠回りに勝つ無駄に解決しました**
  
### Gem がインストールされているか確認
Gem がインストールされているか確認してみます。
**(本来であればこの段階で簡単に気づけましたが、知識不足でかなり遠回りなことをしています。)**
```
> gem list capybara

*** LOCAL GEMS ***

capybara (3.37.1, 3.35.3)
```
インストールされています。ではなぜか？
  
公式を見てみると
>If the application that you are testing is a Rails app, add this line to your test helper file:
`require 'capybara/rails'`
  
とあり、Rails アプリの場合は`require 'capybara/rails'`の追加も必要そう?なので追加してみるも変わらずエラー。
  
## 解決まで
そもそも Rails5.1 以降はデフォルトでインストールされてるはずだし、gem もインストールされていたのになぜ Capybara が読み込まれないのか。
`Gemfile`を確認してみると`group :test do ~ end`間が全く記載されていませんでした。`Gemfile.lock`も確認してみると`capybara`がありませんでした。
  
### 結論
アプリに`gem 'capybara'`がインストールされていなかった。
なぜ早く気づけなかったのか。その原因としていくつか勘違いしていた事がありました。

#### グローバルの gem について
グローバルにインストールされている gem は明示的に追加しなくてもアプリ内で使えると勘違いしていました。
`グローバル`、`ローカル`、`bundle exec コマンド`らへんのことについて、まだ理解しきれていないことがありました。
そこについての知識があれば今回の件であれば`gem list`を調べる際にも`bundle exec gem list capybara`とすることでローカルにインストールされていないことに気づき簡単に原因追求できたかもしれません。

参考:

[bundler、bundle execについて](https://qiita.com/dawn_628/items/1821d4eef22b9f45eea8)
  
#### rails new の際の -T オプションについて
`-T オプション`をつけると Gemfile の`group :test do ~ end` 間の gem のインストールもスキップされることを知りませんでした。-T オプション は `Minitest`で使用される test ディレクトリが作成されないだけだど勘違いしていました。
　こちらもその知識があれば、そもそも今回のようなことにはなりませんでした。
  
## まとめ
今回のエラーは簡単に解決できるにもかかわらず、知識不足によりかなり遠回りな解決となってしまいました。
今回学んだこととして
- rails new の `-T オプション`は Gemfile の`group :test do ~ end` 間の gem のインストールもスキップされる
- 現在のプロジェクト内でのコマンドの場合は`bundle exec`をつける
- `Gemfile.lock`にない gem はプロジェクトで使用できない

とても初歩的なことばかりですが、今回こうして知る事ができてよかったです。
  
  
間違っている点・勘違いしている点などありましたら、ご教授いただけると幸いです。
EDI業界に3年いたのでまとめてみる①

# はじめに
この記事はポエムです。
参考になる情報はほぼありません。

# EDIとは何か
https://it-trend.jp/edi/article/80-0004#chapter-1

`EDI（電子データ交換）とは、企業間取引で発生する契約書や受発注書、納品書や請求書といった帳票のやり取りを専用回線やインターネットを用いて電子的に行えるシステムのことです。`
具体的に言うと、発注する際の注文書や、納品書、請求書は従来紙でB2Bでも、B2Cでもやり取りしていました。
これを、電子でやり取りできるようにしましょうというのがEDI。
EDIの歴史はかなり古く、
`1980年に、日本チェーンストア協会が流通業界用 EDI標準通信プロトコルとして発表したのが JCA 手順である。`
歴史的背景から見た日本型 EDI と欧米型 EDI 
https://www.dal.co.jp/download/ediblog/Rep_10_200007BookITkeieiRironntoJissai.pdf

と書いてあった。


# EDIの種類

https://www.smclbms.com/smcl/useful_edi/guide_edi_type#title1

`EDIには「レガシーEDI」と「インターネットEDI」があります。`

レガシーEDI:通信手段に固定電話回線を用いるデータ交換の仕組み
→2024年に固定電話回線を用いたデータ交換ができなくなる（2024年問題）のため、下のインターネットEDIに移行の真っ最中。
　閉域網に移行するなどして一部は生き残ると思われる。
具体例：JCA手順、全銀手順、全銀TCP/IP、FAX

インターネットEDI:JX手順やebXML MSなどの手順によってデータ交換するものや、ブラウザからデータの送受信を行うWeb-EDIなどがある。
具体例：JX手順、EDIINT AS2、ebXML MS、FTP、SFTP、HTTPS

関連：2024年問題

https://www.intercom.co.jp/biware/column/pstn-migration.html

引用してまとめてみたら意外に長くなった。
続きは別のところに書こう。
【チートシート】Linux systemctlコマンド使い方まとめ

# はじめに
systemdの使い方はすぐ忘れてしまいます。
忘れてもすぐに思い出せるようにまとめておきました。

# 目的別
## 起動
```
# systemctl start サービス名
```

## 停止
```
# systemctl stop サービス名
```

## ステータス確認
```
# systemctl status サービス名
```

## 再起動
```
# systemctl restart サービス名
```

## 再読み込み
```
# systemctl reload サービス名
```

## サービス自動起動ON
```
# systemctl enable サービス名
```

## サービス自動起動OFF
```
# systemctl diable サービス名
```

## サービス自動起動設定確認
```
# systemctl is-enabled サービス名
```

## 全サービス起動状態の確認
```
# systemctl list-units -t service
```

## サービス自動起動設定の確認
```
# systemctl list-unit-files -t service
```

## 設定ファイルの再読み込み
```
# systemctl daemon-reload
```

# おまけ
もう少し詳しく知りたくなった時
```
# man systemctl
# man systemd
# man journalctl
# man loginctl
# man machinectl
# man systemd.unit
# man systemd.resource-control
# man systemd.special
# man systemd.preset
# man systemd.generator
```
で詳しい情報が見れます。
nvm windowsで「Unexpected token '.'（ピリオドエラー）」を直した話

nvmはnodejsのバージョン管理ツールで、複数のnodejsやnpmバージョンを使いたい場合にとても便利です。しかしWindows版ではnvmのバージョン1.1.7で以下のようなエラーが生じていました。
[GitHub](https://github.com/npm/cli/issues/4234)でも長期に渡って議論されていたようですね。

```
$npm init                  
npm ERR! Unexpected token '.'                                                                                                                                                                                                                   
npm ERR! A complete log of this run can be found in:                                                                    
npm ERR!     C:\Users\****\AppData\Local\npm-
cache\_logs\2022-05-19T13_51_46_969Z-debug-0.log   
```

そこでなんとか直そうとした履歴を残していきます

# 仕様
Windows10
nvm v1.1.7(v1.1.9でもエラー出る人は居るみたいです...)
node v16.15.0

# 目標
以下のスペックを満たせばミッションコンプリート
```
$nvm -v
Running version 1.1.7.
$node -v
v16.15.0 (2022年5月現在のLTS)
$npm -v
8.5.5
$npm init
package name: (test)  #この行が出てほしい
```

# 解決策
とりあえず「Unexpected token '.'」が出たときのエラーログはこんな感じ
```
28 verbose stack C:\Users\****\AppData\Roaming\nvm\v16.15.0\node_modules\npm\node_modules\libnpmexec:1
28 verbose stack ../workspaces/libnpmexec
28 verbose stack ^
28 verbose stack
```

なるほど、一つ上のディレクトリを示すピリオドが反応していないと。ならバッチファイルで書き換えよう。
どうやらシンボリックリンクがlinux用になったままのようだ。
ならば、相対パスを絶対パスに書き替えれば動きそうですね。ということでお得意のバッチファイルを作成してみました。

```bash:npm_rename.bat
@echo off 

rem キーボード入力
set INPUT_VERSION=
set /P INPUT_VERSION="対象のnodejsバージョンを入力してください(例：16.15.0): "

rem 遅延環境変数を設定
setlocal ENABLEDELAYEDEXPANSION

rem ディレクトリ移動
cd %NVM_HOME%\v%INPUT_VERSION%\node_modules\npm\node_modules

rem 今回対象となるlibnpmで始まるファイルをfor文で処理
for %%a in (libnpm*) do (

  rem 変数に上書きしたいパスを代入
  set line="%NVM_HOME%\v%INPUT_VERSION%\node_modules\npm\workspaces\%%a"

  rem ファイルを上書き
  echo !line! > %%a
)

echo 上書きに成功しました。
pause
exit /b
endlocal

```

ということで5時間掛かりましたが、なんとかシンボリックリンクとの闘いは終結しました！
Windows特有の二重バックスラッシュを付けたり、スラッシュにしたり、いろいろ試しましたが、やはり絶対パスをダブルクォートで括るのが正攻法でしたね。
いや～解決してよかったよかった！
もし自身の環境でnvmの入れ直しを行いたくない場合などにはぜひご利用ください！！！

# p.s.
本当はnodejsのバージョンも含むパスが変数で取れれば良かったんですけど、今回は手当たり次第だったので超絶長いパスになってしまってます。
また時間ある時に探してみます(きっとあるはず)。もし知ってる方居ましたらお気軽にコメントお願いします。
Pythonスクリプトのメモリリークを探す

どんなプログラミング言語でもメモリリークの追跡は難しいものです。特に、他人の作ったライブラリでメモリリークがある場合、原因を切り分けるのは非常に面倒な仕事になります。

Pythonにはtracemallocという組み込みモジュールがあり、これがメモリリークの調査に便利だったのでまとめてみます。

## メモリ消費量トップ10を出す

tracemallocのマニュアルにも書いてあるのですが、下記のようにするとメモリ消費量のトップ10が出せます。

```python
import tracemalloc

tracemalloc.start()

# ... メモリリークしてるっぽい処理 ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

print("[ Top 10 ]")
for stat in top_stats[:10]:
    print(stat)
```

これを実行すると、下記のような結果が得られます。

```
[ Top 10 ]
/usr/lib/python3.7/encodings/utf_8.py:16: size=11.1 MiB, count=307696, average=38 B
/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/utils.py:45: size=4466 KiB, count=15042, average=304 B
/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/utils.py:38: size=3617 KiB, count=53719, average=69 B
/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/scanner.py:276: size=2592 KiB, count=37355, average=71 B
/home/pi/.local/lib/python3.7/site-packages/bleak/backends/scanner.py:35: size=2318 KiB, count=35176, average=67 B
（以下略）
```

どうやら`encodings/utf_8.py`の16行目で確保しているメモリが解放されていないようです。

## バックトレースつきで表示する

上記の内容だけで原因がわかればいいのですが、ライブラリの最内側の処理だけ示されても問題の特定が難しいことがあります。バックトレースつきで表示すると原因がわかりやすくなります。

```python
import tracemalloc

tracemalloc.start(15)

# ... メモリリークしてるっぽい処理 ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('traceback')

print("[ Top 10 ]")
for stat in top_stats[:10]:
    print(stat)
    for line in stat.traceback.format():
        print(line)
    print("=====")
```

実行結果は次のようになります。

```
[ Top 10 ]
/home/pi/.local/lib/python3.7/site-packages/dbus_next/aio/message_bus.py:365: size=5133 KiB, count=153575, average=34 B
  File "/home/pi/.local/lib/python3.7/site-packages/dbus_next/aio/message_bus.py", line 365
    if self._unmarshaller.unmarshall():
（中略）
  File "/home/pi/.local/lib/python3.7/site-packages/dbus_next/_private/unmarshaller.py", line 172
    return decode(str_mem_slice)
  File "/usr/lib/python3.7/encodings/utf_8.py", line 16
    return codecs.utf_8_decode(input, errors, True)
=====
（以下略）
```

呼び出し元が表示されるので、原因特定の助けになりますね。

ちなみに`tracemalloc.start()`の第一引数がバックトレースの段数で、これを増やせばもっと上まで追いかけることができます。

## スナップショット2回の差分を表示する

特定の期間でのメモリ消費量の差分を表示したい場合は次のように記述できます。

```python
import tracemalloc
tracemalloc.start()
# ... アプリケーション開始 ...

snapshot1 = tracemalloc.take_snapshot()
# ... メモリリークしてそうな関数呼び出し ...
snapshot2 = tracemalloc.take_snapshot()

top_stats = snapshot2.compare_to(snapshot1, 'lineno')

print("[ Top 10 differences ]")
for stat in top_stats[:10]:
    print(stat)
```

この場合も `Snapshot.compare_to()` の第二引数を`'lineno'`から `'traceback'` に変更することでバックトレース表示できます。

## 参考URL

- https://docs.python.org/ja/3/library/tracemalloc.html
Railsのマイグレーション関連のコマンド（備忘録）

# はじめに
Rialsのマイグレーション関連のコマンドを備忘録としてまとめました。

# migrationとは？
<details><summary>【Railsガイド参照】</summary>
マイグレーションは、データベーススキーマの継続的な変更（英語）を、統一的かつ簡単に行なうための便利な手法です。マイグレーションではRubyのDSLが使われているので、生のSQLを作成する必要がなく、スキーマおよびスキーマ変更がデータベースに依存しなくなります。

個別のマイグレーションは、データベースの新しい「バージョン」とみなせます。スキーマは空の状態から始まり、マイグレーションによる変更が加わるたびにテーブル、カラム、エントリが追加または削除されます。Active Recordはマイグレーションの時系列に沿ってスキーマを更新する方法を知っているので、履歴のどの時点からでも最新バージョンのスキーマに更新できます。Active Recordはdb/schema.rbファイルを更新し、データベースの最新の構造と一致するようにします。
</details>

マイグレーション機能があることにより、SQLを書くことなくRubyでデータベース内にテーブルを作成することができます。Rails内のActiveRecordという機能がRubyをSQLに自動翻訳することができるため、SQLを書く必要がなくなります。

# コマンド
### migrate
```
$ rails db:migrate
```
migrationファイルを元に、データベースに変更を加える。

### status
```
$ rails db:migrate:status
```
migrationファイルの適用状態を確認する。
up・・・マイグレーションファイルを実行済み。
down・・・マイグレーションファイルがまだ実行されていない。

### up
```
$ rails db:migrate:up VERSION=20220101080718
```
指定したマイグレーションファイルのみ実行する。

### down
```
$ rails db:migrate:down VERSION=20220101080718
```
指定したマイグレーションファイルのみ外す。

### rollback
```
$ rails db:migrate:rollback
```
データベースの構造を前の状態に戻す。

### reset
```
$ rails db:migrate:reset
```
データベースの初期化し、何も入っていない状態にする。

# 参考URL
[Active Record マイグレーション](https://railsguides.jp/active_record_migrations.html)
[【Rails入門】データベースを設定するrails db:migrateを説明！](https://www.sejuku.net/blog/14229)
[Rails初心者がつまずきやすい「マイグレーション」](https://www.transnet.ne.jp/2015/12/29/rails%E5%88%9D%E5%BF%83%E8%80%85%E3%81%8C%E3%81%A4%E3%81%BE%E3%81%9A%E3%81%8D%E3%82%84%E3%81%99%E3%81%84%E3%80%8C%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8Dcolnr/)
Kibanaを学習する際に役立つサンプルデータ集

Kibanaを用いてVisualizeやDashboardの学習を行うためには、それに表示するデータが必要です。
既に学習に利用可能なデータが存在している場合はそのデータを使用すれば良いですが、そうでない場合は自身でデータを作成するか、サンプルデータを利用する事になると思います。この記事では、学習に役立つサンプルデータを追記していきます。

# Kibana とは
全文検索エンジン「Elasticsearch」と連携して使用するデータ解析, 可視化ツールです。
データを図や表などの形で視覚化可能なWebアプリケーションです。
Kibanaの導入方法などは前提とし、今回は割愛します。

# サンプルデータ
##### 1. シェイクスピア全集
ダウンロード先URL: https://www.elastic.co/guide/jp/kibana/current/tutorial-load-dataset.html

シェイクスピアデータセットは、次のスキーマで構成されています。
```json
{
    "line_id": INT,
    "play_name": "String",
    "speech_number": INT,
    "line_number": "String",
    "speaker": "String",
    "text_entry": "String",
}
```

##### 2. ランダムに生成された架空口座集
ダウンロード先URL: https://www.elastic.co/guide/jp/kibana/current/tutorial-load-dataset.html

架空口座データセットは、次のスキーマで構成されています。
```json
{
    "account_number": INT,
    "balance": INT,
    "firstname": "String",
    "lastname": "String",
    "age": INT,
    "gender": "M or F",
    "address": "String",
    "employer": "String",
    "email": "String",
    "city": "String",
    "state": "String"
}
```

##### 3. 架空従業員5万人の情報集

架空従業員5万人データセットは、次のスキーマで構成されています。
```json
{
    "FirstName": "String",
    "LastName": "String",
    "Designation": "String",
    "Salary": INT,
    "DateOfJoining":"date"
    "Address": "String",
    "Gender": "String",
    "Age": INT,
    "MaritalStatus": "String",
    "Interests": "String"
  }
```

##### 4. 架空従業員10万人の情報集

架空従業員10万人データセットは、次のスキーマで構成されています。
```json
{
    "FirstName": "String",
    "LastName": "String",
    "Designation": "String",
    "Salary": INT,
    "DateOfJoining":"date"
    "Address": "String",
    "Gender": "String",
    "Age": INT,
    "MaritalStatus": "String",
    "Interests": "String"
  }
```
AWS Lambda における Python 3.6 のサポート終了

# 課題
皆さんにもこんな通知が届きましたよね。
>「AWS Lambda における Python 3.6 のサポート終了」

今回、ご丁寧に一覧表示する為のコマンドラインまでプレゼントされています。
ただ、クラウドエンジニアな私達は世界中に駆け回っているわけなので、一定のリージョンを調べるだけではダメなのです。

ということで今回は単にリージョン全てをチェックする sh をどうぞ。

# 解決
## AWS公式
>次のコマンドは、AWS CLI [3] を使用して、特定のリージョン内の Python 3.6 を使用しているすべての関数を一覧表示する方法を示しています。お客様のアカウント内のこうした関数すべてを確認するには、リージョンごとに次のコマンドを繰り返してください。

```
aws lambda list-functions --function-version ALL --region us-east-1 --output text --query "Functions[?Runtime=='python3.6'].FunctionArn"
```

## カスタマイズ版
### コード
```sh
#!/bin/sh

for region in `aws ec2 describe-regions --region ap-northeast-1 --all-regions | jq -r .Regions[].RegionName`
do
  echo "# region: ${region}"
  aws lambda list-functions --region ${region} --output table --query 'Functions[?Runtime == `python3.6`].{FunctionName: FunctionName, Runtime: Runtime}'
done
```

### 結果
```text
# region: ap-northeast-1
--------------------------------
|       ListFunctions          |
+-----------------+------------+
|  FunctionName   |  Runtime   |
+-----------------+------------+
|  hoge_function  |  python3.6 |
|  fuga_function  |  python3.6 |
+-----------------+------------+
```

# 一言
もっと言うと複数のAWSアカウントを股に掛けて仕事していますけどね。
Moralis Unity SDKでスマートコントラクトの実行まで

## 概要
Moralis SDKのサンプルがスマートコントラクトの実行の部分で古い関数を使っていたので、新しい関数を使用したコントラクトの実行について記載します。

## 準備
ウォレットのログインや署名を済ましておきます。
ここができていないとスマートコントラクトの実行時にエラーが発生します。

## 実行
実際のコードです。

以前だとスマートコントラクトインスタンスの生成などが必要でしたが、新しい関数ではそのままスマートコントラクトの実行が可能です。

```c#:コード
        private const string CLAIM_FUNCTION = "fugaFunction";
        private const string ABI ="hogehoge";
        private const string NFT_ID = "1";
        private const string CONTRACT_ADDRESS = "fugafuga";

        public async void Execute()
        {  
            if (BigInteger.TryParse(TOKEN_ID, out var bi))
            {
                // コントラクトコールが期待するように、トークンIDを16進数に変換します。
                object[] pars = {bi.ToString()};

                // ガスの推定値を設定する
                var gas = new HexBigInteger(0);

                var resp = await MoralisInterface.ExecuteContractFunction(CONTRACT_ADDRESS,
                    ABI,
                    CLAIM_FUNCTION, pars, new HexBigInteger("0x0"), gas, gas);
            }
        }
```

## 注意点
ちなみに私は以下の２つでエラーが発生しましたので、ご注意ください。
- ログインが正しくできていない。
- ABIが正しく設定されていない。

ABIはremixから以下のように取得することができます。
（ダブルクオーテーションをエスケープして上記の定数に設定します。）

1. コンパイル
1. 対象のコントラクトを選択
1. ABIボタンを押下

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480278/40d8a0f4-ee79-c4ee-6987-e9678490d5b3.png" width = 50%>

## お知らせ
Web3ゲームを新たに作ろうかなと思っています。
構想とかも含めてになりますが、興味ある方がいればツイッターからDMください！
よろしくお願いします。
【AWS】セキュリティグループに紐づいているEC2インスタンスを特定する方法

# はじめに
備忘録レベルにはなりますが、セキュリティグループに紐づいているEC2インスタンスを特定する方法について記事に残したいと思います。

# 環境

|  項目 |  内容  |
| ---- | ---- |
|  OS  |  macOS Monterey バージョン 12.3.1  |
|  Homebrew  |  3.4.10  |
|  AWSCLI  |  2.6.3  |

```zsh:Homebrew
% aws --version
aws-cli/2.6.3 Python/3.9.12 Darwin/21.4.0 source/x86_64 prompt/off
%
```

:::note info
個人で作成したAWSの擬似環境を利用します。
EC2インスタンス作成済み
:::

# 作業手順
以下の流れで作業を実施します。

**①マネジメントコンソールにて対象のセキュリティグループのセキュリティグループIDを確認**
**②AWSCLIにてセキュリティグループの詳細情報を確認**
**③EC2インスタンスの特定**

## ①マネジメントコンソールにて対象のセキュリティグループのセキュリティグループIDを確認
マネジメントコンソールからEC2ダッシュボードを開き、「セキュリティグループ」を選択する。
選択後、対象のセキュリティグループのセキュリティグループIDを控える。

![スクリーンショット 2022-05-19 22.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/49666c03-ec7f-9a76-7995-22d43a9690bd.png)

## ②AWSCLIにてセキュリティグループの詳細情報を確認
ターミナルを起動し、以下コマンドを実行する。
実行結果の`InstanceId`を控える

```zsh:コマンド
aws ec2 describe-network-interfaces --filters Name=group-id,Values=<group-id> --region <region> --output json
```

```zsh:実行例
% aws ec2 describe-network-interfaces \
--filters Name=group-id,Values=sg-0eb9c************ \
--region ap-northeast-1 --output json
{
    "NetworkInterfaces": [
        {
            "Association": {
                "IpOwnerId": "amazon",
(省略)
                "NetworkCardIndex": 0,
                "InstanceId": "i-0ae56a60********", ← これ
(省略)
%
```

## ③EC2インスタンスの特定
マネジメントコンソールにてEC2ダッシュボードを開き、インスタンスを選択。
控えたセキュリティグループIDにて検索を実施し、対象のインスタンスを確認する。

![スクリーンショット 2022-05-19 22.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/ad083002-6d6b-9eb2-a288-6214ad069ef7.png)

※AWSCLIでも確認可能です。(タグのみ抽出)

```zsh
 % aws ec2 describe-instances \
  --filters "Name=instance-id,Values=i-028*********" \
  --query "Reservations[].Instances[].Tags[]"
[
    {
        "Key": "Name",
        "Value": "tspserver01"
    }
]
%
```

`--filter`や`--query`の使用方法は、以下を参照下さい。

https://qiita.com/masato930/items/e480bca687052d447538


# 参考記事
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-find-security-group-resources/
Laravelでデフォルト以外のディレクトリでfactoryを読み込む

# 背景

先日ユニットテストを実装中に、factoryを規定のディレクトリ以外から読み込みたいことがあった。

そのプロジェクトではリポジトリパターンを採用していて、

factoryがvendor配下にあるという特殊な作りをしていたため。

# 実装方法
```
app()->useDatabasePath('vendor/models/database');
```

これでvendor配下がfactoryの置き場所として読み込まれる。
Amanon LinuxでApacheのインストール

【AWS】Amazon LinuxにてApacheのインストールを行いました。

Apacheのインストール
-
まずはEC2でインスタンスを立ち上げて、下記のコマンドを入力します。
![インストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/e5f8f9ae-fee9-cab7-f892-1e9335fb3132.png)

Complete!が表示されればOK！
![コンプリート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/50aa83a5-2747-7a79-43f1-b68902a5302f.png)

状態確認
-
下記コマンドを入力して状態確認を行います。
![状態確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/97f66518-52c6-0371-255b-5cbf39cad4b8.png)
状態が『inactive(dead)』になっているのでapatchが起動していないことが分かります。

root権限に変更
-
ここで、この後使うコマンドのためにec2-userからrootに変更しました。
![root.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/9ce49c26-7cf1-1dc0-06ba-9c7e10d3d05b.png)

Apacheを起動
-
![起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/afefd64d-6625-7605-e667-f8f615cfc4f4.png)

コマンドを打っても何の反応もないので心配になりますが、ちゃんと命令は届いてます。
次の状態確認コマンドで確認しましょう。

再度状態確認
-

![起動完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664791/1fd52412-7bad-db59-f623-cdea8755c0c3.png)


状態が『active(runnning)』になっていることが確認できました。以上で完了になります。ありがとうございました。


参考
-
下記のサイトを参考にさせていただきました。

https://www.dot-plus.com/cloud-service/aws/3033/

https://otablo.net/apache-basic-commands/#:~:text=Apache%E3%81%AE%E7%8A%B6%E6%85%8B%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%9F%E3%81%84%E3%81%A8%E3%81%8D%E3%81%AF%20systemctl%20status%20httpd%20%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%20%E5%81%9C%E6%AD%A2%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E6%99%82%E3%81%AF%20Active%3A%20inactive,%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82%20%EF%BC%88%E5%88%86%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%88%E3%81%86%E3%81%AB%E8%B5%A4%E5%AD%97%E3%81%AB%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82%20%EF%BC%89%20Apache%E3%81%8C%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E6%99%82%E3%81%AF%20Active%3A%20active%20%28running%29%20%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
【Python】話題の音声認識ツールキット Vosk を試してみた

# はじめに

こちらの記事は[Zenn](https://zenn.dev/kama_meshi/articles/517acebcdd1d61)にも投稿しています。

たまたまTLで見かけたので試してみました。結果から言うとすごく簡単、触っていておもしろかったです。

https://twitter.com/meganetaaan/status/1525855166284861440

# What is Vosk?

20言語以上に対応した音声認識ツールキット。言語モデルが50MBと軽く、組み込みがしやすいです。[^1]
PythonはもちろんのことNode.jsやJava, C#でも実装可能。ラズパイ/iOS/Android用のビルド、Websocketサーバまで用意されているという準備の良さです。
**なおM1 Macには非対応です。**
詳しくは [Vosk](https://alphacephei.com/vosk/) のリファレンスで。

# サンプル音声の準備

まずは音源の準備をします。フリーの素材がないかと探していたところ [こえやさん](https://www.koeyasan.com/) と言うサイトを見つけたので今回は[こちら](https://www.koeyasan.com/voices/558)のファイルを拝借。

Voskのページをみると、しれっと以下のような記載があったのでffmpegで変換します。
> When using your own audio file make sure it has the correct format - PCM 16khz 16bit mono.

```shell
ffmpeg -i sample_voice.wav -ar 16000 -ac 1 -f s16le sample_voice_16khz.wav
```

# Let's coding

Voskはpipでのインストールが可能です。ただ私は[poetry](https://python-poetry.org/)が好きなのでそちらでインストールしてみます。
どうやらMacOSだと最新版 (`0.3.38`) が対応しておらずインストール時にエラーに。pipでインストールできるバージョンに落としてインストールします。（2022-05-19 執筆時点）

また言語モデルは[こちら](https://alphacephei.com/vosk/models)にあがっているのでDL。Zipを解凍して使います。

```shell
poetry add vosk@0.3.32
curl -O https://alphacephei.com/vosk/models/vosk-model-small-ja-0.22.zip
unzip vosk-model-small-ja-0.22.zip
mv vosk-model-small-ja-0.22/ model/
```

PythonモジュールはExampleがあったのでそこから落として適当に書き換えます。（引数でファイル名渡していたのを先述の音源ファイルに変えただけ。バージョンはインストールしたものに合わせています。）

```Python:main.py
# wf = wave.open(sys.argv[1], "rb")
wav = "sample_voice_16khz.wav"
wf = wave.open(wav, "rb")
if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
    print ("Audio file must be WAV format mono PCM.")
    exit (1)
```

https://github.com/alphacep/vosk-api/tree/v0.3.32/python/example/test_simple.py

そうして実行すると、、、

![Terminal gif](https://storage.googleapis.com/zenn-user-upload/b5161254f3d1-20220519.gif)


おぉ、少し違うところもあるけどちゃんと漢字まで日本語認識できてる！！
> ちなみに音源のテキストは「ご視聴ありがとうございました！グッドボタンとチャンネル登録よろしくお願いします！」です。

Exampleには他にマイクからとってくるモジュールもありましたのでそちらも試してみたいですね。

# おわりに

いかがでしたでしょうか？
精度の高さ＆50MBという軽さ＆気軽に試せると3点よしでVoskとってもいい感じでした。
皆さまも是非試してみてください！

コードはGitHubとReplitにあげています。
よろしければ気軽にフォローしていただけるとアヒルくんが喜びます。

Thank you for reading my post. Happy Development!!

https://github.com/kama-meshi/HelloVosk

https://replit.com/@kama-meshi/HelloVosk

[^1]: 後にリンク乗せていますが、まさかReplitでも動くとは思わなかった。。。それだけ組み込みしやすいということですね。
[初学者]　HTMLでwebサイトを作成するために必要な知識　①

# HTMLでwebサイトを作成する


## 用語

### タグ

```:タグ
<> </>
```
開始タグ、終了タグなど
要は<>１つでタグ

### 要素
```:要素
<h1>HTML</h1>
```
タグも含めた、これ全体を要素と呼ぶ
**h1は要素名**である

### 属性

```:書き方
<要素名 属性="属性値">

1.要素名の後ろに半角スペース
2.属性に = を付ける
3.属性値を " or `で囲む
```

要素名に対して、属性という設定をつけるイメージ

```:意味
要素名の、属性（設定）は、属性値
```
と置き換えて読めばいい


```:例
<img src="http://......">
```

画像(img)の場所(src)は”http://.....”(url)




## 語法一覧

### 見出しをつける

```:書き方
<h1>見出し</h1>
<h2>見出し</h2>
.
.
.
<h6>見出し</h6>
```

`<h1>...</h1>`から`<h6>...</h6>`まで大見出し、中見出し、子見出しと昇順で重要度は低くなる

### リンクを貼る

```:書き方
<a href="http://.......">リンク名</a>
```

ブラウザにURLは表示されない


### 段落をつける

```:書き方
<p>段落</p>
```

見出し以外の要素に使用


### 画像の表示

```:書き方
<img src="http://......">
```

img 要素はテキストを囲まないので、終了タグは不要


### リストの表示

```:書き方
<li>リスト</li>
```

#### リストの種類

•箇条書きリスト
```:書き方
<ul>
 <li>赤</li>
 <li>青</li>
 <li>黄</li>
</ul>
```

```:表示
•赤
•青
•黄
```

•順序付きリスト

```:書き方
<ol>
 <li>赤</li>
 <li>青</li>
 <li>黄</li>        
</ol>
```
```:表示
1.赤
2.青
3.黄
```

•説明リスト
```:書き方
<dl>
 <dt>質問A</dt>
 <dd>回答A</dd>
 <dt>質問B</dt>
 <dd>回答B</dd>      
</dl>
```

```:表示
質問A
   回答A
質問B
   回答B
```

>参照
>>Progate 
HTML & CSS 初級編
Axios × Rails 複数の画像を非同期通信で楽天FTPサーバにアップロードする

# 前提
仕事で楽天FTPサーバに画像をアップロードする作業ができてしまって、毎回FTPソフト開くのが面倒だなと思い簡単なウェブアプリを作りました。

# 完成品
ファイルを選択し、アップロードボタンを押すだけ。あとはRailsくんが頑張ってFTPにあげるのを待つのみ。
画像は1枚でも複数枚でも対応できます。
![スクリーンショット 2022-05-19 21.05.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227249/244644db-6a23-17c1-ad39-2b1b937a379b.png)

# この記事で言及しないこと
* 上記の画像プレビュー機能（`new FileReader`とか`readAsDataURL`でググると良記事がたくさん出てきます）
* フロントはVue3で書いています。`@change`とか文法的なことは説明しない。
* axiosの使い方

# フロント
## html
```html
<label for="image-uploader">ファイルを選択</label>
<input type="file" multiple accept=".jpg"
    id="image-uploader" style="display:none;"
    @change="onFileChanged"
/>
...
<button @click="uploadToFTP">アップロード</button>
```
`multiple`: 複数のファイルを選択できるようにする
`accept=".jpg"`: .jpg画像のみ受け付ける
`style="display:none;"`: ファイル選択の窓は`<label>`で発火させているので隠す
`@change="onFileChanged"`: ファイル読み込み終わったら`onFileChanged`関数を呼ぶ

## JavaScript
```js
const formData = new FormData(); // ......A
// データを準備
function onFileChanged(e) {
    const files = e.target.files; // ......B
    [...files].forEach((file) => { // ......C
        formData.append("images[]", file); // ......D
    })
}
// アップロードした画像をFTPにあげる
function uploadToFTP() {
    axios.post("/Rails側で決めたパス", formData) // ......E
}
``` 
**A**
非同期的にデータを送るので[formData](https://javascript.keicode.com/newjs/how-to-use-formdata.php)をまずnewします。
**B**
読み込んだ画像データは`e.target.files`から取り出します。
**C**
取り出した`files`の中から画像データを一件ずつformDataに追加します。しかしこの`files`は[FileList](https://developer.mozilla.org/ja/docs/Web/API/FileList)という型のオブジェクトで、`forEach`が使えません。なのでスプレッド構文で配列に変換します。
**D**
`formData`に画像データを入れます。`images[]`の”[]”が味噌です。
後ほどRails側のparamsから`params[:images]`で受け取ったものを`each`で繰り返し処理できるようになります。
”[]”が抜けると画像データ一件しか入らなくなります。
ここを参考：[MDN-FormData.append()](https://developer.mozilla.org/ja/docs/Web/API/FormData/append#:~:text=As%20with%20regular%20form%20data%2C%20you%20can%20append%20multiple%20values%20with%20the%20same%20name.%20For%20example%20(and%20being%20compatible%20with%20PHP%27s%20naming%20conventions%20by%20adding%20%5B%5D%20to%20the%20name)%3A)
**E**
axiosでPOSTします。
urlは自分で決めたルートで大丈夫です。(/api/upload/upload_imageとか)

# バックエンド
## Rails（コントローラ）
routes.rbなどは割愛します。
```rb
def upload_image
    # ftpインスタンスを生成し、ログイン
    ftp_host = 'upload.rakuten.ne.jp'
    ftp = Net::FTP.new(ftp_host)
    ftp.login(user = "xxx", passwd = "yyy")
    
    # 画像用フォルダーを作る(「すでにそのフォルダーが存在してます」のエラーが起こりがちなので、エラーハンドリングをちゃんと書いた方がいいかも)
    ftp.mkdir("/cabinet/images/xxxxxxx")

    # 作業対象のフォルダーに入る
    ftp.chdir("/cabinet/images/xxxxxxx")

    # 画像をアップロード
    image_files = params[:images]
    image_files.each do |image|
        ftp.putbinaryfile(image, image.original_filename)
    end

    # ログアウト
    ftp.close
end
```

FTP関連のメソッドは[ここ](https://www.qoosky.io/techs/8a72ab5d45)と[公式Doc](https://docs.ruby-lang.org/ja/latest/class/Net=3a=3aFTP.html)を参考しました。

# おわりに
`formData.append("images[]", file);`のところ"[]"をつけるのが全然分からず苦労した。
次はアップロードの進捗バーとか、アップロード先をフロントで指定するなど色々実装したいのですが、今日はここまでです。
netcat(nc) for telnet

# netcat(nc) tips
telnet関連開発をするにあたり、netcatを使って、擬似telnetサーバーやクライアントを実現しようとしたときのメモ。

## nc (netcat)
使い方は多数見つかる。
- [使いたいときに必ず忘れる便利なコマンド「nc」](https://ltside.com/kizyo/nc.html)
- [【Linux】ncat (nc, netcat) コマンドの使い方とオプション](https://milestone-of-se.nesuke.com/sv-basic/linux-basic/ncat-command-options/)
- [ nc(netcat)コマンドで覚えておきたい使い方8個](https://orebibou.com/ja/home/201511/20151117_001/)
など

## telnet
１文字ずつ送るのが特徴。ポート番号は23。

### サーバーでのエコーバック
FIFO（パイプ）を使って実現。mkfifoコマンドを使う。

```
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | nc -l -p 23 > /tmp/f
```

#### 参照サイト
サーバー側での[リモートアクセス](https://gist.github.com/gerjantd/9787489)の実現。内容は少々リスキー。

### １文字送信
1. 入力中のCtrl-Dで即時送信
1. stty -icanon && nc 相手のIPアドレス 23
[How can I force netcat to send my input immediately, not just on newlines?](https://superuser.com/questions/429128/how-can-i-force-netcat-to-send-my-input-immediately-not-just-on-newlines)

## 実験
サーバー側は上記のエコーバックを実行中とする。クライアント側（Mac利用）の状況。
### 1. Ctrl-D
```
$ nc 192.168.250.2 23
abc　　　　// "abc"とタイプ後にEnterキー
abc　　　　// エコーバック
112233D　　// "1"をタイプ後にCtrl-D、"1"がエコーバック
　　　　　　//　"2"をタイプ後にCtrl-D、"2"がエコーバック
　　　　　　//　"3"をタイプ後にCtrl-D、"3"がエコーバック、最後になぜか"D"が表示
```
このときのWireshakの様子。
![nomarlのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/834de769-1c87-7485-92d2-2bdf4f65e6b1.png)
![nomarl2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/8e179387-9d82-d3c2-65d4-0ee83c7503c3.png)

### 2. stty
```
$ stty -icanon && nc 192.168.250.2 23
AABBCC　　// "A"をタイプ直後に"A"がエコーバック
　　　　　//　"B"をタイプ直後に"B"がエコーバック
　　　　　//　"C"をタイプ直後に"C"がエコーバック、
```
このときのWireshakの様子。
![sttyのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/12b1d80c-fb38-5986-043d-fa9d5d975e45.png)


EOF