OmniAICreator/Qiita-1.07M huggingface dataset:
オブジェクト指向のイメージを掴む

# オブジェクト指向以外の言語との違い
オブジェクト指向の言語が生まれる前は、「手続き型言語」に分類される言語があった。
「手続き型言語」は処理させたい内容を基本的には上から順に記述する。

## 手続き型

* 処理A
* 処理B
* 処理C
* 処理D
　・
　・
　・

上記のように記述する場合、記述量が増えてくると可読性が下がる。
そのために「関数」を使用し、複数の処理を１つのグループにまとめ、そのグループに名前をつけて使用していた。

rubyで再現すると以下のようになる。(rubyは手続き型言語ではない)
```ruby:ruby
def mixer(fruit)
  puts "#{fruit}を細かく砕く"
  return "#{fruit}のジュース"
end

puts "フルーツを入力してください"
input = gets.chomp

puts mixer(input)
```

上記のように関数を利用しつつ、上から順にコードを記述していくのが手続き型言語のスタイル。
ただ、上述の通り手続き型言語はコード量が多くなると管理しきれなくなる。
それを解消するためにオブジェクト指向と呼ばれる考え方が生まれた。

## オブジェクト指向
オブジェクト指向では、オブジェクトと呼ばれるパーツを連携させることでアプリなどの機能を実現する。

手続き型では、処理をまとめるために関数という仕組みがある。
オブジェクト指向では、さらに複数の関数をまとめて１つのオブジェクトとして扱っている。

# 手続き型とオブジェクト指向の違い

「カレーをつくる」という作業を例に、手続き型とオブジェクト指向の発想の違いのイメージを掴む。
手続き型的アプローチは、1人でカレーを作る時に適しており、オブジェクト指向的アプローチは複数人で大量にカレーを作る時に適している。

## 手続き型のイメージ
以下のように手順を紙にまとめ、上から順に取り組んでいくイメージです。
1. 食材を買いに行く
2. 野菜を洗う
3. 野菜を切る
4. 肉を切る
5. 野菜を炒める
6. 肉を炒める
7. 水を入れて煮る
8. ルーを入れる

## オブジェクト指向のイメージ
例えば10人でカレーを作る場合、以下のように全員が同じ手順を踏んでいくことは効率がいいとは言えない。

* 10人で食材を買いに行く
* 10人で野菜を洗う
* 10人で野菜を切る

通常は、以下のように買い出しや野菜担当などのチームに分かれて、それぞれの作業を行うことが考えられる。

* リーダー
* 買い出しチーム
* 野菜チーム
* 肉チーム

また、必要な材料や道具をチームごとに配っておけば効率よく作業ができる。

このカレー作りでの「チーム」に当たるのが、オブジェクト指向における「オブジェクト」にあたる。

役割ごとに分けたチームが連携してカレーを作るように、機能ごとに分けたオブジェクトを連携させてアプリを開発するのがオブジェクト指向の考え方になる。

__オブジェクトとは役割ごとに分けたチームのようなもの__

# オブジェクトの特徴

オブジェクト指向におけるオブジェクトについて、必ず押さえておきたい特徴
1. １つのオブジェクトには、１つの責務がある
2. オブジェクトにはメソッドと変数が含まれる
3. 他のオブジェクトに公開するメソッドや変数は必要最低限のもののみとする

先ほどのカレー作りに当てはめていく。

## 1. １つのオブジェクトには、１つの責務がある

上記のカレー作りの場合、野菜に関する調理は野菜チーム、肉に関する調理は肉チームが行なっていた。
これを「単一責任の原則」と言い、アプリ開発では、１つのオブジェクトに１つの機能を持たせるよう設計する。

例えば、フォームからの投稿機能を実装する場合は、以下のようなオブジェクトを作成し、それらを連携させることで機能を実現できるようにする。

* データの入れ物となるオブジェクト
* フォームからデータを受け取るオブジェクト
* SQLを発行するオブジェクト
* 上記のオブジェクトをコントロールするオブジェクト

## 2. オブジェクトにはメソッドと変数が含まれる
カレー作りの場合では、各チームにメンバーが配置され、下記のように必要な道具や材料が割り振られていた。
* 買い出しチーム・・・買い出しに必要な費用、買った材料を入れる袋
* 野菜チーム・・・包丁
* 肉チーム・・・包丁

オブジェクトは「メソッド」と「変数」をひとまとめにしたもの。
メソッドは、チームに配置されたメンバーのようなもの。メンバーが野菜を加工するように、メソッドはオブジェクト内の変数の変更や参照といった処理を担っている。

## 3. 他のオブジェクトに公開するメソッドや変数は必要最低限のもののみとする

カレー作りでも、初めに決められた仕事以外を手伝うと、たとえそれが善意であっても返って混乱することが考えられる。

カレー作りで、じゃがいもの皮むきを追加で10個行う必要が出たとした場合でも、別チームのメンバーが代わりに手伝うことはしない。

混乱を防ぐためには、別チームのタスクを直接行うのではなく、そのチームの担当にタスクを依頼する仕組みにする必要がある。
必ず、野菜担当に「追加で１０個皮をむいてほしい」ということを伝えるのみで、実際の皮むきは担当者が行う。

それと同じように、オブジェクト指向では、あるメソッドが別のオブジェクトの変数に直接アクセスしないよう設計する。
別のオブジェクトに含まれる変数を取得したい場合は、相手方のオブジェクトに含まれる「取得用のメソッド」に対して、データ取得を依頼する形にする。

オブジェクトごとにメソッドや変数を分離して、他オブジェクトに必要以上に干渉しないようにする考え方を「カプセル化」という。

カプセル化を含む以下の３点がオブジェクト指向の特徴だと言われている。

* カプセル化
* 継承
* ポリモーフィズム

今回の内容はカプセル化にあたる。
next.jsでtableタグを使用したらエラーが出た

tableタグを使って表を作成している中で出会ったエラー

```jsx
return (
        <table>
            <tr>
                {tableData.map((item, index) => (
                    <th key={index}>
                        {item}
                    </th>
                ))}
            </tr>
        </table>
    );
```
このように記述すると以下のエラーを吐く

サイト更新前に吐くエラー
```
app-index.js:31 Warning: 
validateDOMNesting(...): <tr> cannot appear as a child of <table>. 
Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by the browser.
```

更新後のエラー
```
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching <tr> in <table>.

See more info here: https://nextjs.org/docs/messages/react-hydration-error
```

更新前のエラーが参考になった。どうやら tbodyかthead, tfootタグで囲んでからtrを使う必要があるらしい。
以下のコードで解決
```jsx
return (
        <table>
            <thead>
                <tr>
                    {tableData.map((item, index) => (
                         <th key={index}>
                            {item}
                        </th>
                    ))}
                </tr>
            </thead>
        </table>
    );
```
Pythonでのツール作成時に困ったこと④

これまでに続き、Pythonのツール作成時に実際に起きた困ったことをまとめてみました。

今回は以下についてです。
・dateframeの結合で発生したエラー
・query後のforループでのミス

①dateframeの結合で発生したエラー
二つのdateframeの結合を行うため、以下のように記載したところ、エラーとなり処理が止まりました。
df1 = pd.contact([df1,df2])

以下のように修正したところ動きました。
df3 = pd.contact([df1,df2])

原因を調べましたが具体的な理由は出てこなかったため予想になりますが
代入先に結合するdateframeを指定することはできないようです。


②query後のforループでのミス
query後にforループで特定列を処理しようとするも、該当のindexがなく想定した処理となりませんでした。
df2 = df1.query( '抽出条件' )
chk = 'NG'
for index, row in df2.iterrows():
  if index == 1:
    chk = 'OK'
print( chk )

調査したところ、query後のdf2のindexはdf2のindexのままであり、抽出条件によりindex = 1のデータが抽出されていないとif条件後の処理がされません。

事前にreset_indexをしてインデックスを振り直したら想定した処理となりました。
Databricksのウェアハウスイベントシステムテーブル

気づいたら[システムテーブル](https://docs.databricks.com/ja/administration-guide/system-tables/index.html)が増えていました。ウェアハウスイベントシステムテーブルを触ってみます。

https://docs.databricks.com/ja/administration-guide/system-tables/warehouse-events.html

> このテーブルには、ウェアハウスが開始、停止、実行、およびスケールアップおよびスケールダウンされるたびに行が記録されます。 この記事のサンプル クエリをアラートと共に使用して、ウェアハウスへの変更を通知し続けることができます。

カタログエクスプローラでも存在を確認できます。
![Screenshot 2024-01-27 at 16.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/826583e0-a1a8-be0a-4d48-84257702f6b0.png)

テーブルの中身を確認します。

```sql
USE CATALOG `system`;

SELECT * FROM compute.warehouse_events we LIMIT 10;
```

ウェアハウスのイベントが記録されています。
![Screenshot 2024-01-27 at 16.02.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9dacf280-6cb0-4792-51cd-91eb698edaf8.png)

いくつかサンプルクエリーを実行します。

# どのウェアハウスがどのくらいの期間アクティブに稼働しているか?

```sql
USE CATALOG `system`;

SELECT
we.warehouse_id,
we.event_time,
TIMESTAMPDIFF(MINUTE, we.event_time, CURRENT_TIMESTAMP()) / 60.0 AS running_hours,
we.cluster_count
FROM
compute.warehouse_events we
WHERE
we.event_type = 'RUNNING'
AND NOT EXISTS (
SELECT 1
FROM compute.warehouse_events we2
WHERE we2.warehouse_id = we.warehouse_id
AND we2.event_time > we.event_time
)
```
![Screenshot 2024-01-27 at 16.04.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fce371b4-5e61-13e0-f9c7-3a95e70b1279.png)

# 初めて起動するウェアハウス

```sql
use catalog `system`;

SELECT
   we.warehouse_id,
   we.event_time,
   we.cluster_count
FROM
   compute.warehouse_events we
WHERE
   (we.event_type = 'STARTING' OR we.event_type = 'RUNNING')
   AND NOT EXISTS (
       SELECT 1
       FROM compute.warehouse_events we2
       WHERE we2.warehouse_id = we.warehouse_id
       AND we2.event_time < we.event_time
   )
```
![Screenshot 2024-01-27 at 16.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8d7f107d-38ea-7cf3-f174-cacef03e4f38.png)

稼働状況のモニタリングに使えそうですね。

### はじめてのDatabricks

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

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【Ruby on Rails】Active StorageがうまくAttachmentされずに苦しんだ話

# はじめに
Ruby on RailsでECサイトを作成する課題に取り組んでいたところ、Active Storageでattachした画像が何度やってもnilになってしまい苦しみました。
私のような稀有な現象に悩む方のために記事として残しておきます。

# 原因
原因はActive StorageがAttachmentする対象テーブルでデフォルトの連番idを使用しなかったことでした。
テーブルを作成した際に「id」カラム、「created_at（作成日時）」カラム、「updated_at（作成日時）」カラムは自動で作成されます。
しかし、今回作成する商品テーブルでは商品IDを使用するため、自動採番される値ではなく、こちらで決めたユニーク値を設定しました。
Active Storageが作成した「active_storage_attachments」テーブルは連番idを参照しているため紐づけることができずnilが渡されることが原因でした。
## 例
### AttachmentされないDB
#### item テーブル
|id|name|price|description|created_at|updated_at|
|---|---|---|---|---|---|
|sid-001|itemName|1200|text text text|2024-01-01|2024-01-01|

#### active_storage_attachments テーブル
|id|name|record_type|record_id|blob_id|created_at|
|---|---|---|---|---|---|
|1|image|Item|0|1|2024-01-01|

このように「active_storage_attachments」テーブルの「record_id」が「item」テーブルの「id」を参照していますが値が違うため、うまく結合されません。

# おわりに
調べても同じような事例が見つからず苦労しました。
同じようなことをする人がいないということでしょうか。。。
少し心が傷つきました（泣）
vscodeで使用するgithubのアカウント切り替え方法

デフォルトのアカウントと違うアカウントに変更する

Visual Studio Codeを起動し、まずはコマンドでemailとuserを確認
```
git config user.name 
git config user.email
```


デフォルトで使用しているアカウントであることを確認したら使用したいアカウントの情報を入れる
```
git config --local user.name ユーザー名
git config --local user.email メールアドレス
```

**プロジェクトの初回push**の場合は**githubで新しくリポジトリを作っておく**(これをうっかり忘れていたため上手く行かず時間がかかってしまった)

ここでpushして問題ないかどうか確認してみる

```
git push
```

こういうエラーが出た場合は
```
push declined due to email privacy restrictions
```
githubのSettings > Emails > Keep my email addresses private にチェックが入っていると、Githubでメールアドレスが非公開になっている。
これを一時的にチェックを外す。外してからpushすると問題なく出来る。
pushしたらチェックを入れ直す。

Eメールのプライバシー制限に引っかかってPushが拒否されたのがエラーの原因らしい。
GoogleドメインからAWSのRoute 53に移管する手順

# 背景

以下の記事でも取り上げたのですが、2023年6月にGoogleドメインのサービス終了（Squarespaceという他社サービスへ移管）が発表されました。

https://qiita.com/minorun365/items/790635f211a14ad6b4db

Googleドメインは使いやすく、安心のGoogleということで愛用していましたが、価格・サービスともにどうなるか不安なため別のサービスへ個人ドメインを移管することにしました。


# 前提（私の場合）

- 個人ドメイン（.com）をGoogleドメインで管理している
- DNSサーバーもGoogleドメインのものを利用
- 個人ドメインを使ったメールアドレスをZohoメールで管理している
- AWSのAmazon Route 53へドメインを移管したい

※Zohoは無料でも使えるGoogle Workspacesという感じでオススメのサービスです。

https://www.zoho.com/jp/mail/

ちなみに価格重視であればCloudflare等、別の選択肢もありますが、私は仕事柄AWSを頻用するため学習の意味も兼ねてAWSのRoute 53を移管先に選びました。

このドメインは個人のメインメールアドレスとして常時稼働しているため、ダウンタイムがなるべく発生しないようにDNSサーバーを先にAmazon Route 53へ移管する手順を実施しています。


# 参照すべきドキュメント

① DNSサーバーをAmazon Route 53へ移行

https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/migrate-dns-domain-in-use.html

② 独自ドメインを移管（転出元：Googleドメイン側）

https://support.google.com/domains/answer/3251178?authuser=0&hl=ja

③ 独自ドメインを移管（転入先：Route 53側）

https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/domain-transfer-to-route-53.html



# 簡易手順まとめ

私が実際に行った手順です。

:::note info
上記ドキュメントを参照していますが、適切でない手順を含む可能性があります。シビアなドメインで移管を実施する場合は、ぜひご自身で十分に手順の正当性を検証ください。
:::

### 1. Googleドメイン側で移管準備作業を行う

- 「DNS」設定よりDNSSEC設定をオフにし、リソースレコードをエクスポートしておく（BIND形式）
- 「登録の設定」より、ドメインのロックを解除して認証コードを取得しておく

### 2. Route 53側へDNSサーバーを移行する

- 移管したい独自ドメイン名でRoute 53のパブリックホストゾーンを作成する
- Googleドメインからエクスポートしたリソースレコード設定（.zoneファイル）をテキストエディターで開き、このホストゾーンへインポートする
- Googleドメインの「DNS」設定より、カスタムネームサーバー設定にRoute 53ホストゾーンのNSレコードに設定されているネームサーバー（4ホスト）を追加し、「これらの設定に切り替える」を実施する

### 3. Route 53へ独自ドメインを移管する

- Route 53の「ドメイン」設定より「移管（イン）」を実行
- ウイザードに沿って必要情報を入力し、移管リクエストを行う
- 数分後、Googleドメインからメールが来るので「移管を承認」する
- 数分後、AWSからもメールが来るので承認URLへアクセスする
- 数十分待つと、AWSからメール通知が来て移管が完了！


# 備考

Amazon Route 53のドメイン利用料は、AWSのクレジット（プロモーションなどでもらえる無料のAWS利用料クーポン）の適用対象外となるためご注意ください。
非エンジニアのサイト運営記

というようなことで、記事を作ってみます。
非エンジニアの僕が見よう見まねで「こんな感じで作ってみてください」みたいな
大雑把な感じで作ってもらい、悪戦苦闘しながらwebサービスをやってます。
執筆するのは就活の名人マガジン(:https://vinc.co.jp/mag/ )を運営する菊池です。
そんなんでもどうにかなってしまうのですが、つぎはぎなのでエンジニアさんにはだいぶ苦労かけてると思います
VSCodeにてReactを使う設定等

EditorにPrettierをインストールし編集の自動整形をする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/5ef7b96c-46c9-264c-c975-78f46ea26831.png" width="80%">
インストール後設定ボタン⚙マーククリックし入力欄にonsaveと入力し「Format On Save」にチェックを入れます。
力欄にformatと入力し FormatterをPrettierに設定する。
![スクリーンショット 2024-01-04 11.49.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/b3660790-a406-398e-bd0c-51a8177c0819.png)
Reactでランダムに画像を表示させる

## 今回作ったもの
https://qiita.com/Sicut_study/items/a27e5789a1b23438d77c 

こちらの記事を参考にして、Reactでランダムに画像を表示させるwebアプリを作りました。
見た目はこんな感じです。new imageというボタンを押すとランダムに選ばれた画像が表示されます。
![Screenshot 2024-01-27 at 14.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958271/0e91fb0e-6805-822f-10cb-92fe1b673adf.png)

## 実装について
今回はAxiosを用いて画像の取得を行なった。コードは以下の通りです。
```javascript:App.js
function App() {
  const [image, setImage] = useState();
  useEffect(() => {axios.get("https://source.unsplash.com/random", {responseType: 'blob',}).then(response => {
    setImage([URL.createObjectURL(response.data)]);
  })}, [])
  return (
    <div className="App">
      <img src={image} width="700px" />
      <button onClick={() => {
        axios.get("https://source.unsplash.com/random", {responseType: 'blob',})
        .then(response => {
          setImage([URL.createObjectURL(response.data)]);
        })}} className='button'>new image</button>
    </div>
  );
}

export default App;
```

一つ躓いたのは、getしてきた画像がうまく表示されなかったことです。
https://stackoverflow.com/questions/42785229/axios-serving-png-image-is-giving-broken-image 
 
この記事を参考に修正して正常に動くようになりました。
win16 apiを叩きたい。 その4

# 概要
win16 apiを叩きたい。
pc98エミュレーターに、ms-dos入れて、windows3.1入れて、turbo pascal入れて、窓を表示する。
練習問題やってみた。

# 練習問題
zundokoを表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/49a8dc06-cf16-b994-f9fe-768340757f21.png)

# サンプルコード

```
program zun;
uses wincrt;
procedure zundoko;
var i: integer;
begin
  Randomize;
  i := 0;
  repeat
    if Random(2) < 1 then
    begin
      writeln('zun');
      i := i + 1
    end
    else
    begin
      writeln('doko');
      i := 0
    end;
  until i = 4;
  write('doko kiyosi!!')
end;
begin
  zundoko;
  readln;
end.

```

以上。
【やってみた】小中学生向けJavaScript教材「サイレントリアル」

# サマリ
小中学生向けJavaScript教材「サイレントリアル」の無料教材をやってみました。

# 背景
ふらふらネットの波に揺られていると、ふとこちらの記事を目にしました。


https://prtimes.jp/main/html/rd/p/000000007.000036248.html

なんとなく興味はあったものの手が出ていなかったJavaScript。
すぐできそうだったので、この機に学べればと思ってやってみることにしました。

# ゴール
サイレントリアルの無料教材である、
- Part1：ジャンプゲームを作ろう！
- Part2：アイコンをデザインしよう！

をそれぞれやってみる

# 対象読者
- JavaScript学習のとっかかりを探されている方

# 前提
必須：PC、インターネット環境
# 環境
- ホストOS：Window10 Home
- ブラウザ：Google Chromeバージョン 120.0.6099.225
# 手順
以下の公式ページにアクセスし、気になる方をクリック。（雑）

https://silentorial.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/35035167-38b8-862e-0a6d-56f5ab2857b4.png)


### Part1やってみた
YouTubeのページに遷移するので、順番に見ていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/37847b0c-a8aa-232c-0091-d2dd435bc5fd.png)

英語なのでパッと見腰が引けそうですが、
[公式ページ](https://silentorial.com/)に記載の通り非言語のチュートリアルになっているため、
あまり気にせず**直感的に学習**できます。

エディタについても、各動画の概要欄に**ブラウザで触れる環境**を準備いただいているのでその場ですぐにコーディングができます。
（便利ですね～）

https://editor.p5js.org

動画によっては、そのセクション用にある程度デフォルトでコードが書かれたテンプレがあるので、各動画概要欄のStart-Up VersionのURLからエディタを開くのが便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/db24c570-f859-b732-3f29-e1e13715fb21.png)


エディタの画面はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/87c8cf5d-bb1f-ba37-4da7-a7466c262413.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/5ac8410b-fb08-7a5f-60fd-e4e8bec5a25b.png)


動画上でログインの指示がありますが、ログインでも一通りチュートリアルを進めることは可能でした。

動画の説明も視覚的にイメージがつきやすく、すっと頭に入りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/97d1acf5-db5a-9674-02ac-00820924d617.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/c217a2b8-0e3a-4b18-67b4-dd8cdcc79564.png)

一通り動画に沿って手を動かし、火の玉をよけるゲーム（といっていいのかわかりませんが）の作成ができました。
シンプルですが、こんな簡単にできるのかと感動です…！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/86f46bc4-c909-172d-0246-36dfbe903996.png)

### Part2やってみた
Part2の方も同じようにやっていきました。
途中経過は割愛しますが、単純なアイコンからグラデーションを付るまで体験できて、
JavaScriptにおける初歩的なデザインのイメージが付きました。
（まだまだ奥は深いのかとは思いますが…）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/bf02c08d-b107-0917-9495-9cb36605ac35.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/d620f87f-3bd0-7009-8a07-94afe0ac7001.png)


# 結果
無事特につまることなく、Part1,2を一通り完了できました。

# 学び
小中学生向けなんて全然あなどることなかれ、
大人でも初学者にとってはありがたいコンテンツでした。

# まとめ

無言語でも動画で直感的に何をすればいいかイメージが付きやすかったです、
さすがに関数・変数の具体的な意味など詳細を説明するものではないので、
これをきっかけにより深い理解を進めていきたいと思います！

今後も気になったことは小学生向けでもなんでもすぐに行動に移せるものから実行していきたいと思いました。
雑談：ユーザーにとしてのトランザクション

データベースの開発者にとって、トランザクションの行為は簡潔に説明するのは難しいです。しかし、ユーザーにとっては、わかりやすく説明する必要があります。そのため、最も簡単で理解しやすい表現は「[厳密な直列化](https://jepsen.io/consistency/models/strict-serializable)」という言葉です。なぜならば、語彙の直列化の定義は**肯定式**です。

様々なデータベースは、自身が可直列化をサポートしていると主張していますが、実際にはユーザーに使用しやすさを感じさせることを意図しています。なぜならば、直列化以外の行為はあいまいすぎる。

トランザクションの行為の定義として最も広く受け入れられているのは [ANSI SQL](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB#%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB) です。私も学生時代にデータベーストランザクションがそのように定義されていると認識していました。その中で、一番問題は否定式の定義です。「何が起こらない場合は、何です」そういうロジカル普段には通じない。考えておく、「Dirty Read」、「Non-Repeatable Read」そして「Phantom Read」を防ぐなら、語彙の直列化ですか。否、[その後の研究](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf)で他の非直列化の異常があると指示された。個人的な意見ですが、語彙の直列化以外の直列化は、定義の不足を利用した小賢さに過ぎません。

どうして、データベースは肯定式の定義に採用しないか。私は以前、データベース開発者として肯定式の定義を書く努力をしました。最後でその件を辞める原因はこの肯定式の定義を理解するのは難しい。データベースのユーザーは学術の専門家ではありません、もしデータベースのマニュアルは文人ぶるの感じなら、結構読みにくくなります。個人の理解は、厳密な直列化以下の一貫性と独立性の理解は難しい過ぎて、[メモリーモデル](https://en.cppreference.com/w/cpp/language/memory_model)と似たような感じ。

なら、どうしてデータベースは厳密な直列化以外を提供しますか。理由は性能です、直列化を破ることで、大幅なパフォーマンスが上がります。その場合、トランザクションの一貫性と独立性は「矢を放ち後から的を描く」ようなものになります。あるデータベースは `for update` 構文と提供している、そして、ユーザーは自分の要求からその構文を使用する。その構文のおかけで、全般のツーフェーズロックを避けることができます。

一部のクエリでは、データをそのまま利用する必要があります。また、複数のクエリが同じデータを変更せずに利用する必要がある場合もあります。例えば、外部キーの親テーブル。変更せずのため、シェアロックが作られた。

そこまで、トランザクションの行為は段々複雑になって、どう理解すればいいという問題が現れる。昔、x86プラットフォームのメモリーモデルを理解するために、Total Store Order (TSO) というモデルが提案されました。同様に、トランザクションの理解には、データベース内部な動作方法を少し理解する必要があります。

今のデータベースほぼ全部 [MVCC](https://ja.wikipedia.org/wiki/MultiVersion_Concurrency_Control) を受け入れる、そして、snapshot という概念が出る。snapshot のおかげで、書くことは新しいバージョンになって、元のバージョンはまだ読むことができます。snapshot 自身は理解しやすくて、いつも同じバージョンが読んでいる。

そこまでの話がりかいしたら、ANSI SQL の定義を切り捨てでも大丈夫だと思う。厳密なツーフェーズロックではない場合、トランザクションの行為は一言で言いにくくて、少し snapshot モデルで思考すれば、アプリの開発ところも気軽になりますかも。
Matplotlib created a temporary cache directory at /tmp/matplotlib-5nsiuvb1 because the default path...の対処法

# 状況
- Ubuntu 20.04のdocker
- pythonでmatplotlibを使用中によくわからんwarningが出る

# 警告
```Python
from mmpose.apis import MMPoseInferencer
```

```terminal
Matplotlib created a temporary cache directory at /tmp/matplotlib-5nsiuvb1 because the default path (/home/【username】/.config/matplotlib) is not a writable directory; it is highly recommended to set the MPLCONFIGDIR environment variable to a writable directory, in particular to speed up the import of Matplotlib and to better support multiprocessing.
```

# 改善方法
```terminal
sudo mkdir -p ~/.config/matplotlib
sudo chmod -R 777 /home/【username】/.config/matplotlib
```
docker runのときにError response from daemon: unknown or invalid runtime name: nvidia.

# 状況
- DockerでGPUを用いた処理のための仮想環境をしようとしていた
- run.shというbashファイルを作成し，runさせようとしていた

# 当該コード
```bash
    docker run -it \
    --privileged \
    --runtime=nvidia \
    -e NVIDIA_VISIBLE_DEVICES=all \
    -e NVIDIA_DRIVER_CAPABILITIES=all \
    --env=DISPLAY=$DISPLAY \
    ...
```

# エラー
```terminal
docker: Error response from daemon: unknown or invalid runtime name: nvidia.
See 'docker run --help'.
```

# 改善方法
以下の通り修正
```
# 修正前
    --runtime=nvidia \
# 修正後
    --gpus all \
```

# 参考文献
- https://qiita.com/gyuta/items/51b6b629e78c46b1b812
- https://github.com/NVIDIA/nvidia-docker/issues/838#issuecomment-558962338
wolfBootを使ってみた

# はじめに
[前回](https://qiita.com/AkimotoMasane/items/2082acfbfb5760602365)までは、wolfBootをNUCLEO-F401REで動作させるための準備を進めてきました。
今回は、wolfBootのメモリ配置について調べてみました。

# メモリマップ
メモリマップは、wolfSSL社が公開しているGitHubの以下のドキュメントに詳細が書かれています。
[ファームウェアイメージ](https://github.com/wolfSSL/wolfBoot/blob/master/docs/firmware_update.md)
[ファームウェアイメージヘッダー](https://github.com/wolfSSL/wolfBoot/blob/master/docs/firmware_image.md)

## ファームウェアイメージ
ドキュメントから今まで行ってきた準備の結果をメモリマップに割り当ててみると、下図のようになると思われます。

::: note info
wolfBootはSecotr0からSector2までの全てを使用していません。
0x0800_0000 から必要なサイズ使用しています。
:::

![map1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/047b6084-b5a5-6c76-2427-78ef633dc3aa.png)

### factory.bin
STM32CubeProgrammerでNUCLEO-F401REに書き込んだ/wolfBoot/factory.binは、wolfBootとtest-appを含んだものになります。
wolfBootの本体とtest-appに使われていないセクタがありますが、ここはmakeしたときにwolfboot.binとimage_v1_signed.binを結合するときに0xFFで埋めてくれています。
```:ターミナル
Output image(s) successfully created.
[MERGE] factory.bin
Added  20952 bytes at 0x8000000 from wolfboot.bin
Added 110120 bytes of 0xff fill
Added   7428 bytes at 0x08020000 from test-app/image_v1_signed.bin
```

### arch.mk
準備のときにarch.mkに下記を追加しましたが、これはwolfboot.binの先頭アドレスを指定していたことになります。
```:arch.mk
ifreq ($(TARGET),stm32f401)
    ARCH_FLASH_OFFSET=0x08000000
    SPI_TARGET=stm32
endif
```

### elfファイル
STM32CubeIDEで、wolfBootを実行するときに、wolfboot.elfとimage.elfのシンボルをダウンロードする設定をしましたが、wolfBootとPrimary(BOOT) partitionでステップ実行するための設定になります。

### その他のパーテーション
Secondary(UPDATE) partition, Swapping(SWAP) partitionは、ファームウェアの書き換えのときに使われるようです。
ファームウェアの書き換えについて調べたときに詳細を確認しようと思っています。

## ファームウェアイメージヘッダー
ファームウェアの先頭から256バイトには、ファームウェアの情報を格納するためのファームウェアイメージヘッダーが配置されています。
使用方法は分かりませんが、終端の4バイトはパーテーションのマジックナンバーになっているようです。

![map2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/934d03b4-07aa-4858-5667-675e5185ea2d.png)

ファームウェアイメージヘッダーの詳細はドキュメントより下記のようになります。
現在の実装では、ファームウェアイメージヘッダーの内容はドキュメントの内容から少し変わっているようです。

![map3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/6cb3d2f2-8cb8-406e-8cf9-e42c2472c85d.png)

タグタイプ、タグサイズのサイズはドキュメントでは1バイトとなっていますが、実装では2バイト（リトルエンディアン）になっているようです。
パティングの位置も変更されているようです。また、最後の"タグの終了"は現在はないようです。

|タグタイプ |意味             |サイズ  |
|:---------|:----------------|:-------|
|0x0001    |バージョン        |4バイト |
|0x0002    |タイムスタンプ    |8バイト |
|0x0003    |SHA256ダイジェスト|32バイト|
|0x0004    |?                |2バイト |
|0x0010    |?                |32バイト|
|0x0020    |署名             |64バイト|

# 編集後記
今後は、内部の処理についての理解を進めていきたいと思います。
Swiftアプリプレイグラウンド（.swiftpm）で画面回転をロックする

# 画面回転をロックしよう

通常のプロジェクトであれば
Generalタブ　> Deployment info > Device Orientation
でロックできます。
ただアプリプレイグラウンドでないと提出できないようなコンテストなど用にコードで回転をロックするのを書いときます。

``` ContentView.swift
import SwiftUI
import UIKit

// UIViewControllerを拡張して、特定の向きを設定
extension UIViewController {
    func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    // 任意のビューで特定の向きを設定するためのメソッド
    func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
        self.lockOrientation(orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        UINavigationController.attemptRotationToDeviceOrientation()
    }
}

// AppDelegateでの設定
class AppDelegate: UIResponder, UIApplicationDelegate {
    var orientationLock = UIInterfaceOrientationMask.all

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return orientationLock
    }
}

// SwiftUIビューで使用
struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .onAppear {
                // ここでポートレートにロックする
                UIViewController().lockOrientation(.portrait, andRotateTo: .portrait)
            }
            .onDisappear {
                // 画面が消えるときにロックを解除
                UIViewController().lockOrientation(.all)
            }
    }
}

```
海外で安全に過ごすためにーブラジル生活等から学んだ治安対策ABC

こんにちはAssieです。
最近回りで海外に行く人が増えてきたので、今日は海外、特に治安の悪そうなところに行く時に気を付けたほうがいいことをまとめてみます。
<br>
私は大学のころから中南米に行くことが多くて、駐在もサンパウロだったので結構サバイバル経験は多めです。（あまりそうは見えないかもしれませんが…）
その中で身に着けた海外、特に治安が悪い場所で気をつけたほうがいいことをまとめておきます。
＊治安だーいぶ悪いところに行く想定なので厳重な感じかもです。
<br>
**1. 治安が悪そうなところには行かない**
治安悪そうな国で気を付けることの第一歩は治安が悪いところに行かないことです。
とても当たり前のことのように聞こえますが、日本は治安が悪いところがあまりないので日本人は「治安が悪い場所かどうか」の嗅覚が鈍くて事件に合いそうなところに普通に行くので危ないです。
場所の治安は私の場合は以下を見ていて、危なそうだったら車で移動するとかにしてます。
・道に人がいるか
　人がゼロのところは襲われても助けが呼べないので曲がるときに人気は見ます。
・窓に鉄格子があるか
　窓鉄格子地区は基本ガラスを壊されるから鉄格子なので治安悪いです。
・壁の落書きが多いか
　ブラジルだと壁の落書きはギャング？の縄張りの暗号とかだったりするので、
　アートっぽい落書き以外は…な時も多いです。
・路上駐車の車種はちゃんとしてるか
　意外と道に止まっている車のジャンルで治安も見れます。高級車普通にとまってるところは安心。
ちなみに日本だとホームレスがいるところは治安が悪いとか思われるかもですが、
ブラジルはホームレスはご飯もらうためにレストランの近くにいたり、お金を集めるためにショッピングモールにいたりするのでちょっと感覚違う気がします。
あと中南米だとだいたい旧市街の中心地（ダウンタウン？）と貧民街（ブラジルならファベイラ）は治安悪いのでちょっと見てみたいとか好奇心でいかないほうがいい。
もひとつ、結構デモとかストとかも多い国に行くときはタクシー運転手のおじちゃんとかと話しながら聞いててデモの場所は避けてます。
<br>
**2.なるべく現地人っぽくする＆高価なものを身につけない**
観光客は結構な勢いでカモられたり襲われたりするので、過度に安全を気にしている素振りとかは逆に「あいつ観光客だ」と思われて微妙です。リュック前に持つとかもいいですが、ぎゅっと握りしめてると逆に観光客感出ちゃいます。
ちなみに私はリュックを後ろに持つと底切られるかもしれないし、前に持つと観光客っぽくも見えると悶々とした結果、斜め掛けA4バックを使ってます。
服装で気にしているのはやっぱり装飾品は最低限にすることです。タグワイヤー(高級時計)をサンパウロでなぜかつけてた同僚はご飯食べてた店ごと拳銃強盗にあってたし、時計・アクセサリー・カメラは目立たないやすそうなものにしといたほうがいいです。あととりあえずジーンズは世界共通なのでジーンズ&Tシャツとかを大体どこの国でも着ています。。。
ちなみにブラジルは携帯も街中で持ってるとチャリで走ってくる人がぱっと取っていくので携帯は町中利用NG、建物の中に入るかスマートウォッチで対応するのが王道です。
<br>
**3. お金で安全は買う**
昔けちってパラグアイで500円のホテルに泊まったら、受付のお兄さんが部屋に入って襲おうとした事件にあってからホテル代はケチらないほうがいいというのを学びました。。あと中米でタクシーで100円値引きしようとした人が銃殺されたの事件とかもあったので、少し高いくらいならネゴって逆上されるよりましなのでいいかなーと思います。移動とかも無駄に安さを求めるとその分危険になったり盗難の確度上がるので値段より安全見たほうがいいです。昔これまた500円くらいでボリビアで24時間バスのったら、バスに預けてた荷物なくなりました(スーツケースの中身が全部パンになってた。。。)。。あとインドで寝台列車乗って夜間移動したら起きたら荷物全部なかったし。。。移動の費用もケチりすぎないほうがいいです。。。

一方でブラジルはまれに外資の超高級ホテルは金持ちのたまり場だと思われて銃持った集団が占拠するのでナンバーワンぽさそうな高いところも微妙なのかもと思います。。。
<br>
**4. 襲われたり、盗まれた時のことは想定しておく**
いかに危ないところに行かないようにしたりしても車ごと襲われたりするときもあるはあるので、襲われたりスリにあった時の対策はしといたほうがいいです。
こないだ友達がイギリスでカバンを盗まれたのですが、なぜかマイナンバーカードまで持っていて諸々再発行大変そうでした。。盗まれた時の被害を最低限にするために、持ち歩く財布は日本のとは別で現金とカード1,2枚くらいにしといて、ホテルに予備カード1枚と多少の現金を置いておくのがおすすめです。あとパスポートもなくしたときのためにコピーは持っておくのが王道。
<br>
**5. 物の置き場には気を付ける**
よく荷物がなくなるのは「ちょっと目を離したすきに…」です。レストランで席にバックかけてたらなくなってたとか、道聞かれてしゃべってる時に置いてたバッグとられたとか。。。
私の場合は首からかけたりして物理的に体から離さないようにしていますが、それ以外の時は基本自分の後ろや離れた場所に物は置いてない気がします。まぁそもそもベストはカバンとか持ってないほうがいいんですけど。
あっそういえば仕事でホテルでイベントやってた時にランチタイムにイベント会場に強盗に入られてホテル内でお客のＰＣも全部なくなる事件もあったので、高級なところでも貴重品はだれかが見ておいたほうがいいです。。。
ちなみに我らが犯罪大国ブラジルはクレジットカードの決済する時にカードを店の奥に持っていって決済する店はその間にカード番号控えられてその後使われる時があるのでカード持っていかれるのは避けてます。。ちなみにカード番号盗んだ後は一気に高額でお金使うとカード止められるかもしれないのでちょっとずつ回数多く使っていってばれないようにする巧妙さです。。。
<br>
**6. タクシーは絶対Uberがいい**
空港出たところのタクシーとか流しのタクシーはメーターが異常な速度で上がるからぼったくられるのはよくありますが、一番タクシーが危ないのは密室空間にされた脅されるところです。。Uberでそれなりに星ある人なら安心なので安全上もUberがおすすめです。ちなみにUberじゃなくて公共機関を使う場合は路線見て途中で治安悪そうなところ通らないかをチェックしたほうがいいです。ブラジルのダウンタウン行きとかはなるべく乗りたくないし、深夜の電車も嫌だ。。。
<br>
こんなところでしょうか？ブラジル基準だから世の中こんなに危なくないと思いますが、皆さんが海外に行かれる時にトラブルに巻き込まれないように、何かお役に立てばです。
GoLand開いているファイルをエクスプローラーに常に表示する設定方法

# 前書き
忘れてしまいそうなので、備忘録的にメモしておきます。

#
1. エクスプローラーを開く
1. 三点リーダーをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539538/181daf62-0449-a290-720e-8864544f81e8.png)

1. Always Select Opened Fileを有効にする
1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539538/93a777b9-9758-2328-5a6a-a47cd85dd8e6.png)
自己満でApexのbotを作った

# はじめに
こんにちは、Sekibuuunです。
大人気fpsゲーム、Apex Legendsのbotを作ったので紹介します。

# なぜ作ろうと思ったか
私はかれこれ4年以上、Apex Legendsをプレイしています。
botを作った時のランクマッチでは、3つのマップで1日ごとにマップローテーションが行われていました。
ランクマッチのマップを確認するには、基本的にゲームを起動する必要がありました。
ランクマッチのマップを確認するためだけに、ゲームを起動するのは非常に面倒だったので、botを作ることにしました。

# botの仕様
botをメンションすると、
- 現在のランクマッチのマップ
- 次のランクマッチのマップ
- マップが切り替わるまでの時間

を教えてくれます。
![スクリーンショット 2024-01-27 135742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549853/e0e04ee6-dbff-63da-80d1-46d9d8adb454.png)


# 使用技術とその理由
- discord.js
    - 慣れているJavaScriptで書けるから
- TypeScript
    - 普段JavaScriptを使うことが多かったので、TypeScriptに入門したいと思ったから
- Biome
    - Eslint と Prettier 両方の設定が面倒だったから
- [Zeabur](https://zeabur.com/)
    - 知人から「GitHubと連携出来て、デプロイが簡単」と教えてもらったから
    - また、日本語のドキュメントがあったから
- [Apex Legends Status API](https://apexlegendsapi.com/#introduction)
    - ランクマッチのマップローテーションのAPIを提供していたから

# 作った感想
discord.jsを使ってbotを作るのは初めてだったので、勉強になりました。
また、ZeaburというHostingサービスは、GitHubと連携してデプロイが出来るので、とても便利でした。
これでわざわざApexを起動しなくても、ランクマッチのマップを確認できるようになったので、満足しています。

# 今後の展望
プレイヤーごとに、ランクマッチのポイント(RP)を確認出来るようにしたいです。

# おわりに
今回は、自己満でApexのbotを作ったというお話でした。
最後まで読んでいただき、ありがとうございました。
今回のリポジトリは[こちら](https://github.com/sekibuuun/apex_map_rotation_bot)

# 参考にさせて頂いた記事
https://qiita.com/one-milli/items/1fb6f90c378d3f2e1ce5
Oracle Databaseの外部認証

Oracle Databaseは、通常のパスワード認証だけでなく外部認証という機能があります。
[以前紹介](https://qiita.com/western24/items/499e59821c920b81946a)したActive Directory連携もその一つですが、クラウドのIDaaSとOAauth2による**トークン・ベース認証**も19cからサポートされており、現在は**OCI IAM**と**Azure AD**が使用可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/38518eab-60fc-f16f-da96-61d5a0c5668b.png)

Azure ADは、19.18以上のOracle Databaseはオンプレミス、クラウドに関わらず認証連携させることが可能です。OCI IAMは、Autonmous DatabaseやBase DatabaseなどのクラウドのOracle Databaseが対象で、接続のDatabase Clientが19.16以上が必要などの制限がありますので詳しくは最新の[ドキュメント](https://docs.oracle.com/en/cloud/paas/base-database/iam/#articletitle)をご確認下さい。

アクセストークンをデータベースに渡すフローは、<font color="RED">TLSで暗号化されている</font>必要があるため、データベース側のリスナーをTCPSでリスニングする設定が追加で必要になります。Autonomous Databaseは、WalletをダウンロードしてTLS接続しかできない仕様になっているのでこの設定は必要ないですが、一般的なOracle Databaseのリスナーは通常1521ポートのTCPだけでリスニングしていると思いますので、まずはこのTLSの設定を行います。

TLSは、クライアント側にOracle Walletを配置する方法、もしくはWalletなしでサーバー証明書だけの方法のいずれかが選択可能です。詳しくは[こちら](https://docs.oracle.com/cd/F19136_01/dbseg/configuring-secure-sockets-layer-authentication.html#GUID-6AD89576-526F-4D6B-A539-ADF4B840819F)。

ドキュメントを参照しながら実際に設定してみると難しく感じるところも多いように思います。Qiita内でも手順が紹介されているものもありますが、私自身の備忘録的にも、それぞれの手順について簡単に極力最小限の労力で構築する手順を紹介します。


[Oracle DatabaseのTLS暗号化を設定する](https://qiita.com/western24/items/4b746c1927d8f0efb9dd)
[OCI IAMとBaseDBのトークン・ベースの認証連携①](https://qiita.com/western24/items/95e4fde85d86be4649ab)
[OCI IAMとBaseDBのトークン・ベースの認証連携②](https://qiita.com/western24/items/9ed6581f5742fcba28db)
[OCI IAMとAutonomous Databaseのトークン・ベースの認証連携](https://qiita.com/western24/items/05f9f5c3d0a4aa9c49c5)

Azure ADの場合は、上記手順のOracle DatabaseをTLS暗号に設定した後、[こちら](https://qiita.com/jenlia3/items/899c059c44a92576a1d6)の記事の手順が参考になります。Azure ADの場合もIAMと同様に排他的マッピングと共有マッピングの方式ができるので、併せて確認頂くと良いかと思います。
クリップボードの文字列をカナにして戻すVBScript（要Excel）

```vb
'// GetPhoneticStr.vbs

txt = GetClipBoardText
CopyToClipboard(GetPhoneticStr(txt))

MsgBox "以下の文字列をカナにしてクリップボードに戻しました。" & vbCrLf & vbCrLf & txt
```
```vb
'// カナを返す

Function GetPhoneticStr(str)

    GetPhoneticStr = CreateObject("Excel.Application").GetPhonetic(str)

End function
```
```vb
'// クリップボードのテキストを取り出す
 
Function GetClipBoardText()

    GetClipBoardText = Trim(CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text"))

End Function
```
```vb
'// テキストをクリップボードにコピーする
'// 一瞬コンソール画面が出る

Sub CopyToClipboard(txt)

    CreateObject("WScript.Shell").Exec("clip").StdIn.Write(txt)

End Sub
```
静的型付けと動的型付け、型推論

## はじめに
学校の授業でPHPを習った際、「PHPは動的型付けだから、型は指定しなくていいですよ〜」と教わりました。気になったので深く調べたところ、動的型付け、静的型付け、型推論など色々と混在していしまいました。そこで、図にしてみたところ、やっと理解できたので記録しておきます。同じような疑問を持つ方の助けになればと思います。

## 静的型付け・動的型付け・型推論　について
プログラミング言語には多種多様な特性があり、その中の一つに「型の扱い方」が挙げられます。以下の図のようにして静的型付けと動的型付けに分けられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/2d730912-0fc2-2eb8-dab1-6b4b929628f6.png)

### 静的型付け言語 （C言語, TypeScript, Swift ...）
コンパイルまでの段階で型が定義・検証される言語を`静的型付け言語`と言います。静的型付け言語では、コンパイル時に型のチェックが行われ、型の不一致があればエラーとなります。このため、実行前に多くのエラーを発見できるといった利点があります。

例：C言語では、変数を使用する前にその型を指定する必要があります。（ `int number;` など ）

#### ~型推論~
静的型付けのうち、プログラマが型を明示的に宣言しなくてもコンパイラが自動で変数の型を推測する機能を`型推論`といいます。型推論によりコードが簡潔になり、型を手動で管理する手間が減少しますが、プログラマが意図した型と異なる型が推論される可能性もあります。

例：SwiftやTypeScriptでは`let number = 5;`のように変数を宣言するだけで、コンパイラが自動的に`number`が`int`であると判断します。

### 動的型付け言語（Python, Ruby ...）
変数の型をプログラムの実行時に検証・決定する言語を`動的型付け言語`といいます。静的型付けと違い、コンパイル時ではなく、実際にプログラムが動作する際に型の安全性をチェックします。動的型付け言語では、型を事前に定義する必要がなく、より柔軟なプログラミングが可能ですが、実行時に型のエラーが発生するリスクもあります。

## 最後に
自分がよく使うFlutterやSwift, C言語は静的型付けであることがわかりました。これから AIを勉強するのにPythonを勉強し始めますが、これまで触ってきた言語とは違い、動的型付け言語であるということに注意してコーディングしていこうと思います。
gh release createで作成するタグ・リリースのリビジョンを指定する方法

`gh release create`はデフォルトだとデフォルトブランチの最新リビジョンへのタグを作成します。
> automatically get created from the latest state of the default branch

https://cli.github.com/manual/gh_release_create

より古いリビジョンや別ブランチのリビジョンを指定するには`--target`オプションを用います。

同名のタグが既に存在する場合はそのタグを再利用してリリースを作成するため（※エラーにならない！）、別のリビジョンへのタグ・リリースを作成するには、新たな名前を指定するか、既存のタグを削除してから`gh release create`を実行します。

GitHubではリリースを削除しただけではタグが削除されません。そのためタグも個別に削除する必要があります。
WindowsでKeycloakをつかう

## 目的
Keycloakは認証認可のためのオープンソースソフトウェアです。KeycloakはJavaで実装されているので、OpenJDKなどのJava仮想マシンがインストールされていればどのOSでも実行可能です。

「とりあえず触りたい」というときはなんだかんだで手元のWindowsPCで実行できると便利です。この記事ではWindowsPCへのインストールからKeycloakの初回起動までの手順をまとめます。WSLやDockerは使いません。

## 要件
- Windows 10 Pro 64bit
- OpenJDK 17
- Keycloak 23

## OpenJDKのインストール
OpenJDKは各ベンダがビルドし提供しています。今回はMicrosoft Build of OpenJDKを利用します。

### OpenJDKの入手
https://learn.microsoft.com/ja-jp/java/openjdk/download#openjdk-17

上記リンクよりzipファイルをダウンロードします。解凍したら任意の位置にファイル一式を配置します。私はCドライブ直下に「Java」フォルダを作成し配置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685537/41649f2a-9109-d527-08d9-3b698c410f04.png)

### 環境変数の設定
いわゆる「パスを通す」を行います。
「コントロールパネル」＞「システム」＞「システムの詳細設定」の順にクリックし「システムのプロパティ」画面を開きます。「詳細設定」タブから「環境変数」ボタンをクリックし「環境変数」画面を開きます。

「環境変数」画面には「ユーザー環境変数」「システム環境変数」の２つがありますが、下段の「**システム環境変数**」に対して設定を行います。

##### JAVA_HOMEの設定
「新規」ボタンをクリックし「変数名」と「変数値」を設定します。
「変数名」は固定値"JAVA_HOME"を入力します。「変数値」はOpenJDKを配置したディレクトリを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685537/db65dc48-1173-a0af-ab84-616215605be6.png)

##### Pathの設定
今度は「システム環境変数」に登録されている変数「Path」をダブルクリックし「環境変数名の編集」画面を開きます。「新規」ボタンをクリックし固定値"%JAVA_HOME%\bin"を入力し、「上へ」ボタンで最上段まで移動させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685537/ebea32f2-bca3-0257-ca04-c439fc5d05bf.png)

##### 環境変数の確認
「コマンドプロンプト」を起動しechoコマンドで変数の内容を確認します。2行目の結果が返ってくれば無事パスが通っています。2行目の結果に「%JAVA_HOME%」がそのまま帰ってくる場合はパスが通っていません。PCを再起動し再度結果を確認してください。
```
echo %JAVA_HOME%
C:\Java\jdk-17.0.10+7
```

なお、Keycloakは実行に「%JAVA_HOME%」を指定するので、OpenJDKの環境変数の設定は必須です。

## Keycloakのインストール
https://www.keycloak.org/downloads.html

上記リンクよりzipファイルをダウンロードします。解凍したら任意の位置にファイル一式を配置します。私はCドライブ直下に「Keycloak」フォルダを作成し配置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685537/dbb0627f-df29-bed6-5b88-559fad808086.png)

### 環境変数の設定（任意）
OpenJDKと同様の手順でKeycloakの環境変数「KC_HOME」を設定します。**本記事では環境変数を設定せずに進行します。**

## Keycloakの実行
コマンドプロンプトでKeycloakのbinフォルダまで移動し開発モードで実行します。
```
cd C:\Keycloak\keycloak-23.0.4\bin
kc.bat start-dev
```
正常に起動した場合は以下のメッセージが表示されます。
```
2024-01-27 11:52:01,904 INFO  [io.quarkus] (main) Keycloak 23.0.4 on JVM (powered by Quarkus 3.2.9.Final) started in 13.142s. Listening on: http://0.0.0.0:8080
```
任意のウェブブラウザのアドレスバーに<http://localhost:8080>と入力しKeycloakが動作していることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685537/2fa7c5e6-e599-1848-c955-791cb64a6c99.png)
「Administration Console」をクリックし管理者ユーザー名とパスワードを設定します。

## 環境の削除（任意）
コマンドプロンプトを終了し、インストールとは逆の手順でOpenJDKとKeycloakのパスの削除、ファイルの削除を行ってください。

## まとめ
この記事ではWindowsPCへのインストールからKeycloakの初回起動までの手順をまとめました。実際のプロジェクトでWindows上に直接Keycloakを構築することは少ないかもしれませんが、Keycloakの学習や検討に向けて本記事がお役に立てれば幸いです。
Marketing CloudのContent BuilderでDEにテスト送信したが、受信できない

## 事象
Marketing CloudのContent BuilderでDEにテスト送信したが、受信できない

## 調査
[公式ドキュメント](https://help.salesforce.com/s/articleView?id=000382628&type=1)に記載されている原因をすべて確認したが、うまく解決できない

## 原因
送信キーが重複して、他のメアドに送信してしまった

## 再現
1．データ準備しよう
DE(A)には、下記購読者を入れてから、
| 送信キー | メール |
|:-:|:-:|
|  ID00000001 |  testA1@test.com |
|  ID00000002 |  testA2@test.com |

DE(B)には、下記購読者を入れた。　※送信キーが重複だが、エラーなく保存できた。
| 送信キー | メール |
|:-:|:-:|
|  ID00000001 |  testB1@test.com |

２．テスト送信に、DE(B)を選択して、送信した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/bfdec8f8-bce2-624e-8019-573651be487f.png)

３．いったい誰に送信したか確認
DE → トラッキング　→ ジョブID → 合計送信回数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/49874e8b-4f00-c257-206d-66b5e2c4b7ce.png)
testB1@test.comではなくて、testA1@test.comに送信してしまった

:::note alert
宛先はDE(A)になるが、メール本文はDE(B)の項目値によって、パーソナライズされている。
:::

４．送信ルールがあるから、、、
メアドではなく、送信キーをもとにして送信しているので、プライマリメールアドレス（古いメアド）に送信する

5.今後
誤送信にならないように、受信できなかったら、すぐ「すべての購読者」で確認しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/67d8fd87-edf2-6ca0-ba44-3081f2915750.png)
データサイエンス（データ分析、モデル構築）で使える高速化処理に関する参考書

# データ分析、モデル構築で使える高速化処理に関する参考書をまとめました（更新途中）

### ハイパフォーマンスPython
https://www.amazon.co.jp/dp/4873119901?&linkCode=sl1&tag=oshimayuki0d-22&linkId=306a08757c39ac228802f837b9c8e892&language=ja_JP&ref_=as_li_ss_tl

### Cython ―Cとの融合によるPythonの高速化
https://www.oreilly.co.jp/books/9784873117270/

### 並行プログラミング入門 ―Rust、C、アセンブリによる実装からのアプローチ
https://www.oreilly.co.jp/books/9784873119595/

### 入門 PySpark ―PythonとJupyterで活用するSpark 2エコシステム
https://www.amazon.co.jp/PySpark-―PythonとJupyterで活用するSpark-2エコシステム-Tomasz-Drabas/dp/4873118182

### 初めてのSpark
https://www.oreilly.co.jp/books/9784873117348/

### アプリケーションエンジニアのためのApache Spark入門
https://www.amazon.co.jp/アプリケーションエンジニアのためのApache-Spark入門-新郷美紀/dp/4798053775

### Apache Spark入門 動かして学ぶ最新並列分散処理フレームワーク 
https://www.seshop.com/product/detail/19579


### DeepSpeed
https://note.com/fukudawataru/n/n5152e6f587c8
https://tech.retrieva.jp/entry/2021/07/26/102514
https://www.deepspeed.ai


### Ray
https://qiita.com/waffoo/items/603bb3df25163fa461e9
https://www.ray.io
https://zenn.dev/honomaru/articles/16121b9124e7b4

#### Learning Ray: Flexible Distributed Python for Machine Learning
https://www.amazon.co.jp/Learning-Ray-Flexible-Distributed-Machine/dp/1098117220

#### Scaling Python With Ray: Adventures in Cloud and Serverless Patterns
https://www.amazon.co.jp/Scaling-Python-Ray-Adventures-Serverless/dp/1098118804/ref=pd_sbs_d_sccl_2_1/357-7170365-9226836?pd_rd_w=D6phS&content-id=amzn1.sym.e146c92a-7981-4c58-8351-e2a023395915&pf_rd_p=e146c92a-7981-4c58-8351-e2a023395915&pf_rd_r=ES2PV0K2T6P4WTYM7TVC&pd_rd_wg=qUA0x&pd_rd_r=e6e5a0b6-8b1f-4090-83d5-d10bad7223d6&pd_rd_i=1098118804&psc=1
【ChatGPT有＋DALL-E3】でコピって描画する際の注意です。


　どうも、カーブミラーです。

　今回は、プロンプトを使って、画風やキャラをコピって使う場合の注意です。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。

プロンプトややり取りは
　ございません。あしからず。
:::

　本題です。

　私のプロンプトは
　　まだまだコピープロンプト
　　　とは言えません(=^･^=)

　さて
　　コピープロンプトができた、
　　　と仮定しましょうか。

　それが楽しくて
　　バンバンとコピーしまくる
　　　なんて姿が、目に浮かびますw

　これは、
　　私だけでしょうか？
　　　みなさんの多くがハマる
　　　　ことと思います。

　それは
　　仕方ないことです。
　　　楽しくて面白いですからねぇ。

　でも
　　想像してみてください。

　みなさんが
　　苦労して作成した作品を
　　　SNSにアップしたすぐあとに
　　　　ほぼ同じ作品が
　　　　　アップされたら
　　　　　　どう思いますか？

　おそらく、
　　怒り憤り、
　　　簡単に真似できる程度なんだ
　　　　私の作品、と落ち込むかと。

　それが目的な人もいます。
　　フェイク画像なんて
　　　そんな人の所業でしょう。
　　　　自分が面白いから
　　　　　アップしてやろう、とか。
***
　そうならないように
　　気を付けましょう。

　コピープロンプトを使って
　　ほかの人の画像をコピっても
　　　それはあなたの作品では
　　　　ありません。

　もちろん、
　　そこから発展させて
　　　昇華させて、
　　　　自分の作品にしたら
　　　　　それはあなたの作品です。
***
　これは
　　自分がやってしまった結果、
　　　発生するかもしれないと思い、
　　　　書かせていただきました。

　このことで
　　みなさんの作品制作が
　　　止まらないことを
　　　　願います。

　今回は、ここまで。
.to_h について

### .to_hメソッドとは
対象のオブジェクト（配列やEnum型）に対してhashの形に変換する

#### 例
```
users = [[:name1, Alice], [:name2, Bob], [:name3, Hanako]]
users.to_hash
 →{name1: Alice, name2: Bob, name3: Hanako}
```
AWS一ミリも分からない人向けサイト2つ

## はじめに
こんにちは、AWSを学ぶ上で一番苦労することは学習教材探しではないでしょうか。
とにかくサービスが多い上に、情報が豊富であるがために初めの一歩目に何をすべきか分からないという方多いと思います(自分がそうだった)。

ちなみに今回紹介するサイトはどちらもAWS公式のものになります。

## IT 初心者向けクラウド入門ウェビナー ’Cloud for Beginners’
サイトは[こちら](http://qiita.com "Qiita Home")

![スクリーンショット 2024-01-27 11.47.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2965124/a91cf2d0-0f20-845b-cabb-27902892238b.png)


### 対象者
- クラウドについてわからない人
- AWSを使う利点がわからない人
- AWSの基本サービス(EC2, ELB, IAM, RDSなど)の概要がわからない人

## AWS Cloud Practitioner Essentials (Japanese) (日本語実写版)
サイトは[こちら](https://explore.skillbuilder.aws/learn/course/1875/play/92485/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-shi-xie-ban)

![スクリーンショット 2024-01-27 11.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2965124/bdfafb3c-a52c-4456-57b4-d5588059500d.png)


### 対象者
- AWSの主要なサービスについて知りたい人
- AWSサービス同士の連携について知りたい人
- AWSを使ってどのようにデプロイするのかイメージがない人

## おわりに
私のおすすめは2つ目のサイトになります。
最初にAWS Skill Builderに登録する必要がありますが、今回紹介した動画は無料で閲覧できます。
最初の一歩にはベストな内容になっていると思います。

また、AWS Skill Builderには他にも様々な講座が無料で公開されているので自分の興味のあるサービスについて探してみるのもいいかもしれません。
LaravelのTrustProxiesミドルウェアとroute(),asset()メソッドで生成されるURLの関係

### 前提
通信の流れは **クライアント ➜ AWS ALB(SSL有) ➜ nginx ➜ php(Laravel）** でクライアントは**httpsリクエスト**をしている。

上記条件の時に`TrustProxies.php`で
#### ➜ `$proxies`になにも設定しない場合
route(), asset()メソッドで生成されるURLは`http://~~~`になる
#### ➜ `$proxies = '*'`とした場合
route(), asset()メソッドで生成されるURLは`https://~~~`になる

### なぜ`$proxies`の設定で`http`→`https`に変わるのか。
まず`$proxies`になにも設定しない場合、プロキシから送信されるX-ForwardedヘッダーをLaravelが無視する。
無視されるヘッダの中には通信プロトコル情報の`X-Forwarded-Proto`も含まれる。
この場合Laravelはクライアントが`http` or `https`どちらでアクセスしてきているのか判別できないので、生成するURLは`http`で返す挙動になる。

一方で`$proxies = '*'`の場合、X-Forwarded-Protoヘッダを読み取って通信元のプロトコルをチェックする。
上の例ではプロトコルをチェックした結果、通信元が`https`プロトコルでリクエストしていることがわかるので、route(),asset()で生成されるURLは合わせて`https`にしている。

### 注意点
`$proxies`のデフォルトは何も設定されてないので、そのままだと`http://~~~`のURLが生成されてしまう。
本番環境ではちゃんと`$proxies`に値を設定すること！

### 参考
https://readouble.com/laravel/10.x/ja/requests.html#configuring-trusted-proxies
インデックス作成時に指定するパラメータ:アナライザー


## アナライザーの指定

Azure AI Search では、Microsoft および Lucene アナライザーがサポートされています。 既定では、検索エンジンは言語に依存しない Standard Lucene が使用されます。 テストで既定のアナライザーが不十分であることが示された場合は、言語アナライザーに置き換えます。

Azure AI Searchで使用できる日本語のアナライザーには、主に以下のものがあります：

- Microsoft アナライザー: 標準のMicrosoftアナライザーは、日本語を含む多くの言語に対応しています。これは、基本的なトークン化とテキスト処理を行います。

- Lucene アナライザー: Apache Luceneは、より高度なテキスト処理機能を提供するアナライザーをいくつか持っています。日本語の場合、`Lucene.StandardAnalyzer` や `Lucene.JapaneseAnalyzer` などが利用可能です。

- カスタム アナライザー: Azure AI Searchでは、独自のカスタムアナライザーを作成し、使用することも可能です。これには、トークナイザー、トークンフィルター、文字フィルターを組み合わせて、特定の言語や用途に最適化されたテキスト処理を実現することが含まれます。

特に日本語のテキスト処理においては、適切な分割や形態素解析が重要です。このため、`Lucene.JapaneseAnalyzer` のような、日本語に特化したアナライザーを利用することが推奨されます。
また、具体的な用途や要件に応じてカスタムアナライザーを構築することも有効な手段です。


## カスタムアナライザーはどんな時に使用する？

### 日本語の社内文書検索におけるカスタムアナライザーの使用例

**特定の形態素解析の必要性**

日本語の文書は、単語間に空白がないため、正確な形態素解析が必要です。
標準アナライザーでは適切な形態素解析が難しい場合、カスタムアナライザーで特定のトークナイザーを使用して、より精度の高い形態素解析を実現できます。

**専門用語の扱い**

社内文書には業界特有の専門用語や略語が頻繁に使用されることがあります。
カスタムアナライザーを用いて、これらの専門用語を正しく認識し、適切にインデックス化することが可能です。

**同義語の処理**

異なる表現で同じ意味の単語が使われることがあります（例：「PC」と「コンピュータ」）。
カスタムアナライザーに同義語フィルターを組み込むことで、異なる表現でも同じ検索結果を得ることができます。

**社内特有の文化や表現の反映**

社内文書は特定の文化や表現スタイルを反映している場合があります。
カスタムアナライザーで特定の単語フィルターを適用し、これらの特有の表現を適切に処理できます。

### カスタムアナライザーの実装例

```json
"analyzers": [
  {
    "@odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
    "name": "my_japanese_analyzer",
    "tokenizer": "kuromoji_tokenizer",  // Kuromojiトークナイザーは日本語の形態素解析に適しています
    "tokenFilters": ["kuromoji_baseform", "kuromoji_part_of_speech", "cjk_width", "lowercase"],  // 日本語特有の処理と基本的なトークンフィルター
    "charFilters": ["html_strip"]  // HTMLタグを除去する
  }
]

```

### カスタムアナライザーのパラメータ解説

**トークナイザー (Tokenizer)**
トークナイザーはテキストをトークン（単語やフレーズ）に分割する役割を担います。
以下は使用可能なトークナイザーの例です：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/13a83f05-fad1-e990-a4cb-4c25cefa5849.png)

**トークンフィルター (Token Filters)**
トークンフィルターは、トークン化されたテキストに対して変換や修正を加えるために使用されます。
以下に例を示します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/ed8453a4-1bae-8e57-741d-6d885b88e1c0.png)

**文字フィルター (Char Filters)**
文字フィルターは、トークン化の前に原始テキストに対して行われる変換です。以下のような選択肢があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/201e8f37-9946-55d5-75fd-24630bcc9385.png)
Mavenで自分で作成したライブラリjar／JavaDocのjarを利用する方法

ライブラリjarやJavaDocのjarファイルを作成する方法を別記事に掲載しているが、作ったjarファイルを使うにはどうしたらええの？？　というやつ。
ちなみにWindows前提で記載しているので、Macの方は脳内変換して頂きたい。
※この手順はライブラリjarやJavaDocのjarファイルを使うほうのプロジェクトで実施する。
　決してライブラリjarやJavaDocのjarファイルを作る方ではない。

# ◆大まかな手順
1. cmdファイル（.cmd）を作成する
1. cmdファイルを実行しjarファイル/JavaDocのjarファイルをインストールする
1. エディタ（cursor/VScode）を再読み込みする
 

# ◆詳細手順
## 1.cmdファイル（.cmd）を作成する
以下の内容にてcmdファイル（.cmd）を作成する。
```
SET groupId=グループID
SET artifactId=アーティファクトID
SET jarVersion=JARのバージョン

SET jarFile=フルパス指定のJARファイル名-%jarVersion%-library.jar
SET javaDocFile=フルパス指定のJavaDoceJARファイル名-%jarVersion%-javadoc.jar


@echo off
echo **************************************************
echo JARインストール
echo **************************************************
@echo on
powershell -Command "./mvnw.cmd clean"
powershell -Command "./mvnw.cmd dependency:purge-local-repository"
powershell -Command "./mvnw.cmd install:install-file -Dfile='%jarFile%' -DgroupId='%groupId%' -DartifactId='%artifactId%' -Dversion='%jarVersion%' -Dpackaging=jar"


@echo off
echo **************************************************
echo JavaDocインストール
echo **************************************************
@echo on
powershell -Command "./mvnw.cmd install:install-file -Dfile='%javaDocFile%' -DgroupId='%groupId%' -DartifactId='%artifactId%' -Dversion='%jarVersion%' -Dpackaging=jar -Dclassifier=javadoc"

@echo off
echo **************************************************
echo Please Ctrl+Shift+P  [Developer: Reload Window]
echo **************************************************
@echo on
```

基本的にはWindowsのバッチファイルなので、色々察して自身の環境に合わせてほしい。
ポイントは基本的にバッチファイルなんだけどMavenのコマンドをPowerShellコマンドで実行しているところ。　
PowerShellコマンドを使わずに、直接```./mvnw.cmd ～```で実行すると、成否に関わらずそこで終了する。

## 2.cmdファイルを実行しjarファイル/JavaDocのjarファイルをインストールする
ターミナルで上記のコマンドファイルを実行する。
```./コマンドファイル名```　のように「./」を付けるのを忘れないように。

cursorやVScodeを起動した直後ならいいんだけど、１回ライブラリjarを使ったあとに修正したライブラリjarを再度インストールしようとするとエラーになる場合がある。

ちなみに↓のコマンドでエラーが出る分には無視して良い。
```powershell -Command "./mvnw.cmd dependency:purge-local-repository"```

↓のコマンドでエラーが出ている場合はインストールに失敗している。
```powershell -Command "./mvnw.cmd install:install-file ・・・```

jarファイルを掴んでいるからなんだけどcursorやVScodeを再起動すればインストールができる。
※そもそもインストールが上手くいかない人は、そっちを先に解消しといてね。

## 3.エディタ（cursor/VScode）を再読み込みする
インストールが正常にいった場合、エディタにjarを認識させるため再起動する。
・・・再起動はメンドイので再読み込みを行う。
```Ctrl+Shift+p```を押して```Developer: Reload Window```を選択し、エディタの再読み込みを行う。
（さっきのcmdファイルの最後に@echoで書いていたヤツ。忘れないように表示している）

ちなみにjarの再インストールが上手くいかないときもこのreloadを行うと上手くいく（何回かreloadすると上手くいく(笑)）
spxコマンドの良さとツラミ

AzureのSpeech to Text APIを使う時、いろいろ方法がありますが、簡単に自動化するにはspxコマンドを使うのがお手軽です。

### REST APIをcurlコマンド経由で行う場合 →　制限あり

REST APIは単発で実行するために、長時間に渡る処理は苦手です。
また、ファイルをアップロードするAPIは小さなファイルでしか対応できません。
大きなファイルを処理しようとすると、AzureBlobストレージにアップロードしないといけません。（Azureでなくても公開Webサーバーに置く方法もあるが、いずれにしても直接ファイルを処理できない）。

ということで、やりたいことに対して、やるべきステップが多いです。

一見、curlコマンド一発でできそうに見えてその後に「あれ？短いファイルしかできないぞ」というステップで後輩が数時間空転するのも無意味な時間なので、「RESTではやめとけ」というのが初弾のアドバイスになります。

### そこでspxコマンド

Azure上では文字起こしの一番お手軽な方法として紹介されていながらも、Qiita上ではタグとして存在さえしないspxコマンド。マイナーだけど手軽です。

### とはいえAPIを利用する面倒さは残る

#### キーとIDの違い

BingChatもまともに説明できないくらい、サブスクリプションキーとサブスクリプションIDと読んだり表記ブレが激しい。

speech to text と呼んだり音声変換と呼んだり表記ブレが激しいということに関しては人間もAIも間違えます。

途中で名前を変えると大混乱という教訓。

### spxコマンドのつらみ

spxコマンドもインストールは面倒です。
単なるAPIのラッパースクリプトかと思いきや、.NETのアプリケーションです。したがってUbuntuやMacにspxコマンドをインストールする場合にも、.NETフレームワークが必要です。私の手元のUbuntu20上でもLinux向け.NETはインストールできるのですが、最新版の.NET7がインストールされます。その状態でspxを動かそうとすると、spxは.NET5で動くんだけどあなたの環境は.NET7だからダメだよね。というエラーメッセージが出ます。ところが、.NET5はサポート停止されいてます。回避策としては、.NET7をアンインストールして、.NET6にダウングレードすることでspxコマンドが使えます。

spxコマンドはdockerでも配布されているので、依存関係を気にしたくない人や.NETのバージョンをコマンド一つのために変えたくない人はdockerバージョンを使うといいでしょう。この手の依存関係の激しさをみると、本気でクロスコンパイルしたかったらgo言語が一番バランスの良さが際立ちます。
[超ラク!!] 複数のWebサイトの状態を効率的に確認する方法

どもども、ogimanです。

最近、10以上のWEBサイトが含まれるシステムの大規模メンテナンスがありました。
その際にメンテナンス画面を作りました。

要件としては
- 外部からの一般的なアクセスを遮断させる(メンテナンス画面を表示させる)
- プロキシサーバ経由であればアプリケーションにアクセスできる

そこで問題が〜〜〜〜！？:scream:
メンテナンス画面設定後に10以上のWEBサイトの状態を一般アクセスとプロキシサーバ経由で各々アクセスするのが非常に面倒で、かつ時間がかかり非効率！！

あ〜〜〜面倒くさい！面倒くさいよーーーー:ghost:

ということで、
今回はこの問題を解決するために「複数のWebサイトの状態を簡易的に効率的に確認する方法」をメモっときます。

# 前提
- 私の環境はMacです。Windowsの方は多少の修正が必要かもしれません。


# 目的
- 複数のWebサイトの状態を簡易的に効率的に確認する。

# 誰向け
- インフラエンジニア
- システムのメンテナンス作業に立ち会うことがある方

# 現状
- メンテナンス画面設定後に10以上のWEBサイトの状態を一般アクセスとプロキシサーバ経由で各々アクセスを手動で確認している。

# 問題
- 10以上のWEBサイトの状態を確認するのに手動で確認している。
  - 時間が掛かる
  - 確認漏れが発生する

# 対処
Curlコマンドで効率的にしよ！

## 具体的

**対象のURLを設定する**
- ダブルクォーテーション内に動作確認するURLをセットする
- 複数ある場合は改行して追加する

```
url=("xxxxx.com"
"xxxxx.co.jp"
)
```

**プロキシサーバを経由する場合**
- 追加でプロキシサーバのURLとID・PWの追加が必要です。

```
proxy_url="プロキシサーバのURL"
login_id="プロキシサーバのID"
login_pw="プロキシサーバのPW"

```

- 実行コマンド

```
for i in ${url} ; do echo -n "[${i}] : " ; curl -X GET ${i} --proxy ${proxy_url} --proxy-user "${login_id}:${login_pw}" -o /dev/null -w '%{http_code}\n' -s ; done
```

**プロキシサーバを経由しない場合**

- 実行コマンド

```
for i in ${url} ; do echo -n "[${i}] : " ; curl -X GET ${i}  -o /dev/null -w '%{http_code}\n' -s ; done
```

## 実行例

**対象のURLを設定する**

```
% url=("https://www.google.com/"
"https://www.yahoo.co.jp/"
"https://www.bing.com/"
)

% echo $url
https://www.google.com/ https://www.yahoo.co.jp/ https://www.bing.com/
```

**コマンドを実行する**
-　[対象のURL]　　:　　httpのステータスコード

```
% for i in ${url} ; do echo -n "[${i}] : " ; curl -X GET ${i}  -o /dev/null -w '%{http_code}\n' -s ; done
[https://www.google.com/] : 200
[https://www.yahoo.co.jp/] : 200
[https://www.bing.com/] : 200
```

## 最後に
ちょっとした効率化ですが、小さい無駄を削減することで仕事の生産性が上がります！
大した記事ではないですが、今後もこんな小さなTipsや経験談を発信していきたいと思います。

この記事が少しでも参考になったら、 :heart: お願いします！
励みになります♪

ではでは、良い一日を〜
MavenでJavaDocのjarを作成する方法

ライブラリjarを作成し、他のプロジェクトに提供する場合JavaDocも提供すると色々と都合がよい。
Mavenでライブラリjarを作成するときに一緒にJavaDocのjarも作成してしまおう！

## pom.xmlを編集する
pom.xmlにJavaDocのjarを作成する設定を追記する。
```
	<build>
		<plugins>
            <!-- 他のplugin情報 -->
            ・・・
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-javadoc-plugin</artifactId>
				<version>3.6.3</version>
				<configuration>
					<show>protected</show>
					<!-- <doclint>none</doclint> -->
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>jar</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
        </plugins>
	</build>
```

ここでのポイントは２点
* confingrationの```<show>protected</show>```
これはJavaDocに公開するレベルをprotectedまで対象にする指定。
通常はpublicだけなので公開レベルを広げたければprotectedやprivateを指定する。
* confingrationの```<doclint>none</doclint>```
例ではコメントアウトしているが、コメントアウトを外すとJavaDoc生成時にdoclintツールのチェックを行わないという意味になる。（コメントアウトしているのでチェックが行われる）
Java 8以降、Javadocツールにはdoclintが導入されJavadocコメントのHTMLとドキュメントタグに対する様々なチェックを行うが、そのことにより標準に準拠した記載が必要となり、特定のフォーマット違反があるとJavadocの生成が失敗する。
標準に準拠した記載が望まれるが、どうしても準拠出来ない場合はチェックを無効にする。

上記の設定して```./mvnw.cmd clean package```や```./mvnw.cmd javadoc:javadoc```でJavaDocのjarを生成しよう。