OmniAICreator/Qiita-1.07M huggingface dataset:
【PowerShell】WinSCPの.NETアセンブリを使ってSCP転送をスクリプト化する

# はじめに
WinSCPはGUIでファイル転送が可能なアプリケーションである。
一方で.Netのアセンブリが提供されており、
プログラムから呼び出すことができる。
※アセンブリはWinSCPの実行ファイルが格納されているフォルダに``WinSCPnet.dll``として格納されている。

これを利用して、PowerShell上でWinSCPでSCPプロトコルを用いた転送スクリプトを作成する。

# スクリプト

```powershell:スクリプト
#パラメータ定義
param(
    [string]$HostName = "<デフォルトIPアドレス>",
    [string]$UserName = "(デフォルトユーザ名)",
    [string]$Password = "<デフォルトパスワード>",
    [Parameter(Mandatory=$True)]
    [ValidateSet("Get","Put")]
    $transferType = "",
    [Parameter(Position=0)]
    [string]$sourcePath = "",
    [Parameter(Position=1)]
    [string]$destPath = ""
)

try
{
    #ライブラリの読み込み
    Add-Type -Path "<WinSCPnet.dllのパス>"

    if([string]::IsNullOrEmpty($sourcePath)){
        $sourcePath = Read-Host "取得先のリモートホストのパスを入力" 
        $sourcePath = $sourcePath.Trim('"',"'")  
    }

    if([string]::IsNullOrEmpty($destPath)){
        $destPath = Read-Host "保存先のディレクトリを入力"
        $destPath =  $destPath.Trim('"',"'")
    }

    #ディレクトリパスの末尾に"\"記号が無い場合追加
    if( ! ($destPath.EndsWith("\") ) ){
        $destPath += "\"
    }

    #セッション情報の設定
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Scp
        HostName = $HostName
        UserName = $UserName
        Password = $Password
        GiveUpSecurityAndAcceptAnySshHostKey = $True
    }

    #セッションを張る
    $session = New-Object WinSCP.Session
    $session.Open($sessionOptions)

    try
    {
        #put/getで分岐
        if( $transferType -eq "Get" ){#Get
            #リモートホストからファイルを取得する。
            $transferResult = $session.GetFiles($sourcePath, $destPath, $false)
        }else{#Put
            $fileName = Split-Path $sourcePath -Leaf
            $transferResult = $session.PutFiles($sourcePath, "${destPath}${fileName}", $false)
        }
        $transferResult.Check()

        #結果出力
        foreach($transfer in $transferResult.Transfers) {
            Write-Host "Source: $($transfer.FileName),succeeded"
            Write-Host "Destination:$($transfer.Destination) "
        }
    }
    finally
    {
        $session.Dispose()
    }
}
catch
{
    Write-Host "Error:$($_.Exception.Message)"
    exit 1
}
```
## 書式
```powershell:書式
script [-HostName <System.String>] [-UserName <System.String>] [-Password <System.String>] -transferType <Get> | <Put> [[-sourcePath <System.String>] [-destPath <System.String>]]
```

## 制作時備忘
- 転送後の終了処理で``Session.Dispose``の場合オブジェクトを破棄する(リソースを開放)
``Session.Close``を用いた場合、オブジェクトの再利用が可能。

- WinSCPのGUIアプリで設定した「サイト」の情報は利用できない模様。
公式リファレンスを見ても「サイト」からセッションオプションの値を取得する方法は特に載っていなかった...

- SCPではputFileやgetFileメソッドはサポートされていない。
転送を行う際は単一のファイルの場合でも``putFile``ではなく、``putfiles``を使う。Getの場合も同様

- ディレクトリのパスを指定する際に末尾にパス区切り文字がないとファイル名として認識されてしまうため、区切り文字を明示する必要有(最初この仕様に気づかず転送に成功したもののファイルが無いという現象が多発しました)

- ファイル転送部分はtry-finallyで記述しエラーが発生した場合でも必ずオブジェクトが破棄されるようにしておく。

# 余談
今回のスクリプトまだちょっとプロトタイプ的な感じが強いです。
WinSCP自体は様々な転送プロトコルに対応しているので、
異なるプロトコルを画一された方法で利用できるという点は便利ですね。

# 参考
https://winscp.net/eng/docs/library
Web開発でよく使うWebサイト

Webhook
https://webhook.site/#!/abf168b6-cd63-4c86-b98d-3aa17bc7e153
POSTデータを作る

PlantUML 概要
https://plantuml.com/ja/
UML図を作成する

Zeplin
https://app.zeplin.io/projects
デザインの共有

apiary
https://apiary.io/
APIの共有、モック

Stoplight
https://stoplight.io/
APIの共有、モック

Open Source Insights
https://deps.dev/
オープンソース、フレームワークの依存関係を調べる

Qase
https://qase.io/
自動テスト
iOS開発でよく使うWebサイト

## apple 公式

iOS & iPadOS Release Notes
https://developer.apple.com/documentation/ios-ipados-release-notes

日本語ドキュメント
https://developer.apple.com/jp/documentation/

iOSのバージョン割合
https://developer.apple.com/support/app-store/

## apple 非公式

OSStatus.com
https://www.osstatus.com/

Xcode Build Settings
https://xcodebuildsettings.com/

## Swift

Swift Package Manager
https://www.swift.org/package-manager/
フレームワークを使用可能になる、podsの代わりにもなる
【メモ】CIFS (SMB) で日本語が文字化けするときはシステムロケールも確認

# 事象
同じオプションでLinuxからWindows 11の共有フォルダを`mount.cifs`でマウントしたとき、片方のLinuxでは日本語のファイル名が正しく表示されるのに、もう一台では文字化け（エスケープされた状態, `$\123\456...`）で表示される。

# 環境
- Arch Linux (最新版)
- (Samba 4.19.2)
- Windows 11 (23H2)

# 原因と解法
文字化けするマシンのシステムロケール (`/etc/locale.conf`) が`LANG=C.UTF-8`のままだったので、`# localectl set-locale LANG=ja_JP.UTF-8`で日本語ロケールに修正したら解決した。

# 効かなかったこと
- [ダメ] `mount.cifs`のオプションに`iocharset=cp932`を指定 ... 表示は変わるがエスケープは解けない。
- [ダメ] `mount.cifs`のオプションに`codepage=cp932`を指定 ... そもそも`codepage`オプションはかなり前に廃止されている様子。

# 感想
ユーザのロケールは`LC_ALL=ja_JP.UTF-8`になっていたので気が付かなかった…こんなこともあるのですね。ファイル名におけるロケールの取り扱いがどうなっているのか気になってきました。
- [この記事](https://stackoverflow.com/questions/56749288/)によれば、カーネル（ファイルシステム）がファイルを操作する際にはファイル名のコードページ・ロケールは関係ない様子。
- となると、`ls`がファイル名を表示する際にロケールを見ながら変換しているのだろうが、そうするとなぜユーザのロケールが無視されたのだろうか…わからん。
Best Off Page SEO Services in Pakistan: Your Trusted Partner


In the dynamic digital landscape of Pakistan, businesses are increasingly realizing the importance of establishing a robust online presence to stay competitive. Off-page SEO services in Pakistan play a pivotal role in enhancing a website's visibility and credibility on search engines. In Pakistan, where the digital market is rapidly evolving, leveraging off-page SEO services has become imperative for businesses aiming to thrive in the online sphere.
Click Here:- https://seoinlahore.com/blog/off-page-seo-services-in-pakistan/
forをforEachに変更するときに新しく知ったこと

# はじめに
forで書いたコードをレビューで「非同期の処理がないなら可読性向上のためにforEachの処理に変えたらどう？」とご指摘をいただいた時に新しく知ったことです。

# 修正したコード
```js
// 修正前
for (let index = 0; index < docArr.length; index += 1) {
    console.log(docArr[index]);
}
```
```js
// 修正後
docArr.forEach((doc, index) => {
    console.log(docArr[index]);
});
```
# 気付いたこと
#### ループ処理をスキップしたい時、forEachの中では`continue`の代わりに`return`を書くこと
ちなみに以下のような処理の違いがあります。
`return`は関数の中で使用され、関数の実行を終了します。
`continue`はループ内で使用され、そのイテレーションを終了し、次のイテレーションに進みます。

#### forEachは同期的な処理をしているため、非同期処理を行うには不十分
以下のようにコールバックで非同期関数を呼び出ししましたが、逐次処理がされていません。
```js
// 参考URLのコードを実行しました
const f = (value) => {
    return new Promise((resolve) =>
        setTimeout(() => {
            console.log(value);
            resolve();
        }, Math.random() * 1000))
};

["A", "B", "C", "D", "E"].forEach(async (v) => {
    await f(v);
});
console.log("終了");
```
```
//　結果
終了
C
D
E
B
A
```

#### for以外でループ内で非同期を実行したい場合のやり方

方法1：for...ofを使用する
```js
const arr = ["A", "B", "C", "D", "E"];
let p = Promise.resolve();

for (const v of arr) {
  p = p.then(() => f(v));
}

p.then(() => console.log("終了"));
```
もしくは
```js
async function callArr() {
	for (const v of arr) {
		await f(v);
	}
    console.log("終了");
}
callArr();
```

方法２：forEachを工夫する
```js
// 参考URLのコードを実行しました
let p = Promise.resolve();
["A", "B", "C", "D", "E"].forEach((v) => (p = p.then(() => f(v))));
p.then(() => console.log("終了"));
```
Promise.resolve()は解決済み（fulfilled）のPromiseを生成します。
pが最初に Promise.resolve() で初期化された後、then以降の() => f(v)の処理が走ります。p= で、新しいPromiseを再代入しています。そのため、前のPromiseが解決された後に、新しいPromiseが生成され、次の非同期処理が順次待機することになります。


方法３：reduceを使う
reduceメソッドは各配列の要素に対して、コールバック関数を適用し、最終的に一つの値にまとめます。
```js
// 参考URLのコードを実行しました
["A", "B", "C", "D", "E"]
  .reduce((p, v) => p.then(() => f(v)), Promise.resolve())
  .then(() => console.log("終了"));
```
reduce(callbackFn, initialValue)の形をとっています。

callbackFnは　(p, v) => p.then(() => f(v))
initialValueは　Promise.resolve()
となります。

pは前回の callbackFn の呼び出し結果の値を受け取ります。
初回の呼び出しでは initialValue がある場合はinitialValueが入ります。

つまり、初回ではpにinitialValueのPromise.resolve()が入り、2回目以降はf(v)の結果のPromiseが渡されることとなります。

vは現在の要素の値です。初回の呼び出しでは initialValue が指定された場合は array[0] の値です。


ダメだった方法：Promise.allとmapを使う
```js
// 参考URLのコードを実行しました
const main = async () => {
  await Promise.all(["A", "B", "C", "D", "E"].map((v) => f(v)));
  console.log("終了");
};
main();
```
```
// 結果
B
D
A
C
E
終了
```
Promise.allでPromiseがすべて解決されるまで待つので、順番に出力されるかと思いました。しかし、各Promiseの解決順序を保証しないので、このような結果になりました。


# おわりに
ループ内で非同期処理を行うならforかfor...ofがよくて、非同期処理を使用しない場合はforよりもforEachの方が記載がシンプルでいいなと思いました。reduceについて詳しく知らなかったので勉強になりました。

# 参考
https://zenn.dev/sora_kumo/articles/612ca66c68ff52
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
【Java】稼働率<->年間停止時間を相互に変換する

# はじめに

職場で非機能要件をまとめる際に「稼働率99%って、年間停止時間がどれ位だっけ？」という話になりました。
1年間で365日ということは、稼働率99%だとざっくり3日強ではないかという予測は立てられますが、正確な年間停止時間をパッと言える人はほとんどいないと思います。

そこで「稼働率から年間停止時間を求める処理」と、逆に「年間停止時間から稼働率を求める処理」を書いてみました。

# 作成したコード

* 可用性を表すAvailabilityクラスには2つコンストラクタを用意しており、引数がdoubleの時は稼働率、intの時は年間停止時間を受け取るという形にしました。
  * そのため、稼働率->年間停止時間の変換処理だけが必要であれば、引数がintのコンストラクタは不要となります。
* 後から思ったのですが、「稼働率クラス」と「年間停止時間クラス」に分けて、それぞれで変換処理を持たせた方が自然だったかもしれません。
  * 他にももっとスッキリ書ける方法があるかもしれませんが、久々にJavaを触ったのでこれが限界でした...

```java:Availability.java
/**
 * 可用性クラス
 * @author NKOJIMA
 */
public class Availability {

	/** 1年間の秒数 */
	private static final int SECONDS_PER_YEAR = 365 * 24 * 60 * 60;

	/** 稼働率(%) */
	private double occupancyRate;

	/** 年間停止時間(秒) */
	private double annualDownTimeSec;

	/**
	 * コンストラクタ
	 * @param occupancyRate 稼働率(%)
	 */
	public Availability(double occupancyRate) {
		this.occupancyRate = occupancyRate;
		this.calcDowntimeAsSec();
	}

	/**
	 * コンストラクタ
	 * @param annualDownTimeSec 年間停止時間(秒)
	 */
	public Availability(int annualDownTimeSec) {
		this.annualDownTimeSec = (double)annualDownTimeSec;
		this.calcOccupancyRate();
	}

	/**
	 * 稼働率(%)から年間停止時間(秒)を求める。
	 */
	private void calcDowntimeAsSec() {
		this.annualDownTimeSec = SECONDS_PER_YEAR - (SECONDS_PER_YEAR * this.occupancyRate / 100);
	}

	/**
	 * 年間停止時間(秒)から稼働率(%)を求める。
	 */
	private void calcOccupancyRate() {
		this.occupancyRate = 100 - (this.annualDownTimeSec / SECONDS_PER_YEAR * 100);
	}

	/**
	 * 年間停止時間を標準出力する。
	 * @return
	 */
	public void printDowntime() {
		int numOfDays = 0;
		int hour = (int)annualDownTimeSec / 3600;
		int minute = ((int)annualDownTimeSec % 3600) / 60;
		int second = (int)annualDownTimeSec % 60;

		if (hour > 24) {
			numOfDays = hour / 24;
			hour = hour % 24;
		}
		System.out.println("年間停止時間：" + numOfDays + "日" + hour + "時間" + minute + "分" + second + "秒");
	}

	/**
	 * 稼働率を標準出力する。
	 * @return
	 */
	public void printOccupancyRate() {
		System.out.println("稼働率(%)：" + String.format("%.5f", occupancyRate) + "%");
	}
}
```

```java:テスト用コード
public class AvailabilityTest {

	public static void main(String[] args) {
		// 稼働率(%)から年間停止時間を求める。
		Availability av1 = new Availability(99d);  // int型で渡すと年間停止時間(秒)として扱われてしまう
		av1.printDowntime();

		// 稼働率(%)から年間停止時間を求める。
		Availability av2 = new Availability(99.5);
		av2.printDowntime();

		// 年間停止時間(秒)から稼働率(%)を求める。
		Availability av3 = new Availability(10000);
		av3.printOccupancyRate();
	}
}
```

```text:実行結果
年間停止時間：3日15時間36分0秒
年間停止時間：1日19時間48分0秒
稼働率(%)：99.96829%
```

# 参考URL

* [String - formatメソッド](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#format-java.lang.String-java.lang.Object...-)
* [時間・分・秒への変換](https://proglight.jimdofree.com/learning/timeconvert/)
ブラウザで簡単画像リサイズ！Jimpライブラリの活用ガイド

JimpをWebアプリケーションで使用するための手順をまとめます。Jimpは純粋なJavaScriptで書かれた画像処理ライブラリで、Node.js環境だけでなくブラウザ環境でも使用できます。以下の手順では、ウェブページで画像をアップロードし、Jimpを使って画像を処理し、最終的な結果を表示する一連の流れを説明します。

# 1. Jimpのブラウザ版を読み込む
ウェブページにJimpのブラウザ版を読み込みます。CDNを介して簡単に追加できます。

```html
<script src="https://cdn.jsdelivr.net/npm/jimp/browser/lib/jimp.min.js"></script>
```

# 2. 画像アップロードのためのHTMLを準備する
ユーザーが画像をアップロードできるように、`<input type="file">`タグを含むHTMLを用意します。

```html
<input type="file" id="image-input" accept="image/*">
<img id="output-image" style="max-width: 100%; height: auto;">
```

# 3. 画像アップロードのイベントハンドラを設定する
JavaScriptを使用して、画像ファイルのアップロードイベントを処理するイベントハンドラを設定します。

```javascript
document.getElementById('image-input').addEventListener('change', function (e) {
    if (e.target.files && e.target.files[0]) {
        const file = e.target.files[0];

        Jimp.read(URL.createObjectURL(file))
            .then(image => {
                // ここで画像の処理を行う
            })
            .catch(err => {
                console.error(err);
            });
    }
});
```

# 4. Jimpを使用して画像を処理する
画像をリサイズ、圧縮、色調整など、必要な処理を行います。

```javascript
Jimp.read(URL.createObjectURL(file))
    .then(image => {
        // 例: 画像をリサイズし、品質を80%に設定
        image.resize(1024, Jimp.AUTO)
             .quality(80)
             .getBase64(Jimp.AUTO, (err, src) => {
                 if (err) throw err;
                 document.getElementById('output-image').src = src;
             });
    })
    .catch(err => {
        console.error(err);
    });
```

# 5. 処理した画像を表示する
画像処理が完了したら、結果をウェブページに表示します。上記の例では、`getBase64`メソッドを使用して画像をBase64エンコードし、`<img>`タグの`src`属性に設定しています。

# GitHubリンク
Jimpの詳細や追加情報については、GitHubの公式リポジトリを参照してください:

[Jimp on GitHub](https://github.com/jimp-dev/jimp)

JimpのGitHubページには、APIドキュメント、使用例、コントリビューションガイドラインなどが含まれています。また、問題が発生した場合のサポートや、コミュニティによる議論もここで行われています。
ローコードしかできない人はいない（多分）_条件分岐

# はじめに

最近，会社の研修等でローコードというものに触れる機会がありました（現在進行形）．
1つずつコードを入力していくわけではありませんが，だからといって初心者が急にできるようになるものではないなと感じました．

今回は条件分岐を通じて感じたことを記載します．

**筆者の状況・経験**
現在新卒でシステム導入・運用部門に所属
学生時代の研究にて，pythonを使用してfor文，if文を使用して配列処理を経験（機械系出身）

**ローコードツールを使用して今回やりたいこと（研修目的）**
基本的にはExcelに保存されているデータを抽出・加工を行い出力すること

# ローコードに備わっているもの
各種操作を実行するためのパーツがそろっています．
例えばですが，リスト内の要素から25以上の値を抽出する作業を実施する際には，
下記のようなイメージで作成します．

!["作成イメージ"](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583708/62e2038a-a774-1ee1-64c7-d5b444359ff7.png)

ローコードでは[データの読み込み], [条件分岐]などのパーツを組み合わせることで，直感的にコードを作成することが出来るのがわかります．

pythonで実行しようとすると下記のようになります．
~~GPTちゃんに修正依頼をしたのは秘密です...~~

~~~python:extract.py
a = [10,20,30,40,50]
b = []

for i in a:
	if i >= 25:
		b.append(i)
print(b)
~~~
(実際にはpandas等を使用してexcelシートを読み込むコードが最初に入ります．)

繰り返し処理（for文）や条件式（if文）を自身で記載する必要があります．

比較をすると，ローコードツールでは細かいプログラミング言語の文法を覚える必要はあまりなさそうです．

# ローコードの罠（条件分岐編）
では，次は下記の条件を満たすデータの抽出を考えます．

__次のリストから，下記に示す条件を満たす数字を抽出してください．__

リストA = [10,15,20,25,30,35,40]

条件
・値が30以上の要素
・偶数の要素

上記の課題ではこのようにコードを作成すればよさそうです．

![case1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583708/2a7dee50-879b-00d3-8fc2-5fcdecd33ffe.png)

しかしながら，実際には条件分岐の要素は一つで済みます．

![case2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583708/c902513b-9365-23af-b259-7d4391ecbf54.png)

実際に処理される動作は同じですが，パーツが1つ少なくなるのですっきりします．
単一の条件式のみしか使えないと，複数の条件分岐があった際に多くの条件分岐要素が必要になってしまうことがわかります．
（ここでいう単一はand, orを含まない条件式を指しています．）

また，〇〇かつ△△（and接続）の条件分岐では2パーツ使ってできますが，
〇〇または△△（or接続）の条件分岐ではパーツの接続がめんどくさくなる予感がします...

このように，ローコードで適当にUI操作で設定をしていると，
思い通りのコードが完成するころには画面が埋め尽くされていくと考えられます．

しかし，上記のような1つの条件分岐のパーツに複数の条件を指定したいときにはカスタムで入力する必要があります．

# 結局はコードは書けた方がいい
私からの結論としては，__コードは書けた方がいい__ ということです．

コードを記述する際にはどのような工程が必要かを考えますが，
ひたすらに工程を1つずつ作成するのではなく，まとまりを考えながら作成する必要があるなと感じました．

ただ，間違えてはいけないのは，
__複数の条件式を1つの条件分岐要素に組み込めばいいわけではない__
ということです．

一見スリムになってよさげに見えますが，透明性が失われて複雑性が増すことで他ユーザが使用・再加工する際に不便になります．

どこまでをひとつのまとまりとして考えるかは，コード作成者の腕の見せ所だなと思います．

また，複数の条件式をひとつに合わせる際には集合の考え方が必要になると思いますので，
その内容についても記載したいなと思います．

最後まで読んでいただきありがとうございました．

（Power automateはWindowsユーザなら無料で使えることを最近知りました．）
（自学習の一環として使い倒したいなと思います．）
【SwiftUI】ScrollView内でframeを指定せず、画面にあったサイズに調整する

# はじめに
iOS17で追加された`containerRelativeFrame`を使用すれば実現できます。

# 目指すUI
今回の完成系のUIはこちらです。
![simulator_screenshot_1DA64188-71A9-4F99-8A37-AFFD79AD1E89.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f7304e97-606b-98eb-4ab8-732100c15545.png)

# 何が問題か説明
縦に図形を並べようと以下のようなコードを書きます。
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView(.vertical) {
            VStack(spacing: 16) {
                ForEach(0..<50, id: \.self) { _ in
                    RoundedRectangle(cornerRadius: 10)
                        .padding(10)
                }
            }
        }
    }
}
```
しかし、このように縦に潰れてしまいます。高さを指定していないからです。
![simulator_screenshot_4691ABB7-4C95-4C5D-A360-50939FFCA2D4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d0c9633c-e1f0-0cec-ea31-3e78024caf12.png)

高さは画面サイズによって変えたいので`GeometryReader`を使って画面サイズを高さに指定することになります。
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        GeometryReader { geometryProxy in
            ScrollView(.vertical) {
                VStack(spacing: 16) {
                    ForEach(0..<50, id: \.self) { _ in
                        RoundedRectangle(cornerRadius: 10)
                            .padding(10)
                            .frame(height: geometryProxy.size.height)
                    }
                }
            }
        }
    }
}
```
こうすることで目指していたUIにする事ができます。
![simulator_screenshot_38B337D6-22D6-4B66-8B02-906E4D28E638.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d05c5bdd-9828-2d0b-19a1-5e67cd33efab.png)

しかし、`GeometryReader`を使うのちょっとやだなということで、
iOS17で追加された`containerRelativeFrame`を使うことで`GeometryReader`を消す事ができます。

# 実装
`containerRelativeFrame`は親コンテナのサイズを使ってサイズ調整をしてくれるようです。
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView(.vertical) {
            VStack(spacing: 16) {
                ForEach(0..<50, id: \.self) { _ in
                    RoundedRectangle(cornerRadius: 10)
                        .padding(10)
+                       .containerRelativeFrame(.vertical)
                }
            }
        }
    }
}
```

# おわり
公式ドキュメントが結構詳しく書いてあるので見てみてください

# 公式ドキュメント
https://developer.apple.com/documentation/SwiftUI/View/containerRelativeFrame(_:alignment:)
【S-Server Advent Calendar 2023】DevHPとHPを作った話

# はじめに
この記事は [S-Server Advent Calendar 2023](https://adventar.org/calendars/9435) 3日目の記事です。

初参加（？）ですので大目に見てくださいーよろしく

# おまえだれ？
あきかきです。一応 **SDev Pro** です。よろしくね。

ここでは私が作った [DevHP](https://sdev.aknet.tech/) と [HP](https://shizen.aknet.tech) についてのポエム書きます。
（自然係鯖のみんななら最後まで見てくれるよね！にこにこ）

# さいとについて

ここでは私が使用したフレームワーク、工夫した点などをいろいろ書いていくよ。

## shizen.aknet.tech

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/ff587f30-7557-df68-26f1-b658628b9532.png)


- 使用フレームワーク
  - Next.js v13.5.4 (App Router)
  - TailwindCSS 

NextJSを使ったページの２作品めぐらいがこれです。
TailwindCSSでのスマホ対応やどうしたらいい感じの配置になるかなど
真剣に考えて作った真面目作でもあります。

- 工夫ポイント
  - **画像がぷかぷかしてる**
見てもらえればわかると思うんですけど、なんかぷかぷかしてませんか？
これはですね、画像置くと単調な感じで真面目な感じ？になってしまうのことがあるので
ぷかぷかさせて自由な感じ、そして青空の雲みたいな、そんなイメージで動かしてます。

  - **12grid**
  そう、あのー開発者ツールとかで見てもらえればわかるんですけど、まさかの12gridで配置してます。
  これは [某官公庁](https://digital.go.jp) リスペクトしました。（あそこまできれいにはならなかったけど、、、）

まさかのこれだけっていう。一応頭をひねったんですけど、、、（笑）

## sdev.aknet.tech

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/29e52206-a6a1-1226-de0a-92407432b72c.png)


- 使用フレームワーク
  - Next.js v14.0.2 (App Router)
  - NextUI v2
  - GSAP
  - VANTA.js (Three.js R134)
  - TailwindCSS 

はい。盛りだくさんですね。
結構かっこよく見せたかったのでいろいろもってみましたがどうでしょうか！
かっこよかったらうれしいよね

- 工夫ポイント
  - **最初のところの斜めになってる S-Server-Developers**
わたしね、これ自分で作っておいてなんですがちょっと結構気にいってるんですよ。
あのー、Developersが自由に作品を作るっていうことで自由な感じにしました。（？）

  - **背景**
そう、これが`Vanta.js`で作れる3Dな感じの波！
人によってはCPUがうなり、GPUは発火、、みたいなことが起きちゃいそうですが、マットな感じの色に光が差し込まれてる感じが本当に大好き！！！！！！！！！！！
結局は自己満ってことです。おわり。

  - **全体が青系で統一**
Sdevは 某M 氏からの提案でダークな青系に統一することになったので私もそれに合わせて作ってみました。
これがね、印象を**すぅぅぅぅぅぅっっっっっごくよく**してくれて、かっこいい感じが出てて本当に好きです。愛してる。

  - **Worksページのギャラリー的何か**
MembersページみたいにGridで配置してもよかったんですが、ちょっと物足りないなーと思ってGSAPを使ってみました。
動きはまぁちょっと難があるっぽいんですけど、、、
かっこいいのですべて解決です！

## 総評


**Next.jsはいいぞ。**

# おわりに

わたしについては [こことか](https://links.aknet.tech) [こことか](https://me.aknet.tech) 見ていただいて、、、（宣伝）

次の4日目は[黒板ちゃんの記事](https://adventar.org/calendars/9435)だね！楽しみだね！

じゃ！そのうちまたどこかで、、、
自作VPN

# SoftEther VPNを使ったVPNを作ってみる
どんな雰囲気で作ったか書きます。
## 制作背景
seccamp2023で登大遊さんの講演を聞いて興味が出た。家に帰ってすぐやってみようと思った。あとVPNを利用してみたかった。けど、金出して契約するほどではないからつくる。
参考にさせていただいたサイト [Link]("https://centossrv.com/softethervpnserver.shtml")
## 制作環境
- Cloud : Microsoft Azure
- Machine : Azure VM (B1ls) 
- OS : Cent OS(7.7)
## つくる
参考にさせていただいたサイト [Link]("https://centossrv.com/softethervpnserver.shtml")
これの通りに進めていく。自分の場合はwebサーバではなかったので443ポートは閉じなかった。
大まかな流れとしては
- SoftEther VPNを入れる
- ポートとかの設定をする
- 仮想HUBとかの設定をする（管理端末Windows からできるので非常に楽）
## つまづいたところ
仮想HUBの設定のところでL2TP over IPsecのところをちゃんとやる。
ブリッジ設定をする。くらい
## まとめ
自作VPNは面白いけどコストがかかるので結局やめたよ。
1か月くらいでやめちゃった。
【Python】csv.DictReaderで遭遇したエラー2件の解決方法 (KeyError / invalid literal for int() with base 10)

# 概要
Pythonの`csv.DictReader`オブジェクトを利用していたら以下の二つのエラーに遭遇しました。
どちらも解決できたので、こちらで紹介します。

- `KeyError: 'XXXX'`
- `ValueError: invalid literal for int() with base 10: 'XXXX'`

## 修正前コード

```py
import os
import csv

csv_directory ='./csv'

for filename in os.listdir(csv_directory):
    if filename.endswith('.csv'):
        csv_file_path = os.path.join(csv_directory, filename)
        
        with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
            csv_reader = csv.DictReader(csvfile)
            
            for row in csv_reader:
                model = row['model']
                pk = int(row['pk'])
                # 略
```

## エラー１の原因

上記で実施すると以下のエラーになりました。

```
    model = row['model']
KeyError: 'model'
```

`csv.DictReader`を使用してファイルを開く際に、ヘッダー行を指定していないため、エラーが発生しています。
明示的に`fieldnames`パラメータを指定して、ヘッダーを設定してあげると、エラーがなくなりました。

## エラー2の原因

エラー１を修正後に実行すると以下のエラーになりました。

```
    pk = int(row['pk'])
ValueError: invalid literal for int() with base 10: 'pk'
```

これは、`int()`関数が数値以外の文字列（上記では`'pk'`という文字列）を数値として解釈しようとしたためエラーになりました。最初の行を読み飛ばさないと、それもデータ行として解釈され、その中にヘッダーであるはずの`'pk'`という文字列がデータとして認識されてしまい、`int()`によって変換しようとしてエラーが発生したのです。

## 修正後コード

上記2点を修正したらエラーが消えました。
修正後のコードは以下です。

```py
import os
import csv

csv_directory ='./csv'

for filename in os.listdir(csv_directory):
    if filename.endswith('.csv'):
        csv_file_path = os.path.join(csv_directory, filename)
        
        with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
            csv_reader = csv.DictReader(csvfile, fieldnames=['model', 'pk'])
            
            next(csv_reader)
            
            for row in csv_reader:
                model = row['model']
                pk = int(row['pk'])
                # 略
```

ちなみに、`os.listdir(csv_directory)`は、 指定されたディレクトリ内のファイルおよびディレクトリのリストを返します。
🔰React基礎メモ（useState）

# はじめに
プログラミング学習中の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。
React基礎を学び始め、その学習メモです😃
1から基礎を全部記載していくというより、自分にとっての学びとなった部分をかいつまんで記載していっています。

![image.png](https://soco-st.com/wp-content/themes/socost/upload/11813_color.svg)

# useState
## useStateは「現在の値」と「更新用関数」のセット
### ❌自分の勘違い
useStateは過去から現在の状態全てを保持したものや、更新用関数などを持った不思議なもの
### ⭕学び
useStateは「現在の値」と「更新用関数」のセット
配列となっており、
配列の0番目→現在の値
配列の1番目→更新用関数

## useStateの更新用関数を実行すると、対象コンポーネントが再レンダリングされる
### ❌自分の勘違い
useStateの更新用関数を実行すると、現在の値が更新されるだけ
### ⭕学び
useStateの更新用関数を実行すると、現在の値が更新される＋対象コンポーネントが再レンダリングされる
### 参考
https://www.udemy.com/course/react-complete-guide/learn/lecture/33042186?start=150#overview

# おわりに
お読みいただきありがとうございました。
雑なメモのため見づらい記事になっており、どこかで書き直せたらと思います😅
もしどなたかの参考になれば嬉しいです。

# 参考
https://www.udemy.com/course/react-complete-guide/
Pythonで「文字列を数値に変換して数値と演算する」の動作を確認してみた

# 概要

Pythonで「文字列を数値に変換して数値と演算する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/num/index6.html

# 実装

以下のファイルを作成しました。
```sample.py
num1 = "25"
num2 = "3.155"
print (18 + int(num1))
print (4.5 + float(num2))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
43
7.654999999999999
```

# まとめ

何かの役に立てばと。
[Python] 土日祝日を除いた営業日の数を調べる

#### 0.初めに
国内株などに投資をして、記録をつけていると、ある期間の営業日数を知りたくなる。


#### 1.仕様
土日に加え、祝日を差し引く。
しかしこれでは証券市場・金融機関の休みに対応できない
12/31,1/2,1/3を差し引く
役所の休みは
12/29,12/30を差し引く

11/22から11/22を指定したら1日と返してほしい。0日ではない。

#### 2.jpholiday,workdaysをインストールする
コマンドプロンプトで
`pip install jpholiday`
`pip install workdays`
を入力

#### 3.サンプルプログラム
任意の日付から任意の日付までの日数
```python:business_day.py
import datetime
import jpholiday
import workdays

start_date = datetime.datetime(2023,1,1)
end_date = datetime.datetime(2023,11,23)
holidays =[datetime.datetime(2023,1,2),datetime.datetime(2023,1,3),datetime.datetime(2023,12,31),datetime.datetime(2024,1,2),datetime.datetime(2024,1,3)]
print(workdays.networkdays(start_date, end_date))#祝日を除く前
for holiday in jpholiday.year_holidays(2023):
    holidays.append(datetime.datetime.fromordinal(holiday[0].toordinal()))
print(workdays.networkdays(start_date, end_date,holidays))#祝日を除く
```
```python:business_day.pyの結果
234
219
```

年初から今日(作成日は2023,11,23)までの日数
```python:business_day.py
import datetime
import jpholiday
import workdays

this_year= datetime.date.today().year
start_date = datetime.datetime(this_year,1,1)
end_date = datetime.datetime.now()
holidays =[datetime.datetime(this_year,1,2),datetime.datetime(this_year,1,3),datetime.datetime(this_year,12,31)]
print(workdays.networkdays(start_date, end_date))#祝日を除く前
for holiday in jpholiday.year_holidays(this_year):
    holidays.append(datetime.datetime.fromordinal(holiday[0].toordinal()))
print(workdays.networkdays(start_date, end_date,holidays))#祝日を除く
```
```python:business_day.pyの結果
234
219
```
#### 4.その他工夫点

役所の休みを追加したい場合は宣言に12/29,12/30を追加する
holidays =[略,datetime.datetime(this_year,12,29),datetime.datetime(this_year,12,30)]
逆に12/31,1/2,1/3を除かなければ純粋な祝日のみを、、、


(#祝日を除く前-#祝日を除く)を実装すれば、期間の実質的な祝日を数えられるな。


参照先
https://github.com/Lalcs/jpholiday
https://pypi.org/project/workdays/
↓でデバッグできる
https://keisan.casio.jp/exec/system/1251167854

#### 5.お願い
もっとスマートな方法を知ってるよ
そういう方おられましたら教えてください。
MUIでポップアップ表示　アイコンクリックで閉じる

muiを使用してポップアップを表示するコードです。
指定したアイコンをクリックするとポップアップが引っ込みます。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621123/0de51184-572c-cf64-8554-5720220b5b8d.gif)



```App.tsx
// 参考
// https://notistack.com/getting-started

import CloseIcon from '@mui/icons-material/Close';
import IconButton from '@mui/material/IconButton';
import { SnackbarKey, SnackbarProvider, closeSnackbar, enqueueSnackbar } from 'notistack'


// クリックするボタンの設定
const action = (key: SnackbarKey) => (
  <IconButton aria-label='Close' color='inherit' onClick={() => closeSnackbar(key)}>
    {/* ボタンのアイコンを設定　https://mui.com/material-ui/material-icons/*/}
    <CloseIcon />
  </IconButton>
);


function App() {
  return (
    <div>
      <SnackbarProvider />
      <button onClick={() => enqueueSnackbar('メッセージ内容', {
        persist: true,
        variant: 'error',
        action
      })
      }>ボタン</button>
    </div>
  );
}

export default App;
```

ポップアップの位置は変更できます。下記では画面真ん中上部に表示されます。
```App.tsx
      <button onClick={() => enqueueSnackbar('メッセージ内容', {
        persist: true,
        variant: 'error',
        anchorOrigin: {
          vertical: 'top',
          horizontal: 'center',
        },
        action
      })
      }>ボタン</button>
```
Apex Relay Debugger設定

### 要件
VsCodeでApexのDebugはどうやってできるか

### 参照資料

https://trailhead.salesforce.com/ja/content/learn/projects/find-and-fix-bugs-with-apex-replay-debugger

### 要点
#### JavaのVersionが限定されていること
　これはVscodeの制限です。Versionが合わないとDebuggerだけではなく、関数のJumpなどもできない
### Breakpoits　と　Checkpointsの区別
　Checkpointsは特別Breakpointsです。その点のStack、Heapの詳しい情報をめもされる
 　Checkpointsは最大５個です。アイコンも違います。（〇に横線　→　Checkpoints）
  Sfdxのtoggle checkpointsコマンドで、設定する

### STEP
①　Install Vscode, Salesforce CLI
   install Java (JDK version 17 (Recommended), JDK version 11, or JDK version 8)
    -> JAVA_HOME
    ->  File > Preferences > Settings (Windows or Linux) or Code > Preferences > Settings
        apex java
        salesforcedx-vscode-apex.java.home
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801991/41a9a723-9f7b-1f48-08bb-74c2604131a7.png)

②　Create Sf project
   create Apex class
   create Apex TestClase and deploy to org
   ( Ctrl shift P)
③　Debug
　　・Set Breakpoints and Checkpoints
  　　（　そのBreakpointラインを選択し、SFDX: Toggle Checkpoint、アイコンが変わる）
    ・SFDX: Update Checkpoints in Org
    ・SFDX: Turn On Apex Debug Log for Replay Debugger
    ・テストクラスを実行する（コマンドか、クラスのアノテーションか）
    ・SFDX: Get Apex Debug Logs
    ・Replay an Apex Debug Log
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801991/fbc8cc17-803c-e930-8ce4-3087b20a46e6.png)
Hyper-V管理者権限だけのユーザーを作る

WindowsにはAdministrator権限のほかに、Hyper-Vだけの管理ができる"Hyper-V Administrators"というローカルグループがあるようで、試してみました。

# 想定されるシーン

:::note info
WindowsやWindows Serverなどで、Hyper-Vの管理権限が必要だが、他のAdmin権限は不要なとき。
たとえば新人研修などのときに、万一マシン全体に影響が及ぼさないようにしたいなど。
:::

# コマンド

標準ユーザー権限のUsersを付与しないと「ユーザーの切り替え」画面に出てきませんでした。

```.ps1
New-LocalUser -Name "Hyper-V管理者" -NoPassword
net localgroup "Users" "Hyper-V管理者" /add
net localgroup "Hyper-V Administrators" "Hyper-V管理者" /add
```

![スクリーンショット 2023-11-23 174344.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/ad2ba173-0dd4-a51c-ddf7-2ba247d14835.png)

# GUIでの確認
![スクリーンショット 2023-11-23 174421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/3957afa7-57f8-1686-1488-950294517b63.png)

# ユーザーの切り替え
Ctrl + Alt + Delでユーザーの切り替えをします。

![スクリーンショット 2023-11-23 174709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/6e56157e-8810-14c6-40c7-f3ddc8864e78.png)

拡張セッションが有効だとユーザー権限に"Remote Desktop Users"が必要なようです。RDPプロトコルを使うためと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/6cdd9b74-d70c-0569-55ad-a8b020d500e8.png)

拡張セッションを切ることでログインできました。

![スクリーンショット 2023-11-23 175249.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/1215120b-fd6c-00e3-b7e4-0a6ff019b3d9.png)

# 動作確認

PowerShellなど管理者権限が必要なものは起動できません。

![スクリーンショット 2023-11-23 175408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/b9c80150-9e7b-6d98-b262-badeae277724.png)

Hyper-Vは問題なく管理できます。

![スクリーンショット 2023-11-23 175515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/1d915157-175a-878e-f1c3-498ad081c642.png)

# まとめ
- Hyper-V管理者権限に加え、D:\Hyper-Vといった特定のフォルダだけにアクセス権限を付与することによって、より安全な仮想サーバー運用ができるでしょう。

# メモ
- 今回はWin11 on Win11のNested Hyper-Vです。コマンドは以下となります。

```.ps1
#（ホストVMで）ネスト仮想化の有効化
Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

#（ゲストVMで）Hyper-Vの有効化
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
```

- 拡張セッションは便利なので、Remote Desktop Usersをコマンドに入れていいかもしれません。
- Ryzenのおかげでここ数年でコア数・速度ともに高速化しており、入れ子の仮想化でも遅延が少ないのは開発がしやすくありがたいです。
- MSがクライアントHyper-Vの開発を地味に続けてくれているのもうれしい（AMD CPU対応など）。
pytest-freezegunを使って有効期限のテストを作成しよう！

## 概要
pytest-freezegunを使うと特定の日付や時間に設定してテストを実行することができます
今回は有効期限のテストを例に使い方について解説します

## 前提
- フレームワークはDjangoを使用

## freezegunのインストール
まずはfreezegunをインストールします
```
pip install freezegun
```

## freezegunの使い方
以下のように
```
    with freeze_time("2012-01-14"):
```
と使うことで指定した日付もしくは日時でテストを実行することができます

```python
from freezegun import freeze_time

def test():
    assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)
    with freeze_time("2012-01-14"):
        assert datetime.datetime.now() == datetime.datetime(2012, 1, 14)
    assert datetime.datetime.now() != datetime.datetime(2012, 1, 14)
```


## pytest-freezegunを使ってみよう！
今回はパスワード再設定用トークンの有効期限が30分なのでパスワード再設定トークンを生成してから31分後にパスワード再設定用APIを実行すると失敗するテストを作成します
テストコードは以下の通りです
今回はDjangoのtimezoneを使って現在の時刻の31分後の日時でテストを実行します

```test_views.py
from datetime import timedelta

import pytest
from django.utils import timezone
from freezegun import freeze_time
from rest_framework import status

from application.tests.factories.user import UserFactory
from application.tests.factories.user_reset_password import UserResetPasswordFactory


@pytest.mark.django_db
def test_reset_password_token_is_invalid(
    client,
    get_reset_password_url,
):
    """パスワード再設定用トークンの有効期限が切れているため、パスワードを再設定できないことを確認"""
    user = UserFactory()
    reset_password = UserResetPasswordFactory(user=user)
    post_reset_password = {
        "token": reset_password.token,
        "new_password": "Test@123",
        "confirm_password": "Test@123",
    }
    expiry_time = timezone.localtime() + timedelta(minutes=31)
    with freeze_time(expiry_time):
        response = client.post(
            get_reset_password_url,
            post_reset_password,
            format="json",
        )
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert response.json() == {"msg": "こちらのURLは有効期限切れです"}
```

以下のようにテストが正常に実行されたら成功です
```
application/tests/views/test_reset_password.py::test_reset_password_token_is_invalid ✓ 
```

## 参考
https://pypi.org/project/pytest-freezegun/

https://github.com/spulec/freezegun
【PostgreSQL】<>演算子を使うと、nullのレコードも除外される

テーブルAには、8028件のレコードがあります。

```sql
select
    count(*) 
from
    public.tablea ;

```

```:実行結果
8028
```

このうち、remarksカラムがnullのレコードが4354件あります。

```sql
select
    count(*) 
from
    public.tablea
WHERE
    ( 
        remarks is null
    );
```

```:実行結果
4354
```

さて、remarksが「aaa」でないレコードを取得したいとします。

```sql
select
    remarks
from
    public.tablea
WHERE
    ( 
        remarks <> 'aaa'
    );
```

**取得結果：**
**remarksがnullのレコードも除外され、取得されませんでした。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180727/8c181622-23cc-5e7d-0dc2-869b96032a54.png)


---------------------------------------

nullのレコードも取得したい場合は、orでつなぐ必要があります。

```sql
select
    remarks
from
    public.tablea 
WHERE
    ( 
        remarks <> 'aaa'
        or remarks is null
    );
```
SPF レコードの見方

この記事では、SPF レコードの見方（文法）を（ざっくり）説明しています。

:::note warn
仕様の詳細は、RFC 7208 をご確認ください。
:::

SPF レコードは次のような形で DNS の TXT レコードとして登録されています。
``v=spf1`` の後に、「修飾子＋メカニズム」＝「値」 をスペースで区切って順に並べ、最後に ``all`` でその他の処理を指定できます。

![spf1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669617/2ac1a182-f743-6be7-f163-7fd96cfcf63a.png)

### 意味
| 修飾子   |                  | 
| -------- | ---------------- | 
| +        | 問題なし         | 
| -        | 不正、配信拒否   | 
| ~        | 不正             | 
| ?        | SPF 指定なし扱い | 
| （省略） | 問題なし         | 

| メカニズム | 説明 | 
| ---------- | ----- | 
| ip4 | 値の IPv4 アドレス（またはネットワーク）から送信された場合| 
| ip6 | 値の IPv6 アドレス（またはネットワーク）から送信された場合| 
| a | 値のドメインの A レコードから送信された場合| 
| include | 値のドメインの SPF レコードを回帰的に参照| 
| mx | このドメインの MX レコードから送信された場合| 

と、書いている途中にとても分かりやすい記事が見つかりました。
~~正直、こっちを見た方が早いです~~

[SendGrid「送信ドメインを認証するためのSPFレコードに詳しくなろう」](https://sendgrid.kke.co.jp/blog/?p=3509)
GitHubとかで最終行に改行がないと警告が出る訳

GitHubにコードを上げたときにこのような絵文字を見かけたことがある人は何人かいるはず｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606626/b186704c-ecea-ad91-0f2a-6e8c9b17b110.png)

これは｢最終行に改行がない｣という警告で､JetbrainsのIDEなどではそもそもファイル作成時に末尾改行を自動的に挿入している場合も多い｡

## なぜ警告がでるのか

これはPOSIXとC言語の標準ルールが原点で､POSIXにおけるファイルの中の行の定義で､

> A sequence of zero or more non- \<newline\> characters plus a terminating \<newline\> character.

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206

｢0個以上の改行以外の文字と終端に一つの改行文字｣が一行の定義で､これからなるC言語の標準として

> A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character.
Since this is a "shall" clause, we must emit a diagnostic message for a violation of this rule.

https://gcc.gnu.org/legacy-ml/gcc/2003-11/msg01568.html

｢空でないソースファイルは改行で終了しなければならない｣というふうに定められたのが､現代においてコーディング規約に残っていると考えられる｡
サポートベクターマシン(SVM)を用いてクラス分類を行う方法 

## サポートベクターマシン(SVM)
サポートベクターマシン(SVM)は、分類や回帰のための教示あり学習アルゴリズムです。SVMはデータセットの特徴を学習し、データポイントを最もよく分離する超平面を見つけることによって分類を行います。

今回はScikit-learnライブラリを使った実装方法を紹介します。


## 必要なライブラリのインポート
```
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report, confusion_matrix
```

## データセットの準備
ここでは、Scikit-kearnで用意されているIrisデータセットを使用します。
```
# データセットのロード
iris = datasets.load_iris()
X = iris.data
y = iris.target

# トレーニングセットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
```
Irisデータセットは、機械学習でよく使われるデータセットの一つです。このデータセットは、アイリス（Iris）と呼ばれる花の3種類（セトサ、バーシクル、バージニカ）のそれぞれ50サンプルから構成されており、合計150のデータポイントが含まれます。
###### X(特徴量)
- がく片の長さ (Sepal Length): がく片（花を包む緑色の部分）の長さをセンチメートルで測定。
- がく片の幅 (Sepal Width): がく片の幅をセンチメートルで測定。
- 花びらの長さ (Petal Length): 花びらの長さをセンチメートルで測定。
- 花びらの幅 (Petal Width): 花びらの幅をセンチメートルで測定。
###### y(ターゲット変数)
- Iris Setosa
- Iris Versicolor
- Iris Virginica

## データの標準化
SVMは特徴のスケーリングに敏感なため、データを標準化する
```
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
```

## SVMモデルの作成とトレーニング
ここでは、RBFカーネルを使用しますが、必要に応じて異なるカーネルを選択できます。
```
# SVMモデルの作成
svm_model = SVC(kernel='rbf')

# モデルのトレーニング
svm_model.fit(X_train, y_train)
```

## モデルの評価
モデルの性能をテストセットで評価します。
```
# テストデータに対する予測
y_pred = svm_model.predict(X_test)

# 性能評価
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

"""
出力結果

[[19  0  0]
 [ 0 13  0]
 [ 0  0 13]]
 
 
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        19
           1       1.00      1.00      1.00        13
           2       1.00      1.00      1.00        13

    accuracy                           1.00        45
   macro avg       1.00      1.00      1.00        45
weighted avg       1.00      1.00      1.00        45
"""

```

一つ目の行列はモデルがどのように各クラスを予測したかを示しています。Irisデータセットには3つのクラス（0: Setosa、1: Versicolor、2: Virginica）があるため、3x3の行列になります。
行: 実際のクラス
列: 予測されたクラス
この行列では、各クラスのすべてのサンプルが正しく分類されています。例えば、Setosa（0）の19サンプル全てが正しくSetosaとして予測されています（左上の19）。同様に、Versicolor（1）とVirginica（2）のサンプルも完全に正確に予測されています
分類レポートではクラスごとのモデルの性能を詳細に示しています。
- Precision: クラスに正しく分類されたアイテムの割合。例えば、Setosa（0）については、予測されたすべてのサンプルが正確であるため、1.00（または100%）です。
- Recall: 実際のクラスのサンプルがどれだけ正しく検出されたか。ここでも、各クラスについて完全なリコールがあります。
- F1-score: PrecisionとRecallの調和平均。これも各クラスについて1.00です。
- Support: 各クラスのサンプル数。

また、レポートは全体的な精度（accuracy）、マクロ平均（macro avg）、加重平均（weighted avg）も提供しています。これらの値もすべて1.00（または100%）で、モデルが高い精度で分類を行なっていることが確認できます。
Laravelでの日付処理： Call to a member function format() on string エラーの解決法

最近、Laravelのviewファイルで Call to a member function format() on string というエラーに直面しました。原因は、文字列として認識されているプロパティから format() メソッドを呼び出そうとしたためでした。

解決方法は複数存在するようですが、モデルで日付フィールドを明示的に指定する方法が一番簡単に思えたので採用しました。（Laravelでは、日付や時刻を扱う際にCarbonインスタンスの使用が一般的とのこと）

例として、以下のコードではBorrowモデルに$castsプロパティを追加し、borrowed_atフィールドをCarbonインスタンスとして扱うようにLaravelに指示しています。（型変換＝キャスト）

```Borrow.php

class Borrow extends Model
{
    // ...


    protected $casts = [
        'borrowed_at' => 'datetime',
    ];

    // ...
}
```
この変更により、$borrow->borrowed_at は自動的にCarbonインスタンスに変換され、viewファイルにてformat() メソッドが利用可能になりました。
（以前のバージョンではdatesプロパティでもキャストできたようですが、Laravel10ではこちらのプロパティは削除されたようです）

勉強になったのが、たとえマイグレーションでカラムを datetime型に指定していたとしても（私の場合は date 型でした）、モデルに$castsプロパティを設定していなければ、そのカラムはPHPレベルでは単なる文字列として扱われるということ。これは、データベースとPHP（Laravel）間でのデータ型の扱い方に違いがあるためのようです。

・PHP（Laravel）レベル： Laravelはデータベースからデータを取得する際、特に指定がなければ、日付と時刻のデータを文字列として扱う。これはPHPがデータベースの日付型に対応するビルトインのデータ型を持たないため。

・型キャストが必要： Laravelで datetime 型のデータを Carbon インスタンスとして扱いたい場合、モデルで明示的に型キャストを指定する必要がある。これにより、データを取得する際にLaravelが自動的に Carbonインスタンスへと変換してくれる。

初歩的な問題かもしれませんが、自分なりの備忘録も兼ねて投稿してみました。
WSLにUbuntu新しく立てたらやること。

## 背景

複数台のWindowsを使っていて、  on WSL2をよく入れます。毎回だいたいやることを調べるのでここは入れたばっかりのUbuntuにやることをメモしておきます。

## ログインユーザの指定(Windows Terminal)

設定＞プロファイル＞対象となるプロファイル＞コマンドライン

修正前
```
C:\WINDOWS\system32\wsl.exe -d Ubuntu
```
修正後
```
C:\WINDOWS\system32\wsl.exe -d Ubuntu -u <your user name>
```

保存したら、WTを再起動してログインする。指定のuserにログインできてたらok.

## sudo の時パスワードを指定しないようにする

```
$sudo visudo
```

修正前
```
%sudo   ALL=(ALL:ALL) ALL
```

修正後
```
%sudo   ALL=(ALL:ALL) NOPASSWD: ALL
```

## python3をpythonで動作するようにする

```
$ which python
$ which python3
/usr/bin/python3
$ ls -al python3
ls: cannot access 'python3': No such file or directory
$ ls -al /usr/bin/python3
lrwxrwxrwx 1 root root 10 Aug 18  2022 /usr/bin/python3 -> python3.10
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1
update-alternatives: using /usr/bin/python3.10 to provide /usr/bin/python (python) in auto mode
$ which python
/usr/bin/python
$ python --version
Python 3.10.12
```

### pipもなければインストール

```
$ sudo apt install python3-pip
$ pip --version
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
```

## vimの設定

### clilpboardが使えるか確認
`+clipboard`ならよし。-ならば別のバージョンのvimを入れる。 
```
$ vim --version |grep clipboard
+clipboard         +keymap            +printer           +vertsplit
+eval              -mouse_jsbterm     -sun_workshop      +xterm_clipboard
```

### .vimrcを入れる

だいたいいつもこれにお世話になっている

https://qiita.com/iwaseasahi/items/0b2da68269397906c14c

## xclipのインストール

```
$ sudo apt install xclip
$ vi ~/.bashrc
alias xclip='xclip -selection clipboard'
```

## .sshの設定 githubにつなぐ用

```
$ ssh-keygen -t ed25519 -C "<your email address>"
$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_ed25519
$ cat ~/.ssh/id_ed25519.pub | xclip
```

https://github.com/settings/keys で`New SSH key`をする

```
$ ssh -T git@github.com
Hi <yor accoutn>! You've successfully authenticated, but GitHub does not provide shell access.
```

## dockerのインストール
ここを見る

https://docs.docker.com/engine/install/ubuntu/

```
$ cat /etc/issue
Ubuntu 22.04.2 LTS \n \l
$ sudo apt update && upgrade
$ for pkg in http://docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo   "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" |   sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$  sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli http://containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo service docker start
$ sudo docker run hello-world
```
HTML & CSS学習の記録

# はじめに
はじめまして！HTML & CSSの学習を始めて一週間経ちました．
Qiitaへの投稿の練習も兼ねて，これまで学んだことを箇条書きでアウトプットしていきます！

# HTML
+ `<head>`要素では，文字コード，ページタイトル，CSSファイルの読み込みなどの設定を記述する．
文字コードを指定することで，ページの文字化けを防ぐことができる．
+ クラスを複数指定するときは，それぞれのクラスの間にスペースを入れる．
```
<div class="btn red">
```
+ viewportとは，レスポンシブデザインを適用する際に，端末に合わせて表示領域を変えるために指定する．
（`content="width=device-width~"`の部分で端末のビューポートサイズを表示領域として認識させている）
viewportを指定しないと，スマホやタブレットでもPCの表示領域で画面が表示されてしまう，といったことが起こる．

（以下サイト参照）

https://skillhub.jp/courses/256/lessons/2016

+ class名は数字からつけてはいけない．

# CSS
+ CSSで子要素をすべて指定するには，「*」を使用する．
+ 不透明度をカラーコード（16進数）で指定するには，末尾に不透明度を16進数で記述する．
```
background-color:#00000CC;
```

![不透明度](https://lh3.googleusercontent.com/pw/ADCreHdF6kn9ABgCVhGFsgAZQiAywpCXnf3Rr23UsrqVgom1mPzyBqjCvGZHzEQbuxLvydSxT-vSoKMhA0CCK2t8lMo_RYq9tjRagjeZxvXmCz6MDuE5d9v2HtCVVZsvlV8U3qvxcRXw-JWkSjr_JdR8KVC1=w711-h412-s-no-gm?authuser=0 "不透明度")

（画像は以下サイトから引用）

https://toriton.link/coding/opacity_colorcode/

+ メディアクエリの`@media all and (max-wdth:~)`の記述について．
「**all**」の部分が，メディアタイプを表す．allがすべてのデバイス，printerがプリンターなどといった具合．
「**()**」内が，メディア特性．width(ビューポートの幅）やheight, aspect-ratioなどが指定できる．メディアタイプがallかつ，メディア特性を指定しているときは，`@media ()`という簡潔な書き方もできる．
「**and**」は論理演算のandで「かつ」の意味．andを複数繋げて複数条件の指定や，「,」でorと同じ「または」とすることもできる．

（以下サイト参照）

https://wemo.tech/839

+ `text-align`プロパティについて．
インライン要素を親要素に対して中央寄せする場合は，**親要素に対して**`text-align:center;`．
要素内の文字列を，対象要素に対して中央寄せする場合は，**親要素または対象要素に対して**`text-align:center;`を指定．

（以下サイト参照）

https://www.akkodis.co.jp/candidate/insight/column_129

# 最後に
今回はHTMLとCSSについて，アウトプットいたしました．
読みやすい記事になるように少しずつ改善を重ねていきます！
繰り返される「RDBMSは死んだ」を振り返る

NoSQLという言葉が出てきて久しいけど、過去に何度もSQLやRDBMSはCOBOLなみのレガシー扱いを受けている。

以下悪者になりがちなポイント

- データが多くなると遅い
- JOINしないと階層構造作れないのがつらい
- データ構造が柔軟ではなくカラム追加するだけでメンテが必要なのがつらい
- SQLという言語がテストし辛い

以下RDBMS、SQLなんか要らんのだとう歴史を振り返る。どちらかというと失敗例。

- xfy
    - https://ja.wikipedia.org/wiki/Xfy
    - 2004年
    - XMLデータベースという切り口も盛り上がってた時代
    - XMLが階層構造持つからJOINが要らない
    - XMLはマシンリーダブルでもありXSLTでヒューマンリーダブルでもあるという夢のファイルフォーマットでもあった
    - ただしxfyもXMLDBも受け入れられず
    - XPathで検索はしやすいけど、CRUDを網羅するにはしんどい
    - その後開発元のジャストシステムは身売りされ、xfyチーム（ほぼ会社の中心）は解散
- MEANスタック
    - https://atmarkit.itmedia.co.jp/ait/articles/1412/01/news041.html
    - 2014年前後に言われていた
    - LAMPスタックはもう古いのでこれからはMEANスタックっしょ！という登場のしかた
    - LAMPのMはMySQL
    - MEANのMはMongoDB
    - RDBではなくKVSが今後のスタンダードですよというメッセージ
    - 実際にはMEANスタックが普及するどころか、AnglerもExpressもレガシー扱いになっている
    - 実際には2023年現在もWebサイトの大半はLAMPのWordPressで作られており、WordPressオルタナティブがNodeやMongoDBで作られる気配がない
- ワークスアプリケーションズ HUE
    - https://xtech.nikkei.com/it/atcl/watcher/14/334361/042000252/
    - 2015年頃の話
    - 脱RDBというのがキーワードだった
    - RDBを捨ててCassandraで構築
    - 人事アプリケーションという比較的RDB向きのようにもみえるパッケージをKVSで作り直したというのが原因かどうかは特定できないが、実際に開発はかなり遅れた
    - ワークスアプリケーションズは経営難に陥り、2019年には米投資ファンドのベイン・キャピタルに売却

逆にRDBMSを使い続けている例を挙げる。

- WordPress
    - 昔ながらのLAMPスタック
    - LAMPのApacheがNginxになったくらいでほとんどかわってない
    - WordPressオルタナティブで置き換わってないことをみると、ここに課題はないのかも
- LINE
    - MySQLを7000インスタンス規模で運用している
        - https://www.publickey1.jp/blog/23/mysql7000linemysqlnewsqlpr.html
    - この記事はMySQLをあほほど運用しているのでつらいよねという記事だが、逆にLINEの規模の運用がMySQLでできちゃってるんだというメッセージにもなる
- TiDB
    - 前述のLINEの記事は「7000インスタンスのMySQLはつらいのでNoSQLで構築し直せるかもね」というメッセージ
    - TiDBはNoSQLなんだけど、インターフェースは完全にMySQLに揃えてる
    - 開発者は普通にSQLを使ってるんだけど実際は各マシンに分散して保存・分散して検索している
    - じゃぁTiDBはRDBなの？KVSなの？というと絶妙なライン
    - そもそもRDMBS自体はいくらでもエンジンは選べてエンジニア向けのインターフェースとしてSQLが使えるだけ
    - その意味ではAWSのAthenaやGoogleBigQueryもSQLで検索するからRDBみたいなもんです

## まとめ

- SQLをインターフェースとするというのは「情報って作成・検索・更新・削除ですよね」ということと等価であって、そこは何も変わっちゃいない
- 複数の表を結合するという概念も人間にとって理解しやすいからそうしているだけであってテーブルのJOINは制約じゃぁない
- SQLをインターフェースとしてCRUDを書くのがRDBなら裏のエンジンなんてなんでもいい
- SQLを排除しても別の不完全なSQLもどきを覚えるくらいだったらSQLでいい
PHPカンファ沖縄2023に参加した話

## はじめに
Qiita初投稿！！
沖縄高専メディア情報工学科1年のPranariaと申します！！

今回の投稿は、初めて行った技術カンファレンスの、
**PHPカンファレンス沖縄2023** に行った感想です。

## 目次
- [はじめに](#はじめに)
- [PHPカンファを知った経緯](#PHPカンファを知った経緯)
- [行ってみての感想](#行ってみての感想)
    - 情報量が多い！！
    - 懇親会に行くのは大事！
- [技術カンファに参加することのメリット](#技術カンファに参加することのメリット)
- [おわりに](#おわりに)

### PHPカンファを知った経緯
私が技術カンファに参加するようになったきっかけは、
高専キャリア夏の交流会という高専生が集まるイベントで
PHPカンファ沖縄というイベントが有るという話を聞いたことがきっかけです。

そもそも技術カンファとはなんぞや？
と気になって行ってみることにしました。

### 行ってみての感想
#### 情報量が多い！！
まず行ってみて感じたのが、情報量が多いということです。
フレームワークの話からバイナリの話まで...
特定のプログラミング言語に関するカンファレンスだと、
専門性の高い方々も多く参加するので、
初学者である私も、
その技術で何ができるのか、
何に使われているのかを
沢山の情報を吸収することで、大まかに知ることができました。


#### 懇親会に行くのは大事！
このイベントでは、短い時間でPHPのLTをしていたため、
会場ではあまり講演者や参加者の方々と話せませんでした。
イベント後には懇親会があり、
そこで参加した方々と沢山お話することができて、
人脈がほんとに広がりました！
コミュニケーションを取りやすい雰囲気ができやすいので
懇親会もカンファの一部だと感じました。

### 技術カンファに参加することのメリット
PHPカンファを通して、
1\.沢山の情報を吸収できる
2\.懇親会で人脈を広げられる
3\.今まで知らなかった技術に出会える

といったものが挙げられます。
技術に関する沢山の情報を吸収すること、人脈を広げることは
技術カンファの大きな意義になるのかなと
個人的には感じています。

## おわりに
普段得られない学びや人脈を形成できる技術カンファに、
これからもジョインし、学びを得ていきたいと思います！

（あとPHPまだ書き始めていないので、Dockerで環境構築して勉強していきます...）
Micropython FW Custom: あなたのハードウェア用のカスタムファームウェア

Micropythontは多くのファームウェアを提供していますが、私のハードウェア環境に合わない場合もあります。
そのような場合、必要なファームウェアを自作する方法をご紹介します。

* この投稿はWIZnetのW5300用 network.WIZNET5K(WIZnet network module)カスタムを基にしていますが、適切に使用すれば他のモジュールにも役立ちます。
> https://github.com/Wiznet/W5300-TOE-MicroPython



## 1. **Gitからダウンロード**
   Micropythonの公式Gitアドレスは以下の通りです：
   > https://github.com/micropython/micropython/tree/master
   
サブモジュールなどもあるため、zip Downloadよりもgit cloneでダウンロードしてください！



## 2. **コードの構造**
まずは構造を簡単に把握しましょう！
主要な説明はメインのREADMEに記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/9fa6e02d-e3fb-50f0-d967-76add4a1c8da.png)

この中で必要な部分は `ports`、`lib`、`extmod` です。

### **ports**
#### あなたのデバイスやMCUを選択できます。
  通常、`ports/{MCUname}/boards/{board name}` の構造になっています。
  - 例1: Stm Nucleoボード: `ports/stm32/boards/NUCLEO_Fxxx`
  - 例2: W5500-EVB-PICO: `ports/rp2/boards/W5500_EVB_PICO`

各MCUの動作（GPIO、SPI、I2Cなど）を修正・追加したい場合は`ports/{MCUname}`にあるコードを修正・追加してください。
  
Make構造によっては、新しいファイルを追加する場合に`CMakeLists.txt`にもファイルを含める必要があることがあります。

 
各プログラムのメイン機能は通常、このディレクトリ内の`main.c`にあります。初期化に関する部分を追加したい場合は、この部分を修正します。
  - 例: STM NucleoFxxボードにWIZnet W5300バス機能を追加
   
      - `fmc.c`ファイルを追加。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/5122a139-4c3f-5a3e-4df7-323a800f602e.png)
    - CMakeLists.txtを追加する（halファイルを含む)

        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/46ca455a-de87-eb0d-0738-be83c06d15a9.png)

        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/790d9d04-47d7-9a50-983e-ba0927f75c7c.png)

     - main.cファイルの変更
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/9e2683f1-6719-3abf-9029-6b84299d00f0.png)

### **Lib**
#### MCUやモジュールのSDKやライブラリを管理します。
このディレクトリには、サードパーティの低レベルCライブラリやSDKが含まれています。MCU関連のSDKについては、ほとんどのコードが既に含まれているため、大きな追加は必要ありません。
  LCD、センサーなどのモジュールを追加する場合、関連するライブラリはこのディレクトリで管理してください。
WIZnetの場合、LibディレクトリにioLibraryがリンクされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/d2833927-924f-bfb0-6ad3-2ab7ca80e482.png)


### **extmod**
#### C言語で実装された追加（非コア）モジュールです。
Micropythonのコマンドが動作する部分をC言語で実装したものと考えてください。
構造は `Micropython: コマンド – extmod: コマンド処理 – lib: モジュール動作` というように見ることができます。

- 例1：`network_wiznet5k.c`: SPI通信 => Bus(FMC)
元々SPI通信用に書かれたコードをFMC通信用に修正します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557303/7ad93692-aa0c-38d1-a6e8-906cfdb207f5.png)

- 例2：micropython => C 
通常、Micropythonのコマンドに対応する関数があります。特定のコマンドを修正する必要がある場合は、その対応する関数を中心に修正すればよいです。

このmicropython exampleの場合,
```python
Import network
self.nic = network.WIZNET5K()
self.nic.active(True)
```
Micropythonで`network.WIZNET5K` は network_wiznet5k.cの `mp_obj_t wiznet5k_make_new(...)` 関数と、
`active(True)` は `wiznet5k_active(...)` 関数と対応するため、これらの部分を修正します。


このように必要な部分を一つずつ修正することで、Micropythonがサポートしていない機能も追加することができます。

---
今年はMicropythonのライブラリ関連の作業が多いです。
現在、microbitボードでWIZNET5Kを使用できるようにポーティング作業を行っています。来月には完成する見込みです。
完成次第、またアップデートします。