OmniAICreator/Qiita-1.07M huggingface dataset:
au通信障害、事後処理、ボランティアします

　auが通信障害を起こした。<a href="https://www.watch.impress.co.jp/docs/news/1422600.html" target="blank">86時間の大障害である。</a>
　どう考えても「何か隠しているだろう」。
　ルーター交換で障害が起こった、というのはありうる話だ。
　問題は「復旧した」と言ってから確認を取り終わるまで２日かかったということだ。
　ちょっと待て。確認に２日かかるなら、ルーター交換がうまくできたとしても、その交換に問題がないか確認が終わるまで恒常的に２日かかるということだ。私のスマホはauだが、ずっとアンテナが立たなかったぞ。

　ということはルーター交換という作業がauにとって今回がはじめて（つねに２日かかるが、いままでやってなかったので事象が起こらなかった）か、実はルーター交換以外になにか障害があってそれを隠しているか、だ。輻輳が起こったとしてもハード障害があったとしてルーター１台分だ。処理しきれない通信量ではなかろう。
　それともあれ、auはみずほグループか？

　補償の話が出ているが、docomoの前例によると「全面ダウンだった時間は２４時間未満だったから補償には当たらない」で逃げたらしい。そりゃそうだろう。社長の携帯だけはどんなことをしてでもつなげるだろうから全面ダウンにならない。

　その時はスルーしてくれたようだが、私なら申し出る。
「データ見せてくれ。処理プログラム書く。それでユーザーひとりひとりについて、サービスできなかった時間を計算する。つまり個別のユーザーについて全面ダウン時間を計算して個人別に補償できるようにしてあげる。」
　もちろんボランティアでやるよ。でも協力者のトップ（いいだしっぺ）に名前を載せてください。
（この業界、名声が一番希少な資源なのよ。これが「オープンソース」運動を支えてます。）

　要求するデータは電話番号別（端末別の）位置情報取得状況。および通話記録。できれば障害時間前の通話記録も。
　位置情報を取得できなかった時間帯は当然「サービス停止」つまり障害継続時間。その間偶然通話ができたことがあるかもしれないが、それが過去の通話記録の実績からいって、ここは統計学の援用がいるね、５％以内の頻度で生じた短い通話であれば、途中で切れたということとしてサービス実施時間に加えない。

　説得力はあると思う。問題は「電源を切っていた人」だけど「サービス停止になっているのだから電源を切った」と見なければなるまい。電力需給逼迫注意報が出ていたのだ。使用していない（できない）機器の電源を切るのは当然である。
　KDDI関係者のうめき声が聞こえたような気が。

　そんなに難しい処理じゃないような気がしてきませんか？じゃあ俺も参加しよう、って人多いんじゃないでしょうか。

　一番言いたいのは「使えている人もいるから全面ダウンではない」というどんぶり勘定、通用する時代じゃないでしょ、ってことだ。
　個人別に料金を請求しているのだ。個人別に補償額を計算する。こちらの方向で動いて当たり前だ。これぞＤＸというものだろう。

　さて、具体的な補償の内容だが、普通は基本料金割引だよな。
　ところで、こんなのどうだろ。auと契約解除しても、ダウンした日数の倍、無償で継続使用できるようにします。理屈は通る。昔、国鉄はストの補償として「１日使える乗車票」を発行していたという例もあるから。
　今度はKDDI関係者の安堵のため息が聞こえてきたような。でも利用者の印象は悪いだろうなあ。
Shell連想配列を勉強した

# 初めに
今回は、最近衝撃だったshellの連想配列で学んだことをまとめてみます。
まさかShellにそんなことまで切ると思っていなかったのでかなり衝撃を受けました。

# そもそもdeclareが有能すぎる
## リードオンリーな -r
```bash:
declare -r static="static content"
echo ${static} # static content
static="test" # bash: static: readonly variable
```

## 配列宣言の　-a
```bash:
array1=(1 2 3 4)
declare -a array2
array2=(2 3 4 5)
echo ${array1[@]} # 1 2 3 4
echo ${array2[@]} # 2 3 4 5
```

## 本命連想配列の -A
```bash:
dict1=([a]=1 [b]=2)
declare -A dict2
dict2=([c]=3 [d]=4)
echo ${dict1[@]} # 1 2
echo ${dict2[@]} # 3 4
```
キーの配列は！で取得できる
```bash:
echo ${!dict1[@]} # a b
echo ${!dict2[@]} # c d
```

# 実際に使った例
Zabbixトラッパーで使った時のデータ
```bash:/etc/zabbix/script/jstat/conf.sh
#!/bin/bash
Prefix=$1
ZabbixServerStr=`grep -e "Server=" test.conf|grep -e "^[^#]"`
temp_str=${ZabbixServerStr//=/ }
ZabbixServer=${temp_str[1]}
if [ "$Prefix" = "JAVA" ]; then
  OEM=(
    ["00"]="tomcat-abc"
    ["03"]="tomcat-cde"
    ["04"]="tomcat-def"
  )
  ServiceName=(
    ["00"]="tomcats@AAA.service"
    ["03"]="tomcats@CCC.service"
    ["04"]="tomcats@ddd.service"
  )
```
```bash:/etc/zabbix/script/jstatjstat.sh
Prefix=$1
ZabbixServer="127.0.0.1"
declare -A OEM=()
declare -A ServiceName()
source /etc/zabbix/script/jstat/conf.sh ${Prefix}
HostName=`uname -n`
TimeStamp=`date +%s`
TempFile="/tmp/Zsender_temp_$$"
CacheFile="/tmp/Zsender_cache_$$"
for key in ${OEM[@}; do
  PID=`ps aux|grep ${OEM[${key}]}|awk '{print($1)}'
  jstat -gc ${PID} > ${CacheFile}
  ProcessStatus=`systemctl status ${ServiceName[${key}]}|grep "Active:"|awk '{print($2)}'`
  echo ${Hostname} ${Prefix}${key}_process ${TimeStamp} ${ProcessStatus} >> ${TempFile}
  jstat_indexes=`cat ${CacheFile}|head -n 1`
  jstat_values=`cat ${CacheFile}|tail -n 1`
  for index in ${!jstat_indexes[@]};do
    echo ${Hostname} ${Prefix}${key}_${jstat_indexes[${index}]} ${jstat_values[${index}]} >> ${TempFile}
  done
done

zabbix_sender -z $ZabbixServer -T -i ${TempFile}
rm ${TempFile}
rm ${CasheFile}
```
jenkins:restoreしてcredentialsIdがぶっ壊れた時の対処法

masterを載せ替えるみたいな感じで、マシンの載せ替えする時、thinbackup pluginとかでrestoreすることができます。

で、新しいマシンでrestoreした時うまくいかなかったケースに遭遇したことがあるのでそれの対処法。

thinbackup plugin とかはここに書いてあるので参照

https://qiita.com/bluelemmon/items/2ec853d6a9b57bd14518

で、壊れた時の対処方法ですね。

https://stackoverflow.com/questions/30704856/how-to-export-credentials-from-one-jenkins-instance-to-another

こちらに解決方法が載っていました。
新しいマシンにrestoreした時に、暗号化するキーみたいなのが不足しててdecodeしてもcredentialsIdの中の値が復元できないというような症状です。

で、下の方をどんどんみていくとこんなことが書かれています。

>his does not convert all the credentials for an easy, automated migration, but >helps when you have only few credentials to migrate (manually).
>
>To summarize, you visit the /script page over at the old Jenkins instance, and use >the encrypted credential from the credentials.xml file in the following line:
>
>println(hudson.util.Secret.decrypt("{EncryptedCredentialFromCredentialsXml=}"))


```
println(hudson.util.Secret.decrypt("{EncryptedCredentialFromCredentialsXml=}"))
```
# 要するにこれをscriptコンソールで打てば良い、という話。

一番上の質問項目をみるとcredentials.xmlに

```
          <username>jenkins</username>
          <password>J1ztA2vSXHbm60k5PjLl5jg70ZooSFKF+kRAo08UVts=    
          </password>
```
こんなふうになっているという記載がある。
このpasswordタグに打ち込まれている値をそのまま入力してやればいいわけだ。　

jenkinsの管理からの
![スクリーンショット 2022-07-06 0.01.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/443fb3b3-aeef-b4a2-c698-2c175dab1a58.png)

ここでじかうちしてあげる。ということ。
![スクリーンショット 2022-07-06 0.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/fff3bc17-014b-60dc-0f8a-f2f7087df885.png)

```
println(hudson.util.Secret.decrypt("{あなたの載せ替え前のマシンのcredentials.xmlに書かれている復元したい値}"))
```
Bokeh 凡例クリックにカスタムイベントを登録する

Pythonのグラフライブラリ [Bokeh](https://docs.bokeh.org/en/latest/index.html)のTIPSです。

凡例クリックで、関連するグラフを一斉に表示させたり、非表示にしたりしたいことありますよね。
ですがBokehでは、凡例にカスタムイベントを直接登録することはできなさそうでした。

解決法を探したところ、[スタックオーバーフローにありました。](https://stackoverflow.com/questions/70392754/how-to-create-working-callback-on-legenditem-in-bokeh)
プロット(Renderer)の表示非表示の状態変化には、カスタムイベントが登録できるようです。

簡単な例ですが、以下のような感じです。

```python
from bokeh.plotting import figure, save
from bokeh.layouts import gridplot
from bokeh.models import CustomJS

p1 = figure(width=400, height=200)
p2 = figure(width=400, height=200)

r1 = p1.circle([1, 2, 3], [5, 3, 1], legend_label='main')
r2 = p2.line([1, 2, 3], [3, 1, 5])

# 凡例へのクリックポリシーの指定は、プロットを作成した後でないと正常に動かない
p1.legend.click_policy = 'hide'

# プロットr1の表示非表示の状態に対し、カスタムイベントを付与する
r1.js_on_change(
    'visible',
    CustomJS(
        args=dict(r2=r2),  # r2をJavaScriptに渡す
        code='r2.visible = !(r2.visible);'))  # JavaScriptでr2の表示状態を反転する

save(gridplot([p1, p2], ncols=1), filename='test.html')
```

![Screen-recording-2022-07-05-23.56.09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591762/dac6be4a-bcf5-13bd-502c-6c498d4eafdd.gif)

狙い通り動きました！
[js]スクロールをブロックしたい

# やりたいこと
ローディング表示中やアニメーション中にユーザーのスクロールをブロックしたい。

# 実装
bodyのoverflowをhiddenにすれば良いです！
reactではこんな感じで実装できた。
```js
useEffect(() => {
  if (isScrollable) {
    document.body.style.overflow = "scroll";
  } else {
    document.body.style.overflow = "hidden";
  }
}, [isScrollable]);
```

# うまくいかなかった例
スクロールのブロックはできるが、removeEventLisnerがなぜかうまくいかない。
```js
useEffect(() => {
  const preventScroll = (e) => {
    e.preventDefault()
  }
  if (isScrollable) {
    document.removeEventListener('touchmove', preventScroll, { passive: false 
 });
    document.removeEventListener('wheel', preventScroll, { passive: false });
  } else {
    document.addEventListener('touchmove', preventScroll, { passive: false });
    document.addEventListener('wheel', preventScroll, { passive: false });
  }
}, [isScrollable])
```

＊ mousewheelは非推奨のためwheelを使っている
https://developer.mozilla.org/en-US/docs/Web/API/Element/mousewheel_event

＊ passiveはスクロールイベントを拾った時にユーザーのスクロールをブロックするかの指定。
https://blog.webico.work/passive-event-listeber01
APIKitのエラーを整理する

[APIKit](https://github.com/ishkawa/APIKit)ではどのようなエラーが定義されていて、それらがどういうときにスローされるかを整理します。

APIKitでAPIClientを実装するときに、エラーハンドリング周りをどう実装するかを考える際の参考になるかと思います。

<br>

# 前提とサンプルコード
APIKitが提供しているデフォルトの実装、つまりURLSessionAdapterを使用することを前提としています。

本記事執筆時点では、APIKitでは以下3つのエラーを定義しています。

- RequestError
- ResponseError
- SessionTaskError

HTTP通信処理の起点となる`send(_:callbackQueue:handler:)`メソッドを実行してエラーになると、`handler`にはSessionTaskErrorが渡されます。なのでRequestErrorとResponseErrorはSessionTaskErrorに内包される形になります。

エラーのパターンを整理すると、こんな感じのコードになります。

```swift
Session.shared.send(request) { result in
    switch result {
    case .success(let response):
        // 成功時の処理
    case .failure(let sessionTaskError):
        switch sessionTaskError {
        case .connectionError(let error):
            break
        case .requestError(let error as RequestError):
            switch error {
            case .invalidBaseURL(let url):
                break
            case .unexpectedURLRequest(let urlRequest):
                break
            }
        case .requestError(let error):
            break
        case .responseError(let error as ResponseError):
            switch error {
            case .nonHTTPURLResponse(let urlResponse):
                break
            case .unacceptableStatusCode(let statusCode):
                break
            case .unexpectedObject(let object):
                break
            }
        case .responseError(let error):
            break
        }
    }
}
```

<br>

以降では、各エラーがどのようなときにスローされるかを説明していきます。

<br>

# SessionTaskError.connectionError
クライアント側の問題によってHTTPリクエストに失敗した場合、このエラーがスローされます。

このエラーは`URLSessionTaskDelegate.urlSession(_:task:didCompleteWithError:)`が受け取ったものです。

URLSessionTaskDelegateの公式ドキュメントに記載がありますが、ホストの名前解決に失敗した場合や、ネットワークの問題でサーバに接続できないときなどにこのエラーがスローされるようです。

https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1411610-urlsession

<br>

# RequestError.invalidBaseURL
Requestの`baseURL`プロパティの値が不正な場合にスローされます。

<br>

# RequestError.unexpectedURLRequest
APIKitのデフォルト実装ではスローされません。

例えば、Requestプロトコルの`intercept(urlRequest:)`メソッドを独自に実装する際に、渡されたURLRequestが不正な状態だったときにスローするように実装すると良いかもしれません。

<br>

# ResponseError.nonHTTPURLResponse
APIKitのデフォルト実装ではスローされません。

SessionクラスはHTTPURLResponseを期待しているにもかかわらず、独自のSessionAdapterが別のURLResponse実装クラスを返すような実装にしているとスローされてしまいます。

<br>

# ResponseError.unacceptableStatusCode
HTTPステータスコードが`2xx`以外だった場合にスローされます。

Requestプロトコルの`intercept(object:urlResponse:)`メソッドのデフォルト実装でそのように実装されています。

<br>

# ResponseError.unexpectedObject
APIKitのデフォルト実装ではスローされません。

例えば、Requestプロトコルの`response(from:urlRequest:)`メソッドを独自に実装する際に、デコード処理に失敗したときなどにスローするように実装すると良いかもしれません。

<br>

# まとめ
APIKitのデフォルト実装を前提に、各種エラーがどのようなときにスローされるかを説明しました。

一部のエラーは定義のみされていて、スローするかどうかは実装者に任されています。

なお、SessionTaskErrorの各エラーケースはError型の関連値を持っているので、どんなエラーでもスローすることが可能です。独自のエラーをスローする場合は、エラーハンドリングの分岐も増えることになります。
【Ruby】バリデーションのかけ方　Part1

## バリデーションの基本的な掛け方
### バリデーションとは？
入力されたデータ、プログラミング言語やマークアップ言語の記述が、適切に記述されているかどうかを検証することである。
多くの場合は、プログラミング言語においてフォームなどに入力された文字列が入力規則に対して妥当に記述されているかどうかを検証する仕組みを指す。記述が妥当でない場合はエラーとして値を返すように設定される。

### 基本的なバリデーションの掛け方
```
validates :カラム名, ヘルパー
```
Railsにはバリデーションのヘルパーが多数用意されている。
このヘルパーを使うとどういう検証を行うかを定義することができる。
主なヘルパーを紹介していきますね。

### バリデーションのヘルパー
#### presence
一番多く使うヘルパー。
定義すると「空でないか」を検証してくれ、空でない場合はエラーで弾かれる。
多くの場合は必須で入力するじゃないかな？
```
validates :カラム名, presence: true
```
入力するカラム名が空でないかを検証する。
例えば以下のように入力するとnameというカラムが空でないかをチェックする。

```
validates : name, presence: true
```

#### absence
presenceとは逆で空であるかを検証する。
```
validates :カラム名, absence: true
```

#### uniqueness
値が一意（unique）であり重複していないかを検証する。
特にメールアドレスや電話番号など重複しては困るときに使うことが多い。
すでに存在している内容と同じものがあるかどうかを検証することができ、すでに値が存在しているものと同じ値であれば保存されません。
```
validates :email, uniqueness: true
```


第一弾として投稿してみました。
次はより複雑で内容の濃い投稿をしていきたいと思います。
よかったらぜひ参考にしてみてください。
【unity】カメラをオブジェクトに追従させ、回転しないようにする


# はじめに
メインカメラをオブジェクトの子オブジェクトに追加すれば、追従自体は簡単に実現できる。
ただし、オブジェクトが回転するとカメラも回転してしまう。これでは画面酔い待ったなしである。

# 内容
結論としては、カメラオブジェクトは子要素として指定せず、スクリプトにて追従を行う。

```c#:カメラにアタッチするスクリプト

public class CameraMoveController : MonoBehaviour
{
    // キャラクターオブジェクト
    public GameObject playerObj;
    // カメラとの距離
    private Vector3 offset;

    void Start()
    {
        playerObj = GameObject.FindGameObjectWithTag(Groval.TAG_PLAYER);
        offset = transform.position - playerObj.transform.position;
    }

    void LateUpdate()
    {
        transform.position = playerObj.transform.position + offset;
    }
}

```

# 詳細
初めに、カメラとターゲットとなるオブジェクトの距離を`offset`として取得する。
`LateUpdate()`にて、ターゲットに対して常に一定の距離を保ったまま追従する。

これで画面酔いすることはない。

# 参考文献
- [【Unity】プレイヤーの回転に影響されない追従カメラを作る方法](https://programming.sincoston.com/unity-camera-follow-player/)
オプトアウト・オプトインメール とは

## 勉強前イメージ

そういう種類のメール？

## 調査

### オプトアウトメール とは

オプトアウト とは英語で脱退や不参加を意味します。
オプトアウトメールとはメールをとりあえず送って
受信者が不要であれば受信拒否をするような方法になります。

日本には特定電子メールの送信の適正化等に関する法律というものがあり
広告や宣伝のメールはオプトアウトでは送れなくなりました。
受信者の同意(=オプトイン)がないと送信者は送れない法律です。

そしてにアウトの逆、インとしてオプトインという言葉もあります。
オプトインメールとして受信者がメールの送信について同意をしたら送信者はメールを送ることが出来ます。

### まとめ

- オプトアウト → `受信した(行われた後)` メールの許可/拒否を選択
- オプトイン → `受信する(行われる前)` メールの許可/拒否を選択

## 勉強後イメージ

先に送られるか
許可したものを送られるか・・・

## 参考

- [オプトイン、オプトアウトって何ですか？](https://salt.iajapan.org/wpmu/anti_spam/universal/measure/optin-optout/)
- [オプトアウト](https://www.synergy-marketing.co.jp/glossary/optout/)
【PHP初級㉔】論理演算子4

［問題］　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)
整数値を入力させ、その値が-10以上0未満、または、10以上であればOK、そうでなければNGと表示するプログラムを作成しなさい。



# コード
```php
$a = intval(fgets(STDIN));
if(($a >= -10 && $a < 0) || $a >= 10){
    echo 'OK';
}else{
    echo 'NG';
}
```


↓「11」と入力



# 結果
```
OK
```
EclipseとMySQLの接続エラー解消

[注意]この記事では、EclipseとMySQLがすでにダウンロード済みを前提としています。

データベース定義の登録で「Could not create connection to database server.」エラーの解消に手間取ってしまったため、同様のエラー解消に困っている人の助けになればと思い記事にしました。


環境情報
--------------------------
・Windows 11 Home
・Eclipse‥‥‥ pleiades-2021-12-java-win-64bit-jre_20220106
・MySQLCommunityServer‥‥‥mysql-installer-web-community-8.0.29.0
・JDBCドライバー‥‥‥mysql-connector-java-8.0.29\mysql-connector-java-8.0.29.jar



エラー内容
--------------------------
![エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730674/434cafa4-3336-c381-977d-30aa8283fac8.png)
下記の接続文字列で接続を試みたところ「Could not create connection to database server.」エラーが表示されました。
jdbc:mysql://localhost:3306/javaweb?characterEncoding=UTF-8&serverTimezone=JST

（MySQL上で文字コードUTF-8でJAVAWEBという名前のデータベースを作成済みです。）
⇒mysql> CREATE DATABASE JAVAWEB CHARACTER SET UTF8MB4


対処内容
--------------------------
接続文字列をjdbc:mysql://localhost:3306/javaweb?characterEncoding=UTF-8に変更するとエラーが解消しました。
![エラー解消.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730674/6bc39bc3-94a9-128b-aeed-07f8719d9ae5.png)





## 参考文献
参考: [EclipseとMySQLの連携方法について](https://qiita.com/nobuya_osako/items/c8bd67d72d2d6b5e1f20)
SQLの学習①


2022年7月より [『スッキリわかるSQL入門 第3版』](https://sukkiri.jp/books/sukkiri_sql3)にてSQLの学習を開始。
学習の記録としてQiitaに記述します。
*文章の引用等は一切行なっておりません。

## SQLとは
- データベースに格納されている情報を操作するための言語

## そもそもデータベースとは
- 管理や分析をするための様々なデータを蓄積したもの
- ITにおいてデータベースの実態は通常の場合ファイルである


## RDBについて
RDB = Relational DataBase
- 複数の表形式でデータを保持する
- ひとつひとつの表をtableと呼ぶ。
- テーブルは列=column、行=rowで構成される

## DBMSについて
DBMS = DataBase Management System
- SQLとRDBの中間に存在するシステム。
- SQL文を受け取り、その命令に従ってデータベースを操作する。
- DBMS自体はデータベースではないが、データベースファイルを含め「データベース」と表現されることも多い。
- 利用するDBMSによってSQL分の記述方法に違いがある。
- SQL文を送信する手段として、開発したプログラムから送信する方法とSQLクライアントから送信する方法がある。
*SQLクライアント ・・・ DBMSに付属しているSQL分をDBMSにそのまま送信できるソフトウェア


## 記述
```
select　カラム名,カラム名
from テーブル名
```
→ 指定したテーブル名からカラムの内容を表示する
```
select　*
from テーブル名
```
→ アスタリスクで全てのカラムを指定することができる
```
select　カラム名
from テーブル名
where 条件式
```
→ SELECT - ある条件を満たす行を探し、その行の内容を取得する
→ テーブルから条件に当てはまる行を表示する。
→ 記述例：where カラム名>1,000 ▶︎ 対象カラムの値より1,000より大きい値の行を表示
```
insert into テーブル名
values (カラムの値,カラムの値)
```
→ 指定したテーブルのカラムにデータを追加する
→ 整数型・文字型に注意。
```
update テーブル名
set 更新するカラム = 更新する値
where 先頭のカラム = 更新する行の値
```
UPDATE - ある条件を満たす行を探し、その行の内容を書き換える
→　特定の値を更新する
```
delete from テーブル名
where 先頭のカラム = 削除する行の先頭の値
```
DELETE - ある条件を満たす行を探し、その行の内容を削除する
→ 特定の行を削除する
Webpackを使ってTypeScriptの開発環境を構築する

# この記事の概要

Webpackを使って、TypeScriptの自動コンパイル、自動リロードを設定する方法を記載する

# 開発環境構築

## プロジェクトディレクトリの作成

```
// プロジェクトディレクトリ作成
$ mkdir typescript
$ cd typescript
// npm initする
$ npm init
```

## ツールのインストール

```
// ツールのインストール
npm install typescript ts-loader webpack webpack-cli webpack-dev-server --save-dev

※以下のツールをインストールした
typescript→typescriptのコンパイラ
ts-loader→typescriptのローダー
webpack→モジュールバンドラ（JSビルドツール）
webpack-cli→コマンドプロンプトからWebpackを動作させる
webpack-dev-server→Webpackに関する開発サーバー
```

## package.jsonにてscriptsの追加

```package.json
{
  "name": "typescript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development", # 追加
    "start": "webpack serve --mode=development" # 追加
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^9.3.1",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  }
}
```

※npm start→webpack-dev-serverの起動
※npm run build→webpackビルド処理起動

## webpackの設定ファイルの作成

```webpack.config.js
const path = require('path');
module.exports = {
    // モジュールバンドルを行う起点となるファイルの指定
    // 指定できる値としては、ファイル名の文字列や、それを並べた配列やオブジェクト
    // 下記はオブジェクトとして指定した例 
    entry: {
        bundle: './src/app.ts'
    },  
    output: {
        // モジュールバンドルを行った結果を出力する場所やファイル名の指定
        // "__dirname"はこのファイルが存在するディレクトリを表すnode.jsで定義済みの定数
        path: path.join(__dirname,'dist'),
        filename: '[name].js'  // [name]はentryで記述した名前(この例ではbundle）が入る
    },
    // モジュールとして扱いたいファイルの拡張子を指定する
    // 例えば「import Foo from './foo'」という記述に対して"foo.ts"という名前のファイルをモジュールとして探す
    // デフォルトは['.js', '.json']
    resolve: {
        extensions:['.ts','.js']
    },
    devServer: {
        // webpack-dev-serverの公開フォルダ
        static: {
            directory: path.join(__dirname, "dist"),
        },
    },
    // モジュールに適用するルールの設定（ここではローダーの設定を行う事が多い）
    module: {
        rules: [
            {
                // 拡張子が.tsで終わるファイルに対して、TypeScriptコンパイラを適用する
                test:/\.ts$/,loader:'ts-loader'
            }
        ]
    }
}
```

## TypeScriptのコンパイル設定ファイルの作成

```
// TypeScriptのコンパイル設定ファイル作成
$ tsc --init
```

# TypeScriptのプログラム作成

## ディレクトリ作成

```
// ディレクトリ作成
$ mkdir dist
$ mkdir src
```

## プログラム作成

```src/app.ts
import {Item} from './item';
var elem = document.getElementById('output');
var aBook = new Item('はじめてのTypeScript',1980);
aBook.say(elem);
```

```src/item.ts
export class Item {
    constructor(private name:string, private price:number){}
  
    public say(elem : HTMLElement | null) : void {
        if(elem){ // 引数がnullでない場合
          elem.innerHTML = '書名：' + this.name + '  価格: ' + this.price + '円';
        }
    }
}
```

```dist/index.html
<!DOCTYPE html>
<html lang='ja'>
  <head>
    <meta charset="utf-8">
    <title>Hello typescript</title>
  </head>
  <body>
    <div id="output"></div>
    <script src="bundle.js"></script>
  </body>
</html>
```

# TypeScriptのプログラム実行

## webpack-dev-serverの起動

```
// webpack-dev-serverの起動
$ npm start
```

http://localhost:8080/

localhostをブラウザで開く

## app.tsの内容を変更すると自動リロードされる
Flask と Electron で作るデスクトップアプリ ①「導入編」

Python でデスクトップアプリを作る際、一つの選択肢とし今回 **Flask＋Electron** という構成を解説していきます。
デスクトップアプリを作る方法を知るだけで**やりたいことを形にしやすい**と思うので私の中ではWebより取っつきやすいのではと**おすすめ**です。
第1章として、最初は**最小構成**で起動するまでを確認します。

## 開発環境
* **Windows 11**(Windows10でも可)
* **Python 3.10**
* **Flask 2.1.2**
* **electron v19.0.6**

## 環境構築
### 1．Electron
以下のリンクから Node.js をインストールし、`npm`コマンドを使えるようにする。
[Node.jsのインストール](https://nodejs.org/ja/download/)

#### 1.1. 作業ディレクトリで以下のコマンドを実行

```ruby:ターミナル
npm init -y
```

#### 1.2. 作成されたJSONファイル
main が実行する際に読み込むファイル名になる。そのため、フォルダ構成を変更した場合はこのパラメータを変更する。
```ruby:package.json
{
  "name": "tmp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

#### 1.3. Electron インストール
```ruby:ターミナル
npm install -D electron
```

#### 1.4. Electron の起動
 npm にバンドルされている npx コマンドランナー を使った Electron の臨時実行し、以下の画像のように初期画面を表示してElectronがインストールされていることを確認。
```ruby:ターミナル
npx electron
```
![electron.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1660691/9633f230-279e-0523-87a3-8532482207f2.png)


### 2. Python のインストール
こちらのリンクから[Python](https://www.python.org/downloads/)をインストール。
念のため、Python がインストールされているか以下のコマンドで確認しましょう。
```ruby:ターミナル
python --version
```


### 3. Flask のインストール
Python の代表的なフレームワークの１つFlask。以下のコマンドを実行しインストール
```ruby:ターミナル
pip install Flask
```

以下のコマンドを実行して、electron で flask を起動するのに必要なモジュールをインストール。
```ruby:ターミナル
npm install --save request
npm install --save python-shell
```

### 4. 最小構成のアプリケーション起動
各公式ドキュメントをもとに最小構成でアプリを作成します。
構成は以下の通りです。
> SampleApp
> 　┝ template
> 　│　└ index.html
> 　┝　app.py
> 　└　index.js


#### index.html
```ruby:index.html
<h1>~~ Hello, World ~~</h1>
```

#### index.js
```ruby:index.js
const {PythonShell} = require('python-shell');
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;

app.on('ready', function() {
  PythonShell.run('./app.py');
  const openWindow = function() {
    mainWindow = new BrowserWindow({width: 800, height: 600 });
    mainWindow.loadURL('http://localhost:5000');
  };
  openWindow();
});
```

#### app.py
``` ruby:app.py
from flask import Flask, render_template

app = Flask(__name__, instance_relative_config=True)

@app.route("/", methods=("GET", "POST"))
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000)
```

#### 実行
上記のサンプルの構成を作り、実行することで以下のようにブラウザが起動すれば完成です。

``` ruby:ターミナル
npx electron .
```
![electron_HellWorld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1660691/d0e46e08-5ff8-daf1-2d1c-ab79a5b48996.png)

## まとめ
いかがでしたでしょうか？案外、簡単に作れそうと思いませんでしたか？
後は好きにコードを書いて実際に何か作ってみましょう。
次回は**Bootstrap5**を使ってデザインを凝ってみようかと思います。
これから作成するElectron＋Flaskのソースコードは[Github](https://github.com/aburayamakeito/Flask-Electron/tree/main/qiita_sample)に掲載していきますのそちらをクローンしてOKです。
RaspberryPi4で電源オフを判断するために

# やりたいこと

RaspberryPi4でshutdownを実行しても、本当に電源を切っていいのかどうか判断できない。
いいタイミングで電源OFFするためにLEDを光らせたりして判断できるようにする。


## やりかたその１

起動している間、ボード組み込みの赤色LEDをチカチカさせる。
これで、チカチカが消えたことで電源OFFしていいと判断できる。

```shell:/boot/config.txt
dtparam=pwd_led_trigger=heartbeat
```


## やりかたその２

poweroffしていい信号をGPIOから出力する。

```shell:/boot/config.txt
dtoverlay=gpio-poweroff,gpiopin=17,active_low=1,timeout_ms=10000
```

電源がONの間はGPIP17がHIGHになって、電源OFFにしてよくなったらLOWが出力される。
ただし、LOWになって10秒以内に電源OFFにしないとエラー（カーネルパニック）が画面に表示される。
TypeScriptを導入しよう！！

# TypeScriptとは
TypeScriptは、JavaScriptを拡張して作られたプログラミング言語です。2014年頃にMicrosoftによって開発・発表されました。
TypeScriptは変数の**データ型をあらかじめ宣言することのできる言語**です。この仕組みは静的型付けと呼ばれ、コンパイルする時点でエラーが分かることや、コードの読みやすさ、大人数が開発に携わる環境で便利なことが特徴です。

# 前提
> node.jsがインストールされていること
[node.jsのインストール](https://nodejs.org/ja/ "node.jsのインストール")

# 導入の仕方
3ステップで簡単に導入ができる(**前提としてnodeがインストールされていること**)
1.　インストール
2.　tsconfig.jsonの書き方
3.　build

#### インストール
```zsh
# npmプロジェクトを作成(package.jsonが作成される)
% npm init

# 開発環境にTypeScriptをインストール(--save-devが開発環境に使用するライブラリとしてインストールするオプション)
% npm install --save-dev typescript ts-loader webpack webpack-cli

# インストールできたことを確認する(現在のディレクトリにあるのnode_modulesにTypeScriptがインストールされていれば、バージョンを返す)
% ./node_modules/.bin/tsc --version
Version 4.7.4

% ls ./node_modules/ts-loader
CHANGELOG.md    LICENSE         README.md       REFERENCES.md   dist            index.js        package.json

# tsconfig.jsonを作成する(TypeScriptをJavaScriptに変換する際の設定ファイルを作成)
% ./node_modules/.bin/tsc --init
Created a new tsconfig.json with:                                                                                       
                                                                                                                     TS 
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true

You can learn more at https://aka.ms/tsconfig
```

#### tsconfig.jsonの書き方
tsconfig.jsonがあるディレクトリは**TypeScriptプロジェクトのルートディレクトリ**になります。
```tsconfig.json
{
    "compilerOptions": {
        "moduleResolution": "node",
        "outDir": "./dist/",
        "target": "ES2015"
    }
}
```
- compilerOptions -> コンパイルする際のオプションを指定する
    - moduleResolution ->　モジュールの依存関係の解決に使用するものを指定する
    - outDir ->　出力先になるディレクトリを指定する
    - target -> コンパイルするJavaScriptのバージョンを指定する

#### build
```webpack.config.json
const path = require('path');

module.exports = {
    entry: './src/index.ts',
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: ['.ts'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'index.js',
        publicPath: 'dist/',
    }
};
```
- module -> 使用するmoduleを指定
    - rules -> 使用するmoduleの設定を書く
        - test -> webpackがビルドする際にチェックする条件を指定する
        - use -> webpackがビルドする際にチェック時、使用するmoduleを指定する
        - exclude -> webpackのビルドする際のチェック対象から外すものを指定する
    - resolve -> 
        - extensions -> webpackのビルド時に解決する拡張子を指定。

その他の設定は過去に書いた記事に書いてるのでそちらを参照してください。
[webpack.config.jsonの書き方](https://qiita.com/shindo-develop/items/583f671fb33004aa8006)
# 参考
[TypeScriptチュートリアル](https://qiita.com/EBIHARA_kenji/items/31b7c1c62426bdabd263)
Invalid Hook Call Warning 

## 環境
- Windows 10
- node@18.0
- next@12.2.0
- react@18.2.0
- typescript@4.7.4
- コマンドプロンプト(UTF-8)

## エラー発生時
```
npx next dev
```
を実行
**Invalid Hook Call Warning** が発生した

JSXで画面レイアウトを作成していた段階で
もちろん、React Hookを使っていなかった

## 解決方法
コマンドプロンプトのパスのドライブrから
ドライブRへ変更した


![スクリーンショット 2022-07-05 221611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499427/d515b5d9-cbda-071f-7461-97135d0cb6dc.png)

コマンドプロンプトだと通常通りコマンドが打てるので、てっきりエラーの原因がこれだとは思わなかった
というわけで備忘録
TypeScriptの環境構築

# この記事の概要

TypeScriptの環境構築について記載する

# TypeScriptの環境構築

## Node.jsのインストール（npmのインストール)

```
// homebrewのインストール
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
// nodebrewのインストール
$ brew install nodebrew
$ nodebrew --version
$ nodebrew ls-remote
// node.js(npm)のインストール
$ mkdir ~/.nodebrew/src
$ nodebrew install-binary stable
$ nodebrew ls
$ nodebrew use v18.4.0
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
```

https://brew.sh/index_ja

上記のページからHombrewインストール用のコマンドを取得

https://blog.yug1224.com/archives/5693a5e0fef2539c7d5b149d/

node.jsインストール時にエラーが起こるので上記を参考に対応

## TypeScriptのインストール

```
// TypeScriptのインストール
$ npm install -g typescript
$ tsc -v
```

# TypeScriptを使ってみる

```hello.ts
const message:string = 'Hello! TypeScript!';
console.log(message);
```

```terminal
// tsをjsにコンパイル
tsc hello.ts
// jsファイルを実行
node hello.js
```
【#20 エンジニア転職学習】Git/Github基礎　rebase

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

本日2回目の投稿になります。
引き続きGit基礎を進めています。学習教材の進捗的におそらく今回がGit基礎の最後になるかと思います。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はGitのプルリクエストに関する基礎を学習しました。

* **rebase　←Topics!!**
* タグ付け

# git rebase
その名のとおり親コミットの情報（ベース）を新しいものに統合していくコマンドです。**mergeが枝分かれを残して**統合するのに対して、**rebaseは履歴が一直線になる**イメージです。
またrebase -iオプションを使用することでコミットの修正や分割・統合等ができます。

* merge：pushした後 or コンフリクトしそうなとき
* rebase：pushしていないローカルの変更時
のような使い分け方をします。

使用している教材はこちら↓


https://www.udemy.com/course/unscared_git/


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
Rubyで宣言的なプログラムを書くためのテクニックTips

## この記事は何
この記事は、宣言的なプログラムを書くために使える、ちょっとしたテクニックを紹介していきたいと思います。

宣言的なプログラミングが何かは以下の記事が参考になると思います。

https://qiita.com/jun1s/items/5f60bbb886626d897abc

## テクニック集

### テクニック1: 変数は使い回さない
Rubyの場合、定数が少しピーキーな挙動になっているので、基本的に全ての変数は可変になってしまうと思います。
変数を使いまわしたり、値を変更するのはできるだけ避けることで、コードが追いやすくなり、冪等性の担保されたコードがかけるようになります。

```rb:bad
a = 1
a += 1
```

```rb:good
a = 1
b = a + 1
```

### テクニック2: 破壊的メソッドは用いない
破壊的メソッドは、自身の状態を変更させるメソッドです。これらのメソッドを用いると、テクニック1で述べた内容と同じく、コードが追いづらくなります。

値の変更はできるだけ非破壊的なメソッドと変数代入を用いるようにしましょう。

```rb:bad
a = [1, 1]
a.uniq!
```

```rb:good
a = [1, 1]
b = a.uniq
```

### テクニック3: `each`の代わりに`map`や`each_with_object`、`sum`などのArrayの組み込みメソッドを用いる
基本的にループ処理は`each`が使えれば実装が行えます。しかし、`each`を用いると基本的に変数の使い回しが発生してしまいます。
Arrayクラスには組み込みのmap/reduce系のメソッドが多く用意されているので、できるだけそれらのメソッドを使うようにしましょう。

```rb:bad

sum = 0
numbers.each |number|
  sum += number
end

scores = []
data.each |datum|
  score <<  datum[:score]
end

```

```rb:good
sum = numbers.sum

scores = data.map |datum|
  datum[:score] 
end
```


### テクニック4: 値による分岐はHashとStrategyパターンを用いる
受け取った値によって返す値や処理を変えたい時は、case文やif文を用いると思います。
これらを用いる代わりに、HashとStrategyパターンを用いることで、より宣言的なコードにすることが可能です。　

```rb:bad
def return_value1(type)
  case type
    when :a then 1000
    when :b then 2000
  end
end

def return_value2(type)
  case type
    when :a then 1
    when :b then 2
  end
end

```

```rb:good
class A
  def value1
    1000
  end

  def value2
    1
  end
end

class B
  def value1
    2000
  end

  def value2
    2
  end
end

VALUE_CLASS_MAP = {
  a: A,
  b: B
}

def return_value1(type)
  VALUE_CLASS_MAP[type].new.value1
end

def return_value2(type)
  VALUE_CLASS_MAP[type].new.value2
end
```
LightSailのApache・MySQL等のコマンド・パスまとめ

最近ちょくちょくLightSailを使用するのですが、ApacheなどのコマンドがEC2と違って困ることが多いので備忘録としてまとめました。

# Apache
### コマンド
```
# ステータス確認
sudo /opt/bitnami/ctlscript.sh status apache
# 起動
sudo /opt/bitnami/ctlscript.sh start apache
# 停止
sudo /opt/bitnami/ctlscript.sh stop apache
# 再起動
sudo /opt/bitnami/ctlscript.sh restart apache
```

### パス
```
# 主な設定ファイル
/opt/bitnami/apache2/conf/bitnami/bitnami.conf
/opt/bitnami/apache2/conf/bitnami/bitnami-ssl.conf
```


# MariaDB
### コマンド
```
# 初期rootユーザーパスワードの確認
cat /home/bitnami/bitnami_application_password
# ステータス確認
sudo /opt/bitnami/ctlscript.sh status mariadb
# 起動
sudo /opt/bitnami/ctlscript.sh start mariadb
# 停止
sudo /opt/bitnami/ctlscript.sh stop mariadb
# 再起動
sudo /opt/bitnami/ctlscript.sh restart mariadb
```
昔使ってた時はmysqlだったような。。
その場合はmariadbをmysqlに置き換えれば動きます。多分。
NMAPでスキャンしたときのサーバーのフットプリンティングをなるべく隠す方法

NMAPでスキャンしたときのサーバーのフットプリンティングをなるべく隠すには
---

nmapは、TCP/IPスタックの特性を利用して、狙っているホスト上で動作しているOSを推測しています。なのでのTCP/IPスタックの動作方法を変更しない限り、これを隠すことはできません。

例えば、今回一度だけ許可をとった上でnmapコマンドつまりサーバーが全世界へ公開している情報のお問い合わせコマンドを実行してみたところ、公開情報について早急にサーバーが応答してくれました。
```
kali@Linux:~# nmap -sV -O shinobi-iroha.com
Starting Nmap 7.80 ( https://nmap.org ) at 2022-07-05 16:53 PST
Nmap scan report for shinobi-iroha.com(127.0.0.1)
Host is up (0.000052s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.29 (())
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Microsoft Windows XP
OS CPE: cpe:/o:microsoft:windows_xp:sp3
OS details: Microsoft Windows XP SP3
Network Distance: 1 hop
Serivce Info: OS: Winodws; COE:/o:microsoft:windows

```

上記の結果からも分かるようにサーバーがApacheでバージョンが2.4.29 (Ubuntu)である事がわかりました。(興味のある方は色々と試してみるといいのかもしれません。)

そこで私はこのような結果からサーバーのバナー情報を隠すために色々と試行錯誤して、何とかその設定に成功する事が出来たので、下記に参考にしたサイトを共有してみます。

・使用しているLinuxでフットプリンティングをなるべく隠すための設定方法について、参考にさせていただいたサイト：
[サーバーのソフトウェアバージョンを隠蔽する方法](https://shinobi-iroha.com/blog/post/1)

nmapのOS検出の仕組み

[Remote OS Detection](https://nmap.org/book/osdetect.html)

[Understanding an Nmap Fingerprint](https://nmap.org/book/osdetect-fingerprint-format.html)

[OS Matching Algorithms](https://nmap.org/book/osdetect-guess.html)
eachの危険性を体で覚えて、その代替手段を知る（Ruby, Rails）

# やっちまった
話を単純化してお伝えすると、1万件以上レコードがあるusersテーブルに対して、`is_active`というカラムがあって、全員trueにしたかったです。

これを実現するのに、**全usersに`each`をかけて`update_column`する処理を仕掛けたら、本番のサーバーを一瞬死なせてしまい、めちゃめちゃ焦りました**。

```ruby
User.all.each do |user|
  user.update_column(:is_active, true)
end
```

`User.all.each`すると、該当するレコードを全て取得してきて、メモリに置いて処理をするので、それで激烈に重くなってしまうようです。この場合、Userのインスタンスを1万件以上取得して配列にしてそれをメモリにドーン！と置いて処理しようとしたので、それがメモリを強烈に圧迫してしまったみたい。

# 解決策１：`find_each`を使う
この時の対処方法の１つが`find_each`を使うこと。

これはレコードを持ってくる数に制限をかけながら処理を実行するので、メモリへの負担を軽減できます。
デフォルトでは1000件です。

```ruby
users.find_each do |user|
  user.update_column(:is_active, true)
end
```

`find_each`の`each`との違いとして、SQLを発行する時に`LIMIT`をかけてくれるのは想像つくが、`ORDER BY id ASC`も入るらしい。

find_each参考
- https://railsdoc.com/page/find_each
- https://pikawaka.com/rails/find_each

rake task参考
- https://docs.ruby-lang.org/ja/latest/class/Rake=3a=3aTask.html
- https://qiita.com/suzuki-koya/items/787b5562d2ae1a215d94

# 解決策２：SQLを直接発行する
結局今回は、上のfind_eachも行わず、DBクライアントアプリでSQLを書いて終わらせることにしました。

```SQL
UPDATE students SET is_active = true;
```

このSQLだけ見ると、「最初からそうしなよ」と思われそうですが、実際はもうちっとだけ複雑なSQL！
これが今回サーバーへの負荷が少ない方法と判断されました。
1のupdate_columnだと結局は`user.update_column`のSQLとその処理が1万回以上連続的に走ることになるが、SQLでやればSQLの発行は一度で済み、めでたしめでたしでした。
Trigger recursively update

エラーメッセージ：
System.DmlException: Update failed. 
SELF_REFERENCE_FROM_TRIGGER
cannot recursively update itself

説明：
Apex トリガが SELF_REFERENCE_FROM_TRIGGER エラーを発生させるのはなぜですか？

解決策：
再帰的に更新したり、Apexトリガから同じオブジェクトを削除することはできません。
 
このエラーは次の様な場合によく発生します。
 
 
・Beforeトリガでオブジェクトを更新するか削除しようとします。
・Afterトリガでオブジェクトを削除しようとします。
 
 
このエラーは直接操作と非直接操作の両方で発生します。下記に非直接操作の例を挙げます。
 
１、A リクエストはオブジェクト A のアップデートのために送信されます。
２、オブジェクト A のBefore Updateトリガ はオブジェクト B を作成します。
３、オブジェクト A はUpdateされます。
４、オブジェクト B のAfter Insertトリガはオブジェクト A を問い合わせ、それを更新します。これはオブジェクト A のBeforeトリガであるため、オブジェクト A の非直接更新です。そのため、エラーが発生します。


Link：
https://help.salesforce.com/s/articleView?id=000324391&type=1
JavaScriptの部分適用とクロージャで処理結果が異なる落とし穴

JavaScriptのクロージャと部分適用は、「引数の一部だけを与えて別の関数を作る処理」という理解だけだと落とし穴があります。
意外にもこの２つを比較して書いている書籍やウェブページが見当たらず、それどころかまったく同じものだと書いてあるサイトもありました。
同じ間違いを犯す人が少しでも減ることを願い、この記事を書くことにしました。

## 前提
* 当然ながらブラウザ・Node.jsのどちらでも同じです。TypeScriptでも同様です。
* 筆者はアマチュアエンジニアかつQiita初心者なので、間違いはお手柔らかにご指導願います。

## 結論
* クロージャの閉包された引数は「**変数**」のように処理される。
* 部分適用で与えられた引数は「**定数**」のように処理される。

## 具体例
遠足に持っていくおやつは300円までというルールがあるとします。
買い物の際にルールに違反していないかを調べる関数を作ってみましょう。

### クロージャの場合
```JavaScript
const budgetClosure = budget => price => {
  budget -= price;
  return budget >= 0;
};
const budgetCheck = budgetClosure(300);

budgetCheck(200);  // true
budgetCheck(120);  // false
```
200円のおやつを買った後に120円のおやつを買うことはできないという判定になりました。
クロージャに入れたbudgetの値は変数のように処理されるので、priceを引くたびに新しい値に更新されるようです。


### 部分適用の場合
```javascript
const budgetBind = (budget, price) => {
  budget -= price;
  return budget >= 0;
};
const budgetCheck = budgetBind.bind(null, 300);

budgetCheck(200);  // true
budgetCheck(120);  // true
```
どうやら300円以下のおやつであればいくらでも買えてしまうようです（~~その手があったか~~）。
部分適用でbudgetに入れた300円は関数内部で定数のように処理される、と考えてよいと思われます（ちなみに筆者はこちらでも変数のように動くと錯覚していました）。

なお、オブジェクトを引数とする関数に対して部分適用するケースでは、オブジェクトのメンバーは変数のように処理されます。
「constはあくまで再代入の禁止なので、オブジェクトのメンバーは上書きできる」ということを考えれば納得できるでしょう。

```javascript
const budgetBind = (budget, price) => {
  budget.amount -= price;
  return budget.amount >= 0;
};
const budgetCheck = budgetBind.bind(null, {amount: 300});

budgetCheck(200); // true
budgetCheck(120); // false
```


## 補足
* （部分適用とは似て非なるものとは理解しているものの）カリー化された関数はどちらの動きになるのか疑問でした。結果は部分適用と同じで、定数として扱われるようです。
* 筆者は他の言語をあまり理解していませんが、[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3#%E3%82%BB%E3%83%9E%E3%83%B3%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9%E3%81%AE%E9%81%95%E3%81%84)によると言語によってはクロージャの動作は異なるようです。関数型言語では不変性が重要視された結果ということでしょうか。
LetとConstとVarの使い分け

プログラミング言語が時代とともに進化していくように、JavaScriptもバージョンが更新されていきます。現在最新版として使われているのが、「ES6（ECMAScript6）」というバージョンです。

以前までは変数宣言にvarのみを使用していましたが、ES6の環境からletとconstが新たに追加されました。

varはスコープの範囲を広げる自由度の高い変数のため、意図していないエラーが起こり得ることから、使用頻度は低いです。特別な意図がない限りはletとconstを使うようにしましょう。

![截屏2022-07-05 21.32.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2662696/48da040a-ca3b-5670-03d0-fd4416067701.png)


Link：
https://tcd-theme.com/2021/04/javascript-difference-let-const.html
Next.jsでThree.jsをサクッと動かしてみる

# はじめに

Three.jsの技術を習得した3次元的なUIを作成できるフロントエンジニアは今後非常に重宝されると思われるため、先んじて技術をキャッチアップしていこうと思っています
Three.js自体はJavaScriptを生のまま書く前提のライブラリのため、フロントエンドのフレームワークではまた書き方が変わってくるため、そのままの形でのThree.jsの導入は現実的ではないとされているのですが、Next.js(React)にはそこをサポートしてくれるライブラリがあるとのことだったので、サクッと動かしてみたのですが、かなり簡単に使用できて感動したので、その使い方を紹介します


# Three.js とは?

Three.jsを知らない人向けに一応補足すると、3次元的なUIを作ることができるライブラリです
大きな特徴としてJavaScriptのライブラリのため、Webアプリケーションとの相性が非常によいというのが最大の特徴です
これまでは3次元的なUIはUnityなどで作られ、ゲーム業界でしか長らく使われてこなかったですが、今後はVRの進展に伴って通常のWebサービスにも3次元的な続々と導入されていくことが期待されています
その一翼を担うと期待されているのが、Three.jsです

この説明でイメージがわかない人は、[three.jsの公式ドキュメント](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene)を見たり、ドキュメントに案内されている[Live example](https://jsfiddle.net/fxurzeb4/)にアクセスしてまずは動きを確かめてみるのがいいでしょう


# Next.jsの導入

まずはNext.jsを導入しましょう
こちらを参考に導入してください
Next.jsのプロジェクトができていてTypeScriptが導入できている前提で話を進めます

導入方法は[こちら](https://qiita.com/koseidaiki/items/73741508dd4b1405ca2a)


# Three.jsの導入

[react-three-fiber](https://github.com/pmndrs/react-three-fiber)というReact用のライブラリがあるのでこちらをインストールします
ちなみに[drei](https://github.com/pmndrs/drei)というライブラリもあるようで、react-three-fiberに満足できなければこちらを試してみるのもよさそうです
では、以下のコマンドで必要なライブラリをインストールしましょう

```
npm install three @types/three @react-three/fiber
```

さて、Next.jsとTypeScriptと上記のライブラリがインストール出来たらpages/index.tsxを以下のように書き換えてみましょう

pages/index.tsx
```tsx
import * as THREE from 'three'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'

function Box(props: JSX.IntrinsicElements['mesh']) {
  const ref = useRef<THREE.Mesh>(null!)
  const [hovered, hover] = useState(false)
  const [clicked, click] = useState(false)
  useFrame((state, delta) => (ref.current.rotation.x += 0.01))
  return (
    <mesh
      {...props}
      ref={ref}
      scale={clicked ? 1.5 : 1}
      onClick={(event) => click(!clicked)}
      onPointerOver={(event) => hover(true)}
      onPointerOut={(event) => hover(false)}>
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

export default function Home() {
  return (
    <Canvas>
      <ambientLight />
      <pointLight position={[10, 10, 10]} />
      <Box position={[-1.2, 0, 0]} />
      <Box position={[1.2, 0, 0]} />
  </Canvas>
  )
}
```

そして実行
```
yarn dev
```

すると以下のようば箱オブジェクトを生成したものが回転しているものが表示されました

![kakepic.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2275128/8c3f03c6-70d2-a27b-2a66-d0c033dd4b6a.gif)


なお、ジオメトリの引数を変えるとちゃんとオブジェクトの形が変わることが確かめられたりするので後はいろいろ試してみてください
例：```<boxGeometry args={[2, 1, 1]} />```


以上のように簡単にThree.jsを使い始めることができました




# おわりに

Next.jsを使えば思ったよりもかなり簡単にThree.jsを使うことができて驚きました
元々はVue.jsで開発を行おうとしていましたが、Three.jsのVue用ライブラリがVue3.0に対応していないとのことだったので、3次元的なUIを作る場合はNext.js（React）一択になるかと思います(Angularは調べてないです)
とにもかくにもThree.jsは非常に楽しいですね
今後もThree.jsの使い方を調べて発信していこうと思いますのでよろしくお願いします
Sending Wrapper object to Apex

public class AccountWrapper
{

    @auraenabled
    public string Name{get;set;}
    @auraenabled
    public integer NumberOfEmployees{get;set;}
    @AuraEnabled
    public List<Contact> Contacts { get; set; }
}

public class AccountService {

    @auraenabled
    public static void createAccountContact(AccountWrapper wrapper)
    {
        system.debug('wrapper:'+wrapper);
        if(wrapper!=null)
        {
            Account act=new Account();
            act.Name=wrapper.Name;
            act.NumberOfEmployees=wrapper.NumberOfEmployees;
            insert act;

            if(wrapper.Contacts!=null)
            {
                for(Contact ct:wrapper.Contacts)
                {
                    ct.AccountId=act.id;
                }
                insert wrapper.Contacts;
            }
        }
    }
}

import { LightningElement } from 'lwc';
import createAccountContact from '@salesforce/apex/AccountService.createAccountContact';
export default class ApexWrapperCall extends LightningElement {

    contacts=[];
    error;
    handleClick(e)
    {
        var contact=
        {
            LastName:'Sahni',
            Email:'salesforcecodex@gmail.com',
            Phone:'9871506648'
        };
        this.contacts.push(contact);
        var pass=
        {
            Name:'Dhanik',
            NumberOfEmployees:2,
            Contacts:this.contacts
        };
        createAccountContact({wrapper:pass})
        .then(result => {
            console.log('Data:'+ JSON.stringify(result));
        }) .catch(error => {
            console.log(error);
            this.error = error;
        }); 
    }
}

Link:
https://salesforcecodex.com/salesforce/sending-wrapper-object-to-apex-from-lwc/
トラブルを未然に防ぐためのリスクブレスト手法！ナイトメアヘッドラインゲームとは

# この記事は何？
某社の通信トラブルを受けて「うわあ。私のシステムでもこんな大トラブル引いたらやだなぁ。大丈夫かなぁ。」と想っている人は多いのではないでしょうか？
ここでは、そうしたトラブルを未然に防止するためのリスクブレスト手法である ***「ナイトメアヘッドラインゲーム」*** を紹介します。

## なんでリスクについて考えるの？
事故が起こると必ずと言って「想定外」といった言葉を聞きます。
我々や我々の作るシステムは「想定外」のことにとても弱く、「想定外」のことが起こった結果がトラブルになるのです。
逆に言うと、事前に想定できているのであれば、前もってそれらのリスクを「回避」したり、「軽減」したり、「転嫁」することができます。
もちろん、全てのリスクについて対応する必要はなく、ときには積極的に「受容」することも大事です。
いずれにせよ、事前にリスクを想定しておかなければ、対策もクソもないということです。なので、安全な日々を過ごせているうちに「リスク」について考えておくことは非常に重要なのです。
[※参考文献:リスクマネジメント(wikipedia)](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%B9%E3%82%AF%E3%83%9E%E3%83%8D%E3%82%B8%E3%83%A1%E3%83%B3%E3%83%88#%E3%83%AA%E3%82%B9%E3%82%AF%E5%AF%BE%E5%BF%9C)

## じゃあリスクってどうやって考えればいいの？
リスクについて考えてみよう！といって頭を捻ってみても、「想定外」のことなど中々考えられません。そりゃそうです。簡単に出てくるのであれば「想定外」になるわけないのです。
じゃあどうすればいいの？ということで、1つゲームをしてみましょう。
それがナイトメアヘッドラインゲームです。

## ナイトメアヘッドラインゲーム
ナイトメアヘッドラインとは「悪夢の見出し」、すなわちこのゲームは起きたらイヤーなことを考えるためのゲームです。
基本的にはブレストで、少しだけルールがあります。
そのルールは「実際に起きたら嫌なニュースのヘッドライン（見出し）」を考える。ということだけです。

![news_wideshow_serious.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181045/444056e0-da48-325c-adad-0ed712ac877f.png)

例えばあなたが「何とかpay」のシステムを開発しているとしましょう。
その「何とかpay」でトラブルが起きて、某日K新聞が記事を書いたとします。どんな記事のタイトルでしょうか？

 ***「何とかPayでチャージできない不具合！利用者x万人に影響！」*** 
 ***「何とかPayで顧客情報流出！見に覚えのない取引履歴も！」*** 

こんなことが考えられそうですね。
他にも、あなたが大手ECサイト「ジャングルEC」の運用をしていたとしましょう。某週刊誌センテンススプリングが「ジャングルEC」に関してすごく嫌な記事を書きました。どんな記事のタイトルでしょうか？

 ***「買ってはいけない！ジャングルECの商品は粗悪品だらけ！」*** 
 ***「システムトラブルで届きもしない商品に返金も出来ず…もはや詐欺！経営者A氏を直撃！」*** 

こんなことが考えられそうですね。
どうでしょう？なんにもないところから考えるよりはよっぽど考えやすくなったのではないでしょうか？
こうして「想定外」を「想定内」にすることは、未曾有の事故を防ぐ助けになります。

## リスクを考えたあとは？
リスクを考えたあとは、原因分析をしましょう。
原因分析のためには「[Fault Tree Analysis(FTA)](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%83%84%E3%83%AA%E3%83%BC%E8%A7%A3%E6%9E%90)」とか色々な分析手法があります。
何らかの分析手法をつかって、いやーなニュースを引き起こす原因を特定し、それぞれ事前にテストしてみたり、起きた場合の対応マニュアルを作っておいたり…と、「回避策」「軽減策」「転嫁先」などを検討していきましょう。
アクションを撃たないリスク分析は、まじで何の意味もありませんので、やるならリスク対応策の実施まで着実にやっておきましょうね。

皆さんが悪夢のようなニュースに出会わないように、今度の会議前にちょいとゲーム感覚でやってみてはどうでしょうか？
Jamstackとは？

## はじめに

案件でJamstackについて使う機会がありそうだったので、メモ程度に記載してみた。

## Jamstackとは
- JamstackのJamとは
    - JavaScript
    - Api
    - Markupの頭文字
- Jamstackの特徴
    - ウェブサーバー停止の影響を受けない
    - 大量のアクセスに強い 
    - 比較的安全

## Jamstackでよく使われるサービス
### ヘッドレスCMS
- コンテンツ内容を管理する部分であるバックエンドの機能だけを持ち、見た目のデザイン部分やCSSなどをもたないCMSの事を言う
- 記事の投稿をヘッドレスCMSで行い、データをAPIで公開する

### 静的サイトジェネレーター
- HTMLを生成するライブラリが必要になる
- ビルド時にAPIをたたいてそのデータを取り込める必要がある

### ホスティングサービス
- 生成した静的コンテンツを配信できるサービスが必要になる

## 現在考えているもの
### microCMS
- ヘッドレスCMS
- 日本製
- 投稿画面もわかりやすく非エンジニアでも扱うことが簡単そう
- 記事が多いのでわからない事があったら調べたらいろいろと出てきそう

### Nuxt.js
- 以前にVue.jsを用いた開発をおこなったことがあるから
- microCMSのブログサイトがNuxt.jsでできており、オープンソースになっていてコードが見れる

### Netlify
- 料金も安く、無料枠でもいけそう

## まとめ
Jamstackのデモサイトを作ってみたが、処理も早くユーザリティがとてもいいと思った。microCMSとの連携も簡単で扱いやすいなと思った。
tfenvを使ったTerraform環境構築

# はじめに

- Terraformを使う場面があり、その際に環境構築を行ったので、方法をメモとして残しておく。

# 環境

- MACでの環境構築。
    - Windowsでは、構築の際に使用したtfenvをそのまま使うことができない。
    - 使う場合はWSLやDockerを利用して、Linux環境を構築する必要がある。
- tfenvを使用。
    - tfenvとはTerraformのバージョン管理ツール。

# 手順

- tfenvのインストール
    
    ```bash
    brew install tfenv
    ```
    
- インストール可能なバージョンを確認
    
    ```bash
    tfenv list-remote
    ```
    
- インストールしたいバージョンのTerraformをインストール
    
    ```bash
    tfenv install 0.12.31
    ```
    
- 使用バージョンを指定
    
    ```bash
    tfenv use 0.12.31
    ```
    
- インストールされているバージョンを確認
    
    ```bash
    tfenv list
    ```
    
    - 使用バージョンを指定している場合は下記のようになる。
    ![eee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/16ca9b48-bd0e-f77e-73ef-6c7090899d74.png)
Ruby で手続きを別プロセスに渡したい

# はじめに
Ruby の並列実行では，[parallel](https://github.com/grosser/parallel) を使うのが簡便である．

```ruby
require 'parallel'

results = Parallel.map(['a','b','c'], in_processes: 3) do |one_letter|
  SomeClass.expensive_calculation(one_letter)
end
```

他方，`in_processes` では，メインプロセスをフォークして実行するので，メインプロセスのメモリ使用量が多く，分割プロセス数が膨大な場合，メモリが枯渇して `Parallel::DeadWorker` や「Killed」が発生してしまう．これを回避するには，子プロセスを，`Kernel.#system` などによる別コマンドとして実行すると良い[^1]．入出力が必要な場合は，`IO.popen` などを使うとよいだろうか．

[^1]: [Ractor](https://techlife.cookpad.com/entry/2020/12/26/131858) を使う手もあるかもしれないが，ちょっと触った限りではちゃんと書くのは結構大変そうだった．

```ruby:main.rb
require 'parallel'

results = Parallel.map(['a', 'b', 'c'], in_threads: 3) do |one_letter|
  IO.popen("ruby #{File.join(__dir__, 'worker.rb')}", 'r+b') do |io|
    Marshal.dump(one_letter, io)
    next Marshal.load(io.read)
  end
end
```
```ruby:worker.rb
# SomeClass.expensive_calculation の定義
# ...

one_letter = Marshal.load($stdin)
result = SomeClass.expensive_calculation(one_letter)
Marshal.dump(result, $stdout)
```

ところで，これを自分用のライブラリの中で使っている場合，expensive_calculation に `Proc` を渡したくなることがある．ところが，`Proc` インスタンスやそれに類するものは `Marshal` に対応していないため，単純には渡せない．どうしようか，というのが本題である．

# 解法例

## `Kernel.#eval`
真っ先に思いついたのは `Kernel.#eval` を使う方法．手続き定義部分を `String` にして，入力として渡してしまう方法だ．

```ruby:main.rb
require 'parallel'

dfn = <<EOS
Proc.new do |arg|
  # ...
end
EOS

results = Parallel.map(['a', 'b', 'c'], in_threads: 3) do |one_letter|
  IO.popen("ruby #{File.join(__dir__, 'worker.rb')}", 'r+b') do |io|
    Marshal.dump([one_letter, dfn], io)
    next Marshal.load(io.read)
  end
end
```
```ruby:worker.rb
one_letter, dfn = Marshal.load($stdin)
pr = eval(dfn)
result = SomeClass.expensive_calculation(one_letter, &pr)
Marshal.dump(result, $stdout)
```

`eval` は強力すぎるので，あんまり頼るのもなーという気持ちや，`String` リテラル内に定義を書き込むのが気持ち悪いなという気持ちが少しある．ちなみに，`Proc.new` だけでなく `def` でメソッドを定義してもよい．定義の仕方と呼び出し方の対応が取れていればなんでもよいが，予めどれかに決める必要がある．

## `Kernel.#load`
手続き定義部分を別ファイルにして，`Kernel.#load` するという手もある．

```ruby:main.rb
require 'parallel'

results = Parallel.map(['a', 'b', 'c'], in_threads: 3) do |one_letter|
  IO.popen("ruby #{File.join(__dir__, 'worker.rb')}", 'r+b') do |io|
    Marshal.dump([one_letter, File.join(__dir__, 'pr.rb')], io)
    next Marshal.load(io.read)
  end
end
```
```ruby:worker.rb
one_letter, pr = Marshal.load($stdin)
load(pr)
result = SomeClass.expensive_calculation(one_letter, &SomeProc)
Marshal.dump(result, $stdout)
```
```ruby:pr.rb
SomeProc = Proc.new do |arg|
  # ...
end
```

pr.rb を別ファイルにすることになるので，ここの定義が大きくなる場合は，大きな `String` を作るよりは見通しが良くなる．小さい場合はわざわざ別ファイルにするのが面倒ではある．

# だめな例
クラス，モジュールはなぜか `Marshal.dump` でエラーにならないが，インスタンスメソッドもクラスメソッドも `Marshal.load` で復元できないので意味がない．[名前がついていれば大丈夫とわざわざ書いてある](https://docs.ruby-lang.org/ja/latest/class/Marshal.html#M_DUMP) のだが，何が dump できるのかよくわからない．

# おわりに
というわけで，`Kernel.#eval` か `Kernel.#load` で渡す方法があった．コードが小さいなら `eval`，大きいなら `load` を使って渡す(受け取る)のが良さそうだ．スコープの問題が発生しにくい方法としては，モジュールあたりの定義を渡すのがいいかもしれない．