OmniAICreator/Qiita-1.07M huggingface dataset:
【paizaランク C 相当】みかんの仕分けをやってみた！：Python3解答例

## 問題: みかんを重さごとに仕分ける

### 入力:

仕分ける重さの区切りを表す整数 N
みかんの個数を表す整数 M
各みかんの重さ w_1 から w_M

:::note info
例えば N = 10 の時、10 g, 20 g, 30 g ... のように仕分けられます。

そして、そのみかんの重さが一番近い数の重さに仕分けられます。
重さが一番近い箱が複数ある場合、数が大きい方の箱に仕分けられます。
- 24 g のみかんはより値の近い 20 g と書かれた箱に仕分けられます。
- 35 g のみかんは 30 g, 40 g の箱と差が同じです。この場合は数の大きい方の 40 g の箱へ仕分けてください。
- 0g に仕分けられることはないので、一番小さい重さに仕分けてください。
:::

inputで複数の値を取得する際に、複数の値を取得する方法をまとめます。
指定された数の文字列を格納します。

``` diff_python
# 入力された文字列を分割してNとMを取得します。
N, M = input().split()
```
stripメソッドとは
stripメソッドは、文字列型のメソッドで特定の文字列や空白文字を削除するためのメソッドです。
空白文字とは、スペースやタブ、改行のことを指します。
``` diff_python
# strip()を使って入力された文字列から特定の文字列や空白文字を削除してNとMを取得します
N, M = input().strip().split()
```

次に、Python3のmap()を用いて、全ての要素に関数を適用します。int関数を使った記述方法は以下の通りです。
``` diff_python
# map()を使って入力された文字列をintを使って、数値として分割してNとMを取得します
N, M = map(int, input().strip().split())
```


### 出力:

各みかんを最も近い重さに仕分け、その重さを出力

### アプローチ:

標準入力から N, M と各みかんの重さを読み込む
各みかんの重さについて、仕分け先の重さを計算
仕分け先の重さを出力


```diff_python

def round_weight(N, weight):
    # weight / N が 1 未満の場合、切り上げを行う。
    if weight / N < 1:
        return N
    else:
    # weight / N が 1 未満以外（weight / N が 1 以上）の場合、四捨五入を行う。
    #ご指摘を受けて、修正しました。
    #Python3のround関数は偶数丸めです。
#（round(5 / 2) = 2になります）
#(weight + N // 2) // Nなら正しく四捨五入できます。
        return (weight + N // 2) // N

# 入力を受け取る
N, M = map(int, input().strip().split())
weights = [int(input().strip()) for _ in range(M)]
# 各みかんの重さを丸める
rounded_weights = [round_weight(N, weight) for weight in weights]

# 結果を出力する
for weight in rounded_weights:
    print(weight)

```

## コードの説明:

### 関数 round_weight の定義:
1. weight: 仕分ける重さの区切り
2. N: みかんの個数

### みかんの重さに対する仕分け先の重さの計算:

1. 各みかんの重さ weight　に対して以下の処理を行います:
2. もし weightをNで割って、1未満なら、そのまま N の箱に仕分けします。
3. そうでない場合、weightをNを計算して、四捨五入します。


### 結果の出力:

1. 各みかんの仕分け先の重さを順に出力します。
3. このプログラムは、与えられた各みかんの重さを最も近い重さに仕分けし、その結果を正確に出力します。

## 他のレベルアップ問題
### レベルD
レベルD相当の足し算についての解説は以下のリンクにあります。
[ 足し算 (paizaランク D 相当) Python解答例](https://paiza.jp/works/mondai/real_event/book_sort)

https://qiita.com/masaya8028/items/06d77486e7a76de4972a
学習記録アプリの改修作業まとめ

## 初めに
昨年3月まで医療職で、そこからWeb制作を学習。
Web制作以外にもスキルを身につけたいと思い、今年の1月よりJISOUに参加しました！

今回は以前に作成した学習記録アプリの改修を行ったので、その過程をお知らせします。

## 以前のアプリ
以前作成し学習記録アプリは以下の通りです。

・ 新しく学習記録が追加できる（学習した日付、学習内容、学習時間）
・ 追加した学習記録は削除もできる

## 今回のアプリ
今回改修した箇所は以下の通りです。

・ 追加した学習記録を編集することができる
・ Chakra UIを用いてUIの改善

## 実装を通して
今回の実装を通してChakra UIの便利さを実感しました。
アプリでは学習記録を登録する際に、登録ボタンを押すとモーダルが開いて、そこで学習内容と学習時間を入力する仕様となっています。
この動きをJavascriptで書くとなると、それなりの工数がかかります...
ですが**Chakra UIでは半分以下の工数で実装できます！**（僕の個人的な感想です）
あまりの簡単さに驚きました！！

Chakra UIとは別に今回の実装で経験を積めたのは、Githubのリポジトリ変更です...
**こちらは本当に苦い経験となりました...**

当初作成していたGithub repositoryに不具合があり、コードを別のリポジトリに引越しする必要がありました。
ただコードを丸々写すだけと侮っていましたが、これが大きな落とし穴です。
実際にはコード写す作業だけでなく、**supabaseやfirebaseとのAPI再接続、Githubアクションとの再連携、環境構築のやり直し**などやることめっちゃあります！
**Githubのリポジトリは安易に変更しないほうがいい！**
これが今回の実装で得た１番の経験でした。

## まとめ
アプリ改修からこの記事を書くまでに、ちょっと期間が空いてしまいました。
そのため実装過程の心境変化を忘れてしまったため、若干内容が薄っぺらなものになってしまいました。
ですがその中でも忘れないのが、Githubリポジトリの変更です。
本当にこの作業で1週間以上かかってしまったため、できればもうリポジトリの変更はやりたくないと感じました。

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからお願いします👇

https://projisou.jp
Docker Tips

# Dockerfileでsourceコマンド使いたい

デフォルトは/bin/shなので、bashに変えてあげる
```Dockerfile:Dockerfile
FROM: xxx:latest

# bashを使うよう設定
SHELL ["/bin/bash","-c"]
# sourceコマンドが使える
RUN source ./xxx.sh
```

# DockerfileのCOPYで上の階層を参照したい

## 環境

work/
　├ text.txt
　├ docker/
　│　└ docker-compose.yml
　│　└ Dockerfile
　└ lib/

## 問題
以下でエラー発生
```Dockerfile:Dockerfile
FROM ubuntu:latest

COPY ../text.txt /home/text.txt
```
## 解決
1. コンテキストをかえる。以下は例
    ```yml:docker-compose.yml
    version: '3'
    services:
     service:
      build:
        context: ../
        dockerfile: docker/Dockerfile
      tty: true
    ```
1. Dockerfileを書き換える
    ```Dockerfile:Dockerfile
    FROM ubuntu:latest
    
    COPY text.txt /home/text.txt
    ```
    ※一つ上の階層がコンテキストになったため、「../」不要

# Docker Composeで他プラットフォーム用コンテナを作りたい

## 事前状態
PC：LinuxPC(amd64) でbuildx使ってhello-worldできている

## 方法
docker-composeにplatformオプション付ける
```yml:docker-compose.yml
version: '3'
services:
    service:
        image: hello-world
        platform: linux/arm64
        tty: true
```

# nfsマウント
## サーバ側
```yml:docker-compose.yml
services:
  nfs-server:
    image: itsthenetwork/nfs-server-alpine:latest
    privileged: true
    network_mode: host　★外部からアクセスときのみ必要
    volumes:
      - <マウントしたいディレクトリ>:/nfsshare
    environment:
      SHARED_DIRECTORY: /nfsshare
```

## クライアント側
```yml:docker-compose.yml
services:
  builder:
    images: ubuntu:24.04
    volumes:
      - nfsserver:<マウントさせたい場所>

volumes:
  nfsserver:
    driver_opts:
      type: nfs
      o: addr=192.168.1.243,rw,nfsvers=4
      device: ":/"　★サーバー側で、/etc/exposeにfsid=0があるとクライアントからは/nfsshareが/として見える。
```
journal Tips

# journald.confの設定何が反映されてるか知りたい

drop-inによる設定上書き含め、journald.confの各項目何が設定されてるか知りたい場合は、以下で確認可能。
```bash
$ systemd-analyze cat-config systemd/journald.conf
# /etc/systemd/journald.conf　★デフォルトの設定ファイル
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it under the
#  terms of the GNU Lesser General Public License as published by the Free
#  Software Foundation; either version 2.1 of the License, or (at your option)
#  any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file, or by creating "drop-ins" in
# the journald.conf.d/ subdirectory. The latter is generally recommended.
# Defaults can be restored by simply deleting this file and all drop-ins.
#
# Use 'systemd-analyze cat-config systemd/journald.conf' to display the full config.
#
# See journald.conf(5) for details.

[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
#ReadKMsg=yes
#Audit=no

# /etc/systemd/journald.conf.d/00-systemd-conf.conf ★drop-inによる上書き
[Journal]
Storage=persistent
```

## 参考
* [How to get the current systemd-journald running configuration?](https://unix.stackexchange.com/questions/529577/how-to-get-the-current-systemd-journald-running-configuration)
Laravel11になってapi.phpがなくなった！


# まずなんでapi.phpが無くなっちゃったの？
> 最新版のlaravelで立ち上げた際にapi.phpが無くなってしまったのでその時の対処法を書きます。Laravel11では、新しいデフォルトのアプリケーション構造が導入され、デフォルトのファイルが少なくなっています。つまり、新しいLaravelアプリケーションには、サービスプロバイダ、ミドルウェア、設定ファイルの数が少なくなっています。
しかし、Laravel10アプリケーションをLaravel11にアップグレードするときに、アプリケーション構造の移行を試みることはお勧めしません。Laravel11はLaravel10のアプリケーション構造もサポートするように注意深く調整してあります。

とのことです。つまり構造が変化したためあまり使われることのなかったapi.phpが無くなったようです。
以下でより詳細な変更点を見ることができます。
https://readouble.com/laravel/11.x/ja/upgrade.html
# Laravel11のインストール方法
以下コマンドでLaravel11を立ち上げることができます。
```
composer create-project laravel/laravel:^11.0 example-app
cd example-app
```

# api.phpのインストール方法
artisanコマンドでインストールすることができます。
```
php artisan install:api
```

これでapi.phpを使うことができます！
ありがとうございました。
AtCoder 勉強記録[C++] その45

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - K Swap
[C - K Swap](https://atcoder.jp/contests/abc254/tasks/abc254_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<int>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  int n, k;
  cin >> n >> k;
  vec a(n);
  vector<vector<int>> b(k, vector<int>(0));
  rep(i, n) {
    cin >> a[i];
    b[i%k].push_back(a[i]);
  }
  for(int i = 0; i < k; i++){
    sort(b[i].rbegin(), b[i].rend());
  }
  sort(a.begin(), a.end());
  vec cp;
  for(int i = 0; i < n; i++){
    cp.push_back(b[i%k].back());
    b[i%k].pop_back();
  }
  if(cp == a) cout << "Yes" << endl;
  else cout << "No" << endl;
}
```
### 解法
`A[i]`において`i`を`K`で割ったあまりの要素において、その要素同士を交換するため、`i%k`の要素の集合`B[i]`を作成する。`B[i]`をソートし、配列に戻すことで昇順かどうか判別することができる。
yt-dlpを使用してyoutubeをmp3で落とす

# youtube-dlを使用してうまくいかない

### 結論
```
ffmpegをwebからダウンロードしてきて元から存在している環境変数PATHが通っているディレクトリに置くだけ
```

youtube-dlをpipでインストールしたがエラーが発生いろいろ調べていたら、youtube-dlはもう古いとのこと、代わりにytーdlpを使用するのがいいと書いてあったので早速実践

`
$pip install yt-dlp
`
`
$pip install ffmpeg
`

mp3などに変換するためにffmpegもインストールしておきます。
後にアンインストールしたのでしなくてもいいんですが、、、

インストール完了後
試しにyoutubeからダウンロード

ターミナルで
`$yt-dlp "URL"`

と打ち込むとmp4で動画のダウンロードはできました。

# mp3に変換してダウンロード

私がメインで使いたいのはサブスクにない曲を携帯に入れたいのでmp3で落としたいのです。
mp3で落とすためのコマンドは

`$yt-dlp -x --audio-format mp3 "URL"`

このように打ち込むことでmp3に変換されてダウンロードできるはずなのですが、エラーが発生。
原因はffmpegがnot foundとのことです。

## PATH環境変数の追加

いろいろ考えた結果PATHが通ってないのかなと思い

:::note
1. 現在のシェルのチェック
1. パスのチェック
1. ffmpegがインストールされている場所のチェック
:::


1.現在のシェルはターミナルで`$ echo $SHELL`と打ち込むと出てきます。私の場合はbashでした
2.パスのチェックは`$ echo $PATH`で確認することができます。
3.インストールされている場所は`$pip show ffmpeg`と打つとlocationと書かれた場所にffmpegがインストールされている場所が書かれています。
3に書かれていた場所に2で確認したパスが通っていなければパスを追加する必要があります。パスは`$export PATH=存在するディレクトリのパス:$PATH`で通すことができます
`$ echo $PATH`で追加されているか確認してあればOK

再度`$yt-dlp -x --audio-format mp3 "URL"`として試したのですが、またしてもエラー

結局ffmpegをwebから落として、それを元からパスが通っているディレクトリに置くことで解決しました。

今回はanacondaを事前にインストールしていたので、そこのディレクトリに置くことで解決
picoCTF Scavenger Hunt writeup

# 概要
サイト：picoCTF2021
ジャンル：Web Exploitation
難易度：easy

# 問題文
このサイトには興味深い情報が隠されている。あなたは見つけられるか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/5d6fb82d-bca8-24e2-e02a-e22ca5e362c2.png)

# 解説

#### 1.サイトの動作確認

まずはサイトのボタンを確認する。

+ 「How」を押すと以下の画面が表示された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/2a3eae75-dd05-2f05-6ec1-9077d76244d0.png)

+ 「What」を押すと以下の画面が表示された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/bd6d98d1-ac57-192e-0d39-f3587e16a490.png)

特に怪しいところはないので次に進む。

#### 2.ページのソースを表示
ページのソースコードを表示してみると、それっぽいのを発見
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/57878321-50a8-f8b3-db5e-dc70cd84cfeb.png)

この感じだと他のパートもありそう。次にCSSとJavaScriptを確認する。

#### 3.CSSとJavaScriptの確認

##### CSS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/a7a799f4-b672-29cf-5cea-9def429c35c5.png)

##### javascript
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/dba032f4-792e-db34-c2d1-6cbd0db4a167.png)

part2を発見。javascriptにはなかったものの怪しそうな文を発見。
Googleにインデックスされないようにするには...どういう意味？

#### 4.Googleインデックス
とりあえずgoogle indexで調べてみると<b>'robots.txt'</b>というのが関連しているっぽい。
サイトのブロックに関係しているファイルらしいので、サイトにアクセスしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/3349ea44-337d-9752-bb7d-edeaa297d4ef.png)

part3を発見。

#### 5.htaccess

Apacheを使っていることがヒントのようで、「Access」の頭文字が大文字で怪しい。「apache Access」で調べると、<b>'.htaccess'</b>というファイルがあるらしいので、とりあえずアクセスしてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/26457504-8711-e248-189c-33778a196b1d.png)

part4を発見。

#### .DS_Store

Macでウェブサイトを見ることが好きらしい。「Store」の頭文字が大文字なので怪しい。
「Mac Store」で調べると検索候補に<b>'.DS_Store'</b>というのがあった。アクセスしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737296/d89045dc-8e7b-27e8-7eff-175fb8ab73fc.png)

part1からpart5まで発見したのでこれをすべてつなげて提出。




# 終わりに
やっぱりCTFは検索もセットになってることなあと。
思ったより時間がかかったので検索能力を上げていきたい。
VirtualBoxでubuntuを使う時に初めに設定すること

# はじめに
VirtualBoxでUbuntu 日本語 Remixを使用して開発環境を作る際に設定することをまとめました。

## 環境
windows 11
VirtualBox 7.0
Ubuntu 日本語 Remix 22.04

## ホストOSとVMでクリップボードを共有可能にする
仮想マシンを新規に作成するときにGuest edition CDをインストールしておく  
仮想マシンUbuntuのデスクトップの上メニューから、デバイス->クリップボードの共有->双方向

## ubuntu上でターミナル(端末)が起動しない時
1. `alt + ctrl + F3` で仮想ターミナルを開く  
2. locale ファイルを編集する
    ```bash
    cat /etc/default/locale
    vi /etc/default/locale
    LANG="en_US.UTF-8"
    reboot
    ```
<!-- ※仮想キーボードのキーボード配列がUS配列な場合に分かりにくいキー -->

ターミナルが開ければok

## sudo できるユーザーの追加
```bash
su
usermod -aG sudo username
```

確認
```bash
groups username
sudo ls /root
```
usernameユーザーが属しているグループを確認する
sudoユーザーでないと使えないコマンドの動作を確認する

## 仮想マシンのGUI画面表示が荒れる時
### 仮想コンソールを開いて閉じる
```bash
alt + ctrl + F3
alt + F2
```
表示が荒れなくなるまで繰り返す
【学習記録　2024-08-08】　JavaScript

## 教材を使用する
Udemy「超JavaScript完全ガイド 2024」

## 学習内容
### 学習時間：1h
- 配列の分割代入
#### 学習メモ

配列で分割代入を行う際は編集を角括弧で囲う。カンマを使用することで代入する値を指定することができる。
```diff_javascript
const person = ['tanaka', 20];
let [name, age] = person;
console.log(name, age); // tanaka 20

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

let [, age] = person;
console.log(age); // 20

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

//　入れ子にもできる！
const person = ['tanaka', 22, ['music', 'run']];
let [name, age, [music, run]] = person;
console.log(name, age, music, run);  // tanaka 22 music run
```

配列内にオブジェクトがある場合、｛受け取るプロパティ名: 変数名｝で値を受け取ることができる
```diff_javascript
const person = ['tanaka', 22, ['music', 'run'], {first: tana} ];
let [name, age, [music, run], {first: firstName}] = person;
console.log(name, age, music, run, firstName);  // tanaka 22 music run tana
```

…変数名を使用することで残りのプロパティを全部受け取ることができる。必ず末尾に定義するに加えて、…変数名のあとにカンマを入力してしまうとエラーになってしまう。
```diff_javascript
const person = [
    'tanaka', 
    22, 
    ['music', 'run'],
    'hello',
    'tokyo'
];

「...rest」で'hello'以降の値を全取得。
let [name, age, [music, run], ...rest] = person;
console.log(name, age, music, run, rest);
```

関数の引数にも指定することができる。
```diff_javascript
const person = (
	'tanaka', 
    22, 
    ['music', 'run'],
    'hello',
    'tokyo'
 ) => {
		console.log(name, age, music, run, rest);
}
```

forOfで値を取得すると便利かもしれない。
```diff_javascript
const userObj = {
		name: 'tanaka',
		age: 22
}
for (const [key, value] of Object.entries(userObj)) {
		console.log(key, value);
		// name tanaka
		// age 22
}
```

## 所感
　配列の分割代入はJavaにはない記法だったのでとても便利だなと思いました！
　特にforOfなどと組み合わせるとオブジェクトのプロパティを取得する際に便利だしコンソールでもかなり見やすい気がしました。...変数名で残り全部取得できる便利かゆいところに手が届く機能もあってびっくり😶
git インストール後に文字化けを直す

git for Windows をインストールした後に
日本語が文字化けしてしまう環境を直すためのコマンド群です。
Windows向けです。

#### １．適当なフォルダで Git Bush を立ち上げる

スタートメニューの Gitから起動するか、
適当なフォルダで右クリック アシストメニューより「Open Git Bash here」をクリック。

#### ２．マルチバイト文字のエスケープ処理を無効にする
```shell
git config --global　core.quotepath false
```

#### ３．２桁の数値ばかりの表示に化けてしまうのを防ぐ
```shell
git config --global core.pager "LESSCHARSET=utf-8 less"
```

#### ４．Git Bashの文字コードをUTF-8に変換する(スキップ可)
```shell
chcp.com 65001
```
ちなみに、
`chcp.com` で現在の文字コードが分かります。
`chcp.com 65001` でUTF-8に変更します。
`chcp.com 932` でShift-JISに変更します。

これは Git Bashを起動するたびに設定する必要があります。

#### ５．Git Bash起動時に自動で文字コードが変わるようにする

`.bashrc`を使います。
ファイルがない場合(デフォルトはない)、以下コマンドで作成します。

```shell
touch ~/.bashrc
```
`~/`はホームディレクトリです。 
初期設定のままであれば、`C:\Users\アカウント名`直下に展開されます。

```shell
echo chcp.com 65001 >> ~/.bashrc
```

`chcp.com 65001` を `.bashrc` ファイルに追記します。

補足：
`.bashrc` は シェル起動時に1回実行される
`.bash_profile` は ログイン時に1回実行される

Git Bashを起動しなおすと、毎回自動で４．が実行されます。

以上です。
MS-900 試験直前メモ

より複雑な作業に対応できるように設計された強力なプロジェクト管理ツール
- 動的スケジュールのサポート
- チーム サイズに関係なくタスクの依存関係とサブタスクを追跡する
- コストの追跡
- 従業員がかんばんボードで共有タスクを整理できるようにする
- タイムライン ガント チャートのサポートを含める
- Microsoft Teams および Power BI Desktop と統合する
- プロジェクトをすばやく開始してタスクとスケジュールを割り当てることで、チーム メンバーとマネージャーの認識を統一できます
- 強力なスケジュール エンジンを使用してタイムラインを自動的に更新し、時間と労力を削減できます
-グリッド ビュー、かんばんスタイルのタスク ボード、タイムライン ガント チャートなどの使いやすいビューを利用します
- Teams と統合して、プロジェクト全体のコラボレーションを強化します
- Power BI で魅力的なインタラクティブ ダッシュボードを作成すると、プロジェクトのあらゆる側面を一目で確認できます
- Project は Power Platform 上に構築されているため、他のプラットフォーム アプリおよびデータを使用して拡張できます
## → Microsoft Project
---
直感的で共同作業可能なタスク管理ツール
- 従業員がかんばんボードでタスクを整理できるようにする
- Microsoft Outlook および Teams と統合する
- タスクを割り当てるための Microsoft Word、Excel、PowerPoint ファイルでの @メンションの使用をサポートする
## → Microsoft Planner
---
Web ベースの予約スケジュールおよび管理システム
- ユーザーは、顧客が予定をスケジュールするための共有可能なリンクを通じてアクセスできるページを作成できる必要がある
- Microsoft Teams と統合する
## → Microsoft Bookings
---
1 日の計画と管理を簡単にするインテリジェントなタスク管理アプリ
- 反復可能なタスクを作成する
- 名前付きタスク リストを作成する
- タスクを重要としてマークする
- 期限に基づいてタスクを表示する
- タスクのアラームをスケジュールする
## → Microsoft To Do
---
- チャット、音声通話、オンライン会議でコミュニケーションを取る
- 電子メール メッセージでコミュニケーションを取る
- 会議と予定をスケジュールする
## → Teams & Exchange
---
- Microsoft Teams で会社ブランド アプリを提供する
- 社内の個々の worker ロール向けにキュレーションされたコンテンツへのアクセスを提供する
- Microsoft Viva Engage と Microsoft Stream との統合を通じて、パーソナライズされたコンテンツを配信する
## → Microsoft Viva Connections
---
- Microsoft Teams と統合する
- 会社の従業員の作業パターンを特定するためにビジネス リーダーに分析情報を提供する
- 従業員の週単位の残業時間数に関する従業員エンゲージメント統計を自動的に生成して表示する
## → Microsoft Viva Organizational Insights
---
- 個々のユーザーに専用のデスクトップ コンピューティング リソースを提供する
- Surface 生体認証とネイティブに統合する
- ペンとインクのエクスペリエンスのサポートを提供する
- 管理作業を最小限に抑える
- 複数のユーザー間でコンピューティング リソースを共有する機能を提供する
- FSLogix コンテナー テクノロジを使用してユーザー プロファイル管理を最適化する
- メンテナンス作業を最小限に抑える
- 柔軟な従量課金ベースの価格モデル
- Windows 7 仮想デスクトップに無料の延長セキュリティ更新プログラムを提供する
- FSLogix プロファイル コンテナー テクノロジを使用できる
## → Microsoft Azure Virtual Desktop
---
- 各ユーザーに専用のデスクトップ コンピューティング リソースを提供する
- 追加のソフトウェアをインストールせずに、Microsoft Intune および Defender と統合する
- ユーザー ライセンスの割り当てによってトリガーされる自動プロビジョニングを提供する
- メンテナンス作業を最小限に抑える
## → Windows 365 Enterprise
---

IP 盗難やデータ漏洩などのインサイダー リスクに対する保護を望んでいる
## → Microsoft Purview
---
- 会社がデータのプライバシーと GDPR の目標を達成する
- データのプライバシー ポリシーと規制を確立したいと考えている
## → Microsoft Priva
https://learn.microsoft.com/ja-jp/privacy/priva/priva-overview

---
Microsoft 365 サービスの購入を希望するボリューム ライセンスをお持ちでないオンプレミスのお客様
## → Add-on USL
---
- ソフトウェア アシュアランス特典を活用する機能を含む、既存のボリューム ライセンスのお客様
- 最新バージョンのソフトウェアを実行できる Microsoft ライセンスがあります。 クラウドに移行する必要があります
## → From SA USL
---
既存のライセンス契約をお持ちでない新規のお客様
## → Full USL 
---
既存の Microsoft 365 サービスをアップグレードする必要があるお客様
## → Step Up USL
---
お客様が Microsoft 365 にオンボードするのに役立ち、会社での Microsoft 365 サービスの導入の促進をサポートします。
## → FastTrack サポート
DjangoのMTVパターンについて理解する【Python】

はじめに
---
Djangoは、Pythonで書かれた高水準なWebフレームワークで、開発者が迅速にWebアプリケーションを構築できるようにするための多くの機能を提供しています。
その中でも重要なのが「MTV（Model-Template-View）」パターンです。

MTVパターンの基本概念
---
MTVパターンは、アプリケーションの構造を整理し、コードの管理や保守を容易にするための設計パターンです。以下の3つのコンポーネントで構成されています：

Model（モデル）
Template（テンプレート）
View（ビュー）

Model（モデル）
---
データベースとのやり取りを担当し、データの構造やビジネスロジックを定義します。

Djangoのmodels.pyファイルでクラスとして定義します。これにより、データベースのテーブルやフィールドを定義できます。
```
from django.db import models
from django.utils import timezone

class Post(models.Model):
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title
```

Template（テンプレート）
---
ユーザーに表示するHTMLを生成します。
データを埋め込むためのプレースホルダーとして使われ、ビューから受け取ったデータを表示します。

Djangoのtemplatesディレクトリ内にHTMLファイルを作成します。テンプレートエンジンを使用して動的なデータをHTMLに埋め込みます。
```
<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
</head>
<body>
    <h1>Blog Posts</h1>
    <ul>
        {% for post in posts %}
            <li>
                <h2>{{ post.title }}</h2>
                <p>{{ post.text }}</p>
                <p><em>Published on {{ post.published_date }}</em></p>
            </li>
        {% endfor %}
    </ul>
</body>
</html>
```

View（ビュー）
---
役割: ユーザーからのリクエストを処理し、適切なデータを取得してテンプレートに渡します。ビジネスロジックを実装し、HTTPリクエストとレスポンスを管理します。

Djangoのviews.pyファイルに関数やクラスとして定義します。
```
from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all()
    return render(request, 'blog/post_list.html', {'posts': posts})
```

MTVパターンのフロー
---
`リクエストの処理`:
ユーザーがURLにアクセスすると、Djangoはurls.pyで定義されたURLパターンに基づいてビュー関数を呼び出します。

`データの取得`:
ビュー関数はモデルからデータを取得し、テンプレートに渡します。

`HTMLの生成`:
テンプレートはビューから渡されたデータを用いてHTMLを生成します。

`レスポンスの返却`:
生成されたHTMLがユーザーのブラウザにレスポンスとして返されます。

まとめ
---
DjangoのMTVパターンは、Webアプリケーションの設計と実装を整理し、効率的な開発を支援します。
モデル、テンプレート、ビューの各コンポーネントを適切に分離することで、コードの保守性や再利用性が向上します。
【Django】settings.pyのINSTALLED_APPS

INSTALLED_APPSとは？
---
Djangoプロジェクトの設定ファイルsettings.pyの重要な部分で、プロジェクトにインストールされているアプリケーションのリストを指定します。
このリストに登録されたアプリケーションは、Djangoによって自動的に検出され、プロジェクト全体で利用できるようになります。

役割
---
`アプリケーションの有効化`:
INSTALLED_APPSにリストされているアプリケーションのみがDjangoプロジェクトで使用されます。
アプリケーションがここに含まれていないと、Djangoはそのアプリケーションを認識せず、機能しません。

`データベースマイグレーション`:
アプリケーションがINSTALLED_APPSに登録されていると、そのアプリケーションのデータベースモデルのマイグレーションが実行されます。
これにより、データベースのスキーマが自動的に作成されます。

`管理画面の設定`:
管理画面に表示するモデルや管理機能も、INSTALLED_APPSに登録されているアプリケーションに基づいて設定されます。

`テンプレートや静的ファイルの検索`:
DjangoはINSTALLED_APPSのアプリケーションからテンプレートや静的ファイルを検索します。
これにより、各アプリケーションのテンプレートや静的ファイルを簡単に利用できます。

設定の例
---
```
INSTALLED_APPS = [
    'django.contrib.admin',  # 管理画面アプリケーション
    'django.contrib.auth',   # 認証システム
    'django.contrib.contenttypes',  # コンテンツタイプフレームワーク
    'django.contrib.sessions',  # セッションフレームワーク
    'django.contrib.messages',  # メッセージフレームワーク
    'django.contrib.staticfiles',  # 静的ファイルの管理
    'blog',  # 自作アプリケーション
]
```
アプリケーションの追加と設定
---
`カスタムアプリケーションの追加`:
プロジェクトにカスタムアプリケーションを追加するには、INSTALLED_APPSリストにそのアプリケーションの名前を追加します。たとえば、blogというアプリケーションを追加するには、リストに'blog'と記述します。

`サードパーティ製アプリケーションの追加`:
サードパーティのDjangoアプリケーション（例: django-rest-framework）も、INSTALLED_APPSに追加して利用します。インストール後は、パッケージ名をリストに追加するだけで利用可能です。

まとめ
---
INSTALLED_APPSはDjangoの設定の中心的な要素であり、アプリケーションの機能やデータベースの扱い、管理画面など、多くの重要な機能に影響を与えます。
【Git】Squash and mergeされたローカルブランチを一括削除する方法

Squash and mergeされたブランチは `git branch -d` で削除できません。
そのため、次のようなコマンドを使用して不要なローカルブランチを一括削除しようとしてもSquash and mergeされたブランチは残ってしまいます。

```terminal
git branch --merged | grep -Ev '^\*|main|develop' | xargs -r git branch -d
```

Squash and mergeされたブランチを一括削除するには`main`ブランチで`git pull --prune`した後に以下のようなコマンドを実行します。

```terminal
git branch --format '%(refname:short) %(upstream:track)' | grep -oP '.*(?=\s\[gone\]$)' | xargs -r git branch -D
```

- `git branch --format '%(refname:short) %(upstream:track)'`
  すべてのブランチの名称とその上流ブランチの追跡情報を表示
    [%(refname:short) %(upstream:track)について](https://git-scm.com/docs/git-for-each-ref#_field_names)
  
- `grep -oP '.*(?=\s\[gone\]$)'`
  Perl正規表現に一致した部分のみ抽出

- `xargs -r git branch -D`
  前述の処理で取得したブランチを削除。ただし、該当するブランチがない場合には実行しない

コマンドが長いのでGitのエイリアスに以下の状態で登録しておくと便利です。

```terminal
git switch main && git pull --prune && git branch --format '%(refname:short) %(upstream:track)' | grep -oP '.*(?=\s\[gone\]$)' | xargs -r git branch -D
```
AWS Lambdaの def lambda_handler(event, context): って決まり文句？？

## この記事の対象者
初めてLambdaを使う人、使い始める人

## 結論
- パラメータ名：決まり文句ではないが **ほぼ決まり文句**

## AWS Lambda ランタイムの基本

### パラメータの基本構造

1. 第一パラメータ：イベントデータ（通常 `event`）
2. 第二パラメータ：コンテキスト情報（通常 `context`） 
    ```
    def lambda_handler(第一パラメータ, 第二パラメータ):
    ```

### 順序の重要性

- 第一パラメータ：常にイベントデータ
- 第二パラメータ：常にコンテキスト情報

## パラメータ名のカスタマイズ例

### 標準的な使用方法

```python
def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

## カスタム名の使用例

```python
def lambda_handler(action, text):
    print(f"Received action data: {action}")
    print(f"Function name: {text.function_name}")
    user_name = action.get('user_name', 'Guest')
    return f"Hello, {user_name}! This is a custom named handler."
```

### さらにシンプルな命名例
```
def lambda_handler(event, context):
```
上記を下記の様にすることも可能
```
def lambda_handler(A,B):
```

```python
def lambda_handler(A, B):
    print(f"Received event data: {A}")
    print(f"Function name: {B.function_name}")
    user_name = A.get('user_name', 'Guest')
    remaining_time = B.get_remaining_time_in_millis()
    return {
        'message': f"Hello, {user_name}!",
        'remaining_time': remaining_time
    }
```

## 特殊なユースケース

### context を使用しない場合

- 用途：S3バケットのCSVファイルをJSON変換
- 特徴：イベントデータのみ使用。context 不要

```python
def lambda_handler(event, _):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    return convert_csv_to_json(bucket, key)
```

### context のみを使用する場合

- 用途：簡単な挨拶ボットなど
- 特徴：Lambda関数の情報のみ使用。イベントデータ不要

```python
import time

def lambda_handler(_, context):
    current_time = time.strftime("%Y-%m-%d %H:%M:%S")
    function_name = context.function_name
    remaining_time = context.get_remaining_time_in_millis()
    
    message = (f"こんにちは！\n"
               f"現在の時刻は {current_time} です。\n"
               f"この関数の名前は「{function_name}」です。\n"
               f"関数はあと約 {remaining_time / 1000:.2f} 秒実行可能です。")
    
    return {
        'statusCode': 200,
        'body': message
    }
```
## まとめ
- パラメータ名：自由にカスタマイズ可能
- 順序：固定。第一がイベント、第二がコンテキスト
## 補足
- 標準名（`event`, `context`）の使用が多め
HTTPSの暗号化の仕組みをわかりやすく説明してみた

# はじめに
この記事は、ITについて全く知らない人に、インターネットでの暗号化の仕組み（特にHTTPS）についてわかりやすく説明することを目的としています。そのため、具体的な暗号化手法やプロトコルについては、あえて触れていません。技術的、専門的な知識を求めている方は、別の記事をご参照ください。

# 説明に使用するもの
この記事では、登場人物としてAさん、Bさん、Cさんを用意します。*1

AさんとCさんでメッセージをやりとりしたいのですが、メッセージは毎回Bさん経由でなければいけない、という設定です。

では、順を追って説明していきます。

# 1.メッセージを暗号化する

Aさんは次のような仕組みを考えCさんと共有します。

- メッセージをすべて**N**文字ずつずらして書き直す
- 例えばN=１の時、「こんにちは」→「さあぬつひ」*2

Aさんはこの仕組みで暗号化した手紙をCさん宛てに送りたいです。

ですが、この方法だとNという値をBさんに知られずにCさんに共有することができなければ意味がありません。
直接会って教えれば可能ですが、ここではそれは無理だと仮定します。

# 2.暗号化用の鍵、復号用の鍵を作成

手紙のやり取りだけで、Bさんにバレることなく鍵を共有したいと考えたAさんは新たにこんなものを発明します。

- 暗号化だけできる鍵　→　**公開鍵**とよぶ
- 復号だけできる鍵　　→　**秘密鍵**とよぶ*3

また、さっきまで使用していた鍵**N**を**共通鍵**とよぶことにします。

Aさんは、**公開鍵**と**秘密鍵**を作り、**公開鍵だけ**をCさんに渡します。

Cさんは、**共通鍵**を作り、それをAさんから受け取った**公開鍵**で暗号化してAさんに返します。

Aさんは、自分だけが持っている**秘密鍵**でCさんからのメッセージを復号し、**共通鍵**を手にいれます。

この時点でそれぞれが持っている（知っている）鍵はこうなります
・Aさん　→　公開鍵、秘密鍵、**共通鍵**
・Bさん　→　公開鍵
・Cさん　→　公開鍵、**共通鍵**

Bさんに知られることなく、共通鍵を共有することができていますね！

その後、AさんとCさんは共有した**共通鍵**を使って安全にメッセージを通信することができました。めでたしめでたし。*4

# 注釈
*1 Aさんがサーバー、Cさんがブラウザ、Bさんが不特定多数の人々と想定しています。


*2 シーザー暗号と呼ばれる方法で、原始的な暗号化方法です。実際はAESという複雑な方法で暗号化が行われています。

*3 実際にはRSA暗号というアルゴリズムで作成され、二つの素数が秘密鍵、その積が公開鍵となります。

*4 本記事の暗号化に加え、公開鍵が本当に正しい相手のものであることを確認するために、公開鍵認証という仕組みも存在します。
CODESYS の為のRaspberry Pi 

CODESYSを家でさわりたかったのでRaspberry Pi 4Bを購入
（5でも良かったが高いのと4Bの方が安定していると思ったので）
インストール時の記録をしておくことにした。
メルカリでセットを購入しSDカードは最初からOSが入っていたがせっかくなのでOSをインストールするところから
# OSインストール
Windows PCにRaspberry Pi　imager v1.8.5 をインストールして
Rasberry Pi OS(32-bit) リリース日2024-07-04のOSを作成した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/03457517-303d-ed2b-3c77-500321cd34c7.png)
モニターが余っていなかったが趣味で購入したキャプボ（4K60Pro MK.2）とOBSを駆使して何とかインストール


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/94701e13-f1bd-5358-28e8-57c1aa6ba598.png)

# Raspberry Pi Connect
ずっとキャプボを占領しているのはつらいので、
OSインストール後、いろいろ調べていると
Raspberry Pi Connectというものがあるらしく
アカウントを作成して設定を有効にした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/5dcf937b-63a6-fb58-7090-3e95dd000504.png)

# その他便利機能
Raspberry Pi Connectを入れたがWindowsのRDPもできるように追加
ついでに起動中のLED点滅設定をしておくと便利っぽかったので追加

# 参考にしたURL
https://zenn.dev/toitoy8/articles/220519_codesys
https://qiita.com/oofunctionblock/items/75ea902b11c9d8d67baf
https://zenn.dev/kmiura55/articles/raspberrypi-connect-fist-touch
https://cgbeginner.net/raspi-led/
エンジニア初心者が感動したCursor vs. VS Code: AIで簡単にコードを書く方法

## はじめに
エンジニアとして効率的にコードを書くことは、開発スピードや品質を向上させるために非常に重要だと思っています。私はエンジニア初心者のため、コードエディタは初めて触りますが、CursorのAI機能はまさに初心者のためにあるようなもので。とても感動しました！
　この記事では、人気のあるコードエディタであるVS Codeと、AIを用いて簡単にコードを書くことができるCursorを比較し、特にAIによる質問機能について詳しく説明します。

## VS Codeとは
Visual Studio Code（VS Code）は、Microsoftが開発した無料のソースコードエディタです。以下の特徴があります：

- **拡張機能**：膨大な数の拡張機能が提供されており、言語サポートやデバッグツールを簡単に追加できます。
- **統合ターミナル**：エディタ内でターミナルを開くことができ、コマンドライン作業を効率化します。
- **Git統合**：Gitリポジトリとの統合が強力で、バージョン管理が容易に行えます。
https://www.cursor.com/


## Cursorとは
Cursorは、AIを用いた次世代のコードエディタです。以下の特徴があります：

- **AIアシスタント**：AIがコーディングをサポートし、コードの補完やバグの検出、改善提案を行います。
- **質問機能**：コードに関する質問をAIに直接行うことができ、即座に回答が得られます。
- **自動化機能**：繰り返し作業の自動化や、コードの生成をAIが行うことで、開発効率が大幅に向上します。

## VS CodeとCursorの比較

### 1. コーディング支援
- **VS Code**：多くの拡張機能が利用可能で、言語ごとの補完機能やLintツールを追加できます。しかし、設定やカスタマイズには時間がかかることがあります。
- **Cursor**：AIがリアルタイムでコーディングを支援し、補完やエラーチェック、リファクタリングを自動で行います。設定不要で即座に利用できる点が魅力です。ただし、無料版は回数が決まっているのでご注意を！！

### 2. 質問機能
- **VS Code**：特定の拡張機能を利用することで質問機能を追加できますが、基本的にはオンラインリソースやコミュニティに頼る必要があります。
- **Cursor**：エディタ内でAIに直接質問ができ、コードに関する具体的なアドバイスや解決策を即座に提供します。例えば、「このエラーの原因は何か？」や「この関数の最適な書き方は？」といった質問に対して、適切な回答が得られます。

### 3. 開発効率
- **VS Code**：拡張機能のカスタマイズにより、開発環境を自分好みに最適化できます。しかし、その分セットアップに時間がかかることがあります。
- **Cursor**：AIが自動で環境設定や最適化を行うため、すぐに開発を開始できます。特に初心者や忙しい開発者にとって大きなメリットです。さらに、拡張機能もVS Codeと遜色ないためVS Codeを使い慣れた人でも容易に使い始めることができます。

## 具体例：AIによる質問機能の活用
ここでは、CursorのAI質問機能を用いた具体的な例を示します。

### エラーメッセージの解決
```python
def divide(a, b):
    return a / b

result = divide(5, 0)
```

このコードを実行すると、`ZeroDivisionError`が発生します。Cursorでは、このエラーに対して以下のように質問できます：

```
このコードで発生するエラーを修正する方法は？
```

AIの回答：
```
ゼロによる除算が原因でエラーが発生しています。引数`b`が0でないことを確認するチェックを追加してください。

修正後のコード：
```python
def divide(a, b):
    if b == 0:
        return "Error: Division by zero"
    return a / b

result = divide(5, 0)
```

### 最適化の提案
例えば、リストの要素を2倍にする関数があるとします。

```python
def double_elements(elements):
    return [e * 2 for e in elements]
```

このコードに対して、「この関数をさらに効率的にする方法は？」と質問すると、Cursorは以下のように提案してくれます：

```
ループを効率化するために、リスト内包表記の代わりにNumPyを使用することを検討してください。

修正後のコード：
```python
import numpy as np

def double_elements(elements):
    return np.array(elements) * 2
```

### コードを指示だけで作
さらに、cursorでは簡単な命令文で大まかなコードを自動で書いてくれたりファイルを作成してくれます。
![スクリーンショット 2024-08-08 1.25.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763893/6b916969-79ef-db47-28a2-4444f073e6a0.png)
この機能がとっても便利です！一番のおすすめポイントと言っても過言ではないです。

## 結論
VS CodeとCursorは、それぞれ異なる特徴を持つ強力なコードエディタです。VS Codeは拡張機能の豊富さとカスタマイズ性が魅力ですが、CursorはAIを用いたコーディング支援と質問機能により、特に効率的な開発をサポートします。どちらのエディタを選ぶかは、開発スタイルやニーズに応じて検討することをお勧めします。

## おわりに
この記事が、VS CodeとCursorの違いを理解し、どちらのツールが自分に適しているかを判断する助けになれば幸いです。私はエンジニア初心者としてCursorのAI機能に感動しましたが、今後もAIを活用した開発ツールは進化し続けるでしょう。常に最新の情報をキャッチアップし、最適なツールを選び続けることが、エンジニアとしての成長につながります。

---

この記事に関するご質問やフィードバックがありましたら、ぜひコメント欄でお知らせください。また、次回の記事では、Cursorの高度な機能やカスタマイズについてさらに詳しく探求していきます。お楽しみに！
アバターのHDRP撮影はじめてみたメモ

c104で配布予定の同人誌にて、アバターのHDRPでレンダリングした画像を使って写真集を作りました。はじめてのHDRPでの撮影ということもあり、様々な記事を参考にさせていただきながら撮影させていただきました。本記事では、その際に引っかかった部分や工夫した点をまとめてみます。

in progress ....
mcframe7とは

https://www.mcframe.com/

### mcframe7の概要
mcframe7は、製造業向けの生産管理システムで、「現場の知」を活かして効率的なものづくりを支援します。システムは以下の特徴を持っています。

1. **導入バージョンの永続保守**:
   - 低コストで長期間利用可能。
   - バージョンアップの要否を選択可能で、業務改革を阻害しません。

2. **製造業に特化**:
   - 日本のものづくりの強みを引き出すパッケージ。
   - 業務ノウハウや豊富な経験を集約。

3. **柔軟性と拡張性**:
   - 多様な業務ノウハウを反映した設計。
   - データベースやソースコードを公開し、個別要件にも対応可能。

4. **他システムとの連携**:
   - MES、スケジューラ、PLM/PDM、EDI、会計システムなどとシームレスに連携。

5. **グローバル対応**:
   - 多言語・多通貨・複数会社管理に対応。
   - 海外自社拠点およびパートナーによる現地サポート。

### mcframe7の機能

1. **SCM（Supply Chain Management）**:
   - 生産管理、外注管理、購買管理、品質管理、需給管理、受注管理、出荷管理などをカバー。

2. **PCM（Product Cost Management）**:
   - 標準原価、予算原価、実績原価、実際原価の管理。
   - 原価差異分析、売上管理、利益分析などが可能。

3. **販売管理**:
   - 受注管理、在庫引当、出荷管理、輸出管理、売上管理、債権管理などの機能を提供。

4. **共通機能**:
   - マスタ管理、履歴管理、権限管理、開発環境、プッシュ通知、KPIダッシュボード、タイムライン・ナレッジ機能など。

### mcframe7の強み
- **短期・低コストでの導入**: パッケージ標準機能を活用した早期導入が可能。
- **ノウハウ満載の豊富な機能**: 日本の製造業の業務ノウハウを活かした機能が豊富。
- **カスタマイズ可能な柔軟性**: 専用開発ツール「FrameManager」によるカスタマイズが可能。
- **多様なシステムとの連携**: SOA基盤を活用し、他システムとのシームレスな連携を実現。

### 導入効果
- **業務の効率化**: 現場の「知」を活かし、業務プロセスの効率化を支援。
- **コスト削減**: 永続保守により低コストで長期間利用可能。
- **グローバル展開支援**: 多言語・多通貨対応により、海外拠点での業務もサポート。

このように、mcframe7は製造業の多様なニーズに対応し、効率的な業務運営を支援するための強力なツールです。

【参考文献】
・mcframeご紹介資料.pdf（ Copyright(C) Business Engineering Corporation. All rights reserved.）
Karabiner Control+左右Commandで一方向IME切り替え

```
{
    "description": "Control+左右Commandで一方向IME切り替え",
    "manipulators": [
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.microsoft\\.rdc\\.macos"
                    ],
                    "type": "frontmost_application_unless"
                }
            ],
            "from": {
                "key_code": "left_command",
                "modifiers": {
                    "mandatory": [
                        "control"
                    ]
                }
            },
            "to": [
                {
                    "key_code": "japanese_eisuu"
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.microsoft\\.rdc\\.macos"
                    ],
                    "type": "frontmost_application_unless"
                }
            ],
            "from": {
                "key_code": "right_command",
                "modifiers": {
                    "mandatory": [
                        "control"
                    ]
                }
            },
            "to": [
                {
                    "key_code": "japanese_kana"
                }
            ],
            "type": "basic"
        }
    ]
}
```
企業のテックブログの更新をまとめてチェックできるサービスを作りました

こんにちは、サクです。

今回「Developers Trend」という企業のテックブログの更新をまとめてチェックできるサービスを作ったので、その内容やシステム構成を紹介します。

## 背景

読者の皆さんの中には、QiitaやZenn、はてブ、大手のテックブログなどから技術情報を取得している方も多いのではないでしょうか？それぞれの更新を追うのは大変で、少し疲れている方もいらっしゃるかもしれません。

また、最近忙しくてGoogle Discoverでサジェストされる記事だけを読んでいる方や、会社のSlackに同僚がシェアしてくれるおすすめ記事だけを読んでいる方もいるかもしれません。

実は私も同じ状況で、そんな忙しいけどサクッと技術情報の更新を追いたいと思っています。

しかし、現状存在しているサービスだと、私にとっては不要な情報（サムネイル、いいね数、description、コメント等）が多く使っていて疲れてしまうという問題がありました。

そこで、シンプルな情報のみを配信して企業のテックブログの更新をまとめてチェックできる「Developers Trend」というサービスを作ってみました。

https://developers-trend.web.app/


## サービス内容

現在提供しているのは、「ユーザーが直近7日間に配信された技術ブログのリストを閲覧できる」という極シンプルな機能です。さらに、記事のキーワード表示や、記事をタップすると訪問済みであることを表示する機能もあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3792607/3a95a6a4-99e1-2b23-ed12-f3ef60a2be9f.png)

## システム構成

個人開発のため、以下の点を意識して作成しました。
- できるだけお金をかけない
- 運用に手間をかけない
- 開発が簡単にできる

以下、システム構成の説明です。
- 記事データをSupabaseに蓄積
    - GASで定期的に追跡対象のRSSを取得し、記事データをSupabaseに格納
    - GASで定期的に格納された記事データをチェックし、Geminiでキーワードを抽出
        - 記事の質を見るために要約も行いますが、その内容は公開していません 
- Next.jsでSSGした静的ファイルをFirebase Hostingにデプロイ
    - SSG時にSupabaseから記事データを取得
    - GitHub Actionsで定期的に実行

![DevelopersTrendアーキ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3792607/5f5435f5-064a-5b8b-e480-b3efb6566e57.png)

工夫点は以下の通りです。
- Next.jsのSSGにより、アプリサーバ無しにCDNで静的ファイル配信のみ（JAMstack）
    - SupabaseのDBアクセスも定期的なビルド時のみのため無料プランで問題無い
- Chakra UIでUIを簡素化
- 生成AIのAPIを無料でも使用できたGeminiを活用（2024年8月現在）
- Sentryでフロントエンドのエラーを監視
- RSS・Atom未対応のページはGASで個別対応（現在はログミーのみ）

## 今後の展望

リリースしたばかりなので、まずは需要があるかの検証を行い、自分自身が気になる点を改善していきます。また、良い情報を対象者レベル別にストックできる機能を少しずつ作り始めています。

そして、もし皆さんからのフィードバックがあればサービスの改善を進めていきたいと思っています。サイト上にGoogleフォームのリンクも用意していますのでぜひご意見やご感想をお聞かせください。

共感してくださる方や気になる方は、ぜひアクセスしてみてください。

https://developers-trend.web.app/
AWSのSSMでの切り替えをバッチでやるサンプル

AWSのSSMでポートフォワーディングをしてDMなり
HTTPS通信をしていたのですが、都度都度コマンドをたたいていたので
バッチを使って自動で起動できるようにしたメモ。

## 実行環境とバッチ
windowsのコマンドプロンプトで切り替え

### メインバッチ
```bat:com_aws_user1.bat
aws ssm start-session ^
--target i-XXXXXXXXXXX ^
--document-name AWS-StartPortForwardingSessionToRemoteHost ^
--parameters %1 ^
--no-verify ^
--profile user1
```
--target i-XXXXXXXXXXXは踏み台のインスタンスID
--parameters に接続先のパラメータを入れる、ホスト情報とか
--no-verify
--profile プロファイルによる切り替え


### 接続バッチ（必要な接続の数だけ作成する）
```bat:接続先.bat
set host="host=xxxxxx.amazonaws.com.portNumber=443,localPortNumber5000"
call com_aws_user1.bat
```

## config / credentials
ユーザーの .aws以下に置く

### config
```
[default]
region=ap-northeast-1
output=json
[profile user1]
region=ap-northeast-1
output=json
```
※profileを書く

### credentials
```
[default]
aws_access_key_id=XXXXXXXXXXXXXXXXXX
aws_secret_access_key_id=XXXXXXXXXXXXXXXXXXXXXXX
[user1]
aws_access_key_id=YYYYYYYYYYYYYYYYYY
aws_secret_access_key_id=YYYYYYYYYYYYYYYYYYYYYYY
```
※こっちにはprofileは書かない

----
こういうのってとてもめんどくさいのだけど
みんな頑張って都度都度接続しているのかな
それともこういうバッチを作ってやってるのかな。
Sandisk PortableSSD が認識しない（ダイソーで解決）

先日、AmazonセールでSandisk PortableSSDを購入しました。
ところがウチの MacBook Air-M1で認識しない！

ネットで調べて、Apple Communityで調べて、ChatGPTに聞いて、解決しなかったので
動きませんーとサポートに連絡したら、すんなり返品交換となりました。

その後、英語のApple Communityで調べてみたら、そのものズバリがありました。


>### Sandisk 1TB ssd not getting detected.
>Sandisk 1TB ssd not getting detected in my MacBook Air-M2.  Model no : SDSSDE30-1T00. The same gets detected in Windows Laptop. I am using a USB C -USB C cable.
>
>Tried formatting in Ex-FAT in windows but still not showing up
>...
>https://discussions.apple.com/thread/254841671?sortBy=rank
>
>>The same issue for me! MacBook Pro M1 2020 and the solution was plug the SSD using the original cable and a USB A -USB C adapter. Then I used the utility disk, erased the volume and worked!!!


付属の USB-AケーブルをUSB-Cに変換かますと認識する？？？

半信半疑でダイソーにて100円のアダプターを買い。

そして本日。
届いた交換品をUSB-C to C で繋ぐと、やっぱり認識しない。

そして、ダイソーのアダプターをかますと・・・

認識しました！

なんてこったい！

念の為速度をきっちり測ります

```
# 書き込み速度テスト、1Gのファイルを作成
time dd if=/dev/zero of=/Volumes/PortableSSD/testfile bs=1m count=1024
1024+0 records in
1024+0 records out
1073741824 bytes transferred in 1.679498 secs (639323074 bytes/sec)

real	0m1.747s
user	0m0.002s
sys	0m0.253s


# 読み取り速度をテスト、1Gのファイルを読む
time dd if=/Volumes/PortableSSD/testfile of=/dev/null bs=1m
1024+0 records in
1024+0 records out
1073741824 bytes transferred in 1.208364 secs (888591371 bytes/sec)

real	0m1.217s
user	0m0.002s
sys	0m0.146s

# 書き込み速度
>>> 1073741824/1.747/1024/1024
586.14768174012593016599

# 読み取り速度
>>> 1073741824/1.217/1024/1024
841.41331142152834839769
>>> 
```

公式スペックをしっかりマークしていました。
まあいいか、ダイソーさん、ありがとう・・・

謎は深まるばかりです。
【React×Jest】data-testidがめっちゃ使いやすいという話

# はじめに
TypeScriptのJest・Testing Libraryを使用したテストにおいて非常に便利だなと思った話の共有です。

# 問題
idやclassを振っていないHTMLタグをテストクラスから取得したい場合、Testing Libraryが用意している専用のメソッドを使うことで簡単に取得することができます！

例えば、以下のコンポーネント（ローディング中を表すスピナー）が画面上に表示されているかどうかの確認をしたい場合

```tsx:LoadingSpinner.tsx
export const LoadingSpinner: FC = memo(() => {
  return (
    <Spinner
      thickness="4px"
      speed="0.65s"
      emptyColor="gray.200"
      color="teal.500"
      size="xl"
    />
  );
});
```

# 解決方法
取得したい要素に`data-testid属性`を付与した上で、
Testing LibraryのgetByTestIdという専用のメソッドを使う。

```diff_tsx:LoadingSpinner.tsx
export const LoadingSpinner: FC = memo(() => {
  return (
    <Spinner
+     data-testid="loading-spinner"
      thickness="4px"
      speed="0.65s"
      emptyColor="gray.200"
      color="teal.500"
      size="xl"
    />
  );
});
```

```tsx:テストクラス
import {screen} from '@testing-library/dom'
const loadingSpinner = screen.getByTestId("loading-spinner");
```

# おわりに
どんな要素でもこの方法で取得できるようです。
これは使えそう！

# 参考

https://blog.autify.jp/article/why-id-should-not-be-used

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
ERP 開発における Java と他の言語の比較: Java が優れている理由

ERP (エンタープライズ リソース プランニング) ソフトウェア開発の分野では、スケーラブルで効率的、かつ信頼性の高いシステムを作成するために、適切なプログラミング言語を選択することが重要です。利用可能な多くの言語の中で、ERP 開発には Java が好まれることがよくあります。この記事では、ERP システムのコンテキストで Java と他のプログラミング言語を比較し、その長所と優れている理由について説明します。

<h2><b>1. プラットフォームの独立性</b></h2>
Java の最も重要な利点の 1 つは、プラットフォームの独立性です。Java アプリケーションは、Java 仮想マシン (JVM) 上で実行されるバイトコードにコンパイルされるため、JVM がインストールされている任意のプラットフォームで同じコードを実行できます。この機能は、さまざまな環境で動作する必要があることが多い ERP システムにとって特に有益です。対照的に、C++ や C# などの言語では、プラットフォーム固有の調整が必要になる場合があり、導入と保守が複雑になります。

<h2><b>2. 堅牢性と信頼性</b></h2>
Java は堅牢性と信頼性で有名で、重要なビジネス プロセスを処理する ERP システムに不可欠な特性です。Java の強力な型指定、例外処理、ガベージ コレクションは、安定したエラー耐性のあるアプリケーションの作成に役立ちます。Python や JavaScript などの言語は多用途で使いやすいですが、Java にあるような組み込みのエラー処理機能やパフォーマンス最適化機能と同じレベルには達していない場合があります。

<h2><b>3. スケーラビリティ</h2></b>
スケーラビリティは、増大するデータ量とユーザー負荷を処理する必要がある ERP システムにとって重要な要件です。Java のアーキテクチャは、マルチスレッドや分散コンピューティングなどの機能を通じてスケーラビリティをサポートします。 Spring や Hibernate などのフレームワークは、複雑なエンタープライズ レベルのアプリケーションを管理するためのツールを提供することで、Java のスケーラビリティをさらに強化します。PHP や Ruby などの言語は人気がありますが、大規模な ERP システムでは同じレベルのパフォーマンスとスケーラビリティを提供しない可能性があります。

<h2><b>4. 成熟したエコシステム</h2></b>
Java には、エンタープライズ開発向けにカスタマイズされた豊富なライブラリ、フレームワーク、ツールを備えた確立されたエコシステムがあります。ERP システムの場合、Java は、堅牢なアプリケーションを構築するための Spring や、データベース インタラクションを管理するための Hibernate などのフレームワークを提供します。この成熟したエコシステムにより、開発が加速され、他のテクノロジと適切に統合されます。JavaScript などの他の言語では、同様の機能を実現するために複数のライブラリやフレームワークに依存することが多く、開発が複雑になることがあります。

<h2><b>5. セキュリティ</h2></b>
ERP システムでは機密性の高いビジネス データが処理されるため、セキュリティは重要な懸念事項です。Java は、強力な型システム、バイトコード検証、アクセス制御を実施する包括的なセキュリティ マネージャーなど、広範なセキュリティ機能を提供します。これらの機能は、一般的な脆弱性や攻撃から保護するのに役立ちます。 PHP や JavaScript などの言語にはセキュリティ対策がありますが、Java に組み込まれたセキュリティ機能により、ERP アプリケーションにとって極めて重要な、より高いレベルの保護が提供されます。

<h2><b>6. コミュニティ サポート</h2></b>
Java は、大規模で活発な開発者コミュニティと、ドキュメント、フォーラム、サードパーティ ツールなどの豊富なリソースの恩恵を受けています。このサポート ネットワークは、トラブルシューティング、開発、ベスト プラクティスの維持に非常に役立ちます。Python や Ruby などの言語にも強力なコミュニティがありますが、Java の広範なリソースと業界サポートにより、ERP 開発の信頼できる選択肢となっています。

<h2><b>7. パフォーマンス</h2></b>
Java のパフォーマンスは、JVM のジャストインタイム (JIT) コンパイルと最適化によって強化され、実行速度を大幅に向上させることができます。Java アプリケーションは、JVM 設定とガベージ コレクションの調整によってパフォーマンスを微調整できます。C++ などの言語の方がパフォーマンスが高い場合もありますが、Java はパフォーマンスと開発の容易さのバランスが取れているため、効率性と保守性の両方が求められる ERP システムにとって魅力的な選択肢となっています。

<h2><b>結論</h2></b>
ERP 開発に使用できるプログラミング言語はいくつかありますが、Java はプラットフォームの独立性、堅牢性、スケーラビリティ、成熟したエコシステム、セキュリティ、コミュニティ サポート、パフォーマンスにおいて際立っています。これらの特性により、Java はエンタープライズ レベルの ERP システムの構築と保守に適した選択肢となっています。ただし、最適な言語の選択は、最終的にはプロジェクトの特定の要件と開発チームの専門知識によって決まります。他の言語と比較した Java の長所を理解することで、企業は ERP システムの実装と運用を成功させるための情報に基づいた決定を下すことができます。
ERP の詳細: <a href="https://www.impactfirst.co/id/g/erp">https://www.impactfirst.co/id/g/erp</a>
【初めてのWEB開発】Node.jsを使用した小説紹介サイト開発

## はじめに

約1ヶ月ほどで友人と共同開発した小説紹介サイト「ノベルバース」について、使用技術や開発過程で直面した課題、そしてセキュリティ面での取り組みを紹介します。

## サイト概要

サイト名：ノベルバース (https://www.novelverse.net)

ノベルバース（以下、本サイト）は、次に何を読もうか迷っている人が最新情報を元に、手軽に小説を探せることを目的に設計されました。ユーザーは多様なカテゴリーや作家名から小説を探索し、お気に入りの作品をブックマークできます。

### 主な機能
- アカウント管理（作成、削除、ログイン、ログアウト）
- 多様なカテゴリーによる小説一覧表示
- 小説詳細情報の閲覧
- ブックマーク機能（「読みたい＋」ボタン）
- 検索機能（全文検索および作家名検索）
- お問い合わせフォーム

## 使用技術

開発に使用した主要な技術スタックは以下の通りです：

### フロントエンド
- HTML / CSS
- JavaScript (Vanilla JS)
- EJS（テンプレートエンジン）

### バックエンド
- Node.js（Express）

### データベース
- MongoDB

### 認証
- Passport.js

### インフラ
- Heroku（ホスティング）
- UptimeRobot（監視ツール）

### 外部サービス/API
- Resend（メール配信サービス）
- Cloudinary（画像ホスティング）

### バックエンド
Express.jsをベースにしたRESTful APIを構築し、MongoDB（Mongoose ODM使用）でデータを管理しています。認証にはPassport.jsを採用し、ローカル戦略を実装しています。

### フロントエンド
サーバーサイドレンダリングにEJSを使用し、動的なUI操作にはVanilla JavaScriptを採用しました。これにより、シンプルながら柔軟な実装を実現しています。

### データベース設計
MongoDBを採用し、小説情報、ユーザーデータ、ブックマーク情報などを柔軟なスキーマで管理しています。

### API統合
Resend APIを使用してアカウント作成時のメール送信とお問い合わせフォームからのメール送信を実装し、Cloudinaryを活用して画像のアップロードと管理を効率化しました。

## セキュリティ対策

セキュリティは最重要事項の一つとして認識し、以下の対策を実施しました：

1. **入力サニタイズ**：`express-mongo-sanitize`と`sanitize-html`を使用し、NoSQLインジェクションやXSS攻撃を防止。

2. **CSRF対策**：`csurf`ミドルウェアを導入し、クロスサイトリクエストフォージェリを防止。

3. **レート制限**：`express-rate-limit`を実装し、DDoS攻撃やブルートフォース攻撃のリスクを軽減。

4. **セッション管理**：`express-session`と`connect-redis`を使用し、安全なセッション管理を実現。Redisをセッションストアとして採用し、セッションデータの永続化と高速アクセスを両立。

5. **環境変数管理**：機密情報は`dotenv`を使用して環境変数で管理し、ソースコード上に直接記述しないよう徹底。

6. **バリデーション**：`Joi`ライブラリを使用してユーザー入力の厳格なバリデーションを実施。

7. **安全なパスワード管理**：`passport-local-mongoose`を利用し、パスワードのハッシュ化とソルト化を自動化。

## 開発で直面した課題と解決策

1. **Herokuの無料プラン廃止対応**：
   Herokuの無料プランが終了したため、アプリケーションが定期的にスリープ状態になる課題がありました。これに対し、UptimeRobotを使用して定期的にアプリケーションにリクエストを送ることで、スリープ状態を回避しました。

2. **データベース設計の最適化**：
   小説情報とユーザー情報の関連付けに時間を要しました。最終的に、効率的なクエリが可能なスキーマ設計を採用し、パフォーマンスを向上させました。

3. **非同期処理の管理**：
   APIリクエストやデータベース操作など、多数の非同期処理の管理に苦心しました。async/awaitを適切に使用することで、コードの可読性と保守性を向上させました。

4. **セッション管理の最適化**：
   大量のユーザーセッションを効率的に管理するため、Redisを導入しました。これにより、セッションデータの永続化と高速なアクセスを実現しました。

## 今後の展望

1. **掲示板アプリの結合**：本サイトの掲示板アプリを開発し、レビューの役割を持たせたいと思っています。

2. **ユーザー体験の向上**：ユーザーフィードバックを基に、UIのさらなる改善や新機能の追加を検討しています。

3. **スケーラビリティの向上**：将来的なトラフィック増加に備え、マイクロサービスアーキテクチャに移行するための学習をし、実装までしたいと思っています。

4. **テスト自動化**：単体テストや統合テストの導入により、品質管理プロセスを強化する予定です。

5. **SEO対策**：現在、metaタグなどの最低限のSEO対策しか施していないので、WEBサイトにおけるSEO対策についてもっと理解を深め、反映させていこうと思っています。

## 結論

本サイトの開発を通じて、フルスタック開発の経験を積むとともに、実践的なセキュリティ対策の基礎を学びました。今後も継続的な改善を行い、ユーザーにとってより価値あるプラットフォームを目指していきます。
Symbolノード証明書作るやつNode.jsにした

## インストール
```sh
npm install -g simple-symbol-node-cert-cli
```

https://www.npmjs.com/package/simple-symbol-node-cert-cli

## 証明書を作る
色々とオプションは付けてますけど、`generate`だけで作れます。
作成時に秘密鍵を暗号化して記録したファイル`privatekeys.yaml`を出力するので、暗号化用のパスワードを入力してください。
```sh
simple-symbol-node-cert-cli generate"
```
自動的にmainアカウントの秘密鍵は削除します。transportアカウントの方は、通信に必要なので残してます。

以下、生成される`privatekeys.yaml`です。
```yaml
main:
  privateKey: >-
    97f90...
  publicKey: EB11A9FCA19BAAF7C744C01E0DE954BC7925FEE888365B42E3CCF73F84C4C8F6
  mainnetAddress: NADLS4Y7VFRY7VZFCIWO6A6TSL2GK7U7UQICBNI
  testnetAddress: TADLS4Y7VFRY7VZFCIWO6A6TSL2GK7U7UQJS7TY
transport:
  privateKey: >-
    f468d...
  publicKey: 67CFEBD698EEF930169A41C20D821163DC311E9BBAD9502F050486839E21B8A6
  mainnetAddress: ND7X3TXX33W34RRMLQT7LOZ6HIR4HW2EDB3BCCQ
  testnetAddress: TD7X3TXX33W34RRMLQT7LOZ6HIR4HW2EDB4CG2Y
```

ちなみにですが、privateKeyに平文の秘密鍵を前もって入れて`generate`すると、その秘密鍵から証明書を作成します。

### オプション

|オプション|説明|
|:-|:-|
|--cadays|CA証明書(mainアカウント)有効日数。デフォルトは`7300`日(約20年)。|
|--nodedays|Node証明書(transportアカウント)有効日数。デフォルトは`375`日(約1年)。|
|--caname|CA名。デフォルトは`Simple Symbol CA`。|
|--nodename|Node名。デフォルトは`Simple Symbol Node`。|
|--certdir|証明書を出力するディレクトリパス。デフォルトは`./cert`。|
|--privatekeys|暗号化した秘密鍵を保存するファイルパス。デフォルトは`./privatekeys.yaml`。|
|--force|証明書上書生成。|

## 証明書を更新
これもオプション何個かありますが、これで更新できます。
`privatekeys.yaml`ファイルが無いとできないので、なくなさないように。
```sh
simple-symbol-node-cert-cli renew
```

### オプション

|オプション|説明|
|:-|:-|
|--cadays|CA証明書(mainアカウント)有効日数。デフォルトは`7300`日(約20年)。|
|--nodedays|Node証明書(transportアカウント)有効日数。デフォルトは`375`日(約1年)。|
|--certdir|証明書を出力するディレクトリパス。デフォルトは`./cert`。|
|--privatekeys|暗号化した秘密鍵を保存するファイルパス。デフォルトは`./privatekeys.yaml`。|

## 証明書を確認
証明書を簡易的に確認出来ます。
```sh
simple-symbol-node-cert-cli info
```

以下の様な出力となります。
```plaintext
==================================================
CA Cert:
       Start Date: Sun Aug 04 2024 20:07:35 GMT+0900 (日本標準時)
         End Date: Sat Jul 30 2044 20:07:35 GMT+0900 (日本標準時)
       Public Key: 5737DBF5B914F8045751E802D5445F61F066053BE1C2C42F6E8F3CC028B96790
  Mainnet Address: NCY7FZBFAEE6DTAOZ5JVN6YL3M7HFKEQ3WQ74UA
  Testnet Address: TCY7FZBFAEE6DTAOZ5JVN6YL3M7HFKEQ3VCIBSA
Node Cert:
       Start Date: Sun Aug 04 2024 20:07:35 GMT+0900 (日本標準時)
         End Date: Thu Aug 14 2025 20:07:35 GMT+0900 (日本標準時)
       Public Key: 5E4574528EF45F68828CB39828DACC58A8CDDA59FBF62EF033CC65F25FC4CC7F
  Mainnet Address: NCNW3OQTLEFUQ5L74FKZTHVOK6KES4VD5G4TKTA
  Testnet Address: TCNW3OQTLEFUQ5L74FKZTHVOK6KES4VD5EWAQ6Y
==================================================
```

### オプション

|オプション|説明|
|:-|:-|
|--certdir|証明書を出力するディレクトリパス。デフォルトは`./cert`。|
diffコマンドの表示形式についてまとめてみる

# 概要
2つのファイルの差分を表示するdiffコマンドですが、オプションによって様々な形式で表示するがことできます。
オプションがなかなか覚えられず、diffコマンドを使用する際にいつも調べ直してしまうので、記事にまとめて知識を整理しておこうと思います。

## この記事で取り扱う表示形式
- オプションなしの形式
- `-u`オプションを使用した形式（ユニファイド形式）
- `-y`オプションを使用した形式

# 今回比較する2ファイル
以下の`before.txt`(元のファイル)と`after.txt`(編集後のファイル)を比較してみたいと思います。

```plaintext:before.txt
before only

not changed
changed
```

```plaintext:after.txt

after only
not changed
changed!!!!!
```

# オプションなしの場合
オプションなしでdiffコマンドを使用した場合の出力は以下のようになります。
```shell:コマンド
diff before.txt after.txt
```
```plaintext:出力結果
1d0
< before only
2a2
> after only
4c4
< changed
---
> changed!!!!!
```
ここで`d`は削除(delete)、`a`は追加(add)、`c`は変更(change)を表しています。

つまり
`1d0`: 元のファイルの1行目が削除された
`2a2`: 新しいファイルの2行目に追加された
`4c4`: 4行目が変更された
という情報が示されており、各変更内容(あるいは削除・追記内容)がその下に書かれています。慣れないと難しいですね。

# -uオプションを使用した場合
`-u`を使用した出力形式はユニファイド形式と呼ばれます。
```shell:コマンド
diff -u before.txt after.txt
```
```plaintext:出力結果
--- before.txt	2024-08-01 20:00:00
+++ after.txt	2024-08-01 20:05:30
@@ -1,4 +1,4 @@
-before only
 
+after only
 not changed
-changed
+changed!!!!!
```
最初の2行は比較したファイルの名前と更新日時が表示されます。

その次の`@@`から始まる行は、比較したそれぞれのファイルの変更開始行と何行分の変更表示をしているかを示しています。
今回のケースだと、両ファイルともに1行目から4行分の変更表示をしていることを表します。
その次の行からが変更内容の詳細です。
`-`が書かれている行は削除された行、`+`が書かれている行は追加された行を表しています。

この`@@`から始まる行からその変更詳細までの単位のことを「ハンク」と呼びます。
今回はハンクが1つだけしか表示されていませんが、もう少し長いファイルなどで試してみるとハンクが複数表示されます。

各ハンクには変更行だけでなく、変更の前後何行かも併せて表示されています。
そのため、ユニファイド形式は似たような変更箇所が多い場合に、ファイルのどの部分が変更されたのかを確認しやすいという特長があります。

# -yオプションを使用した場合
個人的には一番使いやすい表示形式です。
比較結果を1行ごとに出力してくれます。
```shell:コマンド
diff -y before.txt after.txt
```
```plaintext:出力結果
before only							<       
									
								>       after only
not changed								not changed
changed								|       changed!!!!!

```
各行の結果が1行ごとに表示されており、
`<`: 左のファイルにのみ存在
`>`: 右のファイルにのみ存在
`|`: 内容不一致
を表しています。
（上記の3種類が表示されていない行は一致を表します。）

1行ごとに表示してくれるので、以下のように左のファイルにのみ存在する内容を抜き出す操作などに便利です。

```shell: コマンド
diff -y before.txt after.txt | grep '<' | cut -f 1
```
```plaintext:出力結果
before only
```

# まとめ
今回はdiffコマンドの3種類の表示形式についてまとめてみました。
diffコマンドには他にも様々なオプションがあるので、興味のある方は`man diff`コマンド等で確認してみてください！

# 参考
[新しいLinuxの教科書　第２版](https://www.sbcr.jp/product/4815624316/)