OmniAICreator/Qiita-1.07M huggingface dataset:
忘れがちなsharingキーワードの特徴

## 用語解説

### with sharing

- 共有ルールを適用する

- 適用されるのはログインユーザの共有ルール

### without sharing

- 共有ルールを適用しない

- 呼び出し元のクラスがwith sharingを使っていても、without sharingを宣言しているクラスには共有ルールが適用されない

### inherited sharing

- 呼び出し元のクラスの共有モードに従う

<br>


## 忘れがちな特徴

### 各記法での共有モード

- メソッド

	- 定義されているクラスの共有モードに従う

- 内部クラス

	- コンテナクラスから継承しない

- 継承クラス

	- 親→子へ継承される

- トリガ

	- sharingキーワードが指定できない

	- デフォルトでwithout sharingが適用される
<br>


### sharingキーワードを省略したとき

**自身のキーワードが省略されている場合**

- 他クラスからの呼び出しなし

    - without sharingが適用される

- 他クラスからの呼び出しあり

    - 呼び出し元の共有ルールに従う

**inherited sharingを宣言していて、呼び出し元クラスのキーワードが省略されている場合**

- with sharingが適用される
<br>


### 匿名ApexやConnect in ApexでApexを実行するとき

sharingキーワードに関わらず、ログインユーザの共有ルールが適用される

<br>


## 参考文献
[Using the with sharing, without sharing, and inherited sharing Keywords](https://developer.salesforce.com/docs/atlas.en-us.234.0.apexcode.meta/apexcode/apex_classes_keywords_sharing.htm)
コマンドラインでpython -〇 の -〇 とは

# コマンドラインでpythonを実行するときの-〇とは

-〇は、インターフェイスオプション（オプション）と呼ばれ、
コマンドラインでpythonを実行するときにつけるオプションである。
オプションは20種類ぐらいあるが、-m 以外あまり使うことはない。

### よく使う-mは何か
pythonモジュール(パッケージ)を実行するためのオプション
どこにあるモジュール(パッケージ)を実行できるかは以下で確認できる

```
C:\Users\user_name>python
>>> import sys
>>> sys.path
['', 'C:\\Users\\user_name\\AppData\\Local\\Programs\\Python\\Python39\\python39.zip', 'C:\\Users\\user_name\\AppData\\Local\\Programs\\Python\\Python39\\DLLs', 'C:\\Users\\user_name\\AppData\\Local\\Programs\\Python\\Python39\\lib', 'C:\\Users\\user_name\\AppData\\Local\\Programs\\Python\\Python39', 'C:\\Users\\user_name\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages']
```

↑はpythonの環境変数に設定したパス
【React / Next】SWRなどでfetchしたデータをreact-hook-formへ流し込んで、取得したデータを初期値として表示させたい

編集画面でfetchデータをフォームへ初期表示させたかったので、その備忘録です。
なお、FormControl などは chakra-ui を使用した環境で行いました。


# 環境
- next: 11.1.3
- react: 17.0.2
- react-hook-form: ^7.28.0
- @chakra-ui/react: ^1.8.5

# だめだったコード
- useForm の `defaultValues` へセットするだけ
- 固定値を `defaultValues` へセットすると表示されたが、fetchData は初期表示されなかった

```tsx
export const Form = () => {
  // 省略
  const { data, error } = useSWR("/api/user", fetcher);

  const {
    handleSubmit,
    control,
    formState: { errors },
  } = useForm({
    // 固定値であれば表示された
    defaultValues: { name: data.name },
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      // 省略
    </form>
}
```

# 初期表示されたコード
- `useEffect` と useForm の `reset` を使用する
- 親コンポーネントで fetch して、props で渡す場合も同様に初期表示できた 

```tsx
export const Form = () => {
  // 省略
  const { data, error } = useSWR("/api/user", fetcher);

  const {
    handleSubmit,
    control,
    formState: { errors },
    reset,
  } = useForm();

  useEffect(() => {
    reset({
      ...data,
      status: data?.status.toString(),
    });
  }, [data, reset]);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      // 省略
    </form>
}
```

# 文献
https://zenn.dev/takepepe/articles/form-with-useswr

https://stackoverflow.com/questions/64306943/defaultvalues-of-react-hook-form-is-not-setting-the-values-to-the-input-fields-i
今更ながらRiverPodのdependenciesをためしてみた

タイトルの通り、今更ながらRiverPodのdependenciesを試してみたメモです。
※RiverPod 1.0.3で確認
# そもそもdependenciesとは？
https://pub.dev/documentation/riverpod/latest/riverpod/Provider/dependencies.html
かんたんにいうと、ProviderRefからScopedなProviderにアクセスするためのパラメータです。dependenciesにScopedなProviderを指定すると、そのProviderもScopedになりアクセスが可能になります。

```dart
final scopedValue = Provider((_) => '1');
final valueDependsOnScopedValue = Provider(
  (ref) => ref.watch(scopedValue),
  // この指定により、scopedValueがoverrideされるとvalueDependsOnScopedValueもscopedになる
  dependencies: [scopedValue],
);
```

触ってイメージを掴みたい方はDartPadがあるので試してみてください。
https://dartpad.dev/?id=f8c9ce39572deed30dc47ed754c1c170

# 注意点
基本的には便利なdependenciesですが、触っていて下記の２点に気をつける必要がありそうだなとおもいました。
1. dependenciesを指定したら、ScopedでないProviderに依存する場合そのProviderを指定しないとExceptionを投げられる
1. overridesされたらdependenciesを指定しないとExceptionを投げられる
1. .futureで呼んでいるFutureProviderは.futureでdependenciesする必要がある

一つづつ見てみましょう。
### dependenciesを指定したら、ScopedでないProviderに依存する場合そのProviderを指定しないとExceptionを投げられる
例として、こんなコードがあります。
```dart
final scopedValue = Provider((_) => '1');
final valueNonAddedScopedValueToDependencies = Provider(
  (ref) => ref.watch(scopedValue),
);
```
この場合、dependencies指定していないからoverrideしても1が返ってくるのかな？と思いますが、overrideすると落ちます。
overridesされるProviderに依存する場合、かならずdependenciesを指定する必要があるようです。

### overridesされたらdependenciesを指定しないとExceptionを投げられる
たとえばこんな実装があったとします。
```dart
final scopedValue = Provider((_) => '1');
final countState = StateProvider(
  (ref) => 0,
);
final _valueDependsOnScopedValue = Provider(
  (ref) => '${ref.watch(scopedValue)}${ref.watch(countState)}',
  dependencies: [scopedValue],
);
```

こちらも問題ないように見えますが、これはoverridesされているか否かに関わらず落ちます。
dependenciesを指定する場合は、そのProviderが依存するProviderをすべて指定する必要があるようです。

### .futureで呼んでいるFutureProviderは.futureでdependenciesする必要がある
タイトルのとおりです
[VBA]WScript.ShellのExecをコマンドプロンプト非表示で実行

# はじめに
Exec実行中コマンドプロンプトがずっと表示されるのがうっとうしい！

ExcelやAccessで外部のexeを起動してやりとりしたいことって多々あると思います。
外部のexeを起動する関数としてRunとExecが有名だと思いますが、Runはコマンドプロンプトを非表示にする引数がありますが、Execにはありません。ですがExecには標準入出力から値を受け渡しできるメリットがあります。

今回はExecで外部exe実行中勝手に表示されるコマンドプロンプトを無理矢理非表示にしてやろうという記事です。
方法は「Exec実行後コマンドプロンプトが表示されていればそのウインドウをサイズ変更する」というものです。

# 使用するWinAPI
・FindWindow
・IsWindowVisible
・GetClassName
・GetNextWindow
・MoveWindow
・Sleep

以下64bit環境ならそのままコピペで宣言できます。
32bitならばPtrSafeを消したり少し手を加える必要があるかと思います。(#if Win32で環境によって場合分けできるといいかも)

```vb
'ウインドウハンドルを取得する
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

'ウインドウが可視かどうかを取得する
Declare PtrSafe Function IsWindowVisible Lib "user32" _
(ByVal hwnd As Long) As Long

'ウインドウのクラス名を取得する
Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

'取得中のウインドウの次または前のウインドウハンドルを取得する
Declare PtrSafe Function GetNextWindow Lib "user32" Alias "GetWindow" _
(ByVal hwnd As Long, ByVal wFlag As Long) As Long


' 指定されたウィンドウの位置およびサイズを変更
Declare PtrSafe Function MoveWindow& Lib "user32" (ByVal hwnd&, ByVal X&, ByVal y&, ByVal nWidth&, ByVal nHeight&, ByVal bRepaint&)

'遅延
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
```

# サイズ変更サブルーチン

```vb
Sub コマンドプロンプトが開いていれば最小化する()
    Dim ret As Long
    Dim className As String
    Dim i As LongPtr
    i = 1
    Const GW_HWNDLAST = 1
    Const GW_HWNDNEXT = 2
    Dim strClassName As String * 100
    Dim strCaption As String * 80
    Dim hwnd As Long
    hwnd = FindWindow(vbNullString, vbNullString) '引数を両方ともvbNullStringにして1つめのウインドウを取得する
    Do
        GetClassName hwnd, strClassName, Len(strClassName) ' クラスネームの取得　プロンプトなら　ConsoleWindowClass
        If IsWindowVisible(hwnd) Then '見えているウインドウならば
            className = Left(strClassName, InStr(strClassName, vbNullChar) - 1)
            If "ConsoleWindowClass" = className Then  'コマンドプロンプトが開いていれば
                ret = MoveWindow(hwnd, 0, 0, 1, 1, True) 'そのウインドウをサイズ変更　引数(ウインドウのオブジェクト,X,Y,幅,高さ,再描画？)
            End If
        End If
        hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)
    Loop Until hwnd = GetNextWindow(hwnd, GW_HWNDLAST)

End Sub
```

```vb
'比較部分を変えればコマンドプロンプト以外にも応用できるかと思います。
'引数として与えてもいいかもです。
If "ConsoleWindowClass" = className Then  'コマンドプロンプトが開いていれば

```

# 使用例
Exec実行の1秒後にコマンドプロンプトのウインドウサイズを変更します。
 ```vb

    '通信用exeファイル起動
    Set wExec = WSH.Exec("%ComSpec% /c " & sCmd)
    
    'プロンプトの表示完了までを待つ
    Call Sleep(1000)
    '十分に待ったところでプロンプト画面サイズ変更処理
    Call コマンドプロンプトが開いていれば最小化する()
    
    '戻値を受け取る　exe側の処理が終わるまでここで止まる
    Result = wExec.StdOut.ReadAll

```
【JavaScript】文字列を切り詰めて「...」を付ける

# 目的
画面上に文字列を表示するときに、長すぎる場合は末尾を切り詰めて、さらに続きがあるよということを示すために「...」等を付加したい時があります。`substr`が使えそうですが、JavaScriptの`substr`はマルチバイト対応してしまっているがために、「あいうえお」でも「abcde」でも同じ5文字とカウントされ、全角のみの場合と半角のみの場合では同じ文字数でも文字列の表示幅が倍近く違うということになります。全角文字は半角文字の倍でカウントして、例えば5文字で切り詰める場合に、「abcde」はそのまま「abcde」、「あいうえお」は「あ...」のように、**「...」分を考慮して必要に応じて文字を切り詰め、結果として半角文字分と同程度の幅の文字列を得たい**と思います。説明がややこしいですが、要はRubyの`truncate`と同じような関数がほしいと思いました。

# 実装
```JavaScript
const truncate = function(string, length, omission = '...') {
    return (string.match(/[^ -~]/g)?.length ?? 0) + string.length <= length ?
           string :
           string.split('')
                 .reduce(
                     (acc, c) => (acc[1] += !c.match(/[ -~]/) + 1) <= length - omission.length ?
                           [acc[0] + c, acc[1]] :
                           [acc[0], length],
                     ['', 0]
                 )[0] + omission;
}
```
2行目の条件は全角を2半角を1と数えて文字列長が指定の長さを超えているかどうかを判定しています。超えていなければ何もする必要はないのでそのまま返すのが3行目。4行目以降が本体ですが、まず`split`で文字列を文字配列にしてそれを`reduce`していきます。アキュムレータとして今までカウントした文字数とそこまでの部分文字列を渡していくので配列になっているのがややダサいところでしょうか。`reduce`内の`match`は文字毎に全角なら2、半角なら1をアキュムレータに足し込んでいく処理です。ここも2行目で全体に`match`かけてるのに、個々の文字にも同じような`match`をするのがちょっとなぁ、と思いますが…。あとはまだ指定の長さに達していなければその文字を足し込み、指定の長さを超えるようなら足さない、という判断をしてグルグル回します。`reduce`の結果の先頭要素が目的の文字列ですから、それに省略したことを表す文字列を付加して`truncate`の結果とします。
Meta Quest 2でVR睡眠をする方法

こんにちは、ほなふくです。
QuestでVR睡眠をすると2分程度でスリープしてしまい困る、ということはありませんか？
この記事では`Oculus Developer Hub`を利用しVR睡眠をするための方法を説明します。
なお、本記事ではPC VRの場合を説明しており、Quest単体ではこの設定でうまくいかない場合があります。

# Oculus Developer Hubの導入
`Oculus Developer Hub`というMeta(旧Oculus)がリリースしているソフトウェアがあります。
これはQuestでのアプリケーション開発のために作られたソフトウェアですが、近接センサーとガーディアンを無効化する機能がついているためこれを利用します。

`Oculus Developer Hub`は以下ページからダウンロードできます。
[ダウンロード - Oculus Developer Hub for Windows](https://developer.oculus.com/downloads/package/oculus-developer-hub-win/?locale=ja_JP)

# 開発者モードの有効化
Questの開発者モードを有効化します。
途中でFacebookアカウントに開発者情報を登録するように言われる場合は手順にしたがって情報を入力します。

[デバイスのセットアップ | Oculus開発者](https://developer.oculus.com/documentation/native/android/mobile-device-setup/?locale=ja_JP#enable-developer-mode)

# 近接センサーとガーディアンの無効化
![quest-vrc-sleep-method_2022-04-23-08-51-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593714/a880b85e-9188-816f-59c1-a8160f60949c.png)


Developer Hubを起動し、`Device Manager`から`Proximity Sensor`と`Guardian`を無効化します。

ただ、この設定だけではAir LinkでVRCが出来ない(有線接続のLinkなら可能)ので`ADB over Wi-Fi`を有効化します。

これでVR睡眠をしても勝手にスリープすることはなくなりましたが、Questを再起動するたびにこの設定をするのは面倒です。
これを自動化する方法は現在調査中ですので進展があれば追記します。

もしうまく設定できない、といった場合は気軽にリプライやDMで質問してください！
[@honahuku_vrc](https://twitter.com/honahuku_vrc)

では、よいVR睡眠ライフを！
Monterey付属のhttpdで、phpのバージョンを仮想ホストごとに設定する

## ことの発端

これまでwindowsのIIS上で、仮想ホストごとに違うバージョンのphpを動かしていました。開発マシンをmacにしたので、こちらでも同じことができないか調べてみました。Montereyはphpが同梱されていないのでbrewで入れることになりますが、brewで入れたphpには署名がされていないためか、付属のhttpdにphpモジュールを組み込むところで弾かれてしまいます。

そこでメモリに組み込むモジュールではなく、TCP/IP経由で処理を投げるphp-fpmを使ってみることにしました。あちこち参考にさせて頂き試したところ、下記の方法でできたので記録として残したいと思います。

## php-fpmの設定

ｂrewで入れたphpにはphp実行サーバとでも言うべきphp-fpmが同梱されており、例えば
brew install php@7.4
で入れた場合、

brew services start php@7.4 (停止はstop)
のコマンドで7.4のphp-fpmがポート9000で起動されます。ちなみに9000は昔はxdebugのデフォルトポートだったので、よくデバッガと干渉します。

ポートは下記のphp-fpm設定ファイル36行名あたりでliste=9000と定義されています。
/usr/local/etc/php/7.4/php-fpm.d/www.conf

そこでこれを9074などに修正し、php@7.4のphp-fpmをポート9074で起動します。

brew services start php@7.4

狙ったポートが待ち受けになっているかは下記で確認します。
lsof -i:9074

## apache2の環境把握

macに付属のhttpdは

実体　/usr/sbin/httpd
設定  /etc/apache2/httpd.cnof
コマンド　/usr/sbin/apachectl

にあります。which httpd 等で確認します。

### httpd.confの設定

/etc/apache2/httpd.confの113行あたり
LoadModule proxy_module libexec/apache2/mod_proxy.so
141行目あたり
LoadModule proxy_fcgi_module libexec/apache2/mod_proxy_fcgi.so
のコメントを外して有効にします。モジュールが組み込まれているかはhttpd -M　で確認できます。

また528行目付近にあるバーチャルホストの設定ファイルを読み込めるようにします。
Include /private/etc/apache2/extra/httpd-vhosts.conf

### httpd-vhosts.confの設定

httpd.confから読み込まれるhttpd-vhosts.confに、仮想ホストと処理するphpを記述します（ここでは省略していますが、port80関係の設定は一応全てコメントアウトしています）。

```httpd.conf:httpd-vhosts.conf
Listen 8080
Define DOCROOT01 "/Users/xxxx/proj/WebPages/VirtualHostTest"
<VirtualHost *:8080>
    ServerName any
    DocumentRoot ${DOCROOT}
    <Directory ${DOCROOT}>
        AddType application/x-httpd-php .php　 #.phpを扱えるようにする。
        Require all granted
        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://127.0.0.1:9074/" #phpならｐｈｐ＠7．4のサーバに投げる
        </FilesMatch>
    </Directory>
</VirtualHost>
```

書き換えたら
sudo apachectl configtest
でコンフィグを確認して、Syntax OKなら
sudo apachectl start
で起動します。これで
/Users/xxxx/proj/WebPages/VirtualHostTest/info.php
のファイルが

http;//localhost:8080/info.php
のURLでphp@7.4処理できるようになりました。

フォルダとphp-fpmのポートの組み合わせを変えることで、ポートごとに処理させるphpを変えることができます。

## 謎な点
/Users/xxxx/Documentsをルートに指定するとForbittenで弾かれてしまいます。ログには
AH00132: file permissions deny server access: /Users/xxx/Documents/index.html
と出ています。Documentsのパーミッションを755にしてもダメだが、/User/xxxx/PhpstormProjectsの下とかだとOKで、原因がよくわからんです。

## 感想とか
dockerとか全盛のいまどき、ビルトインのapahce2を使う需要がどれだけあるかワカランのですが、あまり色々インストールしなくて済むのと、コンフィグもそれほど多くないので暫くこれでいきたいと思っております。
AnimatedSwitcherが動かない！というときの対処法

# 結論
これを
```dart
class _BadWidget extends ConsumerWidget {
  const _BadWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return AnimatedSwitcher(
      duration: const Duration(milliseconds: 100),
      child: Icon(
        ref.watch(_shouldShowDetail)
            ? Icons.keyboard_arrow_up
            : Icons.keyboard_arrow_down,
      ),
    );
  }
}
```
こうする
```dart
class _GoodWidget extends ConsumerWidget {
  const _GoodWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return AnimatedSwitcher(
      duration: const Duration(milliseconds: 100),
      child: ref.watch(_shouldShowDetail)
          ? Icon(
              Icons.keyboard_arrow_up,
              key: UniqueKey(),
            )
          : Icon(
              Icons.keyboard_arrow_down,
              key: UniqueKey(),
            ),
    );
  }
}
```

# 参考
https://api.flutter.dev/flutter/widgets/AnimatedSwitcher-class.html
> If the "new" child is the same widget type and key as the "old" child, but with different parameters, then AnimatedSwitcher will not do a transition between them, since as far as the framework is concerned, they are the same widget and the existing widget can be updated with the new parameters.

要約すると、 **新しいウィジェットが古いウィジェットと同じキーならパラメータ違くても同じWidgetとして認識するからアニメーションしないよ** という感じです。
grub rescue になった時の対策

## grub rescue ##

ブート直後に次のようになりました。

```text
grub rescue>
```

ls, set などを使って、コマンドが使えることを確認します。

```text
grub rescue>ls
```

```text
grub rescue>set
```

insmod が使えることを確認します。

```text
insmod (hd0,msdos1)/boot/grub/i386-pc/echo.mod
echo Hello
```

起動するために次のコマンドを実行しました。

```text
insmod (hd0,msdos1)/boot/grub/i386-pc/normal.mod
error: symbol 'grub_disk_get_size' not found
```

解決方法が分からずギブアップしました。

## usb boot ##

USB でブートしました。

grub-install が使えることを確認

```bash
# which grub-install
```

パーティションをマウント

```bash
# mkdir /mnt/sda1
# mount /dev/sda1 /mnt/sda1
```

grub を修復

```bash
# grub-install --boot-directory=/mnt/sda1/boot /dev/sda
```

ディスクで再起動して、問題の解決を確認
100日後くらいに個人開発するぞ！day005

# 今日はフッターを作ってみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/1624b47d-7885-7743-f30b-57aed54a8bc8.png)

```
- フッターの構造
    - フッターは基本的に<div>でロゴとリストで分けたHTML構造になっている
- 入れ子のセレクタ
    - 入れ子の中にある任意の要素にCSSを反映させる時はclass名と要素名をセレクタにする
        - class名footer-listの<div>内にある<li>要素だけ右寄せにする例：.footer-list li{float:right;}

```
チェックマークをRealmを使って保持する!!

# はじめに
ToDoアプリ等でよく使われる、
TavbleViewを使った、セルをタップするとチェックマークを付ける挙動を付けた所、tableView.reloadData()すると、チェックマークが外れた状態　(セルが選択されていない状態)になってしまいます。

これでは何をチェックしたのか解らないので、本末転倒な結果になります。
なので、tableView.reloadData()してもチェックマーク(セルが選択した状態)を付いた状態にする為に私が実践したやり方を紹介します。

## ロジック(論理,筋道)を考える

### 1.チェックマークを保持する為の変数を定義する
```swift:
 @objc dynamic var checkMark: Bool = false
```
私はセルが選択していない状態をfalse,選択している状態をtrueにする事にしました!!

### 2.変数checkMarkがセルが選択された状態になるとtrue,選択解除されるとfalseになる(保存される)状態を作る

セル選択時のメソッド
```swift:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        try! realm.write {
            list[indexPath.row].checkMark = true
        //listは表示したいセルの配列の名前ですね
        }       
    }
```
セル選択解除時のメソッド
```swift:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        
            try! realm.write {
                list[indexPath.row].checkMark = false
            }
        }
```

RealmStudioではこんな感じで動いてます
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/b7bfec6b-cfe7-e449-b2cb-9c1cdf1d9861.gif)

### 3.TableViewが表示される際に、選択状態だったセルを選択状態にする
```swift:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
        
        cell.textLabel?.text = list[indexPath.row].title
        //チェックマークがtureの時に選択状態にする
        if list[indexPath.row].checkMark == true {
            tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
        //それ以外は非選択状態にする    
        }else {
            tableView.deselectRow(at: indexPath, animated: false)
        }
        return cell
    }
```

これで起動時でもTableViewの更新時でもチェックマークを保持する事が出来ました!!
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/9bc9b9c7-afba-caae-9ac4-9851263fecdb.gif)

以上です!!
2022/4/23主にITとかセキュリティの記事

進化する「Emotet」に対応した感染チェックツール最新版を公開 - JPCERT/CC
https://www.security-next.com/136067

「Java SE」脆弱性の詳細が明らかに - 発見者が影響の大きさ指摘
https://www.security-next.com/136055

「Log4Shell」緩和する「ホットパッチ」にホスト乗っ取りが可能となる脆弱性
https://www.security-next.com/136029

サイバー攻撃の侵入経路、VPN脆弱性の可能性 - 日邦産業
https://www.security-next.com/136076

新型コロナ検査キットに脆弱性 - 検査結果が改ざん可能に
https://www.security-next.com/136035

2022年1Qの脆弱性届け出は176件 - ソフトとウェブともに増加
https://www.security-next.com/136034

ハンモックのIT資産管理製品に脆弱性 - 修正プログラムが公開
https://www.security-next.com/136059

Splunk、今日の企業が直面しているセキュリティの問題について調査した年次グローバル調査レポート「The State of Security 2022〜2022年のセキュリティの現状〜」を発表(4/21)
https://securityinsight.jp/news/13-inbrief/5011-220421-1

取引先にも影響を及ぼすサイバー攻撃(5/19開催)
https://www.sbbit.jp/eventinfo/70414/

“世界最恐マルウェア”「Emotet」、3月の検知数は前月比3倍に　露カスペルスキーが注意喚起(4/21)
https://news.infoseek.co.jp/article/itmedia_bizmakoto_20220421169/?tpgnr=it

クオリティア、新日本空調への2週間で約100件のEmotet攻撃メールを防御(4/21)
https://www.weeklybcn.com/journal/news/detail/20220421_190490.html

KPMGコンサルティング、「サイバーセキュリティ主要課題2022」（日本語版）を発表(4/22)
https://www.jiji.com/sp/article?k=000000030.000088324&g=prt

サイバー攻撃組織が「従業員研修」に用いる４０ギガバイトの動画が発見される(4/21)
https://s.netsecurity.ne.jp/article/2022/04/21/47499.html

過去最大の仮想通貨ハッキングに北朝鮮が関与…新たなサイバー戦争の時代に突入(4/21)
https://www.businessinsider.jp/post-253263

フィッシング詐欺に悪用されるブランド、第2位は国際宅急便「DHL」、第1位は？(4/20)
https://news.mynavi.jp/techplus/article/20220420-2325879/

The Citizen Lab、英政府ネットワークがスパイウェア「Pegasus」に感染と指摘(4/21)
https://www.zaikei.co.jp/article/20220421/669430.html

【ITワード365】DDoS攻撃／デジタルツイン／RISC-V／Twitter Blue／家庭用ローカル5G／5G SA／iSIM(4/21)
https://atmarkit.itmedia.co.jp/ait/spv/2204/21/news017.html

「Java」に署名検証がフリーパスになってしまう危険な脆弱性 ～影響は計り知れず(4/21)
https://forest.watch.impress.co.jp/docs/news/1404535.html

個人の属性情報を連携利用、慶應義塾大学など実証実験で有用性確認(4/21)
https://univ-journal.jp/153249/?show_more=1

Googleドライブでこれだけは知っておきたい「共有」の使い分けと注意点(4/21)
https://www.lifehacker.jp/article/2204google-drive-how-to-use/

SiBANはナイジェリア当局に仮想通貨業界参加者の「悪魔化」をやめるように促す(4/21)
https://nextmoney.jp/?p=49854

「Web3が栄える欧州に」 仮想通貨企業がEU規制当局へビジネス環境整備求める(4/21)
https://jp.cointelegraph.com/news/let-s-build-a-europe-where-web3-can-flourish-crypto-companies-sign-an-open-letter-to-eu-regulators

「ライセンスどおりにしたのに違反？」「バージョンアップでライセンスが変わった！？」(4/21)
https://atmarkit.itmedia.co.jp/ait/spv/2204/21/news007.html

グローバル越境プライバシールール（CBPR）フォーラム設立に向けた宣言をすることに合意しました(4/21)
https://www.meti.go.jp/press/2022/04/20220421001/20220421001.html

やっておくべきパソコンのウイルス対策とおすすめのセキュリティソフト(4/20)
https://news.nifty.com/article/technology/techall/12276-1588306/

サイバー特捜隊発足　「日本式」で国際標準に挑む(4/21)
https://www.nikkei.com/article/DGXZQOCD196JJ0Z10C22A4000000/

Fetch APIがデフォルトで利用できるNode.js v18(4/21)
https://news.mynavi.jp/techplus/article/20220421-2326768/

材料豊富なETH（イーサリアム） アップデート延期もイーサキラーに対する光明あり？【仮想通貨相場】(4/21)
https://jp.cointelegraph.com/news/dmm-bitcoin-market-report-2022-0421

IBMが新メインフレーム発売　店じまいの富士通とは正反対(4/22)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600008/041400111/

ランサムウエア攻撃に遭った徳島・半田病院、被害後に分かった課題とは(4/22)
https://xtech.nikkei.com/atcl/nxt/column/18/01157/041900059/
sshとOpenSSHの違いは？

## 勉強前イメージ

httpとapache的なやつ？
sshできるソフトウェア的なイメージ

## 調査

### ssh とは

Secure Shell の略で、リモートと通信する際に使用されるプロトコルになります。
telnetとは違い、通信が暗号化されるので安全に通信が可能になります。

### OpenSSH とは

sshプロトコルを行うためのオープンソースのソフトウェアになります。
OpenBSDプロジェクトによって開発が行われています。
OpenSSHはサーバとクライアント、両方の昨日を持っており、
またUnix/Linux OS でデフォルトでインストールされています。
最新バージョンは9です。

### OpenSSH以外のソフトウェアってあるの？

Apache MINA/SSHD というのがあるそうです。
Javaでネットワークアプリケーションを構築するフレームワークライブラリですが、
サブプロジェクトとしてSSHDプロジェクトがあるそうです。

また、他にも有償の商用ソフトウェアはいくつかあるそうですが、
基本的にはOpenSSH一択のような感じがしています。

### ssh と OpenSSH の違い

- ssh → プロトコル
- OpenSSH → sshプロトコルを使用するためのソフトウェア

## 勉強後イメージ

なんか大体知ってたけど、調べてなかった。
OpenSSH強い・・

## 参考

- [SSHとは？仕組みとSSHサーバーの設定をわかりやすく解説します！](https://www.kagoya.jp/howto/it-glossary/server/ssh/)
- [SSHソフトウェア(サーバ/クライアント)の一覧](https://weblabo.oscasierra.net/ssh-software/)
- [OpenSSH](https://www.openssh.com/)
典型90問010 Score Sum Queriesで解く！

# はじめに
AtCoder現在茶色(年内には緑が目標！）のあんこちゃん(@Chunky_RBP_chan)です。\
典型問題は抑えとかねばということで、★2〜★5に取り組んでいます。\
Pythonで取り組まれている方も多いと思うので自分の解答をシェアしたいと思います！

# 問題
https://atcoder.jp/contests/typical90/tasks/typical90_j

# 解法
学籍番号ごとに各組の累積和を持っておきます。
あとは各jについて(R_jまでの和)-(L_jまでの和)を行えばよいです。


```python
N = int(input())
Point = [[0]*(N+1) for _ in range(2)]
for i in range(N):
    c,p = map(int, input().split())
    Point[c-1][i+1] = Point[c-1][i]+p
    if c == 2:
        Point[0][i+1] = Point[0][i]
    else:
        Point[1][i+1] = Point[1][i]
Q = int(input())
for _ in range(Q):
    l,r = map(int, input().split())
    print(Point[0][r]-Point[0][l-1],Point[1][r]-Point[1][l-1])
Loguruでライブラリのログを出力する

[Pythonのライブラリが出力するログを活用しよう](https://www.rhoboro.com/2020/12/29/logging-and-debug.html)
をloguruでやる方法



# logging版

```py:a.py
import requests
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())

try:
    requests.get("https://expired-rsa-dv.ssl.com/")
except requests.exceptions.SSLError:
    logger.info("SSLError")
```

```
$ python3 a.py
Starting new HTTPS connection (1): expired-rsa-dv.ssl.com:443
SSLError
```


# loguru版

[Want to intercept standard logging messages toward your Loguru sinks?](https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging)
[Standard library logging plus loguru](https://stackoverflow.com/questions/65329555/standard-library-logging-plus-loguru)

```py:b.py
import requests
from loguru import logger
import logging

class InterceptHandler(logging.Handler):
    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 2
        while frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0)

try:
    requests.get("https://expired-rsa-dv.ssl.com/")
except requests.exceptions.SSLError:
    logger.info("SSLError")
```

```
$ python3 b.py
2022-04-23 02:59:17.605 | DEBUG    | urllib3.connectionpool:_new_conn:1005 - Starting new HTTPS connection (1): expired-rsa-dv.ssl.com:443
2022-04-23 02:59:18.125 | INFO     | __main__:<module>:27 - SSLError
```
【検証】PHPのrequireにスコープ？

こちらの記事でrequireについて検証しました。

https://qiita.com/4U5zo/items/7ee8114a94d7d410037a

その際コメントでrequireにもスコープがあって必ずしも一度宣言すればよいわけではないとご指摘を頂きました。ご指摘いただけると学習になるので本当に助かります！！
今回は続編としてrequireのスコープについて検証します。

いきなりですが公式ドキュメントの文章を引用します。
>ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。 呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。 しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。
https://www.php.net/manual/ja/function.include.php

初見ではなかなか悩ましい文章でした。
実行された行のスコープを継承しますと言いつつグローバルスコープとなります？？ってなりますが今回の検証を終えればやっと公式の言いたいことが少しわかるかと思います！
では準備に取り掛かりましょう。材料はたったの2つ！(webサーバは前提というあるある)

# 材料
材料となるファイルはすべてwebサーバの同じディレクトリの中に格納してください。

一つ目はただクラスと変数が定義してあるだけの読み込み用のファイルです。
```php:YomikomiFile.php
<?php
//読込み用ファイル
$a = 100;
class a{}
```
二つ目はブラウザでアクセスするファイルです。
htmlのh1タグで3つの変数を表示するプログラムです。可読性のためにソースの中にコメントとして何を目的としているのか記載します。
```php:ReqScopeStart.php
<?php

function a()
{
    //変数とクラスを含んでいるファイルです。変数はクラスの外に$aとして定義してあります。
    require 'YomikomiFile.php';
    //ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。
    //すなわち関数の中のでrequireしたので関数内だけのローカルスコープになります。
    //requireがローカルスコープなので同じ関数からならアクセスできるはずということでYomikomiFile.phpの$aにアクセスしています。
    return $a;
}
//$rsltは関数の外にいるため関数から間接的に値を貰います。
//$rsltが表示出来たら、関数の中でrequireされたファイルであれば同じ関数の中からアクセスできることが証明されます。
$rslt = a();
//読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。
//つまりYomikomiFile.phpで定義されているaクラスもグローバルスコープだから問題なくインスタンス化できるはず
$class = new a;
?>

<html>
<h1>
    <?php 
    //問題なく表示されればクラスはグローバルスコープとして使えることが証明される。
    var_dump($class); 
    ?>
</h1>
<h1>
    <?php
    //問題なく表示されれば関数の中でrequireされたファイルであれば同じ関数の中からアクセスできることが証明される
    var_dump($rslt);
    ?>
</h1>
<h1>
    <?php
    //これはグローバルスコープになるクラスでも関数でもないし、
    //関数内のローカルスコープも及ばないので公式曰くエラーになることが仕様となる
    var_dump($a);
    ?>
</h1>
</html>
```



# 実験
材料が用意出来たらブラウザからReqScopeStart.phpにアクセスしてみましょう！
うまくいけばブラウザに下記が表示されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626978/b00ed34d-96aa-584b-1585-42e9721ad2ff.png)


# 検証
改めて公式の文章を見てみましょう！
>ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。 呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。 しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。
https://www.php.net/manual/ja/function.include.php

一行ずつ違うこと説明してたんですね。解釈しやすい順にみていきましょう。

> しかし、読み込まれたファイル内で定義されている関数やクラスはすべて グローバルスコープとなります。

これは関数の中や関数の外やらどこでファイルが読み込まれようと、一貫して読み込まれたファイル内で定義しているクラスや関数はグローバルスコープになるという意味のようです。
実際に実験結果もクラスにはアクセスできたけど変数にはアクセスできませんでした。

>呼び出し側の行で利用可能である全ての変数は、読み込まれたファイル内で利用可能です。

呼び出したファイルの変数を呼び出されたファイルが使うことができます。実際呼び出された側のファイルで使えることを確認はできましたがルールまではまだ理解できていません。これは今回扱っていないので機会があればまた調べたいところです。

>ファイルが読み込まれるとそのファイルに含まれるコードは、 includeもしくはrequireが実行された 行の変数スコープを継承します。

この文章が本当に悩ましかったです。今も6割くらいしか理解できていない気がしますが実験は成功したので安心しました。
関数とクラスに関しては常にグローバルスコープなのでスコープをそれほど意識する必要はないように感じましたが、クラスや関数に含まれていない変数についてはrequire呼び出し行のスコープが適応されるのでそこだけ注意ということかと思います。
今回の実験ではYomikomiFile.phpの$aが関数でもクラスでもなかったためrequire呼び出し行のスコープ、すなわち関数の中だけのローカルスコープが適用されていました。なので関数外からアクセスしようとしてもできなかったということになります。

# 最後に
なるべく正確な情報を発信できるように心がけておりますが間違えた情報を発信していることもあるかと思います。
そういう時はコメントでご指摘いただけますと幸いです！
どうぞ宜しくお願い致します。
【OpenWeatherAPI】リクエスト・レスポンスの項目に関するメモ書き

## 概要
天気の情報を取得できるAPIとして、けっこう挙がるのが[OpenWeatherAPI](https://openweathermap.org/api)でしょう。無料枠もあるので試しに使ってみたのですが、レスポンス項目について調べないとピンとこないのがあったので、今回メモ書きします。

## 前提
* 今回使用するAPIは無料プランで使える`3-hour Forecast 5 days`です。無料プランで使えるAPIは[こちら](https://openweathermap.org/full-price)を参照ください。（おそらく他のAPIもほぼ同様の形式だと思いますが）
* `3-hour Forecast 5 days`のAPIの仕様については、[こちら](https://openweathermap.org/forecast5)のドキュメントを参照ください。
* 前提とするAPIの仕様について、2022年4月時点のものとします。
* APIのメモ書きについて、主に使われそうな項目をピックアップして取り上げます。（全項目は触れません）
* API　送信時に使用する`appid`の取得については、[世界の天気API「OpenWeatherMap」の無料APIキー発行・取得、リクエスト方法](https://auto-worker.com/blog/?p=1612)の記事を参照ください。

## メモ書き

### ＜リクエスト＞
リクエスト項目で主に指定するのは`appid`、`lat(緯度)`、`lon(経度)`、`units（単位）`だと思います。
unitsの詳細については[こちら](https://openweathermap.org/forecast5#data)で解説されてます。基本的には気温の単位を設定するものになっていて、日本では摂氏での表記が一般的だと思うので`metric`を指定すれば良いと思います。
というわけで、リクエストのURLは以下の通りに投げれば、ほぼほぼ問題ないかなと思います。
```
https://api.openweathermap.org/data/2.5/forecast?lat=35.6806429&lon=139.7599219&appid=xxxxxxxxxxxxxxxx&units=metric
```

### ＜レスポンス＞
上記のURLでリクエストを投げると、以下のようなレスポンスが得られると思います。
```json
{
  "cod": "200",
  "message": 0,
  "cnt": 40,
  "list": [
    {
      "dt": 1650790800,
      "main": {
        "temp": 17.04,
        "feels_like": 16.39,
        "temp_min": 17.04,
        "temp_max": 17.04,
        "pressure": 1014,
        "sea_level": 1014,
        "grnd_level": 1013,
        "humidity": 61,
        "temp_kf": 0
      },
      "weather": [
        {
          "id": 500,
          "main": "Rain",
          "description": "light rain",
          "icon": "10d"
        }
      ],
      "clouds": { "all": 100 },
      "wind": { "speed": 2.46, "deg": 15, "gust": 2.72 },
      "visibility": 10000,
      "pop": 0.54,
      "rain": { "3h": 0.2 },
      "sys": { "pod": "d" },
      "dt_txt": "2022-04-24 09:00:00"
    },
    ・
    ・
    ・
  ]
}
```

ざっくりと項目毎に内容を以下で補足します。

**【天気】**
`weather`項目に入ってるのが天気の情報です。`main`項目にざっくりとした天気の文字が入っています。`id`と`icon`の意味合いについては、[Weather condition codes](https://openweathermap.org/weather-conditions)のドキュメントを参照ください。
**【日時】**
`dt`項目にUnixtimeが入っています。一応、`dt_txt`でテキスト形式の項目もありますが、上記のリクエスト形式で投げるとUTCで返ってきます。

**【気温】**
`temp（気温）`、`feels_like（体感気温）`、`temp_min（最低気温）`、`temp_max（最高気温）`が摂氏で取得できます。

**【気圧】**
`pressure（気圧）`、`sea_level（海面気圧）`、`grnd_level（地点気圧）`がヘクトパスカル（hpa）の単位で取得できます。気圧の詳細については[気圧と高さ・高度の関係【気象予報士が解説】](https://zutool.jp/column/glossary/pressure_altitude)を参照頂きたいのですが、基本的に`pressure`には`sea_level`が設定されるようです。

**【湿度】**
`humidity`の項目でにて、%表記で取得できます。

**【雲】**
`clouds`の項目で、雲が覆われてる度合いが%表記で取得できます。

**【降水量】**
天気が`Rain`の時だけ、降水量が`rain`の項目で取得できます。3時間単位でミリメートルで設定されます。

**【風】**
`wind`の項目にて、`speed（風速）`、`deg（方位角）`、`gust（最大瞬間風速）`が取得できます。風速の単位はメートル/秒になります。方位角の詳細については[方位角･仰角･偏波角の解説](http://www.satellite.co.jp/houikaku-gyoukaku.html)を参照ください。
【React / Next】onClickがクリックしなくても描画時に実行されてしまう

onClickイベントに引数のある関数をセットしていたところ、クリックをしていないのに、描画時に実行されてしまうケースを経験したので、その解決方法の議事録です。

# 結論
公式に記載がありました。

https://ja.reactjs.org/docs/faq-functions.html#why-is-my-function-being-called-every-time-the-component-renders

- `onClick={someFunc}` のように()を使わない
- `onClick={() => someFunc(arg)}` のように関数でラップする

# NGコード
```tsx:親
export const Parent = () => {
	const handleClick(id: UUID) {
		//
	}

	return (
		<Children handleClick={handleClick} />
	)
}
```

```tsx:子
interface Props {
	handleClick: Function;
}

export const Children = (props: Props) => {
	// functionを()で実行してしまう
	return (
		<Button onClick={props.handleClick(id)}>Click</Button>
	)
}
```

# OKコード
```tsx:親
export const Parent = () => {
	const handleClick(id: UUID) {
		//
	}

	return (
		<Children handleClick={handleClick} />
	)
}
```

```tsx:子
interface Props {
	handleClick: Function;
}

export const Children = (props: Props) => {
	return (
		<Button onClick={() => props.handleClick(id)}>Click</Button>
	)
}
```

# 文献
https://ja.reactjs.org/docs/faq-functions.html#why-is-my-function-being-called-every-time-the-component-renders

https://gist.github.com/webgyo/da195e126195955f050730830fd3c053
【React / Next】親から関数をpropsで子へ渡したら「is not assignable to type ts(2322)」の型エラーがでた

親コンポーネントで定義した関数を子コンポーネントへ渡す時に、型エラーが出たのでその解決方法の議事録です。

# 環境
- next: 11.1.3
- react: 17.0.2

# やろうとしたこと
- 親コンポーネント側で、子コンポーネントのボタンがクリックされた時の関数を定義
- 関数を子コンポーネントへpropsで渡す


```tsx:親
export const Parent = () => {
	const handleClick() {
		//
	}

	return (
		<Children handleClick={handleClick} />
	)
}
```

```tsx:子
interface Props {
	handleClick: Function;
}

export const Children = (props: Props) => {
	return (
		<Button onClick={props.handleClick}>Click</Button>
	)
}
```

# エラーメッセージ
```
(property) onClick?: MouseEventHandler<HTMLButtonElement> | undefined
Type 'Function' is not assignable to type 'MouseEventHandler<HTMLButtonElement>'.

Type 'Function' provides no match for the signature '(event: MouseEvent<HTMLButtonElement, MouseEvent>): void'.ts(2322)
index.d.ts(1451, 9): The expected type comes from property 'onClick' which is declared here on type 'IntrinsicAttributes & Children'
```

# 解決方法
- `onClick={() => handleClick}` のように関数でラップする
- 引数ありでもこれでOK

```tsx:子
interface Props {
	handleClick: Function;
}

export const Children = (props: Props) => {
	return (
		<Button onClick={() => props.handleClick}>Click</Button>
	)
}
```

## 関数の引数があるパターン
```tsx:親
export const Parent = () => {
	const handleClick(id: UUID) {
		//
	}

	return (
		<Children handleClick={handleClick} />
	)
}
```

```tsx:子
interface Props {
  handleClick: Function;
}

export const Children = (props: Props) => {
  return (
    <>
      {users.map((user) => {
        <Button onClick={() => props.handleClick(user.id)}>Click</Button>;
      })}
    </>
  );
};
```

## 型をきっちり記述するパターン
```tsx:親
export const Parent = () => {
	const handleClick(id: UUID) {
		//
	}

	return (
		<Children handleClick={handleClick} />
	)
}
```

```tsx:子
interface Props {
  handleClick: (_id: UUID) => void;
}

export const Children = (props: Props) => {
  return (
    <>
      {users.map((user) => {
        <Button onClick={() => props.handleClick(user.id)}>Click</Button>;
      })}
    </>
  );
};
```

# 文献
https://stackoverflow.com/questions/51977823/type-void-is-not-assignable-to-type-event-mouseeventhtmlinputelement

https://awesome-linus.com/2020/01/22/react-is-not-assignable-to-typets2322-error/

https://awesome-linus.com/2020/01/10/react-props-function-type/
Rails+docker環境構築でyarnが上手くインストールできない

## 概要
Rails6系とdockerで環境構築する際に詰まったので、その原因と解決方法についてを書いています。

## 事象
- dockerfileを使って、docker環境にRailsサーバを立てようとした。
- その際、Railsを使う際の環境要件としてYarnが必要となるが、上手くインストールできなかった。

webpackerをインストールしようとすると...
```
RUN bundle install && rails webpacker:install
```
バージョン1以上2以下のyarnが必要ですという下記エラーが発生。
```
Webpacker requires Yarn ">=1 <2"
```

apt-get installでインストール済みと想定したが、上記エラーにより上手く入っていないことが分かった。
```
RUN apt-get install -y yarn
```
## 原因
- yarnのバージョンが古い
エラー文の内容をヒントにして原因をググってみたところ、yarnのバージョンが古いと今回のようなエラーが発生するそう。

## 解決方法
- 古いバージョンのyarnを一度削除して、最新のパッケージを取得・参照するリポジトリ設定を追加。
- 再度yarnをインストールする。 

```
# デフォルトでインストールされているcmdtestを削除
apt remove cmdtest
# 古いバージョンのyarnを削除
apt remove yarn
```
```:Dockerfile
# 最新パッケージの取得と、パッケージインストール時のリポジトリ設定を追記
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update && apt-get install -y yarn
```

### 参考
https://k-koh.hatenablog.com/entry/2020/04/02/143017

https://zenn.dev/shibata/articles/2e6c7345b57b3e

https://github.com/yarnpkg/yarn/issues/2821

https://classic.yarnpkg.com/en/docs/install/#debian-stable
> On Debian or Ubuntu Linux, you can install Yarn via our Debian package repository. You will first need to configure the repository:
- 今回は、Rails6系+Ruby3.0を使用したため、LinuxOS情報を確認しました。
- yarnをインストールするOS環境がDebianだと分かったので、Yarn公式サイトの該当ページを参考にしてみました。
```
# cat /etc/issue
Debian GNU/Linux 11 \n \l
```

## 最後に
Yarn公式サイトを読んでみると、ちゃんとインストール手順やエラー発生時の対処方法が記載されていました...
とりあえずapt-getでインストールしたため、今回のエラーが発生してしまったので、まずは公式ドキュメントを読む癖をつけようとしみじみ感じました。。
EC2のキーペア ssh接続の際の権限エラーの解決方法

# 目次

* 初めに
* 環境
* 経緯
* エラーの対処
* 参考文献


# 1. 初めに
* こちらの記事はEC2インスタンスにssh接続をしようと際に吐いたエラーの対処になります。
* EC2初心者の方向けの記事兼自分のエラー対処の記録となります。


# 2. 環境
Mac OS Monterey 12.2

# 3. 経緯

* チーム開発の際、EC2のプライベートキー(pemファイル)をslackで貰い、ローカルに保存し、
ssh接続で"ssh -I [pemファイルのパス].pem [接続先のURL]"で接続を試みると、、、

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '[pemファイルのパス].pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
```
#### え？開きすぎって何？

って思いました。その後の文を読んでみると、、

#### 秘密鍵やのに誰でもアクセスできるやん

って書いてました(⌒-⌒; )

# 4. エラー対処

要するに誰でもアクセスできるということは権限が甘いってこと

```
chmod 600 xxx.pem
```

によって権限変更可能です。
所有者のみ読み書き可能の設定にしました。

600がどういう意味か大変わかりやすい[記事](https://www.server-memo.net/tips/command/chmod/chmod.html)を見つけたので
ご参照ください。

# 5.参考文献

https://www.server-memo.net/tips/command/chmod/chmod.html
プロデルで「千反田える」

昨日4月22日は、TVアニメ「氷菓」放送10周年だったそうです。

# 「一反田えー」から「千反田える」までを出力する

[日本語プログラミング言語「プロデル」](https://rdr.utopiat.net/)で「一反田えー」から「千反田える」までを出力するプログラムを放送当時、作っていたことを思い出したので投稿してみました。

「一反田」から「千反田」まで、つまり一から千まで値をカウントしていき、
一方で「えー」(A),「びー」(B),「しー」(C),...,「ぜっど」(Z),「えー」,...とループしていきます。
そして、1000までカウントしたときに、本当に「千反田える」になるでしょうか。

## プログラム

変数名には作品に関係するキーワードを入れてみました。

```
カンヤ祭は、｛「えー」,「びー」,「しー」,「でぃー」,「いー」,「えふ」,「じー」,「えいち」,「あい」,「じぇい」,「けー」,「える」,「えむ」,「えぬ」,「おー」,「ぴー」,「きゅー」,「あーる」,「えす」,「てぃー」,「ゆー」,「だぶりゅ」,「えっくす」,「わい」,「ぜっど」｝
部数を1から1000まで増やしながら繰り返す
	部数を売り切ったもの&「反田」&カンヤ祭（部数-1を26で割った余り+1）を報告する
繰り返し終わり

[氷菓]を、売り切るための手順
	古典部は、｛「」，「十」，「百」，「千」｝
	神山高校は、｛「」，「」，「二」，「三」，「四」，「五」，「六」，「七」，「八」，「九」｝
	奉太郎を空にする
	里志を1にする
	氷菓が1以上の間繰り返す
		入須を古典部の（里志）番目にする
		里志を増やす
		摩耶花は、氷菓を10で割った剰り
		もし摩耶花が0なら、入須は、「」
		奉太郎は、神山高校（摩耶花+1）&入須&奉太郎
		もし奉太郎の文字数が0かつ奉太郎の文字数が0奉太郎の文字数が0奉太郎の文字数が0奉太郎の文字数が0氷菓が1なら、奉太郎を「一」にする
		氷菓を10で割ったものを切り捨てして氷菓とする
	繰り返し終わり
	奉太郎を返す
終わり
```

## 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/370e1837-3dee-40c8-be96-3e9661d3db33.png)
AWS Certified Solutions Architect - Professional(SAP)取得のための勉強方法と試験前に心がけたこと

# はじめに
以下のAWS認定資格を取得しました。

* AWS 認定 クラウドプラクティショナー（CLF）
* AWS 認定ソリューションアーキテクト – アソシエイト（SAA）
* AWS 認定ソリューションアーキテクト – プロフェッショナル（SAP-C01）

本記事では、SAP取得までの約2ヶ月間本気で取組んだ<font color="LimeGreen">**勉強方法**</font>と試験時に<font color="LimeGreen">**パフォーマンスを最大限発揮するために心がけたこと**</font>についてご紹介します。
恥ずかしながら1回落ちたんですが、2回目で合格するために**心がけた教訓**をまとめております。
皆様のお役に立てば幸いです。

:::note warn
「これで絶対合格できる！」といった保証はできませんので参考程度に見ていただければと。。
:::

:::note warn
AWS認定試験の規約により試験内容の情報公開はNGとなっているため、試験内容については一切触れません
:::


# SAP試験対策

### １．SAP試験ガイドを確認すべし！

まずは、出題分野/比率を把握しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611811/359c3dc8-bfdf-f33c-0a71-88f5176a6979.png)
参照：[SAP試験ガイドPDF](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-pro/AWS-Certified-Solutions-Architect-Professional_Exam-Guide.pdf)




これ。意外に重要で、テスト前の時間がないときにどの分野を重点的に勉強すればよいかの判断材料になります。
また、各分野でどういった問題が出そうかの予想もできます。

例えば、「第2分野：新しいソリューションの設計」が一番比率が高い(31%)です。
概要を見ると信頼性や継続性のワードがあります。2021年3月の大阪リージョン開設や現在も新リージョン準備中という状況であることから、
マルチリージョンのDR対応についての問題がいくつか出ると予想しました。

### ２．SAP対策本をひたすら解きまくるべし！
私は2冊の本を何周もひたすら解きまくりました。
2冊とも全内容全問題を完璧に理解するまでひたすらです。

https://www.google.com/aclk?sa=L&ai=DChcSEwiG496J_pn3AhVOxJYKHXtpBS8YABAIGgJ0bA&ae=2&sig=AOD64_0tAcE1vtdKdti7eYZ4KUzOgXxVVA&ctype=5&q=&ved=2ahUKEwjN0teJ_pn3AhWAwosBHfJQCmIQ9aACegQIAhBN&adurl=


https://www.google.com/aclk?sa=L&ai=DChcSEwiG496J_pn3AhVOxJYKHXtpBS8YABANGgJ0bA&ae=2&sig=AOD64_3Vd1_JxreN16dogcKsISvHkxqGhw&ctype=5&q=&ved=2ahUKEwjN0teJ_pn3AhWAwosBHfJQCmIQ9aACegQIAhBF&adurl=


### ３．SAP模擬試験をひたすら解きまくるべし！
以前まで有料だった模擬試験が2021年11月から無料で受験できるようになったので、
２．に引き続きこちらも何度もひたすら解きまくりました。
こちらは問題数が20問と少なく、完璧になるまでそこまで時間はかかりませんでした。

https://dev.classmethod.jp/articles/new-aws-official-practice-questions/



対策本は問題数が多く、1周するのに時間がかかりますが、
慣れると1日で「2冊＋模擬試験」を対応できるようになります。

これら２,３を2週間みっちり取り組めば相当自信がつきます！

試しにSAP取得後、Udemy(買っただけでやってない)をやってみましたが、
1発で正解率80%超えだったので、知識としてはだいぶ身についていると思います。


# 試験時にパフォーマンス発揮するために心がけたこと
きっちり事前対策を行っても、試験中に集中が途切れると本末転倒です。
SAPはCLF/SAAと違い問題数が多くかつ、難易度も上がります。
(問題内容を把握するのに手こずりました)

180分で75問（<font color="LimeGreen">**1問あたり約2.4分**</font>ペースで)解く必要があり、
集中力がカギとなります。

試験時にパフォーマンスを最大限発揮するために、
私が心がけたことをまとめます。


>* 試験は午後一にする
>* 試験会場は家ではなくテストセンターで受験する
>* テストセンターはきれいなところで受験する
>* 昼食は抜いて朝食をガッツリ食べる
>* カフェインは朝食時に飲む
>* 試験直前まで糖分を大量摂取
>* ウォームアップをする（模擬テスト1回分[75問]）


# 最後に
実は今回、会社の昇格がかかっており評価期間までの残２ヶ月で必死で取得したという背景があります。
時間に余裕がある方は、より多くの問題や情報に触れることをオススメします。

次は、AWS Certified Advanced Networking - Specialty(ANS-C00)をチャレンジする予定です。

取得できたらまたこういった記事を投稿しようと思います。
その際も宜しくお願いします！
[覚書]Dockerコンテナ上のUbuntuでsudoコマンドが使いたい

## 経緯
Dockerコンテナを仮想環境として使おうと思いsudoコマンドを使おうとしたら怒られたので解決法をメモしておく.

```:CMD
root@hogehoge $ sudo
bash: sudo:command not found
```

## 解決
```:CMD
root@hogehoge $ apt-get update

root@hogehoge $ apt-get -y install sudo

root@hogehoge $ sudo
usage: sudo -h | -K | -k | -V
...
```
これで使えるようになりました. やったぁ

## おまけ
Dockerfileも作ってみたけど

```Dockerfile:Dockerfile
FROM ubuntu:12.04

RUN apt-get update && apt-get install -y sudo

USER docker
CMD /bin/bash
```

これだとなぜかエラーが出る.
```
...> Docker build <filepath>
(中略)
-----
executor failed running [/bin/sh -c apt-get update && apt-get install -y sudo]: exit code: 100
```
毎回手作業でインストールするのは面倒くさいのでイメージ化したかったけどできなかったとさ.  
## 参考にしたサイト
[How to use sudo inside a docker container?](https://stackoverflow.com/questions/25845538/how-to-use-sudo-inside-a-docker-container)
## 小言
~~なんでデフォルトで使えないんですか？？？~~
MacのPython環境構築で3系にならないときの解決方法

先日、ふとAIをやってみたいと思い立ち、Pythonの環境構築を行ったのだが、手順通りにやったはずなのに、Pythonのバージョンが変わらない。
__Python2.7.16__ から __Python3.10.2__ にしたいのに、なんでか変更されない。。。。。。

## 環境
PC：Mac
Version：BigSur
shell：bash
　 →bashかzshでインストール方法が若干変わるみたい。私はbashだったので、ここではbashの場合の解決方法

## やりたいこと
Macには初期でPythonがインストールされているが、
__Python2.7.16__ であるため、最新の __Python3.10.2__ をインストール、メインバージョンとしたい

## インストール手順
インストールは以下サイトを参考に実施した
参照：[Pythonの開発環境を用意しよう！（Mac）](https://prog-8.com/docs/python-env)

## 現状
インストールを手順通りに実施した後に、適用バージョンを確認したところ、
期待値としては

```
$ python --version
Python 3.10.2
```

となって欲しいのだが、
実際には

```
$ python --version
Python 2.7.16
```

と、インストールした最新バージョンが適用されていない状態である。

## 解決方法
##### 1.まずは以下コマンドを実行し、「.pyenv」ディレクトリ内を確認確認する

```
$ ls ~/.pyenv
plugins		shims		version		versions
```
※ 「.pyenv」ディレクトリは隠しファイルとなっているので、Finderで確認したい場合は`Shift + alt + .`コマンドをFinder上で実行することで表示されるようになる

##### 2.原因判明
「.pyenv」ディレクトリ内を確認すると、「bin」ディレクトリが存在していない。
インストール手順内で「.bash_profile」を書き換えpyenvの設定を変更したが、そのうちのコマンドで「bin」ディレクトリを指定しているコマンドがあった。

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile    ←これ
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

これが原因か！
__ここのパスの指定を「bin」→「shims」に変更してあげる__

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/shims:$PATH"' >> ~/.bash_profile    ←ここ
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

##### 3.確認
以下コマンドで「.bash_profile」の変更を適用する
※これ重要。.bash_profileを変更した都度やる

```
$ source ~/.bash_profile
```

そしたら、再度Pythonのバージョンを確認する

```
python --version
Python 3.10.2
```

変わった！！！！！！！！

## おわりに
やっぱり環境構築が一番いやだわ〜
絶対なにかしらのエラーがでて、数日格闘することになる。
今回も一度諦めて、数週間たったあとに再チャレンジしてやっと解決することができた。
思い立ったときが一番熱入ってるのに、環境構築で冷めちゃうよね。

簡単にでしたが、同じようなエラーに躓いている人たちの参考になれば幸いです。
（無限積÷無限積）が対数となる場合

二次式

```math:
x^2 - y^2 = \left( x + y \right) \left( x - y \right)
```

から

```math:
\begin{eqnarray}
a - b
 & = & \left( \sqrt{a} + \sqrt{b} \right) \left( \sqrt{a} - \sqrt{b} \right)  \\
 & = & \left( a ^ \frac{1}{2} + b ^ \frac{1}{2} \right) \left( a ^ \frac{1}{2} - b ^ \frac{1}{2} \right) \\
 & = & \left( a ^ \frac{1}{2} + b ^ \frac{1}{2} \right) \left( a ^ \frac{1}{4} + b ^ \frac{1}{4} \right) \left( a ^ \frac{1}{4} - b ^ \frac{1}{4} \right) \\
 & = & \left( a ^ \frac{1}{2} + b ^ \frac{1}{2} \right) \left( a ^ \frac{1}{4} + b ^ \frac{1}{4} \right) \left( a ^ \frac{1}{8} + b ^ \frac{1}{8} \right) \left( a ^ \frac{1}{8} - b ^ \frac{1}{8} \right) \\
 & & \cdots \\
 & = & \left( a ^ \frac{1}{2} + b ^ \frac{1}{2} \right) \left( a ^ \frac{1}{4} + b ^ \frac{1}{4} \right) \left( a ^ \frac{1}{8} + b ^ \frac{1}{8} \right) \cdots \left( a ^ {2^{-n}} + b ^ {2^{-n}} \right) \left( a ^ {2^{-n}} - b ^ {2^{-n}} \right) \\
 & = & \left( a ^ {2^{-n}} - b ^ {2^{-n}} \right) \prod_{k=1}^{n} \left( a ^ {2^{-k}} + b ^ {2^{-k}} \right) \\
\frac{ a - b }{ a ^ {2^{-n}} - b ^ {2^{-n}} } & = & \prod_{k=1}^{n} \left( a ^ {2^{-k}} + b ^ {2^{-k}} \right) \\
\end{eqnarray}
```

を考えます。すると

```math:
\begin{eqnarray}
\frac{ s - t }{ u - v }
 & = & \frac
 { s ^ {2^{-n}} - t ^ {2^{-n}} }
 { u ^ {2^{-n}} - v ^ {2^{-n}} }
 \cdot \frac
 { \prod_{k=1}^{n} \left( s ^ {2^{-k}} + t ^ {2^{-k}} \right) }
 { \prod_{k=1}^{n} \left( u ^ {2^{-k}} + v ^ {2^{-k}} \right) }
\end{eqnarray}
```

も考えることができます。式の一部

```math:
\frac
 { s ^ {2^{-n}} - t ^ {2^{-n}} }
 { u ^ {2^{-n}} - v ^ {2^{-n}} }
```

を $n \to  \infty$ の極限として Mathematica 様に喰わせると

```math:
\lim_{n \to \infty} \frac{ s ^ {2^{-n}} - t ^ {2^{-n}} }{ u ^ {2^{-n}} - v ^ {2^{-n}} } = \frac{ \log s - \log t }{ \log u - \log v } = \frac{ \log \frac{s}{t} }{ { \log \frac{u}{v} }} = \log_{\frac{u}{v}} \frac{s}{t}
```

を求めてくれました。よって

```math:
\begin{eqnarray}
\frac
 { \prod_{k=1}^{\infty} \left( s ^ {2^{-k}} + t ^ {2^{-k}} \right) }
 { \prod_{k=1}^{\infty} \left( u ^ {2^{-k}} + v ^ {2^{-k}} \right) }
 & = & \frac{ s - t }{ u - v } \cdot \frac{ \log u - \log v }{ \log s - \log t } \\
 & = & \frac{ s - t }{ u - v } \cdot \frac{ \log \frac{u}{v} }{ \log \frac{s}{t} } \\
 & = & \frac{ s - t }{ u - v } \cdot \log_\frac{s}{t} \frac{u}{v} \\
 & = & \log_\frac{s}{t} \left( \frac{u}{v} \right)^{ \frac{ s - t }{ u - v } }  \\
\end{eqnarray}
```

となるようです。
Ubuntu 21.10 から 22.04 へのアップグレードの仕方

# 1. まず現在の Ubuntu 21.10 を最新状態にします。
```
$ sudo apt update 
$ sudo apt full-upgrade
```

# 2. 次に不要物を全消しします
```
$ sudo apt autoremove
```

# 3. 更新の設定をします。
`/etc/update-manager/release-upgrades` を開いて、`Prompt`を`lts`に設定します。

```
# Default behavior for the release upgrader.

[DEFAULT]
# Default prompting behavior, valid options:
#
#  never  - Never check for a new release.
#  normal - Check to see if a new release is available.  If more than one new
#           release is found, the release upgrader will attempt to upgrade to
#           the release that immediately succeeds the currently-running
#           release.
#  lts    - Check to see if a new LTS release is available.  The upgrader
#           will attempt to upgrade to the first LTS release available after
#           the currently-running one.  Note that this option should not be
#           used if the currently-running release is not itself an LTS
#           release, since in that case the upgrader won't be able to
#           determine if a newer release is available.
Prompt=lts
```

# 4. 最後に 22.04 へのアップグレードを実行します。
```
$ sudo do-release-upgrade -d
```
いつも通り数時間、時間がかかりますので、余裕をもって作業してください。

お疲れさまでした。
【Rails】マイグレーションコマンド

コマンド

「bundle exec rails」は「bin/rails」でもOK

# 新規モデル作成
```
bundle exec rails g model モデル名 カラム名1:型 カラム名2:型
```

例えば「nameというstringのカラムだけを持つuserモデル」を作成する場合↓
```
bundle exec rails g model user name:string
```
これだけで下記ファイルを自動生成してくれる
```
      create    db/migrate/20220422143603_create_users.rb
      create    app/models/user.rb
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
```

気になるマイグレファイルの作成結果
```db/migrate/20220422143603_create_users.rb
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :name

      t.timestamps
    end
  end
end
```

# マイグレーションを適用する
```
bundle exec rails db:migrate
```
# 適用済みマイグレーションを確認
```
bundle exec rails db:migrate:status
```
# マイグレーションを1つ戻す
```
bundle exec rails db:rollback
```
HTMLの文章を行ごとに（折り返し位置も）分割して装飾をつける

おら、アクセシビリティのことはよくわかんねぇんだけど、
とりあえず見た目は動いたぞ。

レイアウト後の折り返し位置も考慮して、行ごとに分割してスタイルを当てたいなって1万年と2000年前から思ってたんで、実装できて個人的にうれしいんですよね。

![test.html - Google Chrome 2022_04_22 23_49_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126428/db4c3020-e647-59f6-0e35-2a41424fa7c2.png)

```html
<html>
  <head>
    <style>
      #tmp-box {
        position: absolute;
        left: -100000px;
        white-space: pre-line;
      }
      #text-box > div {
        border-bottom: dashed 1px #aaa;
      }
    </style>
  </head>
  <body>
    <div id="tmp-box"></div>
    <div id="text-box"></div>
    <script>
      const text =
        '素早い茶色の狐はのろまな犬を飛び越える。\n素早い茶色の狐はのろまな犬を飛び越える。素早い茶色の狐はのろまな犬を飛び越える。';
      const tmpBox = document.getElementById('tmp-box');
      const textBox = document.getElementById('text-box');
      // 画面外に逃がしたtmp-boxに、描画領域の幅を設定する
      tmpBox.style.width = textBox.clientWidth + 'px';
      // 一文字ずつspanでつつむ
      const chars = text.split('').map((c) => {
        const span = document.createElement('span');
        span.textContent = c;
        return span;
      });
      // 仮想DOM使わないと重くなる
      const div = document.createElement('div');
      div.append(...chars);
      tmpBox.append(div);
      // 行ごとのdivに変換
      const lines = chars
        .reduce((prev, span) => {
          const lastLine = prev[prev.length - 1];
          // offsetTopの値が変わっていれば改行しているはず
          if (lastLine && lastLine[0]?.offsetTop === span.offsetTop) {
            lastLine.push(span);
          } else {
            prev.push([span]);
          }
          return prev;
        }, [])
        .map((line) => line.map((c) => c.textContent).join(''))
        .map((line) => {
          const div = document.createElement('div');
          div.textContent = line;
          return div;
        });
      textBox.append(...lines);
    </script>
  </body>
</html>

```