OmniAICreator/Qiita-1.07M huggingface dataset:
ログローテーションとcronの設定

## 概要
今回、業務の中にて新規にログ取得のファイルの作成を行うにあたり、
ログローテーションの設定を行った。

その際に設定ファイルの中身（設定方法）について触れる機会もあったので、
そのアウトプットとして本項目を記載します。




## 要件
・新規にスクリプトを実装するにあたり、以下内容を併せて用意したい
　①スクリプト実行の中身がわかるログ
　②①のログの一年間保持する設定（その後は削除）
　③日次でスクリプトを定期実行させるための設定

## 実行環境
OS（ホスト）：MacOS 10.15.4　Darwin Kernel Version 19.4.0
OS（仮想）：Linux CentOS 7.9.2009

## 実装手順
要件満たすため、以下のような設定を実施していく。

　①スクリプト実行の中身がわかるログ
 　　→/var/log配下にスクリプト内容を出力するログファイルを用意
　②①のログの一年間保持する設定（その後は削除）
 　　→/etc/loglorate.d配下にログローテーションの設定ファイルを用意
　③日次でスクリプトを定期実行させるための設定
 　　→/etc/cron.d配下に用意したスクリプトを定期実行する設定ファイルを用意
   ※今回作成したスクリプトファイルの詳細については割愛

順々に実装の仕方とその中での技術的なまとめについて、記載していきます。

### ①スクリプト実行の中身がわかるログ
□ /var/log配下にスクリプト内容を出力するログファイルを用意する

今回、下記コマンドでログファイルを作成しました。
こちらに後述するcronの設定にて、スクリプト実行のログを残すようにします。

    # touch /var/log/[ファイル名]

### ②①のログの一年間保持する設定（その後は削除）
□ /etc/logrorate.d配下へログローテーションの設定ファイルを配置する

こちらも新規に設定ファイルを作成しました。
この設定により①のファイルが１ヶ月ごとに分かれ、1年だけ保持するようにしています。
→具体的には、１ヶ月でログの切替りを行い、12世代まで管理する設定

    # touch /etc/logrorate.d/[設定ファイル名]
    ~ファイル内設定後~
    # cat /etc/logrorate.d/[設定ファイル名]
    
       /var/log/[ファイル名]
        {
            create 0644
            mothly
            rotate 12
            start 1
            missingok
            shredscripts
            postrotate
                /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
            endscript
        }

上記、いくつか設定項目がありますが、肝になってくるのが、
・”create 0644”にてローテーション後、自動的に作成されるファイルの権限を指定
・”mothly”にてローテーションされる期間を指定
・”rotate 12”にて世代管理される数を指定
の3つとなり、要件に適した内容を実装するのに必要な設定となります。

※各設置値詳細は以下を参照

https://qiita.com/Esfahan/items/a8058f1eb593170855a1


### ③日次でスクリプトを定期実行させるための設定
□ /etc/cron.d配下に用意したスクリプトを定期実行する設定ファイルを用意する

最後にスクリプトを定期実行するための設定を行います。
また、設定ファイル内にて①で作成したファイルへ、実行内容を出力するように指定をしてあげます。

    # touch /etc/cron.d/[設定ファイル名]
     ~ファイル内設定後~
    # cat /etc/cron.d/[設定ファイル名]
    00 3 * * * root bash -xv /opt/bin/[スクリプト名] >> /var/log/[ファイル名] 2>&1

大まかな設定内容の詳細としては以下のようになります。
・毎日AM3:00に実行する
・root権限にてスクリプトを実行
・/var/log/[ファイル名]へ上書きしていく

また、”bash -xv”の実行結果は標準出力ではないので、”2>&1”を最後に追記しないと、
ファイルへ出力されません。

※詳細は以下記事が分かりやすかったです

https://qiita.com/ritukiii/items/b3d91e97b71ecd41d4ea


## 全体を通して

簡単ですが、以上がログローテーションとcronの設定についてです。
実装内容は資格試験の学習内で触れたことはあったが、
実装は初だったので、調べながらやってなるほどねと改めて理解しながら行えたと思います。

個人的にはスクリプトのログ出力がうまくできず、苦戦しました
（”2>&1”を入れず実行していた）
付随して、標準出力、エラー出力の仕組みについても触れることができよかったです。

今後も実装でためになったことをどんどん発信していければと。
ExpressにstaticなReactアプリを配置する方法 (改)

# はじめに
先日作った[Expressアプリ](https://threed-scatter-app.onrender.com/)の改造です。

https://qiita.com/yo16/items/e3ef757a1f5ea6548e18

このときの課題として、Reactアプリを、サーバーアプリのpublicの直下に置く方法しかわからなかったのですが、フォルダを掘れたのでその内容です。
上の記事では、②-3のあたりの話。

## 最終系
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f05de3e1-84da-38b4-b564-5390ec325dd5.png)
`public/scatter-app-build` 以下に、丸っとコピーしています。

# routes/index.jsだけの話
```javascript:routes/index.js
router.get('/', function(req, res, next) {
  // res.sendFile("index.html");  // 削除
  res.sendFile("index.html", {  // ①追加
    root: path.join("public","scatter-app-build"),
  });
});
// ↓②追加
router.use(express.static(path.join("public","scatter-app-build")));
```
①の追加分がある`router.get()`の目的は、URLで`/`とリクエストが来た場合は、`index.html`を返すよということ。なのでここで、デフォルトの`public/index.html`から、`public/scatter-app-build/index.html`を返すよう変更します。
参考：[Express 4.x - API リファレンス](https://expressjs.com/ja/api.html#res.sendFile)（Express公式）

②の関数は、URLで`/`以下でファイル名を指定された場合に見に行くファイル群のこと。たとえば、`http://～～～/favicon.ico`を頂戴って言われたら、どのファイルを渡す？という設定。ここでは、`/～`と最上位の直下で呼び出されるときは、`public/scatter-app-build/～`のファイルを返してということ。`http://～～～/favicon.ico`と言われたら、`public/scatter-app-build/favicon.ico`となります。
これは、`public/scatter-app-build/index.html`の中から、.jsファイルやら.cssファイルを呼び出しているので、その時に行きます。逆にいうと、②の関数がないと、.jsとか.cssがない（読み込めない）となります。

以上です。

# ついで話
今後、別のアプリもこのExpressに載せたくなった場合、`http://～/`以下は入口として、`http://～/scatter-app/`で今のアプリ、`http://～/another-app/`で別のアプリ、とかやりたくなります。
その場合も今回の話が生きて、②の関数の書き方を変えて対応します。

やり方は２つあって、１つは、
```JavaScript:index.js
// public以下を階層ごと全部公開する
router.use(express.static("public"));
```
として、public以下の構造を、全部公開すること。まぁこれもありのケースも多そう。

もう１つは、このURLの場合はこのフォルダ、このURLの場合は別のこっち、という方法。第一引数に、"このURLの場合は～"というのを追加します。
```JavaScript:index.js
// アプリごとに公開するフォルダを指定する
router.use("/scatter-app", express.static(path.join("public","scatter-app-build")));
router.use("/another-app", express.static(path.join("public","another-app-build")));
```
どちらもやりたいときはありそうではあります。

参考：[Express での静的ファイルの提供](https://expressjs.com/ja/starter/static-files.html)（Express公式）

## 階層を分けた場合、追加でやらないといけないこと
URLのルーティングはそれでいいんですが、Reactアプリでbuildされる、`index.html`は、`/～.js`を読むようになってます。`http://～/scatter-app/index.html`のファイルを開けても、そのjsファイルが`/`から始まるということは、`http://～/～.js`を見にいっちゃうという問題。
`./～.js`になっててくれれば、`http://～/scatter-app/～.js`を読んでくれるので、`./`にする＝相対パスにする設定が必要です。

方法は、Reactアプリの`package.json`に、`homepage: "./"`を追加するだけ。
```json:package.json
{
  "name": "scatter-app",
  "version": "0.1.0",
  "private": true,
  "homepage": "./",
  "main": "index.html",
・・・略・・・
}
```
もし厳格にやりたければ、`scatter-app/`とかにすればいいのかもしれないけど、アプリの設定でサーバーのURLを書くのは嫌な気分です。なのでカレント以下を見てねという相対パス設定がよいと、思います。


# まとめ
少しずつ、Expressさんとも仲が良くなってきた気がします。恰好悪くてもとりあえず作って出し、改善点があったら直していくというスタンスで、どんどんアウトプットしていこうと思います！

今思ってる改善点は、[Renderを使った今のサイト](https://threed-scatter-app.onrender.com/)は、15分アクセスしないと次回起動時に数十秒かかるので、Next.jsの一部にしたいなーという点。
今回気づいた相対パスの設定があるので、できそうな感触です。

ではまた。
What is Pagefind?

Pagefind[^1] について。
![179d0240881160-a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569971/9f6c4888-aa10-9430-5a2e-4dc941f06b5e.png)

Pagefind は SSG 用の全文検索エンジン。

https://www.youtube.com/watch?v=v79VRrfVau8

Pagefind は Rust で実装されている。Turbopack[^3] や Biome[^2] など Frontend 系のツールが Rust で書き換えられているケースが多い。Rust は性能が良い。

個人的には Rust が幅広く使われるようになることを期待している。low layer だけでなく。
一方で stack の選定は組織的な問題だと思うので、実例が多く出てくるのは、後数年は待つ必要があると思う。

## tl;dr
- 前提は SSG で生成された HTML ファイルがあること。
- `html` tag が無い場合 scan されない。
- Build command の後で `pagefind` を実行する。

## About Pagefind

https://pagefind.app/

> Pagefind is a fully static search library that aims to perform well on large sites, while using as little of your users’ bandwidth as possible, and without hosting any infrastructure.
> 
> Pagefind は完全に静的な検索ライブラリで、ユーザーの帯域幅をできるだけ使用せず、インフラをホスティングすることなく、大規模なサイトで優れたパフォーマンスを発揮することを目的としています。

## Usage
```bash:log
[Building search indexes]
Total: 
  Indexed 1 language
  Indexed 6 pages
  Indexed 448 words
  Indexed 0 filters
  Indexed 0 sorts

Finished in 0.069 seconds
```

- `html` tag が無い場合 scan されない。
```bash: error message
1 page found without an <html> element. 
Pages without an outer <html> element will not be processed by default. 
If adding this element is not possible, use the root selector config to target a different root element.
```

- UI を変更するには custom properties[^4] を設定する。以下の変数。

https://github.com/danny-yamamoto/rough/blob/1828f38a8b09c169c3e396bc633217d91cf3cddf/src/components/Search.astro#L15-L29

以上。

code と Cloudflare Pages の URI はこれ。

https://rough-ey6.pages.dev/hoge/

https://github.com/danny-yamamoto/rough

[^1]: https://pagefind.app/
[^2]: https://biomejs.dev/ja/
[^3]: https://turbo.build/pack
[^4]: https://pagefind.app/docs/ui-usage/#customising-the-styles
Vagrant＋VirtualBoxで、Amazon Linux 2023／Amazon Linux 2を使う

# What's？

Amazon Linux 2023の仮想マシンイメージが利用可能になっていたので。

https://aws.amazon.com/jp/about-aws/whats-new/2023/12/amazon-linux-kvm-vmware-images-al2023-3/

調べてみると、VirtualBoxのVagrant Boxを公開している方がいたので、ちょっと使ってみようかと。

オマケで、Amazon Linux 2の方も載せておきます。

# Amazon Linux 2023の仮想マシンイメージ

以下のとおり、Amazon Linux 2023のKVMおよびVMwareのイメージが公開されています。

> 本日より、お客様は Amazon Linux 2023 (AL2023) を Amazon EC2 上で直接実行する以外に、仮想ゲストとして実行できるようにもなります。現在、KVM (qcow2) イメージと VMware (OVA) イメージが提供されています。

https://aws.amazon.com/jp/about-aws/whats-new/2023/12/amazon-linux-kvm-vmware-images-al2023-3/

ドキュメントはこちらですね。

https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/outside-ec2.html

以下からダウンロードできます。

https://cdn.amazonlinux.com/al2023/os-images/latest/

# VagrantでのAmazon Linux 2023

Vagrantでは、VirtualBox用のBoxを公開している方がいます。

https://app.vagrantup.com/gbailey/boxes/al2023

今回はこちらを使わせてもらいましょう。これでAmazon Linux 2023をローカルで起動できるようになります。

なお、中身はVMwareの仮想マシンイメージをVirtualBoxで使えるように変換したもののようです。

GitHubリポジトリはこちら。

https://github.com/gebailey/vagrant-boxes

Amazon Linux 2023に関する内容はこちら。

https://github.com/gebailey/vagrant-boxes/tree/main/al2023

# 環境

macOS。

```shell
$ sw_vers
ProductName:            macOS
ProductVersion:         13.6.3
BuildVersion:           22G436
```

VirtualBox。

```shell
$ VBoxManage --version
7.0.14r161095
```

Vagrant。

```shell
$ vagrant version
Installed Version: 2.4.1
Latest Version: 2.4.1

You're running an up-to-date version of Vagrant!
```

# Amazon Linux 2023のVagrant Boxを使う

`vagrant init`。

```shell
$ vagrant init gbailey/al2023
```

起動。

```shell
$ vagrant up
```

起動したらログイン。

```shell
$ vagrant ssh
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
```

Amazon Linux 2023が起動しました。

OS情報の確認。

```shell
$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2023"
ID="amzn"
ID_LIKE="fedora"
VERSION_ID="2023"
PLATFORM_ID="platform:al2023"
PRETTY_NAME="Amazon Linux 2023"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2023"
HOME_URL="https://aws.amazon.com/linux/"
BUG_REPORT_URL="https://github.com/amazonlinux/amazon-linux-2023"
SUPPORT_END="2028-03-15"


$ uname -srvmpio
Linux 6.1.66-93.164.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Jan  2 23:50:53 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

Fedoraベースなので、パッケージのインストールなどは`dnf`で。

# Amazon Linux 2のVagrant Boxを使う

オマケ的に。

Amazon Linux 2023のVagrant Boxを公開している方は、Amazon Linux 2のVagrant Boxも公開されています。

https://app.vagrantup.com/gbailey/boxes/amzn2

こちらを使うことで、Amazon Linux 2をローカルで実行できます。

GitHubリポジトリも同一ですね。

https://github.com/gebailey/vagrant-boxes/tree/main/amzn2

```shell
$ vagrant init gbailey/amzn2
$ vagrant up
```
AWS S3のオブジェクト(画像や動画)を特定のドメインからのみ開けるようにする方法

# AWS S3のオブジェクト(画像や動画)を特定のドメインからのみ開けるようにする方法
開発している際に、特定のドメインの時のみURLが開けるように設定したい場合があったので、備忘録として残しておく。

## 1. パブリックアクセスの一部無効
**下記で対応するBucket Policyの編集で競合するため下記2つを無効にする**
・ 新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする

・ 任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする

![スクリーンショット 2024-01-22 12.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130166/f952ef31-4441-9094-613b-30b0000edfb0.png)

---

## 2. Bucket Policyの編集
1. AWS Management Consoleにサインインし、開くAmazon S3 コンソール。
2. ポリシーを適用するバケットを選択します。
3. [Permissions] タブを選択し, [Bucket Policy] をクリックします。
4. Bucket Policy Editor に上記のポリシーテキストを入力または貼り付けて、yourbucketを実際のバケット名,example.comを許可するドメインに置き換えます。
5. [Save] をクリックします。

ドメインとバケットは各自のものを使用する
```json
{
    "Version":"2012-10-17",
    "Id":"http referer policy example",
    "Statement":[
        {
            "Sid":"Allow get requests referred by any subdomain of example.com",
            "Effect":"Allow",
            "Principal":"*",
            "Action":"s3:GetObject",
            "Resource":"arn:aws:s3:::yourbucket/*",
            "Condition":{
                "StringLike":{
                    "aws:Referer":[
                        "http://*.example.com/*",
                        "https://*.example.com/*",
                        "http://example.com/*",
                        "https://example.com/*"
                    ]
                }
            }
        }
    ]
}
```

---

## 完成物

下記HTMLを許可したドメインとそれ以外のドメインに入れて検証した.

```html
<video controls="" width="250">
  <source src="s3のバケットのオブジェクトURL" type="video/webm">
</video>
```

### 設定したドメインからアクセスすると下記のようになる
![スクリーンショット 2024-01-22 12.42.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130166/e0ba82a2-11d6-09fe-51de-6e855730c64e.png)

### それ以外のURLのアクセス
![スクリーンショット 2024-01-22 12.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130166/d62e3ae4-f3ee-9f2a-1e44-3fdbebcf4c9d.png)

### URLを直接開いても開けない
![スクリーンショット 2024-01-22 12.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1130166/a606487f-55e6-8b8c-0397-b1dc9894a0a7.png)


---
vue-qrcode-readerでQRコードを読み取る（2024年1月）

以下の記事が分かりやすかったのですが、ライブラリが更新されてイベント名等に変更があったため、記事を作成しました。
`decode`から`detect`に変更されていることに気づかず、1日費やしてしまいました...
https://qiita.com/TakenoriHirao/items/8906fb01e5bb542dd0f9
[vue-qrcode-reader](URL "https://github.com/gruhn/vue-qrcode-reader")

## 追加
```
yarn add vue-qrcode-reader
npm install vue-qrcode-reader
```
## vueに登録
```
import Vue from 'vue'
import { QrcodeStream } from 'vue-qrcode-reader'
```
```
Vue.component('my-component', {
  components: { QrcodeStream },
)
```
## 使う
#### html
```
<qrcode-stream @detect="onDetect"></qrcode-stream>
```

#### scripts
```
methods: {
  onDetect (content) {
    console.log('onDetect')
  }
}
```
VSCodeで踏み台サーバ経由で接続したリモートサーバ上のファイルをエクスプローラー表示する

<h1>やりたいこと

VSCode上で、踏み台サーバ経由で接続したリモートサーバ上のファイルを直接エクスプローラー画面から開いて作業できるように設定を行う。

<h1>前提条件</h1>

* 作業マシン: Windows 10
* リモートサーバへの接続に必要な公開鍵・秘密鍵のペアが既に作成済みで且つ、接続先サーバへ設定済みである事

<h1>手順

<h3>devサーバへSSHコマンドで入れるように設定する 

まずは、devサーバへSSHコマンドで入れるように設定を行います。

`~/.ssh` 配下に、以下の内容でconfigファイルを作成します(すでに存在する場合は編集・追記)。

```
# 踏み台サーバの接続情報
Host bastion
    HostName xxx.xxx.xxx.xxx
    Port 22
    User keso_keso
    IdentityFile ~\.ssh\id_rsa
# 踏み台を経由して接続するサーバの接続情報
Host dev
    HostName xxx.xxx.xxx.xxx
    User keso_keso
    IdentityFile ~\.ssh\id_rsa
    ProxyCommand ssh -CW %h:%p bastion
```

以下のコマンドで `dev` サーバにログインできるようになればOKです。

```
ssh dev
```

<h3>拡張機能「SSH」インストール

次に、以下の拡張機能をVSCodeにインストールします。

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh

<h2>settings.jsonを編集

コマンドパレットを開き、`>基本設定：ユーザ設定を開く(JSON)` をクリックします。
settings.jsonが表示されたら、以下を追記します。

```
{
	"remote.SSH.configFile": "~\\.ssh\\config",
	"remote.SSH.remotePlatform": {
			"bastion": "linux",
			"dev": "linux"
	},
}
```

<h3>SSH接続の確認

上記手順で拡張機能「SSH」のインストールが完了していると、VSCodeにタブが新規に追加されます。

![vscode-ssh-extense.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/b39e0f8d-9289-6302-4209-5d7de84bb7e0.png)

`SSH TARGETS` 内のから `dev` サーバを選択して右側の `現在のウィンドウで接続` または `新しいウィンドウで接続` を押して、SSH接続されたエクスプローラー画面が表示されればOKです。

![vs06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/98c63d8c-18bf-a12a-0282-140e4001a27e.png)
entgoで生成されるモデル構造体から`json:"omitempty"`を駆逐したい

:::note info
**要するに**
entgoで生成されるモデル構造体から`json:"omitempty"`を駆逐するためのライブラリを作成しました。

- https://github.com/a10adotapp/entfw
:::


# 困ったこと

goのORMに[ent.](https://entgo.io/)を使用し、スキーマファイルからモデル構造体を自動生成する際、
生成される構造体には`json:"omitempty"`のタグが自動で付与されています。

例えばこのようなスキーマを作成して、

``` go
package schema

import (
	"entgo.io/ent"
	"entgo.io/ent/schema/field"
)

// Pet holds the schema definition for the Pets entity.
type Pet struct {
	ent.Schema
}

// Fields of the Pet.
func (Pet) Fields() []ent.Field {
	return []ent.Field{
		field.Uint32("id"),

		field.Uint32("sex"),
	}
}
```

モデル構造体の自動生成（`go generate ./ent`）を行うと、以下のような構造体が生成されます。

``` go
// Pet is the model entity for the Pets schema.
type Pet struct {
	config `json:"-"`
	// ID of the ent.
	ID uint32 `json:"id,omitempty"`
	// Sex holds the value of the "sex" field.
	Sex          uint32 `json:"sex,omitempty"`
	selectValues sql.SelectValues
}
```

`ID`, `Sex`のフィールドに`json:"omitempty"`が勝手に付与されているのがわかるかと思います。

`json:"omitempty"`が勝手に付与されていることにより、
例えばWeb APIのエンドポイントを作成し、`Pet`のインスタンスをJSONレスポンスとして返却しようとすると、

``` json
{
  "pets": [
    {
      "id": 1,
      "sex": 1
    },
    {
      "id": 2
    }
  ]
}
```

のように、場合によってJSONからフィールド自体が消えてしまい、クライアント側の実装次第では困ったことになってしまいます。

これを回避しようとすると、全てのフィールド定義で<code>StructTag(`json:"id"`)</code>のように手動でJSONタグを定義するしか無いのですが、面倒臭い上に人間がコードを書く以上定義漏れを完全に防ぐことが難しい状況でした。

# 解決

以下のようにJSONタグを書き換える関数を作成し、その関数で変換したフィールドを返すようにすることで解決しました。

``` diff
package schema

// ...

// Fields of the Pets.
func (Pets) Fields() []ent.Field {
- 	return []ent.Field{
+ 	return WrapFields(
		field.Uint32("id"),

		field.Uint32("sex"),
- 	}
+ 	)
}
```

**ent/schema/wrapfields.go**

```go
package schema

import (
	"fmt"

	"entgo.io/ent"
	"github.com/a10adotapp/a10a.app/lib/slices"
)

func WrapFields(fields ...ent.Field) []ent.Field {
	return slices.Map(fields, make([]ent.Field, 0), func(field ent.Field) ent.Field {
		field.Descriptor().Tag = fmt.Sprintf("json:\"%s\"", field.Descriptor().Name)

		return field
	})
}
```

また、ent.を使用しているプロジェクト全てに関数を作成するのも大変だったので、ライブラリを作成しました。

- https://github.com/a10adotapp/entfw

これを引っ張ってきてスキーマのフィールド定義部分をラップしてしまえば`json:"omitempty"`の自動付与から脱却することができます。

# おわり

同じようなことで困っていたら使ってみてください。
AWS Sagemakerで気づかないうちに300$課金された話

学習のためにAWS Sagemakerを利用していたのですが、課金の仕組みを理解しきれずに300$程度課金されたのでここに対処方法を書いておきます。

## AWS SageMakerとは
機械学習モデルの開発からデプロイまでを容易にするマネージドサービス。データサイエンスのプロセスを統合し、スケーラブルで柔軟な機械学習ワークフローを提供。

## 何をしていたか
AWS SageMakerを使い、テストデータを作成し、それをトレーニングさせモデルを作成し分析を行っていた。

## 原因
共有スペースの削除が出来ておらず、スペックの高いインスタンス(ml.g5.4xlarge)が90h程度立ち上がりっぱなしだった。

## 料金がかからないように注意していたつもりだったが・・
コンソール上からSageMaker　Canvasはログアウトしていたし、SageMaker　Studio上からも起動しているインスタンスはすべて停止していたが、共有スペースの削除に気づけなかった。

## 対処方法
対処方法を探している間にも課金され続けるので焦りながら調査。
コンソール上からの対応方法がすぐに見つからなかったため、AWS CloudShellを利用。

AWS CloudShellを起動し、ドメイン内の共有スペースのリストを取得
```
aws sagemaker list-spaces
```
すると共有スペースのリストが表示され、`"Status": "InService"`となっている共有スペースが料金がかかっているものと分かる。

これを削除するため、AWS CloudShellで以下のコマンドを実行。
```
aws --region Region sagemaker delete-space \
    --domain-id DomainId \
    --space-name SpaceName
```
これで共有スペースでかかっていた料金を止めることができる。


## 一番安全な方法
学習や調査目的の場合は終わり次第、AWS SageMakerのドメイン自体を削除してしまった方が確実と思われる。
あとはコスト異常検出を設定しておくべきと改めて感じた。

## 対応にあたり参考にしたサイト
[Delete an Amazon SageMaker Domain](https://docs.aws.amazon.com/sagemaker/latest/dg/gs-studio-delete-domain.html#gs-studio-delete-domain-studio "Delete an Amazon SageMaker Domain")
CORS備忘録

# はじめに
皆さんは開発をしていて「blocked by CORS policy」というエラーに遭遇したことはありませんか。
自分はそのような経験があるため、今回はCORSについて勉強してみました。

# CORSとは
CORSとは「Cross-Origin Resource Sharing」、日本語に訳すと「オリジン間リソース共有」のことです。これは「同一オリジンポリシー (Same-Origin Policy)」という規約によって設けられた制限を緩めるためのもので、異なるオリジン(URL)からのリクエストでもアクセスできるようにした仕組みです。

# なぜ必要
ブラウザはデフォルトで同一オリジンポリシーに従っているため、異なるオリジン間でのデータのやり取りはできません。これは異なるオリジンからのXSS(クロスサイトスクリプティング攻撃)やCRSF(クロスサイトリクエストフォージェリ)といったセキュリティ上のリスクを減らすための制限です。

- **XSS**
ユーザーがWebサイトにアクセスすることで不正なスクリプトがClient(Web ブラウザ)で実行されてしまうセキュリティリスク。

- **CRSF**
Webアプリケーションのユーザーが、意図しない処理をWebアプリケーション(Web Server)上で実行されるセキュリティリスク。

# 解決法
この制約はユーザー側にとっては優しい仕組みかもしれませんが、開発者側からするとエラーの原因になってしまうため、非常に不便です。これを解決するには**サーバー側で許可する**ことが必要です。
「http://<foo>localhost</foo>:5500」というクライアントと「http://<foo>localhost</foo>:3000」というサーバーがあったとすると、localhost:3000側でlocalhost:5500とのータのやり取りを許可してあげれば解決できます。ではどのようにして許可してあげるのかというと、「**Access-Control-Allow-Origin: http://<foo>localhost</foo>:5500**」というように指定してあげれば良いわけです。また、「**Access-Control-Allow-Methods: PUT**」(GETとPOSTは予め許可されている)のように、必要に応じて許可するHTTPメソッドを指定することもできます。

# 最後に
短いですが、本記事はここで終わります。最後まで読んでいただき、ありがとうございます。
Stripe備忘録

ECサイトのように有形のものを販売する場合と、サービスやサブスクを提供する場合でStripeの決済方法が変わってくる。

# ECサイトのように有形のものを販売する場合
[Payment Element](https://stripe.com/docs/js/element/payment_element)を使って一回限りの決済を行う。顧客からの購入情報に基づいてサーバー側で`payment intent`を作成し、クライアントに返却する。

クライアント側ではサーバーから受け取った`payment intent`を元に決済を行う。この間にトークンの生成やカード情報の送信は行われない。

## 参考
[Custom payment flow](https://stripe.com/docs/payments/quickstart?platform=web)

# サービスやサブスクを提供する場合

顧客がクレジットカード情報をもとにトークンを生成し、サーバーに送信する。サーバー側では[Customers](https://stripe.com/docs/api/customers)オブジェクトを作成する。この顧客情報に決済情報が紐づけられるため、定期的な決済をサーバー側で行うことができる。

プログラムから自動的に決済を行うことも、手動でダッシュボードから請求を作成することもできる。

請求を行う際は[Invoices](https://stripe.com/docs/api/invoices)オブジェクトを作成する。さらに[Invoice Items](https://stripe.com/docs/api/invoiceitems)オブジェクトを作成することで、請求の明細を作成することができる。

# 審査
Stripeの本番環境で決済を行うためには、審査を通過する必要があります。

まずサービスのWebページを作り、フッターに`特定商取引法に基づく表記`を記載する必要があります。

# 参考
ドキュメント

- https://stripe.com/docs/js
- https://stripe.com/docs/api
CSS設計の基本とリファクタリング

# 1.はじめに

CSSはウェブ開発において不可欠な技術です。

この記事では、CSS設計の重要性とその基本原則について掘り下げ、フロントエンド開発における効果的なスタイル指定の方法を提案します。

# 2. この記事を読んで欲しい人
・CSSについて基本的な知識を学びたい方
・CSSのリファクタリングについて知りたい方


# 3. 前提条件
・HTMLとCSSの基本的な知識
・フロントエンド開発に関する一般的な理解

# 4. CSSにおける設計とは

### 4.1. CSS設計の重要性

**フロントエンドとCSSの仕事**
フロントエンド開発では、ユーザーインターフェースの見た目と機能を実現するためにCSSが重要な役割を果たします。CSSを適切に設計することで、メンテナンスが容易で、拡張可能なスタイルを実現できます。

**開発に欠かせない設計**
CSSの設計は、単にスタイルを適用するだけでなく、将来的な変更や追加機能への対応を容易にするために不可欠です。良い設計はプロジェクトの成功に大きく寄与します。

**より良いCSSのゴール**
目指すべきは、再利用可能で、予測可能な、そしてメンテナンスしやすいCSSです。そういったCSSは、時間とリソースの節約につながります。

### 4.2. 破綻しやすいCSS
**HTMLの構造に依存している。**
HTMLの構造変更によってスタイルが意図しない形で変化することを避けるため、依存性を低減させる設計が重要です。
（例）
NG ：HTML構造が変更されると、スタイルが意図しない形で適用される可能性があります。
```
#sidebar div ul li a {
    color: green;
}
```

OK：HTML構造の変更がスタイルに影響を与えにくくなります。
```
.sidebar-link {
    color: green;
}
```

**スタイルを取り消している。**
一度適用したスタイルを別の場所で取り消すような設計は、複雑さを増し、デバッグを困難にします。

**絶対値を多用している。**
絶対値（ピクセル単位など）の多用は、レスポンシブやフレキシブルなデザインを妨げます。
相対値を用いることで、さまざまなデバイスや画面サイズに対応しやすくなります。

**修正しやすいCSSへ**
メンテナンスしやすいCSSを目指すには、クリーンなコード、モジュール性、そしてスコープの明確化が必要です。コンポーネントごとにスタイルを分割し、影響範囲を限定することが重要です。
（例）
NG ：ヘッダー内の多くの要素に対してスタイルが適用されていますが、一つの大きなCSSブロックにまとめられているため、メンテナンスが困難です。
```
.header {
    /* ヘッダーに関する多くのスタイル */
}
.header a, .header li {
    /* ヘッダー内のリンクとリストアイテムに関するスタイル */
}
```
OK：個別のクラスを作成し、それぞれにスタイルを適用することで、各コンポーネントのスコープを明確化し、修正が容易になります。
```
.header {
    /* ヘッダーの基本スタイル */
}
.header-link {
    /* ヘッダー内のリンク専用スタイル */
}
```

# 5. CSSの基本を振り返る
### 5.1. CSSセレクタと詳細度
**5.1.1 カスケーディングの基本**
CSSは「カスケーディングスタイルシート」の略で、スタイルの継承と優先順位がその特徴です。
この原則を理解することは、効果的なスタイル指定に不可欠です。

**5.1.2 詳細度**
詳細度は、どのスタイルが最終的に適用されるかを決定します。
タグ、クラス、IDの選択肢から適切に選び、予期せぬスタイルの上書きを防ぎます。

**5.1.3 詳細度の計算**
詳細度は、セレクタの種類に応じて異なる「重み」で計算されます。
IDセレクタはクラスセレクタよりも、クラスセレクタはタグセレクタよりも重みが高いです。

### 5.2. セレクタのリファクタリング
セレクタをより安全でシンプルなものにすることで、読みやすく、保守しやすいCSSを実現できます。

**要素セレクタを省略する。**
特定のHTML要素に依存するセレクタは、将来的なマークアップの変更に弱いです。
クラスセレクタのみを使用することで、より柔軟で再利用しやすいスタイルを作成できます。
（例）
NG ：ul要素内のすべてのli要素にスタイルが適用されます。HTML構造の変更に弱く、再利用が困難です。
```
ul li {
    margin: 10px 0;
}
```
OK：独立してスタイルを適用できます。よって、構造に依存しない柔軟で再利用しやすいスタイルが作成できます。
```
.list-item {
    margin: 10px 0;
}
```

**セレクタを短くする。**
長いセレクタは、そのスコープや影響範囲が広がり、意図しないスタイルの適用を招く可能性があります。短く明確なセレクタを目指しましょう。
（例）
NG ：他の場所で意図しない影響を及ぼす可能性があります。
```
header nav ul li a {
    color: blue;
}
```
OK：独立してスタイルを適用できます。よって、構造に依存しない柔軟で再利用しやすいスタイルが作成できます。
```
.nav-link {
    color: blue;
}
```

**セレクタを限定的にする。**
特定のコンテキストにのみ適用されるセレクタは、スタイルの予測可能性を高めます。
不必要なグローバル影響を避けるために、セレクタのスコープを適切に管理することが重要です。


# 6. まとめ
この記事では、CSSの設計と基本を振り返り、効果的なフロントエンド開発に必要なスタイル指定のテクニックのアウトプットをしました。

良いCSS設計は、プロジェクトの成功に直結し、メンテナンスや拡張性を大幅に改善します。
この原則を実践することで、より品質が高く、使いやすいウェブサイトやアプリケーションを作成できます。

# 7. 参考にしたもの
Web制作者のためのCSS設計の教科書
VSCodeの拡張機能でMySQLに接続する

<h1> 使用する拡張機能

https://marketplace.visualstudio.com/items?itemName=cweijan.vscode-mysql-client2

:::note warn
無料版は設定できる接続が最大3つまでなので注意
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/c5deb2f9-df5a-811a-9b4b-8bfff9146010.png)

<h1>データベースへ接続する手順

VSCodeのサイドバーで拡張機能を選択し、「MySQL」を検索してインストールします。

![vs01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/6654c4ab-c5c0-d6f5-2742-eb598d1921bf.png)

インストールが完了すると、サイドバーに「MySQL」のアイコンが表示されますので、そちらをクリックします。
クリックすると、 `Create Connection` ボタンが表示されますのでクリックします。

![vs02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/db178be5-ea69-f0f4-ae27-9d36646f9862.png)

接続設定の画面が開きますので、必要な情報を入力していきます。
入力できたら `Connect` で接続できるか確認します。

![vs03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/dd0bad05-5d47-4335-2c17-86ac6f7a1ee1.png)

以下のように表示されれば成功ですので、設定を保存します。

![vs04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/7e3fda21-342c-762e-29ba-37ff8327b88b.png)


<h1>踏み台サーバを経由した接続の設定

踏み台サーバを経由したMySQLへの接続を設定する事も可能です。

`SSH Tunnel` のトグルボタンをONにし、開いた下側のパネルに踏み台サーバへの接続情報を入力します。
上側のパネルには最終的に接続したいMySQLの接続情報を入力します。

![vs05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679544/e290efcf-e120-2d2e-a33b-cbd77e540876.png)

:::note warn
リモートエクスプローラーと併用する場合は、あくまでリモート接続したサーバ上からの接続設定になりますので、注意が必要です。上手く接続できない場合は、データベース接続用に別プロジェクトを開くなどしてから接続するといった事が必要になります。
:::
ARC170回答メモ

# 0.はじめに
　前回は見逃していたため、久々のARC。1問は解きたいと思っていましたが
　なんとかAだけクリアできました。
　Bもあがいてみましたが、思い描く仕様を実装するにはスキルが足りず
　その仕様も後に解説と見比べると今一だったので、まだまだ修行が足りなそうです。
　とはいえ、去年からの緑はキープし、初のレート900台（901ですが・・・）に達しました。


# 1.A - Yet Another AB Problem
　単純な解き方だと穴が発生してその穴に気づかないと嵌る問題(個人の感想)。
　【考え方】
　　〇基本ケースのカウント
 　　・S[i]がB＆T[i]の時をBA、S[i]がA、T[i]がBの時をABとする。
　　 ・SとTを先頭から一文字ずつ比較し、BAの個数とABの個数をカウントしていく
   　　→BAが1以上かつABの時、一緒に変換可能なので、別途変数PCにカウントを追加し
     　　BAのカウントを1減らす（ABにも加算しない）
　　〇一致させることが可能かのチェック
  　　・例えば以下のような場合問題の条件（i<j）より、SとTを一致させられない
　　　　例１）変換が必要となる先頭がABのため、変換できない
　　　　　1-1.先頭がAB
　  　  　　S：ABABA
  　  　　　T：BBABA
　　　　　1-2.ABは先頭ではないが、ペアで変換するAが前にない
　  　  　　S：BABABA
  　  　　　T：BBBABA
　　　　　※例えば以下のような場合、i＝1、J＝2とすれば、変換可能
　  　  　　S：AABABA
  　  　　　T：ABBABA
     　　　
　　　　例２）変換が必要となる末尾がBAのため、変換できない
　　　　　1-1.末尾がBA
　  　  　　S：ABABB
  　  　　　T：ABABA
　　　　　1-2.BAは末尾ではないが、ペアで変換するBが後ろにない
　  　  　　S：BABABA
  　  　　　T：BABAAA
　　　　・例１の状態チェックのため、先頭から見ていき、T[i]がAの時FAフラグに1をセット
    　　　→AB状態かつ、FTフラグが0の場合は変換不能のため、-1を出力して終了
　　　　・例２の状態チェックのため、末尾から見ていき、T[i]がBの時LBフラグに1をセット
    　　　→BA状態かつ、LBフラグが0の場合は変換不能のため、-1を出力して終了

 　上記を実装し、O(2N)でAC頂けました。


　https://atcoder.jp/contests/arc170/submissions/49549016


以上
エクスプローラーのサクラエディタ系右クリックメニューを後から追加

# 概要

サクラエディタはインストール済。
でもエクスプローラーの右クリックメニューに『SAKURA EditorでGrep』や『SAKURA Editorで開く』が無い。
再起動やログオフをせずにメニュー追加したい。

# やり方

下記でインストーラーをダウンロード。

https://github.com/sakura-editor/sakura/releases

下記にチェック入れてインストール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/97f3bd15-d008-d8ea-d596-31be59ffe137.png)

* チェック入れて再インストール。
* 再インストール前のアンインストールは不要。

# バージョン

Microsoft Windows [Version 10.0.19045.3930]
サクラエディタ   v2.4.1.2849 32bit (tag v2.4.1)
Oracleデータを繰り返しCSV出力するためのバッチについて

# はじめに

Oracleデータベースを使用したシステムを運用していると、データをCSV形式で出力する
機会は多いですが、繰り返し同じ作業が必要となる場合があります。

毎回ツールを起動、SELECT文を実行、実行結果をコピー＆ペースト/ファイル出力 で取得
でも良いのですが、手間だと感じる場合や、誰がやっても同じ結果となることを期待する
場合には、何かしらの方法/手順 を確立しておきたいです。

方法はいくらでもあるかと思いますが、そのうちの1つをまとめてみます。
※Windows環境での話

# やりたいこと/制限事項

- OracleデータベースのデータをCSV形式でファイル出力
- <font color="red">***何度でも繰り返し、誰でも簡単に***</font>実行できる
- Windows環境

# 方法(具体的な手順)

Windowsバッチを実行、SQLPLUS経由でSELECT文を実行し、結果をファイル出力。

### 1.Windowsバッチ (output_csv.bat)

```bat:記載例 (output_csv.bat)
SQLPLUS [oracle_user]/[oracle_pass]@[server_name] @select.sql
```
- oracle_user - Oracle接続ユーザ名
- oracle_pass - Oracle接続ユーザのパスワード
- server_name - Oracleデータベース名(IPアドレスも可)
- select.sql  - SELECT文等を記載するスクリプトファイル名

### 2.SELECT文発行スクリプト (select.sql)

```sql:記載例 (select.sql)
set echo off
set linesize 1024
set pagesize 0
set trimspool on
set feedback off

spool output.csv

SELECT
'"カラム１","カラム２","カラム３","カラム４","カラム５"' FROM DUAL;

SELECT
'"' || trim(COLUMN1) || '"' || ',' ||
'"' || trim(COLUMN2) || '"' || ',' ||
'"' || trim(COLUMN3) || '"' || ',' ||
'"' || trim(COLUMN4) || '"' || ',' ||
'"' || trim(COLUMN5) || '"' AS "CSVデータ"
FROM
[テーブル名]
ORDER BY
COLUMN1,
COLUMN2
;

spool off
exit
```

- spool - 出力ファイル名 (上記例では output.csv といったファイル名を指定)
- CSVの引用符 - '"' としている箇所で指定 (上記例ではダブルクォーテーションを指定)

### 3.出力結果 (output.csv)

テーブル構造を把握するためのカラム名がヘッダ行として1行目に出力され、2行目以降に
データが出力されます。

```csv:出力結果例 (output.csv)
"カラム１","カラム２","カラム３","カラム４","カラム５"
"COLUMN1_DATA1","COLUMN2_DATA1","COLUMN3_DATA1","COLUMN4_DATA1","COLUMN5_DATA1"
"COLUMN1_DATA2","COLUMN2_DATA2","COLUMN3_DATA2","COLUMN4_DATA2","COLUMN5_DATA2"
"COLUMN1_DATA3","COLUMN2_DATA3","COLUMN3_DATA3","COLUMN4_DATA3","COLUMN5_DATA3"
```

# 最後に

テーブルの1レコードを引用符、カンマで結合した結果を出力するだけですが、あれば何かと
便利です。
python.Fileから複数行を読込むreadlineを使わず。

一番簡単なFile読込。

```python
import os
import sys
import re
# ファイル名
data_file_name = 'my_test.txt'
f = open(data_file_name, 'r')#ファイル読み込み
str = f.read()
f.close()
my_list_in2=str.split("\n")

print(my_list_in2)#各行は配列に収められている。
```
with を使わないのが特徴です。
my_list_in2=['1','','3','']の様な物も読み込めます。

最後に改行を入れず書けます。
if my_list_in2[3]==''
    my_list_in2[3]='4'

```python
strw = "\n".join(my_list_in2)
print('myjyoin',strw)
f = open("mytest2.txt", 'w')#ファイル書込み
f.write(strw)
f.close()
```
CRM Analytics REST API 



+ [Creating a Replicated Dataset through REST](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Wg4F8)

+ [Replicated Datasets List Resource](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Wg4F8)

```
[{"errorCode":"JSON_PARSER_ERROR","message":"Unrecognized field \"connector​Id\" at [line:2, column:22]"}]
```

:::note
UPDATE: I was able to fix this, it was a user error. What had happened is that I copied the litteral connectionId string from the web page https://developer.salesforce.com/docs/atlas.en-us.bi_dev_guide_rest.meta/bi_dev_guide_rest/bi_resources_replicateddatasets.htm

Unknown to me, there was a hidden UNICODE character between the connection and Id that was picked up in eclipse, and consequently was passed as part of the JSON. I discovered this when I pasted my code into a text editor.
:::
Wiresharkでリモートデスクトップのパケットを除外してキャプチャー

# やりたいこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/26428d5d-d952-05c5-93f6-8f8875b5b8dd.png)

1. 別拠点にWiresharkをインストールしたPCがある。
1. そのPCへリモートデスクトップしてその拠点のネットワークのパケットをキャプチャーしたい。
1. でもリモートデスクトップのパケットは除外してキャプチャーしたい。

# やり方

```:キャプチャー時のフィルター
not port 3389
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/55977429-bb1a-7325-4cf0-63998623d7c2.png)

# 参考サイトさん

http://blog.livedoor.jp/tuckey3/archives/51420189.html

# バージョン

Microsoft Windows [Version 10.0.19045.3930]
Wireshark Version 4.2.2
pipのCERTIFICATE_VERIFY_FAILEDを回避する

信頼済みホストを追加して、pipコマンドを実行する

```bash
pip install hoge-library --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org 
```

CAの証明書を指定する場合は、Windowsの設定から環境変数の設定で、下記を指定する。

```
PIP_CERT=C:\path\to\ca.pem
```

ちなみに、requestsライブラリは
```
REQUESTS_CA_BUNDLE=C:\path\to\ca.pem
```
でOK。
【Swift】【Combine】mergeとCombineLatestの違いを説明してみる

# 目次
[1.mergeとCombineLatest](#1-SwiftCombineとは)
[2.marge](#2-sink)
[3.CombineLatest](#3-store)
[4.おわりに](#5-おわりに)

# 1. mergeとCombineLatest
RxSwift＋MVVM　→　Combine＋TCAにリファクタしている過程で以下の疑問点が湧いてきました。
`marge`と`CombineLatest`どちらもストリームを束ねる点では共通です。
では、何が違うのか解説していきます。

# 2. merge
`merge`は２つのストリームを束ねて、どちらかが流れてきたら実行しまっせという感じです。
:::note info
mergはOR条件と思っておけば良いでしょう！
:::

~~~swift: merge.swift
import RxRelay
class ExampleViewModel {
    // input
    let didTappedIndexButton = PublishRelay<Void>()
    let didInputtedTextField = PublishRelay<String>()

    init() {
        let fetchSomethingResult = Observable.merge(didTappedButton, didInputtedTextField)
            print("ログインボタンorテキストフィールドのどちらかがタップされました")
        }
~~~

上のコードでは、ログインボタンorテキストフィールドのどちらかがタップされた時にprintが実行されます。

# 3. CombineLatest
`combineLatest`は２つのストリームを束ねて、両方が流れてきたら実行しまっせという感じです。
:::note info
combineLatestはAND条件と思っておけば良いでしょう！
:::

~~~swift: CombineLatest.swift
import RxRelay
class ExampleViewModel {
    // input
    let didTappedIndexButton = PublishRelay<Void>()
    let didInputtedTextField = PublishRelay<String>()

    init() {
        let fetchSomethingResult = Observable.combineLatest(didTappedButton, didInputtedTextField)
            print("ログインボタンandテキストフィールドの両方がタップされました")
        }
~~~

上のコードでは、ログインボタンandテキストフィールドの両方がタップされた時にprintが実行されます。
（状況的にあり得るかは置いておいて笑)

# 4. おわりに
今回も本記事を読んでいただきありがとうございました。
似たような考え方でややこしいですが、AND条件、OR条件と思うとシンプルだと思います♫
【Swift】条件分岐について（switch文）

今回は、前回投稿した記事の条件分岐の第二弾で、switchについて学習したので、アウトプットしていきます
※以下の内容は、学習内容のアウトプット用のため、誤りがある場合があります。予めご了承ください

## switch文
```swift:title.swift
switch 値 {
case 条件:
   "条件が合致した時に実行されるコード"
case 条件:
   "条件が合致した時に実行されるコード"
case 条件:
   "条件が合致した時に実行されるコード"
default:
   "どの条件にもマッチしなかった場合に実行されるコード"
}

```
- switch文を用いて網羅的に条件分岐を記述できます。
- 条件はどのデータ型（String型、Int型、Double型、enum型）でも指定が可能です。


### サンプル
```swift:title.swift
let day = "水曜日"

switch day {
case "月曜日":
   print("酢豚")
case "火曜日":
   print("親子丼")
case "水曜日":
   print("豚の生姜焼き") // ⇦条件が成立するこのコードが実行されます。
case "木曜日":
   print("鯖の塩焼き")
case "金曜日":
   print("ラーメン")
case "土曜日":
   print("カレー")
default:
   print("うどん")
}

```

また少し変化を加えてみよう。もし同じ条件を組み込んだ時にはどのような挙動をするのでしょうか。

```swift:title.swift
let day = "水曜日"

switch day {
case "水曜日":
   print("酢豚")  // ⇦　最初に条件が成立するこのコードが実行されます。
case "火曜日":
   print("親子丼")
case "水曜日":
   print("豚の生姜焼き") // ⇦　既に条件が成立しているため、このコードは実行されない。
default:
   print("うどん")
}

```


## fallthrough(フォールスルー)
switch文は条件が成立しコードが実行したら処理は終了します。
条件が成立した際に、意図的に直下のcaseのコードも評価したい場合はfallthroughを使用します。

### サンプル
```swift:title.swift

for value in 1...6 {
    switch value {
    case 1:
        print(" \(value)の時にCase1を処理")
        fallthrough
    case 2:
        print(" \(value)の時にCase2を処理")
    case 3:
        print(" \(value)の時にCase3を処理")
    default:
        print("Default Case\(value)")
    }
}


実行結果
// 1の時にCase1を処理    // 1で条件が合致し処理を実行
// 1の時にCase2を処理   　 // 1で条件が合致し、直下のcase2処理を実行
// 2の時にCase2を処理
// 3の時にCase3を処理
// Default Case4
// Default Case5
// Default Case6

```
今回のサンプルコードの場合、１が条件で合致しその処理を行いましたが、fallthroughによって直下のcase 2"の処理も同時に実行しました。


## 列挙型（enum型）で条件分岐をする
switchは網羅的に条件分岐を指定することができ、条件漏れの可能性を低くするメリットがあります。
しかしcaseの条件を文字列に指定した際にタイポによる可能性があり、安全なコードではなくなります。

これを列挙型とセットにすることにより、簡潔且つ安全に条件分岐を行うことができるようになります。

### サンプル
```swift:title.swift

enum JLeagueTeam {
    case fcTokyo
    case sanfrecceHiroshima
    case kawasakiFrontale
}

let team = JLeagueTeam.sanfrecceHiroshima

switch team {
case.fcTokyo:
    print("ユニフォームの色は赤と青")
case.sanfrecceHiroshima:
    print("ユニフォームの色は紫")
default:
    print("ユニフォームの色は水色")
}

```

## まとめ
今回も条件分岐制御構文の基本であるswitch文について纏めてさせて頂きました！
基本中の基本であるが故にしっかり身につけておく必要がありますね。

次回はこれらを踏まえてif文とswitch文の使い分けについて、もう少し深堀して纏めた記事を出したいと思います。
それでは！
Windowsで.NET Frameworkを一時的に完全無効化


:::note warn
この記事のやり方は試行錯誤した結果の裏技的なものです。
参考情報として見て下さい。
:::

# 背景

.NET Frameworkのバージョンアップをしたい。
でも.NET Frameworkを使っているかどうか曖昧なソフトがインストールされているため、バージョンアップに踏み切れない。


**一時的に.NET Frameworkを完全に無効化してもそのソフトが動くかどうか確認**
もし動けば **.NET Frameworkを使っていないのでバージョンアップしても悪影響が出る可能性がかなり低い** と予想できる。

# やり方

下記フォルダーへ行って…

```
C:\Windows\Microsoft.NET
```

この2フォルダーを…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f394d051-54b4-9a63-d862-6ae24c09e1a2.png)

なんでもいいからリネーム。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/fa0239c6-4bc9-a39c-5d8c-c0ead061a244.png)

リネームには管理者権限が必要です。

# 無効化できたか実験

こういう超単純なexeを用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/224643f1-ca90-a31f-e9cb-e935d031af99.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bba237c4-9c95-c803-b4de-4aac3864ab3c.png)

通常は下記のように起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0583e523-88aa-4ae4-0d7b-6233c4238bce.png)

無効化すると下記のように起動できなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bdd279f3-f205-cd42-6527-9afab4c050ae.png)

# 『Windowsの機能』では完全な無効化はできなかった

下記に.NET Frameworkの有効化or無効化設定がありました。
ですが、ここでチェックを外しても単純なexeは起動できてしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/05ef13b4-0e69-31ac-42d7-7fbbc08d48b0.png)

# 蛇足

基本的に.NET Frameworkはアンインストールは不可で、ダウングレードも不可なようです。
処理に必要なフォルダーを強制的にリネームするぐらいしか方法見つからなかった…。

# 参考サイトさん

https://learn.microsoft.com/ja-jp/dotnet/framework/install/troubleshoot-blocked-installations-and-uninstallations

https://answers.microsoft.com/ja-jp/windows/forum/all/windows10%E3%81%AE-net-framework/f54fdfbd-5764-4454-b877-41eff56ab76a

# バージョン

Microsoft Windows [Version 10.0.19045.3930]
[未解決]VSCodeVimでノーマルモードに戻ったときに日本語入力をオフにする

:::note warn
20234/01/21 現在
いろいろ試しているが、うまく動作していない。
ので、試したことの（書きかけ）メモとして残します。
:::

# 環境
- win11
- VSCodeVimを利用している
- USキーボード
- 日本語入力を利用している

# 経緯
- 下記で紹介されている方法ほぼそのままなのですが、USキーボード、Pythonスクリプトを利用する点が異なっているので、メモです。
- [VSCodeVimでインサートモードから抜ける時に日本語入力をオフにする](https://qiita.com/toriwasa/items/5517b36f85d6ce1ca5a5)
- [【VScode】vim拡張機能でノーマルモードに戻る時に合わせて英数入力に切り替える](https://qiita.com/tea-red/items/23dfc89edc11ecdced03)

# 設定方法

## 1. IME設定
無変換キー押下でIMEオフになるように設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26413/8a7f27e8-cf7e-3847-01c0-b5dc7883ce4d.png)

## 2. キーのリマップ
USキーボードには無変換キーがないため、適当なショートカットキーを無変換キーに割り当てる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26413/aac5e47d-601a-3ec5-6878-bcaad9f4dabe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26413/28bf23b2-063d-5733-3280-5535a3ebaee8.png)

下記のような形で、ショートカット作成機能で、何かしらのキーの組み合わせを無変換キーに割り当てます。

:::note warn
20234/01/21 現在
私の環境ではショートカットリマップを設定するときにCtrlあるいはAltの左右を明示しない設定にすると、キーボードの動作自体がおかしくなりました。入力できなかったり、まったく見当違いのキーが入力されたりします。左右を明示するように注意してください。
原因は不明ですが、MSにフィードバックは送りました。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26413/5975b5c0-731b-184a-6848-8052c39a0ec0.png)

## Python プログラムの作成
実行すると左ALt+左Ctrl+Uを押下するプログラムです。

```python send_alt_U.py
import pyautogui
import time

def send_key(key):
    pyautogui.keyDown(key)
    pyautogui.keyUp(key)

def simulate_unconverted_key():
    pyautogui.keyDown('altleft')
    pyautogui.keyDown('ctrlleft')
    pyautogui.keyDown('U')
    pyautogui.keyUp('altleft')
    pyautogui.keyUp('ctrlleft')
    pyautogui.keyUp('U')

if __name__ == "__main__":
    # 動作確認用スリープ：プログラムを実行してから数秒後にキーを入力
    # time.sleep(5)
    simulate_unconverted_key()
```

### 参考
- [puautoguiで設定できるキー](https://pyautogui.readthedocs.io/en/latest/keyboard.html#keyboard-keys)
- [ChatGPTに聞いた](https://chat.openai.com/share/04357654-7c0e-491c-a9e8-175e17ce2daa)

## 現状
- vimでノーマルモードに戻ったときに日本語入力がオフにならず、正常動作しない
- Pythonスクリプトも、PythonExe化したものも、AHKも、コマンドライン上で単体で正常に動作するが、エディタの日本語入力がオフにならない
おそらく、ウィンドウフォーカスが関係している
- im-selectは単体自体動作せず、実行すると4桁の数値が返ってくる、引数0で実行しても何も起こらず
おそらく、win11では動作しないのかもしれない、MSのIMのAPIが不足しているのかもしれない（憶測）
- im-selectはgit-bashで実行しても結果は変わらず
Javaにおける桁区切り文字の効果的な使い方

### はじめに
Javaプログラミングにおいて、大きな数値の可読性を向上させる方法として、Java 7から導入された桁区切り文字（アンダースコア`_`）について紹介します。

### 桁区切り文字の基本
Javaでの数値リテラルは、読みやすさを向上させるためにアンダースコアを使用して桁を区切ることができます。この機能は、特に大きな数値を扱う際に有効です。

### 使用方法
アンダースコアは、整数、浮動小数点数、そして長整数リテラル内で使用できます。例えば、`1_000_000`や`2.5_000`のように使います。ただし、アンダースコアを数値の始まり、終わり、小数点のすぐ隣、または接尾辞の直前には置くことはできません。

### 利点
桁区切り文字を使うことで、コードの可読性が大幅に向上します。これは、特に数値の桁数が多い場合や、複雑な計算式を扱う際に役立ちます。

### 実例
実例として、Javaでの桁区切り文字の使用方法を見てみましょう。以下にいくつかの具体例を示します：

1. **整数リテラルの例**:
   ```java
   int maxUploadSize = 20_971_520;
   // これは 20,971,520 と同じですが、桁がはっきりと分かります。
   ```

2. **長整数リテラルの例**:
   ```java
   long accountBalance = 1_000_000_000_000L;
   // これは 1,000,000,000,000L と同じですが、読みやすさが向上しています。
   ```

3. **浮動小数点数リテラルの例**:
   ```java
   float pi = 3.141_592_653_589F;
   // 小数点以下の数値を桁区切りで分けて、視認性を高めています。
   ```


### まとめ
桁区切り文字の使用は、Javaプログラミングにおけるコードの可読性を高める簡単かつ効果的な方法です。正しい使い方をマスターすることで、より清潔で理解しやすいコードを書くことができます。
使ったコマンドから覚える！【Git Docker】

# はじめに
Git / Docker 触り始めたマンです。
実際使いだすと、ｳｯ過去の苦手意識が・・・
となりましたが、なんとかやってます。

今回は、とりあえず「実際に使ったコマンド」のみを記録する記事です。
流れを整理しつつ、実務ベースで習得していきたい！！
※`Dockerfile`の作成などはなく、すべて引っ張ってくるケースです。

# コマンドず
## 1. 下準備：`git clone`
**`git clone URL`** で`clone`してくる。
ユーザー名とパスワードが必要な場合も
## 2. Dockerでイメージのビルド
1. **`docker compose build`**
   `docker-compose.yaml`ファイルで定義されたすべてのサービスのイメージをビルド
2. **`docker compose up`**
   ビルドしたサービスを起動（イメージがビルドされてなければ自動で`docker compose build`を行うらしい？）。
## 3. ビルドされたサービスの中身を準備・起動
1. **`docker-compose exec web bash`**
   `web`というコンテナ（サービス）の中で`bash`シェルを開始。これにより、「コンテナ内のCLI操作」が可能に。
   （`docker-compose exec` コマンドは、稼働中のコンテナ内に入りコマンドを実行する。）
   （`web`は`docker-compose.yaml`ファイルで定義されている）
1. **`bundle install`**
   Rubyの依存関係管理ツール`Bundler（gemのversion依存関係管理）`を使用して、依存関係（`gem`）インストール。これにより、Railsが必要とするすべてのRubyライブラリがインストールされる。
3. **`yarn install`**
   JSのパッケージマネージャー`yarn`を使用して、`package.json`に定義された依存関係をインストール。
4. **`bin/rails db:create`**
   Railsのコマンドラインツールを使用して、データベースを作成。`database.yml` ファイルで指定された設定に基づき、必要なデータベースをセットアップ
5. **`bin/dev`**
   Railsアプリケーションのサーバーが起動し、開発に必要な他のサービス（例えば、Webpacker、CSSのコンパイルサービスなど）も同時に起動。これにより、開発者は一つのコマンドでRailsアプリケーションの全ての関連サービスを起動できる。
   （Rails 7以降で導入された新しい開発サーバー起動コマンド）
## 4. ブランチを切る（新しいブランチを作成）
`git switch -c branch_name`
ブランチを切る（新しいブランチを作成）。`git checkout -b branch_name`というやり方もあるが、`checkout`コマンドは推奨されない。
## 5. コーディング・開発
僕の場合は`http://localhost:3000/welcomes`にアクセスしつつ、VSCodeでコーディング
## 6. テスト（`spec`の実行）
**`docker compose run web bundle exec rspec`**
`web`の中で新しいコンテナを作成し、Bundlerを使用して指定されたコマンド（`rspec`）を実行。
`rspec`はRubyで広く使用されているテストフレームワーク。

※`docker compose run`は`docker compose exec`と同じくコンテナ内に入りコマンドを実行する。
違いは、`run`は新しいコンテナを作成するのに対し、`exec`は既存のコンテナに入る。
※`bundle exec`を使用すると、Bundlerに従って正しいバージョンの`rspec`が使用されることが保証される。
```
~~ 0 failures
```
と表示されたら成功。
## 7. コミット・プッシュ
1. `git add file_name`
   ステージング
2. `git commit -m 'message'`
   コミット
3. `git push origin branch_name`
   ローカルのブランチをリモートリポジトリ（通常は`origin`）に`push`する。

`add` / `commit` / `push` の前に`git status`でステージング漏れがないかチェックすると良い。

ちゃんと`commit`できたか不安なら`git log`でコミット履歴を表示できる。
また、`git log -p file_name`で、詳細な変更履歴を見ることができる。

## その他注意事項
### 所有者の変更
「Docker上で生成されたファイルは、所有者が異なるユーザーになっており、そのままでは編集できません。」の場合がある。
権限と所有者は`ls -l [directory_name]`コマンドで確認できる。
所有者の変更は、ルートディレクトリで`sudo chown -R $USER ./`でできる。
`./`：現在のディレクトリを、`sudo`：管理者権限で、`chown`：`change owner`するよ、`-R`：再帰的に（ファイルとサブディレクトリも）。`owner`は`$USER`：現在ログインしているユーザーにしてね。
# 終わりに
書くことで頭の中でまとまったかな！と思います。見返せるし。
今日中に追記あればしていく予定！
あと、Docker / Git がいい感じにまとまってるサイト、おすすめの本、他経験談などあればお聞きしたい！TwitterでもQiitaでも。
お待ちしております。
Javaプログラミングにおけるリテラル

Javaにおけるリテラルは、ソースコード内に直接記述される固定値を指します。これらのリテラルは、プログラム実行中に変化することがない値で、プログラムの中で様々な目的で使われます。リテラルの使用は、プログラムの可読性を高め、意図した操作を明確にするために重要です。


## 目次
- [整数リテラル](#整数リテラル)
- [浮動小数点数リテラル](#浮動小数点数リテラル)
- [文字リテラル](#文字リテラル)
- [文字列リテラル](#文字列リテラル)
- [ブールリテラル](#ブールリテラル)
- [特殊リテラル](#特殊リテラル)
- [リテラルの利点と制約](#リテラルの利点と制約)
- [まとめ](#まとめ)


### 整数リテラル
整数リテラルは、日常で最も一般的に使われるリテラルの一つです。10進数、8進数、16進数、2進数の形式があり、通常の数値の表現に使われます。例えば、10進数の整数リテラルは「123」のように書かれ、8進数は「017」のように先頭に0を付けて表現されます。16進数リテラルは「0x7F」のように「0x」で始まり、2進数リテラルは「0b1010」のように「0b」で始まります。これらの異なる形式は、特に計算機科学やエンジニアリングの分野で重要です。

### 浮動小数点数リテラル
浮動小数点数リテラルは、小数点を含む数値を表現するために使用されます。これには「double」と「float」の2つの型があります。例えば、「3.14」や「-2.5」などがこれに該当します。浮動小数点数リテラルは精度が重要な科学計算や金融計算でよく使われます。

### 文字リテラル
文字リテラルは、シングルクォート（' '）で囲まれた単一の文字を表します。例えば、「'a'」や「'\n'」（改行文字）が文字リテラルです。文字リテラルは、テキストの処理や表示において重要な役割を果たします。

### 文字列リテラル
文字列リテラルは、ダブルクォート（" "）で囲まれた文字のシーケンスです。これには文字、数字、特殊文字、空白などが含まれます。例えば、"Hello, World!"や"Java programming"などが文字列リテラルです。文字列リテラルは、ユーザーインターフェイス、メッセージ、テキスト処理など、広範囲にわたる用途に使用されます。

### ブールリテラル
ブールリテラルは、真偽値を表す「true」と「false」の2つの値です。これらは、条件分岐やループ制御などの論理的な決定に使用されます。例えば、「boolean isJavaFun = true;」はブールリテラルを使用しています。

### 特殊リテラル


### 特殊リテラル

特殊リテラルには、主にnullリテラルとエスケープシーケンスを使った文字リテラルがあります。nullリテラルは、オブジェクトが存在しないことを示すために使用されます。例えば、「String myString = null;」は、myStringがまだどの文字列オブジェクトも指していないことを意味します。

一方、エスケープシーケンスを使った文字リテラルは、通常の文字では表現できない特殊な文字を表します。例えば、「\n」は改行を表し、「\t」はタブを表します。

### リテラルの利点

リテラルを使用することの利点は、プログラム内で値を直接、明確に表現できることです。変数名や定数名を使う代わりに、リテラルを使うことで、その値がプログラムのどの部分で使われているかを簡単に追跡できます。また、リテラルを使うことで、コードの読みやすさや保守性が向上します。

### リテラルの制約

ただし、リテラルには制約もあります。リテラルは固定値なので、プログラム実行中にその値を変更することはできません。また、大きな数値や複雑な文字列を扱う場合、リテラルの使用はコードを読みづらくする可能性もあります。そのため、適切な場合に適切な方法でリテラルを使用することが重要です。

### まとめ

Javaのリテラルは、プログラムの中で直接使われる固定値を表し、その使い方にはさまざまな種類があります。これらのリテラルは、プログラムの可読性を高めるために重要な役割を果たしますが、その使用方法には注意が必要です。
【iPhone画面開発】Safariで高さを vh指定するのは危険⚠️

最近iPhone画面を開発しております。
開発が完了し、実際にアプリをデプロイ。
それをSafariで確認すると、なんと高さがうまくあわない、、という事象が発生しました。
ただし、GoogleとかLineからアプリを確認しても問題ない。。。

Safariが悪いんだなあと思いながら色々調べてみると、対応策が見つかりました。

# 何が起こっているのか
下の図のようにSafariでWebを開くと、画面上部と画面下部にiPhone特有のエリアがあります。
私の場合、cssでheightをvh指定することで、画面いっぱいに伸ばし、はみ出すとスクロールバーを表示、という想定でしたが、SafariではiPhone特有のエリアを含んだ状態でfitするようになってました。

ちなみにvhは「viewport height」の略で、vhを100vhとすることでviewport全体を覆うことが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749685/d0c599fd-af72-cc03-0334-575314f03a16.png)

# 対応
対応ですが、vhではなく別のviewportの単位dvhを使い解決できました。

```css
// 全体を囲うスタイル用class
.container {
    // この指定だけでOK
    height: 100dvh;
}
```

dvhはDynamic Viewpoerの略で、動的に画面が拡大、縮小される原因となるパーツ（Safariの下のエリアなど）が画面の中に入ると、それを動的に考慮してviewportサイズを調整してくれるとのこと。

原因は不明ですが、Safariではvh指定をすると下のパーツなどを考慮してくれないっぽいので気をつけたいですね。
調べてみると、他にもlvh,svhなどがあるそうで、もしかするとvhの指定自体を使うべきではないかもしれませんね。

Safariさん、勘弁してください。。

以上。
スプレッドシートで考えるプログラム

## ITスキルをつけるためには？
下記の実施環境はAndroid携帯で完結するので是非実践してほしいです。
１．普段からプログラム目線で見るためにメモはスプレッドシートを使う
２．手を動かすため、書き溜めた計算を使えるようにPython変換してみる
という手順を４つの動画にまとめました。

## Googleスプレッドシートをメモとして使おう
スプレッドシートをメモとして使うことの意義について、トイレットペーパーの単価計算をもとに考えてみる

https://youtu.be/WHw2dQFGPrw

## Googleスプレッドシートをインストール
Googleスプレッドシートをインストールして簡単な計算を入力してみます。

https://youtu.be/C_3Hjfy2sgE

## スプレッドシートにトイレットペーパーの単価計算を入れる
スプレッドシートにトイレットペーパーの単価計算を入れて計算部分をpythonに置き換えてみる

https://youtu.be/7JaXqOGDuWU

## 比較できるようにするには？
具体的にスプレッドシート表をPythonプログラムに置き換えてみる

https://youtu.be/xXjWQmmGK_I

## おまけ
アンドロイド携帯でpythonを使えるようにする

https://youtu.be/ftJbVRI8ZLU

iPhoneではa-Shellというアプリからpythonを起動できるようです。
mermaid つかってみる

```mermaid
%%{init: {'theme':'themeVariables': { 'pie1': '#FFFFFF', 'pie2': '#FFFF00', 'pie3': '#00FF00', 'pie4': '#0000FF', 'pie5': '#800080', 'pie6': '#ff0000', 'pie7': '#FFA500'}}}%%
pie
  "White" : 5
  "Yellow" : 20
  "Green" : 30
  "Blue" : 10
  "Purple" : 10
  "Red" : 20
  "Orange" : 5
```
jsdom の HTMLDialogElement APIの対応状況について

# 結論 
showModalは対応していますが、close,showは対応していないと思われます。
showModalが使える理由が不明です。

showModalも使えなかったです、という方いらっしゃいましたら教えて頂けますとありがたいです。。

# 1. 背景

```
jest-environment-jsdom version:29.5.0
                   |- jsdom version: 20.0.3
```

showModal()は使用できてclose()は使用できないので状況を一旦整理しようと思った為です。

```ts
const dialogElm = document.querySelector('dialog');
dialogElm.close();
// TypeError: dialogElm.close is not a function
```

# 2. jsdomのissue

jsdom version: 18.1.0

https://github.com/jsdom/jsdom/issues/3294

show,showModal,close全て対応していないことが伺えます。

# 3. jsdomのPull request

https://github.com/jsdom/jsdom/pull/3403

# 3. jsdom 20.0.3 で実際にAPIを呼び出してみる

jest-environment-jsdomの最新版もjsdomのバージョンは同じでした。

```
─┬ jest-environment-jsdom@29.7.0
│ ├── @jest/environment@29.7.0
│ ├── @jest/fake-timers@29.7.0
│ ├── @jest/types@29.6.3
│ ├── @types/jsdom@20.0.0
│ ├── @types/node@14.18.48 deduped
│ ├── canvas@2.11.2 deduped
│ ├── jest-mock@29.7.0
│ ├── jest-util@29.7.0
│ └── jsdom@20.0.3
```

- showModal
    - 対応済？
    - TypeErrorにならず、modalが開いているか確認するテストも通ってしまいました。

以下の処理を通してからテストを実行しました。
```ts:Dialog.ts
static openDialog() {
        const dialogElm = document.querySelector('dialog');
        dialogElm.showModal();
}
```

```ts:test
test('Dialogが見える', () => {
        const dialogElm = document.querySelector('dialog');
        expect(dialogElm.open).toBe(true);
});
```

- close
未対応
- show
未対応
Macbook放置しちゃって時間ずれた

経緯
-
普段デスクトップだけど、外出でノーパソないと何もできないってなって、導入したおにゅーのMacBookAir、しばらく外出の予定もなかったので1ヶ月近く放置してました...ごめん
またやってしまった時のために残します。（時間ある時にもう少し記事見やすくしたい）

まず、出てくる不具合
・Chromeブラウザで時計のエラー「時間がずれています」で、サイトが開けない
・メールからimap.gmail.comの警告
なんかGoogle関連が多い？？safari苦手でchrome使いがちだからかも。。

原因
・充電切れたまま長時間の放置（きっとこれ絶対これごめん）

解決方法
-
とりあえず一番最初に検索にかかった記事を試したら解決しました。
ありがとうございます。(参考url↓)
https://zenn.dev/ssk_ats/articles/f790a1456d0458
https://discussionsjapan.apple.com/thread/252960467?sortBy=best

試した後で、🍎「システム設定」＝＞「一般」＝＞「日付と時刻」
で自動設定をオフにして再起動してオンにするとなおったも見かけたから、
調べてみて先にそっち試しても良いかも。(ハードル低め)

ここからはターミナルを開いて作業。

具体的なコマンド
//com.apple.timed.plistを消す
(必要性はわからないけどした。今のところ不具合はないけど怖い時は飛ばしてもいいかも？)
```
sudo rm /var/db/timed/com.apple.timed.plist 
```
//時間の確認
(後に出てくるコマンド打った後に変更確認できる)
```
ps -ef | grep timed
```
//時間を合わせる
ntp.nict.jpは日本の時間のサーバーらしい。
そもそもこの問題自体がntpサーバーと同期できなくなってることで起きている...
```
sudo sntp -S ntp.nict.jp
```
または、
```
sudo sntp -sS ntp.nict.jp
```
再度確認コマンドを試すと、一番下のgrep timedが正しい時間に変わってた。

//正しくない時間を消す
/usr/libexec/~の時間がずれているみたいだったからkillコマンドで強制終了した
```
sudo kill 「ずれているところの左から二番目の数字」
```

//PCを再起動する
私はコマンドを打った後に再起動忘れてて、
スリープするたびに時間がずれて心折れそうになった。

最後に
-
長期間放置するならせめて充電切れじゃなくて、電源切っておこう。
ちゃんと外に出よう。
Macに慣れたい_1

**初めてMacOSを触るので
基本的なショートカットとコマンドまとめ**

+ スクリーンショット `command + shift + 3`
+ 画面録画 `command + shift + 5`
:::note info
不安なときは自分がした操作の記録を取るべしと教わった。
:::

VSCodeをcodeコマンドで開けるようにする
1. VSCodeでコマンドパレットを開く`command + shift + p`
2. `shell command`と入力して`シェルコマンド：PATH内に'code'コマンドをインストールします`を選択。
これでもうターミナルから好きなディレクトリに移動して`code .`でVSCodeで開ける

VSCode公式ドキュメント
> https://code.visualstudio.com/docs/setup/mac

Homebrew`brew -v`
> https://original-game.com/how-to-install-homebrew/
2024/1/22主にITとかセキュリティの記事

御社は大丈夫!? 中小企業の4割以上がサイバー攻撃を受けた経験あり(1/20)
https://ascii.jp/elem/000/004/180/4180423/?rss

Microsoft、ロシアのハッカーが幹部メールに侵入と発表(1/20)
https://www.nikkei.com/article/DGXZQOGN200AU0Q4A120C2000000/

MSにサイバー攻撃、ロシア関与　幹部メールなど流出か(1/20)
https://www.47news.jp/10415717.html

【Windows10】Update：KB5034441の0x80070643エラー対処備忘録（2024年1月）(1/19)
https://qiita.com/ryuml/items/06235fc1c4c367b906a6

ウェブサイトに侵入してくる相手にZIP爆弾を送りつけて撃退する方法(1/20)
https://gigazine.net/news/20240120-how-to-defend-your-website-with-zip-bombs/

日本とNATO、安保情報を迅速共有 専用回線を検討(1/20)
https://www.nikkei.com/article/DGKKZO77828000Q4A120C2MM8000/

中国発の越境オンライン通販「Temu」の安全な使い方(1/20)
https://news.mynavi.jp/techplus/article/20240120-2866177/

ブロックチェーンのビジネス活用法は？メリットや活用事例を紹介(1/19)
https://xrcloud.jp/blog/articles/business/3442/

友人がメルカリの偽サイトに引っ掛かる → “意外の理由”で致命傷を避けられた話に身が引き締まる(1/20)
https://news.yahoo.co.jp/articles/8e50f744262c5c56277e2e26cde3a9fdd414a657

レムチャバン港、LCITにサイバー攻撃(1/22)
https://www.jmd.co.jp/article.php?no=292917