OmniAICreator/Qiita-1.07M huggingface dataset:
[Dify] v0.6.11でリリースされた目玉機能「Webサイトから同期」と「ワークフローにメモ追加」を解説


## はじめに

今回はリリース機能を一部まとめてみました。
全リリース内容は以下を参照してください。
https://github.com/langgenius/dify/releases/tag/0.6.11

リリースのアナウンスはDiscordに入っているとめちゃくちゃ気づきやすいのでおすすめです！
Discordは[こちら](https://discord.gg/FngNHpbcY7)

では初めていきます。

## Webサイトから同期

Webサイトから同期の機能はみなさん待望の機能ですね！
**特定のURLを入力すると、そのURLからいい感じにサイト内をクロールし、内容をベクトルDBに格納しておく機能です！**
これがあることでLLMが知らないような最新の情報などを回答するようなRAGを構築するのがめちゃくちゃ楽になりますね！
LangGraphとか最近出てきてめちゃくちゃ使われるツールなどはこれでめちゃくちゃ捗りますね。
では使い方解説です。

1. FireCrawlの設定に移動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/9d33cd20-d6fb-791a-5d76-a4a89d4a7450.png)

2. APIキーを設定する。
基本はAPIキーの設定だけで大丈夫です！FireCrawlをセルフホスティングしている場合はBaseURLが必要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/d9e7450f-7762-b70e-01d7-5e5fce7cbe79.png)

3. ナレッジのWebサイトから同期に移動。ベクトルDBに格納したいURLを入力する。
基本的にFireCrawlは入力したURLを元にして、パスを探索していきます。探索する時の設定はオプションから設定できます。
オプションは以下。
- Crawl sub-pages: サブページもクロールするかどうかを指定します。
- Limit: クロールするページの最大数を指定します（必須項目）。
- Max depth: クロールの深さを指定します。
- Exclude paths: クロールしないパスを指定します（例: blog/*, about/*）。
- Include only paths: クロールするパスを指定します（例: articles/*）。
- Extract only main content: メインコンテンツのみを抽出するかどうかを指定します（ヘッダー、ナビゲーション、フッターなどを除外）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/10d0a96a-67ca-b45d-290b-f23d74316268.png)

4.　こんな感じで取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/91e2ba94-32e1-0370-a2a3-ee479df31016.png)

## ワークフローにメモ追加
正直これはすぐには使わなさそうな機能です。
ただチームでDifyを使う時や、社内でDifyを使う時などは重宝されそうです！
使い方は簡単。以下の画像のようにメモを追加ボタンをクリックするだけ！
書き心地は普通のマークダウンエディターなので良いです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/64cadc97-7ab9-e512-7437-1c4750920479.png)


## 他のアップデート
GPT-4oでまとめさせました。
### Model Support
- Jina: Jina-CLIP-v1モデル対応。
- Zhipu: GLM4新モデルとZhipu embedding-2追加。
- ERNIE-4.0-8K-Latest: ERNIE-4.0-8K-Latest対応。
- Doubao: Doubao LLMの機能呼び出し対応。
- Hunyuan: Hunyuan LLMモデル対応。
- SiliconFlow: SiliconFlow対応。
- Novita.ai: Novita.aiをモデルプロバイダーとして追加。

### 🛠️ ツール
- DuckDuckGo: 画像検索、翻訳、AIチャットツール追加。
- Feishu: 多次元表操作ツール追加。

### 🗄️ ベクターデータベース
- TiDB Vector: TiDB vector対応。
- Chroma Vector Store: Chroma vector store対応。
- Tencent Vector DB: Tencent vector DB対応。

### ☁️ AWS
- EKS Pod Identity: boto3ライブラリをEKS Pod Identity対応にアップグレード。
- IAM Role for Bedrock: IAM Role for Bedrock使用可能に。
- AWS S3 IAM Check: AWS S3 IAMチェック追加。

### 🏗️ APIサービスインフラ
- Poetry Support: Poetryビルドツール対応。
- 次バージョンでpipは主要パッケージ管理ツールから除外予定。
- Poetry in CI: CIジョブで依存関係インストールにPoetryをデフォルト使用。
- Pydantic Migration: バリデーションをPydantic 1.xから2.xに移行。

### その他の強化
- Editor User Permission: 新しい編集者ユーザーパーミッションプロファイル追加。
- Memory Messages Limit: デフォルトのメッセージ数制限を無限に設定。
- DOCX Image Handling: DOCX画像抽出時の外部画像処理改善。
- Dataset Delete Endpoint: データセット削除エンドポイント追加。
- Knowledge Retrieval: データセットクエリをバッチ処理で知識検索性能を最適化。
- Jina Tools: APIキー、プロキシサーバー、キャッシュバイパスパラメータ追加。
= HTTP Request Fix: HTTPリクエストのDELETEメソッドが動作しない問題を修正。
Spring Bootでのエラーハンドリング--@RestControllerAdviceのテスト方法--

# はじめに
Spring BootのRestControllerAdviceを利用して、アプリケーション全体でエラーハンドリングを一元化することができます。
[参考](https://qiita.com/only/items/de21656f72e2f7259c33)
この実装に対してのテストが書きたくなったので
RestControllerAdviceのテスト方法について詳しく説明します。

### RestControllerAdviceの設定
まず、RestControllerAdviceの基本的な設定を確認します。以下は、簡単な例です。

```kotlin
@RestControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(value = [CustomException::class])
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handleCustomException(ex: CustomException): ErrorResponse {
        return ErrorResponse("Custom error occurred", ex.message)
    }
}

data class CustomException(val message: String) : RuntimeException(message)

data class ErrorResponse(val error: String, val message: String?)
```

この例では、CustomExceptionがスローされたときにHttpStatus.BAD_REQUESTでエラーレスポンスを返します。

### テスト用のエンドポイントの作成
次に、RestControllerAdviceをテストするためのエンドポイントを作成します。

```kotlin
@Profile("test")
@RestController
class TestController {
    @GetMapping("/test")
    fun testEndpoint() {
        throw CustomException("Test error")
    }
}
```
このコントローラでは、/testエンドポイントにアクセスするとCustomExceptionがスローされます。

### テストの作成
次に、RestControllerAdviceのテストを作成します。テストにはMockMvcとmockkを使用します。


```kotlin:エラーハンドリング確認用コントローラーのテスト
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

@ExtendWith(SpringExtension::class)
@WebMvcTest(controllers = [TestController::class, GlobalExceptionHandler::class])
class GlobalExceptionHandlerTest {

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Test
    fun `should return BAD_REQUEST for CustomException`() {
        mockMvc.perform(get("/test"))
            .andExpect(status().isBadRequest)
            .andExpect(jsonPath("$.error").value("Custom error occurred"))
            .andExpect(jsonPath("$.message").value("Test error"))
    }
}
```


上記のテストコードでは、MockMvcを使用して/testエンドポイントを呼び出し、CustomExceptionがスローされたときのレスポンスを検証しています。このテストを実行することで、RestControllerAdviceが正しく動作していることを確認できます。
またTestControllerClassに
```
@Profile("test")
```
を付与することでテスト時のみに読み込まれるAPIになるので本番環境で公開されないので安心です。

## まとめ
Spring BootのRestControllerAdviceを使用することで、エラーハンドリングを簡単に一元化できます。この記事では、その設定方法とテスト方法について説明しました。正しいテストを行うことで、アプリケーションの信頼性を向上させることができます。
課題（014）ー2

お疲れ様です。

先日の続きを進め、先ほど課題提出をして参りました:raised_hand:
htmlは指定通りに完了しておりましたが、cssが最後までできていませんでしたが、残りも数項目であったため、30分ほどでできました。
<br>
![2024-06-15 225058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/bdf44e7b-b4ea-f86b-cd31-aa64be1f1564.png)

![2024-06-15 225605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/572015c0-42dc-03fd-e163-b75a352689d5.png)

![2024-06-15 225213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/01b1fd09-df85-0a0b-4509-d122e64abdd7.png)
<br>
上記の内容で提出して参りましたが、今回は文字に影をつける箇所以外、特につまずくこともなかったなという印象です。この辺りは理解できているようです。
結果は明日にでも確認しようと思います:smiley:
<br>
次回からはflexboxを使って、見本通りに幾何学模様を作って提出するという内容です。
このあとにjsの勉強をするため、html/cssはここまでにして、また明日から取り組んでいきます。
ARKit FaceTrackingが使えるiPhone, iPadの機種を調査しました

Apple公式情報によれば、ARKitが使えるOSバージョンの記載はありますが、使える機種については情報がありません。

https://developer.apple.com/documentation/arkit/arkit_in_ios/content_anchors/tracking_and_visualizing_faces

レガシー機種をどこまでサポートするのか、対応している, していない機種の境目はどこかを知りたかったので調査しました。

---

# 対応,非対応に影響しそうな項目

1. TouchID vs FaceID
直感的にわかりやすいところですが、FaceIDで認証している機種は機能として顔の形状をとらえることができると容易に予想できるので、FaceTracking対応していそうです。

FaceID対応機種は以下の通りで、iPhone X 以降と、iPad Proが対象になります。
逆にFaceIDでない機種は、iPhone X以前の機種、iPhone SE, iPad, iPad mini, iPad Airです。

https://support.apple.com/ja-jp/102854

2. TrueDepthカメラの有無

こちらの情報ではiPhone8はTrueDepthカメラがついてないから使えないぜー的な情報ががありました。TrueDepthカメラも要件になりそうです。

https://support.apple.com/ja-jp/102854

3. チップ番号とNeaural Engine

A11からNearal Engineが搭載されています。

https://ja.wikipedia.org/wiki/Apple_A11

FaceIDでなく、TrueDepthカメラがなくともARKitのFaceTrackingが使える機種がある！（iPhone SE2）って気づいたのが今回の調査の発端だったりします。


---

# 調査方法

実機上で、ARConfiguration.isSupported を参照すると対応いているかわかりそうです。

https://developer.apple.com/documentation/arkit/arconfiguration/2923553-issupported

---

# 結果

サポートしていなかった機種
| デバイス | チップ | Neaural Engine | FaceID |TrueDepth| 調べた機種OSバージョン |
|:-:|:-:|:-:|:-:|:-:|:-:|
|iPad（第5世代）|	A9 | ×| ×	| ×	| 14 |
|iPad (第7世代）| A10 |× |× | ×	|14 |
| iPhone8 |A11 |◯ |× | ×	|16 |
| iPad Air (第3世代）|A12 |◯	| ×| ×	 | 15|
| iPad Mini (第５世代)|A12 |◯ |×| ×	 |16 |

サポートされている機種

| デバイス | チップ | Neaural Engine | FaceID |TrueDepth| 調べた機種OSバージョン |
|:-:|:-:|:-:|:-:|:-:|:-:|
|iPhone X | A11 |◯ |	◯ |◯ 	 |16 |
|iPhone12 Pro Max |A12 |◯ |◯ |◯ |15|
|iPad Pro (第１世代)|A12X|◯|◯|◯|14|.2
|iPhoneSE2| A13 | ◯ | × | × |15 |
|iPad Mini (第６世代) | A15 |◯ |×|×|15|

---

# 結論

なんとなく見えてきた結論ですが、
* A9チップ以前の機種はARKit FaceTrackingは使えない
* A11〜A12Xチップは、FaceIDが使えてTrueDepthがついている機種なら使える
* A13以降は使える

というかんじになりました。
全機種網羅的に調べたわけではないので、もしかしたらこの条件に当てはまらないケースがあるかもですが、
何かのご参考なれば幸いです。
ABC358をPythonで（A～E）

CodeQUEEN 2024 予選 (AtCoder Beginner Contest 358)の解答等のまとめ

https://atcoder.jp/contests/abc358



# A問題
https://atcoder.jp/contests/abc358/tasks/abc358_a

問題文どおりにする
```python:A
print("Yes" if input() == "AtCoder Land" else "No")
```

# B問題
https://atcoder.jp/contests/abc358/tasks/abc358_b

直前の人がいつ終わるかが解ればいいので
直前に回答したものを記録すればいい
```python:B
n, a = map(int, input().split())
t = list(map(int, input().split()))

last = 0
for t_i in t:
    print(max(t_i, last) + a)
    last = max(t_i, last) + a
```

# C問題
https://atcoder.jp/contests/abc358/tasks/abc358_c

bit全探索
bitで行くパターンを決めて、そのパターンですべての味が手に入れられるか調べる
```python:C
n, m = map(int, input().split())
s = [input() for _ in range(n)]

ans = m + 10
for bit in range(1 << n):
    store = []
    for i in range(n):
        if bit >> i & 1:
            store.append(i)
    data = [0] * m
    for s_i in store:
        for j, s_j in enumerate(s[s_i]):
            if s_j == "o":
                data[j] = 1
    if data == [1] * m:
        ans = min(ans, len(store))

print(ans)
```

# D問題
https://atcoder.jp/contests/abc358/tasks/abc358_d

AとBをまとめて多いほうから考える（同数の時はAが先になるようにする）
Aがきたときは、スタックに入れる
Bがきたときは、スタックの最後の値を取得する
（なぜならスタックの最後に入っているのは、まだ選択していないものの中で買う条件を満たす最小のものになるから）
途中でスタックが空の状態でBが来たら条件は必ず満たせないので-1を返す
```python:D
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

data = []
for a_i in a:
    data.append([a_i, True])
for b_i in b:
    data.append([b_i, False])

data.sort(reverse=True)

ans = 0
stack = []
for d_i, is_gift in data:
    if is_gift:
        stack.append(d_i)
    else:
        if stack:
            s_i = stack.pop()
            ans += s_i
        else:
            exit(print(-1))

print(ans)
```
# E問題
https://atcoder.jp/contests/abc358/tasks/abc358_e

メモ化再帰
$i$文字目以降でで$k$文字を埋める時の組み合わせは
$i$文字目を$c_i$個使うとしたとき、どこを埋めるかの組み合わせ$ \times$ $i+1$文字目以降で$k - c_i$文字埋める組み合わせ
を0から$min(k, c[i])$までの和が答えになる

```python:E
class combination:
    # nが小さい(10**7未満)でないと厳しい
    def __init__(self, N, mod):
        self.fact = [1, 1]
        self.factinv = [1, 1]
        self.inv = [0, 1]

        for i in range(2, N + 1):
            self.fact.append((self.fact[-1] * i) % mod)
            self.inv.append((-self.inv[mod % i] * (mod // i)) % mod)
            self.factinv.append((self.factinv[-1] * self.inv[-1]) % mod)

    def cmb(self, n, r):
        if (r < 0) or (n < r):
            return 0
        r = min(r, n - r)
        return self.fact[n] * self.factinv[r] * self.factinv[n - r] % mod


k = int(input())
c = list(map(int, input().split()))
mod = 998244353

C = combination(1010, mod)

memo = [[-1] * 1010 for _ in range(26)]


def dfs(i, k):
    global memo
    if i == 26:
        return 1 if k == 0 else 0
    elif memo[i][k] >= 0:
        return memo[i][k]
    else:
        res = 0
        for c_i in range(min(c[i], k) + 1):
            res += dfs(i + 1, k - c_i) * C.cmb(k, c_i) % mod
        memo[i][k] = res
        return res


ans = 0
for k_i in range(1, k + 1):
    used = 0
    ans += dfs(0, k_i)
    ans %= mod

print(ans)
```
行末にあると警戒したくなる文字


```C++:foo()関数がなくてもコンパイル可能
int main()
{
  // foo表
  foo();
  return 0;
}
```

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226677/097db145-b11e-93e1-734b-a051b6b388c4.png)

flycheck は foo の未定義を検知していますが、clang++ でのコンパイル && 実行

```console:
clang++ -W a.cpp && ./a.out
```

は "Compilation:exit [0]" で正常終了しています。

これは、コンパイル オプション "-Wcomment" を付けると、文字「表」は改行を無視するコード

```console:
$ clang++ -Wcomment a.cpp
a.cpp:3:10: warning: multi-line // comment [-Wcomment]
  // foo<95>\
            ^
1 warning generated.
```

```C++:この2行はコメント
  // foo表
  foo();
```

として扱われることが分かります。同様の文字は

```text:S-JISではエスケープ文字 "\\" 扱いになる場合がある
 ― ソ 十 表 能 申 貼 噂 浬 欺 圭 構 蚕 曾 箪 暴 予 禄 兔
 喀 媾 彌 拿 杤 歃 濬 畚 秉 綵 臀 藹 觸 軆 鐔 饅 鷭 Ы
```

です。昔(主に前世紀)、「ソ」にはだいぶやられました。

ナントカの法則ではないけど、遭遇する可能性がゼロでないものは何故か出会してしまうので(運がいいのか悪いのか…)、無用なトラブルを避けるため行末に "." を付けるようにしています。

```C++:
// コメント.
```
DockerでGinのコンテナを立てようとしたらエラーが出た。

# エラー内容

docker composeでコンテナを立てようとしたら
```
docker compose up --build

[+] Building 0.0s (1/1) FINISHED                                                                     docker:desktop-linux
 => [server internal] load build definition from Dockerfile                                                          0.0s
 => => transferring dockerfile: 200B                                                                                 0.0s
failed to solve: dockerfile parse error on line 13: unknown instruction: CMD["./main"]
```

とエラーが出てしまいました。
これはCMDの部分の記述がおかしいので、dockerfileが解析できないというエラーだそうです。

# 解決方法

CMDの空いたにスペースを入れる必要がありました。
```
CMD ["./main"]
```

とっても簡単なミスでした...
ABC358振り返り

ABC358開催日だったので適当に参加した結果をまとめる

https://atcoder.jp/contests/abc358

結果はABCDの4完
いままで3完しかしなかった壁を越えることができて嬉しい

A,Bについてはただやるだけなので省略するとしてC以降の感想を書いていく

# C
bit全探索すれば行ける気はしたがやり方がわからないので
色々検索して出てきたのをコピペしてアレンジ
今度からこれをテンプレにしたいね

## ソースコード

```python:main.py
import sys
from itertools import product
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

p = {"o":1,"x":0}

def prod_or(g):
    x = 0
    for f in g:
        x |= f
    return x
def main():
    N, M = rLI()
    S = [rS() for _ in range(N)]
    target = sum( 1 << i for i in range(M))
    g = [sum(p[k] << i for i, k in enumerate(s)) for s in S]
    ans = N
    for k in product((0, 1), repeat=N):
        chk_g = [g[i] for i, bit in enumerate(k) if bit]
        if prod_or(chk_g) == target:
            ans = min(ans,len(chk_g))
    print(ans)

if __name__ == '__main__':
    main()

```

# D

尺取り法的なやつ使えば行けそうだと思い適当に実行
なんかうまく行った感じがしたので提出したらACでちゃった

今まで解けなかったD問題なのにこんなにあっさり解けていいの？

## ソースコード

```python:main.py
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

def main():
    N, M = rLI()
    A = rLI()
    B = rLI()
    A.sort()
    B.sort()
    ans = 0
    j = 0
    for i,a in enumerate(A):
        if a >= B[j]:
            ans += a
            j += 1
            if j == M:
                print(ans)
                break
    else:
        print(-1)
if __name__ == '__main__':
    main()

```

# E

色々考えた結果、DP使えばいけそうな気がしたけど
どうテーブルをいじればいいかよくわからなくて時間切れ

# F

Eやる前にチラ見したけど
迷路の出力むずくない？

# G

ここもEやる前にチラ見
値が最大のところにいって経路探索すれば行ける気はしたが
そもそもそこら辺のアルゴリズムまだ使いこなせないので撤退

# まとめ

とりあえずAtCoder Daily Trainingとかで頑張った成果を出せた気がしてうれしい

これからは4完を安定させていきたい
Ginの環境構築をdockerでやってみた

# はじめに
Goの有名なフレームワークの一つであるGinを触ってみたいと思い、dockerで環境構築してみました。
# Dockerでの環境構築

## 1.Ginのインストール
まず、`Dockerfile`を記述します。

```Dockerfile
FROM golang:latest

WORKDIR /code
```

`docker-compose.yml`を記述します。
```docker-compose.yml
services:
  server:
    build: .
    container_name: gintest
    tty: true
    volumes:
      - .:/code
    ports:
      - 8080:8080
```

一度、`go.mod`を作成するためにイメージを作成します。
```
docker compose build
```

ここから一旦コンテナを起動して、go.modを作成します。
```
docker compose run --rm server sh -c "go mod init gintest"
```

ginをインストールします。
```
docker compose run --rm server sh -c "go get github.com/gin-gonic/gin"
```

## 2.Ginが機能するか確認
`Dockerfile`を書き直します
```
FROM golang:latest

WORKDIR /app

COPY go.mod go.sum ./

RUN go mod download

COPY . .

RUN go mod tidy

RUN go build -o main .

CMD ["./main"]
```

`main.go`を記述します。
このコードでは、アクセスできたら`{"message": "Hello, Gin!"}`とjsonが表示されるようにしています。
```main.go
package main

import (
	"github.com/gin-gonic/gin"
)

func helloWorld(c *gin.Context) {
	//リクエストが成功した場合に、JSONを返す
	c.JSON(200, gin.H{
		"message": "Hello, Gin!",
	})
}

func main() {
	//*gin.Engineをrに入れる
	r := gin.Default()
	//エンドポイントの指定
	r.GET("/", helloWorld)
	//サーバーを起動
	r.Run()
}

```
:::note
*gin.Engineは、エンドポイントやミドルウェアを登録する際に使うそうです。
:::

:::note
*gin.Contextは、リクエストやURLのパラメーターにアクセスする際に使う構造体です。
[こちら](https://qiita.com/SDTakeuchi/items/7f6314d166580a06d36c)の記事を参考になるかなと感じました。
:::

ここまでできたら、下のコマンドでイメージの再作成とコンテナの立ち上げを行います。
```
docker compose up --build
```

http://localhost:8080

にアクセスして、

![スクリーンショット 2024-06-15 3.22.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/a3b32932-c080-10de-81a2-fd8dd9b930f4.png)

Ginの環境構築ができました。

# 感想

今までDjangoをかじっていましたが、結構構築の仕方が違うなと感じるところが多く難しく感じました。

ただ*ginEngineや*ginContextの理解が奥深いと感じたので、これから勉強してみようかなと感じました。
Dockerで簡単なGOの環境構築してみた

# はじめに
Goを触りたいと感じることが多くなり、Dockerで簡易的に環境構築してみようと思ったので、やってみました。

# Dockerで環境構築
`Dockerfile`は以下のように記述します。
```Dockerfile
FROM golang:latest

WORKDIR /app

COPY . .

RUN go mod init myapp
```

`docker-compose.yml`は以下のように記述します。
```docker-compose.yml
services:
  app:
    build: .
    container_name: gotest
    tty: true
    ports:
      - 80:8000
    volumes:
      - .:/app
```

:::note
tty:trueとつけるとコンテナを永続させることができるので、`docker exec`コマンドが使いたい場合はつけたほうがいいです。
:::

`main.go`にHello Dockerと表示させるスクリプトを書いてみます.
```main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello Docker")
}

```
:::note
fmtを使わずとも`Println()`のみでも出力はできます。ただfmtを使って出力している方が多いので統一しておいたほうがいいかもしれません。（自分はそう感じました)
:::

以上の三つのフォルダが
```
.
├── Dockerfile
├── docker-compose.yml
└── main.go
```
となっていたら準備完了です。

# 実行
ターミナルで以下のコマンドを入力して、ターミナルにHello Dockerを表示させてみます。
```
docker exec gotest go run main.go
```
すると
```
Hello Docker
```
と出力できました。
ReactをAmazon S3とCloudFrontでデプロイし、FastAPIと接続する方法

## 前提条件
AWSアカウントを持っている
AWS Management Consoleにアクセスできる
ドメインを取得済みで、Route 53で管理している
FastAPIとPostgresがEC2でデプロイ済み
## ステップ 1: Reactアプリケーションのビルド
Reactアプリケーションのビルド:
Reactプロジェクトのディレクトリで以下のコマンドを実行します。

```bash
npm run build
```
これにより、buildディレクトリにアプリケーションの静的ファイルが生成されます。
ステップ 2: Amazon S3バケットの作成と設定
S3バケットの作成:

AWS Management Consoleにログインし、S3サービスに移動します。
「Create bucket」をクリックし、新しいバケットを作成します。バケット名はグローバルに一意である必要があります。
バケット名を指定し、リージョンを選択して「Create」をクリックします。
### バケット設定:

作成したバケットを選択し、「Properties」タブに移動します。
「Static website hosting」を選択し、「Use this bucket to host a website」を有効にします。
「Index document」に index.html を入力し、「Error document」に index.html を入力します。
「Save」をクリックします。
### バケットポリシーの設定:

「Permissions」タブに移動し、「Bucket Policy」を選択します。
以下のバケットポリシーを追加し、すべてのオブジェクトが公開されるようにします。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
```
### 静的ファイルのアップロード:

Reactアプリケーションのビルド成果物（buildディレクトリの内容）をS3バケットにアップロードします。
「Upload」をクリックし、ファイルを選択してアップロードします。
## ステップ 3: CloudFrontディストリビューションの作成
CloudFrontディストリビューションの作成:

AWS Management ConsoleでCloudFrontサービスに移動します。
「Create Distribution」をクリックし、「Web」を選択します。
「Origin Domain Name」にS3バケットのドメイン名を入力します（例：your-bucket-name.s3.amazonaws.com）。
「Default Cache Behavior Settings」で「Viewer Protocol Policy」を「Redirect HTTP to HTTPS」に設定します。
「Distribution Settings」で「Alternate Domain Names (CNAMEs)」にカスタムドメイン名を使用する場合は入力し、証明書を設定します。
「Create Distribution」をクリックします。
### カスタムエラーページ設定（オプション）:

「Error Pages」タブを選択し、「Create Custom Error Response」をクリックします。
「HTTP Error Code」を 404 に設定し、「Customize Error Response」をチェックします。
「Response Page Path」に /index.html を設定し、「HTTP Response Code」を 200 に設定します。
「Create」をクリックします。
## ステップ 4: Route 53でドメイン設定
Route 53でホストゾーンを作成:

AWS Management ConsoleのRoute 53に移動し、「Create Hosted Zone」をクリックしてドメインを設定します。
Aレコードの追加:

ドメインのAレコードを作成し、CloudFrontディストリビューションのドメイン名を指します。
## ステップ 5: ReactアプリケーションとFastAPIの接続
ReactアプリケーションでFastAPIエンドポイントを使用:

Reactアプリケーションのコードで、FastAPIエンドポイントを使用するAPI呼び出しを設定します。
例:

```javascript
const fetchData = async () => {
  const response = await fetch('https://your-ec2-public-dns/api-endpoint');
  const data = await response.json();
  console.log(data);
};

useEffect(() => {
  fetchData();
}, []);
```
CORS設定:

FastAPIでCORSを設定して、Reactアプリケーションからのリクエストを許可します。
FastAPIアプリケーションに以下を追加します。

```python
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "https://your-react-app-domain",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```
## まとめ
これで、ReactアプリケーションがAmazon S3とCloudFrontを使ってデプロイされ、Route 53で管理されているドメインに接続されます。ReactアプリケーションはFastAPIエンドポイントにアクセスし、データを取得できます。これにより、AWSの各サービスを統合して、スケーラブルでセキュアなWebアプリケーションを構築できます。
いまさらIPA試験に取り組んだハナシ。

# 先日、情報セキュリティマネジメント試験に合格しました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/c88a6c06-8408-796c-33ef-2d09a1e9d463.png)
# 今回情報セキュリティマネジメント（SG）試験に挑戦した理由
- 国家試験の資格が欲しかった。
    - ベンダー資格を持っていても定期的な更新があったり、所詮ベンダー試験という印象があってちゃんとした国家試験に挑戦しておきたかった。（ベンダー試験は受験料が馬鹿にならん・・・金の亡者ですわ汗）
- 基本情報（FE）試験の足掛かりにしたかった。
    - 駆け出しのころFE試験に挑戦したものの、文系出身のため数学の問題が大半を占めるこの試験はとても苦痛だった。CBT試験がない頃だった当日は午前でバックレ。当時FEより下はiパスしかなかったためSGはリベンジの足掛かりになったと思う。（既にFE学習を進めているが、範囲も少し被っているようです）
# 対策
以下、使用テキスト・学習サイトになります。

https://www.seshop.com/product/detail/25883

https://www.sg-siken.com/

2ヶ月合格で予定を立てた。
まずテキストをサラッと１周。
あとは過去問道場をスキマ時間を見つけて全問ぶん回し、不明点があればテキストを確認。まず知識問題だけを完璧にし、苦手な計算問題に関しては残り2週間前に集中して取り組むことにした。
科目Bにおいては1週間前から対策を開始。どういう形式なのか慣れておく程度にとどめた。内容的には科目Aの応用になっているためだ。
以下、注意点。

:::note warn
過去問を解くときは他の選択肢も必ず確認しよう！！
:::
:::note warn
過去問ばかりに頼らないこと！！
:::
# 本番
会場が分からない・・・
いつも使っている会場が結構埋まっていたので違う場所にて予約。
余裕をもって出発したがそれでも怪しくタクシーで向かうことに💦
CBT形式は既になれていたものの、IPA試験はレイアウトが全然違う。
ベンダー試験が見にくいため、綺麗すぎて少々面食らうが大したことはない。
思っているより見直しに時間をかけることができず、時間いっぱいまで試験に臨んだ。

その場でスコアが表示され、650点/1000点。
思っているより科目Aに手ごたえなかった故の点数。
科目Bのほうが自信あったため、何とかボーダーを超えることができたと思う。
# 最後に
受けてみて、まだまだセキュリティについての知識が不足していると痛感した。
今年中にFEのリベンジを果たしたいという思いとともに、
最終的にセキスぺを取得したい気持ちが強くなった。
SG→FE→AP→SCの順で頑張っていきたい。

PS.真偽のほどは不明だが、どうやら特定の現場だと一定数のFE取得者を確保したり管理者は応用情報（AP）持ちである必要があるとかないとか？頑張って学習を継続していきたい。
【論文読み】Asynchronous Methods for Deep Reinforcement Learning

# はじめに
元論文: Asynchronous Methods for Deep Reinforcement Learning
著者: Volodymyr Mnih, Adrià Puigdomènech Badia, Mehdi Mirza, Alex Graves, Timothy P. Lillicrap, Tim Harley, David Silver, Koray Kavukcuoglu

https://arxiv.org/abs/1602.01783

引用数1万超え．

# 概要

深層強化学習とは強化学習と深層学習を組み合わせたもので，表現力が増すなどの利点があります．

### 解決したい課題
経験リプレイ (過去のエージェントのデータを保存しておいて学習に使用する技術) は，学習を安定させることができるため使われてきました．

しかしメモリを大量に使用するという問題点があります．

### アイデア
エージェントを非同期的に学習させます．これにより，メモリ使用量を削減しつつ学習が安定するらしいです．

# 提案アルゴリズム

## 非同期1ステップQ学習（Asynchronous One-Step Q-learning)

各エージェントが独立してQ学習を行い，報酬を基に行動を改善します．

ステップごとに勾配が計算され，dθとして蓄積されていきます．
一定ステップごとに，蓄積された勾配を使用して共有パラメータを更新します．

### アルゴリズム
<img width="400" alt="Algorithm 1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/59c0e8e5-3602-741e-3b28-b1da56daf6fc.png">


## 非同期1ステップSarsa（Asynchronous One-Step Sarsa)
非同期1ステップQ学習とほぼ同じですが，Q学習の代わりにSarsaを用いたものです．

## 非同期nステップQ学習（Asynchronous n-step Q-learning)
一度にnステップを考慮して学習し，効率を上げます．

勾配を一定ステップ分蓄積するのは非同期1ステップQ学習でもしていました．
こちらではn回行動を決定してn回状態を更新し，その結果から勾配を計算することで，n回の行動をまとめて計算し効率化しています．

<img width="600" alt="Algorithm S2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/25f212ff-ca4f-59cf-a9d7-12fbefde2bdc.png">

## 非同期アドバンテージアクタークリティック（Asynchronous Advantage Actor-Critic, A3C)
行動と価値の両方を学習し，より賢い行動を選べるようにします．

学習すべきものを価値関数と行動を決めるポリシーに分割し，ポリシーを間接的ではなく直接的に学習させます．

<img width="600" alt="Algorithm S3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/8dafd470-7d31-ca68-4d5a-79e960c8d2ff.png">

# さいごに

実験では既存手法に比べてかなりスピードアップしており，高性能も出していました．

A3Cが良い結果を出し，1-stepよりn-stepの方が良い結果を出すようです．

A3Cでポリシーを価値関数と分けて明示的に学習させるというのは，単純ですが確かに効果が高そうで，広く活かせそうに思います．
n-stepが1-stepより効率だけでなく最終的な性能でも勝っているのは一見意外ですが，ある程度まとめて学習することで，ノイズを過剰に学習せずに済んだのかもしれません．
Dockerを使用してAWS Lambda Layerを作成するシェルスクリプト作ったよ

Dockerを使用してAWS Lambda Layerを作成する方法
AWS Lambdaで使用するライブラリを簡単にLayerとして作成する方法をご紹介します。この手順では、Dockerを使用してPythonライブラリをインストールし、それをLayerとしてパッケージ化します。

## 前提条件
そもそも自作しなくてもlayerがAWS公式から準備されてないか確認します。
また有志の方がまとめてくれてる
https://github.com/keithrozario/Klayers/tree/master
このリポジトリで自分の環境にあったlayerがあればそれを使うのが手っ取り早いです。

上記でもないマイナーなライブラリなどをlayerにしたい時、以下の手順で簡単にできるように
シェルスクリプトを作りました。
※pythonにしか対応してません。

Dockerがインストールされていることが前提です！

## 手順

### 1. 必要なフォルダとファイルの準備

まず、任意のフォルダに移動し、Layerに含めたいライブラリ名を`requirements.txt`ファイルに記述します。

```text:requirements.txt
requests_toolbelt
```

次に、以下のシェルスクリプトを`create_layer.sh`として保存します。
pythonバージョンは各自の環境に合わせて編集してください。

```sh:create_layer.sh
#!/bin/bash

# シェルスクリプトの実行を中止するためのエラーハンドリング
set -e

# Pythonバージョンを変数として定義
PYTHON_VERSION="3.12"

# 必要なフォルダ構成を作成
mkdir -p python/lib/python${PYTHON_VERSION}/site-packages

# Dockerコンテナを使用してライブラリをインストール
docker run -v "$PWD":/var/task "public.ecr.aws/sam/build-python${PYTHON_VERSION}" /bin/sh -c "pip install -r requirements.txt -t python/lib/python${PYTHON_VERSION}/site-packages/; exit"

# ライブラリを含むフォルダをZIPアーカイブに圧縮
zip -r lambda_layer.zip python > /dev/null

# pythonフォルダを消去
rm -rf python

# 完了メッセージ
echo "Lambda Layer ZIP file has been created successfully: lambda_layer.zip"

```

### 2. シェルスクリプトに実行権限を付与

次に、ターミナルで以下を実行しシェルスクリプトに実行権限を付与します。

```sh
chmod +x create_layer.sh
```

### 3. シェルスクリプトを実行

シェルスクリプトを実行して、Layerを作成します。

```sh
./create_layer.sh
```

実行が成功すると、現在のディレクトリに`lambda_layer.zip`ファイルが作成されます。これをAWS LambdaのLayerとしてアップロードして使用します。

ちなみにrequests_toolbeltライブラリの動作確認用のlambda関数は以下みたいな感じです。
```python:requests_toolbelt確認
from requests_toolbelt.multipart import decoder
import json


def lambda_handler(event, context):
    try:
        # デコーダを使用してみる（例として空のバイト列を渡す）
        multipart_data = decoder.MultipartDecoder(b'', 'multipart/form-data; boundary=---BOUNDARY')
        
        # インポートとデコーダの使用が成功した場合
        return {
            'statusCode': 200,
            'body': json.dumps('requests_toolbelt is successfully imported and used.')
        }
    except Exception as e:
        # エラーが発生した場合
        return {
            'statusCode': 500,
            'body': json.dumps(f'Failed to import or use requests_toolbelt: {str(e)}')
        }
```
うまくlayerが作れていたら
ログにrequests_toolbelt is successfully imported and used.　が表示されるはずです。


## まとめ

以上の手順で、必要なPythonライブラリをLambda Layerとしてパッケージ化することができます。
Dockerを使用することで、ローカル環境に依存せずにライブラリをインストールできるのでおすすめです。

ぜひ試してみてください！
デプロイ設計メモ

# 質問

AWSで
ReactはS3とCloudFrontでデプロイ。デプロイしたURLはRoute53と接続(ドメイン取得済み,SSL証明書取得済み)
FastAPIとPostgresはEC2とEBSとでデプロイ。Reactと接続させるようにする。

これを実現したときの1か月分の各サービスでの見積もりを教えて。

# 回答

### 1. Reactのデプロイ (S3とCloudFront)
#### コスト構成
Amazon S3: 静的ファイルのホスティング
Amazon CloudFront: CDN（コンテンツ配信ネットワーク）
Amazon Route 53: ドメインのDNS管理
詳細見積もり
#### Amazon S3:

ストレージ: 1GB (0.023 USD/GB/月)
リクエスト: 100,000リクエスト (0.004 USD/1000リクエスト)
Amazon CloudFront:

データ転送: 100GB (0.085 USD/GB)
Amazon Route 53:

ホストゾーン: 0.50 USD/ホストゾーン/月
DNSクエリ: 1,000,000クエリ (0.40 USD/1,000,000クエリ)
計算：

#### S3ストレージ: 1GB x 0.023 USD/GB = 0.023 USD
S3リクエスト: 100,000リクエスト x 0.004 USD/1000リクエスト = 0.40 USD
CloudFrontデータ転送: 100GB x 0.085 USD/GB = 8.50 USD
Route 53ホストゾーン: 0.50 USD
Route 53 DNSクエリ: 1,000,000クエリ x 0.40 USD = 0.40 USD
合計：0.023 USD + 0.40 USD + 8.50 USD + 0.50 USD + 0.40 USD = 9.823 USD

### 2. FastAPIとPostgresのデプロイ (EC2とEBS)
#### コスト構成
Amazon EC2: インスタンス（t2.micro）
Amazon EBS: ストレージ（16GB 汎用SSD）
データ転送: 1GB/月（外部データ転送）
詳細見積もり
Amazon EC2:

#### インスタンスタイプ: t2.micro
料金: 0.0116 USD/時間（オンデマンド料金）
稼働時間: 730時間
Amazon EBS:

#### ストレージタイプ: 16GB 汎用SSD (gp2)
料金: 0.10 USD/GB/月
データ転送:

料金: 0.09 USD/GB
#### 計算：

EC2インスタンス: 0.0116 USD/時間 x 730時間 = 8.468 USD
EBSストレージ: 16GB x 0.10 USD/GB = 1.60 USD
データ転送: 1GB x 0.09 USD = 0.09 USD
合計：8.468 USD + 1.60 USD + 0.09 USD = 10.158 USD

### 総計
|サービス	|コスト (USD/月)|
|-|-|
|Amazon S3とCloudFront	|9.823|
|Amazon EC2とEBS|	10.158|
|合計|19.981 USD|

### まとめ
ReactアプリケーションをS3とCloudFrontでデプロイし、Route 53で管理する場合の月額費用は約9.823 USDです。FastAPIとPostgresをEC2とEBSでデプロイする場合の月額費用は約10.158 USDです。総計で、約19.981 USD/月になります。

これらの見積もりは一般的な利用量を前提としており、実際のコストは使用状況に応じて変動する可能性があります。また、SSL証明書の料金はAWS Certificate Manager（ACM）を使用して無料で提供されることが多いですが、他のサービスを使用する場合は追加料金が発生する可能性があります。


https://qiita.com/raisack8/items/1a21c3ddc342646717c5

https://qiita.com/raisack8/items/fdeb8336b8c2839c6a91
【認知科学】駆け出しエンジニアを卒業するめに必要なスキル

# どこから駆け出しエンジニアじゃなくなるのかという問い

「初心者」もしくは「駆け出しエンジニア」といわれる方々は、問題解決の場面でどういったスキルが持っていれば、駆け出しではなくなるのか認知科学っぽく視点で考察してみる。

(chatgptの駆け出しエンジニアイメージ、頭からもやし生えている)
![A_novice_engineer_depicted_in_the_style_of_Irasuto.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552182/613220e9-3d2f-d101-63d9-7962fde281cf.jpeg)

## 大きなチャンクで処理するスキル

チャンクとは情報の塊のようなものです。複雑なシステム全体の構造を大きなチャンクとして理解することで、各システムの関係性を紐解き効率良く問題解決を行うスキルです。

また、システムに関わらず課題、問題の構造を大きなチャンクとして処理するスキルは持っていると良い思う。

これは単純に「記憶力」の問題でなく、その場におけるシステム構成やネットワークを意味のある構造として記憶できているかが問われる能力のようです。

以下のリンクの記載が分かりやすくまとまっていました。
[アドリアン・デ・グルートが行った実験](https://www.chessprogramming.org/Adriaan_de_Groot#Chase_.26_Simon)


## スキーマの多さ

スキーマとは、知識の構造化された表現を指します。（ちょっと何言ってるか分かりませんよね。）これは、「レストランに行く」というスキーマに対して、メニューを選ぶ、注文する、食事する、支払いという流れが含まれす。新しいレストランに行ったとして、多くの場合は困らないですよね。よく「引き出しの多さ」のような表現されるスキルですね。

簡単な例をあげると、デバッグするというスキーマがあるとすると、エラーメッセージをみる、原因を切り分ける、修正箇所を特定する、などの一連のステップが含まれます。



## 具体例
初心者の例
新人エンジニアのAさんは、ウェブアプリケーションのパフォーマンスが低下しているという問題に直面しています。Aさんは、データベースクエリが遅いという表面的な症状を見て、クエリの最適化に集中しますが、実際にはバックエンドサーバーの設定ミスが原因であることに気づきません。

専門家の例
ベテランエンジニアのBさんは、同じ問題に直面しています。Bさんは、まずシステム全体のパフォーマンス指標を確認し、データベースクエリが遅いのはバックエンドサーバーの設定ミスによるものだと迅速に特定します。Bさんはすぐに設定を修正し、アプリケーションのパフォーマンスを回復させます。




参考：
[Cognitive Load During Problem Solving:Effects on Learning](https://onlinelibrary.wiley.com/doi/epdf/10.1207/s15516709cog1202_4)
オンプレサーバーで研究室・社内用のGitLab環境を構築する

## 🚀はじめに

　個人利用の際は GitHub を使用していれば、基本的に困ることはないかと思います。しかし、研究室や企業で開発している際、機密性の高い情報は、個人リポジトリにあげにくいですよね。そこで、オンプレサーバーで GitLab (GitHubと非常に似たウェブアプリケーション) を構築する方法を紹介します。


## 🧑🏻‍💻Git環境の用意

　git 環境が整っていることを前提としています。整っていない場合は、インストールしてください。ユーザー名、メールアドレスも設定しておいたほうがいと思います。

Windows: https://www.git-scm.com/download/win
Ubuntu: `sudo apt install git`

## 🐋Dockerの用意

　docker 環境が整っていることを前提としています。整っていない場合は、以下を参考にインストールしてください。docker desktop は個人利用のみ無料なので注意してください。docker engine は無料での商用利用が可能です。

Windows: https://docs.docker.com/desktop/install/windows-install/
Ubuntu: https://docs.docker.com/engine/install/ubuntu/

## 🏙️EEと🏠CEの違い
　GitLab には、EE 版と CE 版があります。CE 版は、MITライセンスで無料での商用利用が可能ですが、EE 版と比べると、一部機能の制限、サポートを受けられない等の制約があります。

CE: https://gitlab.com/gitlab-org/gitlab-foss/
CE-RELEASES: https://gitlab.com/free-releases/gitlab-ce
EE: https://gitlab.com/gitlab-org/gitlab/
参照: https://gitlab-docs.creationline.com/ee/development/licensing.html

## 🦊Local GitLab のデプロイ

　以下のサイトを参考にDockerを利用して GitLab のサーバーを建てます。イメージは、GitLab が公式で公開している Image を使用します。コンテナ化する際は、ホストとポートとデータを紐づけます。ポートの紐づけはコンテナ外からのHTTP接続のために行います。データの紐づけはコンテナを削除してもデータがホストPCに残すために行います。GitLabのバージョンアップへの対応は、基本的にイメージを最新のものに置き換えるだけOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631481/a7c7e357-74ed-58e1-acf4-a0917d88ba88.png)

参考： https://gitlab-docs.creationline.com/ee/install/docker.html
Docker Hub：https://hub.docker.com/r/gitlab/gitlab-ce

#### 1 リポジトリをクローン

　以下のコマンドを実行しリポジトリをでクローンしてください。

```terminal
git clone https://github.com/TakanariShimbo/local-gitlab.git
```

#### 2 .env を作成

　.env_sample を参考に .env を用意してください。

```.env
GITLAB_HOME="./volumes"     # GitLabがデータを保存するディレクトリを指定します
SERVER_IP="XXX.XXX.XXX.XXX" # サーバーのIPアドレスを設定します。"XXX.XXX.XXX.XXX"を実際のローカルIPアドレスに置き換えてください
HTTP_PORT="58080"           # HTTP接続用のポート番号を指定します
SSH_PORT="52424"            # SSH接続用のポート番号を指定します
```

#### 3 docker compose 

　以下のコマンドを実行すれば、サーバーが立ち上がります。立ち上がるまで数分かかるので少々お待ちください。

```terminal
docker compose up -d
```

#### 4 root権限でログイン

立ち上げたサーバーにアクセスするとログイン画面が表示されます。アカウントを作ってもアドミンユーザに承認されないとログインできないようです。初回はrootユーザーでログインする必要があります。

```
username: root
password: check file of .volumes/config/trusted-certs/initial_root_password
```

## 🙇終わりに
　オンプレサーバーで GitLab を構築する方法を紹介させていただきました。是非試してみてください。
 

written by @hmkc1220 @shun15
PCの歴史と操作の変容２

# BASIC搭載PC
前回、パーソナルコンピュータ(PC)の前身であるワンボードマイコンの操作についてご紹介しました。
その時点から約３年後PC-8001というパソコンが発売されました。
このコンピュータ以降のパソコンは、BASICインタープリタが搭載されているPCが販売され始めました。

# BASIC搭載PCの操作
NECのPC-8001を起動するとROM(リードオンリーメモリ)から、マイクロソフト社製のBASICインタープリタが起動するようになっており、BASICの命令を打込む事で操作できるようになりました。

そのためにBASICインタープリタを扱うこと自体が、PCの操作につながることからOSのような働きをしていました。

# この頃のPCの性能
この頃使用されていたCPUは、ザイログ社製のZ80というCPUとモトローラ製のMC6809というCPUが使われておりクロックはZ80が4MHz、MC6809が1MHz動作でした。
Z80のほうが早そうに見えますが、１つの命令を実行するためのマシンサイクルが４サイクルであったため、実質１Mhz動作であるためMC6809とほぼ同じ性能と言えます。

またメモリは32kbyteから64kbyte搭載されていました。

# 初期のPCで使用されていたメディア
この頃から、外部記憶装置としてカセットテープ(オーディオ用に開発された磁気テープ)にプログラムやデータを記録していました。
記録スピードは1200bpsか2400bpsで記録されることがほとんどでした。

[前の記事](https://qiita.com/kawamo55/items/2e3ea7485657498a54ac)　　　[次の記事](https://qiita.com/kawamo55/items/7288fc55f37783ae5ff3)
Engine modules are out of date, and cannot be compiled while the engine is running. Please build through your IDE. の解決法

# Engine modules are out of date, and cannot be compiled while the engine is running. Please build through your IDE.

Unreal Engineのソースビルドのエンジンで.uproject ファイルを開こうとするとこのようなエラーが出る場合があります。

# 解決法

1. プロジェクト名.slnを開く
slnファイルがない場合は、プロジェクト名.uprojectを右クリックして、Generate Visual Studio project filesを選択してください。
![fileExplorer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288957/d190b04b-51c0-ea3b-3a4f-93ffcda02ba3.png)

2. ビルド構成を選択する
ドロップダウンから Development Editorを選択する
![buildConfiguration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288957/55e05eaf-ca26-c20e-9273-1184a7e59ffa.png)

3. ビルドする
ソリューションのビルドを実行する
![build.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288957/2395fcb4-b11a-95bb-e5e7-8f926eb047a2.png)
Unicode正規化について調べてみた

個人的「質はともかく継続する」8日目です

# Unicode正規化について調べてみた

日本語を扱うソフトウエアエンジニアにとって、避けては通れない関門、それが「文字コード」。
その文字コードにまつわる問題を調べて行くうちに辿りついたのが、Unicode正規化。
Unicode正規化とは何なのか、調べて見ました。

## Unicode正規化とは

すごく簡単にまとめると「表記揺れを抑える」こと。

Unicodeの文字体系は柔軟で、
たとえば「ギ」という文字があった場合、Unicodeでは２つの方法で表現できます。

1つのコードで表す、正準等価性
U+30AE

「キ」と「゛」を組み合わせて表す、互換等価性
U+FF77
U+FF9E

どちらも同じ「ギ」ですが、コードポイントが異な
ります。
普段は困ることはないのですが、sjisに変換する時なんかに困ったことが起きます。

変換前後で値を比較するときに、変換前はU+30AEで表されていたのが、変換後にはU+FF77、U+FF9Eの組み合わせになると、
見た目は同じなのに判定では違う文字として判定されてしまいます。
こういった表記揺れを抑えるために、正規化を行うそうです。

## 4種類の正規化

正規化には4種類あるようです。

### NFD
文字を正準等価性によって分解します。

### NFC
文字を正準等価性によって分解し、再度合成します。結果として文字の並びが変換前と変わることもあります。

### NFKD
文字を互換等価性によって分解します。

### NFKC
文字を互換等価性によって分解し、正準等価性によって再度合成します。

- - -
今日はここまで...明日はそれぞれの正規化を掘り下げていこうと思います。
Laravelで準備されているinspireコマンドが誰得過ぎた

PHPのWebアプリケーション向けのフレームワークのLaravelは便利な機能が多いですが、その中でも特に誰得だと感じたのが`php artisan inspire`コマンドです。

試しに実行してみると

```shell
$ php artisan inspire
I have not failed. I've just found 10,000 ways that won't work. - Thomas Edison
```

このコマンドがしていることをソースコードリードをして理解してみます。

（ソースコードリードの一例として生暖かい目で見守ってください）

## Laravelのコマンド

11.xのLaravelのソースコードにはroutes/console.phpに以下のように記述されています。

```php
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');
```

https://github.com/laravel/laravel/blob/11.x/routes/console.php


このInspiringクラスはIlluminate\Foundation\Inspiringに定義されています。

次にInspiringクラスのファイルを見てみます。

```php
<?php

namespace Illuminate\Foundation;

use Illuminate\Support\Collection;

class Inspiring
{
    public static function quote()
    {
        return static::quotes()
            ->map(fn ($quote) => static::formatForConsole($quote))
            ->random();
    }

    public static function quotes()
    {
        return Collection::make([
            'Act only according to that maxim whereby you can, at the same time, will that it should become a universal law. - Immanuel Kant',
            ~~~
            'I have not failed. I\'ve just found 10,000 ways that won\'t work. - Thomas Edison',
            ~~~
        ]);
    }

    protected static function formatForConsole($quote)
    {
        [$text, $author] = str($quote)->explode('-');

        return sprintf(
            "\n  <options=bold>“ %s ”</>\n  <fg=gray>— %s</>\n",
            trim($text),
            trim($author),
        );
    }
}
```
（途中のコメントや一部の配列内の文字列は省略しています）

staticメソッドのquoteメソッドはquotesメソッドで返されるCollectionの中からランダムに一つの引用を返します。

https://github.com/laravel/framework/blob/11.x/src/Illuminate/Foundation/Inspiring.php

（ちなみにこのファイルにはアスキーアートが含まれていた。誰得）

## 最後に

Laravel開発者の方へ、たまにはこのコマンドを実行してインスパイアされてください。
ケース別"git reset"

# 1. リモートにプッシュしていない最新のコミットが1つあり、そのコミットを取り消したい

![01_gitreset_local1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/ab45bcd7-32a9-1b12-c6d2-e370c6143dd1.png)

```sh
# 現在の変更はステージングしたまま
git reset --soft HEAD~1
# 現在の変更のステージングは外す
git reset --mixed HEAD~1
# 現在の変更は破棄する
git reset --hard HEAD~1
```

# 2. リモートにプッシュしていない最新のコミットが2つあり、そのうちの最後のコミットだけ取り消したい
最新のコミットを取り消すので、1.と同じ

![02_gitreset_local1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/8fe25c91-230a-c8f2-4be2-b4fa4b89d2c0.png)

```sh
# 現在の変更はステージングしたまま
git reset --soft HEAD~1
# 現在の変更のステージングは外す
git reset --mixed HEAD~1
# 現在の変更は破棄する
git reset --hard HEAD~1
```

# 3. リモートにプッシュしていない最新のコミットが2つあり、2つともコミットを取り消したい

![03_gitreset_local2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/74b65a5f-b79a-d25d-5fe2-744fc0d52945.png)

```sh
# 現在の変更はステージングしたまま
git reset --soft HEAD~2
# 現在の変更のステージングは外す
git reset --mixed HEAD~2
# 現在の変更は破棄する
git reset --hard HEAD~2
```

# 4. リモートにプッシュ済みの最新のコミットを取り消したい

![04_gitreset_remote1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/9407cd3b-1374-1436-7d4b-5f54cce5e698.png)

```sh
# ローカルの最新のコミットを取り消す（現在の変更は破棄する）
git reset --hard HEAD~1
# リモートにフォースプッシュ
git push -f origin
```

:::note warn
リモートの履歴を改変するので、共同作業者がいる場合は事前にコミュケーションを取るなど、注意が必要
:::

**※コミット履歴を残す場合は`git revert`**
最新のコミットを受け消す、新しいコミット履歴が作成される。

![04_gitreset_revert.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/a3803c5a-64d5-ebd6-c1fe-280edae49348.png)

```sh
git revert HEAD
git push origin
```

# 5. ローカルのコミット履歴に関わらず、リモートの最新コミットの状態に戻したい

![05_gitreset_remote.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432480/9d21e970-5985-b733-9767-3e4628c516e8.png)

```sh
# 指定したリモートブランチの最新コミットに戻す（現在の変更は破棄する）
git reset --hard origin/ブランチ名
```
python: requirements.in ってなに？って思ったら、requirements.txt の makefile 的な？

# 背景

以下デモを触っていたら、requirements.in ってのがあって、なに？と思ったら便利なことを知らされた。
pythonist にとっては当たり前のことのような気がするけど

https://github.com/Azure-Samples/azure-search-openai-demo

# 概要

- requirements.in に適当に記述して、compile すると、依存関係をよしなに解決して requirements.txt を生成してくれる。
- 実際に python で利用するのは txt 側なので、git で両方管理しておけば、library 調整が楽になる

ってことかな、と。常に最新版でいいやって思ったとしても、正確な環境を残せるってのは素敵ですね :yum: 

で、compile は以下を利用

## [pip-tools](https://pypi.org/project/pip-tools/)

> pip-tools = pip-compile + pip-sync
A set of command line tools to help you keep your pip-based packages fresh, even when you've pinned them. You do pin them, right? (In building your Python application and its dependencies for production, you want to make sure that your builds are predictable and deterministic.)

![](https://github.com/jazzband/pip-tools/raw/main/img/pip-tools-overview.svg)

## 利用例

- まずはインストールして

```powershell
pip install pip-tools
```

- あとはコンパイル: 
```powershell
pip-compile requirements.in
```

- 出力先変えたい場合
```powershell
pip-compile requirements.in -o requirements_new.txt
```

- 単に結果だけ見たい場合（出力変更不要）
```powershell
pip-compile --dry-run
```

- 詳細見たい場合
```powershell
pip-compile --verbose
```

# あとがき

以下とか出来そうなので調べたいところだけど、とりあえず後回し・・:sweat: 

- python version を指定した compile
    - py -{version} で 行けそうだったんだけど・・なんか上手くいかなかったので
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f5110bd2-826e-51ce-4fc2-0aaf7fb5f448.png)


現状、python 環境を変えつつしか方法知らない・・。
その前に、venv を学習しないとあかんっぽいけど・・
それ以前に、セキュリティを・・

おじいちゃんの脳には入っていきません :cry:
【ネタ枠】ChatGPTで美女のイラストを描く

今回は漢の夢とロマンの世界です(笑)

ChatGPTでイラストや写真を作れることをご存じの方は多いと思います。

画像生成できるならあんなことやこんなことが・・・
とニヤニヤ期待しながら早速試してみようとして「プロンプトに水着の美女を描いて」と投入しても「規制がかかっているのでムリっす！」とChatGPTに回答されてションボリングした方も多いのではないかと思います（えっ？違う！？）


以前はこういったコンテンツが強く規制されていて、このレベルでもダメなの？というのが結構あったのですが、最近どうやら緩和されたということで早速試してみました。

使用したプロンプトはこちらです。

```
デジタルアートで、20代の女性が海で友達の女性と水をかけあって楽しく遊んでいる姿をえがいてください
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620986/b4a259e3-5c97-8662-5042-87dc89643d85.png" width=75% height=75%>


ChatGPTの良いところは、ここから会話で軽微な修正ができるところです。
以下のように変更点だけ簡潔にプロンプトで依頼します。

```
アジア系の女性に変えてください
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620986/ae323a6c-9973-d799-cab2-f4a18ab1767f.png" width=75% height=75%>

アジア系の美女が楽しく水遊びしているイラストになりましたね。

そのシーンを細かく指定すると指定した通りに描いてくれますし、雑に指定すると空気を読んでそれっぽく描いてくれます。ただし、あまり性的要素の強いものを指定すると内部ポリシーに引っかかってしまい「申し訳ありませんが、画像生成に問題が発生してイラストを作成することができませんでした」のような回答が返ってきますので、やりすぎには注意が必要です。

それではAI作画を楽しんでください♪
【リハビリJS学習】瞑想アプリを作る①

# はじめに
前回の記事でいいねやフォロワーさんが増えて、妙に緊張している・・・
学習＆Qiitaの再開のため、下記の記事からプロジェクトを選んでやってみようと思います！
関心のあるものなら取り組めそうなので、瞑想アプリを作ります。

https://qiita.com/baby-degu/items/33acb94e404feaf58d35#1%E7%9E%91%E6%83%B3%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8B

瞑想は前から好きで動画やアプリを見ながら取り組んでいたりします。メンタルケアにも良さそうです。
（余談ですが、Netflixのヘッドスペースシリーズが好きです。クセのない声で聞きやすいです🧘‍♀️）

-----
ではYouTubeの動画を見ながらすすめていきます。

### 1. 初期ファイル構築
githubからベースとなるファイルをCloneします。画像や音楽などの素材ファイルが入っていました。

### 2. 格納されていたindex.html、CSSファイル、README.md、app.jsを削除する

また、SCSSを使えるようにしたく、下記のサイトを参考にgulpの導入にチャレンジしてみました。

https://ics.media/entry/3290/

### 3. 新たにindex.htmlを作成して、`<html>`タグや`<head>`などを記述する
`<title>`に適当なタイトルをつける。

### 4. 必要なコンテンツをマークアップ
``` html
<div class="app">
  <div class="time-select"></div>
  <div class="player-container"></div>
  <div class="sound-picker"></div>
</div>
```

### 5. CSSでスタイルをあて、全体的なレイアウトを作成
SCSSを使います。
リセットは動画を参考にします。

``` scss 
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.app {
  height: 100vh;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
}
.time-select,
.sound-picker,
.player-container {
  height: 80%;
  flex: 1;
}
.time-select {
  background-color: lightblue;
}
.sound-picker {
  background-color: lightgreen;
}
.player-container {
  background-color: lightcoral;
}
```

見た目はこんな感じです。
![スクリーンショット 2024-06-15 21.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/8b463edd-8b3d-7811-0645-a791110a75b8.png)

### 6. tile-selectに必要なボタンを追加
瞑想の長さを選択できるボタンです。
```html
<div class="time-select">
    <button>2 Minutes</button>
    <button>5 Minutes</button>
    <button>10 Minutes</button>
</div> 
```
jsで使用できるようにデータ属性を追加し、秒数を入れます。

``` html
<div class="time-select">
    <button data-time="120">2 Minutes</button>
    <button data-time="300">5 Minutes</button>
    <button data-time="600">10 Minutes</button>
</div>
```

### 7. player-containerにオーディオトラックを追加
``` html
<div class="player-container">
    <audio class="song">
      <source src="./sounds/rain.mp3">
    </audio>
    <img src="./svg/play.svg" alt="play" class="play">
</div>
```
imgタグの下にsvg/track-outline.svgのコードをコピペし、クラス名track-outlineをつける。
その下にsvg/moving-outline.svgのコードをコピペし、クラス名moving-outlineをつける。
``` html
 <div class="player-container">
    <audio class="song">
      <source src="./sounds/rain.mp3">
    </audio>
    <img src="./svg/play.svg" alt="play" class="play">
    <svg class="track-outline" width="453" height="453" viewBox="0 0 453 453" fill="none" xmlns="http://www.w3.org/2000/svg">
      <circle cx="226.5" cy="226.5" r="216.5" stroke="white" stroke-width="20"/>
    </svg>
    <svg class="moving-outline" width="453" height="453" viewBox="0 0 453 453" fill="none" xmlns="http://www.w3.org/2000/svg">
      <circle cx="226.5" cy="226.5" r="216.5" stroke="#018EBA" stroke-width="20"/>
    </svg>
  </div>
```
見た目はこんな感じです。
![スクリーンショット 2024-06-15 22.01.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/3486dabb-07fb-9772-5f82-774c8d333a43.png)

jsには入りませんでしたが、一旦ここまで！
[Unity]UnityNetcodeのマルチプレイヤーで位置を同期してみる

# 概要
前回の記事[UnityNetcodeでマルチプレイヤーを試してみる記事](https://qiita.com/kazuma_f/items/e8b0fd9bb6a8069f3d36)の続きです。キー操作で動くプレイヤーキャラクターの位置をユーザー間で同期するようにしてみます。
# 本文

UnityNetcodeでキャラクターの位置を同期するためにはNetworkTransformコンポーネントが必要です。ですがそのまま使うとホスト側でしかコントロールできなくなるのでここで一手間加えます。
NetworkTransformを継承したNetworkTransformClientを作成してNetworkPlayerにアタッチします。

```cs
using Unity.Netcode.Components;
public class NetworkTransformClient : NetworkTransform
{
    protected override bool OnIsServerAuthoritative()
    {
        return false;
    }
}
```

通信される情報量を少しでも減らすためにScaleはOFFにしました

![スクリーンショット 2024-06-15 214539.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/62a0e765-29f8-4f5f-ca19-c3b9f18f0c30.png)

テスト用にプレイヤーを移動させるコードもついでに作成してNetworkPlayerにアタッチします。

```cs
using UnityEngine;

public class PlayerMovement : NetworkBehaviour
{
    private const float Speed = 5f;
    private const float rotationSpeed = 500f;

    private void Update()
    {
        float horizontalInput = Input.GetAxis("Horizontal");
        float verticalInput = Input.GetAxis("Vertical");

        Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
        movementDirection.Normalize();
        
        transform.Translate(movementDirection * Speed * Time.deltaTime, Space.World);
        
        if(movementDirection != Vector3.zero)
        {
            Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
        }
    }
}
```

Windows用アプリとしてビルドしてUnityEditorでも実行します。WASDキーで上下左右に移動させるとお互いの画面でお互いのキャラクターの動きが同期されていることが確認できました！:confetti_ball:

![Movie_001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/8e05ddbd-0ef8-2dd5-1b1e-5932029f18b5.gif)

# UnityNetcode関連記事目次
[1.UnityNetcodeをちょっと触ってみたい人用の記事](https://qiita.com/kazuma_f/items/dd88c7132c343500702e)
[2.UnityNetcodeでマルチプレイヤーを試してみる記事](https://qiita.com/kazuma_f/items/e8b0fd9bb6a8069f3d36)
3.UnityNetcodeのマルチプレイヤーで位置を同期してみる ← :triangular_flag_on_post:
[4.UnityNetcodeのマルチプレイヤーで変数を同期してみる](https://qiita.com/kazuma_f/items/907b01705e78bd199fdd)
闘魂Elixir ーー AtCoder Beginner Contest 344(B)をElixirで楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>


# はじめに

[AtCoder Beginner Contest 344](https://atcoder.jp/contests/abc344)を[Elixir](https://elixir-lang.org/)で解いてみます。

[AtCoder](https://atcoder.jp/)を解くのが趣味で、休憩時間に解いているという若い人がいて、それってすごい意識の高い休憩時間の過ごし方だと思って、私も真似してみることにしました。


# [AtCoderをElixirでやってみる](https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01)

入力の読み取り方や解答の作り方は、別の記事にまとめています。


https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01

ご参照くださいませ。

[Elixir](https://elixir-lang.org/)で[AtCoder](https://atcoder.jp/)を楽しむためには、エントリポイントを`Main.main/0`にする必要があります。つまり`Main`モジュールを作って、その中に`main/0`関数を定義するわけです。

# [B - Delimiter](https://atcoder.jp/contests/abc344/tasks/abc344_b)

問題はリンク先をご参照くださいませ。
私の解答を貼っておきます。


<details><summary>私の解答</summary>

_問題文を読んでいることを前提にひとこと解説をしておきます。_

珍しい問題かもしれません。
入力の読み込みを0が出現したときに打ち切ればよいわけです。
私は、[https://hexdocs.pm/elixir/1.17.0/Enum.html#reduce_while/3](Enum.reduce_while/3)関数を解法の骨格に据えました。

```elixir
defmodule Main do
  def main do
    (1..(10 ** 9))
    |> Enum.reduce_while([], fn _, acc ->
      a = IO.read(:line) |> String.trim() |> String.to_integer()
      do_solve(a, acc)
    end)
    |> Enum.join("\n")
    |> IO.puts()
  end
  
  defp do_solve(0, list), do: {:halt, [0 | list]}
  defp do_solve(a, list), do: {:cont, [a | list]}
end
```




</details>




---

# さいごに

[AtCoder Beginner Contest 344](https://atcoder.jp/contests/abc344)を[Elixir](https://elixir-lang.org/)で解くことを楽しみました。

あなたのお好きなプログラミング言語でお楽しみください。

---


**闘魂**とは、  **「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
**アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。**

---

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>
<b><font color="red">$\huge{１、２、３ ぁっダァー！}$</font></b>