OmniAICreator/Qiita-1.07M huggingface dataset:
SQLでのテーブル作成（Postgres SQL）

# はじめに
SQLを学習しているので備忘録として記載
RDBMS:Postgres SQL
本記事で記載する以下画面はSQL Shell(psql)での画面とする。
```
```
## データ型の種類
・INTEGER型
　整数を入れる列に指定
・CHAR型
　文字列を入れる列に指定
　CHAR(5)のように列の中に入れることができる文字列の長さ(最大長)を()内の数字で指定する
　最大長になるまで半角スペースで埋める（固定長文字列）
　 例：CHAR(5)の列に'aaa'を入れると'aaa□□'（□は半角スペース）で格納される
・VARCHAR型
　CHAR型と同様に文字列を入れる列に指定
　CHAR型と違い、最大長に満たなくても半角スペースで埋めない（可変長文字列）
・DATE型
　日付を入れる列に指定する

## 制約
　・NOT NULL制約
　　必ずデータが入っていないといけない（無記入だとエラー）
　・プライマリーキー制約

## テーブルの作成
データベースができたらCREATE TABLE文でテーブルを作成

```
CREATE TABLE テーブル名
(
列名1　データ型　この列の制約,
列名2　データ型　この列の制約,
列名3　データ型　この列の制約,
・
・
・
テーブルの制約;
)
```

```:例
CREATE TABLE shohin_01
(
ID　           CHA(3)　     NOT NULL,
shohin_mei     VARCHAR(25)  NOT NULL,
shohin_bunrui  VARCHAR(25)  NOT NULL,
tanka          INTEGER      ,
day            DATE         ,
PRIMARY KEY (ID);
)

```



## テーブルへのデータ登録
上記（例）で作成したテーブルへデータを登録する。
BEGIN TRANSACTION文→行の追加
COMMIT文→行の追加を確定

```
BEGIN TRANSACTION;
INSERT INTO shohin_01 VALUES ('001','カメラ','精密機械',100000,'2022-04-30' );
INSERT INTO shohin_01 VALUES ('002','フライパン','キッチン用品',10000,'2022-03-30' );
・
・
・

COMMIT;
```

## SELECT文で行を検索
SELECT *
FROM テーブル名;
 →　全ての列を出力
SELECT 列名
FROM テーブル名;
 →　指定した列だけ出力

```
SELECT *
FROM shohin_01
     ID    |   shohin_mei   | shohin_bunrui |     tanka    |    day
-----------+----------------+---------------+--------------+--------------
 001       | カメラ    　   | 精密機械      |       100000 |  2022-04-30
 002       | フライパン  　 | キッチン用品  |        10000 |  2022-03-30

SELECT shohin_mei,tanka
FROM shohin_01
   shohin_mei   |     tanka    
----------------+---------------
 カメラ    　   |        100000 
 フライパン  　 |         10000
同じものを含む順列の生成と数

### 同じものを含む順列(distinct_permutations)

結構よく使うけど自分で作ると実装に工夫が必要なので**more_itertools**の**distinct_permutations**を使うと簡単です。

```python 
from more_itertools import distinct_permutations

for p in distinct_permutations('1122'):
    print(''.join(p))
#1122
#1212
#1221
#2112
#2121
#2211
```

### 同じものを含む順列の数

もちろんdistinct_permutationsを数えても良いのですが、もう少し効率よく以下の手順で。

* ソート ⇒ ランレングス ⇒ 全体の階乗をランレングスの階乗で割る

```python 
from math import factorial as fct
def rl(a):  # run length of the list 
  a.sort()
  ret, l = [], 1
  for i in range(1,len(a)):
    if a[i] != a[i-1]:
      ret.append(l)
      l = 1
    else: l += 1
  ret.append(l)
  return ret

def dperm(rl): # run length --> number of distinct permutations
  ret = fct(sum(rl))
  for r in rl:
    ret //= fct(r)
  return ret 

lst = [6, 3, 2,  3, 6]
print(lst, rl(lst), dperm(rl(lst)))
# [6, 3, 2, 3, 6] [1, 2, 2] 30
```

### ランレングスをCounterで求める

PythonのCounterを使えば求まりますね。**dperm**も1 lineにしてみました。

```python
from math import factorial, prod
from collections import Counter

def dperm(rl): # run length --> number of distinct permutations
  return factorial(sum(rl)) // math.prod([factorial(r) for r in rl])

lst = [6, 3, 2, 3, 6]
rl = list(Counter(lst).values())
print(lst, rl, dperm(rl))
# [6, 3, 2, 3, 6] [2, 2, 1] 30
```


このアルゴリズムはProject Euler: Problem 240を解くのに役に立ちます。

（開発環境：Google Colab）
プログラマー孔子「学而不思則罔」

プログラマー孔子が言いました
「新しいプログラミング言語を勉強しただけで、実際にプロダクトを作ってみないと身につかない。ほんとやべーぐらいすぐ忘れる。
でもコーディングするだけで他人のコードを読まなければ、属人化したコードになってしまう。」

## 漢文
>子曰、學而不思則罔。思而不學則殆。

## 現代訳
>　先師がいわれた。――
「他に学ぶだけで自分で考えなければ、真理の光は見えない。自分で考えるだけで他に学ばなければ独断に陥る危険がある。」

青空文庫 
現代訳論語 下村湖人
https://www.aozora.gr.jp/cards/001097/files/43785_58836.html


## ポエム
属人化しちゃうと、ほんと引き継ぎがキツいんですよね
スプレッドシートのIPv4アドレスをソートするGAS

スプレッドシートに書かれたIPv4アドレスをソートして出力する関数です。
IPアドレスをスプレッドシートの機能でそのままソートしようとするとうまくできません。

例えばこんなセルがあったとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/3ecb091d-a85e-ac7d-ba77-f38468c41011.png)

これを「降順でシートを並び替え」すると以下の結果になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/a2053f89-d5c8-1aa6-3a8e-8a08eb7a79af.png)

セルA1とA2を比較した際にA2の方が第2オクテットの桁が少ないため、先頭にしてほしいところですが、セルA1の第2オクテット **10**0 と同じくセルA2の **15** を比較してしまい、セルA1のIPアドレスの方が先頭となってしまいます。

# IPv4をソートする関数
解決方法としては、オクテットごとに0を埋めてあげることでIPv4アドレスをソートすることができます。

Google Sheets（Googleスプレッドシート）で、拡張機能からApps Scriptを開き、以下の関数を記述します。

```javascript
function myFunction() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  var sheet = spreadsheet.getSheetByName('シート1')

  var ipv4List = sheet.getDataRange().getValues()

   ipv4List.sort((a, b) => {
    const ip1 = a[0].split('.').map(el => el.padStart(3, '0')).join('')
    const ip2 = b[0].split('.').map(el => el.padStart(3, '0')).join('')
    return ip1 - ip2
  })
  Logger.log(ipv4List)

  for(var i=0;i<ipv4List.length;i++){
    sheet.getRange(i+1, 2).setValue(ipv4List[i])
  }
}
```

B列にソートした結果を出力しており、うまくソートできていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/27c5a847-8fa1-a5a4-11a7-9a1f8dfe7ee1.png)


# CIDRが記載されている場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/b8bf9ab4-2443-d0df-1c5e-f0a93cd226e5.png)

この場合は、ソートする部分を以下のように変更すればソート可能です。
```javascript
ipv4List.sort((a, b) => {
    const ip1 = a[0].split('/')[0].split('.').map(el => el.padStart(3, '0')).join('')
    const ip2 = b[0].split('/')[0].split('.').map(el => el.padStart(3, '0')).join('')
    return ip1 - ip2
})
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379397/28e5040c-9978-7f6e-9a7d-aa5a179b6894.png)

`.`や`/`で分割してますが、これを`:`にすればIPv6アドレスにも対応できると思います。
【GAS】便利な関数をまとめたい

下記のようなスクリプト.gsを用意しておくと便利。


```general.js
// ━━━━━━━━━━━━━━━
// シート定義
// ━━━━━━━━━━━━━━━
var ss = SpreadsheetApp.openById('シートID');
var paramSh = ss.getSheetByName('シート名');

// ━━━━━━━━━━━━━━━
// シート列定義
// ━━━━━━━━━━━━━━━
var titleCol = 1;

// ━━━━━━━━━━━━━━━
// 共通関数
// ━━━━━━━━━━━━━━━
function logger(message) {
  var logSh = ss.getSheetByName('log');
  var date = new Date();
  var lastrow = logSh.getMaxRows()

  logSh.getRange(lastrow + 1, 1).setValue(date);
  logSh.getRange(lastrow + 1, 2).setValue(message);
}

function getLastrow(sh, col) {
  return sh.getRange(sh.getMaxRows(), col).
    getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
}

function getLastcol(sh, row) {
  return sh.getRange(row, sh.getMaxColumns()).
    getNextDataCell(SpreadsheetApp.Direction.PREVIOUS).getColumn();
}

function convUnixtime(jsttime) {
  var unixtime = Date.parse(jsttime)/1000;
  var unixtime_str = unixtime.toFixed();
  var unixtime_int = parseInt(unixtime_str);

  var year = jsttime.getFullYear();
  if (year === 1899) {
    return unixtime_int + 2209194000;
  } else {
    return unixtime_int;
  }
}

function convJsttime(unixtime) {
  return Utilities.formatDate(new Date( unixtime * 1000 ), "JST", "yyyy/MM/dd HH:mm:ss");
}
```
WSL + Dockerの豆知識

# 前書き
WSL（ここのWSLがWSL2を指しています。）とDocker Desktopの組み合わせで色々テストしてみて、凄く便利だと感じて、一応今まで学んだことをメモします。

Linuxのシステムレベルの開発やテストなどはまだ工夫しないといけないかもしれませんが、WebAppの開発、色んなプログラミング・DB・ソフトの動作確認には相当使いやすいと思います。

仮想環境の構築も簡単で、Docker hubにも既存の環境は山ほどありますので、開発や動作確認などは楽になります。

# Docker専用のディストリビューション（その１）
WSLエンジンが使用される際、Docker  Desktopが専用の「docker-desktop」と「docker-desktop-data」というディストリビューションを使用します。
「docker-desktop」にDockerエンジンがあって、「docker-desktop-data」にDocker Desktopで使用されているイメージがある感じです。

# Docker専用のディストリビューション（その２）
Docker専用のディストリビューションはDocker DesktopのGUIに表示されませんが、「wsl -l -v」などのWSLコマンドで表示でき、exportとimportの組み合わせで普通のWSLディストリビューションと同じようにデフォルト以外のところに移動できます。

# WSLのディストリビューションの開始・自動停止（その１）
WSLのディストリビューションがPowerShellなどで入ってから起動され、「exit」コマンドなどで閉じた後に、しばらく待つと自動停止になります。

# WSLのディストリビューションの開始・自動停止（その２）
Docker Desktopの設定の「WSL INTEGRATION」で統合済みのWSLディストリビューションが、Docker Desktopの起動によって自動開始になり、PowerShellなどで「exit」で閉じても自動停止になりません。

# デフォルトのWSLディストリビューション
Docker Desktopの設定の「WSL INTEGRATION」で「Enable integration with my default WSL distro」がチェックされている場合、この設定の下にある統合リストに、該当のデフォルトのWSLディストリビューションが選択されいるかにもかかわらず、統合済みになります。

# WSLとDocker Desktopの統合
WSLとDocker Desktopの統合後、WSLのディストリビューションでDockerを実行する際、DockerコマンドもDockerのイメージも、Dockerのコンテナーも、実はDocker専用のディストリビューションを経由して実行されています。
MacのTabでハマった(vscode-python-split)

pythonでタブ区切りのデータを取得しようとした時にうまくいかなくてハマったのでメモを残しておく

元データはとある教本（とても勉強になります）に書いてあったらサンプルデータをダウンロードしたもの

```sample.txt
# 実は区切りがスペース4個になってしまっています
こんばん(は|わ)$    こんばんは|お疲れ様です
・・・・・
```

ファイル自体は恐らくWindows向けを想定されていると思います。
それを以下の文で読んでみる

```getdata.py
pfile = open('sample.txt','r',encoding='utf_8')
p_lines = pfile.readlines()
pfile.close()
new_lines = []
for line in p_lines:
      # 区切り文字で右から分割
  str = line.rstrip('¥n')
  if (str != ''):
    new_lines.append(str)
  pattern = {}
  for line in new_lines:
      # 区切り文字で分割
      # ¥tはタブ
    ptn,prs = line.split('\t')
    pattern.setdefault('pattern',[]).append(ptn)
    pattern.setdefault('phrases',[]).append(prs)
    print(pattern)
```

そうすると以下のようなエラーとなる

```
Traceback (most recent call last):
  File "**/practice.py", line 17, in <module>
    ptn,prs = line.split('\t')
ValueError: not enough values to unpack (expected 2, got 1)
```

どうやらタブで分割できてないようである
そのことに気が付かずVscod上でテキストファイルを新しく作ってMacのキーボード上の[tab]を作ったり、スペースの数を変えてみたりが解決しなかった
（マシンガン的解決方法、、、）

## 解決策

Vscodeでは普通にtabボタンを押すとスペースとして入力されてしまう
以下のようにしてtabを打てるようにする
①コマンドパレット（ctrl + shift + p） で「open keyboard Shortcuts」を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/a6a0d575-f5c2-f9a7-93ec-b21625f16f04.png)

②以下のように入力する　※割り当てるボタンは任意

```
// 既定値を上書きするには、このファイル内にキー バインドを挿入します
[
  {
    "key": "ctrl+t",
    "command": "type",
    "args": { "text": "\t" },
    "when": "editorTextFocus"
  }
]

```

これでVScode上でタブを入力することができた
テキストファイルのスーペースを全てタブに置き換えて完了しました。

## 追記
タブ以外にも「¥」も曲者だった
Windowsだと正規表現などで使う「\」（バックスラッシュ）が「¥」（円マーク）になる
そのためWindows用の教本を読む時には「¥」を「\」に読み替えないといけない
※全てではない
読み替え例
文字の先頭が何らかの数字であるものをマッチさせる：「^¥d」　⇨　「^\d」



参考サイト
https://kotsukotsu.work/tech/2020-10-15-visual-studio-code-%E3%81%A7%E3%82%BF%E3%83%96%E3%82%92%E5%85%A5%E5%8A%9B%E3%81%99%E3%82%8B/
社内アプリの自動生成に挑戦（概要）

powerAppやkintone、AppSheetなどを使ってみましたが、今までのエクセル置き換えなどの需要にはすぐに役立ちます。
ただ、ある程度やっていくと急に覚えることが増えるし、バグが無いようにするには結局のところアプリ開発とそれほど変わらん壁が待ち構えている気がします。

ノーコード、ローコードの利点としてはエクセルの行列やセル設計をする程度の手軽さでアプリが作れる。これを踏襲しながらアプリを自動生成、テストコードも自動生成してしまい、そこから込み入った機能は作り込んでいくというアプローチに挑戦しました。

・OpenAPIを中心にデータ周りを整える
・DBやサーバーはMicrosoft製品中心で作成
・クライアントはvue.jsを利用

製品的には
１．StoplightStudioにてOpenAPIをUIで作成
２．DB周りはOpenAPIを読み込んでからコードの自動生成
３．クライアントはAxiosのインターフェースをOpenAPIから自動生成

自動生成するアプリはVisualStudio2022、C#（.net6.0)の最新環境にて作成

１に関しては他の記事が詳しいですし、それほど問題はないはず。
２が情報が少なくて。特にコードを自動で書いてくれるSwagger-codegenやOpenAPI-Generatorはテンプレートの修正程度は出来るのですが、内部でmustacheを利用していて型の変更など複雑なことをしようとすると出来なくなります。
Nswag-codegeneratorも使ってみましたし、C#なのでコードも追っかけてみましたが複雑すぎるアーキテクチャとOpenAPIのセキュリティ絡みの部分は自動生成してくれないので諦めました。

https://github.com/microsoft/OpenAPI.NET
を利用してOpenAPIコードをDocumentとして読み込み、こちらを利用してテンプレートファイルから自動生成していきます。
Stoplightなどで生成したOpenAPIファイルを読み込むだけで、C#からは手軽に使えます。

テンプレートエンジンはFluid.coreを利用します。
https://github.com/sebastienros/fluid
[改定]
https://github.com/dotliquid/dotliquid
テンプレートエンジンはdotliquidを利用。Fluid.coreは最新の開発がされていますが、ドキュメントが少なくて困るため。
ハマりました
https://qiita.com/yukihiro-hyakuta/items/f61e0264faee507d8962


テンプレートエンジンからasp.net core WebAPIなどを自動生成させてしまいます。

クライアントに関してはMicrosoftがAutorestというTypescriptクライアントを生成してくれるものがあるのでこちらを利用します。
https://github.com/Azure/autorest
[Swift] 文字列、配列、辞書の空判定には.countではなく.isEmptyを使うべし

``` swift
// Bad
"".count == 0
[Int]().count == 0
[String: String]().count == 0

// Good
"".isEmpty
[Int]().isEmpty
[String: String]().isEmpty
```

＜理由＞
公式リファレンスにて、`.isEmpry`の使用が推奨されています。
**`.count`の取得は、計算量がO(n)となる場合があるから**、だそうです。

https://developer.apple.com/documentation/swift/collection/3017670-count

＜補足＞
[SwiftLint](https://github.com/realm/SwiftLint)においては、`.count`との比較と同様にリテラルとの比較も警告対象となります。

``` swift
// Bad
myString == ""
myArray == []
myDict == [:]
```

https://realm.github.io/SwiftLint/empty_string.html

https://realm.github.io/SwiftLint/empty_collection_literal.html
リストからL以上R以下を取り出す

# きっかけ
範囲指定のあるクエリを処理していくタイプの問題で、以上以下の条件を満たす個数だったり要素だったりを集計することがあります。その問題対策用の個人的なメモです。

# 注意点
高速化を考えてみたのですが、二分探索でのゴリ押ししか思い浮かびませんでした。
なので、配列をソートしている必要があります。なにかいいアイデアがあったら教えてください。。。

また、コンテストでの利用などは自己責任でお願いいたします。

# コード

```python
from bisect import bisect_left,bisect_right

#任意の数列
seq = [3,5,8,9,12,12,22,23,30]

def LR_calc(L,R,seq):
    # L以上R以下の要素の個数と、切り出したリストを返す
    return bisect_right(seq,R)-bisect_left(seq,L),seq[bisect_left(seq,L):bisect_right(seq,R)]

# すべて取り出す
print(LR_calc(2,31,seq))
print(LR_calc(3,30,seq))
# (9, [3, 5, 8, 9, 12, 12, 22, 23, 30])
# (9, [3, 5, 8, 9, 12, 12, 22, 23, 30])

# チェック
print(LR_calc(4,8,seq))
print(LR_calc(4,9,seq))
print(LR_calc(4,10,seq))
print(LR_calc(5,8,seq))
print(LR_calc(5,9,seq))
print(LR_calc(5,10,seq))
# (2, [5, 8])
# (3, [5, 8, 9])
# (3, [5, 8, 9])
# (2, [5, 8])
# (3, [5, 8, 9])
# (3, [5, 8, 9])

# 存在しない要素、重複している要素部分のチェック
print(LR_calc(7,7,seq))
print(LR_calc(7,8,seq))
print(LR_calc(8,8,seq))
print(LR_calc(12,12,seq))
print(LR_calc(9,12,seq))
print(LR_calc(12,22,seq))
print(LR_calc(9,22,seq))
# (0, [])
# (1, [8])
# (1, [8])
# (2, [12, 12])
# (3, [9, 12, 12])
# (3, [12, 12, 22])
# (4, [9, 12, 12, 22])

# リストのはじまりを含む場合のチェック
print(LR_calc(2,4,seq))
print(LR_calc(2,5,seq))
print(LR_calc(3,4,seq))
print(LR_calc(3,5,seq))
# (1, [3])
# (2, [3, 5])
# (1, [3])
# (2, [3, 5])

# リストのおわりを含む場合のチェック
print(LR_calc(23,30,seq))
print(LR_calc(23,31,seq))
print(LR_calc(24,30,seq))
print(LR_calc(24,31,seq))
# (2, [23, 30])
# (2, [23, 30])
# (1, [30])
# (1, [30])
```
カプセル化と情報隠蔽

## カプセル化とは

関連するデータと処理を一つにまとめる設計原則

### カプセル化はオブジェクト指向での使用が最も有名である！
フィールドを操作するメソッドでオブジェクトの内部要素への直接アクセスを制限する際によういる。

### カプセル化はオブジェクト指向だけではない！

抽象データ型、プログラムモジュール、ソフトウェアコンポーネントの実装にも使用されている。

### ビジネスロジックのカプセル化

カプセル化が本領を発揮するのは、ビズネスロジックのカプセル化です。

ビズネスで扱う値の計算や判断は変更されたすく、値の種類ごとに一つのモジュールにまとめておけば、どこに何が書いてあるかをわかりやすく、変更するときも楽にできます。
またビジネスで扱う値は、より具体的に定め、モジュール化にする事で計算ロジックが増えすぎず、変更理由を狭まります。

### カプセル化の狙い

- アルゴリズムの変更を際に変更箇所がそのモジュールの内部に限定されることになるので、保守管理しやすい。
- 関連するデータと処理をまとめることで単一責任の原則となり、変更理由を狭める

## 情報隠蔽
プログラムやモジュールに関する設計情報は濫りに公開してはならず、むしろ積極的に隠蔽すべきで。つまり、公開すべきものはプログラムやモジュールの仕様であるという設計原則

### 情報隠蔽狙い
- モジュールの使い方がわかりやすくなる
- モジュールを作成者の想定通りに使ってもらえる
    - データを不用意に変更されることを防ぐ

## カプセル化と情報隠蔽の違いとは

|    |  説明 | 簡単に言うと|
| ---- | ---- |---- |
|  カプセル化  |  データとロジックをモジュールにまとめること  | まとめること |
|  情報隠蔽  |  モジュールの実装詳細は隠しましょうということ  | 隠すこと |

## まとめ

カプセル化＝情報隠蔽というイメージだったが違う設計原則であり、オブジェクトのアクセサは、カプセル化と情報隠蔽の設計原則で行われていることがわかりました。
カプセル化することで保守しやすく可読性が高いモジュールになります。

## 参考資料

https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96 

https://boukenki.info/kapuseruka-jouhouinnpei-chigai/ 

https://masuda220.hatenablog.com/entry/2020/06/26/182317#ビジネスロジックのカプセル化

https://saycon.co.jp/portal-for-newcomer/javase8/java-11
テストで使うLinuxコマンドなど備忘録

リモートのサーバーなどへLinuxを用いて繋げなきゃいけない時
コマンドなどを覚えていられないため、備忘録としてコマンドを残しておこうと思う。

ほとんどテストでしか使用しないので、使うコマンドは少なかった。

## cd ファイルパス
現在開いている場所から、指定したファイルパスへ現在の場所を移動する。
基本的にコマンドでのファイルパス指定は、絶対パスにしない限り「開いている場所」を参照するので
必ずと言っていいほど使う。

## ls 
現在開いている場所のファイルリストを表示する。
ディレクトリ内に何のファイルがあるかを調べるときに使うことが多い。

## ls -l
ファイルの詳細を表示する。
ファイルサイズや書き込み権限等を表示してくれる。

基本的に状態の確認以外で使うことはない・・・と思う。

## ls −１
単純に表示のリストを縦に並べて表示するだけのコマンド。
テストのエビデンス等で見やすくするために使う。

-lとの違いは、**ファイルの詳細を表示しない**ことのみ。

## cat ファイルパス
ファイルの中身をターミナル上に表示するコマンド。
0件の時は何も表示しない。

## del /P ファイルパス
ファイルを削除するコマンド。
コマンドミス等でファイル削除されるのを防ぐため
`/P` をつけることで確認をしてからファイルを削除するようにする。

## less ファイルパス
ファイルの中身をターミナル上に表示してくれる。
Vimと同じ見た目になるので、閉じるときには`:q`で閉じる必要がある。

表示した後は`&検索したい文字列`のコマンドを使って、絞り込みを行う。

## scp 取得したいデータのファイルパス 転送先のフォルダ
リモートサーバーにあるファイルなどを見たい時や更新したいときに使用するコマンド。

## mv -i 変更前のファイル名 変更後のファイル名
ファイル名を変更したいときに使用するコマンド。
Spring Boot備忘録2

# 2022/4/30
### ・金額の3桁区切り

```#{$numbers.formatInteger(num,1,'COMMA')}```
num：区切り対象の金額

現時点では、リスト形式で全体に影響させる記述がわからないため個別で記述。

### ・RequestParam

ビューからコントローラへhiddenで値を受け渡すとき、
パラメータのnameをbeanやinfo、formと同名にすると変換できないエラーが発生。
原因として、すでにmodelAttribute済のbeanのプロパティと被ると、java側が区別できないため？

エラーログの一部：Integer is present but converted to null
発生エラー：MissingServletRequestParameterException
[Ubuntu] Windows 10インストール用USBメモリをUbuntu 21.04上で作成する

# はじめに

Ubuntuマシンしか持たない人が、Windows 10のインストール用USBメモリを作成するお話です。

1804だったか1904だったか、以前は[ppaパッケージをインストールする](https://qiita.com/sengoku/items/e18e16ed1c268a242131)ことで、WoeUSBを使用できました。

今はsnapにあるようですので、snapパッケージを使用します。

# 環境

* Ubuntu 21.04
* snap 2.51.4

# インストール

いつものようにsnapでインストールします。

```console
sudo snap install woe-usb --edge
```

# 実行……できない!?

`/snap/bin/woe-usb.woeusb` というsnap経由のラッパーコマンドができますが、パーミッション諸々で実行できないです。

# 実行

本体を直接実行します。

```console
sudo /snap/woe-usb/current/bin/woeusb --device ISOファイル名 /dev/sdc --target-filesystem ntfs
```

`/dev/sdc`は、USBメモリのデバイス名です。

4GBを超えるサイズのファイルがあるので、`--target-filesystem ntfs`を付けます。

## こちらのほうがよいかも？

一応上記で動いていますが、ラッパーを使ったほうがよいかもしれません。

```console
SNAP=/snap/woe-usb/current /snap/woe-usb/current/command-woeusb.wrapper
```
[Apache Hop] Dockerで動かしてみた

他の環境(DBなど)を構成して、まとめて動かそうとするとDockerのほうが都合がいいということで、試してみました。

# 対象者
- Apache Hop (データ統合プラットフォーム) を試してみたい方。
- データ収集、変換処理を試してみたい方。
- Dockerで動かしたい方。

# 前提環境
- Docker Desktopをインストールしている

# 手順の流れ
- Dockerのイメージをダウンロードする
- apache/hop-webを動かす
- apache/hopを動かす

## Dockerのイメージをダウンロードする
コマンドプロンプト、ターミナルを起動して、以下のコマンドを実行します。
サイズが2GBちかくあるので、時間がかかります。

GUIで変換処理を定義するのに必要
```
docker pull apache/hop-web
```
サーバ機能などを実行するのに必要
```
docker pull apache/hop
```
https://hop.apache.org/download/

## apache/hop-webを動かす
Docker DesktopのImagesタブでhop-webの再生ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/5a515e80-76f9-21ee-6f3c-ffefede13a58.png)

Optional Settingsでコンテナ名、ポート、ボリュームを指定してRunを押下します。Dockerのイメージが起動します。
ボリュームは、ホストOSとDockerのイメージでファイル共有したいときに、自分の環境にあわせて割り当ててください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/27e4d08f-3282-a653-10c7-dabca210966a.png)

Containers/Appsで実行したイメージが一覧にでてきます。
Open in Browerを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/7735c445-5ddf-4f17-5748-e8048f6e1e48.png)
今回の例だと、以下のurlにアクセスします。
http://localhost:8080/ui

以下のようにETL処理を定義するための画面が出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/3dd61216-07af-0270-02ce-6807f294c9d0.png)

Hop WebのGUIの場合は、DokcerでWeb経由であるのでHop GUIをWindowsなどでjavaで直接起動した場合とは操作性、反応には違いがありました。今回試していいる1.2.0時点では、Javaで起動のGUIのほうが操作のレスポンスは良かったです。Hop Wepはおそらく今後改善されていくとは思いますが。

https://qiita.com/Tadataka_Takahashi/items/58f69ceb466a5c3a295a

## apache/hopを動かす
Optional Settingsでコンテナ名、ポート、ボリュームを指定してRunを押下します。Dockerのイメージが起動します。Optional Settingsに必要な設定を定義して起動します。ポートのLocal HostにはWebとは異なる番号を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/870d2df4-3110-099a-a5bd-d8cd2d14c3f1.png)

Containers/Appsで実行したイメージが一覧にでてきます。
Open in Browerを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/ef1026ae-90c7-e0c2-54ef-6ab873616ab5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/6e3a6fa4-00f9-9440-a76d-fccc514d8a93.png)

ログイン画面出てきた場合には、デフォルトの場合には以下のユーザ名、パスワードでログインできます。
ユーザ名: cluster
パスワード: cluster

今回の例だと、以下のurlにアクセスします。Hopサーバの状態を確認できる画面が表示されます。
http://localhost:8081/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/300e693d-bab9-155b-b793-64423c275526.png)

RestAPIでの変換処理の登録、実行管理、Webサービスの実行などができるようになります。時間があれば投稿してみます。
その詳細については、参考を参照ください。

## 参考

https://hop.apache.org/manual/latest/hop-gui/hop-web.html

https://hop.apache.org/manual/latest/hop-server/index.html

https://hop.apache.org/tech-manual/latest/docker-container.html#

https://youtu.be/v2rNxAQEhu0
Electronのビルド環境を整える（整えられなかった

# これはなに？

Electronで作ったアプリをビルドするのではなく、Electron自体をビルド~~する~~しようとした話です。

先達のかた [独自ビルドしたElectronを使ってみる（Windows）](https://qiita.com/kenyog/items/178792f3dd3ce833502c) を参考にしながらやっていきます。

# 環境

* macOS Monterey 12.3.1
* xcode select version 2395
* nodenv
* node.js 16.13.2
* python 3.9.12
* yarn

# @electron/build-tools をインストール

npm でインストールします。

```console
npm i -g @electron/build-tools
nodenv rehash
```

さらに必要なものを取得します。

```console
node ~/.nodenv/versions/16.13.2/lib/node_modules/@electron/build-tools/preinstall.js
```

`~/.electron_build_tools` の下にbuild-tools自体のソースやらなんやらが入ります。全部で650MBくらいあります。


# Electronのソースを取得

始める前に、お茶を用意します。


```console
e init --root=~/Documents/Electron/electron --bootstrap testing
```

`e` は electron build toolsのコマンド名です。打ち間違いじゃないです。
`~/Documents/Electron/electron` の下にソースを取得します。


ネットワークとマシンの性能によって、~~数時間〜~~ 延々とかかります。
~~用意しておいたお茶を飲みながら~~ ベッドに入って気長に待ちます。

# ……12時間経過

まだElectron本体に取りかかれず、Chromiumをごにょごにょしてます。

プロセスを眺めてみると、スポットライトのインデクサが負荷をかけている様子です。
無効にしましょう。

```console
sudo mdutil -a -d
```

# ……24時間経過

未だ終わらず。
うちのMac(Intel Core m3-7Y32 1.10GHz) には荷が重すぎたらしい。
諦めました。
[Rails]RSpecでbinding.pryがNoMethodError: undefined method `pry' for *** になるときの対処法。

RSpec初心者です。

RSpecのテストがどうしても通らないので、変数の中身を確認したい、という状況がありました。
調べてみるとexample中(`it 'hoge' do`の中)で`binding.pry`が使えるらしいです。

しかし、`NoMethodError`が出てデバッグできませんでした。

```console
Failures:

  1) DeviseSessions POST #sign_in パラメーターが有効な場合 ユーザー個別ページにリダイレクトされる（リクエストが成功する）こと
     Failure/Error: binding.pry
     
     NoMethodError:
       undefined method `pry' for #<Binding:0x00007f9d27b2d9c0>
       Did you mean?  try
...
```

## 原因
`spec/spec_helper.rb`に`require 'pry'`が記載されていない。

参考：

https://stackoverflow.com/questions/17837882/how-to-examine-rspec-variables-with-pry-debugger


## 対処法
`spec/spec_helper.rb`に`require 'pry'`を追加します。

```spec/spec_helper.rb
RSpec.configure do |config|
  require 'pry'   <=ここ！

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end
  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
  config.shared_context_metadata_behavior = :apply_to_host_groups
  config.filter_run_when_matching :focus
end
```
adb コマンド一覧

## はじめに

今更ながらせっかくなので個人的によく使う adb のコマンドをまとめました。

> 参考：Android Debug Bridge (adb) とは？

Android デバイスと通信するための多用途のコマンドラインツールになります。
adb コマンドを使用すると、アプリのインストールやデバッグなど、さまざまなデバイス操作を実行できます。（公式より）

> 公式ページ

[Android Debug Bridge (adb)](https://developer.android.com/studio/command-line/adb)

> サンプルソース

- GitHub
[adbtool-for-mac](https://github.com/ngkr327/adbtool-for-mac)

## 環境

macOS Ventura 13.1

## コマンド一覧

### IP アドレスを使用してデバイスに接続する

```
$ adb connect <device_ip_address>
```

### 接続済みデバイスのリストを取得する

```
$ adb devices
```

### エミュレータまたは接続されたデバイスに apk をインストールする

```
$ adb install -r <path_to_apk>
```

### デバイスからトレース情報を取得する

Android では、ANR が発生するとトレース情報が保存されます。

```
$ adb pull /data/anr/traces.txt ./
```

### デバイスにファイルをコピーする

```
$ adb push <pc> <dvice>

// ダウンロードフォルダにコピー
$ adb push <file> /sdcard/Download/
```

### 指定したパッケージをデバイスオーナー設定する

アクティブな管理者として設定し、そのパッケージをデバイスオーナーとして設定します。
パッケージ名/デバイスアドミンを実装したクラス名を component に指定します。

```
$ adb shell dpm set-device-owner <component>
```

### デバイスにインストールされているパッケージの一覧を取得する

```
$ adb shell pm list package
```
実用に耐えるプログラムを書く教育ができそうかを懸念しております

# 実用に耐えるプログラムを書く教育ができそうかを懸念しております

　Microsoft Windowsにおいて、組織変更やファイルサーバーを入れ替えるとパスが変わり、それまでに作ったショートカットが使えなくなるという問題がある。これを、ショートカットのリンク先を一括で繋ぎ替えることによって[解決するというプログラム][1]を昔作った。
　自らソフトを書かないことが前提の組織文化なので、目立たぬようMicrosoft ExcelのVBAで書いている。
　１０年以上前に作ったのが最初のバージョンで、それから誰でも使えるようにちまちま改良を重ねている。
　それでも最初の最初から、この機能だけは持っていた。
「リンクを変更した場合、その先に該当のファイルが有るかどうかを確認してからショートカットを書き換える。」

　つまり「今より絶対悪くならない」のである。ショートカットの張り替え先についての設定を間違えたら何もしない。リンクのパスに含まれた組織名が変わるので、パスの組織名だけを書き換えるつもりが、たまたま一致する文字列がヒットした場合でもスルーするだけだ。
　では何を改良したかというと、最初は他のソフトでリンクファイルの一覧を取得して、それを書き換えの入力にしていたのを一気通貫でやるようにしたとか、複数のパス変更に対応するようにした。ローカルでドライブレターを割り当てていたものも対象とした（ローカルのドライブレター割当状況もツール内で取得）といった、部分である。要するに誰にでも使えるようにしたわけだ。

　さて、このへんの「今より悪くはならない」というセーフティネットを張る感覚、持っている人どれくらいいるだろうか？
　気になっているのは「情報」の授業が必修になったらしいこと。そこそこコンピュータを扱えることが普通になりそうだ。しかし、そいつらがこういう実用に耐えるプログラムが作れるかどうか、ははっきりとしない。いや、絶対無理だろう。フォイエルバッハに関するテーゼの第３項「教育者自信が教育される」。教えられる教員が一体どれだけいるだろうか。果てしなくゼロに近いような気がする。

　もうひとつ、こういうセーフティネットを張ることが重要と認識している人が（たとえば文部科学省の）意思決定者にいるか、も不安材料である。教えられる人がいなければ呼んでこないといけないのだが、その決定がされるかどうか。

　というわけで誰でも使えるプログラムを作って欲しいなら、入社してからそーゆーことを教えないといけないのだが、なまじっか「情報」の教育を受けているがゆえに素直に「そーゆーめんどくさいこと」をうけいれられないのではないかなぁ、というのが懸念していることである。

　ひょっとして彼らは「テスト」すら嫌がるかもしれない。AIというか機械学習ライブラリを使った経験くらいは持っていてもおかしくないからだ。機械学習させたAIが判断ミスしたとき、それを作った人たちはどう言うだろう？「学習させたデータが足りなかった」「過学習におちいったのではないか」、ようするに「教え方が悪かった」という発想になるようで、自分の作ったプログラムがおかしい、とは少なくとも第一義的には考えなくなっているのではないかな。
　機械学習のライブラリをコールして結果を出せれば「情報」のカリキュラムの範囲では上位層なのかもしれないけども、たぶん彼らのプログラムは「必要なライブラリをpip installして、きちんと出力が返ってきたか」の動作確認しかやっていそうもない。
　であれば「プログラムが期待した結果を出さないとすればそれは使い方が悪い」と考える傾向も強かろう。テストの重要性を認識しないかもしれない、ましてや誤った使い方をしても今より悪くならないというセーフティネットを張る意識はないんじゃなかろうか。

　でも、テスト代行業者の方のテスト手法も旧態依然の先入観から脱しているような気がしなくもない。えっと、ラジオボタンの入力が一箇所増えると、テストケースが２倍になる、ですか？ラジオボタンの選択によって以後の入力可能箇所を切り替えるとか、そーゆーの考えません？普通は。そりゃテストケース数が増えるとあなた請求額は増やせるからあなた儲かるかもしれないですけど。（ちょっとムカっときた見積もりがあったので余計なことですが付け加えさせてください。m(_ _)m）

[1]:http://hp.vector.co.jp/authors/VA015862/freesoft/relink.html
スプレッドシートの最終行を取得する

最終行を取得するには

```
let lastRow = sheet.getLastRow();
```
これがシンプルですが、シート全体の最終行をとってしまうので

特定の列を指定したい場合、例えばA列の最終行をとりたいとすると

```

function codeForGetRow() {  
  let range = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN);
  let lastRow = range.getRow();
  return lastRow
}
```
途中に空白があるが、最終行を取りたい場合

```
function myFunction() {  
  var lastRow = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  Logger.log(lastRow);   
}
```
Python3エンジニア認定基礎試験の勉強でつまずいたところ【ユーザー定義関数編】

# はじめに
2022年4月15日、Python3エンジニア認定基礎試験に合格しました。
試験対策は各認定スクールさんが出している模擬試験で行っていました。
模擬試験を解いていて、プログラミング初学者の私がつまずいたところを備忘録としてまとめようと思います。
今後同じ箇所でつまずいた方の一助となれば幸いです。
*問題は一部改変しています。

# 模擬試験の問題
##### 問1.以下のプログラムを実行した際の出力結果を答えよ。
```python:test.py
def dive_into_code(teacher, L = []):
	L.append(teacher)
    return L

print(dive_into_code('Noro'))
print(dive_into_code('Nakao'))
print(dive_into_code('Miyashita'))
```
***正解***がこちら。
```console:console
['Noro']
['Noro', 'Nakao']
['Noro', 'Nakao', 'Miyashita']
```
ここで私は思いました。
関数`dive_into_code`を呼び出す度に、`L = []`とデフォルト引数が代入されリストが初期化されるので、
```console:脳内cosole
['Noro']
['Nakao']
['Miyashita']
```
となるのではないか、と。これは間違いでした。

正しくは、**Pythonではデフォルト引数の値が評価(代入)されるのは関数を定義した時だけ**、です。
関数を呼び出す時にその都度デフォルト引数が評価されるわけではないのでご注意ください。[^*]
ですから、**関数の定義時にのみ初期化されたリスト`L`に**第一引数の`teacher`が`append`されて正解の出力結果となります。

デフォルト引数の値が関数定義時のみ評価されることを可視化するため、試しに次のようなプログラムを書いてみました。
```python:test.py
def hoge():
    print('hogehoge')

def dive_into_code(teacher, L = [], H = hoge()):
    L.append(teacher)
    return L

print('---ここから関数呼び出し---')
print(dive_into_code('Noro'))
print(dive_into_code('Nakao'))
print(dive_into_code('Miyashita'))
```
実行結果がこちら。
```console:console
hogehoge
---ここから関数呼び出し---
['Noro']
['Noro', 'Nakao']
['Noro', 'Nakao', 'Miyashita']
```
この結果からも、関数`dive_into_code`の定義時にのみ`D = hoge()`が評価され、**関数の呼び出し時には評価されていない**ことがわかります。

では、続いての問題も見てみましょう。

##### 問2.以下のプログラムを実行した際の出力結果を答えよ。

```python:test.py
i = 5
i = 6

def f(arg = i):
    i = 7
    print(arg)

i = 8
i = 9
f()
```
**正解**がこちら。
```console:console
6
```
この問題と初めましての時は`f()`となっていることをわかっていながら`9`と答えてしまいました。
なぜ`6`なのか。もうお分かりだと思いますが、先ほど同様、Pythonでは**デフォルト引数の値が評価(代入)されるのは関数を定義した時だけ**だからです。
つまり、プログラムが上から実行されて関数`f`が定義された時、直前で変数`i`には`6`を代入していました。この`i`がデフォルト値として`arg`に代入されたので、関数`f`に実引数を渡さなければ評価は`arg = 6`のまま、というわけです。

では少し書き換えて、次の場合ではどうなるでしょうか。
```python:test.py
i = 5
i = 6

def f(arg = i):
    i = 7
    print(arg)

i = 8
i = 9

f()
f(i)
f()
```
実行結果は以下となります。

```console:console
6    #f()
9    #f(i)
6    #f()
```

`f(i)`と、実引数`i`を渡した時は直前で`i`に代入した`9`となっていますが、もう一度実引数なしで呼び出した`f()`ではデフォルト値である`6`になっています。
当然と言われればそれまでですが、**関数定義時にされたデフォルト引数の値の評価**(今回は`arg = 6`)**は実引数を渡して関数を呼び出しても変わらない**ことがわかりました。

では最後に、問1を書き換えた以下のプログラムを実行した結果を予想してみてください。

```python:test.py
def dive_into_code(teacher, L = []):
    L.append(teacher)
    return L

M = []
print(dive_into_code('Noro'))
print(dive_into_code('Nakao', M ))
print(dive_into_code('Miyashita'))
```
実行結果がこちら。
```console:console
['Noro']
['Nakao']
['Noro', 'Miyashita']
```
**関数定義時にされたデフォルト引数の値の評価は実引数を渡して関数を呼び出しても変わらない**ので、実引数として空のリスト`M`を渡したあとも、**関数を定義した時にできたリストがデフォルトの引数**となっています。

# まとめ
**・Pythonではデフォルト引数の値が評価(代入)されるのは関数を定義した時だけ。
・上記から、関数を定義した時に評価されたデフォルト引数の値は、関数に実引数を渡しても変わらない。**

# 最後に
資格としては強いものではありませんが、勉強する中で疑問が疑問を呼び色々と手を動かしながら学ぶうちに新たな知見が得られ、今回の受験は非常に有意義でした。
次はデータ分析の方の受験も考えています。
なにか間違いなどあればコメントでご指摘いただけると、この記事を見られる方、私の勉強になりますので、よろしくお願いします。
初投稿、初学者故の拙さもあったかと思いますが、最後までお読みいただきありがとうございました。

[^*]:JavaScript、Rubyなど、関数を呼び出した時にデフォルト引数の値が評価される言語もあるようです。
2022/4/30主にITとかセキュリティの記事

あなたのパソコンから会社の重要情報が盗まれる…「ランサムウェア」の“本当の脅威”(4/28)
https://gendai.ismedia.jp/articles/-/94513

法人向けIoT機器の悪用によるサイバー攻撃防止を啓蒙するサイトを公開 - ICT-ISAC
https://www.security-next.com/136176

「サイバー攻撃検知レポート」公開 - 3月に攻撃が急増、連休前後の対策を(4/28)
https://news.mynavi.jp/techplus/article/20220428-2332583/

ランサムウェア攻撃を受けた組織は66％、身代金は5倍に--Sophos年次調査(4/28)
https://japan.cnet.com/article/35186948/

最悪の脆弱性「Log4Shell」、依然として数百万のJavaアプリに存在(4/28)
https://news.mynavi.jp/techplus/article/20220428-2332533/

ハッカーが法執行機関になりすましてAppleやGoogleから入手した個人情報が未成年への性的恐喝に悪用されている(4/28)
https://gigazine.net/news/20220428-fake-legal-requests-used-sexually-extort/

大阪の病院に不正アクセス　数万人分の電子カルテ使えず(4/28)
https://www.nikkei.com/article/DGXZQOUF289170Y2A420C2000000/

ロ、ウクライナへ２３７件超のサイバー攻撃(4/28)
http://www.shikoku-np.co.jp/flash/article.aspx?id=20220428000234

【伊藤が解説します】北朝鮮のハッカー集団、オンラインゲームで暗号資産約780億円を奪取(4/28)
https://coin-otaku.com/topic/67869?utm_source=rss&utm_medium=rss&utm_campaign=post-67620-3-3-6

マルウェアEmotetの新たな手口にかかる注意喚起について(4/28)
https://www.npa.go.jp/newlyarrived/2022/20220428001.html

グーグル検索、個人情報の非表示ルール拡大　口座情報なども(4/28)
https://jp.reuters.com/article/alphabet-google-search-idJPKCN2MK043

ネットで個人情報を入力する前に！ 後悔しないための4つのチェックポイント(4/28)
https://news.nifty.com/article/technology/techall/12276-1603368/

Windows 11の右クリックメニューに好きな項目を追加できる「Custom Context Menu」がv3に
追加したコマンドの並び順を指定する機能が追加(4/28)
https://forest.watch.impress.co.jp/docs/news/1405926.html

IPv6のアクティブユーザー数、2022年末までに7億人に―中国(4/26)
https://www.recordchina.co.jp/b893269-s6-c20-d0189.html

サイバーセキュリティ対策の促進に関する助成金募集のお知らせ 東京都(4/27)
https://www.metro.tokyo.lg.jp/tosei/hodohappyo/press/2022/04/27/05.html

ロシア関係ハッカー集団、ウクライナ標的に計237以上もの作戦～米マイクロソフト報告書(4/28)
https://news.ntv.co.jp/category/international/67e7ebcdf7d44791953130c4e9a78917

米、中国の知財保護「抜本的な改善を」　法改正後も懸念(4/28)
https://www.nikkei.com/article/DGXZQOGN280AY0Y2A420C2000000/

Google Cloud での音声関連テクノロジーに関する究極のガイド(4/28)
https://cloud.google.com/blog/ja/products/ai-machine-learning/your-ultimate-guide-to-speech-on-google-cloud

金融法務研究会第1分科会報告書「デジタル化に伴う金融サービスに関する法的諸問題」について（金融法務研究会）(4/27)
https://www.zenginkyo.or.jp/news/2022/n042702/

マカフィー、判決を不服として控訴　PC販社との訴訟(4/28)
https://www.nikkei.com/article/DGXZQOUC278JE0X20C22A4000000/

掲示板やSNS、ブログなどに投稿された自分への誹謗中傷コメントを削除するには？(4/28)
https://internet.watch.impress.co.jp/docs/column/dousuru_risk/1404713.html

＃Ｗｅｂ３・０　〝支配者〟介さず個人情報管理(4/28)
https://www.sankei.com/article/20220428-5GZZUU2IMVNAXIZYDA3HLZUDRQ/

金融法務研究会第2分科会報告書「社会的要請の変化を踏まえた銀行取引における現代的課題」について（金融法務研究会）(4/27)
https://www.zenginkyo.or.jp/news/2022/n042703/

Windows10 ログインパスワードを変更する方法 【PassFab 4WinKey 7.3.2】(4/28)
https://prtimes.jp/main/html/rd/p/000000012.000098839.html

Google、検索結果からの個人情報削除リクエスト範囲を拡大　住所やメアドも(4/28)
https://www.itmedia.co.jp/news/spv/2204/28/news087.html

ディズニーが陰謀論「Ｑアノン」の標的に－ネット上で偽情報が拡散(4/28)
https://www.bloomberg.co.jp/news/articles/2022-04-27/RB0FAJDWX2PS01

軽量Linuxの実力を比較、重視するのは軽さ？それとも見た目？(4/28)
https://xtech.nikkei.com/atcl/nxt/column/18/01997/032500007/

違法なネタバレサイトもあると知らずに利用してヒヤリ(4/28)
https://ascii.jp/elem/000/004/089/4089992/?rss

NEWS pickup＆digest（2022/3/8～4/11）
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/041800011/041900054/
Qiita API でAPI Testerの練習してたら仕事で肝を冷やした件

仕事でTalend API Tester使わなきゃいけなくて、
使ったことないって言うとなんだコイツって言われそうなので（笑）、
練習しとこうかな～と思ったら、
Qiita APIってのがあって、それがちょいどイイじゃん。
で、みんながばかみたいに言う（笑）「APIたたく」って実際どんなか分かって良かったんだけど、
いざ仕事でAPI Tester使う時に、肝を冷やすことが起きたので、語っちゃおうとおもいます。

ぼちぼち書いていきまっせ
サーバ設定で見た記事

[サンプル](http://url-plumber.com)

## Git
https://www.task-notes.com/entry/20170507/1494126000

## Docker

https://docs.docker.com/engine/install/centos/#install-using-the-repository

https://docs.docker.com/compose/install/

https://tech.librastudio.co.jp/entry/index.php/2018/07/14/post-1924/

https://docs.docker.com/get-started/08_using_compose/

https://qiita.com/sam8helloworld/items/e7fffa9afc82aea68a7a

## nginx
https://oki2a24.com/2018/07/28/difference-between-nginx-latest-and-nginx-alpine/

https://karuta-kayituka.hatenablog.com/entry/2019/06/30/221301

## Redis

https://qiita.com/uggds/items/5e4f8fee180d77c06ee1

https://www.sraoss.co.jp/tech-blog/redis/redis-persistdata/

## PostgreSQL

https://crudzoo.com/blog/docker-postgres

https://www.hostinger.com/tutorials/how-to-install-postgresql-on-centos-7/#1_Access_Your_Server



https://self-development.info/postgresql%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A%EF%BC%88%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E4%BD%9C%E6%88%90%E3%81%A8%E5%A4%96%E9%83%A8%E6%8E%A5%E7%B6%9A%E8%A8%B1%E5%8F%AF%EF%BC%89/

# 蛇足
https://qiita.com/JeJeNeNo/items/ca677e56ea58fd5eb93f

https://qiita.com/yunzeroin/items/480a3a677f78a57ac52f

https://linuc.org/study/knowledge/544/

https://qiita.com/akiakishitai/items/69bb68f4f6fbd6a88016

https://github.com/git/git/blob/master/INSTALL
サブフォルダ内のファイル名をキーに対応するファイルをこねくり回すPowershellスクリプト書いてみた[aws cli][s3]

ちょっと面白いスクリプト作成依頼があったので状況とソースコードを記録しておく。
（ファイルとフォルダという言葉を使っているが、AWSのS3に詳しい人ならオブジェクトとプレフィックス等と表現するのが正しいのではないかと訝しむ人もいるだろう。が、ここでは便宜上そう表現しているだけなので気にしないで頂きたい。）
# 背景
とあるWeb系システムでは、申請情報と共に画像ファイルをアップロードする仕組みがある。
このアップロード先はAWSのS3を利用しており、画像ファイルは任意の圧縮形式でバケット直下の「picture」フォルダに、申請情報はJson形式で同じくバケット直下の「json」フォルダにアップロードされる。
ただし「json」フォルダはそのアップロード日情報を元に、「yyyymm」フォルダと「dd」フォルダから成る階層構造を持つフォルダ配下に割り振られて格納される。
この画像ファイルとJsonファイルは１：１の関係にあり、かつその組み合わせはファイルベース名を同一にすることで表現する。
下記の例で云えば2022/3/2に申請された情報と画像の組み合わせはccccc.jsonとccccc.jpegといった具合だ。
```
s3://mybucket
  ├──json
  │  ├──202203
  │  │  ├──01
  │  │  │  ├──aaaaa.json
  │  │  │  └──bbbbb.json
  │  │  ├──02
  │  │  │  └──ccccc.json
  │  │  └──~~~
  │  └──202204
  │     └──~~~
  └──picture
     ├──aaaaa.jpg
     ├──bbbbb.png
     ├──ccccc.jpeg
     └──~~~
```
# 依頼内容
今般、月次でこれらの申請内容の分析をする要件が発生し、同AWS環境内に存在する既存の別システムに申請データを連携することとなった。
連携方法は、毎月一日に当該AWS S3バケットから「json」フォルダ配下の「yyyymm」を上記別システムを管理するサーバ(Windows OS)上の受入れフォルダ内に丸ごとダウンロードし、かつこのダウンロードした申請情報に紐づく画像ファイルを、同じく受入れフォルダ内にダウンロードすることで完了する。
この時の受入れフォルダ内の階層構造は当該AWS S3バケット(上図)と同一とする。
ただし、月次の連携処理開始時点での当該AWS S3バケットをまるまるaws s3 syncコマンドで同期することは禁止とする。
（この禁止理由は明かされなかったが、おそらくデータ量が膨大なので月日を経る毎に処理時間が増大するであろうことを懸念したとか、連携先のシステムで分析する際にデータを編集したりする都合上、過去データを含む全データを毎回処理対象にすることを嫌ったとかだったのだろうと推察する。いや前者はsyncなんだから関係ないか？）
これらの要件を満たすPowershellスクリプトを製造してほしい、というのが依頼の全容だ。
# 作ったスクリプトのコード
とはいえ色々問題になりかねないので全文そのまま記載するわけではなく、コア部分のみの記載とする。
パスとかも諸々ぼかさないとだしね。
```
# ローカル作業フォルダを変数化
${local_work} = "Z:\work"

# 処理対象月を決定する
${dst_month} = (Get-Date).AddMonths(-1).ToString("yyyyMM")

# 処理対象月に該当するS3バケットのJson格納フォルダをローカルに複製する
aws s3 sync s3://mybucket/json/${dst_month}/ ${local_work}\json\${dst_month}\

# 処理対象月のJSON格納フォルダ内の全ベースファイル名をリストアップする
$basename_list = Get-ChildItem "${local_work}\json\${dst_month}\" -Recurse -File | ForEach-Object {$_.BaseName}

# S3バケットのPicture格納フォルダから$basename_listを順にローカルに複製する
foreach( $filename in $basename_list -split "`r`n" ){
    aws s3 cp s3://mybucket/picture/${filename} ${local_work}\picture\ --include *
}
```
# 感想
Powershellスクリプトってあんまり作ったことなかったので色々いじってて面白かった。
コマンドレットにオプションを付けることで出力結果の形式とかががらりと変わるのも面白かったし、純粋なループ構造を無理やり1行にまとめるとかじゃなく、そうした処理専用のコマンドレットが用意されているというのも初見だったので楽しかった。
個人的には最初に覚えたVBScriptやbashとかがやはり自分のベースにあるものの、別言語を触ると色んな考え方を経験することになって視野が広がる感じが良いね。
Minikube on MacOS Monterey 環境構築

Monterey に アップデートして minikube on virtual box が動かなくなった。
```
❌  IF_VBOX_NOT_VISIBLE が原因で終了します: Failed to start host: driver start: Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue
💡  提案: VirtualBox インストールを完了させるために再起動し、VirtualBox がシステムや別のハイパーバイザーにブロックされていないことを検証してください
```
検索すると同じ様に困っている人たちがいる。
（まぁ、近頃は OpenShift on IBM Cloud を使っていたので、久々に minikube を動かした環境が Monterey だったりしたのかもしれないけど。。。）

記載してあるように VirtualBox をアンインストールし、最新版をインストールしてみたが状況が改善しない。
エラーメッセージの最後に記載してある[リンク](https://stackoverflow.com/questions/52277019/how-to-fix-vm-issue-with-minikube-start)を見ると、mac で Virtualbox の権限が許可されていないとのことで、これを許可してあげれば良い。
でも、せっかくなので minikube on virtualbox に代わる ローカルK8s環境はないか？と探したところ、「hyperkit を使って minikube を動かす」といった記事をよく見かける。
この度は、[Rahul Kumar さんの記事](https://gist.github.com/rahulkumar-aws/65e6fbe16cc71012cef997957a1530a3)を元に minikube on hyperkit を構築してみる。

１． 既存環境のお掃除
```
minikube stop; minikube delete &&
docker stop $(docker ps -aq) &&
rm -rf ~/.kube ~/.minikube &&
sudo rm -rf /usr/local/bin/localkube /usr/local/bin/minikube &&
launchctl stop '*kubelet*.mount' &&
launchctl stop localkube.service &&
launchctl disable localkube.service &&
sudo rm -rf /etc/kubernetes/ &&
docker system prune -af --volumes
```

２． xhyve (MacOS XにおいてLinux KVMに相当する仮想化ハイパーバイザ by Wikipedia ) ドライバーインストール
```
brew install docker-machine-driver-xhyve
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
```

３． Minikube インストール
```
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && \
chmod +x minikube && \
sudo mv minikube /usr/local/bin/
```

４． hyperkit インストール
```
curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit \
&& chmod +x docker-machine-driver-hyperkit \
&& sudo mv docker-machine-driver-hyperkit /usr/local/bin/ \
&& sudo chown root:wheel /usr/local/bin/docker-machine-driver-hyperkit \
&& sudo chmod u+s /usr/local/bin/docker-machine-driver-hyperkit
```

５． minikube 起動
```
minikube start --logtostderr --v=3 --vm-driver=hyperkit
minikube version
```
※このとき、以下のように「/usr/local/bin/kubectl のバージョンは 1.16.0 で、Kubernetes 1.23.3 と互換性がないかもしれません」と warning が出るけど、エラーではない。
![スクリーンショット 2022-04-30 3.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/68b66f89-46b7-3615-140f-856e7fc398d0.png)


６． 起動確認
```
minikube ssh
```
![スクリーンショット 2022-04-30 2.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682574/e28839fd-478b-003a-fd01-4fecb96c51e0.png)

minikube が無事 macOS Monterey で起動することを確認することができました。
(^_^)v
「たぶらかす」の意味って、「だましまどわす。あざむく。」なのか…笑

Tablacus Explorerってとっても便利で、使わない手はないじゃんって感じです。
ここでは、一ファンとして気づいた所を挙げたいと思います。

## 検索について
Windowsエクスプローラで当たり前に再帰的検索やってくれるから、
いかしてるTablacusなら当然だと思ったら、
標準では今開いてるフォルダしかやってくれないんだね。
調べたらアドオン入れたら出来る様になるみたいね。

https://tablacus.hatenablog.com/entry/2014/06/17/210155

だけどむやみにアドオン入れると変なことにならないかな…

## SVN更新しても、表示が自動で更新されない
TortoiseSVN使ってて、チェックアウト（ローカルにダウンロード）してあるファイルやフォルダを
サーバと同期（SVN更新）すると、
Windowsエクスプローラは自動的に表示が更新されるから、
いかしてるTablacusも当然そうだと思ったら、
自分で更新操作しないと全然更新されないね。
Multi-Page Tiff で保存された動画をPythonで開く

昔 ImageJ で撮影した動画を再生するために

```py
from PIL import Image, ImageSequence # Tiffファイルを開くのに使う
import numpy as np # PILの画像ファイルを numpy の array に変換する
import cv2 # 動画を表示する
import time # フレームレート算出のため

im = Image.open("multi-page.tif")

frames = map(np.asarray, ImageSequence.Iterator(im))

FRAME_RATE = 30
delay = int(1000 / FRAME_RATE)

t = time.time()
for frame in frames:
    # show frame
    cv2.imshow("frame", frame)
    
    # frame rate (viewing)
    _t = time.time()
    print("Frame Rate: {}".format(1.0 / (_t - t)), end="\r")
    
    # press "q" to close window
    if cv2.waitKey(delay) & 0xFF == ord('q'):
        break
    
    t = _t

cv2.destroyWindow("frame")
_ = cv2.waitKey(1)
```
[Unity] シーン遷移のフェードアウト実装

シーン遷移時のフェードアウト機能の実装について！
アニメーションを使用して作成する方法です。

:::note info
使用PC： MacBook Pro (13-inch, M1, 2020)
OSバージョン: 11.5.2
Unityバージョン：2020.3.30f
:::

# 完成図
![フェードアウト_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/b2873305-8a34-b9a8-2f36-a5a28d0afef4.gif)

# やり方
## シーン遷移本体のオブジェクトを作成
① `【Hierarchy】→【Create】→【Canvas】`を作成

② `Canvas`の子オブジェクトに`Image`を作成

③`Image`のcolorを黒に、サイズをcanvasいっぱいに変更する。

![画面収録_2022-04-30_1_36_57_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/28220e2b-1bbe-df50-f267-37b612ebaa9c.gif)


④`Image`に`Add Component`から`Canvas Group`を付け加える。
![スクリーンショット 2022-04-30 1.39.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/b2a44cb2-a0a3-bab4-e51f-6d36d9613648.png)


④`Image`のinspectorビューで、gameビューでcanvasにピッタリになるように設定。colorを黒色にする。
![スクリーンショット 2022-04-29 23.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/181cd042-7000-3eea-ee0c-5c6884775df7.png)

## アニメーションの作成

（もし表示されていなければ、`【Window】→【Animation】`で`Animator`と`Animation`のビューを開いておいてください。）
![スクリーンショット 2022-04-29 23.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/5055e3c1-422b-3196-87d1-0738f2c3bd76.png)

①`Animationビュー`から`Create`を押し、保存先を好きなところに設定し保存する。（名前も自由に！）
![画面収録-2022-04-29-23.27.45.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/c200acc3-e0a0-9051-8544-768c6fae0c38.gif)

②`【Add Property】→【Canvas Group】→【Alpha】`から+ボタンで追加する。タイムライン0秒のキーフレームを選択。`Color.a(透明度)`をクリックして「0」に設定する。
（キーフレームの「1」のところの`Color.a`が「1」になるようにする。）
![画面収録_2022-04-30_1_01_31_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/e088b636-2f9d-28c2-f1ab-062ecf53dee4.gif)
>※キーフレームは自由に調節してください。

③Projectビューに`fade(Animation)`と`Image(Animator Controller)`ができているか確認する。

>※ループが一回で良ければ、AnimationのLoop Timeのチェックを外してください。
![スクリーンショット 2022-04-30 1.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/0cc4bd02-9a53-f805-dce1-454a0ee9faba.png)

# 以上！！

# 参考記事
https://qiita.com/KatouKanade/items/ecada1ed1b4d6f607298
AWSのEC2内にWordPress用のWebサーバー(Apache)とデータベースサーバー(MySQL)を構築する（備忘録）

## EC2インスタンス内にApacheサーバーとMySQLサーバーを設置する

```
//Apacheサーバーの起動
$ systemctl start httpd

//インスタンス軌道とともにApacheサーバーが起動する設定
$ systemctl enable httpd

//phpサーバーの設定
$ amazon-linux-extras install php7.2
$ yum install -y php

//MySQLサーバーの設定
$ yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm -y
$ yum install -y mysql-community-server

//MySQLサーバーの起動
$ systemctl start mysqld

//インスタンス軌道とともにMySQLサーバーが起動する設定
$ systemctl enable mysqld
```

## MySQLDBの作成

```
//ログインの初期パスワードを取得
$ cat /var/log/mysqld.log | grep localhost

//先ほどの新規パスワードでログイン後に、ルートユーザーに新規パスワードで作成
$ mysql -u root -p
$ alter user root@localhost identified by 'パスワード入力';

//新規データベースを作成し確認
$ create database [データベース名];
$ show databases;

//新規ユーザーを作成しパスワードを設定
$ create user [ユーザー名]@localhost identified with mysql_native_password by 'パスワードを入力';

//作成した新規ユーザーのデータベースを利用する権限を付与
$　 grant all privileges on [ユーザー名].* to [ユーザー名]@localhost;
$ flush privileges;
```

## WordPressのインストール
```
//WordPressをDLし解凍後にhtmlディレクトリに移動
$ wget http://ja.wordpress.org/latest-ja.tar.gz
$ tar -xzvf latest-ja.tar.gz
$ cp -r wordpress/* /var/www/html

//ApacheサーバーがWordPressを読み取れるように設定し再起動
$ chown apache:apache /var/www/html/ -R
$ systemctl restart httpd.service
```

## WordPressの設定
[![Image from Gyazo](https://i.gyazo.com/251a7a57c1004b84cdaa705e71796003.png)](https://gyazo.com/251a7a57c1004b84cdaa705e71796003)

[![Image from Gyazo](https://i.gyazo.com/0b4be837abda4b75d1d057a86df39c6c.png)](https://gyazo.com/0b4be837abda4b75d1d057a86df39c6c)

[![Image from Gyazo](https://i.gyazo.com/633b032de8a0c488b571d535d859391b.png)](https://gyazo.com/633b032de8a0c488b571d535d859391b)
上記が出れば無事に成功

[![Image from Gyazo](https://i.gyazo.com/1b032ec842c9dec9dd40a3eb8fd8fe87.png)](https://gyazo.com/1b032ec842c9dec9dd40a3eb8fd8fe87)
作成したサイトの設定

[![Image from Gyazo](https://i.gyazo.com/608bfeb2af6507bddcc0f3e9013d9084.png)](https://gyazo.com/608bfeb2af6507bddcc0f3e9013d9084)

[![Image from Gyazo](https://i.gyazo.com/cb36712f79008aad74deaa4aa19b26ef.png)](https://gyazo.com/cb36712f79008aad74deaa4aa19b26ef)
早速ログインしてみる

[![Image from Gyazo](https://i.gyazo.com/a042451b7c84019fd1e0001fa691e7ae.png)](https://gyazo.com/a042451b7c84019fd1e0001fa691e7ae)
無事に完成！

## 関連記事

[AWSプライベートサブネット内のインスタンスにMySQLサーバーを設置（備忘録）](https://qiita.com/Teru_3/items/d287422558ac3c599225 "AWSプライベートサブネット内のインスタンスにMySQLサーバーを設置（備忘録）")
[AWSのEC2にApacheサーバーを設定してWebサーバーを立ち上げる（備忘録）](https://qiita.com/Teru_3/items/77f05a28ff895d8e41bf "AWSのEC2にApacheサーバーを設定してWebサーバーを立ち上げる（備忘録）")
[AWS SSH 認証のメモ（備忘録）](https://qiita.com/Teru_3/items/e0a759af684c7ebe72f4 "AWS SSH 認証のメモ（備忘録）")
Firestore Security Ruleで、特定の値を特定の値に変更する更新のみを許可する

RDMSだと、特定の更新のみを許可する場合が良くあります。たとえば、status = "done"にする場合だけ許可するようなパターン。これを、どう書くか、汎用的に関数化すると以下のようになります。

このテクニックを使えると、Cloud Functionsを使わなくて良いパターンがかなり増えるのではないかと思います。


```js
    // 指定されたキー以外は変化していない
    function isNotChangedExcept(keys) {
      return request.resource.data.diff(resource.data).affectedKeys().hasOnly(keys) 
    }
  	// 更新後の値が、valueを含んでいる
    function hasFixedUpdate(value) {
      return request.resource.data.diff(value).unchangedKeys() == value.keys().toSet();
    }
  	// 更新時のupdate条件がvalueと一致する
    function isFixedUpdate(value) {
      return isNotChangedExcept(value.keys) && hasFixedUpdate(value);
    }
　　　　　　　　// 使用例
    isFixedUpdate({"status": "done"}) || isFixedUpdate({"status": "cancelled"})
```
C#で自前スレッドプールとTaskを結びつける方法調査

# 問題点

C#ではスレッドプールが１プロセスにつき１つしかない。もしCPU主体処理とブロッキング有り処理の２種を扱いたい場合はどうすればよいのか。それぞれで欲しいワーカースレッド数が異なる。

# 対策方向性

- 方法１、プログラムからブロッキング関数を排除する。
- 方法２、ブロッキングする処理としない処理とで別プロセスに選り分け、プロセス間通信で協調動作させる。
- 方法３、１プロセス中で２つのスレッドプールを使い分ける。

１か２が採用できるならそれでよし。できない場合は３番でがんばる。

# １プロセス中で２つのスレッドプールを使い分ける

## C#での複数スレッドプール実現方法

２つのプールの内１つは.NETのデフォルト実装が使える。もう１つはnew Threadして自前で用意する。
ブロッキング関数がいつか排除できるかもしれないことを考えると、.NET実装プールはブロッキング無し用、自前実装プールはブロッキング吸収用とするのがよさそう。

## 結果受け取り方法検討

ブロッキング関数の実行結果は `Task` クラスで受け取りたい。例外も返せるし便利。

## 実行先スレッドプール指定方法検討

検討に使うブロッキング関数はこちら。これをブロッキング吸収用の自作スレッドプールで実行する想定。

```
int SleepFuncA(int arg)
{
    Thread.Sleep(3000);
    return arg + 1;
}
```

なお以降の検討案は実装確認をしておらず頭の中で検討したのみ。間違いあるかも。

### 直接スレッドプール利用 + TaskCompletionSource

MyThreadPoolの実装が必要。

```
int arg = 0;
var tcs = new TaskCompletionSource<int>();
Task<int> t = tcs.Task;
MyThreadPool.Enqueue(() => {
    try {
        var result = SleepFuncA(arg);
        tcs.SetResult(result);
    }
    catch (Exception ex) {
        tcs.SetException(ex);
    }
});
await t;
```

参考： https://devblogs.microsoft.com/pfxteam/the-nature-of-taskcompletionsourcetresult/

### TaskScheduler + Task.Start

MyThreadPoolとそれをラッピングしたMyTaskSchedulerの実装が必要。

```
int arg = 0;
Task<int> t = new Task<int>((obj) => SleepFuncA(arg));
t.Start(MyTaskScheduler.Instance);
await t;
```

参考： https://stackoverflow.com/questions/15143948/create-but-not-start-a-task-with-a-custom-task-factory

### TaskScheduler + TaskFactory.StartNew

MyThreadPoolとそれをラッピングしたMyTaskSchedulerの実装が必要。

```
static TaskFactory MyTaskFactory = new TaskFactory(MyTaskScheduler.Instance);
...
int arg = 0;
Task<int> t = MyTaskFactory.StartNew<int>(() => SleepFuncA(arg));
await t;
```

参考： https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=net-6.0

## まとめ

- ブロッキング関数の数が少ないなら、自前スレッドプール＋TaskCompletionSourceの構成が手間が少なくてよい。
- ブロッキング関数の種類が多いなら、自前スレッドプールをTaskScheduler派生クラスでラッピングしてTaskFactory.StartNew経由で使うのが便利。
- `new Task(...)` の方法は未開始状態の `Task` が得られる点がユニークだが特に利点は感じられない。逆に未開始状態がありえることに注意を割く必要性が生まれる分だけ作業効率が落ちる。もし起動順序制御が必要になったとしてもTaskScheduler派生クラスをいくつか用意して使い分けるほうがわかりやすくて良いように思える。
Jetstreamに軽く触れてみた

# Jetstreamとは
ログイン機能にメール検証、２段階認証やteams(権限)の機能が付与できる
Vue.jsを使用したライブラリ?である。
便利そうなので残しておく。

jetstream公式サイト

https://jetstream.laravel.com/2.x/introduction.html

## インストール
Laravelを先にインストールし、その後にjetstreamをインストールする
```
composer require laravel/jetstream
```

その後livewireかinertiaを選択することになると思います。
livewireはVue.jsの知識があまり無くても使える認識です。

inertiaはVue.jsの知識があれば使いやすいと思います。
Vue Routerを使わずAction(Controller)で直接やりとりできるので
便利だと思います。
```
php artisan jetstream:install inertia

php artisan jetstream:install inertia --teams
```
--teamsのオプションをつけるとteamsテーブルが作成され権限で使えそうな設定を付与することもできます。

あとは以下のコマンドでログイン画面やダッシュボードが自動で作成されます。
```
npm install
npm run dev
php artisan migrate
```
新卒2年目が1か月でAWS-SOAを取得してみた


　2022年4月23日にAWS-SOAを取得したので、勉強法や試験のコツを紹介します。
若手、経験が浅い方でも取得できるので、一緒に頑張りましょう！！

## 私のスペック(簡単に紹介)
 新卒2年目、メーカー系SIerでインフラエンジニアをしている。実務で半年ほどAWSを扱っている。
AWS-CLF,SAA,基本情報取得済み。大学は情報系出身。
 ただ、入社時にインフラの知識はほぼ0...知識や日々の勉強が大切なので、インフラに文理は関係ないと思います。

## AWS-SOA取得にあたってやったこと
 1.有料のweb問題集(koiwa)を解く　
　→　まず1週解く　→　2週目は、7問中正解が5問未満のものを解きなおす　
　　
　1.ができたら試験実践形式で試す。8割超えないなら、1.の3週目を解く

 2.　1.の問題でイメージわかないものは実際にマネジメントコンソールやCLIで触ってみる。
 3. AWS公式ハンズオンをやってみる

ほんとにこれだけです。試験に受かるのも大事ですが、実務で役立つのがこの勉強法のいいところです。
SOAに関しては、書籍のおすすめが特にありません。本読むならAWS公式ハンズオンの方がいいです。

## ラボ問題について
　YouTubeでAWSパートナー企業が投稿している解説動画が参考になります。大体どんな感じで解けばいいかわかるはずです。
AWS公式からもサンプル問題が出ています。こちらも調べてみてください。

私が大切だと感じたのは、余計な設定をしないことだと感じました。問題文に書かれている通りの設定をすればいいのです。
いってもアソシエイトレベルなので、ラボ問題はそんなに難しくないです、安心してください。

## まとめ
　SOA試験が改訂され、難しくなったと噂ですがそんなことないです。ちゃんと手を動かしたかの確認であり、実務に役立つものになっただけです。
ポジティブシンキング大事です！！比較的取得のハードルは低いのにも関わらず、実務や転職のチャンスになります。若手や未経験からの転職を考えているみなさん一緒に頑張りましょう！！
　この記事が少しでも参考になれば幸いです。