OmniAICreator/Qiita-1.07M huggingface dataset:
SQL・Databesを基本からまとめてみた【INSERT/UPDATE/DELETE文】

## INSERT
テーブルにレコードを追加するのに用いる命令文

```Basic.sql
INSERT INTO テーブル名(カラム名1, カラム名2, ...)
VALUES (値1, 値2, ...)
```
例：membersテーブルのid=11に吉田さんを追加する
```
INSERT INTO members(id, name, height, weight, age, job_id)
VALUES (11, "吉田", 186.2, 97.1, 23, 5);
SELECT * FROM members;
```
INTOの後のカラム名とVALUESの後の値の数は合わせる！
複数追加した時は、カンマで区切れば複数のレコードを追加できる！
idは他と重複しないように設定する！

## UPDATE
テーブル中にあるデータの値を更新する命令文

```Basic.sql
UPDATE [テーブル名] SET　カラムと値の指定;
```
例：全てのレコードのageカラムを30に変更する
```Sample.sql
UPDATE members SET　age = 30;
```
『カラム = 値』という形で、変更するカラムと値を指定する
　
このようにすると全てのレコードが変更されるので、特定のレコードのみを変更したい場合は以下のように書く
```Basic.sql
UPDATE [テーブル名] SET　カラムと値の指定　WHERE 条件式;
```
例：佐藤さんの身長を172.1cmに変更する
```Sample.sql
UPDATE members SET　height = 172.1 WHERE id = 1;
```
今入っている値から指定した数だけ増加させることもできる

例：membersの全員の年齢を1歳増やす
```Sample.sql
UPDATE members SET age = age + 1;
```
WHEREで指定したレコードにおいて、複数列を同時に変更することもできる

例：佐藤さんの身長を１増やし、体重を10追加する
```Sample.sql
UPDATE members SET height = height + 1, weight = weight + 10, 
WHERE id = 1;
```
## DELETE
テーブル中にあるレコードを削除する
```Basic.sql
DELETE FROM [テーブル名];
```
例：membersテーブルの全てを削除する
```Sample.sql
DELETE FROM members;
```
例：特定のレコードのみを削除するには、以下のようにWHEREで条件を指定する
```Basic.sql
DELETE FROM [テーブル名]　WHERE　[条件式];
```
例：membersテーブルから、id = 10の加藤さんを削除する
```Sample.sql
DELETE FROM members　WHERE id = 10;
```
条件次第では複数のレコードを削除することも可能

例：伊藤さん(id = 6)より、idが大きい人のレコードを削除する
```Sample.sql
DELETE FROM members　WHERE id > 6;
```
例：伊藤さん(id = 6)より、idが大きい人のレコードを削除する
```Sample.sql
DELETE FROM members　WHERE heght >= 180 OR weight <= 50;
```

例：membersテーブルにおいて身長が180cm以上、または体重が 50kg以下のレコードを削除する
```Sample.sql
DELETE FROM members　WHERE id > 6;
```

UPDATEと同様にWHEREで条件式を指定しないと、全てのレコードが削除されるので注意する！
データを削除する際には、本当に削除して良いのか確認するなど慎重に行うこと！



## 参考サイト
[3時間で学ぶ SQL ・データベース 超入門【丁寧な解説+演習問題で SQL データ抽出の基本が身につく】標準 SQL](https://itplusjp.udemy.com/course/sql-begginer/learn/lecture/14052761#overview)
.NET MAUI　Prismテンプレートのインストール方法

#  必要環境　
VisualStudio2022

#  手順1
**VisualStudio2022**の
**ツール → Nugetパッケージマネージャー → パッケージマネージャーコンソール**
で以下のコードを張り付ける。
```
dotnet new --install Prism.Templates::8.1.97'
```

#  手順2

インストールが完了すると新しいプロジェクトの作成からPrismテンプレートが増えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958553/71b2ee0a-7c1f-824a-152f-a89a51caaff7.png)

#  最後に
プロジェクトを作成するとこのような感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958553/a9d27fda-ed20-7f64-4b6b-38a4806e11d5.png)


**PrismStartup.cs**という見慣れないファイルがあると思いますが、こちらのファイルでは主にNavigation関連の登録を行っているファイルです。
OnAppStartで起動時に表示されるページを設定し、RegisterTypesメソッドではナビゲーションページを登録しています。ページを増やした際には毎回ページを登録する必要があります。
```PrismStartup.cs
using PrismApp1.Views;

namespace PrismApp1;

internal static class PrismStartup
{
    public static void Configure(PrismAppBuilder builder)
    {
        builder.RegisterTypes(RegisterTypes)
                .OnAppStart("NavigationPage/MainPage");
    }

    private static void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<MainPage>()
                     .RegisterInstance(SemanticScreenReader.Default);
    }
}
```
【Railsチュートリアル11章】:idがnilになりNo route matchesが発生する

# エラー概要
Railsチュートリアル11章リスト11.24にて
ユーザー登録にアカウント有効化を追加後Minitestが通りませんでした。

```rb:users_controller.rb
class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      UserMailer.account_activation(@user).deliver_now
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new', status: :unprocessable_entity
    end
  end
  .
  .
  .
end
```

エラー内容
```
ActionView::Template::Error: No route matches {:action=>"edit", :controller=>"account_activations", :email=>"user@example.com", :id=>nil}, possible unmatched constraints: [:id]
```

# 原因
本来`new_token`メソッドで生成されるランダムな文字列が入るはずの`:id`がnilになっているためルーティングエラーが発生しているようです。

今回`:id`にあたるランダムな文字列を生成する`new_token`メソッドを使用している箇所が怪しそうなので確認します。

```ruby:user.rb
class User < ApplicationRecord
  .
  .
  # 有効化トークンとダイジェストを作成および代入する
  def create_activation_digest
    self.activation_digest = User.new_token
    self.activation_digest = User.digest(activation_token)
  end
end
```

`self.activation_token`とすべきところを`self.activation_digest`にしていました、、

修正すると無事テストが通りました。
`@user.save`が実行された時点でインスタンス変数である`activation_digest`に値がセットされていないことが原因でした。

```ruby:user.rb
class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token
  before_save :downcase_email
  # before_create :create_activation_digest
  .
  .  
```

before_createで指定を忘れた場合も同様のエラーが発生します。

# まとめ
同じ箇所でつまずいた方の参考に少しでもなれば幸いです。
後進の育成＃１

こんな言い方、社会人になってからしかしないよね。
読み方は「こうしん」だよ。なにそれ。でしょ。
社会に出てから聞く言葉って、なんとなくわかりにくいです。

で、今日は「後進の育成」について。
まずは、インターネットから
「後進育成とは、自分の後に続いていく部下に対して知識や経験から学んだノウハウを伝えながら育成していく手法を指します。」
「自分の後に続く後輩に、自分が持つ技術や知識を伝えること。」
と書いてますね。

定年、病気、死亡、落選などにより、誰もが、１００％引退するわけです。
自分がやってきたことは、どんなことで、どういう目的で、どんなことをしてきたのか？
それが、自分が居なくなっても必要なことであれば、誰かに引き継がなければいけないですね。

例えば、自分が自分のために趣味で行ってきたことは、引き継がなくてもいいですよね。
自分はゴルフが趣味ですが、引き継ぐ気はないですね。
でも、仕事の場合は、基本的に「誰か」のために行うものです。
自分が居なくなっても、仕事が進まないと、その「誰か」が困りますよね。
そうならないようにするのは、現在仕事をしている人の責任です。
だから、「後進の育成」は重要なんです。

これが出来ない方は、「自分のお客様に無責任」としか言いようがなくて、そんな人に仕事を任せるべきではないんです。

時々会社でも「この仕事は自分しかできないんだ！」なんて、誇らしげに言う人もいるけど、「無責任の塊」の人です。
そんな人に仕事をさせる人も、無責任を助長しているます。
管理者は「後進の育成」を促すか、他の人に仕事を任せるべきです。

でもこんな、自分だけが出来ると考える人が、世の中にはたくさんいるんですね。
特にそんな人が、一番トップに立つとたちが悪い。
自分が一番で、他の奴は無能なので、引継ぎ委なんかできない。と考えるんですかね。
引退しなくなるんです。

某国に居ませんか？御社や身の回りには居ませんか？

そう考えると、定年制は素晴らしい仕組みだと思いませんか？
バカがトップに立つと、定年制というか、「長期継続を防止する仕組み」を壊すんですよね。
「自分が居なくなった後なんか知ったこっちゃない。自分がいるときだけ皆がたたえてくれればよい。自分は無責任の塊だ！」
と自分で表明しているんですんよね。
（もう一度言いますが、某国にいませんか？）

世の中に必要なことをしているのであれば「後進の育成」を大切にしてください。
すると、「後進の育成」をすることが、「自分を伸ばすことになる」のにも気づくでしょう。

P.S.
ちなみに、俺の背中を見て学べ！も「後進の育成」のへたくそなバージョンですかね。
へたくそでは、なかなか育たないかもしれません。育てることが重要なんです。
育たなかったら、それは育てる人の責任なんですよ！
と書いたけど、誰でも育つわけではなく、育ちたいという気持ちが無いと育たんけどね。
「成長したい」という気持ちは、向き不向きがとても重要だと思う。
ゴルフが好きじゃない人に、「こうするとドライバーは飛ぶようになる。」なんて、いくら教えるのが上手な人が教えても無駄だし、
興味が無い人に対して、「ゴルフがうまくなりたいように、モチベーションを上げる」のが名コーチではないし。
自分に向いていることを探せた人が、育っていくのですね。
ディレクトリ内の特定の文言を含むファイルを検索するコマンドレット（Windows PowerShell）

# 概要
特に外向けに難しいことを発信しようとしたわけでもなく、今後もたまに使いそうだと思った、ファイル検索＠Windowsローカル環境のコマンドレットを備忘しておきます、そのいくつか。
linuxだとよくやるんですが、Powershellかあ、と個人的に思ったもあります。

# 指定ディレクトリ内で、特定の文言のファイル名を検索する

こういう感じ。

```terminal
Get-ChildItem -Path "（ディレクトリの指定）" -Recurse -Include "*（検索文字列）*" -ErrorAction SilentlyContinue -Force | Select-Object -ExpandProperty FullName
```

# 終わり

なんだかんだ、手元のWindows環境のドライブでも検索できたら便利なんですよね。
[Nuxt2(bridge)]CSSでSVGをインラインに展開する

CSS(SCSS)内にて、`url()`で指定されたSVGをインラインでエンコードして展開する方法

## 動作環境
- nuxt: ^2.15.8
- @nuxtjs/composition-api: ^0.32.0

## 必要なパッケージ
- vue-svg-loader
- url-loader

### インストール
```Bash
$ yarn add -D vue-svg-loader url-loader
```

## nuxt.config.js
`nuxt.config.js`に次のように追記する

```js:nuxt.config.js
  build: {
    ...

    extend (config, ctx) {
      config.resolve.alias['~@'] = path.resolve(__dirname)
      const svgRule = config.module.rules.find(rule => rule.test.test('.svg'))
      svgRule.test = /\.(png|jpe?g|gif|webp|ogg|mp3|wav|mpe?g)$/i

      config.module.rules.push({
        test: /\.svg$/,
        oneOf: [
          {
            resourceQuery: /^\?vue/,
            loader: 'vue-svg-loader',
            options: {
              svgo: {
                //svgがエンコード時に改変されることを回避
                plugins: [{ removeViewBox: false }] 
              }
            }
          },
          {
            loader: 'url-loader',
            options: {
              limit: 10000, // インラインにするファイルサイズの閾値を設定
              encoding: 'base64', // Base64エンコーディングを有効にする
              esModule: false // CommonJSモジュール形式を使用する
            }
          }
        ]
      })
    }

    ...
  },    
```
こう書くことで、vueファイル内、CSS内のSVGがwebpackによりエンコードされる

## .vueファイル
次のように、svgファイルを指定する
### <template>
```
<img src="~@/assets/hoge.svg">
```

### <style>
```
background-image: url("~@/assets/hoge.svg")	
```
FlutterのSDKパスで詰んだ話

# 原因はパスエラー

さっきFlutterのプロジェクト作成をしようとしたところ、SDKのパスの間違いが発覚したので、、、


https://qiita.com/amamiya_dev/items/03dece98d8f5d7a00e2f

早朝に投稿した記事ではパスをbinフォルダまで指定したのですが、IDE等でFlutterを使う場合はflutterフォルダのルートを指定するぽいです。

## パス指定の例

> (ホームディレクトリにSDKを置いている場合)

```
C:\Users\<User Name>\flutter\
```
ちなみに環境変数の時は
```
C:\Users\<User Name>\flutter\bin\
```
でした。

むむむ。
Bridge or Switch

ルーターでLANポートとWANポートが有る場合、以下のようにSwitchを使っているケースが多いです。

![comcerto-sw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/9d002b87-ed54-5679-814d-0bff7579ac79.png)

WANポートのMACは未使用で、PHY切り出しでWANポートにしています。

WANポートが必要なく、WANポートとLANポートを透過に使う場合以下の方法があります。

* GEMAC0とGEMAC1でBridgeする

* GEMAC0を使わずWANのMACをSwitchで使ってGEMAC1だけで使う

後者の方がOS内の処理が少なくて良いかもしれません。

ちょっと厄介なのが、SwitchがGEMAC0のmdioで制御されてるので、GEMAC0をconfigから外すわけにはいきません。

と思ったのですがComcertoのAR8316で設定を試したのですが、うまくいかなかったのでbridgeにしようかと思ったのでが、bridgeはNetBSD 10で仕様が変わるようで、当面様子見します。

AR8316の設定は2日くらい試したのですが、上手くいきませんでした。可能性としては、一度設定するとHardware Resetをしないと再設定できないなどの特殊な条件が可能性が考えられます。ターゲットではU-Bootが設定しているように思われます。ひょっとするとrgmiiがPHY5に接続されてると、MAC接続は出来ないのかもしれません。ともかくデーターシートも、メーカのコードもないのでお手上げです。

AR8316は初期のGigaのSwitchでどちらかというと100のAR8216に近いようです。AR8316の後のGigaのSwitchは大きく変わっていて、これらの情報は参考になりません。
G.I.Gに潜入！第6期1回目で学んだことをレポート

## 概要
G.I.Gプログラムの第１回セッションに参加したので、そこでの学びを簡単にまとめます。

### G.I.Gとは
G.I.GとはGoogle Cloud Innovators Gymの略称で、Google Cloudに詳しい人になり、プロジェクトなどでGoogle Cloudの活用を推進することを目指すものです。

### 充実したプログラム
G.I.Gが提供しているのは以下の通りです。

- セッション3回
- もくもく会
- Courseraプログラム

Courseraコースは、各資格に合わせて編成され、日本語版も提供されています。

![スクリーンショット 2023-04-13 14.18.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/4899be3c-9c3a-87ec-19ad-ccd3955ffdde.png)

すごいですね。


## ハンズオン

今回は、第１回セッションで実施されたハンズオンについてまとめます。
ハンズオンでは主に「スケーリング」と「トラフィック」に関することを学びました。

### スケーリング
ハンズオンでは、インスタンス数をビジュアライズするツールをWebアプリケーションとしてデプロイし、どのようにスケーリングされているかを表現しました。

```
gcloud run deploy metrics-writer \
 --concurrency 1 \
     --allow-unauthenticated \
     --image \
     asia-northeast1-docker.pkg.dev/gig6-1/gig6-1/metrics-writer:latest
```
最初のコンカレンシーを1に設定した状態で、大量のリクエストを送信すると以下のようになります。

![スクリーンショット 2023-04-13 16.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/c5d6b578-85ef-6574-f681-2fba7a4b8449.png)

コンカレンシーが設定されていないため、リクエストが大量に送信されるとその分だけインスタンスが増えます。

![スクリーンショット 2023-04-13 16.12.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/e05107da-8438-8254-4c24-80accc20d67f.png)

これに対して、コンカレンシーを設定すると以下のようになります。
```
gcloud run services update \
 metrics-writer --concurrency 5
```

![スクリーンショット 2023-04-13 16.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/583bf01d-1c6e-76f4-e653-9b7a0fd4678d.png)

インスタンス数がだいぶ減ります。
１つのCloud Runで捌けるリクエスト数が変わるのでインスタンスの個数が変わります。


更にそれに対してmaxのインスタンス数を設定します。
```
gcloud run services update \
 metrics-writer --max-instances 5
```
![スクリーンショット 2023-04-13 16.16.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/118b16d8-695f-7735-6da2-a5721f2ae462.png)
するとスケーリングされても最大インスタンスが5個になります。

設定1つでここまでスケーリングを自由に扱えるのすごいな...


### トラフィック
続いてトラフィックの流す割合を調整しました

このコマンドで新しい Cloud Run インスタンスを作成し、トラフィックの流れる先として10%設定しました。そして、次のコマンドで元のインスタンスのトラフィック割合を変更して、新しいインスタンスに10%のトラフィックが流れるようにしました。


もとは１つのCloud Runに100%トラフィックを流していたのですが、もう一つCloud Runを立ち上げてそれに10%流すように設定します。
```
gcloud run services update-traffic \
 metrics-writer --to-tags \
     green=10
```
![スクリーンショット 2023-04-13 16.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/b7dcede0-d865-fa95-e5d6-51592335f123.png)
すると、グラフのように一定の割合でそちらにもトラフィックが流されているのがわかります。

次に50%ずつ振り分けるようにしてみましょう。
```
gcloud run services update-traffic \
 metrics-writer --to-tags \
     green=50
```
![スクリーンショット 2023-04-13 16.28.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/227b4e77-7692-c5e9-d146-5b419c05641b.png)
すると、最初は立ち上がりに差がありますが途中から50%づつになっているのがわかるかと思います。

A/Bテストとかとってもしやすそう。

## 感想


この手のハンズオンはめちゃくちゃシンプルなCRUD形式のアプリを動かしがちだったりするが、そうではなくてインスタンス数をビジュアライズしたものを動かしたりするのはとても面白かったし、効果がとてもわかりやすかった。
Cloud Runとても使いやすそうなので今度何かデプロイする時とか使ってみたい。
レポート、ダッシュボードのフォルダーの権限


レポート、ダッシュボードのフォルダーに権限をつけて参照できる人を制限していたはずなんですが、なぜか全員アクセスできてしまう。
何でだろう？

ここにあるように従来のフォルダーでなく、拡張フォルダーを使っています。

[従来のフォルダ共有の廃止は、Spring ’22に延期になりました。](https://sf.forum.circlace.com/articles/576867245481791488)


これだな。　ユーザのプロファイルを見ると以下が有効になっていました....

拡張フォルダ共有の有効化による影響

・フォルダを明示的に共有していない場合や、「参照」アクセス権しか持っていない場合も、「公開フォルダのレポートを管理」または「公開フォルダのダッシュボードを管理」を持つユーザはすべてのダッシュボードフォルダまたはレポートフォルダ (他のユーザの非公開フォルダを除く) を管理できます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/08a2233b-27cb-ba10-d648-b8fc714ae313.png)


# レポートの作成はさせてもいいが、編集はさせない、参照はできるという設定をしたい

+ [レポート・フォルダーの編集等の権限について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X7zMC)

:::note
「レポートの作成とカスタマイズ」をオフにしたところ、

確かに作成も編集もできなくなりました。作成不要なプロファイルにはこちらを活用したいと思います！
:::

# 解答例

+ [レポートフォルダで共有していないユーザにもフォルダ内のレポートが参照できてしまっています。 該当ユーザのプロファイルでは「公開フォルダーのレポートを参照」権限が付与されております。 ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PYTvB)
VDIの複数割り当て

## 複数割り当て

* 元のvdiを変更せずに、増分のみ別diskイメージに書き込んでいく。
* OneDriveなどの共有で便利

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/b9b852d4-091c-b7e7-debc-4b6e3f3574ea.png)
XcodeでいつものようにArchiveしようとしたらrsyncエラーがでてマジで焦った

# 現象
Xcodeでアプリを修正して、配布するためにArchiveしたら以下のrsyncエラーがでました。

```
rsync error: some files could not be transferred (code 23) at /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54.120.1/rsync/main.c(996) [sender=2.6.9]
Command PhaseScriptExecution failed with a nonzero exit code
```

# 対処方法
運良く同じ現象に遭遇している[Stackoverflow](https://stackoverflow.com/questions/63533819/rsync-error-some-files-could-not-be-transferred-code-23-command-phasescriptex)を見つけました。CocoaPodsの問題みたいです。

以下のように「Pods-APPNAME-frameworks.sh」を修正するとArchiveが通りました。"-f" を入れるだけ。

```Swift:Pods-APPNAME-frameworks.sh [修正前]
if [ -L "${source}" ]; then
    echo "Symlinked..."
    source="$(readlink "${source}")"
  fi
```

```Swift:Pods-APPNAME-frameworks.sh [修正後]
if [ -L "${source}" ]; then
    echo "Symlinked..."
    source="$(readlink -f "${source}")"
  fi
```

# 真因はわからず
Xcodeのアップデートが絡んでいるように思いますが、まったくもって真因にはたどり着けませんでした。こうして備忘録を残していくことくらいしかできませんが、誰かのお役に立ったなら幸いです。
Quarkusで外部APIをHttpClientで叩いてレスポンスを任意の型で受け取りたい

# はじめに

新しい職場に転職して早2ヶ月、ついに会社の特徴でもある会社として新しい技術に挑戦していくという経験をする機会が訪れました
今回は「Quarkus」というJava(Kotlin)のフレームワークを使ってAPIを構築していくことになりました

詳しくはドキュメントを見たほうが早いです

https://ja.quarkus.io/about/

チームで取り組むに至ったメリットは簡単にまとめると
- 立ち上げが高速
- Kubernetesと相性が良い

という点になります

今回はそんなQuarkusでAPIを作成するときに詰まったことをまとめます

# 問題

外部のGetリクエストを叩くDriver層を作成していました

```kotlin:UserDriver.kt
@ApplicationScoped
class UserApiDriver {
    val client = HttpClient.newBuilder().build();
    val request = HttpRequest.newBuilder()
        .uri(URI.create("https://jsonplaceholder.typicode.com/users/1"))
        .build();
    return client.send(request, HttpResponse.BodyHandlers.ofString());
}
```

https://zetcode.com/kotlin/getpostrequest/

しかし、作成して思いました
これだと`レスポンス`の型がないので、なんでもレスポンスとして受け取って、ゲートウェイに返してしまうから問題だと

なんとかしてレスポンスの型のチェックをする仕組みがほしいと思いました

# 解決方法

以下のページを参考にすることで実現ができました

https://ja.quarkus.io/guides/rest-client-reactive

```kotlin:UserApiDriver.kt
package com.sample.driver

import com.sa.domain.NewsIdimport org.eclipse.microprofile.rest.client.RestClientBuilder
import java.net.URI
import javax.enterprise.context.ApplicationScoped
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.PathParam

@ApplicationScoped
class UserApiDriver {
    private val baseUrl = "https://jsonplaceholder.typicode.com"
    private val newsService = RestClientBuilder.newBuilder().baseUri(URI.create(baseUrl)).build(NewsService::class.java)

    @Path("/users/{userId}")
    fun find(userId: String): UserJson {
        return userService.getById(userId)
    }
}

interface UserService {
    @GET
    @Path("/users/{userId}")
    fun getById(@PathParam("userId") userId: String): UserJson
}

data class UserJson(val id: String, val name: String, val username: String......(省略))

```

またもう一つのつまづきポイントは

`@PathParam`を`@PathQuery`にしていてエラーにはまりました


# おわりに

これからたくさん躓くと思うのでまとめていきます
またハンズオンも作成予定です

# 参考

https://ja.quarkus.io/about/

https://zetcode.com/kotlin/getpostrequest/
「エンジニアに必要な技術力だけではなく、コミュニケーション能力の重要性」

エンジニアの場合、技術力だけではなくコミュニケーション能力も重要であり、ビジネス力の不足は技術力を十分に活かせなくすることがあるようです。クライアントの意図を正確に汲み取ることやチーム内での意見交換が求められるため、柔軟なコミュニケーション能力が必須と言えます。

エンジニアという職種は、技術力が重視されるというイメージがあります。しかし、実際にエンジニアとして働いてみると、技術力だけではなく、コミュニケーション能力が非常に重要であることがわかります。

ビジネス力がないために、技術力を生かすことができずにいるエンジニアは少なくありません。例えば、クライアントの意図を正確に汲み取れずに実装を進め、1ヶ月かけて作ったものが無駄になってしまうこともあります。また、チーム内でのコミュニケーションも重要であり、仕事を円滑に進めるために避けては通れないものになっています。

コミュニケーションが苦手と感じる人は多いかもしれませんが、仕事におけるコミュニケーション能力は、面白い話をするためのものではありません。技術的な問題を適切に伝えたり、チーム内で意見を交換したりするために必要なものです。

「相手が理解しやすい言葉で専門的な知識を伝えること」「相手の考えを正確に理解すること」「自分の考えや仕事の状態を相手に適切に伝えること」などが、コミュニケーション能力に含まれます。

流暢な話し方や面白い話ができることも重要ですが、これらのスキルがなければ、ただのモノローグになってしまいます。コミュニケーションにおいて重要なのは、相手との対話による意思疎通です。上手に話せなくても、意思が通じ合えばそれで十分です。それができない人は、コンピューターとの対話すらできないかもしれません。
CORSのエラーが出た時の対処法 - Laravel 9.x Sail + Bootstrap on Windows 

## 発生した環境

WSL2でDocker Desktop for WindowsでLaravel9でSailでbootstrapな環境で、うぷぷうぱうぱ。

###ホスト
- OS: Windows 10 Pro
- Docker: Docker Desktop 4.17.0
- Laravel: Laravel 9.x
- WSL: Ubuntu 22.04

### Sail (Docker コンテナ)
- sail 8.0
- pgsql
- mailpit

## 発生までの手順

ざっくりコマンドだけ羅列しますが、
```
composer create-project . "9.*"
composer require laravel/sail --dev
composer require laravel/ui --dev
php artisan sail:install
vi docker-compose.yml
sail up -d
sail composer update
sail php artisan ui bootstrap --auth
sail npm install
sail npm run dev
```
とこんな感じです。

ここで、`http://localhost/` は、普通に見れますが、例えば `/login` とか、bootstrapのCSS使ってるようなページを開くと、スタイルが適用されずに表示されます。

Firefoxのウェブ開発ツールからコンソールみると

> クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、http://0.0.0.0:5173/@vite/client にあるリモートリソースの読み込みは拒否されます (理由: CORS 要求が成功しなかった)。ステータスコード: (null)

>クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、http://0.0.0.0:5173/resources/js/app.js にあるリモートリソースの読み込みは拒否されます (理由: CORS 要求が成功しなかった)。ステータスコード: (null)

の２つが出ていた。

ググってると、以下の記事を見つけた。
[GitHub | Windows - Failed to load when loading vite dev server resources #28](https://github.com/laravel/vite-plugin/issues/28)

## 私の環境で解決した方法
上記ページにもあるが、`vite.config.js` に以下のように`server`部分を追加した。
``` vite.config.js
export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/sass/app.scss',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
    server: {
        hmr: {
         host: 'localhost',
        },
    },
});
```
作者曰く、どうやらWindowsではIP(0.0.0.0)で通信出来ないことに起因してるらしい（[jessarcher commented on Jun 28, 2022](https://github.com/laravel/vite-plugin/issues/28#issuecomment-1169519127)）。
`localhost`を`127.0.0.1`に変更してもエラーは解消された。

この情報がどこかの誰かに役に立つといいな。
python初学者がchatGPT先生に教わる/スクショメール編

## はじめに
初学者がPythonを勉強しています。
間違っている内容や改善などご教示いただければ幸いです。

## 目的
（共通）Pythonを学習するにあたり、まずは身近にある業務の省人化を目的とする。
（今回）Screenshot撮影（今回は全体） → メーラー(OUTLOOK）起動

:::note warn  
＊2023.4 chatGPT参考に作成
:::

## 環境
Windows10
Python 3.8.3 (memo: python -V 

## 全体コード
以下、全体コード

```python:screenshot_to_mail.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import tkinter as tk
from tkinter import messagebox
import pyautogui
import win32com.client as win32

outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)

mail.to = 
mail.bcc = 
mail.subject =
mail.body = 

def take_screenshot():
    i = 1
    while True:
        # スクリーンショットを撮影する
        screenshot = pyautogui.screenshot(region=(0, 0, 1920, 1080))
        screenshot = screenshot.resize((960, 540))

        # スクリーンショットを保存する
        screenshot_path = os.path.join(os.getcwd(), "temp" + str(i) + ".png")
        screenshot.save(screenshot_path)

        # スクリーンショットをメールに添付する
        attachment = mail.Attachments.Add(screenshot_path)
        attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", "temp" + str(i) + ".png")
        html_tag = '<img src="cid:temp' + str(i) + '.png">'
        mail.HTMLBody += html_tag

        # スクリーンショットがメールに添付された旨のメッセージを表示する
        print("temp" + str(i) + ".pngがメールに添付されました。")

        i += 1

        # ユーザーに繰り返しの可否を尋ねる
        answer = messagebox.askquestion("繰り返し", "もう1回キャプチャしますか？")
        time.sleep(0.4)
        if answer == 'no':
            print('if break')
            break

    root.destroy()

    # Outlookを最前面に表示する
    print('Outlookを最前面に表示する')
    os.startfile("outlook")
    time.sleep(6)  # Outlookが完全に起動するのを待つ

    # メールを表示する
    print('メール表示')
    # メールを表示する
    mail.Display(True)

    # Outlookを終了する
    outlook.Quit()

    # スクリーンショットを削除する
    for j in range(1, i):
        screenshot_path = os.path.join(os.getcwd(), "temp" + str(j) + ".png")
        os.remove(screenshot_path)

    # 終了メッセージを表示する
    print("プログラムを終了します。")

root = tk.Tk()
root.withdraw()  # GUIウィンドウを非表示にする
messagebox.askquestion("","キャプチャする画面を開いてください。開くとすぐにキャプチャします")

take_screenshot()  # messageboxを表示する    

```
## 今後の課題（雑感多め）
【全体】
chatGPTへの指示によりほぼ作成したため、コードがどこまで正しいかの判断をつけるのが困難。（コード理解はあるが、その関数を用いる理由まで深掘りすると・・
可続性、メンテ性を考慮した場合、コメントでの理解（これはchatGPTがベース作成→人が補完）が必須。

当方のようなpython実務経験が浅い人間でも
chatGPTを用いるととりあえずは完成できる。（人は指示する能力、修正させる能力を上げた方がよい）
これは企業規模が小さい場所の方が優位性がある。（自由度が高い、ミスしても影響範囲が小さく、ケアしやすく人の経験値も上がりやすい。）
＊リスクもあるため、そこは天秤　

【細かい箇所】
chatGPTを用いたため、これからは出力を増やすことに注力。（時間をかけていくより、OUTPUT量を増やす）

## 次の展開
目的に沿って、次の業務改善に繋がるプログラムを作成する
OUTPUT継続

## 最後に
今回もお付き合いありがとうございました。
画面フローのデータテーブル検索


+ [検索結果のデータテーブルの値は、リードと取引先責任者を一緒に表示できますでしょうか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Otbs8)

リードと取引先責任者ではないですが、３つのオブジェクトをデータテーブルに表示したいとの質問です。

+ 各々のオブジェクトに参照関係があれば、元になるオブジェクトの数式フィールドを作れば表示はできる...
+ LWCでコンポーネントを作れば可能（私もそう思いました）

との回答ですね。

[Flow datatable to show data points from different objects/fields](https://salesforce.stackexchange.com/questions/395130/flow-datatable-to-show-data-points-from-different-objects-fields)

 

以下のヘルプをみてもソースコレクションの定義をみても複数オブジェクトを設定できるようには思えないですね。

データテーブルソースの設定
ソースコレクション： テーブルに入力するために使用するレコードのコレクション。

[フロー画面入力コンポーネント: データテーブル (ベータ)](
https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements_screencmp_data_table.htm&type=5)

# 必須の属性設定

+ [フローのDatatableについて](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007JlBfJ)

:::note
ヘルプを見る限りは必須の属性設定はないようです。

フローの中でチェックしてエラーを別途表示するしかないと思います。

フロー画面入力コンポーネント: データテーブル
https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements_screencmp_data_table.htm&type=5

インライン編集もこのコンポーネントでは直接レコードを更新するのではなくコレクションを返すだけみたいですね。別途フロー側でコレクションを使って更新するようです。ということで、入力の関係でのオプションはなさそうです。

The Datatable component itself does not update your records.  It passes back a collection of edited records that you can use in an Update Records element to write the changes back to your datatabase.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000CipCKSAZ

UNOFFICIAL SFを見ても必須の設定はなさそうです。

Enhance your Flows with Data Tables – Part 4 (Inline Editing)
https://unofficialsf.com/enhance-your-flows-with-data-tables-part-4-inline-editing/
:::
Googleデータアナリティクス：データの信頼性を評価する（誤差の範囲）

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b583930d-fecb-13ad-85a2-3f44e309d8a5.png" width="800">

# データの信頼性を評価する

データアナリストとして、 テストや調査を行う前に、 
- サンプル サイズ
- 信頼度
- 誤差の範囲

などの 変数を把握することは重要なことです。 

これは、結果が客観的であることを確認する ベストな方法であり、統計的に有意な結果を 得られる可能性が高くなります。 しかし、分析すべき調査結果がすでに 手元にある場合など サンプル サイズが分かっている場合は 自分で誤差の範囲を計算できます。 そうすれば、サンプルと母集団の間に どれくらいの差があるのか よりよくわかるようになります。 

***<font color="MediumVioletRed">『誤差の範囲とは、サンプルの結果が 実際の母集団の結果と 異なることが許容される最大値』</font>***

母集団全体を調査したり テストしたりするのは素晴らしいですが、 通常は不可能、または非現実的です。 そこで代わりに、大きな母集団から サンプルを取ります。サンプルに基づいた誤差の範囲は 母集団全体を調査した場合と比較して 結果がどの程度異なるかを示します。

誤差の範囲は、仮説検証で得られた データがどの程度信頼できるかを 理解するのに役立ちます。 誤差の範囲がゼロに近ければ近いほど サンプルから得られる結果は 母集団全体から得られるものと一致します。

例えば、 全国からサンプルを集め 調査を行うとしましょう。 週 5 日勤務の人に、週 4 日勤務の導入を 希望するか尋ねるとします。 すると、60% の人が週 4 日勤務を 希望しているとわかりました。 誤差の範囲は 10% で、 50% から 70% の人がこの案に 賛成だということになります。 ということは、もし全国の 週休 2 日制の労働者にアンケートをとれば 50〜70% の人がこの結果に 賛成するということです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b2f8636b-f798-ebfd-e0a1-3ad3273068bc.png" width="600">

この 50〜70% という幅に着目してください。 調査結果の 60% から誤差の範囲分が 増減してカウントされるためです。 信頼度を 95% を設定していた場合 95% の確率で、母集団全体の回答のうち 50～70% が、週 4 日勤務に賛成する、 ということを指します。50% という数字と誤差の範囲が重なるので 「国民は週 4 日勤務を望んでいる」と 断言することはできません。 この場合、この調査は結論が 出なかったと言わざるを得ません。

もし、より少ない誤差の範囲、 例えば 5% にしたいとき、つまり 55% から 65% までにおさめたければ サンプル数を増やせばよいでしょう。 サンプル サイズがすでに確定している場合は 自分で誤差の範囲を計算できます。

そして、その誤差の範囲に基づいて 結果が統計的に有意である可能性が どの程度あるか、自分で判断できます。 一般的に、アンケートに参加する人数が 多ければ多いほど、サンプルが 母集団全体を反映している可能性が上がります。

信頼度を下げることも 同じ効果をもたらしますが それは皆さんの調査が正確である可能性を 低くすることにもなります。つまり、誤差の範囲を計算するには 

- 母集団のサイズ
- サンプル サイズ
- 信頼度

の 3 つが必要なのです。

サンプル サイズの時と同様、 「誤差の範囲　計算」で検索すると、 たくさんの計算ツールがオンラインにはあります。
- [誤差の範囲計算ツール][tool]

[tool]: https://docs.google.com/spreadsheets/d/1g4izDdYFFQI4_hb5G1gcWKo8z7Q1LNkN6zmZXy2uPyI/edit#gid=77526548

たとえば、新薬の有効性に関する 研究を行っているとします。 世界人口の 1% が罹患している 疾患を持つ 500 人の被験者を サンプルとします。 約 8,000 万人の母集団が 研究対象です。薬の研究ですから、信頼度は 99% である必要があります。 また、誤差の範囲も 小さくする必要があります。 早速、計算してみましょう。 

スプレッドシートの該当セルに 母集団、信頼度、そして サンプルサイズの数字を入れます。 その結果、誤差の範囲は ±約 6% になります。 治験が完了したら、その結果に 誤差の範囲を当てはめて 結果がどの程度信頼できるかを 判断します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/4a2d2cc3-2ff8-bed9-64c7-48d55fdb8070.png" width="600">

:::note info
データ完全性を確認し、 データと目的を一致させることで 良い状態で分析を完了できることも 覚えておくとよいでしょう。
:::

# 誤差の範囲を計算するツール

https://goodcalculators.com/margin-of-error-calculator/

https://www.checkmarket.com/sample-size-calculator/#sample-size-margin-of-error-calculator
RubyでAtCoder ABC281(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC281のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Count Down
https://atcoder.jp/contests/abc281/tasks/abc281_a
```ruby:a-281.rb
n = gets.to_i
array = *(0..n)
puts array.reverse
```
## 解説
reverseメソッドを使って配列を逆転させることができます。

# B - Sandwich Number
https://atcoder.jp/contests/abc281/tasks/abc281_b
```ruby:b-281.rb
s = gets.chomp
n = s[1..-2].to_i
if s.size != 8
  puts "No"
else
  array = *"A".."Z"
  if !array.include?(s[0]) || !array.include?(s[-1])
    puts "No"
    exit
  end
  
  if 100_000 <= n && n <= 999_999
    puts "Yes"
  else
    puts "No"
  end
end
```
<追記>
コメントでいただいた別解になります。
```ruby:別解
s = gets.chomp

a, b, c = s.partition(/\d+/)
judge = ->(chr) { chr&.length == 1 && /[A-Z]/.match(chr) }
f = b.length == 6 && b.to_i.between?(100_000, 999_999)
puts judge.(a) && f && judge.(c) ? "Yes" : "No"
```
## 解説
問題文の条件を満たしているかを順に調べていき、１つでも満たさなければNo、すべて満たせばYesを出力します。

# C - Circular Playlist
https://atcoder.jp/contests/abc281/tasks/abc281_c
```ruby:c-281.rb
n, t = gets.split.map(&:to_i)
a = gets.split.map(&:to_i)
sum = a.sum
t %= sum
i = 0
while t > 0
  if t <= a[i]
    puts "#{i + 1} #{t}"
    exit
  end
  t -= a[i]
  i += 1
end
```
## 解説
N<=10^5と大きいので、modを利用して操作回数を減らしています。そして、余りをもとにどの曲で終わるかを調べています。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
base64コマンド: decodeした時にエラーが出る原因と対処方法（パディングが必要）

以下はLinux(CentOS7)での実行結果。

# base64デコード時のエラー

`base64: invalid input`というエラーが出る。

```txt:エラーが出力される例
$ str=eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

$ echo -n ${str} | base64 -d
{"sub":"1234567890","name":"John Doe","iat":1516239022}base64: invalid input
```

# 対処方法

原因は、パディング(`=`で適切な長さに埋める作業)が実施されていないから。対処方法の一例は[ここ](https://unix.stackexchange.com/questions/631501/base64-d-decodes-but-says-invalid-input)に書いてあったが、パディングしてからdecodeすること。

```txt:成功例
$ str=eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

$ echo -n ${str}==== | fold -w 4 | sed '$ d' | tr -d '\n' | base64 -d
{"sub":"1234567890","name":"John Doe","iat":1516239022}
```


# 補足

なお、厳密にはechoコマンドはデフォルトで行末に改行コードが入るので、利用する際には`-n`オプションを使うか、printfコマンドを利用した方が良い。
行末に改行コードが入る時と、入らない時とではbase64エンコードの結果も異なる。

```txt:echoコマンド。行末に改行コードが入る。
$ echo '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | od -c
0000000   {   "   s   u   b   "   :   "   1   2   3   4   5   6   7   8
0000020   9   0   "   ,   "   n   a   m   e   "   :   "   J   o   h   n
0000040       D   o   e   "   ,   "   i   a   t   "   :   1   5   1   6
0000060   2   3   9   0   2   2   }  \n
0000070

$ echo '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | base64
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQo=
```
```txt:echoコマンドに-nオプションを付けた場合。行末に改行コードが入らない。
$ echo -n '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | od -c
0000000   {   "   s   u   b   "   :   "   1   2   3   4   5   6   7   8
0000020   9   0   "   ,   "   n   a   m   e   "   :   "   J   o   h   n
0000040       D   o   e   "   ,   "   i   a   t   "   :   1   5   1   6
0000060   2   3   9   0   2   2   }
0000067

$ echo -n '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | base64
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ==
```
```txt:printfコマンド。行末に改行コードが入らない。
$ printf '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | od -c
0000000   {   "   s   u   b   "   :   "   1   2   3   4   5   6   7   8
0000020   9   0   "   ,   "   n   a   m   e   "   :   "   J   o   h   n
0000040       D   o   e   "   ,   "   i   a   t   "   :   1   5   1   6
0000060   2   3   9   0   2   2   }
0000067

$ printf '{"sub":"1234567890","name":"John Doe","iat":1516239022}' | base64
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ==
```
「ユーザーとしてエクスペリエンスにログイン」経由でサイトにアクセスできない


+ [Unable to access to a site via "Log in to Experience as user" because I am being forced to log in to it](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jgyme)

I am not an expert in Digital Experience, so I am keen to learn through this community.

After following steps:

+ I created a Person Account record and enabled it as Customer User
+ A contact was created automatically (Person Account behaviour)
+ I enabled that contact as Customer User. This allowed me to create a user with the same name with the Customer Community Login License and Customer Portal User profile
+ When I go to the contact record and click on "Log in to Experience as user" I am being led to log in with username and password. If I write the username and password of that user, it still is forcing me to log in

+ 個人取引先レコードを作成し、顧客ユーザーとして有効にしました
+ 取引先責任者が自動的に作成された (個人取引先の動作)
+ その連絡先をカスタマー ユーザーとして有効にしました。これにより、カスタマー コミュニティ ログイン ライセンスとカスタマー ポータル ユーザー プロファイルを使用して、同じ名前のユーザーを作成できました。
+ 連絡先レコードに移動し、[ユーザーとしてエクスペリエンスにログイン] をクリックすると、ユーザー名とパスワードでログインするように誘導されます。そのユーザーのユーザー名とパスワードを書いても、ログインを強制されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/928a3b98-6c8e-3d3a-c1fc-3f2d4ea5c244.png)

:::note
that will be the key. Did you add the Registration Visualforce Pages and attempt to register again?

それが鍵になります。登録 Visualforce ページを追加して、再度登録を試みましたか?
:::

# パスワードを忘れた場合のリンクをすぐに期限切れにしない= TRUE に設定 しましたが、パスワードをリセットしようとしているユーザーは引き続きループに巻き込まれます。

+ [ExperienceCloudサイトユーザーのパスワードリセットがループでスタックしている](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000G4C2g)

:::note
This was a Salesforce issue, they confirmed that communities using a Salesforce content delivery network partner (CDN) are impacted in APAC and EMEA regions. SF observed a recent change as the likely cause of the issue and they rolled back the changes https://status.salesforce.com/incidents/8830

これは Salesforce の問題であり、Salesforce コンテンツ配信ネットワーク パートナー (CDN) を使用するコミュニティが APAC および EMEA 地域で影響を受けることを確認しました。SF は、問題の原因として考えられる最近の変更を確認し、変更をロールバックしましたhttps://status.salesforce.com/incidents/8830
:::
セキュリティ基本：ファイアウォールの動きについて

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回は具体的なファイアウォールの動きについて更に詳しく調べてみましょう！
![インスタスライド_2023032301.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/68217a67-d6d3-b764-9cb3-cbd0f17bb447.gif)

# ファイアウォール
ファイアウォールは、ネットワークの通信において、その通信をさせるかどうかを判断し許可するまたは拒否する仕組みで、不正アクセスを防ぐ仕組みです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/9feb5878-e0b5-bcf4-0fc1-8b1a5a153c86.png)

# パケット通過の制御
- ファイア･ウォールの基本的な仕組み
- ルールに基づいたパケット通過の可否
- パケットの取捨選択を決めるルール
- パケット･フィルタリング
- アプリケーション･ゲートウェイ
- ステートフル･インスペクション

# ルールの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/43f8ad7f-0dc3-5cfd-4272-097d53082ebc.png)

# パケット通過の制御
- パケット・フィルタリング
    - 処理が早い
    - ルーターに兼用させることができる
    - 上位のアプリケーションに依存しない

- アプリケーション・ゲートウェイ
    - 高度なアクセス制御が可能
    - パフォーマンスが悪い

- ステートフル・インスペクション
    - パケット･フィルタリングとアプリケーション･ゲートウェイのメリットを組み合わせた強力な機能
    - アプリケーション･データそのものをチェックできない

# まとめ
- ファイアウォールは不正アクセスを防ぐ仕組み
- パケットフィルタリング、アプリケーションゲートウェイ、ステートフルインスペクション
等がある

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Rubyは全てがオブジェクト「②Rubyを構成している3種類のオブジェクト」

## はじめに

今回は「Rubyを構成している３種類のオブジェクト」というタイトルで書いていきます。
学習している中で、rubyを構成しているのは大きく以下の3つだと感じました、
・クラス
・インスタンス
・モジュール
今まではクラスとインスタンスしか知らなかったのですが、モジュールについて勉強した際に
「クラスの中にモジュールをミックスインして、インスタンスを作成する」流れを見てそう思いました。

この記事では「上記3つ」と「オブジェクト」について
自分なりに感じたことを書いていきたいと思います！:bow_tone1:
（上記3つについて細かく説明しているわけではないです）

## 「Ruby3.2リファレンスマニュアルのオブジェクトとは」より抜粋
オブジェクトは、特定のクラスに対比して、その「インスタンス」とも呼ばれます。

## 「IT用語辞典バイナリのオブジェクトとは」より抜粋
オブジェクトは、いわゆる「物体」や「対象」といった意味であるが、現実の世界に存在する事象や概念を指す場合もあるし、そうした事象や概念をモデルとして再現したものや、さらには現実世界には存在せずにモデル上のみに存在する何物かを指すこともある。

## クラスとインスタンスとオブジェクト
オブジェクトという表現が抽象的で、色々な捉え方ができるのが難しい理由なのかなと思います:sweat:
rubyではオブジェクトとインスタンスは同じようですね。

クラスとインスタンスは、スクールやサイトでよく見る表現で
・クラス：設計図　(例、たい焼き機)
・インスタンス：設計図からできた実体 (例、たい焼き)
のような例えを見てなんとなくわかった気になっていました。

しかしふと、オブジェクトとインスタンスが同じなら
「Rubyは全てがオブジェクトということは、全てがインスタンスということ？？？」
「そもそも同じ意味ならわざわざ2つの言葉が存在する意味はなぜ？？？」
という疑問が湧き、頭の中が混乱しました。

ネット検索している中で
「クラス・インスタンス・オブジェクトの違いは神の気分になるとわかる」(最後にURLを掲載してます)
という記事を見た際に、少しわかりました。

内容としては
・オブジェクトはすべての物や事柄などを指している
・クラスはオブジェクトの設計図のようなもの
・インスタンスはクラスを元に作ったオブジェクトのこと
・「インスタンスはオブジェクトである」と言えるが、「オブジェクトはインスタンス」と言えない
といったものです。
もはや少し哲学的な内容にはなりますが、オブジェクトとインスタンスは厳密にいうと言葉としては違うのだなという感じです。

ここまででなんとなく、オブジェクトとクラスとインスタンスの違いはわかりました。
しかし、「rubyは全てがオブジェクトならクラスやモジュールもオブジェクトじゃないとおかしいな」と感じました。
結論から言うと、クラスとモジュールもオブジェクト（インスタンス）です。
これについては次回「③クラスについて理解の深掘り」で書いてみたいと思います。


## まとめ
・オブジェクトとインスタンスはほとんど同じ意味だが、インスタンスはクラスを元に作ったもので、オブジェクトはより概念的なものという違いがある。
・Rubyにおいてはインスタンスとオブジェクトは同じ意味で使っても問題ない。
・クラスとモジュールもオブジェクト（インスタンス）


## 参考にしたサイト
・Ruby 3.2 リファレンスマニュアル>オブジェクト

https://docs.ruby-lang.org/ja/latest/doc/spec=2fobject.html

・IT用語辞典バイナリ>オブジェクトとは

https://www.sophia-it.com/content/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88#:~:text=%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AF%E3%80%81%E3%81%84%E3%82%8F%E3%82%86%E3%82%8B%E3%80%8C%E7%89%A9%E4%BD%93%E3%80%8D,%E3%82%92%E6%8C%87%E3%81%99%E3%81%93%E3%81%A8%E3%82%82%E3%81%82%E3%82%8B%E3%80%82

・クラス・インスタンス・オブジェクトの違いは神の気分になるとわかる

https://kensawai.com/blog/class-instance-object.html
[Python] matplotlibを使おうとしたらImportError: DLL load failed while importing _cextが出てハマった

## 概要

matplotlibをimportしたファイルを実行したところ，ImportError: DLL load failed while importing _cextが出てしまいました．
msvc-runtimeをインストールすることで解決しました．

## 環境
OS : Windows10
エディタ : VS Code
Python : 3.11.3
matplotlib : 3.7.1

## 起こったこと

VS Codeで，matplotlibを用いたプログラムを作成するため，同ライブラリをインストールしました．
```
pip install matplotlib
～中略～
Successfully installed matplotlib-3.7.1
```

次のようにimportし，プログラムを作成・実行したところ，
```.py
import matplotlib.pyplot as plt
```

下記のエラーが発生して止まってしまいました．
```
～上略～
File "C:\Users\Username\AppData\Local\Programs\Python\Python311\Lib\site-packages\kiwisolver\__init__.py", line 8, in <module>
    from ._cext import (
ImportError: DLL load failed while importing _cext: 指定されたモジュールが見つかりません。
```

## 解決策
結論，msvc-runtimeのインストールで解決しました．
```
pip install msvc-runtime
～中略～
Successfully installed msvc-runtime-14.34.31931
```

実のところ自分で読み解いたわけではなく，stack overflowにそのままの答えがありました…
https://stackoverflow.com/questions/75824703/matplotlib-importerror-dll-load-failed-while-importing-cext

検索しても意外と引っかからなかったのと，環境構築自体が久しぶりなのもありだいぶハマったので，困っている人の検索に引っかかればいいなと思い投稿することにしました．
たまたまハマった少数派なのかもしれないし，そもそも自分の検索能力が低かっただけという話ではあります…
create-turboで新規プロジェクトを作成する場合に、npmが選択できない場合の対処法

Turborepoを使ってモノリポのプロジェクトを作成使用した。
すると、使用したいパッケージマネージャーを選択する時に、`npm`が`not installed`と表示され、選択することができない問題が発生した。

```bash
% npx create-turbo@latest

>>> TURBOREPO

>>> Welcome to Turborepo! Let's get you set up with a new codebase.

? Where would you like to create your turborepo? ./new-turborepo
? Which package manager do you want to use? 
  - npm (not installed)
  pnpm 
❯ yarn  
```

`turbo`のリポジトリで同じような問題が発生していることが書かれたIssueを見つけた。

https://github.com/vercel/turbo/issues/4556

2023年4月14日現在において最新バージョンである`1.9.1`で発生しているようだ。

そこで、`@latest`から、`@1.8.8`に変更してコマンドを実行した。
すると、今度は`npm`が選択できるようになっていた。

```bash
% npx create-turbo@1.8.8

>>> TURBOREPO

>>> Welcome to Turborepo! Let's get you set up with a new codebase.

? Where would you like to create your turborepo? ./new-turborepo
? Which package manager do you want to use? (Use arrow keys)
❯ npm 
  - pnpm (not installed)
  yarn 

```

同じような問題に遭遇している方がいる場合、最新版ではなく`1.8.8`の`create-turbo`を使用することをお勧めする。
M5Stack(Core2)のボタンを添え字アクセスしたい

M5Stack Core2のボタンアクセスは`M5.BtnA`のように行われます。しかしボタンは3つ付いているので、`M5.getBtn[0]`のように添え字アクセスがしたくなることもあるはずです。
ちょっとしたものですが、その処理を関数化したので共有しておこうと思います。

## ソースコード

```C++
#ifdef _M5STACK_H_
Button& M5getBtn(M5Stack &M5, uint8_t id) {
  static Button M5Stack::*const btn[] = {&M5Stack::BtnA, &M5Stack::BtnB, &M5Stack::BtnC};
  return (M5.*btn[id]);
}
#endif
#ifdef _M5Core2_H_
Button& M5getBtn(M5Core2 &M5, uint8_t id) {
  static Button M5Core2::*const btn[] = {&M5Core2::BtnA, &M5Core2::BtnB, &M5Core2::BtnC};
  return (M5.*btn[id]);
}
#endif
Button& M5getBtn(uint8_t id) {
  static Button*const btn[] = {&M5.BtnA, &M5.BtnB, &M5.BtnC};
  return *btn[id];
}
```

参考文献：[C++マニアック： クラスメンバへのポインタ](http://stlalv.la.coocan.jp/Pointer.html#POINTER_TO_CLASS_MEMBER)
2引数版は、M5Core2インスタンス(若しくはM5Stackインスタンス)がヘッダファイルに定義された`M5`以外のものを使う場合に効果的（かもしれません）。
通常はM5getBtn(0)のように指定して扱えばいいでしょう。

## おわりに
C++に統一関数呼び出し記法採用されないかな。
BigQueryでカラム名に日本語が使えるようになってますやん！あれ、LookerStudioさん…！

# BigQueryでカラム名に日本語が使えるようになっていたよ

こんにちは、見習いデータエンジニアのつざきです。
変なタイトルですみません。

たまたま気がついたんですが、
2023年3月22日に行われたリリースによってカラム名でUnicode文字が使えるようになっていました。

（今更かよ！ 知ってたよ！ って方はそっと閉じて）

![スクリーンショット 2023-04-14 1.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/865ad8e2-fda9-d610-9aee-78bf7f3b07d1.png)

https://cloud.google.com/bigquery/docs/release-notes#March_22_2023 より



まだプレビュー版なので正式な機能ではなく、本番環境で使うのはよした方がよさそうです。
とはいえ、問題なければ数ヶ月のうちに正式にサポートされるようになるでしょう（たぶん）

社内ユーザーが使うデータマートテーブルなんかは日本語のカラム名の方が使いやすいと思うので正式リリースが楽しみですね。

# 試してみたよ

```sql
CREATE TABLE temp_developer.`テストテーブル`
(
  x INT64,
  `日本語カラム` STRING 
)
```
![スクリーンショット 2023-04-14 1.17.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/0d671604-98d0-6818-d838-7f451910d9d1.png)

特に設定せずとも普通に日本語カラムのテーブル作れますね〜〜

# え、テーブル名も日本語いけるやん！

カラム名が行けるってことはテーブル名もいけるのか？ と思って試してみましたが日本語使えました。

テーブル名の方は 2020年のリリースで使えるようになっていたみたいですね。知らなかった。

![スクリーンショット 2023-04-14 1.32.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/b904fbb1-e9a7-55a1-6747-b932717d2483.png)


https://cloud.google.com/bigquery/docs/release-notes#October_14_2020 より

# Looker Studioで日本語カラム名のテーブル使えるの？

Google謹製のBIツールLooker Studioさんなら当然使えますよね ？？

![スクリーンショット 2023-04-14 1.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/b18e4b53-4fa6-3c06-a076-8679a03403cc.png)

えっ！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/415702d3-54a4-8770-02aa-dfffb2a6d12f.png)

# まとめ

BigQueryではカラム名とテーブル名が使えるようになっていました。
Looker Studioではまだ使えません。 
多分、他のBIツールも望みは薄いでしょう。
トラブルを避けるため日本語カラム名は（しばらく）使わない方がよさそうです。ぴえん。

BigQueryなどのデータ基盤技術は日進月歩で進化していくので主要なツールのリリースノートはウォッチしておいた方がいいですね。

以上、参考になりましたら幸いです。
【Kotlin】コレクション(List, Set, Map)の特徴

Kotlinで頻繁に使用されるコレクション（`List`, `Set`, `Map`）の特徴について、ラムダ式を用いて勉強する

## List

:::note info
要素の順序があり、重複した要素を持つことができるコレクション
:::

Listの要素をラムダ式で処理する場合、`forEach()`メソッドを使用することができる

```kotlin
fun main() {
    val list = listOf("apple", "orange", "apple")
    list.forEach { println(it) }
}
```

Listの各要素を順番に取得し、それぞれの要素を引数としてラムダ式を実行している

```:出力結果
apple
orange
apple
```

## Set

:::note info
要素の順序がなく、重複した要素を持たないコレクション
:::

Setの要素をラムダ式で処理する場合、`forEach()`メソッドを使用することができる

```kotlin
fun main() {
    val list = setOf("apple", "orange", "apple")
    list.forEach { println(it) }
}
```

Setの各要素を順番に取得し、それぞれの要素を引数としてラムダ式を実行している

```:出力結果
apple
orange
```

## Map

:::note info
`キー`と`値`のペアを持つコレクション
キーは重複を許さず、値は重複を許す
:::

Mapの要素をラムダ式で処理する場合、`forEach()`メソッドを使用することができる

```kotlin
fun main() {
    val map = mapOf("apple" to 100, "orange" to 200, "banana" to 100)
    map.forEach { (key, value) -> println("$key: $value") }
}
```

Mapの各要素を順番に取得し、それぞれの要素を引数としてラムダ式を実行している
（ラムダ式の引数には、`キー`と`値`のペアを表すPairオブジェクトが渡される）

```:出力結果
apple: 100
orange: 200
banana: 100
```


### キーの重複に注意

:::note warn
キーが重複した場合の挙動に注意が必要
:::

```kotlin
fun main() {
    val map = mapOf("apple" to 100, "orange" to 200, "apple" to 300)
    map.forEach { (key, value) -> println("$key: $value") }
}
```

`mapOf()`関数で作成されたマップには、キーとして`apple`が2回登録されているが、マップはキーの重複を許さない

そのため、2回目の`apple`の登録は無視され、<font color="Red">値のみが上書きされる</font>

```:出力結果
apple: 300
orange: 200
```
Streamlit Plotlyサンプル

# 概要
お手軽にデスクトップアプリ代わりを作るのにStreamlitでplotlyグラフを描画するサンプル。
試作機評価ソフトのたたき台にどうぞ。

# やりたいこと
センサから値を取得しながらグラフを描画させたい。下記Gif参照。
今回は、センサにアクセスする代わりに乱数を取得して描画。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/9d194e7f-0355-5a4b-1c7e-8c2b0714b645.gif)

# サンプルコード
[Streamlit公式ページ](https://streamlit.io/)のドキュメントだけではピンとこなかったので測定しながら描画するためのロジックだけ作成。測定結果の保存処理、レスポンス改善のための非同期処理導入などは後日検討。


``` python
import streamlit as st
import plotly.graph_objects as go
import numpy as np
import time

# 測定値取得ダミー関数
def GetSensorValue():
    return np.random.randn()

# ページレイアウト
st.set_page_config(
    layout="wide",
    page_title='測定リアルタイムグラフ',
    page_icon='☔'
)
st.sidebar.title('Setting menu')
start_btn = st.sidebar.button('Start', key=0)

st.title("Realtime streamlit plotly sample")
fig = go.Figure()
fig_chart = st.plotly_chart(fig, use_container_width=True)

# グラフ初期化
def GraphInit():
    fig = go.Figure()
    fig.update_layout(title='sample graph title')
    fig_chart.plotly_chart(fig)

GraphInit()

# グラフ更新
def RealTimeProcess():
    measure_count = 100
    x_data = np.empty(0)
    y_data = np.empty(0)
    fig = go.Figure()
    fig.add_hline(y=2, line=dict(dash='dash', color='red'))
    fig.add_hline(y=-2, line=dict(dash='dash', color='red'))
    fig.add_trace(go.Scatter(x=x_data, y=y_data))
    trace_data = fig.data[-1]
    for i in range(1, measure_count):
        x_data = np.append(x_data, i)
        y_data = np.append(y_data, GetSensorValue())

        trace_data.x = x_data
        trace_data.y = y_data
        fig_chart.plotly_chart(fig)
        fig.update_layout(title=f'measure count:{i}/{measure_count}')
        time.sleep(0.25)

if start_btn:
    RealTimeProcess()


```

# 今後の改善ネタ
1. 非同期処理導入（描画処理と測定値取得処理を分離して非同期化）
1. 指定長より古いデータを間引く処理追加（長時間連続測定対策）
1. 測定終了後にDownloadボタンで測定結果のファイル保存
1. 上加減リミットを手打ちできるようにするtextinput追加
1. 測定周期を設定するtextinput追加
1. 測定回数を設定するtextinput追加
1. x軸をindexではなくタイムスタンプに（datetime型をplotlyでうまく扱えなかった）
WordPressテーマ制作においてクライアントへの質問リスト

# WordPressブログを始める前に確認すべき8つの重要なこと
新規のクライアントとの取り組みにおいては、テクノロジの選択に入る前に、まずテクノロジに関する詳細なリサーチが必要となります。クライアントの目的や、ウェブサイトが必要な理由、サイトの目的を確認することが重要です。ただし、ブログが必要であることが明確になり、WordPressでの運営が決まった場合は、以下のリストから確認すべき事項を尋ねることが重要です。（順不同）

#### 1. 複数の著者がいる場合、サイトに著者情報を明確に表示する必要がありますか？🤔
コンテンツの作成者を明確に示すブログもあれば、匿名性を重視するブログもあります。WordPressには、登録ユーザーごとに経歴情報を追加できる小さなセクションがあります。また、ユーザーごとに写真を追加するためのプラグインもあります。

#### 2. 長い特集記事や短いクイック記事など、複数のスタイルのブログ記事がありますか？📝
ほとんどのブログでは、すべての投稿が同様に扱われますが、必ずしもそうである必要はありません。異なるスタイルの投稿を作成することができます。ブログの所有者が公開しようとしているコンテンツの種類を把握することは重要です💡

#### 3. サイトには他にどのような種類のコンテンツがありますか？📋
サイドブログ、お問い合わせページ(例：[contactform7](https://contactform7.com/))、ブログロール、フォトギャラリーなど、多様な投稿タイプを扱うプラグインがあります。ただし、ブログであっても、サイトがブログに限定されるわけではないことに注意してください👀

#### 4．広告に対応する必要がある場合、どのようなタイプとサイズが必要ですか？
この点はとても重要です！デザインのプロセスをスムーズに進めるために、クライアントが**768×90**のバナーをどこかに配置することを知るだけでなく、**125×125**、**300×250**、**160×600**など、一般的な多くのサイズにも対応できる必要があります。これらのサイズを事前に知っておくことで、それに合わせたデザインを行い、設計に反映できます👀

#### 5．サイトにはカテゴリやタグを使用する予定がありますか？
多くのブログでは、投稿を**カテゴリ**に分類しています。これにより、アーカイブを閲覧しているユーザーや、特定のトピックにのみ関心があるユーザーに役立ちます。クライアントの希望によっては、タグもカテゴリと同様に使用することができます。**タグ**はカテゴリに似ていますが、各投稿に複数のタグを適用することで、サブトピックを識別するために使用されます🔖

#### 6．アーカイブページの処理方法についてはどうしますか？
WordPressでは、カテゴリやタグのページに加えて、日付や作成者別のアーカイブページを提供する機能があります。また、より高度なアーカイブページを作成するためのプラグインもあります(例：[Advanced Custom Fields](https://ja.wordpress.org/plugins/advanced-custom-fields/))。訪問者に提供するオプションの数を考慮し、最適な方法を選択することが重要です。

#### 7．検索をどのように処理しますか？
WordPressには、標準的に検索機能が備わっていますが、一般的には機能が限定的なため、多くのブログでは[Google Site Search](https://developers.google.com/custom-search/)を利用しています。これにより、検索結果の表示が優れていることがあります。さらに、サードパーティの検索ソリューションも存在します。検索結果ページは非常に重要なページなので、適切に設計することが重要です。

#### 8．投稿でソースコードを紹介する予定はありますか？
JavaScriptライブラリやWordPressプラグインなどのソースコードを投稿内で紹介する場合は、それらを適切に表示する方法が必要です。これらの方法には異なる要件があるため、適切な処理方法を事前に選択することが重要です。例：[SyntaxHighlighter Evolved](https://wordpress.org/plugins/syntaxhighlighter/)

## まとめ📌
WordPressブログを運営する前に確認すべきことについて、これら8つの要素が重要であることが分かりました。これらの要素を考慮に入れて、計画を立ててからブログを運営することをお勧めします。

* 参考にすべきサイト：
  * WordPress 公式ドキュメント：[投稿タイプ](https://wordpress.org/support/article/post-types/)
  * WordPress 公式ドキュメント: [カテゴリ](https://wordpress.org/support/article/posts-categories/)
  * WordPress 公式ドキュメント: [タグ](https://wordpress.org/support/article/posts-tags/)
  * Google AdSense ヘルプセンターの「Google広告の一般的なサイズ」：https://support.google.com/adsense/answer/6002621?hl=ja
  * AdWords 広告のディスプレイ広告のサイズとフォーマット：https://support.google.com/google-ads/answer/1209686?hl=ja
  * 一般的なディスプレイ広告のサイズと比較：https://www.displayadsbenchmark.com/ja/creative-sizes-comparison/
  * IAB Display Advertising Guidelines：https://www.iab.com/guidelines/display-guidelines/
* 検索系プラグイン🔧：
  * 検索機能強化: https://ja.wordpress.org/plugins/search-filter/
  * 画像検索: https://ja.wordpress.org/plugins/enhanced-media-library/
  * ユーザーごとに写真を追加する: https://wordpress.org/plugins/user-photo/
***
chatGPT APIをgolangから使ってみるサンプル

成果物はこちら
https://github.com/ymstshinichiro/my-chatgpt-tool


chatGPTで遊んでいて、毎回似たような文言をプロンプトに入れるのがだるかったので、APIの勉強がてら実装してみたものです。動かすとこんな画面が出ます。

![スクリーンショット 2023-04-14 0.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254731/fe3942eb-151d-5f67-1d26-0516322742ea.png)

一応動くんですが結構すぐMaxTokenに引っかかってしまって、その辺の考慮とかは特にしてません。あくまでAPIを使って何か作ってみたい人向けの参考という位置付けです。

以下やってみての感想。

#### 作る過程
- Golang自体書くのが数年振り (Productionで書いた経験はない)
- chatGPTに聞きながら書いてみたら割とできた
- 自分が指示を出す係でペアプロしていく感じ
- 意図と若干異なるコードを出力したりするので、全くの言語未経験からこれをやるのはちょっと難しいかもしれないなと思った
- なんだかんだやっぱ手を動かして作るのは大事。今までのRESTなAPIとは根本的に異なるものなので、使いこなしとかを考える上でとりあえず触っておくべきやなと思った

#### chatGPT APIについて
- chatGPTに聞いて返ってくるコードだと古いAPIの使い方なのでうまく動かなかったりしたのが若干ハマりだった
    - 単純にエンドポイント違ってたり、modelの指定とかがおかしかったり
    - messagesの扱いとかを考慮しない感じで実装したコードになってる
- リファレンス見るなり、最新のAPIで実装してる人のコードを参考にした方が早そう
- 使えるモデルが GPT3.5系だとやっぱまだ厳しいなーという。普段はGPT4と話しているのでどうしても差を感じる。waitlist早く通ってほしい


-------

こんなとこかなと。
GPTはプロンプトをどう入れて得られたものをどう使っていくかに無限の可能性があって、使いこなしてる人を見るとすごいなと思います。

なんか思いついた時にパッとやれるように、今後も素振りしておきたいなと思いました。
久々のGo実装楽しかった。あと画面のコードも書いてくれるのがすごい楽だった。。。