OmniAICreator/Qiita-1.07M huggingface dataset:
jqの長いフィルターを改行したい

# 目次

- [やりたいこと概要](#やりたいこと概要)
- [どうやるか](#どうやるか)
  - [結局どうしたらいいか](#結局どうしたらいいか)
- [ややデメリット](#ややデメリット)
  - [最初は何やってるかわかりにくいように見える](#最初は何やってるかわかりにくいように見える)
  - [VSCodeにはJSONとして認識されない（折りたたみが使えない）](#vscodeにはjsonとして認識されない折りたたみが使えない)
- [おわりに](#おわりに)

# やりたいことの概要

フィルター処理が多いjqコマンドを書いていると、思いがけず横に長くなってしまいがちなので、可読性向上のために改行したくなるものです。

安易にバッククォートで改行できるかなぁと思って試行錯誤していたら、結構手間取ったのでメモとして残しておきます。

# どうやるか

例えば、以下のようなデータがあるとします。

```json:test_data.json
[
    {"id": "1", "name": "Yamada Taro", "age": 16, "score": 90},
    {"id": "2", "name": "Suzuki Hanako", "age": 17, "score": 85},
    {"id": "3", "name": "Tanaka Ichiro", "age": 15, "score": 88},
    {"id": "4", "name": "Sato Emiko", "age": 16, "score": 92}
]
```

このデータから、各要素のキー: `id`, `name` , `score` だけを抽出し、新たなキーを付与して別の配列として再構成するものとします。

これは以下のようなコマンドで実現できます。

```bash
cat test_data.json | jq '[.[] | {student_id: .id, student_name: .name, student_score: .score}]'
```

もしかするとこれくらいなら許容できるかもしれませんが、JSONが1行に記載されており、一見では最終的にどのようなJSONが出力されるのかがイメージしづらいです。
jqで新しいJSONを定義する部分は、key-value がパッと見でわかったほうが良さそうです。

そこで、jqコマンドのクエリ部分を改行しようと思い、まずは次のような安直に改行したコマンドを考えましたが、エラーになってしまいました。

```bash: だめだった例
jq '{\
    student_id: .id, \
    student_name: .name,\
    student_score: .score\
}'
```

どうやら、シングルクォート内のバックスラッシュによる改行はエラーとなってしまうようです。（もしかしたら常識？）

## 結局どうしたらいいか

結論としては、「シングルクォートで一度jqのクエリのクォートを抜けて、バックスラッシュで改行できる」ことがわかりました。

なので、前述したコマンドは以下のようにすれば改行を含んだままコマンドが通ります。

```bash:うまくいった例
jq '{'\
'    student_id: .id, '\
'    student_name: .name,'\
'    student_score: .score'\
'}'
```

イメージとしては、シングルクォートを一度挟むことで、jqのクエリ文字列を一旦解除している感じでしょうか。

そういえば、jqのクエリの中でシェルの変数を展開するときも、一旦シングルクォートでjqを解除するような記述をする必要がありました。

参考: [https://qiita.com/takehilo/items/79a89a943f1ae1e6be0b#フィルタの一部を変数化](https://qiita.com/takehilo/items/79a89a943f1ae1e6be0b#%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%81%AE%E4%B8%80%E9%83%A8%E3%82%92%E5%A4%89%E6%95%B0%E5%8C%96)

# ややデメリット

このjq改行メソッド（いま名付けた）には、少しばかりデメリットがありそうです。

## 最初は何やってるかわかりにくいように見える

個人的にはあまり見慣れない記法だったので、最初は少し抵抗のある記述でした。

複数人で開発を行っている場合などには、もしかしたら最初の私と同じように抵抗感があるメンバーもいるかも知れません。

## jqクエリのJSONはVSCodeにはJSONとして認識されない（折りたたみが使えない）

当たり前っちゃ当たり前なんですが、シングルクォートで囲まれてるので、jqクエリ内にあるJSONは改行したとてVSCodeにはJSONとして認識されませんでした。

VSCodeでコードやJSONなどのファイルを扱う際、ソースのグループに応じてリソースを折りたたんだり開いたりできますが、それができません。

# おわりに

実はこの記事が私のQiita初記事です！
この記事とそんなことは全く関係ないのですが、めでたさのあまり最後に書いてしまいました。

この記事がどなたかの役に立てたら幸いです！
SNMP community で VRF を指定した

# 概要
cisco の NW機器（C9200）に監視サーバからログインできない事象が発生。
調べてみるとどうやらMIBの取得に失敗しているようで、SNMP関連の設定ミスなのではないかとあたりをつけ、ログインしようとしているIPアドレスに紐づいたvrfをsnmp communityの設定にも紐づけてあげることで解決。

# 結論
まずvrfの設定は以下。
```a:vrf
ip route vrf {VRF name} x.x.x.x x.x.x.x x.x.x.x
```

SNMP Community で設定した内容は以下。
```a:snmp community
snmp-server community {community name} RO {VRF name}
```

以上。
送信したメールが迷惑メールにならないように

# はじめに
システムやアプリケーションを開発していると、**メール送信**は避けて通れない重要なタスクの一つです。
ですが、そのメールが受信者側の**迷惑メール**フォルダに入ってしまうと、ビジネスの信頼を失うだけでなく、場合によっては大きな損失につながることもあったりします。

この記事では、メールが正しく届けられるようにするための基本的な**メール認証**についてまとめました。
メール送信を実装する際のお役に立てれば幸いです。

# なぜメール認証が必要なのか？
まず、メール認証がなぜ重要かについて。基本的に、メール認証の目的は以下の3つです。

- 送信者の正当性を証明する（本物だよ！と証明する）
- 受信者に安心感を与える
- なりすましやフィッシングを防ぐ

これらを実現するために、**SPF**、**DKIM**、**DMARC**といった認証の技術を使います。
これらをきちんと設定すれば、迷惑メールフォルダに振り分けられるリスクを減らしてメールの到達率を大幅に改善できます。

# SPF
SPFは「このドメインからメールを送信して良いサーバーはこれです」と宣言する仕組みで、これを正しく設定することで、なりすましメールを防ぎ、メールの信頼性を高めることができます。

## SPFレコードの作成例
例えばexample.comからメールを送る場合、DNSに次のようなレコードを追加します。
```
example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 include:_spf.google.com ~all"
```

それぞれを解説すると、
- v=spf1：SPFのバージョンを指定
- ip4:192.0.2.0/24：このIPアドレス範囲からのメールを許可
- include:_spf.google.com；Googleのサーバーも許可
- ~all：許可されていないサーバーからのメールは警告に

:::note warn
SPFのincludeは最大10個までしか使えず、多すぎると無効になります。
:::

また、SPFはメール転送時に失敗することがあります。
そのため、SPFだけでなく、DMARCやDKIMと併用していくのことが重要になります。

# DKIM
DKIMは、送信したメールに電子署名を付けることで、送信者を認証し、メールが途中で改ざんされていないことを保証します。
簡単にいうと、途中で変なことされてないよ！と証明できる仕組みになります。

## DKIMの設定手順
1.鍵を作る
まずは秘密鍵と公開鍵を作成します。

```bash
openssl genrsa -out dkim_private.key 2048
openssl rsa -in dkim_private.key -pubout -out dkim_public.key
```

2.公開鍵をDNSに登録
公開鍵をDNSレコードに設定します。

```plaintext
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=公開鍵"
```
3.秘密鍵をメールサーバーに設定
使用しているメールサーバー（Postfix、SendGridなど）でDKIM署名を有効にします。

:::note warn
複数の鍵を使う場合はセレクター名（defaultなど）を一意に設定しましょう。
また、半年ごとや1年ごとに定期的に鍵を更新してセキュリティを確保することも重要です。
:::

# DMARC
DMARCはSPFやDKIMと連携して、メールがどう扱われるかを決める仕組みです。
さらに、メールが届いた状況をレポートで確認できるのも便利なポイント。レポートで不正なメールの送信元や失敗した認証の情報を収集できます。

## DMARCレコードの作成例
以下は「example.com」に設定するDMARCレコード例です。

```
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-failures@example.com; sp=reject; aspf=r"
```
- p=quarantine: SPF/DKIMに失敗したメールは迷惑メールフォルダに入れる
- rua: 集計レポートを送る先
- ruf: フォレンジックレポートを送る先
- sp=reject: サブドメインのポリシー
- aspf=r: SPFの緩やかな一致（Relaxed Alignment）

:::note info
まずp=noneでレポート収集から始め、問題がないことを確認してからquarantineやrejectに移行するのが安全です。
:::

# その他の運用ポイント
- スパムっぽい言葉を避ける
メールの内容に「無料」「今すぐ」「限定」などの言葉を多用すると、スパムフィルターに引っかかりやすくなります。
特に、「全額無料！」「クリック必須！」のような誇張表現はリスク高いので、避けた方がいいかもしれません。

例えば、
×：今すぐ限定セール！
○：この週末限定セールをお見逃しなく
など。

- HTMLとプレーンテキストを両方用意する
HTMLメールはデザイン性に優れているものの、例えば古いメールクライアントなど、すべての受信環境で正しく表示されるとは限らず、一部のスパムフィルターやメールクライアントではプレーンテキスト版がないと**不完全なメール**と判断されることもあったりします。

- 送信頻度の管理
大量のメールを短時間に送ると、受信サーバー側でスパム攻撃とみなされるリスクがあります。
丁寧にやるのであれば、以下のような安全な運用方法をとるといいかもしれません。

1.段階的に送信数を増やす
初回は1000通程度から始め、問題がないことを確認しながら徐々に増やしていく

2.送信間隔を調整する
メールサーバーがサポートするスロットリング（送信速度制限）機能を活用して、適切なペースで送信していく

3.リストの品質を保つ
定期的にアドレスリストを見直し、配信エラーが続くアドレスを削除することで、信頼スコアを維持する


---

このように、メール認証の基本的な部分をおさえた上で、日々の運用にも気をつけることで、迷惑メールフォルダに入るリスクを減らし、より信頼性の高いメール送信ができるようになります。
LPIC101_1 システムアーキテクチャ(主題101)　よくわからないところをAIに聞いてみた

丸暗記が苦手な私がLLPIC101_1を受験することとなった。
苦手な暗記をしなくてすむように、AIに質問しまくって、意味で理解するようにした。

以下、 **LPIC101_1 システムアーキテクチャ(主題101)** でAIに教えてもらったことを書いていく。AIが100%正しいとは言えないが、今回の目的は試験に合格することなので正確さは二の次とする。

こんなことも知らないのかと思われそうだが、誰かの役に立てれば嬉しい。

# システムアーキテクチャ(主題101)
### ハードウェア設定の決定と設定

<INS>全体的な流れ</INS>
ハードウェア(デバイスとして扱う)をカーネルが認識し/sysに情報提供
            ↓
/sysを監視しているudevデーモン(デーモン：バックグラウンドで動いてるプログラム）が発見し、/udevがデバイスファイル作成
            ↓
/procで一部のデバイス情報が表示される
            ↓
D-busがアプリケーション間でのデバイス連携を可能にする


カーネルモジュール(デバイスドライバを提供)
            ↓
ロード←必要なカーネルモジュールをカーネルに取り込む
            ↓
lsmodコマンド←ロードされたモジュールの確認
※手動の場合はmodprobe

<INS>initシステム（起動プロセス管理システム）の変遷</INS>
**sysvinit→upstart(あまり普及せず)→systemd**
 upstartから並列処理可能でイベント駆除型(状況に応じた対応が可能)
 upstartはjob、systemdはunit
 
<INS>用語など</INS>
- **モデム**
インターネットの信号を変換するもの
- **TA(ターミナルアダプタ)**
電話回線での通信時に使用されるもの
- **ACM(Abstract Control model) Communication Device**　
Abstract→抽象的な
通信機器など用途が目に見えない抽象的なデバイスなどに使用
- **/etc**
変更可能な設定ファイル
- **/proc**
実体のないファイルを格納、基本的に設定の変更等ができない
- **IRQ(割り込み要求)に関する情報**
 設定を変更することはないので/etc/ではなく/proc/interrupts
 おそらくたくさんあるのでinterruptは複数形
- **I/Oポートアドレスの情報**
上記と同じ理屈で/proc/ioports
 - **SATA**
 コンピューターのマザーボードと記憶装置を接続するインターフェース

 ### システムの起動
 - **dmesg**
 display messageの略、カーネルメッセージログを表示
 - **journalctl -k**
 kはカーネルの略→dmesgと同じ結果になる

 

  ### ランレベル/ターゲットの変更
  - **telinit q,init q**
/etc/inittab(SysVinit設定ファイル)の変更を即座に反映
q→quit 即座に
div要素でKeyboardEventが発火しない理由と対策【React】


## 問題のコード

以下のコードでは、`onKeyDown`イベントが発火しません。
```React:qiita.rb
  const startAction = (e: any) => {
    if (e.key === 'Enter' || e.key === ' ') console.log('hello');
  };
  
  return (
    <div
      className='h-screen w-full flex items-center justify-center'
      onKeyDown={startAction}
    >
      スペースかEnterを押してね!
    </div>
  );
```
これではeventが起こりませんでした。
## 原因

以下の2点が原因です

- `KeyboardEvent`はフォーカスを持つ要素でのみ発火する
-  `div` 要素はフォーカスを持たない



> ### Interactive elements must be focusable
> If the user can interact with an element (for example, using touch or a pointing device), 
> then it should be focusable using the keyboard. You can make it focusable by adding a 
> `tabindex=0` attribute value to it. 
> That will add the element to the list of elements that can be focused by pressing the Tab key, 
> in the sequence of such elements as defined in the HTML document.

https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Keyboard

https://react.dev/reference/react-dom/components/common#keyboardevent-handler

## 解決法

`div`に`tabIndex`属性を追加して、フォーカス可能にすることで解決できます。

:::note info
`HTML`の場合は`tabindex`ですが、`JSX`の場合は`tabIndex`になります
:::

それでは`tabIndex`を`div`に追加します。以下は修正後のコードです

```React:qiita.rb
  const startAction = (e: any) => {
    if (e.key === 'Enter' || e.key === ' ') console.log('hello');
  };
  return (
    <div
      tabIndex={0}
      className='h-screen w-full flex items-center justify-center'
      onKeyDown={startAction}
    >
      スペースかEnterを押してね!
    </div>
  );
```
結果↓
```React:qiita.rb
hello
```
新卒2年目エンジニアの学習記録：学習11カ月目

# はじめに
新卒2年目エンジニアのA.Kと申します。
**1月から職場が変わり、研修ではフルスタックに技術を学んでいます**。
**毎日出社の中、思考錯誤して学び続けているので**その内容について書いていきます。

先月の記事です↓

https://qiita.com/AK_React/items/38db01fb08f8db282130

# 学習11カ月目にやったこと

### <font color="Red">**AWS・Dockerデビュー**</font>

**これまでフロントの技術を学習してきましたが、業務で必要なAWS・Dockerのキャッチアップを始めました**。
ありがたいことに、研修の中で学習できる環境があるので、下記のチュートリアルを参考に手を動かしています。

https://zenn.dev/shitakemura/books/todo-app-book/viewer/introduction

個人的に、インフラ領域は実態が掴みづらく苦手意識が強い＆AWSコンソールの情報量の多さに圧倒されておりました。。いったい何がどうなってるんだ。。？と何度思ったことか笑
***

### <font color="Red">**毎日学習の振り返りタイムを設ける**</font>

今月から、帰路につく電車の中で始めました。
背景としては、**研修で学んだことを確実に自分のものにしたい＋SEとして自信が持てない自分と向き合いたい**　という想いからです。

特に、今は新しい分野を学んでいるのもあって、エラーの解消に数時間かかることもあったり、覚えるべきことが多かったり。。
こうした中で「今日なにしたっけな〜」と振り返ることで、知識の定着を図り、次に活かすことができると考えています。

まだ模索中ですが、**下記の流れでAIと一緒に振り返り**をしています

・**業務中にエラー解消のプロセスや自分の気づき・学んだこと等をざっくばらんにメモしておく**
・**AIに「プロのSEとプロの心理カウンセラーそれぞれの視点から、本日の振り返りに対してアドバイスをください。」と上記のメモを投げる。**

**出力例：**

↓AWS（CloudFront＋S3）でデプロイ時に発生したエラーについて

![IMG_0184.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/39074a3f-ee12-bfca-5e5e-374458b5a30a.jpeg)

↓自分の課題に応じて寄り添った回答をくれます。

![IMG_0185.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/596e71b0-3f31-2ab1-879c-ba31695abc35.jpeg)

最後に全体の総括もしてくれます。
![IMG_0186.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/1d2cc62f-4b9f-518b-45c4-4e03db8daddd.jpeg)

ちなみに、心理カウンセラーの視点からもアドバイスをもらっていることの理由としては、私自身が「その日できなかったこと」にばかり目を向けてしまう癖があるからです。

しばらくこの取り組みを続けた上で、変化や発見があればまた発信しようと思います。

### <font color="Red">**ITに関連するポッドキャストを聞く**</font>
**通勤時間を少しでも有効活用したくて、耳からの学習も取り入れました**。
今聞いてるのは下記の２つです！他にオススメあれば教えてください！

あの有名なゆる言語学ラジオが親元、雑談ベースで技術の話してます。

https://open.spotify.com/show/32qgIhAHYnseWxiGyrFzSt


駆け出しエンジニアからのスキルアップがコンセプトです。

https://open.spotify.com/show/2uv9mONog0nr9q5YJJsvIt

どちらも純粋に面白い&つよつよSEの思考を知ることができて有益だと思います。
時間が限られているからこそ、五感をフルに使って学習できたら良いですね！

# おわり
以上が11カ月目の振り返りでした！
**新年とともに環境が変わったこともあって、改めて今まで向き合えていなかった自分の課題や弱さと対峙して、成長に繋げていきたい**。そんな思いが強くなっています。
（この辺のお話はまたNoteにでも書こうかな）
私の取り組みや葛藤が、誰かにとっての励みになればと思います。

今年はXの投稿も頻度高めにやっていくので、一緒に頑張るぜ！って方はぜひフォローお願いします！

https://x.com/AK_React
Cisco Catalyst 4948 で interface を SYSLOG監視したかった。

# 概要
NW機器のマイグレーション時に抜き差しするポートを対象機器上でSYSLOG監視し、対象ポートが正しいか判断したかった。
コンソール接続すればデフォルトでSYSLOG監視してくれる（C2960はデフォルトを確認済）と思っていたが、C4948は画面上に表示されなくて調べたので、備忘録として残す。

# 結論
以下のコマンドで設定すれば解決。

```a:全インターフェースへ適用
Catalyst(config)#ogging event link-status global
```

特定のインターフェースのみに適用する事も可能
```a:特定のインターフェースへ適用
Catalyst(config)#interface range GigabitEthernet 1/1
Catalyst(config-if)#logging event link-status
```
以上。
(４次式) 例題1:集中荷重を受ける片持ち梁 ＜【② 構造力学の「構造」例題】様,AI先生に積分→４次式に変換できませんでした。


・積分→４次式に変換をあきらめました。私は、ちょっと図々しかったです。
・未 手作業

:::note info
元　 [(積分)例題1:集中荷重を受ける片持ち梁 へ](https://qiita.com/mrrclb48z/items/3247352386176f692a1d)
　　[私のsympyの目次 へ](https://qiita.com/mrrclb48z/items/b6207ec7e429458fe7a7
)
:::

```
下記のvが4次式なので、最初にvを4次式と定義して、積分を使わないで、微分を使って書き換えて解いて下さい。
(ソースコード貼り付け。省略。ver0.2)
```
# ChatGPT先生へ
>(回答抜粋) 回答ソースコード
```python
from sympy import symbols, Eq, solve, diff

# 変数と未知係数の定義
x, L, P, EI = symbols('x L P EI')
a4, a3, a2, a1, a0 = symbols('a4 a3 a2 a1 a0')  # 未知係数

# 仮定する4次式
v = a4 * x**4 + a3 * x**3 + a2 * x**2 + a1 * x + a0

# 境界条件
# 1. 幾何的境界条件: v(0) = 0
eq1 = Eq(v.subs(x, 0), 0)

# 2. 幾何的境界条件: v'(0) = 0
eq2 = Eq(diff(v, x).subs(x, 0), 0)

# 3. 力学的境界条件: EI * v'''(0) = -P
eq3 = Eq(EI * diff(v, x, 3).subs(x, 0), -P)

# 4. 力学的境界条件: EI * v''(L) = 0
eq4 = Eq(EI * diff(v, x, 2).subs(x, L), 0)

# 連立方程式を解く
solutions = solve([eq1, eq2, eq3, eq4], [a4, a3, a2, a1, a0])

# 解を代入して変位式を求める
v_final = v.subs(solutions).simplify()
print("v(x) =", v_final)

# 必要ならば展開形を出力
v_final_expanded = v_final.expand()
print("展開形 v(x):", v_final_expanded)
```
**sympyのコードが間違っていませんか。a2がでています。**
(質問多数。繰り返し多数。省略)
**...あきらめました。**

# GeminiT先生へ
>(回答抜粋) 回答ソースコード
???改良されたコード例
```python
from sympy import *

# 変数の定義
x = symbols('x')
P, L, EI = symbols('P, L, EI')

# 4次多項式を仮定
v = C1*x**4 + C2*x**3 + C3*x**2 + C4*x

# 微分方程式を立てる
EI*v.diff(x, 4) = 0  # 片持ち梁の微分方程式

# 境界条件
bc = [
    v.subs(x, 0),  # x=0 でたわみv=0
    v.diff(x).subs(x, 0),  # x=0 で傾きv'=0
    -EI*v.diff(x, 2).subs(x, 0) - P,  # x=0 で曲げモーメントM=-EI*v''=P
    -EI*v.diff(x, 3).subs(x, L)  # x=L でせん断力Q=-EI*v'''=0
]

# 連立方程式を解く
sol = solve(bc, [C1, C2, C3, C4])

# 解を代入
v = v.subs(sol)

# 結果を表示
print(v)
```
(質問多数。繰り返し多数。省略)
??? # 微分方程式を立てる
??? EI*v.diff(x, 4) = 0  # 片持ち梁の微分方程式
**...あきらめました。**
S3とWebKitのディスクキャッシュが引き起こすCORSエラーの解決策

## 問題の概要
SP(iOS)のChromeおよびSafariで、チャットボットサービスのチャットウィンドウ内に画像を表示する際、最初の表示は問題なく行われるのに、ウィンドウを一度閉じて再度開くとCORSエラーで画像が表示されなくなる現象が発生していました。この問題は、PC(macOS)のChromeでは発生しませんでした。

## 問題の原因
今回、クライアントからバックエンドのAPIを叩き、バックエンドで生成されたS3の署名付きURLを介して画像を取得するプロセスを採用していました。この際、S3のCORS設定でフロントエンドのURLを適切に設定していたのですが、iOSデバイスでの二度目のアクセス時にブラウザのディスクキャッシュが使用されて、`Access-Control-Allow-Origin`ヘッダがレスポンスに含まれないためにCORSエラーが発生していました。

## 解決策
WebKitをレンダリングエンジンに使用するブラウザ(Chrome(iOS), Safari(iOS), Safari(macOS))では、画像などの静的リソースをキャッシュする際にCORSに関するヘッダー(`Access-Control-Allow-Origin`)を省略して保存する挙動が確認されました。

この問題を解決するために、S3から画像を取得する際にキャッシュを無効にするための`ResponseCacheControl: 'no-cache'`オプションをGetObjectリクエストに明示的に含めました。これにより、すべての画像リクエストがネットワークを通じて行われて、キャッシュされたレスポンスが原因でCORSエラーになるのを防ぐことができました。

```javascript
const command = new GetObjectCommand({
  Bucket: bucketName,
  Key: key,
  ResponseCacheControl: 'no-cache'  // キャッシュ無効化
})
```
新年の目標をたてる！マンダラチャートアプリを作成しました

マンダラチャートを作成できるWEBアプリをリリースしました。
![chrome-capture-2025-0-18.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/1d72cfa3-2776-a73c-34d7-1f0158d2b5df.gif)

https://mandalachart.jp/mandalachart

ログイン不要で使えるので、是非使ってみてください！

# URL
#### WEBアプリ
https://ikenohotori.github.io/MandaraChartApp/

#### GitHub
https://github.com/ikenohotori/MandaraChartApp

# 目的
2025年の目標を書きたい！と思い、マンダラチャートを作成できるアプリ探していましたが、手軽に使えるものが見つかりませんでした。せっかくなので自分で作ってみました（新年の時期はとっくに過ぎてしまいましたが）

# 機能
- マンダラチャートを表示する
- 目標を入力して保存する（**目標はブラウザのローカルストレージに保存しています。ブラウザの履歴データを削除すると消去されます**）


### 一覧画面
PC
![mandaraChartApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/c992300e-b538-3ffa-9420-cceb7ef8618a.png)

スマホ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/d2881da0-ef05-edeb-af10-16d37cc82651.png)

### 作成画面
PC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/7a674e3d-7ce4-e004-d9e4-f26cc7afbfd6.png)

スマホ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/d20eca72-a4df-69b5-cecf-6ea8b01d56fd.png)


# 感想
新川崎市の改善要望のアンケートのサイトを見ていたら、回答の一時保存ボタンでデータを保存しており、ブラウザのストレージが使えることに気づきました。そこから一気に道が拓けたので、改めて色々なサイトを触ってみることは大事だと思いました。

感想や改善要望があればぜひご連絡ください！
Mujocoインストールメモ

# WSL2へのUbuntuインストール

- 前提条件を整えておく（BIOS設定、拡張機能にチェックなど）

PowerShellを起動して以下を実行する



```
# WSLのインストール

wsl --install
wsl --set-default-version 2

# ディストリビューションの選択
wsl --list --online

# Ubuntuインストール
wsl --install -d Ubuntu-22.04
```

# Mujocoのインストール
```
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential libgl1-mesa-dev libosmesa6-dev \
    patchelf python3 python3-pip python3-venv unzip wget

# python3をデフォルトにする
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1

# 以下はバージョンに合わせて変える
wget https://github.com/google-deepmind/mujoco/releases/download/3.2.7/mujoco-3.2.7-linux-x86_64.tar.gz

tar -xvzf mujoco-3.2.7-linux-x86_64.tar.gz
sudo mv mujoco-3.2.7 /opt/mujoco

# Pythonのインストール
pip install mujoco gym numpy
```


# パスの設定

rcファイルに追加
```
export MUJOCO_HOME=/opt/mujoco
export LD_LIBRARY_PATH=$MUJOCO_HOME/bin:/usr/lib/wsl/lib:$LD_LIBRARY_PATH
export PATH=$MUJOCO_HOME/bin:$PATH
```

# 動作確認
```
# GPUが有効なことを確認
nvidia-smi

# OpenGLが有効なことを確認
# 出力に「OpenGL renderer」と「NVIDIA」の情報が含まれていればOK
glxinfo | grep OpenGL
```

以下の内容を保存し実行
```python:test_mujoco.py
import mujoco
from mujoco.viewer import launch

# XMLモデルファイルを読み込む
model = mujoco.MjModel.from_xml_path('/opt/mujoco/model/humanoid/humanoid.xml')
data = mujoco.MjData(model)

# ビューアを起動
launch(model, data)
```

動作画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/800891/bde363d7-7f10-8675-646f-4225a9b19ecf.png)
【ServiceNow】選択肢がバグったら

:::note info
バージョンはVancouverです。
:::

### 問題概要
選択肢がバグる。一番下は作成していない選択肢です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/a2e167b8-4d87-a566-3e68-94c27f7131aa.png)

### 問題の再現
従業員テーブルに「職務カテゴリー」項目を新設、サンプルの選択肢を3つ作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/ec8094df-071a-bba6-4da0-afde862a7193.png)
フォーム画面で確認（英語）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/56924589-8c49-eefc-67d8-43e228add196.png)
フォーム画面で確認（日本語）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/5c73503e-75a2-b053-414d-0aaa1aef742f.png)
「カスタマーエクスペリエンスと顧客関係管理」を選択して更新します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/af027cd2-fb5c-5ebb-ef17-442b20547393.png)
更新したレコードを確認します。あれ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/899e2386-d7e1-eb6f-3622-73847ae09a64.png)
### 原因
選択肢の値の最大長は40です。
参考：[選択肢リストの定義を表示する](https://www.servicenow.com/docs/bundle/vancouver-platform-administration/page/administer/field-administration/task/t_ViewChoiceListDefinitions.html)
辞書エントリに選択肢は増えていませんが、フォーム画面上で見ると選択肢の最大長40を超える選択肢の物理名が勝手に追加されているように見えます。
またよく見ると不自然なところで途切れています。数えてみるとちょうど40です。
> customer experience and relationship man

選択肢を作成するときエラーは出ないので余計に分かりにくい。

### 対応：選択肢の長さを40におさめる
最大長は40と決まっているので40におさまるように選択肢を作成し直しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/2fe74230-88d4-ed6a-d7ed-7e486ffb1209.png)
フォーム画面で確認。
レコードを更新してもバグは起きません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931295/8589cae9-a5ba-6d09-8f82-112f56a53bb3.png)

### 余談
こちらは業務で実際に起きたバグです。
環境壊したかもと大変焦りました。
選択肢で日本語が40を超えることは滅多に無いと思いますが、英語に訳したとき長さが40を超えてしまうというのはあり得るかもしれません。
英語に訳したときの最大長にも注意が必要です。
Laravelでカスタムバリデーション時にフォームの値を保持する方法

## 起こっている現象
リクエストバリデーションの他にコントローラー内でチェックを行い、引っかかったら元の画面にreturn viewで返していた。
```php:元のコード
public function store(Request $request)
{
    // バリデーション処理
    $isCheck = ...;
    
    if($isCheck){
        session()->flash('status', 'フォームの内容に問題があります。');
        return view('create');
    }
}
```
するとview側でoldヘルパ関数を使っていても値が保持できず消失してしまった。

## back()とwithInput()を使用する
view()ではなく、redirect()->back()->withInput()を使用します。
```php:修正後のコード
if($isCheck){
    session()->flash('status', 'フォームの内容に問題があります。');
    return redirect()->back()->withInput();
}
```
これでフォームの値を保持することができました。
Enabling Self-Signed SSL Certificates in Java Runtime


## Prerequisites

- Java
- Windows environment

## Procedure

1. Download the certificate. (It's easiest to open it in a browser by specifying the host and port number, then export it from "Certificate Details" and save it to your local disk.)
2. Run Command Prompt as 'Administrator'. (Administrator privileges are necessary to add to the keystore.)
3. Execute the following command:
```
"c:\Program Files\Java\jre1.8.0_241\bin\keytool.exe" -import -trustcacerts -file c:\work\yourhost.crt -keystore "c:\Program Files\Java\jre1.8.0_241\lib\security\cacerts"
```

---
Javaのランタイムで自己署名のSSL証明書を使えるようにする

# 前提

- Java
- Windows環境

# 操作方法

1. 証明書をダウンロードする。（ホストとポート番号を指定してブラウザで開き、「証明書の詳細」からエクスポートしてローカルディスクに置くのが簡単）
1. コマンドプロンプトを'管理者権限'で実行する（管理者権限でないとキーストアに追加できない）
1. 以下のようなコマンドを実行する
```
"c:\Program Files\Java\jre1.8.0_241\bin\keytool.exe" -import -trustcacerts -file c:\work\yourhost.crt -keystore "c:\Program Files\Java\jre1.8.0_241\lib\security\cacerts" -alias mykey1
```

### help
```
>"c:\Program Files\Java\jre1.8.0_241\bin\keytool.exe" -import -help
keytool -importcert [OPTION]...

証明書または証明書チェーンをインポートします

オプション:

 -noprompt                       プロンプトを表示しない
 -trustcacerts                   cacertsからの証明書を信頼する
 -protected                      保護メカニズムによるパスワード
 -alias <alias>                  処理するエントリの別名
 -file <filename>                入力ファイル名
 -keypass <arg>                  キーのパスワード
 -keystore <keystore>            キーストア名
 -storepass <arg>                キーストアのパスワード
 -storetype <storetype>          キーストアのタイプ
 -providername <providername>    プロバイダ名
 -providerclass <providerclass>  プロバイダ・クラス名
 -providerarg <arg>              プロバイダ引数
 -providerpath <pathlist>        プロバイダ・クラスパス
 -v                              詳細出力

使用可能なすべてのコマンドについては"keytool -help"を使用してください

C:\Windows\System32>
```



---

以上.
読書感想文「Gitlabに学ぶ。パフォーマンスを最大化させるドキュメンテーション技術」

# 書籍名「Gitlabに学ぶ。パフォーマンスを最大化させるドキュメンテーション技術」
翔泳社
著：千田和央
監修：伊藤俊廷/佐々木直晴

# 本稿の目的
・読んでいて、印象に残った箇所を記録するため

# 対象読者
チーム開発で認識のズレに課題を感じている人

# 読もうと思った動機
・「GitLabに学ぶ 世界最先端のリモート組織のつくりかた ドキュメントの活用でオフィスなしでも最大の成果を出すグローバル企業のしくみ 」を元々読んでいて、その新作が出たとのことなので　読もうと思いました。

# 印象に残った部分

## p3 はじめに
「ドキュメント」と「テキスト」という素晴らしいツールを持っているにもかかわらずそれを使いこなせない状態にある。
→うまく使いこなせれば、時間や場所価値観の違いを乗り越えて、コラボレーションすることが可能になる。


## p24 GitLab Hand
ドキュメントの作成コストは高いという暗黙の内に考えられている。
そのため済ますこと多い。
ドキュメント作成のコストの大半は、
「頭の中にあるアイディアを言語化すること」
「文章構成を構想すること」に割かれている。

## p39 ドキュメントの大きな価値
ドキュメントがあることで「人と人がわかり合える」


## p44 gitlab　handbook
・公式情報はハンドブックのみ集約するというルールを定めています。
・「信頼できる唯一の情報源」(SSOT = Single Source Of Truth)
・「すべては下書き」という行動原則がある。より良い判断基準や記述が見つかれば常に改善を続けていく。

## p46　ライブドキュメント
・参加者全員がミーティングしながら記載するという方法、話された内容をもれなく記録することができる

## p52 かすかな鉛筆は鮮明な記憶にまさる
・技術や知識がすべて口伝で行われていたとしたら誤って伝わってしまったり、
何らかの事故で失われてしまったりすることもあるかもしれません。

・ドキュメントという客観的な場でお互いの情報をアウトプットして、確認し合うことが効果的なのです。

## p53　パフォーマンスの非効率
以下のような問題は、実はドキュメントによってほとんど解決できます。
・社会的手抜き
　個人がチームで作業をするときに、一人で作業するときと比べて手をぬきやすくなってしまう減少

・損失の調整
　他の人との調整を行う際に発生する損失のことです。


## p89 ドキュメントが無いことによるコスト
・アクセスしづらい
・透明性がない
・信頼性が低い
・記録性が低い



# 実践できること or 感想

## 感想
・今私が直面している問題についてよく書かれておりとても勉強になりました。
私も実務上ではドキュメントを書けていません。原因としては、以下が考えられます。
・書く時間がない
・学習コストが高い。身近にレクチャーできる人が少ない（忙しい）ので教わることができない。習得方法が独学になる。

ドキュメントがないことによる弊害は
・実装ミスが発生し手戻りが発生する
・仕様が曖昧になり、コミュケーションを何度も繰り返す

書きにくい環境だとしても、それでもやりようはあるとは思いますね。


## 実践すること

・Googleのテクニカルライティングコースを受講する。
・GitLabのテクニカルライティングコースを受講する。
・社内打ち合わせでライブドキュメントで議事録を取る
　カレンダーに議事録のURLを加えておく
WSLへのraylib/Exrayのインストール

# 1. Over View

どもども、あー、スカッシュゲームは作れましたけど、リファクタしております。
そうこういている間に、一週間連続投稿が途切れて。残念無念。

と、言うわけで本日は、並行してやってる別の方を記事にしておこうと思います。

題して、「WSLへのExrayをインストールする」です。

元記事はこちらでございます。

Exrayを使ってElixirで円を描画してみる
https://qiita.com/t-yamanashi/items/35f89051c53899e49d70

いやまぁ、元のraylibを入れてるだけなんですけどね。
https://dev.to/andevr/get-started-with-rayexraylib-for-elixir-53gl


# 2. 本日の手順

## 2.1 Raylibのインストール

まずは準備
```
sudo apt-get update -y
sudo apt-get install -y pkg-config
```

C言語のインストール
```
sudo apt-get  install clang
sudo ap-get install cmake
```

Raylibのインストール
```
sudo apt-get install libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev
sudo apt-get install glibc-source -y
```

そして！インストールしたライブラリを、LD_LIBRARY_PATHへ追加します。

あなたのユーザの~/.bashrcの最後へ、以下を追加してください。

```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
```

変更後、~/.bashrcを読み込みます。
```
source ~/.bashrc
```

## 2.2 WSLへのExrayをインストールする

上記の元記事の通りに、してください。
- exrayを追加
- ライブラリ取得＆コンパイル

```
onodera@NucBoxG5:~/hoge$ mix deps.get
onodera@NucBoxG5:~/hoge$ mix compile.exray
```

終わったら実行です。


補足：
セットアップ後、segmentation faultで動かない様でしたら、環境変数DISPLAYを設定してください。

export DISPLAY=:0
[Supabase]エラー：new row violates row-level security policy for table "study-record"

## 背景
React + Supabaseで学習記録アプリを開発している時、アプリ上で入力したデータをSupabase上のテーブルに追加できないエラーに遭遇した。

## エラー詳細
```json
{code: '42501', details: null, hint: null, message: 'new row violates row-level security policy for table "study-record"'}
```
※ここで、「study-record」はSupabase上に作ったテーブル名

## エラー原因
結論としては、Supabase上でテーブルに対するセキュリティポリシー（policy）を設定していなかったことが原因だった。

SupabaseはRow-Level Security (RLS) を使用して、データベースへのアクセス制御を強化しており、これにより、特定の条件を満たすユーザーのみがデータの挿入（INSERT）や更新（UPDATE）などの操作を行えるように制限されている。

## 解決方法
1. 下記画像の「Create policy」をクリック
![スクリーンショット 2025-01-18 13.53.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609373/ed5d1f47-3cc2-60bb-7c1f-ea1930152d8c.png)

2. 「Policy name」を設定し、「SELECT」操作を許可するポリシーを作成する場合、`using`句を`true`に設定します。これにより、すべてのレコードに対して`SELECT`が許可されます。
 ![スクリーンショット 2025-01-18 14.00.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609373/af4b30c1-145b-f885-9762-b07b42dc011a.png)

3. 最後に、作成したポリシーを「Save policy」を押して有効にし、エラーがなくなる事を確認する。

### 注意点
- `using`句を`true`に設定すると、全ての行に対して無条件で操作が許可されるが、特定のユーザーやデータに対してのみ許可を出すほうがセキュリティ上より安全。
例えば、特定の条件（ユーザーIDや役職など）に基づいてアクセス制御を行う方法が一般的であるらしい。
GORM 朝の体操（Go言語の ORM）

# はじめに
朝の体操シリーズは、プログラミング言語などを習熟するためのトレーニングメニューです。
今回は、GORM（Go 言語の ORM）の練習です。
繰り返しやって身につける、またはお手軽に GORM を体験したいという用途でも使えると思います。

※朝の体操シリーズ：[React 朝の体操](https://qiita.com/y74h1116/items/539bf7b7cdcb64e9984f)

# 「GORM 朝の体操」練習環境（Docker 環境）のありか
Github に置きました。
https://github.com/y74h1116/go-gorm-taiso
※README.md にコンテナの起動方法等を記載してありますので頑張って起動してください。

# 練習環境について
- 「GORM 朝の体操」練習用の Docker には PostgreSQL と Go 言語の実行環境を含めてあります。
- PostgreSQL には users テーブルが作られます。
- Go言語の実行環境には、GORM がインストールされます。
- GORM で、users テーブルを操作する練習ができます。
- users テーブルの定義は以下
``` storage/postgres/init/init.sql
CREATE TABLE "users" (
  "id" BIGSERIAL PRIMARY KEY,
  "user_name" VARCHAR(15),
  "email" VARCHAR(255) /* 練習用に UNIQUE は指定しない */,
  "password" VARCHAR(32),
  "location" VARCHAR(30),
  "created_at" TIMESTAMP DEFAULT current_timestamp,
  "updated_at" TIMESTAMP DEFAULT current_timestamp
);
```

# GORM 朝の体操の内容紹介

- main.go の下の方に練習問題があるので、そこに実装して → 実行・確認します。

- 練習：users テーブルにデータを insert しましょう
main.go に定義済みの変数 db、User 構造体を利用します。
``` main.go
// DB 接続インスタンス
var db *gorm.DB

// User 構造体 (users テーブルのモデル)
type User struct {
	ID        int
	UserName  string
	Email     string
	Password  string
	Location  string
	CreatedAt time.Time
	UpdatedAt time.Time
}
```
insert するデータを定義して、Create や Save メソッドを実行します。
``` main.go
+	// 回答例
+	// insert するデータを定義
+	newUser := User{
+		UserName: "taro",
+		Email:    "taro@aaa.com",
+		Password: "password",
+		Location: "tokyo",
+	}

+	// insert 実行
+	err := db.Create(&newUser).Error
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
```

- 練習：insert したデータの id を表示しましょう
db.Create が成功すると newUser.ID が設定されるので、fmt.Println で表示します。
``` main.go
+	// 回答例
+	fmt.Println("id:", newUser.ID)
```

- 練習：insert したデータを select で取得してみましょう
作成したデータを select 文で取得してみましょう

``` main.go
+	// 回答例
+	user := User{}
+	err = db.First(&user, "id = ?", newUser.ID).Error
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}

+	fmt.Println("User:", user)
```

- 練習：データの user_name を更新してみましょう
データの更新を試してみます。
``` main.go
+	// 回答例
+	user.UserName = "hanako"
+	err = db.Save(&user).Error
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
```

- 練習：データを delete しましょう
データ削除も試してみましょう。
``` main.go
+	// 回答例
+	err = db.Delete(&user).Error
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
```

# おわりに
飽きるくらいまで繰り返しやれば身につくかなと思います。
Flask - app.loggerが2重に出力される問題の解消

# 内容

AWS ECS上で実行しているFlaskアプリでログ出力（`app.logger.info()`）した際、  
CloudWatch logsに2重にログが出力される現象が発生したため、原因の調査、解消を行った

# 結論

以下の変更を行うことで解消

## 問題発生時のコード

```python
import logging
from flask import Flask

app = Flask(__name__)
logging.basicConfig(level=logging.INFO)  # ログレベル設定

app.logger.info('INFO')
```

## 問題解消後のコード

```python
import logging
from flask import Flask

app = Flask(__name__)
logging.getLogger().setLevel(logging.INFO)  # logging.basicConfig から logging.getLogger().setLevel に変更

app.logger.info('INFO')
```

# 原因

https://stackoverflow.com/questions/69044301/duplicate-logs-when-calling-logging-basicconfig  
によると、Pythonのloggingは階層構造をしており、下位から上位の階層にログが伝播する、  
`logging.basicConfig`を実行するとルートにロガーを設定しているとある  
また、この伝播を停止することで2重ログが解消できそう

## Flask、logging.basicConfig の挙動

`Flask`、`logging.basicConfig`によってloggingに設定されるconfig内容を確認

### Flask

[Flask Default Configuration](https://msiz07-flask-docs-ja.readthedocs.io/ja/latest/logging.html#default-configuration)によると、  
「もし自分でログ処理設定をしない場合、Flaskはapp.loggerへStreamHandlerを自動的に追加する」とある

### logging.basicConfig

[logging.basicConfig](https://docs.python.org/ja/3.13/library/logging.html#logging.basicConfig)によると、  
「デフォルトの Formatter を持つ StreamHandler を生成してルートロガーに追加し」とある

## logging-tree で logging の階層構造を確認

[logging-tree](https://pypi.org/project/logging-tree/)を使用して logging の階層構造を確認

### logging.basicConfig を実行しなかった場合の logging 階層構造

```text
<--""
   Level WARNING
   |
   o<--"app"
   |   Level NOTSET so inherits level WARNING
   |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
   |     Formatter fmt='[%(asctime)s] %(levelname)s in %(module)s: %(message)s' datefmt=None
   |
   o<--"asyncio"
   |   Level NOTSET so inherits level WARNING
   |
   o<--[aws_xray_sdk]
   |
   ...
```

treeの"app" にのみ Handler Stream が設定されていることがわかる

### logging.basicConfig を実行した場合の logging 階層構造

```text
<--""
   Level INFO
   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
     Formatter fmt='%(levelname)s:%(name)s:%(message)s' datefmt=None
   |
   o<--"app"
   |   Level NOTSET so inherits level INFO
   |   Handler Stream <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
   |     Formatter fmt='[%(asctime)s] %(levelname)s in %(module)s: %(message)s' datefmt=None
   |
   o<--"asyncio"
   |   Level NOTSET so inherits level INFO
   |
   o<--[aws_xray_sdk]
   |
   ...
```

treeのルート（""）と、"app" に Handler Stream が設定されていることがわかる  
また、ルートのログレベルにINFOが設定され、下位のログレベルにも継承されていることがわかる  
やはり"app"からルートにログが伝播することで2重ログが発生していると思われる  

# 解決方法

上記原因より、"app"のログをルートに伝播しない、もしくはルートに Handler Stream を設定しなければ良い  
`logging.basicConfig`の代わりに[logging.getLogger().setLevel](https://docs.python.org/ja/3.13/library/logging.html#logging.Logger.setLevel)でルートのログレベルを設定するように変更することで解消した
Laravel Artisan コマンド解説まとめ


## 基本コマンド

### 1. `about`
**説明**: アプリケーションの基本情報を表示します。

```bash
php artisan about

## 環境を表示
php artisan about --only=environment

## データベース情報表示

php artisan config:show database
```

---

### 2. `clear-compiled`
**説明**: コンパイル済みのクラスファイルを削除します。

```bash
php artisan clear-compiled
```

---

### 3. `docs`
**説明**: Laravelの公式ドキュメントを開きます。

```bash
php artisan docs
```

---

### 4. `down`
**説明**: アプリケーションをメンテナンスモードにします。

```bash
php artisan down
```

---

### 5. `up`
**説明**: アプリケーションをメンテナンスモードから復帰させます。

```bash
php artisan up
```

---

### 6. `serve`
**説明**: PHPの組み込みサーバーでアプリケーションを起動します。

```bash
php artisan serve
```

オプション: ポートを指定する場合

```bash
php artisan serve --port=8080
```

---

### 7. `migrate`
**説明**: データベースのマイグレーションを実行します。

```bash
php artisan migrate
```

---

## キャッシュ関連

### 8. `cache:clear`
**説明**: アプリケーションのキャッシュを削除します。

```bash
php artisan cache:clear
```

---

### 9. `config:cache`
**説明**: 設定をキャッシュして高速化します。

```bash
php artisan config:cache
```

---

## データベース関連

### 10. `db:seed`
**説明**: データベースにダミーデータを挿入します。

```bash
php artisan db:seed
```

特定のシーダークラスを指定する場合

```bash
php artisan db:seed --class=UserSeeder
```

---

### 11. `db:wipe`
**説明**: すべてのテーブル、ビュー、タイプを削除します。

```bash
php artisan db:wipe
```

---

## ルート関連

### 12. `route:list`
**説明**: アプリケーションで登録されているすべてのルートを一覧表示します。

```bash
php artisan route:list
```

特定のルートメソッドをフィルタリングする場合

```bash
php artisan route:list --method=GET
```

---

## 認証関連

### 13. `auth:clear-resets`
**説明**: 有効期限切れのパスワードリセットトークンを削除します。

```bash
php artisan auth:clear-resets
```

---

## ビュー関連

### 14. `view:cache`
**説明**: Bladeテンプレートを事前にコンパイルしてキャッシュします。

```bash
php artisan view:cache
```

---

### 15. `view:clear`
**説明**: コンパイル済みのビューを削除します。

```bash
php artisan view:clear
```

---

## Make系コマンド

### 16. `make:controller`
**説明**: 新しいコントローラクラスを作成します。

```bash
php artisan make:controller MyController
```

---

### 17. `make:model`
**説明**: 新しいEloquentモデルを作成します。

```bash
php artisan make:model Post
```

モデルにマイグレーションとファクトリを同時に作成する場合

```bash
php artisan make:model Post -mf
```

---

### 18. `make:migration`
**説明**: 新しいマイグレーションファイルを作成します。

```bash
php artisan make:migration create_posts_table
```

---

### 19. `make:seeder`
**説明**: 新しいシーダークラスを作成します。

```bash
php artisan make:seeder UserSeeder
```

---

### 20. `make:middleware`
**説明**: 新しいミドルウェアクラスを作成します。

```bash
php artisan make:middleware CheckUserRole
```

---

## マイグレーション関連

### 21. `migrate:fresh`
**説明**: すべてのテーブルを削除して再実行します。

```bash
php artisan migrate:fresh
```

---

### 22. `migrate:rollback`
**説明**: 最後に実行したマイグレーションをロールバックします。

```bash
php artisan migrate:rollback
```

---

## キュー関連

### 23. `queue:work`
**説明**: キューワーカーを起動してジョブを処理します。

```bash
php artisan queue:work
```

---

### 24. `queue:restart`
**説明**: 現在のジョブが終了した後にキューワーカーを再起動します。

```bash
php artisan queue:restart
```

---

## その他

### 25. `storage:link`
**説明**: シンボリックリンクを作成してストレージを公開します。

```bash
php artisan storage:link
```

---

## まとめ

以上がLaravelの主要なArtisanコマンドの解説とサンプルコードです。初めてLaravelを学ぶ方でも、これらのコマンドを使いながらアプリケーションを構築していくことができます。

Laravelのドキュメントやコミュニティを活用しつつ、自分のプロジェクトに合ったコマンドをどんどん試してみてください！
```
【ChatGPT】新しい知識を学ぶときに理解をサポートしてくれる思考方法をPromptにしてみました。


　どうも、カーブミラーです。

　今回は、新しい知識を学ぶときに理解をサポートしてくれる思考方法をPromptにしてみました。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　まずは、ニュースです。

　ChatGPTの
　　Custom instructions
　　　（カスタム指示）が、
　　　　新しくなりました。

　[OpenAI公式ポスト](https://x.com/OpenAI/status/1880323050798973295?t=OMFaIMr6OlOf5wkiKrnb4A&s=19)
>（ChatGPT翻訳）
>カスタム指示が更新され、ChatGPTの応答をより簡単にカスタマイズできるようになりました。
>
>新しいUIでは、ChatGPTに望む特徴、話し方、守ってほしいルールを伝えることができます。
>
>新しいUIは現在、chatgpt.comとWindowsのデスクトップで展開中であり、数週間以内にモバイルとMacOSのデスクトップにも提供される予定です。
>
>EU（欧州連合）、ノルウェー、アイスランド、リヒテンシュタイン、スイスのChatGPTユーザーにもまもなく利用可能になります。
>
>すでにカスタム指示を使用している場合、現在の設定に変更はありません。

　こちらがその画面。
![Screenshot_20250118-085357.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/e4c9015e-6d13-5f09-ac63-99e6e3169160.png)

　ChatGPTが
　　より個人に寄り添った回答を
　　　してくれるようになります。

　スマホアプリ版と
　　MacOSのデスクトップアプリ版は
　　　数週間以内に解放されるみたい。
***
　次は、
　　OpenAI o3-miniについて。

　[サム・アルトマンポスト](https://x.com/sama/status/1880356297985638649?t=f9PsdsKN4qovQP9IYDyVoA&s=19)
>（ChatGPT翻訳）
>o3-miniをテストしてくださった外部の安全性研究者の皆様、ありがとうございます。
>
>私たちは現在、バージョンを確定させ、リリースプロセスを開始しました。およそ2週間以内に出荷を予定しています。
>
>また、フィードバックをいただきました：APIとChatGPTを同時にリリースします！
>
>（とても良い感じです。）

　このポストのあと、
　　さまざまな質問に
　　　答えてくれています。

　【GPT-5】
　　　まだ確定的な情報はなく、
　　　2025年にGPTシリーズと
　　　oシリーズの統合を
　　　模索している段階。

　【o3】
　　　o1 proよりもっと賢い。
　　　OpenAIは今、o3に注目している。

　【o3-mini】
　　　「o1 proほどの性能はないが、
　　　　その分非常に高速」
　　　　　であることが大きな特徴。

　　　o3-miniはPlusユーザーも使える。
***
　では、【本題】です。

　今回は、
　　新しい知識を学ぶときに
　　　理解をサポートしてくれる
　　　　思考方法をPromptに
　　　　　してみました。

　＊＊＊に問題を入力して
　　送信してください。
```Text:理解をサポートするPrompt
問題「＊＊＊」

1. 問題について、まずその定義や本質的な側面を明確にしてください。それは何で、なぜ重要なのでしょうか？  
2. 問題が生じる主な原因や背景について、具体的に考えてください。それをどのように特定できますか？  
3. 問題を解決するための既存の方法やアイデアを挙げてください。それらにはどのような利点と限界がありますか？  
4. 問題に関連する他の問題や制約条件を特定し、それがどのように影響を及ぼしているか考えてください。  
5. 問題を解決するための新しいアプローチを提案してください。それはどのように機能し、既存の方法と何が異なるのでしょうか？  
6. 提案した解決策の実現可能性を評価してください。それに必要なリソースや時間、課題は何ですか？  
7. 問題を解決することで得られる具体的なメリットや、社会的・経済的な影響を考えてください。  
8. 提案の内容を他者に説明する場合、どのような言葉や資料が説得力を持つか考えてください。
9. 総合的なまとめを作成してください。
```

　参考程度のものと
　　考えてください。

　なんかのヒントが
　　得られるかも、くらいな😅

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
変更不可能なリストについて

# はじめに
どうも、稲葉です。この記事では、変更不可能なリストについてまとめます。
# 定義
変更不可能なリストとは、要素の追加や削除、置換、整列ができないリストです。`List.copyOf`や`List.of`、`Collectors.toUnmodifiableList`で作成でき、`add`や`addAll`、`remove`、`replaceAll`、`set`、`sort`を呼び出すと、`UnsupportedOperationException`がスローされます。
```Java:リスト1
// 変更不可能なリスト[A, B, C]を作成
final List<String> list12 = List.of("A", "B", "C");

// 要素を追加しようとすると、UnsupportedOperationExceptionが発生
list12.add("D");
list12.addAll(List.of("E"));

// 要素を削除しようとすると、UnsupportedOperationExceptionが発生
list12.remove("F");

// 要素を置換しようとすると、UnsupportedOperationExceptionが発生
list12.replaceAll(String::toLowerCase);
list12.set(0, "a");

// 要素を整列しようとすると、UnsupportedOperationExceptionが発生
list12.sort(Comparator.reverseOrder());
```
# 似て非なるもの
`Arrays.asList`で作成したリストは、要素の追加と削除ができませんが、要素の置換と整列ができるため、変更不可能なリストではありません。
```Java:リスト2
// Arrays.asListでリスト[a, b, c]を作成
final List<String> arrayList = Arrays.asList("a", "b", "c");

// 要素を置換し、[a, b, c]を[Z, X, Y]に変更
arrayList.set(0, "Z");
arrayList.set(1, "Y");
arrayList.set(2, "X");

// 要素を置換し、[Z, Y, X]を[z, y, x]に変更
arrayList.replaceAll(String::toLowerCase);

// 要素を整列し、[z, y, x]を[x, y, z]に変更
arrayList.sort(String::compareTo);

// リストをコンソールに表示
System.out.println(arrayList); // [x, y, z]
```
`Collections.unmodifiableList`で作成したリストは、その引数を変更すると変更が反映されるため、変更不可能なリストではありません。変更不可能なビューといいます。
```Java:リスト3
// 変更可能なリスト[foo]を作成
final List<String> arrayList = new ArrayList<>();
arrayList.add("foo");

// List.copyOfとCollections.unmodifiableListで変更不可能なリストとビューを作成
final List<String> list12 = List.copyOf(arrayList);
final List<String> unmodifiableList = Collections.unmodifiableList(arrayList);

// 引数のリスト[foo]を[bar]に変更
arrayList.set(0, "bar");

// 変更不可能なリストとビューをコンソールに表示
System.out.println(list12); // [foo]
System.out.println(unmodifiableList); // [bar]
```
# 気を付けること
`List`インタフェースを実装しているため、変更不可能なリストは`add`や`addAll`、`remove`、`replaceAll`、`set`、`sort`を呼び出してもコンパイルができてしまいます。開発チームで使用方法を取り決めておかないと、テスト時・運用時に`UnsupportedOperationException`が発生するかもしれません。
# 変更不可能なリストを変更可能なリストに変換する方法
`ArrayList`や`LinkedList`、`Vector`のコンストラクタに変更不可能なリストをやると、変更可能なリストに変換できます。新規のインスタンスを作成するため、変更可能なリストを変更しても引数のリストは変更されません。
```Java:リスト4
// 変更不可能なリスト[foo]を作成
final List<String> list12 = List.of("foo");

// ArrayListで変更可能なリストを作成
final List<String> arrayList = new ArrayList<>(list12);

// 変更可能なリスト[foo]を[bar]に変更
arrayList.set(0, "bar");

// List.ofとArrayListで作成したリストをコンソールに表示
System.out.println(list12); // [foo]
System.out.println(arrayList); // [bar]
```
# おわりに
というわけで、この記事では変更不可能なリストについてあらましを書いてみました。詳細については[Java Platformm, Standard Edition Core Libraries, Release 11](https://docs.oracle.com/javase/jp/11/core/java-core-libraries-developer-guide.pdf)を読んでください。
個人開発したサービスが２日で3 万リーチした話

## はじめに

こんにちは、[nogu](https://x.com/_nogu66)です。

今回は、私が個人で開発したサービスが、公開からわずか 2 日間で 3 万リーチを達成するという、予想外の出来事についてお話ししたいと思います。

この短い期間で、多くの方々にサービスを知っていただき、実際に利用していただけたことは、私にとって大きな喜びであり、驚きでもありました。

この記事では、その過程や背景、そしてそこから得られた学びについて共有させていただきます。

まずは、以下の投稿をご覧ください。

https://x.com/_nogu66/status/1878042981997125780?ref_src=twsrc%5Etfw

https://x.com/taishi_jade/status/1878035585673347477?ref_src=twsrc%5Etfw


この投稿はいずれも、私が個人開発したサービスが 2 日で 3 万リーチを達成した際の投稿です。

この記事では、その過程や背景、そしてそこから得られた学びについて共有させていただきます。

**※どうやって、３万リーチしたのかを知りたい方は、この記事の最後をご覧ください。**

## サービスの概要

このサービスは、『さとり構文ジェネレーター』（通称：『Satorify』）[『さとり構文ジェネレーター』（通称：『Satorify』）](https://www.satorify.jp/)という X（旧 Twitter）でバズを連発する「さとり構文を」を誰でも簡単に作成することができるサービスです。[概要](https://www.solomaker.dev/products/069e7ef7-ea4b-46e1-a96e-da3ff1d59686)

「さとり構文」とは X（旧 Twitter）でバズを連発する「さとり([@satori_sz9](https://x.com/satori_sz9))」さんが考案した、短くても効果的な文章構造です。

https://www.satorify.jp/
さとり構文の詳細は[こちら](https://note.com/nogu66/n/n935806694006)でご覧いただけます。

## システム構成と使用技術

このサービスは、ユーザーが入力したテキストを、LLM（大規模言語モデル）を活用してさとり構文風に変換する機能を提供しています。これにより、誰でも簡単にさとり構文調の文章を生成することができます。

また、このサービスは、β 版のリリースということでかなりシンプルな構成となっています。

### システム構成

![satorify-architecture-diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660847/2facfbbb-d198-68d7-e5a3-823831cecf13.png)

#### フロントエンド

- Next.js
- TypeScript
- TailwindCSS

#### サーバーサイド(API)

- Dify

#### ホスティング

- Vercel

#### LLM

- DeepSeek V3

### プロトタイピング

- Bolt

### エディタ

- Cursor

## 開発スケジュール

会社に勤めているため、終業時間外の朝昼夜の時間を使って開発しました。

とにかく、早く出すことを優先したため、以下のようなスケジュールで進行しました。

- １日目 要点定義、プロトタイピング
- ２日目 プロンプトエンジニアリング、Dify API 作成
- ３日目 デザイン修正、バクフィックス
- ４日目 デプロイ

## 機能

ベータ版のリリースでは、とくかく動くこと、LLM から精度の高い結果を得ることを優先しました。

そのため、以下のような機能を実装しました。

### ベータ版

- テキスト入力
  - 自由入力
  - 構文タイプの任意選択
- 「さとり構文」の生成
  - 3 つの改善提案
  - コピー機能

![satorify-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660847/33bdd195-017d-31d4-7024-4108e650f299.png)

![satorify-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660847/d4f878f6-49ad-b9d9-3fbb-6f2523521254.png)


### リリース版（予定）

- 改善案を 1 つ提示: シンプルかつ具体的な改善案を提供。
- 改善案のコピーおよび SNS 投稿ボタン: 改善案をそのままコピー、SNS でシェア可能。
- ユーザー登録機能: ユーザー体験をカスタマイズ可能。
- プレミアムプランの追加: より便利に使える有料プランが登場。
- プレミアムプラン特典
  - カスタマイズオプション: 構文のスタイルやトーンをユーザーごとに調整可能。
  - 保存と管理: 作成した構文を保存し、後で編集・再利用が可能。
  - 改善案へのフィードバック修正: 改善案を修正して、より良い文章を生成。

## おわりに

このようなサービスが１週間と経たずに、多くの方にリーチできたのは、[Solomaker](https://www.solomaker.dev/)のおかげです。

個人開発者は、アイディア段階でもいいので、ぜひ、[Solomaker](https://www.solomaker.dev/)にプロダクト登録することをオススメします。

ニーズの確認ができたり、早期のリーチができます。また、モチベーションにも継続的に繋がります。

## せんでn

[Satorify](https://satorify.com/)は、現在正式リリース準備中です。近日中にリリース予定ですので、お楽しみに！

ベータ版は以前として利用いただけますので、[Satorify](https://satorify.com/)をご利用ください。

[Satorify](https://satorify.com/)は、SNS の投稿の質を高め、文章を考える時間を最小化してくれるサービスです。SNS マーケにお悩みの方はぜひご活用でください。
TrueNAS で作成した zvol を iSCSI を使って Ubuntu でマウントする手順

# TrueNAS で作成した zvol を iSCSI を使って Ubuntu でマウントする手順

忘れそうなのでメモ

## iSCSI について

ちょっと調べただけなので, 間違いある可能性あり

iSCSI は, smb や nfs のようなファイル共有と異なり, ディスクを丸ごとマウントする.
NAS 側では zvol という大きなファイル? しか見えず, どのようなファイルが格納されているかは分からない (何のファイルシステムかも分からない).
クライアント側でディスクをマウントして, ファイルシステムを作成する.

### メリット

- ファイル共有より高パフォーマンス
- smb や nfs などのファイル共有で発生する面倒なエラー (シンボリックリンクやパーミッション) が出なくなる.
  → クライアント側からは物理ディスクと同じように見えるため.

### デメリット

- 一度に複数のクライアントでマウントして使えない

## 参考文献

- https://www.server-world.info/query?os=Ubuntu_22.04&p=iscsi&f=3

## 実行環境

- **iSCSI ターゲット**
  - TrueNAS (サーバー) 側
  - hostname: `truenas-primary`
- **iSCSI イニシエーター**
  - Ubuntu (クライアント) 側
  - hostname: `ubuntu-workstation`

## 手順

### TrueNAS 側

1. zvol を作成する.
1. Shares > iSCSI で iSCSI の設定を行う.
   - "Extents" で zvol を関連付ける. 関連付けた順に sda, sdb, ... になる模様.
   - 下の例の場合, games と repos という二つの extent を iSCSI ターゲットに紐づけている. (games は 4TB, repos は 1TB, games は Windows でマウントして使用中)
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191898/d1cf22bb-e88a-89f1-5ab4-7aa2ba081ad1.png)
   - 今回は repos を Ubuntu にマウントして使えるようにしたい.

### Ubuntu 側

(参考文献のいくつかのコマンドはスキップ)

```sh
# ターゲットを discovery する
$ sudo iscsiadm -m discovery -t sendtargets -p truenas-primary.local

# discovery したターゲットにログインする
$ sudo iscsiadm -m node --login -p truenas-primary.local

# システム起動時に自動ログインさせる
$ sudo iscsiadm -m node -p truenas-primary.local -o update -n node.startup -v automatic

# パーティション確認
$ cat /proc/partitions
major minor  #blocks  name
...
   8        0 4294967360 sda
   8        1      16367 sda1
   8        2 4294949888 sda2
   8       16 1073741824 sdb
# ↑ sda の方は "games", sdb の方は "repos"

# GPT 形式でフォーマット
$ sudo parted --script /dev/sdb "mklabel gpt"

# パーティション作成
$ sudo parted --script /dev/sdb "mkpart primary 0% 100%"

# ext4 形式でフォーマット
$ sudo mkfs.ext4 /dev/sdb1

# マウント
$ sudo mount /dev/sdb1 /mnt/repos

# マウント確認
$ df -hT
...
/dev/sdb1                                   ext4  1007G  139G  818G  15% /mnt/repos
```
Unityで本当の空のプロジェクトを作る方法

空のフォルダーを作ってください。
その中に、AssetsとProjectSettingsフォルダーを作りUnityHubでプロジェクトとして開けば完成です。
プロジェクト作成に30分くらいかかる悪夢とはもうおさらばｄ
【小ネタ】Bedrock ウォーターマーク検出について調べてみた

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

Bedrockを学んでいる中で**ウォーターマーク**について少し興味を持ったため個人的に調べてみた内容を記事として残しました。

## 公式ドキュメントによる説明

ウォーターマークに関して次のように説明がなされていました。

>ウォーターマーク検出を使用すると、有害なコンテンツの生成を抑え、誤った情報の拡散を減らすことで、AI 生成コンテンツの透明性を高めることができます。コンテンツ作成者、報道機関、リスクアナリスト、不正検出チームなどがこの機能を活用して、Amazon Titan Image Generator モデルを使用して生成された AI 生成画像を識別して認証できます。Titan Image Generator のウォーターマーク検出では、信頼度スコアも得られるため、元の画像が変更されている場合でも検出の信頼性を評価できます。Amazon Bedrock コンソールに画像をアップロードするだけで、Titan Image Generator によって作成された画像に埋め込まれたウォーターマーク (ベースモデルやカスタマイズされたバージョンで生成されたものを含む) が API によって検出されます。

:::note info
利用可能なリージョンは**米国東部 (バージニア北部) と米国西部 (オレゴン) **です。
:::

## コンソールで試してみた

ChatGPTで生成した画像で試してみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/920bebcd-4dc4-ba7a-1c93-7364f7e9b21c.png)

## 検出方法

- Bedrock画面>左側ペインの**ウォーターマーク検出**をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/5d01e253-ec04-704b-2a44-4dc7df2a2913.png)

- 画像をアップデートすると分析ボタンを押下できるため押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/cc32fa38-dd1b-512c-75cd-ba52efe7d088.png)


- 結果が表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/16e91116-0b81-f951-e649-9a83020b7682.png)

**ウォーターマークは検出されませんでした**といったメッセージが表示されました。そのうえで、よくよく見てみたら、**Titan Image Generator モデル対応**と表示されていたので、**Titan Image Generator モデル**しかウォーターマーク検出ができないようですね。

**Titan Image Generator G1**で生成した猫の画像でチェックしてみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/e9e698b5-e64b-8c94-e8fc-ca135dec544d.png)


結果として以下の通りでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/e37ed180-ced3-1745-a134-1c172d389478.png)

ちゃんとウォーターマーク検出が引っかかってくれましたね。

イメージとして利用可能な**Stable Diffusion 3.5 Large**でも試してみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/275939f6-b0e2-d3c2-4ec0-34734424f096.png)

結果として以下の通りでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/79e9d60f-c2e2-bb55-eed2-4b3e128779c6.png)

やはりウォーターマーク検出は行ってくれなかったですね。

個人的にTitan以外のモデルで画像生成を行うシーンもあるかと思いますので、ウォーターマーク検出機能は強化すると、よりよい開発が実現するのかなぁと思いました。

小ネタレベルの記事ですが、少しだけBedrockに関する解像度を上げることができました。
最後まで記事を読んでいただきありがとうございました。
map に存在しない値を指定したときの挙動

ゼロ値が出力される
```go
package main

import "fmt"

func main() {
	m := make(map[string]int)

	// map に存在しない値
	a := m["あ"]

	fmt.Println(a) // 0
}

```

カンマokイディオムを使ったときも同様
```go
package main

import "fmt"

func main() {
	m := make(map[string]int)

	// map に存在しない値
	b, ok := m["あ"]

	fmt.Println(b, ok) // 0 false
}

```
tkinopi/eiyoushitensyokunabi_scraping

Title: A Comprehensive Introduction to Tkinter & Eiyoushitensyokunabi Scraping

Introduction:

In this blog, we will delve into a fascinating concept, 'tkinopi/eiyoushitensyokunabi_scraping,' a powerful Python-based utility for web scraping while working with GUI programming. Specifically, eiyoushitensyokunabi_scraping employs Python's libraries, Tkinter for creating graphical user interfaces (GUIs) and BeautifulSoup for web scraping, providing a user-friendly platform to scrape valuable data from eiyoushitensyokunabi, a website that offers nutrition job information.

GUIs with Tkinter:

Python offers various libraries for GUI programming, but Tkinter, by and large, tops them all. Utilizing tkinter makes GUI apps look and feel like real-world programs, standardizing the feel of an input/output type of program.

Tkinter allows developers to create windows, labels, buttons, menus, textboxes, and other widgets. The 'Tk’ of Tkinter stands for 'Tk toolkit,' and 'inter' is short for 'interface.' It is widely popular due to its simplicity and generally comes bundled with standard Python distributions.

Web Scraping with BeautifulSoup:

BeautifulSoup is a Python library made for pulling data out of HTML and XML files. It offers simple, Pythonic idioms for iterating, searching, and modifying parsed trees, inevitably making it an invaluable tool for web scraping.

This library provides a few simple methods and Pythonic idioms for navigating, searching, and modifying a parse tree - it sits atop an HTML or XML parser, providing Python-friendly means of accessing these parsers' data structures.

Utilizing eiyoushitensyokunabi_scraping:

Eiyoushitensyokunabi_scraping is a custom-built utility that uses both Tkinter and BeautifulSoup to effectively scrape data from eiyoushitensyokunabi web page. This application was specifically created for gathering information related to nutrition jobs.

A usual workflow would involve the following steps:

1. Launch the GUI built with Tkinter
2. Input into the textbox the website to be scraped
3. Click on a button that initiates the scraping process
4. The data is then scraped from the website using BeautifulSoup, parsed, and organized.
5. The results are displayed back in the GUI and could be exported for further processing and analysis.

Conclusion:

Tkinopi/eiyoushitensyokunabi_scraping represents an effective blend of GUI programming and web scraping. With the ease and flexibility of Python's Tkinter and BeautifulSoup libraries, it provides a simple yet powerful utility for anyone keen on collecting nutrition-related job data.

The prospect of Python utilities like tkinopi/eiyoushitensyokunabi_scraping hints at the potential these libraries hold in data processing and user interface fields. Understanding and properly harnessing these tools' power indeed opens up myriad possibilities in data analysis and interpretation.

In subsequent blog posts, we'll dive deeper into eiyoushitensyokunabi_scraping's code, dissect the core functionalities of Tkinter and BeautifulSoup, and finally understand firsthand how this utility aligns the power of these two libraries. Keep scraping!