OmniAICreator/Qiita-1.07M huggingface dataset:
PHPの連想配列で特定のキーを先頭に持ってきたい（小ネタ）

# 先頭に持ってきたいキーの配列 + 元の配列 で出来る
```php
$attributes = [
    'name' => 'たろう',
    'sex' => '男',
    'age' => '24',
    'id' => 12345
];

$attributes = ['id' => $attributes['id']] + $attributes;
// $attributes = [
//   'id' => 12345,
//   'name' => 'たろう',
//   'sex' => '男',
//   'age' => '24'
// ];

```

配列演算子では左側の配列の要素が優先される。
この特性のおかげで、先頭に持ってきたいキーの配列を左辺に置けばそれが先頭になる。

> + 演算子は、右側の配列を左側の配列に追加したものを返します。 両方の配列に存在するキーについては左側の配列の要素が優先され、 右側の配列にあった同じキーの要素は無視されます。

https://www.php.net/manual/ja/language.operators.array.php

かつ、PHPの配列は順序が保持されるので「+」で先頭にidを足しても他要素の順番は変わらない。

> PHP の配列は、実際には順番付けられたマップです。

https://www.php.net/manual/ja/language.types.array.php


# おまけ
これをやりたいと思ったのは、
LaravelのEloquentモデルで`getAttributes()`した際、PKのidが配列の最後に入っていたのを先頭にしたかったため。
具体的には、createしたレコードのデータを完了画面で順番通りに表示させたい！という場合。
DBによってはauto incrementのidがレコード挿入後に生成されるため、DBから結果が返される際に他のカラムより遅れてidの値が返されることがあるらしい。
Redmine（Ruby v3.1.4）で2025年2月29日を発見！

お仕事中に遭遇したRubyの不具合のお話です。

# Problem

2025年2月28日、お仕事で運用しているRedmineで次のような問題が発生しました：

* チケットの変更履歴に記録される変更前のチケットの「開始日」（`start_date`）や「期日」（`due_date`）に「2025年2月29日」の何時何分（例：`2025-02-29 18:00:00 +0900`）という不正な日時が記録され、チケットページ表示時にエラーとなる
* チケットの変更履歴の作成日（`created_on`）に、2月28日現在にもかかわらず、「2025年3月1日」の何時何分（例：`2025-03-01 16:44:36`）という不正な日時が記録され、変更履歴の表示内容と表示順序が狂う

この不具合は Ruby v3.1.4 で発生します。
2025年2月27日までは問題発生はなく、28日になり発生、3月1日を迎えて収束しました。
試みに、サーバーのシステム時刻を28日に戻すと事象再現しました。
おそらく26年以降も同じ問題が起こるのでは？と想像しています。

:::note info
28日に事象発生した当時、同じ画面オペでも不具合が発現するときとしない時があり。後日再現実験した折も厳密にどういう条件であれば発現をするのかが掴みきれませんでした。
システム時刻は28日9時より前なのか後なのか、28日0時や28日9時を迎える前にhttpdのプロセスが起動しているかどうか、などなど
:::

:::note warn
なお、少なくとも1つ目の事象は、私がお仕事で運用しているRedmineが「開始日や期日に、日付ではなく日時を入力できるよう、カスタマイズされている」という背景もあって発現している可能性が高いです。
:::

# Solution

本件はRuby v3.1.4の実装に潜む、閏年の処理の不具合に起因するようです。

この事象は[うるう日の午前0時から9時までに起動したプロセスでのみ再現するサーバー障害](https://developer.aiming-inc.com/ruby/leap-year-bug/)で報告されているものと同じ原因のように見受けられます。
この記事で報告されている事象は閏年であった2024年2月29日に発生したものですが、閏年でない2025年にも別のかたちで問題が発生しました。

対策として考えられるものをいくつか列挙します：

* プランA： Ruby 3.2系にアップグレード
* プランB： Webサーバーを再起動
* プランC： 2月28日が終わる（3月1日0時）のを待つ

今回は事象そのものの性質が掴みきれておらず、`journals`表の`created_on`列や`journal_details`表の`old_value`列をデータメンテしつつのプランC。

今後についてはプランAを有望視しつつ、Redmine側のビジネスロジックのカスタマイズも選択肢として考えています（前述の通り、私が運用しているRedmineはすでにカスタマイズが入ってしまっているので・・・）。
【Unity初心者】Unityでネットゲームを作りたい【20】共有のやり方がわからない～ボタンの角を丸くする

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
### 共有のやり方がわからない
別のPCで開発をしたい。できるみたいだが、やり方がよくわからん...
なので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/75336e1c-b157-41f3-9fdc-611bd0fab1de.png)
こんな感じでUSBメモリーにAssetsをコピーして持ち歩いてます
削除して貼り付けすれば同じになる
___

### ボタンの角を丸くする
できるんじゃね？と調べてみた
[【Unity】角丸ボタンを簡単に作る、再び](https://note.com/hikohiro/n/n9100eae28208)　こちらを拝借

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/d1779049-3af9-47ba-b9fd-eb0909db793a.png)
ここからアセットストアへ
Shapes2D　で検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/8d50e13e-1838-474c-8a6d-8c9800a9c059.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/0915ae1a-f45e-4178-91d7-00c68200490a.png)
マイアセットに追加するをクリック
で、無事インストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/807aa5da-00fc-42da-9dd8-0baf8cc402f2.png)
ここにボタンが出現

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/9158c25c-b8cb-4990-807c-bcf84794c4e7.png)
作成すると、インスペクターの中にShapeの項目が出現し、いろいろいじれるみたい

丸みの数字を調整すると、角が丸くなった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/6ce3e8c1-e17c-492b-9141-58c132b64315.png)

←前  [【Unity初心者】Unityでネットゲームを作りたい【19】少しだけPlayFabへの書き込みに時間がかかる気がする～PlayFabの仮想通貨に手を出す](https://qiita.com/ysyss5500/items/8259b7ee93a05ea21ecb)

[]()　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
【簡単AWS】【AWS Elastic Beanstalk】AWS Elastic Beanstalk とは？（初心者向け解説）

# 概要

AWS Elastic Beanstalk（以下、EB）は、**簡単にアプリケーションを AWS にデプロイできる PaaS（Platform as a Service）** です。

「サーバーの設定とか、負荷分散とか、全部 AWS に任せて、アプリ開発に集中したい！」という方にピッタリのサービスです。🎩✨

---

## 🎯 Elastic Beanstalk で何ができるの？

従来、AWS でアプリを運用する場合、次のような準備が必要でした。

✅ **EC2（サーバー）を用意する** → インスタンス選びや OS 設定が必要  
✅ **ロードバランサーを設定する** → 高負荷時のスケール調整  
✅ **オートスケーリングを組む** → トラフィックに応じてサーバーを増減  
✅ **環境変数・監視・ログ管理の設定**  

😵 **「やること多すぎ！」**

**Elastic Beanstalk を使えば、これらをすべて AWS におまかせできます！** 🎉

1. **サーバー（EC2）を自動作成**
2. **ロードバランサー（ELB）の設定を自動化**
3. **オートスケーリングを自動化**
4. **コードをデプロイするだけで動作**
5. **監視（CloudWatch）も標準装備**

つまり、AWS の**インフラ管理をほぼ意識せずに Web アプリをデプロイできる**のが Elastic Beanstalk です。

---

## 📌 具体例：Django アプリをデプロイする場合

例えば、Django の Web アプリを AWS にデプロイしたいとします。

### 🔴 **従来の方法（自分でセットアップする場合）**
1. EC2 インスタンスを立ち上げる
2. Python、Django、Gunicorn、Nginx をインストール
3. ELB を設定して負荷分散
4. Auto Scaling を設定
5. RDS との接続、セキュリティ設定
6. デプロイ、ログ管理、アップデート対応... 😩

### 🟢 **Elastic Beanstalk を使う場合**
1. Django プロジェクトを ZIP にまとめる or GitHub 連携
2. Elastic Beanstalk にアップロード
3. AWS が**自動でサーバーを用意＆デプロイ** 🚀
4. `xxx.elasticbeanstalk.com` にアクセスすればアプリが動く！ 🎉

サーバーの管理を気にせず、アプリ開発に集中できるのが魅力です。

---

## 🎯 Elastic Beanstalk のメリット・デメリット

### ✅ **メリット**
- **超簡単にデプロイ可能**（初心者でも扱いやすい）
- **インフラ管理不要**（サーバー、スケーリング、ロードバランサーは AWS におまかせ）
- **マルチプラットフォーム対応**（Node.js、Python、Ruby、Java など）
- **無料枠あり**（EC2 や RDS の料金のみ発生）

### ⚠️ **デメリット**
- **設定の自由度が低い**（細かいチューニングが必要なら EC2 や ECS のほうが良い）
- **大規模運用には向かない**（Kubernetes や ECS のほうがスケールしやすい）
- **デプロイの速度が遅め**（変更が即時反映されるわけではない）

---

## 🎯 こんな人におすすめ！
✅ **初心者 / 開発者** → AWS の細かい設定を知らなくてもデプロイ可能  
✅ **小規模プロジェクト / スタートアップ** → 開発に集中できる  
✅ **テスト環境やプロトタイプのデプロイ** → すぐに動作確認したいときに便利  

**本格的な商用環境には ECS / EKS / Lambda などの他の選択肢も検討しましょう。**

---

## 🎯 まとめ

- **AWS Elastic Beanstalk = "自動デプロイ & 運用おまかせサービス"**
- **サーバー構築不要、コードをアップするだけで動く**
- **初心者でも扱いやすく、Web アプリのデプロイが簡単**
- **ただし、自由度は低め & 大規模運用には向かない**

AWS の環境構築に悩んでいる方は、まず **Elastic Beanstalk** を試してみるのがオススメです！ 🚀

---

📝 **参考情報**  
- [AWS Elastic Beanstalk 公式ドキュメント](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html)
Databricksノートブックやファイルのタブのサポート

気付いたらサポートされていました。これまでは、複数のノートブックなどを同時に編集したい場合には、ブラウザのタブを使っていましたが、この機能を有効化することで単一のブラウザタブで開いているDatabricks画面の中でタブを切り替えることができます。

画面右上のユーザーアイコンから**設定**を選択し、**ユーザー**セクションの**開発者**を開きます。**実験的な機能**の一番下に**ノートブックとファイルのタブ**が追加されています。

![Screenshot 2025-03-05 at 9.26.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/72485ce4-189d-4871-be65-c36fc4666789.png)

これをオンにします。

![Screenshot 2025-03-05 at 9.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3ad716b3-1878-48d1-a92f-3d0231611438.png)

画面の上部にタブが表示されます。

![Screenshot 2025-03-05 at 9.28.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/37603ce8-096e-4c7b-8f77-6494da2e330d.png)

ノートブック、クエリー、ファイルがタブの対象となります。

![Screenshot 2025-03-05 at 9.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/80b07994-62b5-49ed-bc72-7fed9facd59f.png)

:::note info
**注意**
クエリーをこのタブで表示できるようにするには、**New SQL editor**をオンにする必要があります。

![Screenshot 2025-03-05 at 17.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f298e3ba-1cf1-40cb-94b1-82d3f964e2b5.png)
![Screenshot 2025-03-05 at 17.08.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fe6aa688-c546-45b8-b967-8e7ff14e9b34.png)
:::


タブの右端にある **+** をクリックすることで新規ファイルや既存タブを開くことができます。

![Screenshot 2025-03-05 at 9.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/14a0a35d-3626-45d8-ab7a-7bb6d3277810.png)

開発効率を改善する機能ですので、是非ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
石取りゲームとGrundy数

石取りゲームとGrundy数の基本的な考え方を説明したいと思います。

### 石取りゲーム（山が一つ）

**【例題 １】以下の石取りゲームを勝つための最初の一手は？**

1. 10個の石を交互に取っていく
1. 1回に取れるのは3個まで
1. 最後に取れる石がなくなったほうが負け

これをGrundy数の考え方で解いて行きます。[Grundy数を使って1次元ドミノ置きゲームを解く（その１）](https://qiita.com/masa0599/items/020b9ed3acb575ec89ac)で紹介したようにに、Grundy数G(P)とは、

>* 負けが確定した状態$P_{lost}$のとき$G(P_{lost})=0$
>* $P$から1手で遷移できる状態が$P'_1, P'_2,..., P'_k$だとすると
> $G(P)=mex(G(P'_1), G(P'_2),..., G(P'_k))$
>* ここでmex(Minimum excludant)は引数に含まれない最小の非負整数で、例えば$mex(0,1,3) = 2$となります

石の個数をPとすると$G(0)=0$でそれ以降3個まで取れるので、それぞれのG(P)を順次求めていくと以下のようになります。

|P|$P'_1,P'_2,P'_3$|mex| G(P)|
|:---:|:---:|:--:|:--:|
|0|-|-|0|
|1|0|mex(0)|1|
|2|0,1|$mex(0,1)$|2|
|3|0,1,2|$mex(0,1,2)$|3|
|4|1,2,3|$mex(1,2,3)$|0|
|5|2,3,4|$mex(2,3,0)$|1|
|6|3,4,5|$mex(3,0,1)$|2|
|7|4,5,6|$mex(0,1,2)$|3|

これで先手は$G(P)=0$となる$P \equiv 0 \pmod 4$になるような手を打てば勝てるということが分かるので、**最初に１０個あった場合には２個とって８個にすればよいということが分かります。**

この例題の場合にはGrundy数が０の場合だけ分かればよかったのですが、$0$以外のGrundy数がどういう意味を持つのかはちょっとピントきませんね。それは山の数が2個以上になると意味を持ってます。

### 石取りゲーム（山が３つ）

**【例題 ２】以下の石取りゲームを勝つための最初の一手は？**

1. ３つの山に、それぞれ3個、5個、7個の石がある
1. 1回に取れるのは1つの山から3個まで
1. 最後に取れる石がなくなった方が負け

ここで使うのが**スプレイグ・グランディの定理**で、簡単に言うと以下のようになります。

> N個の部分ゲームに対するGrundy数を求めてXORを取ったものが全体のGrundy数となる

すでに部分ゲーム（山が一つの石取りゲーム）のGrundy数は分かっているのでそのXORを取ります。

```math
\begin{align}
&G(3,5,7) = G(3) \oplus G(5) \oplus G(7) = 3 \oplus 1 \oplus 3 = 1   \\
\end{align}
```
従ってこれが０になるように石を取れば良いので、例えば**5個の山から1個**取ればよいことが分かります。その後はGrundy数が0になるように取っていけば勝てるということです。

### 山が３つでGrundy数が0になる配置

それではこのゲームでGrundy数が0になる配置は何個あるでしょう？
個々の山のGrundy数は$[0,1,2,3]$なので3個の重複組み合わせでXORが０になるもの求めるの以下の5個の配置があることが分かります。

```python 
from itertools import combinations_with_replacement
[(a,b,c) for a,b,c in combinations_with_replacement(range(4),3) if a^b^c == 0]
# [(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 2, 3)]
```
この基本的な考え方をで、色々なパターンの石取りゲームの必勝パターンを求めることができますね。

（開発環境：Google Colab）
【Vue,Vuetify】formのバリデーションチェック

## Vueのformでのバリデーションチェックの仕方
* 基本的なバリデーションの実装
Vuetifyでは、rulesプロパティにバリデーション関数を設定することで、入力値のチェックを行うことができます。例えば、必須入力のバリデーションは以下のように定義できます。
```vue
<v-text-field
  label="項目"
  v-model="form.itemName"
  :rules="[requiredValidation, limitLengthValidation]"
  :counter="maxLength"
></v-text-field>
```
バリデーション関数はdata内で定義します。
```javascript
data() {
  const maxLength = 64;
  return {
    maxLength,
    requiredValidation: (value) => !!value || '必ず入力してください',
    limitLengthValidation: (value) =>
      !value || value.length <= maxLength || `${maxLength}文字以内で入力してください`,
  };
}

```

* URLのバリデーション
URL入力欄では、文字数制限と正規表現を使ったバリデーションを組み合わせることができます。
```vue
<v-text-field
  label="URL"
  v-model="form.link"
  :rules="[limitUrlLengthValidation, urlPatternValidation]"
  counter="1024"
></v-text-field>
```

```javascript
data() {
  return {
    limitUrlLengthValidation: (value) =>
      !value || value.length <= 1024 || `1024文字以内で入力してください`,
    urlPatternValidation: (value) =>
      !value || value.match(/^https?:\/\/[\w!?/+\-_~;.,*&@#$%()'[\]]+/) || 'URLを入力してください',
  };
}

```

rulesプロパティを活用することで、簡単にバリデーションを実装できます。
必須チェック、文字数制限、正規表現チェックを組み合わせることで柔軟なバリデーションが可能になります。
rex0220 印刷屋プラグイン 見積書の担当者をユーザー選択項目から表示

rex0220 印刷屋プラグインで、見積書の担当者をユーザー選択項目から表示します。

# 概要

レコードの担当者を見積書に表示します。
ユーザー選択項目のフィールドコードを指定するだけで、簡単に表示できます。

![2025-03-05_09h05_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d04b4e5e-31db-4d49-8153-860710a4c846.png)


# 印刷屋プラグイン設定

文字列で指定した"開発 太郎" をユーザー選択項目の「担当者」に変更します。

![2025-03-05_09h11_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/2c69124a-ed74-4a22-a509-4b92f0a26593.png)

```js:
PAGE_HTML(
  TAG("div", ATTR("class", "pcraft-inv-header"), "見積書"),

  TAG("div", ATTR("class", "pcraft-inv-info"),

    // header left
    TAG("div", ATTR("class", "pcraft-inv-left"),
      TAG("p", 宛名 & " 御中"), VTAG("br"),
      TAG("p", ATTR("class", "pcraft-inv-estimate-amount"), "見積金額:", TAG("span", FVAL(合計金額))),
      TAG("p", ATTR("class", "pcraft-inv-validity"),
        "見積の有効期限: " & DATE_FORMAT(見積有効期限, "YYYY年M月D日")
      )
    ),

    // header right
    TAG("div", ATTR("class", "pcraft-inv-right"),
      TAG("p", "見積番号: " & 見積番号),
      TAG("p", "発行日: " & DATE_FORMAT(見積日, "YYYY年M月D日")),
      TAG("p", "株式会社サンプルサンプルサンプル"),
      TAG("p", "〇〇県〇〇市〇〇〇〇〇-〇-〇"),
      TAG("p", "TEL: 00-0000-0000"),
      TAG("p", 担当者),
      VTAG("img", ATTR("class", "pcraft-inv-seal", "width", "250", "height", "120", "src", "#{&f(20250302031501227586874B104969A58F90E42C4C3C26073)}"))
    )
  ),

  // table
  TABLE_HTML(見積明細,
    OPT("pref", "pcraft-inv-item-"),
    ARRAY("#", ROWNO(見積明細) + 1),
    商品名, 数量, 単価, 金額
  ),

  // summary
  TAG("div", ATTR("class", "pcraft-inv-summary-section"),
    // 備考
    TAG("div", ATTR("class", "pcraft-inv-remarks-section"),
      TAG("strong", "備考:"), VTAG("br"),
      TAG("span", HTML(FVAL(備考)))
    ),
    // 合計
    TAG("div", ATTR("class", "pcraft-inv-total-section"),
      TAG("table",
        TAG("tbody",
          TAG("tr", TAG("th", "小計"), TAG("td", FVAL(小計金額))),
          TAG("tr", TAG("th", "消費税 (10%)"), TAG("td", FVAL(消費税))),
          TAG("tr", TAG("th", TAG("strong", "合計")), TAG("td", TAG("strong", FVAL(合計金額))))
        )
      )
    )
  )
)
```
ハッカソン振り返り：ハッカソンで学んだ「やっておけばよかったこと」を、どんどん『ハッカソンTips』に投稿しよう！

## はじめに

ハッカソンは、短期間でアイデアを形にし、チームで開発を進めるイベントです。

:::note info
***参加することで技術力の向上はもちろん、チームワークやタイムマネジメント能力も鍛えられます。***
:::

しかし、実際に参加してみると、思いがけない課題に直面することが多いのも事実です。本記事では、ハッカソンでの困りごとやその対策、振り返りの重要性についてまとめました。

## 書こうと思ったきっかけ

私がITスクールのハッカソンに参加した際、さまざまな壁にぶつかりました。

:::note warn
**しかし、その経験を共有することで、これからハッカソンに参加する人の助けになればと思い、本記事を書くことにしました。**
:::

困りごとは誰かにとっての貴重な知見になることもあります。***ぜひ参考にしてみてください。***

## ハッカソンで困ったこと・共有しておきたいこと

ハッカソンは短期間でプロダクトを作り上げるイベントですが、実際に参加するとさまざまな困難に直面します。以下に、私が経験した困りごとをまとめました。

### 1. チーム内の認識のズレ
ハッカソンでは、限られた時間の中でアイデアを形にするため、チーム全員が同じ方向を向いていることが重要です。しかし、
- 役割分担が曖昧
- ゴールの認識が違う
- 技術的な知識レベルの違いによる作業スピードの差

など、チーム内での認識のズレが発生すると、開発がスムーズに進まなくなります。

**解決策:**
- 最初にしっかりと「今回のゴール」を全員で確認する
- こまめに進捗報告を行い、ズレが発生していないかチェックする
- 必要ならば適宜役割を見直す

### 2. 技術的な壁
ハッカソンでは、新しい技術に挑戦することも多いため、技術的な壁にぶつかることがあります。
- 使ったことのないフレームワークに挑戦したけど、実装が進まない
- APIの使い方が分からない
- 環境構築で時間を取られすぎる

**解決策:**
- 事前に最低限の技術調査をしておく
- 公式ドキュメントを活用する
- スクールのメンターや他の参加者に相談する

### 3. タイムマネジメントの難しさ
時間配分を誤ると、最後に慌てることになります。
- 初めの設計に時間をかけすぎて、実装時間が足りなくなった
- デバッグやテストの時間がなく、動かないものを提出することに
- プレゼン資料を準備する時間が足りなくなり、説明が雑に

**解決策:**
- 開発スケジュールを事前に大まかに決めておく
- 最低限動く状態を早めに作り、余裕を持ってブラッシュアップする
- プレゼン準備の時間も確保する

## ハッカソン後の振り返りの重要性

ハッカソンは、終わった後の振り返りが非常に大切です。

### 1. チーム内での振り返り

チームメンバーと以下の点を共有すると、次回のハッカソンに活かせます。
- **良かった点:** うまくいったこと、チームワークが機能した部分
- **改善点:** もっとこうすればよかったこと、時間配分や役割分担の反省点
- **学んだこと:** 新しく学んだ技術や、今後使えそうな知識

### 2. 他のチームとの振り返り

他のチームの発表を聞くことで、新しいアイデアや工夫を学べます。
- **他のチームの良い部分を学ぶ**
- **自分たちのプロダクトの改善点を見つける**
- **次回のハッカソンの目標を決める**

## まとめ

ハッカソンに参加することで、技術力だけでなく、チームで協力する力やプレゼン能力も鍛えられます。

:::note info
***また、困難に直面することで新しい学びが生まれ、それを次回に活かせるようになります。***
:::

今回のハッカソンを通じて感じたことや得た知識を次回のイベントに役立て、より良い開発体験を積んでいくことをおすすめします！

## 関連記事

https://qiita.com/free-honda/items/161198c52e41f89ac02d
rex0220 印刷屋プラグイン 見積書に住所・電話番号を追加

[rex0220 印刷屋プラグイン](https://qiita.com/rex0220/items/9be2d9b20a3a1f016c76)の見積書に住所と電話番号を追加してみます。

# 概要

見積書に住所・電話番号の項目を追加する例です。
自社の住所・電話番号は、固定の文字列を追加します。

- 住所： "〇〇県〇〇市〇〇〇〇〇-〇-〇"
- 電話： "TEL: 00-0000-0000"

![2025-03-05_08h48_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/b279e36a-12c4-4b06-88d2-0d5f97d65ad9.png)


![2025-03-05_08h48_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c8740d81-1e0b-49fe-bf42-1df14591948f.png)

# 印刷屋プラグイン設定

住所と電話番号の2行を追加します。

![2025-03-05_08h54_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/75f32604-fcfb-4574-a545-abc39b38b9c3.png)

![2025-03-05_08h51_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d10eee61-18de-481b-9e31-f48fcd34880a.png)


```js:
PAGE_HTML(
  TAG("div", ATTR("class", "pcraft-inv-header"), "見積書"),

  TAG("div", ATTR("class", "pcraft-inv-info"),

    // header left
    TAG("div", ATTR("class", "pcraft-inv-left"),
      TAG("p", 宛名 & " 御中"), VTAG("br"),
      TAG("p", ATTR("class", "pcraft-inv-estimate-amount"), "見積金額:", TAG("span", FVAL(合計金額))),
      TAG("p", ATTR("class", "pcraft-inv-validity"),
        "見積の有効期限: " & DATE_FORMAT(見積有効期限, "YYYY年M月D日")
      )
    ),

    // header right
    TAG("div", ATTR("class", "pcraft-inv-right"),
      TAG("p", "見積番号: " & 見積番号),
      TAG("p", "発行日: " & DATE_FORMAT(見積日, "YYYY年M月D日")),
      TAG("p", "株式会社サンプルサンプルサンプル"),
      TAG("p", "〇〇県〇〇市〇〇〇〇〇-〇-〇"),
      TAG("p", "TEL: 00-0000-0000"),
      TAG("p", "開発 太郎"),
      VTAG("img", ATTR("class", "pcraft-inv-seal", "width", "250", "height", "120", "src", "#{&f(20250302031501227586874B104969A58F90E42C4C3C26073)}"))
    )
  ),

  // table
  TABLE_HTML(見積明細,
    OPT("pref", "pcraft-inv-item-"),
    ARRAY("#", ROWNO(見積明細) + 1),
    商品名, 数量, 単価, 金額
  ),

  // summary
  TAG("div", ATTR("class", "pcraft-inv-summary-section"),
    // 備考
    TAG("div", ATTR("class", "pcraft-inv-remarks-section"),
      TAG("strong", "備考:"), VTAG("br"),
      TAG("span", HTML(FVAL(備考)))
    ),
    // 合計
    TAG("div", ATTR("class", "pcraft-inv-total-section"),
      TAG("table",
        TAG("tbody",
          TAG("tr", TAG("th", "小計"), TAG("td", FVAL(小計金額))),
          TAG("tr", TAG("th", "消費税 (10%)"), TAG("td", FVAL(消費税))),
          TAG("tr", TAG("th", TAG("strong", "合計")), TAG("td", TAG("strong", FVAL(合計金額))))
        )
      )
    )
  )
)
```
【Python】毎週勉強するシリーズ ～辞書～

# 概要
AI が流行ってる昨今 Python は必須級のスキルになってきてます。
時代に取り残されないようにコツコツと Python を勉強しようと思います！
三日坊主にならないように Qita でアウトプットしながら進めます💪

# 今日やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) の辞書を理解する。

# 辞書(dict)

### 1. 基本的な書き方
辞書(dict)は `{...}` でキーと値のペアのリストを保持します。

```py
d = {'Yamada': 30, 'Suzuki': 40, 'Tanaka': 80}
```

### 2. 各要素へのアクセス
各要素には次のようにアクセスします。
```py
d1 = d['Yamada']
d2 = d['Suzuki']
d3 = d['Tanaka']
```

### 3. 要素を追加する
存在しないキーペアで代入することで追加できます。
```py
d = {'Yamada': 30, 'Suzuki': 40, 'Tanaka': 80}
d['Kimura'] = 60
```

### 4. 要素を更新する
存在するキーペアで代入することで追加できます。
今回は `Yamada` のキーに対する値を `30` → `60` に変更しています。

```py
d = {'Yamada': 30, 'Suzuki': 40, 'Tanaka': 80}
d['Yamada'] = 60
```

### 5. 全ての要素や値を参照する
`items()`, `keys()`, `valus()` を使用します。
参照される要素の順序は順不同です。

```py
d = {'Yamada': 30, 'Suzuki': 40, 'Tanaka': 80}

for k, v in d.items():
    print(k, v)            # Tanaka 80, Yamada 30, Suzuki 40

for k in d.keys():
    print(k, d[k])         # Suzuki 40, Yamada 30, Tanaka 80

for v in d.values():
    print(v)               # 80, 30, 40
```

# 感想
今日は辞書をやってみました！

今回も見ていただきありがとうございました。
また次回お会いしましょう！！

# 次回やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) のリスト関数(map(), filter(), reduce())を理解する。
機械学習のモデル選定について

機械学習プロジェクトにおいて、適切なモデルを選定することは極めて重要です。しかし、単にモデルを選ぶだけでなく、その選定理由を明確に説明できなければ、クライアントや採用担当者の信頼を得ることが難しくなります。

## **1. モデル選定の流れを体系的に整理する**
モデル選定において、以下のようなステップを踏むことで、論理的な説明がしやすくなります。

1. **問題の定義**: 何を解決するためのモデルなのかを明確にする。
2. **データの性質を分析**: データの構造や特徴量を理解し、適切な前処理を施す。
3. **評価指標の決定**: 何をもって良いモデルとするのか（精度、AUC、F1スコアなど）。
4. **候補モデルの選定**: 複数の手法をリストアップし、それぞれの特性を比較。
5. **ハイパーパラメータ調整と評価**: 候補モデルの性能を比較し、最適なものを選ぶ。
6. **ビジネス要件との整合性を確認**: 現場での実装や運用面を考慮する。

---

## **2. モデル選定の根拠を明確に示す**

### **(1) どのような課題を解決するのか？**
まず、**解決したい問題を具体的に定義**し、その問題に対してどのようなモデルが適切かを考える必要があります。

例えば、
- **画像認識** → CNN（畳み込みニューラルネットワーク）
- **時系列予測** → LSTM, Transformer
- **カテゴリ分類** → ロジスティック回帰, ランダムフォレスト, XGBoost
- **異常検知** → Isolation Forest, Autoencoder

このように、問題の特性に応じたモデルを選択することが重要です。

### **(2) なぜそのモデルを選んだのか？（比較を示す）**
候補となるモデルをいくつか挙げ、それぞれの**長所・短所を比較**することで、選定理由を明確にできます。

#### **例: 画像分類タスクでのモデル選定**
| モデル | 長所 | 短所 |
|--------|------|------|
| ResNet | 高い精度、深い層でも学習可能 | 計算コストが高い |
| MobileNet | 軽量でモバイル環境でも使いやすい | 精度はResNetより劣る |
| ViT (Vision Transformer) | 画像分類の最新技術、解釈しやすい | 計算資源が必要 |

このように比較表を用いると、なぜ特定のモデルを選んだのかを明確に説明できます。

### **(3) 評価指標と数値データを用いる**
モデルの選定には、定量的な評価が欠かせません。例えば、
- **分類問題** → Accuracy, Precision, Recall, F1-score, AUC-ROC
- **回帰問題** → RMSE, MAE, R²
- **異常検知** → F1-score, Precision-Recall Curve

「ResNetを選んだのは、テストデータでF1-scoreが0.92と最も高かったため」といった具体的なデータを示すことで、選定理由の説得力が増します。

---

## **3. 採用の場面でモデル選定をクリアに伝える方法**

### **(1) 説明の際に「なぜ？」を繰り返す**
採用面接やクライアントへの説明では、モデル選定の際に「なぜ？」を繰り返すことで、論理的な構成を作ることができます。

**例:**
1. **なぜこのモデルを選んだのか？** → 「データが大量にあり、高精度な画像分類が求められるためResNetを採用しました。」
2. **なぜResNetが適切なのか？** → 「CNNの中でも層が深く、高精度な分類が可能だからです。」
3. **他のモデルではダメなのか？** → 「MobileNetは軽量ですが、精度が求められる場面では不十分と判断しました。」

このように、「なぜこのモデルなのか？」を多角的に説明できるように準備すると、選定理由がクリアになり、説得力が増します。

### **(2) 図やグラフを活用する**
テキストだけではなく、以下のようなビジュアルを活用すると、理解がしやすくなります。
- **精度比較のグラフ**（例: AUC-ROC曲線）
- **誤分類ヒートマップ**（どのラベルで間違えたのかを示す）
- **モデルの構造図**（例: ResNetのブロック構造）

これにより、直感的にモデル選定の理由を伝えることができます。

---

## **4. まとめ**

モデル選定の際に重要なのは、**論理的に根拠を示し、クリアに説明できること**です。以下のポイントを押さえることで、採用面接やクライアントへの提案時に納得感のある説明ができるようになります。

✅ **モデル選定の流れを体系的に整理する**（問題の定義、評価指標の決定、モデル比較）  
✅ **選定理由を明確にする**（問題の特性に適したモデルを選び、比較表を活用）  
✅ **評価指標を定量的に示す**（F1-scoreやAUCなど具体的な数値を提示）  
✅ **「なぜ？」を繰り返し、多角的な説明を準備する**  
✅ **図やグラフを活用して視覚的に説明する**  

こうした工夫をすることで、「モデル選定の理由がクリアでない」といったフィードバックを防ぎ、より信頼されるデータサイエンティストやエンジニアとして評価されるようになるでしょう。
家計簿アプリを作る＃７

![スクリーンショット 2025-03-05 082753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/c7a621bd-b509-4ab5-ba97-023efa166d78.png)
pagesフォルダの中に、NoMatch.tsxファイルを作成します。

![スクリーンショット 2025-03-05 082923.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/2ca3d657-9a24-4aa6-9367-5c471456f2a0.png)
ひな形を作成し、このページはありませんと記述しておきます。

![スクリーンショット 2025-03-05 083038.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/793158e9-3307-4806-bc37-e7a244badfbe.png)
そして、Nomatchファイルをインポートします。

![スクリーンショット 2025-03-05 083200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/d470c5b0-9693-4d65-b95a-9a4b12b2139d.png)
このページはありませんと表示されれば、成功です。
RASISについてのメモ

### **📌 RASISとは？**  

**RASIS（ラシス）** は、システムの品質を評価するための **5つの指標** で、特に **システムの信頼性や運用管理** に関わる場面で使われます。  

---

### **📊 RASISの5つの指標**  

| 指標              | 意味                         | 具体的な内容 |
|------------------|----------------------------|-------------|
| **R**eliability<br >（信頼性） | システムがどれだけ **壊れにくいか** | - システムが安定して動作するか<br>- ハードウェアやソフトウェアの耐障害性 |
| **A**vailability<br >（可用性） | システムが **使える状態を維持できるか** | - サーバーダウンの頻度や時間<br>- 稼働率（99.99%など） |
| **S**erviceability<br >（保守性） | **問題が起きたとき、どれだけ早く直せるか** | - 障害対応のしやすさ<br>- 修理やアップデートのしやすさ |
| **I**ntegrity<br >（保全性） | データが **改ざん・破損されずに守られるか** | - 不正アクセス対策<br>- データの整合性の維持 |
| **S**ecurity<br >（安全性） | システムやデータを **脅威から守れるか** | - 不正ログインやウイルス対策<br>- 認証・暗号化の強度 |

---

### **📌 RASISのはバランスがとても大事！**

RASISのバランスを取るのは、**スポーツチームの編成** に似てると思います。

例えば、強いチームを作るには「安定感のあるベテラン」「体力のある若手」「優秀なコーチ」「ルールを守る姿勢」「選手や観客の安全対策」のバランスが大事だと思いますが。
システム設計も同じで、**RASISの5つの要素をバランスよく組み合わせる** ことが重要なんです！

---

### **🏀 RASISをスポーツチームに例えると？**

| **指標** | **スポーツで例えると…？** | **何が起こる？** |
|----------|----------------|--------------|
| **Reliability<br >（信頼性）** | 安定したベテラン選手 | 経験豊富で安定感はあるけど、新しい戦術に対応しづらい。 |
| **Availability<br >（可用性）** | 試合に出られる体力 | 選手がいつでも試合に出られるのは大事だけど、酷使しすぎるとケガのリスクが増える。 |
| **Serviceability<br >（保守性）** | 優秀なコーチやトレーナー | ケガをしたときにすぐ治療や対応ができると安心。ただし、休ませすぎると試合に出られなくなる。 |
| **Integrity<br >（保全性）** | ルールを守るフェアプレー精神 | ルール違反をすると信用を失う。でも慎重になりすぎると攻めのプレーができなくなる。 |
| **Security<br >（安全性）** | 選手や観客の安全対策 | ケガや事故を防ぐために安全対策は必須。でも厳しくしすぎると試合がつまらなくなる。 |

---

### **⚠️ 1つだけを重視しすぎると…？**

🏉 **Security（安全性）** は「選手や観客の安全対策」
→ 会場のセキュリティや、ケガのリスクを減らす工夫が必要。

💡 **1つだけを強化しすぎると…？**

✅ **信頼性（R）を重視しすぎると**
👉 ベテランばかりで安定するけど、新しい戦術が使えず、競争力が落ちる。

✅ **可用性（A）を最優先すると**
👉 とにかく試合に出ることを優先するが、選手の疲労が溜まりやすくケガのリスクが高まる。

✅ **保守性（S）を上げすぎると**
👉 怪我のリスクを考えて休ませすぎると、試合に出られる選手が減る。

✅ **保全性（I）を厳しくしすぎると**
👉 ルールを守るのは大事だけど、慎重になりすぎてプレーの自由度が下がる。

✅ **安全性（S）を強化しすぎると**
👉 選手を保護しすぎるあまり、試合がスリルのない退屈なものになる。

---

### **🎯 業界や用途に応じて、RASISのバランスを考えることが重要ですね**

強いチームを作るには **すべての要素を適度に組み合わせることが大事だよね！**
システム設計も同じで、**どれか1つだけを優先しすぎると、他の部分が弱くなってしまう**んだよね。

例えば：
---

#### 🏦 **金融システム（銀行・決済・証券取引など）**  
**重要要素：保全性（I）と信頼性（R）**  
データの改ざんや不正取引は致命的な問題を引き起こさないように
システムの正確性と安定性が最優先!  

---

#### 🏥 **医療システム（電子カルテ・診療記録・医療機器制御など）**  
**重要要素：保全性（I）と信頼性（R）**  
患者の命に関わるため、データの正確性とシステムの安定稼働が必須！  
データの誤変更や不具合は避けるべき!  

---

#### 🏢 **行政システム（住民情報・税務・選挙管理など）**  
**重要要素：保全性（I）と信頼性（R）**  
住民情報や税務データが誤って消失したり改ざんされると、社会的に大きな影響が出る
データの正確性とシステムの安定運用が重要!

---

#### ⚖️ **法務システム（裁判記録・契約管理など）**  
**重要要素：保全性（I）と信頼性（R）**  
裁判記録や契約書など、法律に関わるデータは一度改ざんされると法的に無効になります。  
信頼性とデータの保全性を確保することが最優先! 

---

#### 🛒 **ECサイト（オンラインショップ・マーケットプレイスなど）**  
**重要要素：可用性（A）と保守性（S）**  
ユーザーがいつでもサイトにアクセスできるように **可用性（A）** を重視しつつ、  
商品の追加やシステムのメンテナンスが簡単にできるように **保守性（S）** も重要！
また、決済部分では **保全性（I）** を確保する必要がある！  

---

#### 🔐 **IoTシステム（スマートホーム・車両制御システムなど）**  
**重要要素：安全性（S）と信頼性（R）**  
外部からの攻撃や不正アクセスを防ぐことが最優先！
その上で、システムが安定して動作し続けることも求められる。  

---

#### 💻 **クラウドサービス（SaaS、PaaSなど）**  
**重要要素：可用性（A）と保守性（S）**  
ユーザーが常にサービスにアクセスできることが最も重要！  
加えて、定期的なアップデートや障害発生時にスムーズな対応を行えるように **保守性（S）** も重視！

---  

**目的に合わせてRASISのバランスを調整し、最適なシステムを作ろう！** 🚀
【Ruby】HTMLエスケープ処理された状態でDBに保存されてしまう...

どうもこんにちは。

今回はRails開発中に、`&`を入力したら`&amp;`として登録されたり、`<`を入力したら`&lt;`として登録されたりという動作をしていたので、それを解消しました。

# 何が起こっていたのか

Railsのコントローラでパラメータを受け取る際に**サニタイズ**の処理をかけていたのですが、この処理によってHTMLエスケープがされてしまっていました。

# 対処方法

安全面を考慮して、サニタイズの処理は外せないので、「**サニタイズの処理の後にHTMLエスケープされた箇所をデコードする**」という対応にしました。

# 元々のサニタイズ処理

`config/initializers/sanitize.rb`にサニタイズの設定を定義しています。

```rb
require 'sanitize'

class Sanitize
    module Config
        RESTRICTED = freeze_config(
            elements: %w[b em i strong u],
        )
    end
end
```

`app/controllers/application_controller.rb`でサニタイズ処理を定義していました。

```rb
  def sanitize_text(text)
    Sanitize.fragment(text, Sanitize::Config::RESTRICTED)
  end
```

各コントローラのストロングパラメータ部分で、`sanitize_text`を呼び出していました。

```rb
  private

  def user_params
    temp_users = params.require(:user).permit(
      :username,  # string
      :name,      # string
      :age,       # integer
      :note       # text
    )

    # 嫌な書き方してました...
    temp_users[:username] = sanitize_text(temp_users[:username])
    temp_users[:name] =     sanitize_text(temp_users[:name])
    temp_users[:note] =     sanitize_text(temp_users[:note])

    temp_users
  end
```

# 修正後のサニタイズ&HTMLエスケープデコード処理

`app/controllers/application_controller.rb`のサニタイズ処理にデコード処理を加えて定義します。

```rb
  def sanitize_and_unescape_html(text)
    sanitized_text = Sanitize.fragment(text, Sanitize::Config::RESTRICTED)
    CGI.unescapeHTML(sanitized_text)
  end
```

各コントローラのストロングパラメータ定義部分で`sanitize_and_unescape_html`を呼び出します。

```rb
  private

  def user_params
    temp_users = params.require(:user).permit(
      :username,  # string
      :name,      # string
      :age,       # integer
      :note       # text
    )

    # これならメンテナンスが楽！
    columns = [ :username, :name, :note ]  # 対象のカラムを配列で指定する
    columns.each do |column|
      temp_users[column] = sanitize_and_unescape_html(temp_users[column])
    end

    temp_users
  end

```

これで、サニタイズとHTMLエスケープのデコード処理が実装できました。

以上
とりあえず十進固定小数点の平方根でSQRT(20)前後を作ってみた


- れんしゅうで作った
- 精度は、ほぼない

![o_coq830.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/79643545-537e-41d3-9243-9e29e8ec8ce7.jpeg)


プログラム
----


オンラインコンパイラ


```c++


#include <iostream>
using namespace std;

int q_rsqrt(int number) {
    
    long long i;
    long long x2, y;
    long long threehalfs;

    x2 = number * 1000000 / 2;
    y  = number * 1000000;
    threehalfs =  15 * 1000000 / 10;
    
    
    printf("x2 = %lld\n",x2);
    printf("y = %lld\n",y);
    printf("threehalfs = %lld\n",threehalfs);

    y = 304049 - (( 7812 * x2 )/1000000);
    printf("y = %lld\n",y);
    
    i = y * y / 1000000;
    i = x2 * i / 1000000;
    i = threehalfs - i;
    y = y * i / 1000000;
    printf("y = %lld\n",y);
    //y  = y * ( threehalfs - ( x2 * y * y ) );
    return y;
}


int main(void){
    // Your code here!
    
    int in = 20;
    int f;
    
    f = q_rsqrt(in);
    f = in * f;
    printf("%d.%d",f / 1000000,f % 1000000 );

}



```


```

x2 = 10000000
y = 20000000
threehalfs = 1500000
y = 225929
y = 223572
4.471440

```
日本語文字数・単語数カウンター: 効率的なテキスト分析ツール

日本語のテキストを扱う上で、文字数や単語数を正確にカウントすることは非常に重要です。特に、文章作成や翻訳、SEO対策、さらには学術的な執筆や記事作成において、正確な文字数や単語数が求められる場面が多くあります。そこで役立つのが、日本語文字数・単語数カウンターです。https://kauntomoji.com/

1. 日本語に特化した精度の高いカウント
日本語のカウントには特有の難しさがあります。例えば、英語のように単語がスペースで区切られていないため、単語数を数える際には日本語の文法や語彙に基づく適切な解析が必要です。私たちのツールは、この難しい日本語のテキストを高精度で解析し、文字数と単語数を正確にカウントします。

2. シンプルで使いやすいインターフェース
オンラインツールであるため、インストールの手間は一切かかりません。ユーザーは、提供された入力フォームにテキストを貼り付けるだけで、すぐに結果を得ることができます。直感的なデザインで、誰でも簡単に操作できるのが特徴です。

3. 学術・ビジネスでの活用
日本語のテキストの長さや単語数が求められる場面は多岐にわたります。例えば、論文やレポートでは文字数制限が設けられていることが多いですし、SEO対策ではページ内の単語数が検索エンジンに影響を与えることがあります。また、翻訳業務でも、文字数によって料金が変動するため、正確なカウントが重要です。私たちのツールは、これらの場面で役立つ強力なサポートを提供します。

4. 高度な解析機能
さらに、私たちのカウンターは、単に文字数と単語数をカウントするだけではなく、テキストの中の漢字、ひらがな、カタカナ、英数字などの各種文字のカウントも可能です。これにより、例えば漢字のみの文字数や、ひらがな・カタカナの割合など、細かなテキスト解析ができるのも大きな利点です。

5. 無料で利用できる
多くのテキスト解析ツールは有料で提供されていますが、私たちの日本語文字数・単語数カウンターは無料で使用することができます。これにより、学生やフリーランスのライター、企業のマーケティング担当者など、幅広い層のユーザーに利用していただけます。

結論
日本語のテキストを扱う際には、正確な文字数と単語数を把握することが非常に大切です。私たちの日本語文字数・単語数カウンターは、その正確性と使いやすさを兼ね備えた優れたツールです。テキスト解析をより効率的に行いたい方々にとって、欠かせないツールとなることでしょう。

ぜひ一度、私たちのオンラインツールを試してみてください。簡単な操作で、あなたのテキストの詳細な分析が可能になります。
モジュールの__name__と__main__について

Pytonモジュールを勉強していく途中、__name__と__main__の内容が出てきたので、ここに書き留めておく。


# import文の処理

通常import文を使うときは、スクリプトの先頭に記述していくが、importされる側の処理が、例えばプリントのみの場合、import文で呼びだした側のスクリプトには、importされた時点で、print関数が読み込まれ、意図せずに出力されてしまう場合がある。


```Python:lesson.py
import lesson_packege.talk.animal

import config

```

```Python:animal.py
def sing ():
    return "#kjaflds;jfiewanfkla;nisesing"

print(sing())
```

```Python:config.py
print("config:",__name__)
```

```Python:lesson.py 出力
#kjaflds;jfiewanfkla;nisesing
config: config

```
プロジェクト内で、インポート先のスクリプトにテスト用として出力されるものがあった場合、インポートした際に、意図せず出力されてしまう。

# 問題の解決策

この問題を解消するために、if文を使いスクリプトを作成する。

```Python:animal.py
def sing ():
    return "#kjaflds;jfiewanfkla;nisesing"

if __name__ == "__main__":
   print(sing())
   print("animal:",__name__)

```

```Python:lesson.py
import lesson_packege.talk.animal

import config 

```

```Python:出力
config: config
```

animal.pyのように、もしスクリプトがmainであるならばsing()を出力せよ。と記述すれば、lesson.pyを実行する時に、animal.pyはmainではないので、出力されなくなる。
※__name__はスクリプト名として処理をされるが、実行するスクリプトは__main__として処理される。

# 具体例

```Python:lesson.py
import lesson_packege.talk.animal

import config #importされた時点で、実行されるプリントがあったら実行されてしまう。

def main() : #このスクリプトもインポートされる可能性があるため、関数に閉じておく
   lesson_packege.talk.animal.sing()

if __name__ == "__main__": #このスクリプトがインポートされた時に勝手に出力されない用
    main()

print("lesson",__name__)

```

```Python:animal.py

def sing ():
    return "#kjaflds;jfiewanfkla;nisesing"


if __name__ == "__main__":
   print(sing())
   print("animal:",__name__)

```
```Python:config.py
print("config:",__name__)
```

```Python:lesson.py出力
config: config
lesson __main__
```

実際のアプリケーション開発では、このように記述する
【SSH】設定方法についてまとめてみた

## 設定に必要なファイルって何？
### 接続先の設定ファイル（~/.ssh/config）
~/.ssh/configとは、ssh経由でのリモートサーバーの接続する際に利用される設定ファイルのこと！
詰まるところ接続先の設定を書くとファイルなのです。
接続先のIPアドレスや接続のオプションやらなんやらって覚えるのって無理ゲーだよね、、、
そんな時に便利なのがconfigファイルってわけですよ！
詳しい書き方は下記を参考にしてみてね♪
https://tech-blog.rakus.co.jp/entry/20210512/ssh

:::note warn
仕事で使う場合は会社の指示に従おうね！
:::

ちなみに私の設定はこんな感じ
vi ~/.ssh/config
```config
Include conf.d/*.conf
Include conf.d/default-config
```
githubにプロジェクト毎の設定、全部ここに書くと可読性は下がるし管理も面倒になる。
だから~/.ssh/config/conf.dっていうディレクトリを作って、設定を個別に作ったものをIncludeしてるってわけ。
同じ設定をしていてもより下に記載された設定が有効になるから共通の設定ファイルは最後に読み込むようにしているんだよね。

### 鍵ファイル
まぁこれがないと繋がらないわけですけど、作り方は至って簡単！
ただ、複数の鍵が混在するとconfigファイルもあって~/.sshフォルダ内がごちゃごちゃになる。
個人的には鍵ディレクトリを作ることをお勧めするよ！

ご参考までに！
```
> ls -l ~/.ssh 
drwx------ 10 {userName}  320  3  7 19:50 conf.d
-rw-------  1 {userName}   55  3  7 19:50 config
drwx------  5 {userName}  160 11 24 14:36 keys

> ls -la ~/.ssh/conf.d
-rw-------  1 {userName}   52  3  7 19:50 default-config
-rw-------  1 {userName}  190  2 21 16:40 github.conf

> ls -la ~/.ssh/keys
drwx------ 4 nonaka_misaki 128 11 24 14:37 github

> ls -la ~/.ssh/keys/github
-rw------- 1 nonaka_misaki 2635 11 24 14:37 id_rsa
-rw-r--r-- 1 nonaka_misaki  560 11 24 14:37 id_rsa.pub
```

下記ファルの生成に関しては記事があるから参考にしてね
https://qiita.com/c_tomioka/items/379a9288d44634ca1daa

## Permissionsエラーでハマるんだよね

### 設定すべき権限
参考用のディレクトリ構成を見ればわかると思うけど、こういうことです。

| 対象 | 権限 |
|:------:|:------:|
| ~/.sshを含む~/.ssh配下のディレクトリ | 700 | 
| configファイル | 700 | 
| 秘密鍵ファイル| 600 |
| 公開鍵ファイル| 644 |

同じデジレクトリ構成の場合で権限エラーがでたら下記を試してみてね！

```shell
find ~/.ssh -print | xargs chmod 700
find ~/.ssh/keys -type -f -print | xargs chmod 600
find ~/.ssh/keys -type -f -name "*.pub" -print | xargs chmod 644
```
競プロ日記#25/03/04

# アルゴ式-[ハッシュ](https://algo-method.com/tasks/866)
- 正直解説を読んでやっと理解できた。（要復習）
```
// 文字列を 30 進法の整数値とみなし、そのハッシュ値を返す関数
int hash30(string& S) {
    int len = S.length();   // 文字列 S の長さ
    int ret = 0;    // 変換後の数値を入れる変数
    for(int i = 0; i < len; ++i) {
        char c = S[len-1-i];    // S の後ろから i 番目の文字 (0-index で)
        int n = c - 'a' + 1;    // 'a' を 1 にするため、+1 が必要
        ret += n * p30[i]; // 記数法的に1の位32の位32^2...とする
    }
    return ret;
}
```
- この「int n = c - 'a' + 1;    // 'a' を 1 にするため、+1 が必要」がかなり重要に感じた。

```
const int M = 30 * 30 * 30 * 30;
    vector<int> counter(M, 0);  // counter[v] : hash 値が整数 v である要素の数。アルファベットa~zで4文字で表記できる文字列のハッシュ値をkeyとしてカウンタの配列
```
- a~zで構成される4文字の文字列のハッシュ値全てをキーとする連想配列をカウンターの配列として用意している。ここも大事な気がする。

# AtCoder-CODE FESTIVAL 2016 qual B
## [B - Qualification simulator](https://atcoder.jp/contests/code-festival-2016-qualb/tasks/codefestival_2016_qualB_b)

- B問題だったのでそんなにむずかしくはない
Gitのrebaseで複数のコミットを１つにまとめる方法

## はじめに
複数の小さな変更を１つのまとまったコミットにまとめることで、コミット履歴を整理し、見やすくすることができます。
ここでは、Git手順を記載します。
１点注意点として、rebaseを実行するとコミットハッシュが変更されます。
push済みの場合は他作業者に作業を実施することを連携しておきましょう。

## 手順
### 1. コミットログを確認する
リベースを開始するまでにどのコミットを変更するのかを指定するためにコミットハッシュを確認します。
```sh
$ git log --oneline
8e75880 (HEAD -> main) fix: text
41a4fe9 fix: header clolor
3e89043 [wip] 一旦コミット
80e3b0d first commit
```
上記を例に、3e89043と41a4fe9をまとめることとします
最新のコミットから2つ目をこの後のrebase開始時に指定します

### 2. リベースを開始する
リベースを開始します。リベースを行いたいコミットの親コミットのハッシュを指定します。

```sh
$ git rebase -i 80e3b0d
```
<details><summary>-iオプションについて補足</summary>

補足ですが、-iオプションはinteractiveの意味でした。
コミットログをどのように変更するかを対話的に再構築するということですね
>-i
>--interactive
>Make a list of the commits which are about to be >rebased. Let the user edit that list before >rebasing. This mode can also be used to split >commits (see SPLITTING COMMITS below).
>
>The commit list format can be changed by setting the configuration option rebase.instructionFormat. A customized instruction format will automatically have the commit hash prepended to the format.
>
>See also INCOMPATIBLE OPTIONS below.


https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt--i
</details>


### 3. vimエディタでコミットを編集する
rebase実行後に、vimコマンド操作から編集します。
vimコマンド詳細は割愛しますが、以下で事足ります
- `i` 挿入モード
- `ESC` 挿入モードを終了する
- `:wq` 保存して終了

まとめたいコミットの行を pick から fixup に変更します。
以下のように編集します。
```vim
fixup 3e89043 [wip] 一旦コミット
pick 41a4fe9 fix: header clolor
pick 8e75880 fix: text
```

次のようなrebase操作を選択できます
| 操作  | 説明 |
|-------|------|
| pick  | そのままの状態でコミットを保持 |
| reword| コミットメッセージを変更 |
| edit  | コミット内容を変更 |
| squash| 複数のコミットを1つのコミットにまとめ、コミットメッセージを編集 |
| fixup | 複数のコミットを1つのコミットにまとめ、最初のコミットメッセージを保持 |
| drop  | コミットを削除 |

### 手順 4: リベースを完了する
vimエディタを終了すると、変更が適用されます
再度コミットログを確認しておきましょう。

### 手順 5: 強制pushする
問題なければ強制pushしましょう。
```sh
git push -f origin <ブランチ名>
```

## まとめ
コミット履歴を整理し、プロジェクトの履歴が明確になります。
細かい点ですが活用するようにしましょう。

## 参考
https://www-creators.com/archives/2850
PHPで「比較演算子」の動作を確認してみた。

# 概要

PHPで「比較演算子」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/if/index3.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
<?php
$var1 = 208;
if ($var1 == 208){
  print "変数の値は208と等しい<br />";
}

$var1 = 12;
$var2 = '12';
if ($var1 == $var2){
  print "12 == '12'はTRUEです<br />";
}

$var1 = 'Tokyo';
if ($var1 == 'Tokyo'){
  print "変数の値はTokyoと等しい";
}
?>
</p>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
変数の値は208と等しい<br />12 == '12'はTRUEです<br />変数の値はTokyoと等しい</p>

</body>
</html>
```

# まとめ

何かの役に立てばと。
Next.js 15でprismaのcreateを実行したら、TypeError: The "payload" argument must be of type object. Received null　というエラーが出た際の解決策

Next.js 15においてprismaで、DBにcreateしたら以下のようなエラーが発生した。
「TypeError: The "payload" argument must be of type object. Received null」

# 対応策
1. node_modules/@prisma/client/runtime/library.jsの``` //# sourceMappingURL=library.js.map ```を削除する
1. ```npm install --save patch-package```を実行して、patch-packageを導入する
1. ```npx patch-package @prisma/client```を実行する
1. 本番環境でもパッチを反映するために、package.jsonに以下のscriptを追加する
``` json
"scripts": {
    "postinstall": "npx patch-package その他のパッケージ",
```

## 参考
https://nkiri.hatenablog.com/entry/2025/03/01/214349
[PowerApps]オセロゲームのロジックを作成してみて困ったこと（碁石をひっくり返す）

# 背景
PowerAppsのキャンバスアプリでオセロゲームの碁石がひっくり返すロジックを開発してみたところ、**苦戦した部分**もあったため、どのように解決したかメモしておきます。
# 参考にしたロジック
[JavaScriptでオセロゲームを作成する方法を現役エンジニアが解説【初心者向け】](https://magazine.techacademy.jp/magazine/22767?utm_source=pocket_shared)を参考にさせていただきました。
![ひっくり返すロジック_参考.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/0c6c4d76-7739-4f07-ad2b-8f0db40df0b2.png)
# 問題点
PowerAppsの**繰り返し関数ForAll関数の繰り返しの途中で終了する関数がない**ため、参考にしたロジックをPowerApps向けに微修正する必要がある。
# 解決策
ForAll関数の繰り返しの中で**更新するコレクションにisTargetという列を持たせ、この列がfalseのレコードが1件でもあれば、処理をしないというロジックにする**。そのことにより、**isTargetという列をfalseにしたデータがコレクションに追加した後から何も処理しないようにすることができました。**
コードの例は以下になります。
```PowerFx
// 先手:黒,後手:白
ForAll(
    boardFromBaseToUpWk, // 打った碁石(星)から北方向へひっくり返すか確認する碁石のコレクション
    If(
        IsBlank(LookUp(returnStoneseWork, isTarget=false)),
        // 碁石の色が相手の色でも隣あっていない碁石はひっくり返す対象外とする
        If (
            // InTurn:0(先手),1(後手)
            // status:1(黒),2(白)
            ThisRecord.status=If(Cell.InTurn=0,2,1), 
            // 碁石の色が相手の色の場合
            Collect(returnStoneseWork,{isTarget:true,row:ThisRecord.row,col:ThisRecord.col,status:If(Cell.InTurn=0,1,2)});,
            // 碁石の色が相手の色でない場合、isTargetをfalseにして、上記の条件によって、そのあとはreturnStoneseWorkに追加する処理をさせない。
            Collect(returnStoneseWork,{isTarget:false,row:ThisRecord.row,col:ThisRecord.col,status:ThisRecord.status});　// returnStoneseWork:ひっくり返す碁石のコレクション
        );
    )
);
```
# プラスα
ひっくり返すロジックをどうしたかも整理しておきます。
![ひっくり返すロジック_PowerApps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/6bbe60b5-cd32-4bad-bf96-83d5c1eb294f.png)
# まとめ
参考にさせていただいたjavascriptのコードをPowerFx(PowerApps)に変換してもらうようにChatGPTにお願いしましたが、**PowerFxにはない関数を出力するなどして、完璧ではないみたいです。PowerFx(PowerApps)向けに微修正する必要がありそうです**。
引き続き、ChatGPTも活用して、どのような手順で進めると、高品質なコードを楽に生成することができるか探求していこうと考えております。
この記事が皆さんの役に立てば幸いです！
また、この記事に興味を持ったという方おられましたら、コメントいただけると幸いです。
記事をご覧いただきありがとうございます。
NetSuiteでグラフを作る　（続：NetSuiteでピボットテーブルを作ってみる）

今回は、SuiteAnalytics Workbookシリーズの最終回、NetSuiteでグラフを作るということで、ワークブックの使い方をご紹介します。

## ワークブックの種類について
まずはデータの見せ方の種類を選択します。
![rapture_20250219111543.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/eb12cdc8-8f25-4322-9b6c-7420497e0b10.jpeg)
<dl>
  <dt>テーブル</dt>
  <dd>データを一覧形式で表示します</dd>
  <dt>ピボット</dt>
  <dd>データをピボットテーブル形式で表示します</dd>
  <dt>チャート</dt>
  <dd>データのグラフ形式で表示します</dd>
</dl>

## グラフの作り方
グラフの種類を選びます。
![rapture_20250304233352.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/b617680e-28ea-482f-8e0e-fac885bd8f7c.jpeg)

グラフに表示する項目を選びます。
![rapture_20250304235740.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/c2372060-6ecb-4d0c-94e1-20964cd5e91d.jpeg)

<dl>
  <dt>X軸</dt>
  <dd>横軸の項目を選択します</dd>
  <dt>シリーズ</dt>
  <dd>データの種類を選択します</dd>
  <dt>計量</dt>
  <dd>グラフ化する数値を選択します</dd>
</dl>

例：クラス別月別売上推移
![rapture_20250304235725.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/20e7f19b-e94c-41c7-9266-aa81abbef29a.jpeg)

## おまけ：グラフをダッシュボードに表示する
作成したグラフをダッシュボードに表示することも可能です。

ダッシュボードのパーソナライズから分析を選択します。
![rapture_20250305000010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/0ee98716-7550-429f-a203-dce87a36f694.jpeg)

表示したいグラフを選択します。
![rapture_20250305000209.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/196ffc68-ed27-4d95-b171-0fdb6896ad93.jpeg)

ダッシュボードに作成したグラフが表示されます。
![rapture_20250305000952.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/8d52d0cb-ce31-4764-a76f-8c7d60d1991a.jpeg)

## さいごに
SuiteAnalytics Workbookの紹介は一旦最後となります。
データセットさえ作ってしまえば、ワークブックはExcelと似た操作で可能です。
NetSuiteのデータをリアルタイムに分析したい場合など、ぜひお試しください。

次回からは新シリーズを投稿予定です。
inout永久機関を発明した話．

# はじめに

こんにちは．専門学生 T.Miuraです．先日，めでたいことに誕生日を迎え24歳になりました．訳ありです．

# 本記事の対象者

- やりたいことが他にあって技術書を読む時間がない方
- 読む本を迷走している初学者の方
- 学習スタイル (Udemy or 技術書) が選べない方

# 私の前提条件

1. Webアプリケーション開発に関わるもの (React, Go) をUdemyで学習していた
2. FWや言語の知識だけではなくWebの仕組みや設計も学びたい

私は正直焦っています．24歳から新卒でIT業界へ入る．ストレートで新卒となった人からみたら2年遅れている．そんな環境が私を焦らせています．

さらに，サービスを作り誰かしらの何かしらの課題を解決したい夢も叶えなくてはなりません．効果的にinとoutのバランスをとり，常に走り続けなければいけない．そんな焦りからin/out putのバランスが最適で，一生学び続けれる永久機関を完成させてしまいました．本日はそちらの学習永久機関を発表いたします．

# 実際にどうやって読んでいたのか

## ポモドーロタイマーのお話

ポモドーロタイマーはご存知でしょうか？有名ですよね。25分学習,5分休憩を繰り返す学習方法です．これを活用しています．

そして，私はそもそも学習と休憩の定義から見直しました．

**学習とは**

```
主に学びたいもの
```

**休憩とは**

```
それ以外
```

だと定義しました．休憩では立ってストレッチしてもぼーっとしても迷走してもYoutube見ても良いわけです(Youtube)
<br>
**うーーーーん？別の勉強しても良くね・・・？**
<br>

25分UdemyでGo,Reactを学び，5分技術書を読む

こ，これは・・・
![永久機関が完成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3865460/8e5f7336-d318-4e14-a9e8-9f688587a86b.png)

**天才的です．**

疲れると思うでしょう？学習から少しでも外れたことをすると意外と疲れないものですよ．シンプルに面白いですし．

# 効果的に読んだ方法

## 何を読むかの難しさ

闇雲に読めば良いわけではありません．それは全員わかっているはずです．しかし，初学者というのはそんな基本的なことすらも迷ってしまう生き物です．優しくしてあげてください．

自分が行きたい分野，興味があるもの，業務で使うもの，わからないもの，極めたいもの

様々な技術書から選ぶのはこんなん困難です．

## 読む本の選び方

私が技術書を選ぶとき，Udemyに出てきた言葉や実際にアウトプットするときにちょっとでも気になったことが書いてある技術書を選びます．

例えばReactを学んでいるときはWeb基礎について，ブラウザの仕組みやHTTP等の基礎の本を読んでいました．

例えばGoを学んでいるときは，API(REST,graphQL)やアーキテクチャについての技術書を読んでいました．

学んでいることの一歩先にあるものを常に読んでいます．これが私の選び方です．

## 読み方の話

5分読むを何度繰り返していてもしっかり理解することはできないのではないか？

そうですね．完全には理解できません．ただ，有名な話では最初は60％程度でいいそうです．

一旦頭に入れて次の in/out putのバランスでも書いてあることを実践すれば不足なく学習できます．

あとは寝る前等にじっくり読めば忘却曲線に喧嘩も売れるし，活字で眠くなるし一石二鳥です．

## in/out put のバランスについて

技術書はインプットに偏りがちになってしまいませんか？

私はなってしまいます．WebAPIの話でも，技術書のコードを読むだけになってしまいます．それではもったいないですよね？

それを解決するのが「一歩先にある」本を選ぶことです．

例えばバックエンドでAPIをUdemyで学んでいるときに，RESTの本を読み進めているとします．

ここのAPI設計はRESTのここに基づいているのかな？等の直前にしたinputを活用できます．

ただ文字を眺めるのではなく，自分の頭で考えるだけでも立派なoutputです．

# 技術書もUdemyも高くない？

## Udemyにも技術書にも共通して言えること

~~バカ野郎！！　先人が叡智を込めたものが数千円で買えるんだぞ！！甘んじて受け入れろ！！~~

そうですね．どちらもバカにならないです．Udemyなんかはセール時の値段が基準ですが，たくさん買うと高いですね．

ただ，その講師の人を雇うと考えれば安いです．

技術書も正直高いです3~5000円は当たり前ですね．
<br>

ただ，これも効果的な選び方があります．

FWや言語を中心としているものは選ばないようにしています．流行り廃りがありますからね．

<br>

しかし，HTTPやWebの仕組み，API設計やアーキテクチャは流行り廃りがあまりないと感じています．

変化の早いIT業界の中でも比較的緩い本は数年前の本だとしても最前線で活躍してくれます．

そう言った本を中古で買うと半額以下まで抑えれます．(中古が気にならなければですが)

# まとめ

- ポモドーロタイマーを活用した学習永久機関
- Udemyを軸に技術書を選ぶ
- 変化の少ない，土台となる知識の技術書を中古で買う

<br>

以上を行っていけば効率的に一人前に近づいていくのではないでしょうか？

私はまだ実務経験もなく，知識も浅いですがここ最近自分に合った学習スタイルを共有したいだけの記事でした．

ちなみに，これを続けていくと体か脳が爆発するかもしれませんが一切の責任を負いませんよ．

私がOutputしなくなったら爆発したと思ってください．

<br>

ありがとうございました．
【Ontap】Ontapからping応答を確認する

Ontap（Netappファイルストレージ）から、他の聞きにpingを実行する。

```
cluster::>network ping -node ping送信元ノード -destination ping送信先IPアドレス
```

上記コマンドにあるオプションは必須のオプション。

その他のオプションなど、詳細は下記ナレッジ参照。
https://docs.netapp.com/us-en/ontap-cli/network-ping.html
有理数・複素数ってそもそも何だっけ？

## はじめに
数学的な話にはなりますが、Rubyで出てくる Rationalクラス・Complexクラスで有理数と複素数ってそもそも何だっけとなったので、自分用としてここにメモしておきます。

* Rationalクラス：有理数を扱うNumericクラスのサブクラス
* Complexクラス：複素数を扱うNumericクラスのサブクラス

どちらもRuby 1.9から組み込みクラスとなっています。

## 目次
1. [有理数と複素数とは？🤔](#有理数と複素数とは)
2. [有理数と複素数の違い](#有理数と複素数の違い)
5. [まとめ📝](#まとめ)

## 有理数と複素数とは？🤔
数学では、数の種類 を分類できます。
その中で、有理数 と 複素数 は異なる特徴を持つ数とされている。

🔢 有理数（Rational Number）とは？
「分数で表せる数」 のこと！
つまり、a/bで表現できる数w指します。

🔢 複素数（Complex Number）とは？
「実数に虚数を加えた数」 のこと！
つまり、**a+bi の形で表せる数を指します。（i は虚数単位）

## 有理数と複素数の違い
| 項目 | 有理数 | 複素数 |
|:-----------|:------------|:------------|
|定義|分数で表せる数|実数と虚数の和で表せる数|
|虚数部分|なし|ある（または0）|
|数直線上の位置|数直線上にある|数直線だけでは表せない（複素平面で表す）|

## まとめ📝
✅ 有理数 = 分数で表せる数（実数の一部）
✅ 複素数 = 実数と虚数の和で表せる数（有理数も含む）
✅ 虚数単位 i(数直線だけでは表せない)

有理数は実数の一部、複素数はさらに広い世界！ 🎭
⭐個人的 Git 開発フロー

---

### 【初回セットアップ (一度だけ)】

1. GitHub からリポジトリをクローン
   ```sh
   git clone https://github.com/kmatsumoto630823/zBot.git
   ```
2. ディレクトリに移動
   ```sh
   cd zBot
   ```
3. develop ブランチを作成
   ```sh
   git checkout -b develop
   ```
4. GitHub に develop をアップロード
   ```sh
   git push origin develop
   ```

---

### 【`main` を最新にして `develop` に反映（共同開発の場合はNG）】

1. main を最新にする
   ```sh
   git checkout main
   git pull origin main
   ```
2. develop を main の状態に完全一致させる
   ```sh
   git checkout develop
   git reset --hard main
   git push origin develop --force
   ```

---

### 【開発開始 (作業のたびに)】

1. develop を最新にする
   ```sh
   git checkout develop
   git pull origin develop
   ```
2. 変更を加える（いずれか）
   - 🖊 **コードを編集**
     ```sh
     code .
     ```
   - 🔄 **パッケージを更新（必要な場合）**
     ```sh
     npm update
     ```
3. 変更をGitに記録
   ```sh
   git status
   git add .
   git commit -m "変更内容の説明"
   ```
4. GitHub にアップロード
   ```sh
   git push origin develop
   ```

---

### 【`main` に反映 (動作確認後)】

1. develop を最新にする
   ```sh
   git checkout develop
   git pull origin develop
   ```
2. main に移動してマージ
   ```sh
   git checkout main
   git merge develop
   git push origin main
   ```

---

### 【まとめ】

| ステップ                                       | やること                          | コマンド                                                                                                                    |
| ------------------------------------------ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **初回セットアップ**                               | GitHub からリポジトリを取得             | `git clone` → `git checkout -b develop`                                                                                 |
| **`main`**\*\* を ****`develop`**** に反映\*\* | `main` を最新にして `develop` をリセット | `git checkout main` → `git pull` → `git checkout develop` → `git reset --hard main` → `git push origin develop --force` |
| **開発開始**                                   | `develop` を最新にして編集            | `git checkout develop` → `git pull`                                                                                     |
| **変更を加える**                                 | コード編集 または パッケージ更新             | `code .` または `npm update`                                                                                               |
| **変更を記録**                                  | Git に記録 & コミット                | `git add .` → `git commit -m "変更内容"`                                                                                    |
| **GitHub にアップ**                            | `develop` にプッシュ               | `git push origin develop`                                                                                               |
| **`main`**\*\* に反映\*\*                     | `develop` を `main` にマージ       | `git checkout main` → `git merge develop` → `git push origin main`                                                      |

💡 **基本は「develop で開発」→ 「GitHub に push」→ 「問題なければ main にマージ」の流れでOK。**
💥 **`git pull`**\*\* の前に「変更を commit or stash」すると安全！\*\*
【Mac】コマンドでPNGを圧縮する方法

optipngを使用するとJPEGを圧縮できます。

## インストール

以下のコマンドでインストールできます。

```terminal
brew install optipng
```

## 使い方

デフォルト設定でPNGを圧縮する。

```terminal
optipng path/to/file.png
```

PNGを最適な圧縮率で圧縮する。
```terminal
optipng -o7 path/to/file.png
```

PNGを最速で圧縮する。
```terminal
optipng -o0 path/to/file.png
```

PNGを圧縮してインターレースを追加する。

```terminal
optipng -i 1 path/to/file.png
```

PNGを圧縮し、すべてのメタデータ（ファイルのタイムスタンプを含む）を保存する。
```terminal
optipng -preserve path/to/file.png
```

PNGを圧縮し、すべてのメタデータを削除する。

```terminal
optipng -strip all path/to/file.png
```
印刷時CSS

印刷時スタイルにはブラウザと違うCSSの適用が必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/061fc7fa-9fd9-4067-9042-7efd055f1759.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/3ee8b273-343f-4fc7-af38-24879eb1daec.png)

@media print{}で記載する。
```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>印刷時CSS適用</title>
    <style>
/* 印刷用 (プリント表示) */
@media print {
  body {
    font-family: "MS Gothic", "ＭＳ ゴシック", "MS Mincho", "ＭＳ 明朝", sans-serif;
    font-size: 30pt; /* 印刷時に適切なフォントサイズ */
    color: #e33535; /* 印刷時は黒色に統一 */
    background-color: white; /* 背景色を白に統一 */
  }


  /* 印刷時の余白設定 */
  @page {
    margin: 10mm; /* 余白をIEと統一 */
  }

  /* 背景色を印刷する設定（ブラウザによっては手動設定が必要） */
  * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}


    </style>
</head>
<body>
あああああああああああああああああああああああああああああ

<h2>印刷時</h2>
<button onclick="window.print()">印刷</button>

<table>
    <thead>
        <tr>
            <th>ヘッダー1</th>
            <th>ヘッダー2</th>
            <th>ヘッダー3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>データ1</td>
            <td>データ2</td>
            <td>データ3</td>
        </tr>
        <tr>
            <td>データ4</td>
            <td>データ5</td>
            <td>データ6</td>
        </tr>
    </tbody>
</table>

</body>
</html>


```

https://zenn.dev/azukiazusa/articles/d8459f81d52d59

https://webtan.impress.co.jp/e/2015/07/28/20508