OmniAICreator/Qiita-1.07M huggingface dataset:
pclpyとpyMeshLabを使っているプログラムをpyinstallerで実行ファイルにする(Windows,Anaconda)

## 目的
- WindowsのAnacondaでpclpyとpyMeshLabを使いたい
  - 動く事を優先
- pyinstallerで実行ファイルにしたい

## pclpy
- PCL(point cloud library)のpythonラッパー

https://github.com/dimatura/pypcl

- condaでもインストールできるが、自分の環境だとうまく動かないのでpipでインストールする

https://pypi.org/project/pclpy/

## pyMeshLab
- MeshLabのpythonライブラリ

https://pymeshlab.readthedocs.io/en/latest/

## 手順
### 仮想環境を作る
`conda create -n py36 python=3.6`

- 動作

### モジュールのインストール
`pip install pclpy`
`pip install pymeshlab`
`conda install pyinstaller`

### プログラムを書く
(略)

hoge.pyとする

### 実行ファイルの作成

`pyinstaller hoge.py --collect-all pclpy --collect-all pclpy_dependencies --collect-all pymeshlab --onefile`

- pclpy_dependenciesにはpclpyで使っているDLLファイルがあるので、それも加える

### 参考
https://stackoverflow.com/questions/71520132/pyinstaller-and-pymeshlab
Sublime Text 4 で Terminal を動かすまで (Mac OS)

## Sublime Text 4 をインストール

* Sublime Text の公式ページにアクセス
  * https://www.sublimetext.com/download
* `macOS` を選択してダウンロード
* ダウンロードした zip ファイルを解凍，起動してインストール

## Package をインストール

* `Command + Shift + P`
* `Package Control: Install Package` を選択
* `TerminalView` を選択

## Terminal を起動

* `Command + Shift + P`
* `Terminal View: Open Bash Terminal` を選択
type parameter with restriction

? extends Xは、?そのものか、サブクラスを意味する
T extends Aは、AかAのサブクラス（以下の例ではB)
```java
class A{
    void method(){
        System.out.println("A");
    };
}
class B extends A{
    @Override
    void method(){
        System.out.println("B");
    };
}
class C {
    void method(){};
}
class X <T extends A>{
    void method(T t) {
        t.method();
    }
}
public class Outer {
    public static void main(String args[]) {
        X<A> x1 = new X();
        x1.method(new A());
        x1.method(new B());
        X<B> x2 = new X();
        x2.method(new B());
//        X<C> x3 = new X();
    }
}
```
```
A
B
B
```
AのサブクラスではないCをtype parameterに指定するとcompile error
```java
        X<C> x3 = new X();
```
```
-------------------------------------------------------------
COMPILATION ERROR : 
-------------------------------------------------------------
com/mycompany/mavenproject1/Outer.java:[37,11] 型引数com.mycompany.mavenproject1.Cは型変数Tの境界内にありません
1 error
```
List,ArrayListを使ったサンプル
declare side, set sideのgenericsは一致しなければならない
```java
class Sample extends Number{

    @Override
    public int intValue() {
        throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
    }

    @Override
    public long longValue() {
        throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
    }

    @Override
    public float floatValue() {
        throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
    }

    @Override
    public double doubleValue() {
        throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
    }
}
public class SampleProject {
    public static void main(String[] args) {
        List<Number> l = new ArrayList<Number>();
        List<? extends Number> l2 = new ArrayList<Number>();
        List<? super Number> l3 = new ArrayList<Number>();
        List<Sample> l4 = new ArrayList<Number>();
        List<Object> l5 = new ArrayList<Number>();
    }
}
```
```
C:\Users\java\Documents\NetBeansProjects\SampleProject\src\sampleproject\SampleProject.java:36: エラー: 不適合な型: ArrayList<Number>をList<Sample>に変換できません:
        List<Sample> l4 = new ArrayList<Number>();
C:\Users\java\Documents\NetBeansProjects\SampleProject\src\sampleproject\SampleProject.java:37: エラー: 不適合な型: ArrayList<Number>をList<Object>に変換できません:
        List<Object> l5 = new ArrayList<Number>();
```
Julia: MQTT の Publish

## プログラム

```js:publish.jl
#! /snap/bin/julia

# --------------------------------------------------------------------
import Pkg
# Pkg.add(url="https://github.com/denglerchr/Mosquitto.jl")
# Pkg.add("JSON")
using JSON
using Mosquitto

println(stderr,"*** 開始 ***")
client = Client("example.com", 1883)

for it =0 : 7
	unit_aa = Dict()
	unit_aa["ledno"] = it
	unit_aa["status"] = true
	json_str = JSON.json(unit_aa)
	publish(client, "M5Stack", json_str)
	sleep(2.0)
	unit_aa["status"] = false
	json_str = JSON.json(unit_aa)
	publish(client, "M5Stack", json_str)
end

disconnect(client)


println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

## 実行結果

```text
$ ./publish.jl 
*** 開始 ***
Single thread, loop will be blocking, start it manually using loop_start(::Client) or call loop(client) regularly.
*** 終了 ***
```
【React】環境変数を渡して、axiosのURLに渡したい

## 実施したいこと
ReactでapiのURLを入れてpost処理を行いたい

## やったこと
* .envファイルを作る
```typescript:.env
REACT_APP_API="http://localhost:3100/api"
```
* Reactで呼び出す
```typescript:App.tsx
await axios.post(`${process.env.REACT_APP_RESERVATION_API}`
```

自分ははじめそのまま打ちこんだままだったのでうまく動きませんでした。バッククォートと{}を付けましょう
```typescript:App.tsx
await axios.post(process.env.REACT_APP_RESERVATION_API
```

.envファイル、Reactファイルともなのですが、Reactで環境変数を呼び出すときは`REACT_APP`が必須のようです。
【Unit Test】Missing required module 'ABC'の対処

## はじめに
UnitTest内で`@testable import (AppName)`を宣言したときに、`"Missing required module （モジュール名）"`が表示された場合の対処方法を備忘録として残します。

## 解決方法
`自分のテストのTarget ▶︎ Build Settings ▶︎ Testing ▶︎ Test Host`へと移動し、

【変更前】
`$(BUILT_PRODUCTS_DIR)/MyApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MyApp`
【変更後】
`$(BUILT_PRODUCTS_DIR)/MyApp.app/MyApp`

の通りに値を変更してください。

※別の対処法もあるみたいです。
[【Xcode】Missing required module 'XXXXX'を修正する](https://qiita.com/SNQ-2001/items/1947c35ab4ed43e11b64)
# 開発環境
- Xcode 14.2
# 参考URL
- [Missing required module 'FirebaseCore' in unit tests #10049](https://github.com/firebase/firebase-ios-sdk/issues/10049)
Render.com(無料枠) データベースの使い分け

# 新しくデータベースを作成したい場合

Render.com（無料枠)は1つまでしかデータベースを起動できないようです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2881997/8c7f4fea-e273-da54-2910-7c58f470e06d.png)

新たに作成する際は、起動中のデータベースを停止してから行う必要があります。
Suspend Database ボタンで停止できます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2881997/677ca2a5-6944-ff2e-bf69-09421b1ecb53.png)

これで新たにデータベースを作成できます。
※複数データベースを作成しても、起動できるのは1つのみです。

# 体験談

Rails チュートリアルで作成した「Sample_app」を元に、
Twitterのような「tweet_app」を作成してRender.comにデプロイしました。

1つしかデータベースを作成できないと思っていたため、「sample_app」「tweet_app」ともに同じデータベースを使っていました。

指定するテーブル名・モデル名が同じだったので、アプリ間でユーザー・投稿が同期する現象になってしまったようです。

それぞれ別のデータベースに紐づけることで解決しました。
Apple M2搭載 Mac miniでJuliaベンチマーク

M2搭載Mac miniを入手したのでごく軽くベンチマークを取ってみました。比較対象を含め、以下の3つのマシンで計測を行いました。言語はJulia1.8です。

1. Apple M2 Pro macOS13.2
2. Intel Xeon W-2245 Ubuntu 22.04（ハイパースレッディングは無効に設定しています）
3. Intel Core i5 12600K Windows 11 Home（ハイパースレッディング有効）

全ての測定で、Juliaに明示的に与えるスレッド数は1です。しかし、`BLAS.get_num_threads()`はマシン１〜３でそれぞれデフォルトの６、４、８となっています。

# 測定
## ソース
```julia
#疎行列と（普通の）ベクトルの積
function bench_sparse(N ;n = 50)
    Ms = [sprand(N,N, 1/N) for i in 1:n]
    v = rand(N)
    
    @benchmark begin
        Y1 = deepcopy($v)
        Y2 = similar($v)
        for M in $Ms
            mul!(Y2, M, Y1)
            Y1, Y2 = Y2, Y1
        end
        Y1
    end
end

#密行列とベクトルの積
function bench_dense(N ;n = 50)
    Ms = [rand(N,N) for i in 1:n]
    v = rand(N)
    
    @benchmark begin
        Y1 = deepcopy($v)
        Y2 = similar($v)
        for M in $Ms
            mul!(Y2, M, Y1)
            Y1, Y2 = Y2, Y1
        end
        Y1
    end
end

#固有値分解
function bench_ed(N)
    rnd = rand(N,N)
    @benchmark eigen($rnd)
end
```

## 結果
疎行列
![bench_sparse.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113311/690a6144-c8c4-d2c8-ff23-1b6804a7fda9.png)

密行列
![bench_dense.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113311/249fa46b-2dd0-b648-d085-7c206c2af813.png)

固有値分解
![bench_ed.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113311/3091842c-d87e-1d94-57c6-95c6176bf911.png)

# ひとこと
こんなに拮抗するとは思わなかった。
covariant, invariant

Objectの変数にStringの変数を代入できるのはcovariantという
Objectの変数にStringの変数を代入できないのはinvariantという

# array
arrayはcovariant
arrayの場合、declareしたarrayのtypeではなくarray ref先のarrayのtypeを示している
初期化子を使ってdeclareすると初期化のtypeではなく、declareに指定したtypeになる。
# generics
genericsはinvariantなので、
List\<Object> l = new ArrayList\<string>();は compile-error
List\<Object>にadd(String)とすれば、その要素はStringになる。
プログラム的にはList\<Object>なので、for(Object o:li)のように取り出す。
new ArrayList\<String>();の\<String>はプログラム的にも意味をなしていないように見える。

```java
public class Outer {
    public static void main(String args[]) {
        Object[] o = {"A","B"};
        Object[] o1 = {1,1};
        Integer[] i = {1,2};
        String[] s = {"A","B"};
        Object[] o2 = s;
        Object[] o3 = i;
        System.out.println(s.getClass());
        System.out.println(o.getClass());
        System.out.println(o1.getClass());
        System.out.println(o2.getClass());
        System.out.println(o3.getClass());
        System.out.println("---------");
        List l = new ArrayList<String>();
        l.add("A");
        l.add(100);
        List<Object> l2 = new ArrayList<>();
        l2.add("A");
        l2.add(100);
        Consumer<Object> c = x -> System.out.println(x.getClass());
        l.forEach(c);
        System.out.println("---------");
        l2.forEach(c);
    }
}
```
```
class [Ljava.lang.String;
class [Ljava.lang.Object;
class [Ljava.lang.Object;
class [Ljava.lang.String;
class [Ljava.lang.Integer;
---------
class java.lang.String
class java.lang.Integer
---------
class java.lang.String
class java.lang.Integer
```
【SSDモデル】Hard Negative Mining について

物体検出の SSD モデルについて勉強中ですが、そこに出てくる **Hard Negative Mining** の実装アルゴリズムが難解で面白かったのでメモっておきます。
基本的に「物体検出とGAN、オートエンコーダー、画像処理入門 PyTorch/TensorFlow2による発展的・実装ディープラーニング」を読んでいますが、Hard Negative Mining についてはわかりにくかったので 、[「つくりながら学ぶ！PyTorchによる発展ディープラーニング」のgitサイト](https://github.com/YutaroOgawa/pytorch_advanced/blob/master/2_objectdetection/utils/ssd_model.py)を読んで理解できました。

Hard Negative Mining とは、大まかに言えば損失値の配列 loss_c から損失値の大きい順に上位の部分を抜き出すものです。以下に簡単化したプログラムを示します。本物のloss_cは（バッチサイズ、8732）の2階テンソルですが、ここでは1階テンソルで、バッチの次元は無視しています。しかしアルゴリズムの本質は同じです。sortを2度取っているところが難解の原因で、これが何を行っているかがこの記事のポイントです。

```python:
import numpy as np
import torch

x_np = np.array([9, 1, 8, 2, 3])
loss_c = torch.tensor(x_np)                    # loss_c : 損失の配列

_, loss_idx = loss_c.sort(0, descending=True)  # loss_c を降順に並べる
print(loss_idx)                                # loss_idx = tensor([0, 2, 4, 3, 1])

_, idx_rank = loss_idx.sort(0)                 # loss_idx を昇順に並べる
print(idx_rank)                                # idx_rank = tensor([0, 4, 1, 3, 2])

```

ここでは以下が成り立つのがポイントです。

**loss_c を降順で並べた時に、loss_c[i] は idx_rank[i] 番目になる。** ここで i は任意のindex。

つまり idx_rank には loss_c の降順の順番が入っています。面白いですよね。
これは以下のような意味です。

```
idx_rank[0] = 0   ==> loss_c[0]=9 は 0 番目
idx_rank[1] = 4   ==> loss_c[1]=1 は 4 番目
idx_rank[2] = 1   ==> loss_c[2]=8 は 1 番目
idx_rank[3] = 3   ==> loss_c[3]=2 は 3 番目
idx_rank[4] = 2   ==> loss_c[4]=3 は 2 番目
```

証明は以下のようになります。

```
loss_c = [c0, c1, c2, ...., cn] のようなテンソル配列とします。

 _, idx_rank = loss_idx.sort(0)                 # loss_idx を昇順に並べる

上の idx_rank の定義から以下が言える。
x = idx_rank[i] とすると、x は loss_idx の i 番目に小さい要素の index です。
そもそも loss_idx の要素は index なので 0,1,2,3,..,n の値となり、
i 番目に小さい要素は i となります。つまり loss_idx[x] = i です。

idx_rank[i]=x
 0             i
|-----------------------------------------------------------
|             |x|
|-----------------------------------------------------------

loss_idx[x]=i
 0                    x
|-----------------------------------------------------------
|                    |i|
|-----------------------------------------------------------


_, loss_idx = loss_c.sort(0, descending=True)  # loss_c を降順に並べる

上の lass_idx の定義から以下が言える。
loss_idx[x] = i　の意味するところは、loss_c を降順に並べたときに、
loss_c[i] が x 番目、つまり idx_rank[i] 番目、であるということである。

loss_c[i]=ci
 0            i
|-----------------------------------------------------------
|            |ci|
|-----------------------------------------------------------
              ↑ idx_rank[i] 番目に大きい要素

```


**idx_rank で　Hard Negative Mining の mask をつくる**


```
num_neg をある閾値とする。
loss_c[i] は idx_rank[i] 番目であるので、idx_rank で 以下のように mask を作ることで、
num_neg 番目以下の loss_c の要素を抽出できる。

neg_mask = idx_rank < (num_neg).expand_as(idx_rank)
```

実際に最初のプログラムの続きとして以下を実行すると望むものがえられます。

```python
num_neg = torch.tensor(3)
neg_mask = idx_rank < (num_neg).expand_as(idx_rank)
print(neg_mask)      # tensor([ True, False,  True, False,  True])
```

つまり neg_mask で loss_c の 0 番目と 2 番, 4 番の要素を抽出することができます。
これは降順のトップ3ですので、期待にあったものです。


今回は以上です。
普通の中学生が競プロに挑戦して挫折した話。

半年ぐらい前にAtcoderに挑戦して挫折した話を備忘録として残します。
なんだか壮大なタイトルですが、コンテスト参加は2回だけです。すいません。
なぜ、2回だけで諦めてしまったのかを書こうと思います。

## 競プロ？ナニソレオイシイノ？
半年ぐらい前だと思います。ちょうどこのQiitaを見始めたときに、ホームの記事にちょいちょい見かけるネタが有りました。入茶、緑、青...... 
そう。競プロです。
気になって調べてみると、なにやら面白そうではないですか。色々な言語を使って問題を解いていく競技プログラミング。ちょうどやっていたUnityで行き詰まっていたので、息抜きがてらやってみることにしました。

## 最初の壁
Atcoderについて調べてみると、使う言語は大半がC++だったので、ある程度知識があったC#ではなく、C++を勉強しました。とはいっても、基礎文法だけでいけるだろなんて舐めていました。
合計5時間ぐらいで[こちら]("https://atcoder.jp/contests/abs")のサイトが殆どできた（と思っていた）ので、週末のBeginnercontestに参加しようと大会情報を見たところ、最初の壁が。

それは、コンテストの時間。

僕は中学生&ロングスリーパーなので大体22時ぐらいには寝てしまうのですが、コンテストは23時までですよね？しかも二時間連続で集中力なんて持つのでしょうか？この時点でちょっと諦めかけていました。

## 次々と迫りくる壁
他にも様々な課題がありました。

1\. 数学
最初のコンテストの日。A問題はすぐに解けたものの、B問題で行き詰まりました。なぜか？
問題文が読めないんです。$\in$とか$\sum$とか。なんですかこいつら？
この記号たちが出てくるのは主に数IA。つまり高校範囲です。中学二年生の自分には全く意味がわかりませんでした。ここでもういいや、と思ってそのコンテストはA問題だけ解いて諦めました。

2\. アルゴリズム
これは自分だけかもしれませんが、半年ぐらいUnityをやっていて、ある程度プログラムが書けると思っていたのがいけませんでした。問題文がわかっても、アルゴリズムはなかなか思いつきません。無理やりfor文で書いたりしてみますが、そう上手くは行きません。アルゴリズムを勉強しなければいけないというのが、苦痛に思えて結局、2回目のコンテストから今現在まで一度もやっていません。

3\.実行速度
何度も提出したのですが、だいたいタイムアウトが帰ってきます。これを見て、いかに自分が効率の悪いコードを書いていたのかわかりました。A,B問題は頑張れば解けるけど、C問題になると途端に手が止まる、そういう人いますかね？

## 結論
自分が挫折したのは、競プロをなめていたのがいけなかったのと、数学やアルゴリズムについての知識がなさすぎるからでした。それをきっかけに数学を頑張り始めて、ようやく理解できるようになったと思います（今は数Aをやってます）。結果的に挑戦したのは良かったんだと思います。プログラムの実行速度も意識してかけるようになったのも大きな成長だと思います。

※自分への警告
この記事を投稿したからにはやらなければと思い、さっそく今週のコンテストに参加登録しました。
何事も逃げていてはだめなので。
必ずやりましょう。

半年でどれぐらいできるようになったのかまた書いてみようと思います。
エンジニアになって初めて出会った用語たち

現在SESの案件に3つほど参画して、初めて知った用語を棚卸ししていこうと思います。
知られていて当たり前な用語もあると思いますが、暖かい目で見てください。

## 用語
【**Vanilla JavaScript**】
この用語と出会ったきっかけは、案件先でエンジニアの方に言われて知りました。最初は新しいJSのフレームワークかな？と思いましたが、素のJSのことを指していたんですね。
>バニラという表現は、業界でもデ・ファクト・スタンダードとして標準的に企業や個人で広く利用されている。語源は、アイスクリームの標準的な風味であるバニラ味からきている[2]。エリック・レイモンドのジャーゴンファイルによると、バニラは "default" （デフォルト）よりは "ordinary" （普通の・平凡な）の意に近いとしている[3]。


【**データベースチューニング**】
この用語に出会ったきっかけは、SESの面談で聞かれました。経験の有無を聞かれたが、言葉自体知らなかったので、単語自体知らないことを自白しました。ちなみデータベースチューニングという作業自体はまだ未経験です。

>データベースのチューニングとは、データベースの性能維持または向上を阻害するボトルネックを見つけ、その原因を調査し、解決していくことです。

【**アンチパターン**】
この用語に出会ったきっかけは、twitterやら勉強会やらで知りました。同じような単語で「デザインパターン」もよく聞きますね。
>アンチパターンとは、問題への対応策・解決策の類型のうち、よく陥りがちな避けるべき悪い典型例のこと。

【**スパゲッティコード**】
この用語と出会ったきっかけは、改修案件に参画した時にPMと別のエンジニアが会議で話していた時に知りました。エンジニアが使う用語って美味しそうだな〜という印象で覚えました。

>スパゲッティコードとは、コンピュータプログラムの状態を表す俗語の一つで、命令の実行順が複雑に入り組んでいたり、遠く離れた関連性の薄そうなコード間で共通の変数が使われるなど、処理の流れや構造が把握しにくい見通しの悪い状態になっているプログラムのこと。

【**ABテスト**】
この用語と出会ったきっかけは、開発でFirebaseを使っていたらツールに入っていて（Firebase A/B Testing）、なんのテストだろう？と思ったのが出会いのきっかけです。

>ABテストとは、
WebマーケティングにおけるCRO（コンバージョン率を最適化）手法の一つであり、このコンバージョン率を最適化していく様々な工程の中の1つです。

【**LT**】
この用語と出会ったきっかけは、現在所属しているコミュニティで企画が挙がり調べたのと、自社開発のアウトプットのイベントで目にする機会が多かったのがきっかけです。

>「ライトニングトーク」とは、英語で「Lightning Talk」と書き「LT」と略されます。これはカンファレンスやフォーラムなどのプレゼンテーションで、3～5分程度の短い時間で発表する手法のこと。トークイベントなどで十分な持ち時間があったとしても、発表内容を短時間に集約して簡潔にプレゼンするスタイルを言います。

## 参考サイト

https://zenn.dev/seya/articles/66809b3d59151c

https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/database-tuning/#:~:text=1.%20%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AF,%E3%81%8A%E3%81%8F%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

https://e-words.jp/w/%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3.html

https://e-words.jp/w/%E3%82%B9%E3%83%91%E3%82%B2%E3%83%83%E3%83%86%E3%82%A3%E3%82%B3%E3%83%BC%E3%83%89.html

https://www.assion.co.jp/blog/guide-of-abtesting/

https://www.brain-gate.net/content/column/engineer-tips-lt/#:~:text=LT%EF%BC%88%E3%83%A9%E3%82%A4%E3%83%88%E3%83%8B%E3%83%B3%E3%82%B0%E3%83%88%E3%83%BC%E3%82%AF%EF%BC%89%E3%81%A8%E3%81%AF&text=%E3%83%88%E3%83%BC%E3%82%AF%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AA%E3%81%A9%E3%81%A7%E5%8D%81%E5%88%86,%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AA%E3%81%A9%E3%82%82%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

## まとめ
まだまだ知らない用語がたくさん出てくるので、第２弾、第３弾と棚卸できるように勉強していきます！
乞うご期待！
deployerでEC2デプロイ失敗する際の備忘

先日、今までデプロイできていたのが突然デプロイ失敗するという状態になり、解決に手間取ったのでここにまとめます。

## 状況：
・deployerでEC2にアプリケーションをデプロイ時、npm run producrionで処理が進まなくなる
・nodeのバージョンはローカルとEC2で同じ
・ローカルでビルドはできる
・デプロイブランチの間違いはない
・突然デプロイできなくなった
・EC2のディスク容量に問題はない

## 結論：
EC2がメモリ不足となっていた

## 詳細：
導入が必要だったソフトウェアを開発の途中にEC2に入れたことで、
これまで足りていたメモリが足りなくなり、npm run productionできなくなっていました。

EC2はt2.microを設定しており、使用可能なメモリは1GBです。
npm run production時に使用するメモリは300~500MB程度のようで、
途中に導入したソフトウェアが常時600MB程度メモリを使用するようになり、
1GBのメモリでは不十分となったようでした。

## 確認すべきポイント：
・OOM killerによるプロセスの停止のログはないか
→メモリが不足するとOOM killerがプロセスをkillしにいき、そのログが残ります

## 最後に
t2.microだとメモリ不足でnpmタスク進まずデプロイできないということがよくあるようなので、
デプロイできない原因の一つとしてメモリ不足を疑うよう心がけます
【関数について】pythonとJavascriptのスコープの違い

# やろうとしていること
1.グローバルスコープ内で変数を宣言
x
y
z→こいつを関数の中で代入したら、その結果は反映されるのか？
2.関数内でグローバル関数スコープ内で代入
```python:python
x = 100
y = 200
z = 0
def main():
    z = x + y
main() //ここで呼び出し
print(z)
```
![スクリーンショット 2023-02-09 13.39.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/790ad9c0-d31a-9c28-6f7e-6122424aaf3e.png)
→関数内が反映されていないので、0になった
```javascript
let x = 100;
let y = 200;
let z = 0;

function main(){
	z = x + y;
}
main()

console.log(z)
```
![スクリーンショット 2023-02-09 13.38.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/396d466b-fdba-15f9-0e44-20156c647d79.png)
→スコープ内の検索
https://jsfiddle.net/guchon/hxneb6y3/
【Swift】Error building iOS Framework: usr/local/bin/carthage: No such file or directoryへの解決策

## 記事の概要
* CarthageでライブラリをimportしてBuildした際に発生したエラー「Error building iOS Framework: usr/local/bin/carthage: No such file or directory」に対する解決策。

## 作業環境
* Xcode Version 13.4(13F17a)
* Swift 5.0
* MacOS Monterey v12.3.1

## 記事の結論
* Run Script: For Install Build Onlyにチェックを入れる

## 試したこと
* Clean Build
* Input Filesのパスを再入力（手打ちしていたのでパス名をコピーして再入力）
* Shellを/bin/sh以外にしてみる
* 「/usr/local/bin/carthage copy-frameworks」をscriptに入力
* Run Scriptの削除&再生成+Clean Build

## 解決策
* Run Script: For Install Build Onlyにチェックを入れる

![スクリーンショット 2023-02-05 12.40.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3087199/24f8d879-77f5-b42c-6aa9-c1c73946c1f3.png)

* その後Clean Buildして解決


## 参考ページ
* https://stackoverflow.com/questions/40938909/error-building-ios-framework-usr-local-bin-carthage-no-such-file-or-directory
演習で学ぶ　ソフトウエアテスト　メモ

## テストプロセス
### テスト計画
テストの目的、攻め方、スケジュールを決める。ソフトウエア開発がウオーターホールやアジャイルなのか、テストレベル、テストタイプによって、行われるテストが変化する。
### テスト分析
テストアイテムのテストすべき特性を見分け、その特性に対応する要件定義書からテスト可能なものを定義する
### テスト設計
テストアイテムをテストするテストケースを設計。また、テストケースに必要なテストデータを識別し、テスト環境を構築する
### テスト実装
テストに必要な環境、データ、テストを行う手順を用意
### テスト実行
ここで、ブラックボックスやホワイトボックス等を実行し、故障を見つける。
### テスト完了
テスト結果を資産として残す。

## 参考資料
［改訂3版］演習で学ぶソフトウェアテスト 特訓200問
DjangoとDockerの自分のための備忘録

# Djangoの中身がわからない自分へ

##djangoのdocker導入参考url
https://engineer-ninaritai.com/docker-django/
```
#プロジェクト作成
docker run -v "$PWD":/code djangotest django-admin startproject mysite .
"$PWD"でカレントディレクトリを指定

#起動
docker run -v "$PWD":/code -d -p 8000:8000 djangotest python manage.py runserver 0.0.0.0:8000
docker run --rm -v "$PWD":/code  -p 8000:8000 djangotest python manage.py runserver 0.0.0.0:8000
オプション
-d 　デタッチモードでdockerコンテナを起動する
　　　デタッチモードとは？
   　コンテナ内に入らず、バックグラウンドで動作させることができる
-rm コンテナ内でのコマンドの実行が終わったらコンテナを自動で削除する

```
## docker環境でのサーバ起動呪文
docker run --rm -v "$PWD":/code/ -p 8000:8000 my-django-app python manage.py runserver 0.0.0.0:8000


## sercret key対策
そのままgithubにpushするとgitguardianメールが来る、
https://de-milestones.com/django-secret-key-unpublish/


## 始め方
startproject コマンドでプロジェクトを作成
コマンド記入
startapp コマンドで必要なアプリを作成(アプリは複数作成可)
コマンド記入

### フレームワークの中身の流れ
1. ユーザーがURIでリクエストを送る
2. my_django/urls.pyのurlpatternsを参照してどこに飛ばすか決める。


### aopの中身について
#### migrations.py
データベースの設定に関連したフォルダ。
あまり触る必要はなし。
#### admin.py
管理画面に関する設定ファイル。
#### app.py
djangoのアプリケーション自体の設定ができるファイル
#### models.py
データベース操作のためのファイル。SQLを使わずクラスを使ってデータベースを管理できるようになるファイル
#### test.py
テストをするためのファイル。今は使わない。
#### views.py
実際の処理を書くファイル

### app作成後手順
1. setting.pyファイルのINSTALLED_APPSのリストに
アプリ名.app.アプリ名(最初大文字)configという文字列を追加
2. urls.pyにimport includeを追加、path関数


### djangoの処理の流れ
1. リクエストオブジェクトが作成される
2. url.pyを参照してパスに一致した処理を探す
3. その処理をrezuestオブジェクトを引数にして関数を呼び出す
4. 呼び出した関数で処理されたあとはhttpresponseオブジェクトを受け取る
5. 最後にhttpresponseオブジェクトをブラウザに返して描画されてユーザーに見れる
Python入門 無名関数(ラムダ式)

## 概要
Pythonの無名関数及び、ラムダ式についてまとめたいと思います。

:::note alert
以下で、ラムダ式を変数に代入するサンプルコードをご紹介致しますが、後々、ラムダ式を変数に代入するのは`PEP8`で非推奨だということを知りました。ですので、下記に出てくる記述方法は理解する為に使用しているという認識で、実際の記述方法として推奨しているものではないということを留意して頂きますようお願い致します。
:::

## 無名関数(ラムダ式)
### 無名関数とは
無名関数(ラムダ式)とは、匿名関数とも読ばれており、**関数の名前をつける必要がない一行で終わるような関数を作る場合に利用します**。

無名関数を作るには、**ラムダ**という書式を用います。

ラムダ式の構文は以下の様になります。

:::note info
**変数 = lambda 引数1, 引数2 : 式**
:::

### 例
実際にラムダ式を使用すると以下の様になります。
```python:ラムダ式の場合
addition = lambda i: i + 2
print(addition(3))
>>5

multiplication = lambda i: i * 2
print(multiplication(3))
>>6
```

上記のラムダ式を用いた例を関数に置き換えて記述すると以下の様になります。
```python:関数の場合
def addition(i):
    return i + 2
print(addition(3))
>>5

def multiplication(i):
    return i * 2
print(multiplication(3))
>>6
```

## 参考
[【初心者向け】Python 無名関数（ラムダ式）とは？lambda を理解しよう！](https://aiacademy.jp/media/?p=1597)
[Terraform] CloudFront のテンプレートをモジュール化するにあたって、ダイナミックにACMをセットできるようにする

Terraform で CloudFront のテンプレートをモジュール化したいとき、ACMつけるときと付けない時の `viewer_certificate{}` の中身を変えないといけないので、モジュール化できなくて枕を濡らしたことはありませんか？

```terraform:ACM無し
viewer_certificate{
  cloudfront_default_certificate = true
}
```

```terraform:ACM有り
viewer_certificate{
  acm_certificate_arn      = aws_acm_certificate.cert.arn
  ssl_support_method       = "sni-only"
  minimum_protocol_version = "TLSv1.2_2021"
  cloudfront_default_certificate = false
}
```

そんな時は `dynamic` ブロックを使えばいいんです。
`dynamic` ブロックは、配列の中身の分だけ動的に設定してくれるので `default_cert` を使う場合と、ACM を使う場合用の `dynamic` ブロックを用意しておく感じです。

こんな感じ

```terraform
variables "acm_arn" { default = "" }
variables "aliases" {
  type = list
  default = []
}

locals {
  aliases          = var.acm_arn == "" ? [] : var.aliases
  use_default_cert = var.acm_arn == "" ? [true] : []
  use_custom_cert  = var.acm_arn == "" ? [] : [var.acm_arn]
}

resource "aws_cloudfront_distribution" "site" {
  enabled             = true
  aliases             = local.aliases
  price_class         = "PriceClass_All"
  http_version        = "http2and3"

  # CloudFront のデフォルト証明書を使用する場合
  dynamic "viewer_certificate" {
    for_each = local.use_default_cert
    content {
      cloudfront_default_certificate = viewer_certificate.value
    }
  }
  # ACM を使用する場合
  dynamic "viewer_certificate" {
    for_each = local.use_custom_cert
    content {
      acm_certificate_arn      = viewer_certificate.value
      ssl_support_method       = "sni-only"
      minimum_protocol_version = "TLSv1.2_2022"
      cloudfront_default_certificate = false
    }
  }

  # :
}
```

`var.acm_arn` に何もセットされていない場合、以下のようになります。

- `local.use_default_cert` → `[ true ]`
- `local.use_custom_cert` → `[]`

なので、1つ目の `dynamic "viewer_certificate" {}` ブロックしか実行されません。

`var.acm_arn` に何かがセットされている場合、以下のようになります。

- `local.use_default_cert` → `[]`
- `local.use_custom_cert` → `[var.acm_arn]`

なので、2つ目の `dynamic "viewer_certificate" {}` ブロックしか実行されません。

これで、モジュール化しても安心ですね。
型推論

代入、値の受け取りで、宣言部のtypeと値を渡す側のtypeがチェックされる
以下の例ではnew arrayList<Object>()の<Object>が、declare のList<String>の<String>と型があっているかチェックされる
<>（型未指定）、もしくは<String>以外はエラーになる

```java
public class Outer {
    public static void main(String args[]) {
        method(new ArrayList<>());
        method(new ArrayList<String>());   //warn  2重定義
        method(new ArrayList<Object>());   //err
        method2(new ArrayList<>());
        method2(new ArrayList<String>());  //err
        method2(new ArrayList<Object>());  //warn
    }
    static void method(List<String> l) {
        l.forEach(System.out::println);
    }
    static void method2(List<Object> l) {
        l.forEach(System.out::println);
    }
}
```
```
-------------------------------------------------------------
COMPILATION ERROR : 
-------------------------------------------------------------
com/mycompany/mavenproject1/Outer.java:[16,16] 不適合な型: java.util.ArrayList<java.lang.Object>をjava.util.List<java.lang.String>に変換できません:
com/mycompany/mavenproject1/Outer.java:[18,17] 不適合な型: java.util.ArrayList<java.lang.String>をjava.util.List<java.lang.Object>に変換できません:
2 errors 
-------------
```
プロキシーとキャッシュサーバーの違いを教えて下さい

# プロキシーとキャッシュサーバーの違いを教えて下さい

プロキシーサーバーは、ネットワークを介してコンテンツを取得するときに使用されます。プロキシーサーバーは、ネットワーク上のサーバーとクライアントの間の各種通信を管理し、効率的なネットワーク利用を実現します。

キャッシュサーバーは、Webサイトのアクセスを高速化するために使用されます。このサーバーは、最も人気のあるデータを保存し、サーバーからのデータ転送を効率化します。ウェブサイトを閲覧するとき、お客様がリクエストしたデータは、キャッシュサーバーが保持している場合は、サーバーからデータを取得する必要がなくなります。

# プロキシーとキャッシュサーバーは共存できますか?

はい、プロキシーとキャッシュサーバーは共存できます。プロキシーサーバーは、ネットワーク内でのデータ転送を管理し、キャッシュサーバーは、サーバーからのデータ転送を効率化します。両者を組み合わせることで、ネットワークのパフォーマンスを向上させることができます。

# 組み合わされた製品パッケージは、どんなものがありますか?

プロキシーとキャッシュサーバーを組み合わせた製品パッケージとして、次のようなものがあります。

・Webパフォーマンスソリューション：ウェブサイトのパフォーマンスを向上させるためのソリューションで、プロキシーサーバーとキャッシュサーバーを組み合わせたものです。

・コンテンツ配信ネットワーク：Webコンテンツを高速かつ効率的に配信するためのネットワークソリューションで、プロキシーサーバーとキャッシュサーバーを組み合わせたものです。

・ネットワークセキュリティソリューション：ネットワークをセキュリティ保護するためのソリューションで、プロキシーサーバーとキャッシュサーバーを組み合わせたものです。

# ソフトについて教えて下さい。pythonのライブラリはありますか?

プロキシーサーバーのソフトウェアには、Pythonのライブラリとして、urllibとrequestsがあります。urllibは、HTTPやFTPなどのプロトコルを使用してURLを取得するためのPythonライブラリです。requestsは、非常に高度なWebアプリケーションを書くためのPythonライブラリです。

キャッシュサーバーのソフトウェアには、Pythonのライブラリとして、memcachedとredisがあります。memcachedは、サーバー上のデータを高速に取得するためのPythonライブラリです。redisは、高速でスケーラブルなキャッシュストアを構築するためのPythonライブラリです。
Graphene-Python とミドルウェアの関係は？

# Graphene-Python とミドルウェアの関係は？

Graphene-Python は、Python 用の GraphQL 実装です。ミドルウェアとの関係としては、Graphene-Python を使用することで、ミドルウェアを介して GraphQL を実行できます。Graphene-Python を使用すると、GraphQL クエリをエンドポイントとして実行できるようになります。これにより、開発者は、Python ベースのフレームワークを使用して、ミドルウェアを介して GraphQL のクエリを実行できるようになります。

# つまりGraphene-Python とミドルウェアは同じものですか？

いいえ、Graphene-Python とミドルウェアは異なるものです。Graphene-Python は Python 用の GraphQL 実装であり、ミドルウェアは、アプリケーションとサーバーの間で処理を行うプログラムです。Graphene-Python を使用することで、ミドルウェアを介して GraphQL のクエリを実行することができますが、Graphene-Python とミドルウェアは異なるものです。

# ミドルウェアとはミドルウェアという種類のサーバーですか？

いいえ、ミドルウェアとは、アプリケーションとサーバーの間で処理を行うプログラムです。ミドルウェアは、Web サーバーとデータベースなどのサーバーとは異なるもので、アプリケーションサーバーなどの中間で処理を行うために使用されます。

# ミドルウェアはどういうところで使われますか？

ミドルウェアは、アプリケーションとサーバーの間で処理を行うために使用されます。ミドルウェアは、Web アプリケーションの開発、セキュリティ、ネットワーク管理、データ管理などの様々なタスクを行うために使用されます。ミドルウェアは、Web アプリケーションを安全に実行するために重要な役割を担っています。

# 無くても良いのでは?

無くても構いませんが、ミドルウェアは、Web アプリケーションを安全に実行するために重要な役割を果たします。ミドルウェアを使用していない場合、Web アプリケーションが安全に実行されない可能性があります。
Laravel SailでLaravel9環境構築！

# はじめに
ついにLaravelがやってくれました。
何を？
Laravelを動かすためのDocker環境の提供です。

[Laravel 9.x Laravel Sail](https://readouble.com/laravel/9.x/ja/sail.html)

>Laravel Sail（セイル、帆、帆船）は、LaravelのデフォルトのDocker開発環境を操作するための軽量コマンドラインインターフェイスです。

今回はLaravel Sailを利用しながら、Laravel9の開発環境を構築してみます！

# 環境
## ホスト環境(ローカル環境)
- macOS Ventura 13.2
- プロセッサ 2.8Ghz クアッドコア Intel Core i7
- メモリ 16GB
- Docker 20.10.22
- PHP 8.2.2
- Composer 2.5.2

## ゲスト環境(Docker環境)
- PHP 8.2.2
- Laravel 9.51.0

# 手順
## 1. ホスト環境の準備
### 1.1 ホストにPHPとComposerをインストール
Laravelプロジェクトを作成するために、ホスト環境にPHPとComposerを用意する必要があります。

macOSの場合はHomebrewでインストールできます。
- [PHP(Homebrew 公式)](https://formulae.brew.sh/formula/php)
- [Composer(Homebrew 公式)](https://formulae.brew.sh/formula/composer)

### 1.2 Dockerのインストール
SailはDockerを使用してLaravelプロジェクトを実行するようになりますのでDocker Desktopをインストールする必要があります。
[Docker Desktop](https://www.docker.com/products/docker-desktop/)

## 2. Laravelプロジェクトの作成

```sh
curl -s "https://laravel.build/example-app" | bash
```

URLの`example-app`がアプリケーション名になります。
※ アプリケーション名は英数字とハイフン、アンダーバーだけが利用できます。
※ Laravel Sailは新しいLaravelアプリケーションとともに自動的にインストールされます。
※ [既存アプリケーションへのSailインストール](https://readouble.com/laravel/9.x/ja/sail.html)も可能です。

:::note warn
PCのスペックやDocker Desktopの設定、ネットワークなどに起因しますが、かなり時間がかかります。
:::

```sh
Building 870.5s (16/16) FINISHED 
```

## 3. Sailで実行
```sh
cd example-app
./vendor/bin/sail up -d
```

## 4. 確認

http://localhost/

![スクリーンショット 2023-02-09 11.47.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290840/2f88c4b7-2a02-9a5c-3041-fe5f42ffe784.png)

## 5. Sailで停止
```sh
cd example-app
./vendor/bin/sail stop
```


# さいごに

Laravel環境の構築がかなり簡単ですね！
ただ、一つネックなのは、Laravelプロジェクト作成の際にホスト環境でPHPとComposerを用意しないといけない点でしょうか。
Laravelプロジェクト内に`docker-compose.yml`がありますので、コンテナの増減は自由に調整できそうです。
ぜひ、一度使ってみてください。

# 参考
- [Laravel 9.x インストール](https://readouble.com/laravel/9.x/ja/installation.html)
- [Laravel 9.x Laravel Sail](https://readouble.com/laravel/9.x/ja/sail.html)
消したAzure DevOps Wikiの中身を取り出す

すでに消してしまったAzure DevOps Wikiの中身を再び見たいということがある。

全く空っぽにしちゃった場合は、とりあえず1つ仮ページを作る。
すると、そのAzure DevOps Wikiに関するメニューが操作可能になる。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36428/b0527e92-b5e7-387d-7343-59baec21aa7d.jpeg)

`Clone wiki` を選ぶとrepositoryをcloneするurlが得られる。

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36428/aaeecfd5-7189-d45b-1cae-11d382ca5f13.jpeg)

これを手元にgit cloneする。
あとは `git log` なり `git revert` なり `git diff prev-commit-id that-commit-id` なりすれば、むかしそこに何があってどう変更されたかわかる。

WYSIWYG編集できるWikiがMarkdownの集合体であってgit reposでもある、というAzure DevOps Wikiの設計は悪くないなぁ……
LaravelでのSQlite3の接続方法

# 環境
laravel: 8.83.27(laravel8)
composer: 2.4.0
sqlite3: 3.40.1

# 環境設定手順
- databaseフォルダーにSQliteファイルを作成
- .envファイルの編集

# sqliteファイルの作成
databaseフォルダーに直接sqliteファイルを作成
config/database.phpには以下のように設定をされている。
```config/database.php
'sqlite' => [
    'driver' => 'sqlite',
    'url' => env('DATABASE_URL'),
    'database' => env('DB_DATABASE', database_path('database.sqlite')),
    'prefix' => '',
    'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
```
sqliteファイルの設定では、デフォルトでdatabase.sqliteが指定されているため、それ以外のファイル名で設定する際は、こちらの設定も変更する必要がある。

※特にファイル名を変更しない場合は、database.sqliteでファイルを作成を行えば、config/database.phpの設定を行う必要はない

# .envファイルの設定
.envファイルでは、データベースの設定がデフォルトでは以下のように設定されている。
```.env編集前
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=(作成したアプリ名)laravel-app
DB_USERNAME=root
DB_PASSWORD=
```
DB_CONNECTIONがmysqlの設定になっているため、こちらをsqliteに変更する必要がある。
また、sqliteでは、データベース名は設定する必要がないため、DB_DATABASEをコメントアウトする必要がある。

※DB_DATABASEをコメントアウトしなければsqliteファイルに接続ができない

以下のように編集を行う
```.env編集後
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
#DB_DATABASE=(作成したアプリ名)laravel-app
DB_USERNAME=root
DB_PASSWORD=
```

以上で設定が完了
macOSにPowerShellとPowerCLIをインストールする

# 事の経緯

- 私が普段使用しているmacOS(Ventura)上でESXi(vSphere Hypervisor)のカスタムイメージを作る必要性ができた
- ESXiのカスタムイメージの作成にはPowerCLIが必要だが、PowerCLIはPowerShell上でしか動作しない
- ということでmacOSにPowerShellとPowerCLIをインストールする

# PowerShellとは
- Microsoftが開発したCLI兼スクリプト言語
- ざっくりとコマンドプロンプトの強化版
- Windows 7以降では標準でインストールされている
- 2016年にオープンソース化され、macOSやLinuxでもサポートされるようになった
    - GitHub: https://github.com/PowerShell/PowerShell
- ちなみにWindowsに標準でインストールされているWindows PowerShellとOSSとして公開されているPowerShell Coreは厳密には違い、前者でサポートされている機能が後者ではサポートされていないこともあるため注意

# PowerCLIとは

- 正式にはVMware PowerCLI
- VMware vSphereを中心としたVMwareの製品群を管理するためのコマンド群を提供する
- Webサイト: https://developer.vmware.com/web/tool/vmware-powercli
- PowerShell上でのみ動作する
- バージョン10.0.0からmacOS/Linuxでもサポートされるようになった
    - https://blogs.vmware.com/PowerCLI/2018/03/installing-powercli-10-0-0-macos.html

# PowerShellのインストール

```bash
# インストール
$ brew install --cask powershell

# バージョンの確認
$ pwsh -v
PowerShell 7.3.2

# PowerShellのシェルに入る
$ pwsh
PowerShell 7.3.2
PS /Users/username>
```

# PowerCLIのインストール

- 公式ドキュメント: https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.esxi.install.doc/GUID-F02D0C2D-B226-4908-9E5C-2E783D41FE2D.html

```bash
# インストール
PS /Users/username> Install-Module VMware.PowerCLI -Scope CurrentUser

# VMware Customer Experience Improvement Programに参加しない
PS /Users/username> Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false

# インストールされたことを確認
PS /Users/username> Get-Module -Name VMware.PowerCLI -ListAvailable

    Directory: /Users/username/.local/share/powershell/Modules

ModuleType Version    PreRelease Name                                PSEdition ExportedCommands
---------- -------    ---------- ----                                --------- ----------------
Manifest   13.0.0.20…            VMware.PowerCLI                     Desk
```
seed_fuのseedメソッドの引数を活用すれば、似たデータが重複して新規作成されることもないし、idをわざわざ書く必要もないぞと気づいた

## 困ったこと
Railsのseed_fu、こういう風にidなどprimary keyを書くのを巷でよく見かけます。

```ruby:db/fixtures/users.rb
User.seed do |s|
  s.id = 1 # ←
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

User.seed do |s|
  s.id = 2 # ←
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end
```

idなんて自動採番されるんだから、書く必要なくない？

```ruby:db/fixtures/users.rb
User.seed do |s|
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

User.seed do |s|
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end
```

...ほら、削除してもデータ作れるじゃん！と無邪気にどや顔していたのですが、青二才でした。

確かにデータは作れます。しかしながら、seed_fuがいいのは、２回目以降流す時に、変更点だけを追加、または更新してくれるところ。primary keyを指定してあげないと、seed_fuは既存データか新規データかを判別できず、新しいデータをcreateしてしまいます。上記の例で言うと、鈴木一朗、鈴木二朗がダブってできてしまいます。

でもそうしたくない時があると思います。


とほほ。じゃあidを書いてあげて、インクリメントしていくしかないのかと諦めかけました。こんな感じで↓

```ruby:db/fixtures/users.rb
id = 1

User.seed do |s|
  s.id = id
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

id += 1

User.seed do |s|
  s.id = id
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end
```

## もっといい感じのやり方

ちゃんとドキュメントを読んだら、もっとスマートな方法のヒントが書いてありました。

https://github.com/mbleigh/seed-fu#constraints

seedメソッドの引数に「このカラム見てね、あったら新しく作らないでね」と教えておけば、そのカラムで同じデータがDBに既にある場合、それは既存のデータとみなしてくれます。`User.seed(:name)`という具合です。

```ruby:db/fixtures/users.rb
User.seed(:name) do |s|
  s.name = "鈴木一朗"
  s.email = "ichiro@example.com"
end

User.seed(:name) do |s|
  s.name = "鈴木二郎"
  s.email = "jiro@example.com"
end
```

上の例では、DBのnameカラムの中で同じものがあればそれは既存のデータと見なされ、新しくcreateされることはありません。
複数のカラムでデータを特定したいときは、`User.seed(:name, :email)`と引数を複数指定してあげることもできます。

スマートで、ちょっとハッピー。

## 余談
本記事のタイトルの文字数が長いです。

`seed_fuのseedメソッドの引数を活用すれば、似たデータが重複して新規作成されることもないし、idをわざわざ書く必要もないぞと気づいた`

70文字です。
でもQiitaのタイトルは255文字まで行けるそうです。

https://qiita.com/narita1980/items/545e2dc92bd9385cbcb7
Flutterで簡易コーポレートサイト（アプリ）を作成する #3 -タブバー編-

# 概要
Top・Contactができたので、tabを設置してtabでTopとContactを行き来できるようにします。

# 完成イメージ

<img width="300" src="https://dl.dropbox.com/s/7y3tknca8i4w051/000001.jpg" alt="000001.jpg">
<img width="300"  src="https://dl.dropbox.com/s/4eslqi3arbysopg/000010.jpg" alt="000010.jpg">

# タブバー実装
top.dartとcontact.dartと同様の階層に「tab.dart」を作成します。

作成したtab.dartを下記のように記述します。

```tab.dart
import 'package:flutter/material.dart';
import 'package:flutter_website/contact.dart';
import 'package:flutter_website/top.dart';

class TabWidget extends StatefulWidget {
  const TabWidget({super.key});

  @override
  State<TabWidget> createState() => _tabWidgetState();
}

class _tabWidgetState extends State<TabWidget> {
  int _selectedIndex = 0;

  static const List<Widget> _widgetOptions = <Widget>[TopPage(),ContactPage()];

  static const List<Widget> _titleOptions = <Widget>[Text("TOP"), Text("お問合せ")];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: const Color.fromARGB(100, 0, 0, 0),
        title: _titleOptions.elementAt(_selectedIndex),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'TOP',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.info),
            label: 'お問合せ',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}
```
## main.dart編集
main.dartでtabを表示するように編集します。

```diff_dart:main.dart
  import 'package:flutter/material.dart';
+ import 'package:flutter_website/tab.dart';

- import 'top.dart';
- import 'contact.dart';

  void main() {
    runApp(const MyApp());
  }

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

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Website',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
+       home: const TabWidget(),
-       home: const ContactPage(),
      );
    }
  }
```

# 確認
このようにタブバーで移動できるようになります。

<img width="300" src="https://dl.dropbox.com/s/7y3tknca8i4w051/000001.jpg" alt="000001.jpg">

<img width="300"  src="https://dl.dropbox.com/s/4eslqi3arbysopg/000010.jpg" alt="000010.jpg">

# 関連コンテンツ
- 前：[Flutterで簡易コーポレートサイト（アプリ）を作成する #2 -Contact画面編-](https://qiita.com/minimumskills/private/15fe7fdcb0cb6bddcde4)
- [超シンプルなWeb（アプリ）作成を通して各種フロントエンド技術を体験する - 2023 Early -](https://qiita.com/minimumskills/private/9e7efe86e244bb9844b0)
Redmine Wiki タグのフォントサイズを変更する

# TAGのフォントサイズが大きすぎるので変更したい

Redmine Plugin [wiki_extensions](https://www.redmine.org/plugins/redmine_wiki_extensions) でWikiにタグを付けることができますが、タグのフォントサイズが大きすぎるので変更したい。

C:\Bitnami\redmine-4.2.3-1\apps\redmine\htdocs\plugins\redmine_wiki_extensions\assets\stylesheets の
wiki_extensions.css を編集します。

下記の箇所の font-size の指定を変更します。元は xx-large / x-large になっています。

```wiki_extensuons.css
#wiki_extensions_tag_form .tag_field {
    margin-right: 1em;
}

.tag_level5{
    font-size:large;
}

.tag_level4{
    font-size:medium;
}

.tag_level3{
    font-size:medium;
}

.tag_level2{
    font-size:small;
}

.tag_level1{
    font-size:x-small;
}
```

変更後、Redmineの再起動・ブラウザのキャッシュクリヤが必要です。
[Swift] 複数の非同期処理を並列に行う

## はじめに
複数の非同期処理を走らせて、全ての処理が完了したタイミングで特定の処理を行った時の内容です。
これは、配列の中のそれぞれ値に対して、API通信を非同期に実行し、すべてが完了したタイミングでUIに反映させようとした時のお話です。

## 非同期処理
以下のような非同期処理を作成します。
ランダムな数値を生成することで、処理が完了するタイミングがバラバラになるように設定しています。
```swift
func asyncAfter(number: Int, completion: @escaping (_ number: Int, _ interval: Double) -> Void) {
    print("#\(number) Start")
    let interval  = TimeInterval(arc4random() % 100 + 1) / 100
    DispatchQueue.global().asyncAfter(deadline: .now() + interval) {
        completion(number, interval)
    }
}
```

## 非同期処理を並列に実行
まず、`DispatchGroup()`を作成します。
そして、それぞれの値に対して非同期処理を実行する際に`.enter()`を呼び、処理が完了したタイミングで`.leave()`を呼びます。
そうすると、全ての処理が完了したタイミングで、`.notify()`の中の処理が実行されるという仕組みです。
```swift
func asyncTask() {
    let dispatchGroup = DispatchGroup()
    for i in 0 ..< 5 {
        dispatchGroup.enter()
        asyncAfter(number: i) { (number: Int, interval: Double) -> Void in
            defer { dispatchGroup.leave() }
            print("#\(number) completed (interval: \(interval))")
        }
    }

    dispatchGroup.notify(queue: .main) {
        // 全ての処理が完了した時に呼ばれる
        print("all process completed!")
    }
}
```
#### 出力結果
実際に実行してみると、出力結果は以下のようになりました。想定通りの挙動になってそうですね。
まず、for文によってそれぞれの値に対して非同期処理が、`Start`します。
その後、インターバルの短い処理から`completed`されていき、全ての処理が完了したタイミングで、`.notify()`内の処理が呼ばれていることが分かります。
```
#0 Start
#1 Start
#2 Start
#3 Start
#4 Start
#0 completed (interval: 0.18)
#3 completed (interval: 0.57)
#4 completed (interval: 0.6)
#1 completed (interval: 0.67)
#2 completed (interval: 0.93)
all process completed!
```

## コード全文
以下、コードの全文です。
```swift
func asyncTask() {
    let dispatchGroup = DispatchGroup()
    for i in 0 ..< 5 {
        dispatchGroup.enter()
        asyncAfter(number: i) { (number: Int, interval: Double) -> Void in
            defer { dispatchGroup.leave() }
            print("#\(number) completed (interval: \(interval))")
        }
    }

    dispatchGroup.notify(queue: .main) {
        // 全ての処理が完了した時に呼ばれる
        print("all process completed!")
    }
}

func asyncAfter(number: Int, completion: @escaping (_ number: Int, _ interval: Double) -> Void) {
    print("#\(number) Start")
    let interval  = TimeInterval(arc4random() % 100 + 1) / 100
    DispatchQueue.global().asyncAfter(deadline: .now() + interval) {
        completion(number, interval)
    }
}
```

## 参考
https://qiita.com/PearlEarringMinion/items/386e3d2c02c6843d39f0

https://qiita.com/shtnkgm/items/d9b78365a12b08d5bde1

https://nomad.office-aship.info/swift-serial-async/
[Node.js] 既に存在するPostgresから、sequelize用のmodelsファイルを生成したい

# はじめに

Node.jsの老舗ORMである`sequelize`を使用するには、公式によると下記2通りの方法で`Model`を作成しないといけません。

>Models can be defined in two equivalent ways in Sequelize:
>
>- Calling sequelize.define(modelName, attributes, options)
>- Extending Model and calling init(attributes, options)

https://sequelize.org/docs/v6/core-concepts/model-basics/#model-definition

しかし、既に実装済みのDBから、すべてのテーブル分Model定義を頑張って作るのは骨が折れます。
しかも、DDLでは`VARCHAR`なのに、Modelでは`INT`にしてしまった、なんて乖離も起きそうです。
ならリバースエンジニアリングできんかや？　と探してみたら、`sequelize-auto`なるライブラリで実現できそうだったので、使い方をメモしておきます。

# 環境

```text
macOS 13.1
node 18.12.1
npm 8.19.2
"pg": "^8.9.0",
"pg-hstore": "^2.3.4",
"sequelize": "^6.28.0",
"sequelize-auto": "^0.8.8"
```

# Reference

https://sequelize.org/docs/v6/other-topics/migrations/

# 必要になるライブラリのインストール

## sequelize-autoのインストール

```terminal
npm install sequelize-auto
```

## Postgresアクセスのためのライブラリをインストール

`sequelize`も必要になります。

```terminal
npm install sequelize pg pg-hstore
```

## TypeScript系

TypeScriptで実装したいので。

```teminal
npm i typescript @types/node ts-node
```

versionはこちら

```text
"@types/node": "^18.13.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
```

# 設定ファイルの準備

https://github.com/sequelize/sequelize-auto#usage

https://sequelize.org/api/v6/class/src/sequelize.js~sequelize

上記の公式を見ながら、設定ファイルを準備

```config.json
{
  "database": "",
  "host": "",
  "username": "",
  "password": "",
  "dialect": "postgres",
  "schema": "public",
  "dialectOptions": {
    "ssl": true
  },
  "directory": "./src/models",
  "port": 5432,
  "caseModel": "p",
  "caseProp": "o",
  "caseFile": "p",
  "lang": "ts",
}
```

## ちょっとだけ説明

`sequelize`の設定と、`sequelize-suto`の設定が混在しています。

- `database`や`host`なんかはDBに接続するための情報
- `caseModel`や`lang`なんかは、sequelize-autoの設定

## ちょっと詰まったところ

Postgresの`sslmode`を`require`としていたのですが、下記を設定しないと上手く接続できないのでご注意を。

```json
{
  "dialectOptions": {
    "ssl": true
  },
}
```

# コマンド発行

```terminal
npx sequelize-auto --config "./config.json"
```

これで、指定した出力先にModelファイルが出力されるはずです。

# (おまけ)sequelizeから、作成したModelを読み込む

https://github.com/sequelize/sequelize-auto#example

公式にも載ってますが。

```index.ts
import dotenv from 'dotenv';
dotenv.config();
import { Sequelize } from 'sequelize';
import { initModels } from './models/init-models';

const connectionString = process.env.CONNECTION_STRING || '';
const sequelize = new Sequelize(connectionString, {
  benchmark: true,
  logging: (sql: string, timing?: number) => {
    console.log(`${timing}ms`);
  },
});

const models = initModels(sequelize);

export { models };
```

```ts
import { models } from './index'
```

してやることで、すべてのModelにアクセスすることができ、依存関係をきれいに整理することができます。
【忘備録】MacでJavaからPostgreSQLへ接続する

### はじめに
SQLの学習を進めていくと、「さあ！ではJBDCドライバをインストールしてJavaプログラムとDBを接続してみましょう！」というフェーズに入ります。

そんな時、またしてもMac派の私が困り果てたので、同じような人がいるのではないかと思い忘備録として残しておきます。

### 前提条件
- Eclipseがインストールされていること（基本的な使い方が分かる）
- MacにPostgreSQLがインストールできており、練習用のDBやテーブルが作成されている
:::note info
PostgreSQLのインストール方法については、[過去の記事](https://qiita.com/kkarimata/items/acb06f0a219499cbd6ad)で忘備録として残しているので
そちらをご参照ください。
:::
### 作業フロー
作業フローは以下の通りです。
あくまで学習用なのでもっと本格的なものがあるかもしれません😇

1. JDBCドライバをダウンロードする
1. テキトーなところにダウンロードしたjarファイルを置く
1. Eclipseにjarファイルを設置する

#### STEP1- JDBCドライバをインストールする
公式ページからダウンロードしてきます。
[PostgreSQL公式](https://qiita.com/hide/items/5bfe5b322872c61a6896)

JavaのバージョンがJava8以上であれば「Java８」の「Download」をクリックします。

ちなみに私はJava17を使っています。
![スクリーンショット 2023-02-09 9.09.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/041a63f2-3e89-516b-b01a-22415224b8af.png)

#### STEP2- テキトーなところにダウンロードしたjarファイルを置く
ダウンロードが完了すると、.jarという拡張子のファイルがダウンロードされていることを確認できます。

このjarファイルをデスクトップとかわかりやすい場所に置きます。

#### STEP3- Eclipseにjarフィルを設置する
- Eclipseを開きます。
※ワークスペースのディレクトリはどこでもいいです。

- なんでもいいのでJavaプロジェクトを作成します。

- 作成したプロジェクトを右クリックし、出てきたメニューの一番下にある「プロパティー」を選択します。

![スクリーンショット 2023-02-09 10.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/074261cb-caa3-945e-b568-0bb471f4b987.png)

プロパティをクリックすると、以下のような画面が出てきます。
ここで「Javaのビルド・パス」を設定し、「ライブラリ」というタブをクリックします。
そうすると下にフォルダ構成のようなものが出てくると思います。
「モジュールパス」をクリックしてください。

![スクリーンショット 2023-02-09 10.04.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/d4417e5a-e95d-c226-ac57-2c059425a7bd.png)

「モジュールパス」をクリックすると、右側にメニューが出てきます。
その中の「外部JARの追加」をクリックしてください。

![スクリーンショット 2023-02-09 10.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/384b2008-c63d-4175-62f5-46c51f7de571.png)
 
フォルダが開くので、 __STEP1, 2__ で保存したjarファイルを選択して、「open」をクリックします。
![スクリーンショット 2023-02-09 10.12.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/abf59f5e-2acc-6959-1f3b-78876910ce37.png)

以下のようになれば、jarファイルを適切な場所に設置できました！！
最後に「適用して閉じる」をクリックして完了です。

![スクリーンショット 2023-02-09 10.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759696/757267c9-8546-702f-bde7-0efc641c021d.png)


### おわり
これでJavaからPostgreSQLへの接続の準備が整いました。あとはプログラムを書いて実行すると、DBと接続できていることがわかると思います。

Windowsだとクラスパスの設定、とかがあってMacではどのようにやるのかと苦戦していましたがEclipseが解決してくれました。
MacでJavaを学習したいという人にお役に立てればいいなと思います。
Keian wizbook KZG14X128BK 買ってみた。その2

# 概要
keian KZG14X128BK 買ってみた。

# 電話認証してみた。

![20160828045201.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e774e2b2-4481-143f-84c7-c0943904147f.jpeg)

# 認証された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/822cbac2-9eb5-4153-1cdb-35165e70f26f.png)

# ウェブサイト

|web|login|
|:--|:--|
|qiita|github
|chrome|gmail
|paiza|github
|heroku|github
|pulunker|github
|codepen|github
|ヤフオク|
|amazon|
||

# wsl(wsl2じゃない)をインストール。
- windowsの機能
Windowsの機能で「Linux 用 Windows サブシステム」のチェックボックスを選択し、「OK」ボタンを押し機能を有効化します。
- Store
スタートメニューの「Microsoft Store」より、 Ubuntuを検索して18.04LTSをインストールします。

![ubuntu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c4148183-40f3-aa8f-508e-37085eb07b63.png)

- 起動する。

```
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: user
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Installation successful!
Linux 用 Windows サブシステムが Microsoft Store で入手可能になりました。
'wsl.exe --update' を実行するか、https://aka.ms/wslstorepage にアクセスしてアップグレードできます
Microsoft Store から WSL をインストールすると、最新の WSL 更新がより速く提供されます。
詳細については、https://aka.ms/wslstoreinfo
をご覧ください。
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

$ ls
$ pwd
/home/user
$

```

# タイル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/165a10bd-84cb-b187-d4c0-f6da3ce23f42.png)

# お勧め、エディタ。

http://www.hi-ho.ne.jp/a_ogawa/oedit/

# ブックマーク

https://www.st.ryukoku.ac.jp/~kjm/security/memo/

# NeosVR

- intel 最新ドライバー当てて、動いた。祝。


# 仕様

Microsoft Windows10 Pro 64bit

Intel Celeron N4120 クアッドコアCPU
Intel UHD Graphics 600
14インチ 広視野角IPS 1920 x 1080 液晶搭載 ノートパソコン

メモリ4GBとストレージ128GB搭載。さらにSATA3 M.2 SSD(B Key Type 2280/2242) ストレージ増設スロットも搭載。

総合オフィススイートKINGSOFT WPS Office 2を同梱。
以上。
indexメソッド

# indexメソッド
文字列や配列の中に、指定した文字列が含まれていたとき、その文字列が何番目から配置されているのかを整数の値で返します。

## 例
```ruby
str.index(検索したい文字列, [検索を開始する位置])
```


indexメソッドの公式リファレンスはこちら。<br>
https://docs.ruby-lang.org/ja/latest/method/String/i/index.html

# indexメソッドを使ってプログラムを作成します

任意の文字列に"code"が、左から何文字目に出てくるかを返し、その数を出力するメソッドを作りましょう。

呼び出し・出力例は以下のような形で行います。
count_code("codexxcode") → 1（ターミナルの返し）
count_code("aaacodebbb") → 4（ターミナルの返し）
count_code("cozexxcode") → 7（ターミナルの返し）



```ruby
def count_code(str)
  puts (str.index("code") + 1)
end

呼び出し例
count_code("codexxcode")
```

## 解説

indexメソッドは文字列の先頭を0番目から数えて返します。
そのため、検索を開始する位置を+1して、1番目からカウントしてもらうように記述しています。


模範解答例として、以下でもプログラムは実行できます。
第二引数である0を省略して記述したものが上記で書いたものです。
```ruby
def count_code(str)
  puts str.index("code", 0) + 1
end
```