OmniAICreator/Qiita-1.07M huggingface dataset:
OpenShift AI - User Management

#### OpenShift AI

Red Hat® OpenShift® AI とは、柔軟でスケーラブルな人工知能 (AI) および機械学習 (ML) プラットフォームです。このプラットフォームにより、企業はハイブリッドクラウド環境全体で AI 対応アプリケーションを大規模に作成および提供できるようになります。

OpenShift AI はオープンソース・テクノロジーを使用して構築されており、実験、モデル提供、革新的なアプリケーションの提供のための、信頼性と一貫性に優れた運用機能を提供します。

https://www.redhat.com/ja/technologies/cloud-computing/openshift/openshift-ai

#### User Management
ここでは、OpenShift AI 2.9.1 / Red Hat OpenShift on IBM Cloud (ROKS) 4.14 の環境で、OpenShift AI の User Management を確認します。

OpenShift AI 導入時点では、`Data Science administrator groups` に `rhods-admins` Group、`Data Science user groups` に `system:authenticated` Group が設定されています。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/2dcff065-7c33-ee1c-2925-b5a2a8c5015f.png)

`rhods-admins` Group は、User 設定がない状態です。
```shell
$ oc -o yaml get group rhods-admins
apiVersion: user.openshift.io/v1
kind: Group
metadata:
  creationTimestamp: "**********"
  name: rhods-admins
  resourceVersion: "********"
  uid: ************-******-*******
  users: []
```

各 Group の役割と権限は以下のとおりで、デフォルトで 全 User が `Data Science user groups` 相当で、cluster-admin 権限のある User が `Data Science administrator groups` 相当でアクセス可能です。

https://docs.redhat.com/en/documentation/red_hat_openshift_ai_self-managed/2.9/html-single/managing_users/index#overview-of-user-types-and-permissions_user-mgmt

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/61e7c614-58e8-d6ba-1d9b-c439e7225680.png)


試しに、以下のような Group を作成し、`Data Science administrator groups` に `openshift-ai-additinal-admin`、`Data Science user groups` に `openshift-ai-additinal-user` を追加してみます。
```shell
$ oc -o yaml get group openshift-ai-additinal-admin
apiVersion: user.openshift.io/v1
kind: Group
metadata:
  creationTimestamp: "**********"
  name: openshift-ai-additinal-admin
  resourceVersion: "********"
  uid: ************-******-*******
users:
- IAM#*******@jp.ibm.com
```
```shell
$ oc -o yaml get group openshift-ai-additinal-user
apiVersion: user.openshift.io/v1
kind: Group
metadata:
  creationTimestamp: "**********"
  name: openshift-ai-additinal-user
  resourceVersion: "********"
  uid: ************-******-*******
users:
- IAM#*******.*******@ibm.com
- IAM#******@jp.ibm.com
```

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/0f8dbff1-7ade-2412-bc55-7573e28fe079.png)

上記設定の確認例として、`Jupyter Notebook` (Applications -> Enabled) の `Administration` Tab を見てみます。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128125/b7ec6704-7c2c-c6cc-3f15-3f42732fcbba.png)

`Privilege` の箇所に各 User の権限が表示されています。ここでは、最下段の User で Login しているため、他 User の Notebook の参照 (View Server) や、停止 (Stop Server / Stop all servers) が実行可能です。
イベントに魅せられて

## 概要
初めまして。
イベントに魅せられて、早速…でもない記事を投稿し始めた`わーちゃん`と申します。
Markdownの書き方に慣れる為、記事の中でいろんな使い方を試してみます。

## 1:君に決めたっ！~~(某キャラクターボイスで復唱推奨)~~
今回のイベントに伴い、ずっと何を書こうか悩んでいました。
で、放置してました。
ふと最近になり、どうせだから挑戦してみようと思い、重い腰(腕)を持ち上げました。
イベント概要を確認すると私にぴったりの記事を発見
[はじめての記事投稿](https://qiita.com/official-events/34628038b7f0b5084b20)


>こんな人におすすめ
アウトプットしたいと思っているが勇気がでない方
Qiitaで記事投稿したことが無い方
この企画をきっかけに初投稿してみようと思っている方
Qiitaオリジナルグッズなどのプレゼントが欲しい方

まさに該当‼というわけでこのテーマに沿って少し頑張ってみようと思います。

## 2:そもそも・・・
私自身、~~「エンジニア王に俺はなる！」~~、エンジニア未経験でゼロベーススタート。
将来色々考えて考えてかんがえて、きめたのが今年。
Rubyはプログラム言語はもちろん、notionやFigmaなどの一般的にも使われているであろうツールも知りませんでした。
「はじめての記事投稿」も何かこう。文字を入力しながら考えている始末です💦

## 3:最近のことアウトプットでも書くべ
最近はスクールの課題を習得する日々を送っています。
直近で学んだ事`ER図`、`Marmeid`？の書き方。
```
erDiagram
    USERS {
        int id
        string name
        string email

省略

    CHOICES ||--o{ CHOICE_ANSWERS
    LISTS ||--o{ QUESTIONNAIRE_LISTS
    CATEGORIES ||--o{ QUESTIONNAIRE_CATEGORIES
```

```
|| は一対一（1:1）の関係
o{ は一対多（1:N）の関係
中間テーブル: 多対多の関係を管理するために使われるテーブル
など
```

GPT等を駆使して回答のコードを紐解いています。
プログラミングの世界を紐解きたい、まではいきませんが、日々精進あるのみ。

## 4:今後
今の時代GPT含め便利なツールがあるから、全くの初心者でもある程度のコードはかけてしまう。すごいことでもあり、恐ろしくも感じる。
でも、下記のようにすぐうまくはならない

- [ ] プロのレシピを参考にマーボー豆腐、挑戦
- [ ] 簡単にできるだろうと思っていたけど、できあがりがいまいち
- [ ] 簡単にはいかない
<br>

- [ ] GPTが回答したコードだから、サイト・アプリ問題なく動くだろう
- [ ] コードを入力したがエラー出まくり
- [ ] 簡単にはいかない

道具、立ち回りのうまさ、何が原因か考える・・・。
うまく言えないけど、たぶんこんな感じ。

日々進化していく世界、だからこそいろんな手法？が存在して、適材適所？で利用するものは最大限利用して、「わーちゃんだから、任せたい」そういう人にわたしはなりたい。:relaxed:
[SQLServer]ストアドプロシージャの作成_3

# 0. はじめに
基本的なMRP(Material Requirements Planning)のストアドプロシージャのサンプルです。
この例では、製品構成表（BOM: Bill of Materials）と在庫情報を使って、必要な部品の発注量を計算します。

# 1. サンプルテーブルの作成
```sql:CREATE_TABLE_BOM.sql
-- 製品構成表（BOM: Bill of Materials）
CREATE TABLE BOM (
    ProductID INT,                  -- 製品ID
    ComponentID INT,                -- 部品ID
    QuantityRequired DECIMAL(10, 2) -- 必要数量
);

-- 在庫情報
CREATE TABLE Inventory (
    ComponentID INT PRIMARY KEY,    -- 部品ID
    QuantityOnHand DECIMAL(10, 2)   -- 在庫数量
);

-- 注文情報
CREATE TABLE Orders (
    OrderID INT IDENTITY(1,1) PRIMARY KEY, -- 注文ID
    ProductID INT,                         -- 製品ID
    QuantityOrdered DECIMAL(10, 2),        -- 注文数量
    OrderDate DATE                         -- 注文日
);
```

# 2. サンプルデータの挿入
```sql:INSERT_BOM.sql
-- 製品構成表（BOM）のデータ
INSERT INTO BOM (ProductID, ComponentID, QuantityRequired) VALUES (1, 101, 2);
INSERT INTO BOM (ProductID, ComponentID, QuantityRequired) VALUES (1, 102, 1);
INSERT INTO BOM (ProductID, ComponentID, QuantityRequired) VALUES (2, 101, 3);
INSERT INTO BOM (ProductID, ComponentID, QuantityRequired) VALUES (2, 103, 2);

-- 在庫情報のデータ
INSERT INTO Inventory (ComponentID, QuantityOnHand) VALUES (101, 5);
INSERT INTO Inventory (ComponentID, QuantityOnHand) VALUES (102, 2);
INSERT INTO Inventory (ComponentID, QuantityOnHand) VALUES (103, 1);

-- 注文情報のデータ
INSERT INTO Orders (ProductID, QuantityOrdered, OrderDate) VALUES (1, 10, '2024-06-01');
INSERT INTO Orders (ProductID, QuantityOrdered, OrderDate) VALUES (2, 5, '2024-06-02');
```

# 3. ストアドプロシージャの作成
```sql:CREATE_PROCEDURE_usp_CalculateMRP.sql
CREATE PROCEDURE usp_CalculateMRP
AS
BEGIN
    SET NOCOUNT ON;

    -- テンポラリテーブルの作成
    CREATE TABLE #MRPResults (
        ComponentID INT,                -- 部品ID
        QuantityRequired DECIMAL(10, 2),-- 必要数量
        QuantityOnHand DECIMAL(10, 2),  -- 在庫数量
        QuantityToOrder DECIMAL(10, 2)  -- 発注数量
    );

    -- MRP計算
    INSERT INTO #MRPResults (ComponentID, QuantityRequired, QuantityOnHand, QuantityToOrder)
    SELECT 
        bom.ComponentID, 
        SUM(o.QuantityOrdered * bom.QuantityRequired) AS QuantityRequired, 
        ISNULL(i.QuantityOnHand, 0) AS QuantityOnHand, 
        CASE 
            WHEN SUM(o.QuantityOrdered * bom.QuantityRequired) > ISNULL(i.QuantityOnHand, 0) 
            THEN SUM(o.QuantityOrdered * bom.QuantityRequired) - ISNULL(i.QuantityOnHand, 0) 
            ELSE 0 
        END AS QuantityToOrder
    FROM 
        Orders o
        JOIN BOM bom ON o.ProductID = bom.ProductID
        LEFT JOIN Inventory i ON bom.ComponentID = i.ComponentID
    GROUP BY 
        bom.ComponentID, 
        i.QuantityOnHand;

    -- 結果の表示
    SELECT * FROM #MRPResults;

    -- テンポラリテーブルの削除
    DROP TABLE #MRPResults;
END;
```

# 4. ストアドプロシージャの使用例
```sql:EXEC_usp_CalculateMRP.sql
-- MRPの計算を実行
EXEC usp_CalculateMRP;
```
### 実行結果
以下の結果が出力されます。
ComponentID | QuantityRequired | QuantityOnHand | QuantityToOrder
------------|------------------|----------------|----------------
101         | 35.00            | 5.00           | 30.00
102         | 10.00            | 2.00           | 8.00
103         | 10.00            | 1.00           | 9.00
@nuxt/eslintを使ったNuxtでのESLint設定

## この記事は
Mac x VScodeでNuxtするときの最低限のESLint設定についてのメモ。
@nuxt/eslintを使います。
https://eslint.nuxt.com/packages/module

## eslintのvscodeへのインストール
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint

## @nuxt/eslintモジュールの追加とeslint.config.mjsファイルの生成
以下コマンドで@nuxt/eslintモジュールを追加する。
```
npx nuxi module add eslint
```
モジュール追加後、npm run devなどでアプリケーションを起動するとeslint.config.mjsが生成されるので、必要に応じてカスタマイズ。
```js:eslint.config.mjs
// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs'

export default withNuxt(
  // Your custom configs here
)
```
## ESLint Stylistic
nuxt.config.tsにESLint Stylisticの設定をする。
``` ts:nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/eslint'
  ],
  eslint: {
    config: {
      stylistic: true
    }
  }
})
```
### ちなみにESlint Stylisticとは
ESLint Stylisticは、ESLint内でコードのスタイルやフォーマットを統一するためのルールセット。
Prettierとは違うアプローチでコードのフォーマットを実行できる。

https://eslint.style/

## NPM Scriptsへlintコマンドを設定
package.jsonにeslintコマンドを設定したのち、npm run lint app.vueを試すと、
``` json:package.json
{
  "scripts": {
    ...
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    ...
  },
}
```
このような感じになる。
![](https://storage.googleapis.com/zenn-user-upload/0ee131ec7599-20240610.png)

## VScodeの設定
以下設定で保存時の自動フォーマットが実行される。

``` json:.vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}
```

ES Lint v9以前はESLint Flat configの設定をのためにVScodeに以下設定が必要だったが、v9以降は不要。
```
{
  // Enable ESlint flat config support
  "eslint.experimental.useFlatConfig": true
}
```

ついでにrecommendationsの設定もしておく。
``` json:.vscode/extensions.json
{
    "recommendations": [
        "dbaeumer.vscode-eslint"
    ]
}
```
https://future-architect.github.io/articles/20200828/
改行

[前回の問題解決しました。](https://qiita.com/suzukidog/items/ed710873b41ac456096a#%E8%A7%A3%E6%B1%BA20240624)

***
最近「本当に俺はwebエンジニアになれるのか…？」という不安と同じくらい「就職できたとして俺は毎朝起きて仕事を続けられるのか…？」という不安も出てきています。
最初はそんな不安を跳ね除けるくらいやる気だったのに；；
それに伴って勉強に熱が入らなかったり、勉強時間も少なくなっています。

最悪諦めても生きられる環境にいるからこんなにのうのうと勉強しているんだと思います。
もっと気合い入れろ！ビシッ！

***
みなさんはマークダウン形式の改行はどうしていますか？
俺はGithubではbrタグ、Qiitaでは普通に改行しています。
しかしこの前、文末にバックスラッシュ単体をつけても改行できると知りました。

いちいちbrタグを打つのを面倒に感じていたし、半角スペース２つの改行はなんとなく…というか視認性？が悪い気がして避けていた（そんなこと言ったらQiitaの改行も同じことですが）ので試しに使ってみました。

が、うーん…。なんか使いにくい…。

brタグと比べたら楽に打てることは間違い無いのですが慣れていないせいですかね、あまり使い勝手はよくなかったです。
Qiitaでは引き続き普通の改行、Githubでは今後バックスラッシュを使っていきましょうかね。

ちなみにバックスラッシュを使うことで起こる弊害があるのかどうかは知らないので、結局brタグに戻るかもしれません。
【Flet】DataTableでスクロールしたい

# 概要
Fletを試していてちょっと躓いたところがあったので備忘録として記載します。
データ表を表現しようと、FletのコントロールであるDataTableを使おうとしたのですが長い表になるとスクロールできませんでした。
スクロールできるようにする方法を簡単な例で説明いたします。

# 結論
スクロール可能なコントロールの中に配置しないといけないそうです。
Fletではスクロール可能なコントロールが決まっているようです。

https://flet.dev/blog/scrolling-controls-and-theming/

# 簡単な例で説明
Pythonバージョン：3.10.10
Fletバージョン：0.22.1

### DataTableをそのまま配置するとスクロールできません
スクロールバーが表示されず、全データ見ることができないです。
![スクリーンショット 2024-05-31 162856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601563/7e771b87-bb2d-f957-d35c-91632fb2185a.png)

<details open><summary>コード例</summary>

```python
import flet as ft

# DataTableのcolumns向けにリストを整形する関数
def get_data_table_columns(header):
    return [ft.DataColumn(ft.Text(t)) for t in header]

# DataTableのrows向けに2次元リストを整形する関数
def get_data_table_rows(data):
    converted_rows = []
    for row in data:
        cells = [ft.DataCell(ft.Text(str(t))) for t in row]
        converted_rows.append(ft.DataRow(cells=cells))
    return converted_rows

def main(page: ft.Page):
    page.window_width = 600
    page.window_height = 600

    # 表示したいヘッダとデータを用意
    header = ["ヘッダA", "ヘッダB", "ヘッダC"]
    data = [[f"データA{str(i+1)}", f"データB{str(i+1)}", f"データA{str(i+1)}"] for i in range(100)]

    data_table = ft.DataTable(
        columns=get_data_table_columns(header),
        rows=get_data_table_rows(data)
    )

    page.add(data_table)


ft.app(target=main)
```
</details>

### Columnコントロールに入れてスクロールできるようになります
ColumnコントロールにDataTableを配置し、スクロールとexpandを設定するとスクロールができるようになります。
![datatable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601563/854ea444-8c45-7d2f-d294-4a7d8fc78b5a.gif)

<details open><summary>コード例</summary>

```python
import flet as ft

# DataTableのcolumns向けにリストを整形する関数
def get_data_table_columns(header):
    return [ft.DataColumn(ft.Text(t)) for t in header]

# DataTableのrows向けに2次元リストを整形する関数
def get_data_table_rows(data):
    converted_rows = []
    for row in data:
        cells = [ft.DataCell(ft.Text(str(t))) for t in row]
        converted_rows.append(ft.DataRow(cells=cells))
    return converted_rows

def main(page: ft.Page):
    page.window_width = 600
    page.window_height = 600

    # 表示したいヘッダとデータを用意
    header = ["ヘッダA", "ヘッダB", "ヘッダC"]
    data = [[f"データA{str(i+1)}", f"データB{str(i+1)}", f"データA{str(i+1)}"] for i in range(100)]

    data_table = ft.DataTable(
        columns=get_data_table_columns(header),
        rows=get_data_table_rows(data),
    )

    # ColumnコントロールにDataTableを配置、
    # スクロール設定と拡大設定をしておきます
    col = ft.Column(
        controls=[data_table],
        scroll=ft.ScrollMode.ALWAYS,
        expand=True
    )
    
    page.add(col)


ft.app(target=main)
```
</details>


# 最後に
同じところで困っている人の手助けになればと思います。
【Flet】ヘッダ表示固定の簡易DataTableを作ってみました

# 概要
FletのDataTableですが、表をスクロールするとヘッダもスクロールされて見えなくなってしまいます。
これを改善するために、ヘッダ表示固定の簡易DataTableを作ってみました。


# 解決したいこと
Flet標準のDataTableは、ヘッダごとスクロールされます。
ヘッダが見えなくなっちゃうので、ヘッダが固定されたデータ表を作りたい。

↓Flet標準のDataTable
![datatable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601563/54cc9143-4e66-f1ff-2c93-fcc9c7a78280.gif)

# ヘッダ固定のデータ表を作ってみました
イメージ図は以下になります。

FixedHeaderDataTableクラスは、Columnコントロールを継承しています。
その中でヘッダ部分とスクロール可能なデータ部を配置しています。
そのFixedHeaderDataTableクラスをPageへ配置しています。

![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601563/9f8981b8-a6f5-523f-1d47-11856de7e4f5.png)


<details open><summary>コード</summary>

```python
import flet as ft

# 簡易DataTableのクラス、Columnコントロールを継承
class FixedHeaderDataTable(ft.Column):

    def __init__(self, headers, rows, column_widths):
        super().__init__()
        self.headers = headers
        self.rows = rows
        self.column_widths = column_widths
        self.expand = True  # ページに対して自動伸縮

        # ヘッダ部の作成
        header_controls = [
            ft.Container(ft.Text(header, weight=ft.FontWeight.BOLD), width=width, alignment=ft.alignment.center, bgcolor=ft.colors.GREY_200) \
                for header, width in zip(self.headers, self.column_widths)
        ]
        header_row = ft.Row(header_controls, alignment=ft.alignment.center, height=50)

        # データ部の作成
        row_controls = []
        for row in self.rows:
            row_cells = [
                ft.Container(ft.Text(cell), width=width, alignment=ft.alignment.center) \
                    for cell, width in zip(row, self.column_widths)
            ]
            row_controls.append(ft.Row(row_cells, alignment=ft.alignment.center))
        # スクロールできるようにColumnコントロールを用意
        scrollable_data = ft.Column(
            controls=row_controls,
            scroll=ft.ScrollMode.ALWAYS,
            expand=True  # 親のColumn内で自動伸縮
        )

        # ヘッダ部とデータ部を配置
        self.controls =[
            header_row,
            scrollable_data
        ]
        

def main(page: ft.Page):
    page.title = "固定行のデータ表"
    page.window_top = 100
    page.window_left = 200
    page.window_width = 1000
    page.window_height = 600

    # ヘッダのリストを用意
    headers = ["名前","射程","サブ","スペシャル","SPポイント"]
    # 列幅のリストを用意
    column_widths = [200, 100, 200, 200, 100]
    # データ部で表示したい2次元配列を用意
    rows = [
        ["ボールドマーカー","1.6","カーリングボム","ウルトラハンコ","180"],
        ["ボールドマーカーネオ","1.6","ジャンプビーコン","メガホンレーザー5.1ch","170"],
        # 更に行を追加
    ]

    # 簡易DataTableを生成しページへ配置、ヘッダ／列幅／データのリストを渡します
    data_table = FixedHeaderDataTable(headers, rows, column_widths)
    page.add(data_table)

# アプリ開始
ft.app(target=main)
```

</details>


# 完成形
データ部分だけスクロールされるデータ表が完成しました。
![datatable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601563/dc705d9f-5ab4-f9d0-886a-5b659e26663d.gif)

テストデータは以下を整形しました。https://wikiwiki.jp/splatoon3mix/%E3%83%96%E3%82%AD/%E3%82%B7%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC%E5%B1%9E


# 課題
- 列幅が事前指定となっている（DataTableは文字内容で幅が動的に変わる）
- 並び替えに対応できていない
- ヘッダ／列幅／データの列数があっていないなどのエラーハンドリングができていない
などなど

# まとめ
色々物足りない部分は多いですが、Fletコントロールのクラスとレイアウトの基本が学べました。
【Apache POI 】SXSSFのストリーミング処理のイメージ

## 概要
Apache POIを使ってExcel出力をjavaで実装する際、XSSFWorkbookと比べてより処理の早いSXSSFWorkbookを使いました。
実際にSXSSFを使うまではSXSSFのストリーミング処理の動きがイメージしづらかったため、図を使って本記事にまとめました。
## そもそもXSSFとSXSSFとは
**XSSF**
Excel 2007およびそれ以降のバージョンで使用されるOffice Open XML (OOXML)形式の.xlsxファイルを読み書きするためのAPI
**SXSSF**
大容量データを処理するために設計された、XSSFのストリーミング版


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334459/a7940230-74c2-fb58-6e7f-93d3a9641505.png)

SXSSFはストリーミング形式により、順番にメモリ上の行データを破棄しながら処理を進めていくため、XSSFに比べて処理速度が速いです。ではどのタイミングでデータを破棄をするのか、SXSSFのストリーミング処理のイメージついて説明します。

## SXSSFのストリーミング処理のイメージ
**＜環境情報＞**
javaバージョン：17
POIバージョン：5.2.3

SXSSFのデフォルトでは100行以上を書き込みした場合、先頭行から71行分をメモリから破棄します。ここで言う100行は連続していなくても問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334459/f29df34f-cc43-63af-8d45-1c055adba906.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334459/c00d6845-4201-4278-7473-08914a1b5403.png)


100行以上書き込みされた状態で、再度先頭行から71行目までにアクセスしようとするとエラーになってしまいます。
```
2024-04-09T19:11:03.579+09:00 ERROR 31191 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Attempting to write a row[9] in the range [0,921] that is already written to disk.] with root cause

java.lang.IllegalArgumentException: Attempting to write a row[9] in the range [0,921] that is already written to disk.
        at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:139) ~[poi-ooxml-5.2.3.jar:5.2.3]
        at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:45) ~[poi-ooxml-5.2.3.jar:5.2.3]
```
デフォルトでは100行が上限ですが、SXSSFWorkbookクラスの第２引数で書き込み上限の行を指定することが可能です。
下図の設定では、10000行以上書き込みがされた時点で再度先頭行から71行目までがアクセスできなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334459/b75532bc-f145-5e10-0f72-12f54df1c67f.png)
## おわりに
SXSSFを使う際はストリーミング処理のイメージが沸かないと先程紹介したjava.lang.IllegalArgumentExceptionのエラーに結構陥ってしまいます（私も苦戦しました…）
本記事が少しでも理解の手助けになれたら幸いです！
AWSデータベースサービス

## AWSデータベースサービス
AWSには複数のデータベースサービスが存在するが、どれも機能が似ていてどう使い分けるか分からなくなってしまうかもしれません。AWS CLFなどの資格を取るためには各サービスの違い熟知する必要があります。今回の記事ではそれぞれの違いと使い分けについて説明します。
## Amazon RDS
その名の通りリレーショナルデータベースを提供するフルマネージドサービスです。AZに配置され、MySQL、PostgreSQL、Oracle Database、SQL Server、MariaDB、Amazon Auroraなどのデータベースエンジンをサポートしており、一般的なリレーショナルデータベースサービスであると言えます。AZに配置されます。オートスケーリングはデフォルトで無効となっているが、有効にでき、冗長化のためにリードレプリカを配置することができます。スナップショットと自動バックアップはデフォルトでS3に保存されます。
## Amazon Aurora
Amazon Auroraはリレーショナルデータベースエンジンです。MySQLやPostgreSQL互換性を持っており、標準のMySQLの最大5倍のスループットと、標準のPostgreSQLの最大3倍のスループットを実現します。また、商用データベースと同等のセキュリティ、可用性、信頼性を、10 分の 1 のコストで実現します。常に自動バックアップが有効化されています。ニーズに応じて起動、停止、スケーリングが行われるAuroraサーバレスも存在します。
## Amazon DynamoDB
フルマネージド型のノンリレーショナルデータベースサービスです。1 桁ミリ秒単位で規模に応じたパフォーマンスを実現する高速で実行することができます。デフォルトでAWSリージョンの3つの施設にデータを複製し、サーバー障害またはアベイラビリティーゾーンの停止が発生した場合のフォールトトレランスを提供しています。デフォルトではバックアップが有効化されていません。
## Amazon DocumentDB
フルマネージドなドキュメントデータベースサービスです。MongoDBワークロードのために設計されています。リアルタイム分析も可能で、モバイルアプリケーションのバックエンドにも使われます。
## Amazon Keyspaces
Cassandraと互換性のあるマネージドデータベースサービスです。
## Amazon Redshift
フルマネージドな高速でシンプルかつ費用対効果の高いデータウェアハウスサービスです。小規模利用からペタバイト単位の構造化データまで、複雑な分析クエリを実行でき、スケールアウトも容易に行うことができます。これはリレーショナルデータベースとなります。 
## Amazon Timestream
IoT アプリケーションに適したフルマネージドな時系列データベースサービスです。IoT機器などから収集したタイムスタンプをもつ時系列データの保存して、その検索や分析を行うことができます。
## 参考文献
https://aws.amazon.com/jp/timestream/
https://aws.amazon.com/jp/redshift/
https://aws.amazon.com/jp/keyspaces/
https://aws.amazon.com/jp/rds/aurora/
https://aws.amazon.com/jp/pm/dynamodb/
https://aws.amazon.com/jp/rds/
https://aws.amazon.com/jp/documentdb/
ファイバーについて

たまたまマニュアルを読んでいたら、

PHP8.1から実装されたファイバーがどこかで使えそうだなーと思い、

学習と備忘録がてら記事にします。

## [ファイバー](https://www.php.net/manual/ja/language.fibers.php) とは
PHP8.1から実装された、完全なスタックを持つ、停止可能な関数のことです。

ファイバーは、コールスタック中のどこからでも停止することができ、

[非同期処理](https://qiita.com/yunity29/items/7ccc84d47e139340ecbc)や[ブロッキングI/O操作](https://wa3.i-3-i.info/word1618.html)に対して効果的らしいです。

```PHP
// ユーザー定義関数を引数にし、ファイバーインスタンス生成
$fiber = new Fiber(function (): void {
   $value = Fiber::suspend('fiber');
   echo "ファイバーの値: ", $value, PHP_EOL;
});

$value = $fiber->start();

echo "ファイバーの値: ", $value, PHP_EOL;

$fiber->resume('test');



ファイバーの値: fiber
ファイバーの値: test

```

実行スタック中のどこからでも、Fiber::suspend() を使って実行を停止できるため、

深くネストされている関数のコールスタックの中から行っても問題ないそう。

これは、Fiber自身がコールスタックを保持しているため、

suspend()が実行された停止ポイントを覚えているから

らしいです。

ファイバーが停止されると、 

ファイバーの実行は Fiber::resume() に任意の値を渡すか、 

Fiber::throw() を使ってファイバーに例外をスローさせることで再開できます。 

再開される時は、Fiber::suspend() から値が返されます(または、例外がスローされます)。

上記コードは、マニュアルからまんまパクってきてますが、

かなり実用的でわかりやすいです。

suspendで引き渡した値は、resumeで引き渡した値に書き換わるみたいですね。

概要は理解したので、あとは実際に使ってみて実践知識つけてみます。

とはいえ現場どこで実装されるかはピンときていないです。

HTTPリクエスト捌く時の非同期処理とかに使えるかな？

実用例等があればぜひ教えていただきたいです。
Pythonで軽減税率のプログラムを作成してみた：8%と10%の消費税を計算

### 前置き
Qiita Engineer Festa 2024に参加し、20個目の記事として、2019年10月1日に消費税が8%から10%に増加した際、導入された軽減税率をわかりやすくするプログラムをPythonで
作成しました。この記事では、ユーザが商品の値段を入力し、8%および10%の消費税を含んだ値段とお釣りを表示するプログラムを紹介します。

### 軽減税率とは
消費税増税に伴って10％となった商品の一部を消費税8%で据え置く制度です。

### 作成したプログラムコード
``` python
def calculate_total_price(price):
  tax_rate_8 = 0.08  # 8%の税率
  tax_rate_10 = 0.10  # 10%の税率

  total_price_8 = price * (1 + tax_rate_8)
  total_price_10 = price * (1 + tax_rate_10)

  return total_price_8, total_price_10

def main():
  # 商品の価格をユーザに入力してもらう
  price = float(input("商品の値段を入力してください（円）: "))

  # 各税率での総額を計算
  total_price_8, total_price_10 = calculate_total_price(price)

  # 結果を出力
  print(f"8%消費税込みの価格: {total_price_8:.2f} 円")
  print(f"10%消費税込みの価格: {total_price_10:.2f} 円")

  # 所持金をユーザに入力してもらう
  money = float(input("所持しているお金を入力してください（円）: "))

  # 各税率での購入時のお釣りを計算
  change_8 = money - total_price_8
  change_10 = money - total_price_10

  # 結果を出力
  print(f"8%消費税での購入時のお釣り: {change_8:.2f} 円")
  print(f"10%消費税での購入時のお釣り: {change_10:.2f} 円")

if __name__ == "__main__":
  main()
```
### プログラムコードの説明
calculate_total_price(price) 関数は、引数として商品の値段を受け取り、
それぞれの税率（8%と10%）を加えた税込み価格を計算します。
main() 関数では、ユーザに商品の値段と所持金を入力してもらいます。その後、calculate_total_price() を使って税込み価格を計算し、結果を出力します。
最後に、各税率での購入時のお釣りを計算し、それぞれの金額をユーザに表示します。

### 出力結果
ここでは、私が1本122円で販売されている伊藤園の1日分の野菜を10本購入したという
前提にし、3000円所持していると設定して、税率8%と10%にした時の価格、
そしてその商品を店頭で購入した後、所持金が残り何円になるか出力される。

```python
商品の値段を入力してください（円）: 1220
8%消費税込みの価格: 1317.60 円
10%消費税込みの価格: 1342.00 円
所持しているお金を入力してください（円）: 3000
8%消費税での購入時のお釣り: 1682.40 円
10%消費税での購入時のお釣り: 1658.00 円
```
このように、1220円の商品ですと、8%の税率ならば価格が1220 x 1.08 = 1317.60円
同じ値段で、10%の税率ならば価格が1220 x 1.1 = 1342円になる。
3000円所持している場合、8%の税率ならお釣りが3000 - 1317.6 = 1682.4円。
同じく3000円所持していて10%の税率ならお釣りが3000 - 1342 = 1658円になる。
現実には、小数点のお釣りはないので、8%の税率なら四捨五入され、この場合のお釣りは、
1682円になる。ちゃんと計算した結果と出力結果が一致している。

### 終わりに
今回の記事では、Pythonを使って軽減税率を計算するプログラムを作成しました。このプログラムコードを使うことによって、約5年前の2019年10月1日に消費税が8%から10%に増加した際に導入された軽減税率をわかりやすく計算し、それぞれの税率での商品価格やお釣りを簡単に求めることができるようになりました。

また、奇しくもこの記事がQiita Engineer Festa 2024に参加してから投稿する20個目の記事ということで、2024年7月3日から20年ぶりに新札が発行されるという節目の年に、このプログラムを通じて日本の消費税制度について改めて理解を深める良い機会となりました。皆さんも時間がある時に、商品の値段を入力し、このプログラムコードを参考にしながら、8%および10%の消費税を含んだ値段とお釣りを表示してみてはいかがでしょうか。
[SQLServer]Window関数

# 1. サンプルテーブルの作成
```sql:CREATE_TABLE_Sales.sql
CREATE TABLE Sales (
    SaleID INT IDENTITY(1,1) PRIMARY KEY,
    ProductName NVARCHAR(100),
    SaleAmount DECIMAL(10, 2),
    SaleDate DATE
);
```

# 2. サンプルデータの挿入
```sql:INSERT_Sales.sql
INSERT INTO Sales (ProductName, SaleAmount, SaleDate) VALUES ('Product A', 100.00, '2024-06-01');
INSERT INTO Sales (ProductName, SaleAmount, SaleDate) VALUES ('Product B', 150.00, '2024-06-01');
INSERT INTO Sales (ProductName, SaleAmount, SaleDate) VALUES ('Product C', 200.00, '2024-06-02');
INSERT INTO Sales (ProductName, SaleAmount, SaleDate) VALUES ('Product D', 250.00, '2024-06-02');
INSERT INTO Sales (ProductName, SaleAmount, SaleDate) VALUES ('Product E', 300.00, '2024-06-02');

```

# 3. Window関数の使用例
```sql:SELECT_Sales.sql
SELECT SaleID, ProductName, SaleAmount, SaleDate,
       RANK() OVER (PARTITION BY SaleDate ORDER BY SaleAmount DESC) AS DailyRank
FROM Sales;
```

### 実行結果

|SaleID|ProductName|SaleAmount|SaleDate|DailyRank|
|-:|:-|-:|:-|-:|
|2|Product B|150.00|2024-06-01|1|
|1|Product A|100.00|2024-06-01|2|
|5|Product E|300.00|2024-06-02|1|
|4|Product D|250.00|2024-06-02|2|
|3|Product C|200.00|2024-06-02|3|

# 4. 解説
・PARTITION BY
Window関数が適用されるデータのグループを指定します。この例では、SaleDateごとにグループ化しています。

・ORDER BY
グループ内の行をどのように並べ替えるかを指定します。この例では、SaleAmountの降順で並べ替えています。

・RANK()
Window関数として使用され、各グループ内の行にランクを付けます。
[Gitコマンド]git log --onelineについて

# [Gitコマンド]gitのログをサッと確認する方法について

今回はGitにコミットした内容をすぐ確認できるようにするコマンドを書きます。
通常の git log コマンドは詳細なコミット履歴を表示しますが、--oneline オプションを付けることで、各コミットが1行で表示され、より見やすくなります

# コマンド
```
git log --oneline
```

これにより、ハッシュ値とコミットメッセージが一目でわかるように表示がされます。
通常のgit logよりパッと見てわかります。

# まとめ
git logを打つ方が早いと思いますが、一覧でサッと確認ができるのは個人的にいいなと思ってます。
引続きGitコマンドのアウトプットを行います。
なぜNbはTiを置換するか？MoはVを置換するか？：Sc-Zr,Ti-Nb,V-Mo対応. NaとLiの配位環境の違い. 陰イオン半径.

酸化物などでの、[原子間距離の統計解析](https://journals.iucr.org/j/issues/2022/05/00/gj5278/)([ソースとデータ](https://github.com/tkotani/CEBond))をしました。

* 周期律表を素朴に見てると、Vの真下にはNbがいる。しかし
TiとNb、VとMo、ZrとScが対応することが明瞭です。おそろしくキレイにずれている。これらはよく混ざりそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/54e962c3-bb0b-e6ba-fc3a-995ed4d7de56.png)

* NaとLiで配位環境の多様性がかなり違います。これはNaイオン電池の可能性を示唆しているようにも思えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/01218d2e-f131-19ad-679a-2dfc6acc489e.png)

* 陰イオンN,O,Fについて稠密パッキングを仮定して、イオン半径を解析しました。たしかにshanonの値はいいところをついています。電気陰性度が高くなると、半径変化もありますが、バラツキの変化のほうが目立ちます。Fだとかなり稠密パッキングを好むけど、Nだとそれほどでもない、ということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482779/d12b1a54-8859-1e72-741a-b86bbb503b04.png)
新卒エンジニアがエンジニア就活を振り返って語る

# 挨拶
はじめましての方ははじめまして、そうじゃない方はいつもお世話になっております。
ヤピ丸です！
イケてる社会への第一歩、皆さんなんだと思いますか？

**私はやっぱりファーストキャリアだと思うので就活を思い出して語ってみようと思います。**

# はじめに
私はもともと情報系の学部だったので初めからエンジニア一本で就活を進めていました。
そんな中で就活中私が思っていたことを話していきたいと思います。

# エンジニア就活は理詰めで乗り切れ！
これは私が就活時代に掲げていたモットーです。
これを前提に読み進めていただけるとありがたいです。

# 就活は志望動機・ガクチカ・強み弱みをいかに一本筋を通して伝えられるか
私が短い就活期間で学んだ真理です。
想像でしかありませんが転職活動もガクチカの部分が自身の経歴やポートフォリオになるだけで本質は変わらないと思っています。

## 1\.自分の軸を定義する
就活において最初にやるべきことは自身が何をしたいか、それはなぜかを突き詰めていき絶対に譲れない部分とその他の優先度を定義することです！そうして**軸を定義**しましょう

私の場合は就活の軸を「研修３か月以上、自社開発がある、初任給400万以上、楽しく働けそう」の４軸で探していました。
これに+αで若いうちから裁量権をもって働けるとなおよし！
なんでこの軸だったかというと、理由はいろいろありますが一番は自身が成長するための必要十分な条件がこれだと思っていたからですね。

正直軸というのは人それぞれだと思うので
**「軸をぶらさない」**
これさえ守れていれば内容は何でもいいです。

なぜ、軸をぶらしちゃダメなのか？簡単ですね、じくがぶれるとエントリーシートに書くことや面接で言うことがぶれます。
これをやってしまうとそれぞれの会社にかけるコストが重くなりすぎてしまいます。何より自分が軸にしているものと合わない企業にかける時間なんて無駄です。
その無駄をなくすためにも、自身の軸はしっかりと定義しましょう。

## 2\.ガクチカを作る
皆さんガクチカなんてないですよね？私もそうでした、でも大丈夫ガクチカは半年あれば十分に作れます。早い人なら一か月あれば十分かもしれません。

個人的におすすめなのは**資格取得**と**インターン**です。インターンは長期のものだとなおよしです。
なぜこの二つがおすすめなのか少し説明すると
### 資格取得
資格取得はコスパがいいです。資格の取得できていることそのものが継続力や計画性があることの担保になるうえ、
取得した資格が自身が行きたい業界で必須の資格だった場合その業界の業務に関して最低限の知識があることの証明にもなります。
これだけ聞いてもめちゃくちゃコスパがよさそうに聞こえるでしょう？

私の場合はエンジニアとして働くなら持っておいて損はない**基本情報技術者**と完全なる興味本位で取った**JDLA E資格**を取りました。
E資格のほうは余り持っている人があまりいない資格だったためガクチカとして重宝しました。
### インターン
ガクチカを作るのにこれが一番楽だと思います。
できるならスタートアップをお勧めしますが、インターン、特に長期インターンに関しては何やっててもウケがいいです。
自分が使える時間とやりたいこと・学びたいことを鑑みて興味があるものに応募してみてください。
バイトとやってることは変わらなくても自分のメンタリティも人事様のウケも段違いなのでだまされたと思って一度経験してみることをお勧めします。

私もプログラミング学習スクールのメンターのようなことを長期インターンをガクチカを作るために始めましたがいまでも本当に始めてよかったと思っています。

## 3\.強み弱みを設定する
これまで自分のやりたいことを定義して、やってきたことを作りだしました。
あとはやりたいこととやってきたことから一本筋が通るように自身の強み弱みを設定するだけです！
**簡単でしょ？**

「こういう部分に惹かれて御社を志望しました。それは学生時代のこういう経験からそういう思いを持ち、その中でこういうことを頑張って自身にはこういった強み弱みを自覚しました」

といったことを質問の形式に従ってきれいに説明できれば一時面接で落とされることはまずないと思います。
それ以上は求める人物像とのマッチング度合いや向き不向きの世界なのでそこに合わせるように強み弱みの伝え方を微調整することが腕の見せ所です！

## まとめ
就活において嘘はついてはいけません。
少し言い回しを変えるだけで伝えられる印象は大きく変えることができます。
軸とガクチカがしっかりしていれば強み弱みはいくつか自覚できるはずです。
これを見てくれた人がそれを用いて就活を乗り切ってくれたらうれしいです！

# おわりに
今回就活について覚書のような形で書いてみましたが、これが誰かの助けになれば幸いです。
同様に、転職においても根本的な考え方は同じだと思うのでそういった方の目に触れ、力になることができたらこれ以上の幸福はありません。

長くなってしまいましたが、ここまで読んでくれてありがとうございました。
また、お会いできる日を楽しみにしています！！
高度なクエリとEloquentのテクニック

LaravelのEloquent ORMは、データベースとのやり取りを簡素化するための強力なツールです。基本的なCRUD操作だけでなく、より複雑なクエリや高度なテクニックを使用することで、効率的にデータを操作することができます。今回は、少し高度なクエリやEloquentのテクニックについて記述します。

### 目次

1. 高度なクエリの使い方
2. Eloquentのリレーション
3. スコープの活用
4. アクセサとミューテータ

### 1. 高度なクエリの使い方

### 条件付きクエリ

Eloquentでは、条件付きでクエリを作成することができます。たとえば、ユーザーがアクティブな投稿を取得したい場合：

```php
$activePosts = Post::where('status', 'active')->get();
```

複数の条件を組み合わせることもできます。

```php
$posts = Post::where('status', 'active')
              ->where('created_at', '>=', now()->subDays(30))
              ->get();
```

### ソートと制限

結果をソートしたり、取得する件数を制限することも簡単です。

```php
$latestPosts = Post::orderBy('created_at', 'desc')->take(10)->get();
```

### 2. Eloquentのリレーション

リレーションを使うことで、関連するデータを簡単に取得できます。

### 一対多のリレーション

ユーザーと投稿の関係を例にして、ユーザーが持つ全ての投稿を取得する方法です。

```php
$user = User::find(1);
$posts = $user->posts;
```

### 多対多のリレーション

ユーザーと役割（Role）の多対多の関係を定義します。

`app/Models/User.php`

```php
public function roles()
{
    return $this->belongsToMany(Role::class);
}
```

`app/Models/Role.php`

```php
public function users()
{
    return $this->belongsToMany(User::class);
}
```

ユーザーが持つ全ての役割を取得する方法です。

```php
$user = User::find(1);
$roles = $user->roles;
```

### 3. スコープの活用

スコープを使うことで、再利用可能なクエリを定義することができます。

### グローバルスコープ

すべてのクエリに対して適用されるスコープです。

`app/Models/Post.php`

```php
protected static function boot()
{
    parent::boot();

    static::addGlobalScope('active', function (Builder $builder) {
        $builder->where('status', 'active');
    });
}
```

### ローカルスコープ

特定のクエリに対してのみ適用されるスコープです。

`app/Models/Post.php`

```php
public function scopeRecent($query)
{
    return $query->orderBy('created_at', 'desc');
}
```

使用方法：

```php
$recentPosts = Post::recent()->get();
```

### 4. アクセサとミューテータ

### アクセサ

アクセサを使うことで、モデルの属性を取得する際にカスタムロジックを適用できます。

`app/Models/User.php`

```php
public function getFullNameAttribute()
{
    return $this->first_name . ' ' . $this->last_name;
}
```

使用方法：

```php
$user = User::find(1);
echo $user->full_name;
```

### ミューテータ

ミューテータを使うことで、モデルの属性に値を設定する際にカスタムロジックを適用できます。

`app/Models/User.php`

```php
public function setPasswordAttribute($value)
{
    $this->attributes['password'] = bcrypt($value);
}
```

使用方法：

```php
$user = new User;
$user->password = 'secret';
```

### まとめ

この記事では、LaravelのEloquent ORMを使った高度なクエリとテクニックについて記述しました。条件付きクエリ、リレーションの操作、スコープの活用、そしてアクセサとミューテータを使うことで、データ操作がより柔軟で強力になります。これらのテクニックをマスターすることで、Laravelでの開発がさらに効率的になると思います。
JavaScriptのPromiseとは何か？

## JavaScriptのPromiseを一言で説明すると？
非同期処理の結果を扱うためのオブジェクト。

## JavaScriptのPromiseの何が良いのか？
非同期処理をよりシンプルで直感的に記述できるようにし、可読性を向上させる。

## 例
### Promiseを利用しない例
```
function asyncTask(callback) {
    setTimeout(() => {
        const result = "成功";
        console.log("非同期処理の完了");
        callback(result); // 5秒後に実行
    }, 5000);
}

function callbackTask(result) {
    console.log("コールバック処理を実行");
    console.log("非同期処理の結果:", result);
}

asyncTask(callbackTask);
```
### Promiseを利用する例
```
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const result = "成功";
        console.log("非同期処理の完了");
        resolve(result); // 5秒後に実行
    }, 5000);
});

promise.then((result) => {
    console.log("コールバック処理を実行");
    console.log("非同期処理の結果:", result);
});
```
### async/awaitを利用してコールバック関数を使わない例
```
async function runAsyncTask() {
    const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            const result = "成功";
            console.log("非同期処理の完了");
            resolve(result); // 5秒後に実行
        }, 5000);
    });

    const result = await promise;
    console.log("非同期処理の結果:", result);
}

runAsyncTask();
```
[SQLServer]ストアドプロシージャの作成_2

# 1. サンプルテーブルの作成
```sql:CREATE_TABLE_Products.sql
CREATE TABLE Products (
    ProductID INT IDENTITY(1,1) PRIMARY KEY,
    ProductName NVARCHAR(100),
    Stock INT,
    Price DECIMAL(10, 2)
);

CREATE TABLE Orders (
    OrderID INT IDENTITY(1,1) PRIMARY KEY,
    OrderDate DATETIME DEFAULT GETDATE()
);

CREATE TABLE OrderDetails (
    OrderDetailID INT IDENTITY(1,1) PRIMARY KEY,
    OrderID INT,
    ProductID INT,
    Quantity INT,
    FOREIGN KEY (OrderID) REFERENCES Orders(OrderID),
    FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
);
```

# 2. サンプルデータの挿入
```sql:INSERT_Products.sql
INSERT INTO Products (ProductName, Stock, Price) VALUES ('Product A', 100, 19.99);
INSERT INTO Products (ProductName, Stock, Price) VALUES ('Product B', 200, 29.99);
```

# 3. ストアドプロシージャの作成
```sql:CREATE_PROCEDURE_usp_CreateOrder.sql
CREATE PROCEDURE usp_CreateOrder
    @ProductID INT,
    @Quantity INT
AS
BEGIN
    SET NOCOUNT ON;

    BEGIN TRY
        BEGIN TRANSACTION;

        -- 在庫チェック
        DECLARE @CurrentStock INT;
        SELECT @CurrentStock = Stock FROM Products WHERE ProductID = @ProductID;

        IF @CurrentStock < @Quantity
        BEGIN
            -- 在庫不足
            RAISERROR ('Not enough stock available', 16, 1);
        END

        -- 注文作成
        INSERT INTO Orders (OrderDate) VALUES (GETDATE());
        DECLARE @OrderID INT = SCOPE_IDENTITY();

        INSERT INTO OrderDetails (OrderID, ProductID, Quantity)
        VALUES (@OrderID, @ProductID, @Quantity);

        -- 在庫更新
        UPDATE Products
        SET Stock = Stock - @Quantity
        WHERE ProductID = @ProductID;

        COMMIT TRANSACTION;
        PRINT 'Order created successfully.';
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        PRINT 'Error occurred. Transaction rolled back.';
        THROW;
    END CATCH
END;
```

# 4. ストアドプロシージャの使用例
```sql:EXEC_usp_CreateOrder.sql
-- 正常な注文の例
EXEC usp_CreateOrder @ProductID = 1, @Quantity = 10;

-- 在庫不足の場合の例
EXEC usp_CreateOrder @ProductID = 1, @Quantity = 1000;

```
Google Apps ScriptでHello Worldを出力するまで

### はじめに
Google Apps Script（GAS）は、Googleのサービス（Gmail、Googleスプレッドシート、Googleドキュメントなど）を自動化するためのスクリプト言語です。
この記事では、初めてGASを使用する方を対象に、開発環境のセットアップから「Hello World」を出力するまでの手順を説明します。

### ステップ1：Google Apps Scriptのセットアップ

1. **Googleアカウントにログインする**  
   まず、Googleアカウントにログインしてください。

2. **Google Apps Scriptエディタを開く**  
   [Google Apps Scriptエディタ](https://script.google.com/)にアクセスします。新しいプロジェクトを作成するために、「新しいプロジェクト」をクリックします。

3. **プロジェクトの命名**  
   プロジェクトにわかりやすい名前をつけましょう。ここでは「HelloWorld」とします。

### ステップ2：Hello Worldスクリプトを作成する

エディタが開いたら、以下のコードを入力します。

```javascript
// Hello Worldをコンソールに出力する関数
function helloWorld() {
  // 「Hello, World!」をログに出力します
  Logger.log('Hello, World!');
}
```

### ステップ3：スクリプトを実行する

1. **保存**  
   コードを入力したら、プロジェクトを保存します。

2. **関数の選択**  
   スクリプトエディタの上部にあるドロップダウンメニューから `helloWorld` 関数を選択します。

3. **実行**  
   「実行」ボタンをクリックします。初回実行時には、Googleアカウントへのアクセス許可を求められるので、必要な許可を与えてください。

4. **ログの確認**  
   実行が完了したら、「表示」メニューから「ログ」を選択して、出力結果を確認します。「Hello, World!」と表示されていれば成功です。

### ステップ4：テストコードにコメントを追加する

コードの各処理に日本語のコメントを追加し、理解しやすくしましょう。

```javascript
// Hello Worldをコンソールに出力する関数
function helloWorld() {
  // 「Hello, World!」をログに出力します
  Logger.log('Hello, World!'); // ここで「Hello, World!」とログに出力します
}

// テスト関数
function test_helloWorld() {
  // helloWorld関数を呼び出します
  helloWorld(); // ここでhelloWorld関数を実行します

  // 期待されるログ出力を確認します
  // ※手動でログを確認するか、Logger.getLog()を使ってプログラムで確認することも可能です
}
```

以上
第一世代管理パッケージ



# 未管理パッケージの開発と配布

https://developer.salesforce.com/docs/atlas.ja-jp.pkg1_dev.meta/pkg1_dev/packaging_developing_unmanaged.htm

未管理パッケージは、開発者にオープンソースプロジェクトを配布するため、またはインストール後にカスタマイズが必要なアプリケーションを一度だけ配布するために使用できます。
未管理パッケージからコンポーネントがインストールされると、コンポーネントはインストールされた組織で編集できるようになります。未管理パッケージを作成してアップロードする開発者は、インストールされたコンポーネントを制御できず、これらのコンポーネントを変更またはアップグレードできません。

パッケージのアップロードに使用した組織がまだ存在する場合にのみ、未管理パッケージをインストールすることをお勧めします。その組織が削除されている場合、未管理パッケージはインストールできません。

Sandbox から本番環境へ移行する場合には、未管理パッケージを使用しないでください。代わりに、Visual Studio Code 向け Salesforce 拡張機能または Ant 移行ツールを使用します。Enterprise Edition、Unlimited Edition、または Performance Edition を使用している場合は、「変更セット」を参照してください。

+ [未管理パッケージには、標準オブジェクトを含めることができない？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007clU3z)
クックパッドの料理（混ぜご飯)をランダムに選択して表示するPGM

<h3>クックパッドの料理（混ぜご飯)をランダムに選択して表示するPGM</h3>
クックパッドの料理（混ぜご飯)をランダムに選択して表示するPGMをpowershellで作りました

<hr>
PGM内容

```powershell
$source = @"
using System;
using System.Runtime.InteropServices;

public static class WinApi
{
    [DllImport("kernel32.dll")]
    public static extern bool Beep(int freq,int duration);
}
"@
Add-Type -TypeDefinition $source

#SendKeysを使うため、System.Windows.Forms名前空間読込
Add-Type -AssemblyName System.Windows.Forms

# .NET Frameworkの宣言
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

# Windows APIの宣言
$signature=@'
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
'@
$SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru


#読み出す本の最大ページ数
#$BookPages = 746
$RPages=1000



echo "ランダム読み出し開始"
#この間にトップ画面をクックパッドのカテゴリ最初の画面にする
Start-Sleep -s 10
echo "Start"


[System.Windows.Forms.SendKeys]::SendWait("^l")
Start-Sleep -s 2
$page = Get-Random -Maximum $RPages -Minimum 1
#カテゴリのURL
$URLSTR = "https://cookpad.com/search/混ぜご飯?order=date&page="
$URLSTR += $page

echo $URLSTR

[System.Windows.Forms.SendKeys]::SendWait($URLSTR)
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

#[System.Windows.Forms.SendKeys]::SendWait($page)
#Start-Sleep -s 2
#[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
#Start-Sleep -s $ReadSecond


# 変数設定
#---A---
$x = 690
$y = 300
# マウスカーソル移動
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($x, $y)
Start-sleep -s 1
# 左クリック
$SendMouseClick::mouse_event(0x0002, 0, 0, 0, 0);


#先のほうのTABリンク読み飛ばし
for($i=0; $i -lt 13; $i++){
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
Start-Sleep -Milliseconds 300
}
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")


Start-Sleep -s 2
$rIdx = Get-Random -Maximum 10 -Minimum 1
echo $rIdx
#先のほうのTABリンク読み飛ばし
for($i=1; $i -lt $rIdx; $i++){
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
[System.Windows.Forms.SendKeys]::SendWait("{TAB}")
}
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

 [WinApi]::Beep(440, 5000)
 
```
【ServiceNow】ボタン押下時の確認メッセージ

## 概要
ServiceNow画面上のボタン押下時にメッセージを表示させることができます。
メッセージを表示するためにはスクリプトを記載する必要があり、そのサンプルを備忘録としてまとめます。

### 環境
PDIで作成しています。
バージョンはVancouverです。
System Administrator（admin）で操作しています。

### 確認メッセージ設定
UIアクションをクライアントに設定し、スクリプトでGlideModalというAPIを使用します。
*GlideModal(String id, Boolean readOnly, Number width)*
|名前|種類|説明|
|:---|:---|:---|
|id|String|モーダルに読み込む UI ページ。|
|readOnly|Boolean|true の場合、Closeボタンが非表示になります。|
|width|Number|幅 (ピクセル単位)。最大幅は 900 ピクセル|


例えば、以下のようにフォーム上の「メッセージ表示」ボタンを押下した際に警告メッセージを表示する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1984141/ae3813e0-6eff-7cf1-a949-45148708fd2b.png)


スクリプトは下記のように設定しています。
```Javascript
function showModal(){
	var gm = new GlideModal("glide_warn", false, 600);
	// メッセージタイトルを設定
	gm.setTitle("警告");
	// メッセージ本文を設定
	gm.setPreference("title", "送信前に入力内容を確認してください。");
	// メッセージウィンドウ内のOKボタン押下時の処理を定義
	gm.setPreference("onPromptComplete", function() {alert("「OK」クリック時の処理")});
	// メッセージウィンドウを表示する
	gm.render();
}
```
標準環境で用意されているメッセージウィンドウ（UIページ）は他にも種類があり、いくつかの例を以下にまとめます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1984141/bebcdbfd-e470-094a-44f4-f31a199428ca.png)
	
#### クライアントスクリプトで複数のボタンに対して確認メッセージ設定
以前に、クライアントスクリプトで複数のUIアクションボタンに対して確認メッセージを設定するといった実装を行いましたのでそのサンプルスクリプトのメモを備忘録として残します。

クライアントスクリプト
onSubmit
```Javascript
function onSubmit() {

    //メッセージウィンドウの表示対象ボタンを定義
    var BUTTON_MESSAGES = {
        "u_test1": {
            "message": "u_test1ボタン押下時の確認メッセージ",
        },
        "u_test2": {
            "message": "u_test2ボタン押下時の確認メッセージ",
        },
        "u_test3": {
            "message": "u_test3ボタン押下時の確認メッセージ",
        },
    };

    //押下ボタン名取得
    var actionName = g_form.getActionName();


    //メッセージを表示する処理
    function showModal() {
        var msg = BUTTON_MESSAGES[actionName].message;
        var gm = new GlideModal("glide_confirm_basic", true, 600);
        gm.setTitle("確認");
        gm.setPreference("title", msg);

        //OKボタン押下時の処理を定義
        gm.setPreference("onPromptComplete", function() {
            //ボタン名を指定し、送信処理を実行する
            g_form.submit(actionName);
        });

        //モーダルウィンドウを表示する
        gm.render();
    }
}
```

### 参考
[ServiceNow 製品ドキュメント GlideModal - クライアント](https://docs.servicenow.com/ja-JP/bundle/vancouver-api-reference/page/app-store/dev_portal/API_reference/GlideModalClientSideV3/concept/c_GlideModalV3API.html)
Pythonでテストクラスを作成できるモジュールについて

### 1. unittest

`unittest`は、Pythonの標準ライブラリに含まれるユニットテストフレームワークです。
標準ライブラリのため、追加のインストールが不要で、基本的なテスト機能を網羅しています。

#### 基本的な使い方

```python
import unittest

# テスト対象の関数
def add(a, b):
    return a + b

# テストクラスの定義
class TestMathMethods(unittest.TestCase):

    # add関数のテスト
    def test_add(self):
        self.assertEqual(add(1, 2), 3)  # 1 + 2 の結果が3かをチェック
        self.assertEqual(add(-1, 1), 0)  # -1 + 1 の結果が0かをチェック

    # エラーテスト
    def test_add_type_error(self):
        with self.assertRaises(TypeError):  # TypeErrorが発生するかをチェック
            add('one', 2)

# テストの実行
if __name__ == '__main__':
    unittest.main()
```

#### 2. pytest

`pytest`は、非常に柔軟で使いやすいテストフレームワークです。
簡潔な構文で記述でき、多くのプラグインが利用可能です。

#### 基本的な使い方

```python
# test_sample.py
def add(a, b):
    return a + b

# add関数のテスト
def test_add():
    assert add(1, 2) == 3  # 1 + 2 の結果が3であることを確認
    assert add(-1, 1) == 0  # -1 + 1 の結果が0であることを確認

# エラーテスト
def test_add_type_error():
    import pytest
    with pytest.raises(TypeError):  # TypeErrorが発生することを確認
        add('one', 2)

# 実行方法：pytest test_sample.py
```

### 3. nose2

`nose2`は、`unittest`を拡張し、簡単にテストを実行するためのツールです。
`unittest`の機能を継承しつつ、柔軟なテストの発見と実行をサポートします。

#### 基本的な使い方

```python
import unittest

# テスト対象の関数
def subtract(a, b):
    return a - b

# テストクラスの定義
class TestMathMethods(unittest.TestCase):

    # subtract関数のテスト
    def test_subtract(self):
        self.assertEqual(subtract(5, 3), 2)  # 5 - 3 の結果が2かをチェック
        self.assertEqual(subtract(10, 5), 5)  # 10 - 5 の結果が5かをチェック

    # エラーテスト
    def test_subtract_type_error(self):
        with self.assertRaises(TypeError):  # TypeErrorが発生するかをチェック
            subtract('five', 3)

# テストの実行
if __name__ == '__main__':
    unittest.main()
```

### 4. doctest

`doctest`は、ドキュメント文字列（docstring）に記述されたテストを実行するためのモジュールです。
簡単な例を使ってテストを記述でき、コードのドキュメントとしても機能します。

#### 基本的な使い方

```python
def multiply(a, b):
    """
    2つの数値を掛け算します。

    >>> multiply(2, 3)
    6
    >>> multiply(-1, 5)
    -5
    """
    return a * b

if __name__ == "__main__":
    import doctest
    doctest.testmod()
```

### 5. Hypothesis

`Hypothesis`は、プロパティベースのテストを実行するためのライブラリです。
入力の範囲を指定し、自動的に多くのケースを生成してテストを行います。

#### 基本的な使い方

```python
from hypothesis import given
import hypothesis.strategies as st

# テスト対象の関数
def divide(a, b):
    return a / b

# プロパティベースのテスト
@given(st.integers(), st.integers().filter(lambda x: x != 0))
def test_divide(a, b):
    result = divide(a, b)
    assert result == a / b  # a / b の結果が期待通りかを確認

# pytestで実行可能
# pytest this_script.py
```

### まとめ

Pythonでテストクラスを作成するための最適なモジュールには、`unittest`、`pytest`、`nose2`、`doctest`、`Hypothesis`があります。
`unittest`は標準ライブラリであり、`pytest`はその柔軟性と豊富な機能で人気があります。
`nose2`は`unittest`の拡張であり、`doctest`はドキュメントテストに便利です。
`Hypothesis`はプロパティベースのテストに適しています。

以上
Session Manager ドメイン参加しているサーバにRun Asでドメインユーザーでログイン

Session Managerの機能の一つであるRun Asを使用すると、ssm-userではなく、事前に設定した任意のユーザーでログインが可能になります。

![スクリーンショット 2024-06-24 14.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542333/9c1e7899-d457-e7d7-787d-be1bdb87693b.png)

Amazon Linux 2023を使用し、Microsoft Active Directory（MSAD）にドメイン参加している場合、Run Asを使用してドメインユーザーでログインすることが可能です。
さらに、パスワードを入力することなくログインすることができます。

![スクリーンショット 2024-06-24 14.54.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542333/dcfa642b-c8d3-4209-8645-7769367a52fc.png)
初めてハッカソンに参加した話

# 概要
6/21-6/23に開催された[RSS Hackathon 2024 Beyond](https://race-ss.co.jp/hackathon)に参加してきました。RSSさんにpaizaでスカウトをいただき参加しました。私としては初のハッカソンでかなり緊張しました。参加方法は現地かオンラインか選べたのですが、宿泊費・交通費を考えると遠方からの現地参加は見送りました。
# 1日目　アイデアソン
冒頭でハッカソンとは言いましたが、1日目はアイデアソンでした。今回のテーマである「”あたりまえ”の、その先へ」をテーマにチームメンバーでアイデアを出し合いました。私たちは「学習は辛くて”あたりまえ”」をテーマに、ウミガメのスープを利用した学習アプリ「エレメントスープ」を作ることになりました。
# 2日目　ハッカソン
2日目からハッカソンスタートです。2日目開始までは開発禁止だったので、前日はゆっくり眠れました笑
チームメンバーと話し合い私はWebアプリのバックエンドをすることに。え、Webアプリ、作ったことあるんですか？あるわけないだろ！！でもせっかくの機会なので挑戦しました。チームメンバーが全員Pythonを触れるということで、PythonのFlaskを用いてプログラムすることになりました。ずっと逃げてきたHTMLも触り、なんとか動くものに。10時30分からほぼぶっ続けで開発して、最低限が作り終わったのはAtCoderABCの始まる21時の数分前でした。そこから2時間離席させてもらい、ABCに出て、~~発狂しながら~~またハッカソンに戻りました。デバックやら次の日のプレゼン準備やらで寝たのは朝の5時近くでした。私は次の日発表控えていたので、早めに就寝しましたが、他のメンバーはもっと起きてた人もいたみたい。

# 3日目　プレゼンテーション　
4時間睡眠をとり、9時から最終チェックをして12時に提出。発表は13時30分からでした。私は発表者で、やはり緊張しました。チームメンバーが頑張ってくれたことが、全部伝わるといいなとそんな思いで臨みました。プレゼンテーションは得意な方なので、筒がなく終わり質疑応答もいい感じに答えられたのではないかと思います。
全てのチームの発表が終わり、表彰式があったのは16時45分でした。結果は残念ながら入賞ならず...アプリ開発もプレゼンテーションも悔いはないので、単純に他のチームが強かったです。FBは後日返ってくるそうなので楽しみにしたいと思います。

# 最後に
初めてのハッカソンで、最初はどうなることかと思いましたが、良きチームメンバーに恵まれ、納得のいくアウトプットが出せてよかったです。本ハッカソンで開発したアプリは[こちら](https://github.com/nashisandesu/RSShackathon)に載せています。よかったら覗いてみてください！
RSSの運営の方々、企画ありがとうございました！
AWS CLIでアカウント作成日を確認する方法





AWS CLIを使用して、AWSアカウントの作成日を確認する方法を紹介します。
この記事では、IAMクレデンシャルレポートを生成し、アカウントの作成日を特定する具体的な手順を説明します。

## 経緯

AWSから「Amazon SESの無料利用枠が85%を超えました」というアラートメールが届きました。
無料利用枠はアカウント作成日から12ヶ月間有効であり、これを把握するためにアカウントの作成日を確認する必要が生じました。
以下に、具体的な確認手順を示します。

## 前提条件

- AWS CLIがインストールされていること
- 適切なAWS CLIプロファイルが設定されていること

## ステップ1: 現在のAWSアカウント情報を確認する

まず、現在接続しているAWSアカウント情報を確認します。

```sh
# 現在のAWSアカウント情報を取得
aws sts get-caller-identity
```

このコマンドを実行すると、以下のような情報が表示されます。

```json
{
    "UserId": "XXXXXXXXXXXXX",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/your-username"
}
```

## ステップ2: 別のプロファイルに切り替える

別のアカウントに切り替えるために、事前に設定しているプロファイルを使用します。ここでは、プロファイル名を`hoge`とします。

### プロファイルの設定

プロファイルを設定するには、以下のコマンドを実行します。

```sh
# プロファイルhogeの設定
aws configure --profile hoge
```

設定が完了したら、環境変数を設定してデフォルトプロファイルとして使用します。

### 環境変数の設定

#### Linux/MacOS

```sh
# デフォルトプロファイルをhogeに設定
export AWS_PROFILE=hoge
```

#### Windows

```sh
# デフォルトプロファイルをhogeに設定
set AWS_PROFILE=hoge
```

これで、以降のAWS CLIコマンドはすべて`hoge`プロファイルを使用します。

## ステップ3: IAMクレデンシャルレポートの生成と取得

1. プロファイル`hoge`を使用してクレデンシャルレポートを生成します。

```sh
# クレデンシャルレポートの生成
aws iam generate-credential-report --profile hoge
```

2. レポート生成が完了した後、以下のコマンドでレポートを取得します。

```sh
# クレデンシャルレポートの取得
aws iam get-credential-report --query 'Content' --output text --profile hoge > credential-report.txt
```

3. レポートをデコードしてファイルに保存します。

```sh
# レポートのデコード
cat credential-report.txt | base64 --decode > decoded-report.csv
```

4. `decoded-report.csv`から`root`ユーザーの情報を抽出します。

```sh
# rootユーザー情報の抽出
grep root decoded-report.csv
```

## ステップ4: アカウント作成日の確認

抽出された情報の中から、アカウント作成日を確認します。例えば、以下のような出力が得られる場合：

```
<root_account>,arn:aws:iam::xxxxxxxxxxxx:root,2022-02-09T05:49:18+00:00,not_supported,2024-06-11T01:48:50+00:00,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A
```

`2022-02-09T05:49:18+00:00`がアカウント作成日です。

## まとめ

この記事では、AWS CLIを使用してAWSアカウントの作成日を確認する方法を説明しました。
IAMクレデンシャルレポートを使用することで、詳細なアカウント情報を取得できるため、運用管理に役立ててください。
DXライブラリを使って学ぶ[入門編]

こちらのサイトで学ばせてもらっています。「新・C言語 ～ゲームプログラミングの館～ [DXライブラリ]」https://dixq.net/g/index.html
今回は「DXライブラリ入門編」の内容を実践してまとめます。

**<内容>**

`puts int LoadGraph( char *FileName ) ;`
**・画像や動画ファイルのロード。**
FileNameはファイルパス文字列へのポインタ(？)
ハンドルという識別番号が得られる。int型の変数に格納する。
ロード(load)。わざわざ毎回ハードディスクにアクセスしないようにメモリにのっけるからloadなのか。Now Loadingってそういうことだったのね…

`int DrawGraph( int x, int y, int GrHandle, int TransFlag ) ;`
**・ロードしたグラフィックの描画。**
第三引数に、メモリにLoadしたファイルのハンドルを入れる。

`int CheckHitKey( int KeyCode ) ;`
**・特定キーの入力状態を得る。**
引数は例えばエンターキーなら　KEY_INPUT_RETURN　
RETURNのところを変えるようだ。
これを利用してプログラムを終わらせるようにすると以下のようになる

    while (1) {
        ProcessMessage();
        if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) {
            break;
        }
    }
escが押されるとbreakする。これだけだとウィンドウの×ボタン押しても処理が続くのでヤバそう。

    while (1) {
        ProcessMessage();
        if (CheckHitKey(KEY_INPUT_ESCAPE) == 1 || ProcessMessage() != 0) {
            break;
        }
    }
`ProcessMessage() != 0`を追加するとうまくいった。

`int ClearDrawScreen( void ) ;`
**・画面に描かれたものを消去する。**
`ProcessMessage();`とともにループの最初に入れて使うことで、画像を動かすことができる。

`int SetDrawScreen( int DrawScreen ) ;`
**描画先グラフィック領域を指定する。**
引数(DrawScreen)→DX_SCREEN_FRONTで表画面、DX_SCREEN_BACKで裏画面を指定できる。とりあえずは裏画面しか使わないかも。`int ScreenFlip( void ) ;`で裏画面の描画を表画面に表示できるようになり、すんごいヌルヌル動く。

:::note info
ScreenFlipは、1/60秒待ってから表画面に描画してくれる。つまりモニタのリフレッシュと同時に表画面に描写してくれるのでヌルヌルなるようだ。
:::

**＜結論＞**

```
#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更とDXライブラリの初期化と裏画面設定

        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 )
        {
                //ここに処理を追加
        }
        
        DxLib_End(); // DXライブラリ終了処理
        return 0;
}  
```
これがテンプレとして使えるようだ。while内にはフレームごとの処理を入れる。