OmniAICreator/Qiita-1.07M huggingface dataset:
【Snowflake】お役立ちリンク集


## はじめに
Snowflakeで私がよく見るサイト、案内するサイトをまとめてみました。
他にも見つけ次第順次追加していこうと思います。
公式・非公式サイトに対し勝手にリンク張ってますが問題あればご指摘ください。
他にこんな便利なサイトがあるよ、とかもあればコメントいただけると嬉しいです。

## リンク集
### 公式のよく使うもの
| サイト | URLと説明 |
|:-|:-|
|日本語公式ドキュメントサイト | https://docs.snowflake.com/ja/<br>わからないことがあればまずはここで検索しましょう。 |
| 稼働ステータス | https://status.snowflake.com/Snowflake<br>クラウドベンダー、リージョンごとの稼働ステータス。何かあった時にメール登録しておけば通知も可能 |
| 料金表 | 公式<br>https://www.snowflake.com/pricing/?lang=ja<br><br>AWS 東京リージョン限定であればこちらの方の記事の途中に出てくる表がとても分かりやすいです<br>https://zenn.dev/hiroshix/articles/8c60a81f76f44c |
|試用アカウント作成|https://signup.snowflake.com/<br>30日間の無料トライアルができます。自宅での勉強用にも使わせてもらってます。|


### 月一くらいで巡回しておきたいもの
| サイト | 説明 |
|:-|:-|
|最新リリース情報|https://docs.snowflake.com/ja/release-notes/new-features.html|
|プレビュー機能一覧|https://docs.snowflake.com/ja/release-notes/preview-features.html|
|Behavior Change Log（仕様変更の確認）|https://community.snowflake.com/s/article/Pending-Behavior-Change-Log<br>上記２つのような最新機能ではなく、既存機能の仕様変更系はこちらをさんｓｙ|
|各種クライアント（ドライバー等）のリリースノート|https://docs.snowflake.com/ja/release-notes/requirements.html<br>ドライバー関連の仕様変更はたまにチェックしましょう|
|クラスメソッドさんのSnowflake関連記事一覧|https://dev.classmethod.jp/tags/snowflake/<br>最新機能をいち早く試して記事にしてくれています |


### コミュニティ系
| サイト | 説明 |
|:-|:-|
|Globalの公式コミュニティ|https://community.snowflake.com/s/|
|Snow Village（日本のコミュニティ）|https://techplay.jp/community/snowvillage<br>https://www.youtube.com/hashtag/snowvillage |


### お勉強系
| サイト | 説明 |
|:-|:-|
|Snowflake公式記事|https://resources.snowflake.com/ja|
|Snowflake公式動画|https://resources.snowflake.com/ja/videos|
|Snowflake University|https://snowflakeuniversity.mindtickle.com/<br>学習用コンテンツ|
|SNOWFLAKE DUMMIESガイドシリーズ|https://www.snowflake.com/thankyou-snowflake-dummies-guide-series/?lang=ja|
|Snowflake認定資格|https://www.snowflake.com/certifications/?lang=ja|
|認定資格のMyPage|https://snowflake.useclarus.com/login|


### 各種ツールのダウンロード
| サイト | 説明 |
|:-|:-|
| ドライバー関連| https://docs.snowflake.com/ja/user-guide/drivers.html<br>ODBC、JDBCドライバーなど|
| SnowSQL（CLIツール）|https://docs.snowflake.com/ja/user-guide/snowsql.html<br>コマンドラインで処理したい場合はこちら|
|SnowCD（ネットワークの診断ツール）|https://docs.snowflake.com/ja/user-guide/snowcd.html<br>接続関連でうまくいかないときに問題切り分けに使用してます|
|VSCodeのExtention|https://marketplace.visualstudio.com/items?itemName=snowflake.snowflake-vsc<br>VS Code上でワークシート感覚で操作が可能になります。|

### その他
| サイト | 説明 |
|:-|:-|
| Snowflakeグッズ購入|https://www.snowflake-store.com/ |
【VSCode】PlantUMLの導入方法

## ローカルの場合
次のコマンドを実行します。  

```terminal
brew install --cask temurin
brew install graphviz
```

VSCodeの拡張機能をインストールします。  

https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml

以下のいずれかの拡張子のファイルを作成します。  

- `*.wsd`
- `*.pu`
- `*.puml`
- `*.plantuml`
- `*.iuml`

作成したファイルの内容を編集します。  

```sample.pu
@startuml Sample
hide circle
skinparam linetype ortho

entity user as "user" {
  *user_id [PK]
  --
  created_at [作成日]
  updated_at [更新日]
}

entity user_profile as "user_profile" {
  *user_profile_id [PK]
  --
  *user_id [FK]
  name [名前]
  email [メールアドレス]
  password [パスワード]
  created_at [作成日]
  updated_at [更新日]
}

entity post as "post" {
  *post_id [PK]
  --
  *user_id[FK]
  title [タイトル]
  body [内容]
  created_at [作成日]
  updated_at [更新日]
}

user ||-d-|| user_profile
user ||-r--o{ post

@enduml

```

`alt`+`D`またはコマンドパレットから`PlantUML: カーソル位置のダイアグラムをプレビュー`を実行します。  
すると以下のようにプレビューが表示されます。  

![image221230_224108.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fa6c6589-ece5-fb81-ffe3-fba8cc921270.png)

## PlantUML Serverの場合

次のコマンドを実行します。  

```terminal
docker run -d -p 8080:8080 plantuml/plantuml-server:jetty
```

拡張機能をインストールして設定を以下のとおり変更します。  

```settings.json
{
  "plantuml.server": "http://localhost:8080",
  "plantuml.render": "PlantUMLServer"
}
```

以降はローカルの場合と同様です。  

- 参考

https://github.com/plantuml/plantuml-server
STMicro 

STMicroのチップを使うことがあった。



# 32
STM32F103C8 で遊ぶ
https://qiita.com/nanbuwks/items/ba37f049f45378da0e2b


# 17
STM32F070xBで組み込みBootloaderを使って書き込んでみる
https://qiita.com/jiuya/items/43268c0bf397a7c21917

# 13
STM32CubeMX とPlatformIOでSTM32開発環境構築（NUCLEO-L432KCでLチカ）
https://qiita.com/desertfox_i/items/c6391e7d38148cfd4041

# 5
STM32F303K8 & mbedでSoftwareSerialを実装する 【TX編】
https://qiita.com/YuseiIto/items/ddc15a77fd7b57ffa757


# 3
STM32マイコン体験セミナー（高性能マイコン編）STM32H755ZI　DualCore STM32H7　2019年7月17日
https://qiita.com/usashirou/items/bb6ce9154c1f79809127


# 1
LoRaWAN対応無線モジュール Rhino WAN で STMicro および Semtech のライブラリを使用する場合の注意点
https://qiita.com/KiKUiCHi_R1R/items/6a272a5827815c4080df
Solidityの例外をcatchした時にerr.reasonの値がうまく取得できなかった

# 背景
- Soldityにて、コントラクトの状態変数のsetterを書く。

- コントラクトの所有者のみsetterが実行できることをテストで確認したい。
↓
SetterをOwner以外で実行すると例外が発生することを確認する。

# 問題
例外を取得しても、例外の理由をうまく取得できなかった。

# 具体的な状況

▼ Contract

```solidity
pragma solidity ^0.8.9;

import "openzeppelin-solidity/contracts/access/Ownable.sol";

class FundRaiser is Ownable {
  address payable public beneficiary;

  function setBeneficiary(address payable _beneficiary) public onlyOwner {
    beneficiary = _beneficiary;
  }
}
```

▼ Test (TypeScript)

```typescript
describe("setBeneficiary" , () => {
  it("throws an error when called from a non-owner account", async () => {
     const accounts = await ethers.getSigner();
     try {
     
       // Deployなどのコードは省略
      await 
        fundRaiser.connect(accounts[3]).setBeneficiary(accounts[2].address);
　   
      } catch (err) {
        const expectedError = "Ownable: caller is not the owner";
        const actualError = err.reason;
        // テストに失敗する
        expect(actualError).to.equal(expectedError, "should not be permitted");
      }
    }
  });
});
```

err.reason が undefined になり、テストに失敗する。

# なぜ上記のようなコードを書いたのか？

オライリー社の[SolidityとEthereumによる実践スマートコントラクト開発](https://www.oreilly.co.jp/books/9784873119342/)
を参考にしながらコードを書いたため。

書籍の中では、Truffule Suite を利用しているが、
私は、周囲のエンジニアがおすすめしていた hardhat を利用して書いたため、
動作が異なり、例外の理由がうまく取得できなかった。

# なぜ例外がうまく取得できないのか？

errの中身を調べたところ、Solidityから返ってくる例外をそのまま受け取っていた。
メッセージも16進数文字列で返ってきて、人間には読めない。

「Solidity undecoded error reason」などで検索をしたら、同様のことで困っている人が散見された。

例）[Custom contract error does not contain decoded error messages](https://github.com/NomicFoundation/hardhat/issues/1882)

# 解決

Error Reasonをパースする独自関数を作りました。

(1) errを文字列に変換する

```typescript
// Error: VM Exception while processing transaction: reverted with reason string 'Ownable: caller is not the owner'
const errString = err.toString();
```

(2) reason string以降の文字列を切り出す

```typescript
export const parseReason = (errString: string) => {
  const reason = errString.split("reason string '")[1];

  return reason.substring(0, reason.length - 1);
};

// Ownable: caller is not the owner
const actualReason = parseReason(err.toString());
```

(3) テストを完成させる

```typescript
it("throws an error when called from a non-owner account", async () => {
      try {
        await fundraiser
          .connect(accounts[3])
          .setBeneficiary(accounts[2]);
      } catch (err) {
        const expectedReason = "Ownable: caller is not the owner";
        const actualReason = parseReason(err.toString());

        expect(actualReason).to.equal(
          expectedReason,
          "should not be permitted"
        );
      }
    });
```

# 補足

Errorの文字列が `Error: VM Exception while processing transaction: reverted with reason string 'Ownable: caller is not the owner'` でした。

`reason string`以降の文字列を取る関数を作ろうと思った時、ぱっと思い浮かばなかったので、chatGPT先生に聞いてやりました。

![Screen Shot 2022-12-30 at 22.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131286/c76df768-d335-0338-b05f-3808fb0a6a98.png)
Ricoh

Ricoh の　竹内 良輔 さんが、リアルタイムOSの教材で、TaskでTaskモニタを作られていた。　

それまで、Taskが大嫌いだった。　

Task MonitorがTaskで書けるのなら、Taskも悪いものじゃないなという気になった。　

残念ながら、そのOSの正規配布版に含んでいない。残念だ。せっかくの機会を損失している。　

世の中には、せっかくのいいものを捨て、つまらないものを売り込もうという人がいるのかもしれない。　

いいものは、お金にならないこともあるのかもしれない。
# 19
RICOH THETA Sをnode.jsから使ってみる
https://qiita.com/FePlus/items/aaeca40468d49786e2f5

# 17
RICOH THETA m15で撮影した動画を使ってハコスコ用のアプリを作る（その１：全天球モデルを作る）
https://qiita.com/ndyuya/items/64d9a952eaf0ba7ea30f


 # 14
RICOH THETA X におけるプラグイン開発
https://qiita.com/KA-2/items/35d7ef550d2aead50cb4

RICOH THETAの全天球動画を正距円筒図法へFFmpegで変換する
https://qiita.com/colspan/items/7aaecc40e085b1a2b943

Go言語でRICOH THETA API v2を叩いてみた
https://qiita.com/toshi3221@github/items/60baf51256d63183e43e


# 10
Ricoh Theta Sで出来ること(基礎機能編)
https://qiita.com/seiya1121/items/58b76a1b1fbc872f88eb


# 8
Batch conversion for RICOH THETA S 360 degree movies
https://qiita.com/mizba/items/d3139e81b38ca6d29260

RICOH THETA＋FLIRC USBで赤外線リモコンなんでも使えますよ？
https://qiita.com/KA-2/items/e3c2149d87cd9e493460

# 7
GDAL で RICOH THETA 画像を再投影
https://qiita.com/tohka383/items/c2c5cf3b0eb76ce1d022


# 5
ESP32でRICOH THETAの静止画を取得する
https://qiita.com/igapon1/items/07b61e2f6b14c9f1828f


# 4
Ricoh camera SDK for .NET,C# のUSB接続カメラ撮影から画像保存まで
https://qiita.com/Kusunoki_/items/db9ca04c559d31cae039
UE5 EQSの雑メモ



さわったのでメモ。

# EQSの準備をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/1ac5ec6e-2a1b-0460-9f53-8543f33e8c1a.png)
 * EQSTestPawn テスト用のPawn（黄色
 * EOC_Xxxx　↓の誰がの部分
 * EQS_Xxxx 本体

# 設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/0cd667a4-1b7c-73b8-475b-64f6b7d2b09a.png)
* Itemを作成する（赤い枠
  * 誰の周りにどんな配置でItemを配置するか
* ItemのScoreやFillterを設定する（オレンジ
  * 誰からの距離（近い、遠い）
  * Trace　Ray,SphereのTrace

# 使用方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/9ce8adc8-af87-f35e-acac-c8d8ec2cbb32.png)

 * BehaviorTreeにてRunEQSQueryで実行
 * 実行結果をBlackBoardのTargetLocationに入れる
 * MoveToでTargetLocationに移動
Unisys 現在は Biprogy

海外資本の日本法人で好感が持てた上位7社

https://qiita.com/kaizen_nagoya/items/3fe73f280edf5e2b6449

で紹介したうちの１社　Unisys。　

今はBiprogyというらしい。

https://www.biprogy.com/com/history.html

日本コンピューター産業の父「池田敏雄」から見る黎明期コンピューターの歩み

https://qiita.com/yaju/items/49de76b5167b0814e64a

の記事にUnisysという文字が２回でているぐらい。　
Qiitaにはほとんど情報がない。　

参考文献の参考文献は参考文献だ。清水吉男「「派生開発」を成功させるプロセス改善の技術と極意」を超えて

https://qiita.com/kaizen_nagoya/items/562a0cf784cf92bc0ebb

の記事にUnisys技報を紹介している。　

風変わりなC言語処理系たち

https://qiita.com/yohhoy/items/74f40005178c48388375

でUnisysの9bit機の紹介がある。
VMware

VMware は、数年お世話になりました。　

最近でも、年に１、２回はお世話になっています。　

クラウド上でVMWareが利用できることを知りました。　

# 20
vmware vSphere (VMware)からAWSへvmimport
https://qiita.com/kazumihirose/items/0f99eff7131dea262a38

# 10
VMwareのエッジソリューション（Edge Compute Stack）でマルチK8s管理のTanzu Mission Controlが使われている件について
https://qiita.com/two2mi/items/279371a1101a78d7d2ca

# 3

【VMware】VMware vSphereにさわってみた
https://qiita.com/kazu56/items/44888dbf5e1edc1149d6

VMware Cloud on AWSとAWS Managed Microsoft ADを連携させてユーザー権限管理してみた
https://qiita.com/sanjushi003/items/5bdc992c2e2c833c9d3b

# 2
VMware Cloud on AWS アップデートまとめ (VMware Explore 2022 編)
https://qiita.com/sanjushi003/items/cae4c9a747a855c48944

# 1
VMware Cloud on AWS のサイジングについて (VMware Cloud Sizer)
https://qiita.com/sanjushi003/items/b81fedb91750e1946d13

VMware Hands-on Lab (VMware HoL)でお手軽ハンズオン体験 (VMware Cloud on AWS編)
https://qiita.com/sanjushi003/items/ba6426b202215f39ba22

OVFテンプレート Export / Import でVMware仮想マシンの移行を試してみた #2 VMware Cloud on AWS 環境間の移行
https://qiita.com/sanjushi003/items/c065bdcde57e112ce10d
PHPでPIDが存在するかチェック【file_exists vs posix_getpgid vs is_dir vs posix_kill】

# TL;DR

`posix_getpgid($pid)`を使うのがオススメ

https://stackoverflow.com/questions/9874331/how-to-check-whether-specified-pid-is-currently-running-without-invoking-ps-from

PHPでPIDがあるか確認する方法はいくつかあるが、最速を検討する

```php
<?php
// cf. https://stackoverflow.com/questions/9874331/how-to-check-whether-specified-pid-is-currently-running-without-invoking-ps-from

$pid_max = file_get_contents('/proc/sys/kernel/pid_max');
$pids = array_map(fn()=>random_int(1, $pid_max), range(1,2**20));


$start = microtime(true);
foreach ($pids as $pid) {
    file_exists("/proc/$pid");
}
echo "file_exists:\t" . microtime(true) - $start . PHP_EOL;

$start = microtime(true);
foreach ($pids as $pid) {
    is_dir("/proc/$pid");
}
echo "is_dir:\t\t" . microtime(true) - $start . PHP_EOL;

$start = microtime(true);
foreach ($pids as $pid) {
    posix_getpgid($pid);
}
echo "posix_getpgid:\t" . microtime(true) - $start . PHP_EOL;

$start = microtime(true);
foreach ($pids as $pid) {
    posix_kill($pid, 0);
}
echo "posix_kill:\t" . microtime(true) - $start . PHP_EOL;
```

結果
```yaml
$ seq 10 | xargs -n1 php pid_perf.php
file_exists:    2.1520388126373
is_dir:         1.6568348407745
posix_getpgid:  0.12570405006409
posix_kill:     0.14235901832581
file_exists:    2.1547100543976
is_dir:         1.6315920352936
posix_getpgid:  0.12148284912109
posix_kill:     0.14736986160278
file_exists:    2.121838092804
is_dir:         1.6587860584259
posix_getpgid:  0.12204599380493
posix_kill:     0.13927102088928
file_exists:    2.1496820449829
is_dir:         1.6658518314362
posix_getpgid:  0.12524199485779
posix_kill:     0.14765810966492
file_exists:    2.1388080120087
is_dir:         1.6538898944855
posix_getpgid:  0.12666511535645
posix_kill:     0.14308190345764
file_exists:    2.0925102233887
is_dir:         1.7037389278412
posix_getpgid:  0.12445998191833
posix_kill:     0.13687419891357
file_exists:    2.0917370319366
is_dir:         1.6500859260559
posix_getpgid:  0.1252658367157
posix_kill:     0.14215397834778
file_exists:    2.0797710418701
is_dir:         1.6966879367828
posix_getpgid:  0.12555503845215
posix_kill:     0.14388394355774
file_exists:    2.099790096283
is_dir:         1.6563739776611
posix_getpgid:  0.12412095069885
posix_kill:     0.14297080039978
file_exists:    2.0959348678589
is_dir:         1.6471560001373
posix_getpgid:  0.12421989440918
posix_kill:     0.13587403297424
```

![100万回実行時の時間.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/1bb79c70-6726-56ab-1938-942f8157d3b5.png)
https://docs.google.com/spreadsheets/d/1eBSfgY25oLwCth579y-LXDclXpoeNCx4crK9x8ypazE/edit?usp=sharing
【SwiftUI】リストにスワイプアクションを追加する

# はじめに
https://developer.apple.com/documentation/swiftui/view/swipeactions(edge:allowsfullswipe:content:)

iOS15から`swipeActions`というメソッドが追加されていました。
以下のような機能を実装することができます。
![Simulator Screen Recording - iPhone 14 - 2022-12-30 at 21 26 13](https://user-images.githubusercontent.com/84154073/210070104-dc608f68-76ed-4290-a86c-49a1d183c535.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        List {
            Text("サンプル")
                .swipeActions(edge: .trailing, allowsFullSwipe: true) {
                    Button {
                        print()
                    } label: {
                        Text("削除")
                    }
                    .tint(.red)
                }
                .swipeActions(edge: .leading, allowsFullSwipe: true) {
                    Button {
                        print()
                    } label: {
                        Text("お気に入り")
                    }
                    .tint(.yellow)
                }
        }
    }
}
```

# 解説
## edge
`edge`は以下の指定ができます
|||
|-|-|
|`.trailing`|左方向にスワイプした時に表示|
|`.leading`|右方向にスワイプした時に表示|

## allowsFullSwipe
`allowsFullSwipe`はBoolでの指定です。
`true`を指定すると、スワイプを長めにすると実行されます。
`false`を指定すると、削除を押さないと実行されません。
|true|false|
|-|-|
|![simulator_screenshot_79BE90E7-187D-45F5-B80F-829A5B3E2B35](https://user-images.githubusercontent.com/84154073/210070508-56016a44-3db5-4e89-a15e-04e26921ee9d.png)|![simulator_screenshot_1971A2D2-CFCE-43AE-A75B-EADC28DCFAC9](https://user-images.githubusercontent.com/84154073/210070587-82b34802-81ca-4e83-a4aa-358d8c1ebea2.png)|

## content
おそらく`Button`のみ有効です。
他のコンポーネントも指定できますが、機能しません。

### 色の変更
`tint`で色を変更することができます。
```diff_swift
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
    Button {
        print()
    } label: {
        Text("削除")
    }
+   .tint(.red)
}
```
![simulator_screenshot_34251ABA-EE7E-4FD5-80A5-27DFD49CBF37](https://user-images.githubusercontent.com/84154073/210071274-2e6e42c2-5cdd-48e0-8787-a1ea9e766f55.png)

### 複数のボタンの配置
`content`内に`Button`を複数配置するだけです
```swift
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
    Button {
        print()
    } label: {
        Text("お気に入り")
    }
    .tint(.yellow)
    
    Button {
        print()
    } label: {
        Text("削除")
    }
    .tint(.red)
}
```
![simulator_screenshot_AE5FF865-6CB2-4715-9288-429631354CC4](https://user-images.githubusercontent.com/84154073/210071154-ebf2b0f2-4f6f-44b8-80eb-edf3b3220d20.png)

# おわり
これは便利ですねー
ラズパイにgitlab runnerをインストールした話

### 前回、ラズパイ4にgitlabをインストールしました。<br>次はCIを行える環境を構築していきたいと思います。

## 関連記事
　　|リンク
---|---
gitlabインストール| [ラズパイにgitlab-eeをインストールした話](https://qiita.com/AQUA651/items/e3780a639682cc87400d)

## 開発環境
　　|バージョン
---|---
筐体|rasberry Pi4 8GB
OS | Ubuntu Server 22.10
gitlab|gitlab-ee 15.6.2-ee
gitlab-runner　<font color="Red">追加</font>|15.7.1

## 今回のお題
1．gitlab-runnerのインストール
2．dockerのインストール
3．動作検証

を行っていきます。

## 1．gitlab-runnerのインストール
#### Gitlabの「Admin Area」→「Runners」→「Register an Instance runner」→「Show runner installation and registration instructions」の順でクリックし、以下の画面を表示してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196226/b5601ea2-75f9-b528-2da5-3c4cb3218553.png)
※「Download and install binary」の項目に記載されている順にインストールを行ってください。

## 2．dockerのインストール
#### gitlab runnersは、裏で、dockerを使って、指定された作業を行っているようです。<br>正確には、この後の設定で、dockerを選択することで、そうなりますが、今回は、その辺の詳細は省きます。（まだ勉強できておらず、理解できてないだけですｗ）
#### 以下のコマンドからdockerの公式GPG鍵を取得します。
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
```

#### 以下のコマンドを実行し、dockerをダウンロードします。
```
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```

#### Docker Engineのインストールを行います。
```
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```

#### 以下の内容が表示されたら、正常にインストールされたことになります。
```
$ No VM guests are running outdated hypervisor (qemu) binaries on this host.
```
## 3．動作検証
#### では、実際に動作検証を行っていきます。<br>利用したコードは、golangでHelloworld!を表示させるだけの簡単なコードです。<br>そのコードに、静的解析とビルド、UnitTESTを行うようにしてみます。ymlファイルは以下です。
```.gitlab-ci.yml
image: golang:latest

stages:
  - lint
  - build
  - unittest

# 静的解析を実施
go_staticcheck:
   stage: lint
   image: golang:latest
   before_script:
     - go install honnef.co/go/tools/cmd/staticcheck@latest
   script:
     - go vet src/main.go
    

# goのビルドを実施
go_build:
  stage: build
  image: golang:latest
  script: go build src/main.go

# UnitTEST実行
go_unittest:
  stage: unittest
  image: golang:latest
  script: go test -v -cover src/main_test.go src/main.go
```

これをgitlab上にコミットしてみると、以下の様に実行され、無事passedとなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196226/146195fb-3bce-68e3-5601-e7c8836e313b.png)

今回は以上となります。

## 終わりに
#### 今回は、説明が少し雑になってしまいました。読んでもらったのにすみません。<br>次回はもう少し、分かりやすく書くようにします。

## 参考にしたサイト
https://matsuand.github.io/docs.docker.jp.onthefly/engine/install/ubuntu/
自動入力を阻止したいのに、autocomplete="off"が効かない

### なぜ自動入力が起こるのか

自動入力はブラウザがinput要素の属性を認識し、その値がブラウザに保存済みの情報と何らかの関連があると判断した場合に発生します。

例：
input要素のname属性に"mail"等メールに関連する単語が含まれる場合、メールアドレスの入力欄として認識される。
または、type属性がpasswordとなっている場合、パスワードの入力欄として認識される。
etc.

対処法として最初に検索結果に上がってくるのは、input要素についてautocomplete="off"と記載する方法ですが、効果がない場合が多いようです。

今回は自動入力の原因となっている要素を画面ロード時、一時的に変更することで自動入力を阻止するコードをjQueryで実装します。

### 処理の流れ

1. 初期表示の段階では、ブラウザに認識されないような属性を設定しておく（例：メールアドレスの入力欄のname属性に"mail"という単語を含まない）
1. mousedownイベントで本来の属性に変更し、自動入力を誘発
1. setTimeout()でタイムアウトさせる

以下のようなHTMLを想定します。

```html
<!-- nameにメールを連想させる単語を記載しない -->
<tr>メールアドレス</tr>
<td><input type="text" name="e"></></td>

<!-- type="password"としない、かつnameにパスワードを連想させる単語を記載しない -->
<tr>パスワード</tr>
<td><input type="text" name="p"></></td>
```

それぞれの入力欄について、以下のようなコードを記載します。

```javascript
// メールアドレス入力欄
let email = $('input[name="e"]');

email.on('mousedown', function() {
    email.attr('name', 'email');
    setTimeout(function() {
        email.focus();
    }, 1);
})

// ブラウザによっては範囲選択が効かなくなってしまうことがありますが、その場合は以下を追加してください
email.css('user-select', 'text');
```

```javascript
// パスワード入力欄
let password = $('input[name="p"]');

password.on('mousedown', function() {
    password.attr('type', 'password');
    setTimeout(function() {
        password.focus();
    }, 1);
})


// ブラウザによっては範囲選択が効かなくなってしまうことがありますが、その場合は以下を追加してください
password.css('user-select', 'text');
```

上記は、すでに保存されているパスワードを黒丸で表示したい場合は使えないので(初期表示がtype="password"ではないため)、実際には値があるかどうかで場合分けします。

```javascript
if (email.val()) {
    email.attr('name', 'email');
} else {
    email.on('mousedown', function() {
        email.attr('name', 'email');
        setTimeout(function() {
            email.focus();
        }, 1);
    })
}
```

```javascript
if (password.val()) {
    password.attr('type', 'password');
} else {
    password.on('mousedown', function() {
        password.attr('type', 'password');
        setTimeout(function() {
            password.focus();
        }, 1);
    })
}
```

今回紹介した方法は、以下の記事を組み合わせて考案しました。
ロードされた段階で自動入力が発生していることが前提となるので、もしmousedownイベントと共に自動入力が発生する場合は、こちらの記事を参照してみてください。

https://blog.soln-sns.net/how-to-solve-the-google-chrome-autocomplete-off-problem/

https://yassu.jp/pukiwiki/index.php?autocomplete%A4%F2%CC%B5%B8%FA%B2%BD%A4%B9%A4%EB
基本処理情報技術者試験　ロールフォワード　ロールバック

技術者試験の問題の

マネジメント系 » サービスマネジメント » サービスの運用
ここに分類される一つにデータベースの問題があります

システムに障害が起きたときに行われる処理があります。

「ロールバック」と「ロールフォワード」についてです。
これらは両方ともデータベースでの処理でエラーが発生した時に行われます。

違いを分かりやすくまとめると最後に行ったバックアップ以降のデータを再現させるかどうかです。

ロールバックとロールフォワードの詳しい処理を説明するためには「トランザクション処理」という言葉を理解しておく必要があります。トランザクション処理とは一連の処理をひとつにまとめた処理として判定をおこなうものである。例えば入出金の処理では入金失敗した場合に出金処理も同時に取り消します。そのためすべての処理が完了するまで結果を確定としません。

それではロールバックとロールフォワードについて詳しい説明をしたいと思います。データベースでエラーが生じたときに定期的にバックアップしているファイルを利用して元の状態に戻します。しかし、それだけではバックアップ後に変更されたデータが反映されません。そこで、バックアップ後の更新データであるジャーナルファイルを反映させてデータを直前の状態に戻します。
ロールバックではトランザクション処理の途中の処理もすべて取り消して最初の状態に戻します。これによってバックアップ直後のデータベースの状態に戻します。この後再び最初からトランザクション処理を行うことでデータの整合性を守っています。

一方で
ロールフォワードにおいてはバックアップファイルに加えて、ジャーナルファイルを利用して障害発生直前の状態に戻そうとします。
![ロールフォワード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606732/a3581178-8dd6-2a86-c725-3ed9176aecec.jpeg)

参考サイト
ロールフォワードとは - ITを分かりやすく解説
https://medium-company.com/%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%89/
[Postman]Run Collectionを使ってcsvの内容を自動で連続postする

## Postman の Run Collectionとは
Postmanで用意したCollection（ディレクトリのようなもの）の中にあるすべてのリクエストを走らせる機能です。

一般的にはpostアクションのapiのテストに使われることが多いようですが、postman経由でbodyが異なる複数のpostアクションのリクエストを送りたい場合にも有用なことがわかったため記事にしました。


## やり方の手順
1. サイドバーのCollectionsをクリックしてCollection（フォルダ）とrequestを用意する
![スクリーンショット 2022-12-30 12.25.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/1e2c6a98-356f-d8fc-8c93-8c91f760bc79.png)

2. 通常のpostmanの使い方で送りたい内容を準備する
![スクリーンショット 2022-12-30 17.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/e72a1a51-d800-3e80-3fa3-e42a563b9122.png)

3. 期待通りのレスポンスが返ってくるか動作確認を行う
![スクリーンショット 2022-12-30 17.28.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/c23eb110-1b26-249a-f470-0d9e0b48e5fa.png)

4. csvから情報を読み取れるようにPre-reqを用意
![スクリーンショット 2022-12-30 17.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/0ed8ae4b-21e3-f9d9-cbe6-334d5abb60e3.png)

5. bodyの中身を変数化
![スクリーンショット 2022-12-30 20.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/1c5b2e1b-be21-3574-4662-44c9d0b858a6.png)


6. お好みでTestsを実装
![スクリーンショット 2022-12-30 18.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/dcd0498a-8b3d-4d30-3319-8451df08fc87.png)

7. Run Collectionの画面を開く
![スクリーンショット 2022-12-30 17.54.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/151a77e7-40b4-4a27-b009-170b59e7a196.png)

8. Select Fileを押してcsvファイルを選択する
![スクリーンショット 2022-12-30 18.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/cb8c8cae-c170-7030-5e5d-e3e0771d380f.png)

![スクリーンショット 2022-12-30 18.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/964813bf-c310-5e1d-0e43-5d9bc2b19ab7.png)

9.Runボタンで実行
![スクリーンショット 2022-12-30 18.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/d63cfd42-d7ff-3bfb-0dcb-3ad276016500.png)

10.成功したか確認
![スクリーンショット 2022-12-30 18.53.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/ce31000a-ea78-d266-2540-894d07a72bcc.png)

11.必要に応じてoption+cmd+cでresponseの詳細を確認
![スクリーンショット 2022-12-30 20.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/24c49717-2761-e1b9-8064-6fb57c6a9755.png)


以上です。

## なぜこのような使い方をしたのか
きっかけはnodeで文字列をpostしようとしたときに、JOSON.stringify()にシングルクォートを含む文字列を入れられなかったのですが、`LET'S GO！`のような文字列はそのままの形でpostしたいと思ったからでした。（サードパーティのシステムだったので、csvのまま読み込ませるのは不可能でした。）

試行錯誤の結果、Postmanを利用すればシングルクォートのままpost可能だと分かったため、csvのデータを連続でpostする方法を探すこととしました。

## おわりに
Run Collectionではテストで使用するための記事が多いですが、もっとできることの幅が広いことを皆さんにも知っていただけたら、さらに開発が楽になるのではないかなと思います。

## 参考
https://blog.postman.com/using-csv-and-json-files-in-the-postman-collection-runner/
AWS EC2のRHEL9にTeraTerm4からログインする

# 突然EC2にログインできなくなった？？

普段通りEC2を起動してTeraterm(バージョン4.106)からログインしようとしたところ、ある日突然以下の画面になってアクセスできなくなった・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820066/4d047b0c-ccc4-08d3-2346-2f3bd7bd377e.png)

# ググってみた結果・・・

ssh-rsaのアルゴリズムがteratermだとSHA-1で、どうやらRHEL9からはSHA-1でのアクセスがNGになっているみたいです。

参考記事：
    [セキュリティーが強化された最新版のRed Hat Enterprise Linux 9 - 日経クロステック](https://xtech.nikkei.com/atcl/nxt/column/18/02195/091300005/)
[OpenSSHがSHA-1を使用したRSA署名を廃止 - Nulab](https://nulab.com/ja/blog/backlog/disables-rsa-sig-using-the-sha-1-in-openssh/)
[OpenSSH、今後はRSA/SHA1をデフォルトで無効に - Think IT](https://thinkit.co.jp/news/bn/18734)

# 対応① EC2起動時のユーザーデータにコマンドを追加する。

以下の参考記事にズバリの記載がありました。

参考記事：
[Red Hat Customer Portral 3.9. SHA-1 を再度有効に](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/security_hardening/proc_re-enabling-sha-1_using-the-system-wide-cryptographic-policies)

それをもとに、ユーザーデータに以下を加えてみます。

```:EC2起動時のユーザーデータ
#!/bin/bash
sudo update-crypto-policies --set DEFAULT:SHA1
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820066/bce26980-b73e-3471-1d05-889e45dbb61d.png)

これを入れたら、無事にログインできました。
暗号化ポリシーが`DEFAULT:SHA1`になっていることも確認できました。

```:TeraTeam
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Fri Dec 30 11:03:25 2022 from 217.178.22.41
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo update-crypto-policies --show
DEFAULT:SHA1
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$
```

# 対応② Powershellからアクセスする。

以下の通り、Powershellからはアクセスできました。
アクセス後に対応①と同じコマンドを打って`DEFAULT:SHA1`に設定した後は、Teratermからもアクセスできるようになりました。(再起動を推奨されたが、再起動しなくてもTeratermからもいけた。)

```:Powershell
PS C:> ssh -i .\xxxkey.pem ec2-user@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
The authenticity of host 'ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com (xxx-xxx-xxx-xxx)' can't be established.
ED25519 key fingerprint is SHA256:2XZ3bR13xYOGSk59jCMSaEGi1VsCSENXOB9MH16PpCM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com' (ED25519) to the list of known hosts.
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
[ec2-user@ip-172-31-37-42 ~]$
[ec2-user@ip-172-31-37-42 ~]$ sudo update-crypto-policies --set DEFAULT:SHA1
Setting system policy to DEFAULT:SHA1
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.
[ec2-user@ip-172-31-37-42 ~]$ sudo update-crypto-policies --show
DEFAULT:SHA1
[ec2-user@ip-172-31-37-42 ~]$
```

# 今後は・・・
おそらくTeratermもSHA-1廃止対応を実施中だと思うので、その動向を見守ろうと思います。
ちなみに、EC2でAmazon Linux2を選択した場合は普通にTeratermでアクセスできました。しばらくは、とりあえずサーバー建てたいときはそっちのほうが楽かも・・・
【技術書まとめ】HTML&CSS コーディング・プラクティスブック 5 実践シリーズ

引き続き現在のCSSを整理するために本書を手に取った。

作成したサイト
https://voluble-meerkat-4d6143.netlify.app/

- レイアウト
    - Flexboxは「横に並べる1次元」
    - CSSグリッドは「縦横に並べる2次元」
        - ガイドラインを基準にパーツを配置できる



## ページ全体に3カラムのグリッドを作成する

```css
.pageGrid {
  display: grid;
  grid-template-columns: 72px auto 72px;
  grid-template-rows: 72px auto auto;
}

/* ナビゲーションボタン */
.nav-button {
  grid-column: 3;
  grid-row: 1;
}

/* SNSメニュー */
.sns {
  grid-column: 3;
  grid-row: 2;
}

/* 縦書きテキスト */
.decor {
  grid-column: 1;
  grid-row: 2;
}

/* フッター */
.footer {
  grid-column: 1 / -1;
  grid-row: 3;
}
```

## 3カラム目の右上に揃えてから余白を調整する・中はgridとgapで余白をとる

```css
.sns {
  grid-column: 3;
  grid-row: 2;

  /* 右上に揃えてから余白を調整する */
  justify-self: end;
  align-self: start;
  margin-top: 187px;
  margin-right: 10px;

  /* gridとgapを使って余白をとる */
  display: grid;
  gap: 30px;
}
```


## すべてのグリッドアイテムを2列目に配置する（擬似要素含む）

```css
.partsGrid > *,
.partsGrid::before,
.partsGrid::after {
  grid-column: 2;
}
```

## 中央のサイズを1074pxに固定して、左右の余白を1frで同じサイズにする

```css
.partsGrid {
  /* 「fr」は「フレキシブル」で、1列目と3例目は全体から1074pxを除いたスペースから1:1で分割したサイズとなる*/
  grid-template-columns: 1fr 1074px 1fr;
}
```


### 左右余白の最低幅を維持しながらminmaxを使って可変にする・中央の最大幅は1074pxとする

```css
.partsGrid {
  grid-template-columns: minmax(72px, 1fr) minmax(auto, 1074px) minmax(72px, 1fr);
}
```

## 2カラム幅固定で3列のギャラリーを作る

```css
.gallery {
    display: grid;
    grid-template-columns: 158fr 167fr; /* pxをfrにして変動幅にする */
    grid-template-rows: 173px 136px 136px;
    gap: 10px;
}

.gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* 画像を切り抜く */
}
```

### グリッドエリアで画像の配置先を指定する

![スクリーンショット 2022-12-26 10.01.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282504/f98a0721-a915-f265-89de-8ee2e5d46617.png)


```css
.gallery {
  display: grid;
  grid-template-columns: 158fr 167fr;
  grid-template-rows: 173px 136px 136px;
  grid-template-areas:
    'A A'
    'B C'
    'B D';
  gap: 10px;
}

.gallery .photoA {
  grid-area: A;
}
.gallery .photoB {
  grid-area: B;
}
.gallery .photoC {
  grid-area: C;
}
.gallery .photoD {
  grid-area: D;
}
```

## グリッドを使ってメニュー項目を中央に寄せる

```css
.nav ul {
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 50px; /* 間隔はgapで指定する */
}
```

- `justify-items`と`justify-content`との違い
    - アイテムに指示するのが`~-items`で、グリッドに指示するのが`~-content`

![スクリーンショット 2022-12-30 19.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282504/68f4e66d-6dbb-5fa2-d9c8-592141f9ef38.png)
ページングしながら全体の表示件数をある倍数にする


```php
 $maxPage = $lastPage = (int) ceil($totalCount / $this->getDisplayNumber());
        // 1ページでおさまるときは調整しない
        if (1 < $lastPage) {
            // 10件ずつにした際の端数
            $modByTen = $totalCount % 10;
            // ページングした際の最終ページの件数
            $modByDisplayNumber = $totalCount % $this->getDisplayNumber();

            // 全てのページが埋まっているときや、もとから10の倍数のときは調整しない
            if (0 !== $modByDisplayNumber && 0 !== $modByTen) {
                $adjust = $modByDisplayNumber - $modByTen;

                if (0 === $adjust) {
                    // 端数落としで最終ページ分がなくなったとき
                    return [$uuids, $maxPage - 1];
                }

                if ($pageNumber === $lastPage) {
                    // 最終ページの件数を調整
                    $roundedUUids = array_slice($uuids, 0, $adjust);
                    return [$roundedUUids, $maxPage];
                }
            }

        }
        return [$uuids, $maxPage];
```
XAMPP 8.2.0がリリースされましたん🎉🐘

https://www.apachefriends.org/blog/new_xampp_20221229.html

こんにちはアパッチフレンズ！

PHP 8.2.0 用の Windows、Linux、および OS X 用の XAMPP の新しいバージョンをリリースしました。これらの新しいインストーラーはhttp://www.apachefriends.org/download.html からダウンロードできます。

これらのインストーラーには、次の主要コンポーネントが含まれています。

8.2.0-0

PHP 8.2.0
アパッチ 2.4.54
マリアDB 5.4.27
phpMyAdmin 5.2.0
OpenSSL 1.1.1p (Windows) および OpenSSL 1.1.1s (Linux および OS X)
PHP バージョン7.4.xは現在サポートが終了していますが、引き続きSourceForge XAMPP サイトから以前のバージョンをダウンロードできます。

OS X ネイティブ インストーラには、新しい OS X M1 および M2 (ARM アーキテクチャ) の OS X Rosetta 環境でサポートされる x86_64 バイナリが同梱されています。XAMPP VM は ARM アーキテクチャと互換性がありません。OS X Rosetta 環境は、x86_64 コンピューター プラットフォームを仮想化する仮想マシン アプリを変換しません。このため、XAMPP は OS X VM をサポートしなくなりましたが、SourceForge XAMPP for OS X フォルダから以前のバージョンをダウンロードできます。

プロジェクトに貢献することもできます。すべてのコードとリソースは、GitHub Apache Friendsプロジェクトで入手できます。また、プロジェクトの次の主要な機能と改善を計画するために、フィードバックをお待ちしております。この匿名フォームに記入して、私たちを助けてください!
Dockerでのcgroupの利用について


# はじめに

Dockerはコンテナのリソース管理をするためにLinuxカーネルの機能であるcgroupを用いています。今回はcgroupについて解説しつつ、Dockerでどのように用いられているか確認します。

## cgroupとは

cgroup（Control Group）は、Linuxカーネルの機能の1つで、システムリソース（CPU、メモリ、ディスクIO、ネットワークなど）を使用する**プロセス**をグループ化し、それぞれのグループに対してリソース使用量を制限することができるものです。

## cgroupのコントローラー

cgroupはリソースごとにコントローラーが存在し、コントローラーはcgroupfsという特別なファイルシステムを介して使います。Ubuntu20.04では `/sys/fs/cgroup` ディレクトリ以下に、各コントローラーに対応するcgroupファイルシステムがマウントされています。ファイルシステムは、ストレージデバイス上に存在するわけではなく、**メモリ**上にだけ存在し、アクセスするとカーネルのcgroup機能を使えるという仕組みになっています。

```console
$ ls /sys/fs/cgroup

blkio  cpu  cpu,cpuacct  cpuacct  cpuset  devices  freezer  hugetlb  memory  misc  net_cls  net_cls,net_prio  net_prio  perf_event  pids  rdma  systemd  unified
```

## Dockerでの利用

Dockerでどのようにcgroupが使用されているか確認します。

### CPU制限付きのコンテナの起動

CPU使用率が30%に制限付きのNginxコンテナを立ち上げます。

```
docker run --cpus 0.3 --name nginx -d -p 80:80 nginx
```

先ほど立ち上げたNginxコンテナのプロセスを確認します。`docker top`コマンドを使いました。

```console
$ docker top 109f9220afcc(CONTAINER ID)
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12199               12175               0                   17:47               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            12248               12199               0                   17:47               ?                   00:00:00            nginx: worker process
```

## Dockerが作成したcpuコントローラーのグループ

Dockerが新たにグループが作成していることが分かります。

```console
$ ls /sys/fs/cgroup/cpu/docker

109f9220afcceff3245cb227beb164c21a25093c7f5300ca34b35d8474f66688
```

`cpu.cfs_quota_us`ファイルの中身を確認すると**30000**となっておりCPU使用率が30%に制限するように設定しています。

```console
$ cat /sys/fs/cgroup/cpu/docker/109f9220afcceff3245cb227beb164c21a25093c7f5300ca34b35d8474f66688/cpu.cfs_quota_us

30000
```

また、`tasks`ファイルには立ち上げたNginxコンテナ関連のPIDが記述されています。これによってコンテナのCPU使用率を制限することができます。

```console
$ cat /sys/fs/cgroup/cpu/docker/109f9220afcceff3245cb227beb164c21a25093c7f5300ca34b35d8474f66688/tasks

12199
12248
```

### CPU使用率が制限されるのか

Nginxコンテナ内に入ってCPU使用率を上げてみます。
```console
$ docker exec -it nginx bash
```

yesを連続で出力することでCPU負荷をかけます。
```console
# yes > /dev/null
```

別でターミナルを開き、ホストOSにて`top`コマンドを使うと コンテナで実行しているプロセスのCPU使用率が制限されていることが分かります。

```console
$ top 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                          
  12725 root      20   0    2388    556    496 R  29.9   0.1   0:36.08 yes
```

# さいごに

DockerはLinuxカーネルの機能であるcgroupを利用していることを確認できました。もっとDockerに詳しくなりたいです。

# 参考文献

https://gihyo.jp/admin/serial/01/linux_containers/0003
Mac で binutils をインストールしている状態で rbenv 経由で Ruby をインストールする際のエラー回避

# 概要

https://qiita.com/Hiragi-GKUTH/items/bbd37608b7a517c6ed6d

を見た後に行った回避方法について記載しています。

# 環境

- macOS Monterey 12.5 / Intel プロセッサ
- rbenv 1.2.0
- zsh 5.8.1 (x86_64-apple-darwin21.3.0)
- binutils 2.37
- インストールしようとした Ruby のバージョン : 2.6.9

# 個人の経緯

rbenv で Ruby のインストールに失敗して、失敗ログを確認したら以下の記事と同様のエラーログということがわかりました。

https://qiita.com/Hiragi-GKUTH/items/bbd37608b7a517c6ed6d

rbenv がビルドの際に使う Mac のコマンドを PATH 的に binutils のものを優先してしまうことでエラーが発生するようです。

binutils 自体は使うためアンインストールしたり、PATH から外したりはしたくないです。
次のように rbenv 実行時にのみ PATH を変更する(=`/usr/local/opt/binutils/bin` を削除する)ように回避することにしました。

# 回避方法: rbenv 実行時にのみ PATH を変更する

PATH から sed を使って `/usr/local/opt/binutils/bin` を削除し、rbenv を実行しました。

```sh
PATH=$(echo $PATH | sed -e 's|/usr/local/opt/binutils/bin:||') rbenv install 2.6.9
```

これで Ruby をインストールできました。

## 補足

コマンド前に環境変数の定義をするとその行だけ環境変数が有効になります。
セッション中ずっと無視していいなら普通に export してもいいです。

```
$ env | grep PATH
PATH=/usr/local/opt/binutils/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

$ PATH=$(echo $PATH | sed -e 's|/usr/local/opt/binutils/bin:||') env | grep PATH
PATH=/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

$ export PATH=$(echo $PATH | sed -e 's|/usr/local/opt/binutils/bin:||')
$ env | grep PATH
```
【初心者】アプリ開発の際にコードを書く前に意識するべきこと

# 結論
「コピペでそのまま使えるサンプルコードが出てくるレベルまで要件を細分化すること」です。
これを意識すると学習不足の言語でも「とりあえず動く」アプリを作れる可能性が高いと感じます。具体的にどうすれば良いのか、以下に書いていきます。


# 前提
あくまでも「とりあえず動くアプリを作りたい！」という方向けの提言です。コードやレイアウトの質より先に、「まずは動く」ことを目標にしています。


# 「要件の細分化」とは？
例えば、Webブラウザで閲覧できる2chのような掲示板を作りたいとします。
すると、大雑把に要件を列挙すると以下のようになります。
* 投稿できる
* 他の人の投稿を閲覧できる
しかし、これでは要件が抽象的すぎます。この要件をもとに初心者がコードを書くのは難しいでしょう。

そこで、「投稿できる」という要件をさらに細分化してみます。
* 投稿内容を入力する入力欄を表示する
* 入力した内容を投稿するためのボタンを表示する
* ボタンを押すとサーバーに入力内容が送信される

ここまで細分化するとHTMLやCSSに疎くてもググりやすいですよね。「HTML 入力欄 作成」とググればコピペできるコードがたくさんヒットすると思います。
このように「ググれるレベルまで要件を細分化する」ことを意識すると、多少勉強不足の状態でも簡単なアプリなら作りきることができると思います。

# まとめ
かなり簡潔な記事になってしまいましたが、僕が何かを開発する時に意識していることをまとめてみました。
カーディナリティとは何か調べてみた

__調べてみた背景__
---
__最近、MySQLを顧客向けにご提供させて頂く機会があり、レスポンスを意識したチューニングをしなければならない機会がありました。データベースのデータは、商用利用のため、膨大でした。そのため、待機時間を減らす必要性があるという課題に直面しました。__

待機時間を減らすための手法の一つに、「インデックスをはる」というものがございます。　
~~~
ALTER TABLE テーブル名 ADD INDEX インデックス名(カラム名);
~~~

ただ、「インデックスをはる」にあたり、考慮しなくてはならない概念がございます。

__カーディナリティ__
---
__カーディナリティは、データベースの列(カラム)に入っているデータの種類の事を指す。__
__異なる値の数（バリエーション）がどれぐらい存在しているかを表す。 基数あるいは濃度という意味。__
__カーディナリティは カラムの値の種類の絶対値である。__


__【カーディナリティとインデックスの関係についての考察】__
__結論：カーディナリティが高い列にインデックスを作成する必要がある。__
__理由：バリエーションが多いので、分類しないと、見分けるのが大変であるため。__
・カーディナリティが低い列にインデックスを作成する意味はない。
インデックスを作成する方が、検索速度が、遅くなる。個別に確認した方が、検索速度が向上する。

__野菜(ごぼう)を調べる事を例にして表現する__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/fa35e7d6-bb97-6ac6-2c5d-ec49af134830.png)

__購入者性別の列で、分類した結果__
バリエーションが少ないので、カーディナリティが低い。

男がごぼうを購入するとは限らず、女がごぼうを買うかもしれない。
男か女かを確認した後で、野菜(ごぼう)を調べるのは、効率が悪い。
分類せずとも、野菜(ごぼう)を調べる時、野菜(ごぼう)を個別に見れば済む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/250627cc-20a5-9f17-a956-0324233ed333.png)

__Vegetable野菜の種類で、分類した結果__
バリエーションが多いので、カーディナリティが高い。

野菜(ごぼう)を調べる時、野菜(ごぼう)を個別に見れば済む。
分類したうえで、項目別に確認したほうがわかりやすい。

ごぼうを調べる時、一旦、根菜類で分類し、項目別に表示する。(余計な情報を削除出来る。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/d2cef654-6892-d168-eaea-3f10b9b8dd1d.png)

__カーディナリティが高い列にインデックスを作成すると、__
__項目を整理する事が出来るので、検索速度が向上する。__
1292 Incorrect datetime value: '0000-00-00 00:00:00'のエラー

エラーが出て困ったのでメモです。
symfonyは自動でcreated_atやupdated_atが入らないようです。
idは入りましたが。

僕のローカルのmysqlが'0000-00-00 00:00:00'を許さない設定のようでこうなったようです。

実際のプロダクトだとmysqlの設定を変えるのがよさそうですが、今回はローカルだけの勉強用なので、簡単にこうしました。

```
[error] Migration DoctrineMigrations\Version20xxxxxxxx failed during Execution. Error: "An exception occurred while executing a query: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1"
```

```
An exception occurred while executing a query: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1     
```

僕は、typeをdatetime_immutableからdatetimeにしてやったらうまくいきました。
```
% symfony console make:entity XxxxXXX

 Your entity already exists! So let's add some new fields!

 New property name (press <return> to stop adding fields):
 > created_at

 Field type (enter ? to see all types) [datetime_immutable]:
 > datetime

 Can this field be null in the database (nullable) (yes/no) [no]:
 > 
```

参考
https://qiita.com/77web@github/items/158540fd4c1e379d1e9d

https://tips.recatnap.info/laboratory/detail/id/482

https://gokhan.ozar.net/blog/how-to-fix-incorrect-datetime-value-mysql-mariadb/

https://www.searchlight8.com/mysql-incorrect-datetime-value-error/

https://qiita.com/tentatsu/items/fd2177777412ebc2f6b9
【Mac】2行でJDKバージョンを切り替える

# 結論
```bash
export JAVA_HOME=`/usr/libexec/java_home -v "17"`
PATH=$JAVA_HOME/bin:$PATH
```

## version確認
```bash
java --version                                   
openjdk 17.0.4.1 2022-08-12 LTS
OpenJDK Runtime Environment Corretto-17.0.4.9.1 (build 17.0.4.1+9-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.4.9.1 (build 17.0.4.1+9-LTS, mixed mode, sharing)
```

# 補足
- `/usr/libexec/java_home -V`でマシン内にインストール済みのJDKのJAVA_HOMEを一覧表示できる。
- `/usr/libexec/java_home -v "{バージョン番号}"`で指定したバージョンのJDKのJAVA_HOMEだけをgrep的に表示できる。
- bashrc, zshrcなどに`結論`の2行を記載しておくのもよい

# 参考
https://amateur-engineer.com/mac-java-version/
【ルール説明・shared】galaxy

こちらの記事は [Ansible lint Advent Calendar 2022 カレンダー2](https://qiita.com/advent-calendar/2022/ansible-lint) 15日目の記事になります。

今回はルール [galaxy](https://ansible-lint.readthedocs.io/rules/galaxy/) について説明します。

### galaxy

[galaxy](https://ansible-lint.readthedocs.io/rules/galaxy/) は`galaxy.yml`のバージョン情報が正しく記載されているか検証します。

* `galaxy[version-missing]` バージョン情報が記載されているか検証します。
* `galaxy[version-incorrect]` バージョンが`1.0.0`よりも大きいか検証します。

#### 問題のあるコードその１

```yaml:galaxy.yml
---
name: foo
namespace: bar
version: 0.2.3 # <-- バージョンが 1.0.0 以下
authors:
  - John
readme: ../README.md
description: "..."
```

#### 修正されたコードその１

```yaml:galaxy.yml
---
name: foo
namespace: bar
version: 1.0.0 # <-- バージョンを 1.0.0 以上にする
authors:
  - John
readme: ../README.md
description: "..."
```


#### 問題のあるコードその２

```yaml:galaxy.yml
---
name: foo
namespace: bar
version: # <-- バージョンが記載されていない
authors:
  - John
readme: ../README.md
description: "..."
```

#### 修正されたコードその２

```yaml:galaxy.yml
---
name: foo
namespace: bar
version: 1.0.0 # <-- バージョン情報を記載する
authors:
  - John
readme: ../README.md
description: "..."
```

### 参考サイト

* [galaxy — Ansible Lint Documentation](https://ansible-lint.readthedocs.io/rules/galaxy/)
【Phaser3】当たり判定を1回だけ処理する方法をUnityから着想を得て解決

現在（2022/12/30）、RecursionCSにて上級者向けのチーム開発に取り組んでいます。

ゲーム画面の描写にCanvasAPIとPhaser3を使用。

その中で、「1回だけ当たり判定を行う」というシンプルな処理に思いの外手間取ったので、解決方法を記録として残します。

## 【解決策】クラス変数に当たったかどうかの状態を持たせておく

```Next.js　Phaser.js　TypeScript

export class GameScene extends Scene {
  private hit: boolean;
  constructor() {
    super({ key: 'GameScene' });
    this.hit = true; // ヒットしたかどうか状態を判別する変数
  }
// ～～中略～～
  create() {
// ～～中略～～
    this.physics.add.collider(
      this.player,
      this.explosion,
      (player: Phaser.Types.Physics.Arcade.GameObjectWithBody) => {
        if (this.hit) { // ヒットした場合の処理（残機を減らす）
          player.damagedPlayer(
            this.stockText,
            this.gameOverText
          );
        }
        this.hit = false; // ヒットしたので状態を変更
      },
      null,
      this
    );
  }
// ～～中略～～
  update() {
// ～～中略～～
    window.setTimeout(() => {
      this.explosion.clear();
      this.hit = true; //  アニメーションなど処理が終了した後にヒットの状態を元に戻す
    }, 600);
  }

```

### create()の中で当たり判定を定義する

colliderやoverlapで当たり判定を作ります。

その中でさらに、ヒットしたかどうかを判定する変数を間に噛ませています。

当たり判定が終わったらfalseにすることで、最初の1回だけ処理を行うようにしています。

### update()の中で処理が完了後にヒット判定を元に戻す

アニメーションが終わったら、変数を最初の状態に戻しています。

これらにより

- 最初の1回だけヒットする
- 処理が完了後に判定があるとまたヒットする

という処理を実装することができました。

## 参考にした記事
こちらの記事が参考になりました。

Unityでもupdate関数をループさせてアニメーションを描写する仕組みは同じなので、同様に実装できるようです。

Phaserの機能の中から探していたので、一見すぐ解決できそうな課題なのに、とても時間がかかりました。

視野を広げるのはとっても大切ですね。

https://tech.pjin.jp/blog/2018/10/25/unity_update_call-once/
date +%s（UNIX時間）に移植性がないのは過去の話

## はじめに

むしろ `date +%s` に移植性がなかったの？と驚く人のほうが多いのではないかと思いますが、現在の [POSIX Issue 7](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/date.html) では、`date` コマンドの書式で `+%s` (UNIXTIME) は対応していません。それが改定され POSIX Issue 8 では対応するようになります。

## `date +%s` が使えない環境

`%s` が使える（または使えない）環境は以下のとおりです。使えない環境に取り消し線を付けています。

- Debian 2.2r7 (2000-08) GNU 版
- FreeBSD 1.0 (1993-11)
- Solaris
  - Solaris 10 (2005-01) ※ 2024 年 1 月サポート終了
    -  ~~`/usr/bin/date`~~  歴史的実装版
    - ~~`/usr/xpg4/bin/date`~~ POSIX 準拠版
  - Solaris 11 (2011-11)
    - `/usr/bin/date` 歴史的実装版
    - `/usr/xpg4/bin/date` POSIX 準拠版
- AIX 5.3 (2004-08)
- HP-UX
  - ~~HP-UX 11.22~~ (2002-06-02)
  - HP-UX 11.23 (2003-10-01）

こうやって見ると使えなかったのは Solaris と HP-UX ぐらいで、現在もサポートが続いている OS は Solaris 10 ぐらいしかなく `%s` が使えない環境はほとんどないといって良さそうです。

参考

- [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=date&apropos=0&sektion=0&manpath=FreeBSD+1.0-RELEASE&arch=default&format=html)
- [AIX](https://www.ibm.com/docs/ja/aix/7.1?topic=d-date-command)
- [HP-UX](https://www.freebsd.org/cgi/man.cgi?query=date&apropos=0&sektion=0&manpath=HP-UX+11.22&arch=default&format=html)
- [date format option - Hewlett Packard Enterprise Community](https://community.hpe.com/t5/General/date-format-option/td-p/5251156?profile.language=en)

## POSIX Issue 8 でどのように変わったのか？

経緯はこちら

https://www.austingroupbugs.net/view.php?id=169

現在の [POSIX date](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/date.html) では `date` コマンドで使える書式がずらずらと書かれているのですが Issue 8 ではそれらがばっさり削られて `strftime()` を参照するように変わっています。現在の [Issue 7 strftime()](https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html) には `%s` はありませんが Issue 8 では追加されます。

## さいごに

`date +%s` に移植性がないのは、あくまで POSIX Issue 7 の話です。現実にはどの環境でも使えると考えてよく、移植性があります。単に POSIX が更新されていないというだけの話です。どうしても `date +%s` に対応していない環境でも動かさなければいけないというのであれば話は別ですが、現在の環境で使えるのであれば `date +%s` を使って構いません。もしどうしても POSIX Issue 7 に準拠したいんだよという方は「[シェルスクリプトでUNIX時間⇔日付の相互変換を行う関数（POSIX準拠）](https://qiita.com/ko1nksm/items/e61728f863c1b2bc829d)」を参照してください。
[Python]サーバーレスアプリ開発入門でハマったところ


# pipenv環境でのModuleNotFoundError

[動かして学ぶ! Pythonサーバレスアプリ開発入門](https://www.shoeisha.co.jp/book/detail/9784798169729)を試して、


ModuleNotFoundError
何度もModuleNotFoundErrorが出てきてハマった。　


pipenv install 'モジュール名'
```sh
pipenv install 'モジュール名'
```
で何度もモジュールをインストールするが、ModuleNotFoundErrorが出て一向に実行できない。

```sh
pip info
```
を実行すると確かにモジュールがインストールされていないことがわかる。

仕方ないので、

```sh
python -m pip install 'モジュール名'
```
でインストールすることで解決しました。

基本、以下は確認しながら進めないと、いろいろ厳しい
[「動かして学ぶ！Pythonサーバレスアプリ開発入門」 サンプルコード](https://github.com/chaingng/shoeisha_serverless_python_tutorial#2flask-login%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%99%82%E3%81%AB%E3%82%B3%E3%83%B3%E3%83%95%E3%83%AA%E3%82%AF%E3%83%88%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B)
新米リーダーが「リーダーの作法 〜ささいなことを丁寧に〜 」を読んでみた。

# はじめに
これまで約1年間、開発チームリーダーとして仕事をしてきました。
しかし、「理想のリーダーとは？」という問いに答えがでず、モヤモヤしてしました。
そんなタイミングで読んだのが本書です。
**新米リーダーがどう感じたのか**という視点で、備忘録を書いていきます。

## 本の紹介
https://www.oreilly.co.jp/books/9784873119892/

下記の3部構成となってます。
- 第一幕：Netscape(マネージャ)
- 第二幕：Apple(ディレクター)
- 第三幕：Slack(エグゼクティブ)

でのリーダーとしての経験を30エッセイとして紹介している本です。
本書内でも、記載がありますが、目新しいTipsのようなものが書いてあるわけではなく、
継続によって効果の出る「**プラクティス**」が記載されています。

## 総評
現時点では、刺さるエピソードと刺さらないエピソードの差が大きい本でした。
Netscapeでのエピソードは私の立場に近いこともあり、
本書を読んだ目的である「理想のリーダーとは？」の問いのヒントを得られたように感じました。
一方で、Apple, Slackでのエピソードは刺さらない(他人事のように感じてしまう)ものが多い印象でした。
上記のように読み手の立場によって、大きく見え方が変わる本のため、
キャリアの節目に読んでみると面白いのかなと思います。

## 刺さった内容
- `マネジメントとはまずチームが直面している障害やメンバー間の軋轢といった情報を明らかにすることであり、さらにそうして得た情報を分析して、進むべき正しい道を見出すこと(序文:Instagram 前CTO マイククリーガー)`
→ マネジメントという言葉には、個人・会社などの正解があると思いますが、私の理想像を言語してくださっている気がしました。

- `あなたが手にしているこの本は、私がマネージャーになった最初の数年間に、しっかりとしたサポートを受けられなかったことへの不満から生まれたものです。(第一幕 冒頭)`
→ この文章から、読み進めることにワクワクし出しました。

- `リーダーは、チーム内で何が許容され、何が許容されないかの基準を設定します。(2章 会議ボケ)`
→ リーダーの行動はチームの基準となる。だからこそ、サブタイトルにもある**ささいなことを丁寧に**行い、チームの基準を作るべきと。

- `意見が洗練されるのは、誰かの同意によってではなく、議論を通じてです。(4章 様子を見る、場をつかむ、味見をする)`
→ ミーティングの席で、「言いづらいな」「自分なんかが」なんて思うことが少なからずあります。そんなタイミングでこの文章を思い出したい。

- `自分の仕事について、どんな風に褒めてもらいたいですか？(6章 プロフェッショナルとしての成長をはかる質問表)`
→ 質問表には19個の質問があり、どれも現時点と将来を見つめ直す鋭い質問であった。特に、「どんな風に褒めてもらいたいか」という質問は、褒めてもらうための行動ができているのか？と考えさせられた。

- `管理職に就くのは昇進ではない、キャリアとしては再出発です。(9章 新任マネージャーのデススパイラル)`
→ 本章では、デススパイラルについてのエピソードが語られており、近しい状況のマネージャーが多い印象を受けました。また章の締めくくりでは、リーダーシップの原点は「信頼」であると語られており、私の「理想のリーダー像」が明確になった章でした。

- `マネージャーの仕事はものづくりではなく、ものづくりができるチームを作ること(11章 我慢の限界まで任せる)`
→ マネージャーになったときに、この文章を読み返して、自分の責務を思い出したいです。

- `フィードバックを与え、受け取るという行為はあらゆる面で、人間関係における信頼関係を構築する機会となります(15章 手厳しいことを言う)`
→ 本章では、手厳しいことを言う・言われることの重要さを説いてくれています。

- `私の経験則によれば、マネージャーとしての仕事の50%は、情報を集め、評価し、再分配することです。(26章 情報ネットワーク)`
→ 序章の「マネジメントとはまずチームが直面している障害やメンバー間の軋轢といった情報を明らかにすることであり、さらにそうして得た情報を分析して、進むべき正しい道を見出すこと」にもつながる話で、なぜ1on1が大事かがわかる章でした。

- `リーダーシップとは、他人に見せるための服であり、私は揺るぎない優しさを選びます(30章 揺るぎない優しさを)`
→ 本書の締めくくりの文章。念頭に置きたい言葉となりました。

## 最後に
みなさんもぜひ読んでみてください。何か気づきがあると思います。
私も、また本書を読んだ時に違った感想を持つのが楽しみです。
DPDKアプリ用アフィニティ設定API

PMD処理を行わせるための各種APIがDPDKには用意されている。
アフィニティ設定処理を隠蔽するための、便利APIもたくさん用意されていて、格好良いのだが、
「実際、コアをどう割り当てているの？」という疑問が残る。極端な例を上げると、

* 1つのコアで2つのPMDを1:2の割合で動かしたい（普通やらないけど）

などの変態動作をサポートできてない。

ということで、アフィニティ設定は自力でやることにした。以下がそのコード。すっきりした！

```
#define _GNU_SOURCE
void *affinity_thread(void *core){
  //
  // スレッドのアフィニティを設定して
  cpu_set_t mask;  // 実行可能なCPUをビットマスクで指定する
  CPU_ZERO(&mask);  // まずマスクを全部オフにして
  CPU_SET(*(int*)core, &mask);  // 実行するコア番号を指定
  if(sched_setaffinity(0, sizeof(mask), &mask) == (-1)){  // アフィニティを設定
    perror("setaffinity:");
    exit(1);
  }
  // PMD処理を行う
  int64_t i;
  for(;;){
    for(i = 1; i < 0x100000000; i++) ;
    printf("zzz\n");
  }
}

// 呼び出し側。PMDに#4のコアを割り当てた例
  int core4 = 4;
  ret = pthread_create(&thread1, NULL, affinity_thread, &core4);

```