OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS認定 DOP対策】この教材以外あり得ない ~ DevOps Engineer Professional 必勝の勉強方法 ~

# はじめに
数ヶ月前の話ですが、AWS認定資格の **DevOps** **Engineer** **-** **Professional** **(DOP)** に合格しました。
DOPは、SAAやSAPと比べて合格体験記が少ない印象なので、対策におすすめの教材や自分の勉強方法を残しておこうと思います。
しばらくAWSには触れていない自分でしたが、スコアは**800点台で合格**できているので、それなりに参考になる勉強法なのではと思っております。

# 対象者
私がDOPを受験する時点で保有していたのは、
- AWS Certified Cloud Practitioner (CLF)
- AWS Certified Developer - Associate (DVA)

の2つになるので、本記事もDVAレベルの知識がある方が主な対象者となります。ご了承ください。

# 対策におすすめの教材
3つ紹介します。この他にも購入したUdemyの講座がいくつかあったりしますが、正直不要でした（ほとんど見てないです）。
これら3つで対策するのが、最も確実で効率的かと思います。

## 1. AWS Certified DevOps Engineer Professional 2023 - Hands On!
Udemyの評価がかなり高いので購入しましたが、DOPの出題範囲となっている各サービスをしっかりと網羅しており、講師の方の解説も非常に分りやすかったです。解説の中では、試験で問われやすいポイントについても教えてくれます。

また、ハンズオン形式の動画であり、実際にAWS環境を操作しながら進めてくれるため、内容が頭に入ってきやすい印象を受けました。
私は自分の手は動かさずに視聴しただけなのですが、AWSアカウントを保有している＆時間に余裕のある方は、自分で操作を真似てみるとさらに理解が深まると思います。

英語のコンテンツではありますが、日本語の字幕も付けられるのでほとんど気にならなかったです。

https://www.udemy.com/course/aws-certified-devops-engineer-professional-hands-on/

## 2. TechStock（問題集）
2022年の9月に「TechStock」へ名前が変わりましたが、以前は「koiwa club」の問題集と呼ばれてましたね。
言わずと知れた**最強の問題集**です。問題集は間違いなくこれ一択。CLFやDVAの受験時からお世話になってます。猛プッシュしてますが、私は決してTechStockの回し者ではありません。

https://techstock.jp/

Udemyで販売されている問題集も、過去CLFやDVAの対策をした際にいくつか解いた経験がありますが、TechStockで扱われている問題の方が圧倒的に本番に近い印象です。今回のDOP対策で活用した問題集はこれ1つでした。

試験当日は、TechStockの類似問題が体感3〜4割ほど（全く同じ問題も数問）出題されましたし、対策としてこの問題集を使わないのは舐めプなんじゃないかってくらい良い教材だと思ってます。

## 3. AWS公式 模擬試験
2年ほど前までは有料だったAWS公式の模擬試験ですが、今では**無料で受験できます**。
模擬試験は問題数が少なめですが、一通りの対策が終わった後に、知識の穴埋めや実力試しとして活用できるので解いておいて損はないです。
模擬試験の受け方は調べればすぐに出てくるので、本記事では割愛します。

# 勉強期間

対策を始めた日から受験日までの期間は、2ヶ月半でした。
平日は忙しく勉強できない日も多々あったので、実質1ヶ月半~2ヶ月くらいかと思います。

# 勉強方法
私は以下のように進めました。

1. **Udemyの講座（本記事で紹介した講座）の動画を一通り視聴する**。重要に感じた点や、自分の知らなかった知識については、自身でメモを取って後から振り返れるようにしておりました。（時間が無い時は1.5倍速で視聴したりも。）

2. **TechStockの問題集を解く**。TechStockで扱われているDOPの問題は全て解きました。一度間違えた問題については、解説を読んだり、[AWS公式ドキュメント](https://docs.aws.amazon.com/)を確認して知識を埋めていきました。公式ドキュメントを確認するのはとても大事だと思ってます。

3. **AWS公式 模擬試験に取り組む**。自分の実力を把握しつつ、知識の穴埋めを行いました。

4. **TechStockの「本試験モード」で本番形式の試験対策をする**。プロフェッショナル資格は3時間という長丁場の戦いであるため、事前にリハーサルしておくことを勧めます。「本試験モード」で実際に体験できるので、何度か実施しました。

5. 試験前日はちゃんと寝る。DOPは問題文も時間もとにかく長いので、当日の集中力が持続するよう、万全の状態で挑みましょう。

# 最後に
大袈裟なタイトルを付けてますが、記事は真面目に書いております。本記事が皆様の参考になれば幸いです。
私はAWS6冠を目指してこれからも勉強していきますので、また次の合格体験記でお会いしましょう！

以上
[AtCoder][典型69] 繰り返し二乗法を使った効率的な累乗の計算

# 概要

こちらの問題を使用して解説
[典型問題69](https://atcoder.jp/contests/typical90/tasks/typical90_bq)

問題の解き方として、
最初のブロックの選び方はK通り
次のブロックの選び方はK-1通り
それ以降のブロックの選び方はK-2通りなので次の式で解答が出せる。

```
K * (K-1) * (K-2)^(N-2)
```

ここで問題になるのは`(K-2)^(N-2)`の計算量

# 繰り返し二乗法とは

`3^50`を考える。
これは`3^25 * 3^25`に分解することが可能。
同じように`3^25`は`3 * 3^12 * 3^12`に分解が可能。
これを繰り返すことで効率良く累乗の計算ができる。

# 実装

```c++
const int MOD = 1e9 + 7;

int pow(long long a, long long n) {
    if (n == 0) return 1;
    if (n == 1) return a % MOD;

    long long ret = pow(a, n / 2) % MOD;
    (ret *= ret) %= MOD;
    if (n % 2 == 1) {
        (ret *= a) %= MOD;
    }
    return ret;
}

int main() {
    long long N, K; cin >> N >> K;
    long long ans = K % MOD;
    if (N >= 2) (ans *= K - 1) %= MOD;
    if (N >= 3) (ans *= pow(K-2, N-2)) %= MOD;
    cout << ans << endl;
}
```
Aurora（MySQL互換）とRDS ProxyのCA証明書/TLS接続/IAM認証について整理する

提題の件について、設計書を書く上で現時点での仕様を整理する必要があったので、まとめた結果を記載しておく。

※調査にあたり、以下の記事を参考にさせていただきました。

https://htnosm.hatenablog.com/entry/2021/08/23/090000

https://dev.classmethod.jp/articles/how-rdsproxy-uses-secrets-manager/

# 整理内容

## 1. CA証明書
### Aurora
- RDSやAuroraはサーバー証明書の署名に独自のCA証明書を使っているため、TLS接続時やIAM認証時にはこれらのCA証明書のダウンロードと指定が必要。
- なお、CA証明書は40年/100年ものが使用可能となっている。Aurora MySQL 2.x（MySQL 5.7互換）や3.x（同 8.0互換）では、デフォルトのrds-ca-2019（来年には切れるので非推奨）、rds-ca-rsa2048-g1のみが選択可能な模様。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.SSL-certificate-rotation.html

### RDS Proxy
- RDS ProxyはACMサーバー証明書を使っている。こちらは一般的な証明書ストアに含まれるCA証明書を使っているので、TLS接続時にもクライアント側で独自CA証明書のダウンロードや指定は必要ない。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.howitworks.html#rds-proxy-security.tls

## 2. TLS接続
### Aurora
- Aurora接続にTLS接続は必須ではないが、IAM認証時は「CA証明書」が必要になる（この場合でもTLS接続は必須ではない）。
- TLS1.3はAuroraではまだサポートされていない。

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Security.html

### RDS Proxy
- RDS ProxyでのTLS接続は必須ではないが、IAM認証時は「TLS接続」が必須となる（この場合でもCA証明書のダウンロードは不要だが、ACMのCA証明書が暗黙的に使われている）。
- TLS1.3はRDS Proxyではまだサポートされていない。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.howitworks.html#rds-proxy-security.tls


## 3. IAM認証
### Aurora
- AuroraのIAM認証はネイティブ認証と併用可能。

### RDS Proxy
- RDS ProxyはIAM認証かネイティブ認証かの二者択一。
- IAM認証の場合、DB側はネイティブ認証必須。ネイティブ認証の場合は、DB側はIAM認証（ネイティブ認証併用）可。いずれの場合も、Secrets Managerにネイティブ認証用のパスワードが格納され、RDS Proxy→データベース間はそれを使ってネイティブ認証する。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy-setup.html#rds-proxy-iam-setup

なお参考までに、アプリケーションからAuroraへの接続については、スロットリング回避のため、IAM認証ではなくネイティブ認証を用いるのがよいと思われる。
IAM認証は原則として「人による認証」で利用するのが吉。

https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
【競プロ/Swift】AtCoder Regular Contest 158

# 注意事項
本記事は復習のための日記的なものであり、丁寧な解説を求めている方には不十分かと思われますので、ご了承のほどお願いいたします。

# 誤答及び、未解答問題
## A - +3 +5 +7
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/arc158/tasks/arc158_a)

**誤答**
初めてのARCの出場。
案の定A問題から難しく、TLEでクリアならず。

やっている事としては、
・受け取った値が同じ場合
・期待する値に絶対にならない場合
の例外パターンを先に処理する。

その後に、3つの値が等しくなるまで計算するという処理になっています。

```swift
let t = Int(readLine()!)!

func isAllEvenOrOdd(numbers: [Int]) -> Bool {
    var isAllEven = false
    var isAllOdd = false

    numbers.forEach { number in
        if number % 2 == 0 {
            isAllEven = true
        } else {
            isAllOdd = true
        }
    }
    return isAllEven != isAllOdd
}


for _ in 0..<t {
    var xArray = readLine()!.split(separator: " ").map{Int($0)!}
    
    if xArray[0] == xArray[1] && xArray[0] == xArray[2] {
        print(0)
        continue
    }
    
    if !isAllEvenOrOdd(numbers: xArray) {
        print(-1)
        continue
    }
    
    var counter = 0
    while !(xArray[0] == xArray[1] && xArray[0] == xArray[2]) {
        let minIndex = xArray.firstIndex(of: xArray.min()!)!
        let maxIndex = xArray.firstIndex(of: xArray.max()!)!
        let middleIndex = [0, 1, 2].first(where: {$0 != minIndex && $0 != maxIndex})!
        
        xArray[minIndex] += 7
        xArray[maxIndex] += 3
        xArray[middleIndex] += 5
        counter += 1
    }
    print(counter)
}
```
**正答**
[こちら解説](https://atcoder.jp/contests/arc158/editorial/5902)

以上の解説を見ても理解に時間がかかった。
問題をそのまま解くのではなくて、問題の読解・簡略化することが大事だとわかった。

```swift
import Foundation
 
func main() {
    let T = Int(readLine()!)!
    for _ in 0..<T {
        let x = readLine()!.split(separator:" ").map{Int($0)!}.sorted()

        // 入力値が全て同じ場合は操作回数０を出力
        if x.allSatisfy({ $0 == x[0] }) {
            print(0)
            continue
        }
        let sumx = x.reduce(0, +)
        let a = sumx / 3

        // 入力値の合計が３の倍数じゃないい場合は、何回操作しても同じ値にならないので、例外パターンの-1を出力
        guard sumx.isMultiple(of: 3) else {
            print(-1)
            continue
        }

        // 正解パターンは3つの入力値とその平均値の偶奇が同じはずなので、割る２した値の数が１以上あると、例外パターンの-1を出力
        guard Set((x + [a]).map({ $0 % 2 })).count == 1 else {
            print(-1)
            continue
        }
        
        // 平均値と今の値の差分の合計（全ての値が等しくなるまで変化しないといけない値の大きさ）を４（一回の操作で変化する値）を割ると、操作回数が出力される。
        let d = x.map({ abs(a - $0)}).reduce(0, +)
        print(d / 4)
    }
}
 
main()
```
# 参考
https://atcoder.jp/contests/arc158
changeDetect.sh

```bash:detect.sh
mkdir -p "$1"
cd "$1"


while true
do
    new=$(date --iso-8601=s).html
    wget -q --no-cache --no-cookies -O $new "$1"
    if [[ -v old ]]
    then
        diff $old $new || canberra-gtk-play -i desktop-login -l 99999
    fi
    old=$new
    sleep 10
done
```

usage

```bash
detect.sh https://localhost/index.html
```
Emmet(エメット)入門 HTML編


## Emmet（エメット）とは
Emmet（エメット）は、HTMLやCSSのコーディングを効率化するための機能です。
VScodeでは、デフォルトで対応しているため、すぐに使用することができます。

## Emmetの基本的な使い方

### タグの生成
```html
<!-- div -->
<div></div>

<!-- section -->
<section></section>

<!-- p -->
<p></p>
```

### クラス名の設定
```html
<!-- .dummy -->
<div class="dummy"></div>

<!-- p.dummy -->
<p class="dummy"></p>
```


### ID名の設定

```html
<!-- div#dummy -->
<div id="dummy"></div>

<!-- p#dummy -->
<p id="dummy"></p>
```


### コメント

```html
<!-- c -->
<!--  -->
```


### 階層の設定

```html
<!-- div>p -->
<div>
    <p></p>
</div>
```


### 複数の設定

```html
<!-- div*3 -->
<div></div>
<div></div>
<div></div>

<!-- p*3 -->
<p></p>
<p></p>
<p></p>
```

### ベースの作成
```html
<!-- html:5 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```
[AtCoder][ABC290E] 貢献度を使った数え上げ問題その2

# 概要
数え上げ問題は貢献度を使った解答が多い気がするのでもう１つ解説
問題はこちら[ABC290E](https://atcoder.jp/contests/abc290/tasks/abc290_e)
自分なりの考え方を整理して実装してみる。

# 考察
問題を下記のように言い換える。
数字の配列Xが存在し、そのうち異なる２つの数字のペア(l,r)を選択する。
そのペアが解答にどれくらい貢献するかを考える。

AtCoderの例を考える。ここではl=X[1]とr=X[2]の数字を選択してみる。
5 **2** **1** 2 2

このときの貢献数は2。なぜなら下記の太字の部分文字列を選んだ場合の２ケースが解答に貢献するため。
5 **2** **1** 2 2
**5** **2** **1** **2** 2

これは要するに選んだ数字から一番近い数列の端までの距離が貢献数になることを意味する。
数式で表すと`min(l+1, N-r)`

## maxやminが出てきた場合は場合分けすると解きやすい

l+1が貢献数になるのはlの位置の方がrよりも数列の端に近い場合(`l+1 <= N-r`)。
lを固定すると`r <= N-l-1`。rが`N-l-1`より小さいもしくは同じ場合に`l+1`が貢献数となる。

## lを決めたときの全てのrに対する貢献数を計算する
lを固定すると貢献数が`l+1`になるrの範囲は`r <= N-l-1`
よって貢献数は`(l+1) * [l+1,N-l-1]の範囲にあるA[l]でない数字の数`
これを全てのlに対して行うことで解答が求められる。

`N-r`が貢献数となる場合は上記の数列をreverseすれば同じ要領で解くことが可能。

## 配列の中で区間[l,r]の間でXではない数字の個数を求める

これは各数字に対するインデックスの配列を作っておくことで二分探索を使って求めることが可能。

例: A = [5 2 1 2 2]
数字2に対するインデックス配列 P = [1 3 4]
Aの2<=i<=4に存在する数字2の個数は次の要領で計算が可能
```c++
upper_bound(P.begin(), P.end(), 4) - lower_bound(P.begin(), P.end(), 2)
```

よって区間に存在する数字の個数から上記の数を引くことでXではない数字の数が求まる。


# 実装

```c++
long long solve(vector<int>& x) {
    int n = x.size();
    map<int, vector<int>> index_array_by_number;
    for (int i=0; i<n; i++) {
        index_array_by_number[x[i]].push_back(i);
    }

    long long ret = 0;
    for (long long l=0; l<n/2; l++) {
        int r = n - l - 1;

        // 要素がx[l]でないものの個数を数える
        vector<int>& v = index_array_by_number[x[l]];
        // [l+1,r]の範囲でx[l]と同じものの個数
        int same_count = upper_bound(v.begin(), v.end(), r) - lower_bound(v.begin(), v.end(), l+1);
        // [l+1,r]の範囲でx[l]でないものの個数
        int diff_count =  r - l - same_count;
        ret += (l+1) * diff_count;
    }

    return ret;
}

int main() {
    int N; cin >> N;
    vector<int> A(N);
    for (int i=0; i<N; i++) {
        cin >> A[i];
    }

    long long ans = solve(A);
    reverse(A.begin(), A.end());
    ans += solve(A);

    // l+1 == N-r-1のケースが重複して数えているのでその分を引く
    for (int l=0; l<N/2; l++) {
        int r = N-1-l;
        if (A[l] != A[r]) {
            ans -= l+1;
        }
    }

    cout << ans << endl;
}
```
【Unity】3D 物理演算が Update で演算できるようになりました【2022.2 から】 

# 概要

Unity 2022.1 以前のバージョンでは、3D 物理演算が `FixedUpdate` と `Update` の間で実行され、`FixedUpdate` と紐づくようになっていました。
しかし 2022.2 から新たな実行タイミングの設定が追加され、
**3D 物理演算を Update に紐づくことができるようになり、`Update()` 後に必ず物理演算させる** ことができるようになりました。

この記事では物理演算の実行タイミングの設定方法を説明して、実際にその効果を確認します。

※ `FixedUpdate` 物理演算のクセについて、 [FixedUpdate に関する別記事](https://qiita.com/tsukimi_neko/items/acf2d1dce01ea97885cf) の前半でまとめていますので、気になる方は是非そちらもご覧ください mm

# 設定方法

Unity 2022.2 を起動して、Edit > ProjectSettings を開き、
Physics のタブで、**Simulation Mode** という物理演算の実行タイミングに関する設定があります。

設定は FixedUpdate、Update、Script の３つの選択肢があり、Update を選ぶと `Update()` 後に物理演算が実行されるようになります。
![physics-simulationmode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295675/f31bdec7-f39d-b32f-9165-0a934a439907.png)

また、アプリケーション実行中でも、下記のようなコードで、演算方法を動的に変えることができます：

```C#
public void SetSimulationModeToUpdate()
{
    Physics.simulationMode = SimulationMode.Update;
}

/* SimulationMode の定義
enum SimulationMode
{
    FixedUpdate,
    Update,
    Script,
}
*/
```

# 確認してみた

現状、`SimulationMode.Update` における物理演算の公式説明がまだ多くありませんが、
実際に `SimulationMode.Update` に設定して、プロファイラーを見ると、 Update の直後に物理演算用の PhysicsLateUpdate のセッションが追加されていることが確認できます。（下図の <font color=orange>オレンジ部分</font> ）
![Update_PhysicsSimulation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295675/27070561-d259-0108-65ea-39abb214a201.png)

下記の検証動画では、`FixedUpdate` 時では `OnCollisionStay()` が `Update()` 直前で呼ばれて、時々すっ飛ばされますが、
`Update` に設定すると `OnCollisionStay()` のタイミングが `Update()` 後になり、また、安定して呼ばれていることが確認できました。

<iframe height="540" src="https://www.youtube.com/embed/RvC735zLbds" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


## Physics.autoSimulation の扱いについて

`enum SimulationMode` の導入により、`Physics.autoSimulation` が **Obsolete** になり、`simulationMode` のほうを使用することが推奨されるようになりました。
`Physics.autoSimulation` に真偽値を代入する時に、 `true` は内部的に `SimulationMode.FixedUpdate`、
`false` は内部的に `SimulationMode.Script` が代入されます。

# 結

結構前に `Physics2D` のほうで `SimulationMode2D` の設定が実装されましたが、2022.2 から 3D のほうの `Physics` でもサポートされるようになりました。

別記事の「[Rigidbody を用いた移動でよく出る不具合と、FixedUpdate 改造による解決法の提案【Unity】](https://qiita.com/tsukimi_neko/items/acf2d1dce01ea97885cf)」の前半でも解説しましたが、`FixedUpdate` での物理演算はクセがあって、知らずに踏むと中々解決できませんので、
今回の機能追加は個人的にとても嬉しくて、これから新規のプロジェクトはガンガン `SimulationMode.Update` を使っていきたいと思います。
Subversionを利用したWordPress公式プラグインの更新方法

## はじめに
今回の記事では自作wordpressプラグインを更新しようとした際の手順を記載していきたいと思います！
プラグインを公開する際の手順は[こちら](https://qiita.com/shun_shiratori/items/e7dd1e27163d2c30612c)の記事と参考にしていただければと思います。


## 手順

1. ディレクトリの作成とローカル環境にクローンの作成
2. ファイルに最新版を格納
3. ファイルのアップデート
4. バージョンの更新

では詳しく見ていきましょう。

### 1.ディレクトリの作成とローカル環境にクローンの作成
まずは公開時と同様に任意のディレクトリを作成しローカル環境にファイルをクローンしていきます。
これは[公開方法の記事](https://qiita.com/shun_shiratori/items/e7dd1e27163d2c30612c)で詳しく説明しているため、わからなくなったらご覧ください。
（my-pluginsの部分に申請したプラグインのディレクトリの名前を入れてください）

```
cd my-plugins-svn
```
```
svn co https://plugins.svn.wordpress.org/my-plugins/
```

### 2.ファイルに最新版を格納
落ちてきたファイルに変更したファイルを格納していきます。
公開時と同様にmy-plugins-svnに入っているそれぞれのファイルに、変更されたプラグインファイルを入れていきます。
![スクリーンショット 2023-03-17 20.21.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690898/6e11fcf3-4f4e-4755-fdcf-b4dc4b95dbe3.png)


### 3.ファイルのアップデート
ファイルを格納後はaddではなくupdateしていきます
```
svn update trunk/*
```

### 4.バージョンの更新
#### tagsにアップデートされたtrunkファイルをコピーしていきます
```
svn cp trunk tags/1.1.0
```

#### commitする
前文では、/trunkを/tag/1.1.0にコピーするという意味のコードを記入しましたが、まだローカル上でのコピーなので、これをコミットしていきます
```
$ svn commit -m "Tag　1.1.0"
```

## 既存ファイルを消去したい場合
### ファイルを削除する
```
svn delete ./trunk/ファイル名
```
消した後もコミットを忘れずにしてください

## 最後に
今回の記事ではプラグインの更新作業の手順を書いてきましたが改めて全体を通しての手順を知りたい方は[こちら](https://qiita.com/shun_shiratori/items/e7dd1e27163d2c30612c)の記事を参考にしてみてください！
【Bash・Zsh】比較演算子


## 文字列の比較
| 比較演算子 | 説明 |
| :-:|:- |
| String1 = String2  | String1とString2が等しければ真  |
| String1 != String2  | String1とString2が等しくなければ真  |
| -n String  | Stringの長さが1以上であれば真  |
| -z String  | Stringの長さが0であれば真  |

## 数値の比較

| 比較演算子 | 説明 |
|:-:|:-|
| Number1 -eq Number2  | Number1とNumber2が等しければ真  |
| Number1 -ne Number2  | Number1とNumber2が等しくなければ真  |
| Number1 -gt Number2  | Number1がNumber2よりも大きければ真  |
| Number1 -ge Number2  | Number1がNumber2以上であれば真  |
| Number1 -lt Number2  | Number1がNumber2よりも小さければ真  |
| Number1 -le Number2  | Number1がNumber2以下であれば真  |

## その他
| 比較演算子 | 説明 |
|:-:|:-:|
| -d file  | 対象ファイルがディレクトリなら真  |
| -f file  | 対象ファイルがファイルなら真  |
| -s file  | 対象ファイルのサイズが0でなければ真  |
| file1 -ot file2  | file1がfile2よりも古ければ真  |
| file1 -nt file2  | file1とfile2が等しければ真  |
WSL2に awsなお砂場作成

https://zenn.dev/creationup2u/articles/a0fc15d00799f1

参考::

https://hackmd.io/@ajorg/HkMn0APGY


...[NixOS](https://nixos.org/) なのかなと思ってたけど、実用を考えるとこちらかも？（Awsのお砂場をここ1年ぐらいのWinPCなら作りこめるってことだろうし）


うーむ。。。（nixos/nix Docker image ）

https://hub.docker.com/r/nixos/nix

https://qiita.com/junjihashimoto@github/items/54f8e25071b2800ee2ee


他
google.co.jp/search?q=WSL2+amazonlinux
ニフクラで作成したサーバーに最速でログインする

## 前置き

* 作成したサーバーがインターネットと直接通信を行えない場合、踏み台サーバーを利用する/必要なACLの設定を行う 等の手順を踏んで対象のサーバーにアクセスする必要がある
* ニフクラの [コンソール](https://pfs.nifcloud.com/service/console.htm) 機能を利用することで、そういった手順を踏まずにサーバーに対してログインすることが可能になる

## 手順

#### 1. サーバー作成時にrootパスワードを設定する

下記のようなスクリプトを指定する
(例では 	`Ubuntu Server 22.04 LTS` で実施)

```bash
#!/bin/bash

echo root:YOUR_PASSWORD| chpasswd
```

※UI からサーバーを作成する場合は下記画面で指定できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139297/37063009-9102-51f3-de50-ca3d2659f42a.png)

#### 2. サーバーの作成が完了するのを待つ

5分ぐらい

#### 3. UIのサーバーメニューからコンソール接続する(図の赤枠)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139297/7660aad8-6f37-e760-5085-b23f2126510a.png)

#### 4. 指定したパスワードを入力することで他の設定不要でログインできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139297/9de9aad4-dfbb-7d57-9ada-b45c9708126b.png)
ChatGPT API を使ってコードレビューしてくれるアプリを作りました

# はじめに

最近話題の ChatGPT の API を触ってみたいと思い、入力したコードの修正点やアドバイスをくれる Web アプリケーションを作ってみました。
https://ku6kaw-code-doctor-code-doctor-ptktx3.streamlit.app/
# 技術スタック

|                | Version          |
| -------------- | ---------------- |
| 言語           | Python 3.10.6    |
| フレームワーク | Streamlit 1.20.0 |
| ライブラリ     | Openai 0.27.2    |

# 概要

![Code_Doctor_2023-03-14-23-18-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655355/1f22f03e-a494-45b2-c9f6-87918b474160.png)


- プログラミング言語をプルダウンメニューから選択します。

  ![Code_Doctor_2023-03-14-23-04-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655355/ea2f32ff-609a-68c6-7e67-c616cb141ffb.png)


- レビューしてほしいコードを貼り付けます。

     ![Code_Doctor_2023-03-14-23-08-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655355/e6ad6d40-6de0-b59a-2e19-c42e0be23dce.png)


- 生成ボタンを押します。

- 簡単なアドバイスや修正案が表示されます。

  ![Code_Doctor_2023-03-14-23-27-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655355/1263988a-ae40-783a-fec2-727408355e11.png)

# ソースコード
```python
import streamlit as st
import openai
import os

openai.api_key = "OPENAI_API_KEY"

def generate_advice(code, language):
    res = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {
                "role": "system",
                "content": f"Please output at least 3 advices for the input program in Japanese. The language specification should follow {language} ."
            },
            {
                "role": "user",
                "content": code
            },
        ],
    )
    return res["choices"][0]["message"]["content"]

language_list = ["Python", "JavaScript", "Java", "Go", "C", "C++", "Ruby", "PHP", "Swift", "TypepScript"]

st.title("Code Doctor")
st.header('プログラムのアドバイスを行うアプリです')
selected_language = st.selectbox("プログラミング言語を選択してください", language_list)
text_input = st.text_area("アドバイスしてほしいコードを入力してください", "")

if st.button("生成"):
    advices = generate_advice(text_input, language=selected_language)
    st.write(advices)
 
```

# まとめ

今回、chatGPT API と streamlit を初めて使ってみましたが、めちゃくちゃ簡単に開発、デプロイができました！（プログラムファイルは 1 つだけ）

使い方がわかったので、chatGPT をもっと生かしたオリジナリティあるプロダクトを次は作ってみたいですね！

# 参考

https://note.com/nero1014/n/n09a2ce7843b8

https://tech.nri-net.com/entry/create_app_using_chatgpt
頑張らないエンジニアのすゝめ

### あなた誰？
どうも初めましてたくびー(@takubii)って言います。
エンジニア歴５年目でWeb系のフロントエンド、バックエンドどちらもそこそこ書けるプログラマーです。

趣味はゲームと漫画です。完全なインドア趣味で帰宅後に時間がいくらあっても足りません。
年はアラサーなんですが、エンジニア歴が短めなのは別の機会があれば記事にしたいと思います。

### ブログを書く目的
エンジニアといえば何かと勉強が必要だと言われがちですが、もっとゆるくてもやっていけるよってことを伝えていきたいなと思ってブログを書いていこうと思います。

私もエンジニアなりたての頃は通勤中に技術書読んだり、土日に少しコード書いたりといったことをやっていましたが、今は趣味に全振りしています。
だからといって、まったく成長していないわけではないと思っています。

じゃあいつ勉強をしているのかというと、業務中の空いた時間だったり、そもそも振られているタスクを解決するために調べたりしているうちに自然と技術力はつくと思います。
あと、インプット量を確保するためにRSSに登録して気になったブログやネット記事はそこそこの頻度でチェックしています。（一応プライベートでもチェックしていますが、これって勉強に入るんですかね？）

そんな感じで仕事時間のみで勉強をして、プライベートは趣味を楽しもうというのが私のモットーです。

エンジニアといえば勉強を続けなければいけない、まわりの人は常に学んでいる、といったエンジニア特有の価値観に疲弊しつつある人にもう少しゆるく成長してもいいんじゃないのということを届けたいと思います。

### 終わりに
初心者向けの記事やポエムが多くなりそうな予感がしていますが、これからよろしくお願いします。
興味を持っていただけた方はまた別の記事を読んでくださると嬉しく思います。
試作2号機使ってみてもらった結果

待ちに待った時が来たのだ。多くの英霊が無駄死にでなかった事の証のために(ガノタァ…)

前回の記事で作った試作2号機(PDFを結合するプログラム)をexe化して、Pythonをインストールしていないパソコンで動かしてもらってみた。

結果、、、

「パスが見つかりません」

…ですよね〜知ってた(^q^)

一旦調べてみたら割とけっこうな人たちがここで足止めを食らっていたみたいな記事がたくさん出てきた。
試していくうちにグチャグチャになっていくコード、かなしい😭

```py
import sys

desktop_dir = os.path.expanduser("~/Desktop")
print(desktop_dir)
```

↑これを入れるとデスクトップまでのパスが共通にできるっぽい。有志の方に感謝🙏💦
さっそく入れてみた。<br>

```py
import os
import sys

desktop_dir = os.path.expanduser("~/Desktop")
print(desktop_dir)

from PyPDF2 import PdfMerger
#モジュールとオブジェクトをインポート#

folder_a = "C:/Users/〇〇〇〇/Desktop/PDF_binding/PDF/"
```

…まあエラー出ますよねえ。こーれ分っかんねえなあ(゜-゜)ｯｽｩｰｰｰｰｰｰｰｰ…

…

…

…

( ﾟдﾟ)ﾊｯ!💡

これfolder_aに代入したパスをそのままDesktop_dirのところに入れてやればええやんけ！！

```py
import os
import sys

#↓ここ変えて下にあったとこ消した
folder_a = os.path.expanduser("~/Desktop/PDF_binding/PDF/")
print(desktop_dir)

from PyPDF2 import PdfMerger
#モジュールとオブジェクトをインポート#
```

結果…

動作したあああああああ良かったああああああああうおおおおお😭
こーれめちゃくちゃ気持ちいいです🌟

忘れないうちに画像圧縮のプログラムもexe化した。やったぜ👍👍👍
次はPDF圧縮のプログラムを組んでexe化までやるぞい！！！

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

PS：この記事HTML形式の装飾できるんかーい！マークダウン記法ってそういうことなんかーい！またひとつ知識がついたZE🌟
初心者向けVisual ChatGPTの使い方with Google Colab

事前：
1.Googleアカウント
2.課金したOpenAi Api key

youtubeにも動画を送った：
https://www.youtube.com/watch?v=bQJWMWSue_Q&t=2s

手順：
Google Colabの画面を開く
新しいFileを作る
下の順で、順次実行（pipエラーを無視して）

# clone the repo
!git clone https://github.com/Armkas/visual-chatgpt-colab.git

# Go to directory
cd visual-chatgpt-colab

# Use my branch
!git checkout runWithCodlab

# Install
!pip install -r requirements.txt

# Replace with your private OpenAI key (Must paid key)
# Execute these 2 lines together
import os
os.environ["OPENAI_API_KEY"] = "sk-ooooooooooooooooooooooo"

# Start Visual ChatGPT !
# Advice for 1 Tesla T4 15GB  (Google Colab)                       
!python visual_chatgpt.py --load "ImageCaptioning_cuda:0,Text2Image_cuda:0"

結構待つ後に、Running on public URL: https://ooooooooooo.gradio.live
が出る。そのリンクを開く。

終わり！
「セキュリティの自動化に向けたDevSecOpsの推進と苦労」参加レポート #DevSecOps_findy

3月14日、「[セキュリティの自動化に向けたDevSecOpsの推進と苦労](https://findy.connpass.com/event/275315/)」に参加してきました。

今回はモデーレータのファインディ株式会社 北川 雅士 [@OnigiriMa_shi](https://twitter.com/OnigiriMa_shi)さん、Ubie株式会社 水谷 正慶 [@m_mizutani](https://twitter.com/m_mizutani)さん、Snyk[^snyk]社 相澤 俊幸 [@ToshiAizawa](https://twitter.com/ToshiAizawa)さんを交えた座談会形式の回でした。

[^snyk]: 読みは「スニーク」です。

## DevSecOpsとは
まず最初に、スピーカーのみなさんがDevSecOpsをどう定義づけているかという話題。
相澤さんは、以下のように定義されていました。
- ソフトウェア開発・運用モデルDevOpsにセキュリティを包含したもの
- DevOpsはソフトウェアデリバリの加速
- DevSecOpsによりセキュリティを考慮してもソフトウェアデリバリの速度が落ちない
- セキュリティは従来では開発の後の方でやっていたが、上流で行う

水谷さんの場合は、「厳密な定義はしていない」と前置きしつつ、以下のお話をされていました。
- プロダクト開発の工程の中で、エンジニアリングによってプロダクトの安全性を向上させる仕組みを構築・展開していく取り組み
- 人間による対応には限界がある
- ソフトウェアの力でスケールさせる
- Devの概念を取り入れてSecをやっていく

## DevSecOpsにおける課題と悩み・乗り越え方
### - Ubie社における推進や苦労したこと
スピーカーはUbie株式会社 水谷 正慶 [@m_mizutani](https://twitter.com/m_mizutani)さん。

- 推進するメンバーの必要性
    - セキュリティに詳しいだけでは不十分。プロダクト開発、セキュリティ両方見通せる人が必要
- 文化や取り組みの浸透
    - セキュリティとは別の問題（たとえば直近のビジネスの問題）に目が行きがち
    - 対応策として
        - DesignDocを作ってデザインレビューを導入している
        - 脆弱性対応に関するガイドラインの作成
        - セキュリティチームによる毎週のチェックと呼びかけ
- 自動化にも限度がある
    - トリアージが困難
    - 把握しきれない問題もある
    - 対応策として
        - CIによるセキュリティチェック
        - プロダクトの脆弱性管理ツールの導入

### - 海外で起きていること・事例など（Snyk社）
スピーカーはSnyk社 相澤 俊幸 [@ToshiAizawa](https://twitter.com/ToshiAizawa)さん。

従来のセキュリティは「ノー」ということが仕事（「脆弱性があるからリリースできませんよ」ということ）だったが、
近年では、セキュリティ担当者がより有効的になり、サービスを利用する人々に重点が置かれるようになってきたとのことです。

Log4Shell(CVE-2021-44228）の脆弱性対応に関する調査[^Log4Shell]によると、Log4Shell修正対応に数週間から1ヶ月以上要したとの回答が52%とのことで、脆弱性対応の難しさがよく分かる結果でした。
Synk顧客でLog4Shell(CVE-2021-44228）を2日間で修正対応した割合についても紹介されていて、こちらは91%とかなり迅速に対応できているようです。DevSecOpsがセキュリティを重視しつつ開発の速度を落としていない好例と言えるのではないでしょうか。
[^Log4Shell]: https://blog.isc2.org/isc2_blog/2022/02/log4j-remediation-exposes-cybersecurity-workforce-gap.html

また、Snyk社はセキュリティチェックの自動化を行うプロダクトを提供している会社ですが、前のトークでの水谷さんの「自動化にも限度がある」という発言には強く共感されていて、「自動化でできること・できないことの切り分けは重要」と話されていました。

## DevSecOpsを考えるときにまずやること・意識すること
最後に、DevSecOpsを考えるときにまずやること・意識することについての話題。

水谷さんは以下を挙げられていました。
- investの小さい施策から始める
- 対応するメンバーのワークフローまで考えながら仕組み化する
- 全体としての統制や情報の管理をどうするかを考える

相澤さんは以下を挙げられていました。
- 開発の戦力化（みんながセキュリティに強くなるのは現実的に不可能なので、ツールの力を借りて強くなる）
- Test early, test often, and test fast

## 最後に
昔はセキュリティというと専門性が高くて分業化されているイメージが強かったのですが、近年ではDevOpsの文脈に組み込まれて、誰でも関わる分野になってきているようですね。
考えてみればソースコードレビューも静的解析ツールを使ってレビューアーの負担を軽くするなど、スーパーエンジニア的な人に頼らない傾向があります。
最短経路で成果を挙げるためには、自分自身が強くなる発想以外にも「以下に楽するか」[^raku]も考えるとよさそうです。
[^raku]: 「プログラマの三大美徳」的な意味で
【Nuxt bridge × axios】でデータを取得する

# 環境
nuxt bridge
vue2.6
@nuxtjs/axios

# 概要
[公式](https://nuxt.com/docs/bridge/bridge-composition-api#useasync-and-usefetch)に書いている`useLazyAsyncData`や`useLazyFetch`がなぜか機能しなかったので、axiosを使ってデータを取得することにしました。

正解ではないかもしれませんので、ご参考程度に見てください。

# 実装方法
```show.vue
<template>
    {{ user.id }}
</template>

<script setup>
const nuxtApp = useNuxtApp();
const user = ref({});

(async () => {
  await nuxtApp.$axios
    .$get('/api/users/' + userId)
    .then((response) => {
      user.value = response.data;
    })
    .catch((error) => {
      console.log(error)
    });
})();
</script>
```
ポイント・注意点としては、、、

composition-apiなのでrefでリアクティブなデータ定義としています。
(あえて、reactiveではなくrefを使う形にしています)

さらに以下のように`{}`として空のオブジェクトを定義しないと、`user.id`が`undefined`となってしまいました。
`const user = ref({});`

もっといい書き方があれば、是非とも教えてください。
【Linux】Linux主要コマンドまとめ


## 背景
- Linuxコマンドを何度学習しても頭から抜けてしまうので、忘れないようにいくつかのLinuxコマンドをまとめた。

## Linuxコマンドとその説明
|コマンド  |説明  |
|---|---|
|cat | ファイルの内容を出力する　|
|chmod | ファイルのパーミッションを変更する |
|chown | ファイルの所有ユーザーと所有グループを変更する  |
|cp | ファイルやディレクトリをコピーする |
|date | 日付と時刻を表示する |
|echo | 指定した文字列を表示する |
|head | ファイルの先頭部分を表示する |
|install | ファイルの属性を指定してコピーを行う |
|kill | プロセスにシグナルを送信する |
|ls | ファイルの一覧を表示する |
|mkdir | ディレクトリを作成する |
|mv | ファイルやディレクトリを移動する |
|pwd| カレントディレクトリの絶対パスを表示する |
|rm | ファイルやディレクトリを削除する |
|rmdir | ディレクトリを削除する |
|sort | ファイルを行単位でソートする |
|tail | ファイルの末尾部分を表示する |
|test | ファイルの存在確認や値の比較を行う |
|touch | 文字の変換や削除を行う |
|who | ログイン中のユーザー情報を表示する |
|whoami | 自分のユーザー名を表示する |
【Flutter】ColumnやRowで使用するMainAxisAlignmentのレイアウトまとめ

## はじめに

タイトルのとおり，ColumnやRowに指定するMainAxisAlignmentのレイアウトがいつも分からなくなるので整理します。
(特に`spaceBetween`, `spaceAround`, `spaceEvenly` これらの違いは整列アイテムの外側スペースのサイズが違う)

## レイアウト

<img width="280" title="Screenshot" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595983/27ab7f27-e7ee-cd0e-adde-0ed778d7be9e.png">


| MainAxisAlignment | 間隔   | 外側                                 |
| ----------------- | ------ | ------------------------------------ |
| start             | なし   | 整列開始のサイドはなし               |
| end               | なし   | 整列開始の逆サイドはなし             |
| center            | なし   | 両サイドは同一スペース               |
| spaceBetween      | 等間隔 | **なし**                                 |
| spaceAround       | 等間隔 | 両サイドにアイテム間隔の**半分**スペース |
| spaceEvenly       | 等間隔 | 両サイドにアイテム間隔と**同等**スペース |

<details><summary>サンプルコード</summary>

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

final List<Widget> items = [
  Colors.black12,
  Colors.black26,
  Colors.black38,
  Colors.black45,
]
    .map(
      (e) => ColoredBox(
        color: e,
        child: const SizedBox(
          width: 40,
          height: 50,
          child: Placeholder(),
        ),
      ),
    )
    .toList();

class MainAxisAlignmentView extends StatelessWidget {
  const MainAxisAlignmentView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('MainAxisAlignment Sample'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: const [
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.start,
          ),
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.end,
          ),
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.center,
          ),
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
          ),
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
          ),
          _MainAxisAlignmentView(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          ),
        ],
      ),
    );
  }
}

class _MainAxisAlignmentView extends StatelessWidget {
  const _MainAxisAlignmentView({
    required this.mainAxisAlignment,
  });

  final MainAxisAlignment mainAxisAlignment;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Padding(
          padding: const EdgeInsets.all(4.0),
          child: Text(
            'MainAxisAlignment.${mainAxisAlignment.name}',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
        ),
        Row(
          mainAxisAlignment: mainAxisAlignment,
          children: items,
        ),
      ],
    );
  }
}

```

</details>

## 参考文献

- [Flutter 公式 MainAxisAlignment](https://api.flutter.dev/flutter/rendering/MainAxisAlignment.html)
Git関連_言葉の学習

# 学習のゴール
- Git関連を理解し、扱えるようになる。
- 自分のPC上にある作品をインターネット上にアップロードできるようになる。
  つまり、ローカルレポジトリをリモートレポジトリにアップロードできるようになる。
## Gitとは
- バージョン管理システム
    - PC内にあるもの。
    - バージョン=変更履歴
    - いつ誰が何を変更したのか、変更内容の差分を確認できる。
    - 変更内容を戻すことができる。
- チーム開発の時に利用する
    - 変更履歴の確認・変更
        - いつ・誰が変更したのかをチェックするため。
        - 前回からどのような変更があったのか確認するため
    - 以前の変更履歴に戻す
        - エラーが出て、どうしようもない時に元の状態に戻す。
## GitHubとは
- Gitを扱ったWebサービス（gitのホスティングサービス）
    - インターネット上にあるもの
    - システム内部を可視化して、チーム全体に情報を共有できる。
## GitHib Desktopとは
- Git操作を可視化してくれるWebアプリケーション
    - 自分のPCからインターネット上にプロダクトをアップロードする際にはGit操作が必要。
    - そのGit操作を絵で見て簡単に操作できるようにしてくれるアプリ（GUIツール）

        - UI = User Intergace（ユーザー境界面 = Webサイトの画面 = 見た目）
        - GUI = Graphical User Interface（ビジュアルで操作できる画面）
        - CUI = Charactor User Interface（文字情報で操作できる画面）
        - UX = Uxer Experience（ユーザー体験 = 使いやすさ）
    - レポジトリ
        - 空間、場所、フォルダ
    - ローカル
        - 地元=自分のPC
        - ローカルレポジトリ
            - 自分のPC上にあるフォルダ
    - リモート
        - 離れた=インターネット上
        - リモートレポジトリ
            - GitHub上にあるフォルダ
    - add
        - Gitシステムへ保存するファイルを選択する
    - commit
        - addされたファイルやフォルダをGitシステムへ保存する
    - push
        - Gitシステムに登録されたファイルやフォルダをGitHubに押し上げる
Javaのクラスについて_staticを理解しよう

paizaラーニングforTEAM Java入門編
レッスン7の#08

```Java:7-#08
// staticを理解しよう

public class Main {
    public static void main(String[] args) {
        // Item apple = new Item(120, 15);
        int total = Item.getTotalAmount(120, 15);
        System.out.println("合計金額は" + total + "円です。");
        // Item orange = new Item(85, 32);
        // System.out.println("合計金額は" + orange.getTotalAmount() + "円です。");
    }
}

class Item {
    // private int price;
    // private int quantity;
    private static double tax = 1.08;

    // public Item(int newPrice, int newQuantity) {
        // price = newPrice;
        // quantity = newQuantity;
    // }

    public static int getTotalAmount(int price, int quantity) {
        return (int)(price * quantity * tax);
    }
}

// staticのメンバー変数は、オブジェクトで共通して利用できる_つまりすべてのインスタンスで共通し利用できる
// オブジェクトを作らなくてもメソッドなどが利用できるようになる
// mainメソッドはstaticとなっているので、オブジェクトを作らなくても呼び出すことができる
// だから、プログラムの実行時にmainメソッドを最初に呼び出すことができる

// "Ctrl + /" で1行分のコメントアウトができる(paizaだから？？)
CMake: 定義済みの変数の値を表示する方法

# 背景
CMake に関わることになった際、既存の定義がさっぱりわからなかったので、まずは表示する方法をと思った際に調べたもの

# 方法

- 変数一覧を取得
- {名前}={値} って感じで表示。
    - VERBOSE で出しても

```cmake
get_cmake_property (_variableNames VARIABLES)
foreach (_variableName IN LISTS _variableNames)
  message (STATUS " ${_variableName}=${${_variableName}}")
endforeach ()
```

# あとがき

set(LINK_LIBRARIES) で読み込んでるやつも、どうやってるのかさっぱり・・
うーん
【Vue】refを使ってリアクティブなデータを扱う

# refとは？
refはvue3のcomposition APIで「リアクティブな変数を扱うために使うもの」です。
vue2ではこんな感じで、dataで定義してましたが、vue3からはdataは使わなくなります。

```test.vue
<script>
export default {
    data() {
        return {
            name: 'hoge'
        }
    }
}
</script>
```

ちなみにリアクティブな変数とは、値が更新された時に変更が検知される状態です。
値の変更を検知することで、即座に画面に反映させたりすることができます。

# refはこうやって使う
今回は簡単な基本パターンを書いていきます。

```ref-test.vue
<script setup>
    const name = ref('山田太郎')
    
    // valueでアクセスすることが可能
    console.log(name.value);
</script>

<template>
    <!-- テンプレート側で使うときはvalueは不要 -->
    {{ name }}　<!-- 山田太郎が表示される -->
</template>

```

ここで混乱してしまうが、`script`と`template`とで値の参照の仕方が異なることです。

`script`内では、refで値をラッピングすることで正確なリアクティブの機能を実現しています。そのため、
valueというプロパティを使ってrefの中身を取り出して使います。

`template`の中では、refでラッピングしていても自動でアンラップしてくれて、直感的にわかりやすくデータを扱うことができます。

# refの中身を更新してみる

```ref-test.vue
<script setup>
    const name = ref('山田太郎')
    
    const changeName = () => {
        name.value = '田中二郎' //値の代入もvalueに対して行う
    }

</script>

<template>
    {{ name }}　<!-- ボタンを押すと、田中二郎が表示されるようになる -->
    <button @click="changeName">名前変更ボタン</button>
</template>
```

値に更新を加えたいときも、valueに代入する形で行います。

vue2と結構書き方が違うので、最初は混乱しましたが、分かれば便利です。
また、応用版とかも書いていきたいと思います。
Javaのクラスについて_アクセス修飾子を理解する

paizaラーニングforTEAM Java入門編
レッスン7の#07

```Java:7-#07
// アクセス修飾子を理解しよう

public class Main {
    public static void main(String[] args) {
        Player player = new Player("勇者");
        player.walk();
        
        // ここから変数myNameにはアクセスできない
    }
}

class Player {
    private String myName;
    
    public Player(String name) {
        myName = name;
    }
    
    public void walk() {
        System.out.println(myName + "は荒野を歩いていた。");
    }
}

// publicやpricateがアクセス修飾子
// publicがついているクラスやメソッドは、他のどのクラスやメソッドからも呼び出すことができる
// privateがついているメンバー変数やメソッドは、そのクラスの中からだけアクセスすることができる

// プログラムを実行するとMainクラスが呼び出される_publicになっているので誰でも利用できる
// Mainクラスにはmainメソッドがあるので、mainメソッドがまず最初に実行される_publicになっているのでどこからでも呼び出せる
[VBS] Excelファイルを開いて最前面に表示する

## 背景

特定のExcelファイルを手軽に開きたくなりました。
実際は開いた後にいろいろやるんですが、うまく開くまでにえらい苦労したので、そのエッセンスを記録しておきます。
これのショートカットファイルをデスクトップに置いて、ショートカットキーを設定するとワンタッチで動かせます。

環境は次の通り。

- Windows 11 Home 22H2
- Excel 365 Desktop 2302(ビルド16130.20218)

## コード

```vb
' SJIS
' 変数の宣言を強制
Option Explicit

Dim oWsh : Set oWsh = WScript.CreateObject("WScript.Shell")
Dim oFSO:Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim fpath:fpath = oFSO.GetParentFolderName(WScript.ScriptFullName) & "\ワークシート.xlsx"

' GetObjectでファイルパスを渡すと、（なければ新たに開いてから）オブジェクトが得られる
Dim oWb:set oWb = GetObject(fpath)
Call oWb.Activate ' なくても動いた
oWb.Windows(1).Visible = True
Call oWsh.AppActivate(oWb.Application.Caption)
' ここでマクロとかいろいろ実行する
```

Applicationは、変数で受けると別インスタンス（ウィンドウ）ができてしまいました。

## 参考

[【VBScript】使える時に使いたいVBScript(WSH)のコード - Qiita](https://qiita.com/Tabito/items/3772ec852908c7a1988f)
[GetObject(, "Excel~")だけで無く、GetObject(ファイル名)も活用しよう - Qiita](https://qiita.com/nukie_53/items/12cc0a3fc295a446a045)
[Bingチャット](https://www.bing.com/)
Javaのクラスについて_文字列や配列もオブジェクトになっている

paizaラーニングforTEAM Java入門編
レッスン7の#06

```Java:7-#06
// 文字列や配列もオブジェクトになっている

public class Main {
    public static void main(String[] args) {
        // 文字列はStringクラスのオブジェクト
        String text = new String("hello world");
        // String text = "hello world";
        System.out.println(text);
        System.out.println(text.length()); // lengthメソッドで文字数を調べられる
        
        int[] numbers = new int[4]; // 0が4つ並ぶ配列オブジェクトを生成
        for (int item : numbers) {
            System.out.print(item + ", ");
        }
        System.out.println("");
        System.out.println(numbers.length); // 配列ではlengthをメンバー変数のように扱うことができる？？
    }
}

// Javaではint, doubleはオブジェクトではない
【Swift】SwiftLintをSwiftPMで導入する

# はじめに

https://qiita.com/SNQ-2001/items/c695beb8b8d033620231

これのSwiftLint版です。

# インストール
① 「File」を選択します
② 「Add Packages...」を選択します
![スクリーンショット 2023-03-14 21.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/44a45d2d-6afc-9301-7070-3a24bee7d6f9.png)

③ `https://github.com/realm/SwiftLint`を検索します
④ 「Dependency Rule」をBranchにして`main`を指定します
⑤ 「Add Package」を選択します
![スクリーンショット 2023-03-14 21.21.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/59b15c02-d268-d1ed-6c49-d82d2a09f80c.png)

⑥ 「Add Package」を選択します
![スクリーンショット 2023-03-14 22.02.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/27ebb84c-6729-a38f-853a-80a24e89138e.png)

# 設定
① プロジェクトを選択します
② ターゲットを選択します
③ 「Build Phases」を選択します
④ 「+」を選択します
![スクリーンショット 2023-03-14 22.06.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3d539db5-a425-8a91-b9af-69a0838673ce.png)

⑤ 「SwiftLintPlugin」を選択します
⑥ 「Add」を選択します
![スクリーンショット 2023-03-14 22.09.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/820039a5-f07e-478e-a2aa-f42644e7a5ff.png)

# 実行
① ビルドします
![スクリーンショット 2023-03-14 22.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8da34a9d-9a92-7b25-34a0-8438b1adb857.png)

② 「Trust & Enable All」を選択します
![スクリーンショット 2023-03-14 22.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/90b59157-5c9c-e71d-fd56-6f00f2013701.png)

動作しました
![スクリーンショット 2023-03-14 22.20.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/200501fe-c047-ceed-b504-e88e02e830a2.png)

# おわり
今まで色々な方法でSwiftLintを実行してみましたが、これが1番簡単な方法だと思います。
Javaのクラスについて_クラスで、引数と戻り値のあるメソッドを作る

paizaラーニングforTEAM Java入門編
レッスン7の#05

```Java:7-#05
// クラスで、引数と戻り値のあるメソッドを作る

public class Main {
    public static void main(String[] args) {
        Item apple = new Item(120, 15); // ItemクラスからItemオブジェクトを作成して変数appleに代入_2つの引数がメンバー変数
        System.out.println("合計金額は" + apple.getTotalAmount() + "円です。");
        Item orange = new Item(85, 32);
        System.out.println("合計金額は" + orange.getTotalAmount() + "円です。");
    }
}

class Item {
    private int price; // 単価というメンバー変数を宣言
    private int quantity; // 個数というメンバー変数を宣言
    // Itemというコンストラクタを用意
    public Item(int newPrice, int newQuantity) {
        // 2つのメンバー変数に引数を代入
        price = newPrice;
        quantity = newQuantity;
    }
    
    // 合計金額を計算するメソッド
    public int getTotalAmount() {
        return price * quantity;
    }
}

// Itemの意味の違い
// 5行目の最初のItem：変数appleがItem型のオブジェクトを格納するということ
// 5行目の後ろの方のItem：クラスのItemコンストラクタの呼び出しを表している
ShellScriptのdateコマンド

# date コマンド

現在の時刻を取得したり、設定したりするコマンド。OSが刻んでいる日時がずれている場合は、root権限でこのコマンドを使って正しい日時を設定する。

時刻の表示フォーマットを指定することもできる。

「30日後は何日か？」などの簡単な日時の計算もできる。

現在日時ではなく、処理にかかる時間を測定するにはtimeコマンドを使う。

# 基本的な使い方
```
# 現在の日時を表示
$ date

# 現在の日時をUTCで表示
$ date -u

# フォーマットは + で始まる書式で指定
$ date "+%Y%m%d-%H%M%S"

# 24時間後の日時を表示
$ date -d tomorrow

# -d の代わりに --date でも同じ
$ date --date tomorrow

# 30日後の日付を表示
date "+%Y/%m/%d" -d "30 days"
```

OSが刻んでいる現在日時を修正するにはroot権限で実行する。
```
$ sudo date -s "2013/09/04 12:17:00"
```
# オプション

- **-d 日時, --date 日時**
日時を指定
- **-u, --utc, --universal**
UTCで表示
- **-r ファイルパス, --reference=ファイルパス**
ファイルの更新日時を表示
- **--help**
ヘルプ表示
- **--version**
バージョン表示

# 日時表示のフォーマットのサンプル 2021/01/24
よくあるフォーマットのチートシート。

|フォーマット	|コマンド例	|出力サンプル |
|--- |--- |--- |         
|YYYY/MM/DD hh:mm:ss	|date "+%Y/%m/%d %H:%M:%S"	|2017/09/07 07:16:51 |
|YYYY-MM-DDThh:mm:ss	|date +%Y-%m-%dT%H:%M:%S	|2017-09-07T07:16:51 |
|YYYYMMDD-hhmmss	|date +%Y%m%d-%H%M%S	|20170907-071651 |

# 参考サイト
https://hydrocul.github.io/wiki/commands/date.html
Javaのメール送信機能を使ってメール送信してみた

今日も備忘録です。

## このドキュメントについて

以前、springの機能を利用してメール送信を実装してみたのですが、今回はjavaのメール送信機能を利用して実装してみました。

前回同様、gmailのsmtpサーバーを利用して、メール送信します。

前回のspringの記事は以下。

https://qiita.com/ry-s/items/4ce9a5856461119a4718

## 実行環境

・Java17

## 実装
```java
@Service
@RequiredArgsConstructor
@Slf4j
public class MailSenderService {
    private final MailConfig mailConfig;
    private final MailConfigValue mailConfigValue;

    public boolean smtpMailSender() {
        var properties = new Properties();
        properties.put("mail.smtp.host", mailConfig.getHost());
        properties.put("mail.smtp.port", mailConfig.getPort());
        properties.put("mail.smtp.auth", mailConfigValue.isAuth());
        properties.put("mail.smtp.starttls.enable","true");

       class smtpAuth extends Authenticator {
           @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(mailConfig.getUserName(), mailConfig.getPassword());
            }
        }
        // メールセッションの確立
        var session = Session.getInstance(properties, new smtpAuth());

       // メッセージ部分の作成
        var message = new MimeMessage(session);
        try {
            // message.setFrom("xxx@gmail.com"); メールのFROMにメールアドレスだけでなく、文字を入れたい時下のを利用
            message.setFrom(new InternetAddress("xxx@gmail.com", "テスト"));
            message.setText("javaのメール送信テスト");
            message.setSubject("テストで送ります");
            message.setRecipients(Message.RecipientType.TO, "xxx@gmail.com");
            message.setRecipients(Message.RecipientType.CC, "xxx.com");
            Transport.send(message);
        } catch (MessagingException | UnsupportedEncodingException e) {
            throw new RuntimeException("smtpメール送信エラー", e);
        }
    }
}
```

説明：

1. Propertiesクラスにキーと値をセットで設定していく。
   サーバー接続に必要なホストとポート番号、ユーザー認証や通信を暗号化するためにSTARTTLSを設定します。
   STARTTLSを設定しないとgmailでは、メール接続できなかったので、注意が必要。

2. Authenticatorクラスを継承したクラスを用意して、getPasswordAuthenticationメソッドをオーバーライドする。
    このメソッドは、パスワード認証が必要な場合に呼び出されるメソッドです。
    返却値はパスワードとユーザー名を保持するPasswordAuthenticationクラス。

3. メールセッションを確立する。
    Session.getDefaultInstance()だとキャッシュが残って、前回の接続が消えないみたいな問題があるみたいなので、getInstance()を利用してます。
    この時に、2.のパスワード認証が呼び出されるのかなと思ってます。

4. あとはメッセージ設定して、Transport.send()でメール送信ができます。


## まとめ
実装してみて思ったことは、フレームワークなので、当然っちゃ当然だとは思いますが、
springでのメール送信の方が断然楽でした。
パスワード認証とかホストの設定とかその辺りはフレームワークの機能としてやってくれているんだろうなと。。

ただ、springを利用しないやり方も知っていて損はないと思うので、やってみてよかったです。
フレームワークのありがたさを知りました。
Javaのクラスについて_クラスから生成したオブジェクトをArrayListに代入

paizaラーニングforTEAM Java入門編
レッスン7の#04

```Java:7-#04
// RPGの敵クラスを作る
import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 生成したオブジェクトをenemiesというArrayListに代入
        // ArrayList<Enemy>もクラスを設計図としてオブジェクトを作成して利用する
        // ArrayList<Enemy>のような、要素であるオブジェクトを入れ、グループを表すクラスをコレクションという
        ArrayList<Enemy> enemies = new ArrayList<Enemy>();
        enemies.add(new Enemy("スライム"));
        enemies.add(new Enemy("モンスター"));
        enemies.add(new Enemy("ドラゴン"));
        
        // 同じEnemyクラスから作った複数のオブジェクトをArrayListのenemiesに追加して、ループ処理で共通のattackメソッドを呼び出す
        // 要素を取り出すメンバー変数はEnemyクラスを元にしたEnemy型になっている
        for(Enemy member : enemies) {
            member.attack();
        }
    }
}

class Enemy {
    private String myName;
    
    public Enemy(String name) {
        myName = name;
    }
    
    public void attack() {
        System.out.println(myName + "は、勇者を攻撃した。");
    }
}

// クラスは分類という意味_同じEnemyクラスにいる敵だから同じattackメソッドが使える
// インスタンスは実例という意味_Enemyクラスで敵という分類を定義して、スライムやモンスターという実例をオブジェクトとして生成している
Python演習問題＿0【　リストとディクショナリ練習問題①　】

# Python #
## リストとディクショナリ ##
```
【問題１：買い物】
あなたは、果物屋さんで買い物をしています。果物屋さんは、リンゴ、バナナ、イチゴ、キウイ、メロン、パイナップルの6種類の果物を売っています。あなたは、以下のようなリストで、買いたい果物のリストを作成しました。

buy_list = ["りんご", "イチゴ", "パイナップル"]
果物屋さんが持っている果物と、その値段は以下のディクショナリで与えられています。

fruits = {"りんご": 100, "バナナ": 80, "イチゴ": 200, "キウイ": 150, "メロン": 500, "パイナップル": 400}
あなたは、買いたい果物のリスト(buy_list)を使って、買い物の合計金額を計算しようとしています。果物屋さんが持っている果物のうち、買いたい果物のみを購入する場合の合計金額を計算してください。
```
##  ##
```
【問題2:ピザを注文】
あなたは、友達と一緒にピザを食べることになりました。あなたたちは、以下のようなリストで、注文したいピザの種類を決めました。

order_list = ["マルゲリータ", "マリナーラ", "クワトロフォルマッジ"]
ピザ屋さんが持っているピザと、その値段は以下のディクショナリで与えられています。

pizza = {"マルゲリータ": 1000, "マリナーラ": 1200, "カプリチョーザ": 1400, "クワトロフォルマッジ": 1600}
あなたたちは、注文したいピザのリスト(order_list)を使って、注文の合計金額を計算しようとしています。ピザ屋さんが持っているピザのうち、注文したいピザのみを購入する場合の合計金額を計算してください。
```
##  ##
```
【問題3：ショッピング】
あなたは、ショッピングリストを作成しようとしています。以下のようなリストを作成しました。

shopping_list = ["りんご", "バナナ", "チーズ", "ヨーグルト"]
あなたは、各商品の数量も記録したいと思い、以下のような辞書を作成しました。

quantity = {"りんご": 5, "バナナ": 3, "チーズ": 2, "ヨーグルト": 1}
あなたは、各商品の合計数量を計算しようとしています。リスト(shopping_list)と辞書(quantity)を使って、各商品の合計数量を計算してください。
```
##  ##
```
【問題4：先生気分】 
あなたは、ある学校の成績処理をすることになりました。学校には、以下のような成績表があります。

grades = [   
 {"name": "Alice", "math": 80, "english": 75, "science": 90},   
 {"name": "Bob", "math": 90, "english": 85, "science": 95},   
 {"name": "Charlie", "math": 70, "english": 65, "science": 80},   
 {"name": "David", "math": 60, "english": 55, "science": 70}
]

上記の成績表では、各生徒の名前(name)と、数学(math)、英語(english)、理科(science)の点数が記録されています。あなたは、以下の機能を実装することになりました。

条件1：各科目の平均点を計算する。
条件2：各生徒の平均点を計算する。
条件3：全科目の平均点を計算する。
以上の機能を実現するために、Pythonで必要な処理を行ってください。
```
##  ##
```
[問題5：スポーツクラブ] 
あなたは、スポーツクラブのマネージャーです。クラブには、以下のようなメンバーリストがあります。

members = [   
 {"name": "Alice", "age": 20, "gender": "female", "sports": ["basketball", "tennis"]},
 {"name": "Bob", "age": 25, "gender": "male", "sports": ["baseball", "soccer", "volleyball"]},
 {"name": "Charlie", "age": 30, "gender": "male", "sports": ["tennis", "golf"]},
 {"name": "David", "age": 35, "gender": "male", "sports": ["swimming"]}
]

上記のメンバーリストでは、各メンバーの名前(name)、年齢(age)、性別(gender)、スポーツ(sports)が記録されています。あなたは、以下の機能を実装することになりました。

条件1：バスケットボールをする人のリストを作成する。
条件2：男性のリストを作成する。
条件3：年齢が30以上の人のリストを作成する。
条件4：ゴルフをする女性がいるかどうかを確認する。
以上の機能を実現するために、Pythonで必要な処理を行ってください。
```
【Chrome111】Tab Hover Card Imagesを無効にする

当然全員が[tab-hover-card-imagesを無効にしている](https://qiita.com/rana_kualu/items/a8f2fd0ba73666a46888)と思いますが、なんとChrome111でこの設定が削除されました。
クソが

Chrome111時点では[一応無効にすることができます](https://support.google.com/chrome/thread/205183151/how-to-disable-this-disgusting-thing-tab-preview-tab-hover-card?hl=en)。


・まず[chrome://flags/](chrome://flags/)を開く
・設定`Temporarily unexpire M110 flags`を`Enable`にしてChromeを再起動する
・設定`Tab Hover Card Images`が現れるので`Disabled`にしてChromeを再起動する

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/b1422c38-7f48-fa90-127f-b6cba76eb3e1.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/c04e4978-4066-f194-09ab-ff24c366f2a2.png)

これで`Tab Hover Card Images`を無効化することができます。
とはいえフラグ`Temporarily unexpire M110 flags`はいずれ削除されるので、すなわち、そのうちこの手順では`Tab Hover Card Images`を無効化できなくなります。
クソが

誰か早くアドオン作って。
未定義のルーティングへのアクセスをエラーハンドリングする方法

# ルーティングを一つ追加すれば良いだけ
    Route::fallback(function () {
    abort(404);
    });

このルーティングを使えば、未定義のルーティングにアクセスした時に404エラーを返すことができる。
開発にて、POST送信用のルーティングにGET送信でリクエストを送ってきた場合に、どう対策しようかと調べていたところ、たどり着いたもの。

簡単にエラーハンドリングできるので、お手軽でした。
Linuxの環境変数の設定ファイルの読み込まれる順番

Linuxの環境変数の設定ファイルの読み込まれる順番について、毎回調べているような気がするので、メモとして残します。

# 1. ログイン時に読み込まれる設定ファイル

<table>
  <tr>
    <th>読込順</th>
    <th>ファイル1</th>
    <th>ファイル2</th>
    <th>ファイル3</th>
    <th>概要</th>
  </tr>
  <tr>
    <td rowspan="2" style="text-align: right;">1</td>
    <td rowspan="2" style="text-align: left;">/etc/profile</td>
    <td colspan="2" style="text-align: left;">/etc/profile.d</td>
    <td rowspan="2" style="text-align: left;">「/etc/profile」の中で「/etc/profile.d」配下のシェルと「/etc/bashrc」が呼び出される。</td>
  </tr>
  <tr>
    <td colspan="2" style="text-align: left;">/etc/bashrc</td>
  </tr>
  <tr>
    <td style="text-align: right;">2</td>
    <td style="text-align: left;">~/.bash_profile</td>
    <td style="text-align: left;">~/.bashrc</td>
    <td style="text-align: left;">/etc/bashrc</td>
    <td style="text-align: left;">「~/.bash_profile」の中で「~/.bashrc」が呼び出され、「~/.bashrc」の中で「/etc/bashrc」が呼び出される。</td>
  </tr>
  <tr>
    <td style="text-align: right;">3</td>
    <td colspan="3" style="text-align: left;">~/.bash_login</td>
    <td style="text-align: left;">「~/.bash_profile」が存在しない場合呼び出される。<br>※CentOS8ではデフォルトでは存在しないファイル。</td>
  </tr>
  <tr>
    <td style="text-align: right;">4</td>
    <td colspan="3" style="text-align: left;">~/.profile</td>
    <td style="text-align: left;">「~/.bash_profile」と「~/.bash_login」が存在しない場合呼び出される。<br>※CentOS8ではデフォルトでは存在しないファイル。</td>
  </tr>
</table>

```console:実行結果
[yasushi-jp@centos85 ~]$ bash --login
/etc/profile start
/etc/profile.d start
/etc/profile.d end
/etc/bashrc start
/etc/bashrc end
/etc/profile end
~/.bash_profile start
~/.bashrc start
/etc/bashrc start
/etc/bashrc end
~/.bashrc end
~/.bash_profile end
[yasushi-jp@centos85 ~]$
```

# 2. Bash実行時に読み込まれる設定ファイル

<table>
  <tr>
    <th>読込順</th>
    <th>ファイル1</th>
    <th>ファイル2</th>
    <th>ファイル3</th>
    <th>概要</th>
  </tr>
  <tr>
    <td style="text-align: right;">1</td>
    <td style="text-align: left;">~/.bashrc</td>
    <td style="text-align: left;">/etc/bashrc</td>
    <td style="text-align: left;">/etc/profile.d</td>
    <td style="text-align: left;">「~/.bashrc」の中で「/etc/bashrc」が呼び出され、「/etc/bashrc」の中で「/etc/profile.d」配下のシェルが呼び出される。</td>
  </tr>  
</table>

```console:実行結果
[yasushi-jp@centos85 ~]$ bash
~/.bashrc start
/etc/bashrc start
/etc/profile.d start
/etc/profile.d end
/etc/bashrc end
~/.bashrc end
[yasushi-jp@centos85 ~]$
```

---
以上