OmniAICreator/Qiita-1.07M huggingface dataset:
16rep - DBSQLでNull値をInsertしたりSelectで取得する方法 

# どういうシチュエーション？
- 特定のカラムに対してNULLで入れたい場合

# 実際のコード
- [exec を含めないコードサンプル](https://play.golang.org/p/UroXDrFj95M)
- Insertでsample_tableテーブルnum_hogeにnullで入れたい場合そのままですとInsertできません
- db driver側でnullに変えてくれる記述で定義してInsertする必要があります

``` go
package main

import (
	"database/sql"
	"fmt"
)

func main() {
	var sampleID int64
	sampleID = 0

	sid := sql.NullInt64{} // sql.NullInt64{}型

	/*
	    // ./src/database/sql/sql.goより
	    // Nullint64は,nullになる可能性のあるint64を表します
	    // NullStringと同様にスキャン先として使用することができます
	    // (今回はint64です)
		type NullInt64 struct {
			Int64 int64
			Valid bool // int64がNULLでない場合有効
		}
	*/

	if sampleID != 0 {
		// 0でない場合（整数など入っている場合）
		// そのまま値として使用します
		sid.Int64, sid.Valid = sampleID, true
	}

	q := `
		INSERT INTO sample_table (
			id,
			num_hoge,
			fuge
		) VALUES (?,?,?)`

	if _, err := Exec(q, 1, sid, "fugefuge"); err != nil {
		return err
	}

}
```

- `sql.NullInt64{}`
    - NullInt64 -> Valuer Interfaceを実装している構造体
    - Valuer Interface -> DBドライバが参照するインターフェース型

# Exec等のメソッド実行
- database/sqlを通じて間接的にブランクインポートしたdb driverが実行される
- db driverにて実行する際、渡された引数をdb driver読み取れるデータ型変更（convert value）
- db driverにてbyte型等に変換してのSQL文に組み込んでSQL実行

> ブランクインポート
> 間接的な参照　パッケージとして直接使用していないもの（アンダーバーで定義されているもの） 

# 最後に
- 今回 `sql.NullInt64{}`ですが `sql.NullInt32{}` `sql.NullFloat64{}` `sql.NullString` 基本的な内容は上記のコードと同じように対応が可能かと思います。
- 痒いとこに手が届く小技でした
null or undefined

以下を区別する必要があるのか？
プロパティ未定義な状態 => undefined
値がない状態 => null

nullはundefinedよりも明示的に値が存在しないことを表す
JSONはnullを表現できるが、undefinedは属性名がエンコードされないためデータの保存の節約になる

nullの利用ケースってapiにnullを渡すくらいの用途しかないのでは？

typescriptの開発者向け。コミュニティの相違でない
https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined

https://github.com/sindresorhus/meta/issues/7

https://media-massage.net/blog/javascript-typescript%E3%81%A7null%E3%82%92%E4%BD%BF%E3%81%86%E3%81%B9%E3%81%8D%E3%81%AA%E3%81%AE%E3%81%8B/
Backlogのリモートリポジトリをクローン（Windows）

タイトル通り初歩的なやつでBacklogのリモートリポジトリをローカルにクローンする方法です。忘れないようにメモがてらの投稿です。

# ssh鍵を取得する
ターミナルに下記のコマンドを入力

```console
$ ssh-keygen
```
すると下記のような文字列が出てきます。
エンターキーやパスフレーズを入力して進みます。
パスフレーズを特に設定しない場合は何も入力しないでエンターします。


```console
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/eguchi/.ssh/id_rsa): <Enterキーを入力>
Created directory '/Users/eguchi/.ssh'.
Enter passphrase (empty for no passphrase): <パスフレーズを入力>
Enter same passphrase again: <もう一度同じパスフレーズを入力>
Your identification has been saved in /Users/eguchi/.ssh/id_rsa.
Your public key has been saved in /Users/eguchi/.ssh/id_rsa.pub.
The key fingerprint is:
57:15:3c:ca:f2:dc:27:6d:c2:9a:88:d0:70:cf:8d:31 eguchi@eguchi-no-MacBook-Air.local
The key's randomart image is:
+--[ RSA 2048]----+
|             .o. |
|             .o  |
|           ... . |
|      . . E.o    |
|       +So.O o . |
|      . ..+ + = +|
|       . . . o = |
|        . . o    |
|                 |
+-----------------+
```
上記のように表示されたらssh鍵が発行されています。

# ssh鍵を表示させる

```console
$ cat ~/.ssh/id_rsa.pub
```
上記のコマンドを入力すると下記のような文字列が表示されます。

```console
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkkJvxyDVh9a+zH1f7ZQq/JEI79dVjDSG
4RzttQwfK+sgWEr0aAgfnxdxQeDKxIxqI1SwyTY8oCcWzvpORuPqwbc7UWWPcCvbQ3jlEdN
5jvwKM82hincEWwI3wzcnVg2Mn8dH86b5m6REDzwRgozQ3lqrgwGVlTvkHDFs6H0b/1PSrM
XGppOP/QXGEVhZ6Hy4m3b1wMjjrbYwmWIeYklgoGHyrldhAaDYc33y7aUcRyFyq5DubtsLn
2oj4K+1q36iviCHxCOri0FDmn2dzylRCI4S+A2/P7Y7rVfdT+8OWYKCBUs8lfjujghEtejq
Qmj9ikyGTEAW1zQCN7hVwYdjL hoge@hoge.local
```
上記をコピーします。

# backlog上でssh鍵を入力
1.backlogページの右上にあるプロフィールアイコンをクリック
2.「個人設定」をクリック
3.左サイドバーの「SSH 公開鍵の登録」をクリック
4.「SSH公開鍵」に``ssh-rsa ～ hoge@hoge.local``をペースト
5.「登録」をクリック（メモは任意）

# ローカルにクローン
1.git管理を行っているbacklogプロジェクトにアクセス
2.サイトバーの「Git」をクリック
3.リポジトリ一覧から対象のリポジトリの「SSH」の文字列をコピー
4.ターミナル上でクローンしたいディレクトリまで移動。移動方法は[ターミナル（コマンド）](https://qiita.com/yoshi-2015/items/90e463a264b041b4f5e3)を参照
5.クローンするコマンドを入力

```console
git clone hoge@hoge.git.backlog.jp:/hogehoge/hogehogehoge.git
```

6.パスフレーズを入力

```console
Enter passphrase for key '/c/Users/Works-01/.ssh/id_rsa':
```
「ssh鍵を取得する」の時に登録したパスフレーズを入力してエンター

```
remote: Enumerating objects: 16592, done.
remote: Counting objects: 100% (16592/16592), done.
remote: Compressing objects: 100% (15123/15123), done.
remote: Total 16592 (delta 2878), reused 12724 (delta 759)

Receiving objects: 100% (16592/16592), 412.95 MiB | 7.41 MiB/s, done.
Resolving deltas: 100% (2878/2878), done.
Updating files: 100% (12516/12516), done.
```
上記のような文字列が表示されたら完了。

# 参考
[SSH接続設定（サル先生のGit入門【プロジェクト管理ツールBacklog】）](https://backlog.com/ja/git-tutorial/reference/ssh/)
TSUTAYAでアルバイトしていた学生エンジニアが退職するので置き土産に業務効率アプリを開発した話

# 概要
私は、大学1~4年生までTSUTAYAで働いていた学生エンジニアです。
この度、大学を卒業し就職するためアルバイトを辞めるので、4年間も働いたTSUTAYAに何か最後に残せるものはないかと思い、業務で使えるアプリを作りました。

# 開発したアプリの概要
開発したアプリは、**食品の賞味期限を管理できるWebアプリケーション**です。
使用した技術は、Next.jsとFirebaseでサクッと作りました。

# 開発した背景
私の勤めていたTSUTAYAでは食品を取り扱っているのですが、賞味期限の管理方法に少し問題を抱えていました。
それは、賞味期限を名簿に書いて管理していたことです。
これにより、以下のデメリットがありました。

① **賞味期限の順にソートできない**
② **紙による管理なので、かさばる**
③ **賞味期限が過ぎていないか、いちいち名簿を見るのが面倒**

また、この名簿を管理する人は決まっておらず、気づいた人がやる形式だったので、ほとんど使用されていませんでした。

# 開発したアプリの仕組み
今回、開発したWebアプリは以下の構成で出来ています。
![TSUTAYAでアルバイトしていた学生エンジニア.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533652/cf10d1b6-872b-bbb9-4e99-1029f9acdf0f.jpeg)

商品が入荷すると、Next.jsで作成されたWebページ上で商品情報を入力し、登録します。
情報は、Firestoreに保存されます。
賞味期限の確認はGoogle Pub/Subを利用し、午後0時にFunctionsにFirestoreに登録されている商品の賞味期限の確認をするように合図を出します。

# 工夫した点
このアプリを工夫した点、**1つ目はLINE Botで賞味期限の通知をする点です。**
これにより、商品のことを忘れていても勝手に通知が来るので、めっちゃ良いです。

**2つ目は、意外な点でデザインです。**
普通、業務で使うWebページやアプリは簡素なものが多く、面白くありません。
ただ、今回私が開発したアプリは、業務に必須なものではなく、効率化を図るためのものです。よって、利用しなくても業務に支障をきたすことがないため、スタッフが利用したいと思うものにする必要がありました。
そのために、面白いアイデアを取り入れたデザインにしました。

商品情報入力フォーム↓
![スクリーンショット 2021-02-16 17.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533652/ccc2193d-5b4d-17b7-637d-ef42d24c123e.png)

商品一覧テーブル↓
![スクリーンショット 2021-02-16 17.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533652/f2446547-92f0-2173-46a6-c7139c1af332.png)

上記が実際に作成したWebページになります。
デザインはニューモフィズムというものを参考にしました。
また、アイコンを作成することにより、愛着のあるものにしました。

**3つ目の工夫点は、Webページの表示速度です。**
これは、当たり前のことなんですが、表示に時間がかかるWebページは見たくないですよね？
どれだけ便利なもので愛着のあるものでもインターネットの世界で、表示が遅いものは良くないと私は考えています。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_533652_a5e197e7-2aac-92c4-6ec8-cfd428c3cd8b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533652/9f559ade-33e1-2ef7-1bed-d4fc6b166f1d.png)


上記の画像は、Lighthouseというツールでレンダリング速度などを測定した結果です。
この画像から、参考の数値にはなりますが、Performanceの点で100点を出すことができています。
これにより、Webページの表示速度もある程度速くすることができていることがわかると思います。

# まとめ
このアプリを開発したことによって、名簿で管理する3つのデメリットを全て解消することができました。
また、このアプリは現在6つの店舗で利用されおり、業務改善に役立っていると思います。

私は、すでにTSUTAYAを退職しているため、職場の人と直接的に関わることはなくなりましたが、このアプリを通して繋がれたら嬉しいです!!
GoogleChromeの新規タブにRSSの記事を流す拡張機能作りました！

![スクリーンショット 2021-02-16 17.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160183/ca0d805c-c138-97e9-a339-09a2527d4d9f.png)

GoogleChromeの新規タブにRSSの記事を流す拡張機能作りました！

[Slack RSS Reader - 拡張機能](https://chrome.google.com/webstore/detail/slack-rss-reader/mmfkogkfphmlkeildihamlilfinbpdfo?hl=ja&authuser=0)

# 作成した背景
- テックブログの情報を効率よく取得したい
  - RSSリーダーアプリだとそのリーダーアプリすら開かなくなる問題
  - chromeの新規タブにするとブラウジングするだけで勝手に情報が入ってくるからいいかも

# 仕組み
- SlackとRSSのアプリを連携し、RSSフィードを指定したチャンネルに流して、そのチャンネル情報の中身をSlackAPIで取得してchromeの新規タブに表示しています


# 使い方
## 事前に用意するもの
- RSSを配信するSlackのチャンネルID
  - チャンネルIDを確認する方法
    - https://app.slack.com/client/T01JCRTD5JR/C01J95JSG4E
    - Web版のSlackにアクセスし、対象チャンネルを開くとURLにのパスにチャンネルIDがあります
      - `https://app.slack.com/client/{ワークスペースのID}/{チャンネルID}`
  - RSS配信用のワークスペースを新たに作成するのがおすすめです
    - https://slack.com/get-started#/create
- SlackAPIのアクセストークン
  - チャンネル内のメッセージを取得する権限付きのトークンを取得してください
    - 取得方法
      - 1 https://api.slack.com/apps にアクセス
      - 2 `Create New App` ボタンをクリック
      - 3 `App Name` を入力（なんでもよい)
      - 4 `Development Slack Workspace` に先ほど作ったワークスペースを選択
      - 5 `Create App` で作成する
      - 6 https://api.slack.com/apps へアクセス
      - 7 `5`で作ったAppをクリック
      - 8 `Add features and functionality` -> `Permissions` -> `Scopes` -> `Bot Token Scopes` -> `Add an Oauth Scope` から `channels:history` を選択
      - 9 https://api.slack.com/apps へアクセス
      - 10 `5`で作ったAppをクリック
      - 11 `Basic Information` -> `Install your app` -> `Install to workspace` ボタンをクリック -> `Allow`で許可する
      - 12 https://api.slack.com/apps へアクセス
      - 13 `5`で作ったAppをクリック
      - 14 `Add features and functionality` -> `Permissions` -> `Bot User OAuth Access Token` をコピーする

## 手順
1. RSS APPを追加
    - https://{ワークスペース名}.slack.com/apps/A0F81R7U7-rss
    - `Add to Slack` で追加
    - `Add RSS integration` よりRSSを登録する
2. 配信したいチャンネルに`RSS APP`を連携(追加)する
    - Slackのチャンネル内から`アプリを連携させる`(slackの言語設定が日本語の場合) リンク より `事前に用意するもの`の`5`で作成したAppを連携(追加)する
- 下記URLでチャンネル内のメッセージ一覧が取得できたらOKです
  - `https://slack.com/api/conversations.history?token=SlackAPIのアクセストークン&channel=チャンネルID&pretty=1`
      
- 拡張機能の画面より`Token`, `Channel`を入力して接続する

## コメント

- SlackがRSSを更新（チャンネルにフィードを流す)するのはリアルタイムでないためタイムラグは発生します
- OSS
  - https://github.com/ryy/slack-rss-reader 
  - テック系企業のRSSフィード一覧
      - https://github.com/ryy/slack-rss-reader/blob/main/FEED_LIST.ja.md 
      - PRください🙆‍♂️
[memo]スネークケースとキャメルケース

#スネークケースとキャメルケースについて

スネークケースとキャメルケースは、それぞれ単語の区切り方を表したものです。
###スネークケース
単語の区切りをアンダースコアで表す

>admin_user_comment_creator


###キャメルケース
先頭が小文字で、単語の区切りを大文字で表す

>adminUserCommentCreator

####アッパーキャメルケース
キャメルケースの1つ。先頭から単語の区切りを大文字で表す
>AdminUserCommentCreator


##Railsの慣習的な命名規則
| 対象     　 | 命名規則      　　  |
|:-----------|------------------:|
| クラス     　| アッパーキャメルケース　|
| メソッド      | スネークケース       |
| 変数    　  | スネークケース       |

メソッドは動詞から始めて、何の処理をするメソッドなのかがわかるとよい。
例：get_week
ViewDidLoad()って実際なにしてるかわからないから、ざっくりまとめる

いろんな部品を配置して〜viewDidLoad()の中に処理を書いていけば、、

はい〜簡単なアプリの出来上がり！

ってな感じでUmedyや教本をみながら色々と作ってますが・・・

いやはや、毎回最初に準備されてるから意識してなかったけど、

```swift
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
```

って具体的にはなにしてるの？

と初歩的なところに疑問をもってしまったので調べたことをアウトプットするために書いていこうと思います。

これからも、いろんな記事をアウトプットで書いていく予定です。
そのたびに、この文言は毎回入れます・・・・・
「間違ってたら教えて下さい！！」笑
むしろそれが目的でもあります。では、、、スタート

### viewDidLoad()ってなんだ？

見た目通り、メソッドです。
ViewControllerの親クラスである、UIViewControllerクラスに定義されているメソッドで
それをオーバーライドして上書きしています。

オーバーライドするということは、中身を全て書き換えることになります。
しかし、UIViewControllerクラス（親）のviewDidLoad()にはアプリを立ち上げるためにとても重要な処理が書かれています。

このままだと、アプリが動かない！！！
そのために、メソッドの一番最初に

```swift
super.viewDidLoad()
```

を書いているんですね。
こうすることで、親クラスの重要な処理が実行され無事にアプリの立ち上げに成功することになります。

### どんなタイミングで動くのか

このメソッドは、UIViewControllerクラスのViewプロパティがロードされたタイミングで呼ばれます。つまり、「**アプリのアイコンがタッチされた**」時に動くメソッドですね！

ただし、すでに**バックグランドで動いている場合**は除きます。
なぜかというと、バックグラウンドで動作しているアプリはViewプロパティがすでにメモリ上にロードされています。改めてタッチしたところでViewプロパティがロードされることはないために再びこのメソッドの処理が動くことはありません。

いつ動いて、どんなタイミングだと呼ばれないのかを知っておくこともアプリ開発では基本として重要かもしれません

### どんな処理を書けばいいのか

まず、処理の最初に必ず書かなければいけないものがあります。

さきほども、お伝えした通り親クラスのVieDidLoad()には重要な処理がかかれています。
そのため、

```swift
super.viewDidLoad()
```

を必ず書きましょう。
プロジェクトを立ち上げると自動で書かれているので、意識する必要はありません。

全部消して１から書いてやるぜ！！みたいなファンキーモンスターじゃない限り大丈夫だと思います。

次に、"viewプロパティがメモリにロードされたタイミング"でおこないたい処理を書いていきます。

難しくいっていますが

・プロパティの記述
・特定の処理を付与する

など、思うがままに処理を書いていけばいいです。

### まとめ

ざっくりですが、いまわかることを書いてみました。上級者ともなると親クラスに書かれている重要な処理ですら理解していると思いますが現段階では理解する必要はないかなと勝手に思っています。（うごけばいいんだっ！）

将来的には、しっかりと理解した上で追記していきたいと思いました。

こんな拙い記事を最後まで読んでいただいた方がいらっしゃったら感謝します！
分かりにくい部分、追記した方がいい部分あれば教えてください！
Firebaseのinitialize

よく書くのでまとめておく。

`main()`の部分

```
void main() {
  runApp(MyApp());
}
```
を以下のように変更する。

```
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
```
ローカルのファイル等を Githubのmainに初めてpushしたいとき

ローカルのファイル等を、Githubのmainに初めてpushしたいとき。

```:terminal
git init
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/xxx.git # 新規リポジトリのHTTPS
git push -u origin main
```
これでOK !
Rails　アプリケーション開発

先日ポートフォリオサイト作成に入ったため、自分の記録用に書いていく。
参考にしている書籍は以下だ。
＊　Ruby on Rails6 超入門
https://www.amazon.co.jp/Ruby-Rails-%E8%B6%85%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798059064/ref=pd_vtp_2?pd_rd_w=Nilxn&pf_rd_p=638bbfd4-45be-4377-9648-d1b79b701034&pf_rd_r=7H549KFMAYZXFD4GJ8GQ&pd_rd_r=4a0ef12d-20c6-40d4-aecd-043132561bc5&pd_rd_wg=bjNdO&pd_rd_i=4798059064&psc=1
　
#①アプリケーション作り方
それではアプリケーション作りから入っていく。
ターミナルを開く。
 
```
% cd Desktop
```
デスクトップに移動。
今回はデスクトップにアプリケーションを作ることにする。

```
% rails new 〇〇（アプリケーション名）
```
次々にファイルができてくる。
ここで注意するべき点は必ず入力待ちになるまで待つことだ。
筆者はこれを待たなかったために、Railsサーバーが立ち上がらず、エラーと戦うことになるのだった😭

##②Railsサーバーを立ち上げる
いよいよRailsサーバーを立ち上げる。

```
% Desktop

% cd app_sample
```
これでアプリケーションの中に入れたはずである。
![スクリーンショット 2021-02-16 17.10.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/1c80fd98-42b7-afe7-63f2-eaf96b47f5f9.png)

いよいよ、サーバーを立ち上げる。

```
app_sample % rails server
```
これで完了。
http://localhost:3000/
にアクセス。

![スクリーンショット 2021-02-16 17.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/83571d61-21c8-5240-4b79-7423e7abfdc8.png)

この画面が出てくれば完了。

railsサーバーを落とす場合は『contril』+　『ｃ』でホストから切断される。
![スクリーンショット 2021-02-16 17.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/889211cc-0192-b194-65b2-126e6edf11db.png)

以上が一連の流れとなる。
Googleカレンダーをアプリ化（無料版）

#はじめに
就職活動をする際、スケジュール管理はどうしようかな？
スケジュールアプリをいくつかインストールして使ってみたが、しっくりこないな・・・

Googleカレンダーが使いやすいので、Macでアプリとして使いたいが、サイトにアクセスすると
「デバイスをお持ちでないようです」との表示・・・

そこで、Googleカレンダーを無料でアプリ化する方法ないかと思い、調べて実行できたので
その実行方法の共有です！！

#概要
Fluidという無料で、webアプリなどをMacアプリ化できるアプリを使い、Googleカレンダーをアプリ化させる方法について述べます。

（Googleカレンダー以外のwebアプリについても同様にMacアプリ化ができます）

#アプリ化の手順
①以下のページからFluidの公式ページにアクセスする
https://fluidapp.com/

②Free Downloadをクリックする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/c4515e2c-507c-612a-d87d-fc8c322b6515.png)

③インストールしたFluidを起動させる。

④起動後に出てくる表示の欄に必要事項を入力しcreateボタンをクリックする。

（項目の詳細）
URL:GoogleカレンダーのURL
Name:自身が付けたい名称（任意）
Location:アプリを置きたい場所
Icon：自身が設定したい画像のURL（任意）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/8de10cd8-74cd-ac2e-452c-dc86af06ae51.png)

※なおIconは指定したい画像をドラッグアンドロップできる
![トリム.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/5d0f5a98-96c9-d3ec-05c2-6b3e9863691f.gif)

Dockなどにセットして完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/f15a4def-7fb9-46c9-94ed-3192e503ad84.png)

#補足
無料版なので、最大化はできないです。

以上です。
MacにFlutterの開発環境を構築する

# FlutterのダウンロードとPATH設定
FlutterをMac環境にインストールする手順は以下の通りです

## SDKのダウンロード
以下のURLからFlutterのzipファイルをダウンロードします

2021/03/04時点の最新はflutter_macos_2.0.1-stable.zip
https://flutter.dev/docs/get-started/install/macos

## SDKのインストール
ダウンロードしたzipファイルを任意のフォルダに解凍します
(ここでは「~/development」に解凍する)

```bash

$ cd ~/development
$ unzip ~/Downloads/flutter_macos_2.0.1-stable.zip
```

## PATHの設定
Flutterを使用するためのPATHを設定します

```bash

$ export PATH="$PATH:~/development/flutter/bin"
```
必要に応じて、~/.bash_profile または ~/.zprofileを開いて上記のPATHを追加します
記述したら設定の反映をします
(ここでは~/.bash_profileに設定を追加)

```bash

$ source ~/.bash_profile
```

これでFlutterのダウンロードとPATH設定は終わりです

# doctorの実行
ここまで完了したら、次にdoctorコマンドを実行して必要な設定やアプリの確認をします。

## flutter doctorの実行
flutter doctorを実行します

```bash

$ flutter doctor
```

実行が終わると次のような結果が表示されます

```
$ flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.22.6, on macOS 11.0.1 20B50 darwin-x64, locale
    ja-JP)
 
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor
      --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 12.4)
[!] Android Studio (version 4.0)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.53.2)
[!] Connected device
    ! No devices available

! Doctor found issues in 3 categories.
```

<font color="Crimson">✗</font>や<font color="GoldenRod">!</font>になっている項目を確認して、インストールする必要がある場合はインストールします

これでFlutterの開発環境の構築は終わりです。
Androidでカスタムスキーマを設定する

##intent-filterの追加
AndroidManifest.xmlにintent-filterを追加します

```xml
<activity
    android:name=".MainActivity"
    android:screenOrientaion="portrait">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        
        <data android:scheme="mailto"/>
        <data android:scheme="tel"/>
    </intent-filter>
</activity>

<activity
    android:name=".SecondActivity"
    android:screenOrientaion="portrait">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        
        <data android:scheme="com.example.hoge"/>
        <data android:scheme="http" android:host="www.example.com"/>
    </intent-filter>
</activity>
```

あとはActivityでdataとactionを取得します

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val action: String? = intent?.action
    val data: Uri? = intent?.data
}
```
wxpythonでGUIで入力した値を取得する

psychopy で刺激を出すときに，刺激パラメータをGUIで記述できるようにしたのでメモ．
python は GUIの選択肢がいろいろあるが，psychopy を入れる際，wxpython がデフォルトでインストールされるはずなので利用する．

レイアウトについては最初理解できなくて苦しんだが，wx.GridSizer を使うことで Psychopy を使う人にはなじみ深い MATLAB/matplotlib の subplot と同様の感覚で使える．python の作法に明るくないのでコードは汚いが，下記コードで動作を確認した．
各GUIをリストに入れることであとでパラメータの追加などをやりやすくしたつもり．

```python:
import wx
class GUIinput:
    def __init__(self):
        self.frame = wx.Frame(None, -1, "textbox")
        self.frame.SetTitle('Exp. Params.')
        panel_ui = wx.Panel(self.frame, wx.ID_ANY, size=(400, 100)) 
        
        layout = wx.GridSizer(rows=6, cols=2, gap=(5, 5))
        labels = ['NI-dev ID', 'Durations[s]', 'ISI [s]', 'Init Wait [s]', 'RGB Channels']
        defaults = ['Dev2', '5,5,5,5', '0', '5', '0,0,1']
        
        self.frame.labels = []
        self.frame.tboxes = []
        for k, i in enumerate(labels):
            self.frame.labels.append(wx.StaticText(panel_ui, wx.ID_ANY, labels[k]))
            self.frame.tboxes.append(wx.TextCtrl(panel_ui, wx.ID_ANY, defaults[k]))
        
        # button        
        self.frame.btn = wx.Button(panel_ui, -1, 'Submit')
        self.frame.btn.Bind(wx.EVT_BUTTON, self.Clicked)
        
        # layout
        for k, i in enumerate(self.frame.labels):
            layout.Add(i)
            layout.Add(self.frame.tboxes[k])
        layout.Add(self.frame.btn, flag=wx.SHAPED)
        panel_ui.SetSizer(layout)

        self.frame.Show(True)
        self.frame.datas = []
    def Clicked(self,event):
        for i in self.frame.tboxes:
            self.frame.datas.append(i.GetValue())
        self.frame.Close(True)

app = wx.App()
guiobj = GUIinput()
app.SetTopWindow(guiobj.frame)
app.MainLoop()
print(guiobj.frame.datas)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28835/5ee9ecbd-131b-a6cf-ba2b-b2afceceeab2.png)
Firebaseの書き方のupdate

自分用メモ
旧の書き方でエラーが出る場合には、新の書き方で試してみる。（順次追記）


|     旧      |       新     | 
|:-----------:|:------------:|
| Firestore   |FirebaseFirestore| 
| document     | doc      | 
| setData       | set        | 
| AuthResult|UserCredential |
| FirebaseUser|User |
Laravelの外部キーって何？ 

#ざっくりした話
Laravel勉強してたら外部キーとかいう知らない言葉に出くわしたので、その正体に迫ったという話。
#あらすじ
Laravelでwebアプリを制作中、usersテーブルとnewsテーブルという2つのテーブルを紐付けようとした。
具体的にはnewsテーブルにuser_idというカラムを追加し、そこにusersテーブルのidの値を格納しようとした。
参考にしてる教材がいきなり外部キーとかいう謎ワードぶっこんできた挙句解説しないという暴挙に出たため自力で探りに行った。
#具体的な話
user_idを追加するためのmigrationファイルを作成

```php:migrationファイル
public function up()
{
    Schema::table('news', function (Blueprint $table) {
        $table->integer('user_id')->unsigned();

        // ここが意味わからんかった
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade);
    });
}
```
#結論
複数のテーブルを連動させる場合、テーブル同士の整合性を保つための仕組みらしい。

例えばユーザーAが複数のニュースを作成し、その後ユーザーAを削除した場合に、作成したニュースも同時に削除されるようにする、など。

コードを詳しく見ると、```foreign('user_id')```でuser_idを外部キーに指定し、```references('id')```で主テーブル(usersテーブル)のidを指定し、```on('users')```で主テーブルを指定している。
```onDelete()```はuserが削除・更新された場合の処理を指定している。
引数にcascadeを取ると親レコードが削除されれば子レコードも削除される。
【Rails】クライアントツール「Table Plus」を使用してデータベースを可視化する

# 概要

* Table PlusとはDB管理のためのGUIツールです。
* Table Plusを使用するとデータを可視化できます。


# 使い方

**① Table Plusをインストールする**

まずはTable Plusをインストールします。
[こちら](https://tableplus.com/)からインストールしてください。
![スクリーンショット 2020-12-30 18.28.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/d8fd008d-49cd-2d64-fded-6c3520bb2bdf.png)

**② データベースを選択する**

Table Plusがインストールできたらアプリを開きます。
アプリを開いたら`Create a new connection`を押下します。
![スクリーンショット 2020-12-30 18.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/d7d98df3-143f-778a-d388-74da1fd613bd.png)
押したら、データベース選択画面が出てくるので使用しているデータベースを選択します。今回はPostgreSQLで設定していきます。
選択できたら`Create`を押しましょう。
![スクリーンショット 2020-12-30 18.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/a0f5d615-1551-1cb0-be49-49cb07aea78a.png)

**③ データベースと接続する**

データベースを選択したら以下のような設定画面が出てきます。
![スクリーンショット 2020-12-30 18.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/dfff897e-4446-5fb6-2274-5a9b05db0153.png)
様々な入力項目がありますが、Databaseのみ入力します。
ここには**config/darabase.yml**の内容から入力します。
![スクリーンショット 2020-12-30 18.44.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/e300a779-4e4f-08a8-d8ab-9ea3caa04b34.png)
入力が完了したら、`Connect`を押下します。

これでデータベースの状況が見えるようになっているはずです。
しっかりデータが反映されているか確認しましょう。
![スクリーンショット 2020-12-30 18.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/30874315-5cfc-132b-6693-361b5018fe4f.png)
上記のようにデータベースの状況が反映されていれば接続は完了です。
GitBashでjqコマンドを使用するための一番簡単な方法

最近は[WSL2](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)があるのであまり出番がなくなってきたGitBashですが、備忘録として残しておきます。

# 前提条件
- Windows 64bit OSを利用していること
- [GitBash](https://gitforwindows.org/)がインストール済であること

# 手順を実行することで出来ること
WindowsにインストールしたGitbash上でjqコマンドを使用できる。

コマンド実行例：

```bash
$ cat hoge.json | jq .
```

# 手順
## jqのexeをダウンロードする
[jqダウンロードリンク](https://github.com/stedolan/jq/releases/latest/download/jq-win64.exe)をクリックする。

## ダウンロードされたexeをリネームする
`jq-win64.exe`という名前でダウンロードされるので、`jq.exe`にリネームする。

## GitBashの/usr/bin配下にjq.exeを配置する
デフォルトでGitBashをインストールしてる場合、`C:\Program Files\Git\usr\bin`に配置する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/873763e3-d8cb-ffee-9216-b1516f007ee9.png)

## GitBashでjqコマンドが使用できるか確認する

GitBashを開き、`jq --version`を実行してバージョンが表示されることを確認する。
後は通常通りjqコマンドを利用できます。

```bash
$ jq --version
jq-1.6
```

# 参考
[海外のQAサイト](https://python5.com/q/lxcnjoui)
Google Play Developer ConsoleでのVALIDATE_APP_MESSAGE_MISSING_COUNTRY_PRICESについて

Androidアプリ（有料）のバージョンアップ時、リリースを作成しバイナリをアップロード後、リリースをレビューしたら
VALIDATE_APP_MESSAGE_MISSING_COUNTRY_PRICES
というエラーが発生しました。

このエラーは、価格が設定されていない国/地域があると発生します。
解決するにはアプリの価格設定を更新します。

商品→アプリの価格設定
を開き「価格を編集」をクリックして、未設定の国/地域欄を入力するか「為替レートを更新」を選べば完了です。
![スクリーンショット 2021-02-16 16.20.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629259/fffb0012-d57d-da03-30ae-541e1f27ff1f.png)
MySQL Workbenchで1175エラーが発生

#事象
MySQL Workbenchで複数のカラムをUpdateしようとしたら、「Error Code: 1175」が発生。

#バージョン
MySQL 5.7.33
MySQL Workbench 8.0

#原因
MySQL Workbenchの仕様。
大量のUPDATE/DELETEをWorkbenchから行えないようにするためのフェイルセーフの設定が有効になっていた。
（しかし、4つだけのカラムでもNGとは・・・）

#対処方法
MySQL Workbenchの設定を変更して再起動する。
変更箇所は以下。

![workbench01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111664/5ac6ee9e-a949-d22d-6201-27375a4cc6eb.png)

1. 「edit」を選択
2. 「Preferences...」を選択

![workbench02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111664/676422c2-4b4d-3720-8c29-4f778a8e1745.png)

1. 「SQL Editor」を選択
2. 下のほうにある「Safe Updates・・・」のチェックを外して「OK」ボタンを押下する。
3. Workbenchを再起動

以上で複数のカラムのUPDATE/DELETEが可能になる。

しかし、なぜフェイルセーフの設定が入っているのかは不明。
（アプリケーションとして、大量のUPDATE/DELETEを許可できない理由があるのかもしれない。）

#参考文献
https://yoneyore.hatenablog.com/entry/2016/01/05/200047
Base64 エンコードと Base64 URL エンコードの違い

API のドキュメントを読み漁っていると、`Base64 Url Safe Encoding` という記述を見ました。
[LINE WORKS API - 顧客/取引先の連絡先の写真アップロード](https://developers.worksmobile.com/jp/document/100600806?lang=ja)

何じゃこりゃ？('Д')
普通の `Base64 Encode` とどう違うの？？

ってなわけで調べてみました。

# Base64 Encode

まずは Base64 Encode について、改めて調べ直しました。

#### Base64

Base64 は、データを 64 種類の印字可能な英数字のみを用いて、それ以外の文字を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱うためのエンコード方式。

`A–Z`, `a–z`, `0–9` までの 62 文字と、2つの記号 `+`, `/` さらにパディング（余った部分を詰める）のための記号として `=` が用いられている。

# Base64 URL Encode

URL に使用できる Base64 Encode のことを指します。

`URL セーフな Base64 Encode` とか `Base64 URL Encode` とか、先ほどの `Base64 Url Safe Encoding` とか、様々な呼び方があるようです。

URL や URI だと `+` や `/` などは別の意味を持ってしまうため、これらを置き換えるようです。

#### Base64 URL

まず、Base64 Encoding をしたあと、に各記号を置き換えるようです。

- `+` を `-` に置換
- `/` を `_` に置換

`+` を `-` に、`/` を `_` に置き換える仕様みたいです。
パディングおよび `=` は省略します。

このように Base64 の中でも URL セーフなものを `Base64 URL` と区別します。

# おわりに

ここまでお付き合いいただきありがとうございました。

調べてみると「なんだ、こんなことか」と思うのですが、そのままザラっと流しちゃうと知識として自分の頭に定着しないんですよ。
頭悪いんで！( ﾟДﾟ)

しっかり書いて、読み返す。
頑張って覚えて、先輩たちのような素敵エンジニアを目指したいと思います。

ではまた！(^^)/

# 参考にさせていただきましたm(_ _)m

[ウィキペディア（Wikipedia）- Base64](https://ja.wikipedia.org/wiki/Base64)
[RFC 4648 - The Base16, Base32, and Base64 Data Encodings](https://tools.ietf.org/html/rfc4648#section-5)
[Base64エンコードとBase64URLエンコードについて](https://akataworks.hatenadiary.jp/entry/2018/02/19/123524
)
[Base64 エンコーダー(画像をbase64エンコードするツール)](https://lab.syncer.jp/Tool/Base64-encode/)
オラクルクラウドでwindowsサーバを構築しRDPでアクセスする方法

普通にOCIでインスタンスを建ててRDPしようとしたら拒否られた。
実は、IPネットワーク上のWindowsインスタンスへのRDPアクセスは、デフォルトでは有効になっていません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/57153d3c-6189-a4e8-dc9a-b30aec289d51.png)

## 今回やりたいこと
オラクルクラウド上に作成したwindowsインスタンスに、自分のPCからRDPアクセスできるようにセキュリティリスト（FW）の設定をする

## 結論から言うと
セキュリティリスト（FW）の設定を先にしないといけませんでした。

本来はこの流れが正しい流れでしたが、2番をやってなかったのが原因でした

1. コンパートメント、VCNの作成（※この作業は既に作成できている前提で進めます）
2. セキュリティリストの設定
3. windowsインスタンスの構築
4. RDPでアクセス、パスワードの変更


## 手順

- NW＞仮想クラウドネットワーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/22f186bd-ed34-4084-a5e6-e6046f0066fb.png)

- 今回windowsインスタンスを構築したVCNを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/ee1abb21-59ba-9ba9-a379-6f208bb90f81.png)
- 左下のセキュリティリスト＞設定されているセキュリティリストを選択
たいていの場合デフォルトのリストがあるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/c401a68b-7d8d-3e31-7980-f9a9e352dc91.png)

- イングレス・ルールの追加を選択し下記のようなRDPを許容する設定を作成します。
0.0.00はすべてのアドレスを許可という意味なので要はインターネットからのアクセスを通すということです。
RDPはTCPの3389ポートと決まっているのでそれを設定、ポートの範囲はAllでいいです。
変更の保存をします。
この設定があれば拒否られません！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/ef3abc78-6f35-b598-41c1-bac0830878b2.png)

- リモートデスクトップよびます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/f1e5c808-f612-f91a-10f5-f246706bb933.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/1b0086be-0f84-b359-7b16-0a69a793d930.png)

- パスワード求められます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/f47b694f-2b4c-5508-a5d5-9c879c328860.png)

- パスワードはブラウザから、「インスタンスの詳細」にかいてあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/7496b68f-ae4d-de3d-8fa4-bdba4b8a1913.png)


- 初回ログインはパスワードの変更を求められますので変更しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/057e1e89-1b39-2547-1b31-28d3ffe9db0f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/c7b86c74-de7f-4f1d-b32c-80fa887c68fe.png)
入れました！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/ca1bb17f-1665-585c-71f4-16cb343b76b1.png)
リロード毎にランダムな音の再生


```rhtml:main.html
		<div class="audio_wrap">
			<div class="audio_button "></div>
			<audio id="audio" class="js-random" loop id="sound" preload="auto">
			</audio>
		</div>
```

```rhtml:main.js
$(function () {
	var sorce = [
	'<source src="sound/A.mp3" type="audio/mp3">',
	'<source src="sound/B.mp3" type="audio/mp3">',
	'<source src="sound/C.mp3" type="audio/mp3">'
	];
	var randomList = Math.floor(Math.random() * sorce.length);
	console.log( randomList );
	$('.js-random').append(sorce[randomList]);
  });

```
ちなみに、コンソールエラーで
`Uncaught SyntaxError: Invalid or unexpected token`が出たら、何かちっちゃなミスがあるよ、ってことです！今回は終わりかっこ忘れでずっと動かなかった


解決のお世話になったURL
https://progblog-web.com/700/
ありがとうございます！
BigQueryのテーブルのサイズ一覧を出すスクリプト

```python

import re

from google.cloud import bigquery
from google.cloud.bigquery.table import Table

MATCH_ALL = r'.*'
MATCH_NONE = r'^$'

client = bigquery.Client(project="your-project")


def list_table_id(dataset_id, include_pattern=MATCH_ALL, exclude_pattern=MATCH_NONE):
    dataset_ref = client.dataset(dataset_id)
    tables = list(client.list_tables(dataset_ref))
    ret = []
    for table in tables:
        if re.search(include_pattern, table.table_id) and not re.search(exclude_pattern, table.table_id):
            ret.append(table.table_id)
    return ret


if __name__ == "__main__":
    datasets = list(client.list_datasets())
    for dataset in datasets:
        dataset_id = dataset.dataset_id
        try:
            for table_id in list_table_id(dataset_id):
                try:
                    dataset_ref = client.dataset(dataset_id)
                    table_ref = dataset_ref.table(table_id)
                    table: Table = client.get_table(table_ref)
                    print(f"{dataset_id}\t{table_id}\t{table.num_bytes}")
                except Exception as e:
                    print(f"{dataset_id}\t{table_id}\terror\t{e}")
        except Exception as e:
            print(f"{dataset_id}\terror\t{e}")
```
Ichigojam BASICでDS1307とAQM0802Aを使い時間を表示する。


前にichigojam用に書いたプログラム
書いたのは、本人だからコピーでは、ない。
説明は、特にない。

```

10 'GOTO 100:'DS1307 AQM0802
20 H=0:M=0
30 INPUT "H 0-23>",H
40 INPUT "M 0-59>",M
50 A=(M/10)*16+(M%10)
60 B=(H/10)*16+(H%10)
70 POKE #700,0,0,A,B,3,1,1,#20
80 R=I2CW(#68,#700,1,#701,7)
90 'READ
100 POKE #700,#0,#38,#0,#39,#0,#04,#0,#14,#0,#70,#0,#56,#0,#6C,#0,#38,#0,#C,#0,#1,#40,#41
110 FOR I=0 TO 10:R=I2CW(#3E,#700+I*2,2):NEXT
120 POKE #700,0,1
130 R=I2CW(#3E,#700,2)
140 POKE #700,0
150 R=I2CR(#68,#700,1,#701,7)
160 FOR I=3 TO 1 STEP -1
170 R=PEEK(#700+I)
180 ?HEX$(R);
190 A=R/16:B=R%16
200 POKE #720,64,48+A,48+B:R=I2CW(#3E,#720,3)
210 IF I<>1 THEN ?":";
220 IF I<>1 THEN R=I2CW(#3E,"@:",2)
230 NEXT:WAIT 60:?
240 GOTO 120

```
VSCode Veturのクイックフィックスを軽い気持ちで押したらハマった

# クイックにフィックスしてくれるなんてすごい

## 一応コード
```
    let htmlButton = document.querySelector('button')
    if (htmlButton) {
      htmlButton.click()
    }
```
こんな感じのコード、当然のようにVSCodeが問題を示してくれます

### VSCode上のエラー(問題)表示

![osekkai](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403275/1d5edad8-cd21-c842-9992-ec64abe4ef19.jpeg)
 ```Property 'click' does not exist on type 'Element'.```
型の指定が足りないようです。これ自体は見慣れたもので型をもう少し詳しく指定すればよさそうです。
でも、クイックフィックスとかあるじゃないですか

### クイックフィックス内容
![shinsetsu](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403275/b1a572b0-45d1-826e-78fa-950044fe3230.jpeg)
```Add index signature for property 'click'```
やってくれるらしいからやってみよう、なんかすごそうだし。


### その後
![okinaosewa](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403275/04f8c92a-b629-9c98-317c-fe3b0c10d2fb.jpeg)
エラーが消えた!?
でも、何が変わったのかわからないし。絶対マズイ。戻して…。戻せない。

### 調べた結果

```vscode\resources\app\extensions\node_modules\typescript\lib\lib.dom.d.ts ``` の中身の

```
interface Element extends Node, Animatable, ChildNode, InnerHTML, NonDocumentTypeChildNode, ParentNode, Slottable {
    [x: string]: any; //この行が追加されてる
```

該当行を削除で見かけは元に戻りました、エラーを回避するために作業フォルダ上に何かが作成されるんだろうなとか思ってボタンを押してみたらえらいことになりました
leafletを鍛える。その33

#概要

leafletを鍛えてみた。
maker cluster使ってみた。

#参考にしたページ

https://qiita.com/terukizm/items/07bea0cdd25e9b83fc11

#成果物

https://embed.plnkr.co/plunk/mOgGzjirkHU7eLve

以上。
入れ子になっているExtensibleレコードの内側の値を操作する

# 要約

Haskell の [`extensible` パッケージ](https://hackage.haskell.org/package/extensible)が提供する拡張可能レコードのフィールド名は Lens として使えるが、入れ子になっているレコードを操作するときは `Data.Extensible.Label.xlb` を入れる必要がある。

https://hackage.haskell.org/package/extensible

# この記事の流れ

Lens で入れ子のレコードを操作する方法を確認し、`extensible` の拡張可能レコードの場合にどうなるかを見ていく。

# Lens の場合

例として、次のように入れ子のレコードを作成する。

```haskell
#!/usr/bin/env stack
{- stack repl
    --resolver lts-17.3
    --package lens
-}
{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data Hoge = Hoge { _fuga :: Fuga } deriving Show

data Fuga = Fuga { _piyo :: String } deriving Show

makeLenses ''Hoge
makeLenses ''Fuga

hoge :: Hoge
hoge = Hoge {_fuga = fuga'}

fuga' :: Fuga
fuga' = Fuga {_piyo = "aaa"}
```

`^.` や `.~` でフィールドの値を操作できる。

```haskell:ghci
> fuga'
Fuga {_piyo = "aaa"}
> fuga' ^. piyo
"aaa"
> fuga' & piyo .~ "bbb"
Fuga {_piyo = "bbb"}
```

さらに、関数合成( `.` )で入れ子になっているレコードの内側の値も操作できる。

```haskell:ghci
> hoge
Hoge {_fuga = Fuga {_piyo = "aaa"}}
> hoge ^. fuga . piyo
"aaa"
> hoge & fuga . piyo .~ "bbb"
Hoge {_fuga = Fuga {_piyo = "bbb"}}
```

# Extensible の場合

例として、拡張可能レコードを次のように定義する。

```haskell
#!/usr/bin/env stack
{- stack repl
    --resolver lts-17.3
    --package lens
    --package extensible
-}
{-# LANGUAGE DataKinds, TypeOperators, OverloadedLabels #-}

import Control.Lens
import Data.Extensible

type Hoge = Record '[ "fuga" >: Fuga ]

type Fuga = Record '[ "piyo" >: String ]

hoge :: Hoge
hoge = #fuga @= fuga <: nil

fuga :: Fuga
fuga = #piyo @= "aaa" <: nil
```

lens と同じ演算子 `^.` `.~` で操作できる。

```haskell:ghci
> fuga ^. #piyo
"aaa"
> fuga & #piyo .~ "bbb"
piyo @= "bbb" <: nil
```

しかし、入れ子になっている拡張可能レコードの値をLensと同じように関数合成で操作するとエラーになる。

```haskell:ghci
> hoge ^. #fuga . #piyo

<interactive>:2:1: error:
    • Non type-variable argument
        in the constraint: GHC.OverloadedLabels.IsLabel
                             "fuga" (b -> Hoge -> Const a Hoge)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall b a.
              (GHC.OverloadedLabels.IsLabel "fuga" (b -> Hoge -> Const a Hoge),
               GHC.OverloadedLabels.IsLabel "piyo" ((a -> Const a a) -> b)) =>
              a
> hoge & #fuga . #piyo .~ "bbb"

<interactive>:4:1: error:
    • Non type-variable argument
        in the constraint: GHC.OverloadedLabels.IsLabel
                             "fuga" (b1 -> Hoge -> Identity b2)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall b1 b2 a.
              (GHC.OverloadedLabels.IsLabel "fuga" (b1 -> Hoge -> Identity b2),
               GHC.OverloadedLabels.IsLabel
                 "piyo" ((a -> Identity [Char]) -> b1)) =>
              b2
```

このような場合、`Data.Extensible.Label` モジュールの `xlb` をラベルの前に入れると解決する。

```haskell:ghci
> hoge ^. xlb #fuga . xlb #piyo
"aaa"
> hoge & xlb #fuga . xlb #piyo .~ "bbb"
fuga @= (piyo @= "bbb" <: nil) <: nil
```

どうやら `xlb` を挿入するのは片方のラベルだけでもいいみたいだ。

```haskell:ghci
> hoge ^. xlb #fuga . #piyo
"aaa"
> hoge ^. #fuga . xlb #piyo
"aaa"
```

理由は知らないけどね。
form_withと非同期通信を

#本記事の内容
・本記事ではform_withについて自身の備忘録も兼ねて説明していきます。
誤った情報等あるかもしれませんが、その場合はご指摘いただけますと幸いです。

#バージョン
Ruby(2.6.5)
Ruby on Rails(6.0.3.5)
※ターミナル上で`rails -v`、`ruby -v`と実行することでバージョンの確認ができます。
#form_withとは
Railsでフォームタグを簡単に作成するためのヘルパーメソッドのこと。
ヘルパーメソッドとは主にviewにおいてHTMLタグを出現させたり、テキストを加工するために用意されているメソッドのことです。
#使い方
下に簡単にコードを記述してみます。

    <%= form_with (モデル or URLベース,[スコープ],[オプション]) do |f| %>
        フォームの中身
    <% end %>
フォームの中身には様々なメソッドを使用できる。
・label
→ラベルテキスト
・check_box
→チェックボックス
・password_field
→パスワード入力フィールド
・submit
→送信ボタン
・text_area
→複数行入力テキストエリア
・text_field
→テキスト入力フィールド
#local: trueの記述
local: trueの記述をしない場合、Ajax通信(非同期通信)がされる。
※AjaxはAsynchronous JavaScript + XMLの略称。
JavaScriptとXMLを用いて非同期でサーバーとの通信を行うという意味。

#非同期通信
webページではwebブラウザからサーバーにリクエストし、レスポンスがかえってくるが、その際に一部の情報のみをリクエストすることによってページ全体のリクエストを**しない**通信のこと。

#XMLHttpRequest
ブラウザ上でサーバーとHTTP通信を行うためのAPI。このAPIを使用してJavaScriptが実装される。

#APIとは
アプリケーションプログラミングインタフェースの略称。**ソフトウェアの機能を共有できる仕組み**のこと。
ex)FacebookやGoogleアカウントを使用したログイン機能など。詳細についてはこちらのURLからご覧ください。非常に分かりやすく、具体例もあるため理解しやすいと思います。
引用元：SAMURAIENGINEERBlog様
https://www.sejuku.net/blog/7278

#JavaScript
ブラウザ上でWebページをダイナミックに動かすプログラムのことです。
上に出てきたXMLHttpRequestはJavaScriptの組み込みオブジェクトです。
故にAjax通信を行う際はJavaScriptも必須となります。
#DOM
Document Object Modelの略称。HTML および XML ドキュメントのための API のこと。
これはドキュメントの構造的な表現を提供し、内容や表示形態の変更を可能にします。
Ajax通信により動的なページを作成する際にHTML・XML上のどの要素に手を加えるのか指定するが、その際に対象をツリー構造として展開する事でアプリケーション側に文章の情報を伝えて加工や変更をしやすくすることができます。
#XML
Extensible Markup Languageの略称。文書やデータの意味や構造を記述するためのマークアップ言語の一つ。現在ではXMLの代わりにJSONという型がよく使われる。Ajaxの名前には含まれていないが混同しない様に注意。

#Json
JavaScript　Object Notationの略。
軽量のデータ交換フォーマットのこと。
JavaScriptのオブジェクトの書き方を元にしたデータ定義方法のこと。
Phython,PHP,JavaScript,C++,Javaなど様々な言語でサポートされているため、各プログラミング言語間でのデータの受け渡しがとても簡単に行われる。

#最後に
form_withから派生して様々な知識に触れてきました。
私自身も完全に理解できているわけではないので、実際に手を動かしたり何度も見返すなどして学習します。
最後までお読みいただきありがとうございました。

#引用
Qiita
https://qiita.com/iverson3kobe0824/items/ab86394f3f04360e6b9f
https://qiita.com/hmmrjn/items/24f3b8eade206ace17e2
https://qiita.com/hisamura333/items/e3ea6ae549eb09b7efb9
rails ガイド
https://railsguides.jp/form_helpers.html
leafletを鍛える。その32

#概要

leafletを鍛えてみた。
maker cluster使ってみた。

#参考にしたページ

https://qiita.com/mitch0807/items/52698a561d4255578657

#成果物

https://embed.plnkr.co/plunk/PEBcYXYdK2z0mpAV

以上。
情報セキュリティ / どのリスク対策に費用をかけるべきか？

限られた予算の中で「どのリスク対策に費用をかけるべきか？」を客観的に評価する為にはやはり各リスクを数値化して比較する必要があります。
IPAの「情報セキュリティ10大脅威 」がその土俵に最適と考えられますが、ランキングの根拠となる各リスクの得票数は公開されていません。また仮に公開されていたとしても、その比率がリスクの度合いを表しているとはいいきれません。
ここでは脅威の順位はIPAの「情報セキュリティ10大脅威 」、各々の脅威の度合いは次の二つのモデルで計算し、個々のセキュリティ対策の効果の数値化を行い、その導入効果の客観評価を試みました。
**①ベイズ統計の無差別の原理をモデルに使ったケース 
②指数法則を使ったケース**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/9354b742-b543-eca4-fe46-0ccb25b3d2fe.png)
##１．ベイズ統計の無差別の原理をモデルに使ったケース vs 指数法則を使ったケース
"ベイズ統計の無差別の原理をモデルに使ったケース"と"指数法則を使ったケース"のグラフを比較すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/8e775770-795d-e98f-861a-249154fa7090.png)
となり、やはり指数法則の方が実際にちかいと考えられます。
この違いが、評価結果にどの様に表れるかを「IdaaS＋CASB」「アンチウィルス」の導入効果の比較すると次の通りとなります。
　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/3bb5ee7a-161c-15c0-760e-5f323308f383.png)
内部脅威に対して「IdaaS＋CASB」で対策を打つことが、アンチウィルスの約２.５倍セキュリティ強化に貢献する結果となりました。
##２．計算方法
上の項で行った計算方法は次の通りです。（非常にシンプルです）
####a) 確率的ランキングに“ベイズ統計の無差別の原理”を利用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/b464fb76-3151-4bf2-f1fe-d268be2aaf26.png)
####b) 確率的ランキングに“指数法則”を利用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/7a325de4-7748-788b-fc13-c61e0fa36cb0.png)

**（関連情報）
ゼロトラストとは**
米国国立標準技術研究所（NIST）が定義した「ゼロトラスト」を、一般の人も理解できる意訳にチャレンジ
https://qiita.com/masaaki-murakami/items/6a7f56079aa95f44119d
**ゼロトラストの基礎知識**
“セキュリティ”の為にみんなが今までやってきた事と、これからすべきことの基礎知識
https://qiita.com/masaaki-murakami/items/28a737c373138f3773ea
**ゼロトラスト / IdaaS + CASB の設計例**
ゼロトラスト　/　“内部の情報漏洩”対策　>>> IdaaS ＋ CASB
https://qiita.com/masaaki-murakami/items/87d9bdc3fc0deb01ffcd
**ゼロトラスト / MDR = EPP+EDR+SOCの設計例**
“外部からの攻撃（身代金、搾取等）”対策【 PC・スマホ 】>>>「MDR = EPP + EDR + SOC」
https://qiita.com/masaaki-murakami/items/0f952c10b17c3dba3815
javaで漢字→ひらがな→カタカナの変換

###漢字→ひらがなの変換
####ダウンロード
phonetic-1.0を使用する

https://blogs.osdn.jp/2017/05/23/phonetic.html
からダウンロードできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/54566bdc-b311-ec32-be26-7bdcc6710cb8.png)

PATHを通さないといけないので、C:\Program Filesに解凍しました。

####システム変数に追加する必要があります
システム変数のPATHに
`C:\Program Files\phonetic-1.0`を追加しましょう。


####jarの読み込み
eclipseで、javaプロジェクトのフォルダから右クリックをしてビルド・パス→外部アーカイブの追加で`phonetic-1.0.jar`を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/53aba88b-312b-8dec-b8d1-e3d9211653d2.png)

こんな漢字で参照ライブラリーにphoneticが表示されれば使えるようになります。

エラーが出る場合はEclipseの再起動をすれば使えるようになると思います。

####使い方

```java
String kana = Phonetic.getPhonetic("本日は晴天なり");
```


getPhoneticの引数に渡した文字列をひらがなに変換してくれます。

###ひらがな→カタカナ
####ICU4Jライブラリをダウンロード
公式サイトからダウンロード↓
http://site.icu-project.org/download

####Mavenプロジェクトならpom.xmlに依存関係を追加

下記をpom.xmlに追記すれば使えるようになります。私はjavaプロジェクトをMavenプロジェクトに変換をして追記しました。

```
<dependency>
  <groupId>com.ibm.icu</groupId>
  <artifactId>icu4j</artifactId>
  <version>55.1</version>
</dependency>
```

####使い方

参考
https://weblabo.oscasierra.net/java-icu4j-1/


```java
// ひらがな→カタカナ変換をする場合
Transliterator transliterator = Transliterator.getInstance("Hiragana-Katakana");
String result = transliterator.transliterate("あいうえおがぎぐげご");
System.out.println(result);
// カタカナ→ひらがな変換する場合
Transliterator transliterator = Transliterator.getInstance("Katakana-Hiragana");
String result = transliterator.transliterate("ｱｲｳｴｵｶﾞｷﾞｸﾞｹﾞｺﾞ アイウエオガギグゲゴ");
System.out.println(result);
// ひらがな→ローマ字変換する場合
Transliterator transliterator = Transliterator.getInstance("Hiragana-Latin");
String result = transliterator.transliterate("あいうえおがぎぐげご");
System.out.println(result);


```


###漢字→カタカナ
上記の２つのライブラリを組み合わせることで実現できます。

流れとしては漢字→ひらがな→カタカナとなりますが。。。

```java


Transliterator t = Transliterator.getInstance("Hiragana-Katakana");

t.transliterate(Phonetic.getPhonetic("金子金太郎"));

String name = t.transliterate(Phonetic.getPhonetic("金子金太郎"));


[結果]
name: カネコキンタロウ

```
powershellでgit statusの表示が文字化けする場合の対処

# 参考サイト
* [git diff や git status での日本語の文字化けを防ぐ](https://maku77.github.io/git/settings/garbling.html)


# 現象
* powershellの`git status`の表示で、日本語のフォルダ名、ファイル名が文字化けする。

# 回避方法
* 下記コマンドを実行し、ore.quotepath 設定を false に設定します。

```
git config --global core.quotepath false
```
Spring BootでBean Validationを有効にする

##環境

Mac OS Big Sur
Apache Maven
Spring Boot 2.4.2


##状況

Bean Validationを使うために@NotNull, @Sizeアノテーションを記述したが、正しくインポートされない。
![スクリーンショット 2021-02-16 15.23.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064956/8990d2e6-413e-e3af-0031-82ae49ab86f9.png)



##解決策
ビルドパスが通っていないことが原因のためpom.xmlに以下の内容を追記

```
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.1-b09</version>
 </dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
```
openssl を使ったRSA暗号化のサンプル

継続的にやらせていただいている仕事で、RSA暗号化を使用するケースがあったんだけど、対向システムの仕様変更でRAS暗号化が不要になったので、gitのリポジトリからは削除して、ここに退避した。
パディングで、ちょいとハマった記憶があったので、コメント参照。
openssl のバージョンは 1.1.1b　です。

```cpp
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include <boost/algorithm/hex.hpp>

void rsaEncryption(
  const std::string modulus,
  const std::string exponent,
  std::istream& srcs, /* 入力ストリーム */  
  std::ostream& dsts  /* 出力ストリーム */
  )
{
  RSA* rsa = ::RSA_new();
  ::BN_hex2bn(&rsa->n, modulus.c_str());
  ::BN_hex2bn(&rsa->e, exponent.c_str());
  const auto blockSize = ::RSA_size(rsa);
  /*
    RSA_PKCS1_PADDINGの場合、ソースの最大バイト数は RSA_size() -11 にしなければならない。
    https://www.openssl.org/docs/man1.0.2/crypto/RSA_public_encrypt.html
    */
  std::vector<uint8_t> raw(blockSize - 11);
  std::vector<uint8_t> enc(blockSize);
  
  while(!srcs.eof()){
    srcs.read(reinterpret_cast<char*>(raw.data()), raw.size());
    const auto readBytes = srcs.gcount();
    
    const auto writtenBytes = ::RSA_public_encrypt(
      static_cast<int>(readBytes),
      raw.data(),
      enc.data(),
      rsa,
      RSA_PKCS1_PADDING);
    if(writtenBytes == -1){
      ::RSA_free(rsa);
      /*
        例外が嫌なら、rsaEncryption() にエラー値入れるなりなんなりと。
        throw_error_internal はウチで作ったエラーライブラリに含まれているので、
        他で使うなら std::exception を派生したオブジェクトかなんかを投げてくだされ。
      */
      throw_error_internal(::ERR_error_string(::ERR_get_error(), nullptr));
    }
    /*
      バイナリ->hex文字列変換
      不要なら、encをそのままdstsに放り込めばOK
    */
    boost::algorithm::hex
    (
      enc.begin(),
      enc.begin() + writtenBytes,
      std::ostream_iterator<char>(dsts));
  }
  ::RSA_free(rsa);
}
```

## openssl 1.1.1l

最近、 openssl を更新する機会があって、若干コードを変更する必要が出てきたのでメモ。

### RSA 構造体へはアクセス関数を使用することになった

```cpp:旧コード
  RSA* rsa = ::RSA_new();
  ::BN_hex2bn(&rsa->n, modulus.c_str());
  ::BN_hex2bn(&rsa->e, exponent.c_str());
```

```cpp:新コード
  BIGNUM* bn_n = ::BN_new();
  BIGNUM* bn_e = ::BN_new();
  ::BN_hex2bn(&bn_n, modulus.c_str());
  ::BN_hex2bn(&bn_e, exponent.c_str());
  ::RSA_set0_key(rsa, bn_n, bn_e, nullptr);
```

### ERR_XXX はヘッダが分割された

```cpp:追加ヘッダ
#include <openssl/err.h>
```

### そんな事より

何年前のソースなのか知らんが、生ポを使っているので面倒がらずに　`std::unique_ptr` と `custom deleter` 使いましょうね。

```cpp:こんな感じかな？
struct rsa_deleter {
  void operator() (RSA* p) { ::RSA_free(p); }
};
auto rsa = std::unique_ptr<RSA, rsa_deleter>(::RSA_new());
```
AWSの「Route53」とは？

今回はAWSの「Route53」について学んだ事をアウトプットさせて頂きたいと思います。

##Route53
**Route53とは、フルマネージド型DNS(ドメインネームシステム)サービスになります。**
ドメインとはIPアドレス(111.222.333.444のような形式)を人間が認識しやすいURL（route53.comのような形式）に変換されたもので、それらの変換（名前解決）を行ってくれるサービスが**ドメインネームシステムサービスと呼ばれます。**

従来のDNSサーバでは自分達で「構築」、「管理」、「維持」などといった作業が必要になるのですが、AWSの**Route53**を使用することでこれらの作業を全て管理してくれます。



###フェイルオーバールーティング
AWSではプライマリ(メイン通信)に異常があった場合は、セカンダリ（予備の通信）に切り替えるために**フェイルオーバールーティング**の機能を使用します。

###ルーティングポリシー
ルーティングポリシーとは、リクエストがRoute53に届いた際にどういった振り分けをするのかを決めるルールになります。
ルーティングポリシーには以下の6種類があります。


|種類|特徴|
|:----|:-----|
|シンプルルーティング|基本的に設定される通信方法になります。1つのリソースに対して名前解決を行いたい際に使用します。|
|加重ルーティング|複数のリソースに対して名前解決を行うルーティングポリシーです。新機能を導入する際のABテスト時などに使用したりします。|
|レイテンシールーティング|複数のリージョンに跨ってサービスを使用している場合に有効な通信方法です。一番レイテンシーが少ないリソースへ通信を行います。つまり、一番応答時間が早いリソースへ通信を流していく方法です。|
|位置情報ルーティング|レイテンシールーティングと同様に複数のリージョンに跨ったルーティングに有効な通信方法です。しかし、位置情報ルーティングでは応答時間ではなく、リクエストの送信元の地域によって通信先が決まります。|　
|複数値回答ルーティング|1つのDNSの問い合わせに対して、複数の値を回答を返す通信方法です。|
|フェイルオーバールーティング|プライマリ(メイン通信)に異常があった場合は、セカンダリ（予備の通信）に切り替えるための通信方法です。|


###レコード
レコードとは、ドメインと何かを設定したものをレコードと呼びます。
代表的なレコードには以下のような種類があります。
(AWS Cloud Tech学習サービス参照 https://aws-cloud-tech.com/)

![Route53講座_2.012.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930396/5f47e2bf-ad79-c294-aa23-f46c51e3974b.jpeg)

###まとめ
Route53とは、フルマネージド型DNS(ドメインネームシステム)サービスです。
従来のDNSサーバーでは、自分達で「構築」、「管理」、「維持」などといった作業を行う必要がありましたが、Route53を使用することでAWS側が代わりに管理をしてくれるようになります。
Route53の使用時には、ルーティングポリシーを設定します。
ルーティングポリシーとは、リクエストがRoute53に届いた際にどういった振り分けをするのかを決めるルールになり、基本的にはシンプルルーティングを使用するのですが、用途に応じてその他のルーティングポリシーを設定したりします。
また、レコードという概念があり、レコードとは、ドメインと何かを設定したものです。
レコードにも様々な種類があり、こちらも用途に合わせて適切な種類を選択します。

この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
STM32G031J6M6のArduinoでの温度,STTS751で温度シリアル出力(i2c)


x 愛用していたSTTS751の入手が難しくなったので代用品は、S-5851A。(おもにアドレスの違い)

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

x書き込みがうまくいかなくなる場合があるので上級者用
xSTM32G031J6M6のシリアル通信については、下記のリンク参照
STM32G031のArduinoでのシリアル通信(STM32G031J6M6)
https://qiita.com/caa45040/items/8b77fe33e80a54b47c3d
x電源を入れる手順を間違えるとうまく動かない　本体が先、シリアルが後
x再度リコンパイルで再起動させている


```c++

#include <Wire.h> //I2C library

//STM32G031J6M6
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

// STTS751のドライブは、下記のアドレスを参考にした。
// mike.saunby.net/2013_03_01_archive.html

// I2C temperature sensor - see table 1 of data sheet.  Resistor selects address. 
#define STTS751 0x39

//
byte i2c_sensor_read_byte( int deviceaddress, int eeaddress ) {
  byte rdata = 0xFF;
  int rc;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)eeaddress);
  rc = Wire.endTransmission(false);
  Wire.requestFrom(deviceaddress, 1);
  if (Wire.available()){
    rdata = Wire.read();
  }
  if(rc != 0){
    //Serial.print("Error ");
    //Serial.println(rc);
  } 
  return rdata;
}


int lo_on = 1; // 1=on 0=off

//プロトタイプ宣言
void stts751_init();

void setup()
{  
    delay(3000); //not delete
    //Wire.begin(); // initialise the connection
    Wire.begin(sdaPin,sclPin); //STM32G031J6M6
    
    Serial.begin(9600);
    
    stts751_init();
} //end setup

void stts751_init()
{
    //4回読み捨てる
    int loop_i;
    for(loop_i=1;loop_i<=4;loop_i++){
      byte lo;
      signed char hi;
      hi = i2c_sensor_read_byte(STTS751, 0);
      if(lo_on == 1 ) {
        lo = i2c_sensor_read_byte(STTS751, 2);
      }
      delay(500);
    } //end for    
} // stts751_init


int stts751_run()
{
 
    byte lo;
    signed char hi;
    float temperature;

    //Serial.println("satart");
    
    // read temperature
    hi = i2c_sensor_read_byte(STTS751, 0);
    lo = 0;
    if(lo_on == 1) {
      lo = i2c_sensor_read_byte(STTS751, 2);
    }
    if( hi > 0){ 
      temperature = hi + lo * 1.0/256.0;
    }else{
      temperature = hi - lo * 1.0/256.0;
    }
    //Serial.print(temperature);
    //Serial.println(" ");
    //delay(1000);
    
    int ret_q;
    ret_q = temperature * 100;
    return(ret_q);
}
 
 
void loop()
{
    //stts751 start 
    int stts751_tmp1 = 0;
    float temperature;
    int hi;
    int lo;
    //stts751 end
  
    //stts751 start  
    stts751_tmp1 = stts751_run();
    temperature = stts751_tmp1 /100.0;
    hi =  stts751_tmp1 >> 8;
    lo =  stts751_tmp1 & 0xFF;
    //stts751 end

    //stts751 start  
    Serial.print(temperature);
    Serial.println(" ");
    //stts751 end

    delay(1000);
}


```

![i2c_stts751_031_j_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5af4251b-8481-5758-ecc3-3e44d86d4f40.jpeg)