OmniAICreator/Qiita-1.07M huggingface dataset:
Livewire\Exceptions\CorruptComponentPayloadException: Livewire encountered corrupt data when trying to hydrate the [abcdefg.index] component.  Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.

超悩まされていたこのエラー
```
Livewire\Exceptions\CorruptComponentPayloadException: Livewire encountered corrupt data when trying to hydrate the [abcdefg.index] component. 
Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests. in file hijk.php on line 21
```
何をやってもエラーになるので対処できずになやんでいたが、
どうもJavascriptで扱える整数を超えている値を扱った場合、出る様子。

例えばこんな感じのコード。

```
    public function mount()
    {
        $this->datalist[2902364376262391407]="AAAAA";
        $this->datalist[2902464817685127830]="BBBBB";
        $this->datalist[2902672707216567430]="CCCCC";
        $this->datalist[1102264376262391407]="DDDDD";
    }
```
livewire view(blade)
```
<select wire:model="selectid" class="m-0 pl-1 pr-4 pt-0 pb-0">
    <option value="0"></option>
    @foreach($datalist as $key=>$data)
        <option value="{{$key}}">{{$data}}</option>
    @endforeach
</select>

```

Livewireだとselectを変更しただけでサーバに問い合わせするが、
option valueで扱った値があまりにも大きいので、サーバに渡したとき多分壊れた値が渡され、
サーバで不一致となりパンクする様子。
どうしても大きい値(Number.MAX_SAFE_INTEGERより大きい)のVALUE値を扱いたい場合は
文字列化してしまえばなんとかなるっぽい。


```
    public function mount()
    {
        $this->datalist["KEY"."2902364376262391407"]="AAAAA";
        $this->datalist["KEY"."2902464817685127830"]="BBBBB";
        $this->datalist["KEY"."2902672707216567430"]="CCCCC";
        $this->datalist["KEY"."1102264376262391407"]="DDDDD";
    }
```

これ、気がつける普通？
ZED SDK のtimestampを取得するには

## 想定する読者
stereolabsのzed2, zed mini, zed x などのステレオカメラの利用者
いまどきのステレオカメラは何ができるのかを知りたい人

## 前提
ZED SDK 4.0

## 
retrieveしたデータ構造にはTimestamp　クラスのインスタンスがある。
そこから時刻の値を取得するには、以下のメソッドを用いる。

```
get_nanoseconds()
get_microseconds()
get_millisecond()
get_seconds()
```

例
```
point_cloud.timestamp.get_nanoseconds()
```

## 公式ドキュメント
https://www.stereolabs.com/docs/api/python/classpyzed_1_1sl_1_1Timestamp.html


## python(linux) のtime.time() 関数との比較
```.py:
        zed.retrieve_image(left_image, sl.VIEW.LEFT)
        unix_seconds = time.time()
        left_seconds = left_image.timestamp.get_seconds()
        left_nanoseconds = left_image.timestamp.get_nanoseconds()
        print(f"{left_seconds=}")
        print(f"{left_nanoseconds * 1e-9 =}")
        print(f"{unix_seconds=}")
        print(f"{int(unix_seconds) == left_seconds =}")
```

### 出力例
```
left_seconds=1711353324
left_nanoseconds * 1e-9 =1711353324.098794
unix_seconds=1711353324.2152798
int(unix_seconds) == left_seconds =True
```

- Linux の場合はZED SDK のtimestamp のEpoch は Unix のEpoch に一致している。
- この例では、JetsonのLinux のtimerの秒数と、ZED2i のカメラの中のtimerの秒数とが整数部で一致した。
- 1秒未満を合わせようとすれば、NTPを使うことは必須のようだ。

## ZEDの時刻をNTP出会わせるには？

公式ドキュメント [Setting up Multiple Cameras on a Local Network](https://www.stereolabs.com/docs/video/multi-camera#setting-up-multiple-cameras-on-a-local-network)

## ユーザーの皆さんには確かめてみてほしいこと
1. retrieve できる対象について、即座のそれぞれretrieveする。
1. その後個別にget_data() したときにデータの整合性をもっているのかどうかという確認。
例：`retreive_measure`したpint_cloud中にある各点の色情報が、`retrieve_image`した左画像の色情報と一致しているかの確認。



```.py:
zed.retrieve_image(image, sl.VIEW.LEFT, sl.MEM.CPU, display_resolution)
zed.retrieve_measure(point_cloud, sl.MEASURE.XYZRGBA, sl.MEM.CPU, point_cloud_res)
xyz_data = point_cloud.get_data()


zed.retrieve_measure(point_cloud, sl.MEASURE.XYZRGBA, sl.MEM.CPU, point_cloud_res)
xyz_data = point_cloud.get_data()

```
DBのユーザー権限はく奪手順

SQLサーバー内でユーザー権限をはく奪するのに使用したコード一覧メモ

#
ユーザーがどのテーブルのどの権限を持っているか確認
```
DBを指定
USE [sampleDB]

SELECT
    USER_NAME(grantee_principal_id) AS ユーザー名,
    class_desc AS クラス,
    OBJECT_NAME(major_id) AS オブジェクト名,
    permission_name as 権限名
FROM sys.database_permissions
WHERE grantee_principal_id = USER_ID('sampleDbRole') --ユーザー名 or ロール名を指定
```

#
はく奪用コード（ALTERはALLだと消えなかったので別枠）
```
DBを指定
USE [sampleDB]

REVOKE ALL ON [テーブル名] TO [ユーザー名];
REVOKE ALTER ON [テーブル名] TO [ユーザー名];

SELECT
    USER_NAME(grantee_principal_id) AS ユーザー名,
    class_desc AS クラス,
    OBJECT_NAME(major_id) AS オブジェクト名,
    permission_name as 権限名
FROM sys.database_permissions
WHERE grantee_principal_id = USER_ID('sampleDbRole') --ユーザー名 or ロール名を指定
```

#
DATABASEクラスのCONNECT権限をはく奪するコード
```
DBを指定
USE [sampleDB]

REVOKE CONNECT ON DATABASE::KENPO_DB TO ユーザー名;


SELECT
    USER_NAME(grantee_principal_id) AS ユーザー名,
    class_desc AS クラス,
    OBJECT_NAME(major_id) AS オブジェクト名,
    permission_name as 権限名
FROM sys.database_permissions
WHERE grantee_principal_id = USER_ID('sampleDbRole') --ユーザー名 or ロール名を指定
```
【ネットワーク】初心者のためのイーサネットで扱うデータ説明

## 概要
前回の記事はイーサネットのアドレスについて説明をしました。
今回はイーサネットで扱うデータについて説明していきます。

前回の記事は下記のものになります。
こちらの記事を読んでからの方が理解しやすいと思います。
是非、こちらも読んでみてください。

https://qiita.com/nakamura_slj/items/ed09a820f7f9dff95248

## 対象とする読者
* ネットワークの基礎から学びたい人
* 前回の記事を読んだ人
* これからIT業界で仕事をしようと考えている人
* CCNAの資格を取ろうとしている人

## イーサネットで扱うデータ
イーサネットでは下記のようなフォーマットのデータを扱い、
そのデータのことを**イーサネットフレーム**といいます。
イーサネットフレームには、IEEE８０２.3で規格されたIEEE８０２.3形式と
Intel、Xerox、DECによって開発されたEthernetⅡ形式があり、下記は幅広く普及している
EthernetⅡ形式を表しています。
![スクリーンショット 2024-03-13 14.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/3c4e75cd-a126-41f2-b334-34efbd637a95.png)

各区切りごとに簡単にまとめたものがこちら↓になります。
| フィールド名 | 説明 |
|:--------|:----------|
|プリアンブル|１と0のビット列信号で、通信時に同期を取るために利用される。|
|宛先MACアドレス|通信する宛先のMACアドレス|
|送信元MACアドレス|通信する送信元のMACアドレス|
|タイプ|上位層のプロトコルを表す値（ネットワーク層、インターネット層）|
|データ|最小46バイト、最大1500バイトのデータを格納|
|FCS|受信したデータに誤りがないかチェックする|

※ネットワーク層、インターネット層などがわからない場合はこちらの記事を見てみてください

https://qiita.com/nakamura_slj/items/0c827de1dab6ebc722d2

イーサネットヘッダ部分には、宛先や送信元を特定するためのMACアドレスのじょゆ方が格納されます。
イーサネットフレームの最大サイズを計算するためには、プリアンブルを除いたサイズが最大サイズとなり
1528バイトになります。

# 最後に
以上となります。
今回はイーサネットで扱うデータについて説明いたしました。
C#/VB.NETでPDFを結合する

## はじめに
複数のPDFファイルを1つのファイルに結合することは、関連する文書、レポート、または資料の組織と管理において大きな利点を持っています。それは可読性を向上させるだけでなく、情報のシームレスな共有を促進します。PDFファイルを一緒に結合することで、複数のファイルを繰り返し開閉する必要がなくなり、時間と労力を節約できます。さらに、このプロセスにより、ファイルの総数が減少し、ファイルの保存とバックアップが簡素化されます。ファイル結合にはソフトウェアを使用する以外に、プログラミングによっても実行できる優れた方法です。この記事では、C#およびVB.NETを使用して複数のPDFファイルを1つのファイルに結合する方法を紹介します。
## ツール
* Visual Studio 2022
* [Free Spire.PDF for .NET](https://www.e-iceblue.com/Introduce/free-pdf-component.html)

このライブラリは、無料でPDFァイルを作成、編集、変換することができますが、ページ数の制限があります。または、有料版の製品の[無料トライアル](https://www.e-iceblue.com/TemLicense.html)を申し込むこともできます。

有料版 : [Spire.PDF for .NET](https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html)
## インストール方法
* [Free Spire.PDF for .NET](https://www.e-iceblue.com/TemLicense.html)をダウンロードします。
* Visual Studioで新しいプロジェクトを作成します。
* 「Solution Explorer」>「References」を右クリックし、「Add Reference」>「Browse」を選択します。
* BINフォルダ内のdllファイルを見つけて、「OK」をクリックします。

## コード
C#
```c#
using System;
using Spire.Pdf;

namespace MergePDFs
{
    class Program
    {
        static void Main(string[] args)
        {

            //ドキュメントのパスを取得する
            String[] files = new String[] {
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-1.pdf",
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-2.pdf",
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-3.pdf"};

            //ドキュメントをマージしてPdfDocumentBaseのオブジェクトを返す
            PdfDocumentBase doc = PdfDocument.MergeFiles(files);

            //結果をPDFファイルに保存する
            doc.Save("Output\\result.pdf", FileFormat.PDF);
        }
    }
}
```
VB.NET
```vb
Imports System
Imports Spire.Pdf
 
Namespace MergePDFs
    Class Program
        Shared  Sub Main(ByVal args() As String)

            'ドキュメントのパスを取得する
            Dim files() As String =  New String() {"C:\\Users\\Administrator\\Desktop\\PDFs\\sample-1.pdf","C:\\Users\\Administrator\\Desktop\\PDFs\\sample-2.pdf","C:\\Users\\Administrator\\Desktop\\PDFs\\sample-3.pdf"}

            'ドキュメントをマージしてPdfDocumentBaseのオブジェクトを返す
            Dim doc As PdfDocumentBase =  PdfDocument.MergeFiles(files) 
 
            '結果をPDFファイルに保存する
            doc.Save("Output\\result.pdf", FileFormat.PDF)
        End Sub
    End Class
End Namespace
```
## 説明
まず、入力パスを取得します。 次に、PdfDocument.MergeFiles() メソッドを呼び出して、これらのファイルをマージします。 最後に、PdfDocumentBase.Save() メソッドを使用して、結果を PDF ドキュメントに保存します。

上記の方法を参照して、このライブラリを通じて[PDFを圧縮](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Document-Operation/How-to-Compress-PDF-Document-in-C-VB.NET.html)し、PDFに[画像の透かし](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Watermark/Add-image-watermark-to-pdf-in-C.html)と[テキストの透かし](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/PDF-Watermark-Add-Watermark-in-PDF-with-C-VB.NET.html)を挿入することもできます。
Simulatorの画面を録画するbash

# Simulatorの画面を録画する方法

下記シェルを実行することにより、録画できます。

```bash
xcrun simctl io booted recordVideo ~/demo.mov
```

aliasにするとこんな感じ

~/.bashrc or ~/.bash_profile

```bash
alias simrec="xcrun simctl io booted recordVideo ~/demo.mov"
```
Gradleビルドプロセス失敗(:Zone.Identifier)

# 新規SpringBootファイルビルドプロセス失敗のエラー
spring initializrのサイトで生成した新規SpringBootファイルをIntelliJ IDEAで開き、実行したところ、下記のエラーとなった。
```
Execution failed for task ':processResources'.
> Cannot convert URL 'application.properties:Zone.Identifier' to a file.

*Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD FAILED in 1s
2 actionable tasks: 1 executed, 1 up-to-date
```
# エラー内容
最初の2行がエラー内容。
application.propertiesのタスクに失敗。application.properties:Zone.Identifierがファイル変換できない。
# エラー原因
チャットGPT先生によると
> Zone.Identifier はWindowsがファイルに付与するメタデータ（別名「代替データストリーム」）で、インターネットからダウンロードされたファイルのゾーン情報を格納します。このメタデータは、Unix系のシステムやJavaのFile APIでは直接サポートされていません。

とのことであった。
私はintelliJをWindows環境ではなく仮想Linux環境で使用している。
spring initializrのサイトで生成した新規SpringBootファイルは、WindowsのDownloadフォルダに入ってしまう(デフォルト設定)。それをLinux環境に持ち込んだ際に生成されてしまうようだ。

# 対応
これだけが原因なのかわからなかったが、プログラムに不必要なファイルではあるので、削除してみることにした。ただ、*:Zone.Identifierのファイルは全てのファイルに対して生成されるので、手作業で全てを消すのはひどい手間になりそうであった。

ググると下記のリンクがヒットした。

https://hajimecreate.com/labo/wsl-zoneidentifier-delete/

こちらで紹介されていた一括削除コマンドで削除できた。
```
$ find ./ -type f -name '*:Zone.Identifier' -exec rm {} \;
```
一発K.O.であった。激しく感謝です。
# 結果
*:Zone.Identifierを全て削除した結果、エラーにならずにビルドすることができた。
*:Zone.Identifier生成自体をさせないようにすることも、もしかしたらできるのかもしれないが、何かしら必要で生成されているはず(そこまでは調べなかった)。
もうワンパン解決なので怖くない。
より早く、より便利になったStorybook 8


Storybook 8がリリースされたので、簡単にまとめ。

https://storybook.js.org/blog/storybook-8/


- 📸 ビルトインのビジュアルテスト
- ⚛️ React Server Componentのサポート
- 🎛️ ReactのパフォーマンスアップとVue control autogenerationの改善
- ⚡️ Vite5やVitestのサポート
- 🧪 2-4倍高速なテストビルド
- 📲 モバイル・デスクトップUIの刷新
- 🙅‍♀️ 非ReactプロジェクトでのReactへの依存性を削除

## 特に気になったもの

### ビルトインのビジュアルテスト

- アドオンで、ChromaticをStorybookに組み込み
- ワンクリックですべてのストーリーを同時テストし、変更点を特定可能
- CIのワークフローを、Storybookの中で直接実行可能に

![sb-vta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10962/af6a2f4a-1bf0-0e98-ebdb-29044de3c011.png)


### React Server Componentのサポート

- React Server Componentを実験的にサポート
- ただし現在はNext.jsのみ、安定版はゆくゆく


## その他

### ReactのパフォーマンスアップとVue control autogenerationの改善

- react-docgenを使用することで、ReactのStorybookの起動時間が最大50%速くなった
- vue-component-metaをサポートし、型の扱いやVue control autogenerationが改善

### Vite5やVitestのサポート

- Vite 5のサポート
- Vitestを活用した @storybook/test が導入。以前の2つのパッケージ(@storybook/jest と @storybook/testing-library)を置き換えるもの

### 2-4倍高速なテストビルド

- Storybookの静的ビルドを2-4倍高速化する「テストモード」
- 様々な標準機能を無効にする新しい --test のCLIのフラグにより余分な処理を省く

### モバイル・デスクトップUIの刷新

- モバイルUIを全面刷新。ナビゲーションサイドバーとアドオンパネルが下から登場
- デスクトップ間のレスポンシブ遷移をスムーズに

![sb-mobile-ui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10962/6a2265dc-d316-6d63-d54c-94eb438c59c3.png)


### 非ReactプロジェクトでのReactへの依存性を削除

- React以外のプロジェクトでReactの依存関係が不要になった
- 以前までは、React以外のプロジェクトでもReactが peer dependency になっていた


## 参考

https://storybook.js.org/blog/storybook-8/
AttributeError: partially initialized module '❓❓❓' has no attribute '❓❓❓' (most likely due to a circular import) 解決法

# 解決法
「AttributeError: partially initialized module '❓❓❓'」

 - 上記の「❓❓❓」の部分のモジュールと同名のファイルがないか確認
 - あれば（というかあるからエラー）、**同名のファイルの名前を変更**


例えば僕の場合は、
```python:sample.py
import subprocess
```
を実行するとエラーが起きたので、、
「`Me/subprocess.py`」を「`Me/subprocess2.py`」へ名前変更
```
Me/
　├ sample.py
　├ subprocess.py　← 「subprocess2.py」などに変更
 
Python/
　├ Libs/
　  ├ subprocess.py
```
すると正規のモジュール「`Python/Libs/subprocess.py`」が読み込まれます。

# 原因
単にファイル名がダブっていたことで、自作の非正規な`subprocess.py`が優先して読み込まれていただけでした。

ちなみにエラーの全文は
```
AttributeError: partially initialized module 'subprocess' has no attribute 'run' (most likely due to a circular import)
```
ですが、`Me/subprocess.py`内でrun関数を定義してしまっていたら更に沼っていたと思います。うっかり😜

# 予想
モジュール（なんとか.py）のimportって
`同ディレクトリ ＞ その他ディレクトリ`の順で読み込まれるんですかね。

**DLLプランティング**と同じ要領で、
`標準モジュール.pyと同名のファイルを優先度の高い隠しディレクトリにインストールする、、`
みたいなマルウェアがあると厄介ですね。
<br>
### DLLプランティングとは？
exeファイルは実行される際、DLLファイルを参照することがあります。
このとき、読み込むDLLの優先度は`カレントディレクトリ（exeがあるディレクトリ） ＞ システムフォルダ等`となります。
カレントディレクトリに正規のDLLが存在しない時、攻撃者はカレントディレクトリに本来読み込むべきDLLと同名のDLLファイルを配置します。

するとexeは優先度に従い、攻撃者が配置したDLLファイルを読み込みます。悪意あるコードが実行されてしまうということです。
【Azure】Azure Virtual Desktop セッションホストのドメイン参加をEntra IDのみで構成する

# Azure Virtual Desktop 概要

本題に入るにあたって前提として、どんなサービスか簡単におさらいしておきます。
Azure上で実行している、Virtual MachinesをWindows ServerやWindows 10,11でデプロイし
デスクトップとしての利用やアプリ仮想化サービスとして利用する事ができます。

基幹業務用アプリ、Microsoft 365、SaaSとしての展開等を行う事が可能です。
また、ゲートウェイサーバー等はMicrosoftがマネージドで用意してくれているので
ユーザーは特に意識する事なく、サービスを利用する事が可能です。

https://learn.microsoft.com/ja-jp/azure/virtual-desktop/overview

# 本題

仮想デスクトップやリモートアプリにアクセスするためには、Entra IDの利用は必須です
Active DirectoryやEntra Domain Servicesだけでの構築はできません。
構成方法は複数存在しますが、タイトル通りに今回はEntra IDでの構成に絞ってまとめていきます。

Entra IDのみ（Entra ID Join 構成 AVD環境）で、AVDを構築する場合には
気を付けなければいけない事項が複数存在するので、条件に当てはまらない場合には、Active DirectoryやEntra Domain Servicesの構築を考慮する必要があります。

特にオンプレミスリソースへのアクセスが必要な場合は
別途VPNやExpress Routeの構築が必要になってきますので、費用は高くなります。


※注意事項（一部）
・クライアント側がAVDへ接続する際にブラウザでは無く、Windows用リモートデスクトップアプリを利用したい場合
・FSLogixを利用する場合にユーザープロファイル領域としてAzure FilesやNetApp Filesを利用する場合
・オンプレミスリソースへのアクセスが必要な場合

https://learn.microsoft.com/ja-jp/azure/virtual-desktop/azure-ad-joined-session-hosts#known-limitations

# まとめ
短いですが初めての投稿なので、こんな感じでまとめて終わります。
下記の様な要件があった場合には、おとなしくADを構成しましょう。

・オンプレミスリソースへアクセスする必要がある
・マルチセッション方式でFsLogixを構成する必要がある
・クライアントの接続要件にWindows用のデスクトップアプリを利用したい

ちなみに、VMベースでプロファイル領域の作成も行う事ができますが
Microsoft的に非推奨です。

読んでくれてありがとうございました。
JuliaでDeep Learningを理解する: 4.3 Deep neural networks

[Understanding Deep Learning](https://udlbook.github.io/udlbook/)の[ノートブック](https://github.com/udlbook/udlbook/blob/main/Notebooks/Chap04/4_3_Deep_Networks.ipynb)をJuliaで確認する。

# 4.3 Deep neural networks
[JuliaでDeep Learningを理解する: 4.2 Clipping functions](https://qiita.com/dokudo9191/items/912384b29c3ff4aa34c4)これまでの記事で見てきたように、Deep Learningは線形関数の合成なので、行列の計算をとにかく行うことになる。また、層ごとに独立して計算できる。

## 行列で多層ニュートラルネットワークを計算する
以下のような多層ニュートラルネットワークを考える。
![DeepKLayer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2279125/6c7f12b0-b4b8-332c-f5d5-50217d4a7fdc.png)
(画像は[udlbook](https://github.com/udlbook/udlbook/tree/main/PDFFigures)より引用)
Juliaは標準で行列の計算をサポートしているので、ライブラリ等の追加は必要ない。
```julia
ReLU(z) = ifelse(z < 0, zero(z), z)
D_i = 3
D_1 = 4
D_2 = 2
D_3 = 3
D_o = 2
n_data = 10
x = rand(Float32, (D_i, n_data))
beta_0 = rand(Float32, D_1)
Omega_0 = rand(Float32, (D_1, D_i))
h1 = ReLU.(beta_0 .+ Omega_0 * x)
beta_1 = rand(Float32, D_2)
Omega_1 = rand(Float32, (D_2, D_1))
h2 = ReLU.(beta_1 .+ Omega_1 * h1)
beta_2 = rand(Float32, D_3)
Omega_2 = rand(Float32, (D_3, D_2))
h3 = ReLU.(beta_2 .+ Omega_2 * h2)
beta_3 = rand(Float32, D_o)
Omega_3 = rand(Float32, (D_o, D_3))
y = ReLU.(beta_3 .+ Omega_3 * h3)
```
`n_data = 10`はバッチサイズであり、3次元のインプットを10セット一気に計算している。
```console
julia> y = ReLU.(beta_3 .+ Omega_3 * h3)
2×10 Matrix{Float32}:
 3.08755  3.31505  3.89058  3.42552  3.03049  3.14105  3.44985  3.19263  3.23905  3.31655
 4.46442  4.8368   5.7742   5.01455  4.37189  4.55211  5.0533   4.63697  4.71287  4.8374
```
正しく計算できている。

## Flux.jlで多層ニュートラルネットワークを計算する
Flux.jlはJulia純正の深層学習用パッケージである。中身がCということはないので、全てのコードを追うことができる。プログラマーとしては１つの言語で完結しているのは非常にありがたい。JuliaはLLVMにコンパイルされるので、速度も問題ない。
```julia
using Flux
model = Chain(
    Dense(D_i => D_1, relu),
    Dense(D_1 => D_2, relu),
    Dense(D_2 => D_3, relu),
    Dense(D_3 => D_o)
)
model(x)
```
`Dense`は全結合層であり、活性化関数をreluに指定している(ちなみに自分で今回作ったReLU関数を指定しても問題なく動作する)。`Chain`で各層を１まとめにして`model(x)`で計算する。
```console
julia> model(x)
2×10 Matrix{Float32}:
 0.0772406  0.00252384  0.0843285  0.145631  0.0692204  0.064958  0.190816  0.0247252  0.0205282  0.119318
 0.900612   0.942941    1.41732    1.20932   0.75046    0.86907   1.32434   0.835291   0.834123   1.06254
```
乱数を使っているので値は異なるが正しい大きさのyが得られている。
パッケージ内で行なっている計算は自前で行った実装
```julia
h1 = ReLU.(beta_0 .+ Omega_0 * x)
```
とほぼ違いはなく
```julia
σ.(a.weight * xT .+ a.bias)
```
となっている。`σ`が`ReLU`、`beta_0`が`a.bias`、`a.weight`が`Omega_0`、`x`が`xT`である。もちろんライブラリなので汎用性のためのコードや型安定性のためのコードはあるが、実装のコアの部分は変わらない。
Juliaの言語仕様に素直に短くコード書けばそれが速度的にも良い書き方になっているので安心してコードを書けるのがJuliaの好きなところだ。
Salesforce認定アドミニストレーターを受験することになったから過去問を解いてアウトプットしていこうと思う。Q41 ~ Q50

## Q41. 次の中から, カスタムフィールドタイプをすべて選択せよ.
選択肢 : 
    Aリストボックス
    B電話
    C番号
    Dパーセント
    Eメール

A: B, C, D, E
### 解説
リストボックスは存在しないフィールドタイプ. 複数選択リストはピックリストと呼ばれるタイプで, 選択肢を一覧から選ぶことができるフィールド. 

## Q42. ガイド付きの経費レポートプロセスでユーザーを支援し, 送信, ルーティング, 承認を簡素化したいと考えている. 管理者がこのソリューションを構築するために使用する必要がある2つのツールは次のうちどれ？
選択肢 : 
    A検証ルール
    Bフロービルダー
    C承認プロセス
    Dクイックアクション

A: B, C
### 解説
フロービルダーは, ユーザーが手順を視覚的にマッピングできるツールで, 特定のアクションを自動化することができる. 設問で言うと, レポートの作成から送信までを自動化するために使用することができる. また承認プロセスは, レコードが特定の基準を満たした場合に承認を必要とするプロセスを自動化する.

## Q43. プロファイルごとにユーザーがログインできる時間帯と, ログインできるIPアドレスを設定できる. 
A: できる
### 解説
ユーザーがログインできる時間帯の設定とIPアドレスからのログインは, プロファイル設定からできる.

## Q44. カスタム集計項目について正しいのは, 次のうちどれ？
選択肢 : 
    Aカスタム集計項目は、カスタム レポート タイプから作成されたレポートで使用できます。
    Bカスタム集計項目は、レポート内の数式項目を参照できます
    Cカスタム集計項目は、別のカスタム集計項目を参照できます
    Dカスタム集計式の結果によってレポートをグループ化できます

A: A, B
### 解説
カスタムレポートタイプを使用して作成されたレポートでカスタム集計項目を使用することができる. また, カスタム集計項目はレポート内の他の数式項目を参照して特定の計算や集計を行うことができる.

## Q45. 管理者は, 過去90件の成立商談のファイルをエクスポートする必要がある. このファイルには商談名, ID, 完了予定日, および金額が含まれている必要があり, 管理者はこのファイルをどのようにエクスポートする必要がありますか？
A: データローダを使う
### 解説
特定の条件に基づいて特定のレコードをエクスポートする場合や大量のレコードをエクスポートする場合には, データローダが適している. 

## Q46. 委任された承認社は, 以前に承認されたプロセスを取り消すことができますか？
A: はい

## Q47. A社は見込み客をSalesforceに登録するためにインターンを雇った. 既存のリードから新しいリードを識別するために, 管理者はどのようなアプローチをとる必要がありますか？
A: 別のリードLightningアプリケーションを作成する. 
### 解説
SalesforceのLightningアプリケーションは特定のユーザーグループや役割に合わせてカスタマイズされたビューを提供するためのものです. 設問のような既存のリードを新しいリードを区別するためには, それ専用のLightningアプリケーションを作成することが効果的である.

## Q48. アクティビティに関するワークフロールールの電子メールアラートを作成できる.
A: できる
### 解説
ワークフロールールとは, 特定の条件が満たされた時に自動的にアクションをトリガーするためのもの. この設問でいう, アクティビティに関するワークフロールールを使用して, 条件が満たされた時に電子メールアラートを送信することは可能である.

-- アクティビティについて 公式ヘルプ --
https://help.salesforce.com/s/articleView?id=sf.mc_es_activities.htm&type=5

## Q49. A社の幹部は, ダッシュボードに不正確なデータが表示されていると報告している. 管理者はソースレポートが変更されていることを発見した. ソースレポートの整合性を維持するために管理者が実行する必要がある2つのアクションはどれ？次から2つ選べ.
選択肢 : 
    Aビューアー アクセスで新しいレポート フォルダーを作成します。
    Bダッシュボードをユーザーのプライベート フォルダーに移動します。
    Cダッシュボードを動的ダッシュボードに変更します
    Dダッシュボード レポートを表示専用フォルダーに移動します。

A: A, D
### 解説
ビューアーアクセスで新しいレコードを作成することで特定のユーザーやグループのみがレポートを閲覧できるようになる. また, ダッシュボードレポートを表示専用フォルダーに移動することで, ユーザーはレポートの閲覧はできるが変更を加えることはできない. これによってレポートの整合性が維持されるようになる.

## Q50. A社は応答待ちのケースについてマネージャーに自動的に通知したいと考えている. 要件としては,　ケースの作成後, 2時間以上です. この要件を満たすために, 管理者はどの機能を使用する必要がありますか？
A: エスカレーションルール
テスト記事

## 見出し2
ここはテキストです。

### 見出し3
ここはテキストです。

#### 見出し4
ここはテキストです。ここはテキストです。

```
<ul>
<li>リストタグ</li>
<li>リストタグ</li>
</ul>
```

**強調文章**

`インラインコード`

- リスト1
- リスト2
- リスト3

1. 番号付きリスト1
1. 番号付きリスト2
1. 番号付きリスト3

![AdobeStock_579677024.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28768/20600bf2-20ca-e0d3-01b7-04fec4437bf0.jpeg)

:point_up:
【ノーコードAIアプリ開発】ADFI画像認識で「きのこ・たけのこ判定アプリ」を作ってみた！

昨日（2024/3/12）、[「ADFI画像認識」のベータ版がリリース](https://www.atpress.ne.jp/news/387798)されました！
さっそく「ADFI画像認識」を使って、AIアプリを作成してみた感想を載せます！
世界最速のレビューかも？


ちなみに、ADFIはクラウド上でAIを開発できるプラットフォームで、「ADFI画像認識」はベータ版なので無料で使えます！



# きのこ派orたけのこ派 判定アプリ

![アプリ画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/50909a8b-caad-a39f-b0f3-421270d3f16a.jpeg)


せっかくなので、日常生活で役立ちそうなアプリを作ろうと思い、
スマホで撮影したものが、「きのこの山」と「たけのこの里」のどちらの派閥か判定（どちらに似ているか識別）するアプリを作ってみました！
今後の「きのこの山 VS たけのこの里」の戦いの必需品になるかも？


# アプリ実験結果

試しにアプリを使って、どちらの派閥か判定してみました！

![実験結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/35a1ad87-0476-0c83-98cd-a11b6bd79443.jpeg)

きのこの山：当然、きのこ派閥ですね！
たけのこの里：これも問題なく、たけのこ派閥です！
えりんぎ：きのこの仲間だけあって、きのこ派閥でした！
アポロ：きのこ派閥かと思いきや、意外に、たけのこ派閥でした！


# アプリ作成手順

今回アプリを作成した手順を解説します！

## 1. プロジェクトを作成する
まずは、ADFIのサイト（ https://web.us.adfi.karakurai.com/webapp/signin?lang=ja ）にログインします。
「ADFI画像認識」のプロジェクトを新規作成したら、作成したプロジェクトの名前のリンクをクリックします。

![プロジェクト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/bc6cc31d-73e8-9bad-17f2-da36a9d6b6b6.jpeg)

## 2. AIモデルを作成する
AIモデルを新規作成します。

![プロジェクト詳細.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/abac21b7-41c7-c89a-6d0e-7935c7f503a7.jpeg)

## 3. カテゴリーを作成する
判定したいカテゴリーを１つずつ作成していきます。

![ステップ１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/12116832-3701-62c8-517c-5cdb007ee36c.jpeg)

## 4. AIの学習画像と評価画像をアップロードする
カテゴリーごとに、AIに学習させたい画像をアップロードします。
評価で使う評価画像もアップロードします。

![カテゴリーの編集.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/6a808405-bd47-cd65-d713-eec9a84e5149.jpeg)

アップロードが完了したら、元の画面に戻ります。

![カテゴリーの編集２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/9afad2fa-749b-9ce0-9d60-109d0f6518d6.jpeg)

同様にして、判定したい全てのカテゴリーを作成します。（下記は、たけのこの画像をアップロードした後の状態。）

![カテゴリーの編集３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/837f40da-b83e-5c1c-b32b-eb835cbd6bc7.jpeg)

## 5. AIの学習を行う

「次のステップに進む」ボタンをクリックしてステップ２に進んだ後、「学習開始」ボタンをクリックします。
AIの学習が完了するまで、しばらく待ちます。
（１～２分で完了しました。）

![ステップ２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/3a13039f-6a06-a5d2-2112-7bf1f6bba1dd.jpeg)

## 6. 評価結果を確認する
AIの学習が完了すると、AIの評価結果が表示されます。
正解率100％でした！
「AIアプリを作成」をクリックします。

![評価.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/c2852e46-6bdd-7592-3ff4-b7775f959249.jpeg)

## 7. アプリ完成
「QRコードを表示」をクリックすると、作成したAIアプリのQRコードが表示されます。
スマホでQRコードを読み取れば、すぐにAIアプリを使用できます！

![AIアプリ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535236/1cbf2a2e-3812-851e-c0e4-82c0b1c8df79.jpeg)


# 感想
すごく簡単な操作で、本格的なAIアプリが作成できました！
AIアプリ作成にかかった時間は、10分ちょっと。（学習画像を準備した時間を除く）
とても面白いので、いくつか他にもアプリを作って遊んでみようと思います！

仕事の観点としては、スマホで撮影した画像を検査するアプリとか簡単に作って業務利用もできそうです！
PowerShellを使ってADの「次回ログオン時、パスワードを変更する」を一括でやる方法

これやるのにめっちゃ時間かかったのでメモ
ユーザー毎とグループ毎で一括設定できます

#
ユーザー用
```
# 複数のアカウント表示名を指定
$userDisplayNames = @("テスト ユーザーA","テスト ユーザーB","テスト ユーザーC")



try {
    $totalUserCount = 0  # 合計ユーザー数をカウントする変数を初期化

    foreach ($userDisplayName in $userDisplayNames) {
        # ユーザーを表示名から取得
        $user = Get-ADUser -Filter "DisplayName -eq '$userDisplayName'"

        # ユーザーが存在する場合のみ処理を行う
        if ($user) {
            # ユーザーに対してPasswordNeverExpiresを設定する
            Set-ADUser -Identity $user.SamAccountName -PasswordNeverExpires $false
            Write-Host "ユーザー '$userDisplayName' のパスワードの有効期限を無期限にする設定を無効にしました。"

            # ユーザーに対してChangePasswordAtLogonを設定する
            Set-ADUser -Identity $user.SamAccountName -ChangePasswordAtLogon $true
            Write-Host "ユーザー '$userDisplayName' のパスワードリセットの準備が完了しました。"

            $totalUserCount++  # 合計ユーザー数をインクリメント
        } else {
            Write-Host "アカウント表示名 '$userDisplayName' のユーザーが見つかりませんでした。"
        }
    }

    # 合計ユーザー数を表示
    Write-Host "設定した合計ユーザー数: $totalUserCount"
} catch {
    Write-Host "エラーが発生しました: $($_.Exception.Message)"
}
```

#
グループごと
```
# 複数のグループ名を指定
$groupNames = @("グループ１", "グループ２", "グループ３")


try {
    foreach ($groupName in $groupNames) {
        # グループのメンバーを取得
        $groupMembers = Get-ADGroupMember -Identity $groupName -Recursive

        # 各メンバーに対して処理を行う
        $userCount = 0
        foreach ($member in $groupMembers) {
            if ($member.objectClass -eq "user") {
                # ユーザーに対してPasswordNeverExpiresを設定する
                Set-ADUser -Identity $member.SamAccountName -PasswordNeverExpires $false
                Write-Host "グループ '$groupName' のユーザー '$($member.SamAccountName)' のパスワードの有効期限を無期限にする設定を無効にしました。"

                # ユーザーに対してChangePasswordAtLogonを設定する
                Set-ADUser -Identity $member.SamAccountName -ChangePasswordAtLogon $true
                Write-Host "グループ '$groupName' のユーザー '$($member.SamAccountName)' のパスワードリセットの準備が完了しました。"

                $userCount++
            }
        }

        # ユーザーの合計数を表示
        Write-Host "グループ '$groupName' のユーザーの合計数: $userCount"
    }
} catch {
    Write-Host "エラーが発生しました: $($_.Exception.Message)"
}
```
MIPSのSIMD其の八

あまりやることがないので、久しぶりにDSPを見てみました。

前までにDSPで追加された64Bitレジスタ4本の保存はできていましたが、復帰が出来ているか確認していませんでした。

コンテキストスイッチ後にDSP命令を実行すると毎回トラップが発生するのかと思っていたのですが、デバッグライト入れたところ、初回しかトラップは発生しません。

どうもどこかでステータスレジスタを保存して復元しているようなのですが、いろいろいじってみたのですが、どこか分かりませんでした。

なのでトラップでDSP固有のレジスタをリストアすることは出来ないようです。

正統方でアセンブラのcpu_switchの最後にレジスタを戻すところの直前にDSPレジスタの復帰を追加してみました。

復帰させるステータスレジスタのMIPS_SR_MXが立っていたら復帰させるようにしました。

テストプログラムを書いて見ました。qemuのテストプログラムをベースにしています。

```c
#include<stdio.h>
#include<assert.h>

int main(int argc, char *argv[])
{
    int acli, aclo;
    int result;

    acli   = atoi(argv[1]);
    result = acli;

for(;;) {
    __asm
        ("mtlo %1, $ac1\n\t"
         : "=r"(aclo)
         : "r"(acli)
        );
sleep(1);
    __asm
        ("mflo %0, $ac1\n\t"
         : "=r"(aclo)
        );
printf("%x %x\n", result, aclo);
    if(result != aclo) {
        printf("error\n");
        break;
    }
}

    return 0;
}
```

これを引数を変えて二つ動かしてerrorが発生しないことを確認しました。（この修正を行う前はちゃんとエラーが出る事も確認しました）

インラインアセンブラがよく分からずmtloのところの引数にダミーの返り値を書かないとコンパイルが通りません。

トラップのコードは意味がないコードがあるので、いつか直します。
k-meansでTitanicデータをクラスタリングしてみた

# はじめに
k-meansを使って、有名なtitanicデータをクラスタリングしてみます。

特徴として、単純なアルゴリズムであることや連続変数を扱いやすいこと、統計的な手法でないこと（正規分布を仮定していたりしないこと）などが挙げられます。

# titanicデータをk-meansでクラスタリング!
### データ読み込み~クラスタの割り当て
```python
# ライブラリをインポート
import seaborn as sns
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
```

```python
# Titanicデータセットをロード
titanic_df = sns.load_dataset('titanic')

# 今回使用する列のみ残す。またageには欠損があるので、dropna()を行う
titanic_df = titanic_df[['survived', 'age', 'fare']]
titanic_df = titanic_df.dropna()

# titanic_df.head()
```

```python
# 特徴量を標準化
features = titanic_df[['age', 'fare']]
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
```

```python
# エルボー法で最適なクラスタ数を探す
sse = []  # 各kにおけるSSE（クラスタ内誤差平方和）を格納するリスト
for k in range(1, 11):
    kmeans = KMeans(n_clusters=k, random_state=123)
    kmeans.fit(features_scaled)
    sse.append(kmeans.inertia_)  # SSE（クラスタ内誤差平方和）をリストに追加

# SSEのプロット
plt.figure(figsize=(6, 4))
plt.plot(range(1, 11), sse, marker='o')
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('SSE')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/385cff97-7d6b-c376-768b-cbf5789b3584.png)

```python
# K-meansクラスタリングを実行して、クラスタラベルを得る
kmeans = KMeans(n_clusters=3, random_state=123) # エルボー法より、k=3とする
clusters = kmeans.fit_predict(features_scaled)

titanic_df['cluster'] = clusters
#titanic_df.head()
```

```python
#クラスタごとの平均を計算
titanic_df.groupby('cluster').agg('mean')
```

|cluster|survived|age|fare|
|--|--|--|--|
|0|0.3968|21.1366|21.6443|
|1|0.7575|31.9672|222.8972|
|2|0.3750|45.1208|32.7964|

クラスタごとの平均を計算すると、以下のようなことがわかります
- cluster1の生存率が高い
    - cluster1は運賃の平均がcluster0,2に比べて高い
- cluster0,2の生存率はだいたい同じ


### 結果の可視化
```python
# クラスタと生存状況に基づいて色分け
sns.scatterplot(x='age', y='fare', hue='cluster', data=titanic_df , palette=['red', 'blue', 'green'])

plt.title('K-means Clustering of Titanic Data - All Passengers')
plt.xlabel('Age')
plt.ylabel('Fare')

plt.xlim(0, 85)
plt.ylim(0, 550)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/933d5801-d243-4370-cedb-f044a99253fe.png)

散布図によると、3つの群の特徴は、それぞれ以下の通りです。
1. Fare（運賃）の高い群
1. Fare（運賃）が低く、Age(年齢)の高い群
1. Fare（運賃）が低く、Age(年齢)の低い群

なお、生存群と非生存群とに分けた散布図を下にお示ししています。
これによると、生存群では非生存群に比べてcluster0の0~10歳の点が多いこと、非生存群では生存軍に比べてcluster2の30~50歳の点が多いことが見えてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/a9548647-dc4e-aa91-0ab9-b3dc9a4af4fe.png)

# おわりに
最後までお読みいただきありがとうございました！

### 関連記事
- [【目で見てわかる】k-meansクラスタリングの基本から限界まで](https://qiita.com/arima_/items/4a775aeec61de07d2548)
- [Rで隠れたグループを発見！潜在クラス分析(LCA)でTitanicデータを解析してみた](https://qiita.com/arima_/items/f38f1cf65290658c6254)
Google Map上にベクトルタイルを描画してみた

# 概要説明
ベクトルタイルを、Google Map上に描画する方法を調査してみました。
結論から言いますと、Vector-Tiles-Google-Mapsといライブラリを使用して、Google Map上にベクトルタイルを描画します。描画のイメージは以下になります
![qiita1 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916958/3015f77b-f370-b0c4-5243-97cab51659b6.gif)


## 使用したもの
### Vector-Tiles-Google-Maps
Google MapにベクトルタイルをレンダリングするためのJavaScriptライブラリ。

https://github.com/techjb/Vector-Tiles-Google-Maps/tree/master

### ベクトルタイル(TerraMap API町丁目ポリゴン)
今回使用したベクトルタイルは、TerraMap APIの町丁目ポリゴンデータをベクトルタイル配信にしたものです。

https://www.mapmarketing.co.jp/terramap-api?grid=qiita&utm_source=qiita.com&utm_medium=referral&utm_campaign=qiita_gmap-vectortile_84a4e1358ec6393100e3_01

## サンプルコード
Vector-Tiles-Google-Mapsをインストールし、optionsオブジェクトにベクタータイルサーバーのURLを指定します。MVTSourceを作成して、overlayMapTypeとしてGoogleMapにインサートします。
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Google Map上TerraMap APIのポリゴンをベクトルタイルで表示する</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <div id="map" style="width: 100%; height: 600px"></div>
    <script src="dist/vector-tiles-google-maps.js"></script>
    <script type="text/javascript">
      var map;

      function InitGoogleMap() {
        map = new google.maps.Map(document.getElementById("map"), {
          center: { lat: 35.681236, lng: 139.767124 },
          zoom: 10,
        });

        google.maps.event.addListenerOnce(map, "tilesloaded", function () {
          InitVectorTiles();
        });
      }

      function InitVectorTiles() {
        var options = {
          //任意のベクトルタイル配信サーバーのURLに変更してください
          url: "http://localhost:3000/tiles/{z}/{x}/{y}",
        };
        var mvtSource = new MVTSource(map, options);
        map.overlayMapTypes.insertAt(0, mvtSource);
      }
    </script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=GoogleMapKey=InitGoogleMap&libraries=&v=weekly"
      defer
    ></script>
  </body>
</html>

```
# おわりに
今回はVector-Tiles-Google-Mapsを使用してGoogle Map上にベクトルタイルを描画してみました。
ライブラリを使用して意外と簡単にベクトルタイルを描画することができました。ただ、Google Mapの機能ではなく外部ライブラリの利用について、色々と考慮しなければいけない点もありますので、Google Mapでmvtやpbf形式のベクトルタイルの表示はまだまだ難しいと思います。

Google Mapにベクトルタイルを描画してみる試しとして、deck.glを使う記事を公開しました。

https://qiita.com/yan_x/items/176ab38c8df090cbdfd0

Google Map以外の地図ライブラリでのベクトルタイル表示について、MapLibreを利用した記事がこちらになります。

https://qiita.com/y-mto/items/f62d4410e063ee98baa7

では、以上になります。最後まで読んでいただき有難うございました。
ブロックチェーンを使った仮想通貨やNFTの仕組みについて解説

# はじめに
初めまして。
奇兵隊という多国籍企業でインターンをしている阿部です！
福島県の磐梯町で地方創生を目的にした「ふるさとメンバーNFT」というプロジェクトに携わっています。
https://furusato-member.com/

# 概要
最近ビットコインだとかNFTだとかweb3.0だとか話題に上がってくるけど結局何なの？って思う人がたくさんいると思います。
今回はそんな人のために、用語の意味や仕組みを解説していきます。
この記事で理解していただいて、今後の役に立てれば嬉しいなと思います。

# web3.0とは
web3.0とはブロックチェーン技術を活用して実現した新しい概念のことで、分散型インターネットの総称です。2018年ころから有名になり、それを機に分散型インターネット社会の実現が見えるようになりました。

web3.0という用語があるようにweb1.0やweb2.0という用語もあります。
web1.0とは1990年代から2000年代前半の初期の頃インターネットの概念で、発信者と読者というのが明確に分かれており、発信者は記事を通して情報を発信することはできるが、読者からは何も情報を発信できない一方通行のような形式でした。

web2.0になると読者からも情報が発信できるようになりました。発信した情報にフィードバックを投稿で出来るようになり、双方向のコミュニケーションが可能になります。
また、X(旧Twitter)やInstagramのように個人が簡単に発信者になることが可能になり、自分の意見が簡単に発信できる時代になりました。

web3.0になるとブロックチェーンという新しい技術により、インターネット上のデータを分散してみんなで保持・保管するという新しい概念が生まれました。web3.0が注目されるのにはセキュリティーの向上や自由に通信することが可能になったためといわれてます。

# ブロックチェーンについて
ブロックチェーンというのは先ほども上げたように、データをみんなで共有することを可能にする技術です。

今までのインターネットだと、googleやfacebookのような大企業が大規模なサーバーを介して取引履歴を管理し、信頼性を担保していました。このような体制だと、サーバーが攻撃を受けた際にサービス全体が停止したり、データが破損してしまう可能性があります。
しかし、ブロックチェーンを活用した分散管理型だと、攻撃が受けづらく仮に攻撃を受けてデータが破損しても復旧することができます。攻撃を受けづらい理由として、ブロックチェーンという名前にあるようにこの技術は、ユーザーの1回の取引記録を1つのブロックにして、今までの記録をチェーンのようにつなぐからだそうです。このデータを攻撃するためには今までの記録を辿る必要があるため、ハッキングするのが難しいのです。
データの復旧が容易なのもデータをユーザーみんなで共有しているため、1人のデータが破損してもほかのユーザーのデータを参照できるためです。

# 仮想通貨の仕組み
仮想通貨は、暗号化技術を用いて発行されるデジタル通貨です。従来の法定通貨とは異なり、中央管理者が存在せず、分散型台帳であるブロックチェーンによって管理されます。
仮想通貨の取引は、P2P(peer-to-peer)と呼ばれる方式で行われます。P2P方式では、取引仲介者を介さずに、ユーザー同士が直接取引を行うことができます。

# NFTとは
NFTとはNon-Fungible Tokenの略で日本語では非代替性トークンと訳されるデジタル上の資産です。
代替可能というものは同じものを同じものと交換することができるということです。
これだとわかりづらいと思うので例を示します。
Aさんが10円硬貨を持っています。またBさんも10円硬貨を持っています。当たり前のことですがこの10円硬貨どうしは交換しても問題ないですよね？
なぜならこの2つの10円硬貨同じ価値を持っているからです。
それでは逆の意味の代替不可能というのは、同じものではあるけど価値が違うため交換できません。
例えば、AさんはただのTシャツを持っています。また、BさんもただのTシャツを持っています。
しかしBさんのTシャツには有名人のサインが入っています。
これは同じものだと言えるでしょうか？
明らかにAさんが持っているシャツよりも価値が高いと言えます。
また、このBさんが持っているものと全く同じシャツは複製ができません。これが代替不可能ということです

今まではインターネット上にあるデジタルアートというのはコピーすることで複製が簡単にできるものでした。そのためデジタルアートには価値が生まれませんでした。
しかし、技術の発展により価値を持たせることが可能になりました。NFTを使ってデジタルアートに代替不可能性を付けることが可能になります

# NFTの特徴
NFTには4つの特徴があります

1.代替不可能で唯一性がある
これは先ほども言ったようにコピーを不可能にして、作品そのものへの価値をつけることが可能になります。

2.誰でも作成・発表可能
デジタルデータをNFTのプラットフォームにアップロードするだけで簡単にNFT化することができます。複雑な知識は必要ないので誰でもできますね。

3.複雑な設定ができる
NFTの技術の1つとしてスマートコントラクトというのがあります。
この技術はNFTに様々な設定を施すことができます。
例えば、自分のアップロードした作品をほかの人が買って、その人が別の人に売ったとします。これを2次流通といいます。
2次流通された際、作品を制作した本人に販売価格の数％が入るような仕組みも設定することができます。

4.破損・紛失のリスクがない
NFTはインターネット上に作品をアップロードするので紛失するリスクがありません。

以上の4つがNFTの特徴です
【HACKTHEBOX】HACKTHEBOX Photon Lockdownの解説

## はじめに
ネタバレ注意&筆者はLinuxやCTFに精通しているわけではないので，
理解できていない部分が多くあります．
環境 win11 wsl2 Ubuntu
問題リンク:https://app.hackthebox.com/challenges/Photon%2520Lockdown
問題内容:ハードコーデイングされた認証情報を読み出せ
## Photon Lockdownの解説
問題ファイルをDLすると，
fwu_ver  hw_ver rootfsが得られる.
rootfsはファイルシステムになっているので，
これをマウントする．
```bash
mkdir -p /home/lexic/aso/hackthebox/ONT/tmppp
#マウント先を作成　tmpppという名前にする

sudo mount -o loop /home/lexic/aso/hackthebox/ONT/rootfs /home/lexic/aso/hackthebox/ONT/tmppp
#rootfsをtmpppにマウント

ls /home/lexic/aso/hackthebox/ONT/tmppp/
#マウントしたディレクトリを見る
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/04d14b0d-feb9-0f69-a1c3-01759421d35a.png)

いつものlinuxのディレクトリ構造がある．
認証情報はetc以下に保存されることが多い．

```bash
cd etc
grep -r "HTB{" .
#HTB形式のフラグを取得
```
grepコマンドで引っ張ってくることで答えのflagが得られました！
先日の続き

[先日](https://qiita.com/k587mama/items/c5248e8fbb2eb3e64de2)の解決策が分かったため記述

どうやらrubyとJavaScript を同時に使うことは相性が悪かったことが原因とメンターさんに伺いました。
解としては、該当するviewファイルの中の

```ruby
<%= form_with model: @item, local: true do |f|%>
```
のなかに`data: {turbo: false},`を追記した
```ruby
<%= form_with model: @item, data: {turbo: false},local: true do |f|%>
```

と記述すること。でした。
(ポエム)「判断ノート」のすすめ #3-1

# 「判断ノート」初級編
## 「はかる」

![B001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/5d00d8f2-3eab-9b5c-386b-bb838e4ffd90.png)


![B002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/e1637544-c42a-ba2c-b6ac-73d58232abc1.png)


![B003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/cce6d879-ea33-016b-3ce8-42e0bfdc7979.png)


![B004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/9ee62ed3-ad0f-5d98-fbbf-634c1352e00c.png)


![B005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/09d83a0d-65cb-bffe-8dec-53322ecf8c54.png)


![B006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/cb65d3d8-f6bc-49c0-df26-1f6a251aec7f.png)

![B007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154569/0dcf1a4b-8350-7e03-c8af-6d5b42f17923.png)
[Google Drive API v3] JavaでDriveのファイルのラベルを更新する

Google Drive API v3（Java）を使用して、
Driveに置かれているファイルのラベルを更新する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Drive API v3] JavaでDrive APIを使う](https://qiita.com/doran/items/15b2c59adb410ddeeb8a)
を参照ください。
:::

|No||目次|
|---|---|---|
|1||[ラベルを更新](#1-ラベルを更新)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|

## 1. ラベルを更新
Driveにあるファイルのラベルを更新します。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
DriveScopes.DRIVE
DriveScopes.DRIVE_FILE
DriveScopes.DRIVE_METADATA
```
[⧉[Google Drive API v3] JavaでDrive APIを使う(2.2 Driveインスタンスを取得)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a#22-driveインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

```java
public static void main(String[] args) throws Exception{
    Drive drive = getDrive();
    Drive.Files files = drive.files();
    
    ModifyLabelsRequest labels = new ModifyLabelsRequest();　//変更したい内容をセットしてください。
    
    Drive.Files.ModifyLabels generateIdse = files.modifyLabels("ファイルID",labels);
    
    ModifyLabelsResponse res = generateIdse.execute();
    System.out.println(res);
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//www.googleapis.com/drive/v3/files/{ファイルID}/modifyLabels
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

#### 1.2.3. リクエストボディ
ModifyLabelsRequestのsetメソッドにより、リクエストボディを設定できます。

|メソッド|引数|説明|
|---|---|---|
|setLabelModifications|List\<[LabelModification](#labelmodification)\>|ファイルのラベルに適用するリスト|

#### LabelModification

|メソッド|戻り値|説明|
|---|---|---|
|setLabelId|String|変更するラベルID|
|setFieldModifications|List\<[LabelFieldModification](#labelfieldmodification)\>|このラベルのフィールドに対する変更のリスト|
|setRemoveLabel|Boolean|ラベルを削除するか|

#### LabelFieldModification

|メソッド|戻り値|説明|
|---|---|---|
|setFieldId|String|変更するフィールドID|
|setDateValues|List\<[DateTime](#datetime)\>|フィールドの日付値|
|setTextValues|List\<String\>|フィールドのテキスト値|
|setSelectionValues|List\<String\>|フィールドの選択値|
|setIntegerValues|List\<Long\>|フィールドのInteger値|
|setUserValues|List\<String\>|フィールドのユーザー値<br>値は電子メールアドレス
|setUnsetValues|Boolean|このフィールドの値の設定を解除するか|

#### DateTime

|メソッド|戻り値|説明|
|---|---|---|
|getValue|long|unixミリ秒|
|getTimeZoneShift|int|UTCからの分数で表されるタイムゾーン|

### 1.3. レスポンスの内容
#### ModifyLabelsResponse

|メソッド|戻り値|説明|
|---|---|---|
|getKind|String|リソースの種類<br>固定文字列：\"drive#modifyLabelsResponse\"|
|getModifiedLabels|List\<[Label](#label)\>|リクエストによって追加または更新されたラベルのリスト|

#### Label

|メソッド|戻り値|説明|
|---|---|---|
|getId|String|ラベルID|
|getRevisionId|String|ラベルのリビジョン|
|getKind|String|リソースの種類<br>固定文字列：\"drive#label\"|
|getFields|Map\<String,[LabelField](#labelfield)\>|フィールドIDをキーとした、ラベル上のフィールドのマップ|

#### LabelField

|メソッド|戻り値|説明|
|---|---|---|
|getKind|String|リソースの種類<br>固定文字列：\"drive#labelField\"|
|getId|String|ラベルフィールドID|
|getValueType|String|フィールドタイプ<br>dateString、integer、selection、text、user|
|getDateString|List\<[DateTime](#datetime)\>|日付情報<br>**valueTypeがdateStringの場合のみ**|
|getInteger|List\<Long\>|数値情報<br>**valueTypeがintegerの場合のみ**|
|getSelection|List\<String\>|選択情報<br>**valueTypeがselectionの場合のみ**|
|getText|List\<String\>|テキスト情報<br>**valueTypeがtextの場合のみ**|
|getUser|List\<User\>|ユーザー情報<br>**valueTypeがuserの場合のみ**|

<br>
<br>
おしまい。。
Zennのいいねランキングを自動投稿してくれるSlack Botをつくりました！


## このアプリを作った経緯

個人的にZennの記事のいいねランキングを作って残しておきたいと思ったのが発端で、どうせ作るなら公開できる形にして通知もほしいな〜ということで、**GAS, Slack, Notion**という最小構成(?)でつくってみました

## 何を作ったか

Zennに投稿された記事で、**週間・月間のいいね数ランキング**をそれぞれ毎週月曜日と毎月一日に作成してNotionに保存し、Slackにも通知します

Slackにはランキングの上位3記事を投稿します

こんな感じ👇
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3065616/1a34ab09-3bb3-9e33-57b9-dceb1f9975a4.png" width=600>

また、週間ランキングでは上位30位まで、月間ランキングでは上位50位までをNotionデータベースに保存して公開します(上の投稿の「ランキングの続きはこちらから」がデータベースへのリンクになっています)

こんな感じ👇
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3065616/c8b83879-c8bf-a026-3851-a77b4c7d2d4c.png"  width=800>

このデータベースはWeb公開しているので誰でもみることができ、また複製することもできます。

:::note warn
週末・月末に集計するため、必然的に週末・月末に投稿された記事はランキングに載りにくい仕様となっています。ご了承ください。
:::

## 使い方

超簡単3ステップです。

1. ランキングを投稿するためのSlackチャンネルを作成
2. [ここ](https://slack.com/oauth/v2/authorize?client_id=6736333290576.6713555915506&scope=incoming-webhook&user_scope=)からSlackアプリをワークスペースにインストール
3. ランキングが投稿されるのを待つ！

ただ、現時点ではこのアプリはSlackの承認をうけていないため、こんなメッセージが出ます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3065616/72406660-07f0-6c73-b50e-1ea0bc1579ef.png"  width=600>

これダサいし、なんか怪しいアプリに見えるなあ....

ということで、現在Slackの[app directory](https://w1709024309-gyp373610.slack.com/intl/ja-jp/apps)に申請中なのですが、前提条件として**10以上のワークスペースにインストール**されているという項目があります（これを満たしていないと審査してくれません😭

**ここまで読んでくれた方は、インストールにご協力していただけると助かります！！！**

:::note warn
このアプリは現在のところ、webhookを利用してランキングをチャンネルに投稿するだけのものなので、チャンネルの情報を読み取ったりはしません
:::

## Botについて

Slack Botの名前はTechをもじってTekTek(テクテク)としました
なんか響きが可愛いくて気に入っています🥰
ランキング上位にテクテク登っていくという意味もあります(後付け)

また、Zennのイメージカラー(?)の青を基調としたキャラクターをChatGPTに生成してもらいました。ChatGPTにしてはそこそこいい出来だと思います

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3065616/f2bcf807-7694-a2f9-1b67-16bd324d02fa.jpeg"  width=400>

ランディングページも作ったのでぜひ見てください！

https://taichiro-s.github.io/zenn_ranking/

## 技術スタック

紹介するほどの技術を使っていないのでアレですが...
一応以下のような構成になっています

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3065616/74bd91df-0c6b-0eb7-3b6b-4fdd0813a653.png"  width=800>

フロントエンド(というか認証のためのリダイレクトページ)とバックエンド処理はGASで行い、登録されたSlackチャンネルのwebhook URLを保存するためにCloud Datastoreを使用しています。記事のデータはNotionデータベースに保存しています。
またGithub Actionsとclaspを使用して自動テスト、プッシュ、デプロイをしています。

実装については別記事にするかもです

## 追加実装予定(時期未定)

とりあえず動くもの作ってみたという状態なので、まだまだ機能を追加していきたい！
今のところ、以下のようなのを考えています

- [ ] Qiitaや海外の技術記事なども取得してランキングを投稿する
- [ ] Twitterのbotも作る

ほかにも欲しい機能があればコメントなどで教えてください！

## 最後に

このアプリに関して何かあれば[こちら](https://forms.gle/S4eAoQG3yeNsjmGq7)までお問い合わせください


## 参考にさせていただいた記事

https://zenn.dev/yoshimaru46/articles/001ff978cc1ecc
【初心者】DNSの動きについて

# DNSとは
インターネットでウェブサイトにアクセスするには、その住所が必要です。しかし、私たちは普段「www.google.com」のようなドメイン名を入力しますが、コンピュータは数字の羅列である「IPアドレス」でしかウェブサイトを認識できません。

そこで登場するのが、ドメイン名とIPアドレスを結びつける**DNS（Domain Name System）** です。DNSはドメイン名とIPアドレスを紐づけた情報を管理し、私たちが使いやすいドメイン名でウェブサイトにアクセスできるようにする仕組みです。

# DNSの動き
DNSの動きについて以下の画像を用いて説明します。
![DNS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571534/00333691-6ae9-f28b-5c8b-d21373a06ec8.png)
### 5つのポイント
#### 1. ブラウザからDNSサーバへの問い合わせ(①、②)
ブラウザに入力されたドメイン名をもとに、OSに搭載されたスタブリゾルバはキャッシュサーバと呼ばれる身近なサーバに問い合わせを行います。キャッシュサーバは、過去に問い合わせたドメイン名の情報を持っている可能性があり、その場合はすぐにIPアドレスを返します。
#### 2. キャッシュサーバによるルートサーバへの問い合わせ(③、④)
キャッシュDNSサーバに情報がない場合は、インターネット上のルートサーバと呼ばれる最上位のDNSサーバに問い合わせを行います。ルートサーバは、TLD（トップレベルドメイン）と呼ばれるドメイン名の情報（例：「.com」や「.jp」）を管理しており、どのTLDサーバに問い合わせればよいかを通知します。
#### 3. TLDサーバへの問い合わせ(⑤、⑥)
ルートサーバから通知されたTLDサーバに問い合わせを行い、そのドメイン名に関連する権威DNSサーバの情報を取得します。
#### 4. 権威DNSサーバからの回答(⑦、⑧)
最終的に、ドメイン名を管理する権威DNSサーバに問い合わせを行い、目的のドメイン名のIPアドレスを取得します。
#### 5. webサイトへのアクセス(⑨-⑪)
キャッシュサーバは得られた目的ドメインのIPアドレスをキャッシュに保存し、スタブリゾルバにもIPアドレスを返答します。スタブリゾルバから送られたIPアドレスをもとにwebブラウザは目的のwebサイトにアクセスします。
### DNSの仕組みのポイント
* 階層構造: DNSは、ルートサーバ、TLDサーバ、権威DNSサーバなど、階層的な構造で構成されています。
* キャッシュ: 問い合わせた情報は、各DNSサーバで一定期間キャッシュされるため、次回同じ問い合わせがあった場合は、すぐに回答できます。
* 負荷分散: 複数のDNSサーバが協調して動作することで、負荷分散を行い、アクセス集中による障害を防ぎます。
【Swift】DIとは？コンストラクタインジェクションについて説明

# 目次
[1.DIとは？](#DIとは？)
[2.コンストラクタインジェクションの実例](#2-コンストラクタインジェクションの実例)
[3.おわりに](#3-おわりに)

# 1. DIとは？
正式名称Dependency Injection、通称DI。日本語で言うと「依存性注入」です。
訳分からないですよね？、、
でも、大丈夫です。本記事で誤解を恐れずに、なるべく簡単に説明します。

DIとは、簡単に言うと「オブジェクトを生成する際に(、もしくは遅れて)、必要なデータセットを渡しますよ〜」と言うことです。
その中でもSwiftのDIでは***コンストラクタインジェクション***というものがあります。
コンストラクタインへクションとは簡単にいうと「オブジェクトを生成する際に、必要なデータセットを渡しますよ〜」です。

# 2. コンストラクタインジェクションの実例
早速コードを見てみます。
## コンストラクタインジェクションを***使用しない***場合
~~~swift: HogeWireframe.swift
protocol Wireframe {
    associatedtype ViewController: UIViewController
    var viewController: ViewController? { get set }
}

class HogeWireFrame: Wireframe {
    typealias ViewController = HogeViewController
    weak var viewController: HogeViewController?
    init(viewController: ViewController) {
        //↓ここが外部から渡されるべきプロパティ
        self.viewController = viewController
    }

    func printName() {
        print(String(describing: viewController.self))
    }
}
~~~

~~~swift: HogeViewController.swift
class HogeViewController: UIViewController {
    let wireframe: HogeWireFrame
    // wireframe.viewController = selfを忘れてしまう可能性あり
    wireframe.viewController = self
    func printVCName() {
        wireframe.printName()
    }
}
~~~
ごにょごにょと書きましたが、要は、***クラスで定義した外部から与えられるべきプロパティviewControllerがnilのままになる可能性***があります。
実際に`wireframe.viewController = self`の処理を記述を忘れたとしてもnilを許容しているので、デバッカーのエラーすら吐かれないのです。怖い！

そこで登場するのがコンストラクタインジェクションです。

## コンストラクタインジェクションを***使用する***場合
~~~swift: HogeWireframe.swift
import UIKit

protocol Wireframe {
    associatedtype ViewController: UIViewController
    var viewController: ViewController? { get set }
}

class HogeWireFrame: Wireframe {
    typealias ViewController = HogeViewController
    weak var viewController: HogeViewController?
    init(viewController: ViewController) {
        //↓ここが外部から渡されるべきプロパティ
        self.viewController = viewController
    }

    func printName() {
        print(String(describing: viewController.self))
    }
}
~~~

~~~swift: HogeViewController.swift
import UIKit
class HogeViewController: UIViewController {
    // ↓ここがコンストラクタインジェクション、インスタンス生成と同時にプロパティの値を注入
    private lazy var wireframe: HogeWireFrame = .init(viewController: self)
    func printVCName() {
        wireframe.printName()
    }
}
~~~

以上のようにDIを正しく行うことで、***クラスのプロパティへの値の渡し忘れを防ぐ***ことができます。

# 3. おわりに
コードの規模が大きくなると、クラスのプロパティが内部で値を持っているもの、外部から渡されるべきものが混沌として、整理がつかなくなります。
その結果、、プロパティ値の渡し忘れなどが発生して正しく画面遷移できないなどのバグが発生し得ます。

DIのひとつコンストラクタインジェクションはこれを解決してくれる、一つの最適解なので頭に入れておいてください！
本記事を読んでいただき、ありがとうございました！！
ハッカソン&&チーム開発で最低限意識したいこと3選

# はじめに
先日、関西ビギナーズハッカソンVol.3に参加させていただきました。

https://kansai-hackathon.com/

そこで、今後のハッカソン&&チーム開発で生かすために、ハッカソンに参加して「これだけは間違えないようにしよう」と考えたことを、備忘録として残しておこうと思いました。
本当はもっと多くの反省点や学びがあるのですが、記述しすぎて結局何が大事なのかが分からなくなってしまわないために、本記事では3つに絞りました。また、筆者が今回初めての記事作成ということもあり、途中で書くのを投げ出さないためという理由もあります...

※ 筆者は受賞してません。悔しいです。

# About Me
・情報系学部所属の大学2回生（2024/03 時点）
・今回でハッカソンの参加は3回目（受賞歴なし）
・フロントエンドエンジニアになりたい

# 最低限意識したいこと
### （1）コア機能から実装しよう
アプリを使用する主な目的の機能のことを、コア機能と言います。

例えば...
- メッセージを送受信できるアプリを作りたい
→チャット画面
- 経路案内アプリを作りたい
→マップ画面の表示

などのことです。

コア機能が実装できていなければ、他の機能をどんなに凝って作ったとしても意味がありません。開発しようと思っているプロダクトのコア機能を最優先で開発を進めるべきです。今作ろうとしている機能が、本当に必要なのか？を一考してみましょう。

### （2）合理的な技術選定をしよう
開発するプロダクトのアイデアがまとまったら、技術選定を行います。
選定するにあたって、なぜこの技術を選んだのかを合理的に説明できるようにしましょう。

ここで、具体的な技術選定方法に関して、良いなと思った記事を添付させていただきます。

https://zenn.dev/kouchanne/articles/5819b0a7c3ecdfc9f880

### （3）はっきり役割分担をしよう
メンバーの力量や、スケジュールにあった役割分担をしましょう。

メンバー間でコードを書く力には差ができてしまいますが、コードを書くことだけがハッカソンではありません。例えば、進捗状況の管理, スケジュールの確認, プレゼン準備などは、コードをかけなくてもできます。

特に、ハッカソンでは最終日に行われるプレゼンが非常に大切になってきます。余裕をもったプレゼン練習を行うためにも、いつからプレゼン資料を作成し始めるかを決めておいた方が良いです。

# まとめ
この記事で記述させていただいたこと以外にも大切なこと/意識しなければならないことはたくさんあります。私は受賞することができませんでしたが、受賞の有無に関わらず、ハッカソンでは非常に多くのことを学べます。今後もハッカソンに参加していく予定ですので、この記事を繰り返し見返すことで、道を逸れてしまわないようにしていきたいと思います。

ここまで読んでくださって、ありがとうございました！
次こそは受賞します！！！
LLMのエラー対応

# llama-cpp-python

llama-cpp-pythonのインストールでエラーが発生した。

```
py -3.8 -m pip install llama-cpp-python
```

ERROR: Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based projects


下記の通り、参考にした。

```
download and install the "Microsoft C++ Build Tools" from the official Visual Studio website. Here are the steps you can take:

Visit the following URL: https://visualstudio.microsoft.com/visual-cpp-build-tools/.

On the webpage, you should see a "Download" button for the Visual Studio Build Tools. Click on it to initiate the download.

Once the download is complete, run the installer and follow the instructions to install the Microsoft C++ Build Tools.

During the installation process, make sure to select the necessary components for C++ development. This typically includes selecting the "C++ build tools" and any required packages or libraries.

After the installation is complete, try installing the hnswlib package again using pip.
```

https://github.com/imartinez/privateGPT/issues/445


# LangChain

## VectorstoreIndexCreator
そのままだと、VectorstoreIndexCreatorが、SSL通信をしてしまい、エラーが発生する。下記のように対応する。

```python
from chromadb.config import Settings
client_settings = Settings(anonymized_telemetry=False)
index = VectorstoreIndexCreator(embedding= embedding,vectorstore_kwargs={"client_settings":client_settings, "persist_directory":"persist"}).from_loaders([loader])
```

Faiss（Facebook AI Similarity Search）のほうが、saveとloadができるので、良さそう。

https://qiita.com/utanesuke/items/6efc03eca94f7de3b9cd


## logger
デフォルトではログを残すことはできない。以下の通り実装すればできるようである。

https://python.langchain.com/docs/modules/callbacks/filecallbackhandler

# Chainlit

SSL通信をしていたので、/.chainlit/config.tomlの設定の通信設定を無効にした。


修正前
```python
[project]
# Whether to enable telemetry (default: true). No personal data is collected.
enable_telemetry = true
```

修正後
```python
[project]
# Whether to enable telemetry (default: true). No personal data is collected.
enable_telemetry = false
```

起動方法

```python
py -3.11 -m chainlit run app.py 
```