OmniAICreator/Qiita-1.07M huggingface dataset:
node-sass から Dart Sass への覚書


# 公式

https://sass-lang.com/documentation/cli/dart-sass

## 参考

https://blog.photosynthesic.jp/2020/11/libsass-to-dartsass/

## 以下覚書

```
$ npm i sass --save-dev
```

※ zsh: command not found:sass をくらったらパスが通ってないので下記あたりで通るハズ

```
$ export PATH=$PATH:./node_modules/.bin
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```

# 使ってみる

```
# 単独のファイルのみ
$ sass style.scss:style.css

# 複数ファイル
$ sass _scss/style.scss:css/style.css _scss/editor.scss:css/editor.css

# ディレクトリごと
$ sass _scss:css
```

# オプション

## 最小化

```
$ sass --style=compressed _scss:css
```

## @charsetを自動出力しない

```
$ sass _scss:css --no-charset
```

## ソースマップを出力しない

```
$ sass --no-source-map _scss:css
```

## エラー出力しない

```
$ sass --no-error-css _scss:css
```

## watch

```
$ sass --watch _scss:css
```
Route53 Resolver とは

## 勉強前イメージ

普通のRoute53と何が違うのか・・・

## 調査

### Route53 Resolver とは

オンプレ環境とVPCの間でDNSの名前解決ができるようになるサービスです。
今まではVPNやDirect ConnectでつながっていてもDNSフォワーダー(別のフルサービスリゾルバへDNS要求を中継するDNSサーバ)がないと出来なかったですが、
Route53 Resolverによってプライベートアドレスの空間で相互利用ができるようになりました。

### Amazon Provided DNS

Amazon Provided DNS はVPCで使用することができるDNSサーバで、
デフォルトでVPCの内部から名前解決を行う際に使用される様になっています。
Amazon Provided DNS は外部から使用することができないので、
↑にも記載しているように今まではVPCと接続していてもDNSフォワーダーが必要でした。

### AWSコンソールではどこから？

Route53のリゾルバーから
インバウンドとアウトバウンドのエンドポイントを設定することが出来ます。

![1Route53Resolver Console - Google Chrome 2021-07-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8d439bf0-c422-5649-b478-7d4af9bf0fa3.png)

## 勉強後イメージ

オンプレとAWSの内部ネットワーク同士のDNSの名前解決を行うためのサービス・・・ってことかー
DNS難しい

## 参考

- [[新機能]Route53 リゾルバー登場! オンプレミス-VPCの相互名前解決が簡単に実現できるようになりました!](https://dev.classmethod.jp/articles/route53-resolver/)
- [【基礎から学ぶ】VPCのDNSについてまとめてみた](https://blog.serverworks.co.jp/tech/2017/04/03/vpc-dns-matome/)
【論文要約】 EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks [Tan+, 2020]

## 要約
[EfficientNet](https://arxiv.org/abs/1905.11946)は、畳み込みニューラルネットワークを用いた画像認識モデルです。既存のConvNetに比べてモデルパラメータを1/8.4倍に削減しつつ、推論速度を6.1倍にしました。

## アーキテクチャ
一般にネットワークを深くすると複雑な表現を捉えられ、幅（特徴量）を大きくすると細かい表現を捉えられます。また、解像度を高くすると扱える画像の情報が増えます。
本研究では、compound scaling method という、ネットワークの深さ・幅・解像度の大きさに同時に制約を加える手法で、バランスのとれたスケーリング（パラメータのサイズの調整）を可能にします。


compound scalingは以下の式に基づいて動作します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3631343039322f37636539376364382d343236622d306466372d386362312d6138656630623935396564382e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/73fffd8a-adcc-30c6-2b6d-9ebad547e75f.png)

ネットワーク各層の幅（特徴量）が2倍になると、4倍のパラメータが必要になります。
また、解像度は（H×W）なので2乗の制約となります。
よって、widthとresolutionのハイパーパラメータは2乗の制約とします。
Φはどれだけ大きなモデルにするかという人間が決定するパラメータで、その他ハイパーパラメータはグリッドサーチを用いて頑張って探索します。


深さ・幅・解像度を変化させたときのモデルは以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/57c35bd2-ab80-2f6e-930a-07664e4c0be5.png)

compound scalingを行うと、画像認識の際にモデルがどこに注目しているかを表すヒートマップの精度も向上しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/b7430bae-c4a7-cc6d-31c2-c770a909026a.png)

## コード
`timm`というライブラリを用いるとEfficientNetを含めた大量の事前学習モデルを手軽に使うことができます。現在も続々とモデルが追加されています。

https://github.com/rwightman/pytorch-image-models



```python
# コマンドで pip install timm
import timm
import torch
m = timm.create_model('efficientnet_b3', pretrained=True)
m.eval()
matrix = torch.rand(2, 3,224,224)

m(matrix).size() # (2, 1000)
m.forward_features(matrix).size() # (2, 1536, 7, 7)
```
【React】device_token_authのcurrent_userでユーザーデータが返ってこないときの対処法【axios】

<h2>症状</h2>
ReactとRailsAPIでアプリを作成し、Railsにdevice_token_authの導入したところ、サインアップ、サインイン、サインアウトは成功するものの、サインインしている状態で、device_token_authのcurrent_userメソッドではnilやuser_signed_inではfalseが返ってきてしまう症状に遭遇しました。

```ruby:エラー
#サインインしている状態なのに、下記になる
current_user #nil

user_signed_in #false
```

結論から言うと、current_userをaxiosでアクセスする際に、access-token,uid,clientの情報が必要で、それを送っていなかったためにcurrent_userでnilが返ってくる状態になっていました。

フロント側はユーザー情報を持っていたとしても、サーバー側に送られていなければ、サーバーは「このリクエストはどのユーザーから送られたものなの？」となってしまうようです。

では、サーバー側に必要なデータを送る実装方法について書いていきます。

<h2>解決方法(実装)</h2>

実装はいたってシンプル。
axiosでデータを送る際に、下記のように必要な情報をjsonで渡してあげればサーバー側も認証情報を受け取ることができます。

以下ではログイン情報を確認するもので、Cookiesに保存していたaccess-token,uid,clientの情報を取得し、axiosでRails側に送信します。

```react:axios
import axios from "axios";
import React from "react";
import Cookies from "js-cookie";

//ログイン状態をチェックする
export const isLoginApi = () => {
    const uid = Cookies.get("uid");
    const accessToken = Cookies.get("access_token");
    const client = Cookies.get("client");
    return axios.get(sessionIsLogin,{
        headers: {
          'access-token': accessToken,
          client: client,
          uid: uid
        },
      })
    .then(res => {
        return res.data
    })
    .catch((e) => console.error(e))
}

```
<h2>参考</h2>

https://qiita.com/arthur_foreign/items/87a930b4d1ed52e1c2b4
UE4の Pixel2D買ってみたよ (Part5.2)　キャラクターの動きPart2/2

いやぁぁこの記事であっという間にストックがなくなってしまったぁぁぁ

Creating 2D games with Unreal Engine using Pixel 2D - Part 5.2 - Character Animation Blueprint

https://www.youtube.com/watch?v=FisTl8NvCIs

# このチュートリアルでやりたいこと
ステートマシーンを使って画像をいい感じに切り替えよう

状態ならこの絵
・歩き状態ならこの絵
みたいなやつ


#前回のキャラクターのブループリントより(00:54)
![2021-07-04_15h35_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/e7c9617e-1bb8-d03c-95d3-538216304bc4.png)

#Stateを追加しよう(01:15)
Pixel2Dは画像を切り替える便利なブループリントを用意したのでそれを使う。
![5.2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/acc6c106-3f18-b6a6-0aaf-5eb9f77d7b9e.png)

↓追加したら名前を適当につける
![5.2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/3df12ffc-4240-a0fe-c709-6e434fb9ccf0.png)

開いたらこんな感じで表示されるので
![5.2-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/a7bafd67-7537-c695-25da-a1c0a3a4ea6a.png)

NewSpriteStateMachineを追加してつなげる。
![5.2-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/908abcca-ae58-6247-da70-079233eea580.png)

こんな感じ。

![2021-07-04_16h01_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/b9a5d11a-3821-6211-a43b-c7b70e4ebd53.png)

開いたら 右クリックで　AddStateを選択して　２つのステータスを追加
![2021-07-04_15h41_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/ba005514-8fa6-cb58-0949-133de8df095a.png)

![2021-07-04_16h14_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/202f52d8-4548-cc36-b1ad-b02381d5fe3e.png)


#キャラクターとステートマシンをリンクしよう(6:00)

![2021-07-04_22h21_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/138ac8f3-b59a-2aa9-6284-5eaaba71c92e.png)


# 右側だけアニメーション完了(14:00)
どっち動いても同じだけど、歩くと止まっているとき絵が変わることは確認できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/0546e6ed-c870-7a3a-be9e-0e4e9635784c.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/ea6249ba-dd5a-aee9-1985-ec280640cb41.png)

# 左右反映されるアニメーションを作るよ(15:00~)

こんな感じのブループリンを追加
![5.2-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/154d687d-d114-be27-9b5b-466395d9317b.png)

再生するとなんか逆を押したとき変になるので
カメラは固定しておく
※１８０度回転するとカメラも１８０度回転してしまうため変に見える。
![5.2-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270619/34d837ae-86e2-6dc2-6832-aef54b33cc08.png)

完成！！

次はジャンプを作るよ！
クラウドコンピューティングの由来

皆さん、こんにちは。Sakunaです。今日はクラウドの理解の基礎となる、Time Sharing System（TSS）、Vitural Machine（VM）、Hypervisorについてご紹介致します。
これら３つの概念を理解することは、仮想化技術の進歩の歴史を理解することとなります。

**(1) メインフレームの効率アップ**
約1950年前後では、企業、官庁に設置されたメインフレーム（大型コンピュータ）は、それぞれの用途が決まっており、多数の利用者で共有する方法が一般でした。このようにメインフレームを共有とする場合、コンピューターの効率が非常に悪く、利用者はプログラムやデータを用意してもすぐには実行できず、自分の番が回ってくるまで他の利用者の処理が終わるのを待たなければなりませんでした。
そのような中、***TSS（Time Sharing System)***方式が生まれました。TSS方式のコンピューターでは、CPUの実行時間を極めて短い単位に分割し、実行中のプログラムに順繰りに割り当てます。各プログラムはCPUを占有できないため、処理性能は落ちるものの、利用者が使いたいときにすぐにプログラムを実行することができるようになりました。その後、メインフレームにアクセスしやすくするため、ダムターミナルといった機能が実現されました。


**(2) Virtual Machineの誕生**
1970年代には、***Virtual Machine***と呼ばれるOSが登場しました。以前、１つのメインフレームに１つのOSしか実装できず、メインフレーム維持費用や場所の確保などインフラの面を考えると非常に高コストでした。一方、VMの場合はメインフレームに複数のユーザーを配置することが可能になり、それぞれのVMにはゲストOSが搭載され、共有資源であるメモリ、CPU、ハードドライブをあたかも自分が持っているかのように振舞います。これにはコストを大幅に節約できるメリットがありました。
仮想化はテクノロジーの推進力となり、通信やコンピューティングの分野で最大の進化をもたらす大きなきっかけとなりました。

**(3) Hypervisorの誕生**
20年前まではハードウェアは非常に高価でした。インターネットが普及したことで、ハードウェアのコストを下げる必要が出てきました。
サーバは共有ホスティング環境、仮想プライベートサーバ、仮想専用サーバに仮想化され、同じ種類のサーバを使用していました。例えば、自社のアプリケーションを実行するために７台の物理システムが必要な場合、1台の物理ノードを７つに分割して使用することができます。これを可能にしたのが***Hypervisor***です。
Hypervisorでは物理的なコンピューティングリソースを共有しながら、複数のオペレーティングシステムを共存させることができます。
また、VMを論理的に分離し、それぞれのコンピューティングパワー、メモリ、ストレージを割り当て、VM同士が干渉しないようにすることができます。そのため、あるOSが突然、クラッシュしても、セキュリティ上の問題が発生しても、他のOSは影響を受けず継続して動くことができます。

**(4) Cloud時代の始まり**
様々な技術と共に、Hypervisorが進歩し、ITリソースが豊富で、自分のようなITリソースを持っていない企業に向けて、確実にこういったサービスを提供できる企業が出現します(他社に確実に提供できる企業の中には、クラウドのメリットを、物理的なサーバーを大量に所有していないユーザーにも享受してもらおうと考え始める企業も続々と出てきました）。
ユーザー企業は、より多くの利用可能なリソースの中から、必要な分だけを注文し、その料金は使用した分に対して支払うことができるようになりました。 この従量制のユーティリティー・コンピューティング・モデルは、クラウド・コンピューティング普及の原動力となりました。

**(5) Pay for Use Model**
使った分だけ支払う制度では、企業はキャッシュフローに優しいOperating Expenseモデルに切り替えることができました。 このモデルは、ハードウェアをほとんど持っていない企業から、十分に持っている企業まで、あらゆる規模の企業に対して魅力的なものでした。ハードウェアに巨額の投資をする代わりに、必要なときに必要なだけコンピューティングリソースに対して支払うことができるからです。
また、使用量のピーク時にはワークロードを拡張し、使用量が減少したときにはワークロードを縮小することができます。
そして、これが現代のクラウドコンピューティングを生み出したのです。
ジェネリクスとは（Swift)

ジェネリクスとは
---
汎用型のデータ型のことをジェネリクス機能という。
本来Swiftは型宣言をして関数を宣言していたが、型を抽象化し柔軟に利用できるようにしている。

```swift:例.swift
//型宣言をする場合
let stringArray: Array<String> = ["a", "b", "c"]
let intArray: Array<Int> = [1,2,3]

//ジェネリック型

struct 構造体<型引数> {}
class クラス<型引数> {}
enum 列挙型<型引数> {}
//Tが多い　引数の型はインスタンス化する際に指定する
構造体<型名>()
クラス<型名>()
列挙型<型名>()

//ジェネリック関数
func 関数<型引数>(引数) -> 戻り値の型 {}
//同じように型指定して発動させる
関数<型名>()

```

型が違うだけで同じ関数を書く必要がなくなるので簡略化につながる
残プロ　第-38回　~コンソールにaa動画を表示する~

# ANSIエスケープシーケンス

[前回](https://qiita.com/R1nY1x1/items/a1ffba791f74987a868d)，画像のアスキーアート化について紹介しました．
今回はANSIエスケープシーケンスを使って動画の表示に挑戦したいと思います．


## .py

必要最低限の機能であれば，以下プログラムで実現できます．
PCに接続されたカメラから画像を取得しAA化，表示を1秒に数回行います．

~~~ python:VideoPrint.py
import cv2

cap = cv2.VideoCapture(0)
wid = 90
density = list("MWN$@%#&B89EGA6mK5HRkbYT43V0JL7gpaseyxznocv?jIftr1li*=-~^`':;,. ")

try:
    while(True):
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        resized = cv2.resize(gray, (int(wid*2),int(wid)))
        for i in range(resized.shape[0]):
            s = ""
            for j in range(resized.shape[1]):
                s += density[(len(density)-1)-resized[i][j]//(256//len(density))]
            print(s)
        print("\033[{}F".format(wid+1))

except KeyboardInterrupt:
    cap.release()
    print("\033[{}E".format(wid+1))
~~~
GitHubに接続できないときに試すこと一覧

# リモートリポジトリを追加できているか？
GitHubで空のリポジトリを作成すると丁寧にコマンドが書いてある。

## 新規にリポジトリを作る場合
```bash
echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:[GitHubアカウント]/[リポジトリ名].git
git push -u origin main
```

## 既存のリポジトリを登録する場合
```bash
git remote add origin git@github.com:[GitHubアカウント]/[リポジトリ名].git
git branch -M main
git push -u origin main
```

# SSHキーは正しく登録できているか？
これも丁寧に公式に書いてある。SSHキーを生成して公開鍵をGitHubに登録する必要がある。

- [GitHub Docs: GitHub アカウントへの新しい SSH キーの追加](https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)

## SSH-Keyの場所
通常は~/.ssh以下にSSH-Keyがある。.pub付きが公開鍵で、何もついていない方が秘密鍵。

```
$ ls -la
-rw-r--r-- 1 devuser devuser   83 Jul  9 23:16 config
-rw------- 1 devuser devuser 2602 Jul  9 22:28 id_rsa
-rw-r--r-- 1 devuser devuser  567 Jul  9 22:28 id_rsa.pub
```

## SSH-KeyのGitHub登録
公開鍵はGitHubにアップロードする必要がある。アップロードと言っても前手順で確認した公開鍵をless等で開いて、その中身の文字列を以下のサイトのNewから貼り付けるだけでOK。

- [GitHub: Account > Settings > SSH and GPG Key](https://github.com/settings/keys)

## SSH configの確認
何らかの理由で~/.ssh/configが壊れるとgitコマンド実行時にエラーになる。例えば以下のようなエラーが出る。

```bash
$ git push --set-upstream origin main
no such identity: /home/myuser/.ssh/id-rsa: No such file or directory
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

よく見れば書いてあるが、秘密鍵が存在しない or リポジトリが存在しない旨のエラーになっている。
GitHubに作ったリポジトリ名が正しいかの確認の他、~/,ssh/config に書かれている秘密鍵のファイル名や置き場所が正しいかも確認すること。

```~/.ssh/config
Host github.com
 HostName github.com
 IdentityFile ~/.ssh/id-rsa　　#本当に正しい秘密鍵の場所を指しているか確認すること！
 User git
```
例えば、上のように秘密鍵のファイル名が違う（本当はid-rsaではなくid_rsaが正しい）という罠があることも・・・。（私はこれで1時間時間を溶かしたことを自戒を込めてここに記す。）

以上。
他にも何かあったら追記していく。増えてほしくないが。
webhookでJenkinsとGithubの連携

##この記事を読む前に


前回の記事の続き: 

https://qiita.com/wanidrums/private/eb761070b8a595241055


##連携の流れ

連携の設定自体はシンプルです。

・Jenkinsの設定画面でAPIトークンの発行。

・GithubのWebhookの設定欄に先ほど発行したJenkinsの[API_TOKEN],[TOKEN_NAME]や[JENKINSのホスト名]、[ジョブの名前]などをURLとして指定するだけです。

##環境

macOS Big Sur バージョン１１.２.２

##参考にしたサイト
（jenkins webhook github 連携　で検索）

https://developer.aiming-inc.com/infra/jenkins-github-webhook-collaboration/

より詳しく知りたい方はこちらのサイトを参考にされた方が良いです。

##連携の前に（前回の記事を参考にした方へ）

**・Ansibleはcloudformationの後に実行して欲しいので、Ansibleジョブの設定で「他プロジェクトの後にビルド」にcloudformationフォルダを選択**
（不安定でも起動でOK）

**・Jenkinsのcloudformationビルドへ移動**
シェルスクリプトを変更
（同じスタック名でcloudformationは実行できないので、今作ったやつを削除するような処理を追加する）
↑本当は更新処理のが良いらしい。今回は手っ取り早く削除してるだけ。

```
例）
aws cloudformation delete-stack \
  --stack-name jenkins

aws cloudformation wait stack-delete-complete \
  --stack-name jenkins
  
aws cloudformation deploy \
  --stack-name jenkins \
  --template-file new.yml \
  --parameter-overrides $(cat new_dev.cfg) \
  --capabilities CAPABILITY_NAMED_IAM

aws cloudformation wait stack-create-complete \
  --stack-name jenkins
```

・保存

##JenkinsとGithubの連携の設定

・再びcloudformationビルドへ
ビルドのパラメータ化をチェック
パラメータの追加からテキストを選ぶ
名前に「payload」と入力。保存。


・Jenkins⇨設定⇨APIトークンの「トークン新規追加」⇨発行されたトークンと名前をメモする⇨Apply、保存
＊次の設定で[API_TOKEN], [TOKEN_NAME]としてそれぞれ使います。

・Githubにあるcloudformationのフォルダを選択し「Settings」,「webhooks」「Add webhook」
・（求められたら）パスワード入力
・PayloadURL入力（Webhookの連携先）

```
書き方
http://[USER_ID]:[API_TOKEN]@[JENKINS_HOST]/job/[JOB_NAME]/[build|buildWithParameters]?token=[TOKEN_NAME]

例）
http://admin:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@jenkins.example.com/job/webhook_job/buildWithParameters?token=hogehoge
```
```
実際に設定した例）
http://test:1168c1852c2cfb7fb5ed63105fd49fa5aa@52.194.253.12:8080/job/cloudformation_pf/buildWithParameters?token=jenkins_token
```

・これで連携成功
Githubのファイルが変更されると、Jenkinsが自動で動いてくれるようになる
CI／CDツールとして本領発揮する
完了
【Swift】CleanArchitectureの要点をまとめる

#はじめに
今回は、CleanArchitectureのそれぞれの要点をまとめていきたいと思います。

#概要
クリーンアーキテクチャでは以下の画像がすごく有名ですね。
この画像からわかるように、クリーンアーキテクチャの本質は中心に向かう矢印の方向（依存方向）です。
![ScreenShot 2021-07-09 23.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/7a918ba1-03bd-9856-9c71-1632e7ec7a17.png)

例えば、赤色のUseCasesは緑色のGateways(Repository)を具体として知っていてはいけません。

また、この画像の右下の図も重要です。必ずUseCasesを経由して全ての制御を行うべきなので、どうしてもUseCasesから緑の領域に向かいたい場合もあります。そういった時にはインターフェース（iOSでのprotocol）と依存関係逆転の原則を使い回避します。

#全体図
以下の例ではMVVMのModelをクリーンアーキテクチャによって細分化しています。

![ScreenShot 2021-07-09 23.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/e3ac2d70-a7cc-cf9b-2f96-d5bbbb9b8ed1.png)

#Presentation層
Presentation層の大切なところのみまとめます。

##ViewModel
・Domain層とのprotocol
・UIイベントをどのように振る舞うかを決める
・ViewControllerを知らない
・UseCaseを実行し、UseCaseから受け取ったデータをViewControllerに渡す

##ViewController
・UIイベントをViewModelに任せる
・ViewModelからの通知によってViewの状態を変更する

##View
・ViewControllerを知らない

#Domain層
Domain層の大切なところのみまとめます。
##UseCase
・全ての制御をここを介して行う
・ViewModelからの要求に対応する
・必要に応じてRepositoryへデータを要求 ・RepositoryからのデータをViewModelに渡す
・ViewModelやRepositoryを知らない

##Repository(protocol)
・インターフェース
・どこに保存されるのかは知らない

##Entity
・データの型

#Data層
Data層の大切なところのみまとめます。

##RepositoryImpl
・Domain層とのprotocolに準拠
・UseCaseからの要求に対し、DataStoreから実際のデータ取得を要求
・DataStoreから受け取ったデータをUseCaseに渡す
・DataStoreを知らない

##DataStore
・データの永続化
・DB, API, Realmなどにつき都度用意する
・Factory Patternを用いてRepositoryがDataStoreの種別を意識しないようにする

##Entity
・純粋なデータ型(なくても良い)

#おわりに
今回は、CleanArchitectureの要点をまとめました。
設計難しい、、、
【Node.js】Node.jsの最大メモリを増やす方法

#Node.jsの最大メモリを増やす方法
　`設定>システム>詳細情報>システムの詳細設定`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/f1a1e8e8-e250-7580-cfc0-933f8add5018.png)

　`詳細設定>環境変数`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/11fa65e6-2791-e494-5c92-64449bb12d88.png)

 `システム環境変数>新規`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/78f798dc-ae1a-fc1f-8969-891e139e88e0.png)

```
変数名: NODE_OPTIONS
変数値: --max_old_space_size=30720(好きな値)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/3dbe0be1-e343-4f79-42cc-66aa298db0dd.png)
Pay.jpを利用する際のJavaScriptの注意点

## 概要

フリマアプリを制作した際、Pay.jpを利用してクレジットカード機能を実装する際にかなりハマったことがあったので書き記したいと思います。

## やりたかったこと

カード情報をJavaScriptでPay.jpに送信し、トークンを取得します。

## 間違えたコード

```card.js
const card = {
      number: formData.get("buy_record_delivery[number]"),
      month: formData.get("buy_record_delivery[exp_month]"),
      year: `20${formData.get("buy_record_delivery[exp_year]")}`,
      cvc: formData.get("buy_record_delivery[cvc]"),
    };
```


### 間違えたコードを実行した結果


```
https://api.pay.jp/vi/tokens 400
```

コンソール上でエラーが出ました。URLをクリックすると下記の通りになりました。

```
{
 "error": {
   "code": "invalid_param_key",
   "message": "Invalid param key to token",
   "param": "card[month], card[year]",
   "status": 400,
   "type": "client_error"
  }
}
```

上記のエラー内容とログ内容を考察すると、カード情報の番号とセキュリティコードはPay.jpに送られているが、有効期限の月と年が送れていない為エラーになっていることがわかった。しかし、なぜ送れるデータと送れないデータがあるのかがわからずハマりました。

## 修正したコード

```card.js
const card = {
      number: formData.get("buy_record_delivery[number]"),
      exp_month: formData.get("buy_record_delivery[exp_month]"),
      exp_year: `20${formData.get("buy_record_delivery[exp_year]")}`,
      cvc: formData.get("buy_record_delivery[cvc]"),
    };
```

monthをexp_manthに、yearをexp_yearに変更することで全てのカード情報を送信することができました。

## まとめ

Pay.jpにカード情報を送る際には、monthやyearだけだと有効期限ではなくただの「month」「year」と認識されてしまうようです。exp_month(year)とすることで有効期限と認識されるとのことで、気付くのに時間がかかりました。
laravel5.8ルーティング

laravelを学ぶ機会があったので、簡単にまとめたいと思います。

# 全体像
![全体流れ-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/db8aa715-8155-29c5-5ae2-c378d6bac6bb.jpeg)

#CRUD処理
CRUD処理とは
システムに必要な4つの主要機能である
「Create（生成）」「Read（読み取り）」「Update（更新）」「Delete（削除）」
の頭文字を並べた用語です。

#HTTPメソッドを指定するルーティング
GET　・・・　（データを取得する基本的なもの）
POST　・・・　（データの追加に使用）
PUT　・・・　（データの更新に使用）
DELETE　・・・　（データの削除に使用）
※他もある

#アクション

![スクリーンショット 2021-07-12 21.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/84084ff7-9036-b0da-6b6a-dcbd18649960.png)


#実装例 
routes/web.php
```
    Route::get('/', 'PostsController@index');
    Route::get('posts/new', 'PostsController@create')->name('posts.create');
    Route::post('posts', 'PostsController@store')->name('posts.store');
    Route::get('post/{id}/edit', 'PostsController@edit')->name('post.edit');
    Route::post('post/{id}', 'PostsController@update')->name('post.update');
    Route::delete('post/{id}', 'PostsController@destroy')->name('post.destroy');
```
AndroidStudio4.2.2 アップデートできないときの解決法

## まず簡単に解決法

1. 公式サイトからダウンロードするなりAndroidStudio内で更新するなりで4.2.2を入れる
1. アプリを起動させようとしてみるが、エラー表示が出てしまう状態になる
1. ```studio64.exe.vmoptions```のファイルを開き、```-Xverify:none```を追加しAndroidStudioを日本語化している場合は```-javaagent...```をコメントアウト(行頭に```#```をつける)しておく

これが一連の解決策になります。
> ちなみに自分の場合のエラー表示はこんな感じ
> ![スクリーンショット 2021-07-08 183905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1080547/46201927-75e4-600b-3846-281f2cd602ac.png)

> 参考サイト
> [Android Studio 4.2 を更新したら起動しなくなったときの対処法](https://qiita.com/idani/items/2acfd88bcc7bca32dd67)
> [Android Studio 4.1 の日本語化を解除する（英語に戻す）](https://zesys.net/pc/android/android-studio-cancel-japanese-localization/)
> [Android Studioが起動しない/起動できない時の対処法](https://appli-world.jp/posts/16955)

## 詳細

### studio64.exe.vmoptionsファイルの場所

```studio64.exe.vmoptions``` ファイルは実は複数あります。

今回編集するファイルは以下の場所にあると思います。
C:\Users\ユーザー名\AppData\Roaming\Google\AndroidStudio4.1\studio64.exe.vmoptions

#### ない場合
もしこのパスが存在しない場合は、ちょっと手間がかかりますが
[Pleiades All in One](https://mergedoc.osdn.jp/)をダウンロードする必要があります。
これはAndroidStudioを日本語化するために必要なソフトになります。

ダウンロード出来たら起動して日本語化するアプリを選択します。
そうすると```studio64.exe.vmoptions```があるところに赤線で囲われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1080547/a6457d89-049c-72c2-1b6a-d2bb800c2c33.png)

### studio64.exe.vmoptionsの編集
```-Xverify:none``` を追加し
```-javaagent...```をコメントアウトしていきます。

ちなみに```-javaagent...```はAndroidStudioの日本語化を解除するためにコメントアウトします。
どうやらAndroidStudioが日本語化された状態だとアップデート時にいろいろ不具合があるみたいです。

``` studio64.exe.vmoptions
# Custom VM options (Generated by Pleiades Installer)
# See https://pleiades.io/pages/pleiades_jetbrains_manual.html
#-Xms256m
#-Xmx1280m
-Xverify:none
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-XX:CICompilerCount=2
-Dsun.io.useCanonPrefixCache=false
-Djdk.http.auth.tunneling.disabledSchemes=""
-Djdk.attach.allowAttachSelf=true
-Dkotlinx.coroutines.debug=off
-Djdk.module.illegalAccess.silent=true
-Djna.nosys=true
-Djna.boot.library.path=
-Didea.vendor.name=Google
#-javaagent:C:\Users\ユーザー名\AppData\Roaming\Google\AndroidStudio4.1\jp.sourceforge.mergedoc.pleiades\pleiades.jar
```

### 起動してみる
編集ができたらAndroidStudioをクリックして起動してみましょう。
自分の場合は日本語化を解除したままにもかかわらず起動後はなぜか日本語化された状態でした。
ですがその後も問題なく動作しているのでたぶん大丈夫だと思います。。。
(もし心配だったらコメントアウトを解除)
Azure Fundamentals 3種取得してみた

# 振り返り

https://qiita.com/morio1101/items/57fdb2a9c35827fea062

前回 DOP を目指してみるか！なんて書いたものの問題集を一周して脳みそに全くインプットされなかった悲しさから Azure に少し浮気していました。

# 前提

## Azure に関する知識

全くない状態だけど、AWS は知識が若干ある状態

## Azure Fundamentals の試験

Azure Fundamentals は以下の三種類あります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532289/ce3f9329-0947-1619-19e5-015009be7bbc.png)

# 私個人の資格取得の流れ

| 試験名 | 資格取得日 |
|:-----------|------------:|
| Azure Fundamentals (AZ-900) | 2021-06-26 |
| Azure Data Fundamentals (DP-900) | 2021-07-04 |
| Azure AI Fundamentals (AI-900) | 2021-07-09 |

# それぞれの試験について

## Azure Fundamentals

### 使用した教材

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

### 学習方法

基本的には解説を読みながら一周した後に、2～3周時間を見つけて周回した

### 感想

AWS の試験を受けて、インフラの基礎知識が定着していたら初見でも 4～5割は取得できた
ただ Azure の機能名と実際の挙動を結びつけるのに問題集を繰り返し説く必要があった
英語が得意だと Azure のほうが直感的という意見もあった

## Azure Data Fundamentals 

### 使用した教材

https://www.udemy.com/course/dp-900-practice-tests-microsoft-azure-data-fundamentals/

### 学習方法

PC 版の Udemy + google ページ翻訳 + DeepL 翻訳ツールを活用して問題集を2～3周ぐらい周回した

### 感想

SQL を書くような案件に関わっていると雰囲気で解ける問題がそこそこある
Azure が提供している機能のそれぞれの特性（AWSでいうDynamoDBやAuroraの違いみたいみたいな）を理解できるようになれば受かる水準に達していると思う
DB 自体は業務で扱うため、個人的にはこの試験が一番簡単に感じた

## Azure AI Fundamentals 

### 使用した教材

https://www.udemy.com/course/microsoft-certified-azure-ai-fundamentals-5-practice-tests/

### 学習方法

PC 版の Udemy + google ページ翻訳 + DeepL 翻訳ツールを活用して問題集を2周ぐらい周回した

### 感想

機械翻訳をした後の問題を読むと何となく雰囲気で問題が解けた（初見で6～8割程度）
機能レベルになると似たような文字の羅列が多くなるので、それぞれの意味と役割を説明できるようになっていると試験にも活かせると思う
ただ機械翻訳された文言のみを確認していると、実際の試験では英語のまま出題されているケースもあったので、翻訳前の文言も見ておいたほうがよいかもしれない


## 体感で試験の難易度

AZ-900 > AI-900 > DP-900

* 仕事で DB を触っている場合、DP-900 は比較的簡単に感じた
* AI-900 は問題集との翻訳のギャップに苦戦を強いられた
* AZ-900 は広く浅い Azure の機能について問われるので一番雰囲気的に苦手だった

# 最後に

次回資格の更新をする必要がない試験ということもあって勢いで受験した
AWS の試験からは横道にそれたけど、AWS 関連の試験も取っていきたいなって思っている

試験は受かれば会社が資格代＋αを出してくれるので、未知の分野でもチャレンジしやすい
（自費だとこんな色々資格取得するのは厳しいですよね:sweat_smile:）
4ian 氏が Google 辞めて GDevelop に全振りする件

2021年6月25日に GDevelop の作成者である 4ian (Florian Rival) さんが Discord 上で「Ask Me Anything（なんでも聞いて）」というイベントを開きました。

そのイベントでは、「Google 辞めて GDevelop のために会社作るよ！」という驚愕の発表がおこなわれたのですが、その件について 4ian さんご本人が Discord 上でまとめていたので、（勝手に）翻訳してここに掲載しておきます。

__※ この翻訳が原文の内容を正しく表現している保証はありません。__

##Discord での 4ian さんの[発言](https://discord.com/channels/258623956158906368/614521284314923025/860542330511032331)（2021年7月3日）
>私がGDevelopに取り組むために設立した新しい会社に関連して、いくつかの質問が多く寄せられていることを知っているので、簡単なQ&Aをします🙂
>
>###GDevelopは有料のソフトウェアになるのですか？
>いいえ、GDevelopは今のように無料で使えます🙂
>
>###GDevelopはオープンソースのままですか？
>はい、アプリもゲームエンジンもオープンソースであることが基本方針です。
>
>###会社の収益はどうなるのですか？
>GDevelop 上に、ゲームをより早く、より成功させるためのサービスをもっと提供したいと思っています。
>
>いくつかのアイデアがありますが、中でもゲームクリエイター（つまりあなた）が自分のやっていることを収益化したり、共有したりする方法があります。（そうすれば、GDevelopを使うことがより充実したものになります）
>
>###投資家からGDevelopを有料ソフトにするように言われますか？
>いいえ、彼らはそれを要求することはできませんし、GDevelopはいずれにせよオープンソースのままです。
>
>もちろん、ゲーム向けのサービスでお金を稼ぐ方法を見つけようとしています。（クリエイター向けにもお金を稼ぐ方法がありますが、今のところ選択肢はあまりにも限られています！）
>
>銀行にお金が残らなければ、会社をたたむことになるでしょう。
>
>###将来的に会社がなくなってしまったら？
>そうならないことを願っています🙂そうなってしまったら、GDevelopにとっては悲しいことです。
>
>しかし、アプリ、ゲームエンジン、拡張機能はすべてオープンソースなので、生き残ることができますし、貢献者の助けだけで以前のように続けることができます。
>
>でもこれは、会社を成功させることが、今後数年、数十年(100年？)にわたってGDevelopが開発・改良され続けるための最良の方法だということです。
>
>でも私はそんなことはどうでもよくて、ただGDevelopが成長し続けるのを見たいのです。
>
>私がGoogleを辞めたのは、GDevelopにフルタイムで取り組むためなんです😉
>
>これと会社を持つことは、将来的にGDevelopをより早く発展させるための最良の方法だと思います。
>
>私の目標は、コミュニティが今のように開発に参加し（これがオープンソースの良さです）、GDevelopを大成功させる方法を見つけることです。（他のエンジンや大作ゲームと比べて知名度が低いことをご存知かもしれませんが、これを変えましょう！）
>
>###GDevelop のロゴや Web サイトが他のエンジンに比べて見栄えがしないのですが、改善する予定はありますか？
>はい、デザイナーの助けを借りて、GDevelopにもっと「遊び心」を持たせて、（さらに）威圧感のないものにしたいと思っています。また、新しいランディングページを作って、よりプロフェッショナルなサイトにしたいと思っています。

以上です。 

今までも 4ian さんとコミュニティの力だけで、これだけのものが作られてきたわけですから、この会社が活動し始めれば、GDevelop が一気に飛躍すること間違いなしですね😆👍

なお、イベントの様子は YouTube にアップされているので、英語バリバリ分かる方は聞いてみてください。（そして詳細を私に教えて下さいｗ）
<iframe width="560" height="315" src="https://www.youtube.com/embed/VXV4fCf2dk8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

今後のさらなる GDevelop の躍進に期待ですね😊
***
あと、これは余談ですが、過去（2019年）に日本では株式会社マイティークラフトが日本語化とサポートを開始すると宣言していましたが、現状（2021年2月確認当時）は「担当者が退社しており対応していない状態」とのことです😥
おそらく本件とも関わりはないものと思われます。（未確認です）

**現在、日本語化などの活動は、有志の方のお力によりおこなわれています。**
日本のコミュニティがもっと盛り上がるよう、私も微力ながらお役に立てるよう頑張ります💪

**※ この投稿は「[GDevelop 無料ゲーム制作ツールを使い倒す Blog](https://gdevelop-jp.blogspot.com/2021/07/4ian-gdevelop.html)」からの移植＆改訂版です。**
ストアドプロシージャ とは

## 勉強前イメージ

DBのなにかの機能？

## 調査

### ストアドプロシージャ とは

データベースに対する処理をプログラムにめまとめてRDBMSに保存したものになります。
論理的に複雑なSQLの呼び出しを一つの処理単位にまとめて名前で呼び出せるようになっており、
繰り返しや条件分岐などの構造を持つこともあります。

### ストアドプロシージャのメリット

- SQLを一つずつ発行しなくてよい

ストアドプロシージャに保存されているので
複数SQLがあっても1つの処理にまとめることができる

- トラフィックの削減

外部からSQLを発行するに比べたら
SQLの解析が完了している状態で保存されているため高速に実行でき、
出力までの時間やトラフィックに関しても削減できる

### Mysqlでストアドプロシージャやってみる

以下のようなテーブルを作成しました

```
mysql> select * from user;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | Bob  |   30 |
|    2 | Saki |   24 |
|    3 | Natu |   25 |
|    4 | Mery |   40 |
+------+------+------+
```

- プロシージャの作成

例では、 `test_procedure` という名前をつけて `arg_age` という定義をしています。

```
CREATE PROCEDURE test_procedure(IN arg_age int)
SELECT * FROM user WHERE age = arg_age;
```

- プロシージャの確認

```
SHOW CREATE PROCEDURE test_procedure\G
```

```
mysql> SHOW CREATE PROCEDURE test_procedure\G
*************************** 1. row ***************************
           Procedure: test_procedure
            sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER
,NO_ENGINE_SUBSTITUTION
    Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `test_procedure`(IN arg_age int)
SELECT * FROM user WHERE age = arg_age
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci
```

- プロシージャの実行

```
CALL test_procedure(25);
```

```
mysql> CALL test_procedure(25);
+------+------+------+
| id   | name | age  |
+------+------+------+
|    3 | Natu |   25 |
+------+------+------+
1 row in set (0.00 sec)
```

- プロシージャの削除

```
DROP PROCEDURE test_procedure;
```

## 勉強後イメージ

実際に自分で動かしてみてイメージ湧いたかも。
↑で言えば `SELECT * FROM user WHERE age = ?` の ? だけを後から変更して取れるようになるってことか
わかりやすいし便利ー

## 参考

- [ストアドプロシージャって何？SQLの応用スキルを身につけよう！](https://style.potepan.com/articles/25739.html)
- [ストアドプロシージャ 【stored procedure】 ストアードプロシージャ](https://e-words.jp/w/%E3%82%B9%E3%83%88%E3%82%A2%E3%83%89%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3.html)
Qiitaで画像のサイズを変更し、リンクを貼り付ける方法

Qiitaで画像のサイズを変更し、リンクを貼り付ける方法



```
[<img width = 100 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/cac6487f-57c5-6692-585e-88dbba16440e.png">](https://amzn.to/3ANnFu4)
```

[<img width = 100 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406910/cac6487f-57c5-6692-585e-88dbba16440e.png">](https://amzn.to/3ANnFu4)



```
[<img width = 100 src = "画像">](リンク)
```

[<img width = 100 src = "画像">](リンク)
Edge アドオンで、Outlook操作が超高速に

# 技術じゃないです
ただ単に、あまりにも便利で、社内で伝えたいのに伝えられないもどかしさを表現したかっただけ

# まずはインストールを
[Microsoft Outlook](https://microsoftedge.microsoft.com/addons/detail/microsoft-outlook/kkpalkknhlklpbflpcpkepmmbnmfailf)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bb660310-9154-c846-2a3a-b90a3252bc38.png)

# これの何が良いの？
それは、Outlookの酷さを思い出せば分かります。

1. 重い
1. 見難い (テキスト固定だから・・）
1. 兎に角鈍重

それに対して、この子は、天使が舞い降りるかの如く軽やか
８Gしか積まれてない亀PCでも軽量に動作するところが素敵すぎる

勿論既存のOutlookでも以下などを進めればある程度快適にはなりました

- 振り分けは最小化し検索フォルダーへ
- ルールは全部サーバールールへ
- Teamsに飛ばしてスレッド化＆Mailは既読化
- 閲覧や検索はOWAで

でも、そんな苦労しなくてもよかったんだ！ってぐらいにこの子は素敵💖
まだまだ色々問題もあるけど、今後のUpdateに期待大

# では動きをどうぞ（ほぼスマフォ？
![OutlookAddin.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7d1113fd-1fea-42ab-8b01-5b59532ddcc9.gif)
正直、これ使うだけで、大量のMail処理はかなり捗ります。

Outlook使ってる方なら是非、一度お試しを👍
データ基盤のアーキテクチャ例

# 概要
データ基盤について調査したので、具体的な事例をまとめておく。

# 具体例

## Data Lakeに対してTransaction機能を持たせるパターン
+ [What is Apache Iceberg?](https://www.dremio.com/data-lake/apache-iceberg/)
+ https://delta.io/

### Netflix
+ `S3`に対して、`Iceberg`を使っている
+ [Optimizing data warehouse storage](https://netflixtechblog.com/optimizing-data-warehouse-storage-7b94a48fdcbe)

### エブリー

+ [Delta LakeとLakehouseプラットフォームによるデータウェアハウス設計](https://tech.every.tv/entry/2021/04/13/120000)
+ [Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics](https://databricks.com/wp-content/uploads/2020/12/cidr_lakehouse.pdf)
+ Bronze、Silver、Goldと定義される三段階にデータ構造を分離する

## DWHを使うパターン

### クックパッド

+ Redshift Spectrumを中心にして構築している
+ [データ活用基盤の今 〜DWH外観図〜](https://techlife.cookpad.com/entry/2019/10/18/090000)
  + 
+ [最新のログもすぐクエリできる速くて容量無限の最強ログ基盤をRedshift Spectrumで作る](https://techlife.cookpad.com/entry/2018/11/21/121500)
  + 遅延データに対する「締め」という概念

### ZOZO
+ BigQueryが中心
+ RDBからDWHのデータ移動にはDigdag/Embulkを使用
+ [ZOZOTOWNの事業を支えるBigQueryの話 / BigQuery behind ZOZOTOWN](https://speakerdeck.com/shiozaki/bigquery-behind-zozotown)

### Klab
+ BigQueryが中心
+ ETLはSQL+CloudFunction or Cloud Dataflow
+ [モバイルゲームのためのデータ分析](https://www.slideshare.net/AtsushiTakada1/ss-128750826)
DartでDateTimeを使用せずhh:mmに時間をフォーマットする


## 目的
- 8時8分を'08:08'と表示したいが、'8:8'となってしまう。


## どのようにするか
- コード

```
void main() {
  final hour = 8;
  final minute = 8;
  print('${twoDigits(hour)}:${twoDigits(minute)}');
}


String twoDigits(int n) => n.toString().padLeft(2, '0');
```

- 出力


```
08:08
```

## DateTimeなら

- DateFormatを使用すると

```
final time = DateFormat('hh:mm').format(DateTime.now());
print(time);
```
一つのformで処理を切り替える

submitすると、formの中は全て送信されます
その為、一つのformで処理を分けるときにはどこかのタイミングで値を変更できるようにしないといけません。

```
<form method="post">
    <input type="hidden" name="kind" value="" >
    <button type="button" onclick="return switching_btn(this.form, 'add')">作成
</button>
    <button type="button" onclick="return switching_btn(this.form, 'edit')">編集</button>
    <button type="button" onclick="return switching_btn(this.form, 'delete')">削除</button>
</form>


<script>
// kind切替
function switching_btn(form, f_flg) {
    form.kind.setAttribute("value",f_flg);
    form.submit();
}
</script>
```

このようにして"kind"の値によって処理を分けることができます
[rspec] Grape APIのhelpersをスタブ化するメモ

grape 1.3.3
rspec-rails 5.0.1

grape使っている際, current_userのようなよく使うものへスタブ差し込む方法が分からなかったのでメモ

諸々省略

```ruby:app/apis/my_service/api.rb
class MyService::Api < Grape::API
  # 省略
  helpers do
    def current_user
      @current_user ||= User.find(params[:id])
    end
  end
end
```

```ruby:spec/app/apis/my_service/v1/users_spec.rb
describe MyService::V1::Users do
  describe "GET /my_service/v1/user/:id" do
    subject { get "/my_service/v1/user/#{user.id}" }

    let(:user) { create(:user) }
    context "no good" do
      before do
        allow(User).to receive(:find).and_return(user)
      end
      it 'response user' do
        subject
        expect(my_response[:name]).to eq user.name
        ...
      end
    end
    context "good" do
      before do
        Grape::Endpoint.before_each do |endpoint|
          allow(endpoint).to receive(:current_user).and_return(user)
        end
      end
      after { Grape::Endpoint.before_each nil }

      it 'response user' do
        subject
        expect(my_response[:name]).to eq user.name
        ...
      end      
    end
  end
end
```

参考
https://github.com/ruby-grape/grape/issues/396
Rubyの基礎概要　[Rubyチェリー本 2章まとめ]

Railsチュートリアルも終え、Railsを用いたポートフォリオアプリ制作も終ました。
その段階で、改めてRailsのチェリー本と呼ばれる、以下の書籍を読み、改めて勉強になったので、以下にいくつか抜粋します。

https://www.amazon.co.jp/dp/B077Q8BXHC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

### 1. &&や||の評価を終了するタイミング

> Rubyは式全体が真または偽であることが決定するまで左辺から順に式を評価します。式全体の真または偽が確定すると、式の評価を終了し、最後に評価した式の値を返します。

その性質を活用すると、以下のようなコードを実行できる。

```bash
# Alice、Bob、Carolと順に検索し、最初に見つかったユーザ（nilまたはfalse以外の値）
# を変数に格納する
user=find_user('Alice')||find_user('Bob')||find_user('Carol')
```

### 2. ヒアドキュメント

複数行に渡る長い文字列を作成する場合にスッキリ書く方法。
以下のような方法で利用可能

```bash
<<識別子
1行目
2行目
3行目
:
識別子
```

```bash
a = "これはヒアドキュメントです。
複数行に渡る長い文字列を
作成するのに便利です。"

a = <<TEXT
これはヒアドキュメントです。
複数行に渡る長い文字列を
作成するのに便利です。
TEXT
```

### 3. requere

Rubyでは、ruby をインストールした際に、多くのライブラリが標準として用意されている。
ライブラリの種類には、組み込みライブラリと標準ライブラリ、外部ライブラリがある。

組み込みライブラリと標準ライブラリは、rubyインストール時に同時にインストールされている。そのおかげで、StringやIntengerなどの組み込みライブラリは、常時使用可能な状態になっている。

一方で、dateやjsonなどの標準ライブラリは、インストールされてはいるものの、明示的に読み込むことで使用可能になる。読み込むために用いるのが`require`である。

```bash
require'date'

Date.today　#=>#<Date:20170407((2457851j,0s,0n),+0s,2299161j)>
```

それとは異なる外部ライブラリとは、bundlerやrailsといった有志で開発されたものを指し、rubyの場合はgemと言う。

### 4. エイリアスメソッド

まったく同じ実装で名前だけ異なるメソッドのことをエイリアスメソッドと呼びます。

.ex) `length`と`size`：どちらも文字数を返す

```bash
'hello'.length　#=>5
'hello'.size　#=>5
```
【コピペだけでできる】Rails 超簡単 フォームのURLをハイパーリンク化する方法

#  はじめに
筆者は [大学生限定 プログラミングコミュニティ 『GeekSalon』](https://geek-salon.com/?utm_source=Direct&utm_medium=attract&utm_campaign=2Q&utm_content=Fukuoka_E_2Q)で活動している者です！ 
もし少しでも興味がありましたら、ぜひお話を聞きにきてくださいね♪

では本題。某SNSサイトなどで、入力フォームに打ち込んだURLが、ただの文字列としてではなく、リンクとして送信されることに対して不思議に思ったことがある人も多いのではないでしょうか？　　
多分、多くないですね、、、^^;

今回は、それをコピペだけで実装できちゃうように紹介いたします。解説などは気が向いたらつけます。。。

#前提
簡単な投稿機能は作成済みであること

#こちらをコピペしましょう！

```ruby:app/helpers/application_helper.rb
module ApplicationHelper

#ここから
  require "uri"

  def text_url_to_link text
  
    URI.extract(text, ['http','https']).uniq.each do |url|
      sub_text = ""
      sub_text << "<a href=" << url << " target=\"_blank\">" << url << "</a>"
  
      text.gsub!(url, sub_text)
    end
  
    return text
  end
#ここまで

end
```

```ruby:app/viwes/tweets/index.html.erb
  <% @twee.each do |t| %>
    <div class="tweet">
      <%= text_url_to_link((h(t.body).html_safe)).html_safe %>   # ←t.bodyのところは自分用に変更してね^^
    </div>
  <% end %>
end
```


#※text_areaの改行をそのまま反映させたい場合

```ruby:app/viwes/tweets/index.html.erb
  <% @twee.each do |t| %>
    <div class="tweet">
      <%= text_url_to_link(safe_join((h(t.body)).split("\n"),tag(:br))).html_safe %>   # ここが変わるよ^^
    </div>
  <% end %>
end
```

###おしまい♪

いかがでしたでしょうか？
仕組みなどが気になったら、とりあえずググってみてくださいまし。

それではバイちゃーーー(^^)／~~~
Radeonは GigaColor(10億色) ゲーミングの夢を見るか


Radeonってこんなに「くすんだ色」だったっけ？（横目で見ながら



####Windowsとグラフィックボードが10bit（10億色）で動作するかどうかを確認する

　俺が10bitと言ったら「互換モードのカラーモード制限」でも10bitだからな？　
　　さすが DirectXさんマジパネェっす

　必要なもの
　　・10BitScanout10.exe（DirectX9.0cSDKに同梱）　
　　・d3dx9_43.dll（エンド ユーザー ランタイム が入ってない場合）
![10BitScanout10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1698056/3f1597a8-dd6c-ef00-aa58-ad5b440a821f.png)
　　10bitと 8bitで背景の階調不足疑似輪郭が変化するなら10bit対応
　　　（Windows10ならフルスクリーン表示に切り替える必要はない）
　　手前で回る急須が何なのかはわからないｗ
　　あと「別の場所にコピー」したら動かなくなる　なぜ？ どうして？ ＷＨＹ？

　DirectX9.0cSDKが消失？ - 窓の杜
　　https://forest.watch.impress.co.jp/docs/serial/yajiuma/1308967.html



####我々は10年待ったのだ

　Steam キュレーター: HDR Games
　　https://store.steampowered.com/curator/33286359-HDR-Games/?l=japanese



####型落ちのクリエイター用 10bit 4Kモニタで特攻 そして玉砕

　何故だ


　Windowsが モニタが 対応が と講釈垂れた挙句、問答無用でsRGB（Rec.709）へ減色する Radeon
　ソースが10bitだろうと Rec.2020だろうとお構いなし
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1698056/84c2d60d-12c0-b402-24ca-94654cd5b3c9.jpeg)
　https://pc.watch.impress.co.jp/docs/column/kaigai/734761.html#%EF%BC%93_s.jpg



　SDRモニタに疑似HDR表示する技術デモはどうなった？
![012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1698056/c3d04bfe-ebc9-5265-a7ed-d085344ea099.jpeg)
　https://www.4gamer.net/games/329/G032949/20160629072/screenshot.html?num=012



####オートHDR これが勝利の鍵だ!!

　必要なディスプレイの設定って Rec.2020対応の YCbCrがあるかどうかの確認？


####いいや、HDRだけは確実にしてもらう

　だからHDRって何なのさ？

　広義のHDRは、どうやら複数の要素をパッケージしたものらしい
　・色域（Rec.2020とか）
　・色深度（10bitとか 12bitとか）
　・モニタのバックライト光量（600nitとか 1000nitとか）
　・色域に対応した転送フォーマット（YCbCr？ 要出展）　など

　ゲームを AdobeRGBで表示とか「そんな どこからクレームくるか判らんような真似が出来るか！」
　　っていうのは理解できなくもないが、だからといってsRGB（Rec.709）へ忠実に減色するとか…
　　　もう少しこう 何というか、手心というか…
　
　あと、やはり「YCbCr非対応モニタ死すべし慈悲はない」のだろうか？



####はいはいバロス（ぽちっとな）目がぁ! 目がぁぁぁぁあ〜!

　眩しいじゃねぇかこの野郎ｗ

　劇的ビフォーアフター　sRGBとはなんだったのか？ 
　鮮やかすぎて目が痛いのでモニタ輝度を10％まで落とした

　発色はかなりいい感じになった
　sRGBをガンマ補正で持ち上げたら おかしな色味になりそうだけど、YCbCrは問題無さげ
　ゲーム用途なら十分すぎる

　でもWindowsはモニタをHDRと認識していない
　現在のスキルレベルではモニタのリンクが10bit深度になってるかどうかもわからない
　ひょっとしたら技術デモにあった「疑似HDR」の可能性も否定できない…
　
　
####あとがき

　結局、AMDの説明だけで「OK！ モニタのYCbCrだな」って、読み取れた人いるの？
　　基本ラデ好きだけど AMDは「わかる人にしかわからない」を平然とやってのける
　　　そこにシビれる!​ あこがれないッ!

　なお、HDMIの帯域とか クロマサンプリングとか 今回のやつは全然関係なかった

　追記
　　ドライバ設定の「色温度の制御」を手動で有効にする必要がある
　　　おま環？
ファイル移動・コピーの操作方法（Mac の Finder上）

こんにちは
Mac において、ファイル移動・コピーの方法（Finder上操作）をまとめました。

#### ドラッグ＆ドロップ操作
対象ファイルを選択し、それを移動先のフォルダー上へドラッグ＆ドロップ操作する。

* 同一ディスク（ヴォリューム）内ではファイル移動、異なるディスク間ではコピーとなる。
 * なお同一ディスク内でコピーしたい場合は、```Option``` キーを押しながら操作する。

#### ショートカットキー操作
もしくは、対象ファイルを選択後にショートカットキー操作を利用してファイルのコピーを行いたい場合は、

* ```Command + C```（コピー）を行い、コピー先のフォルダーウィンドウ上で ```Command + V```（ペースト）を行う。
 * なおコピー元ファイルは不要で消去するには（したがってファイル移動）、移動先のフォルダーウィンドウ上で ```Command + Option + V``` を行う[^1]。
* ```Command + D```（複製）を行うと、同一フォルダー内に複製が作られる

##### ゴミ箱への移動
なおゴミ箱への移動は、他に ```Command + deleteキー```（削除）も可能

[^1]: なお Windows OS の場合に、ショートカットキー操作のファイル移動は、対象ファイルを選択後に　```Control + X```（削除）した後に移動先で ```Control + V``` を行います。
flake8の設定をpyproject.tomlに統合する

# tl;dr

* [pyproject-flake8](https://github.com/csachs/pyproject-flake8) を導入する
* vscodeのflake8のパスには **p**flake8 （pyproject-flake8についてくるflake8のラッパー）を指定する

# はじめに：flake8はpyrproject.tomlに対応していない

最近はPEP 518に従い、 `pyproject.toml` ファイルで設定を管理できるPythonツールが増えてきました。

しかしflake8は[pyproject.tomlに対応していません](https://github.com/PyCQA/flake8/issues/234)。

この記事ではflake8の設定をpyproject.tomlで管理する方法を説明します。
また、エディターにVisual Studio Code（以降vscode）を使ったときにうまく動作する方法についても説明します。

# pyproject-flake8を使えばpyproject.tomlで管理できる

## 解決方法：pyproject-flake8を使う

有志が作った[pyproject-flake8](https://github.com/csachs/pyproject-flake8)を使えばpyproject.tomlで管理できるようになります。

pyproject-flake8はflake8のラッパーツールで、flake8の代わりに**p**flake8というコマンドを実行することで、pyproject.tomlからflake8の設定を読み込んでくれます。

## pyproject-flake8のインストール

```bash
# pipの場合
pip install pyproject-flake8

# poetryの場合
poetry add -D pyproject-flake8
```

## pyproject.tomlへのflake8の設定の追加

つぎにpyproject.tomlにflake8の設定を追加します。

```pyproject.toml
...

[tool.flake8]
max-line-length = 88
extend-ignore = "E203,"
max-complexity = 10

...

```

`.flake8` から移行される方はセクション名が `[flake8]` ではなく、 **`[tool.flake8]`** になっていることに注意してください。

指定できる設定ですが、flake8のCLI実行時のオプション名がそのまま指定できます。
例えばflake8では `--max-doc-length 1000` のようにdocの最大長を指定できるオプションがありますが、これをpyproject.tomlで書くと、

```pyproject.toml
[tool.flake8]
...
max-doc-length = 1000
```

のようになります。
[Full Listing of Options and Their Descriptions](https://flake8.pycqa.org/en/latest/user/options.html) を参考に追加してみてください。

## vscodeにpflake8のパスを指定する

さて、ここまででpyproject-flake8のセットアップは完了しましたが、このままではvscode上では有効になりません。

前述のとおり、pyproject-flake8はflake8のラッパーであるpflake8コマンドを実行することで動作します。
よってvscodeがpflake8コマンドを認識するようにしなければなりません。

vscodeで `Code -> 基本設定 -> 設定` を開き、右上あたりにあるアイコン「設定（JSON）を開く」を押してvscodeの設定を開くか、あるいはプロジェクト内でvscode設定を管理されている方は `.vscode/settings.json` を開きます。
そして以下の３行を足します。

```settings.json
{
...
    "python.linting.enabled": true,
    "python.linting.flake8Enabled": true,
    "python.linting.flake8Path": "＜ここにpflake8のパス＞",
...

}
```

`python.linting.flake8Path` にはインストールしたpflake8のパスを指定してください。

たとえばPoetry + pyenvな環境の場合、パッケージはプロジェクト内の`.venv`フォルダー下で管理されることが多いと思いますので、以下のような設定になります。

```settings.json
{
...
    "python.linting.enabled": true,
    "python.linting.flake8Enabled": true,
    "python.linting.flake8Path": ".venv/bin/pflake8",
...

}
```

# おわりに

flake8の設定をpyproject.tomlから読み込む方法を説明しました。

# 2022/01/27追記

pyproject-flake8のアイディア ~~をパクった~~ にインスパイアされた [pyproject-autoflake](https://github.com/quwac/pyproject-autoflake) というパッケージを作りました。
【育児×IoT】ぴよログにワンフレーズで音声入力する方法

#1. 目的
わが家では、育児記録アプリ『ぴよログ』を使って夫婦間の育児の情報共有をしています。
ぴよログには、ミルクをあげた時間や、おしっこ、うんちの回数、睡眠時間などの記録を残すことができます。

ただし、これらの記録を毎回スマホから手入力するのは正直かな〜り面倒です。
また、育児中は両手が塞がってスマホを操作できないことも多く、手が空いたときにあとで入力しようと思っても忘れてしまうこともあります。
そんな時に、ながら操作ができる**『音声入力』**は大活躍します。

例えば、
・哺乳瓶を洗いながら、ミルクの記録をする
・オムツを交換しながら、うんちの記録をする
・洗濯物を畳みながら、前回ミルクをあげた時間を確認する
などなど。

そこで、今回は『ぴよログ』にワンフレーズで音声入力できる便利な方法を解説します。

#2. 設定環境
#####１） 育児記録アプリ「ぴよログ」
iOSバージョン：6.11.5

#####２） スマートスピーカー
デバイス：Google Nest Mini
ファームウェアバージョン：1.54.250118

※アレクサやSiriでも同様の設定は可能です

#3. 運用イメージ
![piyopiyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128340/1fed5fb7-1de6-13cb-eed8-37d6447f348b.png)

#####１） 入力例
「OK,Google! うんちしたよ」 ➡︎ 「14時45分にうんちを記録しました」
「OK,Google! 寝たよ」 ➡︎ 「19時30分に寝るを記録しました」

#####２） 出力例
「OK,Google! 前回のミルクは？」 ➡︎ 「2時間30分前の10時30分にミルク160mlを飲みました」
「OK,Google! 前回寝たのは？」 ➡︎ 「3時間前の19時30分に寝ました」

#4. 設定方法
#####１） ぴよログとGoogleアカウントをリンクさせる

1-1. ぴよログアプリを開く
1-2. メニュー > アカウント > アカウントリンク ➡︎ Googleアカウントをリンクする
1-3. メニュー > 設定 > Googleアシスタント設定 ➡︎ Googleアシスタントを利用する赤ちゃんを選択する

#####２） Google Homeのルーティン機能を使って、ワンフレーズで操作できるようにする

2-1. Googleアシスタントアプリを開く
2-2.［ルーティン］をタップし、［＋］で新規登録をする
2-3.［開始条件］>［音声コマンド］を選択し、操作フレーズ（*1）を登録する
2-4.［操作］>［カスタムアクション］を選択し、ぴよログで定義されたワンフレーズ（*2）を登録する
2-5.［保存］して完了

*1
「うんちをしたよ」「寝たよ」など、言いやすいフレーズを定義しましょう。
言葉揺れがありそうなときは、複数のフレーズを登録しておくと良いです。
「ミルクを飲んだよ」「ミルクをあげたよ」など。

*2
記録用ワンフレーズ：
「ぴよログに寝たことの記録を頼みたい」
「ぴよログに起きたことの記録を頼みたい」
「ぴよログにおしっこの記録を頼みたい」
「ぴよログにうんちの記録を頼みたい」
「ぴよログに両方の記録を頼みたい」

確認用ワンフレーズ：
「ぴよログに最近の食事の記録の確認を頼みたい」
「ぴよログに最近の睡眠の記録の確認を頼みたい」
「ぴよログに最近の排泄の記録の確認を頼みたい」

上記以外にも使えるワンフレーズは少しずつ増えているみたいなので、自分がよく利用する記録、確認フレーズが使えるか試してみると良いでしょう。


##参考サイト
* [Googleアシスタントでの利用方法](https://www.sakabou.co.jp/app/piyolog/google_assistant/)
* [Googleアシスタントヘルプ 日常的なルーティンを手助けしてもらう](https://support.google.com/assistant/answer/7672035)
* [Googleアシスタントを使って『ぴよログ』に一言で記録する方法](https://mochisyufublog.com/piyolog-google-nest-hub)
[正規表現] 全角カタカナあれこれ

# はじめに
入力項目に対するチェックに必ずと言っていいほど出てくる正規表現。

自分自身苦手意識がある部分で何がどうでチェックできるのかさっぱり。
特に全角カタカナに関しては日本人ですら理解しがたい文字がちらほら・・・

そんな自分でもすんなり入ってきた内容に関して備忘録として投稿する。

# よく見る表現とその意味
```
var str = 'カタカナ'
str.match(/^[ァ-ンー　]+$/)
```

**/^[ァ-ンー　]+$/**

ググってよく見る表現が上のモノ。
一体これは何なんだ。
ハイフンで”ァ”と”ン”を繋いでるけどこれ何？
どういう意味？

実はカタカナをUnicode順に並べると下のようになっており、
そして**ァ-ン**、つまりその範囲の中に含まれるすべてのカタカナが対象となるのです！！
特殊カタカナ文字**”ヴ”**などを含めたい場合には**”ァ-ヴ”**と
変えてあげれば**”ヴ”**までの文字を含めてあげることができるのです。

```
ァ, ア, ィ, イ, ゥ, ウ, ェ, エ, ォ, オ, カ, ガ, キ, ギ, ク, グ, ケ, ゲ, コ, ゴ, サ, ザ, シ, ジ, ス, ズ, セ, ゼ, ソ, ゾ, タ, ダ, チ, ヂ, ッ, ツ, ヅ, テ, デ, ト, ド, ナ, ニ, ヌ, ネ, ノ, ハ, バ, パ, ヒ, ビ, ピ, フ, ブ, プ, ヘ, ベ, ペ, ホ, ボ, ポ, マ, ミ, ム, メ, モ, ャ, ヤ, ュ, ユ, ョ, ヨ, ラ, リ, ル, レ, ロ, ヮ, ワ, ヰ, ヱ, ヲ, ン, ヴ, ヵ, ヶ
```

###### では後ろの"ー"と"空白"は？
はい、そうです。それは**伸ばし棒と空白も含めます**という意味になるのです！！
まさかこれでそうなるなんて新米の私にはさっぱりでした。。。
STM32G031とMCP9701で温度を128x32 OLEDに出力 (Arduino)


x MCP9701-E/TO 販売コード 103199

x あまり正確では、ない
x たまにOLEDのリセットに失敗する　全体の電源を数回入れ直す
x UNO と　767違いは、ADCの最大電圧が5V,3.3V
x U8glibとU8g2があるから各自、確認の事

目的
秋月で売っている安価なMCP9701(約25円)を使って温度を出力する。

構成
MCP9701-E/TO I-03199
AL12832AWWB-H-U02 P-14686

説明
説明すると長くなるので各自勝手に調べて
ヒント　MCP9701 AL12832AWWB


![i2c_oled_9701_031_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/91663159-7936-9ef0-11f9-7475d121d536.jpeg)



ArduinoUNOとMCP9701で温度を128x32 OLEDに出力 (Arduino)

https://qiita.com/caa45040/items/c17eb94921878edc47e8

●ぼやき
OLEDリセットには、プルアップは、入っていなさそう
OLED自体がマイコンみたいなものだからジャムると液晶と違い
コマンドを受け付けなくなる
当然、全体の電源投入時にジャムるとその後、うごかない
全体の電源を数回入れ直すと復活する。焦ってびびらないように
OLEDが途中でじゃむっても同じ
ちゃんとした、OLED用にリセット回路を作るか、外部からリセットを
掛けて上げないとだめかも、その為にOLEDのリセット端子が外部に
出ている。



```c++


#include <Arduino.h>
#include <U8x8lib.h>

U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(/* clock=*/ PA9, /* data=*/ PA10, /* reset=*/ U8X8_PIN_NONE);   // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED

int     cursor1;      //カーソルの位置
char    data_read[8]; //i2cバッファー

void i2c_oled_w(char *s)
{
            //文字の表示
            u8x8.drawString(
            ((cursor1-0) & 0x07  )*2, // x
            (cursor1>>3)*2,           // y
            s);
            
            while(s[0] != 0) {
              s++;
              cursor1++;
            }
            
            //cursor1=cursor1 + 3; 
} //i2c_oled_w

//初期化
void setup(void) {

  delay(2000); //oledのリセット時間

  u8x8.begin();

  u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);

  //スタートロゴ
  cursor1 = 0;
  i2c_oled_w("START");
  delay(500);

  //画面の初期化
  u8x8.drawString( 0,0,"        ");
  u8x8.drawString( 0,2,"        ");
  cursor1 = 0;

} //setup

int s;                //ADCの値
int n0;               //温度　小数点以上
int nt[] = {0,2,5,7}; //温度

void loop(void) {

//  //画面の初期化
//  u8x8.drawString( 0,0,"        ");
//  u8x8.drawString( 0,2,"        ");
  //カーソルのクリア
  cursor1 = 0;

  //adcの読み込み 0から4096
  analogReadResolution(12);
  s = analogRead(A9); // PB7 PIN1

  //電圧を温度に変換 ex 20.0 -> 200 温度の十倍を出力
  s=((s*1692)>>12)-205;

  //s=0;   //0    debug
  //s=200; //20.0 debug

  //小数点以上と小数点以下を分ける
  n0=s/10;    // 小数点以上
  s =(s-(n0*10)); // 小数点以下
 
  //画面に表示
  i2c_oled_w("TMP=");
  data_read[0] = '0' + n0/10;;
  data_read[1] = '0' + (  n0-(  (n0/10)  *10)  );
  data_read[2] = '.';
  data_read[3] = '0' + s;
  data_read[4] = 0; 
  i2c_oled_w(data_read);

  //1秒待つ
  delay(1000);
} //loop



```
@ObservedObjectと@Publishedを使ってみた

#はじめに
前回、`@State`と`@Binding`について記事を書いたので、今回は`@ObservedObject`と`@Published`について見ていきます。
`@ObservedObject`と`@Published`を使用することでオブジェクトのプロパティの変化を観測することができます。

#`@Published`
ObservableObjectプロトコルに準するAnimalクラスを作成し、プロパティのkind,name,voiceの値を観測させます。
観測対象のプロパティには`@Published`をつけます。

```swift:Animal.swift

import SwiftUI

class Animal:ObservableObject{
    @Published var kind = ""
    @Published var name = ""
    @Published var voice = ""
}

```

#`@ObservedObject`

観測する対象のオブジェクトに`@ObservedObject`をつけて変数を設定します。

```ContentView.swift
import SwiftUI

struct ContentView: View {
    @ObservedObject var animal = Animal()
    
    var body: some View {
        VStack (alignment:.leading, spacing:15){
            Group{
                TextField("種類",text:$animal.kind)
                TextField("名前",text:$animal.name)
                TextField("鳴き声",text:$animal.voice)
            }.textFieldStyle(RoundedBorderTextFieldStyle())
            Text("\(show(kind: animal.kind, name: animal.name, voice: animal.voice))")
        }.frame(width:200)
    }
    
    func show(kind:String,name:String,voice:String)-> String {
        if !kind.isEmpty || !name.isEmpty || !voice.isEmpty {
            return "\(kind)の\(name)は\(voice)と鳴きます!"
        }else{
            return ""
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

3つのテキストフィールドに入力を行うと、即時画面下部にメッセージが反映されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651213/681605f6-6ea9-79b4-aea7-b8ef2269f90b.png" width=300px> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651213/c2f59ace-0035-9a92-4be0-6d95035398bc.png" width=300px>


#参考
[SwiftUI iPhoneアプリ開発入門ノート](https://www.amazon.co.jp/SwiftUI-iPhone%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80%E3%83%8E%E3%83%BC%E3%83%88-iOS-Xcode-12%E5%AF%BE%E5%BF%9C/dp/4800712793)