OmniAICreator/Qiita-1.07M huggingface dataset:
ベイズ統計モデリング 写経2

#### 3.4.1.5 ベクトルへのアクセス

``` r
x=c(2.718, 3.14, 1.414, 47405)
```

``` r
names(x)=c("e","pi","sqrt2","zipcode")
```

どの要素を返すか数値で指定

``` r
x[c(2,4)]
```

    ##       pi  zipcode 
    ##     3.14 47405.00

どの要素を除外するか指定

``` r
x[c(-1,-3)]
```

    ##       pi  zipcode 
    ##     3.14 47405.00

それぞれの要素を返すか指定する

``` r
x[c(FALSE,TRUE,FALSE,TRUE)]
```

    ##       pi  zipcode 
    ##     3.14 47405.00

要素名を指定する

``` r
x[c("pi","zipcode")]
```

    ##       pi  zipcode 
    ##     3.14 47405.00

### 3.4.2 ファクター型

``` r
x=c("high","medium","low", "high","medium")
```

ファクター型に変換

``` r
xf=factor(x)
xf
```

    ## [1] high   medium low    high   medium
    ## Levels: high low medium

factor型を数値に変換

``` r
as.numeric(xf)
```

    ## [1] 1 3 2 1 3

levelsを指定

``` r
xfo=factor(x, levels=c("low","medium","high"), ordered=TRUE)
xfo
```

    ## [1] high   medium low    high   medium
    ## Levels: low < medium < high

``` r
as.numeric(xfo)
```

    ## [1] 3 2 1 3 2

既に存在しているfactor型のlevelを変更

``` r
x=c("high","medium","low", "high","medium")
xf=factor(x)
xf
```

    ## [1] high   medium low    high   medium
    ## Levels: high low medium

``` r
as.numeric(xf)
```

    ## [1] 1 3 2 1 3

``` r
xf=factor(xf, levels=c("low","medium","high"), ordered=TRUE)
xf
```

    ## [1] high   medium low    high   medium
    ## Levels: low < medium < high

``` r
as.numeric(xf)
```

    ## [1] 3 2 1 3 2

levelsの名前を変えたい場合

``` r
xfol=factor(xf, levels=c("low","medium","high"), ordered=TRUE, labels = c("bottom", "middle", "top"))
xfol
```

    ## [1] top    middle bottom top    middle
    ## Levels: bottom < middle < top
「保守性の高いコード」とは何なのか考える。 

「保守性の高いコード」とは、プログラムが容易に理解、変更、修正できる状態を指します。保守性が高いコードは、ソフトウェアのライフサイクル全体にわたって、変更やアップデートが必要な場合に効率的かつエラーが少ない方法で修正できるコードです。以下は、保守性の高いコードを書くためのいくつかの原則や実践例です。

明確性とシンプルさ: コードは他の開発者が理解しやすく、シンプルであるべきです。変数や関数の名前はわかりやすく、冗長なコードを避けるようにします。

適切なコメント: コード内には必要に応じて説明コメントを追加することで、他の開発者がコードの目的や処理フローを理解しやすくなります。

適切な構造化: 適切なデータ構造やアルゴリズムの選択、モジュールやクラスの適切な分割が重要です。関連する機能はまとまり、コードの断片が論理的な単位で構造化されているべきです。

一貫性の維持: コード内のスタイル、変数の命名規則、インデントなどを一貫性を持って適用することで、コードの可読性を向上させます。

テスト: ユニットテストや結合テストを適切に行い、コードが期待通りに動作することを確認します。これにより、変更やアップデートが予期せぬバグを生じにくくなります。

ドキュメンテーション: ドキュメントはコードの一部として考え、外部や内部の仕様、APIなどに対して十分なドキュメンテーションを提供することが重要です。

変更の容易さ: ソフトウェアの変更が容易であるように、コードは柔軟で拡張可能な構造を持つべきです。デザインパターンやベストプラクティスを活用して、将来の変更に対応できるようにします。

これらの原則を守ることで、コードの品質が向上し、保守性が高まります。
AIはパートナー？ライバル？ツール？

AIのおかげで仕事の効率は急激に上がり、各事業ドメインでの活用が容易になったのでユーザーも増え、コンテンツは溢れています。結局競争は激化し、遅れることに不安を感じる人々も多いのではないでしょうか？

AIによって世界はどのように変わるでしょうか？

私の分野、私のものが必要です。それなしでAIを使って何かをするのは本当に難しいです。やりたい、よくやっていて生活のためにもっとうまくやるべきことを最初に定義する必要があります。
そのうちパターン化できる仕事は人工知能によって代わりになるでしょう。パターン化できない仕事は何でしょうか？感情的で、毎回違う反応が得られる仕事です。
そういえば人こそが感情的存在です。
人ができること、やるしかないことは大体感情労働でした。近所の病院のレビューを見ると「治療が上手ですよ」より、「その病院は親切です」が大切に見えました。医者も感情労働者に近い存在です。
私たちが素敵と思っていたこと、例えばデザインやマーケティングも、他の仕事のようにパターン化作業が多いです。こういう仕事はAIが取り替えられて当然でしょう。
医師がまさに感情労働+高級パターン化労働の代表職種のようです。医大進学熱風が正しいかどうかから離れて、偏差値が高くなって受験者が集まるのは、AI時代の観点からは合理的な結果と思われます。

先日、OpenAIのサムアルトマンの解雇と復帰を見てびっくりしました。人類の未来を賭けた決断が少数の人々の瞬間的、感情的、そして純粋に資本と力の論理で決定するということです。
わずか数人によって決定する現実も心配ですが、意思決定の速度にも驚きました。彼らが普段追求する最高価値である効率とスピードの向上が、今回の事態の展開と決定過程で影響していることが明らかになっているのではないしょうか。

疑問は果たして誰かが一定以上の収益を創出しているのかです。コスト削減だけ見えます。コスト削減による利益増加は限界があります。（唯一お金を稼ぐ分野はAI活用成人物コンテンツ制作ではないかと思いますが）
World Economic Forumによると、今後4、5年間で8300万件の雇用が減り、6900万件の雇用が生じるというのでパイ縮小は確定です。
このような状況でShift/Pivotしながら新しい雇用に入る準備ができているのかと本人と本人組織に尋ねなければなりません。

某アメリカのデザイン会社でデザイナーにマウスとペンを使わないでキーボードだけ打つように指示したそうです。プロンプトを入力するとすぐに高レベルのイメージが出てくるのに、なぜマウスとペンで描いていますか？主にキーボードでプロンプトを打ち、補助でマウス、ペン書きするデザイナーになれる時代が来ました。
結局最も重要な競争力は、変化する時代に対する収容力と適応力と思われます。
本人の収容力/適応力に対する判断は、AIを私の能力を拡張させる道具として見るのか、私のご飯を持っていく競争者や敵と見ているのかで一応一次判断は可能です。

現在まで、AIを活用している絶対多数はオンライン/デジタル上で行われています。ところで、デジタルだけに頼ってはお金にならないです。ますます落ちるデジタルの価値にAIはむしろ油を注いでいます。
オフラインで実物、経験、体験につながらならない限り、人々は財布を開けません。スマホの画面ではなく、オフラインで目を埋める360度の視野、イヤホンの中に詰まったサウンドではなく、オフラインで聞こえる立体サウンド。そこにデジタルとオンラインが与えられない触覚、味覚、嗅覚の組み合わせに価値が上がります。
AIが導くデジタル価値の下落をオン・オフライン統合またはデジタル・アナログ統合が価値下落を防ぎ新しい価値創造が可能と思われます。その答えを探している人（会社）がもっと多くなることを期待します。
AIで大騒ぎだと思いがちですが、それくらい多くの人は使ってないです。ユーザー数はそこまで増えていません。
SimilarWebで訪問者数から見たら、Googleの月別ユニーク訪問者数30億人に比べて、ChatGPT（OpenAI）は約2.5億人で10分の1にも達してないです。AIを使える人がまだ少ない、または使ったことはあるけど使い続けてないようです。
なぜChatGPTのような素晴らしいツールを使い続ける人が増えないのですか？

AIが人間を凌駕するからといえ、私のご飯を奪う競争相手だという心配はあまり意味がないです。
まず、AIはマルチモーダルが一般化しても人間ができる多くのものの中でごく一部しかできません。一部機能に特化したAIと全般的に仕事ができる人間との比較は意味がないと思います。
次に、AIを競争相手と思いながら、その背後でAIを作っているIT企業を肯定視するのは皮肉です。AIは競争相手ではありません。それはAIを作る人間であり、AIを活用して私を置き換えるかもしれない他の人間です。
最後に、AIは指示を受けて仕事をよく処理する存在それ以上でも以下でもありません（現在まで。おそらくこれからも非常に長い間）。指示し、決定し、最後に行動し、その責任を負うのはまだ人間です。
行動することは人間の最も重要な力量の一つだと思います。もちろん、行動の主動的主体になるのか、他人やAIの命令を受けて被動的主体になるのかは別の話です。

普段、私たちが話していた意志、主体的行動がどれほど重要かを改めて悟ります。
今必要なのは、融合・統合能力です。企画だけ、デザインだけ、開発だけうまくいくのではなく、AIを持ち上げ、事業企画をしながら、デザインを一人でしながら、開発まで完結することです。
以前は、ある分野を非常に「深く」掘ることを重視しました。所謂専門家です。それでないと、ある事業の始終を「広く」一人でやってしまう人です。
今、どちらかを決める必要があります。以前と変わったことは、今はAIのおかげで、一人で事業を一から始めることができるようになったことです。
人間には簡単な歩く、感じる、見るなどの動作は人工知能やロボットには難しく、逆に人工知能には簡単な動作が人間には難しいということです。
この話は人間が上手くできることとAIが上手くできることは違うということです。私ができることとAIができることをよく分ける必要があります。
私が何をするか、何をAIにアウトソーシングするかに関することです。企業であれば何を従業員に任して、何をAIに任せるか考えなければなりません。
そして、AIの使用は今すぐ対応必要な緊急問題ではありません。数週間経ったらより良いツールが出てきて、以前は二つのツールを使って行った仕事が一つのツールにまとまることも頻繁に出てきます。
代わりに、時代に遅れないようにトレンドを追う必要はあります。流れだけ把握して、いざ自分が必要なもの、やりたいことが明確になったらしっかり入れば十分です。
人間とAIは循環構造で絡み合っています。人間がこれまで積み重ねたデータセットに基づいてAIは成果物を作り出し、人間はAIが作った成果物を通じて進化しています。

AIはパートナー？ライバル？ツール？
それとも私とは関係ない存在ですか？
状況に応じて、役割によって異なる答えが出てくると思いますが、一度考える価値があると思います。
iOS/Swiftで小顔加工フィルターをつくる

# 美顔小顔加工アプリを作る

![小顔.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6acc1374-59e9-0b01-937f-19e9a2c0b476.gif)

インスタにアップロードする時って小顔にしますよね？
小顔フィルターの実装の仕方です。

# 顔を検出してゆがませる

顔の領域を中心にゆがませます。
これで、周囲はなるべく自然に、顔だけ徐々に小さくできます。

### 顔の検出

```swift
let request = VNDetectFaceRectanglesRequest()
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try? handler.perform([request])
guard let results = request.results, let firstFace = results.first else { return nil }
let box = firstFace.boundingBox
let boxInImage = VNImageRectForNormalizedRect(CGRect(x: box.minX, y: box.minY, width: box.width, height: box.height), cgImage.width, cgImage.height)
```

これが画像内の顔の領域です。
この領域に、
**CIBumpDistortion**
というフィルターを適用します。

```swift
let boxCenter = CGPoint(x: boxInImage!.minX+boxInImage!.width/2, y: boxInImage!.minY+boxInImage!.height/2)
        
let radius = boxInImage!.height * 1.7
        let filter = CIFilter(name: "CIBumpDistortion", parameters: [kCIInputImageKey:ciImage,
                                                                    kCIInputCenterKey:CIVector(cgPoint: boxCenter),
                                                                    kCIInputRadiusKey:NSNumber(floatLiteral: radius),
                                                                     kCIInputScaleKey:NSNumber(floatLiteral: -Double(scale))
                                                                    ])?.outputImage!
let cropped = filter?.cropped(to: ciImage.extent)
```

これで顔部分だけ歪んで収縮した画像が得られます。
radiusが画像の端を越えると、画像領域全体が小さくなってしまうので、最後にクロップしています。

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
ワールド紹介を約二週間やってみた感想

本来服作成してただろう予定の時間が色々あって突然空いてしまい、
その空いた時間にやってたんですが、めっちゃハマりましたｗ

思ったより楽しく、予約ツィートは一か月後までつづいてる始末！！おはツイはそうでもない！！！（すぐ枯渇する）

Q:何が面白いの？
A:一人で黙々とやれる！！
私にとっては「一人でいる時間」も好きなタイプなので（もちろんみんなでワイワイ会話したり、１対１で時間をすごすのも好き。ただ人と接する時に充電が必要なタイプなので、一人でなにかしてメンタル充電→人と接するという感じ！

また、ＶＲＣにおいてもリアルにおいても「他人の干渉を受けず、一人で何かつくる時間を確保する」っていうのはすごく大切。『誰もいなくても楽しい時間を作れる状況』が大切。（ソーシャルひらいても、仲良いフレがみんなオフラインだったりプラベだったりするしね・・・）

あと単純に情報を受けとるだけだと、どうしても会話内容がネガティブになりがちなので、情報を発信する側（ブログや動画、服作成、イベント主催などなど）になったほうが絶対楽しいよ！というのはあります、特にＶＲＣにおいてはコミュニティの会話内容は顕著ですよね・・
知らん人の悪口大会になってるインスタンスなんて二回目以降行こうと思いませんからね

Q:気を付けてるコトはある？
Ａ：ミラーやペンがあった場合は「ペン有」「ミラー有」って書いてる。
本当は有無を記載したいけど、無いってわざわざかくのもワールドつくった人に悪いかなあ～って思ったので（あと有った場合にみつけられなかっただけかもしれないしｗｗ

Ｑ：ワールド探索してる時はどういうスタイルでやってる？
Ａ：デスクトップでやってます。ＨＭＤずっとかぶってると首とか背中とかすぐ痛くなるので・・・。
デスクトップはなぜか声がでない↓ので、無言デスクトップで徘徊してます！
https://twitter.com/vrc_machida2/status/1736920865043063051
↑のツィートの解決法わかったらツィッターのリプライかここのコメント欄で教えていただけるとすごく助かります！！！！！！！
ディスコードの画面共有通話でもいいですし

マイクのドライブのアンインストールとインストールはしました・・・ｗ

Q:今後やりたいことある？
Ａ：
①私がツィートで紹介したワールドを巡るイベントをやりたいですねえ～

②クエスト対応に特化したワールド紹介も、例えば一週間！とか一か月！とか期間決めて期間限定でやってみたいです

③癖のワールド紹介したいです。口のワールド紹介した時に結構引用ＲＴだったりリプライだったりと反応があったので！
https://twitter.com/vrc_machida2/status/1735935291221753950
みんなこういうトガったワールド好きなんだなあ～と！
ＶＲ感度がある人用のワールド紹介もしたいですね～
ラズパイでoverleaf(onlineでTeX組版できるサイト)をつかってみた話

# ラズパイはdocker imageがひけない

arm64 CPUなのでそれのためのイメージが準備されてないとうまくいかない。docker自体のインストはかんたんにいくだけに残念。`miktex`, `pandoc`のイメージをひいてみたが、いずれもプラットフォームなんとかエラーであきらめた。OSは、`raspbian`です。

`pandoc`は、arm64のためのインストーラーがあるので、そちらをつかった。

`git`, `pandoc`がインストールされれば`md`ファイルを編集したりそいつを`tex`ファイルに変換できるようになるけど、組版が問題あるので、overleaf.comに頼った。ありがとう！

必要なファイルを次のような`zip`コマンドで圧縮した後、このサイトにアップロードした。そのあとコンパイルというボタンをクリックすると組版できた。pdfをダウンロードした。

```
zip overleaf main.tex
zip overleaf -r ref
zip overleaf -r img
```

ちなみにそれぞれのディレクトリのなかには、bib, bstファイルと図面のPDFファイルが入ってる。
今の場合、`TeX`ソースは英文なので、`latexmkrc`とか設定はやらなくてすんだ。

和文でしかも`Latex`っていうユーザーさんはいろいろ苦労されてるようだけど、和文の場合、すなおに`MS Word`で執筆すればいいよねっていう考えなので、今回の　overleaf.comには助けられた。ありがとう！

## Macの場合、arm64でもイメージがひける

という報告があるので、ラズパイでもいけるのかもしれないが、それ系のオマジナイは　だめ　だった。
Erlang/Elixirのパーサー

# はじめに

ErlangやElixirの言語自体を解析する際に、パーサーは避けては通れません。
パーサーはプログラムのソースコードを、その言語の文法にしたかって（ソースコードの)テキストを解析し、プログラムで扱えるようなデータ構造に変換（構文解析）するプログラムです。

一般的にパーサーは非常に煩雑（でめんどくさい)処理なので、現代的なプログラミング言語では、パーサージェネレータを使って、言語のルールを記述したファイルを元に自動生成されます。
つまり、パース(構文解析)の処理をゼロから実装するのではなく、ルールを記述したファイルを入力として、パーサージェネレーターを通してパーサーのプログラム(ソースコード)を自動生成します。

有名なパーサージェネレータとしては、yacc(Yet Another Compiler Compiler)やbison等がありますが、ErlangやElixirでは、yaccに似たyeccというパーサージェネレーターが利用されています。

# yecc

yeccはErlang用のパーサージェネレーターです。
名前からわかるようにyaccに似た仕様で、yrl(yeccのルールを記述)ファイルを受け取ってパーサーモジュールのerl(Erlangのソースコード)ファイルを自動生成します。
yrlファイルはerlcにそのままわたす事ができ、erlファイルが生成されます。

yeccの使い方は[公式ドキュメントのyecc](https://www.erlang.org/doc/man/yecc)に詳細が記載されています。

# Erlangのパーサー

Erlangのパーサーファイルは[lib/stdlib/src/erl_parse.yrl](https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_parse.yrl)です。
つまり、Erlangのプログラムの文法はここのファイルで定義されます。もしErlangの文法に手を加えたい場合はこのファイルを更新することで、Erlangの文法を変更する事ができます。

例えば、OTP-17でErlangにMapが導入された際は[以下の様な変更](https://github.com/erlang/otp/commit/703a9aa47168f7f8c11bf835502281bd59ba77f7)がerl_parse.yrlに追加されました。（昔はErlangにはMapがなかったのです!)

```
+map_expr -> '#' map_tuple :
+	{map, ?line('$1'),'$2'}.
+map_expr -> expr_max '#' map_tuple :
+	{map, ?line('$2'),'$1','$3'}.
+map_expr -> map_expr '#' map_tuple :
+	{map, ?line('$2'),'$1','$3'}.
+map_expr -> map_expr '.' atom :
+	{map_field, ?line('$2'),'$1','$3'}.
+
+map_tuple -> '{' '}' : [].
+map_tuple -> '{' map_fields '}' : '$2'.
+
+map_fields -> map_field : ['$1'].
+map_fields -> map_field ',' map_fields : ['$1' | '$3'].
+
+map_field -> map_key '=>' expr :
+	{map_field,?line('$1'),'$1','$3'}.
+
+map_key -> expr : '$1'.
```

# Elixirのパーサー

Elixirのパーサーファイルは、[lib/elixir/src/elixir_parser.yrl](https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir_parser.yrl)です。

[以下の変更](https://github.com/elixir-lang/elixir/commit/3b52a04354dbf95d5bec56d86d201517949b529f)は、関数呼び出し時に末尾にカンマ(,)がある場合にワーニングを出力する対応です。

```
 kw_call -> kw_base : reverse('$1').
+kw_call -> kw_base ',' : warn_trailing_comma('$2'), reverse('$1').
 kw_call -> kw_base ',' matched_expr : maybe_bad_keyword_call_follow_up('$2', '$1', '$3').

〜略〜

+%% TODO: Make this an error on v2.0
+warn_trailing_comma({',', {Line, Column, _}}) ->
+  elixir_errors:erl_warn({Line, Column}, ?file(),
+    "trailing commas are not allowed inside function/macro call arguments"
+  ).
```

# まとめ

パーサー（のルールファイルであるyrl)関連のコードを読む事で、ErlangやElixirのシンタックスをより深いレベルで理解する事ができます。文法レベルの変更や大きな機能の追加の際、ほぼ確実にyrlファイルに手が入るのでyrlファイルを読める様になっておくと、どの様な変更をしようとしているのかについてより深く把握できます。
ErlangやElixirを改造したい人やコントリビュートをしたいと考えている方は、yrlファイルとyeccの概要を把握しておくとよいでしょう。
Next-auth(prisma)をセットアップする

# Next-auth(prisma)をセットアップする

## 経緯
next-authの最新versionでsetupを行なったが、記事がまとまってなかったので調査しながらsetupを行なった備忘録

## next-authの仕組みを確認する

[ライブラリのコード](https://github.com/nextauthjs/next-auth/tree/a14fe18eb9626f4179cf7a510721f874f240cdc4)と公式の[demoアプリ](https://github.com/nextauthjs/next-auth/tree/a14fe18eb9626f4179cf7a510721f874f240cdc4/apps/examples/nextjs)を参照しながら仕組みを知る。

大まかに説明するとAuth関数がauth()の本体であり、middlewareと認証パス(/signin)も最終的にはこのAuth関数が呼び出される。

### 認証の流れ(googleの場合)
NextAuth.jsを使用したGoogle認証のフローは次のようになります：

1. **外部リクエスト**: ユーザーがログインページ（例：`/api/auth/signin`）にアクセスします。(Auth関数)
2. **内部リクエスト**: NextAuthは設定に基づきGoogle認証URLを生成し、ユーザーをGoogleのログインページにリダイレクトします。
    - toInternalRequest: actionなどの情報を取得
    - AuthInternal: toInternalRequestで取得した情報を使用して処理を実行
3. ユーザーはGoogleで認証します。
4. **外部リクエスト**: GoogleはユーザーをNextAuthのコールバックURL（例：`/api/auth/callback/google`）にリダイレクトします。(toInternalRequest)
5. **内部リクエスト**: NextAuthはGoogleからの情報を処理し、セッションを作成または更新します。
    - toInternalRequest: actionなどの情報を取得
    - AuthInternal: toInternalRequestで取得した情報を使用して処理を実行
6. ユーザーは認証後のページにリダイレクトされます。

### memo
toInternalRequest関数は、入力されたリクエストを解析して、actionなどの内部リクエスト情報を取得します。次に、この内部リクエスト情報をAuthInternal関数に渡し、具体的な認証処理（例えば、action: signInの場合はサインイン処理）を行います。これにより、NextAuth.jsは様々な認証アクションを柔軟に処理することができます。
Auth関数によって単一のルート（例えば /api/auth/[...nextauth].js）が複数の認証関連の処理（サインイン、サインアウト、コールバックなど）に対応できるようになります。これにより、NextAuth.jsは柔軟かつ効率的に認証フローを管理できます。

## 最終的な構成
### nextjs
最新のversion(nextjs@0.0.3)
### next-auth
最新のversion(next-auth@4.24.5)
### prisma(accelarate)
最新のnext-authではedgeロケーションをベースにしているので、prisma accelerate(edge対応)をdatabaseに登録しないといけない。
ただしlocalhostのデータベースではprisma accelerateに登録できないため、下記のライブラリで対応

ライブラリ: https://www.npmjs.com/package/prisma-accelerate-local
参照: https://zenn.dev/sora_kumo/articles/prisma-accelerate-local

## 結論
```Error: PrismaClient is unable to run in Vercel Edge Functions (in local dev environment)```に関する対応方法が公式ではまとめられておらず詰まる。ただしこの部分以外は難しくない。
https://github.com/nextauthjs/next-auth/issues/9423

## 付録
デモアプリ: https://github.com/tokiyoshi-yudai/next-auth-test-app
自分のVRCワールド巡りツィートのまとめ記事　

私がワールド紹介したツィートを淡々と貼っていくだけの記事だぜえええ

２０２３年１２月だから、冬、雪、クリスマス、を中心にワールド探索しました。


毎日のワールド紹介の記録を残していきます！

日付：1/3
https://twitter.com/vrc_machida2/status/1742376483879022909

日付：1/2
https://twitter.com/vrc_machida2/status/1742018122805096889

日付：1/1
https://twitter.com/vrc_machida2/status/1741658251455070299

日付：1/1
https://twitter.com/vrc_machida2/status/1741654224792916415


12/31
https://twitter.com/vrc_machida2/status/1741290578669896132/photo/1

12/29
https://twitter.com/vrc_machida2/status/1740570836103553104

12/28
https://twitter.com/vrc_machida2/status/1740200474371084504

12/26
https://twitter.com/vrc_machida2/status/1739482414827606301

12/25
https://twitter.com/vrc_machida2/status/1739117006303981863
(12/28までの限定公開)

12/24
https://twitter.com/vrc_machida2/status/1738755625071612273

12/23
https://twitter.com/vrc_machida2/status/1738403806831112554

12/22
https://twitter.com/vrc_machida2/status/1738043180753252653

12/21
https://twitter.com/vrc_machida2/status/1737664434984591792
期間限定のワールドです

12/20
https://twitter.com/vrc_machida2/status/1737311358641930748

12/19
https://twitter.com/vrc_machida2/status/1736944692690878655

12/18
https://twitter.com/vrc_machida2/status/1736582304976253267

12/17
https://twitter.com/vrc_machida2/status/1736333163016917115

12/16
https://twitter.com/vrc_machida2/status/1735935291221753950

12/15
https://twitter.com/vrc_machida2/status/1735576426542178494

12/13
https://twitter.com/vrc_machida2/status/1734853162056491052
投稿機能の検索機能の実装


検索機能は必須機能ではないですがあると便利ですね！
テックキャンプの備忘録です！

### 目的
- ルーティングのcollectionとmemberを理解
- 検索に必要なメソッドを理解

### seachアクションのルーティング設定
#### collectionとmember
ルーティングを設定する際に使用でき、生成されるルーティングのURLと実行されるコントローラを任意でカスタムできる
ルーティングに`:id`がつくかつかないかの違い
config/routes.rb
```ruby
Rails.application.routes.draw do
  devise_for :users
  root to: 'tweets#index'
  resources :tweets do
    resources :comments, only: :create
    collection do
      get 'search'
    end
  end
  resources :users, only: :show
end
```

### 検索フォーム作成
app/views/tweets/index.html.erb

```ruby
<%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
  <%= form.submit "検索", class: "search-btn" %>
<% end %>
```

### 検索のメソッドをモデルで定義
#### ビジネスロジック
データに対する処理などを行うプログラム処理
「データをどのように処理するのか」
「どのデータを取得するのか」
「どのような手順で処理をしていくのか」　など指す。

#### whereメソッド
ActiveRecordメソッドの一つ
`モデル.where(条件)`のように、引数部分に条件を指定することで、テーブル内の「条件に一致したレコードのインスタンス」を配列で取得できる
`モデル.where('検索対象となるカラムを含む条件式')`
#### LIKE句
曖昧な文字列の検索をするときに使用 whereと一緒に
```ruby
class Tweet < ApplicationRecord
  validates :text, presence: true
  belongs_to :user
  has_many :comments

  def self.search(search)
    if search != ""
      Tweet.where('text LIKE(?)', "%#{search}%")
    else
      Tweet.all
    end
  end
end
```
引数のsearchは、検索フォームから送信されたパラメータが入るため、
`if search != ""`と記述し、検索ふぉーむに何かが入力されていた場合を条件としています。
もし検索ふぉーむに何も入力をせずに検索ボタンを押すと、引数で渡されるsearchの中身は空になります
この場合elseに該当し、`Tweet.all`という記述は、その時全ての投稿を取得して表示するためのもの
 _*テーブルとのやりとりに関するメソッドはモデルに置く*_　という意識が必要

 ### searchアクションをコントローラーに定義
 ```ruby
 ~略~
before_action :move_to_index, except: [:index, :show, :search]
 ~略~
   def search
    @tweets = Tweet.search(params[:keyword])
  end
 ~略~
 ```
 Tweetモデルに書いたsearchメソッドを呼び出し、
 seachメソッドの引数に`params[:keyword]と記述して、検索結果を渡す`
 未ログイン時に検索するとトップページにリダイレクトされるのでbefore_actionのexceptオプションに`:search`追加

 ### 検索結果のビュー作成
 app/views/tweets/search.html.erbを作成
 ```ruby
 <%= form_with(url: search_tweets_path, local: true, method: :get, class: "search-form") do |form| %>
  <%= form.text_field :keyword, placeholder: "投稿を検索する", class: "search-input" %>
  <%= form.submit "検索", class: "search-btn" %>
<% end %>
<div class="contents row">
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
</div>
 ```
Go 言語の開発環境構築（Mac）

## Go 開発ツール
Mac に Go 開発ツールをインストールする場合は、Homebrew を使い、下記のコマンドで実行できます。
```
$ brew install go
```

下記のコマンドでバージョンが表示されれば、完了です。
```
$ go version
go version go1.21.5 darwin/amd64
```

### 注意点
brew install コマンドを実行してもターミナルに何も表示されない、もしくは下記が表示される場合は、Homebrew の更新に時間がかかっているため、しばらく待つ必要があります。
```
Updating Homebrew...
```

また、下記のエラーが出る場合は、Frameworks フォルダに書き込み権限が無いため、ターミナルに表示された `sudo chown -R [user name] /usr/local/Frameworks` コマンドで、フォルダのオーナーを変更する必要があります。
```
Error: The following directories are not writable by your user:
/usr/local/Frameworks

You should change the ownership of these directories to your user.
  sudo chown -R [user name] /usr/local/Frameworks

And make sure that your user has write permission.
  chmod u+w /usr/local/Frameworks
```

## VS Code
VS Code を下記からダウンロードしインストール
https://code.visualstudio.com/
※ バージョン: 1.85.1

マーケットプレイス（Code -> 基本設定 -> 拡張機能）で Go（Go Team at Google）を検索し、インストール

### 注意点
Go 拡張機能をインストールしただけでは、定義へのジャンプ等が行えないので、コマンドパレット（表示 -> コマンドパレット）で「Go:Install/Update Tools」を選択し、gopls をインストールします

## 依存関係の解消
GitHub のプライベートリポジトリのライブラリに依存している場合は、下記の設定が必要です。

### GitHub の認証
[パーソナルアクセストークン](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)を使用する場合は、~/.gitconfig に下記を追加
```
[url "https://<アカウント名>:<アクセストークン>@github.com/"]
        insteadOf = https://github.com/
```

[ssh](https://docs.github.com/ja/authentication/connecting-to-github-with-ssh)を使用する場合は、~/.gitconfig に下記を追加
```
[url "git@github.com:"]
        insteadOf = https://github.com/
```

### GOPRIVATE の設定
go get などでライブラリを取得した場合に、チャックサムが行われます。
sum.golang.org のデータと検証が行われ、下記の様なエラーが出ます。

```
go: github.com/xxx-xx/xx-sample@latest: github.com/xxx-xx/xx-sample@v0.0.0-20240118131021-7a2bd4d910f8: verifying module: github.com/xxx-xx/xx-sample@v0.0.0-20240118131021-7a2bd4d910f8: reading https://sum.golang.org/lookup/github.com/xxx-xx/xx-sample@v0.0.0-20240118131021-7a2bd4d910f8: 404 Not Found
```

プライベートなライブラリは、環境変数 GOPRIVATE に登録する必要があります。
GOPRIVATE=github.com/<アカウント名>/<リポジトリ名>

```
export GOPRIVATE=github.com/<アカウント名>/<リポジトリ名>
```

## Version up

Mac で Go をバージョンアップする場合は、Homebrew を使い、下記のコマンドで実行できます。

```
$ brew upgrade go
```

下記のコマンドで新しいバージョンが表示されれば、完了です。

```
$ go version
go version go1.23.3 darwin/amd64
```
Nuxt3 / Vue3 – defineExpose + ref に型を当てる

# 呼び出し側の記述

refで定義する時に普通に型を当てれば良い

```vue
<script setup lang="ts">
type Book = {
  title: string
}

const book = ref<Book>()

</script>

<template>
   <div>{{ book.title }}</div>

  <Book ref="book"/>
</template>

```

# 呼びされるComponentの記述例


`components/Book.vue`

```vue
<script lang="ts" setup>
const title = ref('')

defineExpose({
  title,
})
</script>

<template>
  <input v-model="title" />
</template>

```


# 参考

https://github.com/vuejs/core/issues/4397


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Shift15M 論文 3章 mean-IW・max-IWまで

# 0.前回の続き
これは、セット間マッチングに対する株式会社ZOZOが論文で公開しているものの輪読になります。

https://corp.zozo.com/news/20210902-zozo_technologies-18444/

https://arxiv.org/abs/2108.12992


# 1.今日変量シフトに対応するには
3章では、共通変量シフトに適応するために、
重要度重み付きセットマッチングを提案しています。
これは、IWERM（Importance Weighted Empirical Risk Minimization）に基づいており、密度比 pte(x)/ptr(x) を重み付け関数として使用します。
重み付け関数として密度比を採用することにより、
重み付きERMによって計算される経験的誤差がテスト分布の期待誤差の
一貫した推定量であることが示されています（Theorem 3.1）。

![スクリーンショット 2024-01-02 2.23.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/b2bfb2ca-2a93-50e1-f1f8-13f58900d855.png)

ここで、
ntrはトレーニングデータの入力個数
(h(xitr) ,yitr)は予測のラベルと正解ラベルとの予測誤差を表しています。
基本的には、それを最小化するだけですが
今回の場合は、密度比というものを採用しています。

ptr(xitr)は、トレーニングデータの入力変数xitrにおける確率密度関数を表し、pte(xitr)はテストデータの入力変数xitrにおける確率密度関数を表します。

つまり、ptr(xitr)はトレーニングデータが生成される確率密度関数であり、pte(xitr)はテストデータが生成される確率密度関数です。

この重みづけをすることでどのように変わるのか？

最小二乗法で表すととてもわかりやすいです。
この場合、トレーニングデータには予測関数はフィットしているが、
テストデータの場合、全くフィットしていません。
これに重みづけを行うことによって、このようにテストデータに合うようなモデルになります。

![スクリーンショット 2024-01-03 11.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/22fe00de-4999-c4a2-8be3-30a72216d021.png)

参照先：

https://ibisml.org/ibis2008/slides-invited/sugiyama.pdf

# 定理3.1

定理3.1は、重み付きERM（Empirical Risk Minimization）によって計算される経験的誤差が、テスト分布における期待される誤差の一貫した推定量であることを示しています。
ここで、w(x) = pte(x)/ptr(x)は重み付け関数として設定されており、pte(x)はテスト分布における事後確率、ptr(x)は訓練分布における事後確率を表します。

## 経験的誤差とは

経験的誤差（empirical error）とは、機械学習や統計学において、モデルの訓練データに対する誤差を指します。具体的には、モデルが訓練データに対してどれだけ正確に予測できるかを示す指標です。一般的には、訓練データセット内の各データ点に対する予測と実際の値との差を測定し、その平均値や合計値を取ることで経験的誤差を計算します。

## K-pair-set loss

ここで
fはVのベクトル集合とWのベクトル集合の類似度を算出する関数になります。
それをソフトマックス関数で求めています。

![スクリーンショット 2024-01-03 11.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/38de64ba-c092-8189-c701-fed155a42cf6.png)

例えば、VはAさんが買った洋服のセットベクトル、Vもセットベクトルとして
１つずつアイテムを選択して、どれくらい類似度があるかを選びます

類似度算出は様々ありますが、適切な類似度を算出する関数を選ぶ必要があります

δijは
Kroneckerのデルタと呼ばれる関数で、以下のように定義されます。

δij = 1 (i = j)
δij = 0 (i ≠ j)

つまり、iとjが同じ場合には1を、異なる場合には0を返す関数です。この式では、iとjが同じ場合にはf(Vi, Wj)の寄与があるため、δijを用いてその寄与を表現しています。具体的には、exp(f(Vi, Wj))の項がδijによって制御され、i=jの場合にはそのままの値が、i≠jの場合には0になるため、式全体の計算に影響を与えます。



![スクリーンショット 2024-01-03 12.48.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/b88d4f77-b7e4-c6a0-0da3-43d228cac92b.png)

max-IWやmean-IWは
訓練データとテストデータの分布の違いに応じて重みを調整する手法です

これらはERMと組み合わせてACCなどを計算します。

最大重み付け（max-IW）は、異なる分布間の適合度を評価するための手法であり、特に重み付け関数を用いて異なる分布間の適合度を比較します。

ERM + max-IWでは、経験リスク最小化において、最大重み付けを用いて異なる分布間の適合度を考慮したモデルの学習が行われます。つまり、訓練データとテストデータが異なる分布に従っている場合にも、その適合度を考慮した学習が行われることを意味します。


数式参考先：

https://arxiv.org/abs/2108.12992
Oracle実験室 / Oracle データベース各種操作

# Oracle実験室 / Oracle Database 19c (19.3) 各種環境設定
https://qiita.com/Que-sera-sera/items/b2a1a9522deecbd69daf

# Oracle実験室 / Oracle Database 19c (19.3) / 各種操作
https://qiita.com/Que-sera-sera/items/a15b242e2c341913ad1d

# Oracle実験室 / Oracle Database 19c (19.3) / トレースファイルの定期的な削除
https://qiita.com/Que-sera-sera/items/c0832b2afe45cfa16690

# Oracle実験室 / 再帰with句
https://qiita.com/Que-sera-sera/items/2b00d52d0471d1ecf43b
Blenderで作成した3DモデルをUnity側に取り込む手順（備忘録）

# はじめに
Blenderで作成した3DモデルをUnityにインポートしてみます。
Unityに取り込むことでVRchatやclusterのワールド、小物制作制作に活用できます。

# 環境
- Blender：4.02
- Unity：2022.3.16f1
- OS：Windows

# Blender側
3Dモデルを作成します。
今回は画像のライトを作りました。
![gardenLightSample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/a0d8b1ed-e482-a9c7-4482-adfa39a8f929.png)

### ◆3Dモデルを準備できたら、エクスポート前に以下3点の確認。
- シーン⇒単位⇒単位系がメートル法になっている事
- オブジェクト⇒トランスフォーム⇒スケールが1.0になっている事
- 光源とカメラを消している事

次にファイル⇒エクスポート⇒FBXを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/59172804-1636-5cbb-446e-8cdd79097d06.png)

以下のようにエクスポート設定の調整。
エクスポート先のフォルダを選択しFBXをエクスポートをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/e92e0de6-9b27-aa02-ffb7-a82b64d5a862.png)

# Unity側
Unity Hubを開きProjectsから対象のプロジェクトを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/262c48fa-ca97-859e-50ac-83ea6adc784a.png)

`Assets`に先ほどBlender側でエクスポートしたFBXファイルをドラッグ&ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/740cf16d-409c-eb33-8eab-392ef20be9bc.png)

最後に`Assets`から`Hierarchy`か`Scene`にドラッグ&ドロップすると、
`Scene`に3Dモデルが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/f3690400-dcb7-bcd2-b739-dc17a8c8aff6.png)


# 参考
https://creator.cluster.mu/2022/07/26/blender-unity/#container
Javaでタプルが使いたいと思ったので作成した

# ごあいさつ
あけましておめでとうございます。
今年もよろしくお願いします。
## 目標
本年は記事の投稿ペースを上げていきたいですね。
最悪一ヶ月に一回とか。

# 本題
では早速コード。
## コード
```java:SimpleTuple.java
public static class SimpleTuple<A,B>{
    private A left;
    private B right;

    public SimpleTuple(A left, B right){
        this.left = left;
        this.right = right;
    }

    public A getLeft(){
        return left;
    }

    public B getRight(){
        return right;
    }

    public void setLeft(A left){
        this.left = left;
    }

    public void setRight(B right){
        this.right = right;
    }
}
```
まあ20行程度のカンタンなコードですね。

## 解説
これはJavaの[ジェネリクス](https://qiita.com/suema0331/items/c5cc61c274fa94b68541)という機能を使って作成しています。
2つ用意して、右のやつと左のやつに分けて、それぞれ保存する。
その保存した変数の[セッターとゲッター](https://qiita.com/takahirocook/items/27828bc8477735612021)を定義してあげてます。

# 終わりに
前々回ぐらいから用語にはQiitaの他の用語解説記事のリンク貼ってます。
わかりやすいかな～と思ってつけました。いらないかなと思ったら言ってくださいね。
あとここにもつけたほうがいいよ!ってときは遠慮せず教えてください。
分かりやすく読んでほしいので。

50行程度の短い記事になりましたね。
(単発シリーズ増えるかも)
いっつも文字にリンク付ける方法忘れるなぁ...
拡張機能でも作ってみるか。
Oracle実験室 / Oracle Database 19c (19.3) 各種環境設定 

# 前書き
- 記事一覧 [Oracle実験室 / Oracle データベース各種操作](https://qiita.com/Que-sera-sera/items/862c77963b841a95ba95)

# プラガブルデータベース操作
- 状態表示
<font color="blue">"OPEN MODE"が"MONTED"で停止している.</font>
```SQL
$ sqlplus / as sysdba
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB1                       MOUNTED
```
- 起動
```SQL
SQL> alter pluggable database ORCLPDB1 open;

プラガブル・データベースが変更されました。
```
- 状態表示
<font color="blue">"OPEN MODE"が"READ WRITE"となり起動完了.</font>
```SQL
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB1                       READ WRITE NO
```
- 永続設定
```SQL
SQL> alter pluggable database ORCLPDB1 save state;

プラガブル・データベースが変更されました。
```

# HRスキーマ有効化
[【参考文献】2 サンプル・スキーマのインストール](https://docs.oracle.com/cd/E82638_01/comsc/installing-sample-schemas.html#GUID-CB945E4C-D08A-4B26-A12D-3D6D688467EA)
- スキーマ作成
```SQL
SQL> @?/demo/schema/human_resources/hr_main.sql

specify password for HR as parameter 1:
1に値を入力してください: ********

specify default tablespeace for HR as parameter 2:
2に値を入力してください: users

specify temporary tablespace for HR as parameter 3:
3に値を入力してください: temp

specify log path as parameter 4:
4に値を入力してください: $ORACLE_HOME/demo/schema/log/


PL/SQLプロシージャが正常に完了しました。


ユーザーが作成されました。

...


Commit complete.


PL/SQL procedure successfully completed.
```
- 確認
```SQL
$ sqlplus hr/PASSWORD@localhost:1521/ORCLPDB1
SQL> select table_name from user_tables;

TABLE_NAME
--------------------------------------------------------------------------------
COUNTRIES
REGIONS
LOCATIONS
DEPARTMENTS
JOBS
EMPLOYEES
JOB_HISTORY

7行が選択されました。
```
負荷テスト / ストレステスト / パフォーマンステストの違い

# ぎもん

負荷テスト / ストレステスト /パフォーマンステストの違いってなんなの？？


# こたえ

パフォーマンステストの中の一種として、負荷テストやストレステストがあります。
いずれもシステムの性能評価に使われるテスト方法ですが、それぞれの目的と特徴が異なります。

### 負荷テスト (Load Testing)
**目的**：
システムが特定の負荷（例：多数の同時ユーザー、大量のトランザクション）の下でどのように機能するかを評価します。

**特徴**：
通常、システムの正常な運用範囲内での性能を測定します。応答時間、処理速度、スループットなどの指標を使用して、システムが定められた要件を満たしているかを確認します。

### ストレステスト (Stress Testing)

**目的：**
システムが極端な負荷や条件下でどのように機能するか、または崩壊するかを評価します。

**特徴**：
システムの限界やブレークポイントを見つけることが目的です。負荷を徐々に増やし、システムがどの程度の負荷まで耐えられるか、障害発生時の回復力などを評価します。

### パフォーマンステスト (Performance Testing)

**目的**：
システムの全般的な性能を評価します。

**特徴**：
負荷テストやストレステストなど、さまざまな種類のテストを含む広範なカテゴリです。システムの応答時間、スループット、リソース利用率などを測定し、パフォーマンスのボトルネックを特定します。これらのテストは、システムの耐久性、信頼性、スケーラビリティを評価し、本番環境での性能問題を事前に特定するために重要です。


## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/a07fad39-6a08-26b4-d7f2-eb4e89daafe9.png)


```markdown

# パフォーマンステストの種類

## 負荷テスト
- **基本的な負荷テスト**: 通常のユーザ負荷の下でシステムのパフォーマンスを評価します。
- **ソークテスト（長時間実行）**: 長時間にわたり一定の負荷をかけ続けることで、パフォーマンスの安定性やメモリリークなどを検出します。

## ストレステスト
- システムが通常よりも高い負荷やストレス状況下でどのように動作するかをテストします。

## 容量テスト
- システムが最大限の能力でどの程度まで処理できるかを特定します。

## スケーラビリティテスト
- システムがスケールアップ（より大きなマシンでの実行）またはスケールアウト（複数のマシンでの分散実行）した際のパフォーマンスを評価します。

## スパイクテスト
- 短時間に急激な負荷の増減がシステムに与える影響をテストします。

## エンデュランステスト
- 長期間にわたる一定の負荷でシステムがどのように反応するかを調べます。

## コンフィギュレーションテスト
- 異なる設定やリソースを用いてシステムのパフォーマンスがどのように変化するかを確認します。

## 分離テスト
- パフォーマンスの問題が特定のコンポーネントに由来するかどうかを特定します。

```
【個人開発】草生えてないと怒ってくれるBOTを作った

明けましておめでとうございます。

新年早々少し個人で開発したのでそのアウトプットとして投稿させていただきます。

全てのツールを無料枠で抑えて作ることができるので、個人で開発してデプロイまでしてみたいと思っている人に参考になれば良いなと思います。

## 作ったもの

草（commit）がされていない場合にはその日の夕方に通知を送ってくれるLineのBOTを作りました。

**Githubリンク**

https://github.com/yuta-2001/go-no-commit-notify

## 作成動機

- 新たな年が始まって、より成長できる年にしたく継続を促せるようなものを作りたかった。
- これまで触れていないものを使って何か作ろう、自分の技術の幅を広げようと思ったから。(Goも含めて全て開発で使ったことはなかったです。)


## 使用技術・構成

- AWS Event Bridge (cron)
- AWS Lambda
- Line Notify
- Github GraphQL
- Golang

(コンテナ化(Docker)は図に乗っていますが、現在進行中です。。😅 別で続きとして記事にします。)


**構成**
![スクリーンショット 2024-01-03 午前9.22.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470041/a6d6f8e9-344f-f4ac-09f4-4e8f245c199d.png)



**説明**
Event Bridgeでcronの設定をし、1日に1回Lamdaの関数を発火させています。
LamdaではGoで作成した関数が走り、Github GraphQLから当日分のcommit数を取得し、草があるかを確認します。
ないことがわかった場合にはLine Notifyでユーザー(自分)に向けて通知を行なっています。

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470041/eb259b1c-a0b9-faee-2346-a9698d43f474.png">


## 使用技術・参考記事の紹介

### Lambda & Event Bridge

Lambdaは関数を定義して、イベントがその関数に対して走った際に、実行を行うサービスです。Event Bridgeは特定のイベントが検知された時や、定期実行(cron)などで設定している時間にイベントを実行してくれるサービスです。

この二つを組み合わせることで、関数の定期実行をすることができます。

実行のログがcloudWatchに自動的に保存されていたのでバグやエラーにも気がつくことができます。

EC2等でアプリケーションをデプロイするのに比較するとはるかに手間も少ないですし、どちらも1日1回程度だとお金はかからないのでぜひ使ってみていただきたいです！

**少し躓いたところ**

Lambdaデプロイ時に、コードをビルドしてバイナリを生成する必要があるのですが、筆者はM1のmacを使用しており、m1で生成されるバイナリはlambdaとの互換性がないことがわかりました。

ですのでm1ユーザーの方は以下のコマンドでLambda互換のものを生成する必要があります。

通常

```go
GOOS=linux go build -o main
```

mac M1

```go
GOOS=linux GOARCH=amd64 go build -o main
```

**参考**

https://www.cview.co.jp/cvcblog/2021.01.15.Pu1pTwLHNUXVe6dnNHrHc

https://scrapbox.io/rebuild-kitashirakawa/m1_Mac%E3%81%AE%E4%B8%8A%E3%81%A7%E3%80%81go_lambda%E3%82%92build%E3%81%99%E3%82%8B%E3%81%A8%E3%82%B3%E3%82%B1%E3%82%8B%E3%80%82


### Github GraphQL

GithubはRest APIとGraphQLからAPIを公開していますが、今回のように草を取得したい場合にはGraphQLの方を使う必要があります。

今回はその日のコミットがあるかを確認したかったので、contributionsCollectionのfromとtoをその日の最初と最後の時刻にすることで対応しました。

```go
query := `
	query($userName: String!, $from: DateTime!, $to: DateTime!) {
		user(login: $userName) {
			contributionsCollection(from: $from, to: $to) {
				contributionCalendar {
					totalContributions
					weeks {
						contributionDays {
							contributionCount
							date
						}
					}
				}
			}
		}
	}
`
variables := map[string]interface{}{
	"userName": os.Getenv("GITHUB_USER"),
	"from":     startOfTodayStr,
	"to":       endOfTodayStr,
}
```

今回はuser情報の取得しかしていませんが、様々な用途に使えるので個人開発したい人にはおすすめです。

**参考**

https://docs.github.com/en/graphql

https://zenn.dev/yuichkun/articles/b207651f5654b0

### Line Notify

Line Notifyは自分のLINEアカウントに対してメッセージを送信できるサービスです。
先ほどあげたデモの画像のように、メッセージやLINEスタンプを簡単に送信することができます。
Line Messaging APIのpush message機能を使うと料金がいくらかかかってしまう可能性があるので、お金をかけずに開発したいという人におすすめです。


**参考**

https://notify-bot.line.me/ja/

https://zenn.dev/protoout/articles/18-line-notify-setup

## まとめ

今回様々なものを初めて使ってみましたが、どれも素晴らしいサービスだなと思いました。
自分ようなので無料で作れたのもまた良かったなと思います。
特にLine Notifyはめちゃめちゃ簡単だったので、様々なことにサクッと導入できそうだなと思いました。
PHP 外部ファイルの読み込み

## はじめに
クラスや関数など書いた外部ファイルを読み込んで使うことがあります。自分用のまとめなので間違いや自分が完全に理解しているところに関しては省略して書いていることもあります。ご了承お願いします。

## requireかincludeで読み込む
同じフォルダ内にあるclass.phpというファイルを読み込んでいきます。
```php
require('class.php'); //ファイルが読み込めなかったらその場で処理が止まる
include('class.php'); //ファイルが読み込まなくても処理が止まらない
```
以下のような少し違う処理の書き方もあります。
```php
require_once('class.php'); //ファイルを一度だけ読み込む
include_once('class.php'); //ファイルを一度だけ読み込む
```
ぶっちゃけ_onceがどのように活躍するかわかりませんが、覚えておきます。

## 一応少しだけパスの書き方
今度自分が見返すようにサンプルパスを少し書いておきます。
```php
require('class.php'); //同じディレクトリ内
require('./class.php'); //同じディレクトリ内

require('../func/functions.php'); //1つ上の階層に行ってfuncフォルダのファイル読み込み
```

## 終わりに
規模によっては莫大なコードになると思います。そのような時に他の人が見やすく、より効率的に作業できるようなコードにしたいですね。
【Elixir】Mockを使ってみる

# はじめに

AtCoderのプログラムは標準入力からデータを読み込み、結果を標準出力に出力するプログラムを作ります。
これをLivebookで実行するにはどうすればよいか。
この方法を模索していていました。
テストで利用するMockを利用する事で、実現できました。この方法を書いてみます。

# やりたいこと

AtCoderの回答のプログラムでは、IOモジュールを使うと想定します。
IO.put, IO.read, IO.getn の第一引数はdeviceで:stdioが渡されます。この値を別の値に置き換えて、実行すること。

# IOモジュールを置き換える方法

次の記事でモック化について、そのバックグランドや、いくつかの方法が紹介されているので、一度みてみると参考になるかと思います。
https://blog.appsignal.com/2023/04/11/an-introduction-to-mocking-tools-for-elixir.html

今回は、この記事でも最初に紹介されている、Mockを使いました。

# 記述方法

Mockはユニットテストで使う事が多いので、testの中での記述例が多いですが、今回は、AtCoderのプログラムを実行するという目的なので、Judgeモジュールの中に実装してみました。
with_mock関数がポイントです。
ここにMock化するモジュールと関数名、置き換える関数を与えて、その中で対象の処理(今回は、Main.main())を実行します。

judge(string_in, string_out) は入力例、出力例を文字列で渡すとMain.main（）を実行して、結果の判定をする関数です。

```Elixir
defmodule Judge do
  import Mock

  def judge(string_in, string_out) do
    {:ok, file} = StringIO.open(string_in)

    with_mock IO, [:passthrough], [
      getn: fn :stdio, a, b -> passthrough([file, a, b]) end,
      getn: fn a, b -> passthrough([file, a, b]) end,
      read: fn :stdio, option -> passthrough([file, option]) end,
      read: fn option -> passthrough([file, option]) end,
      puts: fn :stdio, item -> passthrough([file, item]) end,
      puts: fn item -> passthrough([file, item]) end,
    ] do
      Main.main()
    end

    {:ok, {_, result}} = StringIO.close(file)

    if string_out == result do
      IO.puts("OK")
      true
    else
      IO.inspect(string_in, label: "Input")
      IO.inspect(string_out, label: "Expected")
      IO.inspect(result, label: "Received")
      false
    end
  end
end

```

# ハマりポイント

IO.read(:stdio,:line)をMockにして、その内部で、IO.read(file,:line)を呼び出す処理が必要です。
この時、IO.readはモック化されているので、そのまま記述すると、定義されていないエラーになってしまいます。
Mockにはpassthough機能があったので、解決できました。

# まとめ

- Mockを使うことで、簡単な記述で、任意のモジュールを入れ替えた状態で実行する事ができる。
- passthough機能もある
- AtCoderの回答を修正することなくLivebook上で実行できた。
2024年のエンジニアとして勉強した方が良いこと


2024年のエンジニアとして、勉強した方が良いことは大きく分けて以下の3つです。

1. **プログラミング言語**
2. **クラウド技術**
3. **データサイエンス**

### 1.プログラミング言語

プログラミング言語は、エンジニアにとって最も基本的なスキルです。2024年も、以下のようなプログラミング言語の需要が高まっていくと考えられます。

* **JavaScript**
* **Python**
* **Java**
* **C#**
* **Go**

JavaScriptは、Webアプリケーション開発の標準言語として、あらゆる企業で需要があります。Pythonは、データサイエンスや機械学習の分野で広く使われており、エンジニアのスキルアップにも役立ちます。Javaは、エンタープライズシステム開発の分野で定番の言語です。C#は、Windowsアプリケーション開発の分野で人気があります。Goは、Googleが開発した比較的新しい言語ですが、近年急速に普及しています。

エンジニアとしてのキャリアを積んでいくためには、複数のプログラミング言語を習得しておくことが重要です。また、新しいプログラミング言語の登場にも常にアンテナを張り、最新のトレンドに対応できるようにしておきましょう。

### 2.クラウド技術

クラウド技術は、近年急速に普及しており、エンジニアの必須スキルとなっています。クラウド技術を活用することで、オンプレミス環境に比べて、コスト削減や運用の効率化を実現することができます。

2024年も、クラウド技術の需要はさらに高まっていくと考えられます。特に、以下のようなクラウド技術のスキルが求められていくでしょう。

* **Amazon Web Services (AWS)**
* Microsoft Azure
* Google Cloud Platform (GCP)

AWSは、世界最大のクラウドプラットフォームです。Azureは、Microsoftが提供するクラウドプラットフォームです。GCPは、Googleが提供するクラウドプラットフォームです。

クラウド技術を習得するには、クラウドプロバイダーの公式トレーニングや、オンライン講座などを利用して学習することができます。また、クラウド技術を活用した実践的なプロジェクトに参加し、スキルを磨くことも大切です。

### 3.データサイエンス

データサイエンスは、ビッグデータの分析・活用を行うための技術です。近年、データサイエンスの需要は急速に高まっており、エンジニアにとっても重要なスキルとなっています。

データサイエンスを習得することで、以下のようなことができるようになります。

* データの収集・分析
* データに基づく意思決定
* 機械学習モデルの開発

データサイエンスを習得するには、データサイエンスの基礎知識を学ぶとともに、PythonやRなどのプログラミング言語を習得する必要があります。また、データサイエンスに関する書籍やオンライン講座を活用して、実践的なスキルを磨くことも大切です。

### まとめ

2024年のエンジニアとして、勉強した方が良いことは、プログラミング言語、クラウド技術、データサイエンスです。これらのスキルを習得することで、エンジニアとしての市場価値を高め、キャリアアップにつなげることができます。
git clone --depth をしたら checkout できなくなった

## 前提
重たいリポジトリを扱っていたので、--depthオプションを使ってクローンした
```
$ git clone --depth 1 <リポジトリ>
```
## checkout時にエラーが
```
$ git checkout -b <ブランチ名> origin/<ブランチ名>
fatal: 'origin/<ブランチ名>' is not a commit and a branch '<ブランチ名>' cannot be created from it
```

## 原因
git configのfetch時のrefspecがmainブランチに限定されていた

**自動生成のgit config**
```
...
remote.origin.url=git@github.com:Minto312/<リポジトリ名>

                                 mainブランチに限定されている
                                 ↓                        ↓
remote.origin.fetch=+refs/heads/main:refs/remotes/origin/main
branch.main.remote=origin
...
```

**修正する**
```
$ git config remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
```

### 最後に
"2024年!初アウトプットをしよう"！ということで、人生初アウトプットをしてみました！
私が書く記事でエラーの苦しみがマシになればいいなーと思います
訂正などあれば教えてください！
WindowsにAnacondaをインストールして仮想環境を作るまで（備忘録）

## 参考1
https://www.python.jp/install/anaconda/windows/install.html

# Anacondaをインストールする
公式サイトからインストーラをダウンロードし、Anacondaをインストール。
インストール途中でチェックボックスの画面とインストール先フォルダの選択が出てくるが、特に変更せずNextを何回か押してインストール完了。

# インストール後の設定を行う
参考1どおりにコマンドラインの環境設定を行う。
```bash
conda init
```
PowerShell 実行ポリシーのRemoteSigned については
>・メールやインスタント メッセージ プログラムを含むインターネットからダウンロードされるスクリプトや構成ファイルには、信頼できる発行者からのデジタル署名が必要です。
>・インターネットからダウンロードされたものではなく、ローカル コンピューターに書かれたスクリプトにはデジタル署名は必要ありません。[^1]

とのことなので、参考サイトどおりに環境設定を行う。
```bash
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
```
Condaの環境の自動起動についてはとりあえずやらない。

* * *

# 参考2
https://www.python.jp/install/anaconda/conda.html

# Condaコマンドを使用して仮想環境をつくる
まず、PowerShellを起動しconda環境を開始する。
```powershell
conda activate
```
環境を作る。
```powershell
conda create --name py310 python=3.10.12
```
環境を切り替える。
```powershell
conda activate py310
```

(base)が(py310)になったので目標達成。
```powershell
(base) PS C:\Users\xxxx> conda activate py310
(py310) PS C:\Users\xxxx>
```

[^1]:https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4
***
#### でも結局、Anacondaインストール後は Anaconda Navigatorのenvironmentからcreateしたほうが簡単
【情報処理安全技術者試験】セキュリティ分野に関する午後問対策part1

# はじめに

こんにちは。現役ITコンサルタントのゲンです。
今回、情報処理安全技術者試験(SC試験)の午後対策の1問1答をアウトプットとして作成してみました。

午後問題は、「○○文字以内で答えよ」「○○の理由を40文字程度で答えよ」などと難易度は高くなります。なので午前問題とは比べ難易度は高いです。

それでは、一緒に情報処理安全技術者試験に合格できるように頑張りましょう！

# セキュリティ分野

| 出題実績　　　　　 | 問題 | 回答 |
| ---- | ---- | ---- |
|- |DNSキャッシュポイズニングを防ぐために行われる対策とは何か？※ポート番号という言葉を使って述べよ。|問合せPIの送信元ポート番号をランダムに変えること|
|- |OSコマンドインジェクションへの対策○○を起動できる言語機能の利用を避ける|シェル例）×　open関数〇　sysopen関数|
|- |AESは、共通鍵暗号方式か公開鍵暗号方式か|(共通鍵)暗号方式|
|-|ポートスキャンはなぜ行われるのか|開いているポートを検出するため|
|-|動的に確保したりできるメモリ空間のこと|ヒープ領域|
|-|日本語に訳すと「高度で継続的な脅威」組織NWに潜伏し続けるサイバー攻撃のことで、主に情報を盗むことを目的として行われる攻撃|APT攻撃(Advanced President Threat)|
|-|配布するプログラムにデジタル署名を施すことで、配布元の認証と第3者による改ざんを検出する技術|コードサイニング|
|令和4年春(午後)|メールヘッダインジェクションへの対策方法として、外部からの入力のすべてについて(　5字以内　)を削除する|改行コード|
|-|脆弱性を検証するためのツール。攻撃者のツールとして悪用されることもあるため扱いには注意が必要|エクスプロイトコード|
|-|OSなどに不正に組み込んだツールの存在を隠す不正なツール|ルートキット|
|-|ベイズ推定を使った機械学習の1種。多くのスパムメールに際立つ特徴を学習することで正確にスパムメールを識別するフィルタリング|ベイジアンフィルタリング|
|平成30年春(午前)|Webアプリケーションのフォームの入力フィールドに，悪意のあるJavaScriptコードを含んだデータを入力する攻撃|XSS(クロスサイトスクリプティング)|
|-|反射型と呼ばれるXSSのこと。利用者からのリクエストの中にスクリプトが含まれており、リクエストに応じて返信されるWebページにスクリプトがそのまま埋め込まれてしまうタイプの脆弱性|Reflected　XSS|
|-|格納型と呼ばれるXSSのこと。悪意のある利用者が脆弱性のあるWebアプリケーションにスクリプトを送信し、そこに保存させるタイプの脆弱性|Stored　XSS|
|-|DOM(Document Object Model)に関する脆弱性|DOM based XSS|
|-|複数の手法を組み合わせて対策しにくくしたDDoS攻撃|マルチベクトル型DDoS|
|-|経済的な損失を目的としたDoS攻撃|EDoS攻撃|
|-|サービスを停止だけでなく、破壊にまで追い込む攻撃|DeOS攻撃
以上
jbuilderでJSONを生成する


# はじめに

jbuilder は、Ruby on Rails で JSON を生成するための Gem です。
この記事では、jbuilder の基本的な使い方をまとめてみました。

# 環境設定

### Gem のインストール

Gemfile に jbuilder を追加するために、以下の行を追記します。

```ruby:Gemfile
gem 'jbuilder'
```

その後、以下のコマンドを実行して、Gem をインストールします。

```bash
  bundle install
```

# 使い方

### controller ファイルの設定

コントローラーで、JSON 形式でデータを返すように設定します。
例えば、[respond_to](https://railsdoc.com/page/respond_to)メソッドを使用して、JSON 形式のレスポンスを許可することができます。

```ruby:app/controllers/UsersController.rb
class UsersController < ApplicationController
  def index
    @users = User.all

    respond_to do |format|
      format.json { render json: @users }
    end
  end
end
```

### 基本的な JSON の生成

app/views ディレクトリ内に、.jbuilder 拡張子のファイルを作成します。
例えば、ユーザーリストを表示するための index.json.jbuilder を作成する場合、以下のような内容になります。

```ruby:app/views/users/index.json.jbuilder
json.array! @users, :id, :name, :email
```

`@users` に格納されたユーザーの配列を JSON 形式で出力します。各ユーザーの id、name、email が JSON 配列の要素として表示されます。

### array! メソッド

配列の各要素に対してブロックを実行し、その結果を JSON 配列として出力します。

```ruby:app/views/users/index.json.jbuilder
json.array! @users do |user|
  json.id user.id
  json.name user.name
  json.email user.email
end
```

```ruby:出力例
[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com"
  },
  {
    "id": 2,
    "name": "Bob",
    "email": "bob@example.com"
  }
]
```

この例では、`@users` 配列の各ユーザーについて、ブロック内で json.id, json.name, json.email を使用し、それぞれのユーザーの id、name、email の情報を JSON 配列に変換しています。

### extract! メソッド

特定のオブジェクトから複数の属性を一括で抽出し、JSON オブジェクトを構築することができます。

```ruby:app/views/users/index.json.jbuilder
json.extract! @user, :id, :name, :email
```

```ruby:出力例
[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com"
  },
]
```

特定のユーザー（`@user`）から id、name、email のみを選択的に抽出し、JSON オブジェクトに変換しています。

:::note info
例えば、ユーザーオブジェクトに status、date_of_birth、address などの他の属性が存在しても、指定された id、name、email のみが JSON 出力に含まれます。
:::

### merge! メソッド

与えられたハッシュやオブジェクトの内容を現在の JSON オブジェクトにマージします。

```ruby:app/views/users/index.json.jbuilder
json.array! @users do |user|
  json.merge! status: user.status
end
```

```ruby:出力例
[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "status": "active"
  },
  {
    "id": 2,
    "name": "Bob",
    "email": "bob@example.com",
    "status": "inactive"
  }
]
```

この例では、各ユーザーの ID、名前、メールアドレスに加えて、単一の status 属性を追加しています。

:::note info
user.attributes と記述すると、オブジェクトの中身のすべての値を返すことができます。

```ruby:app/views/users/index.json.jbuilder
json.array! @users do |user|
  json.merge! user.attributes
end
```

```ruby:出力例
[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "status": "active",
    "date_of_birth": "1990-01-01",
    "address": "123 Main Street"
  },
  {
    "id": 2,
    "name": "Bob",
    "email": "bob@example.com",
    "status": "inactive",
    "date_of_birth": "1992-02-02",
    "address": "456 Elm Street"
  }
]
```

この例では、ユーザーの全属性を JSON オブジェクトにマージしています。

:::

# 参考

https://railsguides.jp/action_view_overview.html

https://railsdoc.com/page/respond_to
カレンダーいいね賞に物申したい

# 今年も良かった

２０２３年のQiitaアドカレも大盛況のうちに終わりましたね。

良記事が豊作すぎて、逆に追っかけるのが大変なのですが😅、新しい知見を得られたり、モチベーションを上げられたりと本イベントを開催してくれているQiitaさんには毎年感謝感謝です。

# 一つだけ物申したい

カレンダーの趣旨と少し違うのですが、ここに書くのが一番Qiitaさんに届きそうなので、お邪魔させていただきます。
もう表彰の対象にもならないので、勘弁していただければ。

私も毎年参加させていただいていて（ポエムばっかりですが😅）、別に賞品目当てでやっているわけではないので別に良いのですが、一つだけ気になる賞が。

そう、それが **カレンダーいいね賞** です。

> カレンダーいいね賞
> 全てのカレンダーの中から、いいねの総数が最も多かった **カレンダーの作成者1名** に贈られます。

**みんなで作り上げたカレンダーなのに、表彰されるのはカレンダー作った人だけ？**

作り上げたのはエンジニア・デザイナーなのに、企画したディレクターだけ表彰される会社を想起しました。

過去にカレンダーいいね賞を取った人の中には、自分のカレンダーに一つも記事書いてないということもありました。
そのカレンダーに投稿した人たちも気にはしてないでしょうが、みんなで面白いカレンダー作り上げたのに、何も記事書いてない人が表彰されちゃうんだー、とちょっともやっとしました。

# カレンダーいいね賞は参加者全員にしてほしい

別に賞品なんていらないです。

そういうバッジだけでも良いです（「2023年〜位カレンダー投稿者」とか）。

**何の見返りを求めてない人たちがただただ面白い記事を書きたくてできた奇跡のような良カレンダー参加者全員を表彰してあげてほしいです。**
Ruby on Railsにおける秘匿データの扱い：メリット、デメリット、および管理方法

#### 秘匿データとは？
Railsアプリケーションでは、APIキー、データベースのパスワードなど、外部に漏れるとセキュリティ上のリスクが高まる情報を「秘匿データ」と呼びます。これらは通常、ソースコードとは別に安全に管理する必要があります。

#### 管理方法の選択肢
1. **環境変数 (ENV)**
2. **Rails Credentials**

## 環境変数 (ENV)
- **メリット:**
  - 簡単に設定でき、多くのホスティングサービスがサポート。
  - ローカルと本番環境で異なる値を設定しやすい。

- **デメリット:**
  - 環境によって設定方法が異なる可能性がある。
  - アプリケーションが多くなると管理が煩雑に。

## Rails Credentials
- **メリット:**
  - ファイル内にすべての秘匿情報を集約できる。
  - 暗号化されているため、安全性が高い。

- **デメリット:**
  - `master.key` の管理が必要であり、これが漏れるとセキュリティリスクに。
  - 初期設定が環境変数よりも複雑。

## どちらを選ぶべきか？
- 小規模なアプリケーションや、環境ごとの値の変更が多い場合は **環境変数**。
- 大規模でセキュリティが重要視されるアプリケーションでは **Rails Credentials**。

### Rails Credentials の使用方法
1. **セットアップ:**
   ```ruby
   # 新しいRailsアプリを作成
   rails new myapp

   # 以下のファイルが生成されます
   config/credentials.yml.enc
   config/master.key
   ```

2. **編集:**
   ```bash
   # credentialsを編集
   EDITOR="vim" rails credentials:edit
   ```

3. **使用例:**
   ```ruby
   # AWSの設定をcredentialsに追加
   aws:
     access_key_id: 123
     secret_access_key: 345

   # アプリケーション内で使用
   Rails.application.credentials.aws[:access_key_id]
   ```

## まとめ
秘匿データの管理はRailsアプリケーションの安全性を保つために不可欠です。
環境変数とRails Credentialsの両方にはそれぞれメリットとデメリットがあり、アプリケーションの規模やニーズに応じて適切な方法を選択することが重要かなと思います。
秘匿データの管理を適切に行うことで、セキュリティリスクを最小限に抑えつつ、効率的にアプリケーションを運用しましょう。
AI-102(Designing and Implementing a Microsoft Azure AI Solution)試験

## はじめに
2023/12/24に、MicrosoftのAI-102試験に合格しました。
AIには興味がある人でも、日本語の資料が少なく勉強しづらい試験だと思いますので、備忘として記載します。


## 受験した理由
2023年はAIが広く普及した年でした。
数年前にG検定は取得したものの、それ以降まったく勉強していなかったのでMicrosoftの最新技術を学んでみることにしました。

とはいえ、個人利用のためAzure OpenAI を触れず、ほぼ机上の学習のみでの受験となってしまいました。つらかった。。

## 勉強のやりかた

### CloudSkillChallenge
試験を受けるにあたって、1つ目の関門がコストではないでしょうか。
クラウドスキルチャレンジで半額になりますので、これは申し込んでおいたほうがよいでしょう。

https://developer.microsoft.com/ja-jp/offers/30-days-to-learn-it

### Microsoft Learn
どれだけ役に立ったかどうかは別として、ひととおり目は通しました。
（後述しますが、試験中にもMicrosoftLearnは参照可能です）
また、試験サンドボックスで知識の確認ができます。
簡単だからやっても意味ない、という記事もありましたが、私は3周くらいしてやっと8割を超えることができました


https://learn.microsoft.com/ja-jp/credentials/certifications/exams/ai-102/


### Udemy
セールで安い時に買いました。
3回分のテストがありますが、どう考えても設問がおかしいところや
四択なのに同じ選択肢があったりするなどありますが、やらないよりは
良いかと思います。こちらも3周くらいしてなんとか8割を超えることができました。
日本語がおかしいところはあきらめて下さい
本番とまったく同じ設問が10問くらいあったと思います。

https://www.udemy.com/course/ai-102-practice-test-questions-prep-exam/

### 無料の問題

CertyIQ というサイトから、無料で問題をダウンロードできました。
こちらも10問近く、似たような問題があったと思います。

https://certyiq.com/




## 試験当日
驚きでした。
なんと試験中に **Microsoft Learn が開けるのです。**
繰り返しますが、**試験中にMicrosoft Learnが開ける**のです！！
（画面分割するか、全画面にするか、設問だけに戻るといった　アイコンが上部に表示されていました）

どこかに書いてあったのかもしれませんが、私がこれまで受験したマイクロソフト試験ではなかったと思います。

そのため開いてよいのか、点数がマイナスになってしまうことがあるのでは？など悩んでしまいましたが、いくつかの設問については実際に確認することで、絶対の自信をもって回答できました。


### 問題傾向
3つのパートにわかれていました。
①ちょっとした文章を読んで答える問題
②普通の選択問題
③ある程度の文章に対して2択で正誤をこたえるような問題（戻れない）
(それぞれのパートが終わると、後ろには戻れない)

操作順序の並び替えがいくつかありましたが、8割程度は事前学習したものとまったく同じでした。

2023年10月に試験が更新された、ということだったので、ちょっと心配だった部分はありましたが、そんなに気になるところはありませんでした。
（2024年2月にまた変更になるそうなので、あくまで参考まで）


## 終わりに
Micorosoft Learnを開けるからといっても、あまり当てにはしないほうが良いと思います。
日本語がいまいちとはいえ、過去問を繰り返すのが最適解ですね。

Azure OpenAIを触ることができれば、もう少し楽に合格できたかもしれません。

サービス名が新しくなっている点は、あまり気にしなくとも大丈夫です。
これから受験する方、頑張ってください。