OmniAICreator/Qiita-1.07M huggingface dataset:
[Ruby, Rails] リファクタリングに役立つTips集 (初心者向け)

Ruby, Ruby on Railsを実務で使用する中で、レビューで指摘いただいたことや自分で調べた便利メソッドなどをリファクタリングの際のTips集としてまとめたいと思います。

### メソッドの返り値にはreturnを使用しない
別の言語を使用する際には```return```を使用して返り値を表現することが多いと思いますが、Rubyでは```return```を明示的に書くことは少ないです。

 ``` Ruby
def total(count)
  price = 100
  sum = price * count
  sum  # ここでreturnは不要
end
```

### 返り値を配列として返したい場合はmapを使用する

``` numbers ```という数字の配列から5以上の数字だけを取り出して ```result_numbers``` という配列に入れたい場合、eachを用いると次のように書くことができます。

``` Ruby
def method
  result_numbers = []
  numbers.each do |number|
    result_numbers << sample if number >= 5
  end
end
 ```

eachの代わりにmapを使えば ```result_numbers = []``` と書かなくても以下のように書くことができます。
mapはブロックで評価した値を配列で返してくれます。

``` Ruby
def method
  result_numbers = numbers.map do |number|
    number if number >= 5
  end
end
```

### ぼっち演算子（&.)を用いてレシーバーがnilの場合のハンドリングをする
オブジェクトがnilの場合のハンドリングをしたいときに下記のように書くことができます。

``` Ruby
if article
  name = article.author
end
```


ここで```オブジェクト&.メソッド``` というようにメソッドの前に ```&.``` をつけることでオブジェクトがnilの場合でもエラーが出なくなり、オブジェクトがnilの時のハンドリングを省略して書けます。

``` Ruby
name = article&.author # articleがnilの場合はnameにnilを代入。
```

### 定数は基本的にfreezeさせて使用する
定数にfreezeメソッドを使用しない場合、以下のように破壊的な変更が可能になってしまいます。

``` Ruby
  MESSAGE = "hello"
  p MESSAGE.upcase! #=> HELLO
```

意図しない書き換えを防ぐために、freezeメソッドを使用してイミュータブルなオブジェクトに変換しましょう。
そうすると破壊的な変更が行われようとした際に以下のようにエラーが出ます。

``` Ruby
  MESSAGE = "hello".freeze
  p MESSAGE.upcase! #=> can't modify frozen String: "hello" (FrozenError)
```

### ヒアドキュメントを用いて複数行の文字列を定義する
複数行の文字列を定義する場合には下記のように書くことがあると思います。

``` Ruby
text = "content1\ncontent2"
```

この程度の長さなら上記の定義でも問題はなさそうですが、例えばjsonのレスポンスを定義したい場合などにこの書き方をすると見づらくなってしまうと思います。そこでヒアドキュメントを使用すると以下のように定義できます。

``` Ruby
text = <<-TEXT
content1
content2
TEXT
```

### 文字列を連結する場合は式展開を用いる
文字列を連結したい場合は #+ を用いて連結するのではなく、式展開を用いると良いです。
式展開を用いれば、自動的に `.to_s` が走り、余計なエラーが発生しなくなります。

```ruby
price = 200

# #+ を用いて連結する場合
content = price.to_s + "円"

# 式展開を用いて連結する場合
content = "#{price}円"
```
【React】event属性を受け取る。


# オブジェクト形式の複数の値を受け取る方法。【自分用メモ】

React勉強中のため、間違っていたらご指摘ください。


## Login画面を想定

### まずは全体像

```react

import axiosInstance from "../../axios";
import React, {useState} from "react";

const Login = () => {
    
   //受け取る初期値
    const initInput = {
        email: '',
        password: ''
    }
    //useStateで初期値を代入
    const [state, setState] = useState(initInput)
    
　　　　　　　　//入力されたときに発火される。
　　　　　　　　const HandleChange = (e) => {
　　　　　　　　　　　　　　　　//入力された値を受け取る。
        const value = e.target.value
　　　　　　　　　　　　　　　　//入力フォームが複数あるため、e.target.nameでインプット要素のname属性を受け取る。
        const name = e.target.name
　　　　　　　　　　　　　　　　
　　　　　　　　　　　　　　　　//スプレッド演算子で要素を分解し、取得したname属性を割り当ててフォームの区別をしている。
        setState({...state, [name]: value})
        console.log(state)
    }
    const HandleLogin = async () => {
       const result = await axiosInstance.post('auth/jwt/create/', state)
        console.log(result)
    }

    return (
        <>
            <form action="">
                <label htmlFor="email">email</label>
                  <input id="email" name="email" type="email" value={state.email} onChange={HandleChange} />
                 <label htmlFor="password">password</label>
                  <input id="password"  name="password" type="password"  value={state.password} onChange={HandleChange} />
                <button onClick={HandleLogin}>ログイン</button>
            </form>

        </>
    )
}

export default Login

```

## ポイント

1. 入力フォームごとにuseStateを設定することもできるけど、コードが多くなるので行けてない。
1. e.target.nameで入力されたname属性ごとにsetStateに渡せるとスッキリする。

```react
　　　　　　　　//入力されたときに発火される。
　　　　　　　　const HandleChange = (e) => {
　　　　　　　　　　　　　　　　//入力された値を受け取る。
        const value = e.target.value
　　　　　　　　　　　　　　　　//入力フォームが複数あるため、e.target.nameでインプット要素のname属性を受け取る。
        const name = e.target.name
　　　　　　　　　　　　　　　　
　　　　　　　　　　　　　　　　//スプレッド演算子で要素を分解し、取得したname属性を割り当ててフォームの区別をしている。
        setState({...state, [name]: value})
        console.log(state)
```

もっといい方法があればご教示ください。

ありがとうございました。
2022春 技術記事リレー Tech Connect

この記事は**[リンク情報システム](https://www.lis.co.jp/)**の**2022春 技術記事リレー Tech Connect!**のインデックス記事です。

Tech Connect! は**勝手に始める技術記事リレー(アドベントカレンダー)**として、
**engineer.hanzomon** のグループメンバによってリレーされます。

もはや毎年恒例となりましたが、今回で6回目となります。
執筆メンバの趣味・嗜好が躍動する渾身の技術記事をご堪能ください。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914640/34bc0509-2981-7a50-46dc-b21b1bda17d8.png)


---

| 日付 | id | タイトル |
|:--:|:--|:------------------|
| 2/1(火) | @hs-lis | [勉強会を主催してみた](https://qiita.com/hs-lis/items/1738b58f86591b6722f3)
| 2/2(水) | @s-kawahito | [MySQLのパーティショニング機能を使ってみよう](https://qiita.com/s-kawahito/items/a4594bd8cf80489a7f68)
| 2/3(木) | @shinmo | [音声認識に空耳英語は通じるのか](https://qiita.com/shinmo/items/71857f391096cc5e41ae#_reference-9d51678596491fdc07b0)
| 2/4(金) | @sssc  |  [にゃんぴんぐじゃっく](https://qiita.com/sssc/items/93548fb37478aac97307)
| 2/7(月) | @n-tanimoto  | -
| 2/8(火) | @following_ng  | [万策尽きる前に手を打て](https://qiita.com/following_ng/items/59fd487e5b12c95e1168)
| 2/9(水) | @dgkz   | [来るかも知れないSvelteの最小ハンズオン](https://qiita.com/dgkz/items/d898ff32294964331db6)
| 2/10(木) | @lis_wk | [言語を比べると見えてくるもの](https://qiita.com/lis_wk/items/5f9ad003987001f26371)
| 2/14(月) | @yuto-yoshida | [ショートカットキーを使おう！](https://qiita.com/yuto-yoshida/items/52fae1ad783b1b94d7b4)
| 2/15(火) | @lis-mw  | [別プロジェクトのGCSからBigQueryへの連携](https://qiita.com/lis-mw/items/6765f901ae5126c3b257)
| 2/16(水) | @yoshi-hanzo | [ゴッドファーザー風の画像の作り方。](https://qiita.com/yoshi-hanzo/items/502c9e43854bf6ea53bc#_reference-5e32a9f80a3432f2fa15)
| 2/17(木) | @taku-chan | [G検定の私用テキストが337ページになってしまった件](https://qiita.com/taku-chan/items/74ccfbb4a3d20703b60e#_reference-bac2152689b4381aea3e)
| 2/18(金) | @mefuku | [MySQL系レプリケーション構成3種とインストール方法](https://qiita.com/mefuku/items/4ac6d71da3d6a39a9df3)
---
**リンク情報システムの過去のアドベントカレンダー**

- [2021新春アドベントカレンダー Tech Connect](https://qiita.com/dgkz/items/eabde6515457d8acec9b)
- [2020新春 Tech Connect](https://qiita.com/dgkz/items/5131349d56354b33ee97)
- [2019夏 Tech Connect! Summer（勝手に始める真夏のアドベントカレンダー）](https://qiita.com/dgkz/items/2862d5e6b77203a126b3)
- [2018冬 リンク情報システム Advent Calendar 2018](https://qiita.com/advent-calendar/2018/lis)
- [2018秋 Tech Connect! Autumn](https://qiita.com/dgkz/items/4c3a449f3168d6c787cf)

---
[リンク情報システム株式会社](https://www.lis.co.jp)では**一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)**しています！
また、**お仕事のご依頼**、**ビジネスパートナー様も募集**しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。
Facebookは[こちら](https://ja-jp.facebook.com/lis.co.jp/)。
Nifi简单Demo

# 概要

根据客户的需求，做一个简单的Nifi Demo
[客户需求](https://drive.google.com/file/d/1KOkG80DLwWfthR_4fOFbk0NK_BRRA7iS/view)

# 结构

![スクリーンショット 2022-02-01 12.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260826/ebfa7df5-fe20-bf3c-3075-929474ea723f.png)

1. ListFile作为入口
1. FetchFile来处理数据，处理完了以后mv到别的目录
1. PutSyslog来处理FetchFile出现错误的情形
1. PutHDFS将处理完的数据存到HDFS上

# 知识点

1. cdp的log都存在/var/log/下面
1. config文件都在/etc下面
1. 查看权限的command namei。使用例子

```ruby
namei -l /home/cdp/nifi_test
f: /home/cdp/nifi_test
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwxrwxrwx cdp  cdp  cdp
drwxrwxrwx cdp  cdp  nifi_test
```

1. touch。对着一个已经存在的文件进行touch，不会覆盖源文件，而是直接更新文件的新建时间
1. dmesg。查看开机信息
1. journalctl。查看系统日志
1. hdfs dfs设置用户可以用`sudo -u hdfs`


# 典型

## 设置udp

在PutSyslog阶段，需要设置udp广播，然后检测nifi出现问题之后，message被广播
![スクリーンショット 2022-02-01 13.09.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260826/655144e8-dbbe-4c7e-c3ff-a7edbb23b184.png)


```ruby:查看运行的syslog
ps auxww | grep syslog
cdp       8198  0.0  0.0 112824   972 pts/0    S+   04:05   0:00 grep --color=auto syslog
```

```ruby:设置config
sudo vi /etc/rsyslog.conf
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
```

```ruby:查看message日志
sudo cat /var/log/messages | grep "there is an error"
[sudo] cdp のパスワード:
Feb  1 02:41:27 zzeng03.novalocal there is an error
Feb  1 02:43:36 zzeng03.novalocal there is an error
Feb  1 02:44:36 zzeng03.novalocal there is an error
Feb  1 02:45:47 zzeng03.novalocal there is an error
```

完成。
[py2rb] 関数の属性

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# 関数の属性 (Python)
```python
def make_func(x):
    def func1():
        return '1'
    def func2():
        return '2'
    func1.__doc__ = x
    func1.other = func2
    return func1

my_func = make_func("func1")
print(my_func())
print(my_func.__doc__)
print(my_func.other())

# output
1
func1
2 
```
関数の属性という説明が正しいか自信はないのですが、特殊属性の代表である`__doc__`ドキュメンテーション文字列の他、自作関数を属性として追加し、呼び出すことができます。
# どうする (Ruby)
```ruby
make_func = lambda do |x = nil, *args, **kwargs|
  def func1()
    return '1'
  end
  def func2()
    return '2'
  end
  if x.nil?
    func1
  elsif x == 'other' || x == :other
    func2
  end
end

my_func = make_func
puts my_func.call()
puts my_func.call('other')

# output
1
2
```
`__doc__`はPythonの文化なので使用しないと思いますが、必要があれば`def __doc__`の追加で対応できそうです。
# メモ
+ Python の 関数の属性 を学習した
+ 百里を行く者は九十里を半ばとす
UE4 TortoiseSVN v1.14.1 で作成したリポジトリをソースコントロールで接続しようとするとサポート対象外のバージョンで出来なかったのでバージョンを合わせて作りなおした話

※本記事は下記の環境で確認してます。
Windows10
UnrealEngine 4.27.2
TortoiseSVN Version 1.14.1



##概要
>svn: E170013: Unable to connect to a repository at URL 'file:///D:/repository/trunk/MyProject'
svn: E180001: Unable to open repository 'file:///D:/repository/trunk/MyProject'
svn: E160043: Expected FS format between '1' and '7'; found format '8'
Failed to connect to source control. Check your settings and connection then try again.

TortoiseSVNで作成したリポジトリに対してソースコントロールで接続を行おうとすると上記のようなエラーが発生しました。
原因は題名の通りなのですが、確認した感じエンジン側に手を入れる以外(※)だと既存のリポジトリのバージョンを下げるしか手段は無く、サポートされているバージョンに合わせてリポジトリ自体を作り直す必要がありそうでした。
※"\Engine\Binaries\ThirdParty\svn" にあるSVNをTortoiseSVNのものに置き換えると一応動作しましたが、動作保証されてなさそうなのでお手軽にはやらない方が良いと思います。

そこで調べてみたらsvnadminのコマンドで互換性のあるリポジトリ形式を作成することができたので、本記事ではその方法を書きます。

検証あまり出来ておらず間違ってたらすみません。

追記 2022/02/01
後述する岡田さんの記事にもあります通り、UEがサポートしているバージョンを扱うTortoiseSVNをインストールして使用する方がリスクが少ないです。
もしもTortoiseSVNのバージョンを気にしないのであれば、下記のリンクなどから適切なバージョンのインストーラーを落として再インストールすることをお勧めします。
https://osdn.net/projects/tortoisesvn/storage/Archive/1.9.5/


##バージョン確認方法

svnのバージョンの確認方法は、右クリック -> TortoiseSVN -> About で出てくるウィンドウのSubversionの部分に書いてます。



UE側でサポートしているバージョンの確認方法については Epicの岡田さんがわかりやすく記事に纏めてくれてますので、こちらをご参照ください。

https://qiita.com/EGJ-Kaz_Okada/items/ca3ff9150bfabf05e1e6

##解決手順
まず最初にTortoiseSVNのインストーラーを起動して Command line client tools がインストールされているかを確認してください。
TortoiseSVNインストール時にデフォルト設定だとCommand line client toolsの欄にチェックが入っておらず、もしチェックが入っていなかった場合はこちらにチェックを入れてインストールしてください。
※これはPowershellで「svnadmin --version」を叩いて入っているか確認していただき、なかった場合インストールとかでも構いません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386876/0b945cff-0415-cd55-9e74-b0acca6981bd.png)

インストール完了後にPowershellで下記のコマンドを叩いて再度リポジトリを作り直すと
UE4.27.2 がサポートしているバージョンのリポジトリが作成されます。
>svnadmin create --compatible-version 1.9（リポジトリを作成したいパス）


参考
https://answers.unrealengine.com/questions/935314/svn-source-control-error-within-ue4.html?sort=oldest

##余談

>svn: warning: W155010: The node 'D:\svnTestProject\trunk\MyProject' was not found.
svn: E200009: Could not display info for all targets because some targets don't exist
Failed to connect to source control. Check your settings and connection then try again.

.uproject が入っているディレクトリがAddまたはCommitされてない場合上記エラーが出ます。
ソースコントロール接続でこのようなエラー文が出た場合はAddまたはCommitされているか確認するのが良いでしょう。
（Command line client tools がインストールされていなくても同様のエラーが出る事がありましたが、手元では再現せず。何か情報があったらコメントください）




##関連
ソースコントロールでSVNを使用する話に関しては公式ドキュメントがありますのでこちらを参照ください。

https://docs.unrealengine.com/4.27/ja/ProductionPipelines/SourceControl/SVN/
DoS攻撃・DDoS攻撃について その種類

## 勉強前イメージ

種類って何個かあるらしい・・・知らなかった

## 調査

### まずDoS攻撃、DDoS攻撃について

- DoS攻撃

DoS攻撃は1台の攻撃元からターゲットにサイバー攻撃を行います。
メールもボム攻撃やF5攻撃などが有名です。

- DDoS攻撃

複数台の攻撃元からサイバー攻撃を行います。
攻撃者はマルウェアなどを用いて、他者のサーバを乗っ取りそこから攻撃を行うため
攻撃元を特定するのも困難です。

### 攻撃手法

主な攻撃手法を以下に記載していきます。

- DNSフラッド攻撃

DNSサーバへの攻撃で、大量の名前解決のリクエストを送ることで正常なユーザからのリクエストを受け付けないようにする攻撃です。
対象へ名前解決できないリクエストを飛ばすことで、
DNSサーバは無効なキャッシュでリソースが割かれ、トラフィックも埋められるということになります。

- SYNフラッド攻撃・FINフラッド攻撃

TCPは接続と切断の際に、サーバ間でお互いの意思疎通(接続してもいいですか？切断していいですか？)を行っていますが、これは利用した攻撃になります。
SYNフラッド攻撃はTCPの接続の際に、FINフラッド攻撃はTCPの切断の際の攻撃ですが
どちらもSYN、FINという要求を大量に送信する攻撃になります。
SYN、FINが送られると、送られた側は返答して相手の応答を一定時間待ちます。
そのため、多くのSYN,FINが来られると大量の応答を待ち続けるのでサーバのリソースが割かれます。

- ACKフラッド攻撃

こちらも上記と同様にTCPの3wayハンドシェイクを使っての攻撃になります。
ACKは最後に、「接続していいって言われたので接続しますね。」「切断していいって言われたので切断しますね。」という確認応答というものですが
こちらを大量に送りつけられる攻撃です。
これは、元々接続していない人から送られると「知らない！」って言って拒否を行いますが、
大量に来られると「知らない！」という拒否によってリソースが割かれて、正常なパケットを受けられなくなります。

- UDPフラッド攻撃

昨日投稿したものですが、UDPのデータを大量に送りつけられてネットワーク負荷やポートの応答でリソースを消費される攻撃です。

- Slow HTTP DoS Attack

少ないパケット数でTCPセッションを維持するようにして、
webサーバのセッションを専有して、正規のユーザが見れないようにする攻撃です。
また細かく3種類に分類されます。

- HTTP GET/POST Flood攻撃

webサーバとブラウザ間でのデータのやり取りはGET/POSTというメソッドを使用しています。
GETはURLに追加でつける、POSTはボディにつけて送ります。
どちらも大量にGET/POSTを送る攻撃で、受けたサーバは処理できなくなります。
しかしGETは特に正常なリクエストに似せるような工夫が多く、攻撃と正常なアクセスの見分けが難しいと言われています。

- Connection Exhaustion攻撃

TCPのコネクションを使っての攻撃です。
ネットワーク機器やサーバなどネットワークに接続する機械は、接続している状態の人をメモリに保持しています。
この攻撃は、TCPのコネクションに使われるメモリのリソースを消費し、他の接続ができないようにする攻撃です。
接続先へTCPのコネクションの確率だけを行いデータのやり取りを行わず、リソースの消費を行います。

- Stream Flood攻撃

パケット通信を利用したサイバー攻撃になります。
ニセの送信元IPアドレスやポート、接続拒否のフラグが設定されたパケットを大量に送信することで
リソースを消費されサーバへ負荷をかける攻撃です。

## 勉強後イメージ

DDoS攻撃ってそういうものだと思ってたけど、
中に細かく攻撃手法あったのね。

## 参考

- [DDoS攻撃の主な攻撃手法8つの特徴をまとめてみた](https://www.shadan-kun.com/blog/measure/1426/)
- [DDoS攻撃の種類・目的は？DoS攻撃との違いや企業が受ける被害、対策方法も解説](https://tokiocyberport.tokiomarine-nichido.co.jp/cybersecurity/s/column-detail89)
Amplify CLIでLambda関数を定期実行させる方法

# Amplify CLIでLambda関数を定期実行させる方法
## 注意点
先に注意点を書いておきます。
`amplify add function`の時点で、定期実行の設定をする必要があります。
「え、更新すればいけるやろ？」と思いますが、私はできませんでした。
また、調べても`amplify add function`の時点で設定している記事しか見つかりませんでした。
**もし後からでも設定できる場合は、教えてください。**

## Amplify CLIでLambda関数を定期実行させる方法
**amplifyの環境が設定済みという前提で書いています。**
もし`amplify`がわからない場合は、こちらを参考にしてください。
[Amplify SNS Workshop](https://amplify-sns.workshop.aws/ja/)

最初に`amplify add function`を実行します。
そうすると、以下の基本的な設定の質問が出てきます。
### 基本的な設定

```bash
? Provide a friendly name for your resource to be used as a label for this category in the project: lambdafunction
? Provide the AWS Lambda function name: lambdafunction(関数名)
? Choose the runtime that you want to use: NodeJs(好きなものを選んでください)
? Choose the function template that you want to use: Hellow World(好きなものを選んでください)
```

### 高度な設定(直訳)
基本的な設定の質問が終わると、以下の質問が出てきます。
`? Do you want to configure advanced settings?`
この質問を`Yes`にすると、定期実行の設定、レイヤーの追加、アクセス権限の設定などができます。
上記の質問を`Yes`にした後は、いくつか質問されます。
そのなかでも、定期実行の質問は、`? Do you want to invoke this function on a recurring schedule?`です。
**必ずこの質問は`Yes`にしてください。**
そうすると、単位(時、分、秒)と、数値の設定をする質問が出てきます。
以下では、例として30分間隔で定期実行するように設定します。

```bash
? At which interval should the function be invoked: Minutes
? Enter the rate in minutes: 30
```

上記の設定が終われば、設定を反映させるために、`amplify push`をすれば終わりです。


### もし追加情報や間違いがあれば、教えてください。
AI-900:Microsoft Azure AI Fundamentals試験に向けて part2

#MSLearnの続き(Azure Machine Learning デザイナーを使用して回帰モデルを作成する)

- MSLearnのLINKはこちら
    - [Azure Machine Learning デザイナーを使用して回帰モデルを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-regression-model-azure-machine-learning-designer/)

- データおよびパイプライン（モデル）の作成
    - 説明が少し「？」だったけど、「＋」を押せばすぐ作成されたので、次に進んでいった（下図はパイプライン送信中のもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/c4f2fa3d-f5da-9d18-4caa-b4ce51d05e88.png)
    - 調子に乗って（？）英語でやって「行削除」の所を「Remove entire column」にしてたら、Normalize Dataで「そんな列ねぇ」ってエラーが出て怒られた。。。「行削除」は「Remove entire row」ですね。。（下図は編集後に再送信して終わったもの）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/0a752626-aa79-6c1a-2f1c-2f96239245f0.png)
    - 引き続きなんとか英語で頑張って次のトレーニングパイプラインを作成、こちらは一発で完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/18236e35-fab5-9822-3a59-4adcbe13320b.png)
- モデルの評価
    - 結果、RAEとR2においてはいいモデルだが、MAE、RMSE、RSEではいい値が出なかったという結果になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/ad2c62cd-c373-8a4f-de15-84ef71749985.png)
        - [参考(機械学習の回帰における評価指標に関して学ぼう！)](https://aiacademy.jp/media/?p=261 "機械学習の回帰における評価指標に関して学ぼう！")

- 推論パイプラインの作成
    - 入力データから「価格」を排除し、モデルを利用して価格を推定
    - pythonも織り交ぜるようになり、3つの入力データに対する予想価格が表示された
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/a2a9a08a-e8ed-df86-c468-6a2d8c9d9bf2.png)

- サービスとしてのテスト
    - エンドポイントと主キーが作成されるので、サンプルソースでテスト（↓は一部）
    - うまくいけばこんな形で予測値が表示されて、これにてトレーニング終了（小テストもあるよ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219847/1f351beb-e2e1-1029-106e-d40b7d8a0465.png)

```
endpoint = 'YOUR_ENDPOINT' #Replace with your endpoint
key = 'YOUR_KEY' #Replace with your key

import urllib.request
import json
import os

# Prepare the input data
data = {
    "Inputs": {
        "WebServiceInput0":
        [
```
論文まとめ：wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations

# はじめに
以下の論文
[1]A. Baevski, et. al. "wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations"
のまとめ。
journal等は不明。

- arXiv:
https://arxiv.org/abs/2006.11477

- github:
https://github.com/pytorch/fairseq/tree/main/examples/wav2vec#wav2vec-20
pytorch/fairseq 全体はMITライセンスか？

既に多くの解説があると思うので、要となる事前学習に関してだけザックリまとめ。


# 概要
- 音声認識のモデル
- 事前学習で大量の音声を用いた教師なし学習を行うことで、本学習時のラベル付き音声データを減らすことができる

# 手法
## 学習の手順

１）巨大なラベルなしの音声データを使って教師なしで事前学習をする
２）それをfine-tuneして教師ありで学習する

の 2 step。

## 事前学習時のモデルのネットワーク構造
事前学習時のネットワーク構造は以下。

![スクリーンショット 2022-02-01 11.01.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/b1e1c92b-ab09-4469-0351-fdd80c8b83b3.png)

１）図中の下部から音声データ $\mathcal{X}$ を入力する

２）それをCNNでlatent $\mathcal{Z}$ に変換する

３）latentを量子化して $\mathcal{Q}$ とする

４）一方でlatentの一部をmaskしてtransformerに入力し、context representations $\mathcal{C}$ を得る。

このcontext representationsは q を表すように学習する。

５）maskをした部分からのcontext representations と 量子化 $q \in \mathcal{Q}$ とでlossを計算する。

mask部分に対応する q とは一致するようにlossを計算し、一方でそれ以外の q とは一致しないようにlossを計算する。（詳細は後述）これにより、全体の意味を考えながら q を推定するように学習されるだろう。

## 事前学習時のloss

事前学習時lossは Contrastive Loss と Diversity Loss の２つからなる。

```math
\mathcal{L} = \mathcal{L}_m + \alpha \mathcal{L}_d \tag{2}
```

### Contrastive Loss
先述の「モデルのネットワーク構造」における５）。

${\bf c}\_t$: context representations の中でmaskされる時間 t に対応するもの
${\bf q}\_t$: latentを量子化したもののうち、maskされる時間 t に対応するもの
${\bf \tilde{q}} \in {\bf Q}\_t$: 全ての時間におけるlatentを量子化したもの
$sim({\bf a}, {\bf b}) = {\bf a}^T {\bf b} / \| {\bf a} \| \| {\bf b} \|$: 両ベクトル間のコサイン類似度
として

```math
\mathcal{L}_m = - \log \frac{\exp( sim({\bf c}_t, {\bf q}_t)/ \kappa )}{\sum_{\tilde{{\bf q}} \sim {\bf Q}_t} \exp (sim({\bf c}_t, \tilde{\bf q})/ \kappa )}  \tag{3}
```

とする。

まず右辺は negative logなので、真数部分が1に近ければlossは０に近くなり、真数部分が0に近ければlossはプラスの無限大となる。

真数部分はsoftmax的なものなので、分子は分母に含まれる。

分子が最大化し、分母のうちの分子以外の部分が最小化すれば、真数は１となり、lossは0となる。

つまり、分子に対応する t 時の量子化した値 q と対応する t 時のcontext representation ${\bf c}\_t$ とのコサイン類似度が１に近くなり、かつそれ以外のペアのコサイン類似度が遠くなれば、真数部分は 1 に近くなり、lossは0に近くなる。

分母の「t-1時の量子化した値とは異なって欲しい」という部分がキモか？真数分子部分のみ最大化させることを考えると、transformerが前時刻の z を量子化するだけというバカな学習をすれば、t-1時のlatentを量子化したものをt時のcontext representationとして返す。さらに入力が音なので、t時とt-1時の波形は似てる -> t時のlatentとt-1時のlatentは似てる -> t時の量子化とt-1時の量子化が似てる、のであればそれでも成立しそう。

なので「前時刻の z を量子化するだけというバカな学習」は行わず、頑張ってmask以外の部分からcontextを考えて、mask部分の context representationを推定するようになるだろう。

## Diversity Loss

これに関してはよくわかってないが、こちらのサイト
https://towardsdatascience.com/wav2vec-2-0-a-framework-for-self-supervised-learning-of-speech-representations-7d3728688cae
のFig 5 においてV entriesを均等に利用するため、V方向に均質したい。

そうすると codebook $p\_g$ はV方向でsoftmaxをとっているので確立であるため、エントロピーを最大化することを意味する。これを全てのG方向の p に対して行う。つまり

```math
\mathcal{L}_d = \frac{1}{GV} \sum^G_{g=1} -H(\bar{p}_g) = \frac{1}{GV} \sum^G_{g=1} \sum^V_{v=1} \bar{p}_{g,v} \log \bar{p}_{g,v} \tag{4}
```
AWS Lambda Layer(レイヤー)を作成する方法

## Lambda Layerとは
複数のLambda関数に、共通の外部ライブラリやビジネスロジックを追加できる仕組みです。
1つのLambda関数に、5つまでLayerを追加できます。
しかし、Layerのサイズには、制限があります。

## Lambda Layerを作成する方法
### nodejsディレクトリを作成する
ディレクトリ名は必ず**nodejs**にする必要があります。
(それ以外の名前では、ダメだと思います。)

### 必要なライブラリをインストールする
```bash
npm init
npm install (必要なライブラリ)
```
`npm init`と`npm install (必要なライブラリ)`を行い、`node_modules`ディレクトリが作成され、中にインストールしたものが入っていれば大丈夫です。

### zipにしてアップロードする
上記で作成した`nodejs`ディレクトリをzip形式にして、アップロードします。
アップロードする場所は、`AWSのコンソール`→`Lambda`→`レイヤー`→`レイヤーの作成`の順に進むと、アップロードするところがあります。

## 既存のレイヤーのバージョンを更新する方法
新しいレイヤーを作成せずに、既存のレイヤーを更新する場合は、既存レイヤーの`nodejs`ディレクトリをインストールできます。
`AWSのコンソール`→`Lambda`→`レイヤー`→`(更新したいレイヤーを選ぶ)`の順に進み、ダウンロードすると、既存レイヤーの`nodejs`ディレクトリがダウンロードできます。
そのディレクトリのなかに、必要なライブラリをインストールしてください。
その後、`AWSのコンソール`→`Lambda`→`レイヤー`→`(更新したいレイヤーを選ぶ)`の順に進み、新しいバーションを作成すると、既存レイヤーを更新できます。
既存のレイヤーを更新した場合でも、新しいバージョンのレイヤーを付け直す必要があります。


## 何か間違いや追加情報があれば、訂正してください！
CoreML Modelに柔軟な入力形状を設定する

#色々な入力形状に対応できるCoreMLモデルに変換する方法です

#固定ではなくさまざまなサイズの入力を使いたい

デフォルト変換では、CoreMLモデルは入力サイズを固定します。
しかし、実際のユースケースでは、色々なサイズの入力を使いたい場合があります。

#柔軟な入力を使う方法

CoreMLToolsは、柔軟な入力の設定が可能です。

###変換時に設定する方法

```python
import coremltools as ct

input_shape = ct.Shape(shape=(1,3, ct.RangeDim(512, 1024), ct.RangeDim(512, 1024)))
model_input = ct.ImageType(shape=input_shape)

mlmodel = ct.convert(model, inputs=[model_input])
```

これで、入力画像の縦と横で512~1024の範囲を受け入れられるようになりました。
ct.RangeDim()とすると、無制限の入力形状を受け入れるようになります。

範囲指定ではなく、いくつかのデフォルト値を設定して、メモリを事前に割り当てることで、範囲指定よりも高速になります。

```python
import coremltools as ct

shapes = [(1,3, 512, 512),(1,3, 768, 768),(1,3, 1024, 1024)]
input_shape = ct.EnumeratedShapes(shapes=shapes, 
                                  default=(1,3, 512, 512))
model_input = ct.TensorType(shape=input_shape)

mlmodel = ct.convert(model, inputs=[model_input])
```

これで、３つの選択肢で入力形状を指定できます。


###変換した後で設定する方法
```python
from coremltools.models.neural_network import flexible_shape_utils
spec = coremltools.utils.load_spec('mymodel.mlmodel')

input_name = spec.description.input[0].name

img_size_ranges = flexible_shape_utils.NeuralNetworkImageSizeRange()
img_size_ranges.add_height_range((256, 4096))
img_size_ranges.add_width_range((256, 4096))
flexible_shape_utils.update_image_size_range(spec, feature_name=input_name,
size_range=img_size_ranges)

from coremltools.models.utils import save_spec
save_spec(spec, 'updatedMyModel.mlmodel')
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
ROS2の勉強　第7弾：TurtleBot3の環境構築

# #プログラミング ROS2< TurtleBot3の環境構築 >

## はじめに
ROS2を難なく扱えるようになることが目的である．その第7弾として，「TurtleBot3の環境構築」を扱う．

## 環境
##### 仮想環境
|||
|:-:|:--|
|ソフト|VMware Workstation 15|
|実装RAM|3 GB|
|OS|Ubuntu 64 ビット|
|isoファイル|ubuntu-20.04.3-desktop-amd64.iso|

##### コンピュータ
|||
|:-:|:--|
|デバイス|MSI|
|プロセッサ|Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz 2.50GHz|
|実装RAM|8.00 GB (7.89 GB 使用可能)|
|OS|Windows (Windows 10 Home, バージョン：21H1)|

##### ROS2
|||
|:-:|:--|
|Distribution|foxy|

## TurleBot3
### 概要
TurtleBot3シリーズは3種の型があり，それぞれ搭載しているセンサなどが異なる．
詳しくは，以下のサイトを参照されたい．

https://www.turtlebot.com/

画像だけ以下に示しておく．
![turtlebot3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/faa5c9eb-0bf1-88c2-7966-74b96e44b8ff.png)

今回はこれらのシミュレーション構築について見ていく．

## 環境構築
環境構築については簡単にできるようにgithubにまとめた．

https://github.com/yuya-0411/turtlebot3_setup

以下に書くことはgithubに示す手順と同じである．

### STEP1: TurtleBot3をインストールするための環境を構築
必要なものはいくつもあるが，shell scriptにまとめたので，先ほど示したリポジトリをgit clone．

```bash:git_clone
git clone https://github.com/yuya-0411/turtlebot3_setup.git
```

あとは，以下のコマンドを実行するだけ．

```bash:依存ライブラリ等のインストール
cd turtlebot3_setup
chmod +x turtlebot3_setup.sh
./turtlebot3_setup.sh
```

**※今回はfoxy用で作成しているため，ROS2のディストリビューションに合わせて``turtlebot3_setup.sh``のfoxy部分を変える**


### STEP2: TurtleBot3のビルド
- "turtlebot3"のリポジトリをROS2ワークスペースのsrcフォルダにgit clone

```
cd ~/ros2_ws/src/
git clone -b foxy-devel https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git
```

- ビルド

```
cd ~/ros2_ws && colcon build --symlink-install
```

### STEP3: TurtleBot3の選択
シミュレーションでTurtleBot3を扱うにあたり，どのタイプを用いるかを決める必要がある．
以下のようにして，シミュレーションで用いるタイプを決められる．例としてwaffle_piにしてみる．

```bash:select_type__example_waffle_pi
export TURTLEBOT3_MODEL=waffle_pi
```

また，以下のようにbashrcファイルに書いておくと便利かもしれない．

```bash:bashrc
# select a model of turtlebot3 for simulation
#export TURTLEBOT3_MODEL=burger
#export TURTLEBOT3_MODEL=waffle
export TURTLEBOT3_MODEL=waffle_pi
```

### STEP4: テスト
最後にちゃんと環境構築ができたかどうかの確認をする．

- 環境の起動

```
ros2 launch turtlebot3_gazebo turtlebot3_house.launch.py
```

- 操作ノードの起動

```
ros2 run turtlebot3_teleop teleop_keyboard
```

これで，環境が立ち上がり，ロボットをキー入力で操作できれば完了である．

#### テストの様子
<iframe width="560" height="315" src="https://www.youtube.com/embed/Tq450KJKtyQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## 感想
turtlebotを使っていくにあたり，ROS2においてTurtleBot3の環境を構築する必要があった．公式の手順が非常に分かりやすかったため，つまづくことなくできた．ただ，上記でも示したとおり，はじめインストールするものが多いため，shell scriptにまとめて実行した．このことで非常に効率がよくなったため，githubで共有している．これで，いつでも簡単に環境構築ができる．これからこれを使ってロボットをROS2で扱うことについて学んでいく．

## 参考
- ROBOTIS e-Manual: turtlebot3/Simulation

https://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/

- ROBOTIS e-Manual: turtlebot3/Quick Start Guide

https://emanual.robotis.com/docs/en/platform/turtlebot3/quick-start/
Python 簡単にランダムな名前(文字列)を生成する

# 参考

[Python実践入門 ](https://amzn.to/2zBKOFm)

# 方法1 uuid

標準モジュール

```python
import uuid

for i in range(10):
    print(str(uuid.uuid4().hex))
```
```
ad37a981e8774484823d3446c1d7cf3a
69b36e62cebd49afa138241c1c9d6282
8329326e86f4417c817bfe372769a96f
2fb71832bb7242c6a7ba7d78c5405cf4
e4bcea0b3f4e45e1a093923145f2488c
8ee8734a6abd4e50a21c923c83f3c1eb
3980c4574fc044dcb18e0802abaf11e1
a3f655f41a6a4c7dafa9d722676a0a3c
a97c6c33963f4795907b71b3d4f04b2b
040e31e4ac804de7b8fd81cf8308a3c4
```

# 方法2 names

サードパーティー製モジュール

https://treyhunner.com/2013/02/random-name-generator/

```
pip install names
```

```python
import names

for i in range(10):
    print(names.get_full_name())
```
```
Amanda Settle
Kevin Bejar
Luella Inman
Sara Runyon
Levi Rezentes
Cesar Smith
Constance Coates
Patricia Schrag
Jessica Cauthen
William Conkle
```
アロー関数でもオーバーロードがしたい

## はじめに
アロー関数でもオーバーロードがしたくなったので書きます。

## function宣言のオーバーロード

```typescript
function func(a: number): void; // interface
function func(a: string, b: number): void; // interface

function func(a: string | number, b?: number) { // 実装
  console.log("a");
  console.log("b")
}
```
typescriptのオーバーロードは、インターフェイス部分と実装部分を分けて書きます。

## アロー関数のオーバーロード
アロー関数は無名関数なので、上記のような宣言方法をすることができません。

でも、function宣言ではなくアロー関数を使用したい場面も多いですよね。
実はアロー関数でもオーバーロードを実装できます。

```typescript
const func: {
    (a: number):void; // interface
    (a: string, b: number):void
} = (a: string | number, b?: number) => { // 実装
    console.log(a);
    console.log(b);
}
```

これで、上記のfunction宣言と同じ実装ができます。

おそらく、見慣れない書き方なのではないでしょうか?
関数の型の書き方には二つあります。

```typescript
type Func = () => void; // FunctionType
type Func = {():void}; // CallSignature
```
CallSignatureの書き方で型宣言をすれば、オーバーロードを実現できます。

## 最後に
[playground](https://www.typescriptlang.org/play?ts=4.5.4#code/PTAEiKGRbhkH4ZCLUwHUwFAGMD2A7AzgF1AQwBsDUB3AMQFd1kAuUAb0VGdAAo870KBbAIwFMATgEoaAN1QBLACYBuUExbs6OQZPQBzADShenHgJHip0xAF9QAXjYdQq9RtAAfUFz5CtvAPz73IqwB8DIrMaFioBPwAdMQa7MKyIaBhmBHRsay8CeaIiCCgAGZUyNiSGIDF2oAAUYhF1KUYhcXKrgZCoqASMom1JWXojdTN9po6ei1+7Z1yuT31-T1D2GqazuOGoz5rbcGhGKmRMahxAER4x9m74QcZx7zn5kA)を用意しています。
Dataiku Version 10で新しい役割のAIガバナンスを実現する

ガバナンスは、データ、分析、AIのチームが一番後回しにすることが多いですが、AIを大規模に提供するための鍵の1つです。多くの人にとって、ガバナンスは一連の行動ではなく、概念です。Dataiku 10では、[AIガバナンス](https://blog.dataiku.com/setting-direction-for-ai-governance)が設計や運用とうまく連携し、AIプロジェクトを大規模に構築・展開するための機能として変化しています。この新機能により、プログラムマネージャーやリスクマネージャー、アナリティクスリーダー、さらにはドメインエキスパートなど、新たな役割がAIチームに加わることになります。

Dataikuは、ソースからモデルへのデータリネージュ、モデルやオブジェクトのきめ細かいバージョン管理、役割ベースのアクセスコントロール、エンタープライズディレクトリサービスとの統合、チームの貢献度の追跡、監査証跡、モデルの自動ドキュメンテーションなど、強力なガバナンス機能をすでに備えています。Dataiku 10は、モデルレジストリ、監視のためのガバナブルアイテム、ガバナンスプラン、リスクと価値の評価、関係者のフィードバック、および本番展開前のプロジェクトサインオフなどの新機能により、AIガバナンスを次のレベルに引き上げます。

すべてはガバナブルアイテムのレビューから始まります。アナリティクスリーダーとリスクマネージャーは、チームとインスタンスにまたがるDataikuの全プロジェクトを見ることができるようになりました。そして、ガバナンスの強化が必要なプロジェクトをレビューして選択し、適切なガバナンスプランとレビュープロセスに適合させることができます。また、ステップバイステップのレビューやサインオフが不要な低リスクのプロジェクトや社内プロジェクトには、ガバナンスを適用しないことを決定することも可能です。


<font color="LightSeaGreen">→Dataiku V10のガバナンス機能について、動画は[こちら](https://youtu.be/I2dxApkyvvY?list=PLWjlCkA2BrRTbtZKMYexw0qeoJahqLLXd)</font>


<br>
また、新しいモデルレジストリは、本番稼働プロジェクトの可視性と管理性をさらに向上させます。モデルレジストリは、分析リーダーやオペレーターに、インスタンス全体のすべての本番稼働モデル、およびそれらの現在のステータスとメトリックを包括的に表示します。Dataikuで開発されたモデル、カスタムモデル、Dataiku以外でMLFlowで作成されたモデルは、すべてレジストリで確認することができます。

<br>
New Model Registry in Dataiku 10
![Screen Shot 2022-01-12 at 10.59.04 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/d26e13ba-dc2e-da2b-8ba3-1ce1cc46930e.png)

新しいガバナンスプランでは、プロセスのステップと承認において、テンプレートドリブンのアプローチをとることができます。計画のステージには、プロジェクトの評価、設計、および運用にまたがる領域を含むことができます。例えば、あるテンプレートで提供されるステージには、探査、適格性の判断、開発、バリデーション、本番稼働で構成され、本番稼働のステップへと進むためのサインオフが可能です。他のテンプレートを使い、より多くの、あるいはより少ないステージで構成することも可能です。各ステージには固有のアクションがあり、ステークホルダーによるレビューを含むこともできます。テンプレート化されたガバナンスプランにより、プロジェクト間で一貫したアプローチを作り出すことができ、ステークホルダーがループに入ることで、リスクを管理しながらプロジェクトの速度を維持することができます。

<br>
Governance Plans in Dataiku 10
![Screen Shot 2022-01-12 at 11.01.06 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/15b1a767-b7a7-eb72-9fc9-a2f4bddc035d.png "Governance Plans in Dataiku 10")


企業がチームやユースケースにまたがるAIの利用を拡大するにつれ、プロジェクトのリスクと価値を評価する一貫したフレームワークを作成することが、リソースの割り当ての際に不可欠となります。ガバナンスプランに搭載された新しいリスクと価値の評価機能により、アナリティクスリーダーは、開発のためのリソースを割り当てる前に、複数の次元でプロジェクトを評価し、AIが組織に与える影響を最大化することができます。

<br>
Risk and Value Assessment in Dataiku 10
![Screen Shot 2022-01-12 at 11.02.23 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/4e09f438-8746-4f15-92e6-8cb350266376.png "Risk and Value Assessment in Dataiku 10")


Dataiku 10では、AIガバナンスをAI開発ライフサイクルの新たな機能として提供し、これは、プロジェクトやリスク管理のための新たな役割と、チーム横断的にAIプロジェクトを評価・管理するための必須ツールになります。これらの新しいガバナンス機能により、アナリティクスリーダーは、リソースの最適化とプロセスの標準化により、価値の最大化と運用・法務・規制遵守リスクの管理を行い、より多くのアナリティクスプロジェクトを開発をリードすることができます。


<br>
####<font color="LightSeaGreen">堅牢なガバナンスプランで、AIの効果を最大化するには</font>
新しいガバナンス機能について、Dataiku Product Daysセッションの視聴は[こちら](https://youtu.be/OyxVZXGN4uw?list=PLWjlCkA2BrRSXTUTspXW5VLc9p5xxCCMt)

<br>
原文：[*Delivering AI Governance for New Roles With Dataiku 10*](https://blog.dataiku.com/ai-governance-new-roles-dataiku-10)
vue.jsユーザーの驚く、JSファーストの世界（特にReact）

はじめまして、これまでvue.jsをメインで開発してきた自分が、最近リアクトを勉強して驚いたJSファーストについて書いてみようと思います。

#*①vue.jsの最初に覚えるv-if,v-modelなどの、「v-hoge」系のvue独自の記法は、無駄なFW自体の学習コスト*


これ自分は、vue学んだ時にフレームワークを学ぶなら仕方ないような〜〜〜的な感じで軽く考えていました。
むしろ何も分かっていなかったので、v-modelとかよくわからんけど、JSで書くより楽なんじゃ？と思ったりしていました。

ただ、MVC（MVVM）の概念をもとに、結構無理に分割した結果、このv-hoge系の機能を実装してることを知りとても驚きました。

JSファーストでは、DX（開発者体験）を重要視するため、無理にMVCやMVVMの概念で分割するのではなく、この辺は機能ごとにコンポーネントに分割しようぜっていう考え方があります。
そのため、フレームワーク独自のお作法(例：v-hogeなど)ではなく、そのままのJSを知っていれば書ける書き方になっており、無駄なフレームワークの学習コストを上げないようになっているんですね。。。

#*②HTMLと、JSが融合していてきもい！！！けど、これが真のJSファーストの姿。*

vue.jsやRailsを勉強していた自分からすると、HTMLと、JSの各場所は分けたい(MVVMの責務の切り分け)をとても重視していました。
ただ、これは初見殺し的な部分が大きく、ある程度JSとHTMLを融合させて書くことで、上で書いたFW独自のルールを覚えるコストを削減し、さらに開発者のDXを上げるため、アプリケーションの機能ごとのコンポーネントの分割をよりしやすくするための工夫なのです。

つまり、MVCやMVVMの概念を無理に当てはめてコンポーネントを実装させるのではなく、機能ごとに分割したほうが良くね？という設計思想のもとReactのようなJSファーストのFEは作られていたのですね。
TeraTermでテンキーを入力できるようにする

[TeraTerm](https://ttssh2.osdn.jp/index.html.ja)は、デフォルトではテンキーからの入力を正しく入力できない。それだと不便なので、テンキーからの入力ができるように設定を変更する。

TeraTermの公式のサイトにやり方が載っているので、それをみてそのようにやればよい。

 - [テンキー(数値キーパッド)について](https://ttssh2.osdn.jp/manual/4/ja/usage/tips/about_tenkey.html)

残念ながら、TeraTermを起動中に設定を変更することはできない。僕はいつも、SSHで開発環境に接続して、ファイルを開いて、ある程度まで編集したところでテンキーを使うときになって、「あ、TeraTermだとテンキーが正しくつかえないんだった」と気づき、開いているvimを閉じたくないので、まあ次に気づいたときにやろうと思い、年単位の時間が過ぎていきました・・・。

::: note warn
残念ながら、TeraTermを起動しなおす以外の設定変更方法はないようです。
:::

設定ファイルは僕の場合は下記の場所にあります。デフォルトだとこのようになると思います。

``` KEYBOARD.CNF
C:\Program Files (x86)\teraterm\KEYBOARD.CNF
```

そして、これが変更前

``` KEYBOARD.CNF
[VT numeric keypad]
;Num pad 0 key
Num0=82
;Num pad 1 key
Num1=79
;Num pad 2 key
Num2=80
;Num pad 3 key
Num3=81
;Num pad 4 key
Num4=75
;Num pad 5 key
Num5=76
;Num pad 6 key
Num6=77
;Num pad 7 key
Num7=71
;Num pad 8 key
Num8=72
;Num pad 9 key
Num9=73
;Ctrl + Num pad '+' key
NumMinus=1102
;Num pad '+' key
NumComma=78
;Num pad '.' key
NumPeriod=83
;Num pad Enter key
NumEnter=284
;Num pad NumLock key
PF1=325
;Num pad '/' key
PF2=309
;Num pad '*' key
PF3=55
;Num pad '-' key
PF4=74
```

公式サイトでは、次のように設定してくださいと書いてあります。


``` KEYBOARD.CNF
[VT numeric keypad]
Num0=off
Num1=off
Num2=off
Num3=off
Num4=off
Num5=off
Num6=off
Num7=off
Num8=off
Num9=off
NumMinus=off
NumComma=off
NumPeriod=off
NumEnter=off
PF1=off
PF2=off
PF3=off
PF4=off
```

でも、僕は、offと打つのがめんどくさいのと、原状復帰をしやすくするために、
すべてコメントアウトしてみました。

``` KEYBOARD.CNF
[VT numeric keypad]
;Num pad 0 key
;Num0=82
;Num pad 1 key
;Num1=79
;Num pad 2 key
;Num2=80
;Num pad 3 key
;Num3=81
;Num pad 4 key
;Num4=75
;Num pad 5 key
;Num5=76
;Num pad 6 key
;Num6=77
;Num pad 7 key
;Num7=71
;Num pad 8 key
;Num8=72
;Num pad 9 key
;Num9=73
;Ctrl + Num pad '+' key
;NumMinus=1102
;Num pad '+' key
;NumComma=78
;Num pad '.' key
;NumPeriod=83
;Num pad Enter key
;NumEnter=284
;Num pad NumLock key
;PF1=325
;Num pad '/' key
;PF2=309
;Num pad '*' key
;PF3=55
;Num pad '-' key
;PF4=74

```

その結果、テンキーからの入力ができるようになったので、この状態でしばらく様子を見たいと思います。
VMware Cloud on AWSの利用料金について (利用料金計算ツール利用方法)

# 1. はじめに
「[VMware Cloud on AWS](https://www.vmware.com/jp/products/vmc-on-aws.html)」の簡易サイジング方法について前回ご紹介しましたので、今回は定価ベースでの利用料金の算出方法についてご紹介します。

https://qiita.com/sanjushi003/items/b81fedb91750e1946d13

# 2. VMware Cloud on AWSの利用料金を把握したい
オンデマンド、１年サブスクリプション、3年サブスクリプションそれぞれの定価ベースの利用料金について、次のVMware社提供のWebツールから簡単に算出できます。

https://www.vmware.com/products/vmc-on-aws/pricing-calculator.html

::: note warn

本記事の内容は、2022 年 2 月時点での公開情報をベースにしています。
最新情報については Broadcom 社の公式サイトをご確認お願いします。

:::

#### 試してみる
本番環境での最小構成であるi3.metalを2台をTokyo Regionで利用する場合は次のようにインプットすると、オンデマンド/１年サブスクリプション/3年サブスクリプションの3パターンで算出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/a605efdb-4152-3dc5-d0c5-b03cdd003da1.png)


1年/3年サブスクリプションの考え方は[「Amazon EC2」](https://aws.amazon.com/jp/ec2/)などで利用できる[「Dedicated Host」](https://aws.amazon.com/jp/ec2/dedicated-hosts/pricing/)と同様の概念です。複数年の利用をコミットすることにより大幅なディスカウントを受けられます。VMware Cloud on AWSの場合では、3年サブスクリプションにすると定価ベースでオンデマンド利用と比較して最大50%のディスカウントを受けることができます。

# 3. 参考記事

https://qiita.com/sanjushi003/items/b81fedb91750e1946d13

https://qiita.com/sanjushi003/items/175aad0ccdbb3488bfda
vistaでillustrator その3

#概要

vistaでillustratorやってみる。
アートボード作って、プリミティブな図形書いて、png出力してみた。

#写真

![ill2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0ebf3b2e-8eab-c3a4-375a-c752c29b3170.png)


#サンプルコード

```
var docRef = documents.add(DocumentColorSpace.RGB, 800, 800);
//var artLayer = docRef.layers[0];
//var artLayer = docRef.layers.add();
var artLayer = activeDocument.layers.add();
app.defaultStroked = true;
app.defaultFilled = true;
var rect = artLayer.pathItems.rectangle(762.5, 87.5, 425.0, 75.0);
var ellipse = artLayer.pathItems.ellipse(512.5, 87.5, 425.0, 75.0, false, true);
var octagon = artLayer.pathItems.polygon(300.0, 325.0, 75.0, 8);
var star = artLayer.pathItems.star(300.0, 125.0, 100.0, 20.0, 4);
var pngOpt = new ExportOptionsPNG24();
pngOpt.artBoardClipping = true;
var filePath = new File("/Users/ore/ill2.png");
activeDocument.exportFile(filePath, ExportType.PNG24, pngOpt);
alert("ok");




```


以上。
VS Code のターミナルに nyagos を追加

最近の VS Code は設定とか GUI っぽくなっててちょいつまづく。

Ctrl + , で設定を開いて... から settings.json を直接編集するまでに、結局ラベルの文字列を打ち込まないとけいないので、いっそ settings.json を直接開く

*ファイル* > *開く* で、`%APPDATA%\Code\User\settings.json` を開く。
なければ、*新規作成* で保存先を `%APPDATA%\Code\User\settings.json` にして保存する。

nyagos.exe をフルパスで指定。

``` settings.json
{
    "terminal.integrated.defaultProfile.windows": "nyagos",
    "terminal.integrated.profiles.windows": {
        "nyagos": {
            "path": "C:\\usr\\nyagos-4.4.11_0-windows-amd64\\nyagos.exe",
        },
    },
}
```

デフォルトを nyagos にするかはお好みで。
vistaでillustrator その2

#概要

vistaでillustratorやってみる。
アートボード作って、jpg読んで、png出力してみた。

#写真

![ill1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7439c899-8445-ea30-2811-88473465f27c.png)


#サンプルコード

```
var docRef = documents.add(DocumentColorSpace.RGB, 800, 600);
var jpgFilePath = "/Users/ore/eki.jpg"
var rasterFile = File(jpgFilePath);
var myPlacedItem = docRef.placedItems.add();
myPlacedItem.file = rasterFile;
myPlacedItem.position = Array(0, docRef.height);
myPlacedItem.embed();
var pngOpt = new ExportOptionsPNG24();
pngOpt.artBoardClipping = true;
var filePath = new File("/Users/ore/ill1.png");
activeDocument.exportFile(filePath, ExportType.PNG24, pngOpt);
alert("ok");




```


以上。
2022年2月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。

# 2022年2月1日の検索結果 (リスティング広告)

![20220201_AIOps_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/dc84890e-7b0f-a7e8-657a-e056c1ee3921.png)

* Dynatrace
* NTTデータ
* Vitria(ビトリア)

リスティング広告だと、トップが Dynatrace でした。NTTデータと Vitria(ビトリア) が続いています。
Vitria(ビトリア) は初めて聞いた会社です。今度調べてみようと思います。


# 2022年2月1日の検索結果 (広告以外)

![20220201_AIOps_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/914a68af-f7c7-13c0-4d23-6c00bfcbd622.png)

* Splunk
* JBSVC
* ITmedia
* マクロセンド
* ServiceNow

広告以外だと、Splunk がトップですね。次にJBSVC、ITmedia、マクロセンド、ServiceNow が続いています。
マクロセンドも初めて聞いた会社です。日本の企業なのですね。
vistaでillustrator

#概要

vistaでillustratorやってみる。
アートボード作って、文字書いて、png出力してみた。

#環境

windows vista
illustrator cs2

#写真

![ill0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1105c41b-e38d-8110-ab5f-e57aabbcb101.png)


#サンプルコード

```
var docRef = documents.add(DocumentColorSpace.RGB, 800, 800);
var textRef1 = docRef.textFrames.add();
textRef1.contents = "Scripting is fun!";
textRef1.top = 700;
textRef1.left = 50;
var textRef2 = docRef.textFrames.add();
textRef2.contents = "Scripting is easy!";
textRef2.top = 625;
textRef2.left = 100;
var textRef3 = docRef.textFrames.add();
textRef3.contents = "Everyone should script!";
textRef3.top = 550;
textRef3.left = 150;
var charStyle = docRef.characterStyles.add("BigRed");
var charAttr = charStyle.characterAttributes;
charAttr.size = 40;
charAttr.tracking = -50;
charAttr.capitalization = FontCapsOption.ALLCAPS;
var redColor = new RGBColor();
redColor.red = 255;
redColor.green = 0;
redColor.blue = 0;
charAttr.fillColor = redColor;
charAttr.textFont = app.textFonts[4]
charStyle.applyTo(textRef1.textRange);
charStyle.applyTo(textRef2.textRange);
charStyle.applyTo(textRef3.textRange);
var pngOpt = new ExportOptionsPNG24();
pngOpt.artBoardClipping = true;
var filePath = new File("/Users/ore/ill0.png");
activeDocument.exportFile(filePath, ExportType.PNG24, pngOpt);
alert("ok");



```


以上。
書籍「プログラミングレスデータ分析のすすめーユースケースで実践編ー」告知

Dataiku DSSを扱った書籍「プログラミングレスデータ分析のすすめーユースケースで実践編ー」を発行しましたのでお知らせします。



|<img width="400" alt="cover.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/4726fa1a-fde7-c1aa-fbc1-e443fa7090ad.png">|
|:--:|


# 本の紹介
本書は、Dataiku社が提供する分析ツールDataiku を使って、ユースケースを通じたデータ分析を体験するための⼀冊です。

本書では、下記の3つのユースケースを通じて、Dataikuの実践的な使い⽅を学んでいきます。

- ⾃転⾞シェアリングサービスの利⽤パターン分析
- マーケティング活⽤のためのWebログ分析
- レンタカーの故障予測

初⼼者の⽅でもデータ分析のことを知っていただけるように、PythonやRなどの分析⾔語の知識がなくても、DataikuのGUIを使ってデータ分析を体験できるようになっています。そのため、現場でのデータ分析をどのように進めていけばよいか知りたい⽅には、きっと役⽴てていただける内容となっていると思っております。本書を通じて、実際のビジネス現場でのデータ分析で活⽤いただれば幸いです。

また、本書は書籍「プログラミングレスデータ分析のすすめーDataiku DSS ver.8対応チュートリアルー」の知識を前提としていますので、先にそちらを読んでおくと、より理解が深まります。

# ダウンロード
以下、URLより無償提供中です。
https://play.google.com/store/books/details?id=841aEAAAQBAJ

既刊である書籍「プログラミングレスデータ分析」は以下からダウンロード可能です。
技術書典
https://techbookfest.org/product/5117838303952896

# 執筆者およびレビュー者
さいごに、書籍執筆計画に再び巻き込まれ、この1年間、時々業務の間に地獄を見せてしまったかもしれない方々です。ありがとうございます、本当にありがとうございます。

##執筆者
@hktonton
@ningendamono

##レビュー者
@goya1021
@ponnchi

以上
CarbonPeriodで今日から月末までの日付の配列を作ろうとしたら日付が足りない

Laravelで開発中、CarbonPeriodで今日から今月の月末までの日付の配列を作ろうとした。

2022年2月1日 ~ 2022年2月28日

```php:
$from_day = Carbon::now();
$to_day = Carbon::create($from_day)->lastOfMonth();

dd($from_day, $to_day,CarbonPeriod::create($from_day, $to_day)->toArray());
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/7f5ab19a-e758-0be6-9e42-548e3a8953c3.png)
28日分だから28個の配列が出来ると思っていた。27日までしかあらへん。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/01d0ee43-9ffa-a843-92c2-a3f057ce1265.png)
時間が中途半端だから何かおかしいのか。
0時0分にしよう

```php:
$from_day = Carbon::now()->startOfDay();
$to_day = Carbon::create($from_day)->lastOfMonth();

dd($from_day, $to_day,CarbonPeriod::create($from_day, $to_day)->toArray());
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/f475030e-bcc1-ff0d-549c-1c9de5b4c903.png)


ちゃんと28日分出来た。

日付の指定配列作る際は時間に気を付けましょう
ChromeでYoutubeや動画再生中に重たい、タスクマネージャーでクライアントサーバーランタイムプロセスなるものがGPUを使用する場合の対策

![1dada8b922c9e5aa8df4d7e29b5434e6[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712840/aae778bd-ac55-86ac-1fa8-ceb0e8952950.png)

表題の通り。ChromeがGPUではなくCPUを使って処理をしようとして、結果としてwindowsの包括的なプロセスがGPUを食う、というよくわからん状況になるみたい。なんでや。

ある程度スペックがあると問題はないが、低スペやCPUが貧弱だとこれでGPU使用率が20とか40%くらいまでいく。

他にも動画再生しているウィンドウを最小化していて再度広げた時などに画面の表示がおかしくなったり、Chromeが操作不能になったりと変な挙動をしたりする。

これを解決するために、ChromeでGPUを使用してもらうようにする。ハードウェアアクセラレーションという機能をオンにする。

Chrome右上の…をクリックし、設定→詳細設定→ハードウェアアクセラレーションをオンにしてChromeを再起動する。

![0fc667072af27f3c1f25d033632af3e6[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712840/1c4f4b30-bbf1-345f-1635-95571b2095ab.png)

これでChromeが画像や動画をGPUで処理しようとしてくれる。

![b6a7ca8b0d026dcf124efefbe7cb389c[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712840/117322dc-4405-3547-fd58-a14510405359.png)

相変わらずメモリの使用率やGPUの使用率は高めな気がするが、とりあえず解決。
AmplifyをつかってAppSyncのsubscriptionに引数を持たせたい

### 1.経緯

ネットの記事をみてると、Amplifyのバージョンが古い？ためかそのまま書くとエラーがでたので、ここに記録として記載しておきます

デフォルトのままだと全てのデータをsubscription（購読）してくるので、特定のRoomIDを持ったコンテンツだけsubscriptionを発生させたい。

イメージ的にはAmplify/ディレクトリにあるschema.graphqlを使って、デフォルトのsubscriptionを生成するのではなく、引数を持ったsubscriptionを生成させたい。みたいな感じです。

### 2.結果

schema.graphqlの@modelのあとに subscriptions: null の引数をもたせることで、Amplifyが勝手につくってくれるはずのsubscriptionに引数をもった関数に書き換えすることができました。あとは引数を持たせたい関数を設定しましょう。今回はonCreateTodoのみがroom_idをsubscriptionしてきます。

```schema.graphql
type Todo @model(subscriptions: null) {
  id: ID!
  room_id: String
  content: String
  description: String
}

type Subscription {
  onCreateTodo(room_id: String): Todo @aws_subscribe(mutations: ["createTodo"])
}
```

### 3.解説

上記の内容に書き換えて、Amplify push をしたら src/graphql ディレクトリ以下にある subscriptions.js にも勝手に引数を付けてデプロイしてくれました✨

下の内容に変わったことを確認したら、onCreateTodoを使っている各ファイルに以下の引数を持たせましょう。これで引数の値がsubscriptionされていることを確認できると思います。

```subscriptions.js
export const onCreateTodo = /* GraphQL */ `
  subscription OnCreateTodo($room_id: String) {
    onCreateTodo(room_id: $room_id) {
      id
      room_id
      content
      description
      createdAt
      updatedAt
    }
  }
`;
```

### 4.最後に
よろしければいいね👍くださると励みになります✨
Deploying to Goerli with Parity


I am writing about the following book.
[Hands-On Smart Contract Development with Solidity and Ethereum](https://www.oreilly.com/library/view/hands-on-smart-contract/9781492045250/)

## 5. Deploying and Interacting with Contracts
The chapter "Deploying to Goerli with Parity" is about creating a local Testnet node and deploying via that node. The biggest bottleneck is probably the time it takes to sync the node.

My recommendation is to **skip this section** and go to "Deploying to Rinkeby with Infura".
AI-900:Microsoft Azure AI Fundamentals試験に向けて

#AzureとかAIとかも学ばないといけなくなった
とりあえず無料セミナーを受講して、MS-Learnなるもので学習できることが分かったので、やってみたものと思ったこと、気づいたことをメモ。

#事前に
- MSアカウントが必要
- 初回であればAzureの無料お試し期間があるのでそれでいい
    - 利用済みで、必要以上に実行したりすると若干料金かかるかも

#実施したもの
- [Azure で AI の使用を開始する](https://docs.microsoft.com/ja-jp/learn/modules/get-started-ai-fundamentals/)
    - ここは特筆することもなく、AIってこうだね、こんなんあるよねっていう内容
- [Azure Machine Learningで自動機械学習を使用する](https://docs.microsoft.com/ja-jp/learn/modules/use-automated-machine-learning/)
    - 機械学習モデルのトレーニングの所では少々時間かかる
    - 「コーヒーでも飲んで待ちましょう」って書いてあるので、その通り時間つぶしが必要ですｗ
    - 進めていくと、bikeのrental数がworkingdayによって特徴づけられることなどが分かります
        - workingday=0が土日なので当然の結果だけど、データから見たらそれは自明でないですからね。
    - [デプロイされたサービスをテストする]の所で、「Response [502]」が出るかも。
        - 深追いしても仕方ないので、成功した場合の例だけ確認しておけばよい
- [Computer Vision サービスを使用して画像を分析する](https://docs.microsoft.com/ja-jp/learn/modules/analyze-images-computer-vision/)
    - やってることはComputer VisionのAPIを実行して結果表示しているだけなんだけど、ブラウザ内でコード書いたり実行できたり・・・すごいね今は

#やってみて
とりあえず1日の隙間時間でここまで実施。
残り他にもいろいろやる必要があるので、また更新するとして今日はここまで。

#次回やるもの
- [Azure Machine Learning デザイナーを使用して回帰モデルを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-regression-model-azure-machine-learning-designer/)
- [Azure Machine Learning デザイナーを使用して分類モデルを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-classification-model-azure-machine-learning-designer/)
- [Azure Machine Learning デザイナーを使用してクラスタリング モデルを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-clustering-model-azure-machine-learning-designer/)
- [会話言語理解を使って言語モデルを作成する](https://docs.microsoft.com/ja-jp/learn/modules/create-language-model-with-language-understanding/)
Windows Update クライアントの情報をクリアにする手順

Windowsアップデートがおかしくなった時に使用した方法。
有用だったようなのでメモ。

**※ Windows 10 の場合です**
#自動更新サービスと BITS サービスの停止
```(net stop usosvc)
(net stop dosvc)
net stop wuauserv
net stop bits
```

#SoftwareDistribution フォルダーのリネーム
```ren %systemroot%\SoftwareDistribution SoftwareDistribution.old```

#BITS のジョブを削除
```del /Q %ALLUSERSPROFILE%\Microsoft\Network\Downloader\*```

#自動更新サービスとBITS サービスの開始
```net start bits
net start wuauserv
(net start dosvc)
(net start usosvc)```

#更新プログラム検出の確認
```usoclient startscan```

約 5 ～ 10 分ほど待ち、更新プログラムのダウンロードおよびインストールが実施できるかどうかを確認
【LevelUp】10年の先輩からピヨピヨな雛エンジニアな私へ【先輩まとめ】

#結論
>1.かっこいいソースを書く
2.思考を他人にゆだねない
3.アホになる


#1.カッコいいって？
なぜかっこよくするのか？

```
理由：
保守がしやすくなる（未来の自分たちの為）
自分が経験、勉強してきた証明(信頼の為)
```

#カッコわるいって？
```
・とりあえずなにやってるか全然わからん
・同じ処理が何度もソースに出現する
```
#Point
```
1.納期内で、できる範囲で
今持っている知識が発揮できればOK
背伸びだめ、絶対
（やばい時は、助けをもらおう）


２．休日に勉強する必要はない
仕事を通して他人のソース、プルリクのコメントをみて勉強する
```


#2.他人に思考をゆだねない
![スクリーンショット 2022-02-01 093214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/46d13068-e361-6033-cf51-1dcc77533452.png)

他人に聞いたときも『そこに至ったプロセス』まで聞いてください。

![スクリーンショット 2022-02-01 093401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/ae7cd5af-11b4-7e5d-3087-aa9cde01d102.png)

![スクリーンショット 2022-02-01 093419.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/0caa5d86-ab5a-dd93-7195-99c8e6c5e69f.png)


自分で決められないことが多かったので
ハッとさせられました🐶

#3.アホになる
「こいつ大丈夫か？」となるくらい発信してみましょう

ずっとまじめにやってても
面白くないので『愛嬌のある人間』になってもろてってことでしたmm



今まで
ありがとうございましたmm

https://qiita.com/testMenta339/items/88138d7ac0845eb8ec6d

こちらも先輩からのお言葉

https://qiita.com/testMenta339/items/a2f8c1bd1257e9fb38cd


◆レベルアップ記事一覧

https://qiita.com/testMenta339/items/1ded57739f972bde371b

https://qiita.com/testMenta339/items/88138d7ac0845eb8ec6d

https://qiita.com/testMenta339/items/435bf5d0e1e98f171b97

https://qiita.com/testMenta339/items/a2f8c1bd1257e9fb38cd

https://qiita.com/testMenta339/items/c7c52befae7bb58bc5ae

https://qiita.com/testMenta339/items/e550c8da7063f15a6418

https://qiita.com/testMenta339/items/ad8c8759a4c0c27ed945
M5StackのLCDをMicroPythonから使う(ハードウェアSPI)

# M5StackでMicroPython
M5StackをMicroPythonで使う場合
1. M5Flow
2. M5Stack Micropython Base Lobo MicroPython
3. M5Cloud
のファームを使う方法あります。これらのファームにはデバイスのドライバーも含まれているので、特別な準備をすることなくハードウェアが使えるはずです
ただ、これらはMicroPythonのバージョンが古く、最新のMicroPythonを使いたい場合には困ってしまいます。

そこでGENERICのMicroPythonでデバイスが使えないかを試してみたいと思います。

MicroPython v1.18 on 2022-01-17; ESP32 module with ESP32

https://micropython.org/download/esp32/

# 開発環境
Thonnyを使うと、ファームの書き込みもらくちんです。optionから
install or update firmware
を選択し、ファームウェアを書き込みます



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205015/68c059b1-95ef-da9e-3063-2f1e618c44f6.png)

# LCDに表示する
こちらの記事を参考にさせていただきました
https://qiita.com/tab4moji/items/e669deeb2efb5ff2c775

M5StackのLCDは幸いにもVSPIに接続されていました
（余談ですがM5StampとかAtomLiteとかは、ハードウェアSPIがピンに割り当てられてなかったりするので不便です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205015/2c9a3c4e-7c00-9dd5-6e5c-0240eab42871.png)
https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#hardware-spi-bus

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205015/93ea2238-002f-5f0b-34fe-765ffc2c15a6.png)
https://docs.m5stack.com/en/core/basic

## コードの修正
ライブラリの `ili9341.py`に一部修正が必要です。
SPIにwriteするときdataが０の時があって `ValueError: buffer too short`が出るのを防ぎます

```python:ili9341.py
    def _data(self, data):
        self.dc.value(1)
        self.cs.value(0)
        if data:
            self.spi.write(data)
        self.cs.value(1)
```

```python:lcd_test.py
import ili9342c
color565 = ili9342c.color565
from machine import Pin, SPI, SoftSPI
#spi = SoftSPI(miso=Pin(19), mosi=Pin(23, Pin.OUT), sck=Pin(18, Pin.OUT))
spi = SPI(2, baudrate=40000000)
display = ili9342c.ILI934X(spi, cs=Pin(14), dc=Pin(27), rst=Pin(33), bl=Pin(32))

c = color565(0,10,0)
#display.fill_rectangle(10,10,100,100,c)
display.fill(c)
count=0
while True:
    count += 1
    display.text(f"Hello,World! {count}", 16, 128)

```

ライブラリに渡すspiをSoftSPIにすると速度の違いを確認できると思います。
文字を表示させるぐらいなら十分使えそうです。