OmniAICreator/Qiita-1.07M huggingface dataset:
Luma Dream Machine: 誰でも無料で高品質な動画が作れる時代に


こんにちは。今回は、最近話題のAIによる動画生成サービス「Luma Dream Machine」について詳しく解説していきます。Luma Dream Machineは、テキストや画像から高品質でリアルな動画を誰でも無料で作成できるサービスとして注目を集めています。

## Luma Dream Machineとは？
Luma Dream Machineは、2024年6月12日にLuma AI社が公開した最新の動画生成AIモデルです。テキストプロンプト（文章の指示）や画像から、5秒間の高品質でリアルな動画を高速に生成することができます。
無料プランでは毎月30本の動画を作成可能で、有料プランもあります。AWSのSageMaker HyperPodとNVIDIA H100 GPUを使ってトレーニングされており、スケーラブルで効率的なマルチモーダルTransformerアーキテクチャを採用しています。

## Luma Dream Machineの強み
Luma Dream Machineの最大の強みは、高品質でリアルな動画を高速に生成できることです。わずか120秒で5秒間（120フレーム）の動画を作成可能で、滑らかな動き、映画のようなカメラワーク、ドラマ性のある動画を実現します。

例えば、興奮した子供がアイスクリームトラックに向かって走る動画では、カメラが子供の後ろから追いかけ、スマホで撮影したような自然な揺れを再現しています。また、恐竜の写真から飛び出してきた恐竜が部屋を破壊する様子を描いた動画では、物理的に正確な動きを表現しています。

Luma Dream Machineのもう一つの強みは、物理的に正確で一貫性のあるキャラクターと動作を実現できることです。人物、動物、物体が物理世界とどのように相互作用するかを理解し、キャラクターの一貫性と正確な物理表現のある動画を生成します。

## 使い方
Luma Dream Machineの使い方はとてもシンプルです。Googleアカウントでログインし、テキストや画像を入力するだけで、誰でも簡単に動画を作成できます。特別な知識がなくても、最新の動画生成技術を試すことができるのが大きな魅力です。

まずはLuma Dream Machineのサイトにアクセスします。

https://lumalabs.ai/dream-machine

TRY NOW をクリックしてログインしますが、その際にGoogleのアカウントが必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620986/8ffc708c-ebfe-bef0-b9e4-7d49dab093a4.png)

あとはテキストエリアに英語でプロンプトを入力すれば動画を作成することができます。もしどんなプロンプトを入力していいかわからない場合は、テキストエリアの下に英語でプロンプトが表示されていますので、とりあえずクリックして実行してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620986/490bbe3b-70c4-2f40-8086-484c573f0c47.png)


## 競合サービスとの比較
Luma Dream Machineの最大のライバルは、OpenAIのSoraです。SoraはLuma Dream Machineよりも高品質でリアルな動画を生成できますが、まだ限定的なパートナーのみが利用可能で、一般には公開されていません。

一方、Luma Dream Machineはオープンベータで誰でも無料で使えるようになっており、オープンエコシステムを重視しています。また、モバイルアプリ(iOS/Android)を提供し、スマホでの動画作成に特化しているのも特徴です。

中国のKling AIなども台頭してきており、生成AI分野では各社が覇権を争っています。今後さらなる技術革新が期待されます。

## 課題と今後の展望
Luma Dream Machineはまだ技術的な課題を抱えており、特定のプロンプトではナンセンスな出力をすることがあります。複雑な動きや複数人のシーンではまだ破綻が見られるなど、一貫性や信頼性の向上が今後の課題です。
しかし、Luma Dream Machineは高品質な動画生成、物理的な正確さ、無料での利用可能性、創造性の追求など、様々な面で強みを持っています。特に、OpenAIのSoraなどの競合と比べ、よりオープンなアプローチを取っている点は大きなアドバンテージと言えるでしょう。

## まとめ
Luma Dream Machineは、テキストや画像から高品質でリアルな動画を誰でも無料で作成できる画期的なサービスです。物理的に正確で一貫性のある動画を高速に生成でき、多彩なジャンルの動画作成が可能です。
まだ技術的な課題はありますが、オープンなアプローチと創造性の追求により、動画制作の新しい時代を切り拓く可能性を秘めています。
LWC Javascript 非同期処理の確認

SalesForceのLWCでJavascrpitを触るので、非同期処理を確認。

JavaScript Primer
https://jsprimer.net/basic/async/

Promiseを明示的に使うか、Async/awaitを使って同期処理的に書くか。
やっていることは同じ。

　　
LWCでAPEXを呼び出すときは非同期処理。

Apex を使用したデータの操作
https://trailhead.salesforce.com/ja/content/learn/modules/lightning-web-components-and-salesforce-data/use-apex-to-work-with-data

```javascript:命令的な Apex コール
handleButtonClick() {
    getContactsBornAfter({ //imperative Apex call
        birthDate: this.minBirthDate
    })
        .then(contacts => {
            //code to execute if related contacts are returned successfully
        })
        .catch(error => {
            //code to execute if related contacts are not returned successfully
        });
}
```

この例はPromiseを使った書き方なので、
Async/awaitに書き換えると...

```javascript:命令的な Apex コール async書き換え
async handleButtonClick() {
  try {
    const contacts = await getContactsBornAfter({ birthDate: this.minBirthDate });
    //code to execute if related contacts are returned successfully
  } catch(e) {
    //code to execute if related contacts are not returned successfully
  }
}
```

どっちを使っても同じなのだが、連続してAPEXを呼び出すような場合だと「Async/await」を使った方がネストが深くならないので読みやすい。
Spring Thymeleaf type="date"で過去の日付を選択できないようにする方法　備忘録#3

# type="date"で、過去の日付を選択できないようにする方法

### 初めに

今回は、WEBサイト開発の中で、`「予約時に過去の日付は選択させたくない！！」`と思い調べても見つからず、周囲の賢い方に教えてもらったので、記録として残したいと思います。


###画像イメージ

![スクリーンショット 2024-06-13 22.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807467/e0b78fa3-ae4e-0d72-2646-33895becd1df.png)

↑このように、カレンダーで選択画面が表示され、過去の日付を押そうとすると現在の日付になります。
※Windowsでは、過去の日付が全てグレー色になって、選択できないようになります。

:::note info
このように、日付を選択させないやり方は、thymeleafの機能だけで行うことができます！
:::

###HTML

```diff_html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
  <meta charset="UTF-8">
  <title>予約</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
    crossorigin="anonymous"></script>
</head>

<body>

  <h1 class="text-center mt-5">予約ページ</h1>

  <form action="/reservation" method="post">
    <div class="w-50 mx-auto">

      <table border="1" class="table">
        <tr>
          <th>名前</th>
          <td><input type="text" name="name" placeholder="名前"></td>
        </tr>
        <tr>
          <th>日付</th>
+          <td><input type="date" name="date" th:min="${#dates.format(#dates.createNow(), 'yyyy-MM-dd')}"></td>
        </tr>
      </table>
    <div class="text-center"> 
    
      <button class="btn btn-primary" type="submit" onclick="return confirm('本当に移動しますか？');">予約</button>
    </div>
    </div>
  </form>
</body>

</html>
```

緑の線が引いてある行のように、
`th:min="${#dates.format(#dates.createNow(), 'yyyy-MM-dd')}"`
とすることで、過去の日付が選択されないようになります。

また、minは最小値という意味なので、`max`にすると、逆に未来の日付を選択できないようにします。

これはthymeleafの機能なので、Springの場合は、Controllerに何も書かなくてもエラーチェックをすることができるのです！！

以上で今回の備忘録を終わります！！
Laravel の Eloquent で bulk update するときに updated_at を更新しない方法

## 結論
`users` テーブルのモデル `User` に対し、 `status = 0` の行の `email` を `null` に更新する時の例。

```php
$query = User::where('status', '=', 0); // 対象の検索条件
$query->getModel()->timestamps = false; // これにより updated_at の自動更新をとめる
$query->update(['email' => null]); // 更新
```

バッチなどで一括更新したいが、更新日を変更したくない時に使う。

## 別解
### Eloquent ではなく Query\Builder を使う場合
updated_at は自動更新されない。

```php
DB::table('users')
    ->where('status', '=', 0)
    ->update(['email' => null]);
```

### 対象を全部取得してループ
効率が悪いので非推奨。
```php
$users = User::where('status', '=', 0)->get();
foreach ($users as $user) {
    $user->timestamps = false;;
    $uesr->update(['email' => null]);
}
```

## 補足
`$model->timestamps = false` にすると、updated_at の自動更新をしなくなる。
bulk update の場合、モデルのインスタンスがコード中に出現しないので、 `getModel()` で取得する必要がある。

**対象を全部取得してループ** のケースでは、1件ずつモデルのインスタンスが生成されているので、それぞれ設定して更新を行っている。
乗除算の近似解を加減算のみで求める技術

10を2度掛けると100になる。3度掛けると1000になる。このことを指数を使って表すとこうなる。

10^1 = 10
10^2 = 100
10^3 = 1000
10^4 = 10000
10^5 = 100000

100と1000の間の数、例えば500を10の何乗かで表せるだろうか。答えはイエスである。500は10^2.6989となる。

1桁の整数の対数表を確認しておこう。

10^0.0000 = 1
10^0.3010 = 2
10^0.4771 = 3
10^0.6020 = 4
10^0.6989 = 5
10^0.7781 = 6
10^0.8450 = 7
10^0.9030 = 8
10^0.9542 = 9
10^1.0000 = 10

2と3を掛けると6になる。この計算を対数表を使ってやってみよう。2は対数表を見ると10^0.3010である。3は10^0.4771である。2×3は10^(0.3010+0.4771)となる。足し算を実行すると10^0.7781となる。対数表を見るとそれは6である。これで2×3という掛け算を足し算の手間でやることができた。同様にして2×5や3×3を求めてみてほしい。

この技術は実は何百年も前からある技術で（「対数表 歴史」で検索）、知らない人のために紹介してみた。現代でも乗除算のコストがシビアな際に使えるかもしれない。
【VSCode】特定の行にマークをつけ移動できるようにする方法

Bookmarks という拡張機能を使用することで特定の行にマークをつけ、移動できるようになります。

https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks

Bookmarks をインストールするとコマンドパレットから以下のようなコマンドが実行できるようになります。

![スクリーンショット 2024-06-13 22.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c896785d-7096-2b54-2bbb-bc0574de3965.png)

![スクリーンショット 2024-06-13 22.41.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c62ac087-052d-ef12-a9e0-a74758900260.png)

ラベル付きマークをつけるとサイドバーやガターに以下のように表示されます。

![スクリーンショット 2024-06-13 22.54.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e0ed7819-a054-96a6-12e5-854a0bfbb8a9.png)

サイドバーの各マークをクリックすることでマーク位置にジャンプできます。
GitHub Actionsを利用して、1週間以内に作成したGitHub ProjectsのIssueやPull Requestを自動でCurrent Iterationに加える

GitHub Projectsでの作業をより効率的にするためのGitHub Action「move-to-next-iteration」について紹介します。私はこのGitHub Actionsをforkし、新たに「auto-assign-current-iteration」オプションを追加しましたので、その詳細について説明します。

## 背景
GitHub Projectsを使用してプロジェクト管理を行っている方は多いと思います。しかし、Iteration（反復）ごとに新しいIssueやPull Requestを手動で移動するのは手間がかかります。そこで、これを自動化する「move-to-next-iteration」アクションが役立ちます。

## 「move-to-next-iteration」アクションとは？
「move-to-next-iteration」は、現在のIterationが終了すると、自動で次のIterationにIssueやPull Requestを移動してくれるGitHub Actionです。プロジェクト管理の効率化に大変役立ちます。

詳細はこちらのリンクを参照してください。
[move-to-next-iteration](https://github.com/blombard/move-to-next-iteration)

## forkして追加した機能：auto-assign-current-iteration
今回、私はこのアクションをforkし、「auto-assign-current-iteration」オプションを追加しました。このオプションを使用することで、新たに作成されたIssueやPull Requestが自動的に現在のIterationに追加されます。すでにIterationに追加されたものだけでなく、新規で作成したものに関しても手動での管理が不要になり、さらに効率的にプロジェクトを進めることができます。

## auto-assign-current-iterationの使い方
基本的な設定は[move-to-next-iteration](https://github.com/blombard/move-to-next-iteration)と同じです。 `auto-assign-current-iteration` を使う場合は、オプションを設定してください。

```
name: Move to next Iterations

on:
  schedule:
    - cron: '0 0 * * *' # 毎日0時に実行
  workflow_dispatch: # 手動トリガー

jobs:
  move-to-next-iteration:
    name: Move to next iteration
    runs-on: ubuntu-latest

    steps:
    - uses: tichise/move-to-next-iteration@master
      with:
        owner: OrgName
        number: 1
        token: ${{ secrets.PROJECT_PAT }}
        iteration-field: Iteration
        iteration: last
        new-iteration: current
        excluded-statuses: "Done"
        auto-assign-current-iteration: "true"　
```

## まとめ
forkして追加した「auto-assign-current-iteration」オプションを利用することで、新たに作成されたIssueやPull Requestを自動的に現在のIterationに追加することが可能になりました。これにより、プロジェクト管理が一層簡単になり、開発に集中できる時間が増えます。

ぜひ、皆さんも試してみてください！

フォークしたリポジトリの詳細はこちらです。
[move-to-next-iteration with auto-assign-current-iteration](https://github.com/tichise/move-to-next-iteration)
npm-check-updatesでpackage.jsonのパッケージバージョンを一括更新する（マイナーアップデートも可）

# package.jsonのバージョンをサクッと上げたい

[npm-check-updates](https://github.com/raineorshine/npm-check-updates)を使えば、`package.json`に記載されているパッケージのバージョンを最新のものに一括アップデートできます。

https://github.com/raineorshine/npm-check-updates

## 導入

以下のコマンドで`npm-check-updates`をインストールします。

```zsh
npm i -g npm-check-updates
```

インストール完了後、`ncu`コマンドが利用できるようになります。

## 実行方法

`package.json`の各パッケージの最新メジャーバージョンを確認

```zsh
ncu
```

メジャーバージョンのアップデート

```zsh
ncu -u
```

```zsh
npm install
```

### マイナーバージョンの最新にアップデートしたい場合

`package.json`の各パッケージの最新マイナーバージョンを確認

```zsh
ncu --target minor
```

マイナーバージョンのアップデート

```zsh
ncu --target minor -u
```

```zsh
npm install
```

### パッチバージョンの最新にアップデートしたい場合

`package.json`の各パッケージの最新パッチバージョンを確認

```zsh
ncu --target patch
```

パッチバージョンのアップデート

```zsh
ncu --target patch -u
```

```zsh
npm install
```
AlmaLinuxでmanページをpdfにする


`ps2pdf`というコマンドを実行することでmanページをpdfに変換する事ができます。この`ps2pdf`は`ghostscript`パッケージにバンドルされています。

### ps2pdfが入っているパッケージを調べる

```bash
dnf provides ps2pdf
```

### 実行例

```bash
[root@AL ~]# dnf provides ps2pdf
Last metadata expiration check: 0:12:16 ago on Thu 13 Jun 2024 12:47:56 PM UTC.
ghostscript-9.54.0-14.el9_3.x86_64 : Interpreter for PostScript language & PDF
Repo        : @System
Matched from:
Filename    : /usr/bin/ps2pdf

ghostscript-9.54.0-14.el9_3.x86_64 : Interpreter for PostScript language & PDF
Repo        : appstream
Matched from:
Filename    : /usr/bin/ps2pdf
```

### ghostscriptをインストール

```bash
dnf install ghostscript -y
```

### PDF化してみる

`man -t コマンド | ps2pdf - 名前.pdf`のようにして実行するとPDFにできます

```bash
[yoyo@AL ~]$ man -t man | ps2pdf - man.pdf
[yoyo@AL ~]$ ls -la
drwx------  6 yoyo yoyo  4096 Jun 13 13:02 .
drwxr-xr-x  3 root root  4096 Apr 25 02:08 ..
-rw-------  1 yoyo yoyo  1425 Jun 13 12:51 .bash_history
-rw-r--r--  1 yoyo yoyo    18 Mar 30  2022 .bash_logout
-rw-r--r--  1 yoyo yoyo   141 Mar 30  2022 .bash_profile
-rw-r--r--  1 yoyo yoyo   492 Mar 30  2022 .bashrc
drwxr-xr-x  3 yoyo yoyo  4096 May 29 14:31 .cache
-rw-r--r--  1 yoyo yoyo 64279 Jun 13 13:02 man.pdf
```

これを開いてみると・・・


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599902/f7a1cf1a-a1fa-9e9e-a195-e893bad3b7ef.png)

こんな感じになっています

### スクリプト化

それほど長くはないですが、沢山PDF化するには少し面倒です。そこで、スクリプトを作ります。
※これをroot権限でコンソールに張り付けて実行すればOKです。
```bash
echo '#!/bin/sh' > /usr/local/bin/man2pdf
echo 'man -t "$1" | ps2pdf - "$1".pdf' >> /usr/local/bin/man2pdf
chmod +x /usr/local/bin/man2pdf
```

こうすることで、

```bash
man2pdf コマンド名
```
と実行するだけで、カレントディレクトリにコマンドのマニュアルがpdfで出来上がります。

最近めのコマンドのマニュアルはうまく変換してくれない事があるので注意です。
【備忘録】Raspberry Pi Imager  ダウンロード キャッシュ の場所

[Raspberry Pi Imager](https://www.raspberrypi.com/software/) は、最後にダウンロードしたイメージファイルをキャッシュしています。

そのフォルダーは、↓これらのパスです。

```terminal:MacOS
"/Users/USERNAME/Library/Caches/Raspberry Pi/Imager"
```

```terminal:Raspberry Pi OS
"/home/USERNAME/.cache/Raspberry Pi/Imager"
```

```terminal:Windows
"C:\Users\USERNAME\AppData\Local\Raspberry Pi\Imager\cache"
```

どれも、パスに空白を含んでいるので、コピペして利用する際は注意してください。

---

調べてみても、意外と見つけられなかったので、ここに残しておきます。
【React】タブ切り替えUIの実装~stateとクエリパラメータ、どちらを使うべきか

## はじめに
実務で、タブを切り替えることで表示するデータを変更するようなUIを実装することになりました。
この実装をするにあたり、設計時に、状態管理の方法として以下の2つのアプローチを検討しました。

1. Stateによって切り替える方法
2. クエリパラメーターによって切り替える方法

こちらの記事で、それぞれのメリットとデメリットを比較し、最適な使い分けを考えました。

https://qiita.com/odendayoko/items/e1de22617faecddb76b5

両者の使い分けについてまとめておきます。詳しくは上記の記事をご覧ください。

:::note warn
**stateを使う場合**
- 簡単なUIや内部的なタブ切り替えで、URLの共有を気にする必要がない場合
- パフォーマンスが重要視される場合

**クエリパラメータを使う場合**
- URLの共有やブックマークが重要な場合。例えば、ユーザーが特定のタブの情報を他のユーザーと共有したい場合
:::

この記事では、実際に2つの方法で実装してみます🎉


## 実装
### stateを使ってタブを切り替える場合
まずは、stateを使ってタブを切り替える方法で実装してみます。
stateを使ってタブを切り替える場合、状態管理が全てReactコンポーネント内に収まります。

https://codesandbox.io/embed/8gxty3?view=editor+%2B+preview&module=%2Fsrc%2FApp.tsx

タブを切り替えたときにURLが変わっていないことが確認できます。タブの状態管理はstateだけなので、コード量が少なく、実装がとてもシンプルですね🎉
React Routerなどの外部ライブラリを導入せずにタブを切り替えることができました。

### クエリパラメータを使ってタブを切り替える場合
続いて、クエリパラメータを使ってタブを切り替える方法で実装してみます。

https://codesandbox.io/embed/l6dcrk?view=editor+%2B+preview&module=%2Fsrc%2FTab.tsx

タブを切り替えたときにURLが変化していることが確認できます。また、stateのときと比べてコード量が増えていることがわかります。

クエリパラメータの管理は、React Routeを導入しました。
useSearchParamsを使用し、クエリを取得しています。

https://reactrouter.com/en/main/hooks/use-search-params

余談ですが、このhooksを使うためには、`<BrowserRouter>`の配下にある必要があると初めて知りました💡
React Routerを導入するだけでは使えないんですね…
実務はすでにReact Routerが導入されていたので、気づきませんでした。自分で1から手を動かしてみると新たな発見がありますね！！

## 終わりに
実装してみると、やはりstateの実装の方がシンプルで簡単ですね！！
**基本的にはstateを使って実装する。ただし、ユーザーさんがURLでタブの情報を共有するようなケースが想定される場合は、クエリパラメータを使って実装する**という方針が良さそうですね🎉
AWS　Sagemaker Studioのお掃除方法

# はじめに
お仕事で、AWSのSagemaker Studioを毎日使っています。

イメージは、これです💡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091004/3b8e6ec5-2ce6-143d-3b53-19d304909263.png)

https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/studio-ui.html


左側にフォルダマークがあります。
作業するときはここをいわゆるフォルダ分けのようにして、いろんな分析のワークスペースとして活用できます。便利！

# 課題
分析するのがゴールなので、アウトプットの報告が終わると次の仕事に移りがちですよね・・・。すると、どんどん作業中の一時ファイルなどがワークスペースに溜まり、コストを圧迫していきます！

これはなんとかせねば・・・！

ー立ちはだかる壁ー
ファイルの容量が大きい＝高コスト　ですが、どのファイルの容量が大きいかは、ぱっと見で判断できない・・・(´;ω;｀)ううぅ



# 対応手順
きっとファイル情報を取得するコマンドがあるはず！ということで下記方法で対応しました✨


・ルートフォルダでipy作成し、立ち上げ
・最低インスタンスを立ち上げ
・適当なセルで
```Python
ls -lRh ./
```
を入力し実行。

たくさんファイルの情報が出力されます！

こんな感じ
![コメント 2024-06-12 125241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091004/6bbf6faf-f234-5b45-7262-b93f2a7ed2a6.png)

各フォルダの中身を見てみると、こんな感じです！
![コメント 2024-06-12 125247.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3091004/8598c48a-5c64-a7b2-4e8e-815b0e43a7c4.png)

う～ん、トータル81GB　１ファイル16GB　・・・

★後工程
・出てきた一覧を、画面上で選択＆コピーし、Excelに貼り付け
・張り付けた列を選択　－　F5から空白セルのみ選択　―　削除　
・Excelのデータタブ　ー　区切り位置　―　スペースで区切り　―　すべて文字列　―　完了
・ここまでで、概ね　各ファイルのサイズ、フォルダのサイズがわかるので、整理する際の参考にできます
・青い文字はフォルダを示し、詳細は下部に記載されています。フォルダのサイズもそっちに記載あります。

# 最後に
たくさんお掃除できてスッキリですね！
トータルで削除したデータ容量は、怖いので非公開です・・・
【Scrapyクローラログ】クローリングにおけるログ出力の考え方【前編】

※本記事は「Scrapyにおけるログ出力設計のベストプラクティス【ログはMiddlewareに書こう】」という記事を書こうとしたらログ出力に関する思想だけの部分だけで1記事分ほどになってしまったので、そこだけ抽出したものです。「クローリングで扱うべきエラーログ」「Scrapyによる実装」についてはそれぞれ中編後編で記述しようと思います。

# 目次

1. 初めまして
1. Qiita Engineer Festaでマラソンを完走したい
1. クローリングにおけるログの重要性
    1. クローラにとってクライアントの仕様変更は辛い
    1. ビジネスにおけるクローリングデータの利点<B><font color="Gree">「鮮度」</font></B>
    1. クローリングエラー=<B><font color="Gree">機会損失</font></B>
    1. ∴ ちゃんとクローリングはモニタリングできる環境を整えようね！

# 初めまして
株式会社 Panta Rhei CEOのかずです。[Pandasista](https://x.com/sotsogprinciple)というハンネでツイッターをやっています。pandas大好きです。データも好き。

![IMG_0587.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540865/4df3af57-b0b2-6061-682e-68e174192f26.jpeg)

# Qiita Engineer Festaでマラソンを完走したい
[Qiita Engineer Festa](https://qiita.com/official-campaigns/engineer-festa/2024)という素敵なイベントがあります。

その中で<B>投稿マラソン</B>という素敵なコースが！！！
なんと「<B>38記事書けば素敵な景品がもらえる！！</B>」らしいです。

1日1記事でギリギリ達成みたいです。
本日は3報目！！！
みなさんの参考になるような弊ナレッジを少しでもお裾分けできたら幸いです！

# クローリングにおけるログの重要性

クローリングとは「インターネット上に公開されているデータをコンピュータで自動的に収集する(小生解釈)」ことです。

クローリングシステムにおいて、ログは重要です。理由は、
<B>クローラシステムの実装やアーキテクチャがどんなに完璧でも、クロール先の仕様変更ですぐに使い物ならなくなってしまうから。</B>

## クローラにとってクライアントの仕様変更は辛い

仕様変更はいろいろあります。
- URLディレクトリ構成の変更
- クラス設計の変更
- 実装技術の変更

そうなると、<B>途端に今まで収集できていたデータが収集できなくなります</B>。

もちろんクローラ実装側も、その手の仕様変更に対してロバストになる(≒ちょっとやそっとの変更をされてもデータを収集し続けられる)ように設計します。
具体例を挙げると、要素のパースを```xpath```による相対的な記述方法にしたり、ページ遷移を「ボタンを押す」のではなく「URL直打ち」で行ったり等です。
ここら辺はある程度それなりの技術的対応があります。ここら辺のTips集も後日書きたくなったらまとめたいと思います。

一方で、それでも対応できない場合はクローラの修正が必要になってきます。

## ビジネスにおけるクローリングデータの利点

ビジネスにおいてクローリングデータの利点は<B><font color='Gree'>「データの鮮度が非常に良い」</font></B>という点になります。
自社にデータのアセットが無い時、データの取得方法は概ね
- 他社(他者)から購入する
- 自社で作る
- クローリング

の3通りになります。
他社から仕入れる場合や自社で作る場合、実地調査などを行うためデータの充実度は高いですが、データの鮮度は良くないと言えます。
一方、自社のクローラを作成する場合、公開情報しか取得できないという制約から充実度という面では前者に劣りますがデータの鮮度は非常に高いです。場合によっては当日公開されたデータをその日のうちにビジネスで活用することができます。

まとめると以下のようになります。

|データ取得方法|データの鮮度|データの充実度|
|---|---|---|
|他社から仕入れる|×|○|
|自社で作る|△|○|
|クローリング|<B><font color="red">◎</font></B>|△|

## クローリングエラー=機会損失
データの鮮度が重要になるシーンは多々あります。

<B>【例: ECサイトで商品を仕入れるような商流を持っている商社】</B>
クローラによってECサイトのタイムセールや大幅値下げを検知し、仕入れ価格を大幅に抑えられるタイミングを伺う。

<B>【例: 他社の求人媒体出稿を見て求人ソリューションを提案する人材会社】</B>
クローラによって自社媒体ではないところからの求人出稿を検知し、その出稿主の求人ニーズをリアルタイムで把握する。

ゆえに、<B><font color='Gree'>データの鮮度は本当に大切です。</font></B>

ここで、<B>クローリングエラー</B>が起こってしまうと、すなわち<B>新鮮なデータを取れない状態が続いてしまう</B>と、
- 仕入れ価格を抑えられない
- 人材不足の企業にアプローチできない

ことを意味します。

すなわち<B><font color='red'>機会損失</font></B>です。

## ∴ ちゃんとクローリングはモニタリングできる環境を整えようね！

ここまで話した内容から、

<B>「クローリングエラーは機会損失を意味するよ！」</B>
<B>「とはいえどんな完璧なクローラでもエラーは発生しうるよ！」</B>

という帰結を得ます。

そんなとき、我々ができることは何でしょうか。

そうです。

<B>「エラーロギング」</B>
<B>「エラーモニタリング」</B>
<B>「エラー通知実装」</B>

です。何というか、SREっぽい思想です。

これらがしっかりできると、全レスポンス400からの仕様変更検知からのSlack通知からのクローラ改修といった手立てが打てるわけです。

# まとめ

<B>クローリングエラーは発生しちゃうしでもそれを放置するとビジネス的に機会損失になってしまうから、<font color='Gree'>ログを出力してモニタリング</font>しようね！！！！！！</B>

# 追記
本記事では小生初めて文字にカラーリングをしてみました。読者の方々のQiitaUXを下げてるのか上げてるのかとても心配になっています。
OpenAIでテキストから音声合成すーる（Python）

# はじめに
OpenAIを用いてテキストから音声合成していきます。

下記記事のアプデ版になります。

https://qiita.com/SatoshiGachiFujimoto/items/01fb948017619a008469

# 開発環境
- Windows 11 PC
- Python 3.11
- OpenAI 

# 導入

~~~Text2Speech.py
from openai import OpenAI
import os
from dotenv import load_dotenv
import time
import pygame

# .envファイルから環境変数を読み込む
load_dotenv()

client = OpenAI(organization=os.getenv("ORGANIZATION"),
                project=os.getenv("PROJECT"),
                api_key=os.getenv("API_KEY"))

speech_file_path = "speech.mp3"

# 処理時間を測定開始
start_time = time.time()

with client.audio.speech.with_streaming_response.create(
  model="tts-1", # tts-1, tts-1-1106, tts-1-hd, tts-1-hd-1106
  voice="alloy", # alloy, echo, fable, onyx, nova, shimmer
  input="こんにちは。がちもとです。今日は、オープンエーアイでテキストから音声合成していきます！"
) as response:
  response.stream_to_file(speech_file_path)

# 処理時間を測定終了
end_time = time.time()
elapsed_time = end_time - start_time
print(f"処理時間: {elapsed_time}秒")

# Pygameを初期化
pygame.mixer.init()

# 音声ファイルを再生
pygame.mixer.music.load(speech_file_path)
pygame.mixer.music.play()

# 再生が終了するまで待機
while pygame.mixer.music.get_busy():
    pygame.time.Clock().tick(10)
~~~

~~~.env
ORGANIZATION=<INSERT-YOUR-ORGANIZATION>
PROJECT=<INSERT-YOUR-PROJECT>
API_KEY=<INSERT-YOUR-APIKEY>
~~~

|種類|処理時間（秒）|
|:--|:--|
|tts-1|1.10|
|tts-1-1106|1.27|
|tts-1-hd|1.85|
|tts-1-hd-1106|2.05|

# 実行結果

https://x.com/sotongshi/status/1801244930117103711

お疲れ様です。
Qiitaの初投稿です！

はじめまして、miu-yです。フロントエンドやReactの勉強を目的に投稿を始めさせていただきました！


# 自己紹介

現在社会人2年目でサーバーサイドのプログラマーとして働いています。
業務経験のある言語はJavaのみで、フロントに関しては経験がありません。

## Reactの学習を始めた理由

個人開発としてWEBサービスをリリースしたい…！やフロントの案件を受けたい…といった思いから、Reactの学習を始めました。

# 目標

将来の目標については、最終的に**WEBサービスを一人で作成・運用できるようになる**ことを目標としております。
そのため、今後以下の学習を行って行きたいと考えています！

## 短期的な目標

フロントやReactの基本的な技術、ツールやソフトの使い方を学んで基礎を固める。
アウトプットの習慣を付ける（Qiita投稿の練習・ハードルを下げる）

## 中期的な目標

Reactで基本的なWEBアプリを作成できるようになる。
アウトプットとして読みやすい記事を出せるようになる。

## 長期目標

Reactの案件に参画する。
個人開発としてWEBアプリをリリースする。

# 最後に

いちばん大事なのは継続とやる気だと思います。これから頑張っていきます！

# 参考

Reactの学習にJISOUというサービスを利用中です！
https://projisou.jp/
Javascript アロー関数の基本

# アロー関数とは
従来の関数を簡略的に書ける構文のこと

```
// 従来
function addNumber(number) {
  return number++;
}
```

このように書く
```
const 関数名 = (引数1) => {
  文
}

const 関数名 = (引数1) => 式
```

```
// アロー関数その1
const addNumber = (number) => {
    return number++;
}

// アロー関数その2
const addNumber = (number) => number++;
```

# アロー関数の制約

・メソッドとして使えない
・コンストラクターとして使えない 
・ジェネレーター関数として作成することができない
UTF8→SJIS文字化け

UTF-8では正しく表示されるものの、
Shift-JIS（SJIS）では文字化けしやすい日本語の文字として、次のようなものがあります。

機種依存文字

丸付き数字（①、②、③など）
特殊記号（㈱、㈲、№など）
囲み文字（①、㈱など）
旧字体や異体字（髙、﨑など）
絵文字

スマートフォンやソーシャルメディアでよく使用される絵文字
😄	😃	😀	😊	☺	😉	😍	😘	😚	😗	😙
😜	😝	😛	😳	😁	😔	😌	😒	😞	😣	😢
😂	😭	😪	😥	😰	😅	😓	😩	😫	😨	😱
😠	😡	😤	😖	😆	😋	😷	😎	😴	😵	😲
😟	😦	😧	😈	👿	😮	😬	😐	😕	😯	😶
😇	😏	😑	👲	👳	👮	👷	💂	👶	👦	👧
👨	👩	👴	👵	👱	👼	👸	😺	😸	😻	😽
😼	🙀	😿	😹	😾	👹	👺	🙈	🙉	🙊	💀
👽	💩	🔥	✨	🌟	💫	💥	💢	💦	💧	💤
💨	👂	👀	👃	👅	👄	👍	👎	👌	👊	✊
✌	👋	✋	👐	👆	👇	👉	👈	🙌	🙏	☝
👏	💪	🚶	🏃	💃	👫	👪	👬	👭	💏	💑
👯	🙆	🙅	💁	🙋	💆	💇	💅	👰	🙎	🙍
🙇	🎩	👑	👒	👟	👞	👡	👠	👢	👕	👔
👚	👗	🎽	👖	👘	👙	💼	👜	👝	👛	👓
🎀	🌂	💄	💛	💙	💜	💚	❤	💔	💗	💓
💕	💖	💞	💘	💌	💋	💍	💎	👤	👥	💬
👣	💭	 	 	 	 	 	 	 	 	 
拡張漢字（𠮟、𠮷など）

異体字セレクターを含む文字
邉

Unicodeには異体字セレクターを使用して特定の表示を指定する文字があり、
これらはSJISではサポートされません。
Azure の認証が社内のFWで邪魔されたので、az cli 認証で回避

# 背景

Azure Samples を会社で動かした際、
ローカルデバッグをしようとしたら FW か何かでブロックされた

調べてみると、json の応答を期待しているところで、HTMLで「禁止されています」とか返してくる為、想定外のエラーで吹っ飛んでいた。

本来、DefaultAzureCredential() で環境に合わせて credential 取得してくれると思ったのに・・と

# 結論

az / azd コマンドは特に問題なく動いたので、az cli / azd cli 認証を優先することにした。

実際には、ローカルデバッグ時は以下のような感じで繋げた。

```python: 認証部分
options = {
    "exclude_environment_credential": True,
    "exclude_shared_token_cache_credential": True,
    "exclude_managed_identity_credential": True,
    "exclude_cli_credential": False, # AZ CLI
    "exclude_powershell_credential": True,
    "exclude_developer_cli_credential": False, # AZD CLI
    "exclude_interactive_browser_credential": False,
    "logging_enable": True,
}
azure_credential = DefaultAzureCredential(**options)
```

# あとがき

ただ、この場合、自分の Credential になるので、
ManagedID で RBAC やってると、自分を割り当ててなくて動かない、とか嵌まることも :sweat: 

特に、Cosmos DB の RBAC あたり・・
便利な小技　Shell編

個人的「質はともかく継続する」6日目です。

# 便利ライナー

忘れがちだけどちょっと使えるShellの便利な小技、
便利ライナーを上げてみる。
なんか便利ライナーって電車みたい。

## 正規表現を使ってファイルを検索する

こう書く。
```shell
find . -type f -regex '正規表現'
```

数値が入っているファイルを探す場合はこんな感じ。
```shell
find . -type f -regex '.*[0-9].*'
```

## 一括でファイル内の文字を正規表現で置き換える

直接変更されるので注意。
```shell
sed -i '' 's/変換対象文字/変換後文字/g' file.txt
```
ファイル内の数値をAに置き換える場合はこんな感じ
```shell
sed -i '' 's/[0-9]/A/g' file.txt
```

別ファイルにしたいときはこれ
```shell
sed 's/[0-9]/A/g' file.txt > new_file.txt
```

##　まとめ

ちょっとずつ増やして行ければいいかと思ってます。
今日はここまで。。
【Python】zip関数

`zip()`関数は、2つ以上のイテラブルオブジェクト(リスト、タプル、文字列など)から要素を取り出し、対応する要素同士を組み合わせたイテレータを返します。
# 基本的な使い方
```python
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']

zipped = zip(list1, list2)
print(list(zipped))  # 出力: [(1, 'a'), (2, 'b'), (3, 'c')]
```
この例では、`zip()`関数に2つのリストを渡しています。返り値は、対応する要素同士をタプルにしたイテレータオブジェクトです。`list()`関数を使って、リストに変換しています。
# 複数のイテラブルを渡す
```python
numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
symbols = ['!', '@', '#']

zipped = zip(numbers, letters, symbols)
print(list(zipped))  # 出力: [(1, 'a', '!'), (2, 'b', '@'), (3, 'c', '#')]
```
3つ以上のイテラブルを渡すこともできます。返り値は、それぞれのイテラブルから取り出した要素をタプルにしたものになります。
# 並行してイテレートする
```python
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 88]

for name, score in zip(names, scores):
    print(f'{name} scored {score} points.')
```
この例では、`zip()`関数を使って2つのリストを併せてイテレートしています。各繰り返しで、対応する名前とスコアが取り出されます。
# イテラブルの長さが異なる場合
`zip()`関数は、最も短いイテラブルの長さまで要素を組み合わせます。
```python
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c']

zipped = zip(list1, list2)
print(list(zipped))  # 出力: [(1, 'a'), (2, 'b'), (3, 'c')]
```
この例では、`list1`の方が長いにもかかわらず、`list2`の長さ(3)に合わせて要素が組み合わされています。

`zip()`関数は、複数のイテラブルを扱う際に非常に便利です。辞書やリストの作成、並行したイテレーション処理など、さまざまな用途に使えます。イテラブルの長さが異なる場合の動作にも注意が必要です。
######
参考)　[東京工業大学情報理工学院 Python早見表](https://chokkan.github.io/python/index.html)

https://qiita.com/Akuuuun/items/d46ec233aecddc1f8c6b
Thymeleaf式の参照プレフィックス

JavaのフレームワークであるSpringBootを用いてアプリ開発について学習している過程で、HTMLをテンプレートを動的に生成するテンプレートエンジンであるThymeleafの参照プレフィックスをいくつか使用したので、備忘録として記録したいと思います。
## 参照プレフィックスとは
参照プレフィックスはテンプレート内で特定の種類のデータや機能を示すために使われる記号のことです。この記号を使うことで、参照プレフィックスの後に続く要素が特定のデータや機能を参照することができます。
## 具体的な参照プレフィックスの例
今回は学習の過程で使用した3つの参照プレフィックスについて説明します。
## '@'：URLや静的リソースの参照
'@'プレフィックスはURLや静的リソースを参照するために使用します。下記のその2通りについて説明します。
### URLの生成
下記は'@'を用いてURLを生成した例です。例では'@'プレフィックスを用いることで、'@{/home}'がテンプレート処理時に'/home'というURLに変換され、該当部をクリックすると生成したURLに遷移できるようになっています。
```HTML
<a th:ref="@{/home}">Home</a>
```
### 静的リソースの参照
静的リソースとはWebアプリにおいて、サーバーから直接提供される固定のファイルやリソースのことを指し、主にHTMLやCSS、JavaScript、画像ファイルのことをいいます。
下記はlinkタグでは参照するCSSファイルのパスを指定する必要があり、そこで'@'プレフィックスを使用しています。
```HTML
<link rel="stylesheet" th:href="@{/css/style.css}" />
```
## '#'：ユーティリティオブジェクトやメソッドの参照
次に、'#'プレフィックスについて説明します。'#'プレフィックスはユーティリティオブジェクトやメッセージリソースを参照するために非常に便利です。これを使用することで、テンプレート内でのデータ操作や表示が簡単になり、コードの再利用性やメンテナンス性が向上します。
ユーティリティオブジェクトは数多く種類があり、日付操作や配列操作、メッセージ操作などがあります。
使用例は下記の通りです。下記のコードでは'#date.format'を用いて日付を特定の形式で表示しています。
```HTML
<p th:text="${#dates.format(date, 'yyyy-MM-dd')}">2024-06-13</p>
```

また、メッセージ操作の例は下記の通りです。下記では、htmlファイルの他にmessage.propertiesファイルを用意し、そのファイルに命名規則を設定しておき、htmlでそれを参照します。
```message.properties
welcome.message=Welcome to our site!
```

```HTML:welcome.html
<h1 th:text="#{welcome.message}">Default Welcome Message</h1>
```

## '*'：テンプレート内のローカル変数やオブジェクトのプロパティ参照
'*'プレフィックスは主に選択式として使われます。このプレフィックスを使用すると、現在のコンテキストオブジェクトのプロパティにアクセスし易くなります。
コードの例は下記の通りです。Model.javaのようにフィールドが設定されているモデルがあったと仮定し、このフィールドの値をform.htmlで表示するというのが大まかな流れです。form.htmlへ遷移する前にController.javaでモデルクラスのインスタンス化とフィールドの値をセットし、model.addAttribute("user", new User());で値をセットし、form.htmlへ渡しています。form.htmlでは'${user}'でuserインスタンスを受け取り、そのインスタンス内のフィールドを'*'プレフィックスを用いて'*{name}'と'*{email}'の値を表示しています。
このように、'*'プレフィックスはコントローラかビューに渡したインスタンス内のデータを使用するのに役立ちます。
```Java:Model.java
public class User {
    private String name;
    private String email;
    // getters and setters
}
```

```Java:Controller.java
@Controller
public class Controller {
    @GetMapping("/form")
    public String showForm(Model model) {
        model.addAttribute("user", new User());
        return "form";
    }
}
```

```HTML:form.html
<div th:object="${user}">
    <p th:text="*{name}">User Name</p>
    <p th:text="*{email}">User Email</p>
</div>
```
## まとめ
今回はThymeleaf式における以下3つのプレフィックスについて使い方を説明しました。
①'@'：URLや静的リソースの参照
②'#'：ユーティリティオブジェクトやメソッドの参照
③'*'：テンプレート内のローカル変数やオブジェクトのプロパティ参照
Thymeleaf式の導入によって、フロントエンド側でも汎用的にデータ操作が可能になる点がとても便利だなと感じました。特に②の一部である配列操作や③のプロパティ参照はJavaで学習した内容をそのまま流用できるので使いやすかったです。
また、プレフィックスという記号を用いることでこのコードがどのような使い方なのか一目で理解できるようになっている点も使いやすいなと感じました。
次回も開発過程で理解できかなった点を深堀りしたいと思います。
AIにチャレンジ！ MidjourneyのPersonalizationで自分好みの絵を描かせる、たった１つのコツ

こんにちは、みなさん！今回は、Midjourneyに新しく追加された「Personalization」機能を使って、自分好みの絵を描かせる方法をご紹介します。

# Personalizationとは？

プロンプトを書くたびに、多くのことが「言わずに済まされて」います。Midjourneyのアルゴリズムは通常、これを独自の「好み」で補います。
これらは実際にはコミュニティ全体のバイアスや好みの集まりです。

でも、好みはみんなそれぞれ違いますよね！
Personalizationは、あなたがどんなものを好むのかを学習して、空白をあなたの好みに合わせて埋めるようになります。

# パラメータ

Personalizationに関しては2つのパラメータが追加されています。
- **--p**: Personalizationを有効化します
- **--s**: 0から1000の値を指定でき、値が大きいほど好みを強く反映させます

`/settings`でPersonalizationをオンにしておくと自動的に--pを追加してくれるようになります。
ただし、Nijiモデルはまだ対応されていないようです。

![Midjourney_Personalization-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809123/2f675d50-62e5-a755-cd91-c3b7d5bbae2a.png)


# 好みの学習

好みを学習させないとPersonalizationは使えません。

[pair rankingページ](https://www.midjourney.com/rank)にアクセスすると2つの画像が表示されます。
![Midjourney_Personalization-005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809123/0329fca4-fe08-3b7d-af48-36e781d0cba6.png)


好みの画像を選択することで好みを学習させます。
200以上学習させるとPersonalizationの機能を使うことができるようになります。

200回も画像選択のためにマウスを使うのは大変です。
でも、簡単に好みを学習させられるショートカットキーが用意されています。
ショートカットキーのおかげで、それほど苦労なく好みを学習させることができました。
- **1**: 左の画像を選択
- **2**: 右の画像を選択
- **3**: スキップ

# たった１つのコツ

次から次と色々な絵が出てきますが、必ずしもどちらかを選ぶ必要はありません。
そのために **3: スキップ** が用意されているのです！
抽象画を好きなら抽象画が出るまでスキップ、写実的な人物画を好きなら写実的な人物画が出るまでスキップ。
こうすることで強く好みを学習させることができます。
スキップを活用して、しっかりと好みを学習させましょう。

# まとめ

Midjourneyは手軽に絵が描けて楽しいですよね。
今まではちょっと好みと違うなと思ったときに修正するのが大変でした。
でもこれからは、Personalizationを上手く使って自分好みの絵を描かせることができるようになります。
さあ、あなたもPersonalizationを試してみて、自分だけの素敵な絵を作りましょう！
Scala CLIのREPLで外部のライブラリを使用する方法

scala-cliでREPLを起動する際に、コマンドライン引数`--dependency`で使用するライブラリを指定することが可能です。

```
$ scala-cli repl --dependency org.scalacheck::scalacheck::1.18.0
Welcome to Scala 3.4.2 (17.0.9, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                                                                                              
scala> import org.scalacheck.Gen
     | 
                                                                                                                                                                                                              
scala> println(Gen.const(1).sample)
Some(1)
```

### 参考: `.sc`ファイル内のライブラリは無視される

次のように`.sc`ファイルを用意して、REPLから`:load`しても外部のライブラリは使用できないみたいです。

```scala:test.sc
//> using dep "org.scalacheck::scalacheck::1.18.0"

import org.scalacheck.Gen

println(Gen.const(1).sample)
```

```
$ scala-cli
Welcome to Scala 3.4.2 (17.0.9, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                                                                                              
scala> :load test.sc
-- [E008] Not Found Error: -----------------------------------------------------
3 |import org.scalacheck.Gen
  |       ^^^^^^^^^^^^^^
  |       value scalacheck is not a member of org
1 error found
```
初投稿

# 初投稿
何かを発信することに不安や恐怖があり躊躇していましたが、自分のステップアップのためにもアウトプットを意識的にしようと思い記事を書くことにしました。
仕事中に出会ったエラーの解消方法や、自己学習のまとめなどちょっとしたことをアウトプットしていきたいと思います。

# 自己紹介
取得済み資格
- Java SE 11 Silver
-  基本情報技術者試験

言語（実務で使用したことあるもの）
- Java
- Python
- JavaScript
- SQL
上記以外にも自己学習で少し触った言語もありますが、本当に基礎レベルなので割愛します。

# やりたいこと
- 自己学習していく中で見つけたポイントや要点まとめ
- ちょっとした成果物（まずは何かを作り上げるところを目指す）
- 競技プログラミング

定期的に何か成果物を作ろうと思って作業し始めても途中で投げ出しがちなので、簡単なもの（電卓とかそういうレベルで）をまずは1から作り上げるというのをいったんは目標にします。
競技プログラミングは練習問題的なものをやってはいるのですが、コンテストには参加したことがありません。まずは自分が納得するレベルまで過去問題に触れ年内にはコンテストに参加することを目標にします。
next.jsとsupabaseでコメントをリアルタイム表示するアプリを作る　その１

こんばんは。
アウトプット太郎です。
技術力をもっと上げたいと考えています。

https://qiita.com/Sicut_study/items/40fd5aac278b001a2fee

こちらの記事を読み、
やっぱりアウトプットしないと知恵として身につかないよな・・・。
と再認識しまして、アプリを作ってみることにしました。

６月中の完成を目指して、頑張っていこうと思います。

作るアプリは題名の通り、リアルタイムでコメントが表示、更新されるアプリケーションです。

使う技術は
next.jsとsupabaseで考えています。
どっちも使ったことはありません。

supabaseは↑の記事でワードが出てきており、
気になって調べたらおもしろそうだったので使ってみようと思いました。
リアルタイムデータベースということなので、
更新がすぐかかったら嬉しいアプリってなんだろうと考え、
コメントを投稿、即反映されるアプリにしようと決めました。

next.jsを選んだ理由は名前は聞くけど使ったことがないので、
どんなものか知りたく、選びました。

今はchatGPTもあるので、
先生役を務めてもらいながらとにかく完成させることを目標に行動していきます。

私は熱しやすく冷めやすいので、
熱いうちにどんどん進めていきます！

まずsupabaseでプロジェクトを作成しました。

そして、
nodeの環境を整え、新しいプロジェクトを作成。

```
npm run dev
```

でlocalhost:3000にnext.jsのテスト環境が立ち上がりました！

これだけでも達成感がありますね笑

次はsupabaseとの接続でしょうか。

次回に続きます！
BubbleでDiscordのロールを変更　Add/Remove Guild Member Role  で　Missing Permissions て返ってくる問題

Discord botの作り方や基本的な設定は、[ノーコードラボさんのこちらの記事](https://blog.nocodelab.jp/entry/discord#3-%E6%96%B9%E6%B3%95Create-Message-API%E3%81%A7%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E9%80%81%E4%BF%A1)

1.BOT PERMISSIONS は、「Manage Role」が必要。もしくは「Administer」
2. **これが重要！！！！　botのロールを一番上にする。**![スクリーンショット 2024-06-13 14.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/646f053a-1bce-216e-cf55-8ca02f5f7ea0.png)これをしないと、権限ありません、っていわれます。。
```JSON
Raw response for the API 
Status code 403
{"message": "Missing Permissions", "code": 50013}
```
3.BubbleのAPI Connectorの方はこんな感じ![スクリーンショット 2024-06-13 21.33.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/42ea484c-707d-5de1-f055-da640cfa5546.png)
Organizations形式のCloudTrailログをAthenaから参照

# CloudTrailログをAthenaで参照
下記ドキュメントに、CloudTrailのログをAthenaで参照するためのCREATE文が存在しますが、こちらは1アカウントのみの形式です。Organizations形式のログについて、記載はありませんでした。

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/cloudtrail-logs.html#create-cloudtrail-table-partition-projection

# Organizations形式のログテーブル
下記CREATE文を実行することで、Organizations形式のCloudTrailログをAthenaから参照することができたため、ご活用ください。
パーティションも考慮してます。

```sql
CREATE EXTERNAL TABLE log_database.cloudtrail_log_table (
eventversion STRING,
useridentity STRUCT<
               type:STRING,
               principalid:STRING,
               arn:STRING,
               accountid:STRING,
               invokedby:STRING,
               accesskeyid:STRING,
               userName:STRING,
  sessioncontext:STRUCT<
    attributes:STRUCT<
               mfaauthenticated:STRING,
               creationdate:STRING>,
    sessionissuer:STRUCT<  
               type:STRING,
               principalId:STRING,
               arn:STRING, 
               accountId:STRING,
               userName:STRING>,
    ec2RoleDelivery:string,
    webIdFederationData: STRUCT<
               federatedProvider: STRING,
               attributes: map<string,string>
    >
  >
>,
eventtime STRING,
eventsource STRING,
eventname STRING,
awsregion STRING,
sourceipaddress STRING,
useragent STRING,
errorcode STRING,
errormessage STRING,
requestparameters STRING,
responseelements STRING,
additionaleventdata STRING,
requestid STRING,
eventid STRING,
resources ARRAY<STRUCT<
               arn:STRING,
               accountid:STRING,
               type:STRING>>,
eventtype STRING,
apiversion STRING,
readonly STRING,
recipientaccountid STRING,
serviceeventdetails STRING,
sharedeventid STRING,
vpcendpointid STRING,
eventCategory STRING,
tlsDetails struct<
  tlsVersion:string,
  cipherSuite:string,
  clientProvidedHostHeader:string>
)
PARTITIONED BY (
   `account` string,
   `region` string,
   `timestamp` string)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://【バケット名】/AWSLogs/【organizations id】/'
TBLPROPERTIES (
  'projection.enabled'='true', 
  'projection.account.values'='【アカウントid, アカウントid, アカウントid, アカウントid】', 
  'projection.account.type'='enum',
  'projection.region.values'='ap-east-1,ap-northeast-1,ap-northeast-2,ap-northeast-3,ap-south-1,ap-southeast-1,ap-southeast-2,ca-central-1,eu-central-1,eu-north-1,eu-west-1,eu-west-2,eu-west-3,sa-east-1,us-east-1,us-east-2,us-west-1,us-west-2',
  'projection.region.type'='enum',
  'projection.timestamp.format'='yyyy/MM/dd', 
  'projection.timestamp.interval'='1', 
  'projection.timestamp.interval.unit'='DAYS', 
  'projection.timestamp.range'='2023/04/01,NOW', 
  'projection.timestamp.type'='date', 
  'storage.location.template'='s3://【バケット名】/AWSLogs/【organizations id】/${account}/CloudTrail/${region}/${timestamp}')

```
PythonでスクレイピングしてExcelに書き出す

自分メモ
業務で使用しているシステム(made by Excel)に郵便番号から配達局をオフラインで検索する機能を実装するため、全国の郵便番号と配達局のデータベースが必要になりましたが、なかったのでデータベースを作成するためのコードを書きました。

郵便番号リストは日本郵便のHPからダウンロードします。

郵便番号だけほしかったので、郵便番号リストをExcelで保存して、郵便番号がA列に来るよう余計なデータを削除し、頭が0の郵便番号は7桁になっていないので、ExcelVBAで桁を揃えました。

スクレイピング前のリストには、A列に郵便番号が入力されているだけの状態です。
このコードを動かすと、スクレイピングでB列に配達局の名前、C列に配達局の郵便番号と住所が入力されます。

完成前に中断しても、コードを書き換えずに途中から再開します。

画面が切り替わったとき、time.sleep(1) でエラーが出ずに進みました。

一応、確認しましたが、スクレイピングを規制するような利用規約は見当たりませんでした。

```py
import openpyexcel
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

workbook = openpyexcel.load_workbook('結果を書き出すブック名.xlsx')
sheet = workbook['シート名']

maxRow = sheet.max_row + 1
maxClm = sheet.max_column + 1

# 列を指定（例：3列目＝C列）
target_column = 3 #C列を指定

# 行を逆ループして最終行を探す 逆ループだと失敗したから消した 表にヘッダーが必要
for i in range(1, maxRow):
    if sheet.cell(row=i, column=target_column).value is not None:
        saisyugyo = i

driver = webdriver.Edge()
driver.get('https://www.post.japanpost.jp/shiten_search/') 
                        #日本郵便HPゆうゆう窓口検索画面

LastRow = sheet.max_row

for i in range(saisyugyo + 1, LastRow):
    driver.get('https://www.post.japanpost.jp/shiten_search/')
    cell_a = sheet.cell(row=i, column=1).value #A列

    driver.find_element(By.NAME, 'zip').send_keys(cell_a) #A列の郵便番号を入力
    time.sleep(1)

    driver.find_element(By.ID,'number').submit() #検索ボタンをクリック
    time.sleep(1)

    search_path = '//*[@id="main-box"]/div/form/table/tbody/tr[2]/td[1]/a'
    driver.find_element(By.XPATH, search_path).click() #検索結果のリストから郵便局名をクリック
    time.sleep(1)

    GetOfficeName = driver.find_element(By.TAG_NAME, 'h1').text #配達局名をB列に書き込む
    sheet.cell(row=i, column=2).value = GetOfficeName

    GetAddress = driver.find_element(By.CLASS_NAME, 'wrap').text #配達局の郵便番号、住所をC列に書き込む
    sheet.cell(row=i, column=3).value = GetAddress

    workbook.save('結果を書き出すブック名.xlsx')

driver.quit()
```
無駄な動きもあると思いますが、とりあえずこれで思い通りの動きをしてくれます。
初心者なので、改善点等を指摘していただけたら助かります。
企業での生成AI利用ガイド（１）～ガイダーAIの現場から

# 目次
[企業での生成AI利用ガイド（１）～ガイダーAIの現場から](https://qiita.com/sdozono/items/c0621de189a1035fa26b)
[企業での生成AI利用ガイド（２）～RAGで「宇宙際タイヒミュラー理論」を読み解く!?](https://qiita.com/sdozono/items/d5a98bf6a147b5b238bc)
[企業での生成AI利用ガイド（３）～夏目漱石と対話？社内知識ベースを活用し、AIで温故知新なるか](https://qiita.com/sdozono/items/fa1e0be23a1214b08004)
[企業での生成AI利用ガイド（４）～2024年のAIまとめ、そして「時間と量子もつれの不思議な関係」](https://qiita.com/sdozono/items/a009dfa49a01bceda878)

## 自己紹介
　はじめまして。企業向け生成AIプラットフォームGidr.aiと製品を協業開発しております堂園（どうぞの）と申します。ここしばらく、毎日のように様々な業種のお客様とお会いして、生成AIをどのように利用できるのか、ということについてお話を伺っています。仕事場にも大きな変化が生じている今、その様子を書き留めて、どんなことを考えているのか記録しておきたくなりました。せっかくですので、お役に立つ情報なども書き連ねていければと考えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114744/2468a83c-62ea-deb4-5e12-46e2edec8d37.png)

## 日々目にしていること
　先日、コールセンター製品の展示会で丸二日、AIに関する説明をひたすら続けていました。周りのブースも8割ぐらいはAIという文字がそこかしこに踊っています。製品を見て回られる皆様も情報集めを目的として、自分の会社で役立つAIがないか、ずっと探しておられました。単にコールセンターのエージェント（オペレーター）をサポートするツールとしてだけでなく、それぞれの企業の事務処理に役立つ機能も提供してくれないのか、ということを探しておられたのは印象的でした。また、コールセンター業界にも大きな変化が起こっており、特に今年は、もう電話の応対がメインストリームだった時代がそろそろ終わるのではないかと思ってしまうほど、「それ以外の」対応方法が注目されるようになっている気がします。
　少し大きい企業になると、ほとんどの会社に「AIチーム」があり、すでにデザインやモックで、自分たちの作りたい夢のAI製品のイメージやコンセプトが固まってきているようです。しかし、自分たちで裏側の実装にかかったとたん、壁にぶつかっておられる、という姿もよく目にします。APIはOpenAI, Microsoft, AWS, Google Gemini, Anthoropic, ローカルLLMまで、いったいどこのサービスを使えば良いのか、RAGは単純なもので要件を満たせるのか、グラフRAGにするべきか、など考えることが多すぎます。またAI周りで悩むだけでなく、データを入力するところでどうやって精度を出すべきなのか（OCRで文書を取り込んで解析するのか。音声認識で質問を判定させるのか、動画やカメラ画像から判定できるのか、などなど、などなど・・・・。）
　AIのおかげで仕事が減っている現実も目の当たりにします。当事者は本当に途方に暮れています。どう変化に対応していけるのか、うまく波に乗れた場合にはどうなるのか、そのあたりもレポートしたいと思います。

今日はこの辺で・・・。またお会いしましょう。

 ## 独り言
 大手航空会社と一緒に働いているチームがうれしそうに写真を送ってきました。うれしそうだなぁ。ガイダーAIも数千人規模でみんなに使ってもらえるAIなのだよ、とつぶやきつつ、そういう時代が来る時を夢見ながら今日もスタートアップの製品を大切に、大切に育てないと思ってます。Gitlabでひたすらイシューを増やしているだけですが・・・。
Qiita Engineer Fest 2024を完走するための準備


# はじめに
タイトルの通り、何やらQiitaさん公式の大きいイベントがやっている模様ですが、完全にスタートダッシュに出遅れました。
38記事投稿するとQiitaのグッズが貰えるそうです。まだマラソン完走を諦めてはいません。

完走するための計画を自分に対しての戒めも兼ねて作っていきます。

:::note
一応技術的なことも書いてあるので、最後まで読んでいただけるとありがたいです。
この記事を読んだ方はぜひ一緒にマラソン完走しましょう:smile:
:::

> ### Qiita Engineer Festa 2024とは？
> Qiita Engineer Festa 2024とは、2024年6月3日から7月25日まで期間限定で開催される、「複数の記事投稿> キャンペーン×かける配信イベント」の夏のお祭りです。
> 今年は楽しみ方を3つご用意しました
>「記事投稿キャンペーン」で豪華プレゼントゲットのチャンス
>「投稿マラソン」でQiitaオリジナルグッズプレゼント
> 親しいメンバーと一緒にアウトプットを楽しむ「Organization対抗戦」
> また、イベントに参加してくれた方への賞品もございます！
> ご自宅から、オフィスから、全国各地より皆様のご参加をお待ちしております。
> 一緒に熱い夏を楽しみましょう！
引用元: https://qiita.com/official-campaigns/engineer-festa/2024

## そもそも何でやろうと思ったの？
- 採用活動を通じて、今の会社をもっと有名にしたいと思ったから。
- Qiitaグッズが欲しいから
- 多分マラソン完走する人少なそうだから(ドヤれそう)

## 投稿ネタを探す
まずはどんな記事を書くか、テーマを決めないといけないですね。
なんとな〜くこんな記事書けそうだなを書き出して39記事分を洗い出してみました。
実際にどんな記事を書くかはこちらに記載はしないです(お楽しみということで)が、今のところ考えている記事のテーマはこんな感じです。

- マネジメント関連: 9記事
- 技術関連: 15記事
- 業務効率化・コミュニケーション: 6記事
- マインド・ライフスタイル: 2記事
- テーマ記事: 3記事
- 記事の書き方: 2記事
- ネタ記事: 1記事(もっと増えるかも)
- 書きかけの記事完成させる

38記事よりも多くなりそうです。
実際こんな書けるかなって感じです。

ちなみにこの記事が記事の書き方についての1本目です。
頑張ります。

## テンプレートを用意する
 たくさん記事を書くなら記事のテンプレートを作った方が良さそうです。

 ```
 # はじめに
 # 対象者
 # ここからは実際の内容をまとめる
 # まとめ
 # おわりに
```

書き出してみましたが、使うかどうかはまだ分かりません。
迷ったときはとりあえずテンプレートから使おうと思います。

## 記事をGit管理する
VSCode上で記事を書くと効率的なので、Gitで管理することにしました。
![スクリーンショット 2024-06-12 22.51.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730384/6e8dd364-96ec-f2b0-eaba-aa560cf7a09c.png)
作りました。

Git管理にしたら色々と良さそうな感じがしたので、ちょっと調べてみるとQiitaのCLIが公式であるようですね！早速やってみます。

## Qiita CLIを使って記事投稿が出来るようにする
~~Github Actions使って自動的に記事投稿するでもいいと思うんですけど、都度CLI叩くのが面倒になったらやろうと思います。~~
後述にありますが、Qiita CLI使ったらGithub Actionsのセットアップも勝手にやってくれました。すごい。

こちらの公式の記事を参考にセットアップしていきます。

ただ自分はDocker環境内を作ってそこでCLIが動くようにしました。
下記コンテナ用ファイルはポチポチして作りました。(不要なところはトリました)

``` .devcontainer/devcontainer.json
{
	"name": "Node.js & TypeScript",
	"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
	"features": {
		"ghcr.io/devcontainers-contrib/features/bash-command:1": {
			"command": "echo hi!"
		},
		"ghcr.io/devcontainers-contrib/features/npm-package:1": {
			"package": "typescript",
			"version": "latest"
		}
	}
}
```

Qiita CLIは下記の公式記事を参考にしてセットアップしました。
参考: https://qiita.com/Qiita/items/666e190490d0af90a92b

限定公開とか、Organizationsの紐づけとかをマークダウンで投稿管理出来るのが、とてもDX的にいい感じです。

## 記事を書く時間を明示的に確保する
**1日のどこの時間を使って記事を書くか決めてブロッキングする**

とはいえ仕事があるため、平日はできるだけ業後の数時間を記事執筆に充てることにしました。少なくとも1時間は確保したいと考えています。(予定があるときは除く)
土日は、朝のルーティン後にPCを起動して執筆を始める予定です。土日にどれだけ記事をストックできるかが重要なので、サボらないようにしたいですね。(2日で5記事書ければ理想です)

## 記事を少しずつ作っていく
CLIを使えば雛形を簡単に作るところまでは出来そうなので、後は簡単に記事のための開発環境をサクッと作るところをマラソン序盤のうちにやっていこうと思います。
後はマネジメント系の記事は構想まではあるんですけど、骨子に作ったり、空いた時間を見つけてマークダウンにメモっていったりとしようと思います。


## 実際のペースを算出してみた
土日5記事(やばすぎる)書く計算をしてみました。

#### 期間の計算
 - 6月13日から7月17日までの日数：35日間
 - 土日の数：土日が5週あるので、10日間
####  土日に書く記事数
 - 土日で5記事×5週＝25記事

#### 平日に書く記事数
 - 38記事 - 25記事 = 13記事
 - 35日 - 10日（土日） = 25日（平日）
 - 平日のペース
  - 13記事 ÷ 25日 ≈ 0.52記事/日

### 結果
  - 土日：毎週5記事
  - 平日：1週間あたり約3記事(2日に1記事のペース)

土日3記事ぐらいにして平日の比重を上げるかを検討中です。

# おわりに
38記事かなり大変そうですが地道に投稿していこうと思います。
DOM, Element, Node について


業務ではjQueryばっかり書いているのですが、JavaScriptをしっかり覚えられていないのでぼちぼちjsも慣れておくか～って思って参考サイト見返してるときに…
そういえばDOMやらそこら辺の認識が曖昧だな？と思ったのでまずはそこら辺の復習。
## DOM
Docment Object Modelの略。
JavaScriptなどのプログラミング言語からHTMLなどのマークアップ言語とCSSにアクセスできるようにするためのAPIのことを指す。
DOMを介してHTMLやXMLの構造を定義し、文書へのアクセスや操作、変更が可能になる。
HTMLの構造全体をDOMツリーと呼ぶ。DOMツリーはNodeで構成されている。
## Node
DOMツリー配下に存在する1つ1つの要素。
DOMツリーを意識して操作を行うときのオブジェクト。
例: appendChild、removeChild、parentNodeなど

Nodeの種類は何種類か存在する。
Document（Document型Node・ドキュメントノード）
Element（Element型Node・エレメントノード）
Attr（Attribute型Node・属性ノード） etc.
## Document
Nodeの種類の一種。
ドキュメント全体を表すオブジェクト。
document.getElementxxx()はDOMツリー全体から引数に指定されたidやclassの要素を取得する。
## Element
Nodeの種類の一種。Nodeの中のタグにあたる部分。
タグに対して操作を行うときのオブジェクト。
例: style、attribute、width、heightなど
### こんな感じのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813674/b5c7343f-2d2c-6d32-62d3-b93ae0b55a45.png)

腑に落ちた参考サイト：https://kuroeveryday.blogspot.com/2018/11/difference-between-dom-and-node-and-element.html
Gitのブランチ運用をストレスなく行えるコマンド１選

# 困りごと
developブランチ等にマージされて、リモートリポジトリから削除されたブランチは何もしないとローカルリポジトリに残り続ける。  
以前使ったブランチ名をもう一度使うことができなかったり、ブランチを移動するときに多すぎてストレスになる。

# 解決方法
`hogehoge`ブランチが削除されたリモートブランチだとする。
以下のコマンドで、削除された全てのリモートブランチ（`origin/hogehoge`はそのうちの一つ）をローカルから消す。
その後、ローカルブランチ`hogehoge`を手動で消す。

```bash
git remote prune origin
```

ローカルブランチを手動で消すときは、VSCodeのGit Graph拡張機能がおすすめ。

https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph

# おわりに
READMEの更新やワークフローの軽い修正をする際に、同じブランチ名を使いがち（ブランチのprefixルールが決められていればなおさら）なので、マージされたブランチはこまめに消していきたい。
はじめてのチーム開発

# 1. はじめに
　この度、アプレンティスの課題として、第一回チーム開発を行いました。その説明・雑感などをまとめます。
# 2. 自己紹介
　弁護士を目指して法学部に進学、大学を休学して独学で司法試験の合格を目指すも挫折。人生に悩んでいたところ、以前からプログラミングに興味があったことを思い出し、2024年1月29日から学習開始。4月からアプレンティス5期生。出身は北海道。
# 3. 仕様技術
・HTML/CSS
・JavaScript
・PHP
・MySQL
・サーバーはPHPビルトインウェブサーバーを使用
・Git/GitHub
・フレームワークの使用は禁止
# 4. プロダクト説明
### 4-1. 開発の背景
　今回私たちのチームが開発したものは日報管理アプリです。「自分たちの役に立つものを開発せよ」というテーマをもとに考えると、アプレンティスの毎日の課題として投稿している日報を有効活用できていないのではないかという点に思い至り、楽に振り返りができるようにするためのアプリを開発することになりました。
### 4-2. 実際の画面
一覧画面
![picture1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774443/7723bd8d-0a35-fe0d-8225-6f96d5b0a3e4.png)
詳細表示のモーダルウィンドウ
![picture2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774443/7ae36156-5c7c-5a87-fe7a-ec6a65e8af74.png)
登録画面
![picture3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774443/64a9a72f-901f-8eb9-dbe2-0210b0bf7129.png)

### 4-3. 機能
##### 日報表示ページ
　登録した日報をカレンダー形式で表示します。中長期的な目標を書き留めておく欄と、月および週ごとの合計学習時間を表示する欄を目立つ箇所に配置しました。カレンダーの日付部分には、その日に勉強したことの概要をタグとして表示しています。さらに、登録画面で入力した自己評価の数字に基づいて各マスの背景色が変わる仕様にすることで、自分がどの程度頑張ったのかを一目でわかるようにしています。各マスをクリックすると表示されるモーダルウィンドウの中の編集ボタンを押すと、登録画面に遷移します。
##### 登録ページ
　登録画面では、何も入力していない日付には当然空欄が表示され、編集済みの日付には入力済みの情報が表示されるようになっています。入力後に登録ボタンを押すと日報が保存され、表示ページに遷移します。CRUD機能のCUDは同じ操作をすることになります。タグを追加、削除する機能も実装しました。
### 4-4. 追加してもよかった機能
　今回の開発では実装できませんでしたが、登録画面の一括リセットボタンはあったほうが良かったと思います。また、機能ではありませんがタグの追加と削除はそのためのページを用意したほうがスムーズに開発できたような気がします。
# 5. チームでの活動
### 5-1. 自分の担当箇所
・形を作ってもらったカレンダーをJavaScriptで自動生成すること
・データベース関係
### 5-2. 終えてみての感想
　端的な感想は、とても楽しかった、となります。開発を進めていく中で自分の成長を実感できました。
### 5-3. 意識していたこと
　チーム開発をできるだけ実務のものと似せる努力をしました。とはいっても私には実務経験がないので、せいぜい「GitHubでmainブランチはリリース用に使うらしいから開発段階で迂闊にプッシュするのはやめよう」程度のものですが、少しは役に立ったと思っています。
　他にも、週2回行われていたチーム会では最初のほうに発言して会話の流れを作るように努めていました。
### 5-4. 反省点
　たくさんありますが、主要なものを挙げます。
##### 反省点その1　作業の選り好み
　書いたコード量はそこそこ多かったのですが、デザインを考えたりプレゼン準備をするなど自分があまり興味を持てない作業は他の人に振ってしまうことが頻繁にありました。今回のチーム開発で（少なくとも私は）ストレスフリーだったのも、チームメンバーがフォローしてくれたからでしょう。実務では楽しいことばかりできるわけはないので、これは良くない点でした。
##### 反省点その2　設計が甘かった
　特にテーブル定義ですが、使用するクエリの洗い出しまでやっておくべきでした。途中で「このINSERT文を使うならこのテーブル設計では問題があるのでは？」となり、急遽変更したことがありました。それどころか、いきなりテーブルをひとつ増やすこともありました。今回は軌道修正にそこまで苦労はしませんでしたが大規模プロジェクトである程度開発が進んでいる場合では容易に修正できるとは思えないので、かなり細かい部分まで設計を詰める必要を感じました。
##### 反省点その3　設計（変更）の共有が遅かった
　データの扱いについて「PDOで引っ張ってきたデータをJSONにエンコードしてJavaScriptで操作する」といった程度の設計すら共有できたのは開発開始1週間前とかだったので、もっと早い段階に学習してメンバーに共有するべきでした。
　設計の変更についても「必要と感じたら変更して事後報告をする」という姿勢でしたが、これも小規模開発だから結果良かっただけで、本来は好ましくないと思います。
# 6. 個人的に学んだこと
　体系的な学習の重要性を強く感じました。今回のプロダクトでは非同期通信を使ったのですが、非同期通信については本腰を入れて勉強したことがなく、開発中は断片的な知識を集めて場当たり的な解決をしていました。そのせいでとても時間がかかり、完成後もいまいち腑に落ちていません。よく耳にする「座学より実務のほうがスキルがつく」という意見も間違いとは思いませんが、体系的な知識の会得という点においては書籍などを用いた座学に軍配があがる気がしました。
　また、余談気味ですが、実務では徹夜作業をすることも当然あるだろうから軽く体験してみようと思い、1日だけですがレッドブルを飲んで朝まで作業する日を設けてみました。作業中はアドレナリンのおかげかそこまで苦ではなかったものの、開発終了後に元の体に戻るのが大変でした。良い体験でした。
# 7. おわりに
　今回のチーム開発で作成したプロダクトは技術的に難しいものではなかったものの、チームでの開発の進め方については多く学べることがありました。第二回チーム開発はもちろん、現場での開発で活躍できる人材になれるよう日々精進していきます。
macOS のストレージ空き容量をチェックするシェルスクリプト

Jenkins の各 macOS ノードでストレージ不足の警告をしたい。

macOS で `df` コマンドを使用して、ルートディレクトリ `/` の空き容量を取得し、それをGB単位で表示するシェルスクリプトの例を以下に示します。

## スクリプト

```sh
#!/bin/bash -xe

# ルートディレクトリの空き容量を取得し、ギガバイト単位で計算
available_kb=$(df -k / | tail -n 1 | awk '{print $4}')
available_gb=$(echo "scale=2; $available_kb / 1024 / 1024" | bc)

# 判定と出力
if (( $(echo "$available_gb >= 50" | bc -l) )); then
  echo "空き容量は ${available_gb} GB です。50GB 以上あります。"
else
  echo "空き容量は ${available_gb} GB です。50GB 未満です。"
fi
```

### 解説

1. `df -k /` コマンドを使用してルートディレクトリの空き容量をキロバイト単位で取得します。
2. `tail -n 1` でヘッダー行を除外し、空き容量の値だけを取得します。
3. `awk '{print $4}'` で空き容量の値を抽出します。4列目が空き容量のため `$4` を指定しています。GNU の df コマンドなら `--output=avail` で空き容量だけが出力されます。
4. `echo` と `bc` を使用して空き容量をキロバイトからギガバイトに変換します。`scale=2` なので小数点以下2桁まででます。
5. 空き容量が50GB以上か未満かを判定し、適切なメッセージを出力します。


## 利用

出力の部分をチャット通知にしました。警告は無視されがちなので、警告メッセージには具体的にどう対処すればいいのかを記載するようにしました。未来のメンバーだったり自分だったりに期待です。

シェルスクリプトのみなので各ノードに実行環境を用意しなくていいのが好きポイントです。
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（6/100）

【6日目】 
トピック1：SAPS/4HANAサプライチェーン計画の概要（6/6）

≪問題6≫
需要計画サイクルの予測に含まれているものはどれですか。
（３つ選択）
□マーケット情報
□過去の見積数量
□過去の生産計画数量
□過去の受注数量
□1回限りのイベント

≪解答≫
■マーケット情報
□過去の見積数量
□過去の生産計画数量
■過去の受注数量
■1回限りのイベント

≪解説≫
◆過去の受注数量は、将来の需要予測の基礎となります。また、マーケット情報や一度限りのイベント（展示会など）も需要予測の対象となります。
◆この需要予測の結果として、需要計画が計画独立所要量としてリリースされ、これらは調達および生産計画の基礎となり、現在の受注などで消費できるようになります。
◆これら一連の流れが、需要計画サイクルと呼ばれます。