OmniAICreator/Qiita-1.07M huggingface dataset:
SQLを復習する 〜その2〜

# はじめに
[その1](https://qiita.com/Jun_rice/items/3c9dd10f9352e7da168e)はこちら

# メモを記載する
他のプラグラミング言語同様にSQL文中にコメントを記載することができる。
- `ハイフン2つ(--)`から行末までコメント扱いになる
- `/* */`で囲われた部分はコメント扱いになる

```sql
/*　ここからコメント行
    文末までコメント行　*/

SELECT * -- 全ての列を取得
FROM テーブル名;
```

# SELECT文の基本構文
### ASを使用して別名を定義する
SELECT文の記述の後ろに、`AS+任意のキーワード`をつけることで別名を定義することができる。
```sql
SELECT 料金 AS ITEM, 支出 AS RECEIVE
FROM 家計簿 AS MONEYBOOK
WHERE 料金 = '給料'
```
Oracle DBやSQL Server、Db2などはASの記述を省略することができる。

### 別名をつけることによるメリット
- 結果として取得する列のタイトルを任意のものに変更できる
- わかりにくい列名でも、わかりやすく短い別名をつけて利用することができる

# DELETE文の基本構文
```sql
DELETE 
    FROM テーブル名
    (WHERE修飾)
```

### DELETE文を使用する際の注意
上記のようにWHEREを使用しないと、全件削除となってしまうためWHEREなしでのDELETEを実行しないように注意する。

# INSERT文の基本構文
```sql
INSERT INTO テーブル名
           (列名1, 列名2, 列名3・・・)
    VALUES (値1, 値2, 値3)
```
2行目の列名指定は、テーブル全ての列に値を追加する場合には丸ごと省略することが可能

:::note warn
注意
2行目を省略して、`VALUES`を記載する際には`SELECT *`を実行した時に取得される列名の順番と同じでなければいけない
:::
PowerDVDでBlu-ray再生時「現在ご利用になられているバージョンはこの機能に…」とエラーが出る場合の対処法

# 事の起こりは…
PCでBlu-rayを見ようと思い、PowerDVDの体験版とやらをインストールしドライブを再生してみる。

すると…
```
現在ご利用になられている powerdvd のバージョンはこの機能に対応しておりません
```
…と、製品版の購入を促す広告付きのダイアログが出てきた。

仕方なく言われるがまま製品版を購入してみることに。

が、**やはり同様のエラーが出て再生出来ず**…。
以前のノートPCでは問題なかったのに何故…？

当時はソフトウェア側の不良なのかと思い、保証で返金もして貰ったので幸い事なきを得た。

# 対処法
何故か**グラフィックボードを交換したら体験版でも問題なく再生できました**。
以前まで使っていたAMDのグラボでの問題だったんだろうか。
【React】検索ボックス実装時のパフォーマンス改善案①

検索ボックスを実装したら画面が重たくなった…
という経験はないでしょうか。

考えられる原因はいくつかあると思いますが、基本的に**onChange**が悪さをしていることが多いです。

## 原因：テキストが入力されるたびにonChangeで重たい処理が実行されてしまっている

処理が重くなりがちな例
```example.js
const filteringName = (inputValue) => {
    // 高負荷な処理
    someHeavyProcessing();
    
    if (inputValue) {
      const filteredNames = nameListData.filter((name) =>
        name.toLowerCase().includes(inputValue.toLowerCase())
      );
      setNameList(filteredNames);
    } else {
      setNameList(nameListData);
    }
};

...

<TextField
  margin="normal"
  fullWidth
  onChange={(e) => filteringName(e.currentTarget.value)}
/>
```
文字が入力されたり消されたりするたびに直接処理を呼び出しているため、処理の重さやユーザーのタイピング速度によってパフォーマンスに影響がでやすい。


## 解決策

テキスト入力が終わってから処理が実行されるように**カスタムフック**を作ります。

```useDebounce.js
import { useState, useEffect } from "react";

export function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return debouncedValue;
}
```
このカスタムフックでは第一引数に更新するstate,第二引数に何秒間の猶予を持たせるかを設定して発火のタイミングを調整します。

例のコードに当てはめてみる
```example.js
import { useDebounce } from "../customHooks/useDebounce";

...

  const [nameList, setNameList] = useState(nameListData);
  // ↓onChange用
  const [inputText, setInputText] = useState("");
  // ↓今回はonChangeで更新されたテキストを0.5秒後にdebouncedInputTextとして返す設定にする
  const debouncedInputText = useDebounce(inputText, 500);

  const filteringName = (inputValue) => {
    // 高負荷な処理
    someHeavyProcessing();
    
    if (inputValue) {
      const filteredNames = nameListData.filter((name) =>
        name.toLowerCase().includes(inputValue.toLowerCase())
      );
      setNameList(filteredNames);
    } else {
      setNameList(nameListData);
    }
  };

　// ↓useEffectを使ってdebouncedInputTextの値が更新されたタイミングで処理を走らせる
  useEffect(() => {
    filteringName(debouncedInputText);
  }, [debouncedInputText]);

...

<TextField
  margin="normal"
  fullWidth
  onChange={(e) => setInputText(e.currentTarget.value)}
/>
```

流れを整理すると
① テキストフィールドにテキストが入力される
② 0.5秒間テキストが入力されなくなったらuseDebounceが値を返す
③ useDebounceの値更新をuseEffectで検知して本命の処理を実行させる

実際の動き
![useDebounce.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674898/039ad0ae-ca49-d780-f5e4-277b82763547.gif)



このようにすることで高負荷な処理があったとしても、文字が入力されるたびに実行されるのを防ぐことができます。


#### 参考にさせていただいた記事
https://zenn.dev/luvmini511/articles/4924cc4cf19bc9

#### 関連記事
https://qiita.com/nakakobiz0281/items/47fefcac8bf2c79cb022

https://qiita.com/nakakobiz0281/items/2cf4138dadb5a1edc7b9
axios(ajax)でエラー時のレスポンスbodyが取得できなかったので調べてみた

## はじめに
RailsのAPIからデータを取得する際に、axiosを使用してエラーが発生した場合、レスポンスを取得することができずに困った

## 問題点
Railsでエラーが発生した場合、通常はstatusコードとmessageをレスポンスボディとして返すので取得の仕方を変えないといけなかった

### 例えば

``` ruby
if user.save
  render json: { status: 200, data: user }
else
  render  status: :unprocessable_entity, json:{ messages: user.errors.full_messages }
end
```
この場合、フロントでaxiosを使用してAPIを呼び出すと、エラーが発生した場合、以下のようなエラーが発生する

``` JavaScript
axios
  .post(process.env.API_URL + '/api/v1/users/signup')
  .then((res) => {
    console.log(res)
  })
  .catch((e) => {
    console.log(e)
  })
```
出力
```
Error: Request failed with status code 422
    at createError (createError.js?2d83:16)
    at settle (settle.js?467f:17)
    at XMLHttpRequest.handleLoad (xhr.js?b50d:69)
```

このエラーは、axiosがエラーが発生した場合、レスポンスbodyをe.responseオブジェクトとして返す
e.responseオブジェクトは、エラーが発生した場合、statusコードとmessageのみを返し、messagesなどの詳細なエラー情報を取得することができない

## 対処法
この問題を解決するには、フロントでaxiosのcatch()メソッドの引数にresponseオブジェクトを渡して、response.dataオブジェクトからエラー情報を取得

``` JavaScript
axios
  .post(process.env.API_URL + '/api/v1/users/signup')
  .then((res) => {
    console.log(res)
  })
  .catch((e) => {
    console.log(e.response.data.messages)
  })
```
出力
```
["Email has already been taken.", "Password is too short."]
```
この方法で、エラーが発生した場合でも、詳細なエラー情報を取得することができる
[TypeScript]typeof型とkeyof型についてのまとめ



# typeof型とは
 typeof型は、変数やオブジェクトの型を取得する機能です。
 変数やオブジェクトの実際の値ではなく、その型情報を取得する際に使います。
 
### 例①
```ts
// type ofについて
const obj = {
  foo: 123,
  bar: "hi",
};
type L = typeof obj;
const obj2 = {
  foo: 234,
  bar: "",
};
```
このコードでは、「typeof obj」とすることで、「obj」オブジェクトの型を取得し、「type L」に適用させています。

### 例②
```ts
const n: unknown = "";
 
if (typeof n === "string") {
  n.toUpperCase;
}
```

### 例③
```ts
function isObject(value) {
  return value !== null && typeof value === "object";
}
```

# keyof型とは
keyof型は、オブジェクト型からそのオブジェクトのプロパティ名を型として取得する機能です。

### 例①
```ts
type Person = {
  name: string;
};
type PersonKey = keyof Person;
// type PersonKey = "name"
```
このコードは、「Person」からプロパティである「name」を取得し、「PersonKey」に反映させているコードになります。


### 例②
```ts
type Human = {
  name: string;
  age: number;
  height: number;
};
type HumanKey = keyof Human;
// 上は次と同じ意味になる
type BookKey = "name" | "age" | "height";
```
こちらも先ほどのと考え方は同じで、「Human」を指定することで、全てのプロパティを取得し、ユニオン型として適用させることができます。

### 例③
```ts
// key ofについて

type Human = {
  name: string;
  age: number;
};

type HumanKey = keyof Human;
let key: HumanKey = "name";
key = "age";
//　型 '"hoge"' を型 'keyof Human' に割り当てることはできません。(エラー)
// key = "hoge";
```
このコードでは、HumanKey型は、「keyof Human」として宣言され、Human型のプロパティ名を文字列リテラル型として取得しています。つまり、HumanKeyは「"name" | "age"」という文字列型のユニオン型です。
最後の行で、「key = "hoge";」 としていますが、これはエラーとなります。なぜなら、「"hoge"」は HumanKey 型に含まれていないため、key の型としては許容されないからです。この行がエラーになることで、型の一貫性が保たれ、予期せぬ挙動を防ぐことができます。

### 例④
```ts
type What = keyof {};
// type What = never
```
「keyof」で何も指定しなかった場合、そのオブジェクトに対するキーが存在しないため、「never」型が結果となります。

### 例⑤
```ts
type AnyKeys = keyof any;
// type AnyKeys = string | number | symbol
```
「keyof」で「any」型を指定した場合、その型のすべてのプロパティのキーが取得され、結果として、「string」「number」「symbol」のユニオン型が取得できます。

# typeofとkeyofを合体
### 例
```ts
// typeofとkeyofを合体
const mmConversionTable = {
  mm: 1,
  m: 1e3,
  km: 1e6,
};

function convertUnits(value: number, unit: keyof typeof mmConversionTable) {
  const mmValue = value * mmConversionTable[unit];
  return {
    mm: mmValue,
    m: mmValue / 1e3,
    km: mmValue / 1e6,
  };
}

console.log(convertUnits(5600, "m"));
// 出力：
```
このコードは、keyofとtypeofを併用して型定義をしているコードです。

```ts
convertUnits(value: number, unit: keyof typeof mmConversionTable)
```
この箇所では、「value」はnumber型を定義して、数値以外を受け取れないようにしています。
「unit」では、typeofで「mmConversionTable」の各プロパティの型情報を取得し、keyofで型情報の


# 参考

https://typescriptbook.jp/reference/values-types-variables/typeof-operator

https://typescriptbook.jp/reference/type-reuse/keyof-type-operator

# 最後に
他にも色々な記事を書いているので、よければ読んでいってください、、、

https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

https://qiita.com/hukuryo/items/2c07c52ff3386d5d75b9

https://qiita.com/hukuryo/items/ebeb26823f944f143b11
単体テストと結合テストの違い

今回は単体テスト仕様書と結合仕様書を書いたため、心得をまとめておきます。
単体テスト：
⓵とにかく個々の機能を細かくテストする。項目一つずつ確認できるように仕様書を作成していく
⓶詳細設計仕様書に沿って必要な確認箇所を書いていく方法は漏れなく、確認必要な箇所をカバーできる
⓷ペアワイズ法(オールペア法)を自動生成できるサイトを利用して、パターンを作る
結合テスト：
⓵該当機能と別機能を組み合わせた業務を想定し、テストデータ、ケースを作成する
例えば：ログイン画面作成したとして、ログインした後に、メンバー登録を行うという一連の流れを実施する

非同期処理の異常系を起こす処理でよく入力規則を作って、エラーに落ちるようなケース見えますが、業務上は起こりえない話ですが、実はこういうのは開発者のためのテストもあったりします。
⓵コーディング上全ケースを網羅するため
⓶追加開発時、入力規則を追加したが、それに伴ったデータの整合性が整えていない際、ちゃんと対応できているかを確認
Azure Functionsで関数が表示されない。

# 起きた問題
PythonでAzure Functionsを利用していてAzure Portal上で関数が表示されなくなった。

# 対処方法
import osやimport requestを関数内に移動した。
import loggingとimport azure.functions as funcと並列にimport osやimport requestを書くとazure portal上から関数がなくなる。

## 対処前
```functuon_app.py
import azure.functions as func
import logging
import os
from urllib import request
from urllib import parse
import json

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    
（以下略）
```

→ポータルで関数が見られなくなる。

## 対処後

```functuon_app.py
import azure.functions as func
import logging

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="http_trigger")
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    import os
    from urllib import request
    from urllib import parse
    import json
（以下略）
```
→関数が見られる。
[RxJS/Angular]retryWhenはDeprecatedなので代わりにretryとdelayを使う

## retryWhenについて

RxJSの`retryWhen`の用途としては、AngularでいえばHttpClientで特定のステータスコード返却時のみリクエストをリトライしたい場合にインターセプターに組み込むケースなどがあります。
しかし`retryWhen`はDeprecatedになっておりv9かv10で削除されるとのことで、代わりに`retry`オペレーターの`delay`オプションを使うことが推奨されています。

https://rxjs.dev/api/operators/retryWhen

## retryとdelayについて
`retry`と`delay`を使用したHttpInterceptorFnの書き方サンプルです。ステータスコードが500の時のみ10回までリトライされ、それ以外は即時エラーを返します。
```typescript
export const responseInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {
  return next(req).pipe(
    retry({
      count: 10,
      delay: (error, retryCount) => {
        if (error.status === 500) {
          // リトライの度に100ミリ秒増やした遅延後にリトライ
          return timer(100 * retryCount);
        } else {
          // 500以外はエラー
          return throwError(() => error);
        }
      }
    })
  );
};
```
retryオペレーターは[RetryConfig](https://rxjs.dev/api/index/interface/RetryConfig)を引数に取ります。
`RetryConfig`の`delay`プロパティの定義は以下のようになっています。
`delay?: number | ((error: any, retryCount: number) => ObservableInput<any>);`
単純に`number`（ミリ秒）が与えられた場合はその分遅延した後リトライとなります。関数が与えられた場合、Observableを返せばリトライされます（上記サンプルの`return timer(100 * retryCount)`の部分。）し、エラーを返せばリトライされずにエラーとなります。この関数部分で条件を記述することで条件付きリトライを実現できます。

## まとめ
冒頭のようなケースにおいてまだまだ`retryWhen`を使った書き方の情報が多いため、Deprecated対応の参考になれば嬉しいです。
表を作成して画像保存




```python


import json
import pandas as pd
import openpyxl
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter
from pathlib import Path
import pprint



```

```python

# path定義

# output path
output_path = Path("C:/Users/kaida/Desktop/weekend_python/env_gui1/myProject/output")
save_path1 = output_path / 'test1.png'
save_path2 = output_path / 'test2.png'

```
```python

# 1. JSONからを持ってくる
with open('.\\dataset_common\\comp_db.json', 'r', encoding='utf-8') as f:
    comp_db_dict = json.load(f)

comp_db_dict

{'fruit1': {'mass_kg': 10,
  'x': [40, 100, 400, 2000],
  'y': [0.05, 0.2, 0.2, 0.03]},
 'fruit2': {'mass_kg': 20,
  'x': [40, 70, 200, 300, 1000, 2000],
  'y': [0.05, 0.2, 0.2, 0.1, 0.1, 0.03]},
 'fruit3': {'mass_kg': 20,
  'x': [40, 250, 500, 2000],
  'y': [0.05, 0.1, 0.1, 0.03]}}

```

```python
#2. JSONからfruitacとfruitcpの紐づけを持ってくる
with open('.\\dataset\\savedata.json', 'r', encoding='utf-8') as f:
    savedata_dict = json.load(f)

{'fruitac': ['fruit1', 'fruit3'], 'fruitac2': ['c1', 'c2'], 'a3': ['a3']}


```

```python
# 2. mesdata
df = pd.read_excel('dataset/mesdata.xlsx')
df.set_index('Hz', inplace=True)
df

   fruit1    fruit2
hz
1   xxx     xxx
2   xxx     xxx
3   xxx    xxx

```

```python

# 3. 可視化1
acc_list = list(df.columns)

for acc_name in acc_list:
    
    fig, ax = plt.subplots()

    # タイトルと軸ラベルの設定
    ax.set_title(acc_name)
    ax.set_xlabel("frequency[Hz]")
    ax.set_ylabel("PSD")

    # 最大値と最小値の設定
    # ax.set_xlim(0, 2000)
    # ax.set_ylim(0, 1000)
    ax.set_xlim([10, 10000])
    ax.set_ylim([0.00001, 1])
    
    # x軸とy軸を対数目盛りに設定する。
    # x軸とy軸を対数目盛りに設定する。
    ax.set_xscale('log')
    ax.set_yscale('log')

    # x, y軸のラベルを指数表記から通常の表記に設定
    ax.xaxis.set_major_formatter(FormatStrFormatter('%g'))
    ax.yaxis.set_major_formatter(FormatStrFormatter('%g'))
    
    # グリッドを表示する。
    ax.grid(True, "major", linestyle="-", linewidth=.7, color='g')
    ax.grid(True, "minor", linestyle="-", linewidth=.3, color='g')

    # ====================================================================
    # ax.plot(x_data, y_data)
    # ax.plot([40, 70, 200, 300, 1000, 2000],[0.05, 0.2, 0.2, 0.1, 0.1, 0.03])
    
    # acのXYデータ
    x_data_ac = df.index
    y_data_ac = df[acc_name]
    # ax.plot(x_data, y_data)
    # ax.plot([40, 70, 200, 300, 1000, 2000],[0.05, 0.2, 0.2, 0.1, 0.1, 0.03])
    ax.plot(x_data_ac, y_data_ac, color='black')

    # 対象fruitのXYデータすべて
    fruit_list_temp = savedata_dict[fruit_name]
    for cp_name in cp_list_temp:
        x_data_cp = cp_db_dict[cp_name]['x_r']
        y_data_cp = cp_db_dict[cp_name]['y_r']
        ax.plot(x_data_cp, y_data_cp)

    fig.tight_layout()

    # ファイル保存
    fig.savefig(f'.\\output\\{fruit_name}.png')


```
ワンチップマイコンが内蔵するデバイスについて

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)

本記事では、ワンチップマイコンが内蔵する主なデバイスとその役割について紹介します。

# ワンチップマイコンとは
ワンチップマイコンとは、__1つのICチップ上に、各種デバイスを合わせて１つのパッケージにしたマイコン__ のことです。

# ワンタップマイコンが内蔵する主な周辺デバイス
### ・クロック発信機
CPUを動かすための同期を取る

### ・割り込みコントローラ
マイクロプロセッサが実行中のプログラムからの外部信号やイベント（割り込み）を処理する

### ・フラッシュROM
プログラムを格納する。通常は読み取り専用。

### ・RAM
データを一時的に保存する

### ・タイマー
クロック発信機の周期から時間をカウントし、設定したタイミングで動作を行う

### ・DMAコントローラ
CPUを介さずに、データ転送を行う

### ・ウォッチドッグタイマー
システムが正常動作しているか監視する。(番犬の役割)

### ・A/D変換器
アナログ信号をデジタル信号に変換する
(D/A変換器の場合は逆の働きをする)


# 終わりに
ワンチップマイコンは、その小さなサイズに多彩な機能を凝縮しており、組み込みシステムや電子機器の中核となります。 ワンチップマイコンは、技術の進化と共に未来のデバイスにおいても、ますます中心的な役割を果たしていくことでしょう。

最後までお付き合いくださりありがとうございました。
Djangoのログインパスワードを再設定する

Django管理画面のパスワード再設定方法の忘備録です。

久しぶりにログインしようとしたときについ忘れがちですよね。

# 方法
### ユーザ名が分かっている場合
```
$ python manage.py changepassword <ユーザ名>
```

### ユーザ名も不明な場合
```
$ sqlite3 db.sqlite3
$ sqlite> select username from auth_user;
$ <ユーザ名一覧が表示される>
$ sqlite> .q
```
ユーザ名を取得した後は下記コマンドで再設定できます。
```
$ python manage.py changepassword <ユーザ名>
```


私はadminのパスワードで実施しましたが、admin以外のユーザも同じ方法で再設定できそうな気がします。
画像の解像度を高めるツール「Magnific」を試してみした。

MagnificはMagnific.aiによって開発された、画像の解像度を最大16倍、10Kまで高められる生成aiツールです。

最近話題になりましたので、私も昨日試してみました。
まず解像度が非常に低い古いゲームの画像（300×400）を入れてみました。

拡大倍数は16倍で、パラメーターはデフォルトの設定のままで実行しました。（一回の使用料は結構高く、約250円かかりますので、あまりパラメーターは試していません）

生成された画像と元の画像は以下の通りです。（生成された画像の鮮明度にびっくりしました。）
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/4409b5f9-f673-06c1-63a3-041db24214b6.png)

次に、富士山の写真も入れてみました。
今回は少し解像度がやや高め（1000×1200）の写真にしました。拡大倍数は４倍で、拡大後の写真は8K解像度になりました。

生成された画像は以下の通りです。ぱっと見るとあまり変わらないようですね。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/bc7b42de-fc0d-9881-ddd3-08616c2cc105.png)

少し右側のほうが鮮明度が高くなっているようですが、拡大するとかなりクオリティーが違います。左側は見づらくなっていますが、右側はまだきれいです。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/deeca5bb-4fe3-8c24-0d5c-deda37a0108d.png)

ちなみに、Magnific.aiはたった二人の社員で運営されている会社です。AIベンチャーはどんどん社員人数が少なくなる傾向にあるですね。


興味ある方試してみてください。

https://magnific.ai/editor/
Windows版 Cursorのターミナルで日本語の文字化けを解消する方法

WindowsのCursorでターミナルに出力する日本語がどうしても文字化けするときの解消方法。
最適解ではないかもしれないが、これも１つの方法という事で。

# ターミナルはPowerShell
設定を変更していなければターミナルはWindowsPowerShellが動作しているのでPowerShellに対して文字コードを指定してあげればよい。
要は文字コードをUTF-8にしてあげれば文字化けは解消する。

ちなみにWindowwsPowerShellではなくコマンドプロンプトに変更することもできる。

### PowerShellでの文字コード変更方法
ターミナルで以下のコマンドを入力する。
>```
>$OutputEncoding = [System.Text.Encoding]::UTF8
>[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
>```

まぁ毎回上記２行を入力するのは面倒なので「changeUTF8.ps1」といったテキストファイルを作成し上記コマンドを記載しておく。
（拡張子ps1はPowerShellスクリプトの拡張子）

ターミナル起動時に上記スクリプトを実行して文字コードをUTF-8にしておく。

## Mavenコマンド
Mavenを使っていると「mvnw.cmd」を使うと思うが、そこにも文字コードをUTF-8に変更する命令を記載しておくと面倒なくて便利。

> mvnw.cmd　テキストエディタで開いて先頭に以下の行を追加
>```
>chcp 65001
>```

chcp 65001はコマンドプロンプトで文字コードをUTF-8にする命令。
これをMavenのコマンドに追加しておくことでコマンド実行時に自動的に文字コードを変更してくれる。
今更だけどPythonの覚書

# はじめに
仕事で大量のCSVファイルから集計してほしいという依頼が来ました。
データを解析するためにPythonを使ってみました。
※今までなら、ExcelVBAでやってたんですが、せっかくなので新しい学びもほしいなと思った次第。

# CSVファイルを操作する
## 読み込み方

```Python
filename = 'target.csv'
with open(filename, encoding='utf8', newline='') as f:
    csvreader = csv.reader(f)
    for row in csvreader:
        print(row)
```

こんな感じで取り込んだデータがrowに格納されるのでそれを利用すればOK

## フィールドサイズが大きいCSVファイルを取り込む
標準の'csv'モジュールでは、131072（約128KB）がデフォルトの上限です。
以下のようにすることで制約によるエラーを回避することができます。

```Python
import csv

OVER_SIZE_LIMIT = 200_000_000
csv.field_size_limit(OVER_SIZE_LIMIT)
```

## 書き込み方
```python
import csv

input_filename = 'input.csv'
output_filename = 'output.csv'
with open(input_filename, encoding='utf8', newline='') as in_file:
    csv_reader = csv.reader(in_file)

    with open(output_filename, 'w', newline='', encoding='utf-8') as out_file:
        csv_writer = csv.writer(out_file)
        
        for row in csv_reader:
            csv_writer.writerow(row)

```

書き込みはこんな感じで行えました。

## 行の要素の取り出し
上の例では、rowにデータが入っていますが、各項目の値はrow[0]のように要素の番号を
指定してあげることで取得できます。

# おわりに

これ以外にもJSONのデータを解析したりしながら
2時間程度で簡単なツール化完了。Python便利ですね。
また、今回はGoogleさんのお世話にならずに、ChatGPTさんと会話しながら
作ったのですが、やはりこの手の作業をするのにはかなり役立ちますね。
覚書として作ったページなので、新しい何かをやったらここに追記していこうと思います。
SQL書式設定-日付

## memo
### 事象
出力された日時がハイフン区切りで出力されてしまった。
ex) 2023-11-15
### 期待値
"/"区切りで出力されること
ex)2023/11/15

## データ型書式設定 to_char
DBから取得したデータ型を指定のデータ型に変換することができる便利なツール
 ### 日付を指定の書式に変更
 select to_char('2023-11-15', yyyy/mm/dd) from aiueo;

 ## 文字の切り取り left, right, substring
 left:DBから取得した値を、入力数分を左から切り取る
right:DBから取得した値を、入力数分を右から切り取る
substring:DBから取得した値を、第1引数から第2引数分切り取る
select left('2023-11-15',4) || '/' || substring('2023-11-15',6,2) || '/' || right('2023-11-15',2) ;

## 参考
https://docs.oracle.com/cd/F19136_01/sqlrf/TO_CHAR-datetime.html#GUID-0C3EEFD1-AE3D-452D-BF23-2FC95664E78F
https://postgresweb.com/post-368
【備忘録】m.2 wifi ワイヤレスカード取付

# 自作PCのワイヤレスカードの取り付け方法

こんにちは。みのです。
自作PCのワイヤレスカードをインストールしたのでインストール方法をメモします。

## やりたかったこと
有線でインターネットに接続していたデスクトップPCを無線でインターネットにつなげようにしたい。

利用していたデスクトップPCのマザーボードはM.2 Wi-Fiのカードが挿せるようだったので、今回はM. Wi-Fiのカードを利用して自作PCのインターネット接続環境を無線化しました。


## 新たに購入したもの

|NO. | Item | メーカー |購入価格(2023/12/26時点)|
|--|--|--|--|
|1.|Intel Wireless AX210NGW (GIG+, AX200後継) 【バルクキット簡易包装】Wi-Fi 6E Bluetooth 5.2 インテル ワイヤレスカード WLAN|	Ichimido|2,600円
|2.|NGFF M.2 ネットワーク 6dBi WiFi 4G アンテナ RP-SMA MHF4 ピグテール ケーブル|	QAREQU|939円

![1000004940.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/2c5056a0-59d7-4ae0-622b-d045ae79be41.jpeg)

## 今回利用したマザーボード
ASRock B365 Pro4

M.2(KEY E) For WiFi
802.11ac対応

Key EのM.2が挿せるようだったので上記のワイヤレスカードを購入しました。ワイヤレスカードの規格はWiFi6E（802.11ax）ということで互換性あるか心配していましたが、互換性ありました。ちゃんと無線化できました😭
![1000004947.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/b7b2ad6a-721b-98c3-852e-b7126d326af2.jpeg)

## 取り付け方法

### ワイヤレスカードへアンテナの取り付け
ワイヤレスカードの上部に突起があり、アンテナの凹部を合わせてドッキングさせます。
ワイヤレスカードの凸部にアンテナの凹部を合わせて細かく回転することでうまくはめ込める事ができました。

![1000004943.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/df0f98db-08ab-4061-8139-6ef65cb49322.jpeg)

### ワイヤレスカードの取り付け
その後マザーボード上のm.2 wifiと記載のある場所にネジ止めでワイヤレスカードをつけます。（私の場合、該当の場所にグラフィックボードを取り付けていたので一度グラフィックボードを外してから取り付けをおこないました。

![1000005419.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/bdbd643d-9249-5273-453f-875fd84a0299.jpeg)

### アンテナの取り付け
とても難しかったです。
自作PCのUSB等を取り付けるI/Oポートにアンテナを取り付けました。
マザーボードを筐体から外すのがめんどくさかったので、ペンチを使ってアンテナを筐体内から引っ張り出しました。
![1000004945.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/31ea449e-334a-d2da-d871-4ebe01be1e1d.jpeg)
![1000004944.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283544/4cc25735-d674-ac31-899c-12a23a8cdcd6.jpeg)

これで取り付け完了です。

## 最後に

無線化にして非常に満足です。
スピード的に有線しか勝たんとおもっていましたが、そんなのは過去の話で今は無線で満足してます。掃除もしやすいです。

マザーボードに取り付けほんとにめんどくさいのではじめから無線対応しているものをおすすめします。

今後はHDMIの無線化もしたいところです。
【SwiftUI】Chartsの円グラフを使ってみた

# はじめに
ChartsにiOS17から追加された`SectorMark`を使ってみました。
めっちゃ便利でした

# 円グラフデータ
円グラフのデータを借りました

https://udemy.benesse.co.jp/business/office/excel-circle-graph.html

# 最低機能実装
![スクリーンショット 2024-01-16 22.17.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b8af2935-9524-99f4-f3e5-a6985c2cbd12.png)

```swift
import SwiftUI
import Charts

struct FavoriteFruit {
    let name: String
    let count: Int
}

struct ContentView: View {
    @State private var favoriteFruits: [FavoriteFruit] = [
        .init(name: "りんご", count: 15),
        .init(name: "いちご", count: 12),
        .init(name: "さくらんぼ", count: 6),
        .init(name: "ぶどう", count: 5),
        .init(name: "バナナ", count: 4),
        .init(name: "オレンジ", count: 2)
    ]

    var body: some View {
        Chart(favoriteFruits, id: \.name) { favoriteFruit in
            SectorMark(
                angle: .value("count", favoriteFruit.count)
            )
            .foregroundStyle(by: .value("name", favoriteFruit.name))
        }
        .frame(width: 300, height: 300)
    }
}
```

# 細かい調整をしてみる
### 中心に穴を空ける
![スクリーンショット 2024-01-16 22.21.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/74730832-4a7b-072c-27b1-78a20547b5b4.png)

```diff_swift
Chart(favoriteFruits, id: \.name) { favoriteFruit in
    SectorMark(
        angle: .value("count", favoriteFruit.count),
+       innerRadius: .inset(30)
    )
    .foregroundStyle(by: .value("name", favoriteFruit.name))
}
.frame(width: 300, height: 300)
```

### 円を小さくする
![スクリーンショット 2024-01-16 22.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e8bb335b-c34b-d486-ed25-7285975d279a.png)

```diff_swift
Chart(favoriteFruits, id: \.name) { favoriteFruit in
    SectorMark(
        angle: .value("count", favoriteFruit.count),
        outerRadius: .inset(50)
    )
    .foregroundStyle(by: .value("name", favoriteFruit.name))
}
.frame(width: 300, height: 300)
```

### 要素と要素の間に隙間を空ける
![スクリーンショット 2024-01-16 22.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/dfb221b2-0159-01f1-83b8-477f0be7636e.png)

```diff_swift
Chart(favoriteFruits, id: \.name) { favoriteFruit in
    SectorMark(
        angle: .value("count", favoriteFruit.count),
+       angularInset: 3
    )
    .foregroundStyle(by: .value("name", favoriteFruit.name))
}
.frame(width: 300, height: 300)
```

# おわり
次回は要素を選択する実装とかしてみたいですね
GoでforEachなど便利機能を提供してくれるgo-funkを紹介したい

## はじめに
go-funkはJavaScriptにあるforEactやMap,PHPなどにあるFindやGetなどの便利機能を提供してくれるライブラリです。
使い方は公式を見ればわかるので、ここでは代表的な機能について数行で紹介していきます。

https://github.com/thoas/go-funk

github.com/thoas/go-funk


## 使用できる機能
個人的によく使用する順で載せていきます。ここに載っているものが全てではないので、公式で使いたいものがあるか探してみるのもいいと思います。

`func Map(arr interface{}, mapFunc interface{}) interface{}`
JSのmapと同じで、配列、スライスの各要素を2乗するなどの加工が可能。ただ、goの場合はMap機能によってmapからslice、sliceからmapに変更することができる。

`func Find(arr interface{}, predicate interface{}) interface{}`
指定された条件に該当する最初の要素を配列、スライスから見つける。funk.FindStringなど型ごとに種類がある。

`func Filter(arr interface{}, predicate interface{}) interface{}`
配列、スライスから指定した条件に合致する要素を抜き出す。

`func Get(out interface{}, path string, opts ...option) interface{}`
ネストされた構造体もしくはmapから要素を抽出する関数。Bar.Bars.Bar.Nameといった深いネストでも要素を取得可能。

`func Set(in interface{}, val interface{}, path string) error`
ネストされていても構造体の要素の値を一括で変更できる。

`func Union(collections ...interface{}) interface{}`
引数にした複数の配列、スライスの要素を全て足し合わせたものを作成できる。それぞれの異なる要素を結合して返すfunk.OuterJoinや2番目のコレクションから異種データを見つけて返すfunk.RightJoinが存在する。

`func ForEach(arr interface{}, predicate interface{}`)
JSのforEachと同じで配列、スライスの各要素を抽出できる。funk.Mapのように各要素の加工できる。最後の要素から順に格納していくfunk.ForEachRightも存在する。

`func Uniq(in interface{}) interface{}`
配列から重複値を除いた新たな配列を作成できる。funk.UniqStringなど型ごとに種類がある。また、抽出した値にコールバック関数を適用できるfunk.UniqByも存在する。

`func Subset(x interface{}, y interface{}) bool`
ある配列、スライスが指定された配列、スライスを含んでいるか(Subsetか)を判定する。

`func ToMap(in interface{}, pivot string) interface{}`
構造体を複数渡すと、キー値 : 格納値 のmapを作成する。

`func ContainsInt(s []int, v int) bool`
slice, mapの中に指定した数字があるか真偽値で返す関数。型ごとにfunk.ContainsStringやfunk.ContainsUIntなどが存在する。

`func IndexOf(in interface{}, elem interface{}) int`
配列、スライス内で値が最初に現れるインデックスを取得する関数。 funk.IndexOfStringなど型ごとに種類がある。また、最後に値が見つかった箇所を返すfunk.LastIndexOfも存在する。

`func Drop(in interface{}, n int) interface{}`
配列またはスライスから指定した数分要素を削除する。DropStringなど型ごとに種類がある。最後の要素だけ捨てるfunk.Initialと最初の要素だけ捨てるfunk.Tailも存在する。また、配列またはスライスから指定した要素(配列、スライスで渡す)を削除するfunk.Subtract,func.Withoutも存在する。

`func Intersect(x interface{}, y interface{}) interface{}`
引数xとyの共通要素を抜き出す関数。文字列版のfunk.IntersectStringがある。

`func Difference(x interface{}, y interface{}) (interface{}, interface{}`)
Intersectと逆で共通ではない要素を抜き出す関数。こちらもfunk.DifferenceStringなど型ごとに種類がある。

`func Reduce(arr, reduceFunc, acc interface{}) interface{}`
JSのreduceと同じで、配列、スライスの各要素を合算して合計値を出すなど可能。要素の合計値を算出するfunk.Sumも存在する。

`func Prune(in interface{}, paths []string) (interface{}, error)`
構造体に他の構造体の値を要素を指定してコピーする。例えば新しい構造体を作るときに既存の構造体からIdとNameだけコピーして他は初期値のままにしておくことが可能。構造体タグに同じ処理を行えるfunk.PruneByTagも存在する。

`func Keys(out interface{}) interface{}`
構造体からkey要素を配列、スライスとして抽出できる。構造体から要素だけを配列、スライスとして抽出するfunk.Valuesも存在する。

`func Chunk(arr interface{}, size int) interface{}`
配列を指定した数で分割する。こちらもfunk.ChunkStringなど型ごとに種類がある。逆に分割してある配列を結合するfunk.FlattenDeepも存在する。

`func RandomString(n int, allowedChars ...[]rune) string`
指定した文字数分のランダムな文字列を作成する。

`func Reverse(in interface{}) interface{}`
渡された配列、スライスの順番を逆転させる。funk.ReverseStringなど型ごとに種類がある。

`func Shuffle(in interface{}) interface{}`
配列、スライスの並び順をランダムにして返す。funk.ShuffleBoolなど型ごとに種類がある。

## 終わりに
車輪の再開発を防いでくれる、素晴らしいライブラリです。作者がパフォーマンスについてissueを求めているみたいなので、腕に自身のある方は参加してみてください。
要件定義のヒアリングリスト427 ①

# 使用している本

[amazon](https://amzn.asia/d/aPkL4zR)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1157150/c5302b6e-8494-24bc-ff19-aebb10f2e70c.png)

kindle unlimited　にあったので読んでみました。
それの記録用として記事を書いていきます。

# 1章
### システム開発における要求とは
システム開発における「要求」とは、日頃の会話で使用されている「要求」とは違うものであり、「ある目的を達成するためのシステム仕様」である。　**顧客が欲しいものを定義することが要求定義ではなく、「目的を達成するため」「問題解決のため」に必要なこと。**
また、開発を行うにあったっては顧客が口にした要求にだけ応えれば良いのではなく、顧客の「目的達成」「問題解決」に必要な**要求を開発側から引き出さなければならない。**

### 要件定義フェーズの目的とは何か？
目的は「顧客のニーズを把握してシステムの要求を確定する」ことです。ただし、これは永遠の目標であり、確定することはほとんど不可能です。
では、どうすべきなのか。
「要件を確定する」ことにこだわらないことであり、要求は必ず追加・変更されるものと理解して要件を確定する。つまり、**「顧客のニーズを把握して、要求が追加編こぅされることを十分に想定した上で、システム要求を確定する」ことです**。

### 要件定義フェーズの作業目的とは何か
要件定義の担当者が意識しなければならないのは「正確に伝達されて初めて意味を持つ」ということです。
要件定義の文書化にあたり、細部を省力したり、要求の根拠や背景を省くことは、節約した時間をはるかに上回る代償を支払うことになりかねません。

# 次は2章
node_modulesをオフラインの環境に持っていくときの備忘録

## はじめに
`npm install`や`yarn install`で簡単にモジュールのインストールができますが、インターネットにつながっていることが前提。
とある事情でインターネットに接続できない環境でNode.jsのプロジェクトを開発する機会があり、少し手間取ったので備忘録としておいておきます。

## 起こった問題
インターネットに接続できる環境でNode.jsのプロジェクトを作成し、node_modulesをzip化しオフライン環境に持っていきました。
オフライン環境で展開し、さあスクリプトを実行しようとしたところエラー(Cannot find module)が発生。

## 原因
`node_modules/.bin`配下のシンボリックリンクが切れてしまっていたことが原因。
スクリプト実行時にこの配下のファイルを参照して実行されるのですが、リンク先が見つからずエラーになっていたようです。

`zip`コマンドを実行した際にシンボリックリンクが実ファイルに置き換わったがゆえ発生した問題。

## 対策
`zip`コマンドで`zip -r node_modules`としていたコマンドを`zip -ry node_modules`に変更し再度実行。
### `-y`オプションについて
`--symlinks`の短縮形。シンボリックリンクをたどらずに、シンボリックリンクのまま格納するオプションです。
https://atmarkit.itmedia.co.jp/ait/articles/1607/25/news021.html

シンボリックリンクのまま圧縮し、オフラインで展開し確認したところオンライン環境と同様スクリプトが動きました。

## まとめ
文字ばかりで見にくい記事ではありますが、備忘録なのでお許しを…
悩んでた部分がかなり初歩的なところだったので恥ずかしい限りですが、node_modulesの中身が少し理解できました。
UnityでglTFを出力する

UnityでglTFが出力できたんですね。知りませんでした。

https://docs.unity3d.com/Packages/com.unity.cloud.gltfast@6.0/manual/index.html

[こちら](https://github.com/atteneder/glTFast)をpackage managerからImportして、
.glbでexportすれば出力できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/accdf05a-8fca-7e9d-2b35-167eb3e93e34.png)

実行中のsceneでも問題なくexportできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/fbd0fd6a-bc9d-dea7-e0a5-ffdc4baf64ab.png)

できたglbファイルを
[glTF viewer](https://gltf-viewer.donmccurdy.com/)に読み込ませたり、

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>glTF stack-chan</title>
        <script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.3.0/model-viewer.min.js"></script>
        <style>
        body {
            margin: 0;
            padding: 0;
        }
        model-viewer {
            width: 600px;
            height: 400px;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <model-viewer src=[YOUR_GLB_FILE] camera-controls touch-action="pan-y"></model-viewer>
</body>
</html>
```
みたいな感じで[どこかのサーバーに置く](https://elix.jp/test/3dmodel/glb/)ことで見ることができます。
p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し

## はじめに
この記事では、以下の記事でも扱った「p5.js の createFilterShader()」を使います。

●p5.js の createFilterShader() を使ったフィルター用シェーダーのお試し - Qiita
　https://qiita.com/youtoy/items/1083d6319ddab6d525d3

今回は、座標を使った着色を試してみます。

## createFilterShader() を使う
### createFilterShader() で座標情報を扱う
まずは公式のリファレンスを見て、「createFilterShader()」で座標の情報を取得する方法を確認します。

●reference | createFilterShader()
　https://p5js.org/reference/#/p5/createFilterShader

サンプルコードの中に、バーテックスシェーダーから受けとった座標の情報が「vTexCoord」の保持されている、という説明が書かれていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d01a77fd-31c7-6750-cc65-240757d160fb.png)

### プログラムを書いてみる
vTexCoord は vec2 となっているので、x と y の座標の値を「vTexCoord.x」「vTexCoord.y」といったやり方で得られそうです。

そうやって得た値を、RGB の R と G にそれぞれ反映させてみました。

```javascript
function setup() {
  let fragSrc = `precision highp float;

  varying vec2 vTexCoord;
  uniform sampler2D tex0;

  void main() {
    vec4 color = texture2D(tex0, vTexCoord);
    color.r = vTexCoord.x;
    color.g = vTexCoord.y;

    gl_FragColor = vec4(color.rgb, 1.0);
  }`;

  createCanvas(400, 400, WEBGL);
  
  let s = createFilterShader(fragSrc);
  filter(s);
}
```

#### 実行結果
上記のプログラムを実行すると、以下の描画が行われることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/56b9623a-edbd-010d-a50d-7813d155557f.png)

vTexCoord に格納された値は、0 から 1 の範囲になっているようで、そのまま R や　G の値として使うことができました。

バーテックスシェーダーはおまかせにして、フラグメントシェーダーだけを扱い、座標情報を使った簡単な描画を行うことができました。
【Hasura】テーブルのカラム名とGraphQLの項目で別の名称を使いたい場合

【Hasura】テーブルのカラム名とGraphQLの項目で別の名称を使いたい場合

## 概要
HasuraでテーブルのカラムをGraphQLにマッピングする際に、通常はカラム名がそのまま使われますが、GraphQLの項目で別の名称にしたいという場合があると思います。
どこで設定するのか忘れてしまうので、今回メモ書きで残しておきます。

## 前提
* 今回使用したHasuraのバージョンは`2.6.1`です。

## 対応
[Postgres: Customize Auto-Generated Field Names](https://hasura.io/docs/latest/schema/postgres/custom-field-names/)のドキュメントにある通り、`Data -> [table-name] -> Modify`の画面から対象のカラムを選択します。そして、設定の`GraphQL Field Name`部分でGraphQLで使いたい名称を入力します。私はPostgresでしか確認してませんが、おそらく他のRDBでも同じ設定方法で大丈夫だと思います。
なお、カラムの追加時はこの設定は表示されないようで、一度カラムを追加した後にModifyから設定する必要があるみたいです。
Oracle Cloud Infrastructure 2023 Certified Foundations Associate　を受けた話

# なぜOracle Cloud Infrastructure 2023 Certified Foundations Associate　を受けたか
1年前まではOCIという言葉がそれほど聞こえず、日本語の教材もほとんどない。さらに、日本のクラジットカードだとアカウントが作れないとかも聞いた。
　数年前まで敷居の高いOCIだったが、最近のOCIは公式で無料教材を提供してくれた。
 しかも、資格試験まで無料だという！！
**受けてみよう！**
 ってな感じで受けました。

# どんなして勉強したの？
公式が教材の動画を出していた。
年末年始、帰省しなかったのでとても暇でした。動画は1.25倍速で見て、ノートにメモを取りながら見ました。勉強時間としては8時間かかってないと思います。勉強時間が8時間で１つの資格を取れるのは嬉しい話！！！

https://mylearn.oracle.com/ou/learning-path/japanese-become-an-oci-foundations-associate-2023-/124995

章末問題も準備されており、資格試験とほとんど同じ内容の章末問題。（問題文が全く同じということはなかったと思う）

**それに加えて試験対策の問題集までついている！**

https://mylearn.oracle.com/ou/course/practice-exam-for-oci-foundations-2023-associate-certification-jp/126849
# 受験
無償で受験をしました。

https://education.oracle.com/ja/oracle-cloud-infrastructure-2023-foundations-associate/pexam_1Z0-1085-23

![OCIF2023CAJPN.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1157150/012bc92f-e68e-a02b-e285-5702706ee3ac.jpeg)

受かることができました。


### せっかくだし、違う資格も受けてみた
大学でAIに触れたことがある人ならほとんどの方が受かると思います。
一度練習問題を解いて臨んで、安心して受けた方が良いですが、、、

![OCI23AIFCAJPN.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1157150/6843dc1d-5919-dfd0-e3c5-22c0b7ac70e3.jpeg)


# 最後に
OCIってこんなに優しいんだ！！！ちょっと好きになりました！
まだ、サーバ構築などは行ってないので、今後遊んでいこうと思います。
皆さんも受けてみてはどうでしょうか。
以上
頼み事をするときは相手の一貫性を活用せよ

**人には、自身の行動、発言、態度、信念などを一貫したものとしてあらせたいという心理があり、これを「一貫性の原理」と呼ぶ。**


## 効果が強くなるケース

- 「自らが何らかの物事にかかわりを持っている」場合
- 「他人に注目されている」場合

これらのケースでは特に一貫性の原理が働きやすい。



### 「自らが何らかの物事にかかわりを持っている」


前者では人から手伝いを頼まれ引き受けると2度目以降も断りにくくなるといった例

### 「他人に注目されている」

後者では禁煙を実行する際に一人でするよりは家族や友人、同じ目的を持つサークルなどの中で宣言して行う場合のほうが成功しやすいなどがあげられる[1]。


### 「賢い」「プライド」

- 相手が賢くなければ、一貫性を把握する力がない。その場合は相手がわかるレベルの一貫性まで落とさなければならない。
- 低いプライド


## 一貫性の法則の原理

この心理の根底には、一貫性を保つことは社会生活において**他者から高い評価を受けるという考え**、複雑な要因の絡み合った社会生活での将来的な行動決定においてより簡易に行動を決定することができるなどの要因があるといわれる。


例えば買い続けている月刊誌が内容が面白くないと感じても、新刊が出るとつい買ってしまったり、好きな歌手のCDだからという理由だけで買ってしまうという行動などである。また一旦観だした映画はたとえ途中で面白くないと感じた場合でも、最後まで見てしまうなどなどが例として挙げられる。




## フットインザドア

「フット・イン・ザ・ドア・テクニック」と呼ばれる手法は「一貫性の原理」を利用しているビジネスの例である。これは、顧客に対して小さな（一般的には顧客にとって損失のない）要求を行い、それが受け入れられてから大きな要求を行うという手法である


## ローボール

また、「ローボール・テクニック」（特典除去法）と呼ばれる手法も「一貫性の原理」を利用している例である。これは、悪い条件を隠しておき、顧客が購入を決定した後で条件を出すという手法である。

「ローボール・テクニック」という名前は、キャッチボールで、初めは取りやすい高さの低い球筋のボールを投げ、徐々に高い球筋のボールに上げていくと、高い球筋のボールでもキャッチできるようになるという話に由来する[3]。
AWS Managed Microsoft ADとFSｘとAD管理用EＣ２についてまとめ

## AWS Managed Microsoft ADとFSｘとAD管理用EＣ２を構築後の設定方法
①AD管理用EＣ２をAD参加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/fb3ae5f0-2bd6-1820-0f2a-3810c9df50a5.png)
DNSサーバーのアドレスに作成したAWS Managed Microsoft ADのDNSアドレスを記載する。

②ドメイン参加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/4ec445ee-cdd3-9420-581b-d64a73b47648.png)
所属するグループのドメインにドメイン名を記載。

ユーザー名とパスワードを聞かれるので、ユーザー名はAdminでパスワードは
 AWS Managed Microsoft AD作成するときに決めたパスワードを入力する。

 これでAD参加が完了。

 ③Active Directory ドメインサービスをインストールする
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/5aecf533-3d5f-c38e-ea3e-567f804c3bd1.png)
 サーバーマネージャーの役割と機能の追加からActive Directory ドメインサービスをインストールする。
Active Directory ユーザーとコンピュータから新規でユーザー作成等可能となる。
NW学習記録#1

〇自戒のための宣誓
1. お前に足りないのはインプットだ！！！インプットしろ！！！インプットの奴隷になれ！！！
2. 記事の書き方とか今はどうでもいいから書け！！！インプットをアウトプットしろ！！！やる前からこだわりとか持つな！！！
3. 見られることとか評価されることとか気にするな！！！MECEとか構造化されてるかどうかとか気にするな！！！構造化はアウトプットの整地であって、インプットが足りないお前が手を出す領域ではない！！！ていうかお前頭良いんだからインプットに注力しろ！！歴史を刻め！！！歴史をまとめようとするな！！！未来を描け！！過去を清算するな若者め！！！！
4. 疑問を持つことを恥じるな！！！お前は頭はいいがインプットが足りない未熟者だ！！！インプットの奴隷になれ（再掲）！！！

〇学習記録
プロキシサーバー経由で通信する場合、クライアントからサーバーで送られるパケットの宛先IPアドレスはプロキシサーバーになるらしい。
→どうやって通信してるの？プロキシサーバーがURLを読んでDNS解決を代行して宛先IPアドレスを代入してる？そんで、プロキシサーバーは送信元IPアドレスとポート番号を記録しといて、

L3, L4, L7のロードバランサーがあるらしい。
L3はIPアドレスを見て負荷分散する。ルーティングが基本。
L4はポート番号を見て負荷分散する。ポート番号やセッション シーケンス番号等の情報の解析や書き換えができるらしい。
L7はHTTPリクエストメッセージのCookieやURLをみて負荷分散する。
→てことはL3負荷分散ってほとんど使い物にならないんじゃねと思ったけど、実際はVRRPなどの冗長構成を組む際に使うのが正しくて、サーバーへの直接の負荷分散には使われないことが多いらしい。UDPなら変わるのかな？TCPならサーバーとのセッション通信？が基本のはずだから、L3負荷分散は使い物にならないはず（L3負荷分散っていう言葉自体が負荷分散の本質と異なりそう）。

プロキシサーバーって送信元IPアドレスを隠すとかっていうセキュリティ向上用途で使われているのかと思ってたけど、元々はキャッシュサーバーとしての役割が強かった？

サーバーとクライアント間で設置する機器や機能はどんなものがある？例えばロードバランサー(L4, L7)やプロキシサーバーなど。
ロードバランサーはL4(TCP/UDP)で負荷分散するものとL7(アプリケーション層)で負荷分散するものの２種類がある。L4LBはIPとTCPヘッダのポート番号やシーケンス番号をみて、L7LBはHTTPリクエストメッセージのCookieやURLなどをみて負荷分散しているらしい。L4LBの方が見る部分が少ないので処理も設定も簡単？
プロキシサーバーはwebブラウザで設定できるとか、PACファイルを設定すれば
NAPT(NAT)っていうのはロードバランサーやプロキシサーバーで使われるもの？
→p.318のQ2を解いて、あってるか質問するのがよさそう。そこから敷衍してメンターさんの知識をもらうのがよさそう。

DNSサーバーを内部に置くのはなぜ？
閉域網での名前解決をするのはわかる。でも、インターネットや外部の閉域網の名前解決もDNSサーバーがするの？
名前解決とブラウザは関係ないであってますよね。
L4とL7の違いはアプリケーション層を見れるかトランスポート層までを見れるかの違いだけど、これってどうやって設定するの？

OSには「プロトコルスタック」というネットワークの処理を行うためのツールのようなものが入っているらしいが、このプロトコルスタックっていうのはRFCに定義されているプロトコルが全てそろってる？基本的に使うものしかない？OSによる？
WindowsやLinux, MacOSにあるプロトコルスタックと、各ベンダーのルーターやスイッチ、Firewall製品のプロトコルスタックには差異がある？もしプロトコルスタックで足りないプロトコルがある場合はインターネットからインストールしたりできる？
プロキシサーバーやDNSサーバーはLinuxなどが入ったコンピュータにプロキシ機能やDNS機能があるソフトウェアを入れて設定すればできるらしいけど、これってつまりLinuxOSなどの汎用的な？OSが入ったコンピュータと、ルーターやスイッチなどのNW機器ができることは同じで、用途に最適化されている（ポートが複数あり、複数ポートを前提とする処理ができたり、ネットワーク関連の設定方法が簡易化されているなど）かどうかが違うっていうこと？
figコマンドを事項するとfig command not foundになる

## 概要

下記の理由からfigを入れ直し、ターミナルで使えることを確認後、Macを再起動したところ`fig command not found`になった。筆者の環境でこれを解決するための方法を簡単にまとめる。

https://qiita.com/miriwo/items/638adfd7a7638741a0cc

## 方法

1. どこかにfigコマンドの実態があるはずなのでちょっと探してみる。ユーザーのトップのディレクトリに`.fig/`を発見した。
1. 下記の内容を`~/.bashrc`に記載する。

    ```~/.bashrc
    export PATH="$PATH:$HOME/.fig/bin"
    ```

1. 下記を実行して`~/.bashrc`を読み込む。

    ```shell
    source ~/.bashrc
    ```

1. figコマンドが使えるようになった。
文字コード、改行コード一括変換ツール KanjiTransrator のインストール

KanjiTransrator（読み方：カンジ　トランスレータ）はファイルの文字コードと改行コードを一括して変換できる無料のソフトウェアです。ここでは18歳の新入社員向けに KanjiTransrator のインストール方法を紹介します。

## KanjiTransrator の目的
KanjiTransrator は以下のような用途で使われます。

### 文字コードの変換
複数ファイルの文字コード（ShiftJIS, ISO-2022-JP, EUC-JP, UTF-8）を一括で変換することができます。

### 改行コードの変換
Mac と UNIX の改行コードが混在する複数のファイルを、まとめて Windows 用に変換することができます。

## KanjiTransrator のシステム要件
KanjiTransrator は以下の環境で動作します。

- オペレーティングシステム: Windows 98, ME, NT4.0 SP6a, 2000, XP, Vista, 7, 8, 8.1

ここでは KanjiTransrator 1.6 を例にして、Windows 11 へのインストール手順を説明します。

## KanjiTransrator のインストール手順
### ダウンロード
ベクターの KanjiTransrator の紹介ページにアクセスし、「**ダウンロードページへ**」をクリックします。

[https://www.vector.co.jp/soft/dl/win95/util/se326595.html](https://www.vector.co.jp/soft/dl/win95/util/se326595.html)

![02_officialsite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/218cf86e-e425-7b40-7957-9b89e19200a7.png)

ダウンロードページが表示されたら、「**このソフトを今すぐダウンロード**」をクリックします。

![03_officialsite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/46a76cd7-e67b-8d31-4975-9aa52e0c6756.png)

### ファイルの展開
ダウンロードが完了したら、ファイルを右クリックし、コンテキストメニューから「**すべて展開**」をクリックします。

![11_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/49bff38e-0632-f713-bb75-32100985e426.png)

### 展開先フォルダの指定
ファイルの展開先を指定します。ここでは例として **C:\ProgramFiles\KanjiTranslator160** というフォルダに展開します。

![21_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/dce197ba-cf5a-ccdf-f854-1fe951a423bc.png)

以上でインストール作業は終了です。

KanjiTransrator を使う時は **C:\ProgramFiles\KanjiTranslator160\KanjiTranslator.exe** を実行します。

![22_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/3c00ee51-d596-7a61-6ae5-fcbac337f8f3.png)
Yarn v2でGithub Packages npm registryからyarn addする方法

# はじめに
Yarn v2でGithub Packagesのprivateなnpm registryからyarn addをする方法です。
Yarn v4にアップデートしてGithub Packagesからyarn addをしなくてはならなかったため記事を書きました。
Yarn v1からYarn v2にアップデートし、アーキテクチャが刷新され.npmrcが読み込まれなくなったため新たな設定が必要になったぽいです。

# 結論
.yarnrc.ymlに下記のSettingsを追加する。
```yml
npmScopes:
  my-scope:
    npmRegistryServer: "https://npm.pkg.github.com"
    npmAuthToken: ${YOUR_TOKEN_HERE}
```

# 内容
npmの場合、.npmrcに下記の様に設定していたと思う。
```shell
@MYSCOPE:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${YOUR_TOKEN_HERE}
```
だが、Yarn v2以降アーキテクチャが刷新され.npmrcではなく.yarnrc.ymlを読み込む様になったと思われる。

なので[こちら](https://yarnpkg.com/configuration/yarnrc#npmRegistryServer)を参考に.yarnrc.ymlに設定をする。
```yml
npmScopes:
  my-scope:
    npmRegistryServer: "https://npm.pkg.github.com"
    npmAuthToken: ${YOUR_TOKEN_HERE}
```
- my-scopeにAddしたいPackagesのNAMESPACEを入れる
- もし環境変数を特定のファイルから使用したい場合は下記を追加する
```yml
injectEnvironmentFiles: [
".my-env",
".my-local-env?",
]
```

# 最後に
間違いや指摘等があればぜひよろしくお願いします。

# 参考文献
https://yarnpkg.com/configuration/yarnrc#npmRegistryServer

https://github.com/yarnpkg/berry/issues/1801

https://docs.github.com/ja/packages/working-with-a-github-packages-registry/working-with-the-npm-registry
【Django x Docker】スクリプトでrunserverの後のコマンドに進まない場合の対応方法

# 概要
DjangoとDockerを使ってローカル環境でコンテナを立ち上げ、スクリプトで`python manage.py runserver 0.0.0.0:8000`を実行していたら、このコマンドが原因で次のコマンドに進まないことがあることがわかりましたので解説します。

# コマンドの順番によって次に進まないことがある
以下はサンプルのシェルスクリプト。
`docker-compose`の`command:`セクションで実行させます。

```docker-compose.yaml
##　略　##　
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: ["./sample-script.sh""]
    volumes:
      - ./myprojects:/code 
    ports:
      - "8000:8000"
```

```sample-script.sh
#!/bin/bash

echo "Hi, this is sample command"

# Djangoのサーバーを起動
python manage.py runserver 0.0.0.0:8000
```

上記のように、後でDjangoのサーバーを起動するコマンドを持ってくれば、`echo`コマンドはdocker logに出力されます。

しかし、以下のように逆にすると、`echo`コマンドは出力されません。

```sh
#!/bin/bash

# Djangoのサーバーを起動
python manage.py runserver 0.0.0.0:8000

echo "Hi, this is sample command"
```

これは、シェルスクリプトの実行が`python manage.py runserver 0.0.0.0:8000`でブロックされ、このコマンドが終了するまで次のコマンドに進まないためです。`python manage.py runserver`は、サーバーが終了するまで実行を続けるため、その行以降のコマンドは実行されません。

## 解決策：バックグラウンド起動＆コンテナ永続化

このような場合、`&`によってDjangoのサーバーをバックグラウンドで起動させ、また、その後にコンテナが終了しないようにしてあげれば、順番通り出力されるようになります。

```sh
#!/bin/bash

# Djangoのサーバーをバックグラウンドで起動
python manage.py runserver 0.0.0.0:8000 &

echo "Hi, this is sample command"

# コンテナが終了しないようにする
tail -f /dev/null
```

### `tail -f /dev/null`とは？
`/dev/null`は、読み込むと即座にEOF（End of File）を返し、書き込みを行っても何も保持せずに破棄されるという、特殊なファイルです。英語圏では`“black hole”`と呼ばれているとか。まぁその通りですね。

シェルスクリプトやコンテナは、実行されたコマンドが終了すると通常終了します。では終わらせないためにどうすればいいか？というと、`tail -f /dev/null`のように永遠に終了しないプロセスを起動させてあげれば、コンテナが終了せずに動き続けることができる、というわけです。

記事「[永遠に終了せず何もしないDockerコンテナを立ち上げる方法](https://genzouw.com/entry/2023/03/24/083011/3332/)」に他にも方法が記載あるので気になる方はご参考まで。


## その他エラー：シバン記載漏れによる`exec format error`

パッと使うサンプル用にシェルスクリプトを作った気でいたら、シバン（シェバン）の書き漏れがありました。

```sh
echo "Hi, this is sample command"

# Djangoのサーバーを起動
python manage.py runserver 0.0.0.0:8000
```

`#!/bin/bash`のようなシバンがない場合、以下のエラーになりました。

```
standard_init_linux.go:228: exec user process caused: exec format error
```

### `#!/bin/bash`とは？
`#!/bin/bash`とは、シェルスクリプトがどのシェルで実行されるべきかを示す特殊なコメント行（宣言）。シバン（shebang、シェバンライン）と呼ばれます。

これがないと、システムはスクリプトをどのシェルで実行すれば良いかわかりません。
スクリプトがデフォルトのシェルで実行されようとしますが、そのシェルがバイナリ形式ではない場合に`"exec format error"`というエラーが発生しているんですね。

`#!/bin/bash`をスクリプトの先頭に追加することで、スクリプトが`bash`で実行されることが明示されるので、エラーは無くなりました。
【Ruby】combinationメソッドで全組み合わせを網羅する方法

# 環境
Ruby 3.0.1

# combinationメソッドとは？
配列の要素に対して使用するメソッドです。
指定した要素数で作成可能な組み合わせを全て生成します。

# 使い方
基本的には、下記の形式で使用します。
```Ruby:Ruby
配列.combination(n).to_a
```
nには、組み合わせたい要素の数を指定します。
またto_aを入れないと、オブジェクト形式で返ってくるので注意です。
具体的な使用例は以下の通りです。
```Ruby:Ruby
array = [1, 2, 3]
p array.combination(2).to_a # => [[1, 2], [1, 3], [2, 3]]
```

# 応用：要素数を含めて、全組み合わせを生成するには？
全組み合わせと言っても、単体要素や3つ以上の組み合わせを含めたい場合があります。
その時はループ処理と組み合わせることで、パターンを網羅できました。
```Ruby:Ruby
array = [1, 2, 3]
size = 3 # 配列の要素数
combinations = []
size.times do |i|
  array.combination(i+1) { |n| combinations << n }
end
p combinations
# => [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
```
（もうちょっと良い書き方もありそうですが）
# 経緯
複合条件網羅のアルゴリズムがどうしても組めなかった時に見つけました。
paizaでお世話になりそうです。

# 参考
https://docs.ruby-lang.org/ja/latest/method/Array/i/combination.html
Arrayのサイズ非指定

## Arrayのサイズ非指定

```C:sample.c
int main() {
  int a[] = { 1, 2, 3 };  

  char c = 'x';
  char *cptr = "xyz";       //equivalent to array[4] = {'x','y','z','\0'}

  char carr1[] = {'a','b'};
  char carr2[] = "text";    //equivalent to array[5] = {'t','e','x','t','\0'}
  char *captr[] = {"p","q"};//equivalent to *array[2] = {*{'p','\0'}, *{'q','\0'}}
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1158607/d965a228-5ec5-0dfb-4178-d6a15c6acaf2.png)


## まとめ
| 記号 | 役割 | 区切り |
|:-----------|------------:|:------------:|
| {}   | xxx(要素に準拠)[]     | カンマ区切り         |
| ""   | char[]  | 文字区切り       |
| ''   |  char   | -      |
改行を含むテキストを改行コードを含む一行に変換する

毎回調べてるので自分へのメモ用に。
改行コード\nの場合（Mac）

# bash
```bash
$ cat hoge.txt
111
222
333
$ cat hoge.txt | tr \\n \\ | sed -e 's/\\/\\n/g'
111\n222\n333\n
```

# fish
エスケープの仕方がちょっと違う
```shell
$ cat hoge.txt | tr \\n \\ | sed -e 's/\\\/\\\n/g'
111\n222\n333\n
```
Trubo を使って複数のパーシャルを更新する

## はじめに
本記事は[猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo)を参考にしています。
勉強中のため、誤りやもっといいやり方があるかも知れません。
その場合は、ご指摘いただけますと幸いです。

また、可能な限りわかりやすく記載するつもりですが、不明瞭な点、追記した方がいい点などがございましたら、合わせてご教授ください。

## この記事の目的
コントローラーで値を更新し、画面に表示されている値だけでなく、フラッシュメッセージなど複数のパーシャルを更新したことがあると思います。
その際、やり方を調べるのに時間がかかったので、備忘録も兼ねて残しておきます。


## パーシャルの記述
更新したい箇所に、タグを挿入します。

```ruby
# ここに書いてあるコードはリロードされない
h2 hogeページ

= turbo_frame_tag "hoge", data: { turbo: true } do

  # データの更新に伴い、一緒にリロードしたい箇所
```

`app/view/hoge/update.turbo_stream.slim` を作成します。
このファイルは、update メソッドが呼ばれた時に読み込まれます。
create の時は、`create.turbo_stream.slim` にします。

```ruby
# app/view/hoge/update.turbo_stream.slim

# update は、要素のコンテツのみ更新
= turbo_stream.update 'hoge'
  = render 'hoge/hogehoge'

# 共通の処理は、ApplicationHelper に定義して、呼び出すことも可能
= turbo_stream_replace_flash('route')

#############################################################
# application_helper.rb
  def turbo_stream_replace_flash(route)
    # replace は、要素も含めてすべて置き換える
    turbo_stream.replace 'flash', partial: "#{route}/flash", locals: { ver: 5 }
  end
```

`turbo_stream.update` と `turbo_stream.replace` の違いは、要素のコンテンツのみを更新するか、既存の要素を完全に置き換えるかの違いです。

## コントローラーの記述

```ruby
# app/controllers/hoge_controller.rb

class HogeController < ApplicationController
  def update
    if @hoge.save
      respond_to do |format|
        format.turbo_stream do
          flash.now[:notice] = '変更しました'
        end
      end
    else
      render :edit
    end
  end
end
```
【Java】パスワードの複雑さの要件をチェックする

# はじめに

パスワードの複雑さの要件として、「8文字以上で半角英数字の全ての文字種が含まれていること」というような文言を見ることがあります。
このチェック処理が以前から気になっていたので、頭の体操がてらJavaを使って力技で実装してみました。

# 作成したコード

* 正規表現を使ってチェック項目を1つずつ処理するコードを作ってみました。
  * あまりスマートな書き方ではありませんが、単体テストなどを考慮して粒度を小さくするとこんな感じになってしまうのでモヤモヤしますね...
* `String#matches()`や`Pattern.matches()`などを使った書き方もありますが、今回はパフォーマンスを重視してPatternオブジェクトを作ってマッチさせる方法を採用しました。
  * 参考URL：[文字列のマッチング方法によるパフォーマンスの違い](https://hhelibex.hatenablog.jp/entry/2017/11/26/155849)

```java:PasswordChecker.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PasswordChecker {

	// パスワードの最低文字数
	private static final int MIN_LENGTH = 8;

	public static void main(String[] args) {
		String[] passwords = {"ABCdef123", "ABCdef1", "ＡBCdef123", "abcdef123", "ABCDEF123", "ABCdefGHI"};

		for (String pw : passwords) {
			if (!checkLength(pw)) {
				System.out.println("「"+ pw + "」はパスワードの長さの要件を満たしていません。");
			}
			if (!checkOnlyAlNum(pw)) {
				System.out.println("「"+ pw + "」は半角英数字以外の文字が含まれています。");
			}
			if (!containsUpperCase(pw)) {
				System.out.println("「"+ pw + "」は大文字の英字が含まれていません。");
			}
			if (!containsLowerCase(pw)) {
				System.out.println("「"+ pw + "」は小文字の英字が含まれていません。");
			}
			if (!containsNum(pw)) {
				System.out.println("「"+ pw + "」は数字が含まれていません。");
			}
		}
	}

	/**
	 * パスワードの文字数が「最低文字数以上」であるか？
	 * @param text
	 * @return
	 */
	private static boolean checkLength(String text) {
		return (text.length() >= MIN_LENGTH);
	}

	/**
	 * パスワードが半角英数字のみで構成されているか？
	 * @param text
	 * @return
	 */
	private static boolean checkOnlyAlNum(String text) {
		Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+$");
        Matcher m = pattern.matcher(text);
        return m.find();
	}

	/**
	 * パスワードに大文字の英字が1文字以上含まれているか？
	 * @param text
	 * @return
	 */
	private static boolean containsUpperCase(String text) {
		Pattern pattern = Pattern.compile("[A-Z]+");
        Matcher m = pattern.matcher(text);
        return m.find();
	}

	/**
	 * パスワードに小文字の英字が1文字以上含まれているか？
	 * @param text
	 * @return
	 */
	private static boolean containsLowerCase(String text) {
		Pattern pattern = Pattern.compile("[a-z]+");
        Matcher m = pattern.matcher(text);
        return m.find();
	}

	/**
	 * パスワードに半角数字が1文字以上含まれているか？
	 * @param text
	 * @return
	 */
	private static boolean containsNum(String text) {
		Pattern pattern = Pattern.compile("[0-9]+");
        Matcher m = pattern.matcher(text);
        return m.find();
	}
}
```

```text:実行結果
「ABCdef1」はパスワードの長さの要件を満たしていません。
「ＡBCdef123」は半角英数字以外の文字が含まれています。
「abcdef123」は大文字の英字が含まれていません。
「ABCDEF123」は小文字の英字が含まれていません。
「ABCdefGHI」は数字が含まれていません。
```

# 参考URL

* [文字列のマッチング方法によるパフォーマンスの違い](https://hhelibex.hatenablog.jp/entry/2017/11/26/155849)
Windows端末へのLINUX環境導入についてのポイント

LPIC Level 1取得のためのWindows端末へのLINUX環境導入。自分が試した環境の感想を記しておく。
* VM Ware （おすすめ）
 機能がフルでインストールされるので学習におすすめしたい。
 デメリット：CENTOSイメージ5GBくらいある。動作は比較的重い。
 高スペックPCでも、centosなら動くけどfedraは重すぎて使い物にならない。
 firefoxで、QIITA投稿でコマンドの貼り付け投稿も可能

* WSL  （おすすめ）Windows10に標準装備されているLinux。Ubuntuはこれでインストールして学習用に使用している。

* docker （いまいち）コンテナ型のためか、インストールは速い。動作も早い。
学習に必要な機能が同梱されていないため学習向きではない。

* OPEN SUSE （いらないかも）インストール系のコマンドでこのOSがでてきたのやむをえず導入した。導入したあとで気づいたが、出題範囲が狭すぎるので得点につながらない。時間に余裕あるならどうぞ。そのほかの人はいれなくていい。