OmniAICreator/Qiita-1.07M huggingface dataset:
Swift で LCA: Lowest Common Ancestor（最近共通祖先)

備忘メモ

## NOTE

- 実装：dfs (post-order)
- 問題：https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/

## コード

```swift
func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
  // Return null if not find nodes we are looking for.
  func dfs(_ root: TreeNode?) -> TreeNode? {
    if root == nil { return nil }
    if root?.val == p?.val || root?.val == q?.val { return root } // current is node we are looking for.
    let left  = dfs(root?.left)
    let right = dfs(root?.right)
    if left == nil && right == nil { return nil } // if not find node in children.
    if left != nil && right != nil { return root } // if current is LCA.
    return left == nil ? right : left // return either if one child found node.
  }
  
  return dfs(root)
}
```

## ポイント

dfs がreturnする TreeNode だが、再帰的に呼び出されてる中で途中で意味合いがことなる。それを１つのTreeNodeという表現かつロジックで書いてあるのでやや混乱した。

再帰的に呼び出されてる dfs がreturn する値の意味は下記の２つのどちらかのケースになる。

1. 探し当てた p または q の位置
2. LCA の位置

![TMP-3 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186228/f2c777f9-3f46-943c-43a2-aa5a1b50bdf3.jpeg)

1) の通りp か q のどちらか１つを見つけたなら return するのはその見つけた p か q になるが、2) のようにchildren の両方ともが p と q を見つけてきてる場合はこのノードがLCAになる。なので、そこから上へ渡すのはLCAになる。
JSTQB Foundation Level試験の勉強をして感じたこと

## はじめに
はじめまして、QAエンジニアの大城です。
2021年8月に実施された「第31回　JSTQB認定テスト技術者資格 Foundation Level試験」を受験しました。
今回は受験勉強をした際に感じたことを書いていこうと思います。

## JSTQBとは
>JSTQBとは、日本におけるソフトウェアテスト技術者資格認定の運営組織で、 各国のテスト技術者認定組織が参加しているISTQB（International Software Testing Qualifications Board）の加盟組織として2005年4月に認定されています。
引用元：[JSTQBの概要](http://jstqb.jp/committee.html)

海外でも有効な資格！

## Foundation Levelとは
>Foundation Level資格は、ソフトウェアテストに関与するあらゆる人々を対象にする。Foundation Level資格の対象者には、テスト担当者、テストアナリスト、テストエンジニア、テストコンサルタント、テストマネージャー、ユーザー受け入れテスト担当者、ソフトウェア開発担当者などが含まれる。このFoundation Level資格は、ソフトウェアテストについて基本的な理解を望む方、例えば、プロダクトオーナー、プロジェクトマネージャー、品質管理マネージャー、ソフトウェア開発マネージャー、ビジネスアナリスト、IT部門長、経営コンサルタントのような人にも適切である。
引用元：[ISTQBテスト技術者資格制度 Foundation Level シラバス 日本語版 Version 2018V3.1.J03](http://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018V31.J03.pdf)

ソフトウェアテストに関する基礎的な知識を問われ、ソフトウェアテスト全般に対する理解力が求められる内容となっています。

## 勉強するうえで(個人的に)感じたこと
**最初はとにかくとっつきにくい**
私は5年程ソフトウェアテストに携わっていますがこれまでテスト業務に関する資格勉強などはしておらず、テスト業務に関する知識は実務経験から得るものが大半を占めていました。
テストに関する用語でも現場独自の意味合いで理解していたためJSTQBで定義されている内容とは若干ズレていたり...
自分では理解していると思っていたことと意味合いが異なることが多々あったので困惑しました。

**業務内容についてギャップがある**
先述の内容と少々被りますが、用語の意味だけでなく実務においてもズレを感じました。
これまで自分が総合テスト(システムテスト)として設計・実行してきたテストケースの多くが単体・結合テストの粒度であり、総合テストで見るべきソフトウェアプロダクト全体に観点を向けた検証が希薄になっているので、本来総合テストで求められているテストレベルとズレがあることに気づきました。

**しっかり身に付ければ仕事の幅が広がる**
テスト技法・戦略などの知識を活用できれば、業務を効率的に進めることができるのはもちろんですが、
JSTQBを軸に考えることで、他社の方と仕事する場合や社外セミナーなどの理解向上にもつながると思います。

## 試験内容
試験で出題された中では以下の問題が印象に残っています。
**テスト技法：境界値分析**
一般的な「境界値の範囲に含まれる値と含まれない値を確認する2ポイント境界値分析」の他に、
「境界値とその両隣を確認する3ポイント境界値分析」という考え方があり、どちらの手法をとるかで確認するパターン数が変わってきます。
図解自体はシンプルなものでも、テキストで条件を追加されるため見た目以上に複雑に感じる問題でした。

**テスト手法の違い**
「静的テスト⇔動的テスト」や「ブラックボックステスト⇔ホワイトボックステスト」といったテスト手法の違いや正しい手法について問われる問題が複数出てきました。
単純な問題ですが、用語の意味をしっかり理解していないとこんがらがってしまい間違えてしまうので正解できないともったいない問題です。

## 勉強して良かったこと
業務内容と比較して現状どこまで実践できているのか把握できるようになりました。
JSTQBに基づいたテスト戦略などを取り入れるには少なからず今の業務フローを見直す必要があるのですぐに導入するのは難しい部分もありますが、現状の課題について考える軸が増えたので今後の取り組みをイメージしやすくなりました！

## 最後に
もうじき受験結果が発表されるので、合格した暁にはテスト技法について書いてみようかと思います。

第32回FL試験　申込受付：2021年10月14日（木）15:00～11月30日（火）15:00（予定）
興味のある方はぜひ！
NCMBのSwift SDKにおける非同期/同期メソッドの使い分け

NCMBの操作はREST APIを介して行います。ネットワーク処理ということは、非同期処理であるということです。非同期処理はプログラミングコードが上から下に流れない、コールバック方式になったりするので、意図した動作にならないケースがあるなど、苦労することがあります。

そこでNCMBのSwift SDKでは同期処理のように扱えるメソッドも用意しています。この記事では同期、非同期処理の使い分けを紹介します。

## データを一括で検索する場合

例えばデータストア（クラウドデータベース）からデータを取り出す場合です。非同期処理の場合は次のように書きます。

```swift
query.findInBackground(callback: { result in
    switch result {
        case let .success(array): // 検索成功
            // メモデータを適用
            self.memos = array
        case let .failure(error): // 検索失敗
            print("取得に失敗しました: \(error)")
    }
})
```

これを同期処理で書く場合です。ぱっと見では同期処理の方が分かりやすいです。

```swift
let result = query.find()
if case let .success(array) = result {
    self.memos = array;
}
```

実際の描画される様子です。まず非同期の場合。

![1.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/57a868bf-0dd3-1283-c818-817f87d55a08.gif)


次に同期の場合。

![3.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/4727a415-3f29-0629-1c39-af51167bfe97.gif)


おそらく、どちらも見た目上は変わりません。

## ループ処理の伴う同期、非同期処理

次にデータを取得した後、ファイルストア（クラウドファイルストレージ）から写真データをダウンロードしてグリッドに描画する処理です。この場合、検索結果が6件あれば、6回写真のダウンロードが実行されます。

非同期の場合です。これが6回繰り返されるようなものです。

```swift
// ファイルストア用のオブジェクトを用意
let file : NCMBFile = NCMBFile(fileName: fileName)
// ダウンロード実行
file.fetchInBackground(callback: { result in
    switch result {
        case let .success(data):  // ダウンロード成功
            self.imageData = data
        case let .failure(error): // ダウンロード失敗
            print(error)
    }
})
```

次に同期の場合です。

```swift
// ファイルストア用のオブジェクトを用意
let file : NCMBFile = NCMBFile(fileName: fileName)
// ダウンロード実行
let result = file.fetch()
if case let .success(data) = result {
    self.imageData = data
}
```

同期で処理した場合です。表示までにかなり時間がかかり、一気に表示されます。これはUXがよくありません。

![2.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d928652d-b2ef-d68d-ab7b-674de28aa79d.gif)


## 同期処理の仕組み

同期処理は DispatchSemaphore を使って処理をwaitし、レスポンスが返ってきたら処理を再開しています。基本的に非同期処理の 〜InBackground をラッピングしているだけです。

```swift
public func find() -> NCMBResult<[T]> {
    var result : NCMBResult<[T]> = NCMBResult.failure(NCMBApiErrorCode.genericError)
    let semaphore = DispatchSemaphore(value: 0)
    findInBackground(callback: {(res: NCMBResult<[T]>) -> Void in
        result = res
        semaphore.signal()
    })
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    return result
}
```

このため、ループで同期処理を行うと、1つ目の写真から6つ目の写真まで順番に1つずつ取得する形になります。これだと時間がかかってしまいます。非同期処理の場合はパラレルでダウンロード処理されるので、写真の表示順番は保証されませんが、表示までは高速になります。

## まとめ

同期処理を使うことでコードの見通しは良くなります。JavaScriptのasync/awaitのように使えるので、ぜひ活用してください。ただ、ループ処理中での利用は控えた方が、アプリのUXとして良いものになるはずです。

[ドキュメント : 開発者向けドキュメント | ニフクラ mobile backend](https://mbaas.nifcloud.com/doc/current/#/Swift)
まとめ：達人に学ぶDB設計

[達人に学ぶDB設計](https://www.amazon.co.jp/dp/B00EE1XPAI/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)を読んだので簡単にメモ

## 感想
主に二つ。
1. 正規化は大事！
2. オプティマイザすごいな〜 

## 正規化
正規化に関しては何も考えずにやっていた節がある。
なぜ正規化をするのか？　＝＞　保守性や速度が上がるから
なぜ保守性や速度が上がるのか　＝＞　？？？
と、最も大事な部分で考えるのをやめていたところを例つきで丁寧に教えてくれる。

正規化にも<b>メリット・デメリット</b>あって必ずしも正義ではない。
ただ基本的には
正規化 ＝＞ 非正規化への変更は容易だが
非正規化 ＝＞　正規化への変更は難しいので<b>迷ったら正規化した方が良さそう</b>。

- メリット
    - 変更が容易になる
    - アップデートの速度が上がる

- デメリット
    - 検索速度が落ちる
    - *初めて知ったけど読み取り用のView作れるみたいなのでそっちで解消できそう

### 第1正規化
一つのセルに複数の値を登録しない。(配列型も含めて)
＝＞複数の値が入るとデータを一意に特定できないから。
ちなみにRDBMSを使っているなら、基本的に複数の値を入れれないからあまり考えなくて良い。
*データが一意に特定される制約を主キー制約という。
*主キー制約からデータが一意に定まることを関数従属ともいう。

### 第2正規化
部分関数従属（主キーが複数あるが、一つの主キーに対して関数従属になっている）を完全関数従属にすること。
簡単に言えばエンティティ（実体）ごとにテーブルを分けよう！
主キー制約を守れていないと更新でデータの整合性を担保できないので必須。

### 第3正規化
推移関数従属を解消する。
簡単に言えば一対多のテーブル同士を混ぜると危険！ちゃんと一対一対応で分離させよう。
ざっくりとは第2正規化と同じと感じた。

### その他の正規化
基本的に第三正規化までで大丈夫！
それ以外に第3.5正規化や第4正規化。第5正規化がある。
4,5に関しては多対多のテーブルを中間テーブル使って分離してれば問題ないと思います。

## オプティマイザ
SQLを発行したらどうやってデータを取るかをオプティマイザが考えてくれています。
感謝！

オプティマイザが正しい(＝速度が速い)判断をするには<b>統計情報</b>と<b>インデックス</b>が必要
統計情報に関しては夜間に勝手に更新しているらしいから特に考えなくて大丈夫！

### インデックス
基本B-treeを知っていれば問題ない。
B-treeは平衡木のデータ構造を持つインデックス。
どの根から葉への高さが等しいからO(log(N))の爆速で検索できます。
*長期運用で木が崩れることがあるからその時は木を直してあげる必要あり。

### どんなデータにインデックスを作るべきか
- <b>大規模テーブル（１万件以上）</b>
    - O(log(N))だから小規模にはあまり効果が出ない。
- <b>カーディナリティ（カラムに含まれるデータの種類）が多い</b>
    - インデックスによって5%ほどのデータに絞れるのが理想
    - 範囲が広すぎるとインデックスの意味があまりない。

*インデックスで演算を行わない => 演算後のデータはインデックスに存在しないから。
*データ型合わせる　例'10'と10

### 意外なグレーノウハウ
<b>代理キー(MySQLでいうID列)は使わない方が良い！？</b>
主キーにできる自然キーがあるならそっちを使う。
~~市区町村データの主キーに代理キーを使ってしまった自戒を込めて~~
理由：意味を持たないものだから

ちなみにIDはオートインクリメントなのでロックしている。つまり大量アクセスでは遅くなる。


### チューニング案
<b>暗黙的にソートを実行しているクエリを見直す</b>
重複削除(DISTINCT, UNION)
集約関数(COUNT, SUM, AVG, MAX, MIN)
ORDER BY

<b>インデックスを適切に作る</b>
NULLを入れない
IN => EXISTS
サブクエリを使わない
VScodeでターミナルが開く位置を変更する

#はじめに
最初はpythonの勉強しかしていなかったため、anacondaに入ってたspyderを使っていたのですが、段々とやる言語が多くなってきたためVScodeに移住しました。
実行したときに生成されるターミナルの位置がエディタの下という(自分的には)死ぬほど使いづらい設定になっていたので直しました。

#環境
ChromeOS/crostini(linux)
Visual Studio Code 1.60

chromebookとかいう謎の機体で作業していることは気にしないで大丈夫です。windowsでも全く操作は変わりません。

#実践
![Screenshot 2021-09-17 10.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034739/eeda9a40-ce53-15b5-e715-b40c5c5c6aae.png)
左下の歯車マークを押して
![Screenshot 2021-09-17 10.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034739/2a067e54-2aa9-8bc5-b77a-2883cae7496a.png)
設定を開いて
![Screenshot 2021-09-17 10.29.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034739/c56676cf-b92b-5c9d-17a5-c60f41e35349.png)
検索欄にワークベンチとか入れて__「Panel: Default Location」__の設定を探してください
bottomからrightに変更すれば終了です

__簡単でしたね！__

#余談
検索弱者なのでいろいろ探し回って二時間位浪費しました。
同士が同じ轍を踏まぬように記しておきます。
Swift で Topological Sort（トポロジカルソート）


備忘用のメモ

## Note

- 実装：dfs + Queue (array で擬似的に作成)
- 問題：https://leetcode.com/problems/course-schedule-ii/

## コード


```swift
// prerequisites = [[to1, from1]], [to2, from2], ... [toN, fromN]]
func findOrder(_ numCourses: Int, _ prerequisites: [[Int]]) -> [Int] {
    var graph = [[Int]](repeating: [], count: numCourses)
    var indegree = [Int](repeating: 0, count: numCourses)
    var visited = [Bool](repeating: false, count: numCourses)
    var queue = [Int]()
    var result = [Int]()
    
    // initialize
    for edge in prerequisites {
        let from = edge[1]
        let to = edge[0]
        graph[from].append(to)
        indegree[to] += 1
    }
    for i in 0..<indegree.count where indegree[i] == 0 {
        queue.append(i)
        result.append(i)
    }
    if queue.isEmpty { return [] }

    // algorithm
    while !queue.isEmpty {
        let from = queue.removeFirst()
        visited[from] = true
        for to in graph[from] {
            indegree[to] -= 1
            if indegree[to] == 0 {
                queue.append(to)
                result.append(to)
            }
        }
    }
    
    // guard
    if !indegree.allSatisfy({ $0 == 0 }) { return []}
    if !visited.allSatisfy({ $0 }) { return [] }
    
    return result
}

```
Nuxtでdotenvを使わずに環境変数を参照する時の罠

こんにてぃあ。[もぐめっと](https://mogmet.com)です。

本日はnuxtで環境変数を参照する際にひっかかったのでご紹介します。

## どんな罠？

最近のNuxtはdotenvを使わずとも.envファイルをトップディレクトリに置いていると環境変数を読み込んでくれるようになりました。
しかし、process.env.HOGEとか参照しても値が全然とれないんです。

下記記事によると、RuntimeConfigに定義するという話があります。

https://qiita.com/taai/items/cbc61b9b4a18aacad57e

しかし、これは$configにセットされるようでprocess.envに読み込まれるわけではないです。
私はprocess.envが使いたいんだーーー！

## 解決策

ということで社内で解決策を聞いたらサクッと答えが出ました。

答えは簡単でnuxt.config.jsのenvフィールドに追加するだけでした。

```nuxt.config.js
export default {
  env: {
    HOGE: process.env.HOGE
  }
}
```

これでどこから読んでもprocess.env.HOGEが呼ばれるようになりました。やったね！

## まとめ

process.envをわざわざセットし直すのはなんだか手間に感じますが、nuxt.config.jsでもenvをセットすることで環境変数が使えるようになります！

最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/
C# 囲まれた文字列の取り出し


複数行も可能

```C#
var bb="{{{aiueo}}}".capture(@"{{{", @"}}}"); //aiueo
```

```C#
    public static class RegexStringExtension{
        public static string capture(this string @this, string head, string tail)
        {
            /*usage
            var aa="(aiueo)".capture(@"\(",@"\)"); //aiueo
            var bb="{{{aiueo}}}".capture(@"{{{", @"}}}"); //aiueo
            */
            var p = head + "(.*?)" + tail;
            var ma = Regex.Match(@this, p, RegexOptions.Singleline);
            if (!ma.Success) return "";
            return ma.Groups[1].Value;
        }
    }

```
Qiita記事（Markdown記法）の書き方について

# はじめに
こんにちは、Qiita初心者の[@Suguru-Terouchi](https://qiita.com/Suguru-Terouchi)です。
今回は初めての記事として、Qiitaで記事をアップするために必須スキルである、
Markdown記法について私なりにまとめていきたいと思います。

# Markdown記法
## 　①見出し
    記述方法：# + 半角スペース + 見出し文字
\#は1～6個で少ない程、大きな見出しになります。　※1,2は下線が含まれる
![20210916_0001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1963640/c8706a28-8788-0e75-8c24-d30d01e54e34.jpeg)

## 　②太字/強調
    記述方法：あ__いうえ__お or あ**いうえ**お
アンダーバーかアスタリスクで囲います。
![20210916_0002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1963640/a9191a89-6a70-d463-367b-e171e4ee148c.jpeg)

## 　③Code記法
    記述方法：あ`いうえ`お
バッククォート（Shift + @ キー）で囲います。
![20210916_0003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1963640/cfe02d42-bf79-ae35-392c-a4fbb8fb255c.jpeg)

## 　④外部リンク
    記述方法：[Google先生](https://www.google.co.jp/)
[]で表示したい文字列を記述して、()にURLを記述します。
[Google先生](https://www.google.co.jp/)

## 　⑤pre記法
    記述方法：半角スペース4個+内容
半角スペース4個のあとに内容を記述します。※タブでも可能ですが、Qiitaの場合だとTabキーで投稿ボタンにジャンプしてしまうので要注意です。
##### pre記法サンプル（複数行にまたがる場合は全ての行の先頭に半角スペース4個必要です）

    #include <stdio.h>
    
    main( )
    {
      printf("hello, world\n");
    }

## 　⑥特殊文字の記述
    記述方法：\# 文字
\#等の特殊文字の前にバックスラッシュを記述します。

# 参考にさせて頂いたもの
[Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)

# まとめ
いかがでしたでしょうか。
私自身は今回、初めてMarkdown記法に触れることになりましたが、
先駆者の方々の記事を眺めていても中々、覚えられないので、
やはりまずは下書きで書きながら覚えていくことが大事だと思いました。

今後の活動の中で良く使うMarkdown記法は随時、追記していければと思います。
ご参考になれば幸いです。

# データ活用をサクッと始めるなら！
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください：
 
https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area
[2022年10月版] FreeRTOS Linux（QEMU）デモ

# はじめに

**「LinuxでシンプルにFreeRTOSを体験する」**
これを目的とした記事です（Windows版は[こちら](https://qiita.com/imagou/items/14c0dd69ea28a5446604)）

# 本編

## 環境

- Linux環境
    Ubuntu 20.04 LTSで動作確認

- QEMU
    4.2.1

- ARMツールチェイン
    10.2.1 20201103 (release)

- FreeRTOS 202112.00
    GitHub最新版（執筆現在）

その他は適宜。

## 手順

### QEMU（とmake）インストール

```console
$ sudo apt-get install -y make qemu qemu-system-arm
```

### ARMツールチェインのインストール

```console
$ cd ~
$ curl https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -o gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
$ tar -xjvf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
```

（`curl`にかなり時間が掛かります）

### パスを通す

`~/.profile`を編集、最下部に以下を追加。

```vim
export PATH="$HOME/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH"
```


### GitHubクローン

[Windowsデモ版](https://qiita.com/imagou/items/14c0dd69ea28a5446604#github%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%B3)と同様です。

```console
$ cd ~
$ git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules --depth 1
```

### ビルド

ディレクトリ移動してmakeするだけ。

```console
$ cd ./FreeRTOS/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC
$ make
```

### 実行

以下コマンドで、無事正常動作が確認できます。

```console
$ sudo qemu-system-arm -machine mps2-an385 -monitor null -semihosting --semihosting-config enable=on,target=native -kernel ./build/RTOSDemo.axf -serial stdio -nographic
blinking
blinking
blinking
blinking
blinking
blinking
blinking
blinking
```

## （軽く）解説

2つのタスク生成、その間のキュー送受信でもって、LED点滅を疑似っています。

[main_blinky()](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_blinky.c#L42)が大元の関数ですので、後は煮るなり焼くなりで、知見を深めてください！

# 参考（ネタばらし）

実はここに記載した内容は、[Readme.md](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Readme.md)にすべて書いてあります。


# おわりに

[Windowsデモ](https://qiita.com/imagou/items/14c0dd69ea28a5446604)と同様に、要は

**GitHubからコード取得してビルドして動かすだけ**

です。とてもかんたんなので、何かきっかけ・参考になれば幸いです。
CSS入門(よく目にする、使用するプロパティ)

# 概要
「あのプロパティは、こういう用途の時に使うはず..」となった時の忘備録として概要的な一覧を作成。

# プロパティ一覧
* 汎用的、FlexBox、メディアクエリ...等ざっくりと分類ごとに一覧化しています。
* 随時、更新します。

## 汎用的

| プロパティ　| 概要 | 備考 |
|:-|:-|:-|
| margin | 要素の周りに追加の領域を作成 | inline要素には、上下のmarginが効かない <br> ※家はそのままで土地だけ広げるみたいな |
| padding | 要素の内部に追加の領域を作成 | ※家の中(部屋の広さ)を広げるみたいな |
| text-align  | 水平方向(横方向)の位置を調整  | block要素に有効  |
| vertical-align | 垂直方向(縦方向)の位置を調整  | inline,inline-block要素に有効  |
| text-decoration | 文字の装飾を指定 |   |
| box-shadow | 要素のフレームの周囲にシャドウ効果を追加　|   |
| border-bottom | 下ボーダーのスタイル・太さ・色を指定 | 初期値はnone |
| cursor | マウスポインターが要素の上にいるときに表示されるマウスカーソルを指定  | 初期値はauto |
| border-radius | 要素の角を丸める設定   |   |
| border-bottom-left-radius | 要素の左下の角を丸める設定  |   |
| border-bottom-right-radius | 要素の右下の角を丸める設定  |   |
| white-space   | 要素内のホワイトスペースをどのように扱うかを設定  |   |
| line-height | 行ボックスの高さを指定 | 主にテキストの行間を設定するために使用する |
| font-weight | フォントの太さを指定 |  font-family に依存する |
| opacity | 要素の不透明度を設定 | 当該要素の内容を含む全体に影響する　<br>【0(透明※見えない) < 0.5(半透明) < 1(はっきり)】 |
| transition | 要素の 2 つの状態の変化を定義 | 擬似クラスや、JavaScriptを使用した動的な設定で用いることが多い |
| min-width | 要素の最小幅を設定 | 指定したサイズ以下にはならない！ってこと |
| max-width | 要素の最大幅を設定 | 指定したサイズ以上にはならない！ってこと |
| position | 要素の配置に関する設定 | ・top、bottom、left、rightプロパティで位置を調整 <br> ・親要素は「relative」子要素は「absolute」を指定 |
| counter-reset | カウンター名を指定するとカウンターとして使用できる(連番などに使用) | 初期値はnone |
| counter-increment | カウンタを増加（or減少）させる | 初期値は+1 |
| transparent | 要素を透明にするプロパティ | |
| top | 基準の上から「〇〇px,%..など」の位置に要素を配置 | どこを基準とするかはpositionプロパティで変わる |
| right | 基準の右から「〇〇px,%..など」の位置に要素を配置 | どこを基準とするかはpositionプロパティで変わる |
| bottom | 基準の下から「〇〇px,%..など」の位置に要素を配置 | どこを基準とするかはpositionプロパティで変わる |
| left | 基準の左から「〇〇px,%..など」の位置に要素を配置 | どこを基準とするかはpositionプロパティで変わる |


## flexbox

| プロパティ　| 概要 | 備考 |
|:-|:-|:-|
| flex-direction | 並ぶ方向を指定 | row(横※初期値),column(縦) |
| justify-content | 子アイテム間や周囲への間隔を配置する方法を指定  |   |
| align-items | flexアイテムの縦方向位置を指定 |  |
| order | 子要素の順番を入れ替え | 0から始まる(「0=1番目」「1を指定=2番目」ということ) |

## メディアクエリ

| プロパティ　| 概要 | 備考 |
|:-|:-|:-|
| min-width | 指定した値以上の時に適用させる <br> ※モバイルファーストはこちら | ブレイクポイントとして使用した場合 |
| max-width | 指定した値以下の時に適用させる <br> ※PCファーストはこちら | ブレイクポイントとして使用した場合 |

## 番外編
| 単位　| 概要 | 備考 |
|:-|:-|:-|
| rem | htmlタグの文字サイズから相対的に指定できる単位| htmlタグに「font-size: 62.5%」と指定しておくと、ブラウザのデフォルト設定の場合は文字サイズが10pxになる |
MinIOの管理画面にアクセスすると別ポートにリダイレクトされる件の解消

下記のようにdocker-compose.ymlに記載して、DockerCompose環境でMinIOを使おうとしました。

```yml:docker-compose.yml
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
    volumes:
      - ./.docker/minio/data:/export
    environment:
      MINIO_ACCESS_KEY: ${AWS_ACCESS_KEY_ID}
      MINIO_SECRET_KEY: ${AWS_SECRET_ACCESS_KEY}
    command: ['server', '/data']
```

`http://localhost:9000`にアクセスしても、なぜか別ポートにリダイレクトされてしまいました。

![スクリーンショット 2021-09-17 8.48.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329420/67e5ca8e-c18b-7f2d-e111-71e914a7ef66.png)


調査に時間がかかってしまい完全にハマっていたのですが、ふと`docker-compose up`した時のログを見てみると、

```
WARNING: Console endpoint is listening on a dynamic port (35135), please use --console-address ":PORT" to choose a static port.
```

リダイレクトしてしまうポート番号に一致する番号が書かれてる！

[こちらの記事](https://qiita.com/potdig/items/601aa883d87efbbbdc65)が大変参考になったのですが、どうやらMinIOの仕様変更で、`--console-address`オプションをつけて起動しないと、ポートが動的に設定されるようになったのだとか。
古い記事を見ながら手探りで構築していたのでハマってしまったようです。

下記のようにdocker-compose.ymlを書き換えることで解決しました。

```yml:docker-compose.yml
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - ./.docker/minio/data:/export
    environment:
      MINIO_ACCESS_KEY: ${AWS_ACCESS_KEY_ID}
      MINIO_SECRET_KEY: ${AWS_SECRET_ACCESS_KEY}
    command: ['server', '/data', '--console-address', ':9001']
```

普段`docker-compose up -d`していたせいで、ログが見つけづらい状況で開発していたのも調査に時間がかかった原因です。
普段からログ出しとく癖は必要ですね、という学びを得ました。
SQL文のDELETEで全件削除とTRUNCATEの違い

DELETEとTRUNCATEの違いをメモ

| | DELETE | TRUNCATE |
| :--- | :---: | :---: |
| 削除スピード | 遅い | 速い |
| 削除条件 | 可能（WHERE句） | 不可能（全件削除） |
| SQLの種類 | データ操作言語（DML:Data Manipulation Language） | データ定義言語（DDL:Data Definition Language） |
| 権限 | DELETE権限 | DROP権限 |
| 注意点 | 処理を確定するためにはCOMMITが必要でROLLBACKで戻すことも可能 | 実行前に暗黙的にCOMMITがかかる。実行後にCOMMITは不要でROLLBACKで戻せない |

## DELETE文
```sql
DELETE FROM テーブル名;
```

## TRUNCATE文
```sql
TRUNCATE TABLE テーブル名;
```
【UNIX】ファイル時刻の取得

# 環境
- Debian GNU/Linux 10

# ①ファイルの最終アクセス時刻の取得

```bash
$ ls -lu
total 4
-rw-r--r-- 1 root root 9 Sep 17 08:19 hoge
```

# ②ファイルの最終修正時刻の取得

```bash
$ ls -l
total 4
-rw-r--r-- 1 root root 9 Sep 17 08:19 hoge

# ファイル書き込み
$ echo "hogehoge" > hoge

# 修正時刻が更新
$ ls -l
total 4
-rw-r--r-- 1 root root 9 Sep 17 08:43 hoge
```

# ③iノード状態の変更時刻の取得
(iノードはUnix系ファイルシステムで使われるデータ構造。ファイルの属性情報が書かれている。)

```bash
$ ls -lc
total 4
-rw-r--r-- 1 root root 9 Sep 17 08:19 hoge

# ファイル権限を変更
$ chmod 777 hoge

$ ls -lc
total 4
-rwxrwxrwx 1 root root 9 Sep 17 08:49 hoge
```

# 参考URL
- https://ja.wikipedia.org/wiki/Inode
- https://wa3.i-3-i.info/word14802.html
- https://e-words.jp/w/inode.html
- https://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/atime%2Cctime%2Cmtime%E3%81%AE%E5%8F%96%E5%BE%97%E3%83%BBls%2Cstat
APEXテストクラスでdatetime.now()の検証

#標準項目【成年月日(CreatedDate)】の場合
apexクラスでオブジェクトのdatetime項目にdatetime.now()を挿入した場合検証
オブジェクトの項目【成年月日(CreatedDate)】の場合、テストクラスの[setCreatedDate](https://developer.salesforce.com/docs/atlas.ja-jp.200.0.apexcode.meta/apexcode/apex_methods_system_test.htm#apex_System_Test_setCreatedDate)使用してください。

#カスタム項目の型が【日付/時間】の場合
カスタム項目の型が【日付/時間】の場合、salesforceシステムのリソース状況により実際テストクラス走行時間も変わりますため、、直接equal検証する方法がないですが範囲検証できます。一定範囲内で収める方法です。(beforce<=datetime.now<=after)

###【注意】
オブジェクトに挿入する際にミリ秒をクリアされるため(beforce.getTime()-1000<=datetime.now.getTime()<=after.getTime())
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2025198/055f54f3-72ac-a5c5-0a3e-9bdd86396e11.png)


#実際テストクラスの書き方

```
long before = datetime.now().getTime()-1000;
DataCreate data = new DataCreate ();
Test.startTest();
data.DataInsert();
Test.stopTest();
list<TEST__c> t = [select id,name,datetime__c from TEST__c];
long after = datetime.now().getTime();
 System.assertEquals(true, before <=t[0].datetime__c.getTime() &&
                               t[0].datetime__c.getTime()<=after);
```
SwiftUIのデータ管理についてのお勉強〜値型編〜

# 本記事について
SwiftUIのデータ管理についてのアウトプットやメモの共有です。
本文に載っているコードは、説明用であり、コピペでは動かないためご容赦ください。

## 前提
順番は違うが、過去にObservableObjectについて調査したため、今回は値型の場合に扱うProperty Wrappersについて調査する。
https://qiita.com/Fuyan777/items/d79eef243e2ded33780e

## SwiftUIのデータ管理におけるProperty Wrappers
改めて再確認...
Property Wrappersの利用方針があり、大きく3つである。

- データは何か？
  - SwiftUIでは値型、参照型のデータを扱うProperty Wrapperが存在
- データをどのように処理するか？
  - 読み込みか、変更もあるのかでデータの扱いも変わる
- データはどこから来るか？
  - View自身から発生、親Viewから渡される、環境値として渡されるのか

### @State
データが値型、データの更新、データの発生源がView自身の場合は@Stateを利用

```swift
struct ParentView: View {
    @State private var countNum = 0

    var body: some View {
        Button(action: {
            counter += 1
        }, label: {
            Text("count: \(countNum)")
        })
    }
}
```

### @Binding
データが値型、データの更新、データの発生源は親Viewなど外から渡される場合は@Bindingを利用

```swift
struct ParentView: View {
    @State private var countNum = 0

    var body: some View {
        ChildView(counter: $countNum)
    }
}

struct ChildView: View {
    @Binding var countNum: Int

    var body: some View {
        Button(action: {
            counter += 1
        }, label: {
            Text("count: \(countNum)")
        })
    }
}

```

# 終わりに

今回は以下の記事を参考に学習しました。
https://blog.personal-factory.com/2020/11/14/publish-swiftui-catalog-book/

ぜひ、参考にしてみてください。
【AWS】Certbotでhttps化後、504 Gateway Timeoutになってしまうバグの解消

#対象者

* Certbotを使用してhttps化した方
* https接続した際に504 Gateway Timeoutと表示される方

#目的

* 504 Gateway Timeoutのバグを修正してブラウザにアクセスする

#前提

下記の記事をもとにしています。

https://qiita.com/nao0725/items/eaa15aff215aa3265c63

#実際の手順と実例
###1.結論

**キャッシュが溜まっていたせいでhttps接続できていなかった。**

というめちゃくちゃ単純なバグだったのですが、
結構ハマったので記事にしてみました。


###2.原因

ページが表示されず、しばらくするとブラウザに504 Gateway Timeoutと表示されてしまう。

そもそも、504 Gateway Timeoutとは下記の通りです。
> HyperText Transfer Protocol (HTTP) 504 Gateway Timeout サーバーエラーレスポンスコードは、サーバーがゲートウェイまたはプロキシとして機能しているときに、リクエストを完了するために必要な上流のサーバーからのレスポンスが時間内に得られなかったことを示します。

https://developer.mozilla.org/ja/docs/Web/HTTP/Status/504


https化しているのになぜhttp接続を試みているのか。
原因としてはサーバーのキャッシュが溜まりすぎていて、
なかなか接続できずに、httpを探しにいってしまったから。

キャッシュとは

> ブラウザが一度表示したWebページのデータを保存しておいて、次に同じページを表示する際、一度目より素早く表示してくれる仕組みのことです。

下記の記事を参考にさせて頂きました。

https://digitalidentity.co.jp/blog/seo/seo-tech/cash-speed-up.html

###3.解決策
３通りあります。
1. シークレットウインドウで開く
2. キャッシュとクッキーを削除
3. 別なWebブラウザで開く

2.でChrome使用中の方は下記を参考にするとできます

https://support.google.com/accounts/answer/32050?hl=ja&co=GENIE.Platform%3DDesktop

Chromeを使用している方はSafariやFirefoxを使用するとうまくWebサイトが開けるかもしれません。


#参照

* [キャッシュと Cookie の消去](https://support.google.com/accounts/answer/32050?hl=ja&co=GENIE.Platform%3DDesktop)
* [キャッシュとは？Webサイト高速化にかかせない機能をご紹介！](https://digitalidentity.co.jp/blog/seo/seo-tech/cash-speed-up.html)
* [504 Gateway Timeout - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Status/504)
UIScrollView　Swift

UIScrollViewの使用方法(storyboard)


①UIscrollViewをviewControllerに配置する。
![スクリーンショット 2021-09-17 8.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/5a681c49-d521-9bf8-c08b-2ae6ad7b1e93.png)

②Autolayoutを上下左右すべて０にする
③UIscrollViewの上にViewを配置する（背景色を変えるとわかりやすいかも）

![スクリーンショット 2021-09-17 8.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/f19523fd-0340-cd81-7caa-53b31fe6bba3.png)

④配置したViewとUIScrollviewをCmd押しながら同時選択して、右下のAdd New Aligment Constraintを選択してLeading Edges,Trailing Edges,Top Edges,BottomEdgesをすべて０に設定する
![スクリーンショット 2021-09-17 8.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/adc391ff-9c12-4ff4-4049-5bd6009a6040.png)

⑤viewからScrollViewの下にあるFrame Layout Guideに対してcontrolキーを押しながらドラッグアンドドロップをして、Equal Widthを選択する
⑥置いたviewのheightの制約をかける。その制約の分スクロールするようになる。
Windows10でインストールされているアプリ一覧を出力する

## Windowsをクリーンインストールしてから今の状態に戻したい

こういう時期なので、わたしはそう思った。実際に作成したドキュメント類は別ドライブにあるので関係ないし、日常的に使うモノは大体覚えているが、念のために出力しておこうとした。面倒なのでそういうコマンドがないかなと探したら、あった。やはり世の中の面倒事の解決方法は大抵調べれば見つかるのだ。人間関係以外。

### [2021/09/17 09:50] windowsストアアプリについてさらに追記

### PowerShellコマンドで収集する

`Get-ItemProperty`というものを使うと良いらしい。以下に書いてあった。
[Windows10でインストール済みアプリの一覧をコマンドで収集する方法](https://4thsight.xyz/26528#PowerShell%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E5%8F%8E%E9%9B%86%E3%81%99%E3%82%8B)

### そしたら実行結果をログファイルに出力したい

俺の性であり世の常である。もちろん、PowerShellで可能なのは間違いなさそうなので探したらすぐ見つかった。

```PowerShell
Start-Transcript （出力ファイル名）
```
パスの指定もできる模様。また、以下のコマンドを打つまでの表示が保存されるようだ。

```PowerShell
Stop-Transcript
```

## まとめ

PowerShellでこうする。

```PowerShell
Start-Transcript （出力ファイル名）
Get-ChildItem -Path('HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') | % { Get-ItemProperty $_.PsPath | Select-Object DisplayName, DisplayVersion, Publisher }
Stop-Transcript
 ```

俺の忘備録として書いておく。ところでこれ、ストアアプリ入ってるのかな？

---

## 追記

ストアアプリは入っていない模様。こちらもこれから調べる。-> 調べた。

### ストアアプリのインストール情報

レジストリの、
`HKCU:Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\`
にあった。

しかしこれを

```PowerShell
Get-ItemProperty "HKCU:Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\*" | Select-Object DisplayName, PackeageID | Format-Table –AutoSize
```

で出力すると、@で始まるシステム的なものまで列挙されるのであまり使い勝手が良くない。よって、

```PowerShell
Start-Transcript （出力ファイル名）
Get-ChildItem -Path('HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') | % { Get-ItemProperty ($_.PsPath),("HKCU:Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\") | Select-Object DisplayName, DisplayVersion, Publisher }
Stop-Transcript
```

で出力すると、要るのか要らないのかわからないファイルまででてくるので困った。あとなぜか出てこないアプリもある。助けて有識者！
Visual Studio CodeでEnter押すと候補が入力されてしまう

#VSCodeで入力中に補完機能が発動してちょっとうざい

VSCodeの設定を変えることでEnter押下時に候補が入力されることがなくなりました。

設定＞テキストエディター＞候補
「Accept Suggestion On Enter」をoff
Fluter それ誤解？Futureを即時関数などで済ませようとする罠

こんにちは。Flutterでは切っても切り離せないFutureのお話。

世界中の老若男女が考えるであろう、

「Futureめんどいから、もうそのまま実行してくれね？」

という願望。私も常々そう思い、ことある毎にGoogle巡礼しています。その中でよく目にする、即時関数やその他その場で実行している感のあるスクリプト。

用途によっては全然良いのですが、場合によってはやばいかも知れません。

## 前置き。awaitできないケース

色々ありますが、例えばコンストラクタではawait出来ません。




## やっちまったCase1: Futureの中でasync awaitする

次の例を見てください。

```dart
main() {
  Future(() async {
    await Future.delayed(Duration(seconds: 1));
    print("future");
  });
  print("now");
}
```

私は最初これを見た時、歓喜に打たれてオレンジジュースを飲み干しました。Futureめんどい問題が見事に解決されている、awaitも入っているので、きっとfutureが先に出力されて、その後にnowが来るだろう。そう思ってオレンジジュースを注ぎました。実際に動かしてみると、結果は次のようになります。

```dart
now
future
```

なぜでしょう。

### 原因

Futureに渡している関数自体はasyncです。これは非同期ですので、実装は知りませんが、概念的には別スレッドで飛び立って、残されたスレッドは粛々と次の作業に移るわけですね。この非同期を繋ぎ止めるのがawaitですが、このスクリプト、awaitはasyncの中にしかありません。つまり別スレッドとして飛び立ったあと、その中でawaitしているわけです。これでは、普通の非同期と変わりありませんね。


## やっちまったCase2: 即時関数でやっちまう

次の例を見てください。

```dart
main() {
  () async {
    await Future.delayed(Duration(seconds: 1));
    print("future");
  }();
  print("now");
}
```

```dart
now
future
```


これも同じです。即時関数ですぐに実行しているので、非同期から解放されて地に足のついた感がありますが、実はまだ非同期です。先程と同様、awaitが中に入っているだけですので、即時関数自体は非同期になっています。

## 終わりに

いかがでしたでしょうか。ちなみに私はFlutter赤ん坊ですので、間違いなどあるかも知れません。ご指摘いただけましたら幸いです。

以上です。
WSL2上で動くUbuntuのプロンプトにGitブランチ情報を表示する

こちらの記事を参考にさせていただきました

https://qiita.com/varmil/items/9b0aeafa85975474e9b6

```shell
vi ~/.bashrc
```

```~/.bashrc
if [ "$color_prompt" = yes ]; then
        PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(\__git_ps1)\$ '
else
        PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(\__git_ps1)\$ '
fi

・・・（省略）

GIT_PS1_SHOWDIRTYSTATE=true
#GIT_PS1_SHOWUPSTREAM=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWSTASHSTATE=1
```

- `PS1`の設定箇所に`$(\__git_ps1)`を追加します
- `GIT_PS1_SHOW～`で編集時の表示オプションを指定できます

↓のような感じで表示されます

```shell
{user}@{machine}:{dir} (master)$
```

# オプションの説明

`GIT_PS1_SHOWDIRTYSTATE`を指定すると、を変更ファイルが存在する場合に`*`が表示されます

```shell
(master *)$
```


`GIT_PS1_SHOWUNTRACKEDFILES=1`を指定すると、追加ファイルが存在する場合に`%`が表示されます

```shell
 (master %)$
```

`GIT_PS1_SHOWSTASHSTATE=1`を指定すると、`git stash`している場合に`$`が表示されます

```shell
 (master $)$
```
vectorについてまとめてみた（つもり）

![IMG_20210816_143641.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293580/58b0f524-7692-663e-50bf-6905704fefd1.jpeg)
詳しい説明はYouTubeでやってます。
https://youtu.be/cLNHhTprpHE
間違いやご指摘、感想等お待ちしてます！
基礎から学ぶReact/React Hooks学習メモ 6-1 環境構築とアプリ作成準備

# 6-1 Create React AppでReact開発環境を準備する

参考
[基礎から学ぶReact/React Hooks](https://www.amazon.co.jp/dp/B09CP8T4TX)

## Create React Appの実行

```sh
# nodeのバージョン確認
node -v
# yarnのインストール
npm install -g yarn
# アプリケーションを作成したディレクトリに移動して、create-react-app プロジェクト名
npx create-react-app todo-app
# 作成されたディレクトリに移動
cd todo-app
# アプリ起動
yarn start
```

## Visual Studio Codeを利用する

- インストーラーをダウンロード&インストール

## 不要ファイルの削除と修正

```
todo-app/
┣ node_modules/
┣ public/
┣ src/
┃ ┣ App.css  ← 削除
┃ ┣ App.js
┃ ┣ App.test.js  ← 削除
┃ ┣ index.css  ← 削除
┃ ┣ index.js
┃ ┣ logo.svg  ← 削除
┃ ┣ reportWebVitals.js  ← 削除
┃ ┗ setupTests.js  ← 削除
┣ .gitignore
┣ package.json
┣ README.md
┗ yarn.lock
```

```js:App.js
function App() {
  return <p>これからTODOアプリを実装します！</p>;
}

export default App;
```

```js:index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/f2e47768-d4da-d980-d3ef-db37a76e7a6b.png)

## ToDoアプリの仕様

- TODOを完了／未完了別にリスト化して表示
- TODOの追加ができる
- TODOの状態（完了／未完了）をボタンクリックで変更できる
- TODOの削除ができる
- モックサーバーでTODO情報を更新管理できる

## モックサーバーの準備

```js:db.json
{
  "todos": [
    {
      "id": 1,
      "content": "Create react appをインストールする",
      "done": true
    },
    {
      "id": 2,
      "content": "JSON Server仮のAPIを作成する",
      "done": false
    },
    {
      "id": 3,
      "content": "Chakra UIをインストールする",
      "done": false
    }
  ]
}
```

- ポート3100番で起動

```sh
npx json-server --watch db.json --port 3100
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/a5442ea7-fa62-7c66-4ba9-ffb1d23d6f17.png)

## axiosのインストール

```sh
yarn add axios
```

- axiosの使用例

```js
const todoDataUrl = "http://localhost:3100/todos"
// axios.get(URL)でgetリクエスト送信
axios.get(todoDataUrl)
```

## ulidのインストール

- ユニークなIDを付与するために、ulidをインストールする。ソート可能でランダムなIDを生成する。

```sh
yarn add ulid
```
Material-UI V5(MUI)へのマイグレーション

# はじめに
ちょっと前からMaterial-UI使っているので浅い知識で色々試行中ですが・・・
v5が2021/09に正式リリースになったので、マイグレーションしてみました。

# v5機能
[MUI Versions](https://mui.com/versions/)に記載があります
[リリースノート](https://github.com/mui-org/material-ui/releases/tag/v5.0.0)によると

* npmで200M DL/月→ 950M DL/月
* コントリビューターは600人以上

この数字はv4→v5の1年間での成長だと思いますが、エコシステムとして順調に成長している感じですね。
個人的には色々コンポーネント試用しましたが、直感的で使いやすいと感じていますし、
ドキュメントも充実していて十分業務でも使えます。

https://deploy-preview-27912--material-ui.netlify.app/blog/material-ui-is-now-mui/
パッケージ見ればわかりますが名称が「MUI」ですね
ロゴも変更されてます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786643/779b9f5c-9686-15e8-55b6-679633c0e070.png)


# v5へのマイグレーション
実装量も少ないので、[移行ガイド](https://next.material-ui.com/guides/migration-v4/)に従ってやってみました。
手修正な部分もありますが基本は「@mui/codemod@next」でマイグレーションできます。

基本的なコンポーネントは互換性があるように見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786643/bbb9336b-6ab4-b42f-3a77-6ac22489ff09.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1786643/553bd220-7e36-9f73-d58c-753bd5bf382b.png)


スタイル周りで非互換や非推奨がありそうですが、まずは移行させて動作確認してを繰り返しですかね？
まだ新しいコンポーネントなどは試していませんが。今後試していきたいと思います。
[Python]FastAPIのチュートリアルをやってみた

タイトルの通りですが、[FastAPIの公式ドキュメント](https://fastapi.tiangolo.com/ja/)にチュートリアルがあったので、一通りやってみました。

私自身は最近プライベート([Pythonチュートリアルをやってみた](https://qiita.com/momonoki1990/items/b85b2b8d006084184449))や業務でPythonを触り始めたばかりで、Pythonのフレームワークを扱ったことはありません。

Pythonのフレームワークといえば、DjangoやFlaskというイメージでしたが、「自動ドキュメント生成機能がすごいらしい」と聞いて気になっていたので、FastAPIを触ってみることにしました。

## FastAPIとは

[Python 製 Web フレームワークを Flask から FastAPI に変えた話](https://note.com/navitime_tech/n/nc0381517d067)

[[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する](https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9)

私も詳しくないのでこちらのふたつの記事を参考にさせていただいたのですが、Flaskに似たマイクロフレームワークで、Pythonで最近サポートされた機能(型ヒントなど)を生かしてOpenAPI(Swagger)仕様のAPIドキュメントを自動で生成する機能を持っています(APIを実装するだけで下記のドキュメントが自動で生成され、ブラウザでアクセスできるように)

<img width=400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555201/6c5264b1-f5e4-899b-f0d5-5ceebf0c92af.png">


また、ドキュメントが充実していて、チュートリアルとAdvanced User Guideの目次を一覧するだけでも、APIとして必要な機能が網羅されているのがわかります。

<img width=200" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555201/b4cf61a8-a20d-6e8f-0458-f28445ccc882.png"><img width=200" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555201/7108f2b6-a4bf-6d0b-19fe-1732d7c2ac67.png">

さらに、APIの書き方も直感的で、公式の[代替ツールから受けたインスピレーションと比較](https://fastapi.tiangolo.com/ja/alternatives/#requests)によるとPythonの標準モジュールであるRequestsから影響を受けているとのことです。

>使い方はとても簡単です。例えば、GETリクエストを実行するには、このように書けば良いです:
`response = requests.get("http://example.com/some/url")`

>対応するFastAPIのパスオペレーションはこのようになります:
```@app.get("/some/url")
def read_url():
    return {"message": "Hello World"}
```

他にも、Pydanticという型バリデーションライブラリを含んでいて、リクエスト・レスポンスのバリデーションを標準で効かせられたり、Starletteというフレームワークの`TestClient`を使うことで、テストの中で簡単にリクエストを再現できます。

```
from fastapi import FastAPI
from fastapi.testclient import TestClient

app = FastAPI()


@app.get("/")
async def read_main():
    return {"msg": "Hello World"}


client = TestClient(app)


def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}
```


## チュートリアルをやってみた感想

所要時間は20時間でした。私はPython自体初学者で、本なども読むのが遅い方なので時間がかかった方だと思います。

https://twitter.com/momonoki1990/status/1430859900331065345

まずチュートリアルの説明がめちゃくちゃ丁寧です。

チャプターごとにサンプルコードに記載してある内容を一つ一つ説明してくれますし、Pythonの基本用語まで備考として説明されていました。

また、認証に関してはトークンの扱いなど、APIを構築する上で必要な知識を含めて説明されていました。

ドキュメントが充実していて、公式サイトも見やすく、また、FastAPI自体が直感的にAPIを記述できるようになっているので、軽量で扱いやすいフレームワークであるという印象を受けました。

ただ、チュートリアルの半分くらいが日本語の翻訳がされておらず英語のままなので、Dependenciesなどフレームワーク独自の考え方の部分は、さすがに理解度が落ちました😅

[翻訳に参加もできるようです](https://fastapi.tiangolo.com/contributing/)
(気になるなぁ。。。)

なんか作ってみようかな！
【Laravel基礎】リレーション

#はじめに#
　Laravelでリレーションはちょっと特殊な書き方をします。備忘録として残しておきます。　
　雑多なメモ書きという感じですがご容赦ください。

#Laravelでリレーション#
　Laravelのリレーションはモデルに書くことで定義できます。
・１対１
・１対多
・多対多
この３パターンで書き方が異なってきます。

#１対１#
　例えば、ケータイは基本的に一人につき一つです。（複数台持ちはここでは無視してください。）
まずはテーブルを作ります。
![スクリーンショット 2021-09-16 23.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/de338b66-56a1-a0a5-0ee5-e2b5e3356c7f.png)

![スクリーンショット 2021-09-16 23.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/77e3eab6-602a-d24c-2502-998aad4849c8.png)
phoneテーブルには外部キーであるuser_idを持たせています。そしてモデルで下記のように定義します。

```User.php
 public function phone(){
   return $this->hasOne('App\Models\Phone');
 }
```

```Phone.php
 public function user(){
   return $this->belongsTo('App\Models\User');
 }
```

これで１対１のリレーションをはることが出来ました。


#1対多#
　１対多の場合も基本的な考え方は変わりません。
例えば、SNSの投稿機能などでは、ユーザー一人につき投稿は複数あります。
まずはテーブルを作成します。

![スクリーンショット 2021-09-16 23.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/de338b66-56a1-a0a5-0ee5-e2b5e3356c7f.png)
![スクリーンショット 2021-09-16 23.26.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/f959d808-6ef7-8ba7-40f9-b7ee0f590ee1.png)

やはりpostsテーブルには外部キーであるuser_idが必要です。
モデルは下記のようになります。

```User.php
 public function posts(){
   return $this->hasMany('App\Models\Post');
 }
```
```Post.php
 public function user(){
   return $this->belongsTo('App\Models\User');
 }
```
このように書きます。

#終わりに#
これで、userを取得してそれぞれで定義したメソッドを使えばリレーション関係にあるphoneやpostsを引っ張ってくることが出来ます。
　多対多はまた少し違うので今回は割愛します。←
【React】コンポーネントのメモ化で怒られる / ESLint: Component definition is missing display name(react/display-name)

# はじめに
コンポーネントのメモ化を試みたところESLintで怒られた、のでその時の対処法。
[メモ化](https://qiita.com/tkmd35/items/065b0ec0d187723ffe14)

```ts
memo(コンポーネント);
```

「コンポーネントの定義に表示名がない」と言われている

```
ESLint: Component definition is missing display name(react/display-name)
```

開発環境でのデバッグ時に、複数のコンポーネントが存在する場合エラーメッセージからのデバッグが難しくなってしまう。
ということがあってこのように怒られるらしい。

https://stackoverflow.com/questions/41581130/what-is-react-component-displayname-is-used-for


# サンプルコード
怒られる

```ts
// ESLint: Component definition is missing display name(react/display-name)
export const Foo: React.VFC = memo(function foo() {
  return <div>memoサンプル</div>;
});
```

# 解決策
## 無名関数から普通の名前付き関数にする
```ts
export const Foo: React.VFC = memo(function foo() {
  return <div>memoサンプル</div>;
});
```

## ESLintを部分的に disable にする
```ts
// eslint-disable-next-line react/display-name
export const Foo: React.VFC = memo(() => {
  return <div>memoサンプル</div>;
});
```

# 最後に
ESLintの設定でそもそも回避できると思いますが、そこまで調べられておらず。
Patch、Hotfix、Upgradeの違いを3000字以内で説明する (Software versioning)

その界隈の用語の整頓です。

## Patchとは

https://en.wikipedia.org/wiki/Patch_(computing)

https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%83%E3%83%81

> コンピュータにおいて**プログラムの一部分を更新してバグ修正や機能変更を行う**ためのデータのこと。「修正プログラム」や「アップデート（プログラム）」などとも呼ばれる。実際に変更を施す際は「パッチを当てる」、「パッチを適用する」と言う。

### Software Updateとは

https://en.wikipedia.org/wiki/Update

> Patch (computing), also known as a software update

ということでPatchのこと。

https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88



### PTFとは

https://e-words.jp/w/PTF.html

> PTFとは、IBM社が顧客に配布している、同社製ソフトウェアの不具合を修正するプログラム。個々の問題に対処する「個別PTF」と、それらを集めて一つにまとめた「グループPTF」、ある時点までのPTFを集積した「累積PTF」などの種類がある。

https://en.wikipedia.org/wiki/Program_temporary_fix

> (翻訳)
> IBM の用語で、プログラムの一時的な修正プログラムまたは製品の一時的な修正プログラム（PTF）は、日付によって異なる場合がありますが[1][2]、お客様がすぐにインストールできる形で配布される単一のバグ修正プログラムまたは修正プログラムのグループです。

> 通常、PTFはAPAR（Authorized Program Analysis Report[3]）に続いて発行され、「APAR修正プログラム」が発行された場合、PTFは「テストされたAPAR」[4]またはAPAR修正プログラムのセットとなります。しかし、APARが「Fixed If Next」や「Permanent Restriction」として解決された場合、それを修正するPTFは存在せず、後続のリリースのみとなることがあります。

https://www.ibm.com/support/pages/ptfs-faqs-question-and-answers

> (翻訳)
> Q1: PTFとは何ですか？累積パッケージとは何ですか？
> A1: PTFとは、ライセンスされたプログラムの現在の未変更のリリースの不具合に起因するとIBMが診断した問題に対する一時的な解決策または回避策です。累積(Cumulative)PTFパッケージは、特定のリリースの一般的なシステム集団に影響を与えるPTFを含んでいます。


### Patch Tuesdayとは

https://en.wikipedia.org/wiki/Patch_Tuesday

> (翻訳) パッチチューズデー（Update Tuesday）とは、マイクロソフトやアドビ、オラクルなどが自社のソフトウェア製品のパッチを定期的にリリースする際に使われる非公式の用語。 マイクロソフトは2003年10月にパッチチューズデーを正式に制定した。 パッチチューズデーは、マイクロソフト社内では「B」リリースとも呼ばれており、第3週目と第4週目にそれぞれ行われる「C」「D」リリースと区別されている。

> マイクロソフトは、偶数月に多くのアップデートをリリースし、奇数月には少なくするというパターンを持っている。マイナーアップデートは、パッチチューズデー以外にもリリースされる。毎日のアップデートは、Windows DefenderとMicrosoft Security Essentialsのマルウェアデータベースの更新。また、通常のパッチチューズデーの2週間後に臨時のパッチチューズデーが開催されることもある。一部のアップデートはいつでもリリースされる可能性がある。


## Hotfixとは

https://en.wikipedia.org/wiki/Hotfix

https://ja.wikipedia.org/wiki/%E3%83%9B%E3%83%83%E3%83%88%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9

> ホットフィックス (hotfix, hot-fix) とは、**ソフトウェア製品において製造元がバグを修正した際に、ユーザへ修正版を提供する形態のひとつ。特に迅速性を重視した形態である。**QFE (Quick Fix Engineering) もほぼ同じ意味の用語で、こちらはマイクロソフト製品で使われる。

> オペレーティングシステム (OS) やソフトウェアに、セキュリティ上の脆弱性などの深刻な不具合や、ユーザーにとって重大な不具合が発見された場合、製造元より緊急に提供される修正プログラム・修正モジュールである。


## Upgradeとは

https://e-words.jp/w/%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89.html

https://e-words.jp/w/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3.html

> **製品を改良し、バージョンを更新、増加させること**をバージョンアップという。和製英語であり、英語では一般的には “upgrade” という。

端的には「バージョンアップ」。


## まとめ: Software versioning

https://en.wikipedia.org/wiki/Software_versioning

https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3

> ソフトウェアは、単一の製品を一度だけ出荷して終了することは比較的少なく、最初の出荷時の製品に含まれていた不具合を取り除いたり、新たな機能を追加したり、既にある機能を改良したりして、そのたびに以前とは異なる版の製品を出荷することがよく行われている。このような時系列による違いを明示することで、流通や利用段階での混乱を避ける目的で、主たる製品名に「バージョン」や「リリース」、「リビジョン」という形での付加的な名称を加えている

ということで、Patch、Hotfix、Upgrade 3者を区別しつつも、さらに微妙な呼び名の変化系が多数ある。開発者と非開発者等など、会話相手との理解差で気をつけなければいけない場面もある。参考になればさいわいです。
typescriptでdoenvを使うときのメモ

dotenvを使って環境変数を使えるようにする

## ライブラリーをインストール

```jsx
npm install dotenv
```

## `.env`  ファイルを作り環境変数の値を設定する

```jsx
#DB_HOST="localhost"  #はコメントアウト

SESSION_SECRET="secret"
TOKEN_SECRET="secret"
```

## ルートファイル( 今回は`index.ts` )でインポートする

```jsx
// jsならしたのように
require('dotenv').config()

// tsならしたのように書けば使える
import 'dotenv/config'

// 使用例
const * as db = import 'db'
db.connect({
  host: process.env.DB_HOST,
  username: process.env.DB_USER,
  password: process.env.DB_PASS
})
```
Typescriptとexpress.jsの環境設定

## 目標

- expressでtypescriptを導入する
- tyepescriptでバックエンドを書く

## 目的

- typescriptの学習
- typescriptを使った環境設定

## 手順

1.環境の確認

```jsx
$ node -v
v16.5.0

$ npm -v
7.19.1
```

2.ワーキングディレクトリーを作成

```jsx
$ mkdir project_name
$ cd project_name
$ npm init
```

3.typescriptのインストールと設定

```jsx
$ npm install -g typescript
$ tsc --init
```

`tsconfig.json` でnodeを使えるようにする

```jsx
// コメントアウトをはずす
"moduleResolution": "node",

"outDir": "./dist", // 出力先を指定する
"rootDir": "./src", //もとのファイルを指定する
```

4.expressをインストールする

expressをtypescriptで使うためのライブラリーも一緒にダウンロードする

```jsx
$ npm install --save express
$ npm install -D @types/express
// nodeをtypescriptで使うためのライブラリーも追加
$ npm install -D @types/node

```

`index.ts` にサーバーを立上げるコードを書く

```jsx
import express, { Request, Response, NextFunction } from 'express'

const app = express()

// /にアクセスが有るときの処理
app.get('/', (req: Request, res: Response) => {
  res.json('Hello World')
})

// エラー処理
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  res.status(500).json({ message: err.message })
})

app.listen(3000)
```

5.ts-nodeを使って開発の効率を上げる

```json
// ホットリロードをするためのライブラリーも追加
$ npm install -D nodemon ts-node
```

現在はts→js→nodeになっている。

それをts→nodeとできるようにts-nodeをライブラリーを追加する

`package.json`に以下のコードを追加して自動で更新されるようにする

```json
"scripts": {
    "start": "nodemon --watch './**/*.ts' --exec ts-node src/index.ts"
  },
```

これでターミナルに `npm start`とホットリロードができるようになる。 

`[localhost:3000](http://localhost:3000)` にアクセスすると

> Hello Wold

がかえってくる。

## 参考


[TypeScript + Node.js プロジェクトのはじめかた2020 - Qiita](https://qiita.com/notakaos/items/3bbd2293e2ff286d9f49)

[TypeScript - Use Nodemon to Restart Your Server on Changes](https://futurestud.io/tutorials/typescript-use-nodemon-to-restart-your-server-on-changes)
Dart　ファイル内に「_」プライベートなんて無い話

スコープはとても大事なわけです。

Dartは通常、変数の前に「_」（アンダーバー）を入れると、ローカル変数とみなされると言われています。私もそれを信じて、今まで生きてきました。関数も同様です。具体的には、



```dart
{
  int _iyann= 0 ;
}
```

は、カッコ外から参照できないと思っていたんですね。ところが、事実は違います。


## Dartのプライベート事情

次のコードを走らせます。

```dart
class Human {
  int _sumikko = 1;
  int oppiroge = 2;
}

main() {
  Human taro = Human();
  print(taro.oppiroge); //2がプリントされる
  print(taro._sumikko); //1がプリントされる
}
```

お分かりいただけたでしょうか？このように、Dartにおけるプライベートなんてあったもんじゃありません。

以下の質問でも書かれています。

https://stackoverflow.com/questions/17488611/how-to-create-private-variables-in-dart

引用
>Every Dart app is a library, even if it doesn’t use a library directive. The >import and library directives can help you create a modular and shareable code >base.

ライブラリとしてなら、プライベートとして機能すると言うことですね。つまり先程のコードを分割して、

```dart:human.dart
class Human {
  int _sumikko = 1;
  int oppiroge = 2;
}
```

```dart:main.dart
import "human.dart";
main() {
  Human taro = Human();
  print(taro.oppiroge); //2がプリントされる
  print(taro._sumikko); //Error
}
```

となるわけです。ファイルスコープのみというわけでしょうか。

以上です。
TWRPでError: 7が出るときに試してみる事

#ERROR: 7
先ほど出たエラー名でググってみたものの情報が少なかったので(基本すぎて？)共有しようと思いました。

```
mkdir "/cache/recovery/2bdde85..../"
failed: No space left on device
E1001: Failed to update system image.
Updater process ended with ERROR: 7
Error installing zip file '/sdcard/TWRP/lineage17.zip'
```
上記のエラーがlineageをtwrpでインストールしようとしたところ出ました。
ストレージに十分スペースは空いています。

#解決策

cacheとdalvik-cacheをwipeしたのち再度インストールを試みたらエラーは出なくなりました。


#環境
- Lenovo Z5ProGT
- Lineage-17.1
- TWRP-3.3.1-1004
 
#最後に
今後同じエラーに遭遇した方の解決時間短縮に貢献できれば幸いです。
rememberLazyListState の仕組み

## 疑問

次のコードは、表示されている要素のインデックスの中で最も小さいものをログに出力するコードです。出力されるタイミングは値が変わったとき、つまり一方向にゆっくりと `64dp` スクロールしたときです。私の環境では `1dp = 2.75px` であるため、`176px` 毎に出力されることになります。

```kotlin
data class Data(val id: Int)
val data = (1..1000).map { Data(it) }

@Composable
fun MainScreen() {
  val state = rememberLazyListState()
  Log.e("TAG", state.firstVisibleItemIndex.toString())

  LazyColumn(Modifier.fillMaxSize(), state = state) {
    items(data, key = { it.id }) {
      Box(Modifier.border(1.dp, Color.Black).fillMaxWidth().height(64.dp))
    }
  }
}
```

それに対して次のコードは、`1px` スクロールするたびに出力されます。

```kotlin
data class Data(val id: Int)
val data = (1..1000).map { Data(it) }

@Composable
fun MainScreen() {
  val state = rememberLazyListState()
  // ここだけを書き換えている
  Log.e("TAG", state.firstVisibleItemScrollOffset.toString())
  
  LazyColumn(Modifier.fillMaxSize(), state = state) {
    items(data, key = { it.id }) {
      Box(Modifier.border(1.dp, Color.Black).fillMaxWidth().height(64.dp))
    }
  }
}
```

私の感覚では、`state` 変数のプロパティの一部だけを参照していようとも、`1px` スクロールする毎に `firstVisibleItemScrollOffset` の値が変わるのだから `state` 自身が変更されると思ってしまいます。しかし実際はもっと賢くて、`firstVisibleItemIndex` だけを参照しているときは `176px` 毎に再描画が走ってくれます。`firstVisibleItemScrollOffset` が変更されているにも関わらず。

## 答え

`rememberLazyListState` の実装を読むと答えは単純でした。この関数は `State#value` を返すのではなく、`State#value` をプロパティに持つ `State#value` でないオブジェクトを返していました。つまり、`state.firstVisibleItemIndex` や `state.firstVisibleItemScrollOffset` は `State#value` ですが、`state` は `State#value` ではありませんでした。

## 終わりに

参照しているプロパティが変更されたときだけ再描画が行われるので、「スクロールするたびに再描画が走るので `rememberLazyListState` を使うことは避けよう」と思わなくていいとわかり、安心しました。