OmniAICreator/Qiita-1.07M huggingface dataset:
非整数階微分

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。

## はじめに
前のエントリ『[非整数階積分（分数階積分）](https://qiita.com/kyamaz/items/831a5a437258ceb67048)』でリーマン-リウヴィル積分（Riemann-Liouville integral）を考えました。微分が積分の逆作用と考えると、非整数階微分（Fractional derivatives）という概念を定義することができます。この非整数階の微分については、Youtubeの[ずんだもんの定理【数学解説】](https://www.youtube.com/@zunda-theorem)さんが２本の動画を投稿されています。

https://www.youtube.com/watch?v=kwpQ5B0lI3M

https://www.youtube.com/watch?v=wSBrfl0Ox2A

本稿では、非整数階微分を紹介します。その前にまずは、リーマン-リウヴィル積分の定義を紹介します。

:::note info
<dl><dt>リーマン-リウヴィル積分</dt>
<dd>正の実数$\alpha$とすると，
$$\begin{flalign}
(I^\alpha f)(x) = {1\over \Gamma(\alpha)} \int_0^x (x-\tau)^{\alpha -1}f(\tau) d\tau \tag{A}
\end{flalign}$$
</dd></dl>
:::

# リーマン-リウヴィル微分
式(A)の逆操作として、微分を考えましょう。段階的に考えるために、$(I^\alpha f)(x)$の$1$階微分をとってみます。

$$\begin{flalign}
\frac{d}{dx}(I^{\alpha}f)(x) = \frac{d}{dx}\Big( I(I^{{\alpha}-1}f)\Big)(x)
=(I^{{\alpha}-1}f)(x)
\end{flalign}$$

同様に、$2$階$,3$階$\dots$と$k$階微分すると、

$$\begin{flalign}
\frac{d^k}{dx^k}(I^{\alpha}f)(x) = (I^{{\alpha}-k}f)(x) \tag{B}
\end{flalign}$$

となります。これは正の整数$k$、かつ$\alpha \gt k$であると自然な拡張ですが、$\alpha \lt k$で考えるには、次のように式(B)とは逆の記述を考えることとすれば拡張できそうです。

$$\begin{flalign}
\frac{d^{\alpha}}{dx^{\alpha}}(I^{k}f)(x) = (I^{k-{\alpha}}f)(x) \tag{C}
\end{flalign}$$

ここで改めて、リーマン-リウヴィル微分を定義します。$\alpha$階積分を$k$階微分することにより非整数階微分$D^{k-{\alpha}}$を導入します。

:::note info
<dl><dt>リーマン-リウヴィル微分</dt>
<dd>
$$\begin{flalign}
(D^{k-{\alpha}} f)(x) &\equiv {d^{k} \over dx^{k}} D^{-\alpha} f(x)  \\\\
&= {d^{k} \over dx^{k}} I^{\alpha} f(x) \\\\
&= {1\over \Gamma(\alpha)} {d^{k} \over dx^{k}} \int_0^x (x-\tau)^{\alpha -1}f(\tau) d\tau \tag{C}
\end{flalign}$$
</dd></dl>
:::

それでは幾つか例を挙げてみます。

例１）$f(x)=x$の$1/2$階微分

$$\begin{flalign}
\frac{d^{1/2}}{dx^{1/2}}x &= \frac{d}{dx}
\left( \frac{1}{\Gamma (\frac{1}{2})}\int_0^x (x-t)^{-\frac{1}{2}}
dt \right) \\\\
&= \frac{1}{\sqrt{\pi}} \frac{d}{dx} \left(
\int_0^x u^{-\frac{1}{2}}(x-u)du\right) & (u=x-t) \\\\
&= \frac{1}{\sqrt{\pi}}\frac{d}{dx}\left( x \int_0^x
u^{-\frac{1}{2}}du - \int_0^x u^{\frac{1}{2}} du\right) \\\\
&= \frac{1}{\sqrt{\pi}} \left(\int_0^x u^{-\frac{1}{2}}du + x \cdot x^{-\frac{1}{2}} - x^{\frac{1}{2}} \right) \\\\
&= \frac{2\sqrt{x}}{\sqrt{\pi}} 
\end{flalign}$$


## おわりに
非整数階微分には詳しく調べると不思議な結果を得ることもあるようですが、本稿は、非整数階微分の紹介にとどめさせていただきます。

ご一読いただきまして誠に有り難うございます。
（●）（●） Happy Hacking!
/""　＿＿""＼
言語処理１００本ノックやってみてる

現在チャプター03をpythonにも苦戦しながらやってみてる最中
わかる人がそもそも居るのかという感じでもあるけど、わかる人はわかるかと思うけど特に脳内の調子的にこういう事をやってる場合でもないけど何かと解決しないんでとりあえずやっとく
問題25で詰まってしまってるけどマストドンでの発言以外ではツイッター（現X）以外での発言は2015年？以降ぶりでかつ初めてのコード掲載記事なのでこの感じで


やってみた問題20のテキストの取得のコード
書いたのは先週の13日か14日ぐらいだった気が
なんかwikiのjson.gzファイルを使ってイギリスを指定するらしいので引数にfilenameとcountryとしmain関数から文字列を渡してる。
ほかの人の回答は見たような気もするけどまだちゃんと見てない。

```
def no20_get_jsontext(filename,country):
 text=''
 with gz.open(filename,mode='rt')as f:
  obj=[js.loads(line) for line in f.readlines()]
  for i,o in enumerate (obj):
   if o[key]==country:
    text=o[value]
 return text
 ```
CloudformationでS3バケット作成

S3バケットを作成するCloudformationテンプレートを作成しました。

# コード
コンソール上から、バケットを作成するときに設定する値を定義しています。

```yml
AWSTemplateFormatVersion: "2010-09-09"

Description: S3 Stack

Parameters:
  BucketName:
    Type: String

Resources:
  S3:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Ref BucketName
      # オブジェクト所有者は、全てのオブジェクトは「バケットを所有しているアカウント」
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerEnforced
      # 暗号化は、デフォルトのAmazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)
      # BucketEncryption:
        # BucketKeyEnabled: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      # パブリックアクセス無効
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      # バージョニング無効
      VersioningConfiguration:
        Status: Suspended
    DeletionPolicy: Delete

  # S3BucketPolicy:

Outputs:
  S3:
    Value: !GetAtt S3.DomainName
    Export: 
      Name: S3
```

## 実行
```shell
aws cloudformation create-stack --stack-name {stack_name} --template-body file://cfn_s3.yml --parameters ParameterKey=BucketName,ParameterValue={backet_name}
```

## ツマリポイント
各項目で、`''`などで囲う必要がある部分とそうでない部分があり、少しハマりました。
たとえば、`AES256`は囲わなくて良いが、`"AWS::S3::Bucket"`は囲う必要がある。
このあたりが慣れていなく、ドキュメントを見ながら進めました。
（ちなみに、Cloudformationテンプレートはjsonでも書けるので、jsonでは囲われていて、ymlでは囲われていないみたいなこともあって、ちょっと罠でした。）

```yml
BucketEncryption:
  ServerSideEncryptionConfiguration:
    - ServerSideEncryptionByDefault:
        SSEAlgorithm: AES256
```

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionbydefault.html


また、cloudformationに文法チェックのコマンドもあるので、これを利用するとどこが問題か確認できるので便利でした。

`aws cloudformation validate-template --template-body file://cfn_s3.ym`
Notchで突然ライセンスが読み込めなくなった時

# 症状
突然Learningライセンスでしか起動しなくなった。Webページ上ではちゃんとライセンスを持っているはずなのに...?
# エラーコードなど
CodeMeterのイベントを見てみると
```
2024-XX-XX 23:51:44: Entry (102820:850) not found - Event WB0035 (EXPIRATION TIME OVERRUN), Request IP-Address local(IPV4)(username,NotchApp.exe) with NoUserLimit 
2024-XX-XX 23:51:44: API Error 35 (EXPIRATION TIME OVERRUN) occurred! 
```
のように出ている。

# 解決方法
Notchのサポートに連絡すると、ライセンスのURLが送られてきて手動でActivationしてみてくれと言われる。手順の通りにやったら治った。
Forumなどでも似た質問がぽつぽつ見つかるが、基本的にはサポートに連絡するしかないよう?


# 追記(2025/05/31)
Notch1.0のRFXライセンスでインスタレーションを運用していて、突然同様の症状でライセンスが外れてしまった。
Notch Launcherから起動し、ログインをして戻った後にCodeMeter再起動で治りました...怖すぎ...



## 雑感
どなたかの助けになれば...!
現場など急ぎの時に発生したらどうするのだろうとは思う...
VSCodeで「ディレクトリ C:Users\〇〇を作成中にエラーが発生しました。」と表示される

VScodeを立ち上げるとディレクトリ「 C:Users\〇〇を作成中にエラーが発生しました。」と表示される．基本は無視してずっとこの状態で使っていたが，VScodeをバージョンアップしようとしたときにこのエラーのせいでできなかったのでさすがに対処した．

# エラーの原因
結論からいうとホームディレクトリの名前を変更したからである．PCの初回起動時に設定をミスった結果ユーザー名が漢字になってしまいC:Users\漢字の名前\みたいになっていたのが気にくわなくてなんか頑張って変更した．その際環境変数とかもろもろ新規の名前に変更したつもりであったが，変更漏れがあったっぽい．

# 試した方法
レジストリエディタから「\前のユーザー名\」を検索して片っ端から「\新しいユーザー名\」に変更する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/9874eae5-25f9-cf11-d559-ea1171f5b98a.png)

左上の編集から検索をクリックし，前のユーザー名で検索をかける．あとは力isパワーですべて変更する．ここらへん勝手に変えることに怖さはあったが，どうせ「\前のユーザー名\」はどうあがいても使えないんだから悪いことにはならないだろうと考えて変更．置換機能がなかったので一つ一つ変更していく

　さすがに途中からあまりの変更箇所の多さに手作業での限界を感じたのでレジストリ編集ソフト「[Registry Finder](https://forest.watch.impress.co.jp/library/software/regist_find/)」をインストール．

https://forest.watch.impress.co.jp/library/software/regist_find/

 これを使えば一括で置換できる．
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/fc8cd96e-b645-5957-0678-e92365115bb1.png)
まず左上の虫眼鏡のマークをクリックして，「Find what:」の項目から「\前のユーザー名\」で検索をかける．
検索後，虫眼鏡の横の「Replace」アイコンが使えるようになるのでそこで「Replace with」に「\新しいユーザー名\」を入力してReplaceする．

そのとき，一部は変更できないよってエラーが出るけどそのままで大丈夫（いいえを選択），これで大部分は変更できた．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/ea3e5be3-57d9-723e-ac39-dd8c3cb3bac4.png)

あとは，Registry Finderで一括変更できなかったものを手作業で変換していく．私はレジストリエディタに戻って変換したけど多分Registry Finderからでも大丈夫．

名前変更してるとたまに「その名前のやつもうあるよ！」みたいなエラー出てくるけどそのときは，項目ごと削除しちゃって大丈夫．もう新しいユーザー名で作られてるけど前の名前のやつがそのまま残っちゃってるだけなので残す価値なし．削除

# おわり
ちなみにまだまだ変更できてない箇所あったけどVSCodeでエラーでなくなったのでとりあえずよしとしています．
【M1Mac】仮想化ソフトUTMにGNS3-VMをインストールする方法

## 1.はじめに
GNS3でDockerやQemu建てたサーバ（Linux等）をトポロジに配置し、シスコIOSとのネットワークテストをやりたいと思いましたが、それらはGNS3-VMが必要とのことなので、ローカルサーバとは別にリモートサーバを仮想化ホストUTMで建てました。VMwareFusionでの構築はたくさん記事がありますが、UTMの記事はあまり見ないので今回書こうと決心しました！

## 2.M1Macのスペック及び仮想マシンの内容
◯スペック
OS：sonoma14.5
メモリ：16G
ストレージ：512GB
◯仮想マシン
OS：ubuntu18.04.6 LTS
メモリ（仮想）：8G
ストレージ（仮想）：30GB
→初期の20GBだとのちのちGNS3のproject数が増えるとストレージがすぐ圧迫するので！

## 3.GNS3-VMの構築のポイントその１
UTMでの仮想マシン作成は基本下記の通りに行えば問題ないです。

https://qiita.com/sakai00kou/items/f50e989d30d5e28c6dc9

今回のポイントとしては、M1Mac（ARM）アーキテクチャ上で**x86アーキテクチャ**をエミュレートする点です。x86ベースにすることで、アーキテクチャに起因するDcokerコンテナ起動、Qemu起動時のエラーが解消できます！！！（ARMに対応していないものが多い！！！）

![](https://raw.githubusercontent.com/bit-and-coffee/zenn-qiita-contents/main/images/utm-gns3vm-install/1.png)

上記の画像通りに「**Emulate**」を選択してください。

## 4.GNS3-VMの構築のポイントその２
上記の3項の通り仮想マシンをx86ベースで作成できればいよいよ**GNS3-VM**のインストールです。
インストールについては、下記の動画通りにやってもらえればOKです！！！

https://youtu.be/hHcQ5BCVHLg?si=qfYy5i_KSBGLLj2z

この動画では、シェルスクリップとで最新？のVMをインストールしてくれます。
無事にインストールが完了すればあとはGNS3上でリモートサーバ設定をするだけ。

![](https://raw.githubusercontent.com/bit-and-coffee/zenn-qiita-contents/main/images/utm-gns3vm-install/2.png)

リモート先を先程作成した仮想マシンのIPアドレスを指定すればOK！
（IPアドレスについては、UTMで仮想マシンを作成するときにNetoworkの項目をBridgeにしているので、自動的に自宅WiFiルータからのIPアドレスが払い出されるようにしています。）

接続はうまくいっていれば、ServerSummaryのランプが緑になります！

![](https://raw.githubusercontent.com/bit-and-coffee/zenn-qiita-contents/main/images/utm-gns3vm-install/3.png)

ちなみに、私のMainserverはVMWareの仮想マシンにインストールしてGNS3-VM（ARMアーキテクチャ）しています。
GNS3のアプライアンスによっては、ARM未対応のものもあるので色々試せるようにVM２本建てにしています。
下図のように色々と試せそうなのでワクワクしますよね！！！

![](https://raw.githubusercontent.com/bit-and-coffee/zenn-qiita-contents/main/images/utm-gns3vm-install/5.jpg)

## 5.さいごに
個人的にGNS3には大きな可能性を感じています。これからも開発が進んでGNS3上で色々なことが試せるようになることを期待しています。また、PCのスペックを積んでさらにたくさんのノードを配置したテスト等ができたらいいなと思っています。（M2Macmminiのメモリ24GBがほしいすぎる。。。）
【Oracle】SQLで文字列を0埋め/空白埋めする方法 


ORACLE MASTER Silver SQLを勉強中に見つけた、実務で使えるもの投稿していく。投稿の練習です。

#### ☆このページでできること
→「123」を「00123」に変換する

方法① **LPAD**　文字型→文字型
方法② **TO_CHAR**　数値型→文字型

---

## ①LPAD(文字列,桁数,埋める文字)
```sql:書き方
SELECT LPAD('123',5,'0') FROM dual
```
**結果**
「00123」

#### ☆右側への埋め込みも可

`lpad` :文字列の左側に文字を埋め込む
`rpad` :文字列の右側に文字を埋め込む

<br>

#### ☆他の文字の埋め込みも可

```sql:例:「ABCDE」を「ABCDE*****」
SELECT RPAD('ABCDE',10,'*') FROM dual
```
**結果**
「ABCDE*****」

<br>

#### ☆埋める文字を省略すると、空白が埋め込まれる

```sql:例:「abc」を「    abc」
SELECT RPAD('abc',7) FROM dual
```
**結果**
「&emsp;&emsp;abc」

<br>


<br>
<br>

---

## ②TO＿CHAR(数値,数値書式)
```sql:書き方
SELECT TO_CHAR(123,09999) FROM dual
```
**結果**
「00123」


#### ☆数値書式で使用できる主な数値の書式要素


|書式要素|説明|例|結果例|
|---|---|---|---|
|9|9の数が有効な桁数を表す|999999|12345|
|0|桁数に満たない場合、先頭にゼロを付けた数値を表す|099999|012345|
|$|$記号を数値の前に付けて表す|$99999|$12345|
|L|ローカル記号を数値の前に付けて表す|L99999|¥12345|
|C|指定した位置にISO通貨記号を付けて表す|C99999|JPY12345|
|D|指定した位置に小数点を付けて表す|999D999|12.345|
|.|指定した位置に小数点を付けて表す|999.999|12.345|
|G|指定した位置に桁区切りを付けて表す|99G999|12,345|
|,|指定した位置に桁区切りを付けて表す|99,999|12,345|
static let について

## はじめに
私は最近プログラミングスクールにて学習をスタートした初学者で、学習していく中で疑問に思ったことや苦労したことなどについて記事を書いております。


知識が浅はかですので、間違っている部分があるかもしれません。
あらかじめご了承ください。

## static let について

'static let'は、Swiftにおいて定数として使用されるクラスプロパティを定義するために使用されます。この定数は、そのクラス全体で共有され、変更不可であり、最初に一度だけ設定されます。

これにより、変更されることがないことが保証された共有データを提供できます。

```swift
class Constants {
    static let appName = "FamousQuoteGenerator"
    static let maxFavorites = 100
}

// 定数にアクセス
print(Constants.appName) // 出力: FamousQuoteGenerator
print(Constants.maxFavorites) // 出力: 100
```

## static let の利点

不変性:
定数であるため、誤って変更される心配がありません。

クラス全体での共有:
staticプロパティであるため、クラスの全インスタンス間で共有されます。

効率性:
定数は一度だけ初期化され、その後は変更されないため、パフォーマンスの最適化に役立ちます

## static let と static var の違い

static letとstatic varの違いは、定数か変数かという点にあります。

#### ・static let: 定数として定義され、一度設定された値は変更できません。

#### ・static var: 変数として定義され、値を変更することができます

static letは、変更されることがないことを保証された共有データや定数を提供するために使用されます。一方、static varは、変更可能な共有データを提供するために使用されます。

## おわりに

名言生成アプリを開発中にstatic letに出会いました。

名言をユーザー操作によって書き換えたりする必要がないので、『不動』のstatic letなのですね。
LLVMのMachine IRの学習メモ #2

この記事は個人的な学習メモです。

- 前記事

https://qiita.com/joule/items/2b1dd70fa846a9ce7884

### MIRの構成

#### エンベデッドモジュール

MIRの前半にはLLVM IRのモジュールが記載される。これは、MIRにはグローバル変数や外部関数への参照、関数属性、メタデータ、デバッグ情報に相当するものがないため、IRの情報を完全にMIRに置き換えることができないという理由がある。

#### マシンファンクション

MIRの後半にはマシンファンクションが記載される。
マシンファンクションは複数のアトリビュートで構成される。

- name: ファンクションを識別する名前
- body: マシン基本ブロックとその命令列
- callSites: ファンクションのコールサイト情報

```mir
---
name:            inc
tracksRegLiveness: true
liveins:
  - { reg: '$rdi' }
callSites:
  - { bb: 0, offset: 3, fwdArgRegs:
      - { arg: 0, reg: '$edi' } }
body: |
  bb.0.entry:
    liveins: $rdi

    $eax = MOV32rm $rdi, 1, _, 0, _
    $eax = INC32r killed $eax, implicit-def dead $eflags
    MOV32mr killed $rdi, 1, _, 0, _, $eax
    CALL64pcrel32 @foo <regmask...>
    RETQ $eax
...
```

### マシン命令の構成

#### マシン基本ブロック

マシンファンクションのbodyに書かれるマシン命令は、基本ブロックの単位で記載される。
基本ブロックには```bb.<ID>```のように識別IDを含むラベルがついている。また、```bb.<ID>.<name>```のようにIDに加えて名前をつけることもできる。

```mir
bb.0.entry
  <instructions>
bb.1:
  <instructions>
```

#### ブロックの参照

定義したマシン基本ブロックを参照するときは```%bb.<ID>```や```%bb.<ID>.<name>```とする。

#### サクセッサー

```successors```はサクセッサーとなるブロックを記載する際のアトリビュートである。分岐先として複数のブロックを記載することができる。

```mir
bb.0.entry:
  successors: %bb.1.then, %bb.2.else
  <instructions>
bb.1.then:
  <instructions>
bb.2.else:
  <instructions>
```

分岐のブランチウェイトを記載することもできる。以下は2つのサクセッサーのブランチウェイトが32, 16で分岐することを示している。

```mir
bb.0.entry:
  successors: %bb.1.then(32), %bb.2.else(16)
```

#### 生存するレジスタ

マシン基本ブロックの開始時にデータが割り付けられているレジスタは```liveins```として宣言する。

```mir
bb.0.entry:
  liveins: $edi, $esi
```

#### その他の属性

マシン基本ブロックの属性として```IsAddressTaken```, ```IsLandingPad```, ```IsInlineAsmBrIndirectTarget```, ```Alignment```を付与することができる。

```mir
bb.0.entry (address-taken):
  <instructions>
bb.2.else (align 4):
  <instructions>
bb.3(landing-pad, align 4):
  <instructions>
bb.4 (inlineasm-br-indirect-target):
  <instructions>
```
markdown AI を使ってみた。AI 機能は、まだない

# はじめに
Qiitaの投稿キャンペーンで目についたので使ってみました。

# markdown AIとは？

## 最初の感想
最初使っていて、markdownエディタとしては特に書きやすいわけでもなく、 
AI機能も未実装で何のためのサービスなのかよく分かりませんでした。

## 公式サイトの説明
https://mdown.ai/content?id=335b81b2-bcb0-4dbb-83d0-531aa132181f

> Create a website easily using Mark Down!
> 
> You can complete everything from creation to publication on one screen, and you can easily display a preview before publishing.
> 
> The concept is not only for engineers to easily exchange information, but also for children to easily create websites and interact with people around the world.

翻訳：
> Mark Downを使用して簡単にWebサイトを作成できます！
> 
> 作成から公開まですべてを1画面で完了でき、公開前にプレビューを簡単に表示できます。
>
> このコンセプトは、エンジニアが情報を簡単に交換するだけでなく、子供が簡単にWebサイトを作成し、世界中の人々と交流することも目的としています。

つまり、これは

**AIを使って簡単にMarkdownを作成出来るサービス**

ではなく、

**Markdown形式で書いた文章を簡単にWebページとして公開でき、他の人とシェアできるサービス**

だったようです。であれば、markdown機能が不完全でもβ版として公開している理由にも納得がいきます。

よく見ると、キャンペーンページの概要にもしっかりと書いてありましたが、名称からの印象で完全に勘違いしていました。

> 弊社開発のmarkdown AIを使用した感想や、独自の使い方についての説明を投稿してください。
> 
> markdown AIとはQiitaでも採用されているMarkdownの記述をするだけで簡単にWebサイトを作成することができるwebアプリケーションです。
> 
> 今後AIを用いてMarkdown方式での出力ができるようになるので、さまざまな表現が可能です。


# とりあえず作ってみた
## 作り方
### 1. マークダウンで文章を書く
### 2. Viewボタンをクリック
最初迷いますが、公開するには、まず「View」ボタンでプレビュー画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/9c09165f-73f5-5d2a-1abc-5b28a9db7e57.png)
### 3. URLボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/bf126237-7dce-5712-279b-791ed2e94155.png)

### 4. Publishボタンをクリック
Publishボタンをクリックすると、ページが公開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/5901e169-2edb-85e6-a8f1-8a6f45f7535d.png)
  
このリンクで、他の人とページを共有することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/b6d507c8-fd7a-747b-a09f-87b3170dc740.png)

## 実際に作成したページ
https://storage.googleapis.com/topdowncom/content/gmfqBTxmxiOVg7e8kax6fbXKmDE2/0ddd704d-9504-41d3-b5ba-ebe885f8e32b/index.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/4b578dbd-94c6-676a-db61-2e52f61030da.png)

# 感想
## markdown エディタ
冒頭で記載した通り、エディタとしては使いづらいです。
最低限のプレビュー機能は備わっていますが、VSCodeのPluginなどと比べると機能が少ないです。  
AI機能が実装されるとのことなので、今後に期待します。

## Webページ公開
簡単に書いたものを共有できるのは便利ではありますが、エンジニアであれば、Gistなど他のサービスを使う方が手軽に感じました。
「誰でも（子供でも）簡単に」ということであれば、markdownではなく、Wysiwygエディタの機能があった方が嬉しいかと思います。

## その他
markdownやAIは主となる機能ではないので、名称は変えた方が良いかと思いました。

# 活用のアイデア
会議や料理教室等の内容を文字起こしして、AIを活用してmarkdown形式にまとめる。
それを、本サービスを使ってWebページにして参加者に共有する、などすると便利かもしれません。

# 最後に
公式でもどのような使い方を想定しているか、もっと具体的に示していただけると、利用イメージや応用した使い方が浮かびやすいかと思いました。
Realmマイグレーションエラー

## はじめに
私は最近プログラミングスクールにて学習をスタートした初学者で、学習していく中で疑問に思ったことや苦労したことなどについて記事を書いております。


知識が浅はかですので、間違っている部分があるかもしれません。
あらかじめご了承ください。

また、今回は自分用に残したいと思います。

## Realmマイグレーションエラー

RealmSwiftをPodsインストールしてアプリ開発をする中で、下記のようなエラーが発生しました。

:::note alert
Thread 1: Fatal error: Failed to instantiate Realm: Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Property 'QuoteDataModel.quoteLabel' has been removed.
- Property 'QuoteDataModel.characterLabel' has been removed.
- Property 'QuoteDataModel.quote' has been added.
- Property 'QuoteDataModel.part' has been added.
- Property 'QuoteDataModel.characterName' has been added." UserInfo={Error Name=SchemaMismatch, NSLocalizedDescription=Migration is required due to the following errors:
:::


![スクリーンショット 2024-06-16 23.58.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715605/b0424f91-8bd1-cc9f-bc5e-7a35771dc579.png)

## Realmマイグレーションエラーとは？

モデルの定義が書き変わってしまったので、Realm側が「どっちを信じればいいんだ？？」
と言っているエラーです。

もう少し掘り下げると、

マイグレーションエラーは、Realmデータベースのスキーマ（構造）が変更された際に発生します。スキーマが変更されると、Realmは古いスキーマのデータを新しいスキーマに適合させるためにマイグレーションが必要になります。

## 解消法

とても簡単で、

一度アプリを削除します。

#### なぜアプリを削除で解消されるのか？


アプリを削除すると、そのアプリが利用していたすべてのデータがデバイスから削除されます。これにはRealmデータベースも含まれます。アプリを再インストールすると、新しいスキーマでデータベースが再生成されるため、マイグレーションの問題が発生しなくなります。


## おわりに

Realmを使う際に、必要になる知識だと思うので
今回このようなエラーに出会えてよかったです。
バグを報告するプロセス

# この記事の想定読者
テストに関連する仕事をしているけど、
バグを報告するプロセスを脳内で整理できていない...
と悩む人

# この記事のゴール
・バグを発見~バグの修正までのプロセスを把握する
・バグを開発者に伝える時の情報の選択肢を知る

# 前提
ここでの単語の定義をします。
故障 = システムの実際の挙動が期待する挙動と異なる
欠陥あるいはバグ = 故障の根本原因。
欠陥レポート = 故障の情報をまとめた資料
JSTQB = Japan Software Testing Qualifications Board
日本のテスト技術者認定資格を発行している組織。
組織のサイト：https://jstqb.jp/

# プロセス
テストで故障が発見されてから修正されるまでのプロセスは以下の遷移図にあります。
このプロセスをJSTQBでは**欠陥ライフサイクル**と呼びます。

状態ごとに担当者がアサインされます。各担当者はアクションを行います。
その後、次の担当者に割り当てます。
こうして各人が状態遷移を進め、欠陥ライフサイクルが回転していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/e720bb90-afa3-ff8b-af23-2edf8036670a.png)

いくつか補足説明をします。
### 解決or延期
故障を修正するか、修正せずにリリースするかの判断をすること
(リリースまでの残り時間が少ない場合などに重要となる)

### 再現不能?情報不足？
欠陥を修正する際には、一般的に故障を再現します。
その再現ができない時、再現のための情報不足の時に
修正を拒否します。追加情報を要求することもありえます。

### 修正を確認
開発者が修正した後、テスト担当者は障害が再現されないことを確認します。
ここで直っていなければ修正待ちの状態に戻すこともあるでしょう。

### 解決済み
この状態に遷移すれば、それ以降はレポートを追いかける必要がなくなります。

# 欠陥レポートの書き方

欠陥レポートの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/479aa3e0-bd8a-ac18-abb4-0650dc941650.png)
引用元：https://knowledge.sakura.ad.jp/26627/

## 欠陥レポートのゴール
1. 欠陥ライフサイクルを回すため
2. プロジェクトの進捗を把握するため
3. プロセスが効率的かを評価するため
4. プロダクト/システムの品質を把握するため
5. テストの終了基準を満たしているか確認するため

## これらのゴールのために含める要素
<table>
  <caption>知識の整理のため私見でカテゴライズしました</caption>
  <thead>
    <tr>
      <th>ゴール</th> <th>情報</th>
    </tr>
  </thead>
  <tr>
    <td> 1. 欠陥ライフサイクルを回すため</td> 
    <td>欠陥発見者</td></tr>
<tr><td>  </td> <td>問題の概要</td></tr>
<tr><td>  </td> <td>問題の詳細</td></tr>
<tr><td>  </td> <td>故障の再現手順</td></tr>
<tr><td>  </td> <td>実際の結果</td></tr>
<tr><td>  </td> <td>期待の結果</td></tr>
<tr><td>  </td> <td>スクリーンショット</td></tr>
<tr><td>  </td> <td>故障を解決する優先度</td></tr>
<tr><td>  </td> <td>テスト環境</td></tr>
<tr><td>  </td> <td>欠陥レポートの現在のステータス</td></tr>
<tr><td>  </td> <td>欠陥レポートの現在の担当者</td></tr>
<tr><td>  </td> <td>問題を解決するためのアクションの実行・不実行の提案と決定内容と承認</td></tr>
<tr><td>  </td> <td>欠陥ライフサイクルの遷移の発生日、過去の所有者、アクション</td></tr>
<tr><td>  </td> <td>何を修正したかに関する情報、推奨されるテスト方法</td></tr>
</table>

<table>
<thead>
    <tr>
      <th>ゴール</th> <th>情報</th>
    </tr>
  </thead>
<tr><td>2. プロジェクトの進捗を把握するため  </td> <td>テストケース</td></tr>
</table>

<table>
<thead>
    <tr>
      <th>ゴール</th> <th>情報</th>
    </tr>
  </thead>
<tr><td>3. プロセスが効率的かを評価するため  </td> <td>欠陥を発見したテストタイプ</td></tr>
<tr><td>  </td> <td>欠陥が存在するサブシステムorコンポーネント</td></tr>
<tr><td>  </td> <td>問題を発見した方法</td></tr>
</table>

<table>
<thead>
    <tr>
      <th>ゴール</th> <th>情報</th>
    </tr>
  </thead>
<tr><td>4. プロダクト/システムの品質を把握するため
  </td> <td>システムのステークホルダへのインパクトの大きさ</td></tr>
<tr><td>  </td> <td>プロジェクトステークホルダーの利害へのインパクト</td></tr>
<tr><td>  </td> <td>ビジネスへのインパクト</td></tr>
<tr><td>  </td> <td>欠陥の種類</td></tr>
</table>

## 欠陥レポートの情報にとって重要な性質 
- 完全(不足がない)
- 簡潔
- 正確
- 客観的
- 適切
(必要な情報を選択していることだと解釈しています)
- タイムリー

# 参考資料
JSTQB テストマネージャ(ALTM) シラバス
https://jstqb.jp/syllabus.html#syllabus_advanced_altm
複数csvを1つのcsvにまとめるスクリプト

# はじめに
現在業務で、大量にcsvを出力している作業をしています。
（※ 大量にcsvを出力している業務とは？となりますが、そこは一旦さておき...。）

そんなcsvたちを最後にBigQueryへインポートする予定ですが、100ファイル以上のcsvを手動でインポートは日が暮れても終わりません。

なので、複数のcsvファイルを1つのcsvにまとめるスクリプトを書いたので、ここにアウトプットいたします。


# 実装

```sh:join.sh
#!/bin/bash

# 出力ファイル名
output_file="join_result.csv"

# 一時ファイル
temp_file="temp.csv"

# 既存の出力ファイルと一時ファイルを削除
rm -f "$output_file" "$temp_file"

# CSVファイルのリストを取得し、日付部分でソート
files=($(ls test_*.csv | sort -t '_' -k 3 -n))

# 最初のファイルのヘッダーを取得して出力ファイルに書き込み
head -n 1 "${files[0]}" > "$output_file"

# それ以降のファイルのデータ行を追加
for file in "${files[@]}"; do
    echo "Processing $file"
    # 最初の行（ヘッダー）を削除してデータを一時ファイルに追加
    sed '1d' "$file" >> "$temp_file"
done

# 一時ファイルの内容を出力ファイルに追加
cat "$temp_file" >> "$output_file"

echo "CSVファイルを統合しました: $output_file"

# 一時ファイルを削除
rm -f "$temp_file"
```

実行コマンドは、`sh join.sh`です。

# 解説
主な箇所を解説していきます。

```sh
files=($(ls test_*.csv | sort -t '_' -k 3 -n))
```

上記で、ディレクトリに格納しているcsvを取得しています。
ファイル名は`test_2018-01-01.csv`のように日付を入れています。

`sort -t '_' -k 3 -n`を記述することによって、日付をソートしてくれます。

```sh
head -n 1 "${files[0]}" > "$output_file"
```

複数のcsvファイルは、全てヘッダーが同じとなっています。
なので、最初に取得できたファイルのヘッダーを、出力するcsvに入れています。

あとは、それぞれのファイルのヘッダーを除いた行を、一時ファイルに入れます。
最後に、まとめたら完成です。

# まとめ
このシェルを使用すれば、数百ファイルを数秒で1つのcsvファイルにまとめることができます。

最初はrubyでやろうと思って作ったのですが、1行ずつ読むようにしないとできなくて、時間がものすごくかかってしまいました。
これを機に、`Linux`や`shell`を勉強していこうと思います。

最後までご覧いただき、ありがとうございました。
【2024年6月】Xcodeでx64とarm64に対応した.appを書き出す方法 (macOSアプリ)

こんにちは！
この記事では、Xcodeでx64とarm64に対応した`.app`を書き出す方法を紹介します！
(2024年06月19日 時点)

# テスト環境
- Xcode 16.0.0 Beta1 (おそらく、Xcode 15でも同じ)
- Mac mini (2023, 32GB-RAM)

# 仕組み
XcodeのArchive機能では、App Store Connectにアプリをアップロードしたりできます。
そのアプリは、`.xcarchive`拡張子のファイルに入っています。
ということは、arm64とx86_64のどちらにも対応しているBuildとしてArchiveし、
その中の`.app`拡張子を取り出せばいいという発想です。
(2024年06月19日 時点では成功)

# 注意
AppleシリコンのMacで動作確認しています。
Intelでの動作はできるか分かりません。

# 手順

## Any Mac (arm64, x86_64)に設定
![スクリーンショット 2024-06-19 0.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/d4b3bc6c-4348-4504-cc7a-3081331351ac.png)
↑ デバイス設定を表示し、

![スクリーンショット 2024-06-19 0.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/e8396eee-828b-5f8c-5e79-009644f35f79.png)
↑ Any Mac (arm64, x86_64)に設定

## Archive
![スクリーンショット 2024-06-19 0.13.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/5832b0d9-cc1a-dedb-7953-c6852a780cee.png)
↑ メニューバーからアーカイブ開始

## Finderで表示
![スクリーンショット 2024-06-19 0.22.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/c1e8bd8a-023e-243e-a940-d15b124f60fc.png)
↑ Finderで`.xcarchive`拡張子のファイルを表示

![スクリーンショット 2024-06-19 0.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/7cf33172-54a7-073a-1cf6-52ae8be13c05.png)
↑ 内容物を表示

## `.app`拡張子のファイルを取り出す
![スクリーンショット 2024-06-19 0.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518709/c0cb03d7-31bf-e26f-b98c-df62189ca52d.png)
↑ 現在の状態から`Products/Applications`に移動し、IntelとAppleシリコンのMacに対応したアプリをコピー
(注意: `Universal == AppleシリコンとIntelチップのMacに対応`ということです)

## 好きなところにペースト
好きなところにペースト

# 以上
どうでしょうか？
うまく.appを書き出せましたか？
この方法を使えば、AppleシリコンとIntelチップのMac用に1つのアプリファイルを配布するだけでいいですね！
それではまた他の記事で！
IBM Cloud Code Engine と Docker Hub でお手軽にアプリデプロイ

## はじめに

IBM Cloud Code Engine(以下 Code Engine) は、IBM Cloud が提供するフルマネージドのサーバーレスプラットフォームである。このプラットフォームは、コンテナ、コード、バッチジョブを実行するために設計されており、インフラストラクチャの管理やスケーリングを自動化する。ユーザーは、コードを直接アップロードまたは、Docker コンテナをデプロイにより、アプリケーションやジョブを実行できる。

https://www.ibm.com/products/code-engine

類似のサービスとして、他のクラウドベンダーでは AWS Fargate や GCP Cloud Run などが挙げられる。

今回は、この Code Engine と、Docker Hub を利用して、アプリをデプロイする方法についてサクッと紹介したい。

### なぜ Docker Hub も使うの？

Code Engine は他所から持ってきた 'アプリの素' からコンテナのインスタンスを作成し実行するようになっている。
アプリの素は、「ソースコード」もしくは「コンテナイメージ」だ。
今回はコンテナイメージを Code Engine に pull してきてアプリコンテナを作成 → 実行するべく、イメージの元の保存先として Docker Hub を選んだというわけだ。


## 前提

- 作業環境: MacBook Pro Apple M1 Max/Sonoma 14
- `docker` コマンド: `Docker version 25.0.4-rd, build c4cd0a9`
    - Rancher Desktop(Rancher Desktop by SUSE Version 1.13.1 (1.13.1)) でインストール
- アプリをコンテナ化するための Dockerfile 等はすでに用意されているものとする
- Code Engine のプロジェクト作成などの手順は割愛
- その他手順的なのも抜けている可能性あり

## やったこと

### 1. ローカルおよび Docker Hub での作業

プッシュするイメージを作成する。

```sh
# '--platform ..' のオプションは、M1 Mac でコンテナイメージ作成する場合に必要とのこと
docker build -t <image_name> . --platform linux/amd64
```

その後 Docker Hub にログインし

```sh
docker login -u <username> -p <password>
```

ローカルで作成したイメージを push するイメージと紐付ける。

```sh
docker tag ローカルイメージ名:タグ名 DockerHubのアカウント名/リモートリポジトリ名:タグ名
```

最後に、紐づけたイメージを Docker Hub に push する。

```sh
docker push アカウント名/リモートリポジトリ名:タグ名
```

### 2. Code Engine

Code Engine > プロジェクト > アプリケーションの作成

<img width=300 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/dcef1be7-dd09-6f28-ae4c-98799ef5f32f.png>

ここで、各項目は以下のように入力し、すべて終わったら **完了** をクリックする。
- レジストリー・サーバー: `https://index.docker.io/v1/`
- レジストリー・シークレット: [**後述**](#レジストリーシークレットに関して)
- 名前空間： [この作業](#1-ローカルおよび-docker-hub-での作業)で指定した `Docker Hub のアカウント名`
    Docker Hub(https://hub.docker.com/) にログインし、Repositories タブ画面で `namespace/リポジトリー（イメージ名）` となっているのが確認できる。(※画像でグレーアウトしている箇所)
    <img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/910535ae-f4b4-13c2-b12f-f24e85077240.png>

- リポジトリー（イメージ名）:[この作業](#1-ローカルおよび-docker-hub-での作業)で指定した `リモートリポジトリ名`
- タグ: Docker Hub に push したイメージに付与したタグ

#### レジストリー・シークレットに関して

上の画像で、「レジストリー・シークレット」はプルダウンメニューになっており、展開して **レジストリー・シークレット**の作成を選択する。

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/5144e527-8eb5-03bc-fb5b-afd6f2ad797d.png>

以下の設定を施す:

- ターゲット・レジストリー: `Dockerhub`
- ユーザー名: Docker Hub のユーザー名（ログイン名/docker login で使用するやつ）
- アクセス・トークン: ない場合新規に作成する必要あり
    - このページに行く: https://app.docker.com/settings/personal-access-tokens
    - **Generate new token** クリック
        - 生成したトークン（ランダムな文字列）をコピーして上の「アクセス・トークン」のところに貼り付ける

全て設定を終えたら、**作成** をクリックする。

#### ポートの設定

アプリがどのポートでリッスンしているかを設定する。
デフォルトでは 8080 となっているが、アプリがたとえば `3000` でリッスンしている場合は、それを入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671630/61ed4fb9-b797-4107-9557-2df8d1dc47fe.png)


## 終わりに

以上のセッティングを問題なく完了すると、アプリがデプロイされて URL が発行され、無事にアクセスできるようになる。（Public エンドポイントの場合）
CI/CD などを考慮するともう少し複雑になるが、「とにかくアプリをインターネット上で動かす！話はそれからだ」な状態において、サーバーレスは有効な手段の一つとなり得るのだろうと思う。
いまさらdockerを始めてみる⑥

# 前回
Dockerfileを記述し、imageをbuildする方法を学んだ

# Using the build chache
For each instrucion, Docker checks whether it cna reuse the instruction from a previos build
以前に似たようなinstruction(コマンド？)を実行していたら、dockerはcacheされた結果を利用して高速に処理を完了する

ただし以下の場合は無効
- RUNコマンドに変更があった場合
- COPYやADDによりimageにfileがコピーされた場合
- cacheがinvalidatedされたlayer以降のinstrucion

RUN, COPY, ADDには注意しろってこと？まあまだ使うことすらままんらないのに高速化とか気にしてもしゃーない気もするが

try it out
```
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
EXPOSE 3000
CMD ["node", "./src/index.js"]
```
```
FROM node:20-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production 
COPY . . 
EXPOSE 3000
CMD ["node", "src/index.js"]
```

上よりも下のほうがcacheの観点からみるといいらしい。共通項としてpackage.jsonを定義したほうが質のいいcacheになるから？
まだnodeもyarnも触ったことないからよくわからん。anacondaみたいな感じでbaseとなるpackege一覧を最初にぶっこんどく的な？

# Multi-stage build
By separating the build environment from the final runtime environment,, you can significantly reduce the image size and attack surface.
buildを分割することで小さくする？現状意味がわからない

try it out
1. リンクされたページに飛び、zipファイルをgenerateする
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/debbf6d7-87ee-fc17-a29b-36361a7a4ed6.png)
1. zipを解凍。dir内に以下のDockerfileを作成
```
FROM eclipse-temurin:21.0.2_13-jdk-jammy
WORKDIR /app
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline
COPY src ./src
CMD ["./mvnw", "spring-boot:run"]
```
1. 解凍したdirにcd.```docker image build -t spring-helloworld .```
1. imageがbuildされた![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/ccac1925-22ed-f57a-aca3-4dd8fe0949a1.png)
1. 動作確認 'docker run -d -p 8080:8080 spring-helloworld'
1. ふぁっ！？？![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/534792cf-a6ed-c5ad-d874-0162eecc087d.png)
1. 本当はこの後Dockerfileを
 ```
FROM eclipse-temurin:21.0.2_13-jdk-jammy AS builder
WORKDIR /opt/app
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline
COPY ./src ./src
RUN ./mvnw clean install

FROM eclipse-temurin:21.0.2_13-jre-jammy AS final
WORKDIR /opt/app
EXPOSE 8080
COPY --from=builder /opt/app/target/*.jar /opt/app/*.jar
ENTRYPOINT ["java", "-jar", "/opt/app/*.jar"]
```
のように分割して、ほらあなたのfinalimageは428MBになったよ。オリジナルは880MBなのにね！みたいなストーリー。
いや、今ところは400MB削減することよりも別のところに学習コストかけたほうがいい気がするんだが。。

ってことで今日はここまで。確かに有意義そうな内容ではあるけど、まだdockerよわよわな自分にとってはハードル高すぎるんでいったんスキップ。何の成果も得られなかったけど許してクレメンス
LeetCode挑戦日記：Day12

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 11. Container With Most Water

整数の配列`height`が長さ`n`で与えられる。
`n`本の垂直な線が引かれており、`i`番目の線の両端点は`(i, 0)`および`(i, height[i])`。

`x`軸と2本の線で構成される容器を見つけ、その容器が最も多くの水を含むようにする。

容器が保持できる水の最大量を返しす。

なお、容器を傾けることはできない。

## 素直に解いてみる → NG

### 考え方

1. `height`配列の全ての組み合わせの容量を計算する
1. 最大量を返す

### コーディング

```typescript
function maxArea(height: number[]): number {
    let max = 0;
    for (let i = 0; i < height.length - 1; i++) {
        for (let j = i + 1; j < height.length; j++) {
            const minHeight = (height[i] < height[j]) ? height[i] : height[j];
            const area = (j - i) * minHeight;
            if (max < area) {
                max = area;
            }
        }
    }
    return max;
};
```

### 結果

Time Limit Exceeded

## 改善：ループ数を減らす

### 考え方

自分では思いつけず...
以下を参考に改善しました。

https://leetcode.com/problems/container-with-most-water/solutions/5139915/video-simple-two-pointer-solution

### コーディング

```typescript
function maxArea(height: number[]): number {
    let max = 0;
    let left = 0;
    let right = height.length;

    while (left < right) {
        const area = Math.min(height[left], height[right]) * (right - left);
        if (max < area) {
            max = area;
        }

        if (height[left] < height[right]) {
            left++;
        } else {
            right--;
        }
    }

    return max;
}
```

### 結果

Runtime：65ms
Beats 84.55%

Memory：59.51MB
Beats 11.90%
Node.js と ws でシンプルな WebSocketサーバー ＋ Node.js v22 でフラグなしで使える WebSocket

## はじめに
以前から利用している「ws」と、Node.js v22 でフラグなしで使えるようになった WebSocket を組み合わせる話です。

### ws
以下の ws は WebSocketサーバーを準備するのに使います。

●ws - npm
　https://www.npmjs.com/package/ws

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3a8a2f70-48d7-046b-6614-74a3972b5003.png)

### Node.js v22 で WebSocket利用
Node.js v22 でフラグなしで使える WebSocket は、以下に書かれているものです。

●Node.js — Node.js 22 is now available!
　https://nodejs.org/en/blog/announcements/v22-release-announce#websocket

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3741c8c6-5f19-2bb6-cd54-133264ea5072.png)

ブラウザと同様に、WebSocketサーバーに接続するクライアントを、簡単にプログラム内で使えるようになりました。

## 実際に試す
### WebSocketサーバーを用意する
まずは WebSocketサーバーを用意します。

ws を npmコマンドでインストールし、以下の「Simple Server」の公式サンプルを参考に、WebSocketサーバーを準備します。

https://www.npmjs.com/package/ws#simple-server

```javascript:server.mjs
import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('error', console.error);

  ws.on('message', function message(data) {
    console.log('received: %s', data);
  });

  ws.send('something');
});
```

上記は、ポート番号 8080 で待ち受けをして、クライアントとの接続が確立した際には、クライアントに対してメッセージ「something」を送ります。
それと、クライアントからメッセージが送られてきた際に、受けとったメッセージの内容を出力します。

### クライアント側のプログラム
クライアント側のプログラムを準備します。

以下の、MDN のページのプログラムを使います。

●WebSocket - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/WebSocket

```javascript:app.js
const socket = new WebSocket("ws://localhost:8080");

socket.addEventListener("open", (event) => {
  socket.send("Hello Server!");
});

socket.addEventListener("message", (event) => {
  console.log("Message from server ", event.data);
});
```

上記は、サーバーに接続をして、接続後に「Hello Server!」というメッセージを送ります。
それと、メッセージを受けとった時に、受けとったメッセージの内容を出力します。

## 動作確認
上記の両方のプログラムを動かし、動作確認を行います。
サーバーを先に動かし、その後にクライアント側を動かします。

以下の左のウィンドウがサーバー側、右側がクライアント側ですが、サーバーとクライアントとの間でメッセージのやりとりが問題なく行えるのを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4c0c9540-73c4-b59f-052d-301cbec0c5b3.png)

Node.js でフラグなしで WebSocket が使えるようになり、JavaScript での WebSocket の利用が、以前より一段と手軽になりました。
CSSで超絶簡単にダークモード対応する（2024年最新版）

前回の記事はこちら

https://qiita.com/yamashee/items/d1f998b27371ca80ec80

というわけで、今回はダークモード対応の実装方法を紹介します。

ダークモードへの対応は基本的にCSSのみで行うことができます。
## prefers-color-scheme
ユーザーが選択しているモードがライトモード（標準）か、ダークモードかを検知して、それぞれ振り分けてくれるメディア機能です。

https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme

CSSではこのように記述します。
```css
@media (prefers-color-scheme: dark) {
  /* このなかにダークモード時のスタイルを記述します */
  body {
    background-color: #000;
  }

  p {
    color: #fff;
  }
}
```
## light-dark プロパティ
2024年からダークモード対応をより簡単にするための新しいCSSプロパティが使用可能になりました。
それが`light-dark()` プロパティ です。ライトモードとダークモードそれぞれ異なる色を簡単に指定することができます。

https://developer.mozilla.org/ja/docs/Web/CSS/color_value/light-dark

CSSではこのように記述します。
```css
.div {
  color: light-dark(#333, #fff);
  background-color: light-dark(#fff, #333);
}
```
このように、`light-dark()` プロパティの中にライトモードとダークモードそれぞれの色を指定するだけで、簡単にダークモードに対応することができます。

[Can I use](https://caniuse.com/mdn-css_types_color_light-dark)で各ブラウザへの対応状況を見てみると、対応率は69.31%と決して高くはないものの、Chrome, Safari, Firefoxなどの主要ブラウザには対応しているため、十分実用可能と言えるでしょう。
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/3eb8a40f-c9de-3261-b83d-ac5898bd6f3a.jpeg)

## 微調整
前述した通り、実装方法自体は簡単ですが、実際にすでに公開されているWebサイトを全面的にダークモード対応しようとすると、おそらく結構大変な作業になると思います。

[前回の記事](https://qiita.com/yamashee/items/d1f998b27371ca80ec80#%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AE%E3%83%87%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88)でも述べた通り、背景色と文字色を一気に変えることによって、どうしてもデザインのバグが発生してしまいます。

それらを修正していくには、実際にダークモードでの表示を確認して、一個一個修正していく必要があります。

### ダークモードの検証方法
ダークモードの表示を確認するには、端末やブラウザの設定を変更すれば、確認できますがいちいちそんなことするのも面倒ですよね。

大丈夫です。Chromeのデベロッパーツールでダークモードの検証ができます。
デベロッパーツールを開いて、右上「︙」をクリックし、「その他のツール」から、「レンダリング」を選択します。
![image (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/36a609d8-f2c1-0e40-f6dd-399b85acede9.jpeg)

CSSメディア特性 prefers-color-scheme をエミュレートするという項目があるので、prefers-color-scheme: darkを選択すると、ダークモードの表示が確認できます。
![chrome-dev2 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/db800934-6237-f904-0745-742e91d24648.jpeg)

ダークモードの表示が確認してみると、なにかしらデザインのバグは発生します。
例えばこのフォームのカテゴリ選択部分、ダークモード対応で文字色を白くしたことによって、白背景に白文字になってしまい、選択肢が見えなくなってしまっています。
![form.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/53c71b65-0ef2-2084-fcde-c27e0c9b99da.jpeg)
この場合に関しては、下記のように別途スタイルを指定することで、ライト/ダークの両モードに対応させます。
```css
select {
    /* 別途スタイルを指定する */
    background-color: #fff;
    color: #000;
}
```

## まとめ
クライアントからダークモードへの対応を依頼されることはまだまだ少ないと思いますが、ユーザーにとってダークモードはだんだん身近な存在になりつつあります。

もしダークモードで閲覧されることを想定していない場合、ユーザーはそのウェブサイトを、こちらが意図せぬ姿で見ている可能性があります。

それは、まだ多くのサイトがレスポンシブ対応できていなかったスマホ黎明期のように、ユーザーとデベロッパーに大きなギャップを生み出している可能性があります。

今こそ、ダークモードへの対応が必要なタイミングなのかもしれません。
『情報発信』は味方を増やす

## はじめに
今回は、社内で頼りにされてる人の特徴の1つとして、**積極的に情報発信する人**が挙げられると感じたため、積極的に情報発信することのメリットについて考えたことを書いていこうと思います。

私の周りにいる積極的に情報発信する人は
・自分が勉強をしたこと
・仕事で怒られたこと
・社内の面白いニュース
・社員全員に共通する対応事項のリマインド
・技術情報
というジャンルにこだわらない内容を、仲のいいメンバーが所属するteamsにて、記事のように投稿しています。
最近は、私もその人を見習い、同じteamsにて情報を発信するようにしています。

## 情報発信のメリット①<br>〜困った時に、頼られる対象となる〜
皆さんは、何か困った時誰に相談しますか？
分からないことがあった時、何も分からない人より、何か情報を持っていそうな人に相談しますよね。
困った時の対処法を情報発信していれば、同じように困った時にその情報を見た人の役に立つだけでなく、投稿者は困った時に対処ができる人間だと認識されて、一石二鳥になります。
社員全員に共通する対応事項のリマインドをすれば、自分も忘れないし、読者の対応遅れも防げてこれまた一石二鳥。
有益な情報を持っていて、自分で困難を乗り越えてきた投稿者と直接話していなくても、読者の中で、投稿者への信頼は高まり、困った時に頼りにされる対象となります。


:::note info
組織では、頼れる存在こそが社内で重宝されると思います。
正しい情報発信することは、その**頼れる存在になれる可能性が高くなるチャンス**になります。
:::

## 情報発信のメリット②<br>〜自分の備忘録を残せて、振り返りができる〜
調べたこと、勉強したことって人間であれば100%覚えておくことなんてほぼ不可能ですよね。
数年経てば、その時の自分がどんなことを勉強していたり、困っていたかなんて思い出すこともないでしょう。
ただ、投稿という形に残しておくことで、自分がどんなことを調べて、勉強したのか、他人に共有しながら自分も振り返ることができて一石二鳥。
ある意味、情報を継続して共有することは、自分の歴史の教科書のような存在になります。


:::note info
過去に発信した情報が、**未来の自分も他人も救う材料**になる。
失敗話も、それをどう乗り越えてきたかのプロセスを共有することで、それは**未来の失敗を防ぐ重要な手がかり**となります。
:::


## 情報発信時に気をつけていること① <br>〜自慢話はしらける〜 
たまに情報発信を、褒めてもらうための機会と履き違えている人を見かける。
ただ、今回のテーマである味方を増やす情報発信に、自慢話は正直いらない。
需要のある情報は、読者にメリットがあるが、自慢話は言ってしまえばただの投稿者がスッキリするだけで、読者にメリットがない。

:::note warn
他人が読んだとき、そして未来の自分が読み返した時に、有益な情報を発信する。
個人的NG例)〇〇の資格を取った！
個人的OK例)〇〇の資格を取るために、使用した教材
:::


## 情報発信時に気をつけていること② <br>〜文字だけの投稿は、とにかく見づらい〜 
せっかく発信した情報も、取扱説明書ですか？かのように大量の文章だけでは、読者も最後まで読もうと思わない。
読み手の目線で、読みやすいか、何を言いたいか分かりやすいように書くことを心がけています。

:::note warn
文字だけでなく、**画像の追加やフォントの強調**等でわかりやすく。
:::

## 『情報発信』は味方を増やす
・情報を持っている人は、頼られる存在になる。
・情報発信によって、コミュニケーションが生まれる。
・有益な情報を発信していれば、その情報を読んだ誰かを助けることができる。
・助けた誰かが、いつか自分が困った時の味方になってくれる可能性がある。

:::note info
何も発信しない人が多い中で、**情報発信する人はとても貴重**です。
どんな小さなことでも、発信という**行動をすることが大事**だと思います。
:::

もし、社内に情報発信ができそうなコミュニティがあれば、ぜひやってみてください！
きっと、未来の自分にも、投稿を読んだ人にもプラスになることでしょう。
【Vim】ハイフンを単語に含める方法

以下のコマンドを実行するとハイフンが単語に含まれるようになります。

```
:set isk+=-
```

実行前（`*`を押下）

![スクリーンショット 2024-06-18 23.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/4b7ad546-68c4-7edf-1857-109c3b15afe6.png)

実行後（`*`を押下）

![スクリーンショット 2024-06-18 23.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/93f2489d-4cf4-edeb-7120-39117de88f05.png)
herokuの検証コードがわからなくて詰みかけた話

# はじめに
ある日、herokuにログインしようとしたら「検証コード」を求められました。
調べてみると、アカウント登録時に表示されたワンタイムパス生成QRを用いた2段階認証が初期設定されているらしい。
そういえばQRで認証したような気がするな。。。QR保存してないし詰んだか。。。
というのが始まり。
Apple製品で認証した人は先に[こっち](#　iCloudに保存されてるかも)を確認推奨。

# ログインまでの流れ
公式ドキュメントを読んでいると、アカウントロックについての項があったのでひとまず記載のアドレスに復旧依頼のメールを送ってみる。(英語で)

https://devcenter.heroku.com/ja/articles/two-factor-authentication#recovering-from-lock-out

20時間後くらいに返信があり、以下の情報を教えてくれとの返答が。
・ [Herokuにデプロイされているn個のアプリの名前](#Herokuにデプロイされているn個のアプリの名前)
・ [Heroku上にデプロイされたn個のアプリれぞれの最新のコミットのgit SHA（ハッシュコミットID）（デプロイの日付を含む)](#Heroku上にデプロイされたn個のアプリれぞれの最新のコミットのgit)
・ GitHubに接続している場合は対応するGitHubのアカウント名
・ 接続されてるGitHubリポジトリのアプリ名またはリポジトリ名
・ Herokuアカウント作成日（Herokuアカウント確認メールに記載）

要求された情報をメールで送ると24時間限定のワンタイムパスを発行してもらえるので、ログインし2段階認証を再設定。
2段階認証を再設定。大事なことなので2回ry

# Herokuにデプロイされているn個のアプリの名前
ログインできないのにどーやって確認すんねん。
と思いつつローカルでガチャガチャしてると、ローカルリポジトリの接続先herokuアプリを確認できるコマンドを発見。
```bash:
$ git git config --list --local | grep heroku

remote.heroku.url=https://git.heroku.com/{application_name}.git
remote.heroku.fetch=+refs/heads/*:refs/remotes/heroku/*
```
または
```bash:
$ git remote -v

heroku	https://git.heroku.com/{application_name}.git (fetch)
heroku	https://git.heroku.com/{application_name}.git (push)
```
urlの`application_name`にあたる部分を連携する。
herokuで現状デプロイされているリポジトリ/ブランチの分確認。

# Heroku上にデプロイされたn個のアプリれぞれの最新のコミットのgit
herokuで現状デプロイされているアプリのコミットログを辿る。
```bash:
$ git log

commit 1742be22d8675bc30e78dfda11111111fc1ce44b (heroku/main)
```
`(heroku/main)`な感じのherokuのタグがついたコミットを確認。

# iCloudに保存されてるかも
Apple製品で認証した人はiCloudに保存している可能性あり。
apple製品ではパスワードの設定情報にワンタイムパスの機能を紐づけられるよう。
apple製品でQRを読み取った際、どのパスワードの設定にワンタイムパス機能を紐づけるか選択させられるので、適当な設定情報に紐づけている可能性あり。
設定の`パスワード`に保存されている各サイトのパスワード情報を確認すべし。
自分はamazonの設定情報に紐づけてました。。。
![スクリーンショット 2024-06-19 10.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3671028/d6e93ba1-abe1-b38d-19e8-fbee03f05a0a.png)
NotebookLMをつかってみた

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

# NotebookLMをつかってみた

いま巷で話題沸騰中のNotebookLMを早速つかってみました。
使い方のメモも含めて、感想を書いてみようと思います。

## 使い方

とても簡単で、使い方の説明もいらないくらいです。
まずはここにアクセスし、使いたいgoogleアカウントで
ログインします。

[NotebookLM](https://notebooklm.google.com/)

すると、こんな画面が表示されます。
まずは左上の「新しいノートブック」を選択します。
※Untitledノートは私がすでに作ったもので、
初回ログインには出てきません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/f20983cc-da10-c0ba-243c-1f4f7c0af073.png)

次は学習させたいソースを選択する画面が出てくるので、
お好みのソースを選択してください。
今回はウェブサイトにしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/e5820853-5beb-754a-2786-857bfd085d53.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/2fbbf826-8bba-31f4-5425-0c19f6aa0093.png)

そうすると、ソースを勝手に学習し、まとめてくれます。
今回ソースに選んだのは、昨日自分で書いた記事です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/262e1a0d-52ea-f69d-3901-b9652fbc0fc4.png)

記事がきれいにまとまってます。
さらに質問の候補まで作ってくれています。
この中にある「GitHub Actionsとは何か？」というを選択してみます。
すると記事の中から答えを探してくれます。
私の書いた記事には、そういった記載はないので
ちゃんとそういうことは書いてない、と返答してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/742c70b9-bce8-3d72-42fd-208c17664984.png)

ソースを追加したいときは左上にあるプラスマークを、
ソースを除外したいときはチェックを外すと良いようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/eaf85539-b180-423b-842a-8d9cc8e4b081.png)

「メモを追加」を選択すると、メモを追加できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/ccb4c057-0bf0-a083-fa29-8a3caaf0f39d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/24058b9a-f0a3-a9f2-938a-0595e35ec5c5.png)

先程の解答をそのままメモにすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/00d6b9b4-e64e-ded2-61e7-b374dcd73e49.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/66ca66d2-401b-4ee7-162f-02df0f0fe6b9.png)

また、使ったことはないですが共有することもできるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/ffd1275f-6eb5-c96c-f840-bb439e82d419.png)

以上、雑ですが簡単な使い方でした。

## まとめ

すごく便利です。RAGが簡単に使える。GUIが優れていて、
これなら非エンジニアの方でも使いこなせるのではないかと感じました。
一昨日のUnicodeの記事はNotebookLMを使って書いたのですが、
いくつかのソースを入れて、まとめて、メモにして、、学習も非常にはかどりました。
これは有料になっても使い続けたい。
この手のサービスやツールには「デザインの壁」があると感じてます。
便利でもとっつきづらいと使ってもらえない。
でも、このNotebookLMはわかりやすいデザインで、
その壁がないと感じました。
調べ物、まとめ、社内資料検索とかに抜群に効果を発揮できるのではないでしょうか。
おすすめです。
【PowerBI】数値に￥マークやカンマ区切りをつけて見やすくしよう

## 完成形

- 数値の先頭に￥マークがついている
- 3桁ごとにカンマを挿入して、数値を区切ってある

# 背景
デフォルトはこんな感じであまりにも見づらいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/db3166c0-e62d-bf98-a1c7-6b0402040e79.png)
よし、変えるか！と思ってもビジュアルの書式設定ではカンマ区切りや￥マークを付けられそうな箇所が見当たりませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/fc0a62f0-1ff1-9930-106a-f6f08dd488a0.png)


# 解決方法
￥やカンマをつける最もスタンダードな方法は**モデルビュー**から**書式をカスタムする**やり方です。
#### モデルビューを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/ddcc823c-b0e8-eb79-56c5-428259058d18.png)

#### 書式を変更したいフィールドを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/4e3f3b86-1042-bedb-8054-6f1c3ab6b7bd.png)

#### プロパティの書式設定からカスタム書式を書式を「￥#,##0」と設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/63bb53e2-7f2e-9cff-f1d8-062e8ec5d73b.png)

- #: 1桁以上の任意の数値を表します。先頭のゼロは表示されません
- ,:  3桁ごとにカンマを挿入して、数値を区切ります（千の位でカンマが入る）
- 0: 数値がゼロである場合でも、ゼロを表示します。桁数を固定するために使われます

#### この状態でカードを作成すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/13658127-53ba-f157-228d-57a5d54df734.png)
￥とカンマ区切りが反映されていますね！

※表示単位は千に変更しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/c8b73d44-c075-4608-7460-ab153dae5e3a.png)

## 補足
特定のビジュアルだけに￥マークを付けたい場合は、**AdvanceCardビジュアル**を使用してPrefixにて設定することも可能です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681026/f41ef331-fcde-386e-4d78-ef6dee607b69.png)
真夏のIT怪談夜話2024 -サーバールーム-

# はじめに

今の世の中、様々な技術が発達しておりまして、とても便利になっております。
しかしながら、まだまだ解明されていないと言うか、不思議なことってあるもんなんです。

今日は、そんな不思議なお話です。（実話）

# 背景
だいぶ昔になりますが、その当時、私は、携帯電話の交換局で作業をしておりました。
携帯電話っていうのは、相手と直接繋がっているようで、そういうわけでもなく、
いくつものサーバーを経由して、ようやく相手と繋がります。

そこは初めて入った現場だったんですが、先に先輩方が作業をされていて、増員で私も行くことになった次第です。

交換局については、こちらをご覧ください。
[https://time-space.kddi.com/au-kddi/20190801/2707.html](https://time-space.kddi.com/au-kddi/20190801/2707.html)

# 作業内容
携帯電話にはたくさんの基地局があって、それを束ねているのが交換局です。
そして、その交換局には何百台という数のサーバーがあって、その中に、エリアごとの基地局データが入ってます。

たまに障害で通信や通話ができないことがあると思いますが、だいたい基地局か、交換局のサーバーのどちらかで障害が起きてます。

私の作業は、サーバーに基地局のデータを設定したり、障害が起きた際に、原因を特定する内容でした。

# 休憩中の出来事
作業にもだいぶ慣れて、合間に休憩するくらいの余裕が出てきたころです。
いつも通り椅子に座って、たくさん並んでるサーバーを眺めてました。

しばらく眺めていると、ふと、サーバーのラックとラックの間を横切るお客さん。
手に何らかの資料を持って、読みながら歩いてます。

なぜお客さんだと思ったかと言うと、見たことがない方だったからです。

初めて見る方だなー、と思いつつ、暇なので、またしばらくサーバーをのんびり眺めてました。

しばらくすると、またサーバーのラックとラックの間を横切る、さっきのお客さんの姿が。

忙しそうだなー、、、と思っていると、また同じように横切る、お客さん。

ここで少し、違和感がありました。

# 違和感の正体

なぜ違和感があったかと言うと、お客さんはラックの間を左から右に横切りました。
毎回、左から右に横切る。何度見ても、左から右です。

しかし、右側には、出入口が無いんです。

私はサーバールームの入り口から入って右の一番奥にいて、そこから同じ方向を眺めている。
そうすると、そのお客さんが左側に戻るには、私に分からないように私の後ろを通るか、ラックの間を右から左に横切るしかありません。

しかし一度も、右から左には移動してないんです。
私の後ろでは先輩方が作業をしているので、通ったら誰かが気付きます。

知らない通路でもあるのか？？と思いながら、また作業に戻りました。

# 思い切って聞いてみた
それから同じことが何度も起きたので、別の協力会社で、そのプロジェクトで長く、私と仲の良いエンジニアに聞いてみました。

何度も見ているので、特徴は覚えてます。
年代、身長、髪型、髪の色、スーツの色や柄、雰囲気などを伝え、それが誰なのかを聞きました。

その瞬間、青ざめる友人。
彼が唯一、心当たりがあるのが、私が現場に入る少し前に、若くして亡くなった方だったんです。。

過労が原因だったのではないか、と言われていたようですが、
とても真面目な方だったようで、まだお仕事をされていたのかもしれません。

# 備考
私はてっきり、普通に仕事をしているお客様だと思ってました。
なぜかと言うと、姿がはっきりと見え、資料を持ってらっしゃったからです。

しかし、私しかその方を見ていない、というのも事実なので、そういうこともあるもんなんだな、と思った次第です。

# 最後に
IT業界には様々な仕事があり、より良いシステム、より安定したシステムのため、様々な方が、日夜働いていらっしゃいます。

自分の仕事に対する責任感も大事ですが、まずは健康であること、それが最優先です。
心の健康も体の健康もどちらも大事なので、困ったときは誰かを頼る癖をつけましょう。

本人だけでなく、周囲の方々も、お互いに声をかけあって、ワークライフバランス（仕事できっちり成果を上げて、プライベートも充実させること）を整えた社会人生活を送りましょう！

# 追記
第二弾も書いたので、よろしければこちらもご覧ください。
[真夏のIT怪談夜話2024 -夜間作業-](https://qiita.com/yam_dev/items/219b05d762522c9b1b07)
Linuxで名前解決を行う流れ

普段何気なく利用しているドメインですがどのように名前解決を行なっているか気になったことはありませんか？

今回はLinuxで名前解決を行う流れについてご紹介します。

## nsswitch.conf

linuxの「nsswitch.conf」は名前解決を行う際の順序が記述された設定ファイルとなります。

下記、該当ファイルのパスとなります。

```
/etc/nsswitch.conf
```

デフォルトでは下記のように「hosts」、「DNS」といった順番で登録されております。

```
hosts: files dns
```

## hosts

hostsファイルにはホスト名と紐づけられたIPアドレスを記述する事ができます。

hostsファイルは基本的にDNSサーバーを利用した名前解決より優先度が高く設定されております。

その為、本番環境切り替え前の動作確認等を行う場合等に利用されます。

下記、該当ファイルのパスとなります。

```
/etc/hosts
```

下記のように「IPアドレス」、「ドメイン」の順で記述する事ができます。

```
127.0.0.1   localhost
192.168.1.1 ドメイン
```

下記のように1つのIPアドレスに対して複数のドメイン名を指定する事も可能となっております。

```
192.168.1.1 ドメイン1 ドメイン2 ドメイン3
```

ただしワイルドカード等では指定できない仕様となっております。

## DNSサーバーの利用

続いてDNSサーバーを利用する方法となります。

一般的なサービス利用者はDNSサーバーを利用し名前解決を行なっているかと思います!

Linuxでは下記設定ファイルにて利用するDNSサーバーを指定する事ができます。

```
/etc/resolv.conf
```

下記はgoogleのDNSサーバーを指定した例となります。
ご利用用途に合わせて指定する事が可能となっております。

```
nameserver 8.8.8.8
nameserver 8.8.4.4
```
Windows10にて、phpredisを使えるようにする


### 開発環境
- Windows 10 Pro(64bit)
- PHP 8.3.4 (cli) (built: Mar 13 2024 11:42:47) (NTS Visual C++ 2019 x64)

:::note warn
phpredisは、composerにはないため、pecl経由でダウンロードすることになります。
:::

**※すでにWindows上にRedisがあって、起動していることが前提です。**

### 拡張機能を追加するまで
1.  [redis ](https://pecl.php.net/package/redis) へアクセス
2. 今回は、`6.0.0`のDLLリンクをクリック
3. 下部の`DLL List`から、自分のPHPの環境と合っているものをダウンロードする。
	1.　自分の場合は、`8.3 Non Thread Safe (NTS) x64` 
4. ダウンロードしたら、解凍して、`php_redis.dll`を、PHPの`ext`ディレクトリ内に入れる
5. `php.ini`に`extension=redis`を追加する
6. `php -v`を実行して、特にエラーが発生しなければ大丈夫。

### 実際に使ってみる
1. `php -a`で対話モードを呼び出す
2. 以下のコードが問題なく動作すればOK
```php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
echo $redis->ping(); // 問題なければ1が返る。

$redis->set('name', 'John');
echo $redis->get('name'); // John
```

### 参考リンク
- [phpredisの使い方まとめ](https://qiita.com/yudsuzuk/items/d88717e6e55b5c7fa16e)
- [phpredis / phpredis](https://github.com/phpredis/phpredis/blob/develop/INSTALL.md)
Node.js で Readline をシンプルに使う（1桁の数字の入力を扱う）

Node.js でキー入力をシンプルに取得したい、という状況があり、以下の標準モジュールを使った簡素なプログラムを作ってみました。

●Readline | Node.js v22.3.0 Documentation
　https://nodejs.org/api/readline.html

## 今回の内容の元にするサンプルプログラム
今回の内容の元にするプログラムは、上記の公式ページ内に書かれているものを使います。

具体的には、以下のものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f0ed0fc0-430e-db34-9215-d523629afcbc.png)

```javascript
const readline = require('node:readline');
const { stdin: input, stdout: output } = require('node:process');

const rl = readline.createInterface({ input, output });

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log(`Thank you for your valuable feedback: ${answer}`);

  rl.close();
});
```

処理の流れとしては、入出力に関する準備的な処理を行い、その後はユーザーからのキー入力を待ち受けます。
そして、ユーザーによるキー入力があったら、ユーザーに入力された内容を出力として返します。

## サンプルを書きかえる
上記の内容を書きかえて、以下の内容のものを作ってみました。

```javascript
const readline = require('node:readline');
const { stdin: input, stdout: output } = require('node:process');

const rl = readline.createInterface({ input, output });

rl.question('数字を入力してください (0-9): ', (answer) => {
  const number = parseInt(answer, 10);
  if (!isNaN(number) && number >= 0 && number <= 9) {
    console.log(`入力された数字は ${number} です`);
  } else {
    console.log('無効な入力です。0から9の数字を入力してください。');
  }
  
  rl.close();
});
```

大まかな流れは参照した内容と同じです。
違う部分は数字の 0 から 9 のみ受け付けるような処理にしているところです。

入力された内容が数字であり、なおかつ 0 以上 9 以下の値なら、入力された数字が何であったかを返します。一方で、それ以外の入力が行われた場合は、0 から 9 までの数字のいずれかを入力するように促すようにしています。

## 作ったプログラムの動作確認
上記を実行し、アルファベットや数字を入力してみました。
そして以下のように、意図したとおりの動作になっているのを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5b7afd56-0ea7-6f83-77b4-f53757d0648f.png)