OmniAICreator/Qiita-1.07M huggingface dataset:
Cloud RunになったCloud Functionsで第一世代を使い続けたいときにやること

# 概要
- 久々にCloud Functionを利用するプロダクトを起動したら動かなかったので修正した
- `firebase-functions` をアップデートしたのが事の始まり


# `firebase-functions` をアップデートしたらどうなったのか

`4.6.0` → `6.0.1` にアップデートしたところ軒並み怒られました

```
firebase-1     | TypeError: functions.runWith is not a function
firebase-1     | TypeError: functions.region is not a function
...
```


https://github.com/firebase/firebase-functions/issues/1616

アップデートしたことで、デフォルトがv2になったため、v1の書き方だと駄目ですよ。ってことですね。理解


# 修正

マイグレーションする必要はありますが、一旦その場しのぎしたい場合は、v1を明示的にインポートすればおｋです


```diff:typescript
- import * as functions from 'firebase-functions'
+ import * as functions from 'firebase-functions/v1'
```

そしたらエラーは無くなりましたー。よかったー（駄目）


# 雑感

さっさとマイグレーションしよう（やばい）
ReactNativeCalendarsのknobをカレンダー外に置きたい!!

## はじめに
今回はReactNativeCalendarsについて解説します。
既存のknobでカレンダーを表示させるのもいいけど既存のスペース以外の場所からknobを開きたいという方に読んでいただけると幸いです！

なぜ今回カレンダーの開くボタンを下に置くのか？
→react-native-calendarsのknobが、日付の下にknobが来るようになっている。その状態だとカレンダーを開いた時にknobがそのまま下に下がってきてしまいiphoneのホームに戻る所とknobの位置が近くなりknobをあげる時にイライラするから
（タップでもknobは上がるけどUI上スワイプする形に見えたりする）

## 今回行いたいこと
画面上部に表示されているknob①の状態から②の状態にする。
- knobをカレンダーボタンにする

題名とは違うけど
- カレンダーを開いた時にknobを非表示にする

①<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844185/3f436603-9a26-51a2-2f08-815abac1803c.png" width=30%>　②<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3844185/d18bc3b6-80a8-e031-43eb-3df3fd17fb63.png" width=30% >

## 行ったこと
- useRef フックを使用してカレンダーコンポーネントを制御
- Ionicons を使ってカレンダーアイコンを表示
- TouchableOpacity でタップ操作を実装
- Agenda コンポーネントでカレンダー表示を管理
``` calendar.tsx
const Component:React.FC= () => {
    const agendaRef = useRef(null);
    
    const calendarButtun= () => (
            <TouchableOpacity
              style={styles.calendar}
              onPress={() => {
                if (agendaRef.current) {
                  agendaRef.current.toggleCalendarPosition(true);
                }
              }}
            >
              <Ionicons name="calendar-sharp" size={size} style={styles.calendarIcon} />
            </TouchableOpacity>
        );

    return(
     <SafeAreaView>
      <Agenda
        ref={agendaRef}
        hideKnob
        renderEmptyData={() => calendarButtun()}
        />
    </SafeAreaView>
    )
};
```
## 題名とは違う内容だけど
カレンダー開いた時にknobを消す方法でもユーザがボタンに迷わなく無くなっていいのかなと思った。

実装内容：useStateでknobが押されたかの状態を管理してその値をhideknobに追加している
``` calendar.tsx
const Component: React.FC = () => {
    const [isCalendarToggled, setCalendarToggled] = useState<boolean>(false);

    const onCalendarToggled = () => {
        setCalendarToggled((prev) => !prev);
    };

 return (
    <SafeAreaView>
      <Agenda
      hideKnob={isCalendarToggled}
      renderKnob={() => {
          if (isCalendarToggled) return null;

          return <View style={styles.calendarButton} />;
        }}
      onCalendarToggled={onCalendarToggled}
      />
    </SafeAreaView>
  );
};
```

## さいごに
ご覧いただきありがとうございます！

まだまだQiitaに書き始めたばかりなのでどういった内容が伝わりやすいかわかっていないので自分の知識を深めるためにも、これから伝わりやすく書けるよう頑張っていきたいと思います！

書き方のアドバイスや内容が間違っていたら教えてください！！
ありがとうございました~
vbsの作法 その94

# 概要
vbsの作法、調べてみた。
練習問題やってみた。

# 練習問題
位置情報CSVをIE11で表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7021f1a6-b9ad-ba58-c8ca-3d505e763abd.png)


# サンプルコード

```

Class ohicompo2
	Private objIE
	Private Sub Class_Initialize
		Set objIE = CreateObject("InternetExplorer.Application")
		objIE.Visible = true
		objIE.Top = 100
		objIE.Left = 100
		objIE.Width = 500
		objIE.Height = 600
		objIE.Navigate("about:blank")
		objIE.StatusBar = False
		objIE.ToolBar = 0
		objIE.Document.Write "<html><head><title>ohicompo2</title>"
		objIE.Document.Write "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.min.css' />"
		objIE.Document.Write "<script src='https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.js'></script></head><body>"
		objIE.Document.Write "<div id='map' style='width:100%; height:70vh'></div>"
		objIE.Document.Write "<input id='btn' type='submit' value='run' onclick='run()'><br>"
		objIE.Document.Write "<textarea id='src'rows='4' cols='30'></textarea>"
		objIE.Document.Write "<script type='text/javascript'>"
		objIE.Document.Write "var map = L.map('map').setView([38.0748331, 139.4574997], 9);"
		objIE.Document.Write "L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {"
		objIE.Document.Write "    attribution: '&copy; <a href=""http://osm.org/copyright"">OpenStreetMap</a> contributors'"
		objIE.Document.Write "}).addTo(map);"
		objIE.Document.Write "function run() {var line = src.value.split('\n');for (var i = 0; i < line.length; i++){"
		objIE.Document.Write "var item = line[i].split(',');var marker = new L.Marker([item[1], item[2]], {"
		objIE.Document.Write "title: item[0]}); marker.addTo(map);};}"
		objIE.Document.Write "</script></body></html>"
	End Sub
	Private Sub Class_Terminate
	End Sub
	Public Sub text(str)
		objIE.Document.getElementById("src").InnerText = str
	End Sub
	Public Sub run()
		objIE.Document.getElementById("btn").Click()
	End Sub
	Public Sub owari()
		objIE.Quit
	End Sub
End Class

Dim str
str = ""
str = str + "P1, 38.077908, 139.542229" + vbcrlf
str = str + "P2, 38.075618, 139.642032" + vbcrlf
str = str + "P3, 38.0738618, 139.441726" + vbcrlf
Dim w1
Set w1 = new ohicompo2
WScript.Sleep 1000
w1.text str
w1.run







```

以上
Ubuntu マシンを 簡単にルーター化

例えば WiFi と 有線が使える PC があってどちらかでインターネットに接続できている。インターネット接続を他の PC に共有したい。すなわちインターネットコンバーターとしてのルーター機能を PC で設定したい。

Ubuntu Linux では以前は dnsmasq とか dhcpd とか iptables とかいろいろ設定しないとルーターにならなかったけれども、今は簡単?


# 環境

IPアドレスの共有元：Ubuntu 22.04 LTS
ネットワークの提供先：Windows10 Pro

# 方法1

「設定」-「ネットワーク」から、共有に使う有線ネットワークを選び、「他のコンピュータと共有」とします。

2 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/218e7ad0-1d30-a93f-1226-3c6793932870.png)

iPv4 および iPv6 を同様にしました。




# 方法2
`nm-connection-editor` を dash またはターミナルから起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/31e3f15f-6926-e807-3822-3a70bf346826.png)






![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/980bd2cf-7e54-0a40-fb7a-95db4498b69d.png)

# 2つの方法の違い

同じ動作をする気がするのだけれども、インターフェースの表示がなんか違っていてよくわからない。

そもそも 「有線接続1」と 「enp37s0」が何故2つあるんだ???

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/20187399-b08d-b3d1-6a29-1c5c1e3e37aa.png)

# 結果

```
$ ip address
```

として様子を確認すると、

```
2: enp37s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 88:d7:f6:78:e4:28 brd ff:ff:ff:ff:ff:ff
    inet6 fd75:3252:442c:18::1/64 scope global deprecated noprefixroute 
       valid_lft forever preferred_lft 0sec
3: wlx4ce67641a85a: <BROADCAST,MULTICAST,UP,LO
```


再起動が必要かな? と思いましたがしばらくすると

```
2: enp37s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 88:d7:f6:78:e4:28 brd ff:ff:ff:ff:ff:ff
    inet 169.254.152.79/16 brd 169.254.255.255 scope link noprefixroute enp37s0
       valid_lft forever preferred_lft forever
    inet6 2406:2d40:30ca:7218::1/64 scope global dynamic noprefixroute 
       valid_lft 239sec preferred_lft 89sec
    inet6 fe80::2e07:45e4:78d4:37a5/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

```
これを経由して
```

2: enp37s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 88:d7:f6:78:e4:28 brd ff:ff:ff:ff:ff:ff
    inet 10.42.0.1/24 brd 10.42.0.255 scope global noprefixroute enp37s0
       valid_lft forever preferred_lft forever
    inet6 2406:2d40:30ca:7218::1/64 scope global dynamic noprefixroute 
       valid_lft 287sec preferred_lft 137sec
    inet6 fe80::2e07:45e4:78d4:37a5/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
```
IPアドレスが割り当てられました。


# 共有

今回は WiFi でインターネットにつながっていたので、有線で接続した MS-Windows でインターネットが使えるようになるかどうか試してみました。

記録が取れていませんが、IP とか割当られてうまくインターネット接続ができるようになりました。

しかしながらいろいろ試した中では iPv6 アドレスが割り当てられて、iPv6 で到達できる Webサイトにはアクセスできるものの、 iPv4 アドレスを持つ Web サイトには接続できなかったりすることがありました。

今後機会があれば改めて調べてみます。
スタックあふれとその対策


## 復習：スタックとは何か(1/2)
- 関数を呼び出すと確保されるメモリ領域
- 関数から関数を呼び出すと確保したメモリ領域（＝枠／フレーム）が積み上がっていく（＝スタック）

----
## 複数：スタックとは何か(2/2)
- スタックの中には以下のようなものが含まれます
  - 呼び出し元スタックの位置情報
  - スタック内の変数の領域

----
## ポイント
- スタックが積み上がると**その分メモリを消費する！**
- これがかの有名はStack Overflow！（スタックあふれ）

----
## スタックあふれが起きる状況
- 関数の呼び出し階層がめちゃくちゃ深くなったら起きる
- 起こる状況は限られている
  現実にスタックあふれが起きるのは、ほぼ再帰呼び出しが原因

----
## 再帰呼び出しとは
- ある関数から自分自身を呼び出す
- 例えばツリー構造の走査など、コレクション操作で起こりやすい

----
## 無限ループとの違いは？
- 無限ループはスタックあふれすら起こらない状況
- 同じスタックの中でループ止まらないループ処理を書いてしまったときに起きる
- スタックあふれより深刻なバグ
  ただ、狙って実装することもある（イベントループやゲームループなど）
  もちろん、ループから脱出する手段が提供される

----
## 再帰呼び出しによるスタックあふれ対策
- 原則・**関数呼び出しを恐れる必要はない！**
- 「末尾再起」

----
## 末尾再起とは
- 関数の最後に再帰呼び出しを行うこと
- こうすると再帰呼び出しをループに変換する最適化が行われる！！

----
## 最後に
- Stack Overflowはこちらです
  https://ja.stackoverflow.com/
家庭用プリンタを選んだ時に考えたことなど

1年ちょい前に、家庭用プリンタを購入した。その時のことと、その後のことを書く。
購入したのは某大手2社ではないメーカーのもの。メーカー名は特に書かないけど、調べたら分かるかも

# 経緯
元々大手（2社どちらか明示しない）の複合機を使っていた。4色インクのうち一つが足りなくて印刷ができない仕様であり、それも不満だったが、ある時に一つのインクが認識できなくなったことで起動が完了せず、スキャナも使えなくなってしまった。
インクの問題でスキャナも使えないというのは、あんまりだと思った。

# 購入の際重視したこと
買い直すしかなかったので探したところ、インクが黒とカラーとの二種類で、片方が切れても印刷できるタイプのものがあり、それを条件にした。いくつかあるうちの一番安いものにした。
スキャナとインクの関係は分かってないので前述の問題が解決したわけではないのだが、インクについては将来的に揃え続けなくても使い続ける選択肢があるので、その点は満足している。

# その後
買ったあとしばらくして使わない期間があり、久々に動かしたら正常に印刷できなくなってしまった。
保証期間内だったので修理覚悟でサポートに問い合わせたところ、インクの使用期限じゃないかということだった。確かにインクを買い変えると正常に戻った。

それまでは、インクに期限があるとは考えたことがなかった。調べたところ、開封後の期限はどこも半年のようだが、未開封の場合の目安にはバラ付きがあり、大手2社の方が断然長いようである。
使い方としては印刷が定期的にあるわけではないので、正直このペースで交換が必要では廃棄が多くなりそうに感じる。あとは（これは理解の上ではあったが）カラーインクが3色一体型なので、印刷の色に偏りがあると当然無駄な出費が発生する。

今回、本体値段の安さで最終的な選択をしたが、インク切れ期限がプリンタ耐用年数に比べて短そうであれば、インクも勘案して値段を比較する方がいい（大変だけど）
チームで利用する開発用Wikiのテンプレートを作成してみた

## 経緯

チームに新しいメンバーが増え、運用作業や障害が起こったときの対応を誰でもできるようにしたいね、という話になり、チームで利用するRedmineのWikiテンプレートを作成することになりました。

## 作成方法
ChatGPTに大まかなテンプレートを出力してもらい、自チームの開発用Wikiとして必要なものとそうでないものを考え、項目の追加・削除を行いました。

## 作成したテンプレート

```
## プロジェクト概要

### プロジェクトの目的
本プロジェクトの目的、プロダクトゴールを記載します。

### システム概要
本システムの簡単な概要を説明します。

## 使用技術

### プログラミング言語
使用しているプログラミング言語と、バージョンを記載します
* 例: Python、Java、Ruby など

### フレームワーク・ライブラリ
使用しているフレームワークとライブラリ、そのバージョンを記載します。
* フロントエンド：例: React、Vue.js、Angular
* バックエンド：例: Node.js、Django、Spring

### 開発ツール
使用している開発ツールと、バージョンを記載します。
* バージョン管理：例: Git, Github, Gitlab
* ビルドツール：例: Webpack、Gulp
* テストツール：例: Jest、Mocha
* CI/CDツール：例: Jenkins、GitHub Actions

### その他の技術
その他に使用している技術を記載します。
* データベース：例: MySQL、PostgreSQL、MongoDB
* クラウドサービス：例: AWS、Azure、Google Cloud
* APIサービス：例: Google Maps API、Stripe

## 環境情報

### 環境URL・認証情報・鍵情報
各環境のURLと認証情報、鍵の情報を記載します。

### AWSアカウント情報
AWSアカウント情報を記載します。
他のクラウドサービスを使う場合は、その情報を記載します。

## セットアップガイド

### 必要なソフトウェアやツール
* 必要なツール1
* 必要なツール2

### 開発環境の構築手順
開発環境の構築手順を記述します

### 環境変数の設定方法
環境変数の設定方法と例を記載します。

### データベースの設定（必要な場合）
データベースの設定方法を記載します。

## システム仕様

### システム仕様書
システム仕様書を記載します。

### 環境構成図
アーキテクチャ構成図を記載します。

### 設計のポイントやアプローチ
主要な設計決定とその理由を示します。

## 画面仕様

### 画面仕様書
画面仕様書を記載します。

### 画面遷移図
各画面間の遷移関係を示します。

### 各画面要素の説明
各UIコンポーネントの詳細を記述します。

## データベース設計

### データベース設計書
データベース設計書を示します。

### ER図（エンティティ・リレーションシップ図）
エンティティとそのリレーションシップを示します。

### 各テーブルとカラム、インデックスやキーの詳細
各テーブルとそのカラムの詳細を記述します。
アプリケーションコードのリンクでも可（schemaなど）

## コード規約

### 命名規則
* 変数名：キャメルケース（例： myVariable）
* 関数名：キャメルケース（例： myFunction）
* クラス名：パスカルケース（例： MyClass）

### インデントやスペーシング
インデントのスタイルやスペーシングのルールを記述します。

### コメントのスタイル
コメントの規則を記載します。

### 使用するリンターやフォーマッター
使用するツールを記載します。

## GitLabルール

### ブランチ戦略
ブランチ戦略を記載します。
* 例
    * production：プロダクション用。
    * main：次のリリースに向けたベースライン。開発環境用。
    * フィーチャーブランチ： feature/Redmineチケット番号 形式（例： feature/000000）。

### コードレビューとプルリクエストのプロセス
コードレビューのプロセスを記載します。

### CI/CDの設定と運用
CI/CDの設定方法と運用ガイドを記します。

## テスト

### テスト環境のセットアップ方法
テスト環境の構築手順を示します。

### テストケースの作成と実行
テストの作成方法と実行手順を記載します。

### 自動テスト
自動テストの設定および実行方法を記載します。

* テストフレームワーク
* 継続的インテグレーション（CI）との統合

## 開発ガイドライン

### 新機能追加の手順
新機能追加の手順を説明します。

### バグ修正の手順
バグ修正の手順を説明します。

### パフォーマンスチューニングの手順
パフォーマンスを向上させる改修の手順を説明します。

## 運用フロー

### 保守・運用作業の手順
運用作業の手順を説明します。

## リリース

### リリースの前に確認すべき事項
リリース前に確認すべき事項を示します。

### 本番環境へのリリース手順
リリース手順を記載します。

### ロールバック手順
ロールバック手順を記載します。

## リリースノート

### リリースノートの更新方法
リリースノートの更新手順を説明します。

## APIドキュメント

### API仕様書
API仕様書を記載します。

## 外部ツール

### 使用している外部ツール
外部ツールのリストを記載します。

### 外部ツールの更新方法
依存関係の更新方法を記載します。

## 障害対応

### 障害の種類と優先度別の対応方法
障害の種類とその優先度別対応方法を記載します。

### 対応手順
対応の手順を示します。

## 請求管理

### 見積もり書
見積もり書を記載します。

### プロジェクト関連のコストや請求先
主要なコスト項目と請求先を記載します。

### コスト監視および報告
コストの監視方法と報告のフォーマットを記載します。

## プロジェクトメンバー

### 主要メンバー
主要メンバーの役割と、社内外かを記載します。

### コミュニケーションツール
使用するコミュニケーションツールを記載します。

### 緊急連絡先
必要があれば、緊急連絡先も記載します。

## プロジェクト管理

### タスク管理ツールやその使用方法
タスク管理ツールとその使用方法を説明します。

### 開発スケジュールと進捗管理
開発スケジュールと進捗管理の方法を記載します。

## マニュアル

### 更新手順
マニュアルの更新手順を説明します。

### 保管場所
マニュアルの保管場所を記載します。
```

# 実際に運用してみての所感
後ほど追記します！

# 最後に
このテンプレートを他の開発チームでそのまま使うのは難しいかもしれませんが、参考程度になれると幸いです
Linux Server環境にAnaonda3のインストール手順

# Linux環境でのAnaconda3のインストール手順

LinuxマシンにAnaconda3をインストールする手順を詳しく解説します。

## 手順 1: Anaconda3の最新バージョンのダウンロード

公式のAnacondaアーカイブサイトから、適切なバージョンをダウンロードします。

ARM (aarch64) アーキテクチャの場合：

```bash
curl -O https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-aarch64.sh
```

x86_64 アーキテクチャの場合：

```bash
curl -O https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh
```

**注**: 必要に応じて、Anacondaのアーカイブページで最新バージョンを確認してください。

## 手順 2: インストーラの実行

ダウンロードしたインストーラを実行してAnacondaをインストールします。

ARM (aarch64) の場合：

```bash
bash Anaconda3-2024.06-1-Linux-aarch64.sh
```

x86_64 の場合：

```bash
bash Anaconda3-2023.09-0-Linux-x86_64.sh
```

インストール中にライセンス条項が表示されるため、`yes`を入力して同意します。インストール先はデフォルトで問題ありませんが、別のディレクトリに変更することもできます。

## 手順 3: 環境変数の追加

Anacondaのインストール後、`PATH`環境変数にAnacondaのバイナリディレクトリを追加する必要があります。次の手順でシェルの設定ファイルを編集し、環境変数を追加します。

1. **シェル設定ファイルの編集**
   使用しているシェルに応じて、`.bashrc`または`.zshrc`を開きます。

   ```bash
   nano ~/.bashrc # bashを使用している場合
   ```

   または

   ```bash
   nano ~/.zshrc # zshを使用している場合
   ```

2. **環境変数の追加**
   ファイルの末尾に以下の行を追加します：

   ```bash
   export PATH="$HOME/anaconda3/bin:$PATH"
   ```

   **注**: `$HOME/anaconda3`がAnacondaのインストールディレクトリです。異なるディレクトリにインストールした場合、そのパスを指定してください。

3. **ファイルの保存**
   `Ctrl + O`でファイルを保存し、`Ctrl + X`でエディタを終了します。

## 手順 4: シェルプロファイルの再読み込み

設定を反映するために、シェルプロファイルを再読み込みします。

```bash
source ~/.bashrc # または zshを使用している場合は source ~/.zshrc
```

## 手順 5: Condaのバージョン確認

インストールが正常に完了したかを確認するために、以下のコマンドでCondaのバージョンを確認します。

```bash
conda --version
```

## 手順 6: Condaの自動起動を無効化（オプション）

デフォルトでは、Condaのベース環境がターミナル起動時に自動的にアクティブ化されます。これを無効化したい場合は、以下のコマンドを実行します。

```bash
conda config --set auto_activate_base false
```

これにより、ターミナルを起動するたびにCondaが自動的にアクティブ化されるのを防ぎ、必要なときに手動で`conda activate`を使用できます。

## 手順 7: 環境の確認と作成

Anacondaのインストールが正しく動作しているか確認し、新しいPython環境を作成します。

```bash
conda create -n myenv python=3.9
conda activate myenv
```

これで新しい環境が作成され、必要に応じてパッケージをインストールして使用できます。

以上で、Linux環境へのAnaconda3のインストールは完了です。お疑問や問題がありましたら、コメントでお知らせください。
KotlinでUnion-Find木を実装

# KotlinでUnion-Findを実装

AtCoderにてKotlinで実装をしているのですが、KotlinにはUnion-Find木が存在しないので自前で実装します。

```kotlin
class UnionFind(n: Int) {
    val par = Array(n){it}
    val rank = Array(n){0}

    fun find(x: Int): Int {
        if (par[x] == x) {
            return x
        } else {
            par[x] = find(par[x])
            return par[x]
        }
    }

    fun unite(x: Int, y: Int) {
        val px = find(x)
        val py = find(y)
        if (px == py) return
        if (rank[px] < rank[py]) {
            par[px] = py
        } else {
            par[py] = px
            if (rank[px] == rank[py]) {
                rank[px] ++
            }
        }
    }

    fun same(x: Int, y: Int): Boolean {
        return find(x) == find(y)
    }

}
```

参考: [蟻本](https://book.mynavi.jp/ec/products/detail/id=22672)
シェルスクリプトの文字列に色をつけよう

# はじめに
シェルスクリプトで一連の処理を書く際に、色をつけると成功の可否がわかりやすくなったりします。

例：
![スクリーンショット 2024-10-17 22.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682035/96d022f5-5150-e5bb-c982-167d36ec6446.png)

# 文字列の色を変える

![スクリーンショット 2024-10-17 18.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682035/f922cdad-2bc7-7113-d08b-17486bccfb76.png)

```sh:color.sh
#!/bin/sh

cd "$(dirname "$0")"

# 黒
echo -e "\e[30m黒\e[0m"

# 赤
echo -e "\e[31m赤\e[0m"

# 緑
echo -e "\e[32m緑\e[0m"

# 黄色
echo -e "\e[33m黄色\e[0m"

# 青
echo -e "\e[34m青\e[0m"

# マゼンタ（紫）
echo -e "\e[35mマゼンタ（紫）\e[0m"

# シアン（水色）
echo -e "\e[36mシアン（水色）\e[0m"

# 白
echo -e "\e[37m白\e[0m"

# 明るい黒（グレー）
echo -e "\e[90m明るい黒（グレー）\e[0m"

# 明るい赤
echo -e "\e[91m明るい赤\e[0m"

# 明るい緑
echo -e "\e[92m明るい緑\e[0m"

# 明るい黄色
echo -e "\e[93m明るい黄色\e[0m"

# 明るい青
echo -e "\e[94m明るい青\e[0m"

# 明るいマゼンタ（明るい紫）
echo -e "\e[95m明るいマゼンタ（明るい紫）\e[0m"

# 明るいシアン（明るい水色）
echo -e "\e[96m明るいシアン（明るい水色）\e[0m"

# 明るい白
echo -e "\e[97m明るい白\e[0m"

exit 0
```

# 文字列の背景色を変える

![スクリーンショット 2024-10-17 18.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682035/d9b3a49b-42be-3264-6569-e41d56a4fde5.png)

```sh:color.sh
#!/bin/sh

cd "$(dirname "$0")"

# 黒い背景
echo -e "\e[40m黒い背景\e[0m"

# 赤い背景
echo -e "\e[41m赤い背景\e[0m"

# 緑の背景
echo -e "\e[42m緑の背景\e[0m"

# 黄色い背景
echo -e "\e[43m黄色い背景\e[0m"

# 青い背景
echo -e "\e[44m青い背景\e[0m"

# マゼンタ（紫）の背景
echo -e "\e[45mマゼンタ（紫）の背景\e[0m"

# シアン（水色）の背景
echo -e "\e[46mシアン（水色）の背景\e[0m"

# 白い背景
echo -e "\e[47m白い背景\e[0m"

# 明るい黒（グレー）の背景
echo -e "\e[100m明るい黒（グレー）の背景\e[0m"

# 明るい赤の背景
echo -e "\e[101m明るい赤の背景\e[0m"

# 明るい緑の背景
echo -e "\e[102m明るい緑の背景\e[0m"

# 明るい黄色の背景
echo -e "\e[103m明るい黄色の背景\e[0m"

# 明るい青の背景
echo -e "\e[104m明るい青の背景\e[0m"

# 明るいマゼンタ（明るい紫）の背景
echo -e "\e[105m明るいマゼンタ（明るい紫）の背景\e[0m"

# 明るいシアン（明るい水色）の背景
echo -e "\e[106m明るいシアン（明るい水色）の背景\e[0m"

# 明るい白の背景
echo -e "\e[107m明るい白の背景\e[0m"

exit 0
```

# 文字列の色と背景色を変える

テキストと背景が同系色の組み合わせと、低コントラストの組み合わせは視認性が悪いので避けてます。

![スクリーンショット 2024-10-17 18.24.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682035/d50c6fe7-7dce-ebb7-f557-ba55d802d569.png)

```sh:color.sh
#!/bin/sh

cd "$(dirname "$0")"

# 黒文字の見やすい背景
echo -e "\e[30;107m黒文字、明るい白の背景\e[0m"
echo -e "\e[30;103m黒文字、明るい黄色の背景\e[0m"

# 赤文字の見やすい背景
echo -e "\e[31;47m赤文字、白の背景\e[0m"
echo -e "\e[31;103m赤文字、明るい黄色の背景\e[0m"

# 緑文字の見やすい背景
echo -e "\e[32;40m緑文字、黒の背景\e[0m"
echo -e "\e[32;100m緑文字、明るい黒（グレー）の背景\e[0m"

# 黄色文字の見やすい背景
echo -e "\e[33;40m黄色文字、黒の背景\e[0m"

echo -e "\e[33;44m黄色文字、青の背景\e[0m"

# 青文字の見やすい背景
echo -e "\e[34;103m青文字、明るい黄色の背景\e[0m"
echo -e "\e[34;47m青文字、白の背景\e[0m"

# マゼンタ（紫）文字の見やすい背景
echo -e "\e[35;40mマゼンタ文字、黒の背景\e[0m"
echo -e "\e[35;46mマゼンタ文字、シアンの背景\e[0m"

# シアン（水色）文字の見やすい背景
echo -e "\e[36;40mシアン文字、黒の背景\e[0m"
echo -e "\e[36;100mシアン文字、明るい黒（グレー）の背景\e[0m"

# 白文字の見やすい背景
echo -e "\e[37;40m白文字、黒の背景\e[0m"
echo -e "\e[37;44m白文字、青の背景\e[0m"

# 明るい黒（グレー）文字の見やすい背景
echo -e "\e[90;40m明るい黒文字、黒の背景\e[0m"
echo -e "\e[90;47m明るい黒文字、白の背景\e[0m"

exit 0
```
connpassのグループ通知設定を一括でOFFにする

ITエンジニアの勉強会でお馴染みの「connpass」を使っていると、参加したイベントのグループからたくさんメールが届きませんか？
イベントに参加すると、そのイベントグループに参加されて、グループからのメールが届きまくっているようです。

今まではグループをいちいち「退会」してたんですけど、最近、通知が設定できることに気づきました😅
でも通知のチェックボックスが3つもあって（3つしかないといえばそうだけど）ぽちぽちするのが面倒です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128429/601200ee-5ae8-c432-cb9b-df3208575cc2.png)

手動でチェックするのは面倒なので、一括でチェックOFFにするスクリプトを使うと、少し楽できました🙌

## 一括でチェックOFFにするスクリプト

まずは、以下のページから設定画面を開きます。
https://connpass.com/settings/

<br>

通知をOFFにしたいグループをクリックして詳細画面を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128429/24812126-b632-7f8d-ab51-ebef4b7f952b.png)

<br>

グループの詳細画面で、consoleに以下のコードを貼り付けます。

```javascript
document.querySelectorAll('.group_inner input[type=checkbox]').forEach(c => { c.checked = false });
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128429/f38e7377-3fc7-2bf2-5ccc-3f6e9e85de25.png)


<br>

コードを実行すると、チェックが外れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128429/e00cdace-9bd5-bbc1-cc31-37d72717f1a1.png)

## ブックマークレットでさらに簡単に！

さらに便利な方法として、ブックマークレットも作りました！これを使えば、毎回コンソールにコードを貼り付ける手間がなくなります。

以下のコードをブックマークに登録しておけば、設定画面でワンクリックするだけで通知をOFFにできます。

ブックマークレットのコードはこちらです。
```javascript
javascript: (() => { document.querySelectorAll(".group_inner input[type=checkbox]").forEach(a => { a.checked = !1 });; })();
```

これで通知メールの煩わしさから解放されますね！✨

---
後から気づいたんですけど、全部のチェックボックスをOFFにするスクリプトで事足りますね😅
こっちの方が他のサイトでの汎用性もあります。
```javascript
javascript: (() => { document.querySelectorAll("input[type=checkbox]").forEach(a => { a.checked = !1 });; })();
```
ACDLを提唱します。その9

# 概要
ACDLとは、アプリは、クラウド、大切なデータは、ローカルです。
アプリ作ったので、plunkerに上げてみた。

# 機能
位置情報のCSVを読んで、MAPのマーカーします。

```
P1, 38.077908, 139.542229
P2, 38.075618, 139.642032
P3, 38.0738618, 139.441726
```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7a974669-0b4d-95d9-ac3b-b7202652de18.png)
 
# サンプルコード

```
<!doctype html>

<html>
  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.js"></script>
  </head>
  <body>
    <div id="map" style="width:100%; height:70vh"></div>
    <input id='btn' type='submit' value='run' onclick='run()'><br>
    <textarea id='src'rows='4' cols='30'>
P1, 38.077908, 139.542229
P2, 38.075618, 139.642032
P3, 38.0738618, 139.441726
    </textarea>
    <script type='text/javascript'>
var map = L.map('map').setView([38.0748331, 139.4574997], 9);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
function run() {
  var line = src.value.split('\n');
  for (var i = 0; i < line.length; i++)
  {
    var item = line[i].split(',');
    var marker = new L.Marker([item[1], item[2]], {
      title: item[0]
    });
    marker.addTo(map);
  };
}
    </script>
  </body>
</html>




```

# 成果物

https://embed.plnkr.co/plunk/fVA0Bl1GwOWFoBUs



以上
【Ruby】初学者向け－メソッドの基本について①

本記事ではメソッドの基本的な文法と使用方法をまとめています。

目次
・メソッドの定義方法
・キーワード引数

<h1>メソッドについて</h1>

**メソッドの定義方法**

```ruby:example_1.rb
def <メソッド> <引数リスト>
    # ここに処理を記述
end
```

引数リストは「（）かっこ」をつけることも、省略することもできる

```ruby:example_2.rb
a = 1
b = 2
def test  a,b
    a + b
    => 3
end
```
一番最後に行われた処理が結果（返り値）となる
上記のように定義したメソッドは、メソッド名を記述して呼び出すことができる。

def式で指定する引数は「仮引数」と呼ぶ

メソッドに引数が設定されている場合は、メソッド名に続いて引数を設定して呼び出す。
メソッドを実行する際に記述する引数を「実引数」と呼ぶ。

```ruby:example_3.rb

# メソッドの呼び出しと実引数の設定
test(3,4)

# 呼び出されたメソッドにて、設定された実引数をもとに処理を行う。ここではaとbが仮引数となる
def test  a,b
    a + b
    => 7
end
```

指定された実引数の数が仮引数の数よりも少ない場合、ArgumentErrorが発生するため、
仮引数ではデフォルト値を指定できる。

```ruby:example_4.rb
# ここでは変数bにデフォルト値を設定している
def test (a, b=100)
    a + b
end

# 仮引数の数 = 実引数の数の場合
test(9,10) => 19

# 仮引数の数 > 実引数の数
test(5) => 105

# 仮引数でデフォルト値を設定していない変数aに対しても引数を渡さない場合
test => ArgumentError
```

**キーワード引数**
仮引数とデフォルト値をコロン「:」で結び付けて定義ができる方法
キーワード引数を用いてメソッドを定義すると以下のようになる。

```ruby:example_5.rb
    def test(a:, b: 100)
        a + b
    end

    test(a: 5, b:9 ) = > 14
    test(a: 5) = > 105

    # 仮引数でデフォルト値を設定していない変数aに対してもキーワード引数を渡さない場合
    test => ArgumentError

    # キーワード引数に存在しない引数名を渡した場合
    test(a:100, c:120) => ArgumentError
```

キーワード引数に任意の引数を使用したい場合は以下のように定義すればArgumentErrorが発生しない

```ruby:example_6.rb
    def test2(a:, b: 100, **z)
        p z
        a + b
    end

    # 仮引数として設定していない変数cとdの値も受け取ることができ、エラーが発生しなくなる
    test2(a: 2, c: 100, d:200 ) => 102
    コンソール上に{:c => 100, d=> 200}が出力される
```
paizaラーニング問題集「【全探索 1】高い寿司を食いたい！」を、解説例に基づいて解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_richer_sushi

▼解説例の考え方

連続するK枚の寿司を、P[(i+j)%N] (j=0,1,...K-1)で表現する考え方です。以下に例を示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/cc02a437-e9f5-fdd5-6517-d8a04d046cb6.png)

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

N,K = map(int,input().split())

P = [0]*N
for i in range(N):
    P[i] = int(input())

# tmp_total: 連続するK枚の寿司の合計金額を格納する変数
tmp_total = 0

max_prime = 0

########## 処理1 連続するK枚の寿司の合計金額および最大値の計算、出力 ###########

for i in range(N):

    # j: 連続するK枚の寿司を走査する変数
    for j in range(K):
        tmp_total += P[(i+j)%N]
    
    if tmp_total > max_prime:
        max_prime = tmp_total

    tmp_total = 0

print(max_prime)
```
▼参考

以下は、本問を解説例ではなく、私の考え方に基づいて解いてみた記事です。
https://qiita.com/toytoy24/items/5792df63ae7195e09c4e
JavaScriptにおける非同期処理、Promise、エラーハンドリングの基本

## はじめに

Webアプリケーション開発において、非同期処理は避けて通れない重要なトピックです。特に画像の読み込みやAPIリクエストなど、時間のかかる操作を扱う際に適切な非同期処理が不可欠です。この記事では、非同期処理の基本、Promiseの活用、そしてエラーハンドリングについて解説します。

## 非同期処理の基本

JavaScriptは単一スレッドで動作しますが、非同期処理を利用することで、長時間かかる処理を待たずに次の処理を実行できます。

```javascript
console.log("Start");
setTimeout(() => {
  console.log("Timeout");
}, 0);
console.log("End");

// 出力:
// Start
// End
// Timeout
```

この例では、`setTimeout`が非同期で実行されるため、"Timeout"の出力が最後になります。

## Promiseの活用

Promiseは非同期処理をより扱いやすくする機能です。

```javascript
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, name: "John" };
      resolve(data);
      // エラーの場合: reject(new Error("Failed to fetch data"));
    }, 1000);
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));
```

この例では、`fetchData`関数がPromiseを返し、データ取得の成功時は`resolve`、失敗時は`reject`を呼び出します。

## async/awaitの使用

async/awaitはPromiseをさらに読みやすく書くための構文です。

```javascript
async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error("Error:", error);
  }
}

getData();
```

`async`関数内で`await`キーワードを使用することで、Promiseの結果を同期的に扱えます。

## エラーハンドリング

非同期処理でのエラーハンドリングは特に重要です。try-catchブロックを使用して、エラーを適切に捕捉し処理します。

```javascript
async function processImage() {
  try {
    await loadImage();
    await processData();
    await saveResult();
    console.log("処理完了");
  } catch (error) {
    console.error("エラーが発生しました:", error);
    // ここでユーザーへのエラー通知などを行う
  }
}
```

この構造により、各処理段階でエラーが発生した場合でも適切に捕捉され、処理されます。

## まとめ

- 非同期処理は、時間のかかる操作を効率的に扱うために重要です。
- Promiseは非同期処理を構造化し、管理しやすくします。
- async/awaitは、Promiseベースのコードをより読みやすく、書きやすくします。
- 適切なエラーハンドリングは、堅牢なアプリケーション開発に不可欠です。

これらの概念を理解し適切に活用することで、より効率的で信頼性の高いJavaScriptアプリケーションを開発できます。
macOSディスクユーティリティの不具合とコマンドでの解決法：フォーマットが進まない問題を回避する方法



macOSのディスクユーティリティでSDカードやUSBのフォーマットが途中で止まる不具合に対処するためのコマンドライン活用法を紹介します。

GUIでは解決できない場合でも、コマンドを使用することで問題を回避できます。

diskutilやddコマンドを活用して、ストレージデバイスの初期化と再フォーマットを行い、作業をスムーズに進めましょう。

https://x.com/maochanz/status/1846720509368848708

# 1. フォーマット進行中にフリーズする問題
macOSのディスクユーティリティを使用して、SDカードやUSBドライブをフォーマット中にフリーズしてしまうことがよくあります。

進行バーが途中で止まり、作業が完了しないという問題が報告されています。特に大容量メディアや長期間使用していたデバイスでこの現象が起こりやすいです。

# 2. GUIでは解決できない問題
GUIを使用してフォーマットしようとしても、ハードウェア自体の問題やファイルシステムの破損により、解決が難しいことがあります。

このような場合、GUIではなくコマンドラインツールを使用して手動でフォーマットを行うことで、問題を回避できる可能性があります。

例えば、次のコマンドを使うことで、問題のあるデバイスを初期化し、再フォーマットを試みることができます。

```shell
diskutil unmountDisk force /dev/disk18
sudo dd if=/dev/zero of=/dev/disk18 bs=1024 count=1024
diskutil partitionDisk /dev/disk18 GPT JHFS+ "My External HD" 0g
```

この手順では、まずディスクを強制的にアンマウントし、ddコマンドで全てのデータをゼロで上書きします。

最後に、diskutilを使って新しいパーティションを作成し、フォーマットを完了させます。

# 3. コマンドラインツールによる回避策
GUIでフォーマットができない場合でも、コマンドラインツールを活用することで、ストレージデバイスをリセットし、新たに使用できる状態にすることが可能です。

上記のコマンドを適用することで、ディスクを完全に初期化し、再フォーマットが実行されます。このプロセスは物理的な問題がない限り、正常に完了することが期待されます。



# 🤔 参考
もしさらに詳しい手順や具体的なトラブルシューティング方法が必要な場合は、こちらの記事を参考にしてみてください。


https://android.benigumo.com/20241017/diskutil-dd/
GASでSlack botを作り、3秒以上かかる処理をさせる方法

# GASを使ってSlack botを作る際の問題点

GAS (Google Apps Script)は無料で簡単に自動化した処理を作れるので便利です。
ただ、その分処理速度に関してはあまり早くないため、ちょっとした処理でも簡単に数秒かかってしまいます。

GASを使ってSlack botを作りたい、というのは比較的よくあると思います。
GAS→Slackの連携に関しては処理時間はあまり関係ないので良いですが、Slack→GASの場合だと、Slackのいわゆる「3秒ルール」により、3秒以内に処理が終わらず、タイムアウトエラーや処理が何度も動いてしまうなどの問題が発生すると思います。

:::note info
※Slackの3秒ルールとは
Slackが呼び出す外部APIは、3秒以内にレスポンスを返さないといけないという仕様。
レスポンスがないと、イベントの種類に応じてタイムアウトエラーやリトライが発生する。
:::

# 解決策：リトライを利用する
Slackのイベントは主に２つのパターンがあります。

1. ３秒以内にレスポンスがないとタイムアウトエラーが出るもの（スラッシュコマンド、フォーム送信など）
1. ３秒以内にレスポンスがないとリトライするもの（メンション、リアクションなど）

このうち１のイベントについては解決できないので、**利用するのを諦めます**。
２のリトライしてくるものについて、以下の処理をします。

1. 初回に来たイベントのリクエストのIDをScriptPropertiesに記録し、その後は普通に処理を実行する
1. ３秒以内に終わらず、２回目のリトライリクエストがくるので、ScriptPropertiesに記録されたIDと比較して、すでに記録済みの場合は200 OKを返す

SessionPropertyとの比較だけであれば３秒以内にレスポンスを返すことは可能なので、これで対応します。

```js:GAS
function doPost(e) {
  const contents = e.postData?.contents ? JSON.parse(e.postData.contents) : {}
  const challenge = contents.challenge;

  // Slackのchallengeはそのまま返す
  if (challenge) {
    return ContentService.createTextOutput(challenge).setMimeType(ContentService.MimeType.TEXT);
  }

  // 一意なIDとしてclient_msg_idを利用する
  const clientMsgId = contents.event.client_msg_id

  const scriptProperties = PropertiesService.getScriptProperties();

  if (!!scriptProperties.getProperty(clientMsgId)) {
    // ２度目以降の起動なので何もしないで200 OKを返す
    return ContentService.createTextOutput("OK");
  } else {
    // 初回起動なのでclient_msg_idを保存する
    scriptProperties.setProperty(clientMsgId, JSON.stringify(contents.event));
  }

  /*
   * 〜〜主処理をこの辺で実施〜〜
   */
  
  // 万が一３秒ギリギリに終わってしまうと、リトライが来るタイミングとの兼ね合いで
  // ２回実行されてしまう場合があるので、３秒スリープさせる
  Utilities.sleep(3000);

  // 保存しておいたclient_msg_idを削除しておく
  scriptProperties.deleteProperty(clientMsgId);

  return ContentService.createTextOutput("OK");
}
```

１度必ずリトライが発生する、というのがちょっとイケてないですが、とりあえず目的は達成できたので良しとします。
キレイにやりたければ、ちゃんとAWSのLambdaとかGoogle CloudのCloud Functionsとかを使いましょう。

なお、Slackではリトライの際に`X-Slack-Retry-Num`というHTTP Headerを付けてくるので、これをチェックするのが本来のやり方ですが、GASではHTTP Headerは取得できないので、このような方法を取っています。

# 試した方法（失敗例）：トリガーを使う
通常のFaaSなどを使う場合、Queueを使ったり別のFaaSを呼び出したりして、３秒以内にレスポンスを返すのがセオリーです。
GASの場合はトリガーを使うことで同様の仕組みが作れます。

```js:newTrigger
  let time = new Date();
  time.setHours(10);
  time.setMinutes(30);
  ScriptApp.newTrigger('someLazyFunction').timeBased().at(time).create();
```

上記コードで３秒以上かかる重い処理を別プロセスとして実行できるようになります。

ただ、この**newTrigger自体、結構時間がかかる**ので、３秒以内に終わらない場合がありました。
そのため、この方法ではうまくいきませんでした。

:::note info
【余談】newTriggerを使うと「指定した時間内のみN分置きに処理を実行する」みたいな柔軟な自動スクリプトが実行可能になるので、仕組みは知っておくと結構有用です。
:::

# まとめ
* Slackの３秒ルールにGASで対応するため、「リトライを無視する」方法を用いた
* リトライを使えないSlackイベントでは実現できないため、GAS以外の方法を使う必要がある
* ３秒ルールにとらわれず処理できるので、GASの活用の幅が広がりそう
paizaラーニング問題集「【全探索 2】コップの水」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__a_cup_of_water

▼考え方

この問題を解くために私が考えた内容1.～3.を以下に示します。

1.N個の小さなコップの組合せをすべて求め、それぞれの容量(ml)を計算します。その容量の中でX[ml]を超えないかつ最も大きい容量を出力します。

2.コップの組合せを求めるために、itertoolsというモジュールを使用します。以下に使用例を示します。
```py
import itertools

w = [30,40,50]

print(list(itertools.combinations(w,1)))
# [(30,), (40,), (50,)] → 1個の小さなコップの組合せすべて

print(list(itertools.combinations(w,2)))
# [(30, 40), (30, 50), (40, 50)] → 2個の小さなコップの組合せすべて

print(list(itertools.combinations(w,3)))
# [(30, 40, 50)] → 3個の小さなコップの組合せすべて
```

3.小さなコップの組合せたときの水の合計量は、sum関数を使用して求めます。

▼コード
```py
########## 処理0(準備) モジュールインポート,インプット ###########

# 考え方2.
import itertools

N,K = map(int,input().split())

w = [0]*N
for i in range(N):
    w[i] = int(input())

# max_ml: 大きなコップに入れられる水の最大量を格納する変数
max_ml = 0

# max_ml: 小さなコップの組合せたときの、水の合計量
tmp_ml = 0

########## 処理1 小さなコップの組合せたときの水の合計量のうち、大きなコップの容量を超えない最大値を求める ###########

for i in range(N):
    # 考え方2.
    wc = list(itertools.combinations(w,i+1))
    
    for j in range(len(wc)):
        # 考え方3.
        tmp_ml = sum(wc[j])
        
        if tmp_ml <= K and max_ml < tmp_ml:
            max_ml = tmp_ml

print(max_ml)
```
プロンプトエンジニアリングの基本と応用：AI生成を自由自在に操るテクニックと実践ガイド

## **はじめに：プロンプトエンジニアリングって何？**

AIに「ちょっとアレなお願い」をして、バッチリ思い通りのアウトプットをもらう。これが“プロンプトエンジニアリング”です。AIにかける言葉の魔法で、画像生成や文章生成など、生成AIの可能性を引き出すスキルなんですね。

今や、AIは画像、テキスト、音声、動画と、なんでもござれの万能ツール。でも、「これ、思ってたのと違う！」なんて結果にお目にかかったこと、ありませんか？そんな時に、あなたの助けとなるのがこの“プロンプトエンジニアリング”なんです。

---

## **プロンプトエンジニアリングの考え方をざっくり解説**

### 1. **プロンプトエンジニアリングの意義とは？**

AIがポンと素晴らしい出力を返してくれるかどうかは、まさにプロンプトの腕にかかっています。このプロンプトエンジニアリング、機械学習で「パラメーターチューニング」なんて難しい顔した用語に似ているのですが、こちらはもっとライトに、気軽に試行錯誤していくのがポイント。

アジャイルな開発（つまり、ちょいちょい調整していくスタイル）にも似ています。こうやって、「ちょっと違うな…」と感じたら、すぐに修正して再度プロンプトを送る。その繰り返しで理想のアウトプットに近づいていくんです。

### 2. **プロンプトエンジニアリングの現状と未来**

日本でもAI使いこなし隊が増えつつありますが、まだまだプロンプトエンジニアリングの達人は少なめ。ですが、需要は右肩上がりの予感がビシビシ。例えば「日本プロンプトエンジニア協会」なんてものが日本では立ち上がっています。どんどん成長していく生成AIと共に、プロンプトエンジニアがガンガン活躍する時代がくるかもしれません！

---

## **生成AIの4大ジャンルとプロンプトのコツ**

生成AIには画像生成、動画生成、テキスト生成、音声生成と、大きく4つのジャンルがあります。それぞれに独自のテクニックがあるので、ここではそのポイントを見ていきましょう！

### 1. **画像生成AI：イメージが命！Stable Diffusion編**

画像生成AIは、いわば“お絵かきAI”。プロンプトに「青空」や「3D風」などの要素を並べてAIに投げるだけで、パッと画像が完成します。

- **プロンプト例**：「masterpiece, hyper-realistic, full shot, sunset background, cinematic lighting」

さらに、生成するイメージから「こんなんいらん！」な要素を排除するために「ネガティブプロンプト」を活用することもあります。例えば「blur, low quality」なんて書けば、ボケた画像や解像度の低い画像を避けられるんですね。

- **小技ポイント**：「重み付け」テクニック。特定の要素に影響を与えるように括弧で囲むことで、狙い通りの絵に近づけます。（例: 「(sunset:1.5)」で夕日を強調）

### 2. **動画生成AI：シネマティックな仕上がりを求めてGen3編**

動画生成AIはまるでAI映画監督のよう。シーンの設定やカメラアングルを詳細に指示することで、希望の映像が出来上がります。キーワードをバッチリ連続して使うと、AIが「お、このシーンね！」と理解しやすくなります。

- **プロンプト例**：「ローアングルの固定ショット: カメラは熱帯雨林に立つオレンジの服を着た女性を見上げる。灰色の空が不安を演出。」

動画生成は、特定の言葉をちりばめてシーンを描写するのがカギ。語彙を揃えることで、AIが場面を一貫して保ちやすくなります。

### 3. **テキスト生成AI：話題のChatGPT編**

テキスト生成は、AIとの会話が楽しいところ。例えば、「深津式」と「シュンスケ式」という2つの質問方法で、その精度と深みを自在に操れるため、こちらの二つを参考文献から紹介！

- **深津式**：「プロンプトエンジニアリングって、どうアジャイルに取り組むべき？」
- **シュンスケ式**：「プロンプトエンジニアリングでぶつかる問題って何？」

深津式はズバリと指示をして具体的な答えを引き出し、シュンスケ式は逆質問させることで回答の質を引き出すスタイル。意図通りの回答を引き出すための工夫が詰まっています。

### 4. **音声生成AI：スムーズなトーンが売り！Whisper編**

音声生成AIは、まるで気分に応じて発声スタイルを変えてくれる声優のよう。強調したい部分を「!!」でマークしたりすることで、聞き取りやすくなります。プロンプト次第で、柔らかい声色から情熱的なトーンまで指示できます。

## **プロンプトエンジニアリングでのポイント**

1. **明確でシンプルなプロンプト**
    - 曖昧さは禁物！具体的にAIに指示することで、お望み通りの結果が手に入ります。
2. **テストと改善の繰り返し**
    - 何度も試して改善、これぞ“プロンプトエンジニアの鉄則”。
3. **学び続ける姿勢**
    - プロンプトエンジニアリングは奥が深い！日々の工夫と経験がスキルを磨きます。

### **関連リンク**

- [プロンプトエンジニアリングの基本と応用 | DOORS DX (brainpad.co.jp)](https://www.brainpad.co.jp/doors/contents/01_tech_2023-12-19-153000/)
- [生成系AIサービス一覧！種類・仕組み・活用事例を解説 (catch-the-web.com)](https://catch-the-web.com/media/generation-ai-list/#%E7%94%9F%E6%88%90AI%E3%81%AE%E4%B8%BB%E8%A6%81%E3%81%AA%E7%A8%AE%E9%A1%9E)
- https://aisuite.jp/column/chatgpt_prompt/#anc1
- [【簡単】便利な文字起こしAI「Whisper」の使い方をわかりやすく解説！ – AiHUB Media](https://media.aihub.co.jp/whisper/)
scoop pytyhon + scoop pipxでpoetryがインストールできなかったとき

`pipx install poetry`を実行したときにpythonが見つからないという旨のメッセージが出てpoetryをインストールできませんでした。

その前までは[Microsoft Storeのpython](https://apps.microsoft.com/detail/9ncvdn91xzqp)をインストールして使っており、それをアンインストールして[Scoop](https://scoop.sh/)にまとめようとしました。

とりあえず、以下の手順で解決しました。

1. pythonと検索して引っかかる、削除してもよさそうなレジストリを削除する
1. `%appdata%`のキャッシュを消しまくる
1. ユーザーフォルダの`pipx`フォルダを削除する

今思えば、`pipx`フォルダの仮想環境で元のpython実行ファイルを見つけられないことが原因で、`pipx`フォルダを削除するだけでよかったのかもしれません。

やはりmac
picoCTF 2024 writeup Super SSH

## Super SSH (General Skills)

Using a Secure Shell (SSH) is going to be pretty important. Can you `ssh` as `ctf-player` to `titan.picoctf.net` at port `63238` to get the flag? You'll also need the password `6dd28e9b`. If asked, accept the fingerprint with `yes`. If your device doesn't have a shell, you can use: https://webshell.picoctf.org If you're not sure what a shell is, check out our Primer: https://primer.picoctf.com/#_the_shell

指示通りssh接続してみる。
```
$ ssh ctf-player@titan.picoctf.net -p 63238
The authenticity of host '[titan.picoctf.net]:63238 ([3.139.174.234]:63238)' can't be established.
ED25519 key fingerprint is SHA256:4S9EbTSSRZm32I+cdM5TyzthpQryv5kudRP9PIKT7XQ.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[titan.picoctf.net]:63238' (ED25519) to the list of known hosts.
ctf-player@titan.picoctf.net's password: 
Welcome ctf-player, here's your flag: picoCTF{s3cur3_c0nn3ct10n_5d09a462}
Connection to titan.picoctf.net closed.
```

フラグが得られた。

`picoCTF{s3cur3_c0nn3ct10n_5d09a462}`
Flask + SQLAlchemyで音楽共有SNSを作る - アプリケーション起動編

## はじめに

前回の記事では、バックグラウンドジョブスケジューラーの設定について解説しました。今回は、Flaskアプリケーションの起動部分、具体的にはメインスクリプトの実装について詳しく説明します。

## メインスクリプトの実装

以下に、Flaskアプリケーションを起動するメインスクリプトの実装コードを示します：

```python
from app import app, db

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)
```

## 機能の詳細解説

1. **メインスクリプトの判定**
   ```python
   if __name__ == '__main__':
   ```
   - このスクリプトが直接実行された場合にのみ、以下のコードブロックを実行します。
   - これにより、このファイルが他のスクリプトからインポートされた場合に、以下のコードが自動的に実行されることを防ぎます。

2. **データベースの初期化**
   ```python
   with app.app_context():
       db.create_all()
   ```
   - アプリケーションコンテキスト内でデータベースの初期化を行います。
   - `db.create_all()`は、定義されたモデルに基づいてデータベースのテーブルを作成します。
   - 既に存在するテーブルは作成されません。

3. **アプリケーションの起動**
   ```python
   app.run(debug=True)
   ```
   - Flaskの開発用サーバーを起動します。
   - `debug=True`を指定することで、デバッグモードで起動します。

## デバッグモードについて

デバッグモード（`debug=True`）には以下の特徴があります：

1. **自動リロード**: コードの変更を検知して自動的にサーバーを再起動します。
2. **詳細なエラー情報**: エラーが発生した際に、詳細なトレースバックをブラウザに表示します。
3. **デバッガーの有効化**: 対話的なデバッガーを使用できます。

注意: デバッグモードは開発環境でのみ使用し、本番環境では必ず無効にしてください。

## 使用例

このスクリプトは通常、`run.py`や`app.py`といった名前のファイルに記述し、以下のようにコマンドラインから実行します：

```bash
python run.py
```

## セキュリティとパフォーマンスの考慮点

1. **環境変数**: デバッグモードの設定や他の設定値を環境変数から読み込むようにし、環境ごとの設定を容易にします。

2. **本番環境での注意**: 本番環境では`debug=True`を使用せず、適切な本番用サーバー（例：Gunicorn）を使用します。

3. **データベース初期化**: `db.create_all()`は既存のテーブルを上書きしないため、データベースのマイグレーション管理を検討します。

4. **シークレットキー**: アプリケーションのシークレットキーを適切に設定し、セキュリティを確保します。

## 改善案

1. **設定の外部化**: 環境ごとの設定を外部ファイル（例：config.py）に移動し、柔軟性を高めます。

2. **コマンドライン引数**: argparseなどを使用して、起動時のオプションをコマンドライン引数で指定できるようにします。

3. **ログ設定**: アプリケーション起動時に適切なログ設定を行います。

4. **アプリケーションファクトリ**: より柔軟な初期化のために、アプリケーションファクトリパターンの使用を検討します。

## まとめ

このメインスクリプトの実装により、以下のメリットが得られます：

1. 簡単なアプリケーション起動: コマンド一つでアプリケーションを起動できます。
2. 開発効率の向上: デバッグモードによる自動リロードと詳細なエラー情報が開発をサポートします。
3. データベースの自動初期化: アプリケーション起動時にデータベース構造が自動的に作成されます。

ただし、本番環境での使用には適切な調整が必要です。セキュリティとパフォーマンスを考慮した設定を行うことが重要です。

## 参考リンク
- [Flask アプリケーションの実行](https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application)
- [Flask-SQLAlchemy データベース操作](https://flask-sqlalchemy.palletsprojects.com/en/2.x/queries/#querying-records)
- [Flask デバッグモード](https://flask.palletsprojects.com/en/2.0.x/quickstart/#debug-mode)
Flask + SQLAlchemyで音楽共有SNSを作る - バックグラウンドジョブスケジューリング編

## はじめに

前回の記事では、日々の楽曲をリセットする関数の実装について解説しました。今回は、この関数を定期的に実行するためのバックグラウンドジョブスケジューラーの設定について詳しく説明します。

## バックグラウンドジョブスケジューラーの設定

以下に、APSchedulerを使用したバックグラウンドジョブスケジューラーの設定コードを示します：

```python
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from app.tasks import reset_daily_songs

scheduler = BackgroundScheduler()
scheduler.add_job(
    func=reset_daily_songs,
    trigger=CronTrigger(hour=4, minute=0),
    id='reset_daily_songs_job',
    name='Reset daily songs every day at 4 AM',
    replace_existing=True)
scheduler.start()
```

## 機能の詳細解説

1. **スケジューラーの初期化**
   ```python
   scheduler = BackgroundScheduler()
   ```
   - `BackgroundScheduler`クラスのインスタンスを作成します。これにより、バックグラウンドでジョブを実行できるスケジューラーが初期化されます。

2. **ジョブの追加**
   ```python
   scheduler.add_job(
       func=reset_daily_songs,
       trigger=CronTrigger(hour=4, minute=0),
       id='reset_daily_songs_job',
       name='Reset daily songs every day at 4 AM',
       replace_existing=True)
   ```
   - `add_job`メソッドを使用して、新しいジョブをスケジューラーに追加します。
   - `func`: 実行する関数（ここでは`reset_daily_songs`）を指定します。
   - `trigger`: ジョブの実行タイミングを指定します。ここでは`CronTrigger`を使用して、毎日午前4時に実行するよう設定しています。
   - `id`: ジョブの一意の識別子を指定します。
   - `name`: ジョブの説明的な名前を指定します。
   - `replace_existing=True`: 同じIDのジョブが既に存在する場合、それを置き換えます。

3. **スケジューラーの開始**
   ```python
   scheduler.start()
   ```
   - スケジューラーを起動し、ジョブの実行を開始します。

## 使用例

このスケジューラー設定は、通常アプリケーションの起動時に行います。例えば、Flaskアプリケーションの`__init__.py`ファイル内で以下のように使用できます：

```python
from flask import Flask
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from app.tasks import reset_daily_songs

def create_app():
    app = Flask(__name__)
    # アプリケーションの他の設定...

    scheduler = BackgroundScheduler()
    scheduler.add_job(
        func=reset_daily_songs,
        trigger=CronTrigger(hour=4, minute=0),
        id='reset_daily_songs_job',
        name='Reset daily songs every day at 4 AM',
        replace_existing=True)
    scheduler.start()

    return app
```

## セキュリティとパフォーマンスの考慮点

1. **エラーハンドリング**: スケジューラーやジョブ実行中のエラーを適切に処理し、ログに記録します。

2. **リソース管理**: バックグラウンドジョブがアプリケーションの他の部分のパフォーマンスに影響を与えないよう、リソース使用を監視します。

3. **タイムゾーン**: CronTriggerのデフォルトはUTCです。必要に応じて適切なタイムゾーンを指定します。

4. **永続化**: アプリケーションの再起動時にジョブスケジュールが失われないよう、永続化の仕組みを検討します。

## 改善案

1. **ジョブの動的管理**: 管理インターフェースを通じて、ジョブのスケジュールを動的に変更できるようにします。

2. **ジョブの実行状況モニタリング**: ジョブの実行状況や結果を監視し、問題が発生した場合に通知する機能を追加します。

3. **分散環境対応**: 複数のサーバーでアプリケーションが動作する場合、ジョブの重複実行を防ぐための仕組みを実装します。

4. **フェイルオーバー**: ジョブ実行が失敗した場合のリトライ機構や、バックアップジョブの実行を検討します。

## まとめ

バックグラウンドジョブスケジューラーの設定により、以下のメリットが得られます：

1. 定期的なタスクの自動化: 手動介入なしで日次のメンテナンス作業を実行できます。
2. 柔軟なスケジューリング: 複雑な実行スケジュールを簡単に設定できます。
3. アプリケーションのパフォーマンス向上: 重い処理をバックグラウンドで実行することで、ユーザー体験を損なわずにタスクを処理できます。

適切なエラーハンドリングとモニタリングを実装することで、安定したバックグラウンドジョブ管理システムを構築することができます。

## 参考リンク
- [APScheduler ドキュメント](https://apscheduler.readthedocs.io/en/stable/)
- [Flask アプリケーションファクトリ](https://flask.palletsprojects.com/en/2.0.x/patterns/appfactories/)
- [Python クロンジョブのベストプラクティス](https://martinheinz.dev/blog/39)
Flask + SQLAlchemyで音楽共有SNSを作る - 日次タスク自動化編

## はじめに

前回の記事では、アルバムアート取得のAPIエンドポイントの実装について解説しました。今回は、アプリケーションの日次メンテナンス作業を自動化する機能、具体的には日々の楽曲投稿をリセットする関数の実装について詳しく説明します。

## 日々の楽曲リセット関数の実装

以下に、日々の楽曲投稿をリセットする関数の実装コードを示します：

```python
from datetime import date, datetime, timedelta
from app import app, db
from app.models import DailySong

def reset_daily_songs():
    with app.app_context():
        yesterday = date.today() - timedelta(days=1)
        DailySong.query.filter(DailySong.date_posted <= yesterday).update({'is_current': False})
        db.session.commit()
        print(f"Daily songs reset at {datetime.now()}")
```

## 機能の詳細解説

1. **アプリケーションコンテキストの使用**
   ```python
   with app.app_context():
   ```
   - この関数がバックグラウンドタスクやスクリプトから呼び出される可能性を考慮し、アプリケーションコンテキストを明示的に使用します。

2. **昨日の日付の取得**
   ```python
   yesterday = date.today() - timedelta(days=1)
   ```
   - `date.today()`で今日の日付を取得し、`timedelta(days=1)`を引くことで昨日の日付を得ます。

3. **古い投稿の更新**
   ```python
   DailySong.query.filter(DailySong.date_posted <= yesterday).update({'is_current': False})
   ```
   - 昨日以前に投稿された全ての`DailySong`レコードを検索し、`is_current`フラグを`False`に設定します。
   - この操作により、過去の投稿が現在の投稿として表示されなくなります。

4. **変更の保存**
   ```python
   db.session.commit()
   ```
   - データベースの変更を確定します。

5. **ログ出力**
   ```python
   print(f"Daily songs reset at {datetime.now()}")
   ```
   - リセット操作の完了時刻をログに出力します。

## 使用例

この関数は、定期的なタスクスケジューラーから呼び出すことができます。例えば、APSchedulerを使用する場合：

```python
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger

scheduler = BackgroundScheduler()
scheduler.add_job(
    func=reset_daily_songs,
    trigger=CronTrigger(hour=4, minute=0),
    id='reset_daily_songs_job',
    name='Reset daily songs every day at 4 AM',
    replace_existing=True)
scheduler.start()
```

## セキュリティとパフォーマンスの考慮点

1. **データの整合性**: このリセット操作が他の操作と競合しないよう、適切なデータベースロックを検討します。

2. **エラーハンドリング**: データベース操作が失敗した場合の適切なエラーハンドリングとログ記録を実装します。

3. **パフォーマンス**: 大量のレコードを更新する場合、バッチ処理を検討し、データベースへの負荷を分散させます。

4. **タイムゾーン**: 日付の計算時にタイムゾーンを適切に考慮し、意図しない動作を防ぎます。

## 改善案

1. **リセット履歴の保存**: リセット操作の履歴をデータベースに保存し、必要に応じて監査やデバッグに使用できるようにします。

2. **段階的なリセット**: 大量のレコードを一度に更新する代わりに、少量ずつ段階的に更新する方法を検討します。

3. **リセット通知**: 管理者に対して、リセット操作の完了を通知する機能を追加します。

4. **手動リセット**: 必要に応じて管理者が手動でリセットを実行できる管理インターフェースを実装します。

## まとめ

日々の楽曲リセット関数の実装により、以下のメリットが得られます：

1. データの鮮度維持: 常に最新の投稿が「今日の楽曲」として表示されます。
2. 自動化によるメンテナンス負荷の軽減
3. アプリケーションの一貫した動作の保証

適切なスケジューリングとエラーハンドリングを実装することで、安定した日次メンテナンス機能を提供することができます。

## 参考リンク
- [Flask アプリケーションコンテキスト](https://flask.palletsprojects.com/en/2.0.x/appcontext/)
- [SQLAlchemy バルクアップデート](https://docs.sqlalchemy.org/en/14/orm/query.html#sqlalchemy.orm.Query.update)
- [APScheduler ドキュメント](https://apscheduler.readthedocs.io/en/stable/)
Flask + SQLAlchemyで音楽共有SNSを作る - アルバムアートAPI編

## はじめに

前回の記事では、Spotify APIを使用してアルバムアートを取得する機能の実装について解説しました。今回は、この機能をアプリケーションの他の部分から簡単に利用できるようにするための、APIエンドポイントの実装について詳しく説明します。

## アルバムアート取得APIエンドポイントの実装

以下に、アルバムアートを取得するAPIエンドポイントの実装コードを示します：

```python
from flask import jsonify
from app import app
from .spotify_utils import get_album_art  # 前回実装した関数をインポート

@app.route('/get_album_art/<artist>/<title>')
def get_album_art_api(artist, title):
    album_art_url = get_album_art(artist, title)
    return jsonify({'album_art_url': album_art_url})
```

## 機能の詳細解説

1. **ルーティング**
   ```python
   @app.route('/get_album_art/<artist>/<title>')
   ```
   - `/get_album_art/`に続いてアーティスト名と曲名をURLパラメータとして受け取ります。
   - 例: `/get_album_art/Beatles/Yesterday`

2. **アルバムアートの取得**
   ```python
   album_art_url = get_album_art(artist, title)
   ```
   - 前回実装した`get_album_art`関数を呼び出し、アルバムアートのURLを取得します。

3. **JSONレスポンスの生成**
   ```python
   return jsonify({'album_art_url': album_art_url})
   ```
   - `jsonify`関数を使用して、アルバムアートのURLをJSON形式でレスポンスとして返します。

## 使用例

このAPIエンドポイントは、フロントエンドから以下のように使用できます：

```javascript
fetch('/get_album_art/Beatles/Yesterday')
  .then(response => response.json())
  .then(data => {
    if (data.album_art_url) {
      document.getElementById('album-art').src = data.album_art_url;
    } else {
      console.log('アルバムアートが見つかりませんでした');
    }
  })
  .catch(error => console.error('Error:', error));
```

## セキュリティとパフォーマンスの考慮点

1. **入力のサニタイズ**: URLパラメータとして受け取るアーティスト名と曲名をサニタイズし、悪意のある入力を防ぎます。

2. **レート制限**: APIの過剰な使用を防ぐため、クライアントごとのレート制限を実装することを検討します。

3. **キャッシング**: 同じアーティストと曲名の組み合わせに対する結果をキャッシュし、Spotify APIへの不要なリクエストを減らします。

4. **エラーハンドリング**: Spotify APIからのエラーや、アルバムアートが見つからない場合の適切なエラーレスポンスを実装します。

## 改善案

1. **非同期処理**: アルバムアート取得を非同期で行い、レスポンス時間を短縮します。

2. **バッチ処理**: 複数の楽曲のアルバムアートを一度に取得できるエンドポイントを追加します。

3. **認証**: APIエンドポイントに認証を追加し、許可されたクライアントのみがアクセスできるようにします。

4. **メタデータの拡張**: アルバムアートURLだけでなく、楽曲の追加情報（アルバム名、リリース年など）も返すようにします。

## まとめ

このアルバムアート取得APIエンドポイントの実装により、以下のメリットが得られます：

1. フロントエンドとバックエンドの分離: アルバムアート取得ロジックをバックエンドに集中させることができます。
2. 再利用性: 同じエンドポイントを異なるクライアント（ウェブ、モバイルアプリなど）から利用できます。
3. パフォーマンスの最適化: サーバーサイドでのキャッシングや最適化が容易になります。

適切なエラーハンドリングとセキュリティ対策を実装することで、安全で信頼性の高いAPIエンドポイントを提供することができます。

## 参考リンク
- [Flask JSON応答](https://flask.palletsprojects.com/en/2.0.x/api/#flask.json.jsonify)
- [Flask ルーティング](https://flask.palletsprojects.com/en/2.0.x/quickstart/#routing)
- [Web API設計のベストプラクティス](https://docs.microsoft.com/ja-jp/azure/architecture/best-practices/api-design)
MuleSoft用語集：知っておきたいキーワードまとめ

# はじめに
皆さん、こんにちは。

MuleSoftのを勉強している中で、製品的な専門用語で多いなと感じましたので、話の中でも混乱しやすいではないかと思います。
特に似ている用語が多いので、MuleSoftに関連する主要な用語をまとめてみました。

# 用語まとめ
**１. MuleSoft**
　製品名です。

**２. Anypoint Platform**
　MuleSoftが提供する統合プラットフォームで、APIの設計、開発、管理を一元化できます。

　主な使用するユーザ：
　　API開発者、API管理者

**３. Anypoint Studio**
　MuleSoftが提供する開発ツールです。Eclipseベースの統合開発環境（IDE）で、Muleアプリケーションの設計と開発に使用します。

　主な使用するユーザ：
　　API開発者

**４. API Manager**
　Anypoint Platform内のモジュールで、APIの管理（共通設定など）とポリシー設定を行います。

　主な使用するユーザ：
　API開発者、API管理者

**５. Anypoint Exchange**
　Anypoint Platform内のモジュールで、APIやコネクタ、テンプレートを共有・再利用できるリポジトリです。

　主な使用するユーザ：
API開発者、


**６. DataWeave**
　MuleSoft独自のデータ変換言語で、さまざまなデータフォーマット間の変換を行います。XML、JSON、CSVなどのデータを柔軟に操作・変換します。

　主な使用するユーザ：
　　API開発者

**７.  Mule Runtime Engine（Muleランタイムエンジン）**
　Muleアプリケーションを実行するためのエンジンです。

　ユーザ：
　　API開発者、API管理者

**８．API-led Connectivity（API主導の接続性）**
　MuleSoftから推奨されたAPIを中心に据えたシステム統合のアプローチです。システムの再利用性と柔軟性を高め、ビジネス要件の変化に迅速に対応できるのが強いところです。
 
　具体的な実現はExp、Proc、Sys層を分けて、マイクロサービスの考え方で、APIを設計することです。

**９. RAML（RESTful API Modeling Language）**
　RESTful APIを設計するためのモデリング言語です。

　ユーザ：
　　API開発者。

**１０. MUnit**
　Muleアプリケーションの単体テストを行うためのフレームワークです。（Junitみたいな役割です。）

　　ユーザ：
　　　API開発者

# まとめ
以上がMuleSoftに関連する主要な用語のまとめでした。まだ整理し切れていない用語たくさん残っているので、
これからも継続まとめていきたいと思いますので、気になる点などがありましたら、コメントなどの連絡をいただければ幸いです。

最後までお読みいただき、本当にありがとうございました。
Oracle システム生成の順序は変更できません

すぐに忘れてよく詰まるので備忘録。

Oracleのテーブルに自動採番列を作成するとき、同時にシーケンスオブジェクトが自動生成される。

このシーケンスの開始値をリセットするには。

通常のシーケンスオブジェクトはALTER SEQUENCE文でリセットできるが、自動生成されたシーケンスオブジェクトにALTER SEQUENCE文を実行した場合、「システム生成の順序は変更できません」というエラーが出てしまう。

ではどうすればよいか。

システムによって自動生成されたシーケンスはALTER TABLE文でリセットできる。
自動生成されたシーケンスオブジェクトを直接変更することはできないが、自動採番列の定義を変更する形で間接的に変更できる。

(例) tab1テーブルのid列のシーケンスの開始値を1からに変更する

ALTER TABLE tab1 MODIFY (id GENERATED ALWAYS AS IDENTITY (START WITH 1)) ;

参考
https://qiita.com/plusultra/items/ff1725d5e4f96ad60e3d
初めて自作PC組み立てた件

# パーツ概要
- CPU：AMD　Ryzen 9 最大5GBクロックぐらい？ core 12
- メモリ：16GB2枚の32GB
- GPU：追々
- CPUクーラー：MUGEN6
- マザーボード：B650M Pro RS WIFI
- PCケース(ファン付き)：CX200M RGB ELITE
- 電源：MAG A650BNL
- SSD：会社がくれた
- ディスプレイ：PA156FH
- OS：自作(予定)
- キーボード：自作予定。会社に置いてある物で代用

##### 費用： 13万ちょっとぐらい。自作物無ければ20万いかないぐらい？

# 経緯
会社PC16GBのメモリが足らないな。
そうだ!!社長に32GBのPC集ろう!!!
経費うまうま。
↓
見積中...
うーん。ただ組み立てるだけじゃ面白くないよな。高いし
そうだ!!OS自作すれば安く済むじゃん(安易な考え)
ついでにキーボードも作ろう!!楽しそう()
↓
数日後
よっしゃ!!届いた。組み立てよ

ちょっと連日の徹夜で気が触れていたのかもしれない。と書いていて思いました
何はともあれ経緯としてはそんな感じです。

# 実際に作ってみて
私は説明書を読まない派なので、案の定苦戦しました。
とにかく電源の配線が上手く組めない。どこから何処を繋ぐのやらさっぱりで。
一回一回電源を点けてみて動作確認しながらなんとか配線を組み終えました。
それと買ったCPU クーラーがデカ過ぎた。めっちゃ配線組む時苦労した。
CPUクーラー買うときはサイズに気をつけましょう!!()

# 最後に
OSとキーボードは自作するので完成したらまた記事にします。
普段の業務と兼ねて作成するので大分遅くはなりますが。
社長からは業務優先してくれれば、残り時間は自由にしていいと許可貰っているので早くなるかもですが。
社長や手助けしてくれた先輩社員の方々に感謝。