OmniAICreator/Qiita-1.07M huggingface dataset:
スムーススクロールのシンプルな記述方法

<h2>スムーススクロールとは？</h2>
スムーススクロール（Smooth Scroll）とは、ページ内リンクやナビゲーションをクリックした際に、画面が急に移動するのではなく、なめらかにスクロールして移動する効果のことです。
通常のスクロールでは、リンクをクリックすると即座に目的の位置にジャンプしますが、スムーススクロールでは自然な流れで目的の位置までスクロールして見せるため、ユーザーにとってより視覚的にわかりやすく、快適かつ少しリッチな体験を提供できます。

<h2>jQueryを使った実装方法</h2>
これまでスムーススクロールの実装を何度か重ねてみて、以下の記述方法に辿り着いたので備忘録として残します。
もっとシンプルで可読性の高い記述方法があれば教えていただけると嬉しいです！
スムーススクロールの挙動に対して、CSSの記述は不要です。

```HTML
<a href="#menu1"></a>
<a href="#menu2"></a>
<a href="#menu3"></a>
<section id="menu1"></section>
<section id="menu2"></section>
<section id="menu3"></section>
```

aタグのリンクを押下したら、sectionタグ要素の先頭まで滑らかな動きで移動することを期待した記述です。

```javascript
  $(function () {
    $('a[href^="#"]').click(function (e) {
      e.preventDefault(); // デフォルトの動作をキャンセル
      var speed = 500; // スクロールのスピード
      var href = $(this).attr('href'); // クリックされたリンクのhrefを取得
      var target = $(href); // ターゲットとなる要素を取得
      if (target.length) { // ターゲットが存在する場合のみ実行
        var position = target.offset().top; // ターゲットの位置を取得
        $('html, body').animate({ scrollTop: position }, speed, 'swing'); // スムーズスクロール
      }
    });
  });
```

- e.preventDefault(); で、リンクがクリックされたときのデフォルト動作（即時ジャンプ）を防いでいます
- $('html, body') で、ブラウザ互換性のためにスクロール処理を html と body の両方に対して行っています
- var target = $(href); で、href が指す要素を選択し、存在する場合にのみスクロールを実行しています

<h3>注意点</h3>
以下、ご注意ください。

- href属性の値が"#"のみを指定している場合は、動きません
- 外部ページから、アンカーリンクが付いたURLにアクセスした場合は、スムーススクロールは機能しません

<h3>初心者の方へ</h3>
jQueryの読み込みをお忘れなく！

24/10/8時点の最新<a href="https://jquery.com/download/" target="_blank">jQuery</a>のバージョンは `3.7.1` です。

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
```

body閉じタグの直前に読み込みます。

<h2>素のjsでの実装方法</h2>

```javascript
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    anchor.addEventListener('click', function(e) {
      e.preventDefault();
      const targetId = this.getAttribute('href');
      const targetElement = document.querySelector(targetId);
      if (targetElement) {
        window.scrollTo({
          top: targetElement.offsetTop,
          behavior: 'smooth'
        });
      }
    });
  });
```
2024/10/8主にITとかセキュリティの記事

あなたのスマホデータも裁判の証拠に!? 「デジタルフォレンジックス」ってなに？(10/6)
https://ascii.jp/elem/000/004/226/4226193/?rss

生成AIをサイバー攻撃に悪用　ラップで規制避け危険情報入手　自律化も「時間の問題」(10/6)
https://www.sankei.com/article/20241006-IB7OP5TXZBN57G4FWY4X7E46RI/

オープンソースLLM、サイバー防衛の新兵器に(10/5)
https://weel.co.jp/media/news/6734/

AI時代、MFA突破の脅威に警鐘(10/5)
https://weel.co.jp/media/news/6735/

県警がインフラ事業者にサイバーセキュリティ講演(10/6)
https://news.yahoo.co.jp/articles/136191f0513051c80558273ea8402074da3f8109

Microsoft装うフィッシングメール、被害者が気づくことはほぼ不可能(10/6)
https://news.mynavi.jp/techplus/article/20241006-3037649/

個人情報流出を防ぐために日常で気をつけるべきポイントとは？神奈川県二宮町保育園の個人情報流出事件に学ぼう！
https://cybersecurity-park.com/3117/

Apple Vision Proに対する新たな脅威「GAZEploit」：視線データからキー入力を復元する攻撃手法(10/6)
https://ledge.ai/articles/apple_vision_pro_gazeploit_keystroke

サイバー攻撃の対応しっかり　盛岡で体験会、経営者ら手順学ぶ(10/6)
https://www.iwate-np.co.jp/article/2024/10/6/171319

EigenLayer投資家、メールハッキングによって600万ドル相当のEIGENトークンを盗まれる(10/6)
https://crypto-times.jp/news-eigenlayer-investors-lose-6-million-in-eigen-tokens-in-email-hack/

10月は世界的なサイバーセキュリティ月間（日本は2月だけど）(10/6)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/10/post-ebcd06.html

日本でも整備が進むGPUクラウド、GMOが明かしたAIデータセンターの「裏側」(10/7)
https://xtech.nikkei.com/atcl/nxt/column/18/02953/092000005/
JISキーボードはクソ、はっきり分かんだね

# 諸注意
⚠️規格がクソであって｢JISキーに慣れた人｣をディスるつもりは皆目ないのでご承知置きを。電気屋のラップトップPCの展示はどれもクソJISキーしかないから、それに慣れてしまうのは致し方ない。それとも印字通りのかな入力が出来る人は尊敬でしかないから今後もJISキーで使い続けて欲しい。
# 経緯
貸与されるラップトップPCが当たり前のようにJIS規格ばかりで頭に来たので書いた。貸与してくれる人に恨みは無いが、ロクに議論も改良もせずのうのうと国内でメインストリームをのさばっているのが本当に許せない。一オプションとして｢JIS配列も選べますよ｣だったら何の問題もなかった。

# 簡単な話
- キートップの印字がいらない
    - かな入力を使うことがない
- メチャクチャな記号配置
    - 7 + ⇧がシングルクォート(')、対して2 + ⇧がダブルクォート(")
    - ブラケット開始([)はQの段、ブラケット終了(])はAの段
- ホームポジションのズレ
    - 記号キーが右側(右手薬指&小指で打つところ周辺)に詰まってるせいでポジションが体の正中線から左にキー1個分ズレている(機種によるけど大方そうなってる)
    - ただでさえキーボード右側にマウスやトラックパッドを置くので余計ズレる
# USキーボードのススメ
- ムダのない記号配置
- 正中線に来るホームポジション
- Enter / Returnキーが横長
    - 右小指を少し伸ばせば届く
- スペースキーが小さい (プログラマー / 英文書く人向け)
    - スペースキーのつもりが違うキーを入力していたあるある
    - スペースを空けたつもりが空いていない

# 勘違いされているコト
- 日本語/英語切り替えキーがない
    - そもそもそんなものは要らない
    - どのキーボードでもショートカットで切り替えられる
        - Mac: ^ + [Space]
        - Win: alt + tab

# 強いて挙げるUSキーボードのデメリット
- デフォルトだとショートカットの組み合わせを覚える必要がある
- 覚えたとして1キーで切り替えられない
    - 以下のアプリで解決
        - Mac: Karabiner Elementsをインストール
        - Win: alt-ime-ahkをインストール

# まとめ
- 以下の人はJIS規格でもいいかも
    - かな入力をマスターしてる人
        - 入力するキーがローマ字入力に比べてほぼ半分少ないので早くて当たり前
    - どうしてもUSキーに慣れなかった経験のある人
        - こればっかりはしょうがないね、仕方ないね
- それ以外の人は全員USキーを買え、ぜったいにだ

IME切り替えとかスペースキーよりEnterキーで確定することが多いとか、いわゆる日本語特有の事情があるとは言え、なぜ今のJIS規格で｢ヨシ！！｣が通ったのか、本当に分からない(特に記号周り)。もし今日のキーボードのJIS規格を決定した人に直接会えるなら、密室で小1時間徹底的に問い詰めたい。規格の背景とか、これを採用するに至った経緯とか、、、
Intel内蔵GPUを使ってWSL(Docker)上でPDFのパスワード解析をしたい

# 前提
- OSはwindows11のWSL上のUbuntu 22.04.5 LTS
- PCを汚したくないので作業はDockerコンテナ内で
- パスワード解析にはIntelの内蔵GPUを使用

:::note warn
この記事は犯罪行為を助長するものではありません。悪用はダメ！！！
:::

# Dockerの準備

```shell
docker run -it --device /dev/dxg --volume /usr/lib/wsl:/usr/lib/wsl ubuntu:latest
```

`--device /dev/dxg --volume /usr/lib/wsl:/usr/lib/wsl`をつけないと、コンテナ内でGPUを上手く認識できないようです。下記を参考にしました。

https://github.com/openvinotoolkit/docker_ci/issues/241

# ハッシュを抽出
目的のPDFからハッシュ値を抽出します。今回はJohn the Ripper（JtR）というツールのjumbo版というものをGithubからcloneして使います。目的のPDFはdocker cpコマンドなどでコンテナ内の任意の場所にコピーをしておいてください。

:::note info
aptにもJtRはあるのですが、そちらはjumbo版ではなくPDF解析ができないと思われます。私はここで滅茶苦茶時間を溶かしました。

:::

```shell
apt update && apt upgrade -y && apt install -y git
git clone https://github.com/openwall/john
./john/run/pdf2john.pl locked.pdf > pdf.hash
```
ここで出力されたハッシュを見ると、ファイルのパスとセミコロンがついていますが、こちらは不要なので、vimなどで編集して削除します。詳しくは下記をご確認ください。

https://qiita.com/v_avenger/items/443358029c333a4a6d13#pdf%E6%96%87%E6%9B%B8%E3%81%8B%E3%82%89%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E6%8A%BD%E5%87%BA%E3%81%99%E3%82%8B

これでpdf.hashにハッシュ値を抽出出来ました！

# hashcatによるパスワード解析

次にhashcatというツールによってパスワードの解析を行います。

:::note info
John the Ripperもパスワード解析ツールなのですが、PDFのGPUによる解析は現状サポートしていないようです。
:::

まずは下記コマンドでインストールを実行。intel-opencl-icdをinstallしないとOpneCLでGPUが読み込めません。
```shell
apt install -y hashcat intel-opencl-icd
```
`hashcat -I`を実行するとGPUが認識されているかを確認できます。ここでGPUに関する記述あれば認識出来ていると思います。

そしていよいよ解析を行います。以下が実行するコマンドの一例です。
```shell
hashcat -a 3 -D 2 -w 4 -m 10700 pdf.hash
```
`-a`で解析方法（総当たりや辞書攻撃など）を、`-D`で使用するデバイス（CPUやGPUなど）を、`-w`でパフォーマンスを、`-m`でハッシュのモードを選択します。まあ大抵のことは`hashcat -h`でヘルプを見れば分かります。モードは必須で指定する必要がありますが、`-m`をつけないで実行しようとするとモードの選択肢を教えてくれるので、そこから選べば大丈夫だと思います。

以降の表示などは他の記事などでたくさん紹介されていると思うので、そちらに説明を譲ります。

# 参考資料

https://qiita.com/asadeyy/items/63656ec0e72c9fa56b51

https://yasuo-ssi.hatenablog.com/entry/2023/01/05/203000
麻雀は何試合で実力が収束するのか？


## 検証方法

N試合の平均着順を求める。
これを10000個のパラレルワールドで行い、
各パラレルワールドごとの平均着順の誤差が0.01になるまでの試合数を求める。

統計学の知識は0なのでプログラムでゴリ押しで求めていく。

あといろいろ検証するのが面倒くさいので平均着順は2.5で固定する。

## ソースコード

```js:main.js
const パラレルワールドの数 = 10000
const 試合数 = Number(process.argv[2])

const 期待順位分布 = [1, 1, 1, 1]
const 期待平均順位 = 平均順位(期待順位分布)

let 誤差合計 = 0
for (let i = 0; i < パラレルワールドの数; i++) {
    const 実際順位分布 = [0, 0, 0, 0]
    for (let j = 0; j < 試合数; j++) {
        const 順位 = ランダム順位(期待順位分布)
        実際順位分布[順位 - 1] += 1
    }
    誤差合計 += Math.abs(期待平均順位 - 平均順位(実際順位分布))
}

console.log(`試合数：${試合数}, 期待平均順位：${平均順位(期待順位分布)}`)
console.log(`平均順位誤差：${誤差合計 / パラレルワールドの数}`)

function ランダム順位(期待順位分布) {
    const 総数 = 期待順位分布.reduce((a, b) => a + b, 0)
    const r = Math.random()
    if (r < 期待順位分布[0] / 総数) {
        return 1
    }
    if (r < (期待順位分布[0] + 期待順位分布[1]) / 総数) {
        return 2
    }
    if (r < (期待順位分布[0] + 期待順位分布[1] + 期待順位分布[2]) / 総数) {
        return 3
    }
    return 4
}

function 平均順位(順位分布) {
    return (順位分布[0] + 順位分布[1] * 2 + 順位分布[2] * 3 + 順位分布[3] * 4) / (順位分布[0] + 順位分布[1] + 順位分布[2] + 順位分布[3])
}
```

## 結果

いろいろ試合数をいじって調べた結果！

```
試合数：3600, 期待平均順位：2.5
平均順位誤差：0.01474852777777778
```

**約3600試合**すれば、実力の平均着順との誤差が0.01になると分かりました。

終わり。
Androidアプリ開発の個人メモ

- 簡単な画像はVector Assetに変換したものを使う方がいい
→pngにするよりも画像が劣化しないなどのメリットがある
※ファイル形式は、**SVG**か**PSD**の形にしておく！！
https://developer.android.com/studio/write/vector-asset-studio?hl=ja#running

## APIレベルとは
AndroidOSのバージョン（Androidバージョン）毎に提供されるフレームワークの標準ライブラリのリビジョン番号のこと

### 参考
https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=ja#ApiLevels

https://coky-t.gitbook.io/owasp-mastg-ja/android-tesutogaido/0x05a-platform-overview

https://qiita.com/Super_Swift_Biginner/items/140a319aa3fbe2f2ece9

https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9



## リソースファイル
 - リソースファイル（string.xmlやdimens.xmlなど）がある意味
     - アプリ内で共通の設定値を一元管理することで、保守・メンテナンスをしやすくする
     - リソースファイルに定義をしておくことで、言語切り替えやシステム設定、テーマに応じて、自動で使われる設定値が変わる（リソースファイルは適切なフォルダ（ディレクトリに入れておくと自動で設定を切り替えてくれる））
（開発者は、設定値の切り替えをあまり意識しなくてOK）
- どのフォルダ（ディレクトリ）に何のリソースファイルを置くかは、Andoridの公式が定めているので、その定義に則ってフォルダ（ディレクトリ）とリソースファイルを作成する
（Andoridはフォルダ（ディレクトリ）が意味を持つ）

https://developer.android.com/guide/topics/resources/providing-resources?hl=ja#AlternativeResources

※自動で切替えるには、ファイルではなく、どのフォルダ（ディレクトリ）に入れるのかが大事

## ビルドバリアント（Build Variants）
- 本番（product）と同じ挙動になる
- debugビルドでは難読化されないが、releaseビルドでは難読化される
→SharedPreferencに保存した値を取ってくる時とかは、難読化されてないかreleaseビルドで確認が必要！！
- 動作確認は一応releaseビルドでも行う（debugビルドよりもビルドの時間が長くなるので注意）
→debugビルドよりも、アプリの動作が早いため、debugビルドでは気づかなかった問題が出てくることも……
- releaseビルドのビルドバリアントは、build.gradle.ktsでisDebuggable = falsを設定すること
- 動作確認の際には、端末の開発者オプションの設定で、「タップを表示」の設定をONにしておくと、画面録画や他の人に画面共有で見せる時に見やすいカモ
### 参考サイト

https://developer.android.com/studio/debug?hl=ja

https://qiita.com/n-seki/items/202054eb5f1c1d79b848
# ライブラリの追加
以下を参照

https://qiita.com/pe-pe-desu/items/4682f10316fae56bdeea
【モチベアップ】情熱プログラマーを読んでみた

# はじめに
私は独学でエンジニアに向けて勉強をしております。
勉強内容で苦労することも当然ありますが、中でもモチベーション管理には特に注意を払って継続しています。
本来であれば勉強が疲れたら友達と飲みに行ったり遊んだりすると思いますが、私は現在アメリカに住んでおり、まだ友達全然いませんｗ
モチベーション管理をするためには、筋トレ（テストステロンが分泌されるので）、ピックルボール、旅行などで気分転換をしています。

本書を手に取った理由は、話には聞くが不透明であるエンジニアについて、エンジニアが持っておくべきマインドなど事前に知っておくことでモチベーションを上げる用途で読み始めました。

今回は知識というよりは印象に残った内容と自分の考えをセットで載せていきたいと思います

## 市場を選ぶ
### コーディングはもう武器にならない
エンジニアを志している私からすると、このテーマが印象的過ぎて　え？となりました
ここではただプログラムをやるだけではなく、その業界についての理解を深めよ。と書いてありました。
受託開発に限らず、自社開発企業でもエンジニアだからコードを書いておけばいいでしょ？と言われたことだけをやるのではなく業界についてより詳しくなったほうが周りと連携もとれるし、マーケやtoCの課題をすばやくキャッチアップできるので事業を迅速に進められると思いました。

## 一番のへたくそでいよう
このタイトルについて、とても思い当たる節がありました。
高校生の時にバレーボールをやっていたのですが肩を壊してしまい大学では新たなスポーツを始めようと思い、バドミントンを始めました。
私は大学4年間のめりこむようにやっていたのですが、私は初心者で実力もないのにあまり手加減せずに相手をしてくれるところでした。
一番下手だったかはさておき、自分がへたくそでいることでうまい人はなぜ故うまいかを身近で学び大学4年生では100人中上位5番くらいの実力まで上り詰めることができました。

また本書では以下のように名言が書いてありました。
>君の周りにいる人たちが君自身 のパフォーマンスに影響する。
仲間は慎重に選べ 
>>ChadFowler; でびあんぐる. 情熱プログラマー ソフトウェア開発者の幸せな生き方 (p.13).

これも私のモットーに似ていると思いました。
"環境が自分を決める。現状を変えたいなら環境を変えろ。"
私は高校生から成したいことがあって公務員へ進み、ビジネスに対してあまりにも疎くなるのに嫌気がさして、知り合いと一緒に起業し、その際に参加した起業家プログラムで自分のスキルのなさを自覚、妻がアメリカに赴任するので英語力向上のチャンスと新たにエンジニアとしてスキルを積み重ねる分野に挑戦しようと思いました。

自分が進んできた道が正しいかわからないですが、こうしてマインドの一部が似ていることを非常にうれしく思います。

## 万能選手になろう

>プラットフォームの垣根を  越えたスキルを身に付けろ 
>>ChadFowler; でびあんぐる. 情熱プログラマー ソフトウェア開発者の幸せな生き方 (p.25).

現在rubyを勉強していますが、企業に入ってからは様々な技術に触れるとともにAIについても勉強できればと考えているのでこのマインドを持ちながら、これからも就職してからも頑張りたいです

## スペシャリストになろう
>ほかに何も知らないことが  スペシャリストだって  勘違いしてるんじゃないか 
>>ChadFowler; でびあんぐる. 情熱プログラマー ソフトウェア開発者の幸せな生き方 (p.27).

自分はできると思っていても、まだまだ知らないこともたくさんあるしできると思ってしまっては成長が止まってしまうということですね。頭ではわかっていても、自分の核の中で意識し続けて、今やっている仕事がうまく回ったとしても、うまくいく原因ともしこのパターンならうまくいかないかも等とケーススタディを自分の頭の中で繰り返し、理解を深めることがとても重要だと思いました。

## 愛せよ、さもなくば捨てよ
>とにかくやれ。やれないはずはない。
>>ChadFowler; でびあんぐる. 情熱プログラマー ソフトウェア開発者の幸せな生き方 (p.33).

本書を見ると、好きこそ物の上手なれということわざが似合うような方で大好きなコンピュータゲームをするためにプログラミングをやっていたようです。
それほどのめりこめるからこそ価値を生むことができるということなのですね

# まとめ
エンジニアになる前の情熱の持ち方などについて記載がありました。
英語の翻訳なので少しイメージしずらかったり、エンジニアの仕事についても書いてあったので、就職してからまた読み直そうと思いました。
インフラ監視　一年目

現在、大手HDの共通基盤インフラ監視業務に従事。
今後の目標を書いていく。

# 1年後転職して、以下の実現のための1歩を踏み出す

## 3年後実現したい働き方
・フロントエンドエンジニア＋webデザイナー
・自社開発会社で働きたい(事業内容に共感できるサービスの開発に携わりたい)
・リモート中心で、どこでも働ける

### そのために学習しなければいけないこと
・フロントエンジニア
　-HTML
　-CSS
　-JavaScript

・webデザイナー
　-Photoshop/Illustrator
　-Premiere Pro/After Effects

・PC基礎
　-Excel
　-基礎情報資格

 ### 上記学習したあとは？
 ・アピールになるポートフォリオや、ソースコードを用意する
 ・1年後以下条件で転職する
 自社開発/職種未経験歓迎/フロントエンドエンジニア
 ・2年間実務経験を積み、選べる案件からサービスに共感できる、フルリモート会社に転職する。
M5NanoC6、I2C経由でマイクの音を拾って遊ぶ


過去ログを見よ!!


結果

![o_coq493.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a0daec7b-d96b-1f64-6968-77641c509d92.jpeg)


![o_coq494.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6c03e959-6ac7-bed3-44fb-e9ec3ed78da2.jpeg)


プログラム


```c++


//Grove_I2C_ADC_MIC_M5NanoC6_1

// test code for Grove - Sound Sensor
// loovee @ 2016-8-30


//ヘッダーファイル
#include <Arduino.h>
#include <Wire.h>
#include "nana_Grvove_ADC.h"


void setup()
{

  //I2Cとシリアルポートの初期化
  Wire.begin();
  Serial.begin(115200);
  //Serial.println("Grove - Sound Sensor Test...");
  delay(1);

}//setup


void loop()
{

    //電圧を求める
    float Voltage = 0; //電圧
    for(int i=0; i<32; i++){

      Voltage = Voltage + nana_Grvove_ADC();

    }//for

    Voltage = Voltage * 0.03125; // Voltage / 32

    Serial.println((int)(Voltage * 1000.0));
    delay(10);

}//loop

```

nana_Grvove_ADC.h

```c++


//インクルド
#include <Arduino.h>
#include <Wire.h>

//I2Cのアドレス
#define Addr 0x50

float nana_Grvove_ADC() {

  //内部アドレスの設定
  Wire.beginTransmission(Addr);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(2);

  //データの読み込み
  Wire.requestFrom(Addr, 2);
  delay(1);
  int h, l;
  if (Wire.available() == 2) {
    h = Wire.read();
    l = Wire.read();
  }//endif
  delay(1);

  //値の変換
  int adc1 = ((h & 0x0F) << 8) + l;
  int vo = (adc1 * 6000) >> 12; // (adc1*(3/4096))*2

  return( ((float)vo) * 0.001 );
  
}


```
【JavaScript】残余引数 / 可変長引数

引数の個数が決まっていない引数のこと「可変長引数」と言います。
JavaScriptでは可変長引数は残余引数(`rest parameter`)と呼びます。
残余引数を書くには、引数の前に`…`(スプレッド構文)を書きます。

`…`についての記事
[JavaScript | 分割代入の使い方(配列, オブジェクト) - わくわくBank](https://www.wakuwakubank.com/posts/461-javascript-destructuring-assignment/)


- 渡された引数をスプレッド構文で展開する
```javascript
function func(...params) {
  // ...
}
// paramsは配列でくるのでそのままforEachを使える
```

- いくつ来ても大丈夫
```javascript
function func(...params) {
  console.log(params); // [1, 2, 3]
}
func(1, 2, 3);
```

- 必ず渡される引数も含められる
```javascript
function func(param1, ...params) {
  console.log(param1, params); // 1, [ 2, 3 ]
}
func(1, 2, 3);
```

- 構文エラーになるコード
```javascript
// 残余引数しかない
function func(...params1, ...params2) {
    //
}

// 必ず来る引数が第一引数に書いていない
function func(...params, param1) {
    //
}
```
【JavaScript】User-AgentでPCとiPadの判別方法

私のUser-Agent (MacBook Air)
```javascript
console.log(navigator.userAgent)
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
```

iPadでSafariブラウザを開いた場合のUser-AgentはなぜかMacintoshの名前がある

```console
iPad Chrome
Mozilla/5.0 (iPad; CPU OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/120.0.6099.119 Mobile/15E148 Safari/604.1

iPad Safari
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15
```

iPadOS13以上から仕様が変わったみたい。
User-Agentに「iPad」の文字列一致だけでは条件が足りないので、「Macintosh」も記述
さらに、`('ontouchend' in document)`を追加することでiPadを判別できる。

```javascript
const userAgent = navigator.userAgent.toLowerCase()
if (/ipad|macintosh/.test(userAgent) && ('ontouchend' in document)) {
	console.log('iPadです。')
} else {
	console.log('PCです。')
}
```

### 参考
[iOS 13以降 iPadのUserAgentに注意 (WKWebView) - Qiita](https://qiita.com/ShingoFukuyama/items/ef573a8e3e23ef12542e)
【Laravel】Carbonで日時操作する時に気を付けること

- `Carbon/Carbon`

通常の`Carbon`は`mutable`(変更可能)なので作成したインスタンスが書き換えられてしまう。
```php
<?php
use Carbon/Carbon;

$now = Carbon::now();
$tomorrow = $now->addDay();

echo $now->format('Y/m/d H:i:s') // "2023/02/22 12:14:00"
echo $tomorrow->format('Y/m/d H:i:s') // "2023/02/22 12:14:00"
```

- `Carbon\CarbonImmutable`

`CarbonImmutable`は(変更不可能)なので作成したインスタンスは値が保持される。
```php
<?php
use Carbon/CarbonImmutable;

$now = CarbonImmutable::now();
$tomorrow = $now->addDay();

echo $now->format('Y/m/d H:i:s') // "2023/02/21 12:14:00"
echo $tomorrow->format('Y/m/d H:i:s') // "2023/02/22 12:14:00"
```

`Carbon`クラスでも`copy()`で最初に作成したインスタンスをコピーできる。
※書き忘れなどが生じるため`CarbonImmutable`推奨
```php
<?php
use Carbon/Carbon;

$now = Carbon::now();
$tomorrow = $now->copy()->addDay();

echo $now->format('Y/m/d H:i:s') // "2023/02/21 12:14:00"
echo $tomorrow->format('Y/m/d H:i:s') // "2023/02/22 12:14:00"
```

結論

`CarbonImmutable`を使用した方が、思わぬエラーを回避できる
【Laravel】Laravelのメンテナンスモード

Dockerのコンテナを落とそうとして、`sail down`をしようと思ったら
間違って`sail artisan down`を実行してしまった。(なぜかこの時気づかず)

```bash
sail up #正
```

```bash
sail artisan down #誤
```

翌日コンテナを立ち上げてローカルにアクセスしようとすると503エラー

![スクリーンショット 2023-07-19 11.18.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752214/6e4c2a53-5d5a-c51b-10c5-1279507fcda2.png)

？？？？？？？

調べてみるとLaravelにメンテナンスモードというものがあり、
そのコマンドを実行してしまった模様

[Laravelでメンテナンスモードを試してみた](https://zenn.dev/akido_/articles/5189280c169f6c)

`sail artisan up`を実行したら元に戻りました💧
httpヘッダーのhostが送信先のサーバのドメイン:ポートと異なっていたら301エラー。 httpヘッダーのhost削除、または、httpヘッダーのhostが送信先のサーバのドメイン:ポートしたら問題なかった。なぜ

HTTPリクエストを送信する際、Hostヘッダーはリクエスト先のサーバを特定するために非常に重要です。サーバは、このHostヘッダーを見て、どのドメインに対するリクエストかを判断します。このため、Hostヘッダーがリクエスト先のサーバのドメインやポートと一致しない場合、サーバ側でリクエストを処理できないことがあり、その結果としてリダイレクト（301 Moved Permanently）が発生する場合があります。

あなたのケースでは、次のようなことが考えられます。

## 1. Hostヘッダーが送信先のサーバと一致していなかった理由
HTTPリクエストのHostヘッダーが送信先のドメインやポートと異なっている場合、サーバはそのリクエストがどのバーチャルホストに対して行われたのかを正しく判断できません。多くのウェブサーバ（Apache、NGINXなど）は、複数のドメインを1つのIPアドレスでホスティングすることができ、Hostヘッダーを使用して正しいリソースを選択します。Hostが誤っていると、サーバは期待するリソースにリダイレクトするために301を返すことがあります。

## 2. Hostヘッダーを削除または正しいものに変更した場合の動作
#### 削除した場合: 
Hostヘッダーがない場合、多くのサーバはデフォルトのホスト（通常はサーバ自体のデフォルト設定）で処理を試みますが、これは正しいリソースに到達することができないため、異なるリソースが返される可能性があります。ただし、サーバによっては、この処理が問題なく成功する場合もあります。
### 正しいHostを設定した場合: 
Hostヘッダーを正しい送信先のサーバのドメインとポートに設定すると、サーバはそのドメインに対するリクエストとして正しく解釈でき、正しいリソースを返すことができます。このため、問題なく接続できたのでしょう。
## 301リダイレクトについて
301 Moved Permanentlyは、リソースが恒久的に別のURLに移動したことを示すステータスコードです。サーバは、リクエストされたリソースが新しい場所にあることをクライアントに伝えるために、Locationヘッダーを使って新しいURLを通知します。正しいHostが指定されていないと、サーバはリクエストを別のホストやURLにリダイレクトしようとすることがあります。

## まとめ
Hostヘッダーが送信先のサーバのドメインやポートと一致しなかった場合、サーバはリクエストを正しく処理できず、リダイレクトやエラーが発生します。
正しいHostを指定するか、不要な場合には削除することで問題が解決されますが、Hostヘッダーが欠落している場合も一部のサーバはリクエストを処理できることがあります。
この挙動は、サーバの設定やアプリケーションの動作に依存する場合もあります。
【PHP】use宣言のグループ化

### Before

```php
<?php

namespace App\Http\Controllers;

use App\Models\Hoge;
use App\Models\Fuga;
use App\Models\Foo;
use App\Models\Bar;
use App\Futaba\Chimaki as Chima;
use App\Futaba\Ribon as Bon;
use App\Futaba\Sakura as Saku;

class HogeController extends Controller
{
	//
}
```

### After (PHP 7 以降のコード)

```php
<?php

namespace App\Http\Controllers;

use App\Models\{
  Hoge, Fuga, Foo, Bar
};
use App\Futaba\{
  Chimaki as Chima,
  Ribon as Bon,
  Sakura, as Saku
};

class HogeController extends Controller
{
	//
}
```

- Tinkerでも有効
- as(エイリアス)も指定できる

途中まで同じパスが多い場合は、まとめてあげると見やすいですね！
フルロード輸送サービスに期待できること

フルロード輸送サービスは、特に大規模な貨物を一度に長距離で運ぶ必要がある企業にとって、非常に有用なソリューションです。この輸送方法は、荷物がトラック全体を占有するため、他の荷物と共有する必要がなく、効率的かつ迅速な配送が可能です。この記事では、フルロード輸送サービスの利点と、企業がどのようにしてこのサービスを最大限に活用できるかを説明します。

フルロード輸送サービスの概要
フルロード輸送（Full Load Transport、または FTL）は、1つの顧客の貨物がトラック全体を占有する形で配送される輸送サービスです。これは、部分積載のLTL（Less than Truckload）とは異なり、途中で他の荷物と一緒に輸送されることがないため、直接的かつ迅速な配送が可能です。

1. 速い配送と信頼性の高さ
フルロード輸送サービスの大きな利点は、そのスピードと信頼性です。LTL輸送とは異なり、他の荷物を積み替える必要がないため、荷物の出発地点から目的地まで直行することができます。これにより、全体の配送時間が短縮され、顧客の要求に応じた迅速な対応が可能になります。

特に、州を越えた長距離輸送が必要な場合、信頼性の高い [Interstate Transport Company](https://www.conceptlogisticsint.com.au/) と提携することで、フルロード輸送の利点を最大限に活用し、時間とコストを節約することができます。

2. 貨物の安全性と一貫した品質
フルロード輸送では、荷物が他の貨物と混ざることがないため、破損や紛失のリスクが大幅に減少します。特に壊れやすい商品や高価な機械類を運ぶ場合には、この点が大きな利点となります。貨物は積み替えが少なく、運送中の取り扱いも最低限に抑えられるため、安全な状態で目的地に届くことが保証されます。

また、フルロード輸送は貨物の温度管理や特殊な取り扱いが必要な場合にも適しています。温度制御が必要な商品や、特定の条件下でのみ運ばなければならない荷物は、フルロードでの専用輸送が最適です。

フルロード輸送のコストと効率性
フルロード輸送は、特に大規模な荷物や大量の出荷がある場合に、コストパフォーマンスが高い選択肢です。一度に多くの貨物を一括して輸送することで、全体の輸送コストを削減し、より効率的な運用が可能になります。

運用コストの最適化
フルロード輸送を活用することで、輸送の一貫性を保ちながら、コストの削減が期待できます。LTL輸送では、途中での積み替えや他の荷物との共有により、運送費が上がる可能性がありますが、フルロードの場合、これらの追加費用が発生しません。特に、長距離輸送や多頻度の出荷が求められるビジネスにとっては、フルロード輸送は最適な選択肢です。

また、[Concept Logistics](https://www.conceptlogisticsint.com.au/) のようなロジスティクスプロバイダーと連携することで、企業はより効率的でコスト効果の高い輸送プランを立てることができます。これにより、物流コストの最適化が可能になり、長期的な利益を得ることができます。

フルロード輸送サービスは、大規模な荷物を効率的に輸送するための信頼性の高い方法です。配送のスピード、安全性、そしてコスト効率を考慮した場合、フルロード輸送は、多くの企業にとって優れた選択肢となります。特に、長距離輸送が必要なビジネスでは、フルロード輸送を活用することで、より迅速かつ安全な輸送を実現することが可能です。
DBは主キーの形式(?)で速さが変わるらしいから検証してみた

# はじめに
こんにちは。普段はWebアプリの開発を行っている者です。
投稿は初めてなので、お手柔らかに...

タイトルの通りですが、今回は以下の記事を見て主キーの形式(言い方があっているかわかりませんが、uuidにするとかランダムな文字列にするとか)によって処理速度に違いが出るらしいので、検証してみました。

# 経緯
今まで特に大規模な開発に携わったこともなく、速さなんて気にしたことがなかったので「一意に決まれば何でもいいっしょ」って思いながら主キーを決めていました。そんなある日、以下の記事を読んで衝撃を受けたので、自分でも検証をしてみました。

https://zenn.dev/uncode_jp/articles/dcf20a2c5b0d76

# やってみる
とにもかくにも動かしてみよう！ということで、実験してみます！
今回は普段私がよく使っているMySQLで試します。

## 方法
以下の手順をidの形式ごとに行います。
1. insertを10万回実行
3. 1で挿入したレコードに対してselectを10万回実行

## エントリーNo.1 uuidv4
まずはuuidv4です。説明するまでもないですね
結果は以下のようになりました。単位はmsで、それぞれの値は平均値です。

| insert | select |
| ---- | ---- |
| 0.450 | 48.041 |

## エントリーNo.2 uuidv7
v4をやったので、v7もやってみました。
結果は以下の通りです。

| insert | select |
| ---- | ---- |
| 0.398 | 54.802 |

## エントリーNo.3 ランダムな文字列
普段私が使用している方法です。アルゴリズムはシンプルで、アルファベット大文字と0～9までの数字をランダムに255桁並べただけです。とりあえず一意の文字列を生成させたくて脳死で作ったアルゴリズムを今でも使ってます笑

| insert | select |
| ---- | ---- |
| 0.429 | 51.542 |

## エントリーNo.4 通し番号
単純に0～100,000までの番号をidにします。
結果は以下の通りです。

| insert | select |
| ---- | ---- |
| 0.411 | 54.225 |

# 結果
上の記録をまとめてみました。
| 形式 | insert | select |
| ---- | ---- | ---- |
| uuidv4 | 0.450 | 48.041 |
| uuidv7 | 0.398 | 54.802 |
| ランダム | 0.429 | 51.542 |
| 通し番号 | 0.411 | 54.225 |

insertが速い順だと 
1. uuidv7
2. 通し番号
3. ランダムな文字列
4. uuidv4

selectが速い順だと
1. uuidv4
2. ランダムな文字列
3. 通し番号
4. uuidv7

となりました！
insertが速いほど、selectは遅くなることにはびっくりです。記事を書く前に「insertもselectもこれが速いからみんな使おうね！」みたいにまとめるつもりが、予期せぬ事態となりました...

# 終わりに
私はDBに関しては必要最低限の知識しかないので、なぜこうなるかは分かっていませんが、何か意味ありげな結果になったので、また今度調べてみたいと思います！

最後までご覧いただき、ありがとうございました。少しでも有益な情報になっていれば幸いです！
ではまた。
【Laravel】テスト時のmiddleware無効化方法

- クラス内のミドルウェア無効化
```php
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    use WithoutMiddleware;

    // 処理
}
```

- 関数内のミドルウェア無効化

```php
class ExampleTest extends TestCase
{
    public function testBasicExample()
    {
        $this->withoutMiddleware();

        // 処理
    }
}
```

- 特定のmiddlewareを無効化
```php
$this->withoutMiddleware([HogeMiddleware::class]);
```
キューってなんやねん!!!

## 題名の通り
AWSで「サーバレス」だとか「非同期」だとかよく言われる単語で毎度おなじみのSQS。
実際に触ったことがないので、実際にやり取りされる「キュー」ってのが実際にどんな奴なのか全然イメージつかなくて困った。のでまずはChatGPT君に聞いてみた。

## ChatGPT君の答え
わし「メッセージキューって何ですか？データレコードみたいなものですか？」
ChatGPT君「メッセージキューの実態は、データレコードそのものではなく、メッセージの一時的な保存・管理を行うための仕組みや構造を指します。メッセージキューは、プロセス間通信や異なるシステム間での非同期通信に利用され、メッセージ（データのパケット）が送信者（プロデューサー）から受信者（コンシューマー）に渡されるまで、キュー内に一時的に蓄積されます。」

聞き方悪かったけど、とりあえずメッセージをキューイングするってのは、上記の通りで、メッセージなるものが送信者から受信者に渡されるまで、キュー内に一時的に蓄積しておくもののことを指す。

じゃあそのメッセージってなんやねん！ってことで聞いてみると、
「Amazon SQS（Simple Queue Service）で扱うメッセージオブジェクトは、主に**メッセージ本文（MessageBody）とメッセージ属性（MessageAttributes）**から構成されます。以下に、具体的な例を示します。Amazon SQSのメッセージオブジェクトは、以下のような構造を持ちます：
MessageBody: メッセージの主な内容。通常はJSON、XML、テキストなどのフォーマットで構成されます。
MessageAttributes: メッセージに付随するメタデータ。キーと値のペアで追加情報を提供します（オプション）。

例
```
{
  "MessageBody": "注文が正常に処理されました。",
  "MessageAttributes": {
    "OrderId": {
      "StringValue": "12345",
      "DataType": "String"
    },
    "CustomerName": {
      "StringValue": "山田太郎",
      "DataType": "String"
    },
    "OrderAmount": {
      "StringValue": "2500",
      "DataType": "Number"
    }
  }
}

```
こんな感じらしい。

## 感想
要はコンパクトに情報がまとめられたJSONだと思えばいいのね。
これをサーバの管理なく一時的に貯めておいてくれるSQSは偉大だわ。
新しい開発言語で必ずやるべき事 (自分用)

# テストで中身を確認
まず言語に依らず、consol.logやfmt.PrintlnやSystem.out.println等の出力クラスがあるのでそれを確認しましょう。
効率的にテストできるよう出力クラスをライブラリ化しましょう。
関数、メソッド、インターフェイスやタイプ等のデータ型を理解
以下確認する標準ライブラリ項目

- 時間
- 数学
- 並列
- 同期処理
- 非同期処理
- 排他処理
- 文字列操作
- DB操作
- ネットワーク関連
- 暗号周り(SHA256,Base64ぐらい?)
- IO処理やストリーム処理
- ログ処理
- 標準エラー処理(自分でエラークラス作成でもいい)
- その他　固有処理

全てのメソッドや関数をテストする必要はなく同じような構文や推測できそうな物はスキップしてもいいかもしれない。
大体の言語はその言語にカーソルやCtrl+space押すと詳細や使い方乗ってるのでドキュメントと合わせて見るのがいいかも。
厄介なのはextendやinterfaceやtype型使ってるもの。

大体のライブラリやプロジェクトは引数、return値、型とクラスの依存関係(import)が分かればどんなライブラリでも解読・習得できる。
余程難解なコードじゃなければ。(参照渡し多用や7行テトリス等)

頻繁にupdateがある言語だとちょくちょくクラス名変わるのでドキュメントは見た方がいいかも。

# 最後に
どちらかというと言語より実行環境周りのDockerfile,Docker-composeやk8sの構築やGitLabのCI/CD自動化の方が大事かもしれない。
【Laravel】セッションのforgetとremoveの違い

`vendor/laravel/framework/src/Illuminate/Session/Store.php`に定義元があります。

- `remove`
```php
/**
 * Remove an item from the session, returning its value.
 *
 * @param  string  $key
 * @return mixed
*/
public function remove($key)
{
   return Arr::pull($this->attributes, $key);
}
```

- `forget`
```php
/**
 * Remove one or many items from the session.
 *
 * @param  string|array  $keys
 * @return void
*/
public function forget($keys)
{
   Arr::forget($this->attributes, $keys);
}

```

どちらも`Arr`ファサードの削除処理で、違いは返り値の有無

### 返り値

- `remove`

```php
session()->put('testSession', 'テストセッション');
session()->remove('testSession'); // テストセッション
```

- `forget`
```php
session()->put('testSession', 'テストセッション');
session()->forget('testSession'); // null
```

`remove`だと返り値でsessionの中身が返るので、条件文とかに使えそうかも
【PHP】演算子の優先順位

変数`$hoge`が`null`だったら`true`を返したい処理を書いてたとき、
演算子の優先順位で少し詰まったので、備忘録として残します。

```php
$hoge = null
return (bool) $hoge ?? true;
```

これはtrueが返りそうですがfalseが返ります。
実は型キャスト演算子は、優先的に処理される部類の演算子です。
PHPのリファレンスによると、型キャスト演算子 → null合体演算子の順で評価されます。
[PHP: 演算子の優先順位 - Manual](https://www.php.net/manual/ja/language.operators.precedence.php)

なので、null合体演算子 → 型キャスト演算子の順で評価したいのであれば、
括弧でグループ化してあげて、以下のように優先順位を決めます。
```php
$hoge = null
return (bool) ($hoge ?? true); // true
```
PNGファイルを集めてアニメーションGIFとして保存する



## 表題のもの

- Windowsでバッチファイルとして使う想定
  - 同じフォルダに名前が64padで始まるpngファイルを置いて実行する
  - もしくはSendToやD&Dからコマンドライン引数でファイルを与えて実行する
  - ファイル名の順番に合成する
- PILを使用
  - FFmpegでやろうと思ったら意外に面倒だった
- [64パッドのレイアウト図示用MIDIモニタ](https://qiita.com/ucosarv/items/d642a70c19a57daf6945)で保存した画像ファイルの処理用


```png_to_anigif.cmd.py
@python -x "%~f0" %*  & pause & exit /b
# vim: set ft=python :

from pathlib import Path
import sys

from PIL import Image

OUTPUT_PATH = "output_ani.gif"
DURATION_MS = 800
PNG_PATTERN = "64pad*.png"


png_list = [Path(png) for png in sys.argv[1:]]
if len(png_list) == 0:
    png_list = [png for png in Path(".").glob(PNG_PATTERN)]
png_list = sorted(png_list)

for png in png_list:
    print(png)

im_list = [Image.open(path) for path in png_list]

print(f"output: {OUTPUT_PATH}")
im_list[0].save(OUTPUT_PATH, duration=DURATION_MS, loop=0,
               save_all=True, append_images=im_list[1:], optimize=True)
```


## 乗算して保存するバージョン

- 注目するところを明るく、そうでないところを暗くしたい用
- 1枚目をベースに乗算したものをアニメーションGIFとして保存する
  - ファイル名順なので`00_base_Mm3rd.png`等にしておけば1枚目になる
- ImageEnhancerで明るさを底上げしている

入力例 
![00_base_Mm3rd_thumb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/3cafa9ac-0f7a-7c0f-3d93-c579080f9f03.png) 
![64pad_2024-10-07T110040_thumb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/95f4a284-2e71-7880-f952-4dbffc85cb74.png) ![64pad_2024-10-07T110043_thumb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/09a5ce26-292b-8ba0-649b-412934fb1f02.png) ![64pad_2024-10-07T110113_thumb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/7b10e6cd-f0f7-df74-077f-263c2b424cf8.png) ![64pad_2024-10-07T110218_thumb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/20b6e500-ad65-0241-9138-945dda141796.png)

出力例 ※(両手1-5-3-7ボイシング) C△7 Dm7 G7 (両手1-5-1-3) C
![output_ani.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282700/d77a6b93-7add-1ead-30a5-b1c82729564e.gif)



```png_to_anigif_BaseMul.cmd.py
@python -x "%~f0" %*  & pause & exit /b
# vim: set ft=python :

from pathlib import Path
import sys

from PIL import Image, ImageChops, ImageEnhance

OUTPUT_PATH = "output_ani.gif"
DURATION_MS = 800
PNG_PATTERN = "64pad*.png"
LIGHT_FACTOR = 1.5


png_list = [Path(png) for png in sys.argv[1:]]
if len(png_list) == 0:
    png_list = [png for png in Path(".").glob(PNG_PATTERN)]
png_list = sorted(png_list)

im_list = [Image.open(path) for path in png_list]
im_base = im_list[0]
im_rest = im_list[1:]

print(f"output: {OUTPUT_PATH}")
print(f"base: {im_base.filename}")

def proc_image(im, im_base):
    print(f"multiply: {im.filename}")
    im_temp = ImageChops.multiply(im_base, im)
    return ImageEnhance.Brightness(im_temp).enhance(LIGHT_FACTOR)

im_result = [proc_image(im, im_base) for im in im_rest]

im_result[0].save(OUTPUT_PATH, duration=DURATION_MS, loop=0,
               save_all=True, append_images=im_result[1:], optimize=True)
```
投稿 99 ロールフォワード 2024/10/07

本日の勉強時間　2H

いろいろありますが、一番大きな違いは「取り消す」か「やり直す」かの違いです。

ロールバックは「取り消す」処理です。
やりかけの処理を中止して、やり始める前の状態に戻します。
最初の時点に時間を巻き戻すイメージです。

それに対して、ロールフォワードは
「やり直す」処理です。
【TailwindCSS】親要素や兄弟要素の子孫要素によってスタイルを変更する方法

## 親要素の子孫要素によってスタイルを変更する

親要素の子孫要素によってスタイルを変更するには、`group-has-[ ]`を使用します。

```html
<div class="group ...">
  <img src="..." />
  <h4>Spencer Sharp</h4>
  <svg class="hidden group-has-[a]:block ...">
    <!-- ... -->
  </svg>
  <p>Product Designer at <a href="...">planeteria.tech</a></p>
</div>
```

上記の場合、`group`を記述した`div`の子孫要素として`a`が存在する場合に`block`が適用されます。

## 兄弟要素の子孫要素によってスタイルを変更する

兄弟要素の子孫要素によってスタイルを変更するには、`peer-has-[ ]`を使用します。

```html
<fieldset>
  <legend>Today</legend>

  <div>
    <label class="peer ...">
      <input type="checkbox" name="todo[1]" checked />
      Create a to do list
    </label>
    <svg class="peer-has-[:checked]:hidden ...">
      <!-- ... -->
    </svg>
  </div>

  <!-- ... -->
</fieldset>
```

上記の場合、`peer`を記述した`label`の子孫要素が`a`チェックされている場合に`hidden`が適用されます。
基本情報技術者に向けて　Part.6

# SMTP
電子メールの送信に使われるプロトコル
# POP
電子メールの受信に使われるプロトコル
# IMAP(Message Access Protcol)
POPと同じく電子メールを受信するためのプロトコル
POPと異なる点は、送受信データをサーバ上で管理するため、どのコンピュータからも同じデータを参照することができる
# MIME(Multipurpose Internet Mail Extensions)
日本語などの複数バイト文字や、画像データなどファイルの添付を行えるようにする拡張機能のこと
## S/MIME
MIMEに暗号化やデジタル署名の機能を加えて規格
JavaScriptでTODOリストを作ってみた part.1

こんばんは！gamubaruです！

これから技術のアウトプットとして、記事を公開していこうと思います。
記事の書き方はどんどん修正していけたらと思うので、まずは書くことを目標にしていきます。
どうぞよろしくお願いします。

jsの参考サイトはよく見るが、全くアウトプットすることなく読んだだけ（覚えてない）になっているので、
手始めにタスク管理を作ってみたいと思う。

機能としては下記３つを実装していきたい！
1\. タスク追加
2\. タスク削除
3\. タスク編集(更新)

partなんぼまでなるか分からないけど、最後まで頑張ります。

ファイル構成はindex.htmlとjsフォルダにmain.js

では、スタート！！

１．HTMLに記入欄と送信ボタンを設置
--
```html
    <section>
        <h1>TODOリスト</h1>
        <div id="id-todoArea">
            <ul id="id-todoList">
            </ul>
        </div>
        <div id="inputArea">
            <label for="id-input">TODOを追加:</label>
            <input type="text" id="id-input">
            <button id="id-add" >追加</button>
        </div>
    </section>
```

![スクリーンショット 2024-10-07 230631.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904515/cf0a6b7a-a7d2-3347-721d-b2da76051639.png)


２．タスク追加
--
初めに、id属性が"id-add"となっている要素(追加ボタン)を取得する
```js
  const addBtn = document.getElementById('id-add');
```
次にaddBtnがクリックされたら動く、という処理を書く
```js

 addBtn.addEventListener('click', (event)=> {
    console.log(`クリックされたよ！！`)
 })
```
クリックされたら、inputの内容を取得する。このとき内容がない場合は処理終了とする
```js
 addBtn.addEventListener('click', (event)=> {
    const inputTodo = document.getElementById('id-input')
    const todoValue = inputTodo.value;
    if(todoValue === null) return
 })
```
最後にli要素を作成して、todoListに反映させる
```js
addBtn.addEventListener('click', (event)=> {
    // Todoの内容を取得する。なにもない場合は処理終了
    const inputTodo = document.getElementById('id-input')
    const todoValue = inputTodo.value;
    if(todoValue === null) return
    
    // li要素を作成して、todoListに反映させる
    const todoArea = document.getElementById('id-todoList')
    const liElm = document.createElement('li')
    liElm.textContent = todoValue
    todoArea.appendChild(liElm)
    inputTodo.value = ""
})
```
こんな具合で書いてみました。
最後にinputエリアはクリアしました

完成した画面はこんな感じ（cssは無視）
![スクリーンショット 2024-10-07 233614.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904515/0fd9df15-6100-5dd0-af38-86bcb9047dda.png)


概ねこんなもんでいいでしょう。。。


次回はタスクを追加したときに、編集ボタンと削除ボタンを追加する実装を書いていこうと思います。


あざした！
Memoryの機能について

Memoryの機能についてどんなものか勉強してみた！

### 概要
まず、langchainのAPIでは1つ前に投稿した内容を記憶できないみたい。

実行コード
```
import requests
import json

def chat(content):
  url = "https://api.openai.com/v1/chat/completions"
  headers = {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + os.environ["OPENAI_API_KEY"]
  }
  data = {
      "model": "gpt-3.5-turbo",
      "messages": [
          {"role": "user", "content": content}
      ],
      "temperature": 0,
  }

  response = requests.post(url=url, headers=headers, json=data)
  print(json.dumps(response.json(), indent=2))

  chat("Hi! I'm Kubota!")
  ```

  結果
あなたの名前は知らないと言われた、、、
  ```
post_chat_completions("Do you know my name?")
{
  "id": "chatcmpl-AFijxmNo9zNeDHB5KSdBZc8xFczaI",
  "object": "chat.completion",
  "created": 1728310265,
  "model": "gpt-3.5-turbo-0125",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "I'm sorry, I do not know your name.",
        "refusal": null
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 13,
    "completion_tokens": 11,
    "total_tokens": 24,
    "prompt_tokens_details": {
      "cached_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0
    }
  },
  "system_fingerprint": null
}
  ```

そこで役に立つのがMemory！投稿を覚えてくれる

```
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
import openai

langchain.verbose = True
openai.log = "debug"

chat = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, max_tokens=100)
conversation = ConversationChain(
    llm=chat,
    memory=ConversationBufferMemory()
)

while True:
    user_message = input("あなた: ")
    ai_message = conversation.predict(input=user_message)
    print(f"AI: {ai_message}")
```

（回答）おもしろすぎる
```
あなた: 私はそらです
AI: そらですね。それは素晴らしいです！そらという名前の由来や意味など、興味深い情報がありますか？お手伝いできることがあれば教えてくださいね。
あなた: 私の名前はわかりますか
AI: 申し訳ありませんが、私はあなたの名前を知ることはできません。私はあなたが「そら」という名前であることを知っていますが、それ以上の情報は持っていません。他に何かお手伝いできることがあればお知らせくださいね。
```
Salesforceで No such column 'EmailTemplateId' on entity 'EmailMessage'. 

# はじめに
表題のエラーの解決に難儀したので、同じエラーを踏んだ誰かのためのメモです。
一見よくある権限不足エラーですが、「わかるわけないやろ…」という解決方法だったので記録します。

# このエラーは何？

```
 No such column 'EmailTemplateId' on entity 'EmailMessage'. 
```
このエラーは、「Salesforce Integration」ライセンスを使用したユーザーで「Minimum Access - API Only Integrations (最小アクセス - API 限定インテグレーション)」プロファイルを設定した場合に、当該ユーザーからAPI経由で「EmailMessage」オブジェクトの「EmailTemplateId」項目をデータ取得しようとした時に発生しました。

通常このようなエラーは、項目への閲覧権限不足で発生しますが、画面から通常通り権限付与を行おうとしてもこの項目を変更する機能が存在せず、特殊な設定方法が必要です。
（Salesforceへの問い合わせで解決方法がわかりました）


# 解決方法

以下は、Salesforceの問い合わせ結果を引用したものです。
（権利的に問題があったら教えてください）

```
■ 参考手順
1 システム管理者で Salesfroce にログイン
2. 開発者コンソールを開く
Salesforce 画面右上の歯車マークをクリックし、[開発者コンソール] を選択することで開発者コンソール画面が開きます。
3. クエリエディターから SOQL を実行
左下寄りのクエリエディター(Query Editor)タブを選択し、タブの下に表示されるテキストエリアに以下 SOQL を入力の上、左下 [Execute] ボタンをクリックします。
----
SELECT Id,Name,PermissionsEmailTemplateManagement FROM PermissionSet
----
【参考：開発者コンソールのクエリエディター】
https://help.salesforce.com/s/articleView?id=sf.code_dev_console_tab_query_editor.htm&type=5
【参考：SOQL クエリまたは SOSL 検索の実行】
https://help.salesforce.com/s/articleView?id=sf.code_dev_console_tab_query_editor_soql_sosl.htm&type=5
4. 実行結果から対象権限セットの "PermissionsEmailTemplateManagement" の値を True に変更
正常に実行された場合には開発者コンソール画面中央の Query Results 画面に結果が表示されます。
対象の権限セットレコードの「PermissionsEmailTemplateManagement」列の false の値をダブルクリックすることで表示されるチェックボックスにチェックします。
5. レコードの変更内容を保存
実行結果左下の [Save Rows] ボタンをクリックして保存します。

```

# まとめ

EmailTemplateIdへの参照権限は「SOQLを使って "PermissionsEmailTemplateManagement" の値を True に変更」する。
Salesforceのサポートに感謝します。

以上、参考になりましたら幸いです。
ターミナルからWebへ！Streamlitで閏年判定アプリを作ってみよう

## ターミナルで動く閏年判定プログラム
まず、こちらがターミナル上で動作する基本的な閏年判定プログラムです。
```python
def checkUruu(birth):
    if birth < 1582: # 定義されていない年代
        print(f'{birth}年は閏年という概念が存在しません')
    elif birth % 400 == 0:
        print(f'{birth}年は閏年です')
    elif birth % 100 == 0:# 平年
        print(f'{birth}年は閏年ではありません')
    elif birth % 4 == 0:
        print(f'{birth}年は閏年です')
    # その他すべて平年
    else: 
        print(f'{birth}年は平年です')

birth = int(input("西暦を入力してください: "))
checkUruu(birth)

```
## 入れて欲しい要素

#### 1. web上での西暦インプット
現状、ターミナルでの入力を受け取っているので、これを修正したいです。
#### 2. 出力の修正
判定結果がターミナル上に出ます。これをweb上に表示させたいです。
#### 3. 判定ボタンの実装
判定ボタンを設置し、押下時に閏年判定がされて結果が返ってくるようにして欲しいです。

## 完成イメージ

https://uruudoshi.streamlit.app/

## ヒント

#### 1. 西暦インプットについて
数値をそのまま受け取れるコンポーネントに以下の2つがあリマス

- [st.number_input()](https://docs.streamlit.io/develop/api-reference/widgets/st.number_input)
- [st.slider()](https://docs.streamlit.io/develop/api-reference/widgets/st.slider)

#### 2. 出力の表示について
テキストを表示できそうなものを探してみよう
https://docs.streamlit.io/develop/api-reference


#### 3. 判定ボタンについて
ボタンを押した際、関数を実行するにはこの例のどこを変えるべきでしょうか

https://qiita.com/pani_py/items/d1bcb4a487da0a81158b#stbutton

## まとめ
Streamlitを使えば、ターミナル上で動いていたプログラムも、わずか数行のコード変更で簡単にWebアプリ化することができます。今回の閏年判定アプリのようなシンプルなものでも、ユーザーにとっては視覚的にわかりやすく、使いやすい形で提供できる点が大きなメリットです。
Dateオブジェクトのついて勉強

お疲れ様です。

ちょっとUnityを扱ったりしてみて横道に逸れておりましたが、戻って来まして、簡単にカレンダーを作りながら勉強を進めるべく、タイトルの「Dateオブジェクト」の勉強をしてきました。
この記事を５分程度で書けるくらいの内容にし、自分のアウトプットの場とできるように意識して投稿しようと思います。

 # const d = new Date()

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGXwGRW" data-pen-title="Untitled" data-user="mtzkmy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mtzkmy/pen/bGXwGRW">
  Untitled</a> by mtzkmy (<a href="https://codepen.io/mtzkmy">@mtzkmy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
今回、[W3 school](https://www.w3schools.com/js/js_dates.asp)というページを参考にしました！
このサイトは使い方を見るだけでなく、自分でコードを書いてテストする機能もあるので、その場でコードを模写しながらどうなるか実感できて勉強になります:grinning:

このDateメソッドは、結果に表示されている通り、取得した日付をdに代入した使い方をしています。

# toDateString()
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOVwOrP" data-pen-title="Untitled" data-user="mtzkmy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mtzkmy/pen/gOVwOrP">
  Untitled</a> by mtzkmy (<a href="https://codepen.io/mtzkmy">@mtzkmy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
ほぼ同じコードなのですが、toDateString()メソッドだと時間が入りませんがすっきりした見た目になりました！
必要に応じて使い分けは必要なようです:relaxed:
マルチモーダルAIによるエンベディングについて超ざっくり理解する

# はじめに
今回はマルチモーダルエンベディングについてのメモ書きです。いつもと違って自分自身忘れないようにという意味合いが強いので、自分用のざっくり説明になります。

# ことの発端
最近、生成AIを使って色々試していることがあるのですが、その中で画像やらテキストやらを何でもベクトル化するマルチモーダルエンベディングという技術があることを知りました。で、最初はマルチモーダルといっても**画像をテキストに直してそれをベクトル化**してるんじゃないの？と勝手に思い込んでいたのですが、どうやらそうではないらしいです。そもそもテキスト化していたらマルチモーダルとは言えないんで気づけよという話ですが。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463753/9ccca471-26f8-d8ab-ed01-710336c05792.png)


これをきっかけにマルチモーダルエンベディング（画像とテキストのエンベディング）について調べたのでそのメモ書きとなります。

# CLIP

CLIPは画像とテキストをベクトル化（エンベディング）できる機械学習モデルです。まさにマルチモーダルエンベディングですね。

CLIPは、「WebImageText」とよばれるデータセットで学習されています。「WebImageText」はインターネット上にある膨大なデータを利用して作成された4億組の画像とテキストのペアです。画像のタイトルや説明がファイル名になっているものを収集しているので、画像とテキストのペアが得られるようです。

学習方法は下記の通りです。

![CLIP学習.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463753/1f33b1a1-7314-31c1-357a-bd647c99fac6.jpeg)


1. 画像を1枚与える
1. 画像を示すテキストを10パターン用意する（正解は1つ、残りは不正解）
1. 画像とテキストをそれぞれベクトル化して、各組み合わせで類似度を計算する
1. 正解を確認する
1. 正解のペアについては類似度が高くなるように、それ以外は類似度が低くなるようにモデルを学習する

これを繰り返すことで、最終的にモデルは画像とテキストを意味ごとにベクトル化できるようになります。図で示した通り直接画像をベクトル化しており、画像⇒テキストではありません。これがマルチモーダルたる理由です。

# プロンプトエンジニアリングについて

最近、生成AIで流行りの「プロンプトエンジニアリング」ですがCLIPでも既に「プロンプトエンジニアリング」がありました。CLIPは画像分類などにも応用できるのですが、その際に与えるテキストを変えることで分類精度が向上する、という性質があります。この、精度向上のためにテキストを変えることを「プロンプトエンジニアリング」とよんでいたのです。

![CLIP_プロンプトエンジニアリング.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463753/177a5295-46bd-4acf-be55-8d67f01c70ba.jpeg)

上の図でいうと"イヌ"、"ネコ"をそれぞれ"イヌの画像"、"ネコの画像"などの文字に変えると精度が上がる、ということです。

# さいごに

マルチモーダルエンベディングはちゃんと画像、テキストをそのままベクトル化してるんですね。調べてみてスッキリしました。

ブログ↓
https://mochinochikimchi.com

自作アプリLP↓
https://mochinochikimchi.com/applications/mealmotion/index.html
React のテストかいてみた

# はじめに

React のテストを書いてみました。jQuery に慣れてる人からすると「え？画面でしょテストは Selenium ですよね？」と思いがちです。でも、意外と簡単ですので紹介しますね。

# どんな風になるの？

RSpec に慣れてる人なら見た目の抵抗はないと思います。処理の流れはこんな感じ

1. render で描画
1. 操作する要素を取得
1. userEvent を使って要素に入力
1. expect を使って期待値を書く

です。

また selenium を使ってると js のイベントを待つために sleep を多用しがちですが、async / await が使えるので処理を待って次に進むことができます。

```javascript
describe("登録処理", () => {
  it("title と time を入力したら正しく登録できること", async () => {
    const user = userEvent.setup();
    
    render(<App />)

    const title = screen.getByRole('textbox', { name: 'title' });
    const time = screen.getByRole('spinbutton', { name: 'time' });

    await user.type(title, 'test');
    await user.type(time, '31');

    expect(screen.getByText('入力されている学習内容：test')).toBeInTheDocument();
    expect(screen.getByText('入力されている時間：31時間')).toBeInTheDocument();
  });
});
```

# 気づき

使ったライブラリは jest と testing-library です。何が何を提供しているか分かりづらいですが、次のようになっています。

- jest
describe や it などテストフレームワークを提供する

- testing-library
react の描画やイベントに必要な仕組みを提供する

Rails でも RSpec や minitest を使ってテストを書くことができますが、その上に shoulda-matcher や rspec-parameterized を追加してテストを書きやすくすることができますよね。

# 終わりに

React のテストはとっても簡単です。selenium や cypress を使わずにコンポーネントのテストができます。もちろん総合的なテストでは selenium や cypress などのツールは活躍すると思いますが、コンポーネント単位であれば jest / testing-library で十分だなと思いました。

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからお願いします👇

https://projisou.jp
[Standard] セキュリティ評価の標準化

# 一覧
|国際規格|JIS|詳細|
|:--|:--|:--|
|Common Criteria<br>ISO/IEC 15408|JIS X 5070|製品のセキュリティを規定|
|ISMS<br>ISO/IEC 27001|JIS Q 27001|組織のセキュリティ運用体制を規定|
||||





# 参考リンク
[R3F1_ComonCriteria](https://www.ap-siken.com/kakomon/03_aki/pm01.html)
書籍「7日間でハッキングをはじめる本」をM1Macで完遂できるようにしたこと

「7日間でハッキングをはじめる本　TryHackMeを使って身体で覚える攻撃手法と脆弱性」の書籍を購入し、読了したので、書籍内で詰まったポイントを備忘録として記載しておく。(誤植などで実行できないところについては、公式サイトを参照してください。)

https://www.shoeisha.co.jp/book/detail/9784798181578

# Day1:kali linuxの導入

### UTMでインストール
M1 Macでは、VirtualBoxが対応していないため、UTMを利用して導入する。

https://zenn.dev/tomo_devl/articles/0abab48f00acd5


# Day4:Burp suiteの導入

### Burp suiteのブラウザが開かない
書籍では、open browserを押すと普通にブラウザを起動できる形で記載されているが、そうはならなかった。

![エラーイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94311/998987a4-d0e2-097c-6522-510a396f9367.jpeg)

ブラウザを開くことができないので、Firefoxのブラウザ通信をBurp suiteに連携させる。

https://burp-resources-ja.webappsec.jp/Documentation/burp/documentation/desktop/external-browser-config/index.html


# Day6:kerbruteが動かない
書籍に記載れている方法では、
kerbrute_linux_amd64を利用するように説明されている。

しかし、UTM上で作成した環境では下記エラーとなるため、実行ができない。
```
$ ./kerbrute_linux_amd64
./kerbrute_linux_amd64: 1: Syntax error: redirection unexpected
```

### Kerbruteのビルドしてarm64用の実行ファイルを作成する。

https://github.com/ropnop/kerbrute/issues/50#issuecomment-1238926177
の手順を参考にして作成を行う。



## 終わり
これで書籍に記載されている方法は全て完遂できると思います。
まだまだ初心者なので、書籍の範囲にとどまらず精進していきます。
TROCCOを使ったSalesforceへの一括データ投入の勘所

# はじめに

みなさん、Salesforceへのデータの一括投入にはどんなツールを使っていますか？
SalesforceのCSVインポート機能や、公式データローダーなどいろいろツールがあると思いますが、これらのツールで10万件〜100万件といったデータ量を扱うのは結構きついところがあります。

この記事では、TROCCOというETL SaaSを使ってSalesforceに大量のデータを投入したり更新したりするときに気をつけるべきポイントについて記載します。

（この記事では特に新規作成と更新について区別しないのでどちらも一括投入と呼びます。）

https://trocco.io/lp/index.html

## そもそもTROCCOでデータ投入すると何が嬉しい？
SaaSだからこその便利さがあります。

- クラウド上で動かしっぱなしにできる
（ローカルだと勝手にPCがスリープになったり、ネットワークが切れたり…）
- WEB上で転送エラーの確認や再実行ができて便利（属人性低下、再利用性もよい）
- 指定した時間に転送をスケジュールできる

## そもそもどうやってTROCCOでSalesforceにデータ投入する？

TROCCOを使ってSalesforceにデータ投入する方法は無数に考えられますが、弊社では以下のステップで実施しています。

1. 投入データ元となるCSVファイル等を用意する 
1. BigQueryにデータをインポートする
1. (必要であればSQLを使ってデータを加工する)
1. TROCCOでBigQuery→Salesforceの転送設定を作成する

BigQueryをかましているのは、SQLで加工したりフィルタできるので転送の前処理に便利なためです。

# 勘所1: フローを止めろ
Salesforceにはフローという自動で処理を行う機能があります。この機能を無効化せず一括投入すると、思わぬ副作用が起こり得るので気をつけましょう。
転送時間が伸びる程度ならいいですが、Slack通知や外部APIへの呼び出しなんかがあると阿鼻叫喚です。

オブジェクトに紐づくフローを確認するには、「設定> オブジェクトマネージャ > (対象のオブジェクト) > フロートリガー」を開くと、一覧できます。

## バリデーションも止めろ
バリデーションも止めましょう。
「投入データに存在しないカラム」についてのバリデーションでも、データ投入時のレコードの更新をトリガにすべての項目に対してバリデーションが再実行されるので、エラーになってしまいます。

# 勘所2: NULLで上書きするか確認しろ

TROCCOの転送設定では、転送データにNULLがあった場合に値をNULLで上書きするか、更新をスキップするか設定することができます。
データ投入の要件に合わせて設定を行いましょう。

すでにあるデータを意図せずNULLで上書きしたらやばいです。

![スクリーンショット_2024-10-07_22_51_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/601381a3-652b-a9ee-7663-bed928fbeb3d.png)


# 勘所3:ちょっとずつ入れろ

最初は10件くらいで試してみるのがいいでしょう。
リリース時間をとっていざやってみようと思ったら「項目名を間違えている」「書き込みに必要な権限が足りない」といったことが起こります。

その後も、100件、1000件、1万件と、区切り方はそれぞれですが、少しずつ入れていきましょう。
「イレギュラーデータがあって止まっちゃった」とか、前述のように「フローや思わぬ副作用で阿鼻叫喚」となるのが怖いです。

ちょっとだけ入れることで転送時間の見積もりにもなります。大量のデータを投入する時は、少量でリハーサルして時間を見積もりましょう。

# 勘所4:データはソートしろ

もし投入データをSQLのLIMITとOFFSETで区切ってちょっとずつ入れるなら、必ずIDのようなユニークなキーでソート（ORDER BY）をかけておきましょう。
２回目以降の転送をする時もずっと同じソート順であることを担保できないと、投入済みのデータと未投入のデータが区別不能になります。
まあ、ORDER BYを指定しない場合にデータの順序が不定になるかどうかは、転送元の仕様によると思いますがORDER BYは指定した方が念のためです。

# まとめ

自分がTROCCOを使ってSalesforceへデータ投入する際に気をつけているポイントを列挙してみました。
参考になりましたら幸いです。
Copilot in Windowsに「ドラゴンに挑む勇者」の絵をお願いしたら…

# はじめに
　我が家のPCをWindows 11 24H2にしようと思って、あれこれWindows Updateの設定をいじっていたら、タスクバーにCopilot in Windowsが降臨しました。普段はEdgeの Copilotで事足りているので、「君はEdgeのCopilotと何が違うの？」と聞いてみたところ、画像生成もできるというのです。それならば…と、ドラゴンクエストのパッケージイラストをイメージしつつ「ドラゴンに挑む勇者」の絵をお願いしてみたのですが、色々プロンプトに指示を加えていっても想定と違う方向に進んでいってしまうのが面白かったので、経緯をメモに残しておきます。

 # 生成してほしかったもの
  こんなの
 　<img src="https://www.dragonquest.jp/stayhome/assets/img/wallpaper/l/DQ1.jpg">

  # プロンプト1回目
  ```
  ドラゴンに挑む勇者の画像を生成してください。
  ```
  さすがに指示が雑だろうとは思いましたが、結果生成された画像はこちら。

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/34ea387f-fc37-32b9-ed63-775edeb630bc.png)

 　なるほど。勇者は一人ではなくパーティを組んでいるんですね。そして竜に背を向けて、こちらを見てくれているという。もう少し、追加の指示をだして、イメージに近づけていくことはできるでしょうか。

  # プロンプト2回目
  ```
  勇者は一人にしてください。またドラゴンと勇者は対面で戦っている様子にしてください
  ```
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/9f327476-3183-3606-1f6b-9b726309b08e.png)

　追加プロンプトの一つ目の指示は無視されてしまいました。いや、勇者は一人で、他は仲間だとすると指示を無視してはいないのか？そして対面で戦っている様子という指示はなぜか円陣を組む感じになってしまいました。
 右上はもやはキャンプファイヤーですね。左下は勇者がドラゴンブレスを放っているようにも見えます。今回は二つの指示を一度に入れてしまったのが良くなかったかもしれません。

 # プロンプト3回目
 とりあえず、描画する対象の数を指定することにしました。
 ```
 勇者は一人、ドラゴンも一体にしてください。
 ```
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/e06e2906-ea48-f225-dd3e-cfbd1577661e.png)

 おおっ！3回目にして、かなりイメージに近づいたように見えます。特に左下はいい感じです。2回目から3回目にかけての画風の変わりっぷりにも驚かされましたが。

 # プロンプト4回目
 　3回目に生成された左下の絵をベースに、改良していきたいのでプロンプトに画像を張り付けてみることにします。
  ```
  以下の画像をベースにアニメ風の画像にしてください。
  ```
  ※実際には上記プロンプトの後に、直前に生成された画像（左下）を貼り付けています。
  
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/07727ecc-40af-48d7-a147-2d0bd0770a8a.png)

　鳥山明先生風のタッチにはなりませんでしたが、実写風の画像からは少し近づいたような気がします。

 # プロンプト5回目
  ```
 ドラゴンは全身を描画してください
 ```
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/e6799c5e-5ab9-1e2e-6918-6e3e882e214b.png)

  あらら、構図が少し変わってしまいました。が、右下あたりはだいぶんイメージに近づいてきたような気もします。

# プロンプト6回目
```
勇者のポーズは、左手の盾を前に出して竜の攻撃に備えている体制にしてください
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/a7ed0c69-e69c-9a26-4bb9-02a6ce871904.png)

「前」の意味を勘違いして、見る人側に盾を向けている画像も生成されてしまいました。が、右下の絵はだいぶん近い構図になってきました。

# プロンプト7回目
```
森の中ではなく、城を背景にして、城の外でドラゴンと対峙しているようにしてください
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/7dd91436-b376-d9d0-fd32-07548bc4d330.png)

左上の画像は、左右の位置関係こそ逆ですが、ドラゴンクエストのパッケージにだいぶん近づいたように見えます。
最後に青空っぽい空模様を直してもらいましょう

# プロンプト8回目
```
天気は暗雲が垂れ込める曇り空に変えてください
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/189bbfb8-30d7-8fea-f3c1-006d40603484.png)

あれっ？お願いしたわけでもないのに構図の左右が反転した画像を生成してくれました。

# おわりに
　30分あまりプロンプトを打ち込みながら出来上がったものがこちらです。ひとつづつ指示を追加していくことで、少しずつイメージに近い画像を作ることはできそうです。
 ただ、大まかな構図は抑えられるものの、言語での指示だけだと細かい部分を指定するのが難しいですね。

## つくりたかったもの
 　<img src="https://www.dragonquest.jp/stayhome/assets/img/wallpaper/l/DQ1.jpg">

## できあがったもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297527/41b636ea-e4fb-b5d5-4777-8e9bf6c3c193.png)
Qiitaのメール認証時に「無効な認証キーです。」と出た件。

## Qiitaのメール認証時に「無効な認証キーです。」と出た件。

この業界に入ってもう5年、いい加減アウトプットをしていこうと思ってQiitaに登録:point_up:
ドキドキしながらも当たり前のように登録を問題なく進めていきました。

最後に、メールアドレス認証出来ていないっぽいから認証しよう～と認証メールを送信。
送られてきたリンククリックしたら **無効な認証キーです。** と出てしまった。

下に小さく書いてあるURLコピーして試したりしたが出来ず、
結局その作業×3くらいやって、数分時間置いてから
最新のメール内のリンククリックで無事認証出来ました。

同じような事象で、結局最初のメールのリンククリックで出来た方もいるようなので、
こうなってしまったときは色々試してみるのが良さそうですね。

幸先よくないですが、マイペースに学習した記録や
トライの軌跡を残していきたいと思います:muscle_tone2: