OmniAICreator/Qiita-1.07M huggingface dataset:
【Git】git add で変更をステージに追加する方法

以前こんなツイートをしました。Gitは、チーム開発では必須のスキルなのでぜひ `git add` についても理解を深めていきましょう。

普段はプログラミングや、フリーランスについて発信しています。<a href="https://twitter.com/div_tomo?ref_src=twsrc^tfw" class="twitter-follow-button" data-lang="ja" data-show-count="false"> フォローする </a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Gitリポジトリの作成方法<br><br>1. コマンドラインを開く<br>2. プロジェクトのディレクトリ（フォルダ）に移動<br>3. git init を実行<br>4. [.git]ディレクトリが作成される<br><br>Gitは、チーム開発では必須のスキルだから必ず覚えてほしい！<br><br>未経験で入ってくる人にありがちなのですがgitコマンドすごい聞いてくる。</p>&mdash; Tomoya@Web系フリーランサー (@div_tomo) <a href="https://twitter.com/div_tomo/status/1695484710858928271?ref_src=twsrc%5Etfw">August 26, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 変更をステージに追加する

変更をステージに追加するためには、以下のように `git add` コマンドを使います。

> ＞_ コマンドライン
> 

```html
> git add ＜ファイル名＞
> git add ＜ディレクトリ名＞
> git add .
```

### 説明

`git add` の後ろにファイル名や、ディレクトリ名を指定して通常は使います。

ワークツリーの変更をすべて追加する場合は `git add .` と入力する必要があります。

# git add の使用方法

```mermaid
flowchart LR

A[ワークツリー] -- git add --> B[ステージ]
```

 `git add` を使用して、ワークツリーからステージに変更を追加することができます。

## ファイルを作成

「index.html」 というファイルを作成して内容を変更ください。内容は何でも良いです。

> index.html
> 

```html
<h1>test</h1>
```

## 変更をステージに追加

変更した内容を `git add` でステージに追加していきます。

```html
> git add index.html
```

これでステージに追加されました。
' 'と" "の違い[PHP]

## はじめに
' '(シングルクォーテーション)と" "(ダブルクォーテーション)の違いについてのメモです。

## " "(ダブルクォーテーション)
・" "内で変数を記述できる

:::note info
余談：文字列内で変数を使う際はバグを出さない為にも __｛ ｝__ を使って囲う
:::

・エスケープシーケンスが利用できる

:::note info
余談：エスケープシーケンスとは\（バックスラッシュ）から始まる特殊なコード
:::

## 最後に
簡単なメモなので今後また知見が増えたら追記するかもしれません。
Linux Ubuntu を有線で載せた時の話

Linuxを暫くraspiなどで弄り倒していて、Ubuntu導入したいと思い、YOUTUBEなんか凄く簡単にUbuntu導入しているように見えて、以外に難しかった。wifiや冗長化など技術的ハードルが少し高い。古いPCにSSD✕２を有線でUbuntuに載せ替えてみたが、その際、GPUのスペックがネックになり、GPUだけ少しスペックの高いものに載せ替えたらトラブルが解決した。今は快適。

同じ問題にぶつかっている人もいるかも。インストールしても何となく気持ちが悪い。快適ではない。インストール途中でブラックアウトしてしまう、セーフグラフィックモードだと出来るなどの問題が出てきた人は、GPUの載せ替えをしてみたら良い。恐らく、UbuntuのインストールはGPUがネックだと分かる。
voicevox_core python binding w/GPU

※2023/8/27現在
github のvoicevox_core のインストラクション通りにやっても動かなかったのでメモ。WSL2のUbuntu20で動かしていますが、特にWSL依存な部分は無いと思う。
以下のCPUバージョンのインストール方法をもとに少し変えました。
https://zenn.dev/hosyan/articles/d38d47c310057d

```sh
# reference: https://zenn.dev/hosyan/articles/d38d47c310057d

curl -sSfL https://raw.githubusercontent.com/VOICEVOX/voicevox_core/8cf307df4412dc0db0b03c6957b83b032770c31a/scripts/downloads/download.sh > download.sh
bash download.sh --device cuda

python -m venv voicevox
source voicevox/bin/activate
wget https://github.com/VOICEVOX/voicevox_core/releases/download/0.14.4/voicevox_core-0.14.4+cuda-cp38-abi3-linux_x86_64.whl
pip install voicevox_core-0.14.4+cuda-cp38-abi3-linux_x86_64.whl
pip install nvidia-cuda-runtime-cu11
export LD_LIBRARY_PATH=${VIRTUAL_ENV}/lib/python3.10/site-packages/nvidia/cuda_runtime/lib:$LD_LIBRARY_PATH

cd voicevox_core
wget https://raw.githubusercontent.com/VOICEVOX/voicevox_core/406f6c41408836840b9a38489d0f670fb960f412/example/python/run.py

python run.py --mode GPU --text "テストです" --speaker-id 1
```

nvidia-cuda-runtime-cu11 を入れているのは、CUDA を/usr/local とかに入れたくなかったためです。CUDA11 が入っていれば不要だと思います。LD_LIBRARY_PATHのところ、"python3.10" の部分は自分の環境に合わせて修正してください。
voicevox すごいですね。とてもありがたいです。
プログラミング初心者の医学生が残り少ない夏休みでGithubcopilotとchatGPTの力を借りてアプリ開発してみた Day6

これら2つのコースを購入されて，下のコースを６日間で学習されたそう．

アプリを１つ作って終わりにするなら最初の方のやり方，アプリを作った後もアプリ開発を続けていくなら二人目の方のやり方が良さそうで，自分には二人目の方のやり方のほうがあっているような気がしたので，最初の予定よりは時間がかかりそうではありますが，一度これら２つのコースを購入して基礎を勉強したいと思います．

昨日までのようにやみくもにやっていたら，知識がとっ散らかって知識の整理ができなそうと薄々感じていたので，ちゃんとした先生から体系だって学ぶことができることはありがたいです．
しかも，8/31まではセールのようで気になる人はリンクから見てみてはいかがでしょうか．

また，Firebaseというものも勉強しないといけないらしく，こちらについてもコースの購入を考えています．他になにかアプリリリースするまでの過程で勉強しておいた方がいいことあれば教えてください．
Cara administrasi karyawan agar mempermudah bidang <a title="manajemen kinerja SDM" href="https://pakarkinerja.com/category/manajemen-sdm/"><b>manajemen kinerja SDM</b></a> via AI dengan contoh soal kompetensi esesmen.

<a title="Informasi Otomotif Terkini" href="https://otomotif.live/"><b>Informasi Otomotif Terkini</b></a>

<a title="Berita Olahraga Terbaru" href="https://scoreup.id/"><b>Berita Olahraga Terbaru</b></a>

The Complete Flutter Development Bootcamp with Dart で学習したこと・調べたこと
The Complete Flutter Development Bootcamp with Dart のほうが英語が簡単らしいので，こちらをとりあえずしようと思います．
映像授業で学んだことをChatGPTにまとめてもらいます．
映像授業が28.5時間もあるそうなので時間が圧倒的に足りない...
夏休み終了までには終わらない...
したがって，当初の計画からは大幅に遅れる予定なのでご了承ください．
【Ubuntu】Ruby3.2.2 をインストールしようとしたらエラーになった

## まとめ
* Ruby(3.2.0)から`libyaml`や`libffi`の同梱が廃止された。
* Rubyインストール前に`apt-get`コマンドで`libyaml-dev`を別途インストールする必要がある。
```
$ sudo apt-get install libyaml-dev
```

## 環境
* Windows(10)
* [WSL2]Ubuntu(20.04)
* rbenv(3.2.2)
    * `ruby-build`追加済み
    * `.bashrc`にいろいろ追記済み

## どうした
rbenvからRuby(3.2.2)をインストールしようとしたらエラーになった。
## エラー内容
Ruby(3.2.2)をインストール
```
$ rbenv install 3.2.2
To follow progress, use 'tail -f /tmp/ruby-build.YYYYMMDD.00000.log' or pass --verbose
Downloading ruby-3.2.2.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz
Installing ruby-3.2.2...

BUILD FAILED (Ubuntu 20.04 using ruby-build YYYYMMDD)

Inspect or clean up the working tree at /tmp/ruby-build.YYYYMMDD.00000
Results logged to /tmp/ruby-build.YYYYMMDD.00000.log

Last 10 log lines:
*** Fix the problems, then remove these directories and try again if you want.
make[1]: Leaving directory '/tmp/ruby-build.YYYYMMDD.00000/ruby-3.2.2'
Generating RDoc documentation
/tmp/ruby-build.YYYYMMDD.00000/ruby-3.2.2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
make: *** [uncommon.mk:598: rdoc] Error 1
```

``/tmp/ruby-build.YYYYMMDD.00000.log``を見てみると最終行辺りにエラーが吐き出されている。
```/tmp/ruby-build.YYYYMMDD.00000.log
/tmp/ruby-build.YYYYMMDD.00000/ruby-3.2.2/lib/yaml.rb:3: warning: It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
uh-oh! RDoc had a problem:
cannot load such file -- psych

run with --debug for full backtrace
make: *** [uncommon.mk:598: rdoc] Error 1
```
Ruby のインストールに使用されるYAML出力用の``psych``が欠けているかららしい。

## どうして
Ruby(3.2.0) から`libyaml`や`libffi`の同梱が廃止されたために起きたエラーだった。

https://www.ruby-lang.org/ja/news/2022/12/25/ruby-3-2-0-released/

> 3rd パーティライブラリのソースコード同梱廃止
> libyaml や libffi のような 3rd パーティのライブラリのソースコードの同梱を廃止しました
>
> Psych に同梱していた libyaml のソースコードは削除されました。ユーザーは自身で Ubuntu や Debian プラットフォームなら libyaml-dev パッケージを
インストールする必要があります。このパッケージ名称はプラットフォームごとに異なります。
>
>Fiddle に同梱していた libffi のソースコードも削除されました

## 解決
Ubuntuに`libyaml-dev`パッケージをインストールした。
```
$ sudo apt-get install libyaml-dev
```
Rubyをインストールして無事にインストール完了。
```
$ rbenv install 3.2.2
$ rbenv global 3.2.2
$ ruby -v
ruby 3.2.2
```

### 補足
不足しているパッケージを一度にインストールするコマンドがある(動作確認無)

https://github.com/rbenv/ruby-build/discussions/2118


```
sudo apt install git curl libssl-dev libreadline-dev zlib1g-dev autoconf bison build-essential libyaml-dev libreadline-dev libncurses5-dev libffi-dev libgdbm-dev
```

## 解決に導いた記事様方
https://zenn.dev/fuuukeee3/articles/22caeb537cf1a6
https://qiita.com/n-yamanaka/items/3268cdd2179d31a93ee3

以上
Bashのinputrc設定(Tab補完時の挙動)

# Bashのinputrc設定(Tab補完時の挙動)について

bashでのTab補完の挙動についての個人的な設定

`~/.inputrc`で以下のように設定している。

`~/.inputrc`は`/etc/inputrc`をコピーして作成。

```
set bell-style none
set show-all-if-ambiguous on
set completion-query-items 0
set page-completions off
```

### 設定の解説

#### (1) `bell-style none`
端末側の設定にもよるが、Tab補完候補がない場合にビープ音が鳴ったりビジュアルベルが反応したりする。これをOffする。

#### (2) `show-all-if-ambiguous on`
デフォルトの挙動はコマンド入力中にTabを1回押すと単語が部分的に補完され、補完候補が多い場合などはもう2回Tabを押すと補完候補が表示される。計3回も押す必要がある。
`show-all-if-ambiguous on`と設定すると、1回Tabを押すだけで全候補表示まで行う。

#### (3) `completion-query-items 0`

補完候補が多い場合に全て表示するかどうか毎回質問される。この機能をOffする。
```
$ ls /etc/
Display all 217 possibilities? (y or n)
```


#### (4) `page-completions off`
bashのデフォルトでは補完候補が多いときに1pageで表示しきれないためpagerで開こうとする。この機能をOffする。

```bash
$ ls /sbin/
ModemManager                 fsck.btrfs                   mke2fs                       swaplabel
NetworkManager               fsck.cramfs                  mkfs                         swapoff
aa-remove-unknown            fsck.ext2                    mkfs.bfs                     swapon
aa-status                    fsck.ext3                    mkfs.btrfs                   switch_root
aa-teardown                  fsck.ext4                    mkfs.cramfs                  sysctl
accessdb                     fsck.fat                     mkfs.ext2                    tarcat
add-shell                    fsck.minix                   mkfs.ext3                    tc
--More--
```
自動で`more`コマンドが適用されてQを押して閉じるのが鬱陶しかったりする

### ちなみに
- zshを使えばこんな細かい設定を調べたりしなくても大体全て解決する気がしている

### 参考：

https://wiki.archlinux.jp/index.php/Readline
Webページが表示されているかを判定

ユーザーにページが表示されているかを判定するPage Visibility APIのメモ。
主に、使用用途としては、ユーザーがページを場合に、動画や重たいアニメーションの再生を停止したい時などに使用する。
プロパティは`Document.hidden`もしくは`Document.visibilityState`があり、イベントの`Document.onvisibilitychange`で処理する。

```js 
const video = document.getElementById('video');
document.addEventListener('visibilitychange', function () {
  console.log(document.visibilityState);
  //コンソールにはhiddenとvisibleが表示される。
  console.log(document.hidden);
  //コンソールにはtrueとfalseが表示される。

  if (document.hidden) {
    console.log('動画は一時停止します。');
    video.pause();
  } else {
    console.log('再生します。');
    video.play();
  }
});
```
ユーザが別のタブに切り替えたり、最小化したりすると実行する。タブを横に並べた場合、そちらにフォーカスしても、実行せず、モニターに映っているかどうかを判定している。

余談ですが、動画って`video.play()`単体では再生できないですね。最初にユーザーに再生してもらう必要があります。
#### 参考

https://gray-code.com/javascript/get-visibility-status-of-page/
Swiftで標準入力から配列を受け取る方法と昇順と降順ソートをする方法。

# 学んだこと
・標準入力で与えられる整数の配列を受け取る方法。
・初期化した配列に標準入力から受け取った整数の配列をappend()を使って追加すること。
・昇順と降順について
・降順ソートはsort { $0 > $1 }でできる。
・昇順ソートはsort { $0 < $1 }でできる。

# 昇順と降順について
<b>参考にした記事</b>

https://www.pc-master.jp/words/shojyun-kojyun.html

# 降順ソートはsort { $0 > $1 }でできる。
<b>参考にした問題</b>

https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_std_in_out_step4

<b>参考にした記事</b>

https://swift.tecc0.com/?p=240
```swift
var number = Int(readLine()!)!
print(number)

// 標準入力から配列を受け取りたいから配列の初期化をする。
var arrSort = [Int]()
for _ in 0..<number {
    // 標準入力で受け取った値arrに代入する。
    let arr = Int(readLine()!)!
    print(arr)
    // 標準入力で受け取った値arrをappend()関数を利用してarrSort配列に追加する
    arrSort.append(arr)
    print(arrSort)
}
// { $0 > $1 }が降順を命令している
arrSort.sort { $0 > $1 }
print(arrSort)
print(arrSort[0])
```
<b>標準入力</b>
```
2
4
7
```
<b>出力結果</b>
```
2
4
[4]
7
[4, 7]
[7, 4]
7
```

# 昇順ソートはsort { $0 < $1 }でできる。
(参考にした問題を忘れたので思い出したら入力例と出力例を追記する)
```swift
var numbers = [Int]()
for _ in 1...5 {
    let intNums = Int(readLine()!)!
    // print(intNums) 
    numbers.append(intNums)
    // print(numbers) 
}
// print(numbers) 
// { $0 < $1 }が昇順ソートを命令している
numbers.sort { $0 < $1 }
// print(numbers) 
print(numbers[0])  
```
OS認証方法

どうやってLinuxにおいて
OS認証を可能にしているんだろうか。

https://github.com/phokz/pwauth/blob/master/pwauth/auth_pam.c

どうも
pam_startみたい。

https://nxmnpg.lemoda.net/ja/3/pam_start



https://ihag.hatenadiary.org/entry/20080617/p1
Xerox Star 8010 Dandelionのエミュレータ Darkstarで、ViewPointを動かす


# Xerox Star 8010 Dandelionのエミュレータ Darkstarで、ViewPointを動かす
- 2023-0826 Created By Shigenobu Koufugata(fox@inforle.com)
- 2023-0827 Updated By Shigenobu Koufugata(fox@inforle.com)

## はじめに
- Xerox Starとは  
  Xerox PARCで開発されたAltoの研究を使って、Xeroxが開発したオフィスネットワークシステムの名称です。特徴等については、後述、参考URLのWikipedia - Xerox Star をご覧ください。
- Xerox Star 8010 "Dandelion"とは  
  1981年にXeroxからStarワークステーションとして発売された製品の名称。Dandelionは、Xerox社内のプロジェクトコードであり、一連のStarシステムは、"D"で始まるプロジェクトコードを与えられたので、D-マシンと呼ばれる。
- Darkstarとは  
  Xerox Star 8010 "Dandelion"のハードウェアの実行を現代のOSでエミュレートするためのエミュレータ・ソフトウェア。OSSであり、今回紹介するViewPoint（Starデスクトップシステム）や、開発環境であるXDE（Xerox Develop Environment）、Interlisp-Dなどを実行することが出来る。ライセンスは、「BSD-2-Clause license」。

## 前提条件
- Microsoft Windows 10 （22H2以降）でテストしました
- ※ Microsoft Windows 10（22H2以前）、Microsoft Windows 11についてはテストしていません

## インストーラーを入手する
- 次のURLから、Webブラウザーを使って、ファイル「DarkstarSetupWindows.zip」を入手する  
  ```https://github.com/livingcomputermuseum/Darkstar/releases ```
- 適当なフォルダーに保存しておく（ここでは、D:\\inforle2023\\03_development\\06_inforle\\02_Darkstar　とする）
- DarkstarSetupWindows.zipを展開する（右クリックで、すべて展開を選択）
- DarkstarSetupWindowsフォルダーが作成されるので、ダブルクリックで開く
- DarkstarSetupWindows.msiが現れる

## インストーラーを起動する
- DarkstarSetupWindows.msi をダブルクリックで起動する
- ダイアログが開くので、適切なフォルダーを指定してインストールする

## ディスクイメージのダウンロード
- 次のURLから、Webブラウザーを使って、ファイル「8010_hd_images.zip」をダウンロードする  
  ```http://www.bitsavers.org/bits/Xerox/8010/ ```
- 適当なフォルダーに保存しておく（ここでは、D:\\inforle2023\\03_development\\06_inforle\\02_Darkstar とする）
- 8010_hd_images.zip.zipを展開する（右クリックで、すべて展開を選択）

## DarkStar.exeの起動
- DarkStarのインストール先（ここではD:\\ProgramFiles\\Darkstar とする）から、DarkStar.exeを起動する
- しばらくすると、DarkStarのスクリーンが開くので、「System」メニューの「Hard Disk」から「Load...」を選択する
- 先程ダウンロードして、展開したディスクイメージから「ViewPoint-2.0-11-9-1990-18-38.img」を選択する
- DarkStarスクリーンの「System」メニューから「Start」を選択する
- しばらく待つ。左下のMPコードが0000からカウントアップするので、しばらくまつ  
→ 時刻の設定画面となるので、適当に時刻を設定する  
→ ここは、1-Dec-97にすると良いらしい（後ほど、ViewPointのSoftware Optionで必要になる。時刻は対して重要ではない。）  
- またしばらくまつ　MPコードが0000から8000までカウントアップするんのでしばらくまつ

## ブートアップを待つ
- しばらくかかります

## ムービングキーボードになったら、デスクトップの作成
- ブートアップが終わったら、ムービングキーボード画面になります。
- ここで、マウスをスクリーンに移動してクリックすると、デスクトップを作成することが出来ます。
- デスクトップ作成には、「fox:inforle:xerox」のように、コロン区切りで3カラムを指定する必要があります。
- デスクトップを作成したら、ログインです。

## ログイン
- 先程作成した、ユーザーアカウントを使って、ログインします。

## デスクトップ操作
- ここからは、VP（ViewPoint）の環境になります。
- マニュアルは下記のURLから、ダウンロードしてください（英語版になります）。  
  ```http://www.bitsavers.org/pdf/xerox/viewpoint/VP_2.0/```

## システムの終了
- デスクトップの上端にあるステータスバーの上でクリックするとシステムメニューが表示されます。
- この中で「End Session」を選択するとダイアログが表示されます。
- ダイアログで、「POWER OFF QUICK RESTART」を選択します。
- 上端にあるステータスバーに、「CAUTION!...|YES|」のメッセージが出ますので「YES」に合わせてクリックします。
- ダイアログの「Start」をクリックします。
- MPコードが、938もしくは939になるので、Darkstarの「System」メニューから「Exit」を選択して終了です。」

## 参考URL
- Xerox Star 8010エミュレータ「Darkstar」を試してみた。ViewPoint、XDEが開く。（DarkstarSetupWindows.msi）  
```https://2ndart.hatenablog.com/entry/2022/03/19/144643```

- Wikipedia - Xerox Star  
```https://ja.wikipedia.org/wiki/Xerox_Star```

- Github - Darkstar  
```https://github.com/livingcomputermuseum/Darkstar ```
【Unity】複数のOS上でWebGLアプリの動画を再生できるようにする

# はじめに
WebGLアプリで利用するOSやブラウザによって再生可能な動画形式が異なるため、適当な動画ファイルを再生すると以下の画像の様に動画が再生されないことがあるため、最適な動画形式とその動画形式への変換方法を調べてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/a2018272-903b-3551-adf4-1d5cb266fd66.png)


# 調査結果
Unity製WebGLアプリ上でVideoコンポーネントの動作を実機調査した結果

* 走査方式インターレース全般
    * iOS-Safariで再生不可
* MPEG-4
    * Windows-Chrome , Android-Chromeでは再生不可

→`H.264 且つ プログレッシブ方式` だと問題なさそう

参考にしたサイト

https://zenn.dev/futa/articles/8cf0f84eadc910400b02

# 動画形式変換方法


本項ではコマンドライン上で`ffmpeg`を使って`H.264 且つ プログレッシブ方式`に変換する方法で説明します。
(色々GUI付きのアプリを試しましたが良い感じのものが見つかりませんでした。)

* インストール方法

以下を参考にインストールする。

https://jp.videoproc.com/edit-convert/ffmpeg-guide-for-beginners.htm

* 変換実行

コマンドライン上で以下のコマンドを実行する

```
ffmpeg -i input.mp4 -vf "yadif" -c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p -preset medium -crf 22 -c:a aac -b:a 128k -movflags +faststart output.mp4
```

:::note info
### 各オプションの説明
必要に応じて任意の設定に変更してみて下さい。

-i input.mp4: 入力ファイル名
-vf "yadif": インタレース解除
-c:v libx264: H.264ビデオコーデッ
-profile:v high: H.264の高プロファイルを使用する。
-level 4.0: H.264のレベル4.0を使用する。
-pix_fmt yuv420p: YUV 4:2:0ピクセルフォーマットを使用する。
-preset medium: エンコード速度と品質のバランスを取るためのプリセット。他のオプションにはslow、fasterなどがあります。
-crf 22: Constant Rate Factor（CRF）は、ビデオの品質を制御する値です。値が小さいほど品質が高く、ファイルサイズも大きくなります。一般的な範囲は18-28で、22は中間的な値です。
-c:a aac: AACオーディオコーデックを使用する。
-b:a 128k: オーディオビットレートを128 kbpsに設定します。
-movflags +faststart: このフラグにより、ビデオがWeb上での再生を開始する前に完全にダウンロードする必要がなくなります。
:::

以上
WSL(Ubuntu)に.NET SDK 7.0をインストールしてハマった

# ハマったこと

- WSL2上のUbuntu 22.04では通常のリポジトリに.NET SDK 7.0が含まれないためMicrosoftパッケージリポジトリからインストールする必要がある
- Microsoftパッケージリポジトリからインストールしたがdotnet --infoコマンドを実行してもSDKがインストールされていないと表示される
- 実はディストリビューションのリポジトリからのインストールと重複していたため、Microsoftパッケージリポジトリからのインストール優先度を下げて再インストールした

```sh
.NET SDKs installed:
  No SDKs were found.

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.10 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.10 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]
```

# インストール手順

## Microsoftパッケージリポジトリの追加

```sh
# Get Ubuntu version
declare repo_version=$(if command -v lsb_release &> /dev/null; then lsb_release -r -s; else grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"'; fi)

# Download Microsoft signing key and repository
wget https://packages.microsoft.com/config/ubuntu/$repo_version/packages-microsoft-prod.deb -O packages-microsoft-prod.deb

# Install Microsoft signing key and repository
sudo dpkg -i packages-microsoft-prod.deb

# Clean up
rm packages-microsoft-prod.deb

# Update packages
sudo apt update
```

## .NET SDK 7.0 のインストール

```sh
# Install SDK 7.0
sudo apt install dotnet-sdk-7.0

# Display .NET command information
dotnet --info
```

ここで以下のように「No SDKs were found.」と表示されていたら、正しくインストールされていないので

```sh
.NET SDKs installed:
  No SDKs were found.
```

## リポジトリ優先度を設定して再インストール

```sh
# Uninstall .NET libraries
sudo apt remove 'dotnet*' 'aspnet*' 'netstandard*'

# Add priority
sudo tee /etc/apt/preferences << EOF > /dev/null
Package: dotnet* aspnet* netstandard*
Pin: origin "packages.microsoft.com"
Pin-Priority: -10
EOF

# Update packages
sudo apt update

# Install SDK 7.0
sudo apt install dotnet-sdk-7.0
```

# インストール結果

成功したら以下のように.NET SDKs installedに7.0が表示される

```sh
.NET SDKs installed:
  7.0.110 [/usr/lib/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.10 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.10 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]
```

# 参考

https://learn.microsoft.com/ja-jp/dotnet/core/install/linux?WT.mc_id=dotnet-35129-website

https://learn.microsoft.com/ja-jp/dotnet/core/install/linux-ubuntu

https://learn.microsoft.com/ja-jp/dotnet/core/install/linux-package-mixup?pivots=os-linux-ubuntu#solutions
DeviseTokenAuthでCookieを使用する方法【Rails】


## DeviseTokenAuthの設定を変更する

認証トークンの送受信にCookieを使用するために`cookie_enabled`を`true`にします。
`cookie`に関する設定は`cookie_attributes`に記述します。
設定項目については以下を参照してください。

https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html

```rb:devise_token_auth.rb
DeviseTokenAuth.setup do |config|
 # ...

  config.cookie_enabled = true

  config.cookie_attributes = {
    http_only: true,
    secure: true,
    same_site: "None"
  }

 # ...
end
```

`cookie_attributes`に`expires`を設定するとサーバー起動時に設定されてしまうため、`set_cookie`の処理を変更してヘッダーの`expiry`の値が設定されるようにする必要があります。

https://github.com/lynndylanhurley/devise_token_auth/issues/1541

## cookiesを使用可能にする
APIモードではcookiesが使用できないため、使用可能にするために`application_controller.rb`に以下を追記します。


```rb:application_controller.rb
class ApplicationController < ActionController::API
  include ActionController::Cookies

# ...
end
```

https://github.com/lynndylanhurley/devise_token_auth/issues/1538

## フロントエンドの`fetch`を変更する

フロントエンドで`fetch`の処理に`credentials: 'include',`を以下のように追加します。

```js
export async function login({ email, password }) {
  try {
    const res = await fetch(
      `${process.env.NEXT_PUBLIC_API_BASE_URL}/v1/auth/sign_in`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          email,
          password,
        }),
        credentials: 'include',
      }
    )
// ...

```

## 参考

https://github.com/lynndylanhurley/devise_token_auth/issues/1281

https://github.com/lynndylanhurley/devise_token_auth/blob/master/docs/config/initialization.md


https://github.com/lynndylanhurley/devise_token_auth/pull/1453
【備忘録】Prisma+NextJSでクエリパラメータからユーザー情報を表示する

# コード本文

```tsx
import {NextRequest,NextResponse} from "next/server";
import {PrismaClient} from "@prisma/client";

const prisma = new PrismaClient();

export default function User({user}) {
    return (
        <div>
            <p>{user.name}</p>
            <p>{user.email}</p>
        </div>
    )
}
export async function getServerSideProps({params}: {params: {id: string}}) {
    const user = await prisma.user.findUnique({
        where: {
            id: Number(params.id)
        }
    });
    return {
        props: {
            user
        }
    }
}

```

# クエリパラメータとWhere文の型について

Whereの方に関しては人によりけりなんですが、この場合idのスキーマの型がIntとなっているため、コードもNumner()で囲むなど工夫が必要です。

ただクエリパラメータはStringで受け取るため工夫が必要です。
HSTS アクティベーションを成功させるためのプラグイン

HSTS アクティベーションを成功させるために、役に立つ TYPO3 と WordPress プラグインを紹介したいと思います。

注: プラグインをインストールして有効化する前、または Web サイトに変更を加える前に、必ずバックアップを作成することが非常に重要です。 この簡単な手順により、何か問題が発生した場合に多くの手間を省くことができます。

エラー メッセージや、最悪の場合、完全に真っ白なページに満足するウェブマスターはいません。 定期的にバックアップを作成しておくと、問題が発生した場合にサイトの動作バージョンにすぐに戻すことができます。

![sixt-HSTS--Ergebnis.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539422/5281c710-3362-cac4-399f-74391fe556c3.jpeg)

もう 1 つのヒント: Web サイトにプラグインをインストールする前に、プラグインを徹底的に調査し、慎重にテストすることをお勧めします。 HSTS プラグインは重要なセキュリティ機能に影響を与えるため、これは特に当てはまります。

HSTS アクティベーションに関して特定の懸念事項や特別な要件がある場合は、経験豊富な Web 開発者またはセキュリティの専門家に相談することをお勧めします。 これらは、お客様固有のニーズやセキュリティ上の懸念を満たす正しい決定を下すのに役立ちます。

![somsak-HSTS-Submit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539422/50378b73-91e1-d798-130f-61b4101c111e.jpeg)

![somsak-seo-spezialist.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3539422/81dfbedf-4312-53cf-4c01-e2720dea7f63.jpeg)


HSTS を有効にするための WordPress プラグインと拡張機能

HSTS (HTTP Strict Transport Security) の有効化に役立つ WordPress プラグインがいくつかあります。


本当にシンプルなSSL

この WordPress プラグインを使用すると、Web サイトで HSTS (HTTP Strict Transport Security) を簡単に有効にすることができます。 これにより、すべての接続が HTTPS 経由で確立されることが保証され、さらに HSTS ヘッダーを追加する可能性も提供されます。 HSTS を有効にすると、すべてのトラフィックが暗号化された接続を介して送信されるため、Web サイトのセキュリティが向上します。 プラグインを使用するとプロセスが簡素化され、技術的なノウハウがなくてもこの重要なセキュリティ機能を実装できるようになります。


WP 強制 SSL および HTTPS SSL リダイレクト

このプラグインを使用すると、すべての HTTP URL を HTTPS に自動的に変換することで、Web サイトに SSL 暗号化を簡単に適用できます。 これにより、Web サイトへのすべての接続が確実に暗号化され、より高いレベルのセキュリティが提供されます。

さらに、プラグインはセキュリティをさらに強化するために HSTS ヘッダーを追加する可能性を提供します。 この機能は、安全な HTTPS 接続を介してのみ Web サイトにアクセスするように Web ブラウザに指示します。

このプラグインを使用すると、SSL 暗号化を簡単に実装し、暗号化されていない接続から Web サイトを保護できます。


簡単なHTTPSリダイレクト(SSL)

このプラグインを使用すると、Web サイトのすべてのトラフィックを HTTP から HTTPS に簡単にリダイレクトできます。 これにより、Web サイトへのすべての接続が確実に暗号化され、より高いレベルのセキュリティが提供されます。

このプラグインでは、HSTS ヘッダーを追加することもできます。 これにより、Web ブラウザは安全な HTTPS 接続経由でのみ Web サイトにアクセスするように指示されます。 さらに、プラグインを使用して HSTS プリロード機能を有効にすることができます。これにより、Web サイトが一般的なブラウザの HSTS プリロード リストに追加されます。 これにより、Web サイトはデフォルトで HTTPS 経由でアクセスされるようになります。

したがって、このプラグインを使用すると、HTTPS へのリダイレクトを簡素化できるだけでなく、HSTS ヘッダーと HSTS プリロード機能を有効にして Web サイトのセキュリティを向上させることもできます。


ヘッダー セキュリティ アドバンストおよび HSTS WP

このプラグインを使用すると、HSTS プリロード リストに合わせて WordPress Web サイトを最適に準備できます。

構成を包括的にレビューして、必要な要件がすべて満たされていることを確認します。

このプラグインは、考えられる改善を実装する方法に関する貴重な推奨事項や指示も提供します。 これにより、Web サイトが HSTS プリロード リストに含まれる基準を満たしていることを確認できます。

このプラグインを使用すると、Web サイトのセキュリティを強化し、ユーザーの信頼を得るのに役立つ信頼できるアシスタントがそばにいます。

このプラグインの機能を使用して、可能な限り最善の方法で HSTS プリロード リスト用に Web サイトを準備し、安全な HTTPS 接続の利点を活用します。

セキュリティヘッダー

この多用途プラグインは、HSTS ヘッダーを含む Web サイト上のセキュリティ ヘッダーを管理するための包括的な方法を提供します。 HSTS 用に特別に設計されたものではありませんが、HSTS ヘッダーを構成およびカスタマイズするためのシンプルで効果的なソリューションを提供します。

このプラグインを使用すると、必要な設定を行うことができます

Somsak Döppers (ドイツ、デュイスブルク出身の SEO スペシャリスト) が執筆しました。

ソース: https://somsak.de/plugins-fuer-eine-erfolgreiche-hsts-aktivierung/
LibreOffice マクロを Ubuntu + Basic で作る




「LibreOffice マクロを Ubuntu + Python で作る」
https://qiita.com/nanbuwks/items/77d5707b9a2507972676

との比較で、同じことを Basic でやってみます。


# 環境

- Ubuntu 22.04 LTS
- LibreOffice Ubuntu package version: 1:7.3.7-0ubuntu0.22.04.3

# IDE を開く

今回は、Calc 上で作業を行います。
「ツール」-「マクロ」-「マクロの編集」で IDE が呼び出せます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d60d58aa-4081-f334-6c24-54000895bf7c.png)




# サンプルプログラム

Pythonと同じように、Calc のセルA1にメッセージを表示してみます。
先程のIDEそのまま、「Standard」の「Module1」に以下のように書いていきます。


```
REM  *****  BASIC  *****

Sub Main
Dim Doc As Object
Dim Sheet As Object
Dim Cell As Object
Dim ShadowFormat As New com.sun.star.table.ShadowFormat

Doc = ThisComponent
Sheet = Doc.Sheets(0)
Cell = Sheet.getCellByPosition(0,0)

Cell.String = " HelloWorldBasic"
End Sub
```

緑のプレイボタンで実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9cbc507b-c44a-6d72-8774-4345f1625388.png)

無事実行できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ea2a4b89-806d-a2d2-e00c-f8f2143175fe.png)


# 保管場所

IDEで作ったものは、以下の場所にあるようです。

```
~/.config/libreoffice/4/user/basic$ tree

├── Standard
│   ├── Module1.xba
│   ├── dialog.xlb
│   └── script.xlb
├── dialog.xlc
└── script.xlc
```


作ったものは「ツール」-「マクロ」-「マクロを実行」で、以下のように呼び出せます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c1dbd5e0-1592-1f07-37c0-39c584331fd0.png)
Packer.nvimにプラグインを追加する方法を忘れたので備忘録

# 概要
Packer.nvimにプラグインを追加する方法を忘れました。昨日勉強したのに！
もう忘れません

# やったこと
Comment.nvimを例に書きます。

https://github.com/numToStr/Comment.nvim

# Quick
`plugins.lua`に`use..`で始まるpluginを追加 
-> configのファイルに　`require("hoge").setup{}`
->`init.lua`に`require('config')`

# luafile
## plugins.lua

あろうことか、`plugins.lua`に追加するのを忘れていました。
```plugins.lua
return require('packer').startup(function(use)
	-- Configurations will go here
	---require('Comment').setup()
	use {
    		'numToStr/Comment.nvim',
    		config = function()
        	require('Comment').setup()
		end
	}
end)
```

## commentout.lua

最後は`{}` です。
```commentout.lua
--enable comment
require("Comment").setup{}
```

## init.lua

```init.lua
require('commentout')
```

## luafile %
```luafile %```を忘れずに。

記憶力悪すぎるけど記事書けたのでヨシ！
8.26

# 今日の日記メモ

Railsの環境作成に挑む
cmd+shift+. ホームディレクトリでのファイルを出す


https://chikinmasa.org/ruby_install/\

試した
```
x21024xx@x21024xxnoAir ~ % echo $SHELL
/bin/zsh
x21024xx@x21024xxnoAir ~ % echo ‘eval “$(rbenv init -)”’ >> ~/.zshrc
x21024xx@x21024xxnoAir ~ % source ~/.zshrc
/Users/x21024xx/.zshrc:1: parse error near `then'
x21024xx@x21024xxnoAir ~ % 
```
なぜか echo ‘eval “$(rbenv init -)”’ >> ~/.zshrc　が上手くいかない
↓　.zshenv　の中身 

```
‘eval “export PATH="/Users/x21024xx/.rbenv/shims:${PATH}" export RBENV_SHELL=zsh source '/opt/homebrew/Cellar/rbenv/1.2.0/libexec/../completions/rbenv.zsh' command rbenv rehash 2>/dev/null rbenv() { local command command="${1:-}" if [ "$#" -gt 0 ]; then shift fi case "$command" in rehash|shell) eval "$(rbenv "sh-$command" "$@")";; *) command rbenv "$command" "$@";; esac }”’
```

### chatgptに聞いた方法もだめ

掲示板かなんかで聞いてみようかな
Linux用 動的トレーサ " ply"の環境構築

# plyとは

eBPFをスクリプト形式で扱えるものになります。
軽量なツールのため、組み込みデバイスで活躍しそうです。

https://wkz.github.io/ply/



# 現在の環境

```
uname -a
Linux hoge 5.4.0-156-generic #173-Ubuntu SMP Tue Jul 11 07:25:22 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"

```
# 環境構築

```
$ sudo apt update
$ sudo apt-get install autoconf
$ sudo apt-get  install libtool

$ git clone https://github.com/iovisor/ply.git

$ cd ply 

$ ./autogen.sh   
$ ./configure
$ make
$ sudo make install

```

# 実行確認

```
$ ply
error: no input
ply - Dynamic tracing utility

Usage:
  ply [options] <ply-text>
  ply [options] <ply-file>

Options:
  -c COMMAND     Run COMMAND in a shell, exit upon completion.
  -d             Enable debug output.
  -e             Exit after compiling.
  -h             Print usage message and exit.
  -k             Keep going in face of trace buffer overruns.
  -S             Show generated BPF.
  -T             Run self-test.
  -v             Print version information.

```

# エラーが出た場合
```
$ ply
ply: error while loading shared libraries: libply.so.0: cannot open shared object file: No such file or directory
```
もしこのようなエラーが出た場合、パスを指定すると実行できます。

```
$ sudo su
# find / -name libply.so.0

/root/ply/src/libply/.libs/libply.so.0
/usr/local/lib/libply.so.0
```
```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

# find / -name libply.so.0
/home/hoge/ply/src/libply/.libs/libply.so.0
/root/ply/src/libply/.libs/libply.so.0
/usr/local/lib/libply.so.0
```

# 最後に

日本語のドキュメントがなかったので、簡単なエラーの対処法とともに、備忘録として載せておきます。
Railsで、Datetime型に対するタイムゾーン無表記+Rspecテストの記述方法

## はじめに
タスク管理アプリを作成する際、日付と時間を入力するため、datetime_fieldを使用した。
しかし、表記にすると謎の+0900が後付けされるわ、Rspecテストでこの場合どうやって入力値を打ち込むんだ？　と混乱した経緯があったので、調べて試してみた。

※Railsに触り始めて１ヶ月ほどほどぐらいの健忘録みたいなものです。生優しい目でご覧ください。

## 開発環境
Rails 6.1.7.4
ruby 3.0.1

### ＋０９００の数字は何？
UTC（協定世界時）、世界各地の標準時を決める基準。日本の標準時は、UTCより９時間進んでいるため、+0900と表示される。
datetime_fieldで取得した情報をそのまま表示すると下記のようになる。
![スクリーンショット 2023-08-21 23.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508102/0cb347eb-cd6a-35bb-e67b-2bfdcae2a08d.png)

正直、この状態になるまで気にしたこともなかった（自分は）ぐらいなので、普段どれぐらいの人が気にしているかわからないこの表記はしなくてもいいだろう・・・と結論に至る。

## 表示変換方法

- strftimeメソッド
> 公式リファレンス
strftime(format) -> String
時刻を format 文字列に従って文字列に変換した結果を返します。

今回は例としてタスク管理の終了期限を表示させるものとしています。

表示を変えたいデータ.strftime(させたい表示形式）
```ruby
task.end_time.strftime('%Y-%m-%d %H:%M:%S')
```
上記だと、%Y(西暦),%m(月２桁）,%d(日2桁),
%H(時　２４時間表記）,%M(分2桁),%S(秒2桁)となる。

しかし、これだと表記毎に後付けしないといけない！
そうだ、メソッド化しよう。Don't Repeat Yourselfだ！（小並感）

<hr>

- メソッド化（最初に言っておきますが、全然DRYになってなかった）

format_datetimeというメソッドを定義

**app/helpers/application_helper.rb**
```ruby
module ApplicationHelper
  def format_datetime(datetime)
    datetime.strftime('%Y-%m-%d %H:%M:%S')
  end
end
```

実際に使用してみる ()内に変換したいデータ名
```ruby
format_datetime(end_time)
```

helper含めたら記述量ふえてませんか？（思わず自分に聞いてしまった）　YES！


## 失敗から模索

他にいい方法はないか？（楽できないか）と更に模索。
 I18nのpublic APIというものを発見する。ちなみに下記記述前提です。

- 日本語化前提

日本語化方法はこの記事の本質じゃないので、記述のみで説明は割愛します。
**app/config/locales/ja.yaml**
```ruby
time:
    am: 午前
    formats:
      default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      long: "%Y/%m/%d %H:%M"
      short: "%m/%d %H:%M"
```
**app/config/initializers/locale.rb**
```ruby
I18n.config.available_locales = :ja
I18n.default_locale = :ja
```
**app/config/application.rb**
```ruby
config.time_zone = 'Tokyo'
```

## 救世主　lメソッド
- l　メソッド
Railsガイドより
> I18n APIで最も重要なメソッドを以下に示します。
localize  # DateオブジェクトやTimeオブジェクトを現地のフォーマットに変換する

lはlocalizeの略のようです。
このメソッドを利用すると・・・

```rb
<%= l task.end_time %>
```

かなりの簡略化ができている！

**結局事前準備や記述多いよね？って思ったそこのあなた!**
もともと日本語対応させるために必要だった記述なので、無駄な記述を増やした訳でないのですよ（現状）　自分でメソッド化したの無駄って言っちゃったよ。。。

ちなみに
"%Y年%m月%d日(%a) %H時%M分%S秒 %z"
**%zがタイムゾーンなので、それを削除すれば+0900が非表示になります！**
![スクリーンショット 2023-08-22 11.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508102/69eb9c44-1a92-c2a6-4847-52a0cadbfe7b.png)


## Rspecテストでの記述方法
もう一つ沼りかけたので記載

datetime_fieldを使用すると、こんな感じの入力になります。
![スクリーンショット 2023-08-22 11.11.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508102/c7ab5f5e-6641-520e-9122-60965aa0cdf4.png)

これテストの時どう記述するの？　ぽちぽちするからclickとか使うのか？？と自力で色々試しても通過せず。色々調べて下記記述に落ち着きました。

**テストにfill_inで記述する場合** 
fill_in "入力欄タイトルとか", with: '設定したい時間'
```rb
fill_in "終了期限", with: '002023-09-01T00:00'
```
**FactoryBotに記述する場合**　
カラム名 {'設定したい時間'}
```rb
end_time { '002023-8-15T00:00'}
```

00が頭に必要ということと、時間表記の前にTが必要でした。
そりゃ通らないわ。

## まとめ
こうゆうのがあったら便利だな、と思うメソッドなどは大体存在しているという言葉を、今回の結果で思い出す。知らないことは知らないんだから、どんどん探して、使ってみて、吸収していきたいと思う。
バグを生み出してしまう心理

遠い昔、多くのソフトウェアは速い動作が望まれ、遅いと罵られた。
今でも処理は速く終わったほうが良いが、昔ほどは罵られない。
昔は何もかも遅くて、ユーザーは待たされるのもので、常にイライラしてるものだった。
そういう背景もあり、中には無茶な高速化を施してしまった例もあったようだが、そういうのは避けたいという話だ。
自分がソースコードを見たわけではないので正確ではないかもしれないけど・・・。

Win32 APIにGetProcAddress()がある。
DLLが抱える関数のアドレスを取得する関数である。
引数に関数名の文字列を与えると関数を探すのに少々時間がかかる。
引数に序数を与えると少々高速化できる。
そこだけ見れば「序数の方がいいじゃん。速いんだし。」となるが、注意すべき点がある。序数と関数の対応の互換性だ。
仮にDLLがアップデートしたとき、序数と関数の対応が必ず維持される仕組みはない。
一度設定した対応が未来永劫に強制されることはなく、変更は可能だ。関数を削除することもできる。
つまり、自分がDLLを制御できない場合、指定した序数で目的の関数をアドレスを取得できなくなるかもしれないわけだ。
「序数の方がいいじゃん。速いんだし。」は「自分がDLLを例外なく100%自由に制御できるなら序数の方がいいじゃん。速いんだし。」となるわけだ。
で、問題が発生するわけだ。
「序数の方がいいじゃん。速いんだし。」しか考えず、副作用を考えず、あろうことか他社のDLLに対して序数でGetProcAddress()してしまった例があったようだ。
それが、いわゆるDLL HELLの正体の一部ではないかな?
序数と関数の対応は互換性が維持されるポイントではないので、自分が制御できないなら序数よりも関数名文字列で指定するべきだろうし、関数が存在しない場合の対応も実装すべきだろう。

Windows 95の登場で、長いファイル名を使えるようになった。
互換性のために、ファイル作成時に「長いファイル名」と「長いファイル名から作った短いファイル名」が作成され、どちらでもアクセスできるような仕掛けが追加された。
「Program Files」には「PROGRA~1」でもアクセスできるわけだ。
これにより、長いファイル名を知らないWindows 3.1用アプリケーションでも「長いファイル名」で作られたファイルにアクセスできる。
それだけなら「めでたしめでたし」だが、後に状況が変わる。
「長いファイル名から作った短いファイル名の作成」は抑制できるのだが、一部で流行ってしまった。無駄な処理を省けるから、その分だけ高速化できるという触れ込みで。
で、問題が発覚するわけだ。
Windows 3.1用でもないのに、短いファイル名でアクセス時するアプリケーションがあった。
短いファイル名でアクセスしたほうが若干速いという話だったと記憶してる。
「長いファイル名から作った短いファイル名の作成」があるから問題ないよね? と考えたのかもしれないが、その仕組みは抑制できる。そして残念ながら流行ってしまった。
トラブルを避けるため、長いファイル名を扱えるなら常に長いファイル名でアクセスするべきだろう。

どちらの場合も、遅いと罵られ、遅いと罵られ、遅いと罵られ続けることによって、「速度こそ正義で犠牲を出しても構わない」という意識が芽生え、判断が鈍ったのだろうと思う。
でも、動かないソフトウェアには価値がない。どれだけ高速化しても動作しないのであれば何の意味もない。
できるだけ幅広く状況に応じて適切に判断することを心がけたいと思う。
【Swift】TCAで2つのActionを同時に実行する

# はじめに
TCAを使っていて同時にアクションを実行したい場面がありました。
やり方を知ったので記録しておきます。

# 実装
```diff_swift
import SwiftUI
import ComposableArchitecture

struct ContentView: View {
    @ObservedObject private var viewStore: ViewStoreOf<Feature>
    
    let store: StoreOf<Feature>
    
    init(store: StoreOf<Feature>) {
        self.store = store
        self.viewStore = ViewStore(store, observe: { $0 })
    }

    var body: some View {
        Button {
            viewStore.send(.buttonTapped)
        } label: {
            Text("テスト")
        }
    }
}

struct Feature: Reducer {
    struct State: Equatable {}

    enum Action: Equatable {
        case buttonTapped
        case printA
        case printB
    }
    
    func reduce(into state: inout State, action: Action) -> Effect<Action> {
        switch action {
        case .buttonTapped:
+           return .concatenate(.send(.printA), .send(.printB))
        case .printA:
            print("A")
            return .none
        case .printB:
            print("B")
            return .none
        }
    }
}
```

# おわり
TCAの知見ためていきたいです
Salesforce画面フロー応用編～画面フローでレコード作成後レコードリンクを表示しよう

こんにちは
本橋孝昭です

前回は画面フローの基本を動画や記事で紹介しました

https://youtu.be/QToa8tKTTkY

https://qiita.com/Takaa/items/9930f392c604cfdf2367

ただ、前回のこちらのフローでは取引先レコード作成後にその作成したレコードに遷移することはできません

今回は前回のフローに１手間かけて
「レコード作成後、作成したレコードURLを表示させ作成したレコードに遷移させる」
という方法を示します
ステップは以下２つです

# ステップ１　Salesforce環境のURLを把握しよう

# ステップ2 フロー修正し、最後に画面フローを追加してフローを有効化しよう


それではさっそく解説しましょう

# ステップ１　Salesforce環境のURLを把握しよう

まずはSalesforce環境のURLを把握しましょう

つまり
https://マイドメイン.force.com/lightning/r/オブジェクト名/

を把握することです

これは既存のSalesforce環境のレコードをみれば容易に把握できます
例えば今回新規作成したいレコードが「取引先」（Account）オブジェクトの場合、なんでもいいので取引先レコードを確認して以下のURL取得しましょう

![取引先1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/dd7f3200-3bd5-4f7e-a66b-7c51c4052be9.png)

例として私のデモ環境のURLは↑のように
https://mindful-unicorn-326r3a-dev-ed.trailblaze.lightning.force.com/lightning/r/Account/0015j000012lwezAAA/view

です。
なのでこの環境のマイドメインは
mindful-unicorn-326r3a-dev-ed.trailblaze.lightning
です。
今回は
https://mindful-unicorn-326r3a-dev-ed.trailblaze.lightning.force.com/lightning/r/Account/
をどこかにメモしましょう（あとでフロー修正に使います）

# ステップ2 フロー修正し、最後に画面フローを追加してフローを有効化しよう

フローを修正します
具体的にはレコード作成後の最後に画面フローを追加します

![０８フロー２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a25307b4-a9e5-242a-94f9-733d9f8d770a.png)

画面フローの中には画像のように「表示テキスト」というコンポーネントが下のほうにあるのでドラック&ドロップして追加して表示テキスト内にレコード作成が完了したことを意味するようなメッセージを入れてください
![０８フロー３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d0e232a5-dfed-1737-79c4-5e1cd0589d0f.png)

そして
リンクを作りたい文字をこのようにして下部のリンクマーク？をクリックします
![０８フロー４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/885746ad-1f5e-d16d-9af4-eafd055035ed.png)

リンクに貼るのはこのようなURLです

”https://mindful-unicorn-326r3a-dev-ed.trailblaze.lightning.force.com/lightning/r/Account/{!CreateAccount}/view

![０８フロー５.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9e01df62-62fb-e94d-69dc-3afbb1b9841b.png)

このリンクですが
https://mindful-unicorn-326r3a-dev-ed.trailblaze.lightning.force.com/lightning/r/Account/
部分は先ほどステップ１でメモした部分

{!CreateAccount}
はレコードを作成の要素の名です

![０８フロー６.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/42a88c74-30d2-83ad-95a1-fea0e400469f.png)


これでフロー修正は完了です
あとは保存と有効化を忘れずに。

実際にレコード作成をすると、
このようにリンクに遷移をする画面が登場します
（この「クリック」をクリックすると作成した取引先画面に遷移します）

![０８フロー７.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/078e5ba2-8a73-1e0c-f6eb-2c7ec81ef9a5.png)


お疲れさまでした！
DBMS(DataBase Management System)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/c61e1e6f-7514-1e41-25b4-205dcda1d073.png)
　DBMSは、データベース本体と利用者を仲介する仕組みです。利用者が指示したSQL文はDBMSによって処理され、結果が利用者に返却されます。また、データの整合性を確保するためのいコミットメント生業、同時実行制御といっ機構や、障害対策のための機構も備わっています。

１：ACID
　データベースを操作する一連の処理は、トランザクション単位で実行されます。例えば、口座Aから口座Bへ振り込み処理を考えます。
①口座Aから指定金額を出金する
②口座Bから指定金額を入金する
という２つの処理が、両方とも実行されなければなりません。①だけ実行され、②が実行されないということは許されません。②が実行されないのであれば、①も実行してはいけないのです。このように、①と②の処理は、一まとまりの仕事であり、分けて扱うことはできません。トランザクションとは、子にお用に、関連する一連の手順をまとめた単位です。
　ACIDは、トランザクションが持つべき特性を表しています。

「ACID」
①原子性：トランザクションは「すべてを実行する」か、「全く実行しない」かのどちらかである。”All or Nothing”である。

②一貫性：トランザクションの実行結果は、データベースの内容を矛盾させない。

③独立性、隔離性：並列同時に実行している他のトランザクションの影響を受けない。

④持続性、耐久性：正常終了したトランザクションの更新結果は、システム障害などで消失することはない。

「すべてを実行する」ことを、コミット（COMMIT）するといいます。「全く実行しない状態に戻す」ことをロールバック（ROLLBACK）すると言います。トランザクションは、必ず、コミットもしくはロールバックで終了しなくてはなりません。先の例では、振り込み処理確認画面で、振込を承認した場合は、
　　　　トランザクション開始（START TRANSACTION）
　①口座Aから指定金額を出金する。
　②口座Bから指定金額を入金する
”振り込み処理承認”　→ コミット（COMMIT）
のようにしてトランザクションを終了します。

一方、振り込み処理確認画面で振込をキャンセルした場合は、
トランザクション開始（START TRANSACTION）
　①口座Aから指定金額を出金する。
　②口座Bから指定金額を入金する
”振り込み処理承認”　→ ロールバック（ROLLBACK）
のようにしてトランザクションを終了します。ロールバックすると、①②で加えた変更は全て取り消されます。
【備忘録】strutsの仕組みが段々と分かってきたぞ✨

# はじめに
<p>新卒で弊社に入社し早4ヶ月。</p>
研修が終わり最初の案件に参画してから早2か月が経とうとしています。

現在の案件ではstrutsを使用しており、最初は訳も分からず時間を浪費するばかりでした。
作業を重ねるうちに段々と構造というか、仕組みというか…が分かってきたので備忘録として書き残します。

後から見返して、加筆修正していくつもりではあります！一応！
以下の内容は<a>https://qiita.com/ebichan_88/items/aaae17e72d068517f33f</a>を参考にしてます。

# 目次
1.構造
2.struts-config
3.jspファイル
4.処理するJavaファイル
5.データを扱うJavaファイル
6.値を格納したJava→jspに値を渡す
7.まとめ


# 構造
strutsは大きくわけて
<ul><strong>struts-config.xml</ul>
<ul><strong>画面に表示させるjspファイル</ul>
<ul><strong>実際に処理を行うjavaファイル</ul>
<ul><strong>データを格納するjavaファイル</ul>
を用いて一つの画面を作ってるようです。

# struts-config
struts-config.xmlは<strong>遷移先の画面と実行するメソッドを指定したもの</strong>です！
<p>(最初の数週間はこれを教えてもらっても「ぽかーん」って感じでした…)


```xml:sturuts-config.xml
<actioin
    path="/example.do"
    type="example_type"
    name="exampleForm"
    scope="request"
    varidate="true">
<set-propertty name="entity" value="entity:◯◯.◯◯◯.example#method" />
<forward name="success" path="index.jsp">
```

<p>ここで特に重要になるのは、<strong>path</strong>、<strong>set-property</strong>、<strong>forward</strong>です！

## path
pathはjsp等で指定された際に、このアクションが呼び出されるための印みたいなものです。（後述します。）

## set-property
set-propertyでは、処理を行うJavaファイルとメソッドを指定します。
<p>先ほどの例で行くとJavaファイルがexample.Javaになり、使用するメソッドはmethodになります。

## forward
forwardは遷移先の画面を指定します。
<p>name="success"が指定されてたら処理が成功したらpathの遷移する。
<div>name="fail"なら失敗したときの遷移先になるっぽいです。

# jspファイル
jspファイルではformとactionを用います。

```jsp:example_1.jsp
<html:form action="/example.do">
  ⋮
</html:form>
```
これで指定したactionを持つstruts-configが呼び出され、form内で入力した値が渡されます。

# 処理するJavaファイル

```xml:struts-config.xml
<set-propertty name="entity" value="entity:◯◯.◯◯◯.example#method" />
```
先ほどのstruts-configで指定されたJavaメソッドが呼び出されます。

```java:example.java
public example_data method(){
    example_data entity = new example_data();
    //色々処理する
    return entity;
}
```
ここで処理を行って最終的にデータを扱うクラスにそのデータをセットし、returnします。

# データを扱うJavaファイル
特にありません。データを格納するクラスです。オブジェクトを作っておきます

```java:example_data
public class example_data{
    private String ex_1;
    private String ex_2;
    //こんな感じ
    //コンストラクタ設定
    //ゲッター、セッター設定
}
```
先ほどの処理を行っているメソッドによって、このクラスに値がセットされます。

<h1>値を格納したJava→jspに値を渡す</h1>
データを格納したはいいものの、それをどうやってjspまで持ってきて表示させるんだ！
<p>3週間ぐらいそう思い続けてました…

やらないといけないことは、use-beanを指定してあげるということです。

```jsp:example
<jsp:useBean id="entity" scope="request" class="××.×××.example_data"/>
```
classにデータ格納したJavaクラスを指定してあげます。
すると、例えば
```jsp:example
<html:text name="entity" property="example_1">
```
これでuseBeenでentityに設定したデータクラスのexample_1というフィールドの値が表示されるようです。


# まとめ
以上のような処理を通して、1つの画面が表示されるまでいきます。
<p>   </p>
<p>struts-configが操縦桿
<div>Javaは処理を行うものと、データを格納するだけのもの
<div>そして表示するjsp

<p>
<p>こんな感じのイメージになります。<div>（自分的には分かりやすく書いたつもりなんでが、どうなんでしょうねぇ…）
<p>
<p>…これ、研修でやったMVCモデルとかいうやつじゃね？！ってなりました。
<p>ほんとに実際に手を動かして体験しないと理解できないこと多いですね。これからも精進です！
TextFormField のテンプレート作ってみた。


公式のパラメータで使いそうなやつをまとめただけ
めっちゃコメント書いたから説明なしで。
こうすると GrobalKey を使うとき面倒なんだよなぁ。。。

``` dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class TFFtemplate extends ConsumerStatefulWidget {
  const TFFtemplate({Key? key}) : super(key: key);

  @override
  TFFtemplateState createState() => TFFtemplateState();
}

class TFFtemplateState extends ConsumerState<TFFtemplate> {

  @override
  Widget build(BuildContext context) {

// parameter : ファイルを複製してべた書きでもOK
// -----------------------------------------------------------------------------
  // key   : 操作のためのキー（これだけProvider？）
    // 以下のように使う
    // これとほかにボタンを設置
    // onPressed に _key.currentState.save() とかく
    // これでボタンを押したときに onSave の内容が実施される
    // これ使わずに Riverpod に任せたほうが楽かも
    final _key = GlobalKey<FormState>();

    String _label        = "hahhahha----";     // form label
    String _placeholder  = "hah----";          // placeholder
  
// ここは固定値でOK
// -----------------------------------------------------------------------------
    // 通常時の枠線
    OutlineInputBorder _borderLine( String when ) {

      Color color = Colors.grey;
    
      if      ( when == "normal" ) { color = Colors.grey; }
      else if ( when == "error"  ) { color = Colors.red; }
    
      return OutlineInputBorder(
          borderSide: BorderSide(
            color: color,
            width: 1,
            style: BorderStyle.solid,
            ),
          borderRadius: const BorderRadius.all(
            Radius.circular(10)
          )
        );
    }

// main
// -----------------------------------------------------------------------------
    return  TextFormField(

    // key
      key: _key,

    // 検証モード
      // AutovalidateMode.disable           : 検証しない
      // AutovalidateMode.always            : 常に検証
      // AutovalidateMode.onUserInteraction : 行動を起こしたときに検証
      autovalidateMode: AutovalidateMode.always,

    // 検証内容
      validator:(value) {

        if      ( value == "" || value!.isEmpty ) { return null; }
        else if ( 20 < value.length )             { return "20文字以内で入力してください"; }

        return null;
      },

    // controller ??
      //controller: ,

    // 入力を許可するか？
      // true or false
      enabled: true,

    // 初期値( String? )
      initialValue: null,
    
    // 入力内容を隠すか（パスワード用）？ 
      obscureText: true,

    // 保存時の処理
      onSaved:(newValue) {
        debugPrint( newValue );
      },

    // 変更したときの処理
      onChanged: (value) {
        debugPrint( value );
      },

    // 装飾
      decoration: InputDecoration(

      // ラベル関係
        labelText : _label,
        labelStyle: TextStyle(),

      // プレースホルダー
        hintText: _placeholder,

      // 枠線
        // 通常時
        border      : _borderLine( "normal" ),
        // エラー時
        errorBorder : _borderLine( "error" ),

      ),

    );
  }
}

```
HTTP/Hostヘッダの調査用サーブレット

https://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#getServerPort--
```java:headers.java
package pkg;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Headers
 */
@WebServlet("/Headers")
public class Headers extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/html");
		response.setCharacterEncoding("utf-8");
		
		PrintWriter print = response.getWriter();

		// HttpリクエストのHostヘッダを取得（Hostヘッダがない場合はnull）
		String hostHdr = request.getHeader("Host");

		// HostヘッダをHostとPortに分割
		String[] aryHostValue = (hostHdr == null) ? null : hostHdr.split(":");

		// Host値を取得（Hostヘッダがない場合はnull）
		String host = (hostHdr == null) ? null : aryHostValue[0];
		// port値を取得
		String port;
		if(aryHostValue.length > 1) {
			port = aryHostValue[1];
		} else if (request.isSecure()) {
			// ポート番号省略かつhttps接続
			port = "443";
		} else {
			// ポート番号省略かつhttp接続
			port = "80";
		}

		if(host == null) {
			// ★Hostヘッダがない場合は 400(BatReqest）
			response.sendError(HttpServletResponse.SC_BAD_REQUEST);

		} else if(port.equals("443")) {
			// ★portが443番の場合は処理Aを実行			
		} else if(port.equals("80")) {
			// ★portが80番の場合は処理Bを実行
		} else {
			// ★portが上記以外は処理Cを実行
		}
		response.setStatus(HttpServletResponse.SC_OK);
		
		// 取得したHostヘッダの値を表示
		if(host == null) {
			print.append("Host header is not set.");
		} else {
			print.append("Host: ").append(host).append("</br>");
			print.append("Port: ").append(port).append("</br>");
		}
	}

}

```
WEBの基礎知識一覧

## はじめに
Webの基礎について自分用にメモを書いていきます。
Qiitaさん曰く目次は自動作成してくれるようなので、本記事の目次にはぱっと見何が書いてあるか確認ようで記述します。

## 目次
・LANとWAN
・IPアドレス
・URLとドメイン
・IPとドメインの関係
・DNSサーバ
・hostsファイル
・TCP/IP
・代表的なプロトコル
・WEB3層アーキテクチャ

## LANとWAN
・LAN
　→プライベートIPを使用しているネットワーク
・WAN
　→グローバルIPを使用し、プライベートIP同士を繋ぐネットワーク

## IPアドレス
・インターネット上で通信する端末が必ず持つ住所。
・IPv4とIPv6がある
　→IPv4枯渇とIPv6の登場
・プライベートIPとグローバルIPの２種類がある

## URLとドメイン
・URLの構成
　　http://www.example.com:80/webdev
　　→スキーム://ホスト.ドメイン:ポート/コンテキストパス
　　　　　　　　　　└ホスト+ドメイン(FQDN)
　　※FDQNをホスト、ドメインと呼ぶこともある

・ドメイン
　メリット①IPよりも覚えやすい
　メリット②サーバー引越しが簡単

## IPとドメインの関係
・一つのIPには複数のドメインが設定可能
・ドメインからIPへの変換の方法
　→名前解決（DNSサーバへ問い合わせを行う）
　例）クライアント　⇄　DNSサーバ
　　　クライアント「ドメインのIPを教えてください」
　　　DNSサーバ「はい。こちらがドメインのIPです」

## DNSサーバ
・階層によってそれぞれのレコードを管理している

## hostsファイル
・PC内に保持しているドメインとIPの紐付けファイル
・開発環境のサーバを追加するとき、チームで開発する時に使う時がある
・実際に編集【[こちら]でご確認ください】

[こちら]: https://qiita.com/krun/items/d22df129a1457fcd6cb3

## TCP/IP
・ネットワーク上でコンピューター同士が通信する際の手順や規格（プロトコル）の集合のこと

## 代表的なプロトコル
・HTTP
・FTP
・TCP/UDP

:::note info
詳しくはOSI参照モデルを利用
:::


## プロトコルとポート
・ポートはある程度の範囲で何を使うかが決められている
・WELL KNOWN PORT（あらかじめ割り当てが決まっている）
・REGISTERD PORT（事業者が使う）
・DYNAMIC PORT/PRIVATE PORT（個人で自由に使用可能）

## WEB3層アーキテクチャ
・一般的なWebサイトはクライアント・サーバー方式
・３層に分けて独立したモジュールとして設計するアプリケーション

## 最後に
より詳しい内容は基本的に調べる前提でメモしました。
CodeMafiaさんの動画で軽く説明してくれているので、Web開発に興味がある方は見てみるのも良いかもしれないです。


* * *
参考サイト
[【PHP, MYSQL, Apache】ガチで学びたい人のためのWEB開発の基礎(バックエンド編)](https://www.udemy.com/share/104AnW3@g--UsIppHYYomHCSuDYhhT0wShU7mg_NUbX_sb6qqgiaIzPskRakl48WaNFIGI1jzw==/)