OmniAICreator/Qiita-1.07M huggingface dataset:
Cobraのコマンドをテストする

## 概要
CobraはGoでCLIを作成するのにすごく便利です

https://cobra.dev/

Cobraで作成したコマンドをテストするにはコツが必要で、以下の記事がとても参考になる

https://zenn.dev/spiegel/articles/20201018-cli-with-cobra-and-golang

ただ、雛形の修正など手間もあるので、より簡易的にテストする方法をまとめる

## コマンドの作成
`sub`というサブコマンドを持ったCLIを作成します
```sh
$ go mod init
$ cobra-cli init
$ cobra-cli add sub

$ go run main.go sub
sub called
```
```go:cmd/sub.go
...
var subCmd = &cobra.Command{
	Use:   "sub",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("sub called")
	},
}
...
```

## テストコード
`os.Args`にテストしたいサブコマンドを追加して、標準出力はキャプチャしてテストする
```go:cmd/sub_test.go
package cmd

import (
	"bytes"
	"os"
	"testing"
)

var originalArgs = os.Args

func setArgs(arg string) {
	os.Args = append(originalArgs, arg)
}

func resetArgs() {
	os.Args = originalArgs
}

func Test_subCmd(t *testing.T) {
	setArgs("sub")
	defer resetArgs()

	got := PickStdout(t, func() { subCmd.Execute() })
	want := "sub called"
	if got != want {
		t.Errorf("subCmd.Execute() = %v, want = %v", got, want)
	}
}

func PickStdout(t *testing.T, fnc func()) string {
	t.Helper()
	backup := os.Stdout
	defer func() {
		os.Stdout = backup
	}()
	r, w, err := os.Pipe()
	if err != nil {
		t.Fatalf("fail pipe: %v", err)
	}
	os.Stdout = w
	fnc()
	w.Close()
	var buffer bytes.Buffer
	if n, err := buffer.ReadFrom(r); err != nil {
		t.Fatalf("fail read buf: %v - number: %v", err, n)
	}
	s := buffer.String()
	return s[:len(s)-1]
}
```
これでコマンドのテストができるようになりました
```sh
$ go test ./...
```

## 参考
https://zenn.dev/_kazuya/articles/5dd984f95d6fef45b6eb

## 最後に

Go強化月間とのこと

https://qiita.com/official-events/ae80b010f51f7018891a
読書感想文  「Linux標準教科書」

エンジニア夏休み企画の読書感想文記事です。


# はじめに
Linuxを開発で使用していますが、1から学んだことがなく、業務でわからないところなどを調べながらという感じだったので読んでみました。

# 読んだ本はこちら
[Linux標準教科書](https://linuc.org/textbooks/linux/)

### 無料でダウンロードできます！(PDF版)

### 本の内容

>基本的なコマンド、正規表現、シェルスクリプト、ファイル管理など、Linuxの基礎知識を系統立てて学べるように構成されており、初心者の方が基礎からLinuxを学ぶために最適な内容となっています。

とあるようにソフトウェアとは、カーネルとは、というレベルから説明してくれています。

CentOSをインストールしてハンズオン形式で実際にLinuxを操作して学んでいくという感じになっていました。自分はCentOSではなく、Ubuntuでやりましたが、あまり問題ありませんでした。

内容
```
1章 Linuxとは
2章 Linuxのインストール
3章 基本的なコマンド
4章 正規表現とパイプ
5章 基本的なコマンド2
6章 viエディタ
7章 管理者の仕事
8章 ユーザ権限とアクセス権
9章 シェルスクリプト
10章 ネットワークの設定と管理
11章 プロセス管理
12章 ファイル管理
```

### 感想
一回読んだだけなのでざっくりわかってなにが書いてあるか把握しているくらいですが、感想を述べると

Linuxを初めて学ぶ人、業務でなんとなく使っている人にとってとてもいい本だと思いました。
普段使っているコマンドも詳しく解説されていてファイルを作成するためのコマンドだと思っていたtouchコマンドは編集日時を変更するコマンドだったなど新しい発見もありました。

目次は長いので載せていませんがかなり細かく書かれているのでなにかわからないことがあったらgoogleするよりも正確な情報がすぐ得られるかもという感じです。
クリックでジャンプできます。
なので一回さらっと読んで辞書的に持っておくのがいいかなと思います。

ちなみにこれを読んでさらにLinuxについて勉強したいと思ったらLinuxでのサーバー管理、運用方法をまとめた教科書もあります。

#### こちらも無料です！
[Linuxサーバー構築標準教科書](https://linuc.org/textbooks/server/)
[Linuxシステム管理標準教科書](https://linuc.org/textbooks/admin/)

### 参考
[Linux標準教科書](https://linuc.org/textbooks/linux/)
[Linuxサーバー構築標準教科書](https://linuc.org/textbooks/server/)
[Linuxシステム管理標準教科書](https://linuc.org/textbooks/admin/)
ファイルのアップロードとダウンロード

# アップロードとダウンロード
S3バケットにファイルをアップロード・ダウンロードする方法は**マネジメントコンソールを使用する方法とCLIを使う方法**がある。ツールやプログラムから操作するにはAPIやSDKを使用する。
マネジメントコンソールを使用する場合は、ドラッグ&ドロップもしくはポイントとクリックの操作でアップロードできる。ドラッグ&ドロップはGoogle ChormeとFirefoxブラウザのみのサポート。
S3には全てのファイルタイプをアップロードできるが、アップロードできるファイルサイズには制限がある。アップロードのファイルサイズ制限は、マネジメントコンソールからは160GBまで。それ以上はSDKやAPIを使う。
# 様々なアップロード
ファイルを**クライアント**からアップロードするには、様々な方法がある。
1. APIやSDK
APIやSDKを使うとサーバーパーティ製のツールを使ってファイル操作できるようになる。使用にはIAMユーザーでアクセスキーとシークレットアクセスキーを発行し、利用したいツールに設定。
1. マルチパートアップロード
**マルチパートアップロード**を使用するとオブジェクトをパーツに分解し、１つのセットをしてアップロードできる。アップロード中はパーツとして表示され、全てがアップされると再びオブジェクトになる。100MB以上のファイルはマルチパートアップロードを使用することが推奨されている。なぜなら、通常のリクエストやアップロードにかかる料金はかかるが、マルチパートアップロード機能を使うことにおける独自の課金はかからない。
マネジメントコンソールやCLIでは大きなファイルを操作するときに、マルチパートアップロードに切り替わる。
1. AWS Transfer for SFTP
**AWS Transfer for SFTP**は、SFTPを使用してファイルを転送できるサービス。SFTPツールでなくSFTPサーバーを提供するサービス。SFTPサーバーエンドポイントを設置することで、サードパーティー製などのSFTPツールが使えるようになる。初期費用はかからないが、SFTPサーバーを使用している期間とデータ転送量（アップロード及びダウンロード）に対して課金される。
1. AWS DataSync
**AWS DataSync**はオンプレミスのストレージサービスとAWSのストレージサービス（EC2やS3）との大量のデータ移動を想定したサービス。コピーした量に対して料金がかかる。
1. その他
S3とクライアントを繋ぐ方法として、S3バケットをオンプレミスのストレージのように扱えるAWS Storage Gateway(ハイブリットクラウドストレージサービス)がある。
# 余談
## 大規模データのやり取り
PB(ペタバイト)やEB(エクサバイト)単位のような非常に大きなデータ通信のアップロードは、物理的にAWSとデータのやり取りをする。
AWS Snowball(HDDにデータを入れて送る方法)
AWS Snowball Edge(データの加工処理もできる)
AWS Snowmobobile(トレックで配送する方法)
がある
## ブロックパブリックアクセス
バケット単位で全てのユーザーにアクセス許可をするかどうかを決定する機能。
バケットポリシーやユーザーポリシーで全員がアクセスをできるように設定していても、ブロックパブリックアクセスがブロックする設定ならば、アクセスできなくなる。バケットを全ユーザーに公開する際は、とても慎重にならなければならないため、このようなバケット単位での設定が必要になる。
[Flutter] BottomNavigationBarのボタンをオリジナルにする方法


こんにちわ。いせきです〜〜〜
久しぶりのFlutterの投稿です！！


今回は、BottomNavigationBarの押すところを色々な形に変更できるとわかったので、共有しようと思います〜〜。

# コード紹介
＊補足＊
写真や背景の調整のため、iconのサイズやcolorをいじっています。

```dart

BottomNavigationBarItem(icon: Icon(Icons.add,color: Colors.black,),label: ''),
BottomNavigationBarItem(icon: Text('タブ!?'), label: ''),
BottomNavigationBarItem(icon: Image.network('https://cdn-images-1.medium.com/max/1200/1*ilC2Aqp5sZd1wi0CopD1Hw.png',width: 40,height: 40,),label: ''),

```

### 写真

![IMG_2003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/ac5978cc-0b72-f650-d640-a267d9cd061a.jpeg)



# 解説
`BottomNavigationBarItem`の`icon`の引数は、`iconData`かと思っていましたが、`Widget`だったので、Widgetなら基本的に使うことができます。

# ソースコード

```dart
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: IndexedStack(
        index: _selectedIndex,
        children: [
          Container(
            alignment: Alignment.center,
            child: const Text('１ページ'),
          ),
          Container(
            alignment: Alignment.center,
            child: const Text('２ページ'),
          ),
          Container(
            alignment: Alignment.center,
            child: const Text('３ページ'),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(icon: const Icon(Icons.add,color: Colors.black,),label: ''),
          BottomNavigationBarItem(icon: const Text('タブ!?'), label: ''),
          BottomNavigationBarItem(icon: Image.network('https://cdn-images-1.medium.com/max/1200/1*ilC2Aqp5sZd1wi0CopD1Hw.png',width: 40,height: 40,),label: ''),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}


```


# 最後に、
便利だね。。てっきりそれ用のDart Packageを探そうと思っていました。ありがたや

# 参考文献
https://www.choge-blog.com/programming/flutterbottomnavigationbar-iconimage/
【Git】Gitリポジトリを取得

# はじめ

　　最近、gitのドキュメントを読んでいます。
　　復習のため、ポイントをメモしました。

# 2.1 Gitリポジトリの取得

Git リポジトリの取得方法：
- 既存のプロジェクトやディレクトリをGitにインポートする方法
- 既存のGitリポジトリを別のサーバーからクローンする方法

## 既存のディレクトリでのリポジトリの初期化
既存のプロジェクトに移動して次のように打ち込む。↓
```
$ git init
```
実行すると、**.git**という名前の新しいサブディスプレイが作られ、リポジトリに必要な全てのファイル（Git リポジトリのスケルトン）がその中に格納される。
この時点では、まだプロジェクト内のファイルは一切管理対象になっていない。

空のディレクトリではなく既に存在するファイルのバージョン管理をはじめたい場合は、まずそのファイルを監視対象に追加してから最初のコミットをすることになる。この場合は、追加したファイルについて**git add**コマンドを自行した後で、**git commit**コマンドを行う。

```
$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'
```

## 既存のリポジトリのクローン

既存のGitリポジトリのコピーを取得したい場合に使うコマンドが**git clone**です。（Gitはサーバーが保持しているデータをほぼ全てコピーする）↓
```
$ git clone [url]
```
実行すると、プロジェクト名のディレクトリを作成してその中で、**.git**ディレクトリを初期化し、リポジトリの全てのデータを引き出し、そして最新バージョンの作業コピーをチェックアウトする。

別の名前のディレクトリにクローンしたい場合、↓
```
$ git clone [url] [new-file-name]
```
**https://**だけではなく、**git://**や **user@server:/path/to/repo.git**という形式を使うこともできる。
for of loopを回すには、ブーリアンの初期値を【false】に設定！

JAVASCRIPTで、ブーリアンの初期値を【false】に設定しないと、for of ループが回らなかったよ、ということを記録に残す記事です。

この記事を見るとわかること：
ブーリアンの初期値は【false】。
初期値を【false】に設定すると、for of ループで配列の各要素を取り出せたよ。
初期値を【true】に設定したら、for of ループで配列の各要素をうまく取り出せなかったよ。


＜書きたいもの＞
仮引数：いろんな要素を持つ配列
返り値；与えられた配列の要素すべてがブーリアンかどうかを表すブーリアン


正しいコード
　～初期値を【false】～

```js
function containsOnlyBooleans(ArrayofAny4) {
    // ここにコードを書きましょう。  
    const result = false;
    for (const array of ArrayofAny4){
        console.log(array)
        if( "boolean" !== typeof array  ){
            // console.log(array)
            return result;
        }
    }
    return true;
}



actual = containsOnlyBooleans([ true,false, true, false, false]);
expected = true;

actual = containsOnlyBooleans([true, true, true,  "not a boolean"]);
expected = false;
```

コンソール画面

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2809792/6978f3e1-e8a6-157b-9970-ee45c669eaac.png)


うまく要素を取り出せないコード　
　～初期値を【true】～

```js
function containsOnlyBooleans(ArrayofAny4) {
     
    const result = true;
    for (const array of ArrayofAny4){
        console.log(array)
        if( "boolean" === typeof array  ){
            // console.log(array)
            return result;
        }
    }
    return false;
}
```

コンソール画面

![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2809792/a0ed45f2-b592-d99b-39c4-8f55f6a97bce.png)


なんで要素が１個しか取り出せないのか、理由がまだ説明できない。

説明できる方いたら、教えてください。


ブーリアンの初期値を【false】に設定しないと、for of ループが回らなかったという記録です。
Azure BlobStorageのファイルパスを指定して直接pandas.DataFrameで読み込む方法

Azure BlobStorageに格納しているオブジェクトファイルについて、いちいちローカルにダウンロードしてからDataFrameに読み込むのではなく、直接ファイルパスを指定してDataFrameに読み込む方法を調査したので備忘録として残しておきます。

[こちらの記事](https://qiita.com/gsy0911/items/3806ca9a6f4cbb74a03b)では独自にライブラリを作成して上記を実現していましたが、接続文字列を引数に指定することでpandasで用意されているread_csvで実現できました。


# 環境
- Python=3.9.13
- pandas==1.4.3
- adlfs==2022.7.0

# 実装コード
```python
import pandas as pd

connect_string = "xxxxxxxx"
path = "abfs://<container>/<file_path>"
storage_options = {"connection_string": connection_string]
pd.read_csv(path, storage_options)
```

# 参考
- https://stackoverflow.com/questions/62670991/read-csv-from-azure-blob-storage-and-store-in-a-dataframe
デプロイ先のどこにアプリを置くべきか

## 前置き
ec2にログインして`git clone`を実行すればアプリのデータを持ってくることができます
しかし、どのディレクトリにアプリを置くべきか。ちょっと調べてみました

## 基本的には`var/www`
実際、どこに置こうが構わないらしいのですが、`var/www`に置くことが多いようです

## `/home`でも構わない
wordpressなどは`/home`に置くこともあるそうです。

ec2にログインした直後にいる場所も`/home`配下なので、ここに置いてしまっても動かすことは可能です

## 使い分け
規模の大きなアプリは複数人でサーバーを管理することが多いです

個人でやる分には構わないのですが、`/home`は個人のディレクトリであるという使われ方をする場合が多いです

複数人で管理する場合、権限管理の都合で、共有管理のできる`/var`を使用することが多いとのこと
技術力を上げたい人はコードレビュー！と言われても...

# 初めに
弊社では以前はレビュアーが何人かいて、そのうちの1人を指定してレビュー依頼を出すというフローでコードレビューを行なっていました。
ある日、
「レビュアーは指定しないでコードレビューを出しましょう！」
「誰でもレビューしていいようにします！」
というふうになりました。

主な理由としては
- レビュアーを指定しないようにすることで1人に依頼が偏らないようにする
- 誰でもレビューすることで技術力を上げる

といったことがあります。

**技術力を上げていきたい人は積極的にレビューしていきましょう！**
と言われても、何をみて、何を言えばいいのかわからなかったので調べたこと、思ったことをまとめます。

:::note
ここに書いてある事は、レビューしてもらう側も意識することでコードがレベルアップすると思います。
:::

# ダメ出しじゃない
まず、
- **コードレビュー＝ダメ出し**

みたいに思ってました。
自分は人の書いたコードにあーだこーだ言えるほど偉くないし、知識も自信もないなと思っていたのですが、
色々調べてみて思ったのは、
- **コードレビュー ＝ コードに対する意見交換機会**

なのかもしれない。ダメ出しではないのかもしれない。
そう思うとレビューするハードルが下がる気がしました。

## レビューのレベル
レビュアーのレベル
- ①diffで見えている部分の問題
- ②diffで見えていない部分の問題
が見えるかどうか
### ①diffで見えている部分の問題
①は比較的簡単。見えているから。
例えば、コーディング規約違反やタイポ、ifの条件が間違っていること、名前が分かりにくい、意図がわからない書き方がある。など

### ②diffで見えていない部分の問題
②は結構難しい。
変更を加えていない部分への副作用や、将来問題となる種がないかなどをチェックする。エンジニアとしての経験がものをいう部分だけれど、自分で実装するならどこに気をつけるかを意識して変更点をみる、悪いコードの典型例を頭に入れておくなどをすると1段上のレビューをする足がかりとなる様です。
[コードの不吉な臭い](https://qiita.com/NagaokaKenichi/items/22972e6ba698c7f2978a)

## 初心者がレビューするときのポイント
- わからない、わかりにくい部分を質問する、指摘する
  - わからない、分かりにくいと感じたということはコードに改善点があるのかもしれないということ。知らないメソッドだったら最低限調べる。
- 複雑な条件などはテストコードを書いてもらう
- 細かいスタイルの修正もちゃんとお願いする

:::note
**わからない部分を質問して、説明してもらうことで**
- 書いた人、質問した人の理解が深まる
- 深まった理解で間違いに気がつくかもしれない
- わかりにくいなら書き直す、コメントを残すなど更なる改善がされるかもしれない。

と質問することはいいことがたくさんあるので臆せずに質問する。
:::
## 他にも見るポイント
- 境界値
- テストコードが正しく失敗するように書かれているか
- 分かりにくい名前
  - [うまくメソッド名を付けるための参考情報](https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)
  - [うまくクラス名を付けるための参考情報](https://qiita.com/KeithYokoma/items/ee21fec6a3ebb5d1e9a8)
- 他と違う書き方、珍しい書き方をしている部分
  - なぜそう書いてあるのか残した方がいい。または書き直す
- 1つのメソッドにifが複数ネストしている
  - メソッドを設計し直した方がいい
- ユーザーの入力値を受け取る部分
  - XSS/SQLインジェクションなど
  - [3分でわかるXSSとCSRFの違い](https://qiita.com/wanko5296/items/142b5b82485b0196a2da)
  - [SQLインジェクションとは？仕組み・被害事例・対策をわかりやすく解説](https://www.shadan-kun.com/waf/sql_injection/)

# 指摘が間違っていたら...
上のポイントに従ってコードをレビューして、もし指摘が間違っていたらどうしようと尻込みしてしまいますが、
そんなときはきっと
「ここは〇〇だからこうやって書いたんだよ。だから問題ない。」
など返してくれると思いますし、書いた理由などがわかるので自分の知識も増えると思います。
またそうやって書いた理由を説明してもらって重要だと思ったらコメントに残してもらうのもいいかもしれません。読んでわからなかったのなら他に読む人も同じ疑問を持つポイントかもしれないです。



# 終わりに
自分は誰でもコードレビューをしていいという環境にいるので積極的にレビュー依頼を取っていきたいと思いました。自分がレビューするときは
### コードレビューはダメ出しじゃない 
と思ってやっていこうと思います。

### チェックリスト
- 不要なコメント、デバッグコードが残っていないか
- わかりにくい部分は質問する
- コーディング規約違反やタイポはないか
- if文の条件がおかしくないか
- 命名がおかしくないか
- テストコードを書いた方がいいか
- 境界値の扱いは適切か
- 他の箇所と書き方がそろっていない部分はないか
- ユーザーの入力をエスケープするなど、正しく処理できているか
- コードの不吉な匂いに該当しないか

## 参考にした記事
- [コードレビューの際に気をつけること
](https://qiita.com/awakia/items/8344ba751426e386e0f5)
- [知識が無いからこそコードレビューで指摘をしよう](https://qiita.com/teshima/items/4eb1c7c09863e71d5ed0)
bundle cacheあるいはbundle package

https://bundler.io/v2.3/man/bundle-cache.1.html

について。かつては、bundle packageという名称であったし、ドキュメントも https://bundler.io/v2.0/man/bundle-package.1.html に残されている（当該Bundlerバージョンは既にdeprecated＝メンテナンスされていない）。両者はほぼ同じことを実現するため、Bundler 2.1くらいに完全に統合された。し、2.3中盤ではそれが[rubygems/rubygems#5785](https://github.com/rubygems/rubygems/pull/5785)において少しだけ分かりやすくされた。

私自身はこれまでほぼ使う場面がなかったのにドキュメントをメンテナンスすることになったしメンテナンスしているのだが、どういう場合に活用するのだろう。活用ケースによって、どちらのサブコマンド名が一般的なのか分かるのかもしれないので、質問してみたい。

例えば、`npm ci` https://docs.npmjs.com/cli/v8/commands/npm-ci では `ci` が標準のサブコマンドになっていて、 `clean-install` はエイリアス扱いである。

## 見つけたケース

今年2Qでは3番目のコントリビュータ *1 であった、世界No.3 (*2) の（OSS）Railsアプリケーションである[Forem](https://github.com/forem/forem) ([dev.to](https://dev.to/)の実装) では2020年くらいからこれを導入している。

経緯としては、当時のForem Core teamであった[@jdoss](https://github.com/jdoss)による https://github.com/forem/forem/pull/8066 で導入されたらしい（今知った）。

開発者体験の観点で行くと、追加・アップデートにおいては手間が増えたり、Git repoサイズも肥大化してしまうデメリットばかりが先行してメリットを感じられなかった。運用目線でも、RubyGemsパッケージレジストリー（[https://rubygems.org](https://rubygems.org)）が突然死んでしまったり、利用していたgemのバージョンがyankされたりしまった場合にわずかなメリットはあるかもしれないが、CIのキャッシュレイヤーに閉じ込めておけば十分だと感じていた。CIのキャッシュレイヤーが適切に機能していることは必須要件になってしまうが。
あり得るのはCI環境（CD環境が分離されていない場合はCD環境を含む）がair-gappedである場合だが、開発者環境はair-gappedではないならあまり意味がないような気がしたのだが、どうだろう。

## そもそもBundler 3では...

先のPRの説明を見返してみると、

> `cache_all` (`BUNDLE_CACHE_ALL`): Cache all gems, including path and git gems. This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3.

-- https://bundler.io/v2.3/man/bundle-config.1.html

ということらしく、いつ出るか分からない（pre-Bundler 2時点でのメジャーアップデート計画と比較してだいぶ長期間のメジャーアップデートになりそう）Bundler 3では「デフォルトになる」らしい（と言っても、デフォルトで `true` になるとは書いていないので、かなり曖昧な表記でがあるが）。有効になったタイミングでは、 `vendor/cache` を `.gitignore` に追加した人が続出しそうに思える。

## まとめ

`bundle package` を主に `bundle cache` を従にすべきじゃないかという考えの前提で、この質問を書き始めたのだが、本当に `bundle config cache_all true` を標準にしていきたいなら、今のままにするのがよさそうに思えてきた。ということで、これはそれに至る思考メモ（と[https://www.google.com/search?q=bundle+package](https://www.google.com/search?q=bundle+package&hl=jp&gl=ja)のSEO）でした。

Bundler 3で予定されている変更点は https://qiita.com/jnchito/items/d3257a5f46f4f1aee200 を参考にするとよさそうです。

## 注記

#### *1

https://github.com/forem/forem/graphs/contributors?from=2022-04-01&to=2022-06-30&type=c

#### *2

https://github.com/topics/rails?o=desc&s=stars

Discourse (36.2k stars), GitLab (Community Edition) (23.0k stars)についで19.5k stars。[rails](https://github.com/rails/rails)本体および[devise](https://github.com/heartcombo/devise)を除く。
システム監査

# ITガバナンスとは？
経産省の定義によると「企業が、ITに関する企画・導入・運営および活用を行うにあたって、全ての活動、成果及び関係者を適正に統制し、目指すべき姿へと導くための仕組みを組織に君こむこと、又は、組み込まれた状態。

ITシステムを適切に管理・運用するための体制や方法のこと

システム監査とはこの体制がちゃんとできているかを確認する仕事。

# システム監査人と監査の依頼者、被監査部門の関係
## システム監査人の要素
### 外観上の独立性
```監査対象から独立```していなければなりません。
監査主体と身分上、```密接な利害関係を有することがあってはならない```。

### 精神上の独立性
変更を排し、常に```公平かつ客観的```に監査判断を行わなければならない。

### 職業倫理と誠実性
```誠実```に業務を実施しなければならない。

### 専門能力
```専門職としての知識および技能を保持```しなければならない。

出典 https://www.meti.go.jp/policy/netsecurity/downloadfiles/system_kansa_h30.pdf

## 監査の一連の流れ
* 依頼組織から監査依頼
* 監査人の監査計画の立案
* 監査人の監査の実施
* 監査人の監査報告
* 依頼組織もしくは被監査部門が改善命令

# システム監査の手順
監査計画の立案から監査実施までの手順
### 監査計画の立案
監査の目的を効率的に達成するための、```監査手続きの内容とその時期、及び範囲などについて適切な計画```を立案します。

### 予備調査
本調査に先立ち、```監査対象の実態把握```に努めます。
```資料の収集やアンケート調査```など、被監査部門の実態調査を行い、適切なコントロールがなされているか確認します。

* 監査実施の本調査に先立って、予備調査を実施します。
    この予備調査の段階では、あくまで```予備知識を収集```し、監査対象であるコントロールの```整備状況を適切に把握```できるように心がけることが重要です。
具体的な手段としては、質問票の作成・送付・回答受領、各種規程類の査読（場合によってはインタビュー）等を実施することが挙げられます。
予備調査の作業項目には、次の事項が含まれます。

    * ```監査目標の設定```
    * 質問票の作成、被監査部門への```質問票送付及び回答の分析```
    * ```規程類等の資料分析```
    * 予備調査結果の総括及び予備調査結果を踏まえた```本調査の立案```

    出典 http://it-sox.com/sa-kansajissi.html

#### インタビュー（ヒアリング）
監査対象の確認のために、非監査部門や関連部署などに対し、```面談して質問（インタビュー)```を行うこと。
その際に問題となる事項を発見した場合は、```裏付けとなる記録を入手```したり、```実際に現場の確認```を行う。
出典 https://gihyo.jp/book/2022/978-4-297-12375-8
#### コントロールとは？
適正に統制するための仕組み
出典　"https://gihyo.jp/book/2020/978-4-297-11781-8" のp５２８

### 本調査
予備調査で作成した監査手続き書に従い、現状の確認と、それを裏付ける```監査証拠の収集、証拠能力の評価```を行い、監査調書としてまとめます。
* 予備調査の結果を反映した監査手続書に基づき、監査目標ごとに監査を実施します。本調査においては、予備調査で把握したコントロールの整備状況が```適切に運用されているかについて手続きを実施```します。
本調査の作業項目には、次の項目が含まれます。

    * 準拠性テスト
    * 実証性テスト
    * 監査の結論の総括及び資料の記録・保管

    出典 http://it-sox.com/sa-kansajissi.html
### 評価・結論
監査長所に基づいて、監査対象における```コントロールの妥当性を評価```します。評価結果は監査報告書としてまとめ、その文書内に```指摘事項や、改善勧告```などの監査意見を記します。
* システム監査実施の総括として、評価・結論の過程があります。この過程においては、予備調査及び本調査で収集した監査証拠を振り返って、監査対象とした```コントロールが監査目的に適合```しているかを判断します。

    * コントロールの整備状況・運用状況の評価
    * 監査実施の結論のとりまとめ

    出典 http://it-sox.com/sa-kansajissi.html

# システムの可監査性
処理の正当性や内部統制を効果的に監査またはレビューできるようにシステムうが設計・運用されてることを指します。

プルーフリストを使って別の担当者が照合するようにしておけば、データの重複や入力漏れに気づくことができる。
このように```遡って検証できることが大事```。

### プルーフリスト
入力データをそのまま加工せずに印刷したもの。

事象発生から最終結果に至るまでの一連の流れを、時系列によった形で追跡できる仕組みや記録を```監査証跡```という。

## 監査証拠
それをもとに監査調書としてまとめていく。
ここには監査意見が記されている。それには証拠が必要になってくる。
監査意見を立証するために必要な事実を```監査証拠```という。

# 監査報告とフォローアップ
監査人には監査意見の```責任を取らなければならない```。
しかし、実際に```変更する権限はありません```。必要に応じて```改善実施状況を確認```する。
```あくまで改善指導```という立場で関わる。改善の```主体は、被監査側```になる。

システム監査人が改善指導することを```フォローアップ```という。

## 監査意見の２種類
### 保障意見
基準に適していることを```保障```する

### 助言意見
```欠陥```の指摘と```改善点```の表明

### 気づき
保障と指摘には責任を持ってするのか。

# テストを解いた時の気づき
システム監査人は、```自分が所属している部門を監査できない```。

# 関連記事
https://qiita.com/masatom86650860/items/e924084f834ecc8ec12c

# 出典
https://gihyo.jp/book/2020/978-4-297-11781-8
16進数順にファイルを並び替えよう。

PLC入出力表のファイル名は先頭IOにすることが多いと思います。
入出力は16進数表記なのでファイル名にA～Fが入ると上のほうに来てしまい、思った順番になりません。

「gpedit.msc」または「ローカルグループポリシー」をPCで検索し開く。
「ユーザーの構成」→「管理用テンプレート」→「Windowsコンポーネント」→「エクスプローラー」
「エクスプローラーで数値による並べ替えを無効にする」を未構成→有効に

これで16進数順にファイルが並ぶ。![16進数並び替え.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141264/53f9a082-25b2-ac14-2fe9-6fa023617747.png)
win2000まではこっちの並びが標準だったらしい。
Webサイトホスティング

# Webサイトホスティングとは
S2では**静的Webサイトをホスティングすることができる**。
静的Webサイトをホスティングするには、バケットをそのままWebサイトとして公開する。
これはURLを設定し、バケットを誰でもアクセスできるようにすることを指す。
バケットはデフォルトでは第三者がアクセスできないので、ブロックパブリックアクセスとバケットポリシーを設定。
## 静的Webサイト
静的Webサイトとは、**サーバー上でスクリプト処理をしないサイトのこと**。
ex)単純なHTMLと画像だけで作成されているWebサイト。
ただし、静的Webサイトには、**JavaScriptなどのクライアント側で処理されるスクリプトが含まれることもある**。
## 動的Webサイト
動的Webサイトとは、PHP、JSP、ASP.NETなど、**サーバー側で処理が必要な言語を含むサイト**を指す。
# Webホスティングで必要な設定
Webサイトとしてバケットを公開するには、バケット作成時や作成後に、いくつか必要な設定がある
* 静的Webホスティング（スタティックWebホスティング）を有効にする
* ブロックパブリックアクセスのブロックを解除する
* バケットポリシーを「全ユーザーを許可」に設定する
* バケット名として使用したいドメイン名を指定する
* 独自のドメイン名で運用したい場合は、Amazon Route 53などのDNSサービスを使って設定する。
## バケット名とURL
バケット名として使用したいドメイン名を指定しても、名前をそのままドメインとして使用できない。
(イメージ)
**https://qiita.com.s3xxxxx.amazonaws.com**
上記のように**使用したバケット名**(qiita.com.s3xxxxx.) + **AWSの指定した文字列がURL**（.s3xxxxx.amazonaws.com）になる。
そのままドメインとして使用したい場合には**DNSの設定が必要**。
# 他のサービスを使用したWebホスティングとの違い
**Webホスティングにおけるサービス間の比較**
|サービス|プログラムの実行|スケーラビリティ|
|-|-|-|
|EC2|◎|△|
|S3|×|◎|
|Lightsail|◎|△|
|Amplify|○（Amplify独自プログラム）|○|
* EC2
最も自由に組み立てられる
* S3
スケーラビリティが最も高いので、プログラムを使わないのであれば有効
* Amazon Lightsail
Amazon LightsailはEC2の簡易版的なサービスで機能は１つに組み合わせたパッケージで提供される。
必要なものを選ぶだけで、Webサイトの必要なサービス一式を定額で揃えられるサービス。EC2であれば、OSやWordPress、固定IPアドレスやDNSをそれぞれ用意しなければならないが、Lightsailでは、これらの複雑さを解決するワンパッケージのサービス。EC2インスタンスと違い、CPUやメモリのスペック、台数を後から変更できない。変更したい場合はスナップショットでバックアップをとり、希望のスペックのLightsailを新たに契約し、バックアップから戻す操作をする必要がある。
* Amplify
AWS AmplifyコンソールはモバイルアプリやWebアプリを作るためのフレームワーク。AWS AmplifyはWebシステムを開発するためのツール一式を提供するサービスで、開発者が使うもの。JavaScriptでAWSの様々な機能を呼び出し、システムを構築する。HTMLファイルや画像などをS3を経由して配信し、Lambdaという機能を使ってバックエンドのプログラムを実行する。Amplifyはこうしたサービスを組み合わせてコンテンツやプログラムを配布する司令塔として機能する。
Microsoft Sustainablitity Manager って何？

# プロローグ

**ほげ君**：ねえねえ、 Microsoft Sustainablitity Managerって知ってる？
**ふが君**：何それ？知らない。
**ほげ君**：僕も知らないんでよね！どんなものなのか教えてよ、 Microsoft 公式ドキュメント君！
**公式ドキュメント君**：分かりました。





# Sustainablitity Manager概要
**公式ドキュメント君**：Microsoft Sustainability Manager is an extensible solution that unifies data intelligence and provides comprehensive, integrated, and automated sustainability management for organizations at any stage of their sustainability journey. It automates manual processes, enabling organizations to more efficiently record, report, and reduce their emissions.
(https://docs.microsoft.com/ja-jp/industry/sustainability/sustainability-manager-overview)

**ほげ君**：は？英語？
**ふが君**：どうやら公式ではまだ日本語対応されていないようだね。
**ほげ君**：最悪。
**ふが君**：まあ、公式が日本語対応していても翻訳が下手で、日本語が崩壊していることが多いし、こっちで自動翻訳掛けるのと大差ないよ。
**ほげ君**：確かにそれは一理あるな。
**ふが君**：じゃあ自動翻訳してもう一度教えてよ。

**公式ドキュメント君**：Microsoft Sustainability Manager は、データ インテリジェンスを統合し、サステナビリティ ジャーニーのあらゆる段階で組織に包括的で統合された自動化されたサステナビリティ管理を提供する拡張可能なソリューションです。手動プロセスを自動化し、組織がより効率的に排出量を記録、報告、削減できるようにします。

**ほげ君**：排出量？削減？何をだ？
**ふが君**：多分名前に sustainability って入ってるから、二酸化炭素とかじゃない？

**公式ドキュメント君**：Microsoft Sustainability Manager を使用すると、組織は排出量の活動を継続的に可視化し、その影響と進捗状況をほぼリアルタイムで確実に報告し、他のユーザーと協力して持続可能性イニシアチブを洗練および拡張し、ビジネスをエンドツーエンドで変革するために必要なインテリジェンスにアクセスできます。

**ほげ君**：えーと、つまり Sustainability Manager を使うと、自分の会社がどれぐらい二酸化炭素を排出しているか分かるってことか。
**ふが君**：そのようだね。サンプルデータとかでちょっと使わせてよ。

# Sustainablitity Manager 触ってみた
**公式ドキュメント君**：Microsoft Sustainability Manager を 30 日間無料で試す
(https://dynamics.microsoft.com/ja-jp/sustainability/sustainability/free-trial/)

**ほげ君**：お！珍しく用意がいいじゃねえか。
**ふが君**：メールアドレスが必要なのか。個人用じゃダメみたい。前になんかテナント作った時のアドレスでいけた。
**ほげ君**：組織向けのアドレスが必要ってことか。
**ふが君**：そうみたい。画面開けたよ。
**ほげ君**：どれどれ。なんだかよくわかんないな。英語だし。
**ふが君**：こっちも日本語対応はまだみたい。自動翻訳掛けるね。

**ほげ君**：ごちゃごちゃしててよくわかんねえな。
**ふが君**：どうやら左下で、三つの画面
・設定
・データ
・分析
の中からどの画面が見たいか選べるみたい。

**ほげ君**：まず、設定画面は何ができるんだ？
**ふが君**：設定画面は、
・組織設定：会社の名前、住所とかの基本情報
・データ設定：使ってる燃料のカテゴリ、出張の種類とか
・アプリ設定：他の製品、Teams とかと連携できるらしい。

**ほげ君**：データ画面は？
**ふが君**：データ画面は、
・データの管理：自分の会社が具体的にどの燃料を、どれぐらいの量使ってるかのデータ
・計算：データから二酸化炭素とかの排出量を計算する為の公式
って感じかな。


**ほげ君**：最後の分析は？
**ふが君**：入れたデータと計算方法をもとにグラフで可視化した画面って感じだね。可視化は Power BI が裏で動いてる感じ。
**ほげ君**：グラフの表示が重いな。これ使いものになるのか？
**ふが君**：怪しいね。

**ほげ君**：あれ、グラフとかは自動翻訳できないのか？
**ふが君**：どうやらグラフの部分はできないみたい。
**ほげ君**：不便すぎるわ。

**ふが君**：でもこれである程度 Sustainability Manager の機能は分かったね。Power BI で企業の二酸化炭素の排出量を可視化するレポートを Microsoft が事前に作ってくれてるから、あとは自分の会社のデータを入れるだけでいいっていう製品なんだね。
**ほげ君**：なるほどな。使う人はレポート作成とかはなしで、操作を覚えればいいってことか。つまり、二酸化炭素の排出量を可視化するアプリケーションってことか。
**ふが君**：そうだね。

**ほげ君**：にしても、これ操作に慣れるのも大変じゃないか？
**ふが君**：具体的な操作は構成ガイドを読みながら一個ずつ見ていくのが一番早く慣れるって感じかな。
**ほげ君**：まあ、いつか使いたくなったらそうするわ。今日は Sustainability Manager がどんなもんか知りたかっただけだし。腹減ったな、かつ丼食いに行こうぜ。
**ふが君**：そうだね。行こうか。
PowerBIでデータを結合するよりDr.Sumでビューをつくろう【データベース】

# 最初に
日本で20年以上も愛されている、国産の超高速集計データベースであるDr.Sum
世界でも日本でも大人気のセルフサービスBIツールの代表格であるPowerBI

2022年5月のDr.Sumのアップデートモジュールにより、この２つのツールの接続が可能になりました。

:::note warn
2022年8月時点で Dr.Sum Ver5.6 と連携できるPower BIの製品は、次のとおりです。
Power BI Desktop
Power BI サービス
:::

さっそく動きを見てみたくて、実際につないでみました❗️

接続設定については、こちらの記事を見てください。
[PowerBI でDr.Sumにつないでみた](https://qiita.com/ilovehome/items/02891b875c56acaea0a1)

さて、冒頭からキャッチーなことを書いてしまっていますが、PowerBIの結合の機能が劣っているとかそういうことではございません！
システムエンジニアの観点から、データベースの加工などのデータマートをつくる領域は、UIをつくるアプリケーション層よりも、データベース層でつくる方が、メンテナンス性が向上するよ、というお話しです。

まずはその理由について、解説をさせていただこうと思います。

## なぜDr.Sumのビューが良いのか
この記事を読んでいらっしゃるPowerBIユーザーの方は、全体設計のことをよくお考えになられる方だと思います。
そうでなければデータベースの必要性をなかなか感じにくいものですから・・・。

BIだけに限った話ではありませんが、ミドルウェアにはアプリケーション部分とデータベース部分があります。
アプリケーション層は現場の皆様に見えるところで、「簡単・直感的な操作」が必要になります。
データベースそうは専門知識が必要になりますが、アプリケーション側でつくる手間が省けます。

これがPowerBIのデータソース結合とDr.Sumのビューの関係にあてはまります。

図解すると、このようになります。
![PowerBIでビューをつくる.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/761f7b1b-c75a-686b-3eee-e560e7dfec2f.jpeg)


上図ではPowerBI側で個別に自由にデータの加工ができますが、テーブル情報の何かが変わると、影響範囲は全ワークブックになり、**メンテナンスが大変**ですね。

![DSでビューをつくる.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/ee5431fd-a308-a3eb-3629-8da86a65e8c0.jpeg)


もし、同じようにデータをくっつけるのであれば、データベース側でおこなってしまった方が、メンテナンスはとても楽になります。
そしてデータガバナンス（統治）を考えても、データに詳しい人がビューをつくり、PowerBIユーザーはそのつくられたビューを参照するようにすると、**データガバナンスが効き、正しいデータを活用**できることになります。

## Dr.Sumのビューを見てみよう
ここまで言っておいて、Dr.Sumのビューが使いにくかったら、何の意味もありません。
使い方を解説していきましょう。

まず最初に、PowerBIのデータソース結合の画面です。
![PowerBIのデータ結合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/78f2d644-6242-bd64-6d45-cfaea078b5bb.png)



この場合ですと、T売上実績_100万件というデータを中心としたスタースキーマで、マスタ結合がおこなわれています。
結合したい項目をドラッグすると、実際に入っている値からカーディナリティを「1対多」や「多対1」、「1対1」などに自動で設定してくれます。
さすがはセルフサービスBI、ユーザー現場層に向けた製品と言えます。

ではDr.Sumはどうでしょう。
![DSのビュー作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656849/85ca1472-0487-5a4e-ecfe-457511455fc6.png)



ちょっとたくさんテーブルがくっついちゃっていますが、もしAccessを触ったことのある方だったら見覚えのある画面かと思います。
Accessのクエリのデザインビューに似ています。

画面真ん中で、各テーブルのキーを結合させています。
今回の場合、真ん中にあるT売上実績_100万件テーブルを中心に、各マスタを結合させています。

真ん中下のグリッドの部分は、結合した項目の中で、何を表示させるかを選択しています。
ここをいじるだけで、PowerBIに公開してもよい項目、NGな項目を選択するわけですね。

一番下はSEさん向け。
どのようなSQLになるかを解説しています。
今回のように結合が複雑な場合など、どのような結合法則になっているかを確認したりします。

このようにGUIで表現することもできますし、最初からSQLをゴリゴリ書いてビューをつくることもできます。
データベース層なので、対象はSEさんやAccessのクエリが操作できる人、となります。

しかし、ビューの作成は簡単な内容なので、少し学んでいただけたら、すぐにゴリゴリ使えるような設定かなって思います。

## 最後に
いかがだったでしょうか。
データの結合や加工をどこでおこなうか、これには答えはありません。
誰にとって、何が最適かというのは、その時々で考える必要があります。

PowerBIをひとりでつかうのではなくみんなで使うようになってきたときに、データの加工部分はデータベース層でおこなった方が、ハンドリングが効きやすいよ、ということを覚えてくださったら幸いです。
【Swift】外観モードを変更の際のアラートを作成した

# はじめに
https://qiita.com/SNQ-2001/items/e907458e506db9fc0418

上記の記事の続きっぽい内容です。

せっかく実装したので使い回しできるように記事にしておきます。

# 完成目標

![Simulator Screen Recording - iPhone 12 - 2022-08-23 at 16.15.00.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8f9331fb-6da2-901e-4e94-4cefdb47f31a.gif)

![スクリーンショット 2022-08-23 15.41.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/486eaef0-2b31-58f0-c956-596d1d4c6203.png)

画像のように現在選択されているものには、
チェック画像を表示してテキストの色を緑に変更したいです。

# 実装
実装コードに関してはパクリなので実装案だけの記事です笑
サンプルを見てください。

https://github.com/SNQ-2001/SwiftUI-AppearanceMode-Alert

# 参考記事
アラートのカスタマイズに関して

https://qiita.com/unicoonn1/items/a009916c87b667ae987f

外観モードの設定に関して

https://qiita.com/MaShunzhe/items/e0b5cab0df689438379f
数式の余白を設定する方法

# はじめに

v3のMathJaxで数式の`margin`や`padding`を設定する方法が、調べても意外と見つからなかったので書き残しておきます。

# 解決策

以下をHTMLのどこかに追加します。

```html
<style>
    mjx-container { margin: 0 !important; }
    mjx-container[display="true"] { margin: 0 !important; }
</style>
```

`[display="true"]`がついていない方がinlineの方のスタイルで、`[display="true"]`がついている方がdisplayの方のスタイルです。
サクラエディタでタブ表示設定

# 概要

こんなふうにタブ表示したい時。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e52e804f-a5b2-080b-cd89-4038e050839f.png)

# やり方

共通設定の…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5587d210-a0fa-1415-299d-2f782be7bdfd.png)

下記の『タブバーを表示する』にチェック。
サクラエディタの再起動は不要。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3932c882-0fce-8e22-a6f1-d804c80bcbd9.png)

# 合わせてやっておきたいタブ移動のキーボードショートカット

『次のウィンドウ』で右のタブへ移動。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a486d70c-dba8-2a61-3c77-13b1f2634381.png)

フォーカスが当たっているのが右端の状態で『次のウィンドウ』のキー操作すると、『一番左のタブ』に移動する。（移動がループする感じ）

『前のウィンドウ』については割愛。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
 サクラエディタ v2.4.1.2849 32bit (tag v2.4.1)
Rのデータフレーム内で文字列を結合・分解する。列方向（横方向）と行方向（縦方向）。

# やりたいことは、文字列の結合
こういうデータフレームを、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/11b3eaeb-769e-79d4-4876-6956ada877be.png)
こうしたい。行方向（横方向）に文字列を結合して、新しい列を作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/f8e997c9-dc14-a7ac-72bd-a39e7958a16c.png)
または、こうしたい。列方向（縦方向）に文字列を結合。labelをグループとしてlabel2をまとめてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/478b82d3-d874-0d1e-891c-997a46a10ab0.png)

# Rのコード
以下のコードで、上の変形ができます。
```r
library(dplyr)
library(tidyr)
#サンプルデータを作る
sample <- data.frame(
  id=1:6
  ,label=c("aaa","aaa","bbb","bbb","ccc","ccc")
  ,label2=c("あああ","いいい","ううう","えええ","おおお","かかか")
)

#行方向（横方向）に文字列を結合。uniteを使用。mutateとpasteでもできるけどuniteのほうが簡単。
#結合に使った列を消すなら、remove=T。結合に使う文字はsepで指定。
sample_col <- sample %>% unite(new_label,label,label2,remove=F,sep="_")

# 列方向（縦方向）に文字列を結合。
# group_byしてからsummariseの中でpaste0を使う。結合に使う文字はcollapseで指定。
sample_row <- sample %>% group_by(label) %>% 
    summarise(new_label = paste0(label2,collapse="-"))

```

# 分解もしたい（1列→複数列に）
これを
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/9adcb85c-fdf6-c3d5-3005-c3bb18c35df2.png)
このように列に分解するなら、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/0307a4d1-178d-8ed5-a7ef-6d27d27cbe2e.png)
以下のコードでOK。
```r
library(tidyr)
# サンプルデータを作成
sample <- data.frame(
  id=1:6
  ,label=c("aaa_あああ","aaa_いいい","bbb_ううう","bbb_えええ","ccc_おおお","ccc_かかか")
)
# separateを使用。分解の区切り文字はsepで指定。分解後の列名はintoで指定。intoの数が合わない分は消えちゃいます。
sample_col <- sample %>% separate(label,into=c("new_label1","new_label2"),sep="_")
```
# 分解もしたい（1列→複数「行」に）

これを
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/9adcb85c-fdf6-c3d5-3005-c3bb18c35df2.png)
このように行に分解するなら、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100646/b0189848-608d-29cf-594e-70486308e9dd.png)
以下のコードでOK。
```r
library(tidyr)
# サンプルデータを作成
sample <- data.frame(
  id=1:6
  ,label=c("aaa_あああ","aaa_いいい","bbb_ううう","bbb_えええ","ccc_おおお","ccc_かかか")
)
# separate_rowsを使用。分解に使う区切り文字はsepで指定。
sample_row <- sample %>% separate_rows(label,sep="_")
```

# おわり
おわりです。お疲れ様でした。
【Flutter】プッシュ通知についてのまとめ

# はじめに
<!-- 発端や概要を記載 -->
　個人開発でユーザーが設定した期日の三日前と期日の当日にプッシュ通知を送信する機能を実装しようと思っていました。
　勉強も兼ねて、Push通知の実装にあたっては、[FCM(Firebase Cloud Messaging)](https://firebase.google.com/docs/cloud-messaging?hl=ja)を利用しようと思いました。
　`FCM`とは、`Firebase`というGoogleが提供しているクラウドサービスの一機能です。
`Firebase`は、アプリケーションや Web サービスを開発する際に用いる、バックエンド機能を提供するクラウドサービスです。
　公式ドキュメントや他の記事を参考にプッシュ通知を送信するところまで実装したところで、
**どうやってUI側からPush通知の送信を登録するかわかりませんでした**。
　したがって、プッシュ通知について調べてみたので記事にして共有したいと思います。

※本記事では、詳細な実装方法について説明していません。
　Flutterのプッシュ通知について知りたい方向けの記事です。
　ただ、いきなりサンプルコードをみて実装するのではなく、
　プッシュ通知について知ったうえで、実装していく方が結果早いと思います。
　(普段、私はサンプルコードをみて実装するタイプで、今回のプッシュ通知の実装もそうしたのですが、プッシュ通知については仕組みから理解する必要があると思いました）

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Flutterのプッシュ通知](#Flutterのプッシュ通知)
1. [リモート通知の仕組み](#リモート通知の仕組み)
1. [まとめ](#まとめ)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Flutterのプッシュ通知"></a>
# Flutterのプッシュ通知
プッシュ通知には以下の二つの種類があります。
* ローカル通知
* リモート通知

### ローカル通知
ローカル通知は、インターネット接続を必要とせずデバイス内部で完結する通知です。スケジュールの通知など、決まった時間をトリガーとする通知の際はこちらを使います。
[flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications)というパッケージで実装できるみたいです。
動作確認していませんが、[こちらの記事](https://dev-yakuza.posstree.com/flutter/flutter_local_notifications/)で実装できそうです。

### リモート通知
リモート通知は、インターネットを通して届くプッシュ通知です。SNSのいいねやメッセージ受信時など、何かしらのユーザーのイベントを契機に通知したい際はこちらを使います。イベントの発行はバックエンド側で実装する必要はあります。

**まとめると、
時間によるイベント→ローカル通知
ユーザーのアクションによるイベント→リモート通知
と使い分けるとよさそうです。**

<a id="#リモート通知の仕組み"></a>
# リモート通知の仕組み
この記事の発端である`FCM`を使ってリモート通知で**どうやってUI側からPush通知の送信を登録するか**を知るために、リモート通知の仕組みについて説明します。
[こちらの記事](https://future-architect.github.io/articles/20220323a/)が大変参考になりました。

リモート通知の送信の流れは以下です。
※通知を送信するにはトークンの発行と保持が必要になりますがその説明については上の記事をご参照ください。
1. **バックエンドサービス**がプッシュ通知を**プッシュ通知サービス**に要求する
1. 要求を受けた**プッシュ通知サービス**が**デバイス**にプッシュ通知を送信する
1. **デバイス**が通知を受け取る

ここで重要なのは、**プッシュ通知の送信は`FCM`のようなプッシュ通知を送信するサービス**で、
**プッシュ通知の送信を要求するのはバックエンドの仕事**だということです。

つまり、UI側からPush通知の送信を登録するには、以下の流れとなります
1. 何らかのタイミングで**デバイス**から**バックエンドにPush通知の送信を要求**
1. **バックエンド**から **`FCM`にPush通知の送信を要求**
1. **`FCM`からデバイス**にPush通知を送信

<a id="#まとめ"></a>
# まとめ
私の実装したい機能は、時間ベースの通知になるのでローカル通知の方がよさそうでした。
ただ勉強のために`FCM`を使った実装もしてみたいです。
そのためには、プッシュ通知を要求するサーバーが必要ですね。
公式ドキュメントによると、[Cloud Functions for Firebase](https://firebase.google.com/products/functions?hl=ja)や、他のクラウド環境が使えるようです。


<a id="#reference"></a>
# 参考文献
- [Flutterのプッシュ通知について知っておきたいこと](https://future-architect.github.io/articles/20220323a/)
個別にファイルをgit add,git resetする意義

>どうもaono1234と申します。記事がいいなと思ったらtwitterのフォローもお待ちしております‼
https://twitter.com/takeshi_program

みなさま、gitはうまく使いこなせていますでしょうか？

私ですか？
まだ使いこなせてません（笑）🤪
gitってコマンドが多いんですよ💢

今日はそんなコマンドの中でも基本的な`git add`、`git reset`にフォーカスして記事を書きたいと思います。
ん～よろしく❗❗

# 1. はじめに
本記事は以下の読者が対象です。

- プログラミング初心者
- gitを使ったことがある
- githubを使ったことがある
- ステージングエリアがよく分かってない
- `git add .`/`git reset --hard`しか使ったことがない


# 2. 先に結論
- コミットメッセージを冗長にしないために`git add ファイル名`、`git reset ファイル名`を使う


# 3. gitの一連の流れを再確認
ご存じかとは思いますが、gitには「ワーキングツリー」「ステージングエリア」「リポジトリ」という3種類のエリアが存在します。
一連の流れとしては
`1. 「ワーキングツリー」でファイルの一部変更して～`
`2. git add .　でステージングエリアにアップして～`
`3. git commit でリポジトリにアップして～`
`4. git push でリモートリポジトリにアップして～`

このような流れだと思います。

この中で2.のステージングエリアへのアップだけ、何のためにやっているのか疑問に思ったのは私だけではないはず！！😠
このステージングエリアについての理解が大事なのす！！（多分）😤

# 4. ステージングエリアの操作について
## 4-1. git add .
git add はワーキングツリーで変更があったファイルをすべてステージングにアップするコマンドです。
試しに3つのファイルを変更し、`git add .`してみましょう。

<b>【git add .前】
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/cd3789cd-a742-e03e-46f5-32474095509d.png)

<b>【git add .後】
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/43e26aeb-85a4-a628-8c76-2196e690ef33.png)

見慣れた感じですね
この状態で`git commit` すると、3つのファイルがリポジトリにアップされます。

## 4-2. git add ファイル名
では次に`git add .` ではなく、`git add blog.rb`を実行してみましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/446de985-dea8-6d99-b526-27bd60344c28.png)
blog.rbファイルだけステージングされました。
この状態で`git commit`すると、`blog.rb`ファイルだけがリポジトリにアップされます。


## 4-3. git reset ファイル名
次は`git add .`した状態から`git reset blog.rb`をしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534058/e6a396b5-04e0-3feb-486d-29b37c3d8e3f.png)

この状態で`git commit`すると、`comment.rb`と`user.rb`がリポジトリにアップされます。

<b>このようにステージングエリアに上げるものを選択してコミットするファイルを指定してるのですねぇ～

# 5.  ファイルごとにgit add,git resetするのはコミットにノイズを乗せないため
新しい機能を作成中に既存コードのバグを発見してしまった😱
急いで修正！😁
そんな経験ありませんか？

このバグ修正だけをコミットしたくないですか？
もし`git add .`で「新機能のコード」と「バグ修正のコード」がごっちゃになった状態でcommitしたらコミットメッセージが冗長になってしまいます。

こういう時に`git add`、`git reset`を使えば、「新機能のコード」と「バグ修正のコード」を分けてコミットできるということなのす😤

# 6. さいごに
今回のような使い方もあるんだなぁ、ぐらいので参考にして頂ければ幸いです。
状況によって使い分けて下さい。

またgitについての記事を書きたいと思ってますのでよかったらご覧くださ～い😀
SnailSVNのメモ（ファイダーに右クリックでショートカットが表示されない)

# 概要
仕事でmacでsvnを使う必要があったので、snailsvnをインストールしましたが、右クリックをしてもaddやcommitなどのショートカットが出てこなかったので、調査しました。

## 調査結果

ローカルリポジトリのパスをWorking Copiesに設定して、客先から渡されているパスワードとユーザーネームを設定してやる必要がありました。

![スクリーンショット 2022-08-24 13.08.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417196/f3776c8d-544a-2237-6148-33024e75d478.png)


参考
https://qiita.com/Labi/items/2ea3958ed20003bcf5c8
https://mjeld.com/macos-catalina-subversion-snail/
とある認証方式の話

## はじめに
おはようございます。こんにちは。こんばんは。キティちゃんです。いつもははじめに色々書いているのですが、今回書いた内容はダメと言わてしまったので、シンプルにしました。それはさておき、今日はとある認証方式の話をしていきたいと思います。

## きっかけ
二要素認証のサイトを見た時に、ふと「これ、Qiitaのネタとして使えそう」と思ったのがきっかけです。
また、二要素認証と二段階認証ってどう違うんだっけということを無くすための意味でも書きたいと思いました。(お恥ずかしながらたまにごっちゃになってしまいます。。)
ここから深堀していくにあたり、まずは二要素認証とは、二段階認証と何が違うのかについて書いていきます。

## 二要素認証
まず前提として3つの要素があります。

1.　知識
2.　所持
3.　生体

上記3つの要素から2つを組み合わせた認証方式を二要素認証といい、また、多要素認証と言ったりもします。

まず、「知識」はユーザーのみが知りえる情報のことを指します。例えば、ID、パスワードなどが該当します。

次に「所持」は、文字通り、ユーザーが保持している情報のことを指します。例えば、スマホへのSMSやメール等で通知されるワンタイムパスワードやICカードが該当します。

最後に「生体」は、人体の情報のことを指します。例えば、虹彩、静脈、指紋が該当します。

## 二段階認証と何が違うのか
言葉通り、二段階認証は認証を2回に分けて(2段階)行うことから、二段階認証と言われます。二要素認証と異なる点としては、段階的に認証を行うこと、また、同じ要素の組み合わせでもいいということです。

二要素認証は例えば、「ID情報(知識)」×「知識」以外の要素」と異なる要素を組み合わせた認証方式ですが、二段階認証は「ID情報(知識)」で認証後、「他の「知識」情報」or「「知識」以外の要素」で認証と段階的に認証を行う認証方式です。

私の記憶では、例えばTwitterにログインだか、アカウント作成だかする際に、メールアドレスを入力後、スマホにSMS通知が行き、SMSに記載された番号を入力したという記憶はありませんか？まさにあれが、「知識」×「所持」の二要素認証です。

ここで、「じゃあ、段階を分けて異なる要素で認証する場合はなんていうの？それは二段階認証じゃないの？」と思った方もいらっしゃるかもしれません。その通りです。先程も説明しましたが、二段階認証は同じ要素"でも"段階を分けることで成り立つ認証方式です。別に要素が同じである必要はありません。なので、ある意味二要素認証は、二段階認証に包含されていると言えます。ですが、あくまで二段階認証と二要素認証は"異なる認証の仕組み"であるということは理解していただければと思います。

## セキュリティ診断でも意外と面倒くさい
Webアプリケーション診断の経験がある方は分かるかもしれませんが、アタックロックがあるかもしれない認証機能を診断するためには、認証に失敗するパターンと成功するパターンをシナリオとして組んだりなんて記憶にあるのではないでしょうか。特にシナリオが長くなると診断にかかる時間も増したりするので、結構進捗に響いたりします。。特にWebアプリケーションを動作させているサーバー側の規模が小さかったりするとより悲惨です。
アタックロックはログインを要するサイトに必要な機能なのは理解していますが、なかなか診断泣かせです。アタックロックとは簡単に言うと、複数回入力に誤りがあった場合に、不正ログインができないようにロックをする機能のことです。
この辺は仕事のことなので、分からない人はいつか知るときが来た時にこの記事を思い出してください。

## 教訓
何かしらの要素を入力する場合は、アタックロックがあるかもしれないと疑うようになりました。特にWeb診断をする場合は、警戒することに越したことはないです。アタックロックがかかってからでは遅いです。場合によってはお客様に解除依頼をしたりする必要が発生するため、作業遅延に繋がります。(そうならないためにも、予備としていくつかアカウントをもらう訳ですが。。)

## 終わりに
今回は二段階認証、二要素認証について触れました。他にも認証方式はありますが、それは別の機会(はないかもしれません）にでも。

実は私自身もアタックロックがかかってしまったことがあります。まさかそんなところでって感じではあったので油断していました。。今回の内容はだいぶ前から構想としてあったのですが、アタックロックにあったことから構成を若干変えて今回のような内容となりました。勉強とかもそうですが、アウトプットすることで自分への勉強にもなるので、今後にも活かせそうです。

一人でも多くの方がアタックロックにかからないことを祈りながらココアを飲みます。最後までお付き合いいただきありがとうございました。

## 追伸
再度お伝えしますが、アタックロックは悪い機能ではなく、ログインを要するようなアプリケーションには必要な機能です。不正アクセス防止などを目的としています。一番は入力した内容に間違いがないかを見直すことです。特に、暗証番号とか自分しか知らない情報を入力して認証しようとしている画面には気を付けましょう。

## 参考
『認証強化』日立ソリューションズ
・https://www.hitachi-solutions.co.jp/iam/sp/sol_kyouka.html

『二要素認証と二段階認証の違いを理解していますか？』キャノン サイバーセキュリティ情報局
・https://eset-info.canon-its.jp/malware_info/special/detail/210311.html
ORMとの付き合いかた

## はじめに
ORMは強力なツールである一方、(ORMに限ったことではないですが)銀の弾丸にはなり得ない付き合いかただったり境界の引き方がむずかしいツールの一つであります。
我々も、ちょうど最近、新規でバックエンドアーキテクチャーを策定するタイミングがありまして。
そのときの考慮ポイントであったり、結論を共有します。
※網羅的でなかったり恣意的な内容もあるかもしれません。ご了承くださいませ。

こんな人に読んでもらいたい！
* ORMとの付き合いかたを悩んでいる人
* これからバックエンドアーキテクチャを策定する人


## 悩めるORM事情

### N+1問題

よく挙げられるのはこの問題でしょう。
注意してコーディングすることで防げることもあるようですが、ORMから生成されるSQLの状態を把握するには相応の時間とエネルギーが必要です。
たかが+1、多少のパフォーマンス劣化は目を瞑るかという現場レベルの整理もあるかとは思います。
されど+1、ユーザーアクセス増によるパフォーマンス劣化が無視できなくなったり、CPU/メモリ/ネットワークなどのリソースを消費などによる環境コスト増を考えると、防げるものは防ぎたいです。
また、DBアクセス部分は特にパフォーマンスに敏感な箇所であるため、メインの関心事は無視できないですね。

ORMの仕様に精通したエンジニアを育て上げるという固有のライブラリーに依存するためスキルの平準化がしにくい、そもそも主な関心事はORMの仕様でなく、仕様やデータ定義の妥当性でありため、むしろ投資の対象はそこにしたいです。

### SQLが隠蔽される問題

前述した「ORMの仕様に精通したエンジニア」に多少かかる内容ですが、こちらも見過ごせない問題の一つです。
特にジュニア〜ミドルエンジニアのSQLレベルアップを妨げる原因の一つになるので、私はあまり好きではないです。
ORMで生成されるSQLが、おおよそイメージができるシニアレベルのエンジニアだけで運用されるのであれば問題ないですが、
ジュニア〜ミドルエンジニアにおいて、まずはSQLがどういう範囲のデータに影響を及ぼすか把握することを優先すべきと思います。

### 複雑化するメソッドチェーン

これもあるあるかと。db.Where().Where().Where().Join()...のように(ある程度それっぽいものを想像で書いてます...)、決してシンプルに書けないケースも往々にしてあるのではないでしょうか。
この辺りは好みの問題かもですね。どのみち複雑化するのであれば、SQLの状態で品質を把握しやすい形の方が嬉しいです。



## 結論

ORMを採用することにしました。あまり依存しすぎず一部機能をDBMSに委譲したりと境界はいじりましたが。

### 美味しいところだけ使う
デメリットに対して多く記載してきましたが、ORM自体は強力なツールであることには変わりはないです。
具体的には下記の機能です(ORMライブラリーに付随する機能もあります。)。
* ORM機能
* prepared statement
* migration機能

その他にも下記のようなライブラリー固有の強力な機能もあったりします。これは利用しない手はないです。

* Hibernate 2nd level cache


### 諸問題にどう対処したか

多くの問題はVIEWを活用することで解決しました。
N+1問題については、あらかじめVIEWとしてテーブル結合して結合ロジックをDBMS側へ委譲することで問題が解消しますし、
複雑化するメソッドチェーンやSQLの隠蔽問題もあらかじめVIEW定義しておくことで、コードをシンプルに保つことができました。
終活をどう進めてゆくか

# 概要
いよいよ、終活を進めて行かなくてはならない時期にきた。
健康保険証が後期高齢健康保険証になつた。この年齢(75才)になると、いろいろなところで年齢による生活面でのパスポートに条件が課される。
先日、銀行系のカードローンが契約期限が来て解約になった。
一定の年齢に達するとカードローンも契約できなくなるらしい。年金だけの収入では許可されないらしい。
銀行も冷たい。今でも電気・ガス・水道などの引き落としは銀行口座から落としているのに。貢献はしているつもりだが。
行政側の仕事として、たとえ高齢者でも返済能力のある人へはカードローンの契約を許可させてほしい。高齢者が安心して生活できるように、銀行への行政指導をきちんとしてほしい。

# 終活内容
まず、家の中の整理・片づけをしなくてはならない。
不要なものは捨てる。断捨離する。
ここで、曽野綾子さんの書籍2017年12月発行　興陽館(￥1,100)「身辺整理　わたしのやり方」を参考にする。
## (1) 身辺整理
本日、郵送でこの本がとどきました。(全238ページ)人生の後始末には納得させられました。身軽になって逝きたいものです。何も残さずがベストです。本に書いてあることすべてに納得させられました。私もそのように逝きたいと思います。最後は野垂れ死にでもいいという、究極の思いでいれば怖いものはありません。それでいいと思います。身辺整理は何も残さないことと教えていただきました。すべて捨て去ることです。それでいいと思います。ものを残して逝くことはしない方がいいと思いました。




## (2) 遺産相続
特にこれといった遺産はないが、自宅と墓、車、少額の共済保険ぐらい。
生命保険は加入していない。株式も所有していない。預金もほとんどない。
唯一の救いは借金がないこと。息子、娘家族には迷惑をかけたくない。
葬儀費用も大して用意していないので、家族だけの、直葬でも構わない。
写真ひとつ飾って火葬してくれればよれでよい。








## (3) 葬儀・墓地
葬儀費用も大して用意していないので、家族だけの、直葬でも構わない。
写真ひとつ飾って火葬してくれればよれでよい。
墓は10年ほど前に購入した。二人とも元気なうちに購入しておこうと決めた。しかし、時代が変わって、これからはもっとシンプルな形になってゆくかもしれない。檀家にはなりたくなかった。お寺との付き合いが大変なのがわかっていた。個人で持つのではなく、市の合同墓地という墓もこれからは一般的になってくるかもしれない。墓は不要という人もいる。戒名もいらない。これからの時代はまったく、不透明である。















## (4) 介護(老老介護)
こればっかりはどちらが先に逝くかわからない。



## (5) 年金と生活
この年になると働くことはできない。老老介護ではまして働くこともままならない。したがって、年金で生活しなければならない。
わずかな年金だが、知恵を絞って夫婦二人が生活しなければならない。
食費を削るのがせいぜい。預金に回す金も残らない。孫に渡す小遣いだけはなんとか工面してあげたい。現役時代はまさか、こんなに年金がすくないのとは思ってみてもいなかった。悠々と第二の人生が送れるとおもっていた。
当時は、年金で十分海外生活もできるとのふれ込みで、海外で行った人もいたが。あれは何だったのか。






## (6) 健康・病気
健康でポックリ逝くのが最上ですが、なかなか難しいと思います。家内の母はそのような逝く方だった。風呂で亡くなっていたとのことです。
それまでは元気でいたので、おそらく心臓麻痺かなんかだったのだろう。
本人は苦痛も感じなかったかもしれません。
## (7) その思いを断ち切るには
この本は残したいとか、この写真は残したいとか思っているといつまでたっても身辺整理はできない。どうやってその思いを断ち切るかが身辺整理で一番の難題。
結局残していても残りわずかな時間に果たして見るかをよく考えてみる。
パソコン、スマホなど日々使用しているものは無理としても、日常生活では使用していないものは捨ててもいいと思わなければならない。そのうち使うかもしれないと思っているものはまず一番に捨てる。
日曜道具がたくさんある。電動の機械類、趣味のもの、高価なカメラや三脚、望遠レンズ、イタリアで買ったベネチヤのワイングラス、健康器具、
この10年間、全く使用していない。
## (8) 交際関係を断つ
現役を退くと人との交際はなくなってしまう。仲間と飲みに行くこともなくなる。そして毎日が日曜日状態になり、老いて行く。昔の同窓会には行きたくない。自慢話が始まると面白くない。豊かな生活をしている人はいいが、そうでない人は行きたくないだろう。
## (9) 車の処分をいつやるか
これが困っている。今はできない。介護で近くの医院へ通うにも車が必要で、自分ひとりなら無くてもいいかと思うが。
行き帰りにいちいちタクシーを呼ぶのも億劫だし。
## (10) 悔いはなかったか
これといった高い望みをもっては生きてはこなかった。ただ普通に生きてきた、流れに乗っていただけかもしれないが、多少の山谷はあった。これまでの人生を振り返ってみると、瀬戸際で滑り込みセーフという人生だったと思う。窮地に陥った時もなんとかクリアできた。運がよかったのかもしれない。ただ一回、若い時に九死に一生の場面があった。もうだめかとあの時は思ったが、運よく生還できた。ありがたいことに二人の子にも恵まれて、二人とも家族をもって暮らしていることがなによりもうれしい。
家内の介護もこれも運命かなと。老老介護が悪いこととは思わない。














# あとがき
終活を書いているとグチぽっくなります。こんな人生だったのかと。
情けない。若い頃は、希望にあふれ、老後のことなんかちっとも考えていなかった。人生を閉じるにあたっては、思い残すこはないことにする。あれもしたかったとか、やり残したとかということではなく、たとえ中途半端のままでも、ああ、十分生きた、これで悔いはないとして逝きたい。足跡、痕跡は残さないで。
【Unity】FSR試してみた！

最近スプラトゥーン３でAMDの超解像技術のFSR1.0が使われていることが話題になっていました。
https://automaton-media.com/articles/newsjp/20220818-215020/

このFSRですが、Unityでも簡単な設定を行うだけで使うことができます。
https://www.youtube.com/watch?v=_cKixSjjTjI

というわけで、さっそく手持ちのpixel3を利用して、アップスケールなし、FSR、そしてBilinearの３つを試してみました。
ちなみに、FSRとBilinearは内部のレンダリング解像度は50%まで落としています。

# 検証動画

[No MSAA, NoUpscale]

<iframe width="560" height="315" src="https://www.youtube.com/embed/sK-PCPKNeUo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

[MSAAx4 FSR]
<iframe width="560" height="315" src="https://www.youtube.com/embed/61ZmCQleGWU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

[MSAAx4 Bilinear]
<iframe width="560" height="315" src="https://www.youtube.com/embed/pqVDpOOUCLM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 結果まとめ

各条件でFPSは下記のようになりました。
|条件 |  FPS  | 
| ---- | ---- |
|  アップスケールなし  |  27～34  | 
|  FSR  |  40～44  |
|  Bilinear  |  55～60  |

中々にいい数字がでてます。ポストエフェクトなどを盛り込んでいくと、もっと差が出てくるはずです。

品質に関して、アップスケールなしとFSRの比較をすると、URPを拡張して描画しているボリュームライトの処理は解像度の低下によって品質が劣化していますが、ユニティちゃんの表示はなかなか綺麗だと思います。

Bilinearは一番パフォーマンスは高いですが、やはり画像にボケが発生しているのが目立ちます。

レンダリング解像度を落として、FSRを使って、ポストエフェクトをモリモリの絵作りをするというのはかなりアリなのではないかと思いました。

今度はもう少し、現実的な条件( HUDなどがある状態 )でも検証してみます。
c++ unordered_map

```
#include <iostream>
#include <vector>
#include <unordered_map>

struct Data
{
    std::string Name;
    double Customval;
}

int main()
{
    std::unordered_map<std::string, Data> dataMap;
    dataMap["Key1"] = Data{"Key1", 0.1};
    dataMap["Key2"] = Data{"Key2", 0.2};

    Data& key1Data = dataMap["Key1"];
    key1Data.Customval;
}
```
【VSCode】Markdownlintの使い方

## Markdownlintとは

Markdownlintを使用することでMarkdownの構文とスタイルをチェックできます。

## インストール

Markdownlintをインストールします。

https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint

## 基本的な使い方

### 指摘事項の確認

ルールに違反している箇所は以下の画像のように指摘されます。  
![image220824_113645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/58900894-458a-b375-da30-c8dd2a7b843f.png)

指摘されている箇所にカーソルを合わせることで指摘事項を確認できます。
![image220824_113807.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/a5683e71-bc0e-559b-2cab-4f27e1b4845e.png)


### クイックフィックス

画面に表示された青い電球マークをクリックすることでクイックフィックスを利用できます。
![スクリーンショット 2022-08-24 午前11.44.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ecc44a77-b6a0-0942-92ca-0acc3ff7defd.png)


## ルールの設定

ルールの設定を自分で行うことができます。
設定には以下の方法があります。

- `.markdownlint.jsonc`または`.markdownlint.json`に記述
- `.markdownlint.yaml`または`.markdownlint.yml`に記述
- `.markdownlint.cjs`に記述
- `setting.json`に記述
  
`setting.json`に記述する場合には以下のようにします。  

まず`cmd + shif + p`でコマンドパレットを開きます。  
`Preferences: Open User Settings (JSON)`を実行し`setting.json`を開きます。  
`setting.json`に以下を追記します。  

```setting.json
  "markdownlint.config": {
    "MD033": false
  }
```
ルールの種類については以下のページをご参照ください。

https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md

## 保存時に修正する

`setting.json`に以下のように記述することでファイル保存時に指摘事項を修正できます。

```setting.json
  "[markdown]": {
    "editor.codeActionsOnSave": {
      "source.fixAll.markdownlint": true
    }
  }
```
Unable to resolve path to module 'xxx'の対処法(pacakge.jsonでexportsが設定されている場合)

## 問題
ESLintにかけると次のようなメッセージが出る。`xxx`の部分は`node_modules`以下のパッケージ。
```shell
Unable to resolve path to module 'xxx'  import/no-unresolved
```
このエラーが出る状況は様々なようですが、今回の場合は`eslint-plugin-import`が`package.json`の`exports`を考慮してくれないことが原因でした。

https://github.com/import-js/eslint-plugin-import/issues/1810

上のissueでワークアラウンドがいくつか提案されていますが、以下では`eslint-import-resolver-typescript`を使った方法を紹介します。

## 解決策

```shell
$ npm i -D eslint-import-resolver-typescript    
```

```json-doc:.eslintrc.json
{
    // その他の設定
    "settings": {
        "import/resolver": {
            "typescript": {}
        }
    }
}
```
最小限の設定を書いただけなので、場合によっては追加の記述が必要かもしれません。
WordPressがクラッキングされたので復旧した時のメモ

WordPressで構築されたサイトがある日突然「**403 Forbidden**」に！
どうやら流行りの巡回クラッキングロボで改竄されてしまったようです。

無事に復旧できましたのでその時のメモです。ご参考に！

## クラックされた時の状況

- ブラウザで開いた時の画面は**403 Forbidden**の状態。トップページも管理画面も。
- サーバにFTPでログインして調べてみると以下のことがわかりました。

#### public_htmlディレクトリ以下のファイルのタイムスタンプをみる

- トップページのindex.phpのタイムスタンプが（更新していないのに）最近になっている。
- トップページのindex.phpのファイルアクセス権限が600になっている。
- トップページの.htaccessが（更新していないのに）最近になっている。
- 全てのディレクトリの更新時刻が（更新していないのに）最近になっている。
- 全てのディレクトリの下に（そんなもの置いていないのに）.htaccessファイルが新規追加されている。
    
**なお上記の状況と異なる場合は、今回とは別のタイプのクラッキングをされていると思われますので以下に記した手順では復旧できません。上記と同じ状況になってしまっている方は、下記の手順で復旧できると思いますので、ダメもとでお試しください。**

#### タイムスタンプが更新されているファイルの一覧を書き出してみる

sshでサーバにログインし、以下のコマンドで一覧を出力しましょう。

```
$ cd domain/public_html
$ find . -mtime -1 -type f > ~/cracked_files.txt
```

ホームディレクトリにcracked_files.txtというファイルが作成され、直近１日以内に更新されたファイルの一覧が出力されます。（クラックされた日が直近１日よりも前の場合は、例えば1週間以内に変更があったファイルを一覧したい場合は上記のオプションのところで、-mtime -7とすれば過去７日以内に変更されたファイルの一覧が出ます。

#### クラックされた内容

以上の操作により、どうやら下記のようなクラッキングを受けたことがわかりました。

- public_html/index.php　が改竄されている。
- public_html以下のすべてのディレクトリの直下に.htaccessファイル（全アクセスDenyの設定）が追加されている。

その他にもあるかもしれませんが上記の2つが403 Forbiddenの原因と思われます。

## 復旧手順

- なお断っておきますがきちんと最新のバックアップをとっている**清く正しい皆さん**は**素直に最新のバックアップからpublic_html以下のすべてのファイルを差し替え**ましょう。
- あいにくバックアップが古いのしかなかった（←典型的なダメ情シス）場合は、次の手順で復旧できましたのでやってみましょう。

#### 復旧手順1 - public_html/index.php を戻す

public_html_index.phpの内容は基本的にはWordPressをインストールしたときの状態からずっと変わりません。したがって[WordPressの本家サイトから（できるだけ）同じバージョンのインストールファイル一式をダウンロード](https://ja.wordpress.org/download/)してきて、その中のpublic_html/index.phpをコピーして改竄されたindex.phpを上書き更新すればOKです。

ちなみにindex.phpは以下のような内容です。（WordPressのバージョンにより異なるのでお使いのバージョンのものを使ってください）

どうしようもないときは下記をコピペして新たにindex.phpという名称でpublic_htmlフォルダの直下に保存すれば大丈夫です。

```
<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define( 'WP_USE_THEMES', true );

/** Loads the WordPress Environment and Template */
require __DIR__ . '/wp-blog-header.php';
```

保存したら権限を修正。

```
$ chmod 644 public_html/index.php
```

#### 復旧手順2 - 不要な.htaccessファイルを削除する

サイトの全てのディレクトリに余計な.htaccessファイルが新規追加されていますのでそれらを一括削除します。
以下のコマンドを**くれぐれも慎重に**実行してください。**一文字でも間違えると致命的レベルでサーバをぶっ壊すので自信のない方は絶対に自分の判断ではやらないでください**。

```
$ cd public_html
$ mv .htaccess .htaccess_save  (トップページの.htaccessだけは必要なので残しておきます）

$ find . -name .htaccess -type f -mtime -1 -exec rm -f {}¥; （←この呪文の意味は、「ファイル名が「.htaccess」で、かつ過去１日以内に編集されたファイルをすべて探して強制的に削除」です）

$ mv .htaccess_save .htaccess (保存しておいたものを戻す）
```

以上で復旧できたと思います。

なおパスワードがクラックされていると思われるのでパスワードを変更し、FTPではなくSFTPやSCPのみを用いるとか、IPアドレス制限をするとか、何らかの追加セキュリティ対策が必要ですので、すぐにやってください。


以上、お疲れ様でした。:smile_cat: