OmniAICreator/Qiita-1.07M huggingface dataset:
Springの400 BadRequestの時のデフォルトのResponseをカスタマイズする

# 400 BadRequestの時の困りごと
[SpringBootでcommons-validatorのチェックを共通化してみよう](https://qiita.com/cozyk100/items/148c14239d1ab151e98e)でcommons-validatorのチェックを共通化しましたが、これで入力チェックで異常値だとResponseに
```json
{
  "errors": {
    "mess": [
      "〇〇は〇〇です", "△△は△△です"
    ]
  }
}
```
が返るようになってめでたし、めでたしでしたが、ひとつ問題が、

このcommons-validatorのチェックはSpringのcontrollerがリクエストを受け取って、型に変換できてから動き出します。そもそもリクエストがぶっ壊れていて、型に変換できない場合、commons-validatorのチェックは全く動きません。

その典型的な例がこれです
```kotlin
 @RequestParam("serialNo") serialNo: String
 ```
 kotlinにはnull許容型、null非許容型があります。上の例ではnull非許容型です。
 この状態でRequestのJSONでserialNoがnullだったら、もしくはserialNoのタグ自体が無い場合、Springのcontrollerはリクエストを型に変換できません。
 型に変換できないので、当然、commons-validatorも動きません。

 Responseには、
 ```json
 {
　"timestamp" : "20XX-XX-XX XX:XX:XX",
　"status" : 400,
　"error" : "Bad Request",
　"message" : ""
　"path" : "http://www.sun-m.co.jp/sample/xxx"
　}
 ```
 と言う・・・受け取ってもなんの意味もない、ありがたくないResponseが返ります。

 何よりも、commons-validatorが動いて入力値異常の時と、そのはるか手前でspringのcontrollerが弾いた時とResponseの形が違うのは、フロント側にとっても困りものです。（最低でも型は同じにしてほしい）

 で、前回のValidationExceptionHandleControllerにメソッドをもう1個追加します

 ```kotlin:ValidationExceptionHandleController
@RestControllerAdvice
class ValidationExceptionHandleController {

    companion object {
        const val ERROR_MESSAGE = "予期せぬエラーが発生しました。"
    }


   ・・・

    @ExceptionHandler(HttpMessageNotReadableException::class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handleHttpMessageNotReadableException(ex: HttpMessageNotReadableException): ResponseEntity<ValidationError> {
        return ResponseEntity(
            ValidationError(
                errors = ValidationErrors(mess = listOf(ERROR_MESSAGE))
            ),
            HttpStatus.BAD_REQUEST
        )
    }


}
 ```
これで型てきには同じResponseが返ります
 ```json
{
  "errors": {
    "mess": [
      "予期せぬエラーが発生しました。"
    ]
  }
}
```
【小ネタ】VSCodeでワークスペース外のファイルをエディターで開く方法

VSCodeがこんな状態とします。
ワークスペースとして、`/workspaces`を開いている状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/55779cea-7172-467f-a947-f405cfc33192.png)

 さて、この状態で、`~/.bashrc`のようにワークスペース以外のファイルを修正したいとき、あなたならどうしますか？

## 方法１）`vi ~/.bashrc`

これで作業できる人に憧れます。。私は弱小者なのでできません。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/26b49eeb-662f-4651-b838-29b0a82c1aa9.png)

## 方法２）`nano ~/.bashrc`

これはギリギリできます。`Ctrl + X` -> `Y` だけ覚えてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/fedf5b83-2cea-4572-98d5-318a378b3837.png)

---

でもですよ。でも、 **ターミナルの上にエディターあるじゃないっすか** ！！これ使ったらいいですやん

方法がわからなかったんですが、 **今日、とうとうわかりました** ！

## 方法３）`code ~/.bashrc`

`code ~/.bashrc`でVSCodeのエディター部分で開いてくれます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/ab5420b9-0213-4107-bed8-a27dbd6f1b34.png)

:::note
ちなみに、`code -w ~/.bashrc`のように`-w`を追加すると、エディター部分を閉じるまでターミナルが待機状態になります。
:::

これを使うとAmazon Q Developer CLIのエディターをVSCodeにできます！

<iframe width="560" height="440" src="https://www.youtube.com/embed/95S2ERPK24Y?si=gLu9uI25tcxiixGe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

という内容が、公式ドキュメントに書いてありましたw

https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-editor.html
MUIのDataPickerで日付をクリアしたい

# MUI DatePickerで日付をクリアできない
最近React/Nextjsでフロントエンドを書いています。アプリケーションの要求仕様上、どうしても表形式のグリッドが必要なのでMUI DataGridを使用しています。
その流れで他のコンポーネントもMUIを使用しています。

MUIのDatePickerを使っていて、ひとつ困ったことが・・・
**一度、DatePickerを使って選択した日付をクリアできない**
のです。
![スクリーンショット 2024-06-09 155452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/cdc64cfc-6171-8c53-13f3-4695ee036da6.png)
一旦、DatePickerを使って日付を選択すると、テキストボックスのところにフォーカスを持って行って、BSキーで削除しても削除できません

うーん・・・困った。日付の項目が入力必須ならいいけど、入力が任意（例えば検索条件）の場合、一旦、日付選択すると空欄にできない。

slotProps で actionBar を指定することにより、クリアのリンクをDatePickerに表示させることができます。

```typescript
import React from 'react';
import {  DatePicker,  LocalizationProvider,} from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import 'dayjs/locale/ja';
import dayjs, { Dayjs } from 'dayjs';


  <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale='ja'>
    <Box sx={{overflow: 'hidden !important'}}>
      <DatePicker
        sx={ dateText('20ch') }
        format="YYYY/MM/DD"
        disablePast = {disablePast}
        value={myDate}
        onChange={onChange}
        slotProps={{
          actionBar: { actions: ['clear', 'cancel', 'accept' ] }, // ★ココ
        }}
      />
    </Box>
  </LocalizationProvider>
```

![スクリーンショット 2024-06-09 155408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/4a483130-6f3e-e2ca-e996-5aae4e09a3d9.png)

「CANCEL」、「CLEAR」、「OK」のリンクが表示できるようになります。
Terraformでタグを一部のリソースのみ追加する方法

## 概要
variableで変数を指定してすでに全リソースにタグが付与している状態だけど
一部のリソースだけ他社に監視をお願いするためにタグを新規に追加しないといけないことがあった
調べたところmerge()を使ったやり方は二つある
個人的には明示的に入れずに変数にしてからmerge()に入れた方がいいかも

## 方法

- リソースブロックの中にタグを明示的に埋め込む

埋め込んだタグが変わらなければ以下を使う

```jsx
resource "aws_s3_bucket" "hoge_bucket" {
  bucket = "hoge-dev-s3-bucket"
  tags   = merge(
    var.previous_tag, 
    {
      new_tag    = "hoge"
    }
}
```

- variable.tfに入れてタグを追加する

埋め込んだタグが変わる可能性がある

また、複数のリソースでタグを入れる必要がある場合は以下を使う

variable.tf

```jsx
variable "new_tag" {
  type = map(any)
  default = {
    new_tag  = "hoge"
  }
}
```

s3.tf

```jsx
resource "aws_s3_bucket" "hoge_bucket" {
  bucket = "hoge-dev-s3-bucket"
  tags   = merge(var.previous_tag, var.new_tag)
}
```
【Render】不具合対応について

# 記事概要
Renderで不具合が発生した際の対応方法について、まとめる

# エラーログの確認
1. ログを確認するアプリを、選択する
1. メニューから「Monitor」の「Logs」を選択する
1. ログが表示される

# データベースをリセット
## ケース
下記条件に当てはまる場合に実施する

- カラムの追加などのテーブルの変更を行った
- ローカルでは、変更内容が正しく反映する
- Renderでデプロイを行った際に、エラーは出ないがテーブルに上記の変更が反映されない

## 注意点
登録済みのデータが、すべて削除される

## 手順(Rails)
1. `bin/render-build.sh`を変更する
    1. `bundle exec rake db:migrate`を、コメントアウトする
    1. `DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:migrate:reset`を、追加する
        - `DISABLE_DATABASE_ENVIRONMENT_CHECK=1`
            →本番環境のデータベースを削除するために必要な設定
            →本番用のデータベースには重要なデータが含まれるため、通常は削除できない
        - `bundle exec rake db:migrate:reset`
            以下を実施したことと同義になる
            - rake db:drop(データベースの削除)
            - rake db:create(データベースの作成)
            - rake db:migrate(マイグレーションファイルの実行)
        ```bin/render-build.sh
        #!/usr/bin/env bash
        # exit on error
        set -o errexit
        
        bundle install
        bundle exec rake assets:precompile
        bundle exec rake assets:clean
        # bundle exec rake db:migrate
        DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:migrate:reset
        ```
1. TablePlusを終了する　※データベースをTablePlusで開いている場合、削除できない
1. GitHubにプッシュし、更新する
1. GitHubにコードをプッシュすると、Renderのデプロイが実行される
1. Railsの設定をもとに戻す
    ```bin/render-build.sh
    #!/usr/bin/env bash
    # exit on error
    set -o errexit
    
    bundle install
    bundle exec rake assets:precompile
    bundle exec rake assets:clean
    bundle exec rake db:migrate
    ```
Spark ネイティブ読み取り

https://docs.databricks.com/aws/en/release-notes/product/


現在の Databricks Serverless 環境では、GCS コネクタに必要な Spark 設定を一切変更できないため、結果として GCS からの直接読み書きがサポートされておりません。
公式ドキュメントでは明記されていませんが、以下の理由から推理し、非対応という結論になりました。

公式ドキュメントを参考し、Databricks の標準クラスタで GCS にアクセスするには、少なくとも以下の Spark 設定を行う必要があります。これらを通じてサービスアカウント認証や GCS ファイルシステムの初期化を行います。
https://docs.databricks.com/aws/en/connect/storage/gcs#global-configuration

Databricks Serverless では、調整可能な Spark 設定がごく限られており（例：spark.sql.session.timeZone、spark.databricks.execution.timeout など数項目のみ）、その他の spark.hadoop.* 系設定を一切追加・変更できません。
そのため、上記の GCS 用設定を注入する術がなく、GCS コネクタ自体を動作させられない仕組みとなっています。

https://docs.databricks.com/aws/en/spark/conf#configure-spark-properties-for-serverless-notebooks-and-jobs





| 観点            | Spark ネイティブ読み取り (`spark.read.csv("gs://...")`) | GCS クライアント (`storage.Client().open()`) |
| ------------- | ---------------------------------------------- | -------------------------------------- |
|  直接読み取り可否   |  可能（`gs://` 経由で直接読み込める）                       |  直接ではなく、blob を open または download 必要   |
| ⚙️ 分散処理対応     |  分散並列読み込みが可能（クラスタ全体でスケール）                     |  単一ノードでの処理（並列読み込みには向かない）              |
|  パフォーマンス    |  高速（Databricks 内部の GCS コネクタ最適化）               |  通信・I/O がボトルネックになりやすい                |
|  コーディングの簡単さ |  1行で完結（非常にシンプル）                               |  blob.open や StringIO の操作が必要          |
|  メモリ使用量     |  Spark の executor 単位で管理（効率的）                  |  全体をメモリに読み込む必要がある（大きなファイルに不向き）       |
|  ファイルサイズ対応  |  数GB〜TB 級でも対応可能                               |  数MB 程度までが現実的                        |
|  セキュリティ管理   |  Secrets + Spark config 経由で統一管理可能             |  自分で認証情報（json）を直接扱う必要がある             |
|  PySpark 統合 |  DataFrame で即利用可能                             |  追加で `pandas` や `BytesIO` を使って加工が必要   |
|  ユースケース適正  | 大量データのバッチ処理、ETL、分析パイプラインに最適                    | 軽量処理、単発のファイルアクセス、API検証などに適正            |



大量データ処理、ETL、分析用途 → Sparkネイティブ方式 が圧倒的に有利

数MB以下の軽量ファイルや、簡易スクリプト → storage.Client() でもOK
文系新卒エンジニアの２年目備忘録　

こんばんわ。

文系新卒エンジニアの学んだことをここに記載して残していこうと思います。



簡単な自己紹介だけします。

４年生大学卒　文系出身の完全未経験でこのITの世界に飛び込みました。
IT業界を選んだ理由としては、これからITは伸びる(もうずっと伸びているけど）と思って
完全未経験でも入社できる会社へ入社しました。

インフラ系です。
ゆくゆくはセキュリティ系を目指していきたいと考えています、、

現在学んでいる内容としては
・AWS(SAAくらいの知見）
・サーバー関連(主にLinuxメイン）
・ネットワークについて少し(AWS/VPCで良く学んだ、SGやルートテーブルなど）
・コンテナ(Docker Kubernetes)
・インシデント対応


上記についてです。


今日学んだことはSPFについて学んだので、少しだけ書き記そうと思います。

まずSPFとは、SPF（Sender Policy Framework）とは、電子メールの送信元ドメインの詐称を検知する技術というもので、簡単に言うとメールをやり取りするサーバーが本当に正しいのかを確かめるようなものです。逆にメールの送信元でドメインなどが少し違って、SPFも違えば完全に怪しいと言えます。

ここでコマンドプロンプトなどで、nslookup -type= TXT gogle.com
と入力するといろいろグーグルについていろいろ情報を入手できると思います。
僕は聞いているだけでは分からず実際に手を動かさないと覚えられないです。

火気のSPFチェッカーなどを駆使して自分の企業で使っている者のSPFを調べてみてくださいー
https://mxtoolbox.com/spf.aspx



本当に大雑把にこんな感じでできれば平日は毎日記載していきたいと思っています。
日本語～１





# １、【何を追加でやればいいか分からなかったので】202506
 追加で（ついかで）
"追加地"或"另外"（表示在现有基础上增加动作）。

**🔸句中的追加で是个什么成分，有没有其他例句。其它相同用法不同意思的词？**
###### 1. 「追加で」的成分分析
「追加で」在句中作 连用修饰语（副词成分），修饰后面的动词「やればいい」。

追加（名詞/サ変动词）："追加、补充"

で（助词）：表示方式或状态，相当于“以…方式”“…地”

结构：
「追加」+「で」→ 以“追加”的方式 → “额外、另外”（副词性用法）

###### 2.其他例句
① 作为副词使用：
追加で注文する
（ついかで ちゅうもんする）
→ “额外点餐”

例：
「コーヒーを追加でお願いします」
（请再给我一杯咖啡。）

追加で提出する書類
→ “需要额外提交的文件”

例：
「この書類は追加で提出が必要です」
（这份文件需要额外提交。）

② 作为名词使用（不加「で」）：
追加の費用
→ “追加的费用”

例：
「追加の費用はかかりません」
（不需要额外费用。）

###### 3.相同用法（副词成分）但不同意思的词
以下词汇也能通过「名词 + で」构成副词，但含义不同：

**词汇	意思	例句**
基本で	基本上	「基本で問題ない」（基本没问题）
無料で	免费地	「無料でダウンロードできる」（可以免费下载）
急ぎで	紧急地	「急ぎで処理してください」（请紧急处理）
単独で	单独地	「単独で行動する」（单独行动）

###### 4.类似「追加で」但含义不同的表达
別途（べっと）で
→ “另外、另行”（更正式，多用于书面或商务）

例：
「別途でご連絡します」
（我们会另行联系。）

改めて（あらためて）
→ “重新、再次”（强调重复或修正）

例：
「改めて説明します」
（我会重新说明。）

总结
「追加で」是 “名词 + で” 构成的副词，表示“额外、补充”。

类似结构的名词（如無料、急ぎ）加「で」后也能变副词，但含义不同。

如果想替换「追加で」，可根据语境选择「別途で」「改めて」等词，但需注意语义差异。


# ２、【问一下关于日语名词前面的动词的形式，如果这个动词不接宾语只是单独一个动词的话能接什么样的动词】２０２５０６

在日语中，当动词直接修饰名词（即作名词的定语）时，无论该动词是否带宾语，其基本形式变化规则是一致的。以下是具体说明：

###### 1. 动词基本修饰形式（不带宾语时）
当动词单独修饰名词（不带宾语）时，使用以下两种形式：

(1) 动词原形（基本形/辞書形）
表示习惯性、经常性动作或未来动作，也可表示与名词的固有关系。

例：

笑う人（わらうひと）→ 笑的人

走る犬（はしるいぬ）→ 奔跑的狗

流れる水（ながれるみず）→ 流动的水

(2) 动词た形（过去时）
表示已完成动作或名词的过去状态。

例：

壊れた時計（こわれたとけい）→ 坏掉的钟表

乾いたタオル（かわいたタオル）→ 干了的毛巾

###### 2. 特殊注意事项
自动词 vs 他动词：

自动词（不带宾语）本身可直接修饰名词（如「開くドア」→ 打开的门）。

他动词即使不带宾语，形式上仍需保留「を」的隐含逻辑（如「本を読む人」必须带宾语，单独修饰时不能说「読む人」表意不完整）。

状态性动词：
部分动词（如「ある」「要る」）通常不直接修饰名词，需用其他表达（如「必要なもの」而非「要るもの」）。

否定形：
动词ない形可修饰名词（如「消えない光」→ 不会消失的光）。

###### 3. 常见错误示例
误用ます形：
×「遊びます子供」→ 正确为「遊ぶ子供」。

时态混淆：
×「書く手紙」（未完成）vs「書いた手紙」（已完成），意义不同。

总结
动词形式	用法场景	示例
基本形	习惯、未来或一般状态	鳴る電話（响的电话）
た形	已完成或过去状态	汚れた服（脏了的衣服）
ない形	否定状态	壊れない箱（不会坏的盒子）
[Chrome]ctrl+Enterで新しいタブで検索（ショートカット）

ChromeのURLバーに検索したい文字列を入力し、`cmd/ctrl + Enter`を押下すると、新しいタブを開いて、そこで検索結果を表示してくれます。

素早い流れは
`cmd + L`→`検索したい内容入力`→`cmd + Enter`

![Screenshot 2025-06-11 at 22.11.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237839/13dd89fe-3eae-4125-9b2e-62d1cd5683e5.png)
M365：動的メンバーシップについての整理

# きっかけ
SESということで製造業の運用保守をはじめとした各種案件に１人月入っているのですが、自社の事業としてMicrosoft製品を導入する仕事もしていくなかでMicrosoft Entraの質問を部下から受けることがあります。やったことないのになーと思いつつ、答えないわけにはいかないので都度調べて回答しています。
その中で今回「動的メンバーシップ」についての質問を受けたので自分の理解もかねて整理をしました。自分の動的メンバーシップ概念の理解を共有しようと思います。これが動的メンバーシップの理解につながりますと幸いです

# 動的メンバーシップとは？
* EntraID 内で設定できる機能です。
* 特定のルールや条件に基づいてユーザを自動的にグループに追加　または削除します。
* 条件にマッチするかどうかを自動的に判断するので手動メンテナンスが不要です。
    * 大規模な組織で効率的なメンバー管理ができるので面倒な運用を減らすことができます。
* Microsoft Entra ID P1 ライセンスまたは Intune for Education ライセンスが必要です
    * E5なら使えますが、E3の場合は追加でライセンスの導入が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/b5f3fd68-6b00-4870-890b-582d439ebf77.png)

# 動的メンバーシップを利用する方法
* セキュリティグループまたはM365グループで利用することが可能です。

1. Entra管理センターから　グループの作成を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/22f4d513-a204-4a17-a615-ed9d043d547d.png)
1. グループの追加からメンバーシップの種類を「割り当て済み」ではなく「動的ユーザ」または「動的デバイス」を選択することで割当条件の設定が可能になります。 注：Microsoft365グループの場合は「動的デバイス」は選択できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/f489f3e3-955a-4fa5-857b-c711249e4a1e.png)
1. 「動的クエリの追加」を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/40458a6c-bc3f-4641-ad93-26be5f732c97.png)
1. ルールを入力してフォーカスを外すと、”規則の構文”の部分に条件式が追記されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/a4cd8a07-4bcf-4e8b-b39c-2fc3f773e9f0.png)
1. 式の追加　ボタンを押すと複数条件式が入力できます。条件を入力し終わったら忘れずに保存　しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/54c1fd7c-4d59-466c-a036-d61a6b9666d5.png)
1. 入力し終わると「作成」ボタンが押せるようになるので、押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/17a01eb5-662d-479c-8a5e-6aa0d061911a.png)
1. グループを作成している旨通知が出ます。しばらく待ちましょう。（ふつうは1分もかからないうちに完了します。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/32ee7508-4bbb-45fe-a2a0-930db5463b1b.png)
1. 正常に作成されたことが確認できれば、動的メンバーシップ付きのグループが作成されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/a389f72a-3036-4f46-a370-6afd688424cc.png)



# 動的メンバーシップの計算式について・・・
参考文献の方の資料がわかりやすいかと思いますが、改めて載せますと・・・

| 意味 | 演算子 |
|------|--------|
| 次の値で終わる | -endsWith |
| 次の値で終わらない | -notEndsWith |
| 等しくない | -ne |
| 等しい | -eq |
| 指定値で始まらない | -notStartsWith |
| 指定値で始まる | -startsWith |
| 指定値を含まない | -notContains |
| 指定値を含む | -contains |
| 一致しない | -notMatch |
| 一致する | -match |
| 場所 | -in |
| 含まれない | -notIn |


# このユーザは動的メンバーシップに該当するか検証する方法
* 管理＞動的メンバーシップルール　にて　ルールの検証　タブに移動してください。
* 検証対象のユーザを追加すると、グループの条件に該当するかしないかを検証することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1920246/c4d3a2a8-fee5-4f33-b705-d0f40ad7d764.png)


# 参考文献
何事にも原則として先達がいらっしゃいます。
これまでの足跡に感謝を込めて共有いたします。

https://qiita.com/ryoma-nagata/items/5a45e8efd13e3c5310b7

また、下記公式ドキュメントにて詳細に説明がされています。
つかみについてほ本稿でも守備範囲のうちになるかと思いますが、細かいニュアンスなどの情報は公式ドキュメント以上にかなうものはありませんのでこちらを参照してより深い理解に結び付けていただければと思います。

https://learn.microsoft.com/ja-jp/entra/identity/users/groups-dynamic-membership

それでは、良い動的メンバーシップライフをお過ごしください。
【TablePlus】DBをアプリで確認する方法

# 記事概要
TablePlusアプリにて、Renderでデプロイしたアプリのデータを確認する方法をまとめる。

# 前提
- TablePlusアプリをPCにインストールしている
- アプリで表示するデータベースは、Renderでデプロイ済みである

# 手順(テーブルインポート)
1. Renderの[ダッシュボード](https://dashboard.render.com/)を開く
1. 操作したいデータベースを選択する
1. 「Connections」欄の「External Database URL」をコピーする
    アイコンをクリックすると、クリップボードにコピーできる
1. TablePlusアプリを起動する
1. 右クリックで表示されるメニューから、「Connect from URL」を選択する
    [![Image from Gyazo](https://i.gyazo.com/9b7739bfdc62b86d3e099fb6f7195758.png)](https://gyazo.com/9b7739bfdc62b86d3e099fb6f7195758)
1. 「Import」をクリックすると、設定画面が表示される
1. Nameの欄に任意の設定名を入力し、「Connect」をクリックする
1. テーブルが表示されれば、設定完了
1. テーブル名をクリックすると、格納されているデータを確認できる

# 手順(データ削除)
1. TablePlusでテーブルを表示する
1. 削除したいデータを右クリックする
1. メニューが開くので、「Delete」を選択する
1. 行が赤くなり、削除対象になっていることが確認できる
1. アイコンをクリックし、削除の操作を反映させる
    操作中にアラートが出た場合、タブを閉じてから再操作する(試用期間中は複数のタブを開けないため)
    [![Image from Gyazo](https://i.gyazo.com/a34365efd622088bc770a1e7f0b71e48.png)](https://gyazo.com/a34365efd622088bc770a1e7f0b71e48)

# 備考
- TablePlusアプリのインストール方法は、[こちら](https://qiita.com/likapantrip/items/e01be160a0e137843c43)を参照
【Drizzle】Not unique table/alias: 'xxx' の解消 🤩

## はじめに
以下、drizzleエラーの解消法を共有します。
```
Error: Not unique table/alias: 'aaa'
```

## 🪄  原因
不要なjoinを行っていた。
```terminal
.from(aaa)
.innerJoin(aaa, eq(bbb.facilityId, aaa.id))
```

## 🪄  解決
以下joinを削除
```diff
.from(aaa)
- .innerJoin(aaa, eq(bbb.facilityId, aaa.id))
```
Auth.jsを導入したプロジェクトを本番環境にデプロイ時に苦戦した時の記録

Auth.jsを導入したプロジェクトを本番環境にデプロイ時する際に苦戦したので、
うまくいった解決方法やどんな不具合が起きていたか記録残したいと思います。

私は、Next.jsのアプリとバックエンド(django)のアプリを同じサーバーに置くように
本番環境を作っていました。

## 不具合① ログイン時に/api/auth/errorにリダイレクトされる
まず疑うべきはバックエンドとの通信です。
apiのエンドポイントのパスが間違っていないか？
apiの認証処理に問題がないか？

自分の場合は、バックエンドは問題ありませんでした。
テスト環境では問題なくログインできており、ログイン以外の処理は問題なし。
Postmanで本番のログイン処理も問題ないが、本番環境に置いたNext.jsプロジェクトでログインすると、
なぜか/api/auth/errorにリダイレクトされてしまう。

### 【原因・解決方法】
原因は、apiエンドポイントのパスがAuth.jsのパスと競合していたことでした。
Next.jsでのAuth.jsは、内部的に"/api/auth"というパスを使って承認などの処理をしているようです。
![名称未設定ささ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/66ed67ac-813f-4912-bc30-b923372a4e0f.png)
今回、私の本番環境ではバックエンドのパスを"/api"が付くように設計していました。
そのせいで、認証失敗時にAuth.jsが/api/auth/errorにアクセスして本来はAuth.jsの処理が走る
ところがバックエンドの処理が走った様子。(そもそもなぜ認証失敗してるかは次に記載します)
そこで、<font color="red">バックエンドのURLを変更し、apiとならないような名前のパス(例えば/backend-apiとか)に修正したところ、この不具合は解消しました。</font>


## 不具合② 正しいメアド&パスワードでログインできない
正しいメアド&パスワードでログインしてもAuth.jsのログイン失敗のエラーページに飛び、ログインできない
不具合が起きていました。ただ、これは私が無知だっただけですが.envの設定の問題です。
公式のdeploymentのページが参考になりますが、"AUTH_TRUST_HOST"と"AUTH_URL"を設定すればOKです。


https://authjs.dev/getting-started/deployment

```.env
AUTH_TRUST_HOST=true
AUTH_URL=(本番環境のURL ex: https://myproduction.com)
```
これを設定したら、ログインできるようになりました。

以上です。
Rhinocerosで任意のポリサーフェースをくるくる回転させるPythonスクリプト

個人的なメモ

# 実装

下記のコードを`EditPythonScript`で実行する

```python:test.py
# -*- coding: utf-8 -*-
import rhinoscriptsyntax as rs
import time
import math

# ユーザーにオブジェクトを選ばせる
obj = rs.GetObject("回転させたいオブジェクトを選んでください", rs.filter.polysurface)
if not obj:
    print("オブジェクトが選択されていません")
    exit()

# 中心点の取得（重心を使用）
center = rs.SurfaceAreaCentroid(obj)[0]

# 回転軸（Z軸）
axis = rs.VectorCreate([0,0,1], [0,0,0])

# アニメーション設定
total_time = 10.0  # 秒
steps = 360  # 1度ごとに更新
delay = total_time / steps  # 秒あたりの待機時間

# 回転処理
for i in range(steps):
    rs.RotateObject(obj, center, 1.0, axis, copy=False)
    time.sleep(delay)
    rs.Redraw()
```

# 結果

<iframe width="560" height="315" src="https://www.youtube.com/embed/KP17Antx8VQ?si=zDSlMfbCUfVsIXCU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
NetlifyとGitHubの連携について簡単に紹介

私は2021年ごろから、試作したウェブページをインターネット上に公開するとき「Netlify」というサービスを使っています。
この記事ではNetlifyの基本的なことについて紹介してみようかなと思います。

# Netlify というサービスがある

私は「ねっとりふぁい」と発音しています。

https://www.netlify.com/

Netlifyはホスティングサービスと呼ばれるものの一種です。
誰でも無料で、ウェブページをインターネット上に公開することができます。

有料プランもありますが私は無料プランで十分使えています。

# GitHubとの連携がオススメ

公開したいファイルをNetlifyに直接アップロードしてもよいのですが、NetlifyとGitHubを連携させると便利です。
GitHubにファイルを置くだけでNetlifyがそれを検知し、自動的に公開してくれます。
しかもGitHubのファイルを修正するたびに、自動的に最新版を公開してくれます。

Netlifyを使ったウェブページ公開をとりあえず体験したいだけであれば、GitHubのリポジトリに置くのは**htmlファイルひとつだけでOK**です。

# 前回の記事のウェブページを公開してみた

こちら（↓）は、私が前回書いたQiita記事です。

https://qiita.com/tobi-on-central/items/9a4e9877c614f9c4aa28

この記事では **「気象庁APIを使って鹿児島県の天気情報を取得するウェブページ」を試しに作ってみる** ということをやっています（詳しくは記事を読んでみてください）。

せっかくなのでそのページをNetlifyで公開しました。踏んだ手順は以下のとおりです。

## 1. GitHubに適当な名前のリポジトリを作成
リポジトリ名は適当でよいです。

リポジトリに関する設定も全てデフォルトでよいですが、恥ずかしがりやな人は非公開に設定してもよいです。

## 2. リポジトリにhtmlファイルを置く

htmlファイルひとつをアップロードします。
このとき、ブランチはmainでよいです。

これでリポジトリの中は**そのhtmlファイルひとつだけ**の状態です。

## 3. Netlifyでプロジェクトを作る
Netlifyで「Add new project」⇒「Import an existing project」を押下すると、プロジェクト作成画面に遷移できます。

下図のように3ステップに沿ってプロジェクトを作れるようになっていて分かりやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/287eaac0-b67d-4921-b277-724720e57395.png)

「1. Connect to Git provider」ではGitHubを選択。
「2. Select repository」では連携させるリポジトリを選択。
「3. Configure project and deploy」ではプロジェクト名を決めて入力し、あとの設定は全てデフォルトでよいです。

## 4. 完了！
今回はプロジェクト名を「jmaapi001」にしたので、公開されたウェブページのURLは
`https://jmaapi001.netlify.app/`
となりました。

https://jmaapi001.netlify.app/

# お手軽だし、発展的なこともできる

勉強がてら作ったウェブページをとりあえず公開したいとき、Netlifyはお手軽なサービスだと思います。

ウェブページ公開手段としてはGitHubPagesも有名ですが、Netlifyのほうが機能豊富なので、やりたいことによっては「GitHubPagesだと実現できないけどNetlifyだとできる」なんてこともありえます。

もしよかったら触ってみては。

以上です。
Spring Bootプロジェクトで使用するGradleコマンド入門

# Spring Bootプロジェクトで使用するGradleコマンド入門

## はじめに

Gradleは、Javaプロジェクトのビルド自動化ツールです。この記事では、Spring Bootプロジェクトでよく使用するGradleコマンドと、その使用方法について説明します。

## 1. Gradleの基本

### Gradleとは

Gradleは以下の特徴を持つビルドツールです：

- 柔軟なビルド設定
- 依存関係の自動管理
- ビルドの高速化
- プラグインによる機能拡張

### Gradle Wrapper

Gradle Wrapperは、プロジェクトにGradleを同梱し、特定のバージョンのGradleを使用することを保証する仕組みです。

```bash
# Gradle Wrapperの生成
gradle wrapper

# 生成されるファイル
# - gradlew (Unix用実行スクリプト)
# - gradlew.bat (Windows用実行スクリプト)
# - gradle/wrapper/gradle-wrapper.jar
# - gradle/wrapper/gradle-wrapper.properties
```

## 2. 基本的なGradleコマンド

### プロジェクトのビルド

```bash
# プロジェクトのビルド
./gradlew build

# クリーンビルド（既存のビルド成果物を削除してからビルド）
./gradlew clean build

# テストをスキップしてビルド
./gradlew build -x test
```

### テストの実行

```bash
# すべてのテストを実行
./gradlew test

# 特定のテストクラスのみ実行
./gradlew test --tests "com.example.HelloControllerTest"

# テストレポートの生成
./gradlew test jacocoTestReport
```

### アプリケーションの実行

```bash
# アプリケーションの起動
./gradlew bootRun

# 特定のプロファイルで起動
./gradlew bootRun --args='--spring.profiles.active=dev'

# デバッグモードで起動
./gradlew bootRun --debug-jvm
```

## 3. 依存関係の管理

### 依存関係の確認

```bash
# 依存関係の一覧表示
./gradlew dependencies

# 特定の設定の依存関係を表示
./gradlew dependencies --configuration implementation

# 依存関係の更新確認
./gradlew dependencyUpdates
```

### 依存関係の解決

```bash
# 依存関係のキャッシュをクリア
./gradlew cleanBuildCache

# 依存関係の強制更新
./gradlew build --refresh-dependencies
```

## 4. プロジェクトの管理

### プロジェクトの情報表示

```bash
# プロジェクトの情報表示
./gradlew projects

# タスクの一覧表示
./gradlew tasks

# 特定のタスクの詳細表示
./gradlew help --task build
```

### プロジェクトのクリーンアップ

```bash
# ビルド成果物の削除
./gradlew clean

# キャッシュの削除
./gradlew cleanBuildCache

# すべてのビルド成果物とキャッシュの削除
./gradlew clean cleanBuildCache
```

## 5. よく使用するGradleタスク

### 開発関連

```bash
# コンパイルのみ実行
./gradlew compileJava

# テストのコンパイル
./gradlew compileTestJava

# コードの静的解析
./gradlew check
```

### デプロイ関連

```bash
# JARファイルの作成
./gradlew jar

# 実行可能JARの作成
./gradlew bootJar

# アーカイブの作成
./gradlew distZip
```

## 6. トラブルシューティング

### 一般的な問題の解決

```bash
# デバッグモードで実行
./gradlew build --debug

# スタックトレースの表示
./gradlew build --stacktrace

# 詳細なログ出力
./gradlew build --info
```

### パフォーマンスの改善

```bash
# 並列ビルドの有効化
./gradlew build --parallel

# ビルドのキャッシュを有効化
./gradlew build --build-cache

# デーモンの使用
./gradlew build --daemon
```

## まとめ

この記事では、Spring Bootプロジェクトで使用する主要なGradleコマンドについて説明しました。主なポイントは以下の通りです：

1. 基本的なビルドコマンド
2. テストの実行方法
3. 依存関係の管理
4. プロジェクトの管理
5. トラブルシューティング

これらのコマンドを適切に使用することで、効率的な開発が可能になります。

## 参考資料

- [Gradle公式ドキュメント](https://gradle.org/documentation/)
- [Spring Boot Gradle Plugin](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/)
- [Gradle User Guide](https://docs.gradle.org/current/userguide/userguide.html)
【Mac】TablePlusの導入

# 記事概要
MacにTablePlusを導入する方法について、まとめる。

# TablePlusとは
データベースの内容を操作するためのアプリケーション

https://tableplus.com/

# 前提
- PCはMacを使用している

# 手順
1. 「Download for Mac」をクリックする
1. TablePlusをインストールする
株式会社ログラスさんの5Daysインターンに参加した感想

## 感想
まずは、株式会社ログラスさんの5Daysインターンに参加させていただき、ありがとうございました。また、今回のチーム（メンターの方も含めて）は最高のチームだったと思います。あと、もう１スプリント、１ヶ月続けてみたかったです。きっと大分強いチームになったんじゃないかと勝手に思っています。終始楽しく、また成長もさせてくれたチームに感謝です。

## 参加のきっかけ
エージェントからおすすめされたこと、1on1での面談の感触や、プロダクト、言語、開発手法に惹かれたため、参加を決めました。（※正直始まる前は、5Daysのインターンなので、そこまで深い内容ではないだろうと思っていました。すみません :bow: ）

## 学んだこと

### DDD
DDD（ドメイン駆動設計）の考え方を学びました。最初自分は、DDDはドメイン部分を最初にガッチリ決めて、そのあとはあまり変更しないようにする開発手法だと思っていました。ただ、これは誤りで、そこを柔軟に変更していけるのがDDDの強みであると知れたのが大きかったです。

実際の開発の流れ：
```
ドメインの理解 -> ドメインモデリング -> ドメインの実装 -> ...
```

いいなと思ったのは、この順序通りにやらないといけないわけではなく、先に進んだ時に設計、実装に困ったり、うまくいかないときは、戻るのもありというものです。
自分たちのチームも、ドメインモデリングに困ったら、ドメイン理解を深めたり、実装で足りないところ、修正すべきところがあったら、モデリングをし直す、修正するということを繰り返していました。最初はいちいちやるのめんどくさいなみたいなのもあったのですが、ドメインの実装がしっかりしていると、実装が大分楽になることを実感したので、今回習ったDDDは自分の開発に取り入れていきたいと思います。

### オニオンアーキテクチャ
DDDをやっていく時にいくつかのアーキテクチャがあるのですが、今回のインターンではオニオンアーキテクチャを使いました。クリーンアーキテクチャと似ているとは思うのですが（オニオンアーキテクチャの後により依存関係を減らしたのがクリーンアーキテクチャという理解）、オニオンはDTOみたいなのがない分、シンプルだなーと思いました。やっぱり、エンジニアとしてはシンプルな方が好きなので、このアーキテクチャはどんどん使っていきたいと思います。まあただ、クリーンアーキテクチャの方はそれぞれの層の依存関係がより少ない？ので、よりテストしやすいのかなーとも思っています。ここら辺の理解はまだまだ浅いので、この先勉強してそれぞれのメリット、デメリットを言語化できるようにしたいですね。

（実はオニオンアーキテクチャ、DDDは一回雰囲気で開発したことがあったので、ある程度は知っていたのですが、今回のインターンで今までの理解の間違いを正すことができ、またそれぞれの理解を深めることができたと思っています。）

### スクラム
ログラスさんはFAST（Fluid Adaptive Scaling Technology）に移行しているらしいですが、今回は普通のスクラムを学びました。５日間を二つのスプリントに分けるという、狂気の沙汰をやっていたのですが、メンターのサポートのおかげで、最初のスプリントよりも、次のスプリントの方が数倍のコミットをすることができたのが驚きでした。

Sprint1とSprint2の違いは、Sprint1ではドメイン理解やモデリングに時間をかけていたのもありますが、チケット分割等がうまく行っていなかったため、スクラムがうまく行っていなかったのがあると思います。Sprint2では、チケットの粒度を小さくし、またチケットごとに何が達成できていれば、このチケットを完了していいかを書くようにしたことで、チケットの分割さえできればあとは開発するだけみたいな状態を作り出したのが良かったのかなと思います。

ただ、チケット分割は大分疲れました。チケットを分割し、それぞれの目標を考えれば考えるほど、これも考えないといけないんじゃない？みたいな気づきが多く、また、このチケット分割でうまく開発できるのかみたいなところも考えないといけないので、相当疲れました... 2~3時間やりましたが、みんな死んでましたね... ただ、これをやったおかげで、開発中にここ考えてなくない？みたいなものが減って、大分開発に集中できたので、やっぱりチケット分割はやるべきなんだなと実感しました。まあ、大分疲れるのでお菓子が欲しいですね〜

### ペアプロ
これは学んだというところなのか怪しいですが、ペアプロの良さを知ることができたのも良かったです。自分は実装することが多かったのですが、ペアプロのおかげで自分の間違いを書いている際に指摘してもらえたり、理解が異なっている部分を知ることができたりしたので、早期に問題を発見し、そこに対応できるというのが素晴らしいなと思いました。

やっぱり、自分一人だとちょっとよくわからないけど一旦PRに出してみるか、みたいなのがあったりすると思うのですが、そもそもPRを出す前に問題を発見できることが多いので、レビュー負荷を減らせるみたいなのも良いなと思いました。また、うちのチームはペアプロもやりながら、レビューをもう片方のペアプロ組がやることで、各々の全体的なコードの理解の差を減らすことができ、得意不得意はあれど、誰にIssueを割り振っても、ある程度対応できるような状態を作ることができたのも良かったと思います。

## 総括
技術好きで、プロダクト志向的なところもある人は大分いいインターンなんじゃないかなって思ってます。普通のインターンで、DDDやオニオンアーキテクチャを教えてもらえるところあります！？ アーキテクチャとか結構気になる自分としては最高のインターンだったと思います。

あと、Kotlin今回初めて使ったのですが、Kotlinいいですね〜 Javaをちょっとモダンにした感じが良かったですね。特に`null`を`?`で処理できるところとか、`.let`からの`it`みたいなのも自分は好きですね。やっぱり静的型付け言語最高です！OOPだし。

あと、個人的な感想なのですが、自分のチームのメンターの方との相性が良かったです。本当にあの方がメンターで良かった！！！と心の底から思います。

今回のインターン本当に行って良かったと思います！
最高でした！ありがとうございます :bow:
加算された数列の最大値　.entries()　-Infinity


Paizaの「`a[i] + i` の最大値を求める」問題に挑戦したときの学習を記録！

<br>

## 問題概要

- N 個の整数 a_1, a_2, …, a_N が与えられる。
- a_i に i を足したとき、a_1 , … , a_N の最大値を出力せよ。

<br>

入力例：

    5
    1 2 3 4 5

出力例：

    10

<br>

https://paiza.jp/works/mondai/loop_problems2/loop_problems2__add_maxseq

<br><br><br>

## ✅ OK例：Math.max() + 配列
```js
const rl = require('readline').createInterface({input:process.stdin});
const lines = [];

rl.on('line', (input) => {
    lines.push(input);
});


rl.on('close', () => {
    const N = Number(lines[0]);
    const nums = lines[1].split(' ').map(Number);
    
    let sum = [];
    for(let i = 1; i <= N; i++){
        sum.push(nums[i-1] + i);
    }
    
    console.log(Math.max(...sum));
});
```

`.push()` で計算結果を全部入れてから `Math.max(...sum)` で最大値を取るやり方。
これは「結果を配列に残したい」ってときに便利。

<br>

### 💡 .entries()

インデックスも値も同時にほしいときは `.entries()` を使うと良い！

`for-of` だと通常「値」しか取れないけど、

`.entries()` は [インデックス, 値] のペアを返してくれるから、
<br>

```js
for(const [index, value] of nums.entries()) {
    sum.push(value + index + 1);
}
```
って書ける。 `index` は 0 始まりだから +1 して i に合わせてるよ。

<br><br><br>

## ✅ sum 配列なしでも最大値だけでOK！

実は、最大値だけほしいなら sum 配列すらいらない。直接更新しながら最大値を求める方法がスマート！
```js
let maxVal = -Infinity;
for(let i = 1; i <= N; i++) {
    const current = nums[i - 1] + i;
    if(current > maxVal) {
        maxVal = current;
    }
}
console.log(maxVal);
```

`-Infinity` って「どんな数よりも小さい」特別な値。

これを使うと「最初に比べる相手がいない」ってときに超便利。順に比べながら更新していくやつだね！

<br><br><br>

## 📝 メモ

- 配列インデックスは 0 から始まるけど、問題は 1 から始まる。ズレに注意！
- `.entries()` は配列操作で「インデックスと値」を同時に扱うのに超便利。
- 最大値だけほしいなら「一時配列 sum を作らず、比較しながら更新」でOK！
- 最小値スタートの `-Infinity` は「どんな数よりも小さい」という覚え方でイメージしやすい。



<br><br><br>[僕の失敗談(´;ω;｀)と解決法🐈](https://paizabeginner.wordpress.com/2025/06/11/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e5%8a%a0%e7%ae%97%e3%81%95%e3%82%8c%e3%81%9f%e6%95%b0%e5%88%97%e3%81%ae%e6%9c%80%e5%a4%a7%e5%80%a4/)
S3からファイル取得

```

import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.sync.ResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.zip.*;

public class S3ZipCsvProcessor {

private static final String BUCKET_NAME = "your-bucket-name";
private static final String PREFIX = "your-folder-path/"; // 末尾 / 必須
private static final String TARGET_ZIP_NAME = "target.zip";
private static final String TARGET_CSV_NAME = "result.csv";

public static void main(String[] args) throws IOException {
Region region = Region.AP_NORTHEAST_1;
S3Client s3 = S3Client.builder()
.region(region)
.credentialsProvider(ProfileCredentialsProvider.create())
.build();

// ① フォルダ一覧取得
List<String> folders = listFolders(s3, BUCKET_NAME, PREFIX);
if (folders.isEmpty()) {
throw new RuntimeException("フォルダが存在しません");
}

// ② 最大番号のフォルダを特定
int max = folders.stream()
.map(f -> f.replace(PREFIX, "").replace("/", ""))
.filter(f -> f.matches("\\d+"))
.mapToInt(Integer::parseInt)
.max()
.orElseThrow();

String maxFolderPrefix = PREFIX + max + "/";

// ③ ZIPファイルの存在確認・取得
String zipKey = maxFolderPrefix + TARGET_ZIP_NAME;
Path zipPath = Paths.get("temp.zip");
s3.getObject(GetObjectRequest.builder().bucket(BUCKET_NAME).key(zipKey).build(),
ResponseTransformer.toFile(zipPath));

// ④ 解凍
Path unzipDir = Paths.get("unzipped");
unzip(zipPath, unzipDir);

// ⑤ 特定CSV取得
Path csvPath = unzipDir.resolve(TARGET_CSV_NAME);
if (!Files.exists(csvPath)) {
throw new RuntimeException("CSVが見つかりません: " + TARGET_CSV_NAME);
}

System.out.println("CSVファイル取得成功: " + csvPath.toAbsolutePath());

// 後処理（任意）
// Files.delete(zipPath);
}

private static List<String> listFolders(S3Client s3, String bucket, String prefix) {
ListObjectsV2Request request = ListObjectsV2Request.builder()
.bucket(bucket)
.prefix(prefix)
.delimiter("/") // フォルダ区切り
.build();

ListObjectsV2Response response = s3.listObjectsV2(request);
return response.commonPrefixes().stream()
.map(CommonPrefix::prefix)
.toList();
}

private static void unzip(Path zipFilePath, Path targetDir) throws IOException {
Files.createDirectories(targetDir);
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath.toFile()))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
Path outPath = targetDir.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(outPath);
} else {
Files.createDirectories(outPath.getParent());
try (OutputStream os = Files.newOutputStream(outPath)) {
zis.transferTo(os);
}
}
}
}
}
}


```
Switch 関数：Power Apps で条件による切替をする方法

ごきげんよう、百合宮桜（Miyu）です(≧▽≦)
世間は今、某スイ〇チの抽選に沸き立っていますね。ということで私も流行に乗って？Switch（関数）の記事を書きたいと思います。

以前こちらの記事で日付や数字などの範囲によって IF 関数で値を切り替える方法を説明しました。

https://qiita.com/YurimyMiyu/items/fcb7f57a70cfc31eda07

今回は同じことを Switch 関数でやってみたいと思います。
例えばテストの点数（30点満点）が

- 10点だったら、お疲れ様の画像
- 20点だったら、すごいよと誉める画像
- 30点なら、流石！と褒めたたえる画像

に切り替えるという形です。
画像のアップロード方法やテキスト入力の配置については前回の記事を参照してください。

# やり方
画像コントロールの Image プロパティに以下の式を書きます。

```
Switch(
    Value(TextInput1_1.Text),
    10,お疲れ様,
    20,すごい,
    30,さすが
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/f87fdf4b-b289-48ca-8c2b-4a84ac77f87f.png)

# IF 関数との違い
IF 関数の場合は「10点以上20点未満」というような範囲指定を条件部分に入れ込むことができます。しかし Switch 関数の場合、条件にできるのは「10点なら」という決め打ちの値だけで範囲指定を行うことができません。

したがって

- 複数条件の範囲指定 → IF 関数
- 単一条件での切り替え → Switch 関数

と使い分けることができます。
ぜひ使い分けをマスターしてくださいね！
それではごきげんよう♪
Next.jsで急にcssがあたらなくなった

# 問題
Next.jsを使って個人アプリをいじっていたところ、急にcssが当たらなくなってしまったので解決策を書きます。

# 試したこと
- スーパーリロード
- ブラウザのcookieなどを消す
- デプロイしたものはcssが当たっている
- node_modulesと.nextを入れ直す

# 解決策
結局node_modulesと.nextを入れ直すことでなおりました。2つまとめて消しましたが多分node_modulesか.nextのどちらかだけでもなおる気がするので、まずはnode_modulesだけ入れ直してみると良さそうです。
```
rm -rf node_modules .next
npm install
```

久々に触ったプロジェクトで全体的に少し重かったのと、直前にプロジェクト自体のディレクトリ配置を変えていたので、キャッシュに問題があったのかと思っています。

ざっとググってもそれっぽいものは出てこなかったのですが、perplexityで色々探索したところ以下の記事でも同じようなことが書かれていました。

https://qiita.com/bearl27/items/4099f6d9bf7e433b2537

# 追記
その後なぜかリポジトリが壊れたので、cloneしなおすのもありかもです。
EndeavourOS（ArchLinux） 初手で躓いた話

# EndeavourOS（ArchLinux）インストール後、ブラックスクリーンになりました。
ArchLinuxって何か魅力的でついつい触ってみたくなります。

少し前に試してみたArchLinux + i3wm 環境では、あーだこーだしている内にpacmanの更新が上手くいかなくなっていき（パッケージの依存関係が崩れたり干渉したり色々）、ボディーブローの様にダメージが蓄積して結局やられてしまったのですが（心が...）、EndeavourOSなら何とかなりそうです。（今のところ...）

でもやっぱりArchなので、当たり前のように初手で躓きました。今回はその時の話です。

EndeavourOS 自体のインストールは簡単で、ArchLinux なのに歯ごたえが無く少し違和感はあったのですが、順調に進みました。

難なくインストールされた後ブータブルUSBを抜け、何となく不安を感じながらも特に何もせずインストールされたOSを起動してみると問題なく起動出来ました。（ここで完全に油断する）

ここから暫く vim などの必要なパッケージをインストールしたり、設定を弄ったりして ArchLinux を満喫。

がしかし、起動時の挙動を確認するために再起動すると画面に何も表示されなくなりました。 <code>Alt + F1,F2</code> を押したりしても仮想コンソールは表示されません。何回再起動しても同じです。

自暴自棄になりアンインストールしかけたのですが、何とか堪えた（自身をコントロール出来た）ので記事にしておきます。

## 何が原因だったのか
暫く休憩して冷静になると、すぐに答えは出ました。

原因は...　ただ Nvidia のドライバーがインストールされていなかっただけです...（小声）

起動時にwelcome to hell的な表示があったので起動自体は出来ていそう、仮想コンソールが表示されないのは画面出力が出来ていないからではないか？からのグラフィックドライバーだろうという推測から判明しました。

言い訳ですけど、インストール前にISOのライブ環境から起動する方法で for nvidia を選択していたのに nvidia のドライバーがパッケージに含まれてないなんて思わなくないですか？


## 解決方法

では復旧作業ですが、archLinux には 便利な chrootコマンド があるので、これを使ってドライバーをインストールしていきます。

ブータブルUSBから EndeavourOS のライブ環境を起動して bash を開きます。

まず、EndeavourOS がインストールされているドライブを確認。
```ruby:bash
lsblk -f

# ドライブ情報が表示されます
```

2つのパーティションにマウントします。ext4 と efi。

1つ目、ext4にマウント。
```ruby:bash
# ext4 システムパーティション
mount /dev/先程確認したext4のドライブ名 /mnt
```

efi は /efi の場合と /boot/efi の場合があるので一旦確認。
```ruby:bash
cat /mnt/etc/fstab

# 情報が表示されます
```

2つ目、efiにマウントします。

```ruby:bash
mount /dev/先程確認したefiのドライブ名 /mnt/efi # /efiだった場合

# または

mount /dev/先程確認したefiのドライブ名 /mnt/boot/efi # /boot/efiだった場合
```

2つともマウント出来たので、chroot します。
```ruby:bash
arch-chroot /mnt
```

ここからインストールされているOSを弄っていきます。

インストールされているパッケージ一に nvidiaドライバーが無いか確認します。

```ruby:bash
pacman -Qq

# インストールされたパッケージの一覧が表示されます。
```
nvidiaの表記はありませんでした。これで解決したも同然です。

ここで原因の nvidiaドライバーをインストールするのですが、nvidiaのドライバーは何種類かあるので使用しているグラフィックボードの型を確認する必要があります。

以下のコマンドで確認。

```ruby:bash
lspci -k -d ::03xx

# 結果
10:00.0 VGA compatible controller: NVIDIA Corporation TU117 [GeForce GTX 1650] (rev a1)
        Subsystem: ASUSTeK Computer Inc. Device 86b9
        Kernel driver in use: nvidia
        Kernel modules: nouveau, nvidia_drm, nvidia

# TU117 というのが型です
```

ArchLinux公式に適合表があります。

https://wiki.archlinux.org/title/NVIDIA

表と照らし合わせると TUXXX のドライバーは <code>nvidia-open</code> でした。

ではパッケージをインストールします。

```ruby:bash
pacman -S nvidia-open
```

あとは chroot を抜けてアンマウントし、再起動すれば完了です。
```ruby:bash
exit
cd
umount --recursive /mnt
reboot
```

無事復旧出来ましたとさ。

無駄な時間を過ごした筈なのに達成感を得る事が出来ました。複雑な気持ちです。

## 直らないとき
他に原因があると思いますが、以下でシステム更新をすると正常に戻る場合があるので試してみると良いかも知れません。

上記と同じように chroot してから以下を順に実行します。
```ruby:bash
pacman -Syyu
pacman -S udev
pacman -S mkinitcpio # ここでエラーが発生する事がありましたが、繰り返すと上手くいきました。
pacman -S linux
mkinitcpio -p linux
```
React商品詳細ページ開発メモ

````markdown
# React商品詳細ページ開発メモ（2025/06/11）

## 今日やったこと

### 1. 商品詳細ページのレビュー表示ロジック修正

- 商品レビュー一覧で「自分のレビュー」と「他ユーザーのレビュー」を分離して表示
  - `myReview`と`otherReviews`をuseSelectorで判別
  - `isMe: review.userId === Number(userId)`で自分のレビュー抽出

### 2. レビュー平均点の整数化
- 商品情報の`averageRating`が `"0.00"` のような文字列で返ってくるため、  
  `Math.floor(Number(product?.averageRating))` で整数に変換してStarRatingなどに渡すよう修正

### 3. 空文字・undefined対策
- レビュー本文`contents`や評価値が`undefined`の場合はデフォルト値で埋める（例：空文字`''`や`0`）

### 4. カート機能・商品追加APIのパラメータ整理
- `/api/orders/add_cart` APIは `productOption` を必須パラメータとして送信  
  - オプションがない商品でも `"default"` や `""` を明示的に送る

### 5. SQL INSERT文再確認
```sql
INSERT INTO cart (user_id, product_id, quantity, product_option, choose, is_deleted)
VALUES ($1, $2, $3, $4, true, false)
````

* `product_option` は必ず値を指定して渡す必要がある
* NULL不可の場合は必ず何かしら文字列で埋めること

## ハマりポイント＆解決

* StarRatingやLabelコンポーネントで「数値で渡しているつもりが文字列でpropsが渡り、レンダリングエラー発生」
* SelectBoxに配列のままobjectを渡してしまい、「Objects are not valid as a React child」エラー発生
  → options配列が正しく{ label, value }構造になっているか常に要チェック
* API呼び出し後にデータは返るが画面が表示されない
  → レビューが「空」だとmyReview部分が何も描画されずに空白になる仕様だった

---

## 感想

* ユーザーごとのレビュー抽出や平均値計算ロジック、APIのパラメータ要件（必須/省略可）を再認識。
* UI不具合はprops型や初期値、データの型整合性を徹底的に見直すことが重要。

```
```
Windowsで始めるClaude Code用のdevcontainer

```json
{
  "name": "Claude Code Minimal",
  "image": "mcr.microsoft.com/devcontainers/base:jammy",
  "features": {
    "ghcr.io/devcontainers/features/node:1": {},
    "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
  }
}
```
PHP8技術者認定上級試験に合格した勉強方法

先日、PHP8上級試験に無事合格できました。

本記事では私の実施した勉強方法について解説しています。
前提として、私はPHPの経験が8年ほどあります。
（フロントエンドやインフラもやっているので、ちょいと薄めの8年です）
PHP8は業務では使っていません。（PHP7まで）
※未経験の方はPHP8初級試験の方をオススメします。

## PHP8上級試験の概要

正式な名称は「PHP8技術者認定上級/準上級試験」らしいです。
全国のCBTテストセンターで年中受験することができます。
```
概要：PHPの言語仕様から実用的なプログラミングテクニックまでの知識を問う試験
設問数：30問
試験時間：2時間
出題形式：選択式
合格ライン：7割以上の正解　上級試験合格 / 5割以上の正解　準上級試験合格
```
公式サイトより引用
> PHP8上級/準上級試験 | PHP技術者認定機構
https://www.phpexam.jp/summary/expert8

5割以上7割未満でも準上級の称号が得られます。
（ちなみに8割以上の正解で、後日論文を提出すると"ウィザード"を名乗れるそうです）

## 私の実践した勉強方法

### 教材

#### 1. 公式問題集

本試験にはリリースされてから日が浅く、参考書はそこまで充実していません。
私は以下のテキストを購入しました。


https://www.amazon.co.jp/dp/B0DMJS9LKJ?ref=ppx_yo2ov_dt_b_fed_asin_title


https://www.amazon.co.jp/dp/B0F7F4H8FP?ref=ppx_yo2ov_dt_b_fed_asin_title

こちらを強くオススメします。
合計で60問分の問題と解説が掲載されています。


#### 2. 模擬試験


https://study.prime-strategy.co.jp/study/ph8ex1/

無料です。
全問回答すると、メールで結果が通知されます。


#### 3. 古庄親方の上級コラム

https://www.phpexam.jp/archives/category/column/oyakata

試験範囲についてわかりやすくまとめられています。
記事内にPHP公式マニュアルへのリンクがあるので、ざっと目を通しておきましょう。


### 勉強の進め方

① [1. 公式問題集]を解く
② [2. 模擬試験]を解く
③ [3. 古庄親方の上級コラム]をすべて読む
　①～③を繰り替えし行います。
　問題は10割正解できるまで何度も繰り返し解きましょう。
 
回答時間は計らなくても大丈夫だと思います。
また、正解でない選択肢についても、理解を深めるようにしましょう。

人によっては2週で終わる方もいれば、4週以上必要な場合もあるかと思います。
焦らず、着実に学習を進めましょう。

私はこの時点で、試験に申し込みました。
（先に受験日を決めてしまうと、プレッシャーを感じるので嫌ですよね）

## 受験後の感想

私は1回目の受験で無事合格できました。
受験後は、なんだか自分の書くコードの質が上がった気がします。

履歴書でも大きなアピールになるので、PHPコーダーは持って損ないかと思います。
[Mac] 同じアプリの複数ウィンドウを素早く切り替える

同じアプリ（たとえば、Chromeで複数プロファイルを開いていたり）で複数ウィンドウをショートカットで切り替えたいときは、
`command + バッククオート`（英語配列キーボード）で実行できます。

キーがわからない場合は、Finderアプリを開いて、メニューバーの[ウィンドウ(Window)]からショートカットキーを確認できます

![Screenshot 2025-06-11 at 20.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237839/8203b143-17cf-487d-8fb3-38be42b6cffd.png)
ChatGPTだけで業務システムを構築してみた話 〜ノーコードで生産管理とQR処理を自動化〜

> ※この記事は「GASに触れたことすらなかった筆者」が、ChatGPTを活用して業務システムを構築した実録です。

# ChatGPTだけで業務システムを構築してみた話

## はじめに

こんにちは。この記事では、**自分ではコードを書かずに、ChatGPTの力を借りて業務用のデータ管理システムを構築した体験**を紹介します。実は、私はGAS（Google Apps Script）もPythonも使ったことがなく、GASについては完全に未知の状態でした。それでも、必要に迫られ、AIを活用してシステムを一から作り上げることができました。

この記事が、「ChatGPTって本当に使えるの？」「プログラミング経験がなくても業務ツールは作れるの？」という方の参考になれば幸いです。

---

## 背景と目的

もともとExcelや手作業で管理されていたある業務フローがありました。複数の工程や製品情報を扱っており、QRコードやCSVデータを取り込んで、Googleスプレッドシート上で一元管理する必要が出てきたのです。

以下のような課題がありました：

* 手入力や転記ミスが頻発
* 複数の現場や作業者が関わるため、統一管理が難しい
* 過去の履歴やエラーが追跡できない

これを**すべてChatGPTのサポートで自動化・統合管理できる仕組みにしたい**と考えました。

---

## ChatGPTとの取り組み方

私自身はGASについては完全に未知だったため、まずは以下のようなスタイルでChatGPTに相談を始めました：

* 「こういう処理をやりたいのですが、可能ですか？」
* 「CSVをDriveから読み込んで、特定の列を加工してスプレッドシートに書き込みたい」
* 「QRコードを使って担当者や製品情報を記録したい」

ここで重要だったのは、**コードではなく“やりたいこと”を丁寧に伝えること**です。

### 🔍 工夫した点：

* 大きな処理は分割して指示
* 背景情報や運用の目的も伝える
* 「このコードの意味を教えて」と逐次確認

GPTは、説明を含んだコードを返してくれるので、その都度内容を確認しながら、自分の理解も深めることができました。

また、ChatGPTとのやりとりの中では、どうしても**コードの意図がすれ違ってしまう場面**があります。そのため、**バージョン管理や履歴の保存、分岐ごとの記録が非常に重要**であると実感しました。

さらに、あまりにもChatGPTに依存するスタイルに慣れてしまうと、**ChatGPTが一時的に使用できない状況（アクセス障害など）になると手が止まってしまう**というリスクもあることを今回強く感じました。

---

## システム全体の概要

完成したシステムの主な構成は以下の通りです：

* Googleスプレッドシート上に操作メニューを追加（onOpen）
* CSVファイルをDriveから読み込み、自動で整形・記録
* QRコードリーダーで担当者・製品・保管場所を読み取り、シートに整理
* 「生産管理番号」と「その補助番号」をキーに、CSVとQRのデータを突合
* 自動ログ記録、古いデータの自動削除、出荷データの上限チェック
* 各種エラーと対処方法の表示

### 実装機能の一例：

* ワンクリックでCSV読み込み・整形・挿入  
  → ボタン操作でDrive内CSVを取得し、成形後にシートに自動反映
* QRコード読み取りとマスタ連携によるデータの補完
* 一定期間経過した履歴の自動削除処理（トリガー制御）
* スプレッドシートメニューに操作項目が集約

---

## 苦労した点と乗り越え方

### ❌ 苦労したこと：

* GASのエラー文が意味不明で、どこで失敗しているか不明瞭
* 処理順や非同期のタイミングで、データがずれる問題
* CSVとQRのデータ突合がうまくいかない（キー重複や空白）

### ✅ 解決のヒント：

* ChatGPTに「どこにバグがあるか」「こういう挙動になるのはなぜか」を対話形式で質問
* エラーが出たらコードを部分的に渡して解析してもらう
* 処理フローを何回も文にしてChatGPTに説明

---

## ChatGPTによる自己評価と技術力の振り返り

ChatGPTからのコードや提案をそのまま使っているように見えて、実際には**システムの意図・流れ・目的を常に自分で整理し続けていた**と思います。

ChatGPTが評価してくれるとすれば、次のような点だと思います：

* 要件を構造的に整理できたこと
* エラーや仕様変更にも柔軟に対応できたこと
* 「コードが動けばOK」ではなく、「使えるもの」にこだわった姿勢

コードを書いていなくても、**設計者・ディレクターとしての立場に近い形でシステム構築に関われた**のではないかと思います。

---

## まとめ

「コードを書かずに業務システムを作った」というと夢物語に聞こえるかもしれませんが、ChatGPTと丁寧に向き合えばそれは現実になっていることを確信できました。

今回の取り組みから得た最大の教訓は：

> **“技術がなくても、自分の言葉で問題を整理し、AIを正しく導ければ、実用的な仕組みは作れる”**

ということでした。

今後は、より複雑な業務フローや制御系（PLC・ST言語）にも応用していけるよう、経験を重ねていきたいと思います。

---

読んでいただきありがとうございました。
一流のIT人材の特徴


1. 高い技術スキル
深い専門知識とスキルを持ち、最新技術を常に吸収している。

2. 継続的な自己学習力
技術トレンドの変化に柔軟に対応し、主体的に自己成長を続ける。

3. コミュニケーション能力
技術的な内容を非専門家にもわかりやすく伝え、円滑なコミュニケーションが取れる。

4. 課題解決力
問題を明確に分析し、実現可能で効果的な解決策を提案できる。

5. 決断力
不確実な状況でも、情報を適切に評価し迅速かつ的確な意思決定ができる。

6. リーダーシップと協調性
チームを牽引し、メンバーを鼓舞すると同時にチーム内で協力し合う姿勢を持つ。

7. ビジネスマインド
技術的成果をビジネス価値として理解し、事業成長や収益につながる施策を考える。

8. 柔軟な思考力と適応力
予期せぬ変化やトラブルに冷静に対応し、柔軟に状況を打開する能力。

9. 強い責任感
自分の役割を果たすだけでなく、チームやプロジェクトの成功にも積極的に貢献する姿勢を持つ。

10. 顧客志向・ユーザー視点
技術やサービスを利用するユーザーの立場で物事を考え、顧客満足度や使いやすさを重視する。




****

レーダーチャートでPG（プログラマ）、SE（システムエンジニア）、PM（プロジェクトマネージャー）の典型的な特徴を点数化すると、次のような分配になります（各10点満点）。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4108487/447fcb33-b477-4033-b92e-5df26e6e98b0.png)


| スキル        | PG    | SE    | PM    |
| ---------- | ----- | ----- | ----- |
| 技術スキル      | **9** | **8** | **5** |
| コミュニケーション力 | **5** | **8** | **9** |
| 決断力        | **6** | **7** | **9** |
| 課題解決力      | **7** | **8** | **9** |
| リーダーシップ    | **4** | **7** | **9** |
| ビジネスマインド   | **4** | **7** | **9** |
| 自己学習力      | **9** | **8** | **7** |
| 柔軟性・適応力    | **6** | **8** | **8** |
Material 3 Expressive実装例 : まとめ

Material 3 Expressive の実装例の紹介シリーズのまとめです。
Material 3 Expressive の変更点や標準で用意されている処理を使った実装例を紹介しています。
実装の参考にでもご利用ください。


## Theme 関連

- [MaterialExpressiveTheme](https://qiita.com/Nabe1216/private/28ea2da0176ccc4497f9)

## コンポーネント

- [App bar](https://qiita.com/Nabe1216/private/46164782644ae974d13e)
- [Button group](https://qiita.com/Nabe1216/private/5a4dcc1910431ed3b101) (new)
- [Button](https://qiita.com/Nabe1216/private/ae30a5ef6a3d3bca833e)
- [Extended FAB](https://qiita.com/Nabe1216/private/f33a3351d3f22cab8e51)
- [FAB menu](https://qiita.com/Nabe1216/private/338cd2d569926e4bac8f) (new)
- [FAB](https://qiita.com/Nabe1216/private/b77f152121e8b536637f)
- [Icon button](https://qiita.com/Nabe1216/private/0d5694da76853c82da3e)
- [Loading indicator](https://qiita.com/Nabe1216/private/55ba3c8971a256d251ba) (new)
- [Navigation bar](https://qiita.com/Nabe1216/private/55d08ceaba099ecb045d)
- [Navigation rail](https://qiita.com/Nabe1216/private/843ea6a669e9985eb131)
- [Progress indicator](https://qiita.com/Nabe1216/private/3abc6433d11a9d87223f)
- [Split button](https://qiita.com/Nabe1216/private/5222aadc7198801a28f0) (new)
- [Toolbar](https://qiita.com/Nabe1216/private/19b024453433e4d790bb) (new)

## 関連

https://m3.material.io/

https://m3.material.io/blog/building-with-m3-expressive


https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/
Genspark AI ブラウザを使う

## 概要
2025/6/11にGenspark AI ブラウザが正式リリースされました。
AIエージェント機能、MCPサーバー連携、広告ブロックを備えたブラウザです。

## インストール
[公式](https://www.genspark.ai/browser)からどうぞ
現在はMacのみ対応でした。Chromeのブックマークはそのまま引き継げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/62f538f5-fa2f-4ef0-b60a-557e95c661dc.png)

## 解説動画を解説してもらう
解説動画が英語だったので、ブラウザの右上にある質問から日本語での解説をお願いしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/3c6f71b1-6d45-4a73-ae48-2b3a5e25fc20.png)

```
このYoutubeの動画で説明されているGenspark AI Browserについての使い方を、
日本語で分かりやすく整理して教えてください
```

## 解説

### 💡 主なメリット
時間節約：手動作業を大幅に削減
情報収集効率化：複数サイトのデータを自動統合
ワークフロー自動化：複数のアプリやサービスを連携
学習支援：動画コンテンツから学習資料を自動生成

### 🛍️ スマートショッピング機能
価格比較
※Amazonを見ると、右にこのようなメニュー表示がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/76af7c17-888c-4b23-ae33-b72155f29c6d.png)

最安値の例では、主要サイトの情報とモデルの違いに言及されてました。
正直、Amazonで買っとけばOKみたいなところあるので、わざわざ使うかは微妙という感想です・・w
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/9f0956cd-4a73-42c3-8b5d-cb1983b43dae.png)


### 📺 YouTube活用機能
コンテンツ処理
動画の要約、文字起こし、スライド生成が可能
例：インタビューから8枚のスライドを自動生成
→これについては先ほど動画の要約をしてもらいましたが、シンプルに良いです。
　ただ、YoutubeのURL載せての解説は他でも出来ますよね。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/85f2ef7b-2102-48b5-8e6d-332129a90732.png)


### 🤖 オートパイロット機能
#### SNSフィード自動処理
X（Twitter）のフィードを自動的にチェック
有料サイト自動操作
ChatGPT、Claude、Geminiのデータを自動収集

→Xのアカウントの投稿を分析してもらいました。
　自動で別タブ開いて過去投稿を遡ってるようでした。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/4966a8a2-a398-452d-9801-3e36c47c88a8.png)


### 🚫 広告ブロック機能
煩わしいバナー広告やポップアップを自動ブロック

### 🛠️ MCPストア
アプリ連携
700以上のMCPツールが利用可能
ワンクリックでインストール

→様々なアプリ連携と、個別でもMCPサーバーが追加できるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/e48f7467-b9fc-4236-9a87-775c68d28123.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/86d755a6-362c-4f50-a8b0-e54147317ab0.png)

## 便利そうなので、誰か有料プランで使いこなしてほしい
まだ表面的な機能しか使っていませんが、Chromeと同じ操作感・ブックマーク引き継ぎ・拡張機能も使えるので良いなと思いました。
Freeプランだとすぐにクレジット切れたので有料プランは必須かと思います。
CodeIgniterのZIP Library

CodeIgniterのZIP Libraryは、ZIPアーカイブファイルの作成や操作を簡単に行うためのライブラリです。

## 基本的な使い方

### ライブラリの読み込み

```php
$this->load->library('zip');
```

### 主要なメソッド

**ファイルの追加**

```php
// 単一ファイルを追加
$this->zip->add_data('filename.txt', 'ファイルの内容');

// 複数ファイルを追加
$data = array(
    'file1.txt' => 'ファイル1の内容',
    'file2.txt' => 'ファイル2の内容'
);
$this->zip->add_data($data);
```

**既存ファイルの追加**

```php
$this->zip->read_file('/path/to/file.txt');
```

**ディレクトリの追加**

```php
$this->zip->read_dir('/path/to/directory/');
```

**ZIPファイルのダウンロード**

```php
$this->zip->download('archive.zip');
```

**ZIPファイルの保存**

```php
$this->zip->archive('/path/to/save/archive.zip');
```

## 実用的な例

```php
class FileController extends CI_Controller {
    
    public function create_zip() {
        $this->load->library('zip');
        
        // データベースからデータを取得してCSVファイルを作成
        $csv_data = $this->generate_csv_data();
        $this->zip->add_data('report.csv', $csv_data);
        
        // 画像ファイルを追加
        $this->zip->read_file('./uploads/image.jpg');
        
        // テキストファイルを動的に作成して追加
        $readme = "このアーカイブにはレポートと関連ファイルが含まれています。";
        $this->zip->add_data('README.txt', $readme);
        
        // ZIPファイルをダウンロード
        $this->zip->download('report_package.zip');
    }
}
```

## 注意点

- **メモリ使用量**: 大きなファイルを扱う際は、メモリ制限に注意が必要です
- **ファイルパス**: `read_file()`や`read_dir()`を使用する際は、適切なファイルパスを指定してください
- **文字エンコーディング**: 日本語ファイル名を扱う場合は、文字エンコーディングに注意が必要です

ZIP Libraryは簡単な操作でアーカイブファイルを作成できるため、レポートの一括ダウンロード機能やバックアップ機能の実装に便利です。​​​​​​​​​​​​​​​​
年収500万のPGでも挫折したSQLのLEFT JOINの質問

**質問**
下記二つのテーブル
TableA：
| PK1 | PK2 |
|:-:|:-:|
| 2  |  3 |


TableB：
| PK1 | PK2 |
|:-:|:-:|
| 2  |  3 |
| 2  | 3  |
|  3 | 3  |

```sql:
SELECT * 
FROM TableA AS A
LEFT JOIN TableB AS B 
  ON A.pk1 = B.pk1 AND A.pk2 = B.pk2
WHERE A.pk1 = 2;
```
上記のSQLを実行すると何行取得されますか？

****
**経緯**
友達に質問したら、「1行」即答されてしまい、その問題で挫けていた自分に驚きました。
正解は２行です！
****
**実行の流れ**
LEFT JOINを実行：
Aの(2,4)に対し、Bの(2,4)が2行マッチする。
よって、2行に増える。
WHERE A.pk1 = 2 は、Aのpk1が2なので条件に合う。

**出力結果の例**
A.pk1	A.pk2	B.pk1	B.pk2
2	4	2	4
2	4	2	4

**SQLite3で検証**
テーブル作成 + データ挿入
```sql:
-- TableAを作成
CREATE TABLE TableA (
    pk1 INTEGER,
    pk2 INTEGER
);

-- TableBを作成
CREATE TABLE TableB (
    pk1 INTEGER,
    pk2 INTEGER
);

-- TableA にデータを挿入
INSERT INTO TableA (pk1, pk2) VALUES (2, 4);

-- TableB にデータを挿入
INSERT INTO TableB (pk1, pk2) VALUES 
    (2, 4),
    (2, 4),
    (3, 3);
```
ターミナルで sqlite3 を起動します。
```bash:

pi@respberry:~ $ sqlite3 sample.db
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> CREATE TABLE TableA (
   ...>     pk1 INTEGER,
   ...>     pk2 INTEGER
   ...> );
sqlite> CREATE TABLE TableB (
   ...>     pk1 INTEGER,
   ...>     pk2 INTEGER
   ...> );
sqlite> INSERT INTO TableA (pk1, pk2) VALUES (2, 4);
sqlite> INSERT INTO TableB (pk1, pk2) VALUES
   ...>     (2, 4),
   ...>     (2, 4),
   ...>     (3, 3);
sqlite> SELECT * FROM TableA;
2|4
sqlite> SELECT * FROM TableB;
2|4
2|4
3|3
sqlite> SELECT *
   ...> FROM TableA AS A
   ...> LEFT JOIN TableB AS B
   ...>   ON A.pk1 = B.pk1 AND A.pk2 = B.pk2;
2|4|2|4
2|4|2|4
sqlite>
```
最後にポチっと実行すると、結果は2行でした！
検証終了！