OmniAICreator/Qiita-1.07M huggingface dataset:
SEとして一ヶ月本気で働いてみて思ったこと

# Tech企業の就業型インターンシップに参加

一ヶ月の間、平日週5回毎日朝から夕方までフルタイムでTech企業でシステムエンジニアとして働いて思ったことをとにかく書き下していく。いろいろ思い出したり感じたことがあれば随時更新していく。大切なのは経験をストックして次に活かすことである。
また、みなさんの体験談やアドバイス、感想も聞きたいのでぜひ気軽にコメントしてくれると嬉しい、です。

## 概要
・Javaを使って社内システムの開発
・学生同士のペアで社員に混ざり働く
・スクラム開発（二週間ごとに課題を決めて毎日報告）
・20出勤8時間労働（えぐい）

## 学んだこと
### 開発者としての意識
何年も使えるコードを作る。
メンテナンスのしやすさや他人が見やすいか。
ー＞　**コードは個人のものではなく会社のもの！**

研究もkaggleも個人開発のためファイル名とか関数名とか雑なことが多かったけど、これでは他の人が見た時何をしているのか一切わからない。**会社のものを共同で作り上げていく**という意識がとても大切。何千行とかのコードだって平気であるし、その中から一つの関数を修正する必要がある場合にわかりやすい名前じゃないと詰む可能性だってある。あと数年前とかのコードって今動かせって言われても微妙だったりするからね。そんな時もメンテナンスがしやすいコードにするべきだなあとしみじみ思ったわね。
これからの開発ではディレクトリの階層構造やファイル名、コメントアウト、空欄とか全部考えていく。

### バックログを明確に
多分これが一番苦労したし一番重要だと思うこと。
序盤には「え、俺今何してるの」と思う瞬間がかなりあった。なぜこのようなことに陥るのかというとタスクの優先順位がしっかり設定できていないからである。これができていれば、「何のために何をしているのか」がはっきりし、コーディングを進めることができる。。これは研究など普段の生活でも役立つだろう。とてもいいことを学ばせてもらった。

脳のリソースは無限じゃないしなんなら自分はその容量が小さいほうだと思う。
だからこそ外部記憶装置（ノートとかnotion）を使って実装に集中できるようにする。
**タスク管理はマジでめちゃくちゃ大切**。



### スーパーフレックスすごい

その企業はコアタイムが存在せず会議さえなければもういつでも働いていいという環境だった。遅刻しないのはでかいけど自己管理が大切でしっかり仕事できる人でないと難しいという印象。実際若手だと在宅より出社メインで周りと合わせて仕事をする人が多かった。

### ペアプロの良し悪し

基本的に学生二人で作業をする形だった。何度か意見が分かれる時があり、その時いつも自分は折れる側だった。そうすると自分のほうが正しかったり、より良い提案であったこともあり、もっと主張したほうが良かったのかなと思う。ここで自分が折れる側だったのは自信のなさが原因だろう、**もっと技術力や知識があれば明確な理由を添えて提案ができた**、まだまだ足りないことだらけだと思った。

ネガティブなことが続いたがここで良かった点。
それはお互いの良さを引き出せること。自分の良さはコードのレビューで相方はコーディングの素早さだった。これはうまくマッチしてタスク完了まで全然時間がかからなかった時もあった。だんだんお互い理解していったので後半は基本的にスムーズだった記憶。

### バージョン管理

システムというのは常に新しくなっていく必要がある。メンテナンスがしやすいようにgitで枝分かれしまくってそれぞれのブランチでなにをしたというのをはっきりさせなくてはならない。プルリクエストの書き方も大切！

コンフリクトとかなるべく避けるためにチーム内でも今それぞれがどのようなことをしているのかは常に共有必須（そのために会議中も積極的に雑談をしていて面白いと思った）。

### 質問について
わからないことをそのままにしておくのが一番ダメ。それは分かっているけど、やっぱり社員の手を煩わしていまうのも申し訳ないし、、。ってなったためそれを聞いた。社員の返答としては、

・ 社員も自分もお金が発生している中で働いている
・ 質問しないでわからないままだと学生の時間が勿体無い
・ すぐ質問しても社員の時間が勿体無い

つまり、学生が1時間考えるものを社員は5分で解決できるかもしれないし、学生自身で　15分で解決できることもある。そこの見極めが大切であるということ。googleの15分ルール(まずは自分で調べて15分経ってもわからなかったら人に聞くルール)は理にかなっているのだなあと改めて実感した。

そして**質問の仕方も大切**。「〇〇ができません」は最悪。理想は「現在の目標が〇〇であり、そのために〜〜を試みているのですが、XXの部分でエラーが出てしまいすすめません。自分としては〜。」と言ってエラー文を見せること。メールの場合は事実を箇条書きにしてその下に自分の思っていることを書く形がいいだろう。

## 結論
### 開発は楽しい
チームで目標を決めて作業するのはやりがいがあった。動いた時の感動はやっぱこれでしか味わえない。しかも今回のシステム開発はチーム独自で考え実行したもの。
自分達が提案して実際にその開発を行うことができるって素敵、、、

ただ、当たり前だが自分の軸は明確にするべき。
**それは本当にしたいことなのか**
妥協はなるべく避けたい。ただ就活は無理を通せるものでもない。結局自分と各企業を比べて自分のしたいこと、したくないことが叶えられるのかを調べまくるのが最適な方法だと思われる。企業同士を比べるのは本当に最後の最後のような気がする（人生の先輩方教えて笑）。

俺の場合システムエンジニアも楽しかったけどデータサイエンティストも捨て難い、、、
DSとしてもどこかのインターンに参加したい。

んで働くってマジで大変。
社会人の人たちへのリスペクトがさらに高まった。シンプル体力持たない。でもめちゃくちゃ超絶ハイパーいい経験だった。


---
# 追記

Qiita週間トレンドにランクイン！！！！！
もうね、めちゃくちゃうれしいですねこれ
なんとなくで始めたQiitaですけどやっぱ見ていただけるならもっと頑張りたいと思います
これからもうどんをよろしくお願いします！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3444528/e42c7c6c-3568-f770-a20e-de01b5515e02.png)
冪等性とは？

# 冪等性とは

ある操作を何回実行しても結果が同じであるという性質。

# 冪等性を保つ実装例

## 簡単な例

* クライアント側 : ボタンの複数クリック防止
* サーバ側 : 重複リクエストの解決

基本的にサーバ側で冪等性が保証されていると、より堅牢であるといえる。

## 障害復旧のケース

処理1で障害が発生したら、中間データを削除して再度処理1を行う(左図)。これを冪等性を保つようにするには、右図のように障害発生時に関わらず、中間データを削除する仕組みを処理1に含めればよい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/6898d46e-a9ea-c29f-4504-c2d7915a2e1c.png)



# マイクロサービスやサーバーレスでの冪等性


## サーバーレスとマイクロサービスはなぜ冪等性が必要？

* 一つの処理単位が小さく独立している

以下の図のようにモノリスアプリケーションの場合はDBトランザクションの原子性によって、整合性が保たれる。それに対して、マイクロサービスは複数のマイクロサービスによって、1つの業務トランザクションが成り立つ。ゆえに、エラーやリトライの処理が複雑になってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/de9221a3-c89e-3927-8edc-f5ea6c1d7127.png)

* リトライが自動で実行される
AWSのlambdaなどではリトライが自動で実行される。

# ステートレスと冪等性

## ステートフルとステートレス

* ステートフル : 記憶を使って判断する。1回目と2回目のレスポンスが異なる可能性がある。
* ステートレス : 記憶を保持しない。常に同じレスポンスを返す。

![スクリーンショット 2023-09-09 17.17.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/4ab8e443-c1b8-d79e-88ca-bb396eea5707.png)


|            | ステートフル           | ステートレス        |
| ---------- | -------------------- | ----------------- |
| **スケーラビリティ** | 低い         | 高い              |
| **データ保持**  | サーバー側         | クライアント側   |
| **フェイルオーバー** | 同期難しい   | 問題少ない        |
| **レスポンスの最適化**    | ○     |  ×  |
| **処理効率**    | 高い | 低い |

ユーザ数やデータ量が増える場合があるなら、個々の処理のベストなレスポンスを求めるよりも、スケーラビリティの高いステートレスの方が向いている。


## ステートレスの実現

ステートレスを実装するには外部DBなどにステートをデータとして保持すれば良い。
ただし、内部に保存する場合よりレスポンスに影響が出る、処理コードの複雑になる可能性がある。

## 早すぎる最適化は諸悪の根源

ドナルド・クヌースの論文 [Computer programming as an art](https://dl.acm.org/doi/10.1145/361604.361612) に **早すぎる最適化は諸悪の根源** という言葉がある。

内部でステートを保持したほうが効率的に思えるが、ある一時点での局所的な最適化を求めることは必ずしも良いことではない。ステートレスであることは、冪等性の確保、スケーラビリティや可用性の向上などの利点がある。

# 冪等性の実装方法

最も簡単に冪等性を担保する方法の一つがデータにユニークなIDを付与することである。
何を一意な値にするかは注意が必要。例えば、webショッピングで購入確定時に処理を呼ぶような場合、`セッションID`は一意な値ではない。同じセッションで複数回の購入を行う可能性がある。購入処理のタイミングで`セッションID+タイムスタンプ`で一意の値を生成する。

## 入力時チェック方式

データストアへの登録時にチェックする
1. ユニークなID(冪等キー)を引数として受け取る。
2. データストアへ格納時に、DBで一意性チェックを行う。
3. 一意性チェックでエラーが出たら、複数回実行されたとみなし、例外処理でログに残し、正常終了。
4. ログを定期的に監視する。本来エラーにすべきでないデータ投入処理がエラーになっていないかを確認する。
5. 処理Xは、DBで一意性チェックエラー発生時、複数回の実行を検知し、ログにエラー情報を記録して正常終了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/616d3b37-6ce1-46d0-434e-5b7cb03bedd5.png)

## 出力時チェック方式

データストアからの取得時にチェックする

1. 一意の値を引数として受け取る。
2. データストアへの格納では、重複チェックをせず、全データを格納するようにする。
3. データストアからの読み取り時に、重複を排除して取得する (SQLのDISTINCT句を使用するなど)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/7d52fd8e-abb0-1e78-7168-4b03b02d0e59.png)

# 最後に

冪等性とは外側から見た性質である。上記で2つの実装方法を挙げたように、内部的な実装は関係ない。APIを使う側から、冪等かどうかを考えればよい。また、冪等性が保たれていても、異常終了した際には、整合性が損なわれる。ゆえに、ログ監視などはしっかり行うことが重要である。

# 参考文献

[Tech Talk vol.2 Backend Engineer 〜マイクロサービスの冪等性〜 を開催しました](https://engineering.mercari.com/blog/entry/2019-12-20-123549/)
[サーバーレスが気になる開発者に捧ぐ「べき等性」ことはじめ](https://aws.amazon.com/jp/builders-flash/202104/serverless-idempotency/?awsf.filter-name=*all)
[実践 Microsoft Microservices](https://zenn.dev/tatta/books/4e993c596e7dc9/viewer/83e94d)
競プロ初心者の挑戦日記①

# 概要
競技プログラミングの初心者が、コンテストに参加した記録です。
問題を回答するにあたって、使用する言語はPythonです。
自力で実装できないものは潔く諦めます。

# 対象コンテスト
AB問題のみ解けました。

https://atcoder.jp/contests/abc322

## [A問題](https://atcoder.jp/contests/abc322/tasks/abc322_a)
所要時間：４分
特定の文字列が現れる最初のインデックスを出力する問題です。
単純にfindして結果を出力しました。
```python
n = int(input())
s = input()

index = s.find('ABC')
if index == -1:
    print(index)
    exit()

print(index+1)
```


## [B問題](https://atcoder.jp/contests/abc322/tasks/abc322_b)
所要時間：７分
与えられた文字２つから、接頭語と接尾語が一致しているかどうかを判別する問題です。
こちらも単純に、関数で接頭語と接尾語をチェックして出力。
```python
n, m = map(int, input().split())
s = input()
t = input()

st = t.startswith(s)
en = t.endswith(s)

if st and en:
    output = '0'
elif st:
    output = '1'
elif en:
    output = '2'
else:
    output = '3'
    
print(output)
```

## [C問題](https://atcoder.jp/contests/abc322/tasks/abc322_c)
所要時間：２１分（LTEで回答失敗）
全ての日数の最大値と特定の日数リストが与えられ、全ての日ごとに、特定の日数までの間隔を出力する問題です。
問題を理解するのに苦戦しました。

サンプルは次のコードで通りましたが、数値が大きくなるとダメですね。
```python
n, m = map(int, input().split())
a = list(map(int, input().split()))

for i in range(1, n+1):
    if i in a:
        print(0)
        continue
    
    next = 0
    for day in a:
        if i < day:
            next = day
            break
        
    print(next - i)
```

### C問題提出コードの問題点

#### リスト内の存在チェック
次のコードが遅すぎた。
```python
if i in a:
    print(0)
    continue
```

#### 特定の日数リストの全件ループ
力技の解決策に頼った結果。
ループでの検索は極力避けるべきですね。
```python
next = 0
for day in a:
    if i < day:
        next = day
        break
```

### C問題の改善後コード
二分探索を使用して、コード内の検索を高速化しました。
```python
n, m = map(int, input().split())
a = list(map(int, input().split()))

def binary_search(a, x):
    left = 0
    right = len(a) 
    
    while left <= right:
        mid = (left + right) // 2
        if x > a[mid]:
            left = mid + 1
        else:
            right = mid - 1
    return right + 1

for i in range(1, n+1):
    index = binary_search(a, i)
    print(a[index] - i)
```

# 反省
C問題を提出してLTEを食らった時、二分探索が必要なのかなと思って諦めてしまいましたが、他の人のコードを見ていると、カウンタ（？）を更新して特定日を取得している人が多かったです。
これであれば既存の知識でも回答が可能だったかなと。
もう少し粘るべきでした。１つの考えに囚われるのは良くないですね。
Javaでコンパイル時に「エンコーディングwindows-31jにマップできません」が発生

# エラー内容
javaの実行の際にエラーが発生したので対処方法をまとめておきます。

コマンドプロンプトからコンパイラ時に以下のようなエラーが発生しました。

```
C:\JavaBasic\03>javac Sample0301.java
Sample0301.java:3: エラー: この文字(0x86)は、エンコーディングwindows-31jにマップできません
                System.out.println("Java縺ｮ荳也阜縺ｸ縲√ｈ縺?縺薙◎");
```

Sample0301.javaの中身は以下の通りです。
```Sample0301.java
class Sample0301 {
	public static void main(String[] args) {
		System.out.println("Javaの世界へ、ようこそ");
	}
}
```

# エラーの対処方法
コンパイラでの実行の際に[-encoding UTF-8]を追記したところ無事解決しました。
以下のとおりです。
```
C:\JavaBasic\03>javac -encoding UTF-8 Sample0301.java
```
エラーが発生しなくなりました。
Reactのフック（useEffect,useLayoutEffect,useReducer,useMemo,useCallback）

# はじめに

* useState、useContext以外の重要なフック群。
* useEffectとuseLayoutEffectはコンポーネントのライフサイクルに組み込まれており、特定のタイミングで初期化やアンマウントなどを行える。
* useMemoやuseCallbackはパフォーマンスチューニングで使用する
    * ただし、ロジックが複雑になるので乱用はしないこと
* useReducerはuseStateの更新部分を抽象化する。

# useEffect

* 副作用となる処理を記述する
    * 副作用は描画の一部ではない処理
    * コンポーネント描画後に行われるので、非同期処理等（API）
* 依存配列
    * 副作用が実行される条件を記述する
    * 記載しない場合、再レンダリングの度に実行される
    * 空配列の場合、初期描画時のみ実施
* 戻り値
    * コールバック関数を返すことで、アンマウント時の処理を行える
```javascript
  useEffect(() => {
    console.log('再レンダリング時実行');
  });

  useEffect(() => {
    console.log('初期化時');
    return () => console.log('アンマウント時');
  }, []);

  useEffect(() => {
    console.log(`val変更時: ${val}`);
  }, [val]);
```

# useLayoutEffect

* useEffectよりも前に呼び出される
    * useEffectは、画面描画後だが、useLayouEffectは画面描画前
    * 画面描画前に取得したい情報：画面サイズやマウス座標等を取得する際に利用する

* 以下、マウス座標を取得するフック関数

```typescript
import { useLayoutEffect, useState } from 'react';

export const useMousePosition = () => {
  const [x, setX] = useState(0);
  const [y, setY] = useState(0);

  const setPosition = ({ x, y }) => {
    setX(x);
    setY(y);
  };

  // 初期化時、アンマウント時のイベントリスナー
  useLayoutEffect(() => {
    window.addEventListener('mousemove', setPosition);
    return () => window.removeEventListener('mousemove', setPosition);
  }, []);

  return [x, y];
};

```

```jsx:利用
export const Render = () => {
  const [x, y] = useMousePosition();
  return (
    <>
        <span>{`x:${x},y:${y}`}</span>
    </>
  );
};
```

# useMemo

* 依存配列が配列やオブジェクト等の参照値だった場合、その値を変更しても同一だとみなされず、毎回レンダリングされてしまう。
* その場合、useMemoを使用する

```javascript
const words = useMemo(() => childeren.split(' '), [childeren]);

useEffect(() => {
    console.log('fresh render');
}, [words]);
```

# useCallback

* useMemoと同様の機能で、関数の場合はこちら

```javascript
  // 初期化時のみ
  const fn = useCallback(() => {
    console.log('function!');
  }, []);

  useEffect(() => {
    console.log('rendaring');
    fn();
  }, [fn]);
```
# useReducer

* useStateのかわりに使用する。戻り値にstateの初期値と、更新関数を返す。
* stateの更新ロジック定義時に記載することで抽象化できる。

```diff_typescript:state→reducerへ
// state
-export const Numbers = () => {
-  const [number, setNumber] = useState(0);
-  // useStateの場合、更新ロジックは使用する際に記載する。
-  return <h1 onClick={() => setNumber((number) => number + 1)}>{number}</h1>;
-};

// reducer
+export const Numbers = () => {
+  // reducerの場合、定義時に記載する。
+  const [number, setNumber] = useReducer(
+    (number, newNumber) => number + newNumber,
+    0
+  );
+  return <h1 onClick={() => setNumber(1)}>{number}</h1>;
+};
```

# フック関数の注意点

* コンポーネント内、またはカスタムフック内で呼び出すこと
* 関数のトップレベルから呼び出す
    * 条件文や、ループ、ネストした関数では呼び出さない
    * やりたい場合は、フック関数内で行う
Rails7 リファクタリング ポリモーフィックな参照を持つレコードの新規作成を共通化する


This article shows how to make a common code to create records when using Polymorphic Associations

## 環境情報＆前提条件
* Ruby 3.2.1
* Rails 7.0.0

## 実装したい内容
* ポリモーフィック関連を使用して複数のテーブルへの参照を1カラムで定義する。
* SNSアプリを作成する上での通知機能の実装を想定する。UserモデルとPostモデルに参照を持つNotificationモデルのレコードを作成する。
* NotificationモデルはPostレコードに対していいね(Like)、コメント(Comment)、リポスト(Repost)された際に作成されるものとする。
* ポリモーフィックなカラムとしてNotificationテーブルには`action`カラムを定義する。

関係するアソシエーションを下記する。
```rb:notification.rb
class Notification < ApplicationRecord
  belongs_to :user
  belongs_to :action, polymorphic: true
end
```

```rb:user.rb
class User < ApplicationRecord
  has_many :notifications, dependent: :destroy
end
```

```rb:post.rb
class Post < ApplicationRecord
  belongs_to :user
end
```

```rb:like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post
  has_one :notification, as: :action, dependent: :destroy
end
```

```rb:comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post
  has_one :notification, as: :action, dependent: :destroy
end
```
```rb:repost.rb
class Repost < ApplicationRecord
  belongs_to :user
  belongs_to :post
  has_one :notification, as: :action, dependent: :destroy
end
```

## 実装手順
* `action`カラムをポリモーフィックにした場合、migrateした際に`action_type`カラムも自動生成される。
* `action_type`にはModelのクラス名を入れないとエラーになる。そのため、Likeモデルの場合は`'Like'`という文字列を設定する必要がある。

* いいねをした際（Likeレコード作成時）の通知レコードの作成は以下のように書ける。
```rb:like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post
  has_one :notification, as: :action, dependent: :destroy

  # 以下を追記
  after_create :create_notification

  private

  def create_notification
    Notification.create(user: post.user, action: self, action_type: 'Like' )
  end
end
```

* また、各レコード作成時の通知レコード作成処理は以下のように書ける。Likeモデルと同様に各モデルの中に処理を記述することを想定。
```rb
# いいねをした際（Likeレコード作成時）の通知レコードの作成
Notification.create(user: post.user, action: self, action_type: 'Like' )
# コメントをした際（Commentレコード作成時）の通知レコードの作成
Notification.create(user: post.user, action: self, action_type: 'Comment' )
# リポストした際（Repostレコード作成時）の通知レコードの作成
Notification.create(user: post.user, action: self, action_type: 'Repost' )
```

* 上記の３つはほとんど同じ処理なのでを共通化したい。差分は`action_type`に設定されている文字列のみ。
  * `self.class.name`とすることで、各モデルのインスタンスのクラス名を取得することができる。このメソッドを使用する。
* `action_type`に設定する内容を変更して共通化すると以下のように書ける。
```rb
# いいね、コメント、リポスト全てに対応した通知レコードの作成処理
Notification.create(user: post.user, action: self, action_type: self.class.name )
```

* この処理を使用して、Likeモデルを変更すると以下のようになる。
```rb:like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post
  has_one :notification, as: :action, dependent: :destroy

  after_create :create_notification

  private

  # 以下を変更
  def create_notification
    Notification.create(user: post.user, action: self, action_type: self.class.name )
  end
end
```

* しかし、このままでは複数のモデルに同じ`create_notification`を記述することになる。リファクタリングとして中途半端な状態になる。
* そのため、共通化した`create_notification`メソッドをモジュールとして切り出して更に共通化する。
  * 続きのリファクタリングは、以下の記事を参照ください。
  * [Rails7 リファクタリング 複数Modelで共通した処理をModuleに切り出す](https://qiita.com/KOH6/items/679426ca5a7d523caafd)
RESTの返却ページ上限を限界突破する方法

# はじめに

SymbolではブロックチェーンのデータにREST API経由でアクセスを行います。
そのREST APIが初期で返せるデータのMax件数は100件となっています。
これは、ノードの設定ファイルをいじることで増やすことができます。
この記事では、このREST APIの返却上限を100以上に引き上げるノードの設定を紹介します。


# 対象読者

この記事では自力でSymbolノードを構築したことがある人を対象としています。
ノードの設定ファイルを編集しますので、記事で紹介している値以外を下手に編集してしまうと最悪ノードが起動しなくなってしまう可能性があるのでご注意ください。（とはいえ、設定ファイルのバックアップを取っておくか、upgradeコマンドを実行すれば初期化されるのでそこまで気にする必要はありません）

Symbolノードの構築方法はこちら

https://symbol-community.com/ja/docs/5


# 現在のノードが返すページ上限を確認

　```https://自身のノード名:3001/mosaics?pageSize=1000```

pageSizeを1000と指定してREST APIを叩くと、以下のようにpageSize100と返ってくると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/aaeb105b-dcbd-441c-d566-93e466374548.png)

これは、ノードのREST APIの設定がMAX100で制限されているからです（現在、全てのノードの設定は共通で、初期値100となっています）


# なぜ限界突破を行うのか

SymbolのREST APIは短時間に問い合わせが増えるとデータを返さなくなってしまう仕様なので、それを回避するためにsetIntervalなどを使って時間をかけてデータを取得してやる必要があります。
これは、データ件数が少ない場合の問い合わせは問題ないですが、データが増えるにつれて描画に時間がかかってしまうという問題があります。

コードで説明すると以下のような感じ。

```
let pageNumber = 0;
let timer = setInterval( async function(){
  pageNumber++;
  const nsInfo = await nsRepo.search(
    {
      pageNumber: pageNumber,
      pageSize: 100,
      aliasType: AliasType.Mosaic
    }
  ).toPromise();

  nsInfo.data.forEach((info) => {
    console.log(info);
  });
  if (nsInfo.isLastPage || maxPage <= pageNumber){
    clearInterval(timer);
  }
},2000);
```

特に説明は不要かと思いますが、2000ｍsecごとに100件のデータを問い合わせています。
先ほども述べたように、データ件数が少ない場合には特に問題ないのですが、データ件数が多くなればなるほど全データの取得に時間がかかってしまいます。

そこで、冒頭に説明したように **REST APIが返す件数の上限を引き上げることでこの問題が回避できるようになります**。

さらに詳しい経緯は以下をご覧いただければと思います。

https://quest-bc.com/quest/n1T1YKUaEqCNrxsBCask?jid=VnXKmdNjNEikYYI4jrhA

# 手順

この記事はノード運用したことがある人向けなので個々の詳しい説明は省きます。
また、ノードはsymbol-bootstrapで建てている前提です。shoestringでも可能ですがディレクトリ構成が若干違うのでもしshoestringで構築したノードを変更するのであれば注意してください。

## ノードの停止

```bash
symbol-bootstrap stop
```

## RESTのコンフィグの書き換え

書き換え対象のファイル
`target/gateways/rest-gateway/res.json`の44行目、「pageSizeMax」という値です。

```yaml
{
  "network": {
    "name": "mainnet",
    "description": "Symbol Mainnet"
  },

  ...省略

  "db": {
    "url": "mongodb://db:27017/",
    "name": "catapult",
    "pageSizeMin": 10,
    "pageSizeMax": 100,　　　　← ここ
    "maxConnectionAttempts": 15,
    "baseRetryDelay": 750,
    "connectionPoolSize": 10
  },

　　　　...省略

  "numBlocksTransactionFeeStats": 300,
  "deployment": {
    "deploymentTool": "symbol-bootstrap",
    "deploymentToolVersion": "1.1.10",
    "lastUpdatedDate": "2023-08-29"
  }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/5cabb7c1-0423-ecbd-4c82-af1e7847bb59.png)

この「pageSizeMax」を1000に設定します。
実際に運用する場合、REST APIが返す件数が増えれば増えるだけサーバーへの負荷やレスポンス応答性能が下がってしまうので400くらいを推奨します。（設定する値はサーバーのリソースと相談してください）

## ノードの再起動

```bash
symbol-bootstrap run -d
```

## ノードが返すページ上限を確認

最初に確認したように`https://自身のノード名:3001/mosaics?pageSize=1000`へアクセス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/f3186170-31b7-0911-429a-778f81282ed6.png)

pageSizeが指定した件数返していれば成功です。

## 最後に

このREST APIの設定変更はノードのupgradeが入ると初期化されてしまいます。
これは`rest.json`がsymbol-bootstrapにより動的に生成されるためです。なので、ノードのアップデート時には再度ここの手順を行いページ上限を上げる必要がありますのでご注意ください。
Xcode Rich Text 

### Rich Text
```swift
//: this is the text with only one line

/* 
ここは多種線で
組まっている　
文書テーキストです。
ここの中には　**強調** とか　*イテリく*　で　書く事ができます。
*/
```
追加したものはRaw markup形式で見られます。


![](https://i.imgur.com/NodW1KK.png)
![](https://i.imgur.com/iwByygk.png)
QoS パケット スケジューラの帯域制御が動作しない

ポリシーを作っても帯域制御が適用されない。

# チェックポイント

- NICの「QoSパケットスケジューラ」が有効になっているか
- レジストリに`Do not use NLA`があるか

## NICの「QoSパケットスケジューラ」が有効になっているか

ネットワークアダプターの「QoSパケットスケジューラ」にチェックがあるか

![alt](https://qiita-image.cloudremix.net/QoS-Packet-Scheduler.jpg)

## レジストリに`Do not use NLA`があるか

ADに参加して**いない**コンピューターの場合は`Do not use NLA`のレジストリ値が設定されているか

```plaintext:追加するコマンド
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\QoS /v "Do not use NLA" /t REG_SZ /d 1 /f
```

# 参考
[Windowsの無線NICでDSCP値を付与して通信させる方法 - やさぐれオペレーター日記](https://yosshis.hatenablog.com/entry/2018/12/20/094632)
[Windows 10でネットワークの使用帯域（アウトバウンド）を制限する方法  |  4thsight.xyz](https://4thsight.xyz/15839)
Databricksの推論テーブルを試してみる

こちらの記事を一通り読んだので推論テーブル(inference tables)を試してみます。

https://qiita.com/taka_yayoi/items/b6a10ce0ff0d709d2349

https://qiita.com/taka_yayoi/items/bce5df57ae5d90bdf971

:::note
**注意**
この機能は[サーバレスモデルサービングのエンドポイント](https://docs.databricks.com/ja/machine-learning/model-serving/index.html)を前提としています。まだ日本リージョンでは利用できません。すみません。
:::

# 推論テーブルとは

推論テーブルは、お使いの[モデルサービングエンドポイント](https://docs.databricks.com/ja/machine-learning/model-serving/index.html)におけるリクエストとレスポンスを自動で捕捉し、Unity CatalogのDeltaテーブルに記録します。MLモデルを監視、デバッグ、改善するためにこのテーブルのデータを後で活用することができます。

例えば、推論テーブルを活用することで以下のようなことを達成することができます:

- お使いのモデルの次のイテレーションの再トレーニングデータセットの作成。
- プロダクションのデータとモデルの品質モニタリングの実施。
- 疑わしい推論の診断とデバッグの実行。
- 再ロードされるべき誤ったラベルのデータの作成。

# 推論テーブルの有効化

すでに、作成済みのモデルサービングエンドポイントがあったので、設定変更の際に有効化します。この時点では`Not enabled`となっています。
![Screenshot 2023-10-01 at 17.02.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/48fdb8e6-c54a-27e4-7e14-bca9349ecb97.png)

編集状態にして、**Inference tables (optional)** を展開します。
![Screenshot 2023-10-01 at 17.03.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a2677f76-f26a-72fe-914f-44b058fe8f65.png)

事前に格納用のカタログとスキーマ(データベース)を作成しておきます。ここでは、`quickstart_catalog_taka`と`inference_tables`となります。指定したら**Update serving endpoint**をクリックします。
![Screenshot 2023-10-01 at 17.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e16b090d-0980-5031-bf70-c29c00971644.png)

少し待つと**Inference table**が`Enabled`になります。
![Screenshot 2023-10-01 at 17.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/dcc5e5ad-31dc-0310-6ebd-e40ce991d5bf.png)

その下のテーブル名のリンクをクリックすると、カタログエクスプローラが開き推論テーブルにアクセスすることができます。まだこの時点ではレコードは存在しません。
![Screenshot 2023-10-01 at 17.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1e954b5c-130f-c443-4cc3-1e3f0d424871.png)

# 推論テーブルの動作確認

モデルサービングエンドポイントを呼び出してみます。なお、このエンドポイントはこちらで作成したDatabricks Q&A botのものです。

https://qiita.com/taka_yayoi/items/43302d79369a36b66ee4

![Screenshot 2023-10-01 at 17.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d40beedc-1a7a-0aa4-83d7-18689b2f0b07.png)

何度か問い合わせを行います。この際にリクエストとレスポンスが推論テーブルに記録されます。
![Screenshot 2023-10-01 at 17.10.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b18288eb-ecf9-934f-cfc8-5c3d2c90926b.png)

数分経ってからテーブルにアクセスするとレコードを確認できました！
![Screenshot 2023-10-01 at 17.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a0b000c4-8e94-093d-c2b6-b26bd9bea3d1.png)

次はパーシングなど行ったり、[こちらのノートブック](https://qiita.com/taka_yayoi/items/3f2ad387de549d64ee74)も試してみます。特に大規模言語モデルを運用する際には、どのようなリクエストが来ていて、それに対して大規模言語モデルがどのようなレスポンスをしているのかをモニタリングすることは品質面でも重要なことかと思います。(日本で利用できるようになったら)推論テーブルを是非ご活用ください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
英語論文のPDFをHTML化してドラッグで翻訳する方法

# はじめに
この記事はPDFをHTML化し、chrome拡張機能の翻訳機能を使用してwebページの読めない文章をドラッグし都度翻訳できるようにすることを目的とします。
PDFをそのまま翻訳機にかけると形式が崩れてしまった、翻訳した文章がおかしく元の文章が見たい時に苦労します。
しかし、この方法を使えばドラッグした文章のみしかもわざわざDeepLのページにアクセスせずとも翻訳をすることができます。
# 必要なもの
- PC
- googleアカウント（大学や会社のアカウントだと拡張機能が使えないことがあるので個人でアカウントを作ろう！）
- webブラウザ（chrome推奨ですがbingやfirefoxでも拡張機能はあるので可能です）
- ソフトウェアのインストールなどはwebブラウザー以外は必要ありません

# 手順
-  WEBブラウザの拡張機能でdeeplを入れる
- 読みたい論文のPDFをダウンロードする
- [IDR online pdf to html converter](https://www.idrsolutions.com/ja/online-pdf-to-html-converter)　を使ってPDFをHTML化する
- 終わったらopen in browserを押してブラウザーでHTMLファイルを開く
- 翻訳したい文をドラッグして翻訳する

## 拡張機能を追加
- まずは使っているwebブラウザーで「ブラウザ名（使用しているもの）　拡張機能」で検索する
(chromeの場合は[chrome webストア](https://chrome.google.com/webstore/category/extensions?hl=ja)が先頭に来ると思うのでクリックします。)
- 以下のような画面が出てくるので左上の「ストアを検索」にdeeplと入れます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/1715e734-5b05-9c1b-79f7-9be6b91df4b5.png)

するとこのような画面が出てくるので先頭のDeepL翻訳をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/cc47853a-96a4-e6e2-f97e-c55c3af51f72.png)

次に右上の「Chromeに追加というボタン」を押してChromeに追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/45a5030f-a767-c06a-0ec5-405403d72c33.png)

そうしたら任意の外国語ページを開いて英文をドラッグし、以下のような表示がされることを確認してください（表示されない場合はリロードしてみて下さい）
ドラッグしたTablesの右下のアイコンをクリックすると任意の言語に翻訳してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/e7127281-f20b-8e19-f278-ebb596907091.png)

するとこのようにドラッグした英語を翻訳してくれます（しかもDeepLのページを開かずに）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/9659d6a4-f488-c778-5c85-f43f675f62aa.png)

これで拡張機能の追加は完了です。

## PDFをHTML化する
次にPDFをHTML化します。なぜこの作業をするかというと、ドラッグで指定した文章のみを翻訳できるようにするためです（pdfをwebブラウザで開いてもこれはできない）

- まず、[IDR online pdf to html converter](https://www.idrsolutions.com/ja/online-pdf-to-html-converter)にアクセスします。
- ファイルを選ぶというボタンを押し、読みたい論文のPDFを選択し変換するを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/89b2f2f4-18a4-c595-5940-df0de512ff6e.png)
変換が完了すると以下の画面がでるのでオンラインでプレビューを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3246015/f9cfd1e8-bd63-9a9d-ba0a-945acccef967.png)

あとは、webページと同じようにドラッグした英文を日本語訳して論文を読みましょう！
## 注意
- 生成されたプレビューリンクは時間が経つと消えてしまうのでその場合はまたPDFをHTMLに変換する必要があります。
- またローカルのHTMLファイルをブラウザで開いてもドラッグして翻訳するとこはできません。
SwiftUIで下から出てくる選択肢アラートの実装方法

今回は下から出てくる選択肢アラートの実装をしてみようと思います。

普段はAndroidの開発をしています。
AndroidにはそういったUIはないので最初名前が何て言うのか調べました。

ActionSheetと、言うみたいです。

ですが、SwiftUiでは別の名前になってました。

confirmationDialogという名前だったので、こちら使用しています。


```SampleAlert.swift
struct SampleAlert: View {
    @State private var showConfirmationDialog = false
    
    var body: some View {
        VStack {
            Button("SampleConfirmationDialog") { showConfirmationDialog = true }
        }
        .padding()
        .confirmationDialog("", isPresented: $showConfirmationDialog) {
            Button {
                // TODO: 押した時の処理
            } label: {
                Text("追加1")
            }
            Button {
                // TODO: 押した時の処理
            } label: {
                Text("追加1")
            }
            Button("キャンセル", role: .cancel) {}
        }
    }
}
```

![スクリーンショット 2023-10-01 17.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/0185234b-93c4-071d-625f-9b97956f57e7.png)

こんな感じの表示になりました。
SwiftUI慣れている方はすぐにわかると思います！
isPresentedに表示のフラグを設定して、表示したいボタンを記載することになります。

以上です。
【できました】LaravelでHTMLをreturnするときにできないこと


## 課題

掌田津耶乃著の[Laravel 入門第 2 版](https://www.shuwasystem.co.jp/book/9784798060996.html)を読んでいて、Controller で html を return するときに想定していたような挙動にならなかった点があったのでメモをする。

## 環境

WSL2 Ubuntu 20.04.6 LTS

Laravel Framework 8.83.27

## 2023/10/02 追記

コメントでこうすればいいよと教えていただきまして、追記します。

ありがとうございます！

```PHP
Route::get('hello/{msg}', function($msg){
    return '<html><body><h1>' . $msg . '</h1></body></html>';
});
```

こういうふうに書くと、ヒアドキュメント使わずでできるみたいです。

変数部分にかっこをつけてしまっていましたが、この部分は PHP の書き方部分になるので、かっこがいらないということでした。

## やりたいこと

view テンプレートではなくて、生の HTML を返したい。

```PHP
Route::get('hello/{msg}', function($msg){
    $html = <<<EOF
    <html>
    <body>
    <p>{$msg}</p>
    </body>
    </html>
    EOF;
    return $html;
});
```

これはうまく動いて、$msg が展開されて表示される。

## できなかったこと

ヒアドキュメントで書かないといけないのか？と思い、以下のように変更してみた。

```PHP
Route::get('hello/{msg}', function($msg){
    return '<html><body><h1>{$msg}</h1></body></html>';
});
```

これは、実行すると、「{$msg}」とそのまま表示されてしまう。

おそらく、return のあと、シングルクォーテーションで囲っている部分が文字列として判定されているのかなあと思った。

それで以下のように試してみた。

```PHP
Route::get('hello/{msg}', function($msg){
    return '<html><body><h1>'{$msg}'</h1></body></html>';
});

Route::get('hello/{msg}', function($msg){
    return '<html><body><h1>' + {$msg} + '</h1></body></html>';
});
```

これはどちらもエラーで動かなかった。

文字列連結みたいなことをイメージして試してみたがだめだった。

## まとめ

とりあえず HTML に変数を入れてそれを展開したい場合で、テンプレートを使わずに返したいときには、ヒアドキュメントで変数にいったんおさめてから、それを return する必要がありそう？

実際のプロダクトでコードを書くとなったらほぼ使わなそうなところではある。
AIについて詳しく知りたい！！

## 知りたいと思ったきっかけ
ChatGPTや自動運転でAI技術が使われているけど、「AI」とは何かを知りたかった。


## AIとは何か？
Artificial Inteligence(人工知能)の略で、コンピュータで人間がやっていることを実現できることを指す。
人間が物事を考える時、脳内でニューロンという細胞体が結合して、信号を受け渡しています。
↓のニューロンが「100億〜1000億個ほどある」と言われているみたいですね。
![2399652_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/87375e6c-37fa-615b-1016-457281e8b31b.jpeg)
「ニューロンを使ってコンピュータに頭脳を持たせたら、コンピュータも人間同様に思考できるじゃないか」と思い、AI時代の幕開けとなりました。


## AI時代の移り変わり

①第一次AIブーム

「推論」と「探索」を中心にAIが研究され、パズルを解いたりチェスで勝利しました。
しかし、ルールが無かったり複雑な問題ではAI機能を発揮できないため、「会社の売り上げがどうなるのか」等の社会問題を解決できず、AIブームが去りました。

②第二次AIブーム

社会問題を解決するために、専門家の知識を蓄積し社会問題の解決するエキスパートシステムが誕生しました。
患者の悩みを入力すれば、専門家に似た回答が返って来て、「AI」の存在が広がって来ました。
しかし、専門家がコンピュータに膨大な知識を用意する必要があったり、曖昧な事例に対応出来ない点があって、再度AIブームが去ったんです。

③第三次AIブーム

2000年代以降にインターネットが普及したおかげで、学習データが集まりやすくなりました。
そして、ビッグデータを使って知識を獲得する「機械学習」が実用化され、後に登場した「ディープラーニング」も実用化されました。
画像解析や言語処理としてAIを導入するケースが多く、ブームの勢いは衰えません。


## まとめ

計算したり、会話をしたり、未来を予測する等の場面で使った脳の仕組みを、コンピュータに実現したのが「AI」
これを見て、「AIに仕事を奪われる！！」と不安な声も出ると思いますが、何でもAIで出来るとは限りません。
AIのメリットとデメリットを理解すれば、AIとの向き合い方が変わるかもしれませんね。
生成AI時代のデジタルリテラシーの高め方

# はじめに
2021年から創設された「[デジタルの日](https://www.digital.go.jp/policies/digital_days)」。最初は10月の10日と11日だったのが、昨年から10月の第一日曜日・月曜日に変わっていたみたいですね。
まだ今年も3ヶ月残っていますが、2023年のデジタル関連の話題は**生成AI**が最大なのは揺るがない様子です。
直近では[ChatGPT-4V](https://qiita.com/Ikwus/items/1471cb67b6454e2d904b)（ビジョンのV）のリリースが遂に発表され、ChatGPT Plusを契約しているユーザーの中でもアーリーアクセス出来ている人が居るようですが、私自身はまだなので触れるのが待ち遠しいところです。

# 結論
生成AIが正しい情報をアウトプットしていても、情報を取り違えてしまうと活用できません。
読解力を高めるために、できるだけ大量の文章を読みましょう。
読み方が分からない・意味が分からない単語や表現に出会った時はチャンスです、その場その場で調べつつ理解度をテストしましょう。

# 背景
デジタルのリテラシーに限らず、これまでは独学で何かを学ぼうとした際にどうしても一方通行なインプットやアウトプットにならざるを得ず、リアルタイムで言い換えてもらったりフィードバックを得たい場合は他者を頼らざるを得なかったと思います。
そこにChatGPTを筆頭とする生成AIというパートナーが出来たのは凄く大きい変化で、何かをアウトプットする際の効率もそうですが、自身の理解を促進する際に自分のレベルにあった形で言い換えてくれたり何度もテストしてくれるのは学習効率が桁違いに上がるため、利用しない手は無い状態です。

[ITパスポート試験のシラバスにも生成AIが追加され来年4月の試験から適用される](https://www.ipa.go.jp/shiken/syllabus/henkou/2023/20230807.html)ようなので、もしまだ生成AIを触ったことが無い方は出来るだけ早く試してみることをお勧めします。

また、[生成AIの技術はWordやExcelなどのMicrosoftオフィス製品にも搭載され、11月にも一般公開される](https://news.yahoo.co.jp/articles/9910af7ebfee2d8e9e55f3db4b4e8cecc8c8982e)ようなので、遅かれ早かれ覚えなければ使える人との生産性が大きく開いてしまいます。

# こんなことを聞いたらバカにされる？
人間を相手にしている時には「こんな（基本的かも知れない）ことを聞いたらバカにされるかな...？」と、恥ずかしかったり怖くて聞けなかったことありませんか？

生成AIは、同じことを何度も聞いても懇切丁寧に答えてくれますし「中学生でも分かる表現に言い換えて」と言えばその通りに簡易な表現で教えてくれます。

ただ、短期記憶できる量がまだまだ少ないのと、あたかも正しい・全て知っているように嘘を言うことがあるので、「少し前に教えたから大丈夫」や「AIが言ってるから正しいのだろう」と鵜呑みにするのは危険で、対人において注意すべき点と変わりなく必要です。

# 知ったかぶりをしない
生成AIは、アイデアを出してくれたり・データを分析してくれたり・文章を要約してくれたり・色々なことを教えてくれますが、生成AIがどれだけ正しい情報をアウトプットしていても、受け取る人（あなた自身）が情報を誤解してしまうと活用できません。

少しでも自身の理解が曖昧な部分は、生成AIに理解度をチェックしてもらうようにしましょう。

# 生成AIが賢くなる仕組みは人間でも使える
生成AIの賢さが、事前学習するデータ量に関係しているのは興味深いことです。
仕事でも何でも、最初は分からなかったけど分かるようになったり、回数を重ねると出来るようになることがありますよね。
よく「コツを掴む」と表現されることは、試行回数の蓄積によって脳や神経の回路が作られているのでしょうね。

# おわりに
毎年この時期になるとデジタルの日にちなんだ何かを書きたくなるのですが、今回は生成AIがテーマでした。
ChatGPT-4Vが手元で使えるようになったら、街や周りを散策する際に色々解説してもらおうと思ってます。ゆくゆくはARグラスが発売されて連動してくれると楽しそうですね。
FortigateのログをCLIにてエクスポートする

## この記事について
FortigateのログをGUIではなく、CLIにてエクスポートする必要があったので調べてみました。しかし、この方法に関するニーズがあまり多くないのか、情報があまり見つからなかったです。そのため、備忘録として残しておきます。

## これやる前に
この方法では、tftpを使用しますので、あらかじめtftpdなどの環境を用意しておきましょう。

### コマンド
- execute backup memory alllogs tftp [ip address]
```
# execute backup memory alllog tftp 192.168.0.100
Connect to tftp server 192.168.0.100 ...
Please wait...
#
Sent log file _tlog.mlog to tftp server as mem_tlog_FGT50Exxxxxxxxxx_root_20231001_164726_mlog OK.
Connect to tftp server 192.168.0.100 ...
Please wait...
#
Sent log file _elog.mlog to tftp server as mem_elog_FGT50Exxxxxxxxxx_root_20231001_164728_mlog OK.
:
<snip>
:
olog memory log is empty.
hlog memory log is empty.
```

### 参考
- Export using the CLI
https://techdocs.broadcom.com/us/en/symantec-security-software/information-security/symantec-cloudsoc/cloud/audit-home/fortinet-home/export-via-cli-all-logs.html
M5Stamp S3でLチカをした話

今まで使ったことのないものを使うのが好きな筆者は、このたびM5Stamp S3に手を出しました。
今回は、M5Stamp S3でLチカ、つまり、LEDを光らせることをやってみるまでのお話です。
ソースコードは公式からのコピペで済みますので、皆さんもお手軽にお試しください。


# M5Stamp S3とは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846834/64a3ef76-f937-d921-f243-61b1e5d202d0.png)

こういう小さいやつです。
（比較は2.54mmピンヘッダ）

もっと詳細な説明は以下をご覧ください。

[https://docs.m5stack.com/en/core/StampS3](https://docs.m5stack.com/en/core/StampS3)

筆者がこのたび注目した点としては、

- 小さい : Stampという名前のとおり、切手サイズです。
- 軽い : 小さいんだから軽いです。鉛が詰まっていたりしません。
- USB端子付き : デフォルトでUSB端子がついています。自分でちまちまハンダ付けする必要がありません。
- ダウンローダー込み : チップにダウンローダーが込みなので、別途ライターとかは必要ありません。
- 端子が2.54mmピッチでも使える : 全端子を使うには1.27mmピッチで使う必要がありますが、一部端子だけであれば、2.54mmピッチで使えます。
- Bluetooth搭載、技適取得済み : Bluetoothで無線通信ができます。日本国内でも安心、技適取得済みです。技適シールは別途付属なので、ぺたっと貼ります。

つまり、Bluetoothが使えて、ダウンローダー込みで、コンパクトなマイコンボードというあたりに、筆者は惹かれました。

これなら、Bluetooth対応の自作キーボードをつくれるんじゃね？と。

# お買い物

面白そうなので買いましょう。
日本国内だと、スイッチサイエンスさんから買うのが手軽です。（以下リンクはアフィリエイトとかないので、お気軽にクリック）

基本はこれです。

M5Stamp S3
[https://www.switch-science.com/products/8777?_pos=1&_sid=f8c4e2485&_ss=r](https://www.switch-science.com/products/8777?_pos=1&_sid=f8c4e2485&_ss=r)

上記のやつの2.54mmピッチのピンヘッダ実装済みが以下です。

M5StampS3 （2.54 mmピッチピンヘッダ実装版）
[https://www.switch-science.com/products/9177?_pos=19&_sid=f8c4e2485&_ss=r](https://www.switch-science.com/products/9177?_pos=19&_sid=f8c4e2485&_ss=r)

ブレッドボードに実装する予定なのであれば、ピンヘッダ実装済みがお手軽です。

また、全てのピンを引き出してブレッドボードで使いたい場合は、
秋月の「１．２７ｍｍピッチピンヘッダ　１×４０　（４０Ｐ）」とスイッチサイエンスの「M5Stamp S3用ピッチ変換基板」があるといいかもしれませんが、筆者は試していないのでご自身で調査してください。

後は、パソコンとマイコンボードをつなぐために、Type-CのUSBケーブルが必要です。

# 開発環境

開発環境はArduino IDEで手軽にやりましょう。

構築の仕方は以下をご参照ください。

[https://docs.m5stack.com/ja/quick_start/arduino](https://docs.m5stack.com/ja/quick_start/arduino)

慣れている人は、以下のURLとライブラリ名「M5Stack」でどうぞ。

```
https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json
```

# Lチカ

光らせるには、以下のサンプルコードを利用します。

[https://github.com/m5stack/STAMP-S3/blob/main/examples/Led/Led.ino](https://github.com/m5stack/STAMP-S3/blob/main/examples/Led/Led.ino)

また、「FastLED」というライブラリが必要です。
「ツール＞ライブラリを管理」で開いたウィンドウに以下を参照してライブラリを追加してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846834/62211bed-0534-5e81-2756-1f84b19df980.png)

次に、書き込みです。

Arduinoで以下の画像の通り、ボードを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846834/81354c04-b098-92a7-307c-293798effa10.png)

M5StampS3をパソコンとつなぎ、ボードの下の項目、ポートも指定します。

これで準備完了！
書き込みアイコンをクリックし、コンパイルと書き込みを行うとLEDが光ります。

光る色は、スイッチ（MACアドレスのシールが貼ってある面の真ん中あたりにあるやつ）を押すことで、レインボー → 赤 → 緑 → 青 の順番で切り替えられます。

# 後書き

これで初期不良がないかの動作確認は済みました。
後はやりたいことをやるだけです。

筆者は以下のファームウェアを利用したBLEキーボードづくりに挑戦するつもりです。
[https://github.com/palette-system/az-core](https://github.com/palette-system/az-core)

進展があったら、また別途記事にしたいと思いますので、お楽しみに。
Dockerコンテナ上で作成したDynamoDBのデータが永続化されない

# はじめに
Dockerコンテナ上で作成したDynamoDBのデータが、docker down → upすると、データが消えるので、毎回テーブル作成する手間がかかる。

# 手順
## 1. docker-compose.ymlにオプション追加

```docker-compose.yml
  api_dynamodb:
    container_name: api_dynamodb
    image: amazon/dynamodb-local:latest
    networks: [overlay]
    command: ["-jar", "DynamoDBLocal.jar", "-sharedDb"] ##オプション追加
    ports:
      - '8000:8000'
    volumes:
      - 'dynamo:/home/dynamodblocal' ##マウントするパスを設定
```
デフォルトのimagesは`inMemory`オプションになっている。
これは、コンテナのメモリ上に保存するもので、コンテナをdownするとそのまま消えてしまう。
そのため、`sharedDb`オプションで、volumesで設定したディレクトリをコンテナにマウントする。
あくまで、データ保存は、コンテナではなく、ホストOSのvolumesの`shared-local-instance.db`で管理する。

## 2. マウントされているvolumesを確認
Dynamoのコンテナに入り、マウントされているvolumesの中身を確認
`shared-local-instance.db`があればOK
```
➜  (main) ✗ docker-compose exec api_dynamodb bash
[dynamodblocal@d63f6813053d ~]$ pwd
/home/dynamodblocal
[dynamodblocal@d63f6813053d ~]$ ls
DynamoDBLocal.jar  DynamoDBLocal_lib  LICENSE.txt  README.txt  THIRD-PARTY-LICENSES.txt  shared-local-instance.db
```

`InMemory:　false`と、`SharedDb:　true`を確認
```
➜  (main) ✗ docker logs api_dynamodb
Initializing DynamoDB Local with the following configuration:
Port:	8000
InMemory:	false
DbPath:	null
SharedDb:	true
shouldDelayTransientStatuses:	false
CorsParams:	null
```

以下のようにvolumeを確認できる
```
 docker volume ls
 docker volume inspect (volume名)
```

以上。

## 参考記事
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html#DynamoDBLocal.Endpoint
Hello World から始める CMake (1)

# 例

　何はともあれ、まずは CMake を軽く動かしてみる。
　一番最初にすべきは、当然 "Hello, world!" の表示だろう！（断言）

~~~CMake:CMakeLists.txt
# 文字を表示するには message() を使う。
message("Hello, world!")
~~~

　上記内容の CMakeLists.txt を用意し、cmake を実行してみる。

~~~Bash:実行
$ cmake -P CMakeLists.txt
Hello, world!
~~~

# 解説

　コマンド引数 `-P` は、指定したファイルを実行する指示だが、まあ、普段はあまり使わないかも？　デバッグのときとか？

　それでも、初めて（もしくは初めてに等しい）の場合は、そこから得られる情報がいくつかあると思う。

## 1. ファイル名は CMakeLists.txt

　cmake では、まず用意すべきは CMakeLists.txt である。
　上記ではコマンド引数で指定したが、通常はこのファイル名がデフォルトで使用される。

## 2. コメントは # で始まる。

　コメントとは、実行に何も影響を与えない文字列のこと。

　上記の例で、 # から始まる行は、cmake 実行には何も影響しない。
あくまでユーザ向けの情報にすぎない。

　なお、cmake でのコメントには複数行可能な Bracket comment と一行だけの Line comment がある。上記の例は Line comment になる。詳細は以下の[参考リンク 4.][link-4] を参照。

## 3. message 文

　メッセージを表示する。
　なお、たんにメッセージを表示するだけでなく、ステータスに応じて表示・非表示を切り替えるなど、多彩な機能がある。詳細は以下の[参考リンク 5.][link-5] を参照。


## 参考リンク：
1. [CMake](https://cmake.org/)
2. [CMake Documentation and Community](https://cmake.org/documentation/)
3. [cmake(1) &mdash; CMake Documentation](https://cmake.org/cmake/help/latest/manual/cmake.1.html)
4. [cmake-language(7) &mdash; CMake Documentation][link-4]
5. [message &mdash; CMake Documentation][link-5]

[link-4]: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html
[link-5]: https://cmake.org/cmake/help/latest/command/message.html
cloud9 laravel導入

### laravelとは？
LaravelはPHPで書かれたWebアプリケーションフレームワークの一つです。フレームワークとは、プログラミングにおいてよく使われる共通の機能をあらかじめ組み込んであり、開発者がその上に独自の機能を追加してアプリケーションを作成するための「ひな形」のようなものです。

### :star:PHP+Laravelのインストール
デフォルトで入っているPHPのVersionは古いため、必要に応じてアップデートする必要があります。
```
php --version
```
#### PHPのバージョンアップ
インストールされているパッケージを最新版に更新します。
php72（PHP 7.2）、php72-mbstring（マルチバイト文字列用PHPエクステンション）、php72-pdo（PHP Data Objects, データベースアクセス用のPHPエクステンション）をインストールします。

```
sudo yum -y update
sudo yum -y install php72 php72-mbstring php72-pdo
```
旧バージョンのPHPリンクの削除
PHP7.2へのリンク張りなおしを行う
```
sudo unlink /usr/bin/php 
sudo ln -s /etc/alternatives/php7 /usr/bin/php 
```

アップデートされているかの確認
```
php --version
```
以下のように表示されればOK!
```
PHP 7.2.24 (cli) (built: Oct 31 2019 18:27:08) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v3.1.6, Copyright (c) 2002-2022, by Derick Rethans
```
___________
###  :star:Laravelのインストール
 **Composerのイストール**
```
curl -sS https://getcomposer.org/installer | php
```
Composerをbin配下に移動
```
sudo mv composer.phar /usr/local/bin/composer 
```
composerの実行確認
```
composer
```
以下のように表示されればcomposerのインストール完了です
![スクリーンショット 2023-10-01 16.48.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492906/4af110a6-eb94-186c-7ce7-36e4df31e052.png)
____________
### Laravelプロジェクトの作成
以下のコマンドで、利用するPHPバージョンに対応している最新のLaravelバージョンでプロジェクトの作成が行われます。
```
composer create-project laravel/laravel プロジェクト名
```
プロジェクトの起動
```
cd プロジェクト名
php artisan serve --port=8080
```
または以下のコマンドで起動してブラウザに``http://127.0.0.1:8000``で表示
```
php artisan serve
```

cloud9 の **preview Running Application**でブラウザを確認して以下のように表示されればlaravelインストール完了です。

![スクリーンショット 2023-10-01 16.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492906/a5d3da60-3c83-b2c2-cbae-5532a0f46366.png)

参考

https://www.simpletraveler.jp/2019/08/18/setup-environment-phplaravel-aws-cloud9/

https://gist.github.com/KiKiKi-KiKi/1e0826dc81b020a33e41fa22b07b9c5d
Databricksモデルサービングエンドポイントのモニタリング

[Monitor model serving endpoints \| Databricks on AWS](https://docs.databricks.com/en/lakehouse-monitoring/monitor-endpoints.html) [2023/9/25時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

:::note info
**プレビュー**
本機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。
:::

Databricksレイクハウスモニタリングを用いることで、[推論テーブル](https://qiita.com/taka_yayoi/items/b6a10ce0ff0d709d2349)により[Databricksモデルサービング](https://docs.databricks.com/ja/machine-learning/model-serving/index.html)エンドポイントの品質をモニタリングすることができます。

# 要件

推論テーブルを用いてサービングエンドポイントをモニタリングするには、推論テーブルのプレビューにも参加し、両方の機能の要件を満たす必要があります。これらのプレビューに参加するにはDatabricks担当者にお問い合わせください。

# 推論テーブルのモニタリング

以下のステップでエンドポイントをモニタリングすることができます:

1. エンドポイント作成時あるいは更新時に、お使いのエンドポイントの[推論テーブル](https://qiita.com/taka_yayoi/items/bce5df57ae5d90bdf971)を有効化します。
1. エンドポイントのスキーマに沿って、推論テーブルのJSONペイロードをアンパッキングし、処理するためのワークフローをスケジュールします。
1. (オプション)モデル品質メトリクスを計算できるように正解ラベルを用いて、リクエストとレスポンスを結合します。
1. 結果のDeltaテーブルに対するモニターを作成し、メトリクスを更新します。

以下の[スターターノートブック](#推論テーブルモニタリングのスターターノートブック)で、このワークフローを実装しています。

# 推論テーブルモニタリングのスターターノートブック

以下のノートブックでは、推論テーブルからリクエストをアンパッキングし、モニタリングを行うための上述のステップを実装しています。このノートブックはオンデマンドあるいは[Databricksワークフロー](https://docs.databricks.com/ja/notebooks/schedule-notebook-jobs.html)を用いてスケジュール実行することができます。

## 推論テーブル、レイクハウスモニタリングスターターノートブック

https://docs.databricks.com/_extras/notebooks/source/monitoring/inference-table-monitor.html


### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Rails7 ストロングパラメータ取得メソッドに画面入力された項目以外を追加する


This article shows how to create/update a record with adding parameters other than Strong Parameters.

## 環境情報＆前提条件
* Ruby 3.2.1
* Rails 7.0.0

## 解決したい内容
* formを使って画面で入力された情報を元にレコードの新規作成/更新を行いたい。
* コントローラで受け取る情報については、StrognPrametersを使用して意図しない項目が設定されることを防ぎたい。
* 一方で、画面で入力された項目以外にパスパラメータやURLのクエリパラメータで指定された内容等を自由に追加したい。

## 解決手順
* StrongPrametersでparamsを取得した後に、自分が追加したい項目を`merge`して返すようにする。

```rb
# 例）Commentレコード作成時にパスパラメータで渡ってきたPostテーブルのIdを追加する場合
class CommentsController < ApplicationController
  def create
    # comment_paramsには"StrongParametesの内容＋mergeした項目"が含まれる
    comment = Comment.create(comment_params)
  end

  private

  def comment_params
    # StrognPrametersとしてはコメント本文(content)と添付画像(image)を許容する
    permit_params = params.require(:comment).permit(:content, image)
    # パスパラメータからpost_idを取得し、paramsにマージして返す
    # 以下ではパスパラメータからpost_idを取得して設定している
    permit_params.merge(post_id: params[:post_id])
  end
end
```
学びなおしで読みなおしたい本 2023 秋

## 読みなおしたい本

### アーキテクチャ
[コンピュータの構成と設計 第5版 上 | ジョン・L. ヘネシー, デイビッド・A. パターソン, 成田 光彰 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4822298426)
[Design It! ―プログラマーのためのアーキテクティング入門 | Michael Keeling, 島田 浩二 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4873118956)
[【感想】『Design It! プログラマーのためのアーキテクティング入門』：モダンなアーキテクトへの地図とコンパス - Rのつく財団入り口](https://iwasiman.hatenablog.com/entry/20200615-design-it)
[ソフトウェアアーキテクチャの基礎](https://qiita.com/e99h2121/items/1844f5ed8da453a6dfb0)
[ソフトウェアアーキテクチャ・ハードパーツ](https://qiita.com/e99h2121/items/139a40bff1f4451c7e23)

### ネットワーク
[マスタリングTCP/IP　入門編（第6版） | 井上直也, 村山公保, 竹下隆史, 荒井透, 苅田幸雄 | 工学 | Kindleストア | Amazon](https://www.amazon.co.jp/dp/B0827QNDNT)
[マスタリングTCP/IPを読んだか読んでないかで随分違う - orangeitems’s diary](https://www.orangeitems.com/entry/2020/01/19/000100)

### リーダーシップ
[新1分間リーダーシップ | ケン・ブランチャード /パトリシア・ジガーミ /ドリア・ジガーミ, 田辺　希久子 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4478029288)
[【#読書メモ】新1分間リーダーシップ｜竹下正光：知識と経験の出会いで人を幸せに](https://note.com/masatake0914/n/nd9e4c735c2e3)


## 参考
[新人さんにすすめる有益な技術書達 2022春 - Qiita](https://qiita.com/e99h2121/items/1b243efb1499527f0701)
[コンピュータサイエンスで1冊ずつ本を上げるとしたら何になりますか？就職前にバイブル的な本を勉強したいと思いました。 -コンピュータアーキテクチャ -データベース -os -アルゴリズムとデータ構造 -セキュリティ -ネットワーク -プログラミング -仮想化技術 | Mond - 知の交流コミュニティ](https://mond.how/ja/topics/01z4xezoi2w49yo)

行き当たりばったりで問題にあたってきて以来、体系立てて読んだ記憶があまりない分野を中心にメモ。
以上です～
[Haskell] 現在の UNIX 時間を取得する

Haskell で現在の UNIX 時間を取得するには `epochTime` を用います。

```haskell
import System.Posix.Time (epochTime)

main :: IO ()
main = do

    epochTimeEpochTime <- epochTime

    print epochTimeEpochTime
```

参考「[epochTime - System.Posix.Time](https://hackage.haskell.org/package/unix-2.8.2.1/docs/System-Posix-Time.html#v:epochTime)」

`EpochTime` は `CTime` の型シノニムであり、コンストラクタ `CTime Int64` より「パターン」によって `Int64` 型の値を得られます。

```haskell
import Foreign.C.Types (CTime(..))
import System.Posix.Time (epochTime)

main :: IO ()
main = do

    CTime epochTimeInt64 <- epochTime

    print epochTimeInt64
```

参考「[EpochTime - System.Posix.Types](https://hackage.haskell.org/package/base-4.16.4.0/docs/System-Posix-Types.html#t:EpochTime)」
参考「[CTime - Foreign.C.Types](https://hackage.haskell.org/package/base-4.16.4.0/docs/Foreign-C-Types.html#t:CTime)」

`CTime` 型は `Enum` クラスのインスタンスのため、`fromEnum` メソッドによって `Int` 型の値を得られます。

```haskell
import System.Posix.Time (epochTime)

main :: IO ()
main = do

    epochTimeInt <- fromEnum <$> epochTime

    print epochTimeInt
```

参考「[CTime - Foreign.C.Types](https://hackage.haskell.org/package/base-4.16.4.0/docs/Foreign-C-Types.html#t:CTime)」
資格勉強のお供にChatGPT

## はじめに
JDLA主催のE資格合格に向けた勉強のお供としてChatGPTを使用しました。
実際に使ってみて有効的だと感じたので、実査にやった内容を紹介します。

## E資格とは
JDLAが主催しているディープラーニングに関する資格試験で4択問題が100問前後出題されます。(資格の詳細は本題からずれるので詳細します。)
https://www.jdla.org/certificate/engineer/

## 課題
AIに関する資格ということもあり試験の出題範囲が良く変わります。そのため、最新の参考書が実際の出題範囲と一致していないという課題がありました。

## やったこと
試験範囲が異なるので、参考書だけを解いても合格できません。
そのため、シラバスを確認しながらChatGPTに試験の模擬問題を作ってもらいました。

### 実際の例
私はAIの勉強をしています。
DQNに関する四択問題を出していただけますか。
私が回答したら、解答を教えてください。
```
もちろん、DQN（Deep Q-Network）に関する四択問題を作成します。

問題:
DQNに関する以下の記述の中で、最も正確でないものはどれでしょうか？

A) DQNは深層学習を使用してQ-learningのQ関数を近似する。
B) DQNは経験再生（Experience Replay）を用いて、過去の経験をランダムにサンプリングして学習する。
C) DQNは毎回の学習ステップで必ず報酬が最大となる行動を選択する。
D) DQNの目的は、累積報酬を最大化するポリシーを見つけることである。

お答えをどうぞ！

（解答するまで、正解を伝えません。）
```
D
```
実際に、選択肢D「DQNの目的は、累積報酬を最大化するポリシーを見つけることである。」は正確な記述です。
DQNの目的は、報酬の総和（累積報酬）を最大化するような行動を見つけることです。

正確でない記述は選択肢C「DQNは毎回の学習ステップで必ず報酬が最大となる行動を選択する。」です。
DQNはε-greedy法を用いることが一般的で、これにより探索と活用のバランスをとります。
εの確率でランダムな行動を選択し、1-εの確率で現在のQ値が最大となる行動を選択します。
したがって、DQNが毎回報酬が最大となる行動を選択するわけではありません。

正解は選択肢Cです。
```
次の問題お願いします。
```
もちろん、DQNに関するもう一つの四択問題を作成します。

問題:
DQNの改良点の一つとして導入された、固定されたターゲットネットワークの役割は何でしょうか？

A) 現在のQネットワークの学習速度を高めるため。
B) Q値の更新時の目標値を安定させるため。
C) Experience Replayメモリのサイズを削減するため。
D) ε-greedy法のεの値を動的に変更するため。

お答えをどうぞ！

（解答するまで、正解を伝えません。）
```

B

```

正解です！

選択肢B「Q値の更新時の目標値を安定させるため。」が正しいです。
DQNにおいて、固定されたターゲットネットワークは学習中のネットワーク（主ネットワーク）とは独立して、一定の間隔で更新されます。
このターゲットネットワークを使用することで、Q値の更新の際の目標値が高頻度で変動するのを防ぎ、学習の安定性を向上させることができます。

お答えいただき、ありがとうございます！何か他に質問や要望があれば、お気軽にどうぞ。
```
## よかった点
### わからない用語はすぐに質問できる。
問題集を解いていると、分からない単語が登場することが多々あると思います。
通常であれば、参考書で調べたりネットでググったりする必要がありますが、ChatGPTであれば問題に回答した流れで、そのまま質問をすることが可能です。

### 出題される問題が毎回異なる。
同じ問題集を解いていると段々と答えを暗記してしまうと思います。
ChatGPTは出題するたびに問題文や選択肢が異なるので、答えを暗記するということが発生しません。

## 注意しないといけない点
### 最新技術に関する問題は出題できない
当たり前ですが、ChatGPTは学習に使用した時期までの知識しか知りません。
今回は大丈夫でしたが、最新技術に関する資格試験の場合はChatGPTに問題を作ってもらうことが難しいかもしれません。

### 解説が正しいとは限らない
あくまでAIなので問題文や解答が100%正しいとは限りません。出力された内容を鵜吞みにしないよう注意が必要です。
とはいえ、実際に使用してみてあからさまに嘘をつかれることはありませんでしたし、ChatGPTが出力した内容が本当かどうかを改めて調べることで、より出題内容の理解を深めることができました。

## おまけ
おかげさまでで無事にE資格に合格することができました。
次に別の資格を受験する際も、またChatGPT先生に頼ると思います。
ABC322振り返り（A~C）

AtCoder Beginner Contest 322
https://atcoder.jp/contests/abc322

# A問題
A,B,C全てを比較するのではなく、`S[i:i+3] == "ABC"`とすればよかったです。
```python
N = int(input())
S = input()

pos = -2
for i in range(N-2):
    if S[i] == 'A' and S[i+1] == 'B' and S[i+2] == "C":
        pos = i
        break

print(pos+1)
```
https://atcoder.jp/contests/abc322/submissions/46060664

# B問題
starswithとendswithを思いつきました。
ただ、出力周りが汚くなってしまいまいた。

```python
N, M = map(int, input().split())
S = input()
T = input()

a1 = T.startswith(S)
a2 = T.endswith(S)

if a1 and a2:
    print(0)
elif a1 and not a2:
    print(1)
elif not a1 and a2:
    print(2)
elif not a1 and not a2:
    print(3)
```
https://atcoder.jp/contests/abc322/submissions/46070226

# C問題
これでいいのか？と思いながら提出したらACでした。
日付を0-indexedにして、現在の日と差を取るだけでした。

```python
N, M = map(int, input().split())
A = [x - 1 for x in map(int, input().split())]

# print(A)

pos = 0
for i in range(N):
    print(A[pos] - i)
    if i == A[pos]:
        pos += 1
```
https://atcoder.jp/contests/abc322/submissions/46077272

# 振り返り
## Keep
C問題まで15分で解けたのがよかったです。
コンテスト中にランキングを見る癖をつけていたので、C問題とD,E問題の崖に気づくことができました。

## Problem
D問題をマス目の濃淡で解決しようとしたが、コマの反転現象を解決できず間に合いませんでした。
ちなみに書いたコードはこれです。

```python
P = []
for i in range(3):
    dark = 0
    light = 0
    for i in range(4):
        p = input()
        for j in range(4):
            if p[j] == "#":
                if (i + j) % 2 == 0:
                    dark += 1
                else:
                    light += 1
    P.append((dark, light))

flag = False
for msk in range(1 << 3):
    sum = 0
    for i in range(3):
        if msk & 1 << i:
            sum += P[i][0]
        else:
            sum += P[i][1]
    if sum == 8:
        flag = True

if flag:
    print("Yes")
else:
    print("No")

```

# Try
途中かE問題の正答数が伸びていたので、そちらに切り替えてもよかったかもしれません。
ただ、結果を見ると動的計画法を使う問題だったので解けたか分かりませんが・・・
【GAS】forEachがいつの間にか非推奨だった件

# はじめに
弊社では定期実行される処理にGAS（Google Apps Script）を使用しているのですが、放置しているといつの間にか動かなくなっていたりするので定期的にチェックするようにしています。
その際に一部修正が必要で直していたのですが、forEachがいつの間にか非推奨になっていて少し調べたので備忘録的に残しておこうと思います。

# forEachが非推奨、、、
タイトルの通りなのですが、どうやら一年くらい前から非推奨になっていたようですね。
とても便利な印象のforEachですが、GASでは嫌悪されているようです、、、
forEachの中ではbreakやcontinueといった処理が使えないのが嫌悪感の一端を担っていそうですね。

# forEachの代わりにforを使おう
名残惜しいですが、forEachが非推奨ということでもう使えないので、forを積極的に使うことにします。
forを使用するとなるとその使い分けが悩ましいところですが、for ofは配列からデータを取り出したいときに用いることが多い一方、for in文はオブジェクトからデータを取り出したいときに用いることが多い印象なのでこの使い分けを基本として選択していくのが良さそうです。

# さいごに
またKotlinでサーバー側の対応を行うことになりそうです。