OmniAICreator/Qiita-1.07M huggingface dataset:
Rのquantedaで始める日本語分析(LDA)

## はじめに
Rのパッケージであるquantedaを用いて日本語のテキストマイニングを行いたいと思いましたが、ドンピシャで自分にハマる記事を見つけられませんでした。なので自分で書きたいと思います。

参考ページではAPIでデータのダウンロードを行っていますが、汎用性を意識して、ここではcsv形式を用いて分析をしてみます。

(*初投稿です。日本語が拙かったらすみません...)

参考にしたサイトは以下のquanteda公式のクイック・スタートガイドです。
[事例: 衆議院外務委員会の議事録](https://quanteda.io/articles/pkgdown/quickstart_ja.html)

## 必要なパッケージの読み込み
参考ページをコピペ＋csvを読み込む時に使う"tidyverse"を読み込みます。
もし過不足あれば、コメントしていただけると幸いです。
```R:package
library(quanteda)
library(stringr)
library(lubridate)
library(topicmodels)
library(tidyverse)
```

## データの読み込みとコーパスの作成
必要なデータを読み込みます。私は研究で用いている市議会の発言内容のcsvファイルを読み込んで使いました。
読み込んだcsvファイルをコーパスにするところまで一気にしてしまいます。

```R:コーパス作成
df <- read_csv("sample.csv")
my_corpus <- corpus(df, text_field = "(分析テキストの入った)カラム名", docid_field = "行番号")
```

## トークン化
ここでは、読み込んだコーパスをトークンにしています。基本的なコードは、quanteda公式のクイックスタートガイドそのままです。

```R:トークン化
toks <- tokens(my_corpus)
```

```r:ノイズの削除
toks <- tokens_select(toks, "^[０-９ぁ-んァ-ヶー一-龠]+$", valuetype = "regex", padding = TRUE)
toks <- tokens_remove(toks, c("御", "君"), padding = TRUE)

min_count <- 10

# 漢字
library("quanteda.textstats")
kanji_col <- tokens_select(toks, "^[一-龠]+$", valuetype = "regex", padding = TRUE) |> 
             textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, kanji_col[kanji_col$z > 3,], concatenator = "")

# カタカナ
kana_col <- tokens_select(toks, "^[ァ-ヶー]+$", valuetype = "regex", padding = TRUE) |> 
            textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, kana_col[kana_col$z > 3,], concatenator = "")

# 漢字，カタカナおよび数字
any_col <- tokens_select(toks, "^[０-９ァ-ヶー一-龠]+$", valuetype = "regex", padding = TRUE) |> 
           textstat_collocations(min_count = min_count)
toks <- tokens_compound(toks, any_col[any_col$z > 3,], concatenator = "")

```

## 文書行列の作成
ここも基本的には参考ページのまま

```r:文書行列の作成
speech_dfm <- dfm(toks) |>
  dfm_remove("") |> 
  dfm_remove("^[ぁ-ん]+$", valuetype = "regex", min_nchar = 2) |> 
  dfm_trim(min_termfreq = 0.50, termfreq_type = "quantile", max_termfreq = 0.99)
```

## LDA分析
ldaの分析に入ります。トピック数は任意ですが、ここでは10にしておきます。
lda分析がたったコード３行で終わるとは、すごいですね。

```r:lda
set.seed(100)
    lda <- LDA(convert(speech_dfm, to = "topicmodels"), k = 10)
get_terms(lda, 10) |> knitr::kable()
```

## 最後に
ここでは何のデータを使っているか明記していない手前、分析方法はLDAのみにしました。ただ、公式クイックスタートガイドにはLDAに他に、相対頻度分析や狂気ネットワーク分析などもありました。反響があれば書いてみたいですね。

今私の研究室で、地方議会(主に近畿地方の市議会)を対象としたデータベースの構築中です。
このDBが完成したら、DBからダウンロードしたデータを用いた分析用に書き直そうかな。と構想中です。
OpenCV.jsをChrome拡張で動かすためにはDYNAMIC_EXECUTION=0でビルドする

# まとめ
OpenCV.jsを「DYNAMIC_EXECUTION=0」を指定してビルドすることで、Manifest V3でも利用できるOpenCV.jsを手に入れることができる。

# 解説
## OpenCV.jsを手っ取り早く利用する方法
公式サイトによるとOpenCV.jsを利用する方法として公式サイトに用意されているファイルをダウンロードして利用するというのが案内されている。

https://docs.opencv.org/4.9.0/d0/d84/tutorial_js_usage.html

## Chrome拡張(Manifest V3)ではevalやnew Functionが禁止されている
しかしダウンロードしたファイルをChrome拡張で利用しようとするとエラーとなる。これはManifest V3でevalやnew Functionが禁止されているために発生する。

https://developer.chrome.com/docs/extensions/develop/migrate/improve-security?hl=ja#remove-execution-of-strings

対応方法としてサンドボックス化されたiframeを用意するというのが案内されている。その中であればeval等も禁止されていない。
この方法で利用する方法はすでに記事になっている。

https://qiita.com/Freedom645/items/74dbff34c3ffd8d3a9fd

## Emscriptenのオプションでevalとnew Functionを避けられる
Emscriptenのオプションを調べていくと「DYNAMIC_EXECUTION=0 」evalとnew Functionを利用しないようにするというそのものズバリなものが存在する。

https://emscripten.org/docs/tools_reference/settings_reference.html#dynamic-execution

一部の連携向けの機能やオプションが利用できなくなるというのもあるが、OpenCV.jsをちょこっと使う程度のことであれば恐らく問題ない。

## OpenCV.jsのビルド環境を整える
OpenCV.jsのビルドはdockerでも提供されておりかなりお手軽に実行することができる。

https://docs.opencv.org/4.9.0/d4/da1/tutorial_js_setup.html

おまけとして [platforms/js/opencv_js.config.py](https://github.com/opencv/opencv/blob/master/platforms/js/opencv_js.config.py) を編集して必要なモジュールだけをビルドするようにすることができるので色々と削るとファイルサイズの削減につながる。

`opencv_js.config.py` の編集を済ませたらあとはコマンド一発でビルドできる。以下は私がビルドした際のコマンドなので参考までに。

```powershell:Power Shell
docker run --rm --workdir /src -v "$(get-location):/src" "emscripten/emsdk:2.0.10" emcmake python3 ./platforms/js/build_js.py build_js --disable_single_file --build_flags="-s DYNAMIC_EXECUTION=0 -s ENVIRONMENT=web -s EXPORT_ES6=1 -s MODULARIZE=1 -s FILESYSTEM=0 -s INCOMING_MODULE_JS_API=[] -s INVOKE_RUN=0"
```

## OpenCV.jsを利用する
私の場合はChrome拡張をTypeScriptで実装しており、また動作オプションによってはOpenCV.jsを利用しない場合もあったので動的に読み込む必要があった。以下に参考となるコードを書いておく。

```ts:OpenCV.ts
let cv: any;

export const initOpenCV = async (): Promise<void> => {
    if (cv) return Promise.resolve();

    const url = chrome.runtime.getURL("opencv_js.min.js");
    const module = await import(/* @vite-ignore */ url);
    cv = await module.default();
    return Promise.resolve();
};
```
```ts:背景差分で物体抽出を行うコード断片
    // 初期化
    frame = new cv.Mat(canvas.height, canvas.width, cv.CV_8UC4);
    fgmask = new cv.Mat(canvas.height, canvas.width, cv.CV_8UC1);
    fgbg = new cv.BackgroundSubtractorMOG2(500, 16, true);

    ...

    // 検出処理
    const ctx = canvas.getContext("2d", { alpha: false, willReadFrequently: true })!;
    const uint8ClampedArray = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    frame.data.set(uint8ClampedArray);
    fgbg.apply(frame, fgmask);
    cv.imshow(output, fgmask);
```

TypeScriptでの型情報をOpenCV.js関係のパッケージから拝借してくる手もあるがそこまで大規模な処理にならないなら割り切ってしまってもイイと個人的には思う。
client is using an unsupported version of the Socket.IO or Engine.IO protocolsの対処方法

#### 現象
PythonのFlask socketioを使って、Javascriptとデータのやりとりをしようとしたところ、以下のエラーが発生：
The client is using an unsupported version of the Socket.IO or Engine.IO protocols

#### 確認
エラーが発生した環境の各モジュールバージョン

＜Python側＞
Flask-SocketIO==5.3.6
python-engineio==4.8.1
python-socketio==5.10.0

＜Javascript側＞
Socket.IO v2.2.0

＜バージョン互換性の確認＞
https://python-socketio.readthedocs.io/en/latest/intro.html

#### 原因
過去のコードをそのまま流用したので、JavascriptのSocket.IOとPython環境のバージョンが合ってなかっただけでした・・・。

#### 対応方法

2024年1月現在、Socket.IOのリリース済みバージョンを調べると( https://socket.io/docs/v4/client-installation/ ) 最新版は4.7.4なので、最新版を使用するようにindex.htmlのscriptを変更：
```
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.4/socket.io.min.js"></script>
```
(使うのはこれじゃなくてもいいのかな。
Javascript超初心者なので何を基準に選べばいいのか分かりません。)

無事「emit」と「on」のやりとりを確認できました。
JetpackComposeテキストをコピーする方法


JetpackComposeでボタンをタップした時などに特定の文字をコピーする方法です。

サンプルコードがこちらです。

```CopyButton.kt
@Composable
fun CopyButton() {
    val clipboardManager: ClipboardManager = LocalClipboardManager.current
    Button(
        modifier = Modifier.fillMaxWidth().height(56.dp),
        onClick = { clipboardManager.setText(AnnotatedString("コピーするテキスト")) }
    ) {
        Text(text = "コピーする")
    }
}

```

`LocalClipboardManager`から`ClipboardManager`を取得できます。
`ClipboardManager`のsetTextに`AnnotatedString`を設定することでコピーする事ができます。

JetpackComposeでテキストをコピーする方法はシンプルにできますね！

# リファレンス

https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ClipboardManager

https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#LocalClipboardManager()
Ruby on RailsにおけるN+1問題

## 概要
N+1問題は、1つのクエリによって複数のレコードを取得した後、
各レコードに対して関連するデータを取得するために追加のクエリが必要になる状況を指します。

N+1問題が発生すると、データベースへのアクセス回数が余計に多くなってしまいます、それはデータベースに対するクエリの数が大幅に増加するからです。

## N+1問題の原因

N+1問題が発生する原因は、データモデル間のアソシエーション・関連にあります。
Ruby on Railsでは、データモデル間にアソシエーションを定義することで、関連するデータを取得することができますよね？

### 具体例

1.ブログアプリケーションで、すべての記事を取得し、
2.それぞれの記事に対して投稿者の情報を表示する必要があるとします。
一見、効率的に見えるこの操作が、実際には非効率的になることがあります。

ステップ1: すべての記事を取得するためのクエリ。
ステップ2: 各記事に対して、投稿者情報を取得するための追加クエリ。
ここで問題となるのは、ステップ2での繰り返しクエリです。記事の数が多いほど、データベースへのクエリ数が増加し、パフォーマンスが低下します。

```Ruby
# ArticleモデルとUserモデルがあると仮定します
# ArticleモデルはUserモデルに属しているとします（belongs_to :user）

# ステップ1: すべての記事を取得
@articles = Article.all

# ステップ2: 各記事に対して投稿者情報を取得
@articles.each do |article|
  puts article.title
  puts article.user.name  # ここで各記事ごとに追加のクエリが発生
end
```
このコードでは、Article.allによってすべての記事を取得した後、
各記事に対してarticle.userを呼び出すたびに、その記事の投稿者（User）をデータベースから取得するための追加のクエリが実行することになります。
記事の数が多い場合、データベースへのクエリ数が大幅に増加し、パフォーマンスが低下します

N+1問題を初心者にもわかりやすく説明するために、スーパーで買い物をする例を挙げると、レジで商品を1点ずつ会計するよりも、カゴごと会計したほうが効率的です。
要はまとめてくれってことですね

## N+1問題の解決方法について取り組む

N+1問題を解決するには、関連するデータをまとめて取得するようにする必要があります。
Ruby on Railsでは、以下の方法でN+1問題を解決することができます。

**includes**
includes メソッドを利用することで、関連するデータをまとめて取得することができます。

```Ruby
@articles = Article.includes(:user).find(1)
```
このコードを実行すると、データベースから1の記事と、そのデータに関連するUserデータをまとめて取得します。

**eager_load**
eager_load メソッドを利用することで、関連するデータをまとめて取得することができます。

```Ruby
@articles = Article.eager_load(:user).find(1)
```

このコードも、includes メソッドと同様に、データベースから1のデータと、そのデータに関連するUserデータをまとめて取得します。

**preload**
preload メソッドを利用することで、関連するデータをまとめて取得することができます。

```Ruby
user = User.find(1)
user.preload(:articles)
```
このコードは、user インスタンスのオブジェクトスコープに、関連するデータをまとめてロードします。

## まとめ
N+1問題は、Ruby on Railsに限らず、データベースからデータを取得する際に発生する可能性のある問題です。
N+1問題を解決するためには、関連するデータをまとめて取得するように意識することが大切です。

データモデル間のアソシエーションを利用する際には、関連するデータをまとめて取得できるように設計する。
データベースからデータを取得する際には、関連するデータをまとめて取得するメソッドを利用するようにする。
などの対策が挙げられます。

N+1問題が発生すると、データベースへのアクセス回数が余計に多くなり、パフォーマンスが低下する原因となります。
頑張ってアソシエーションとクエリを意識してコードを書いてくようにしましょう！
【Rails】デプロイ時にロードバランサーのタイムアウト値をカスタムするのだ

どうもこんにちは。

今回はRailsアプリケーションのデプロイ時にロードバランサーのタイムアウト値を自動で更新できるようにしました。

# 経緯

私の会社では、新しいバージョンをデプロイするときに、以下の流れで作業を行います。

1. RDSのデータをバックアップ
1. ElasticBeanstalkの環境をクローン（複製）する
1. EC2の画面から、ロードバランサーのアイドルタイムアウトの値を60秒→1200秒に変更する
1. ソースコードをデプロイする

60秒→1200秒へ変更する理由は、「動画ファイルなどの容量の大きなファイルをサーバーへアップロードするときに60秒以上が経過してしまうと504ステータスエラーが発生してしまう」からです。

つまり、動画ファイルをアップロードしている途中にサーバーが通信をストップしてしまうということです。

# ebextensionsを使用する

今回はebextensionsを使用してカスタムを行いました。

ebextensionsとは、Elastic Beanstalkでの環境構築時に環境をカスタマイズする設定ファイルを配置するディレクトリです。

これを使用することで、AWSコンソール上でポチポチ設定を変更する必要がなくなります。

# 手順

## 1. .ebextensionsというディレクトリを作成

プロジェクトのルートディレクトリに移動して、以下のコマンドを叩いてください。

```sh
mkdir .ebextensions
```

### 2. 任意の名前でconfigファイルを作成

```sh
touch load_balancer.config
```

### 3. 設定値を記述

YAML形式で設定値を記述します。

```config
option_settings:
    aws:elb:policies:
        ConnectionSettingIdleTimeout: "1200"
    aws:elbv2:loadbalancer:
        IdleTimeout: "1200"
```

これで`git commit`して`eb deploy`を叩けばデプロイできます！

# 補足

## aws:elb:policiesとaws:elbv2:loadbalancerの違い

### aws:elb:policies

Elastic Beanstalkの環境設定の一部として使用されます。
Elastic Beanstalkが管理するロードバランサーの設定に影響を与えます。

### aws:elbv2:loadbalancer

Amazon Elastic Load Balancing (ELB) の設定の一部として使用されます。
ELBが管理するロードバランサーの設定に影響を与えます。
pythonでAES暗号化する方法：②Crypto編

# やりたいこと
pythonでAES（共通鍵方式）でパスワードの暗号化・複号化したい

# 前提
・Pythonインストール済み
・PyCryptodome インストール済み

※Cryptoは以前はcryptoライブラリで動いてたのですが、2024/01現時点では、cryptoではもう動けないらしくて、PyCryptodomeでやりました。

※すでにcryptoを入れてる人は、cryptoをアンインストールしないとうまくいけないので、エラーで落ちたらcryptoをアンインストールしてください

# やり方
さっそく調べた内容をソースコードで作りました

CryptoのAESは128, 192, 256 bitなどの鍵を生成でき、CBCやECBなどいろんなモードを対応できるようです。

今回はCBCモードを採用しました！

暗号化複号化するときは、パラメータはbyte形式じゃないとだめなので、b64encodeへ変換しました・

```ruby:qiita.rb
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes


# 鍵の作成
def create_key():
    key = get_random_bytes(16)
    return b64encode(key).decode('utf-8')


# 暗号化する
def encrypt(key, data):
    key = b64decode(key)
    data = bytes(data, 'utf-8')
    cipher = AES.new(key, AES.MODE_CBC)
    ct_bytes = cipher.encrypt(pad(data, AES.block_size))
    iv = b64encode(cipher.iv).decode('utf-8')
    ct = b64encode(ct_bytes).decode('utf-8')
    return ct, iv


# 復号化する
def decrypt(key, iv, ct):
    key = b64decode(key)
    iv = b64decode(iv)
    ct = b64decode(ct)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    pt = unpad(cipher.decrypt(ct), AES.block_size)
    return pt.decode('utf-8')


password = 'password'
# 新しい鍵の作成
key = create_key()
# 新しい鍵のprint
print(key)
# 暗号化する
ct, iv = encrypt(key, password)
# 暗号化したパスワードのprint
print(ct)
# hash値のprint
print(iv)
# 復号化する
pt = decrypt(key, iv, ct)
# 結果確認のため、復号したものをprint
print(pt)
```

前回試したFernetと異なったのは、keyだけでなく、ivというHASH値みたいなものが暗号化複号化するとき必要となります。。。（二重鍵みたいなイメージかな）

keyとivは毎回同じものを生成しなくても大丈夫なので、以前作ったやつを覚えて流用するのはOkということです。

実際実行した結果はこちらです。
上から下は、鍵（str）、暗号化したパス（str）、iv（str）、複号化したパス（str）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/70b14a50-d2fb-7334-8bc3-88cae45dadc2.png)

# 終わりに
暗号化された値はFernetのやつより短いですね。。。


# 参照サイト
https://pycryptodome.readthedocs.io/en/latest/src/cipher/classic.html#cbc-mode

https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html
addEventListener()の使い方

# はじめに

クライアントJavaScriptでは、ブラウザ（window）操作・ドキュメント操作（DOM操作)・イベント・HTTP操作がある。
その中でもイベントハンドラはブラウザで起こったイベントが発生した時に実行される関数である。イベントハンドラを登録するには、以下の3つの方法がある。

1. <html>要素の属性に設定する。
2. DOM要素のイベントハンドラプロパティに設定する。
3. addEventListener()メソッドを使用

今回は３番目のaddEventListener()について、アウトプットする。


# addEventListener()メソッドとは
addEventListener()メソッドを使用することで、イベントオブジェクトを使用して、さまざまな処理を記述できる。
基本的には、以下のような構文で使用する。

```DOMオブジェクト.addEventListener("イベントの種類", 処理(関数))```

第1引数にイベントの種類を指定することで、このイベントがどのようなケースに対応するのかを特定。第2引数に関数を指定することで、任意のイベントが発生した時に関数内に書かれた処理を実行できる。

イベントには、以下のような種類がある。

![スクリーンショット 2024-01-19 15.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576805/bdcfef61-b635-ec6d-1880-9d79e3f866e1.png)


# 3種類の関数設定方法について
「addEventListener()」を記述する方法として、3種類の関数を設定する書き方があるのでまとめて解説する！　

#### 外部の関数を設定する方法

```

対象要素.addEventListener(種類, sampleEvent);

function sampleEvent() {

  //ここに処理を記述する
  
}
```


#### 無名関数を設定する方法
 ```
 対象要素.addEventListener(種類, function() {
  
  //ここに処理を記述する
  
}); 
```


#### アロー関数を設定する方法
```
対象要素.addEventListener(種類, () => {
  
  //ここに処理を記述する
  
}); 
```

# イベント処理の上書きについて
「addEventListener()」には大きな特徴が1つあります。それは、イベント処理が上書きされない。

addEventListener()を使ったイベント処理は、複数のイベントを追加することで同時に実行できる。
JSON Patchのpathにスラッシュを含んだフィールドを書きたい

# 問題

AKSのWorkload Identityを有効化するために、KustomizeのJSON Patchを使って`/azure.workload.identity/use`に`true`を設定したい。

素直に書くとこうなる：


```yaml
- op: add
  path: /spec/template/metadata/labels/azure.workload.identity/use
  value: "true"
```

しかしパッと見て違和感のあるとおり、パス形式の文字列にスラッシュを含む文字列を繋げているため、有効な形式にならない。

# 解決方法

GitHubのIssueで発見した[こちら](https://github.com/kubernetes-sigs/kustomize/issues/1256#issuecomment-535007229)の回答を参考にして、`/`を`~1`に置き換えて以下のように書く必要がある。

```yaml
- op: add
  path: /spec/template/metadata/labels/azure.workload.identity~1use
  value: "true"
```

# 参考

- https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview?tabs=dotnet#pod-labels
- https://github.com/kubernetes-sigs/kustomize/issues/1256#issuecomment-535007229
&nbsp;の使うべきタイミングっていつなの・・？

# $nbsp;とは
> NBSP（Non-Breaking Space）とは、コンピュータ上で扱う特殊な文字の一つで、前後での改行を禁じるスペース（空白）文字。処理系によってはスペース文字を複数並べたいときにも用いられる。
[NBSP（ノーブレークスペース）とは - 意味をわかりやすく - IT用語辞典 e-Words](https://e-words.jp/w/NBSP.html)

です。

# 使うべきタイミングっていつなの
これが色々考えましたが全く思いつきませんでした。
いつなんだ・・？

~~各要素の間に空白を開けたい！というときに使うのはなしとします。marginを使おう~~

## 前後の要素が横並びになっても、自動改行されない場合
この場合、上記の通りmarginで良いと思います。
わざわざ改行不可とする必要がありません。

## 前後の要素が横並びになると、本来自動改行される場合
この場合、後ろの要素は自動改行されませんが、それはつまり本来自動改行によって回避されるはずだった、他の要素と被っちゃうのでは・・？

ギリギリありそうなケースとしては要素を重ねたい場合とか・・？
（それもCSSでどうとでも出来る気がする）

# おわりに
と、いうことでしょうもない脳みそを頑張って働かせてみたのですが全く思いつきませんでした。
どなたか`&nbsp;`を使うのが最適なケースをご存知のかたがいたら教えてください！
何卒よろしくお願いします・・。

# おまけ
これについて調べたときに知ったのですが、他の種類もあるんですね。
勉強になった・・かもしれない。
[[HTML] スペースを表す特殊文字 | ぱそまき](https://pasomaki.com/html-space-special-char/)
C#の変数宣言いろいろ

## 参考
この記事は、下記の動画をもとに書いています。動画もご覧ください。

https://youtu.be/Sa184usBTXk?si=i9YYVqfaV9Qa11ld

## データ型を明示する
```C#
SomeClass v = new SomeClass();
```
以下の場合に、変数のデータ型を明示するために、この構文を使う。
- 変数のデータ型を、初期値のデータ型が実装するインターフェイスにしたい場合
- 変数のデータ型を、初期値のデータ型の基底クラスにしたい場合
- 初期値のデータ型が、コードから読み取りづらい場合

## varキーワードを使う
```C#
var v = new SomeClass();
```
以下の場合に、この構文を使い、変数のデータ型をコンパイラーに推論させる。
- 変数のデータ型は、初期値のデータ型と同じである場合

Visual Studioの以下の設定をすれば、推論したデータ型を`var`の後ろに表示させることができる。
- オプション → テキストエディター → C# → 詳細 → 「インライン型のヒントを表示する」にチェック → 「推論された型の変数のヒントを表示する」にチェック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293884/3192d076-9156-4493-90ae-d745e9114b31.png)

## データ型を明示し、new()で初期化する
```C#
SomeClass v = new();
```
- 変数のデータ型と同じ型のインスタンスを初期値とする場合
- C# 9以降で記述できる（ターゲット型のnew式）

## データ型（コレクション）を明示し、[]で初期化する
```C#
SomeCollection c = [];
```
- 変数がコレクションで、要素なしの状態で初期化する場合
- C# 12以降で記述できる（コレクション式）
- 配列や`List<T>`のように、データ型がコレクション初期化子に対応していれば、要素を持つコレクション式も記述できる
<AWS>なるべくお金をかけずVPCピアリングの検証をしてみた

ごきげんいかがですか

今回のテーマは「なるべくお金をかけずVPCピアリングの検証をしてみました」です

## 1.本記事の背景

プロジェクトでVPCピアリングをすることになったのですが、
その検証をすることになり、先輩のAWSアカウントで検証をすることになりました。

そこで、先輩から一つ重要なミッションを渡されました😎

それは、、、
**「なるべくお金をかけず、VPCピアリングの検証をすること」**

です。（笑）

なので、同期といろいろネットで調べながら一番お金をかからない方法で頑張ったので
ぜひ共有させてください！

## 2.検証環境の構築

まずは全体像として以下をイメージしてください。

EC2は各プライベートサブネットに一つずつ作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/0f8cf71b-fa09-e64c-b655-9056cfde6156.png)
画像出典（https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-peering.html）

ここでお金をかけずに工夫したことを二つ挙げます。

１つ、EC2を払い出すときは一番お金がかからないサービスで

２つ、プライベートサブネットをもちいる
　　　（疎通確認をするのに、セッションマネージャ―での接続が必要になります）

では、一つづつ見ていきましょう。


#### 2.1 VPCの作成

VPCは、二つ以下の画面ではらいだします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/700e5c4d-3def-e61a-3dc9-0be7bff99ce2.png)



#### 2.2 プライベートサブネットの作成

サブネットは二つ、先ほど作成したVPCにそれぞれ紐づけて作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/96e1d404-9c89-1205-195c-089ca371de57.png)



#### 2.3 EC2の払い出し

EC2を先ほど作成した二つのプライベートサブネットにそれぞれ作成します。

AMIは無料のものを選択します😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/df3a5335-07d4-5f3a-c84a-6be02e1b35b0.png)

インスタンスタイプも無料のものを選択します😊
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/84008681-ff03-b5ec-648e-3dc3cb9224b4.png)


セキュリティグループもついでに作成しましょ、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/beccd1bf-95cf-68d1-6257-e5a0b05dbf3d.png)


#### 2.4 IAMロールでセッションマネージャーの許可を追加

セッションマネージャーを許可するIAMロールを作成しましょう
そしてそれを、先ほど作成したEC2にアタッチします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/087a4486-2b1f-279b-349a-2cc77cf3e11f.png)

これで土台は整いました。

## 3.VPCピアリングをしてみる

#### 3.1　VPCピアリング設定作業

以下の画面でピアリング接続を作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/c1ad2654-af9f-7d9a-1684-5ceea6da0456.png)


#### 3.2 ルートテーブルの編集、セキュリティグループの編集

ルートテーブルをそれぞれのVPCで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/9b2eaf57-c517-fa09-5d9d-cea75b2f303f.png)

セキュリティグループもちゃんとお互いのEC2が疎通できるように設定してあげましょう👍

## ４．セッションマネージャーで疎通確認

プライベートサブネット内でEC2を作成してるので、疎通確認をするのにセッションマネージャーを用います。

では、マネジメントコンソールでSession Managerの画面にいきます。
ターゲットインスタンスに、作成したEC2が見えると思います😉

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583957/2d91b8e8-12df-0f05-d001-f8fe601767e3.png)

セッションをスタートさせてpingで疎通が成功したら完了です！

## 5.さいごに

ここまでなるべくお金をかけずにVPCピアリングの検証をしてきました。

そして、「検証完了しましたー」と先輩に報告し楽しい年末を迎えました🤞


そして年が明けて、
上司とTeamsで話していると、、、
**「使用したサービスを消すのを忘れていて、3ドルかかってました」**
とのことでした（笑）

ぼくが検証を終わったあと、使用したサービスを消せばよかったです😂
結局お金がかかってしまいましたが、勉強になりました。

ありがとうございます！！
pythonでAES暗号化する方法：①cryptography.fernet編

# やりたいこと
pythonでAES（共通鍵方式）でパスワードの暗号化・複号化したい

# 前提
・Pythonインストール済み
・cryptographyライブラリインストール済み

# やり方
さっそく調べた内容をソースコードで作りました
cryptography.fernetは**AES128**で**CBC**モードで暗号化複号化しているらしいです。
暗号化複号化するときは、パラメータはbyte形式じゃないとだめなので、strをbyteへ変換しました・


```ruby:qiita.rb
from cryptography.fernet import Fernet


# 鍵作成
def create_key():
    key = Fernet.generate_key()
    print(key)
    print(key.decode('utf-8'))
    return key.decode('utf-8')


# 暗号化する
def encrypt(key: str, data: str):
    fernet = Fernet(bytes(key, 'utf-8'))
    encrypted_pass = fernet.encrypt(bytes(data, 'utf-8'))
    print(encrypted_pass)
    print(encrypted_pass.decode('utf-8'))
    return encrypted_pass.decode('utf-8')


# 復号する
def decrypt(key: str, data: str):
    fernet = Fernet(bytes(key, 'utf-8'))
    decrypted_pass = fernet.decrypt(bytes(data, 'utf-8'))
    print(decrypted_pass)
    print(decrypted_pass.decode('utf-8'))
    return decrypted_pass.decode('utf-8')


password = 'password'
print(password)
key = create_key()
encrypted_pass = encrypt_password(key, password)
decrypt_password(key, encrypted_pass)


```
結果をprintすると、このようになります。
上から下までは、パスの初期値、鍵（バイト）、鍵（str）、暗号化したパス（バイト）、暗号化したパス（str）、複号化したパス（バイト）、複号化したパス（str）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/614e737f-7817-5fea-21c2-1108884d7d80.png)

ちなみにですが、鍵は毎回新しいものを作る必要がなくて、以前作ってたものを覚えて流用するもの大丈夫とのことでした。

# やり方
暗号化をかけたら、値が結構長くなりましたね。。。


# 参考サイト

https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet.generate_key
新規登録できないを解決　Unpermitted parameters: :~

タスク管理アプリの開発中、新規タスク登録画面での問題に直面しました。全項目を記入して、「登録する」ボタンを押しても、入力したはずの項目が空欄に戻り、バリデーションエラーが発生していました。

## 問題の原因
ターミナルでログを確認したところ、以下のようなエラーメッセージが赤文字で表示されていました。

```
Unpermitted parameters: :空欄になってしまったパラメーター名
```
このメッセージは、コントローラーのストロングパラメーターに、必要なパラメーターが含まれていないことを示しています。

## 解決策
問題を解決するために、コントローラーファイルのストロングパラメーターを以下のように修正しました。
```
private
  def task_params
    params.require(:task).permit(:title, :content, :deadline_on, :priority, :status)
  end
```
この変更により、新規登録画面でのデータ登録が正常に行えるようになりました。
熊猫(Pandas)と和解せよ

# はじめに

本投稿は、社内勉強会を目的に作成した資料をまとめたものです。

一通りの資料は、下記からダウンロードすることができます。

https://github.com/matsu2254/study/tree/main/material/20240112_pandas_nyumon

今回の勉強会では、pythonの知識はあるが、Pandasに触ったことがない人をターゲットとしています。

ふらっとさらっとPandasの概要を説明後、notebookを一通り実行しながら理解を深めます。


## スライド

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRyZL93vpkRQ5YyBBXUPwCWy6Bj7CocyoQV_6rLvi6d4D5KKx9fJsU6ko7M0U_mNJ9w3dCPc1aan5Bp/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

## notebook

あまり込み入った説明をしないので、下記サイトなどを参考に、各自自分の言葉としてしゃべれるようにする。

https://note.nkmk.me/pandas/

https://qiita.com/kaita_kakihara/items/bf66e9e4927a3e3589e4


### 入門

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](http://colab.research.google.com/github/matsu2254/study/blob/main/material/20240112_pandas_nyumon/notebook/pandas_nyumon.ipynb)

https://gist.github.com/matsu2254/e08e3f3b47cf839f71907b1b71067d90

---

### 応用（１）

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](http://colab.research.google.com/github/matsu2254/study/blob/main/material/20240112_pandas_nyumon/notebook/zissen1.ipynb)

https://gist.github.com/matsu2254/c1f4121fa43c15f7ed132234e9c01b6a

---

### 応用（２）

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](http://colab.research.google.com/github/matsu2254/study/blob/main/material/20240112_pandas_nyumon/notebook/zissen2.ipynb)

https://gist.github.com/matsu2254/4c559cb3992e9a5388eaaab00b701bec

---
# 参考文献

あちこち書いている参考サイトをまとめ

notebook各所の説明はChatGPTに書いてもらったものをちょくちょく直して掲載している。

## pandasについて

https://pandas.pydata.org/docs/getting_started/index.html

https://ja.wikipedia.org/wiki/Pandas

https://note.nkmk.me/pandas/

## titanicデータセットについて

https://atmarkit.itmedia.co.jp/ait/articles/2007/02/news016.html

https://qiita.com/kaita_kakihara/items/bf66e9e4927a3e3589e4

## pandas taについて

https://github.com/twopirllc/pandas-ta

https://github.com/twopirllc/pandas-ta/pull/693

## mplfinanceについて

https://github.com/matplotlib/mplfinance/tree/master

https://github.com/matplotlib/mplfinance/blob/master/examples/external_axes.ipynb
GCP Cloud Data fusion機能/実装

# GCPのCloud Data Fusionの概要と機能

## 目次
1. [概要](#概要)
2. [機能/詳細](#機能詳細)
3. [まとめ](#まとめ)

## 概要<a name="概要"></a>
GCPのCloud Data Fusionは、エンタープライズデータ統合のための完全マネージドなサービスです。データパイプラインの構築、監視、管理が簡素化されます。Cloud Data Fusionは、異種のデータソースを統合して、高度なデータ変換やトランザクションを行うことができます。

## 機能/詳細<a name="機能詳細"></a>
- **データ統合パイプラインの作成**: Cloud Data Fusionは、直感的なビジュアルユーザーインターフェースを提供し、データパイプラインの作成を簡単にします。ビジュアルドラッグアンドドロップエディタを使用して、異なるデータソースやトランスフォーマーションステップを組み合わせてデータフローを構築できます。

- **スケーラビリティと信頼性の向上**: Cloud Data Fusionでは、自動スケーリングがサポートされています。トラフィックの増加に応じて自動的にインスタンス数を調整し、タスクの処理にかかる時間を短縮します。また、可用性の高いアーキテクチャも提供されており、データパイプラインの運用における信頼性が向上します。

- **豊富なコネクタとトランスフォーマーション**: Cloud Data Fusionには、多数のデータソースとの接続が可能なコネクタが含まれています。また、データ変換やトランスフォーマーションステップのためのプリビルトコンポーネントも提供されています。これにより、複雑なデータの統合や変換を容易に実現できます。

- **監視と管理**: Cloud Data Fusionは、データパイプラインの監視と管理を簡単に行うためのツールを提供します。統合ダッシュボードから、データフローの実行状況をリアルタイムで確認することができます。さらに、ログやアラートの設定など、運用管理に必要な機能も提供されています。

## まとめ<a name="まとめ"></a>
Cloud Data Fusionは、エンタープライズデータ統合のための強力なサービスであり、データパイプラインの構築と管理を簡素化します。ビジュアルユーザーインターフェースを通じて、異なるデータソースとの統合やデータ変換を効率的に行えます。高度なスケーラビリティと信頼性が提供され、データパイプラインの運用が容易になります。


以上がGCPのCloud Data Fusionの概要と機能についての詳細な説明でした。ビジュアルなインターフェースや豊富な機能が備わっており、データ統合やパイプラインの構築を容易にすることができます。さらに、Java、Go、C#、Node.jsなどのサンプルコードも利用できます。
Verilogにおける代入方法、" = "と" <= "の違い

=（イコール記号）:

=は、同時に実行される複数の操作を表します。つまり、すべての代入が同時に行われます。

<=（ノンブロッキング代入演算子）:

<=は、代入文が順次実行されることを示します。つまり、1つの代入が終わってから次の代入が行われます。
Windows Remote Desktopを使ってUbuntuをGUI操作する

# はじめに
Windows 11からUbuntu 22.04にGUI操作ができるように環境構築をしました．
WindowsのRemote Desktopから接続できるようにしました．

# 手順
## Ubuntu側の手順【仮書き．操作の内容など未追記】
0. ユーザを開設 & sudo追加しておいてください
1. SSHでログイン
2. ``sudo apt update && sudo apt -y upgrade``
3.  ``sudo apt install xrdp``
4.  ``sudo systemctl status xrdp``で何やら動いていることを確認
5.  ``sudo adduser xrdp ssl-cert``
6.  ``sudo ufw allow from 192.168.1.0/24 to any port 3389``
5.  ``sudo ufw enable``
6.  ``sudo ufw reload``
7.  ``sudo ufw status``
## Windows側の手順
0. Remote desktopの各種設定をしておくこと
1. Remote desktopで，PCのIPアドレスとUbuntuのユーザー名を入力
2. 青い背景のログイン画面でパスワードを入力
3. ログイン完了！

# 参考文献
- https://qiita.com/Shunmo17/items/b8346777397068ed475b
- https://zenn.dev/takahiro_kawai/articles/afd96c2e8407d9
- https://qiita.com/RyoMa_0923/items/681f86196997bea236f0
Sharepoint OnlineのリストフォームにJSONで登録日時を表示したかったけど出来なかった

自分用メモ。

## やりたいこと
Sharepoint Onlineのリストフォームに登録日時、更新日時、登録者、更新者を表示させたい。

## 失敗した方法
「レイアウトの構成」→JSONで書式設定をしようと試みた。
MicrosoftのリファレンスにJSONの例が書かれているが、fieldsに対応する内部名を入れても表示されなかった。

https://learn.microsoft.com/ja-jp/sharepoint/dev/declarative-customization/list-form-configuration

・登録日時（Created）
・更新日時（Modified）
・登録者（Author）
・更新者（Editor）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537508/8af1aabd-d2f0-c4d9-606e-664a111d6bcf.png)

こちらのページによると、取得できないっぽい？

https://firstaudience.com/wp/sharepoint-online-view-formattings/


## 成功した方法
結局JSONは諦め、列の設定で登録日時の表示に成功した。※他の項目は未確認

リストの設定>列の作成 で以下のように設定する。
・列名：登録日時以外であればなんでもOK
・この列の情報の種類：集計値 (他の列を基にした計算結果)
・列の追加設定：「列の挿入：登録日時」を数式に追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537508/19ae9d10-9a2e-cd03-9dda-0233add7d4af.png)

そして、リストフォームを開いて「列の編集」から先程登録した列を表示させる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537508/009dd7ba-1250-344a-5086-1648031beae5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537508/26ac3d43-be20-bbf2-43e5-ef0a209bdd5e.png)


## 参考にしたページ
https://learn.microsoft.com/ja-jp/sharepoint/dev/declarative-customization/list-form-configuration

https://firstaudience.com/wp/sharepoint-online-view-formattings/

https://qiita.com/Momono_gg/items/58bf768fb83bddfbdca1
ローディング・スピナーを邪魔しないCLIロガーを実装する

以下のインターフェイスをもつロガーを実装する

```ts
const terminal = new TerminalLogger();

const spinner1 = terminal.spinner("loading1...").start()
const spinner2 = terminal.spinner("loading2...").start()

terminal.debug("this is logging in the middle")

spinner1.succeed()
spinner2.succeed()
```

スピナーと通常のロギングの責務をまとめて持たせることで、スピナーの再レンダリングなどのタイミングを隠蔽して、スピナーの途中でログを吐いても画面を汚さない。

複数スピナーが同時にレンダリングされるケースも考慮できる。

あとはスピナーライブラリの依存もカプセル化できるので、たとえばこの記事ではoraをスピナーライブラリとして使うが、そこから別のスピナーに乗り換えたい、などのケースも変更点を小さく実装できる。

### 実装

具体的な実装は以下。

ログレベルなどの制御は一旦無視。

```ts
import { randomUUID } from "crypto";
import ora, { Ora } from "ora";

export class TerminalLogger {
  private readonly logger: Console;
  private spinners: Map<string, Ora>;

  constructor() {
    this.logger = console;
    this.spinners = new Map();
  }

  error(msg?: unknown, ...params: unknown[]) {
    this.withRerenderSpinners(() => {
      this.logger.error(msg, ...params);
    });
  }

  info(msg?: unknown, ...params: unknown[]) {
    this.withRerenderSpinners(() => {
      this.logger.info(msg, ...params);
    });
  }

  debug(msg?: unknown, ...params: unknown[]) {
    this.withRerenderSpinners(() => {
      this.logger.debug(msg, ...params);
    });
  }

  spinner(msg?: string) {
    const spinner = ora(msg);
    const id = randomUUID();
    const controller = {
      start: (text?: string) => {
        spinner.start(text);
        return controller;
      },
      succeed: (text?: string) => {
        this.spinners.delete(id);
        return spinner.succeed(text);
      },
      fail: (text?: string) => {
        this.spinners.delete(id);
        return spinner.fail(text);
      },
    };

    this.spinners.set(id, spinner);
    return controller;
  }

  private withRerenderSpinners(cb: () => void) {
    this.spinners.forEach((s) => {
      s.clear();
    });
    cb();
    this.spinners.forEach((s) => {
      s.render();
    });
  }
}
```

まず `spinner` メソッドで新しくスピナーが生成されるたびにTerminalLoggerにいま表示中のスピナーインスタンスを保持させるようにしている。

こうしておけば、`info`/`error`/`debug`などのロギングのタイミングで保持しているスピナーすべてイテレーションし、毎回クリア＆再レンダーできる。それをやっているのが `withRerenderSpinners` メソッドになる。
【PowerBI】DAX関数のUNIONの謎結合について

# 概要

複数のテーブルを縦に結合したいときは以下のようにUNION関数を用いることで解決します。

``` 
結合テーブル = UNION('テーブル1', 'テーブル2')
```

ただこれだけの処理なんですが、ここの結合周りの仕様で結構躓いたので備忘録として残しておきます。

# 具体例を用いて確認

## UNIONの仕様確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/cd7ceb46-6707-11b1-5149-8eb61a25628d.png)   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/7dc1379b-ef17-f67a-e071-8dd7f4168972.png)

例として二つの食べ物テーブルを用意しました。
この二つのテーブルをUNION関数で結合すると以下のようになります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/5387ab54-0e6c-6463-1f39-a6da94e5a68d.png)

**テーブルビューでの並び**をそのままに縦に結合します。

:::note warn
同じカラム名同士で結合してくれたりはしません
:::

## 躓いた仕様

じゃあ、列の並びを揃えればいいじゃないかとなるんですが、**PowerBIのテーブルビューでは列の並び替えを行うことはできません。**

**テーブルビュー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/aee22e32-23a5-e795-3e0c-812ef97e743c.png)

:::note warn
テーブルビューでの列の並び替えは**不可**
:::

じゃあ、クエリを発行する際に並び替えをすれば良いじゃないかとなるんですが、**クエリを発行する際の列の並び順はテーブルビューの並びに影響を与えません。**

**クエリ発行画面でのむなしい抵抗**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/faf710ed-dc82-9b71-7458-6a631d582f6a.png)

:::note warn
クエリを発行する際の列の並び順とテーブルビューの並びは**関係無い**
:::

## 解決方法(旧)

~~いろいろ試しましたが、元のファイル(xlsxやcsv等)の並び順を直すしか見つかりませんでした。~~
**追記：コメントで解決方法を教えていただいたため、後述します。**

**インポート元のエクセルファイル**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916360/c4ce985f-e479-edc1-ccc4-6e55c6bc6b1c.png)

:::note info
UNIONで結合するファイル群は、読み込み前から列の並びを揃えておく
:::

また、元データの並び順を揃えるだけではテーブルビューに並び順の反映がされないので、現在使っているデータ取得のクエリを消して再度作り直す必要があります。

:::note info
元ファイルのデータの並びを揃えたら、
クエリの再発行も忘れずに！
:::

## 解決方法(新)

```
結合テーブル=UNION(GROUPBY('テーブル1','テーブル1'[番号],'テーブル1'[名前],'テーブル1'[色]),GROUPBY('テーブル2','テーブル2'[番号],'テーブル2'[名前],'テーブル2'[色]))
```

UNIONで結合する際にGROUPBYで各テーブルのカラムを明示してあげると、対応関係を紐づけて結合することができます。


# まとめ

今回の教訓としては、

:::note info
結合する際にはGROUPBYでカラム名を明示する。
:::

:::note info
~~インポート前のデータを整形できるのであれば、なるべくきれいな並び順にしてから読み込ませよう~~
:::

UNIONを使って同じく躓きをした人の一助になれば幸いです。
Windows10で範囲指定スクショを撮る

<h1>対象環境

Windows10

<h1>標準で入っている「切り取り＆スケッチ」を使う

Windows10で範囲指定キャプチャを撮りたい場合、標準で入っている **「Snipping Tool」** の **「切り取り＆スケッチ」** 機能を使用します。**「Winキー + Shift + S」** で呼び出し可能です。

<h1>どうしてもファイルとして保存したい場合

上記の「切り取り＆スケッチ」を使用した場合、クリップボードに保持されるのみでファイルで保存はされません。Slackなどのチャットツールやスプレッドシート上に貼り付けたり、qiitaの記事編集画面にもそのまま貼り付けたり出来るので、ほとんどの場合これで事足りるのですが、どうしてもファイルで保存したい場合もあると思います。
そういった場合、[上記のやり方でスクショ撮影後にデスクトップ画面右下の通知領域に通知が表示され、そちらから保存の操作を行う](https://allabout.co.jp/gm/gc/20843/#6)ようなのですが、私の環境ではこの通知がどうしても表示されず困ってしまったので、 **「SnapCrab」** というキャプチャアプリを使用することにしました。

https://www.fenrir-inc.com/jp/snapcrab/

インストールして起動すると、下のようなツールバーが表示され、キャプチャ方法に応じてアイコンボタンクリックで使用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679383/c448ad29-286f-dc9b-3311-ded4d117ba09.png)

ホットキーの設定も可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679383/128b4964-b38a-7ddc-40b0-4dd218453e25.png)
M88 88Betking 

M88 88Betking - 88betking.com
các loại kèo trong cá cược bóng đá online
https://www.88betking.com/cach-xem-ty-le-keo-cuoc-w88-co-ban-phan-1/
#88betking, #m88, #nhacaim88, #linkvaom88bangdienthoai, #trangchum88,#cadobongdaonline
stanで確率的主成分分析

多変量時系列モデルの中で使う可能性があり、調べてコードがどこにもなかった(bingも）ので。
参考はビショップ本の下巻の終わりの方など。

YをG次元の確率変数（データ）、xを圧縮したい次元（例では1次元)のベクトル確率変数、$\epsilon$を正規ノイズとして

``` math
\textbf{Y}=W*\textbf{x}+\mu+\epsilon
```
というモデル。Y-$μ$をWの列ベクトルの線形結合で表現し、xやWを推定する。分散最大の軸を決めるという定義でなく、こう書かれると因子分析とよく似ているが、εの分散が共通なのがPCA。潜在変数が無相関(→covmatが対角行列）なのは同じ。


データの生成から、単純な１次元
```r
N=300
x=rnorm(N)
y=0.8*x+3+2*rnorm(N)

qplot(x,y)

library(rstan)
lst=list(Y=tibble(x,y),
         N=length(x),G=2,D=1
)
```

![1ce929f9-915c-47eb-8fd0-bdfcd2dc5fc9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38159/bf80f43e-c666-a59b-ae3d-54f944b7e5d7.png)


以下、stanコード。多変量分布と行列の書き方で微妙に格闘。

```stan

data {
  int<lower = 1> N;
  int<lower = 1> D;
  int G;
  vector[G] Y[N];
}

transformed data{
  matrix[D, D] I;
}

parameters {
  vector[D] X[N];
  vector[G] mu;
  matrix[G,D] W;
  
  real<lower = 0> s;
}
model {
  for (n in 1:N){
    X[n] ~ multi_normal(rep_vector(0, D),diag_matrix(rep_vector(1, D)));
  }
  
  for (n in 1:N){
    Y[n] ~ multi_normal(W * X[n] + mu, diag_matrix(rep_vector(s,G)));
  }
}
```

```r
fit=stan(model_code = scode,
         data=lst,
         warmup=300,iter=1000,
         chain=1)

X=get_posterior_mean(fit,"X")
mu=get_posterior_mean(fit,"mu")
W=get_posterior_mean(fit,"W")
Y=t(W%*%t(X))+matrix(mu,nrow=lst$N,ncol=2,byrow=TRUE)

qplot(x,y)+geom_point(aes(Y[,1],Y[,2],col="red"))


```
![a44c5c19-b18d-4962-8c0f-b363bb996411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38159/19fa73e0-ac40-2a89-d3a4-fc3b5cd4749b.png)
Oraを用いたローディング・スピナーの途中でconsole.logを綺麗に出力する

CLIツールを作っていて[ora](https://www.npmjs.com/package/ora)でスピナーを出しながらconsole.logでログも出力したい

例えば以下のようなケース

```js
import ora from "ora";

const spinner = ora("loading...").start();

console.log("this is logging in the middle");

spinner.succeed();
```

上記を実行すると以下のようになってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18973/6bfde53c-4b43-60a7-146a-c595ce4e3802.png)

途中で出力したログのせいでspinnerがおかしなことになっている。

これを回避するには `console.log` の前後でspinnerを停止し、再レンダーしないといけない

```diff
const spinner = ora("loading...").start();

+ spinner.clear();
console.log("this is logging in the middle");
+ spinner.render();

spinner.succeed();
```

これで綺麗にでる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18973/f7b67c15-feea-d5c2-3f5a-ba12f13513a7.png)

とはいえ、これでもダメではないが、複数スピナーが同時に出ている状態でconsole.logを呼び出すなどは、かなり難儀することになる。

なので個人的にはスピナーとロガーを同一の責務にカプセル化した実装を用意することをオススメしたい。詳しくは以下の記事を参照。

https://qiita.com/IzumiSy/items/0f822a5ba7c0b2bc3579

(参考: https://github.com/sindresorhus/ora/issues/120#issuecomment-830563448)
[DatePicker]DatePickerの使用方法を紹介！


# はじめに
今回はDatePickerを使用して、日付と時刻を入力するための便利なコンポーネント作成、使用方法を紹介します！

# 1.DatePickerをインストール
以下のコマンドを打ち、react-datepickerをインストールしてください。
```bash
npm install react-datepicker
```
# 2.InputDateTimeコンポーネントを作成
次に、以下の日付と時刻の入力を可能にするInputDateTimeコンポーネントを作成してください。
```jsx
// components/InputDateTime.js

import React from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';

/**
 * @param selectedDate - 選択された日付と時刻
 * @param onChange - 日付と時刻が変更されたときのコールバック関数
 */
const InputDateTime = ({ selectedDate, onChange }) => {
  return (
    <DatePicker
      selected={selectedDate}
      onChange={(date) => onChange(date)}
      showTimeSelect
      timeFormat="HH:mm"
      timeIntervals={15}
      dateFormat="MMMM d, yyyy h:mm aa"
      timeCaption="Time"
    />
  );
};

export default InputDateTime;
```
# InputDateTimeの基本的な使い方

InputDateTimeを利用して、日付と時刻を入力するコード例を紹介します！

```jsx
// pages/index.js

import React from 'react';
import InputDateTime from '../components/InputDateTime';

/**
 * @param initialDate - 初期(ページ遷移時)の選択日付と時刻
 */
const HomePage = ({ initialDate }) => {
  // stateの初期化
  const [selectedDate, setSelectedDate] = React.useState(new Date(initialDate));

  // 日付が変更されたときのハンドラ
  const handleDateChange = (date) => {
    setSelectedDate(date);
  };

  // 選択された時刻をフォーマットする関数
  const formatSelectedTime = (date) => {
    return date.toLocaleTimeString();
  };

  return (
    <div>
      <h1>InputDateTime Example</h1>
      
      {/* InputDateTimeコンポーネントの呼び出し */}
      <InputDateTime
        selectedDate={selectedDate}
        onChange={handleDateChange}
      />
      
      {/* 選択された時刻を表示 */}
      <div>
        選択された時刻: <b>{formatSelectedTime(selectedDate)}</b>
      </div>
    </div>
  );
};

/**
 * サーバーサイドプロップスを使用して初期データを取得
 */
export const getServerSideProps = async () => {
  const date = new Date();

  return {
    props: {
      initialDate: date.toISOString(),
    },
  };
};

export default HomePage;
```

![スクリーンショット_20240119_154120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/43f7a344-2a49-579a-0798-20bf50d33a70.png)

![スクリーンショット_20240119_154128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/e40a9333-3050-6162-0a1a-5edd1e15a376.png)



# まとめ
今DatePickerを使用して、日付と時刻を入力するための便利なコンポーネント作成、使用方法を紹介しました！
今回の記事を参考に、日付と時刻の入力フォームの実装をしてみてください！
また、DatePickerはもっと詳細にカスタムができるので調べてみることをお勧めします！
時間を指定しコマンドやプログラムを実行する

https://eng-entrance.com/linux-command-at
atコマンドについて詳しくまとめました 【Linuxコマンド集】
atは時間を指定しコマンドやプログラムを実行するコマンドだ。

ATでの設定
```
[whoamijc@0211developing work]$ at -t 202308151451
warning: commands will be executed using /bin/sh
at> date >> bbb.txt 2>&1
at> hogehoge >> bbb.txt 2>&1
at> <EOT>👈「<EOT>」を打つのではなく、「Ctrl➕D」で終了させる。
job 17 at Tue Aug 15 14:51:00 2023
[whoamijc@0211developing work]$
```
実行結果
```
[whoamijc@0211developing work]$ ll bbb.txt👈指定した日時にファイルが作られたことを確認
-rw-rw-r-- 1 whoamijc whoamijc 76 Aug 15 14:51 bbb.txt
[whoamijc@0211developing work]$ cat -n bbb.txt👈ファイルの中身を確認。「date」と「hogehoge」の実行結果が書き込まれている。
     1  Tue Aug 15 14:51:00 JST 2023
     2  /bin/bash: line 2: hogehoge: command not found
[whoamijc@0211developing work]$
```
標準出力・標準エラー出力とも1ファイルに出力可。
ターミナルをシャットダウンしても、ATで仕込んだコマンドは実行される。
sleep nで秒数指定も良いが、ターミナルがダウンすると実行されない。
React NativeでFirebase authのメール検証値の変更を監視する方法

# Firebase authで変更監視できるものは下記のみで、メール検証値は自分で監視するしかない
- onAuthStateChanged
  - サインイン、サインアウトしたときに通知される
- onIdTokenChanged
  - トークンが変更さたときに通知される
- beforeAuthStateChanged
  - 新しいユーザが設定される前に通知される（使用していないのでよくわからない）

# メール検証値を監視するソース
- 下記のソースはstack overflowの[How do I listen to email verification event with firebase authentication and react native?](https://stackoverflow.com/questions/66174106/how-do-i-listen-to-email-verification-event-with-firebase-authentication-and-rea)を参考にして作成しました
- 簡単な説明
  - タイマーで10秒ごとにリロードしてトークンを変更
  - トークンの変更通知を受けてメール検証値を確認
```
  const user = getAuth().currentUser;
  const [emailVerified, setEmailVerified] = useState(user?.emailVerified);
  let timeoutId : any;

  useEffect(() => {
    if (emailVerified) return;
    const onIdTokenChangedUnsubscribe = getAuth().onIdTokenChanged((user) => {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
      if (user && user.emailVerified) {
        console.log("verified");
        setEmailVerified(user.emailVerified);
        return onIdTokenChangedUnsubscribe();
      }
      timeoutId = setTimeout(() => {
        console.log("unverified");
        getAuth().currentUser?.reload();
      }, 10000);
    });
  }, []);
```
【Rails7 + Docker】ビューファイルの変更がlocalhostで反映されない不具合を解消する

Docker化したRailsアプリを開発中、ビューファイル(.html.erb)のソースコードを変更して開発環境のlocalhostをリロードしても変更が反映されない不具合に遭遇しました。`docker-compose.yml`でホストのディレクトリをコンテナにマウントしているため、それまではソースコードの変更はブラウザをリロードすると反映されていたのですが、急に反映されなくなりました。`docker compose down`で一旦コンテナを落としてから`docker compose up`をすれば反映されるのですが、ソースコード変更の度にそれをやるのは効率が悪すぎるため、解決方法を調べ、自分が実際に上手くいった方法をまとめました。

環境は以下のとおりです。
- OS：IntelMac
- Docker
- docker-compose
- Rails7.0.6
- PostgreSQL

```docker-compose.yml
version: '3'
services:
  web:
    build: .
    image: rails_template:latest
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
```


## 設定を追記
`config/environments/development.rb`を下記のようにします。

```diff_ruby:config/environments/development.rb
config.cache_classes = false

# 以下の設定はデフォルトでは記載なしの可能性もあり
- config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+ config.reload_classes_only_on_change = true
+ config.file_watcher = ActiveSupport::FileUpdateChecker
```

いろんな記事を見ていると「デフォルトで`EventedFileUpdateChecker`になっているから`FileUpdateChecker`に変えればよい」と書かれているのですが、自分の環境ではこの行が最初からなかったので、その場合下2つを追記すればいいと思います。
- 参考記事1によると、`config.cache_classes = false`かつ`config.reload_classes_only_on_change = true`の場合、`config.file_watcher`がenableになるようです。また、「`ActiveSupport::FileUpdateChecker`および`ActiveSupport::EventedFileUpdateChecker`が指定されており、Rails7 系を利用している自分の環境では設定は必要なさそう」とあり、そもそも必要ない可能性もあるようです。
- 参考記事2ではRails6を使用していますが、`config.reload_classes_only_on_change = true`の設定はしておらず、結局何が正解かはわからないです。

## PCを再起動
使っているPCを再起動しましょう。最初は上記の追記をやってコンテナを再度立ち上げても解消されませんでしたが、Macを再起動するときちんと反映されるようになりました。
- 参考記事1や参考記事3にあるように、Dockerとホストで時間がずれていると、先程の追記だけでは解消されないようです。自分の場合、今回のエラーに遭遇するまでおそらく1週間以上はずっとMacの再起動やシャットダウンはしてなかったので、時間のずれが生じていた可能性があります。


### 参考記事
1. [【Docker CE/Rails】ソースコードの変更が反映されない](https://zenn.dev/ndjndj/articles/7f092191638571)
2. [Docker + Rails6環境でコード即時反映されない件 - yposiのブログ](https://yposi2.hateblo.jp/entry/2020/10/11/114640)
3. [dockerでrails5環境構築 #Ruby - Qiita](https://qiita.com/pocari/items/456052a291381895f8b3#%E3%83%AA%E3%83%AD%E3%83%BC%E3%83%89%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C)
3. [【Rails】Viewファイルの変更がページのリロードで反映されないときの対処法｜Dockerのコンテナを再起動は不要(ビューファイル .html.erb)](https://prograshi.com/framework/rails/autoload_view-file_on_docker/)
3. [【Rails6】Dockerコンテナを再起動しないとソースコードが反映されない #Rails - Qiita](https://qiita.com/Kiyo_Karl2/items/147d604e625b8a55e12e)
3. [dockerにて、編集がローカルで反映されない](https://teratail.com/questions/o000w252aog2zg)
3. [railsでテンプレートがないと怒られる](https://teratail.com/questions/294330)
3. [Vagrant + Rails 6.0.2.1 のdevelopmentでコード変更が反映されない現象を解決 - Just do IT](https://k-koh.hatenablog.com/entry/2020/02/12/105351)
3. [Docker + Rails で開発していてソースコードが即時反映されない時のたったひとつのcoolな答え](https://zenn.dev/junki555/articles/7e98b108148ad4)
デフォルトポート以外での疎通確認方法（telnet）

httpを80番以外でポート開放しているときの動作確認

ポートが開いているか、接続できるかの確認。（※１．IPアドレスとポート番号は適当なモノに変更の上、実行してください。※２．疎通が許可されているホストから実行して下さい。）

```
curl -v telnet://192.168.33.10:50080
```
ページの取得・ダウンロード

```
$ curl -H 'Host:example.com' http://192.168.33.10:50080/
```
dsnの形式に注意してください
スキーム：//[ユーザー名：パスワード@]ドメイン名：ポート番号/パス

参考にしたURL
1.
telnetやcurlでポートが開放されているか確認
http://teqspaces.com/Linux/9
2.
curlでhost指定・名前解決して実行
https://iettty.hatenablog.jp/entry/2018/10/23/235142
3.
URI（Uniform Resource Identifier）
http://www.dataondemand.co.jp/documents/data_integrator814/connectors/URI_Uniform_Resource_Identifier_.html

:skull: アクセス元IPを偽装しての動作確認も可能

```
[opc@0205oci_opeweb httpd]$ curl --header "X-Forwarded-For: 92.202.58.126" http://myproject.com/
<html>
<head>
</head>
<body>
        403 Forbidden
</body>
</html>
[opc@0205oci_opeweb httpd]$
```

```
curl --header "X-Forwarded-For: 92.202.58.126"  -H 'Host: who.myproject.com' --dump-header -    'http://133.106.63.247/'
```
参考URL：
カスタムIPを使用したCURLリクエストの送信
https://www.web-dev-qa-db-ja.com/ja/curl/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0ip%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9Fcurl%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AE%E9%80%81%E4%BF%A1/960803849/
htaccess mod_rewriteで403発生【URLに半角スペースがある場合】

URL内に「%20（半角スペース）」が含まれていると403エラーが発生します。
１．まずURL内に「%20」があると→403エラー発生。
２．「whoami20230614 a.php」など半角スペースが含まれた実在ファイルに直アクセス→200OK
３．「?」マーク以降に「%20」があるとき（クエリーパラメーター扱い？）→200OK
４．「/detail_history/?/iuid=314/ab%20cd/?a=12%2134?xyz=1%202」など第一セグメントの後ろに「?/」をつけてアクセス→200OK
５．「%21（!ビックリマーク）」では発生しない。
４の補足
http://xxx2019.ce99.net/detail_history/iuid=314/ab%20cd/?a=12%2134?xyz=1%202👈403
http://xxx2019.ce99.net/detail_history/?/iuid=314/ab%20cd/?a=12%2134?xyz=1%202👈200

ブラウザからページ確認。
※ステータスが403であることも確認する。

```
Forbidden
You don't have permission to access this resource.
```
シェル端末からエラーlogを確認。
/home/myproject/logs/httpd/error_log.20230626

```
[opc@0206oci_opewebstaging httpd]$ cat /home/myproject/logs/httpd/error_log.20230626
[Mon Jun 26 19:42:50.143089 2023] [rewrite:error] [pid 2609218] [client 113.35.72.50:62987] AH10411: Rewritten query string contains control characters or spaces
[Mon Jun 26 19:45:00.058456 2023] [rewrite:error] [pid 3110208] [client 113.35.72.50:62899] AH10411: Rewritten query string contains control characters or spaces
```
/etc/httpd/conf/extra/my_httpd.conf
```
  RewriteRule ^(.+)$ index.php?$1
#↓末尾に「 [B]」を追加する。
  RewriteRule ^(.+)$ index.php?$1 [B]
#httpdを再起動の上、動作確認をお忘れなく…。
```
参考にしたURL
【.htaccess】mod_rewrite モジュール – その 5 RewriteRule のフラグ一覧
https://www.google.com/amp/s/web.hazu.jp/htaccess-rewriterule/amp/
htaccess 301リダイレクト【URLに半角スペースがある場合】
https://monostyle.net/investment/htaccess.html
LM Studio でローカル環境でLLMを動かす手順について

# はじめに

ネットワークに接続されていないローカル環境でLLMを使用したい場合、LM Studio と
呼ばれるAIツールがあるとのことで試してみました。

結果、GPUは NVIDIA の GTX1650 (4GBメモリ) でも問題なく動作しましたので、
動作確認までの手順をまとめてみます。

# インストールまで

公式サイト (https://lmstudio.ai/) からインストーラをダウンロードします。
今回は Windows版 を試しました。
![0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/289ee4fa-06d5-6d8c-62de-1dbe01717c55.png)

![0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/e78410ce-e030-7fde-89de-3aab9aa6c43d.png)

起動すると下記のようなスプラッシュ(？)が展開され、その後起動してきました。
特にインストールオプションを聞かれるようなこともなく、自動的にインストールが進み、完了しました。
同時にデスクトップにショートカットが作成されました。
![0002_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/693c43b4-75cb-543d-7e65-8906d2db6c89.png)
![0002_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/3f8785cc-747a-dc95-42b2-c8c2a39cb71e.png)

初期画面はこのような感じ。
![0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/c5f8d753-5ee9-1f53-e4ea-4f5990228a20.png)

# ELYZA-japanese-Llama-2-7b-instruct を試す

日本語対応のLLMを試したいので、ELYZA-japanese-Llama-2-7b-instruct を選択してみました。
画面左側の虫眼鏡🔍(Search)を選択し、検索ボックスに「ELYZA-japanese-Llama-2-7b-instruct」と入力してGo。
![0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/d4feff1b-87e3-ba4f-35ff-bb7eaf19d6a8.png)

画面右側にGGUF一覧が表示されるので、「ELYZA-japanese-Llama-2-7b-fast-instruct-q4_K_M.gguf」の「Download」を押してダウンロード。
![0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/41157cb5-dd29-589c-960d-69d96e9b7c7c.png)

画面下部でダウンロードの進捗が確認できます。
![0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/dee86cd9-d9c5-40af-b8be-bb4a2d916d1a.png)

画面左側の💭(AI Chat)を選択し、画面上部より使用するモデルを選択し、読込ます。
![0007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/38e14df6-997a-8440-d5ee-b5ef7e96d50a.png)

試しに日本の首都を聞いてみましたが、イマイチな回答でした。
でも2秒程度で回答されました。
![0008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/467c6513-0d18-9a36-29aa-e2addb6ca39a.png)

ちなみに画面右側の Settings にある GPU Offload が GPU使用の設定のようでした。
(right click for options) と薄っすらと記載がある箇所を右クリックすると CUDA、OpenCL 等の設定
が出てきます。
![0009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/89614c74-2ae4-0af0-873f-4ef4b150ea26.png)

画面左側のフォルダ(My Models)を選択すると、ダウンロード済みのモデル一覧が表示されます。
![0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3668873/bd203db7-9416-844c-eeb1-c3535a9c6721.png)

# 最後に
ローカル環境でLLMを使用したい場合、LM Studio で気軽に試せることが分りました。
ただ使っているうちに回答が生成されず、延々と待たされることもあり、安定していない面もあるようです。

ChatGPT等で扱いにくいような社内情報を扱う場合、LM Studio は使えるものかもしれません。

## 参考文献
この記事は以下の情報を参考にして執筆しました。
- [My LLMこと始め ③ Macでいろいろ](https://note.com/owlet_notes/n/nd64667412f88)
Renovate で main 以外のブランチを対象にする設定

# 設定

ranovate.json とかの設定で baseBranches に対象ブランチを指定すれば良いようだ。

```
{
  "baseBranches": ["main", "xxx"]
}
```

# 反映方法

Github のベースブランチ ( 通常は `main` ) に反映すれば良いようだ

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Macのコンソールで毎回パスワードを聞かれるのを無効化する ( sudoコマンドなど )

# 手順

- `whoami` でユーザー名を確認する ( 例: yumainaura )
- `sudo visudo` で sudo 設定を開く
- ファイルの「末尾」に `<ユーザー名> ALL=NOPASSWD: ALL` を追記する ( 例: `yumainaura ALL=NOPASSWD: ALL` ) ( 他のユーザー系の設定より後に書かないと、効かない場

## セキュリティ的にどうか

パスワードを聞かれないとセキュリティ的によろしくないという懸念があるが、自分のPCでこの設定をする分には、そもそもPCアカウント自体にパスワードもかかっているし、問題ないはず。たぶん。

# チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura



# 公開日時

2024-01-19