OmniAICreator/Qiita-1.07M huggingface dataset:
MacOS X 10.4でファイル転送

我が家では10.4のiBook Dual-USBがありCDのリッピングなどでまだまだ現役です。

リッピングしたファイルを他のホストにコピーするには以下のような方法があります。

* scp
* ftp
* tftp
* nc

USBメディアを使う方法もありますが、USB 1なので激遅です。

scpはNetBSD 10とは鍵交換が失敗して通信できません。

ftpやtftpは設定が面倒です。

ここはncの出番です。

受け取るホストで

nc -l 8000 > hoge.tar

したあと10.4で

nc 10.0.1.41 8000 < hoge.tar

します。EOFの処理が出来ないようなのでファイルサイズを確認して終ったら^Cします。

mp3のようなファイルは圧縮されているので、gzipなどで圧縮しないほうが良いです。

ファイルが正しいか心配だったらmd5してみるのも良いかもしれません。

WiFi経由で40Mのファイルの転送が10分くらいでした。

EOFでcloseしなくて不便なのでOpenBSD版のncを使うことにしました。

https://qiita.com/yamori813/items/c9ce2738bc6620113959

tarを標準入出力で使ってncする方法もあります。

受け側

```
$ nc -l 8000 | tar xf -
```

送り側

```
$ COPY_EXTENDED_ATTRIBUTES_DISABLE=1 tar cf - --exclude ".DS_Store" * | ~/netcat-openbsd-mac-master/nc 10.0.1.41 8000
```

10.5以降ではCOPY_EXTENDED_ATTRIBUTES_DISABLEではなくCOPYFILE_DISABLEのようです。
USB PD 対応 50円マイコン CH32X035 

__20円マイコン RISC-V CH32V003とは__ の続編として __USB PD（PowerDelivery）__ 対応RISC-Vマイコン __CH32X035__ を触ってみます。
https://qiita.com/usashirou/items/35d53f4b659232b89a21
# USB PD対応のCH32X035とは
__USB PD__ の __PHY__ を搭載し __USBホスト、USB PD__ に対応している __RISC-Vマイコン__ になります。
__USB PD（PowerDelivery）__ として5Vだけでなく、__9V,12V,15V,20V__ の出力が可能です。
近年マイコンボードにもUSB Type-Cのコネクタが普及してきましたが、USB　PDに対応しているものは少なく電圧は5Vのままが一般的でした。
__CH32X035__ を使用するとUSB電源からモーターの駆動などに使える12Vや20Vの出力が可能なうえ、USBホストデバイスになれます。
ch32v003と同じくクリスタルレスで動作するのも特徴です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/dc1519cd-9c7b-1383-2544-96ea28b989f0.png)

https://www.wch-ic.com/products/CH32X035.html?from=search&wd=eyJpdiI6Ijk3bFJSb3ZYMTFQSythbzFmdkNIQlE9PSIsInZhbHVlIjoiNDNpdDlcL2dScGRcL3JHNldMcGlMZjlnPT0iLCJtYWMiOiJlMjU2ZjQ4MGVmZmE3NzA0NDAwYjY3YTRkNDZlOTY0Y2U0Y2JlZTM0MTYxYzIwMzllNTg2NmVlMzYwNjdmNDUyIn0=
# CH32X035 -EVTを触ってみる
今回は、__CH32X035__ の開発ボードである __CH32X035-EVT__ を触ってみましょう。
![CH32X035-1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/66cebca7-a443-6fbb-2b3b-2f4fa6c226f3.jpeg)

# ArduinoでUSB PDを触ってみる
Arduinoのサンプルをもとに __GPIOに合わせて出力電圧を変化させるプログラムの例__
特に問題なく、各電圧が出力されます。
ただし、対応していない場合　__20V__ が出力される事があったので要注意です。
![スクリーンショット 2023-09-16 200847.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d65f4fb0-a4c3-2680-99c2-3acf345d77cb.png)

# USB機能
ArduinoではUSBホストが使えないようなので、__MounRiver Studio__ のサンプルプログラムを使って __USBホストやUSB-HIDなどを扱った例__
キーボードとして認識しています。
![スクリーンショット 2023-09-16 200757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ddede5ff-89a7-0ca1-55e0-da3ac018fd4a.png)
![スクリーンショット 2023-09-16 200936.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/a195c3fc-c8a2-7b65-fe7b-7775750c6084.png)

# 総評
Arduinoの開発環境が十分に出来ていませんが、1個50円のマイコンにおいてUSB PDが扱えるというのはゲームチェンジとすら言えるのではないでしょうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3b1135c8-eef1-2515-f7f7-b1b3d7d48b62.png)
価格的にも __CH32X035__ をUSB PDとUSBホストを両立する必要はなく、どちらかだけでも十分に使用する価格のマイコンと言えます。
USB PDとUSBホストにより今後面白いものが作れるのではないかと期待しています。
SharePointのURLエンコードかかったリンクを日本語に戻す（Python版）

# はじめに
　SharePointやTeamsで日本語含むリンクをコピー&ペーストすると、パスにURLエンコードがかかって、長いし何のパスかわからない。リンクを日本語変換してから貼り付けたいなと思い調べてみた。

PowerShell版はこちら

https://qiita.com/tapitapi/items/549111fe2e651f59ebf7

# URLデコード
　Pythonで日本語のURLへデコードする方法。Pyhonの標準ライブラリ```urllib```を使う。
urlがデコードしたいURLだった場合の例。
```Python
import urllib.parse
urllib.parse.unquote(url)
```


# クリップボーにURL出力
　pythonでクリップボードを操作する場合は、専用ライブラリ```pyperclip```が必要になるのでpipでインストールする。
　```pyperclip.paste()```でクリップボードの内容をペースト。
　```pyperclip.copy('コピーする内容')```でクリップボードへコピー。

クリップボードのURLをデコードし、再度クリップボードにコピーするまでの一連の処理の例。
```Python
import pyperclip	#クリップボード操作
import urllib.parse	#url操作

#-------------------------
#URL変換関数
#-------------------------
def URL_decode(url):
	return urllib.parse.unquote(url)

#クリップボードからURL取得変換
url=URL_decode(pyperclip.paste())

#クリップボードにコピー
pyperclip.copy(url)
```
Google (GSuite) を IdP として Azure AD (Office 365) にサインインする方法

# Google (GSuite) を IdP として Azure AD (Office 365) にサインインする方法

*****
# 1, Graph 用 Azure Active Directory PowerShell モジュールに接続する				
	手順 1: 必要なソフトウェアをインストールする			
		❶	Install-Module -Name AzureAD	
			[Y] はいでインストール対応。	
				
	手順 2: Microsoft 365 サブスクリプション用の Azure AD に接続する			
		❶	Connect-AzureAD	
****
# 2, Microsoft PowerShell の Microsoft Azure Active Directory モジュールとの接続			
	手順 1: 必要なソフトウェアをインストールする		
		❶	Install-Module MSOnline 
			[Y] はいでインストール対応。
			
	手順 2: Microsoft 365 サブスクリプション用の Azure AD に接続する		
		❶	Connect-MsolService
		❷	Get-MsolDomain
*****
# 3, 既存ユーザーの ImmutableId を設定する							
			※「xxx.jp」の部分を対応ユーザーのメールアドレスに変更して下記コマンドを実行する。				
							
		❶	Set-MsolUser -UserPrincipalName xxx.jp -ImmutableId hogehoge@mail.jp				
							
		❷	確認コマンド				
			※「xxx.jp」の部分を対応ユーザーのメールアドレスに変更して下記コマンドを実行する。				
			Get-MsolUser -UserPrincipalName xxx.jp | Select ImmutableId				

# 参考となるサイト

https://support.google.com/a/answer/6363817?hl=ja

https://www.misuzilla.org/Blog/2019/07/26/FederatingGSuiteWithAzureActiveDirectory

https://docs.microsoft.com/ja-jp/office365/enterprise/powershell/connect-to-office-365-powershell


****
# 一括更新コマンド	
	Get-MsolUser -ALL | ?{ $_.UserPrincipalName.EndsWith("ドメイン") } | %{ Set-MsolUser -UserPrincipalName $_.UserPrincipalName -ImmutableId $_.UserPrincipalName }

# 結果確認コマンド	
	Get-MsolUser -ALL | select UserPrincipalName , ImmutableId

# ライセンスが付与されていないユーザーを確認する	
	Get-MsolUser -All -UnlicensedUsersOnly
	
# ライセンスが付与されているユーザーを確認する	
	Get-MsolUser -All | where {$_.isLicensed -eq $true}
	
# 特定のユーザーのライセンス付与の状態を確認する	
	(Get-MsolUser -UserPrincipalName test1@mail.jp).Licenses.ServiceStatus
	
# 全ユーザー確認	
	Get-MsolUser -All
	
# 「NewUserPrincipalName」列に変更後のユーザープリンシパル名を記載。

	Set-MsolUserPrincipalName -UserPrincipalName Colin@mail.jp -NewUserPrincipalName colin@mail.jp

****
正規表現の活用 CSVの体裁を変えずに特定のデータを抽出する

## csvの体裁を変えずに特定のデータだけ抽出したい
エンジニアを約１年やってきて、こんな時正規表現が役立った！という場面を記録。

### 使用アプリケーション
- サクラエディタ
- Visual Studio Code

たとえば、下記のようなデータがあり、リンゴが含む行だけ抽出してCSVの形を維持したい場面があるとします。
```csvs:fruits.csv
    "ID", "果物の名前", "色",
    "01", "リンゴ", "赤",
    "02", "みかん", "オレンジ",
    "03", "リンゴ", "青",
    "04", "ブドウ", "紫"
```

抽出と聞いてすぐに思いつく方法は、Excelでフィルターをかける方法だと思います。しかし、その方法であるとCSVをExcelのシートに取り込む際にダブルクォーテーションが削除されてしまいます。そのため、ここで活用できるのが正規表現です。

私が使用した正規表現は下記です。
```
^(?!.*リンゴ).*$
```
特定の文字を含まない列が対象となる正規表現です。こちらで対象となる行を空文字で置換し、さらに改行を示す下記の正規表現を空文字で置換することで「リンゴ」を含む行のみ抽出することができます。
```
^\r\n
```

## まとめ
この正規表現はただ○○を含む行のみを抽出したいという時によく使用しています。
一度履歴として残っていると、いざとなったときに使用することができるため特にサクラエディタで使用することをおすすめします。


# English ver.
## How to extract specific data　from a CSV without altering its format

After working as an engineer for about a year, I've encountered situations where regular expressions proved to be useful! Here's a record of one such instance:

### Applications Used
- Sakura Editor
- Visual Studio Code

For example, let's say you have the following data, and you want to extract only the rows containing "リンゴ" (apple) while maintaining the CSV format:

```csvs:fruits.csv
    "ID", "果物の名前", "色",
    "01", "リンゴ", "赤",
    "02", "みかん", "オレンジ",
    "03", "リンゴ", "青",
    "04", "ブドウ", "紫"
```

The first thought for extraction might be using Excel's filtering. However, using that method, when importing CSV into an Excel sheet, the double quotations get removed. Therefore, regular expressions can be handy in this situation.

The regular expression I used is as follows:
```
^(?!.*リンゴ).*$
```
This regular expression targets lines that do not contain a specific word. By using this regular expression to replace matching lines with an empty string and further using the following regular expression to replace newlines with empty strings, you can extract only the lines containing "リンゴ" (apple):
```
^\r\n
```

## Summary
I frequently use this regular expression when I need to extract only lines containing specific keywords. Once it's saved in your history, you can easily use it when needed, making it especially useful in Sakura Editor.
Bootstrap 5 アップデートエラーの記録

## Error: Undefined variable. 'primary': $primary-text-emphasis-dark,

Bootstrap 5.3 へのアップデートで発生。
解決法: Sass の Bootstrap 変数を設定している箇所で `$enable-dark-mode: false;`


## Deprecation Warning: Passing percentage units to the global abs() function is deprecated.

v5.2 → v5.3.1 アップデートで発生。
原因は、Dart Sass v1.65.0 以降、パーセント単位をグローバル abs() に渡すことは非推奨になったため。
v5.3.2 へのアップデートで解決する(divide() 関数に渡される値を変更することで内部的に修正)。
v5.3.2 へのアップデートが無理な場合は、dart-sass を 1.66 → 1.64.2 にダウンデートで解決。
[dart-sass deprecation warning: Passing percentage units to the global abs() function is deprecated. · Issue #39028 · twbs/bootstrap](https://github.com/twbs/bootstrap/issues/39028)
Javaで「累乗した値を取得する」の動作を確認してみた

# 概要

Javaで「累乗した値を取得する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/math/index4.html

# 実装

以下のファイルを作成しました。
```JSample4_1.java
class JSample4_1{
  public static void main(String[] args){
    double d = 3.0;

    System.out.println(Math.pow(d, 0.0));
    System.out.println(Math.pow(d, 1.0));
    System.out.println(Math.pow(d, 2.0));
    System.out.println(Math.pow(d, 3.0));
    System.out.println(Math.pow(d, 4.0));
    System.out.println(Math.pow(d, 5.0));
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample4_1.java 
$ java JSample4_1 
1.0
3.0
9.0
27.0
81.0
243.0
```

# まとめ
何かの役に立てばと。
SQLでのFizzBuzz

さっき、記事にまとめたSQLの書き方で
私なりのfizzbuzzを作るとこんな感じになります。

https://qiita.com/tako_and_kitune/items/f273ce61baecd6351473

2025/03/15 追記
もっと楽なSQLがあった。
```sql
with seq  as (select  generate_series(1,100,1) as seq)
   , fizzbuzz as (select 3 as num ,'fizz' as str
                        union
                  select 5 as num ,'Buzz' as str)

select seq.seq 
        ,coalesce(string_agg(fizzbuzz.str,'') , seq.seq::text) as FIZZBUZZ
    from seq
    left join fizzbuzz 
              on seq.seq % fizzbuzz.num = 0
group by seq.seq
order by seq.seq
    
```











```sql
with seq as (select generate_series(1,100) as seq)
, fizzbuzz as (select * 
                 from ( values (3,'fizz') 
                              ,(5,'buzz' ) 
                              , (15,'fizzbuzz')) as t (num , text))

select seq.seq
        , coalesce((select text     
                                from fizzbuzz 
                              where seq % num = 0 
                              order by num DESC
                              limit 1)
          ,seq ::text) as fizzbuzz
from seq
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319265/ad18f8aa-83bb-548d-ba6a-39676a837f28.png)
【Linux】ssh公開鍵認証

## SSHクライアントでの作業

・公開鍵の作成

```
# ssh-keygen -t rsa -b 4096
Enter file in which to save the key (/root/.ssh/id_rsa):<エンターを入力>
Enter passphrase (empty for no passphrase):<エンターを入力>
Enter same passphrase again:<エンターを入力>
```

・ディレクトリの権限を変更

```
# chmod 700 ~/.ssh
```

・公開鍵をSSHサーバに転送

```
# ssh-copy-id -i ~/.ssh/id_rsa.pub user@192.168.10.100
```

## SSHサーバでの作業

・権限を変更

```
# chmod 700 ~/.ssh
# chmod 600 ~/.ssh/authorized_keys
```

・sshd_configのバックアップ

```
# cp -ip /etc/ssh/sshd_config /etc/ssh/sshd_config.org
```

・sshdの設定変更
```
# vi /etc/ssh/sshd_config
```

```
PasswordAuthentication no
AuthorizedKeysFile      .ssh/authorized_keys
```

・サービス再起動
```
# systemctl restart sshd
# systemctl status sshd
```

# 動作確認

・SSHクライアントでパスワードなしでSSHログインできることを確認
```
# ssh -i ~/.ssh/id_rsa user@192.168.10.100
```
【CSS】フォーム苦手でも簡単！ ラジオボタンやチェックボックスの背景色を変えてみよう！

🌻フォーム苦手でも簡単！
ラジオボタンやチェックボックスの背景色を変えてみよう！

👇たったこれだけ！！
form { accent-color: #AC582F; }

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEVXGKL" data-user="tomok7" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tomok7/pen/ZEVXGKL">
  accent-color</a> by tomok7 (<a href="https://codepen.io/tomok7">@tomok7</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

色はきんにくんの胸筋をスポイトしました💪😁

試してみてね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/6d46107b-2c41-3eca-904a-a7d566c2ba6e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/a06136b0-64fa-b4c9-6ee4-58eb134e4705.png)
notionでdraw.ioを挿入・編集する

# はじめに
notionでDraw.ioを挿入・編集したいことってありますよね？
そのやり方教えます。

# 前提
1. googlechromeに、以下のプラグインを入れてください。
https://chrome.google.com/webstore/detail/drawio-for-notion/plhaalebpkihaccllnkdaokdoeaokmle?utm_source=app-launcher&authuser=0
    ↓のように、拡張をピン止めしておくと楽だよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/e6298e9a-d5a3-f95e-91fe-615d2d509a81.png)

2. 挿入したいdrawioのsvgファイルを用意してください。
    今回は、以下を作成し、svgファイルにエクスポートしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/303ea2da-5411-0bf4-66f1-b2f2a72f585b.png)

# 手順

## notionのページを開く
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/4b0703db-f3ed-ab0f-ab6f-533ccab8aa4a.png">

## 拡張機能がnotionでアクセス許可されているか確認
notionのページ開いて、拡張機能のアイコンにカーソル合わせて確認してください。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/d580f4e0-11a5-5e26-8a49-0131af4f9259.png">

## svgファイルをドラッグアンドドロップ
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/8ad22db3-c092-8ec4-7b48-1ce5ab3e1263.png">


## 図形をクリックすると、編集できます。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/06732f58-4026-c249-58d1-1f632930ce11.png">

↓おっきな画面でやりたい人は、"フルスクリーン"アイコンをクリックしてください
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/f312bc1e-2c6c-65af-0003-723ce16c1da7.png">


# 本当にやりたかったこと
"Insert Diagram"ってボタンで、notionのページにdrawioの編集画面でてくれてほしかったですけど、出来ませんでした。
なぜかは、わかりません。

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/17b7726e-8a6c-4f84-1d6e-47892ad78fde.png">


↓ボタンをクリックするとこんなエラーが出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/01734594-7f69-f978-1d60-85827dc8d969.png)

# notionの埋め込みURLを作成してやろうしているけどうまくいかない人へ
まじであきらめたほうがいいです。
<img width="500" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333125/6c392d68-2265-6ed9-a0dc-dc7a4cd8c94f.png">
さくらサーバーのメールをGmailで読む


あるメールアドレスのメールを外部から読みたい場合、普通は転送設定を行うと思います。しかしさくらサーバーの場合、 **MTA(maildropらしいです)の不具合によりテキストメールのDKIM署名が破壊されます** (HTMLメール(正確にはmultipartテキストメールを含む)だと大丈夫なようですが、かなりメーラー依存となることは想像に難くない[^1])。DMARCにはSPFとDKIMがありますが、さくらドメインのままの場合SPFは使えないのでDKIMに頼らざるを得ないのです。

- https://sakura.uservoice.com/forums/913570-%E3%81%95%E3%81%8F%E3%82%89%E3%81%AE%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90/suggestions/44993737-%E3%83%A1%E3%83%BC%E3%83%AB%E8%BB%A2%E9%80%81%E3%81%A7dkim%E7%A0%B4%E6%90%8D
- https://sakura.uservoice.com/forums/913570-%E3%81%95%E3%81%8F%E3%82%89%E3%81%AE%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90/suggestions/34858240-%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AEdkim%E5%AF%BE%E5%BF%9C

この辺でも触れられていますが、肝は **メール本文が勝手にデコードされる** ことにあります。HTMLメールだとデコードが発生しないので問題ないというわけですね。

さてこんな状況ですが、Gmailでさくらサーバーのテキストメールを読むことに成功しました。

----

方法ですが、 **転送設定をきっぱりやめてしまい** 、GmailのPOPアクセスを使うことです。なお(この用途の場合)メールのコピーを残す設定はしないほうが良いでしょう。

cf: https://www.google.com/search?q="自分のPOP3メールアカウントを追加"+gmail

表題がGmailに限定されてることからもお察しです。

PS: こんな馬鹿な設定、戻したいです。

[^1]: この際だから言うてしまいますが、結城浩先生にメーラーを変更して頂く必要が生じました。本当です。
[Xcode] テストをforやwhileを使わずに複数回実行する方法

asyncなテストを実装した際、複数回実行するとまれに失敗することがあります。信頼性を向上させるためにテストを複数回実行してもテストが失敗しないことを確認する必要があります。
そこで今回はテストをfor文を使わずに何回も繰り返す方法を発見したので紹介します。

# 方法
複数回実行したいテストのここを右クリックします。

![スクリーンショット 2023-09-17 3.08.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627061/eb31a193-2874-c496-eca2-2baf90f7b704.png)

次に、Run "<テスト名>" Repeatedly...をクリックします。
![スクリーンショット 2023-09-17 3.11.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627061/47cfeeaa-88a2-6bce-1c91-67a80ecfad79.png)

すると、このような画面が現れます。
![スクリーンショット 2023-09-17 3.12.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627061/8082b1c9-9d93-8256-f080-3418646ace04.png)

ここでは実行する際の細かい設定が行えます。
Stop Afterでは、何をTriggerにテストを中断するかが決められます。
Failureが失敗した時, Successが成功した時に中断, そしてMaximum Repetitionsが失敗でも成功でも中断しないようにすることができます。

実行してみると、しっかりとテストが100回繰り返していることがわかります。
![スクリーンショット 2023-09-17 3.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627061/439d690a-a381-d10e-aa76-14b15d07a456.png)

# さいごに
複数回実行するのにforを使っていたのでこれは便利ですね。
3D Slicer まとめ

# Github

https://github.com/Slicer/Slicer

# 概要

# preparetion
## ubuntu 20.04
```
sudo apt update && sudo apt install git subversion build-essential cmake cmake-curses-gui cmake-qt-gui   qt5-default qtmultimedia5-dev qttools5-dev libqt5xmlpatterns5-dev libqt5svg5-dev qtwebengine5-dev qtscript5-dev   qtbase5-private-dev libqt5x11extras5-dev libxt-dev
```
ChatGPTなどで見かけるTop PとTemperatureを雑に理解

# はじめに
OpenAIのAPIのパラメータやAzure OpenAIのプレイグラウンドでよく目にする「Top P」と「Temperature」の違いについて、簡単に理解したのでメモとして残す。
詳しい理論などについてはこの記事では触れない。

# Top PとTemperatureの違い。
以下の図は、横軸にモデルの出力（回答候補）を、縦軸にその出力候補が正しい確率を表示している。
![Temperature_TopP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401742/e1528082-aa03-92fd-d93c-db6927c482ac.png)


## Top P
Top Pは出力の確率が高い順にソートした際の、上位何％までの出力を回答候補として考慮するかを定めるパラメータである。
Top Pの値を低く設定すると、選ばれる回答候補が少なくなり、結果として出力の回答が一貫性を持つようになる。

## Temperature
Temperatureはモデルが出力する確率分布の形を調節するパラメータである。
Temperatureの値を低く設定すると、出力間の確率の差が大きくなり、逆に値を高く設定すると、出力間の確率の差が小さくなる。
ゆえに、Temperatureの値を低くすることで、高い確率の出力が選ばれやすくなり、回答の一貫性が高まる。
【x64】アセンブリ読解の基礎知識①

# 目次
- 対象読者
- この記事を読んで得られるもの
- intel記法とAT&T記法
- オペコードの接尾辞
- leaとmovの違い
- おすすめ文献
- 参考文献

# 対象読者
- アセンブリ初心者
- とりあえずアセンブリに関する知識が欲しい人
- x64アーキテクチャに興味がある人
- mov、add、オペコード、オペランドのような超基礎的なことは知っている人

# この記事を読んで得られるもの
- アセンブリの基礎的な知識

# intel記法とAT&T記法
アセンブリには、**intel記法**と**AT&T記法**の2種類の表記法があります。これら2つの記法は、使う記号とオペコードの表記が異なっていたり、オペランドの順番が逆になっていたりします。

以下のコードは2つの記法で``5``を``eax``に代入する処理を書いたものです。

### intel記法
```nasm
mov eax, 5
```
### AT&T記法
```nasm
movl $5, %eax
```
英語wikiに違いが載っています。

https://en.wikipedia.org/wiki/X86_assembly_language#Syntax


# オペコードの接尾辞
- b (=byte) : オペランドのメモリサイズは1byte
- w (=word) : オペランドのメモリサイズは2byte
- l (=long) : オペランドのメモリサイズは4byte
- q (=quadword) : オペランドのメモリサイズは8byte

```nasm
movq %rax, %rbx
movzbl %al, %ebx        ;movzのように2つの接尾辞を持つものもあります。
```

# leaとmovの違い
leaとmovは両方、アセンブリでは頻出で、``<何か>``を``<場所>``に入れるという操作を行います。

```nasm
mov A, B                  ;アドレスBの値(もしくは定数B)をアドレスAに入れる
lea A, B                  ;アドレスBをアドレスAに入れる

;例
mov [A], B                ;アドレスBの値(もしくは定数B)をアドレスAの値が指すアドレスに入れる。
lea A, [B]                ;アドレスBの値が指すアドレスをアドレスAに入れる。
mov [ebx+04], eax         ;eaxの値をアドレスebx+4hに入れる
lea ecx, [ebp-10]         ;ebp-10hの値が指すアドレスをecxに入れる
```

# おすすめ文献

どのように関数が実行されるかが分かる。

https://gihyo.jp/dev/serial/01/antique_assembler/0005

r/mやimmなど、知っていると役に立つ用語の説明。

https://www.mztn.org/lxasm64/amd06_sum.html


# 参考文献

https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf

https://en.wikipedia.org/wiki/X86_assembly_language#Syntax

https://en.wikibooks.org/wiki/X86_Assembly/GNU_assembly_syntax
DocumentFragmentオブジェクトでノードを追加

DocumentFragmentオブジェクトでDOMツリーを作成できます。ノードをその都度追加するのではなく、DocumentFragmentオブジェクトを作成し、DOMツリーに複数のノードを追加したあとで、オブジェクトを追加することで画面の位置調整などの計算を最小限にすることができます。

```html
<div class="wrapper"></div>
```

```js
const target = document.querySelector(".wrapper");

let divElement = document.createElement('h1');
let pElement = document.createElement('p');
divElement.append(document.createTextNode('タイトル'));
pElement.append(document.createTextNode('テキスト'));

const fragment = new DocumentFragment();

fragment.append(divElement)
fragment.append(pElement)

console.log(fragment);
target.append(fragment);
```

結果
```html
<div class="wrapper">
  <h1>タイトル</h1>
  <p>テキスト</p>
</div>
```
fragmentを一度にHTML上に追加することで、ブラウザ側のレンダリング処理は1回で済むので、パフォーマンスの改善になります。
#### 参考
https://www.javadrive.jp/javascript/dom/index25.html

https://developer.mozilla.org/ja/docs/Web/API/DocumentFragment
apt-key list から鍵を削除する方法は

# apt-key list から鍵を削除する方法は

```
$ sudo apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg
--------------------
pub   dsa1024 2007-03-08 [SC]
      4CCA 1EAF 950C EE4A B839  76DC A040 830F 7FAC 5991
uid           [  不明  ] Google, Inc. Linux Package Signing Key <linux-packages-keymaster@google.com>
sub   elg2048 2007-03-08 [E]
.
省略
.
.
.

```

pub 次の行にあるフィンガープリント末尾８桁を使用する  
4CCA 1EAF 950C EE4A B839  76DC A040 830F 7FAC 5991  

末尾８桁を抽出してスペースを無くす  
7FAC5991  

```
$ sudo apt-key del 7FAC5991
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK
```

#### 補足

apt-key をエクスポートして /usr/share/keyrings に保存する方法  
https://askubuntu.com/questions/1398344/apt-key-deprecation-warning-when-updating-system-key-is-stored-in-legacy-trust  

以上
Laravel勉強日記

# laravel勉強日記

#### シーディングを利用してデータを一括挿入
シーダーを作成するには以下のコマンド
```
sail artisan make:seeder TweetsSeeder
```
database/seeder にTweetSeederクラスが作成される

## DBにデータが挿入される流れ
#### ① database/seederに作成されたデータを挿入するためのファイルを作成する。
```
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;


class TweetsSeeder extends Seeder
{
    public function run()
    {
        DB::table('tweets')->insert([
            'content' => Str::random(100),
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }
}
```
こんな挿入するためのファイルを書く

#### 2,さっきのファイルを呼び出すためのファイルを作成する
```
public function run()
{
    // \App\Models\User::factory(10)->create();
    $this->call([TweetsSeeder::class]);
}
```
####　③最後にシーダーを実行するArtisanコマンドを実行する
```
sail artisan db:seed
```
個別にシーダーを呼び出す際には、classオプションを使う
```
sail artisan db:seed --class=TweetsSeeder
```
NestJSプロジェクトのヘルスチェックAPI実装


## 前提
BFF（Backend For Frontend）は、フロントエンドとバックエンドの間に位置する特定のタイプのサーバーとして機能し、フロントエンドとバックエンドのコミュニケーションを効率化します。この記事では、BFFとして機能するNestJSプロジェクトをAmazon ECS（Amazon Elastic Container Service）にデプロイする際のヘルスチェックAPIの実装について説明します。ヘルスチェックはサービスの健全性を監視し、問題が発生した場合に迅速に対応できるようにします。Amazon ECSでは、ヘルスチェックは必須の要件であり、失敗するとサービスが停止します。

## 実装
NestJSプロジェクトでは、ヘルスチェックコントローラを作成するだけでなく、ルートモジュールにヘルスチェックコントローラを含むモジュールを追加するか、ヘルスチェックコントローラを直接追加するかのいずれかが必要です。これにより、サービスの健全性を効果的に監視できます。

## ヘルスチェックコントローラ
- HealthCheckService: ヘルスチェックのロジックをカプセル化します。
- HttpHealthIndicator: HTTPサービスのヘルスチェックを支援します。
- HealthCheck: 特定のメソッドがヘルスチェックエンドポイントとして機能することを示します。この例では、checkメソッドがヘルスチェックエンドポイントとして機能し、/healthエンドポイントにHTTP GETリクエストが送信されたときに呼び出されます。このメソッドはGraphQLサーバのヘルスチェックを行い、その結果をレスポンスとして返します。

```health.controller.ts
import { Controller, Get } from "@nestjs/common";
import {
  HealthCheckService,
  HttpHealthIndicator,
  HealthCheck,
} from "@nestjs/terminus";
import { AxiosResponse } from "@nestjs/terminus/dist/health-indicator/http/axios.interfaces";

type GraphQLHealthResponse = {
  status: string;
};

@Controller("health")
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () =>
        this.http.pingCheck(
          "GraphQL",
          // ECSにデプロイしたら環境変数はタスク定義によってBFFエンドポイントを指定します
          `${process.env.APP_URL}/.well-known/apollo/server-health`,
        ),
      () =>
        this.http.responseCheck(
          "GraphQL",
          // ECSにデプロイしたら環境変数はタスク定義によってBFFエンドポイントを指定します
          `${process.env.APP_URL}/.well-known/apollo/server-health`,
          function (res: AxiosResponse<GraphQLHealthResponse>) {
            return res.data?.status === "pass";
          },
        ),
    ]);
  }
}
```

## ヘルスチェックモジュール
- HttpModule: HTTPリクエストを行うためのモジュールです。

```health.module.ts
import { Module } from "@nestjs/common";
import { HttpModule } from "@nestjs/axios";
import { HealthController } from "@/controller/health.controller";
import { HealthCheckService, HttpHealthIndicator } from "@nestjs/terminus";

@Module({
  imports: [HttpModule],
  providers: [
    HealthCheckService,
    HttpHealthIndicator,
  ],
  controllers: [HealthController],
})
export class HealthModule {}
```

## ルートモジュール
- GraphQLModule: GraphQLサーバを設定します。
- ConfigModule: アプリケーションの設定を管理します。
- TerminusModule: ヘルスチェックとグレースフルシャットダウンのサポートを提供します。
- join: パスを結合するためのユーティリティ関数です。

```app.module.ts
import { HealthModule } from "@/modules/health/health.module";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { GraphQLModule } from "@nestjs/graphql";
import { TerminusModule } from "@nestjs/terminus";
import { join } from "path";

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: join(process.cwd(), "src/schema.gql"),
      sortSchema: true,
    }),
    ConfigModule.forRoot({
      envFilePath: [".env"],
    }),
    TerminusModule,
    HealthModule,
  ],
})
export class AppModule {}
```

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
【Swift】OptionSetプロトコル

# この記事は何

Swiftプログラミングにおける[OptionSet](https://developer.apple.com/documentation/swift/optionset)について、Appleの開発者向けドキュメントを独自に解説する。

> Swiftを基礎から学ぶには
自著、工学社より発売中の「[まるごと分かるSwiftプログラミング](https://amzn.asia/d/7YPWJwl)」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。

オプションセットを使用すると、定数や変数に設定する値を「予め決められた選択肢」に制限できる。
それだけなら列挙型でも同じことができるが、オプションセットでは単一の値だけでなく、コレクションのように複数の選択肢をひとつの値に設定することもできる。
また、包含や和のようなセット演算を実行できる利点がある。

# 概要

`OptionSet`プロトコルは「それぞれがセットのメンバーを表すビット」のセットをモデル化する。
独自に定義した型に`OptionSet`プロトコルを採用すると、それらの型の関係、集合、交差などのセット関連の操作を実行できる。
さらに、特定の基準に則って実装した場合、余分な作業をせずにプロトコルの採用できる。

オプションセットを作成するには、型の宣言に`rawValue`プロパティを含める。
独自の型が「セットに関する操作のデフォルト実装」を自動的に受けるには、この`rawValue`プロパティは`FixedWidthInteger`プロトコルに準拠した（`Int`や`UInt8`などの）型である必要がある。
次に、一意なメンバーを作成するために、`rawValue`プロパティに「2の累乗」を掛けた値で初期化した独自の型の型プロパティを作成する。
それぞれの型プロパティは「単ビットの原生地」で表現される。

以下に定義する`ShippingOptions`型は、「顧客が購入した品の出荷方法」をモデル化したオプションセットの例。
`ShippingOptions`型に定義されている`Int`型の`rawValue`プロパティは「利用可能な配送方法のビットマスク」を格納する。
定数の型プロパティ`nextDay`、`secondDay`、`priority`、`standard`はユニークな個別の選択肢。

```swift:出荷方法のオプションセット
struct ShippingOptions: OptionSet {
    let rawValue: Int    // プロトコル要件

    // ユニークな選択項目
    // 翌日配送、翌々日の配送、優先配送、通常配送
    static let nextDay    = ShippingOptions(rawValue: 1 << 0)    // 2^0 = 1
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)    // 2^1 = 2; x2
    static let priority   = ShippingOptions(rawValue: 1 << 2)    // 2^2 = 4; x2x2
    static let standard   = ShippingOptions(rawValue: 1 << 3)    // 2^3 = 8; x2x2x2

    // 選択項目のコレクションも可
    // 速達（翌日、翌々日配送）、すべての配送方法
    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}
```

予め設定済みのオプションセット値として宣言を追加した`express`と`all`は、「他の選択肢を含む配列リテラル」で初期化された型プロパティ。
例えば、`express`プロパティには「`nextDay`と`secondDay`のふたつの選択肢を要素に持つ配列」が割り当てられている。

# オプションセットのインスタンスを初期化する

オプションセットのインスタンスを作成するには、型プロパティのいずれかを変数または定数に割り当てる。
「複数のメンバーを持つオプションセットのインスタンス」を作成するには、「オプションのメンバーを要素に持つ配列リテラル」を割り当てる。
空のインスタンスを作成するには、変数に空の配列リテラルを割り当てる。

```swift:
// 単純なオプションセットのインスタンス
let singleOption: ShippingOptions = .priority

// 複数のメンバーがあるオプションセットのインスタンス
let multipleOptions: ShippingOptions = [.nextDay, .secondDay, .priority]

// 空のオプションセットのインスタンス
let noOptions: ShippingOptions = []
```

# オプションセットの操作

セット関連の操作を行なって、集合関係を確認したり、独自のオプションセット型のインスタンスからメンバーを追加したり、削除したりできる。
次の例では、顧客の購入価格に基づいて、無料の配送方法を決定する。

```swift:
let purchasePrice = 87.55    // 購入価格は87.55ドル

// 50ドルより高ければ、無料の配送方法に「優先配送」を追加
var freeOptions: ShippingOptions = []    // 空のオプションセットを作成
if purchasePrice > 50 {
    freeOptions.insert(.priority)    // オプションセットにメンバーを追加
}

// 配送方法に「優先配送」が含まれていれば、「優先配送は無料です!」を出力
// そうでなければ、「優先配送を無料にするにはカートに商品を追加してください!」を出力
if freeOptions.contains(.priority) {    // メンバーの有無を確認するセット操作（包含）
    print("You've earned free priority shipping!")
} else {
    print("Add more to your cart for free priority shipping!")
}
// Prints "You've earned free priority shipping!"
```
【備忘録】PlatformIOでM5Stackを使おうとしたら、Wire.hやFS.hがインクルードできなかった話

# 状況
[M5Stackの開発環境を整える - PlatformIO IDE編](https://qiita.com/lutecia16v/items/1c560bdd7eac7ebeaff7)を参考に環境構築を進めていたところ、コンパイル時にWire.hやFS.hのインクルードできないと言われた。
![スクリーンショット 2023-09-16 233533.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526610/c8af5b43-068a-406a-13ff-8fa94eb2f153.jpeg)

# 解決方法
platformio.iniに **lib_ldf_mode = deep** を追加することで解決。

```ini:platformio.ini
[env:m5stack-core-esp32]
platform = espressif32
board = m5stack-core-esp32
framework = arduino
lib_deps = m5stack/M5Stack@^0.4.5
lib_ldf_mode = deep
```
VirtualBox Guest Additions がうまくインストールできない（GUI）ときはコマンド（CUI）でインストールする

# VBoxLinuxAdditions.run をコマンドラインで実行する

VirtualBox7.0  

VM VirtulBox のメニューで Guest Additions をインストールしたら下記のエラーが発生。コマンドラインで実行した。  

デバイス ＞ Upgrade Guest Addition..
```
Automatic update of Guest Additions has failed: files were installed, but kernel modules were not reloaded automatically. Please consider rebooting the guest.  
```
ゲスト追加の自動更新に失敗しました。ファイルはインストールされましたが、カーネル モジュールは自動的にリロードされませんでした。 ゲストを再起動することを検討してください。  

```
Result Code:
VBOX_E_GSTCTL_GUEST_ERROR (0X80BB000F)
Component:
GuestSessionWrap
Interface:
IGuestSession {234f0627-866d-48c2-91a5-4c9d50f04928}
```

## VBoxLinuxAdditions.run 実行する上で必要なもの。
```
sudo apt install bzip2
sudo apt install gcc make perl -y
```
上記でインストールされていないものがあれば、それが原因だったのかもしれない。この時点で、GUIでのインストール（Upgrade Guest Addition..）をすればうまく行くかもしれない。  

前提  
仮想ホスト（VM）を立ち上げた状態で上のメニューの
デバイス＞Guest Additions CD 挿入 をクリックしGuest Additions CD がマウントされていること。  
エラーがすでに出ているのでマウントはうまく行ってるはず余計なお世話かもしれない。  

```
sudo /media/uchi/VBox_GAs_7.0.10/VBoxLinuxAdditions.run
```

以上
StreamCatを使って失われた30年の物価推移を調べてみた


[**StreamCat**](https://github.com/sabanyan/streamcat-web)はデータ前処理プログラムの開発・運用プラットフォームです。データ分析の経験はあるけどプログラム開発の経験が乏しいユーザが、簡単に開発・運用できることを目指しています。

https://qiita.com/hiro80/items/2b3111eea768cc9c91b4

## 動機
この数年で品物の値上げが当たり前のように報道されるようになりました。ヒキニートの自分にとってなけなしの貯金が目減りするのは辛い。

ふと、失われた30年でどれほど物価が上がったのか(下がったのか)が気になり、軽くググったのですが得られたのは直近2〜3年の期間か、終戦直後からの期間のグラフしか得られませんでした。それならと、**公開されているデータから物価推移のグラフを作ろうと思いました**。

## 京都市物価統計データ

日本全国の消費者物価指数ではなく私が現在居住している[京都市の消費者物価指数データ](https://data.bodik.jp/dataset/260002_tokeisyo1501)を使うことにしました。理由は、日本経済の指標を知りたいのではなくて自分の貯金の目減りを知りたいからです。貯金は自分の生活圏で使いますしね(多分)。
<img width="384" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/c2f0fae2-b557-7392-d4d9-0e7f69786eea.png">

得られたのは1991年から2020年までのCSVで、月ごと・品目ごとに物価指数が記録されています。物価指数は1991年(平成2年)を基準値100にした相対値のようです。

月ごとの行と年平均の行が混ざっているのに注意です、この様な正規化されてないデータが存在する限り前処理の出番は無くなりませんね。
![RawData](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/cd9dfa1b-9161-89b1-a478-6b8c39cf160d.png)

## 前処理フロー

サクッと作ってみました
<img width="512" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/c98e5f0c-c1bf-740a-95f8-748bb820b8b0.png">
<img width="512" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/8b93a6a5-8636-7f9b-3e6b-5fbe41200506.png">

StreamCatはデータをグラフで表示する機能があります。このフローで前処理したデータを時系列のグラフにしました。

## うん？

<img width="384" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/d98172bf-3a63-1ca2-a00c-43d2d232c37b.png">


それっぽく表示できたけど何か違和感が、、
そう、矢印で示した部分に断層のような急激な変化が見て取れます。1ヶ月で物価がこんな急激に変化するとは思えないので作ったフローが誤っているのかも。

フローを遡っても原因は分かりませんでしたが元データまで辿ると分かりました。どうやら物価指数の基準年は5年ごとに変更されるみたいです。
![baseYear](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/fbba8bf5-2977-911d-3732-57c7db09b8ba.png)
つまり5年ごとに指数が100に振り戻されるわけです

## グラフを切り貼り

知りたいのは失われた30年間の推移なので、全ての指数を1991年(平成2年)基準に補正する必要があります。ところが、各基準年の間に変換率みたいな情報が提供されてないので困ってしまいました。

仕方ないので、「基準年の変更前後の指数はたぶん同じ」というやや乱暴な前提に立って基準年の異なるデータ同士を繋ぎました

```math
当月の物価指数(平成2年基準) = \frac{前月の物価指数(平成2年基準)}{当月の物価指数(平成7年基準)}
```

![largeFlow](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/38c95a80-a873-a27a-de89-a7c8ce4bbd21.png)
データを5年ごとに切り出して補正したのでフローが大きく育ち過ぎました。この程度の処理で大きくなるのはコマンドの機能粒度が小さすぎるからなのですが、現時点のStreamCatの課題ですね、何とか改良したいです。

## 消費税率UP？！
![resultPlot](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554253/276bf320-fa33-2be5-c25f-854a40b59abf.png)

まだ何箇所か断崖が残ってます、ですが元データの値からしてこのグラフの通りの変化量でした。


1997年、2014年、2019年に消費税率が上がりました、①と③は増税と時期が一致するので理由がつきます。②は1年間指数が張り付いてます、元データの値も張り付いてました、欠測したのでしょうか？


なんと、この記事作っている途中にWikipediaで全国の物価指数グラフを見つけてしまいました、でもこのグラフは2015年迄ですね。
<img width="384" src="https://upload.wikimedia.org/wikipedia/commons/0/0f/%E6%B6%88%E8%B2%BB%E8%80%85%E7%89%A9%E4%BE%A1%E6%8C%87%E6%95%B0.png">
青線のCPIと比べると②の部分を除いて京都市と形は似ています、**やはり②が謎だ**

## わかったこと

- バブル崩壊の影響で1997年からデフレが始まったとされてるが、消費増税分が寄与したためか1997〜2020年で見ると物価は上がっている
- 1991〜2020年の間に約14%物価は上がっている(消費増税分含む)
- 今の貯金でいつまで生き延びられるんだろうか・・
Linuxのviエディタのコマンド

# はじめに
こんにちは。nagamineです。

Linuxについて、以下の本[1週間でLPICの基礎が学べる本 第3版 徹底攻略シリーズ](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7LPIC%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC3%E7%89%88-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B07TD1TTYJ/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)を読んで、
後々使いそうだなと思ったviエディタのコマンドを、後から見返せるようにまとめていきたいと思います。
詳しくは[1週間でLPICの基礎が学べる本 第3版 徹底攻略シリーズ](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7LPIC%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC3%E7%89%88-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B07TD1TTYJ/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)をご覧ください。
# コマンド

viエディタを起動(指定したファイル名のファイルがない場合、そのファイル名でファイルを新規作成する)。
```
vi ファイル名
```

viエディタの終了
```
:q
```



### カーソルの移動

|コマンド|説明| 
| --- | --- | 
|l または →(右矢印キー) |1文字右へ移動|
|h または ←(左矢印キー) |1文字左へ移動|
|k または ↑(上矢印キー)|1文字上へ移動|
|j または ↓(下矢印キー)|1文字下へ移動|
|gg|ファイルの先頭に移動|
|G|ファイルの末に移動|
|0|行頭へ移動|
|$|行末へ移動|

### コマンドモードから挿入モードへの切り替え

|コマンド|説明| 
| --- | --- | 
|i|現在のカーソル位置で挿入モードへ切り替える|
|I|行頭に移動し、挿入モードへ切り替える|
|o|現在位置の下に空白行を挿入し、挿入モードへ切り替える|
|O|現在位置の上に空白行を挿入し、挿入モードへ切り替える|
|a|１文字右に移動して挿入モードへ切り替える|
|A|行末に移動し、挿入モードへ切り替える|

### 切り取り、コピー、貼り付け

|コマンド|説明| 
| --- | --- | 
|dd|現在の行を切り取る|
|yy|現在の行をコピーする|
|x|右側の１文字を切り取る|
|X|左側の１文字を切り取る|
|p|貼り付ける|



### ファイルの保存
|コマンド|説明| 
| --- | --- | 
|:w|上書き保存|
|:w ファイル名|別名で保存|
|:wq　または　ZZ|ファイルを保存して終了|
|:q!|ファイルを保存しないで終了|

### コマンドの繰り返しと取り消し

|コマンド|説明| 
| --- | --- | 
|繰り返す回数繰り返すコマンド|例　4p<br>pコマンドを4回繰り返す|
|.| 直前のコマンドを実行する|
|u|直前の操作を取り消す|
|Ctrlキー ＋ Rキー|直前の操作の取り消しを取り消す|

### 文字列の検索

```
/検索したい文字列　
```

を入力してEnterキーを押す。
すると検索した文字列にカーソルが移動するのでNキーを押すと次のヒットした文字列に移動する。 
Nキー＋Shiftキーを押すと反対方向に移動する。

### viエディタの設定を変更

|コマンド|説明| 
| --- | --- | 
|:set number|行番号を表示|
|:set nonumber|行番号を非表示|
|:set hlsearch|検索結果のハイライトを表示|
|:set nohlsearch|検索結果のハイライトを非表示|
|:set ts=<文字数>|タブのスペース数を設定|


# 参考
[1週間でLPICの基礎が学べる本 第3版 徹底攻略シリーズ](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7LPIC%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC3%E7%89%88-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B07TD1TTYJ/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)
Libertyで「SRVE9967W: マニフェスト・クラスパスが～見つかりませんでした」が出力されるのを抑止する

Libertyでは古かったり自作のjarがクラスパスにあると次のメッセージが出力されることがよくあります。

```
[INFO] [警告      ] SRVE9967W: マニフェスト・クラスパス commons-logging.jar が、JAR ファイル file:/xxx/target/xxx/WEB-INF/lib/struts-1.1.jar またはその親に見つかりませんでした。
[INFO] [警告      ] SRVE9967W: マニフェスト・クラスパス commons-validator.jar が、JAR ファイル file:/xxx/target/xxx/WEB-INF/lib/struts-1.1.jar またはその親に見つかりませんでした。
```

server.xmlに次のエントリを追加すれば出力されなくなります。
```
    <logging hideMessage="SRVE9967W" />
```
PHPで配列の末尾の要素を取得する

PHPで配列の要素を取得する方法を3パターン紹介します。

1. array_key_last()
2. count()とインデクサを使用
3. end()

上記の3パターンが使われる可能性が高いですが、最新のPHPバージョンではarray_key_last()を使うことがベターです。

使用例は以下の記事にまとめています。
https://hishikiryu.com/php-get-last-array-value/
ジオコーディングAPIを使ってみた ~メザスタ~

# はじめに
息子がポケモンのメザスタにはまっているのだが，公式サイトではどこに設置されているかの情報がわかりづらい。

公式サイトには，店名，住所，イベント情報のみが記載されるのみ，下記は一例です。
- 店名
    -アピナ富谷店
- 住所
    - 宮城県富谷市大清水１丁目 33 番地１　イオンモール富谷別棟 109 シネマズ富谷 １階
- イベント
    - 開催なし

ということで，Web地図に落とし込むために，住所文字列から緯度，経度情報を取得するAPIを使ってみた。


# GeoCodingツール
jageocoderを利用。インストール方法は，githubを参照

https://geonlp.ex.nii.ac.jp/jageocoder/

https://github.com/t-sagara/jageocoder

# code
``` python
import pandas as pd
import jageocoder

jageocoder.init()

def return_x_y(address):
    res = jageocoder.search(address)['candidates']
    return (res[-1]['x'], res[-1]['y'])

data = pd.read_csv("Mezasta.csv",index_col=0)
data["lon"] = data.address.apply(lambda x: return_x_y(x)[0])
data["lat"] = data.address.apply(lambda x: return_x_y(x)[1])

data.to_csv("Mezasta_geoinfo.csv")
```

# マイマップへの登録
Googleマイマップで作成した`Mezasta_geoinfo.csv`を登録
csvのデータ点数，2133個なのだが，Googleマイマップの仕様のため2000点までしか表示できず・・・

https://www.google.com/maps/d/u/3/edit?mid=1dou61C2T3g2mvU4KyA_CWO0T04XnO8Y&usp=sharing

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601976/4be5c5f5-3530-72ca-a961-3b50ec13df66.png)
async/awaitでNotificationCenter通知をタイムアウト付き待機する方法

# はじめに
「`async`/`await`で`NotificationCenter`の通知を待機し、時間経過でタイムアウトさせる方法」をご紹介します。
# 背景
この処理は少し特殊な非同期通信でリクエストに対するレスポンスを`NotificationCenter`で受信していました。またレスポンス受信できない場合にアラート表示をするためにタイムアウトを設ける必要がありました。タイムアウト処理は元々`DispatchSemaphore`を使って実装していたのですが、この処理をCombineではなく`async`/`await`を使って置き換えたいと思って実装しました。
# 実装方法
以下の2つの方法を組み合わせます。
- `NotificationCenter.Notifications`で通知を待機
- `TaskGroup`でタイムアウト

## `NotificationCenter.Notifications`で通知を待機
`async`/`await`で`NotificationCenter`を待つのは以下のようなコードで実装します。
`NotificationCenter.Notifications`を使用しています。
```swift
let notificationName = Notification.Name("hoge")
let notifications = NotificationCenter.default.notifications(named: notificationName, object: nil)
for await notification in notifications {
    print(notification)
}
```
これで`NotificationCenter`の通知が来るまで待つことができます。簡単ですね。

https://developer.apple.com/documentation/foundation/notificationcenter/notifications?changes=_9

マニュアルに記載の通り`NotificationCenter.Notifications`はiOS15以降のサポートです。
## `TaskGroup`でタイムアウト
`TaskGroup`と`cancelAll`を使うとタイムアウトが実装できます。
こちらの記事のコードを参考にさせていただきました。

https://qiita.com/maiyama18/items/a1aed9501b8ebfb94d5b#cancelall-%E3%81%8C%E5%91%BC%E3%81%B0%E3%82%8C%E3%81%9F%E5%A0%B4%E5%90%88

## 2つを組み合わせる
2つを組み合わせたコードが以下です。
```swift
@available(iOS 15, *)
func waitWithTimeout(notificationName: NSNotification.Name,
                     timeoutNanoseconds: UInt64) async throws {
    try await withThrowingTaskGroup(of: Void.self) { group in
        group.addTask {
            let notifications = NotificationCenter.default.notifications(named: notificationName)
            for await _ in notifications {
                // レスポンス取得後の処理
                return
            }
        }
        group.addTask {
            // 指定時間待機後にタイムアウト
            try await Task.sleep(nanoseconds: timeoutNanoseconds)
            throw CancellationError()
        }
        let _ = try await group.next()!
        group.cancelAll()
    }
}
```
`withThrowingTaskGroup`のクロージャで`TaskGroup`に2つ`Task`を追加しています。
1つは`NotificationCenter`を待つ`Task`です。
もう1つは指定時間を待機した後にタイムアウトのthrowを投げる`Task`です。
どちらかの`Task`が終了したら、もう一方は`cancelAll`でキャンセルされます。

以下のような使い方です。
```swift
Task {
    // 何かしらのリクエストを送信する。
    request()
    do {
        let responseNotificationName = Notification.Name("response")
        let timeoutNanoseconds = UInt64(10 * 1_000_000_000)
        try await waitWithTimeout(name: responseNotificationName,
                                  timeoutNanoseconds: timeoutNanoseconds)
    } catch {
        // タイムアウト処理
    }
}
```
# まとめ
`TaskGroup`と`NotificationCenter.Notifications`を組み合わせることで、
`NotificationCenter`を`async`/`await`で待ちつつ、時間経過するとタイムアウトする処理が書けました。

この方法は以下の要件に合致する場合に有効です。
- iOS15以降サポートであること。
- レスポンスを`NotificationCenter`で受信するケースであること。
- レスポンスにタイムアウトを設ける必要があること。
- Combineでなく`async`/`await`を使いたい時。
C++ 競プロ　学習記録#2

## はじめに

# 配列
* 配列の大きさ
    arr.size();

* 整数配列　宣言
    #include \<vector\>
    vector\<int\> arr(要素数);
* 整数の２次元配列　宣言
vector\<vector\<int\>\> arr(要素数1, vector\<int\>(要素数2));

* 要素を配列の最後に追加
arr.push_back(要素);

* 要素を配列の最後から削除
arr.pop_back(要素);

# ソート
* 整数２次配列の降順ソート
#include \<algorithm\>
sort(arr.begin(), arr.end(), greater\<vector\<int\>\>());
* 昇順
sort(arr.begin(), arr.end());

# 他
* 配列のメモリサイズ
    sizeof(arr)
* markdownで記号をそのまま使いたいとき
記号の前にバックスラッシュ
meta要素の重要性を知っているか？

## 知っておくべきこと
HTMLの仕組み

## なぜ知りたいと思ったか？
ブラウザ上で表示されないhead要素の中に、meta要素を使って文字コードを設定してきた
文字コード以外に設定できると思うけど、meta要素がどんな機能を持つかを知りたかった

## まずは「メタ」を知ることから
メタ認知やメタデータの「メタ」は、「高次元の」「超越した」といった複数の意味があります。メタデータは「データに関するデータ」と呼ばれていますが、これでは分かりませんよね。

## データに関するデータとは？
例えば画像を保存した後に、「いつ更新したか」「データ量はどれ位か」「データの拡張子は何か」といった情報を確認できますよね。
![スクリーンショット 2023-10-06 21.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/96cfa0a6-04ae-43cd-542e-9795c7d1c050.png)
実はこれらの情報がメタデータなんです！！
「メタデータ = 対象データを紐づけるデータ」とイメージした方が良いと思います。

## HTMLで扱うメタデータとは？
「meta要素を使わなくても、Webサイトは作れる」
と思った方は、以下の点を考えてみて下さい。

「作ったWebサイトの説明なしで、ユーザーが見てくれるか？」
![スクリーンショット 2023-10-06 22.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/ab5ab5c7-ef46-4594-9b0f-7c8ceda766ed.png)
ハイパーリンクの下にある説明を読んで、続きが気になって押した方が多いのではないでしょうか？
ユーザーを誘導しやすくするために、HTMLにWebページの内容を紐づける良い参考になりますね。

HTMLのメタデータは他にもあるので、気になる方は調べてみて下さい。

## meta要素は何のために必要か？
Webページに色々な情報を結びつけるため
Elastic IPアドレスの関連付けを解除した後、解放せずに、放置してたら課金されてしまった話と対処法

# Elastic IPアドレス関連で課金されてしまった...
AWSの1年無料期間の終わりが近づいていたので、昨日、Elastic IPアドレスの関連付けの解除とインスタンスの削除を行いました。すると次の日（厳密には日付が変わって1時間後）に、Budgetsで設定していたアラートがメールで飛んできていました。

Billingで確認すると、なぜかElastic IPアドレス関連で課金されている事態になっていることがわかりました。
![スクリーンショット 2023-10-06 17.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/20a9dbc4-16b3-6f0b-fd06-2d46beafd741.png)

# 原因は？
メッセージの内容やGoogle検索した結果、Elastic IPアドレスがどのインスタンスにも関連づけられておらず、そのまま放置していると、自動的に課金されるという仕様だったらしいです。

状況としては、以下の手順を行い、そのまま放置していたことが原因でした。
1. インスタンスを削除するために、Elastic IPアドレス関連付けの解除
![スクリーンショット 2023-10-05 14.09.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/3a0ca587-f18f-99af-7ccf-662b0ec4fd5b.png)
1. 関連づけられたインスタンスが消えていることを確認して、インスタンスを削除する作業に入って、そのまま放置......
![スクリーンショット 2023-10-05 14.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/20299097-c91b-572c-9a8a-23abd425db16.png)

# 対処
対象のElastic IPアドレスを選択し、Elastic IPアドレスを解放（削除）して対処しました。
![スクリーンショット 2023-10-06 17.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/b1cb720b-8dd4-183f-bdca-f2f231daa13c.png)

# 感想
Google検索などで調べると、他にも、Elastic IPアドレスがインスタンスに関連づけられていたとして、そのインスタンスが稼働していない場合でも同じように課金されるみたいです。突然、身に覚えのない課金がされていると、一瞬、焦りますね💦

特にAWSの初学者（私）は気をつけましょう🎉
（もし間違ったことを言っていたら、指摘してください🙇）
Xcode15以降でSwiftLintが動かないときの解決方法

### はじめに
Xcode15にアップデートしてSwiftLintを利用すると下記エラーが発生して動きませんでした。

```
Command PhaseScriptExecution failed with a nonzero exit code
```
解決方法はシンプルだったので紹介します。


### 環境
- Xcode15
- SwiftLint 0.46.4
- swift 5.9


### 原因
Xcode14で追加されたBuild Settingの`ENABLE_USER_SCRIPT_SANDBOXING`フラグが原因でした。
Xcode14ではこのフラグがデフォルトで`NO`（無効）になっていたのですが、Xcode15からデフォルト値が`Yes`（有効）に変更されたことが原因でSwiftLintが実行されなかったようです。

`ENABLE_USER_SCRIPT_SANDBOXING`とは、`ScriptPhases`がソースファイルや中間ビルド・オブジェクトにアクセスするのをブロックするかどうかを指定するフラグです。


### 解決方法
`ENABLE_USER_SCRIPT_SANDBOXING`フラグを`No`（無効）に変更する必要があります。
Xcodeのプロジェクト名→TARGETS→Build Settings→Build Options→User Script Sandboxingを`No`に変更

Build SettingsでUSER等と入力してフィルタリングするとすぐに見つけることができます。

![スクリーンショット 2023-10-06 22.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953855/b0da032d-4d39-cbc4-09d1-ef39ab2ae17d.png)


### それでもエラーが出る場合
エラーが消えない場合は一度SwiftLintを設定している箇所を削除して、再度追加すると正しく動作する可能性があります。

Xcodeのプロジェクト名→TARGETS→Build Phases→Run Scriptを削除
再度プラスボタンを押下→New Run Script PhaseからSwiftLintを追加→ビルドしてエラーが消えるか確認


![スクリーンショット 2023-10-06 22.42.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953855/c2897978-075e-2e33-088b-404866148f88.png)
スクロールバーを表示しないようにする方法【TailwindCSS】

## カスタムクラスを作成する
以下の内容でカスタムクラスを作成します。

```css
.hidden-scrollbar{
  overflow: scroll;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.hidden-scrollbar::-webkit-scrollbar {
  display:none;
}

```

## 要素に適用する

適用したい要素に上記のクラスを記述します。
【IBM Cloud】CodeEngineで改行を含む環境変数を扱う

# 発生した問題
Node.jsで開発したアプリで認証ありのRedisサーバーに接続しようとした際、ローカルで動作させて接続できていたものが、CodeEngineにデプロイしたアプリでは正常に接続されなかった。
正確には接続する際の認証に失敗していたようだ。
```
REDIS_CERTIFICATE="-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIUFIO1EGeecAJjDhDdmSdOfCWPboYwDQYJKoZIhvcNAQEL
...
FTel34h4s8q8kPTaEWuohkoV80IYKLSZthAzzXtJpTW1
-----END CERTIFICATE-----"
```
証明書を上のような形で環境変数に入れることでローカルでは動作していたが、CodeEngineの環境変数にはこのまま突っ込んでも認識されないようだった。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/0d8aa8ba-0f7a-70a3-653a-a18e792e89b5.png" width="400px">
"値"の部分にペーストした時点で改行コードから見た目同様の半角スペースになってしまうようだ。

# 解決策
```
REDIS_CERTIFICATE=-----BEGIN CERTIFICATE-----\nMIIDHTCCAgWgAwIBAgIUFIO1EGeecAJjDhDdmSdOfCWPboYwDQYJKoZIhvcNAQEL...\nFTel34h4s8q8kPTaEWuohkoV80IYKLSZthAzzXtJpTW1\n-----END CERTIFICATE-----
```
このように、文字列を囲うダブルクォーテーションを外し、改行を`\n`に置き換えた。
その後Node.js側で`REDIS_CERTIFICATE`を読み取り、`.replace(/\\n/gm, "\n")`を行うことで無事接続が行えた。

# 考察？

CodeEngineでは、改行は半角スペースへ。
ダブルクォーテーションやバックスラッシュなどは環境変数の一部としてエスケープされるようだ。

| CodeEngine上の環境変数で設定した値 | アプリケーション側で認識される値 |
|:-:|:-:|
|` `<br>(改行)|` `<br>(半角スペース) |
|`\`|`\\`|
|`""`|`\"\"`|
|`\n`|`\\n`|

わかりづらいと思うのは私だけ？
Vue.js簡単説明

下記二つ記事をご覧ください。
[Vue.js概要解説](https://qiita.com/training_zhang/items/8cc73fd5206b80d01efa)
[「Thymeleaf + Springboot + Mybatis + MySQL + VSCodeーThymeleafとVuejs V2の統合」のVUE部分](https://qiita.com/training_zhang/items/84f5f0190e233459092e#vuejs-v2)
プロセス中心設計とデータ中心設計

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/dcc3f4c8-624d-d517-9d8f-a4049df9c780.png)
１：プロセス中心設計の手順
①業務処理分析：DFD（データフローダイヤグラム）などを用いて、業務やシステムにおける各機能の関係を整理する。
②機能分析：機能を分割し、詳細化していく。
③機能設計：各機能の仕様を定義する。
④プログラミング：使用に従って実装する。
⑤テスト：テストを行う。

２：DFD（データフローダイヤグラム）
　DFDは、プロセス間のデータの流れに注目してシステムや業務を分析し、全体像を図式化する方法です。

　DFDの表記ルールとして、
・データの流れには必ずプロセスを介在させる。例えば、データストア（ファイルやデータベースの表がデータストアに相当する。）からデータストアにデータフローを設けてはならない。
・各プロセスは、必ず、入力のデータフローと出力のデータフローを持つ。

DFDは、概要から小サイズへと段階的に詳細化して作成します。最も大まかなDFDは、ターミネータとプロセス１つで描かれます。これをコンテキストダイアグラムと言います。最終的には、１つ１つのプロセスに対して機能仕様が作成できるレベルにまで詳細化します。
$_ENVがすっからかん


variables_order: GPCSのときは、`$_ENV`が空になります。回避するには、`getenv('PWD')`を使いましょう。
すべての環境変数がほしいなら、`getenv()`を実行しましょう

```php
<?php
var_dump($_ENV);
var_dump(getenv());
var_dump(getenv('HOGE') ?: 'DEFAULT_VALUE');
```

`shell_exec('printenv')`も、すべての環境変数を取得できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/6830fbce-b013-a39f-db3e-15fb9c5d8482.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/b0de161f-d25f-1e78-104f-dd38520ee71d.png)


https://www.php.net/manual/en/ini.core.php#ini.variables-order

https://www.php.net/manual/ja/reserved.variables.environment.php#98113
【プラクティス紹介】1分でさらっと分かる「スプリントゴール」

## プラクティス名
スプリントゴール

## プラクティスの目的・狙い
* そのスプリントでチームが目指すべき場所を1つにする
* ゴールを達成するための手段について、柔軟な判断を可能にする

## どんな時に使うか
* スクラムでは必須（スプリントプランニングで決定する）
* DEVがPBIを消化することだけが目的になってしまっている時

## 実施手順
1. POが今回のスプリントゴールを簡潔な言葉で提案する（ことが多い）
1. コミットできない点や、人によって解釈が異なる部分がないことを確認する
1. DEVがそのゴールにコミットする
1. スプリント中、常に目にする場所にスプリントゴールを掲示する

スプリントゴールを定義しないとどうなるか？
スプリントの唯一の目的は「選択したPBIを全て消化すること」になります。
それが目的になってしまうとDEVは「PBIを消化するマシーン」と化します。
例えばスプリント中にそのPBIを消化しても本来の目的にはあまり役立たないことが分かったとしても、別のPBIに入れ替えるといった発想はできず、作業は硬直化します。

スプリントゴールという別の「目的」があることで、PBI消化はそのための「手段」となり、目的が達成できるのであれば別のやり方でもよいという柔軟な判断ができるようになるのです。

## アレンジ例
* 今回のスプリントにスプリントゴールにちなんだ名前をつける
（例えばゴールが「新たなユーザ獲得につながる機能をリリースする」なら「ユーザ獲得スプリント」と呼称する）

## アンチパターン
* 選択されたPBIの要素を全て羅列して、"全部入り"の一行にまとめようとする
（→本来、スプリントゴールは選択されたPBIよりも一段抽象度の高いものになるハズ）

## 参考情報
[公式スクラムガイド(2020年日本語版)](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf)

https://www.agile-studio.jp/post/apm-sprint-goal

## こぼれ話（私的コメント）
僕の経験では初心者スクラムチームがスルーする確率が最も高いプラクティスがコレです。最初にSMから説明されてもピンとこない→なんとなくそれっぽいスプリントゴールを立ててやってみる→効果が実感できないのでそのうちやらなくなる、という負のスパイラルに陥っているチームをよく見かけます。そんな時はSMからPOに「これはあなたがDEVをドライブするために用意された便利なハンドルですよ」と教えてあげることをオススメしています。

「スプリントゴール」と「プロダクトゴール」の違いについては[別の記事](https://qiita.com/kakashi_h5/items/42f3ac38477abbac380d)にまとめています。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)