OmniAICreator/Qiita-1.07M huggingface dataset:
京セラDIGNO端末(Android)にAPKセットを転送できない

つまらないことですが時間がかかってしまったのでメモ書きという言い訳で投稿

### 問題
[Android App Bundleを実機にインストールして試すために使うbundletoolの使い方](https://www.virment.com/how-to-use-bundletool-to-test-app-locally/) に従って

```
$ java -jar bundletool.jar install-apks --apks=app.apks
```

のコマンドでAPKセットを転送しようとしても許可がありませんという（Error: Authorization is not allowed のような）エラーが出て転送できないという状況です。

```
$ adb devices
```
のコマンドでも unauthorized と表示されます。


### 環境
windows10
android端末(スマホ) Kyocera DIGNO

### 結論
初歩的な話で、 [Kyocera DIGNO のドライバ](https://www.kyocera.co.jp/prdct/telecom/consumer/lineup/wx04k/developers/) のインストールが必要だっただけです。

### ただ、
インストール後もWindowsの(ファイル)エクスプローラーでの表示は以下のアイコンのまま。(DIGNOの端末をUSB-typecケーブルでPCから繋いでいます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501146/9e3b4f71-d98a-0ecc-fce9-4116d510d98a.png)
：不明なデバイス

Windowsが不明なデバイスとして認識した場合に選択されるアイコンで表示され、プロパティを見たりしようとしても「このデバイスに対する許可がありません。」となるまま。

この文言で検索してもヒットしなかったので記事を書きました。。
情報処理安全確保支援士試験を合格するために読んだ本まとめ


### 情報処理安全確保支援士試験について

> https://www.jitec.ipa.go.jp/1_11seido/sc.html
> サイバーセキュリティリスクを分析・評価し、組織の事業、サービス及び情報システムの安全を確保するセキュリティエンジニアや、技術・管理の両面から有効な対策を助言・提案して経営層を支援するセキュリティコンサルタントを目指す方に最適です。
> 春季・秋季に試験実施予定

---

### どこが難しかったか

- （初学者にとって）いきなりセキュリティ分野を勉強するのは、とっつきにくい
- 過去問は無料公開されてるが解説がなく、とっつきにくい
- 独特の文章問題があり、とっつきにくい

---

### 読んだ本１

- 「要点早わかりネットワークスペシャリストポケット攻略本」
> https://www.amazon.co.jp/dp/B01BGL7VBC/ref=cm_sw_r_tw_dp_G1GXEF1M4SW2C445M1MS

- ネットワークの基礎知識を学ぶために読んだ
- ネットワークスペシャリスト試験用であるが、セキュリティについても触れている
- 一通り網羅する目的であり、深い所までは読み込まない

---

### 読んだ本2

- 「情報処理安全確保支援士「専門知識+午後問題」の重点対策 (重点対策シリーズ) 」
- 「情報処理安全確保支援士パーフェクトラーニング過去問題集」

> https://www.amazon.co.jp/dp/4865752404/ref=cm_sw_r_tw_dp_A0WSK9K7EAM2YQ4ZRSY9?_encoding=UTF8&psc=1 
> https://www.amazon.co.jp/dp/4297125269/ref=cm_sw_r_tw_dp_DKCQGGKJFNMAVCP1WW92?_encoding=UTF8&psc=1 

- 過去問集
- 過去4回分を一通り網羅する（午前2,午後1,午後2）
- 午前1は共通試験であり免除者は不要かもしれないが、復習に便利である

---

### 読んだ本3

- 「うかる! 情報処理安全確保支援士」
> https://www.amazon.co.jp/dp/4532415462/ref=cm_sw_r_tw_dp_YA4QSFRJ6WREW5J1H7N1?_encoding=UTF8&psc=1 

- 試験対策本
- 出題範囲は過去問からであり、新しい知識を得るというよりかは、要点の整理に活用
- 過去数年間の出題ポイントや、回答観点が整理されており分かりやすい

---

### まとめ

- ネットワークスペシャリスト試験の範囲を含めて勉強すると後が楽だった（私の場合）
- 過去問は4回分を解ければ良かった（私の場合）
- 午前1はなるべく免除制度を活用したい（勉強リソースを午後問題対策に集中したい）

---

### とはいえギリギリ合格ですので、ご参考程度にして下さい

![20220220_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/6c24a53b-73e1-f9dc-ae56-3c2166a4f838.png)

---

以上
priority_queue

優先度付きキューというデータ構造を管理できる型(降順、昇順など)

a.push(x) (xを追加)

a.pop() (xを削除)

a.top() (xを習得)

a.size()

a.empty()

計算量は O(logN)


```c++
//最も小さい値を取り出す(定義)
priority_queue<int, vector<int>, greater<int>> a;

//最も大きい値を取り出す(定義)
priority_queue<int, vector<int>, less<int>> b;
```
【Laravel】ルートパラメータ制約は「正規表現」よりも「ヘルパメソッド」をお勧めしたい理由

# ルートパラメータを制約するには？

Laravelは、ルート情報に `where` メソッドをチェーンして、ルートパラメータに制約をかけることができます。

```web.php
// 例1：
// 「name」パラメータはアルファベット大文字か小文字の1文字以上であること
Route::get('/user/{name}', [SampleController::class, 'name'])
    ->where('name', '[A-Za-z]+');
 
// 例2：
// 「id」パラメータは数字1文字以上であること
Route::get('/user/{id}', [SampleController::class, 'id'])
    ->where('id', '[0-9]+');

// 例3：
// 「id」は数字1文字以上かつ「name」はアルファベット小文字の1文字以上
Route::get('/user/{id}/{name}', [SampleController::class, 'id_name'])
    ->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
```

ルートパラメータが1つの場合は、`where` メソッドの第1引数に「パラメータ名」を、第2引数に「制約の正規表現」を指定します。
ルートパラメータが、上記 `例3` のように複数ある場合は、`where` メソッドの引数を連想配列にして対応できます。

# ルートパラメータ制約にヘルパメソッドを推したい理由

さて、このようにルートパラメータの制約をする際は `where` メソッドを使用するだけでも十分に機能するのですが、この **`where` メソッドを使用しない「ヘルパメソッドを活用した制約」** があるのはご存知でしたか？

## whereNumber メソッド

`whereNumber` メソッドは、**1文字以上の数字であること** を制約とします。引数にルートパラメータ名を記入します。

```web.php
Route::get('/user/{id}', [SampleController::class, 'id'])
    ->whereNumber('id');
```


## whereAlpha メソッド

`whereAlpha` メソッドは、**アルファベットで大文字か小文字の1文字以上であること** を制約とします。引数にルートパラメータ名を記入します。

```web.php
Route::get('/user/{name}', [SampleController::class, 'name'])
    ->whereAlpha('name');
```

## whereAlphaNumeric メソッド

`whereAlphaNumeric` メソッドは、**アルファベットの大文字もしくは小文字、または数字の1文字以上であること** を制約とします。引数にルートパラメータ名を記入します。

```web.php
Route::get('/post/{slug}', [SampleController::class, 'slug'])
    ->whereAlphaNumeric('slug');
```

このように、ヘルパメソッドを活用した制約をチェーンすることで、**メソッド名自体が何の制約をするのかが想像できるような名前となっている** ので、処理のイメージがより分かりやすくなります。

ぜひ、積極的に使用してみてはいかがでしょうか？(=ﾟωﾟ)ﾉ



参考URL：
https://laravel.com/docs/9.x/routing
https://readouble.com/laravel/8.x/ja/routing.html
Azure ADからGoogle WorkspaceへのSSO設定のポイント

#やりたいこと
個人で契約しているAzure ADからGoogle WorkspaceへのSSOを設定したい。

#公式ドキュメント

## Azure AD側
https://docs.microsoft.com/ja-jp/azure/active-directory/saas-apps/google-apps-tutorial

※Google Workspace側はユーザー単位でSSOのON/OFFができないとあるが、
最近の機能追加により実現可能となった（後述）。

## Google Workspace側
https://support.google.com/a/answer/6349809?hl=ja

## 補足
自動プロビジョニングする場合はこちら。

https://docs.microsoft.com/ja-jp/azure/active-directory/saas-apps/g-suite-provisioning-tutorial

#ポイント

## SAMLリクエストの発行元の確認方法
開発者ツールでAzure ADへ飛ばされるリクエストを見て、エンコードされた文字列を取得する。
（例えば）VSCodeでSAML Extensionを入れる。エディタに上記の文字列を貼り付け、
全選択→コマンドパレット→SAML: Decode and Inflate elementでAuthnRequestの中身が見える。
ProviderNameを確認し、Azure ADで設定したものと一致しているか確認する。

## Logout URLは固定値を使う
```
https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0
```
を使う。
Azure ADで生成されるURL（Login URLと同じもの）を使うとログアウト時にエラーとなるので注意。

https://github.com/MicrosoftDocs/azure-docs/issues/75124

## 組織部門やグループ単位でSSOをONにするには、先に組織全体でSSOを設定する
`組織向けのサードパーティ の SSO プロファイル`で設定後、
`セキュリティ`→`サードパーティのIdP による SSO`→`SSO プロファイルの割当の管理`から
組織部門またはグループ単位での個別設定ができる。
Azure AD側に無いユーザーは特定の組織部門かグループに入れて、SSO対象外に設定して使う。

https://support.google.com/a/answer/10723804?hl=ja
【iOS】UnitTestプロジェクトのディレクトリ内にあるJSONファイルのロード方法

# 課題
UnitTestをする時にテストデータのJSONファイルを、アプリ本体のディレクトリではなく、UnitTestのディレクトリに配置し、Test実行時に読み込もうとしたら、上手く読み込みができなくてハマったので解決方法を記事にしました。

今回やろうとしたことは、画像で見ていただいたほうが早いかもしれません。
![スクリーンショット 2022-02-21 16.30.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580445/530fb202-32eb-05ef-6f04-52f117791647.png)

上記のように、`QiitaPracticeTests`（UnitTest）のディレクトリ直下にテストデータ（JSONファイル）を配置している状態。

これをやる理由としては、テストでしか使わないデータを、アプリ本体のプロジェクトに入れたくないからです。
**→ 混乱するので、テストデータはテストディレクトリにしか入れたくない。**

### エラーになるコード
```swift
class QiitaPracticeTests: XCTestCase {    
    private func loadJson(fileName: String) -> Menu {
        
        let data: Data
        // ファイルの存在チェック・取得
        guard let file = Bundle.main.url(forResource: fileName, withExtension: nil) else {]
            // ↓ここに入ってエラーになります。
            fatalError("\(fileName) が存在しません")
        }
        // ファイルの読み込み
        do {
            data = try Data(contentsOf: file)
        } catch {
            fatalError("\(fileName) の読み込みに失敗しました。\n\(error.localizedDescription)")
        }
        
        do {
            let decoder = JSONDecoder()
            let object =  try decoder.decode(Menu.self, from: data)
            return object
        } catch {
            fatalError("デコードに失敗しました。\n\(error.localizedDescription)")
        }
    }

    func testExample() throws {
        let menu = loadJson(fileName: "menu.json")
        print(menu)
    }
}
```

`testExample()`を実行すると、ディレクトリにあるファイルを見つけられずに、
`fatalError("\(fileName) が存在しません")`のところに入ってしまいます。

# 原因
`Bundle.main`としてしまうのが、問題の原因です。
上記では、テストプロジェクトにある、リソースを取得できないようです。

# 解決方法
`Bundle.main.url(forResource: fileName, withExtension: nil)`
の1行を、
`Bundle(for: QiitaPracticeTests.self).url(forResource: fileName, withExtension: nil)`
と修正するれば、ファイルが取得でき、期待通りに動くようになります。

`QiitaPracticeTests`は、メソッドを実行する対象のクラス名になります。

https://stackoverflow.com/questions/34980996/how-to-load-a-local-json-file-in-xcode-for-unit-test-purposes

上記のstackoverflowを参考にして解決しました。

今回は、以上となります。
PEAR Crypt BlowfishをOpenSSLにリプレースする

PHP5.5から7.3へのバージョンアップ作業で、
既存サーバで使用している暗号化ライブラリがPHP7.3で非推奨の Crypt_Blowfish だったため、
推奨されている OpenSSL にリプレースする必要がありました。

# 作成した関数

まずは完成したコードから。

```php:openssl.php
    public function encrypt($plain_text)
    {
        // 暗号鍵の読込
        $pass_phrase = 'angoukanokagiwoiretene';

        // パディング処理
        if ($m = strlen($plain_text) % 8)
        {
            $plain_text .= str_repeat("\x00", 8 - $m);
        }

        $encrypt = openssl_encrypt(
            $plain_text,
            'bf-ecb',
            $pass_phrase,
            OPENSSL_RAW_DATA | OPENSSL_NO_PADDING
        );

       return base64_encode($encrypt);
    }

    public function decrypt($encrypted_text)
    {
        // 暗号鍵の読込
        $pass_phrase = 'angoukanokagiwoiretene';

        $decrypt = trim(
            openssl_decrypt(
                base64_decode($encrypted_text),
                'bf-ecb',
                $pass_phrase,
                OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
            )
        );

        return $decrypt;
    }
```

シンプルなコードですが、この形になるまでに色々とつまずきました。

## つまずいた項目

### パディング処理の実装

テキストをパディングしてから暗号化する事は分かっていましたが、
見つけたサンプルコードもそれぞれ違う実装のため右往左往していました。
私の場合は下記ページの実装方法がドンピシャでした。

https://github.com/LancersDevTeam/PHP_versionup/blob/master/PHP5.6toPHP7.3/1.1_mcrypt%E5%AF%BE%E5%BF%9C.md

### 第二引数 暗号メソッド(cipher_algo)はどれなのか

正解はECBモードだったのですが、
CBCモードだと思い込んでいて気付くまで時間が掛かりました。

### 第四引数 指定するoptionsは何か(openssl_encrypt)

https://www.php.net/manual/ja/function.openssl-encrypt.php

> OPENSSL_RAW_DATA と OPENSSL_ZERO_PADDING のビット OR。

リファレンスでは上記の説明でしたが、
下記ページを参考に **OPENSSL_NO_PADDING** を指定し、
パディング除去が行われないようにする必要がありました。

https://blog.shin1x1.com/entry/openssl-add-pkcs7-padding

### 第五引数 初期化ベクトル(Initialization Vector)が不要だった

BlowfishでIVを渡して使用していたため、
OpenSSLにリプレースする場合も第五引数にIVを渡すのが必須だと思い込んでいました。

Blowfishで使用していたIVをそのまま渡すと長さが違うと怒られるので、
IVにも何かしら処理を加えて渡さないといけないのか？と悩んでいました。

# 参考ページ

https://qiita.com/Uchikoba/items/7784e1f1eb7bae3b1593
クラスメソッド(Classmethod)の(DevelopersIO)記事を参考にしてPhysicalResourceIdを雑に扱ってAWSカスタムリソースを作るとおかしいことになるのでAWS公式のドキュメントをちゃんと見よう

# 先行研究

CDKではないけど参考になる

- https://qiita.com/willco21/items/534436ba89a3c6f217ac

# TL; DR

- PhysicalResourceId はちゃんと指定しよう。何も考えずに `context.logStreamName` をそのまま使うのはやめよう。

```JavaScript:custom_resource_lambda.js
function sendResponse(event, context, responseStatus, responseData) {
   var responseBody = JSON.stringify({
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
        // ↓ ここをちゃんと管理しないとカスタムリソースのDELETEが無駄に発生するので、
        // ↓ `context.logStreamName` をそのまま使うのはやめよう
        PhysicalResourceId: context.logStreamName,
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        Data: responseData
    });
```

- ちゃんと公式のドキュメントを読もう。クラスメソッドの技術ブログだからといってそのまま使うのはやめよう。


## 見るべき記事

- https://ks888.hatenablog.com/entry/2017/05/18/123000
- https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html
- https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html
- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html

## 見るべきではない記事(見るべきではないのでリンクしない)

- `https://dev.classmethod.jp/articles/get-latest-ami-by-using-lambda-backed-custom-resources/`
- `https://dev.classmethod.jp/articles/cloudformation-lambda-backed/`

## 何が問題か？

カスタムリソースの応答を返す為に作られた、この関数が問題です。

```JavaScript:lambda.js
//Sends response to the pre-signed S3 URL
function sendResponse(event, context, responseStatus, responseData) {
   var responseBody = JSON.stringify({
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
        PhysicalResourceId: context.logStreamName,
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        Data: responseData
    });
```

ここでカスタムリソースの削除を検知するために `PhysicalResourceId` へ文字列を設定するのですが、デフォルトの値は Amazon CloudWatch のログストリームの名前です。
この名前は時間経過とともに変わっていくため、久しぶりにカスタムリソースを更新したつもりが、(`PhysicalResourceId`が変わってしまって)更新のあとに削除が入り込む流れになってしまうことがあります。そのため、設定したカスタムリソースの削除とは何なのかをちゃんと把握して `PhysicalResourceId` を設定する必要があります。デフォルト実装(あるいはクラスメソッドの技術ブログの実装の単純コピペ)で設定してしまうと、忘れた頃に酷い目に遭うかも知れません……。

**ちゃんと公式のドキュメントを読もう。クラスメソッドの技術ブログだからといってそのまま使うのはやめよう。理解しないままパラメータに適当な値を指定するのはやめよう。**
RailsでRSpecを使う

## Rspecを使う前の事前準備

### RSpecのインストール

‘rspec-rails’というgemをインストールするとRSpecとRSpecのrails用の機能がインストールできます。

```ruby
group :test do
  gem 'rspec-rails' # test環境だけにインストールする
end
```

 bundle install

gemのインストールが終わったら以下のコマンドでRSpecに必要なディレクトリと設定ファイルが作成されます。

```
rails g rspec:install
```

これでrspecのインストールは終了です。

### Capybaraのを利用できるようにする

・Capybaraとは
Webアプリ用のE2E（ある機能の初めから終わりまで）テスティングフレームワークのこと。Webアプリをブラウザで自動実行してくれる。
Capybaraを利用することで、実際にユーザーがアプリを利用する状態をテストすることができます。

・Capybaraの設定
RSpecのテストでCapybaraを使えるよう```spec/helper.rb```に設定を追記します。

```ruby
require 'capybara/rspec' # 追加

RSpec.configure do |config|
  config.before(:each, type: system) do # ここから
    driven_by :selenium_chrome_headless
  end                                   # ここまで追加
end
```

### FactoryBotのインストール

・FactoryBotとは
テストデータを簡単に作成できる機能を提供してくれるgemのこと。

・FactoryBotのインストール

```ruby
group :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails' # 追記
end 
```

bundle install

## RSpecの基本文法

```ruby
describe '何をテストするのか(テストをする対象)', type: 'specの種類' do
  context 'ある状態・状況' do
    before do
	  # テストをする前の事前準備
	end
	it '個別のテスト内容（~であるべき内容を書く）' do
	  # テスト内容
    end
  end
end
 
```

'it'が実際のテストに当たる部分。'describe', 'context'は'it'に至るまでの状況の場合分けをする部分です。例えば、ユーザーがログインしているかしていないかで表示が分かれているであろうページをテストする場合

```ruby
describe 'task一覧の表示をテストする', type: 'system' do
  context 'ユーザーがログインしている場合' do
    before do
	  # ユーザーをログインさせておく
	end
    it 'task一覧が表示されること' do
	  # task一覧の表示をチェックするコード
    end
  end
  context 'ユーザーがログインしていない場合' do
    # before doは必要無い
    it '　task一覧が表示されないこと' do
	  # task一覧が表示されないことをチェックするコード
    end
  end
end
 
```

となります。
2つ目の'context'はユーザーのログインをする必要がないため```before do```は必要ありません。もし、両方のcontextでユーザーのログインが必要な場合はcontextの外にユーザーログインの```before do```を記述すればOKです。

・FactoryBotを使いユーザーを作成する
テストをする上で検証しなければいけないデータがある場合、FactoryBotを使いデータを作成しやすい状況にしておきます。

```ruby
FactoryBot.define do
  factory :user do
    name {'user_1'}
    email {'test@co.jp'}
	password {'password'}
  end
end
```

先ほどのテストファイルで使用する場合FactoryBotを使いユーザーを作成、ログインさせる場合

```ruby
describe 'task一覧の表示をテストする', type: 'system' do
  before do
    user_a = FactoryBot.create(:user) # ここでユーザーが作られる
  end
  context 'ユーザーがログインしている場合' do
    before do
	  # ユーザーをログインさせる
    end
    it 'task一覧が表示されること' do
	  # task一覧の表示をチェックするコード
    end
  end
  context 'ユーザーがログインしていない場合' do
    # before doは必要無い
    it '　task一覧が表示されないこと' do
	  # task一覧が表示されないことをチェックするコード
    end
  end
end
```

## RSpecを実行する

テストコードが書けたら実際にテストを実行してみましょう。

```ruby
bundle exec rspec # 実行するファイル名を続けて書くとそのファイルだけが実行される。
```

```ruby
2 examples, 0 failure
```

```0 failure```と表示されれば全てのテストが成功していることになります。
vector

vector< int > a;

a.push_back(x); (末尾に追加)

a.pop_back();　(末尾を削除)

a.size()

a.clear() (全ての要素を削除)

```c++
sort(a.begin(), a.end())
sort(a.begin() + l, a.begin() + r)
```
erase( 削除 )の使い方
```c++
 // (1)
  {
    std::vector<int> v = {1, 2, 3, 4, 5};

    v.erase(v.begin() + 2);
    print("(1)", v);
  }

  // (2)
  {
    std::vector<int> v = {1, 2, 3, 4, 5};

    v.erase(v.begin(), v.begin() + 2);
    print("(2)", v);
  }

  //a.end() = a.begin() + a.size() - 1
```

```c++
(1) : {1, 2, 4, 5}
(2) : {3, 4, 5}
```
【Javaのデータ型の操作①】プリミティブ型のデータ・参照型

## はじめに
オラクル認定資格教科書 Javaプログラマ Silver SE８
第一章　Javaの基本　
第二章　Javaのデータ型の操作←　ｲﾏｺｺ！！
第三章　演算子と判定構造の使用
第四章　配列の作成と使用
第五章　ループ構造の使用
第六章　メソッドとカプセル化の操作
第七章　継承の操作
第八章　例外の処理
第九章　Java APIの主要なクラスの操作

## データ型について
Javaには大きく分けて**プリミティブ型**と**参照型**の２つのデータ型がある。
数値（整数、浮動小数値）、真偽値、文字を扱うのがプリミティブ型（値そのものを扱う）
オブジェクト型、列挙型、配列型を扱うのが参照型（インスタンスへの参照）

## プリミティブ型
数値、真偽値、文字を扱うのがプリミティブ型（値そのものを扱う）
### プリミティブ型一覧
| データ型 | 値 | 
|:-----------|:------------|
| boolean | true, false |
| char | 16ビットUnicode文字¥u0000~¥uFFFF |
| byte | 8ビット整数　-128~127 | 
| short | 16ビット整数　-32768~32767 | 
| int | 32ビット整数 -2147483648~2147483647 | 
| long | 64ビット整数　とりあえずintよりいっぱい | 
| float | 32ビット単制度浮遊小数点数 | 
| double | 64ビット倍精度浮遊小数点数 | 

### リテラルとは
リテラルとは、ソースコード中に記述する値のこと。
Javaには、整数、浮動小数値、真偽値、文字の４つのリテラルある。
デフォルトでは、`整数: int型、浮動小数値: double型、真偽値: boolean型、文字: char型`

##### 型変換
リテラルを他のデータ型であることを明示したい場合は、「100L」や「3.0F」のようにlong型であれば「L」や「l」、
float型であれば「F」や「f」といった接尾詞をつける。
なお、byte、shortに対応した接尾詞はない。

#### 整数リテラル
`byte、short、int、long`
整数リテラルの記述は2進数、8進数、10進数、16進数でできる。
記述する際は次の接頭詞をつける。
2進数「0b」、8進数「0」、16進数「0x」

整数リテラルでは数字以外に、「_」(アンダースコア)を使用できる。
ただし、リテラルの先頭と末尾、記号の前後には記述できない。

##### 進数
| / | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:---|:---|:---|:---|:---|:---|:---|
| 2進数 | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000| 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 | 10000 |
| 8進数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 |
| 16進数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 |

#### 文字リテラル
`char`
char型は文字を表すデータ型（文字列ではない）
文字リテラルは「'a'」シングルクォーテーションで括る。
文字**列**リテラルは「"a"」ダブルクォーテーションで括る。

char型の変数に代入できるのは以下の３種類
・シングルクォーテーションで括った文字（単文字）
・シングルクォーテーションで括った「¥u」から始まるUnicode番号(文字リテラル)
・0~65535までの数値
　→Unicodeでは16進数4桁で記述するが、これを10進数に直すと0~65535となる。

## 参照型
オブジェクト型、列挙型、配列型を扱うのが参照型（インスタンスへの参照）
参照型の変数はオブジュエクトへの参照（リンク）を保持する。

## リンク集
[【Javaの基本①】クラスの構造](https://qiita.com/vitamin_b12/items/3f920cd223fd3cc1ceae)
[【Javaの基本②】パッケージとインポート](https://qiita.com/vitamin_b12/items/be766c8c3ef2366d9fea)
[【継承の操作②】インターフェース](https://qiita.com/vitamin_b12/items/cdc76298d7f6a494dff2)
[【Javaのデータ型の操作①】プリミティブ型のデータ・参照型](https://qiita.com/vitamin_b12/items/f922ab56e4d8b6580f49)
[【演算子と判定構造の使用①】論理演算子(&&、||)、同一性（==）、同値性(equals)](https://qiita.com/vitamin_b12/items/9feb89e8fb1bc67a8d6d)
[【演算子と判定構造の使用②】分岐処理(if、swich)](https://qiita.com/vitamin_b12/items/523467908e683474eac7)
[【配列の作成と使用】](https://qiita.com/vitamin_b12/items/2fc45588640c479e1f4d)
[【ループ構造の使用】while文、do-while文、for文、拡張for文](https://qiita.com/vitamin_b12/items/23d853dda9baf727e4ac)
[【メソッドとカプセル化の操作①】メソッドの概要](https://qiita.com/vitamin_b12/items/215ad731221c2691c441)
[【メソッドとカプセル化の操作②】オーバーロード、コンストラクタ](https://qiita.com/vitamin_b12/items/e4fd3d51a35bb6a5566c)
[【継承の操作①】クラスの継承](https://qiita.com/vitamin_b12/items/19f8ad6f9801ac8f6a8f)
[【例外の処理】](https://qiita.com/vitamin_b12/items/f7ebf2c1106a7dcbdb41)
[【Java APIの主要なクラスの操作】](https://qiita.com/vitamin_b12/items/dcd3edfe2273e5a09231)
【JavaScript】filter()の使い方

# filter()の使い方
``filter()``は、コールバック関数で指定された条件を満たす要素だけを取り出して新しい配列を生成するメソッド。``filter()``の基本的な書き方は以下となる。

```javascript
// arrayは配列
array.filter((element, index, array) => {
    //　処理内容
});
```
上記のようにコールバック関数は以下の3つの引数を取る。ただし、```index```と```array```については省略可能。
■ **element** : 配列の要素の値
■ **index** : 配列のインデックス
■ **array** : 処理対象の配列
また、コールバック関数は既に削除済みや未代入の添字に対しては呼び出されず、値が代入されているもののみが呼び出される。

``filter()``を使って配列の要素から偶数だけを取り出す簡単なサンプルが以下となる。

```javascript
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const result = array.filter((value) => {
	return value % 2 === 0;
});
console.log(result);    // [ 2, 4, 6, 8, 10 ]
```
また、オブジェクトを要素に持つ配列の場合のサンプルが以下となる。

```javascript
const array = [
	{ id: 1, score: 70 },
	{ id: 2, score: 50 },
	{ id: 3, score: 55 },
	{ id: 4, score: 85 },
	{ id: 5, score: 60 },
];

const result = array.filter((value) => {
	return value.score >= 60;
});
console.log(result);    // [ { id: 1, score: 70 }, { id: 4, score: 85 }, { id: 5, score: 60 } ]
```

もし条件を満たす要素が存在しない場合は空の配列``[]``が返される。
sort

sort(a, a + N); (a[0] ~ a[N-1])

sort(a + l, a + r); (a[l+1] ~ a[r-1])

sort(a, a + N, greater< int >()); (大きい順)

計算量は O(NlogN)

string 型のソートでは、辞書式順序で早い方が小さいとみなされる
100日でSQLの達人になる@LeetCode! Day21 <cross join>

## 1280. Students and Examinations （問題レベル: Easy）要課金
今日の問題はこれ。
IDと名前の入ったテーブル、科目名のみが入ったテーブル、IDと科目名の入ったテーブルと３つのテーブルから、各生徒が各科目毎に何回試験を受けたかをリストアップするという問題。

なかなか、ややこしいテーマではあるが、ひとつずつ積み重ねていけば問題自体は簡単。

今回のポイントは`cross join`句。これを使えば2つのテーブルの総当りのテーブルが作成できる。`left join`などと違って`on`で条件指定も不要。

一応、私の最終回答を載せておきます。
最初に総当りで生徒と科目の表を作成しておき、その表に、試験回数を集計した結果を`LEFT JOIN`するという考え方。
`NULL`の出力を避けるために`ISNULL`関数を使用しています。
```
SELECT c.student_id, c.student_name, c.subject_name, ISNULL(num.num,0) as attended_exams
FROM
　　　　(SELECT s.student_id, s.student_name, sub.subject_name
　　　　　　　　　FROM students s
　　　　　　　　　CROSS JOIN subjects sub) c
LEFT JOIN
　　　　(SELECT student_id, subject_name, count(*) as num
　　　　　　　 FROM examinations
　　　　　　　 GROUP BY student_id, subject_name) num
ON c.student_id=num.student_id and c.subject_name=num.subject_name
ORDER BY c.student_id ASC, c.subject_name ASC
```

* [LeetCode](https://leetcode.com/)の問題は、MS SQL Serverで解いています。
reverse

reverse(a, a + N) (a[0] ~ a[N-1] を逆順にする)

reverse(a + l, a + r) (a[l] ~ a[r-1] を逆順にする)

計算量は O(N) 

```c++
 int a[8] = {8, 3, 7, 1, 4, 6, 2, 5};
 reverse(a + 2, a + 7);
```

```c++
{8, 3, 2, 6, 4, 1, 7, 5}
```
コルーチン非常識から少しだけまともになれるかもしれない記事

#概要
unityで2Dゲームのターン制バトルを実装中にプレイヤーの入力を待たせる処理の実装とデバッグに悩んだので解決策の一つを置いておきます。コルーチンを自分以外の処理を停止する処理であると思っていた非常識の書く、上記の解決策を含むメモです。

#対象
* unity超初心者の方
* コルーチンで処理を止めたいのにyield return --- を置いても止まらない、という状況に陥っている方

#状況
```c#:example.cs
//usingなど頭の部分は省略します

void start(){a();}
void update(){}

void a(){
 for(int i=0;i<3;i++){
   StartCoroutine("player");
   boss();
 }
}
IEnumerator player(){
 //何かプレイヤーの処理
 yield return new WaitUntil(()=>Input.anyKeyDown);
}
```
プレイヤーとボスが互いにHPを削りあうというターン制バトルなら、このコードでは一瞬でプレイヤーのHPが0になります。
#対処法
```c#:example_REVISED.cs
//usingなど頭の部分は省略します

void start(){StartCoroutine("a");}
void update(){}

IEnumerator a(){
 for(int i=0;i<3;i++){
   //何かプレイヤーの処理
   yield return new WaitUntil(()=>Input.anyKeyDown);
   boss();
 }
}
```
結論から言うと、コルーチンは非同期処理ということです。
**コルーチンが実行中でもコルーチン以外の部分は進行している**ことが問題点になります。なので、ターン制を管理するループまるごとコルーチンに含めましょう。そうすればどんなループも一時停止できます。

[非同期処理について](https://www.rworks.jp/system/system-column/sys-entry/21730/)
[waituntilの書き方について](https://docs.unity3d.com/ja/current/ScriptReference/WaitUntil.html)
【JavaScript】実行環境のネイティブDEFLATE実装を使えるCompressionStreamsAPI

こんにちは。

今回は、個人的に地味に待望していた機能が実装されたので、そのご紹介となります。

# ネイティブの圧縮伸張
- [Compression Streams API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API)

昨今のHTTP通信は、帯域や読込時間を削減するために何らかの圧縮処理がほぼ必ず施されています。
そして、それらの圧縮処理は実行エンジン内部で自動的に行われているため、ふだん私たちがJavaScriptでHTTP通信するときは意識する必要もありません。
しいて言えば `Accept-Encoding` ヘッダでどのアルゴリズムが使用されているか、垣間を見ることができるくらいです。

最近のJavaScriptは他の言語と遜色ないほど高速で汎用になり、バイナリ操作や計算をする機会も増えてきました。
私も「汎用ランタイム環境としてのChromium系」というかたちでウェブアプリを作成しています。

その過程で、やはりデータを圧縮したり伸張したりしたい場面は出てくるもので、しかし標準機能としては提供されていないため、何らかのサードパーティ製ライブラリを使用する必要がありました。
(幸いJavaScriptには [pako](https://github.com/nodeca/pako) という優秀なライブラリがあるので重宝していました)

しかし、上述のとおり実行エンジン内部でHTTP通信のために圧縮処理をしているということは、内部にも圧縮機構を搭載していることを意味します。
しかもネイティブなので実行速度も信頼性も断然上です。

この内部の圧縮機構をJavaScript上で使えるように整備したAPIが `CompressionStream` というわけです。
HTTPで使用される圧縮アルゴリズムは [DEFLATE](https://datatracker.ietf.org/doc/html/rfc1951) 系なので、大抵の場合は [zlib](https://datatracker.ietf.org/doc/html/rfc1950) が実装されています。
(正確にはもうひとつ [brotli](https://ja.wikipedia.org/wiki/Brotli) と呼ばれるアルゴリズムも搭載されていますが、これは巨大辞書を使用した文章を高効率で圧縮するためのアルゴリズムなので、今回は除外しています)

# 使用例
名前に "Stream" とあることからも分かるように、このAPIは [Streams API](https://developer.mozilla.org/ja/docs/Web/API/Streams_API) のなかで機能します。
ストリームは、通信においては便利な仕組ですが、ことバイナリ操作においては、そのまま使用するには少し複雑な場合があります。
そこで、バイナリデータも簡単に扱えるラップ関数を用意してみました。

```js:compression.js
function deflateEncode(data, gzip){
    return new Response(new Blob([data]).stream().pipeThrough(new CompressionStream(gzip ? "gzip" : "deflate"))).arrayBuffer();
}

function deflateDecode(data, gzip){
    return new Response(new Blob([data]).stream().pipeThrough(new DecompressionStream(gzip ? "gzip" : "deflate"))).arrayBuffer();
}
```
まず、入力されたデータをBLOBへ変換します。
これは `Blob.prototype.stream()` を使用するためで、固定データをストリーム化するいちばん手っ取り早い方法です。

次に、ストリームを `CompressionStream` へパイプします。
`CompressionStream` インスタンスは `readable` と `writable` プロパティを持っているので、そのままパイプの接続先として適用できます。
なお、圧縮アルゴリズムはDEFLATEとGZIPを選択できます。
どちらもアルゴリズム自体は同じなので、単純にファイルシステム周りのオプションヘッダの有無ということになりますが、ファイルシステムと切り離されているJavaScript上で圧縮にGZIPを使うのはあまり意味がないようにも思えます。
GZIPは受けたデータを伸張する場合に活躍しそうです。

最後に、ストリームを終端して `ArrayBuffer` で返します。
`Response` は本来 `fetch` 関連として実装された機能ですが、仕様としてネットワーク通信からは切り離されており、任意のストリームを受けることができます。
そのうちのひとつとして `fetch` の応答があるわけです。
`Response`も `Blob.prototype.stream()` と同じく、ストリームを固定データ化するいちばん手っ取り早い方法です。

適当なサンプルデータを用意して圧縮してみるサンプルです。
なおランダムなので圧縮率は低いです。
Chrome v98 で実行しました。

```js:compression-sample.js
const sample = new Uint8Array(new Float32Array(4 * 0x100000).map(() => Math.random()).buffer);
const encode = await deflateEncode(sample, false);
const decode = await deflateDecode(encode, false);
```

![compression-stream.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253070/9c357e61-9811-79c8-9a5a-baf4b82fd484.png)

denoでも使えます (v1.19で待望の実装!)

# さいごに
他にも、ネイティブ実装を整備してJavaScriptで活用しようとする試みがいくつかあるので、そのうち紹介できればと思います。
例えば [Web Codecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API) など、これはネイティブのメディアコーデックを使えるようにすることで、わざわざWASMでffmpegなどを用意しなくても動画変換などが出来てしまう、割と革新的なAPIです。
回転行列を低ランク近似してみる

#　角度に依存する行列を低ランク近似してみた。

juliaで自動微分とテンソル分解の勉強も兼ねて、ある行列を低ランク構造を持つとして、それを近似するようなコードを書いてみた。
以前書いた[行列の再現](https://qiita.com/RhT/items/d28ed563ddb80700b897)とコード的には大体同じなのですが、今回はある角度に依存する行列が低ランク構造を持つとし、低ランク近似した場合についてまとめます。
具体的には、

```math
 M=\left(\begin{array}{ll}
x_{11}(\theta) & x_{12}(\theta) \\
x_{21}(\theta) & x_{22}(\theta)
\end{array}\right) 
```

が低ランク構造を持つと仮定して、以下の適当なパラメータからなる行列Xで低ランク近似できるとします。


```math
\begin{aligned}
\operatorname{X} &=\left(\begin{array}{l}
a_{11} \\
a_{21}
\end{array}\right) \times\left(b_{11} \cdot b_{12}\right) \\
&=\left(\begin{array}{ll}
a_{11} b_{11} & a_{12} b_{12} \\
a_{21} b_{11} & a_{24} b_{12}
\end{array}\right)
\end{aligned}
```


## 必ず分解できる場合

テストとして、まずは、ある与えられた行列が必ずベクトル同士の積で分解できる場合を試してみる。（これは角度には依存していない場合）

```julia
using Zygote
#using Pkg; Pkg.add("Optim")
using Optim
```

```Julia
a_gt = [0.4, 0.3]
b_gt = [0.1, 0.2]
A = a_gt * b_gt'　#この行列Aを再現することがゴール
```

```Julia
# x\_1 [TAB] 
#準備として、ベクトルから行列を構成する。
a₁ = 1.
a₂ = 2.
b₁ = 3.
b₂ = 4.

a = [a₁, a₂]
b = [b₁, b₂]
X(a, b) = a * b'

print(a) #縦ベクトル
print(b')　#横ベクトル
print(X(a, b)) #行列
```


```Julia
square(x) = x^2
metric(X, A) = sum(square, X.-A)
f(a,b) = metric(X(a, b), A)　#|X-A|^2

∂f(a₁, a₂, b₁, b₂) = gradient(f, [a₁, a₂, b₁, b₂])[begin]　#4変数a₁, a₂, b₁, b₂に関するfの微分を定義する。

# 1変数x（一次元配列）に対するfの微分を定義する。
# これは勾配法による最適化時に必要になる。
function ∂f(x)
    a₁, a₂, b₁, b₂ = x
    ∂f(a₁, a₂, b₁, b₂) #１つ上で定義した
end

# 微分の定義で必要となる４変数を引数にもつ関数fを定義する。
function f(a₁, a₂, b₁, b₂)
    a = [a₁, a₂]
    b = [b₁, b₂]
    f(a, b) #metric(X(a, b), A)
end

 #∂f(X(a, b))
# fに関しても∂f(x)と同様に、１変数xに対して定義する。（∂f(x)が呼び出される時に内部で呼び出される、はず。。）
function f(x::Vector)
    a₁, a₂, b₁, b₂ = x
    f(a₁, a₂, b₁, b₂)
end
```

```Julia
Random.seed!(1)
x = 2*rand(4) .-1
η = 0.01

for _ in 1:10000
    x .-= η .* ∂f(x)　#x=[a₁, a₂, b₁, b₂]に含まれるパラメータが勾配法に従って変化する。
end

a_new = x[1:2]
b_new = x[3:4]
X_new = X(a_new, b_new)

2×2 Matrix{Float64}:
 0.0401788  0.0803576
 0.0297585  0.0595169
```

## BFGS法を使ってみる

```julia
function X(a₁, a₂, b₁, b₂)
    x = [a₁, a₂]
    y = [b₁, b₂]
    X(x, y)
end

f(a₁,a₂,b₁,b₂) = metric(X(a₁, a₂, b₁, b₂), A)
function f(x)
    a₁,a₂,b₁,b₂ = x
    f(a₁,a₂,b₁,b₂)
end

function g!(G, x)
    G .= f'(x)
end

x = rand(4)
G = zeros(4)
g!(G, x)

x_1 = 2*rand(4) .-1
results = optimize(f, g!, x_1, LBFGS()) 

Optim.minimizer(results)
```

```julia
a_new2 = Optim.minimizer(results)[1:2]
b_new2 = Optim.minimizer(results)[3:4]
X(a_new2, b_new2) #Aを再現
```


## 角度に依存する場合

上のコードで以下のようにAを変更してあとは同じ。

```julia
θ = π/6
   A = [
    cos(θ) -sin(θ)
    sin(θ) cos(θ)
    ]

2×2 Matrix{Float64}:
 0.866025  -0.5
 0.5        0.866025
```

コードを実行してみると、元々の行列全体は再現できていないことがわかる。

```
2×2 Matrix{Float64}:
 0.853372  0.0207356
 0.520736  0.0126531
```


行列が角度に依存するためなのか、部分的に行列要素と近い値はある（行列の左半分）一方、再現できない箇所（行列の右半分）が出てきてしまった。

## まとめ
今回行った角度に依存する２行２列の回転行列の場合には、低ランク構造を持たず、うまく再現ができないことがわかった。
DockerのVolumeで特定のもの以外を削除したい

## なぜこの記事を書いたのか
複数のプロジェクトの開発を行っている上で不要なVolumeがいっぱい増えるので、一括で削除する方法がないかを考えて作成しました。
使用中のボリュームは削除されないので、削除したいものは未使用にした後に削除してください。その場合はコンテナを落としているだけではなく、コンテナを消す必要があります。

## コマンド
```
docker volume rm `docker volume ls -q | grep -v "削除したくないVolumeの名称を入れる。正規表現なので注意"`
```

## 解説
```
docker volume rm　引数
```
引数として与えられたVolumeを削除する。

```
docker volume ls -q
```
存在しているボリュームの名称の一覧を返す。
-q　オプションがなければDRIVERも一緒に表示されてしまう。削除は実行されるが、関係ない箇所でErrorが連発されるため、-qオプションは推奨。

```
grep -v "削除したくないVolumeの名称を入れる。正規表現なので注意"`
```
Linuxコマンド、正規表現を使用して出力されたコマンドに対して検索を行なっている。
-vオプションで正規表現でHitしたもの以外となる。
今回はdocker_dataを削除せずに他を削除したいので、-vでdocker_dataを指定している。

```
`docker volume ls -q | grep -v "削除したくないVolumeの名称を入れる。正規表現なので注意"`
```
`で括っているのはdocker volume rmの引数に実行結果を渡すためです。

### 結論
Docker Fileを実行する際には-rmオプションをつけることで不要なVolumeはコンテナ停止時に削除されます。（https://docs.docker.jp/engine/reference/run.html#clean-up-rm）

しかし、docker-composeで起動した場合匿名ボリュームを削除する方法がわかりませんでした。また、名前付きボリュームでも特定のもののみを残したい場合があると思います。その場合には上記のコマンドで消せるので、不要なボリュームを削除するのが楽になりました。

docker-composeでも紐づいていない匿名ボリュームを消す方法はあるよ！　って方はコメント欄で教えていただけるとすごく嬉しいです！！
min/max

min({a1, a2, ..., an}) (a1 ~ an の最小値)

max({a1, a2, ..., an}) (a1 ~ an の最大値)

*min_element(c + l, c + r) (c[ l ] ~ c[ r ]の最小値)

*max_element(c + l, c + r) (c[ l ] ~ c[ r ]の最大値)
VIEWからControllerに値を渡す方法~備忘録~

## viewからcontrollerに値を渡す方法

### ①formを利用する場合
#### input typeをhiddenにすることによって隠しデータとしてフォーム送信

```
[VIEW]~~.blade.php

<form action="{{route('store')}}" method="POST">
　　　　<div class="form-group">
   　　　　<input type="hidden" name="member_id" class="form-control" id="member_id" value="{{$member_id}}">
　　　　</div>
<button type="submit"></button>
</form>
```
```
[Route]web.php

Route::post('/store', [HomeController::class, 'store'])->name('store');
```

```
[Controller]Homecontroller.php

public function store(Request $request)
{
  $posts = $request->all();
  $member_id = $posts['member_id'];
}
```
### ②URLを利用する場合
#### 1.ルートパラメータの利用
#### member_idの数字が書いたリンクを踏むことで、その値をcontrollerに渡す

```
[VIEW]~~.blade.php

<a href=/{{$member_id}}>{{$member_id}}</a>
```

```
[Route]web.php

Route::get{'/{member_id}', 'UserController@index');
```

```
[Controller]Homecontroller.php

public function index($member_id)
{
    $data = $member_id;
    ~~~~
}
```

#### 2.クエリパラメーターの利用
#### member_idの数字が書いたリンクを踏むことで、その値をcontrollerに渡す

```
[VIEW] ~~.blade.php

<a href="/?id={{$member_id}}"> {{$member_id}}</a>
```

```
[Route]web.php

Route::get('/', [HomeController::class, 'index'])->name('log');
```

```
[Controller]Homecontroller.php

 public function index(Request $request)
{
  $member_id=$request->id;
}
```
複数渡したい場合は下のように'&'でつなげる。

```
[VIEW] ~~.blade.php
<a href="/?id={{$member_id}}&name=1234"> {{$member_id}}</a>
```

#### 3.ルートパラメーターとクエリパラメーターの併用

https://kojinjigyou.org/11862/

もっと便利なやり方があれば教えてください> <
【Rails】コールバックとは

##コールバックとは
モデルを保存、更新、削除後や削除前のタイミングで実行されるメソッドのこと指す。
例) 記事を投稿し保存後には〜をする。

```rb
before_save => #保存前
after_save => #保存後
after_update => #更新後
before_destroy => #削除前
after_destroy => #削除後
```

##使用例
例①
before_save(保存前)コールバック後にメソッド実行。
下記コードはemail保存前に、大文字のローマ字がある場合、小文字に変換するメソッド。

```rb
class << self
  before_save :downcase_email
  def downcase_email
     self.email = email.downcase
  end
```

例②

```rb
class ShopsController < ApplicationController
　　before_action :logged_in_user
```
上記はpostsコントローラーの各アクション前にログインユーザーであることを指定している。

ネットで何か購入する時、ログインしていない場合はログインまたは会員登録を促されると思われるが、ログインユーザーでないため、弾かれる(``before_action :logged_in_user``)のもコールバックによりログインを要求しているものと言える。

##使用できるコールバック一覧（呼び出される順）
**オブジェクトの作成**

```
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit / after_rollback
```

**オブジェクトの更新**

```
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit / after_rollback
```

**オブジェクトに削除**

```
before_destroy
around_destroy
after_destroy
after_commit / after_rollback
```

##参考記事
[Active Record コールバック](https://railsguides.jp/active_record_callbacks.html#:~:text=%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%81%A8%E3%81%AF%E3%80%81%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88,%E6%9B%B8%E3%81%8F%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)
[【Rails】コールバックについて](https://zenn.dev/tkengineer/articles/670398cf56aeb0589276)
オブジェクトの分割代入(destructuring)メモ  `Cannot destructure property '**' of 'undefined' or 'null' , '***' as it is null.` を防止する

# オブジェクトの分割代入(destructuring)メモ

- JavaScript の分割代入(destructuring)に関するセルフメモです

- デフォルト値を指定したオブジェクトの分割代入をつかって
 `Cannot destructure property '**' of 'undefined' or 'null' , '***' as it is null.` を防止したいための備忘録


```js
const { prop1 } = { prop1: "value1",prop1_1:"value1_1" };
console.log(prop1);// => "value1"

const { prop2: prop2_new } = { prop2: { prop2_1: "value2_1" } };// 新しい変数名への代入
console.log(prop2_new);// => { prop2_1: "value2_1" }

const { prop3: { prop3_1 } } = { prop3: { prop3_1: "value3_1" } };// ネスト
console.log(prop3_1);// => "value3_1"

const { prop4 } = {};//
console.log(prop4);// undefined

const { prop5 = "value5_default" } = {};// デフォルト値(prop5 == "value5_default"。prop5の値が undefined のときはこのデフォルト値が割り当てられる
console.log(prop5);// => "value_some"

const { prop6: prop6_new } = {};// 新しい変数名への代入
console.log(prop6_new);// => undefined

const { prop7: { prop7_1 }} = { };// ネスト
console.log(prop7_1);// => エラー Cannot read property 'prop7_1' of undefined

const { prop8: { prop8_1 }={}} = {};// ネスト　＆　デフォルト値(prop8 == {}　。prop8の値が undefined のときはこのデフォルト値が割り当てられる)
console.log(prop8_1);// => undefined

const { prop9: { prop9_1="value9_1_default" }} = {};// ネスト　＆　子プロパティデフォルト値
console.log(prop9_1);// => エラー  Cannot read property 'prop9_1' of undefined (prop9が undefined のため)

const obj10=null;
const { prop10: { prop10_1="value10_1_default" }={}} = obj10 || {} ;// obj10 が null や undefined の可能性のある場合のエラー回避
console.log(prop10_1);// => "value10_1_default"
```


## 関数の引数にも分割代入＋デフォルト値でスッキリ

【Before】改善前：これを分割代入＋デフォルト値で改善したい

```js
const fnWhatsYourNameOld = (options) => {
  const opts = options || {};
  const { firstName, lastName } = opts;
  let fullName = '';
  if (!firstName) {
    fullName += 'ナナシノ';
  } else {
    fullName += lastName;
  }
  if (!lastName) {
    fullName += 'ゴンベイ'
  } else {
    fullName += firstName;
  }
  return fullName;
};

console.log(fnWhatsYourNameOld());// =>"ナナシノゴンベイ"
console.log(fnWhatsYourNameOld({}));// ==>"ナナシノゴンベイ"
console.log(fnWhatsYourNameOld({ firstName: 'ノビタ', lastName: 'ノビ' }));// => "ノビノビタ"
```

【after】改善後：関数の引数に分割代入とデフォルト値を使ってスッキリ

```js
const fnWhatsYourNameNew = ({ firstName = 'ゴンベイ', lastName = 'ナナシノ' } = {}) => {
  return `${lastName}${firstName}`;
};

console.log(fnWhatsYourNameNew());// =>"ナナシノゴンベイ"
console.log(fnWhatsYourNameNew({}));// =>"ナナシノゴンベイ"
console.log(fnWhatsYourNameNew({ firstName: 'ノビタ', lastName: 'ノビ' }));// => "ノビノビタ"

```
- `{ firstName = 'ゴンベイ', lastName = 'ナナシノ' }={}`の右辺の`{}`は引数のデフォルト値。引数が undefined や　null の場合に効く
- `{ firstName = 'ゴンベイ', lastName = 'ナナシノ' }`は引数が Object だった場合の、各プロパティ（変数）のデフォルト値

- これで、関数内での引数の null(undefined)チェックやデフォルト値まわりの処理をだいぶシンプルにできる。
`export * from` で export した内容を部分的に上書きする

# `export * from` で export した内容を部分的に上書きする

Material-UI などをプロジェクト内で `export * from '@mui/material'` などとする必要がありそのようにしたが、
部分的にローカルで定義した内容で `export` を上書きする必要がありどのようにするか迷いました。

## 対応

```ts:export-all-from-material-ui-partially-override
// @mui/material の中身をすべて export
export * from '@mui/material'
// ローカルで定義したコンポーネント
export Button from './Button'
```

上記のようにすることで `@mui/material` の `Button` をローカルのもので export する形になりました。
”できないエンジニアの特徴”別視点

最近みかけた下記の記事が興味深かったので、一部の項目について別視点で記事を書いてみます。

https://qiita.com/sagae_twins_developper/items/399c233ea6b00c8f5734

この記事の内容をエンジニアに対しての１つのメッセージやアドバイスとして書かれているものと思います。なので、**ここでの別視点とは特にそのエンジニアの周囲の人々に対して**ということになります。

多角的視点の提供をすることで新たな改善点も見え柔軟な対応ができ、双方でよりよい成果につながるのではと思いました。

サマリーとしては「**そのエンジニア自身や、おかれている現在の環境（現環境）**」に目を向けてみる、です。というのは、外からスレートに見える姿が本当の姿であるかというと、そうではない事もあるだろうからです。

更に、はじめから何事も完璧にできる事はなくそれぞれが様々な事を学習し、その学習された経験がその後の意思決定や言動に影響を及ぼしているためです。また、おかれている現環境との相互作用も影響してきます。

# 「1. 4. 5. 9.」の別視点：受け止め側の姿勢と行動

>「1.  納期に間に合わない時、自分から報告してこない」
「4.  No と言えない」
「5.  仕様でわからないところを適度に質問できない」

確かにきちんと報告をしていただきたい、わからないなら質問していただきたい、などと思う事あるでしょう。しかし、そんな時「（したくても）**自ら報告や質問・提案ができない**」ということもあるかもしれません。これらの行動を阻害している要因はないか？と考えてみます。

過去に、報告・質問・提案をしたことにより、**その相手（先輩や上司など）から辛い刺激を受けた場合、次回からそのような行動を控えてしまう**、といった事が考えられます。質問・提案についても同様です。（参考：行動分析学における「嫌子」の出現）

もし、報告やわからない事の質問などをしてもらいたい、といった場合には、される側はその「受け止め方」についても一度、振り返り（あるいは観察）をするとよいでしょう。

ここで「**受け止め方**」のポイントを１つお伝えするなら、受ける側は、まず”報告や質問・提案”などをしてくれたその行為そのものについて「**感謝**」を伝える事です。

>「9.  反論 = ケンカだと思っている人」

こちらはミーティングなどの場において、「ケンカだとおもって反論している」あるいは「反論そのものができない」という状況が浮かびます。

なぜそうしているか？やはりこれも過去の経験および現環境が作用している可能性はあります。
逆の意見を放った際に、それが受け入れられなかったり辛くあたられたり、つめられたり・・・そういうことを自ら経験したり感じたり、他人のことでも見ていたりすることで「反論するときはケンカ腰で！」や「反論できない（別のの意見をもっていても言えない）」であったり、という認識となってしまっている可能性があります。

**反論を「建設的な別の意見と捉え、議論し改善活動や新たなアイディアの創出につなげられる」**とし、率直に意見をとりかわしたいのであれば、まずそのような認識が持たれるように関係者で共有し、そういった**意見を発言しやすい環境を作る努力**をし、やはり**受け止め方**を振り返る事も大事かと思います。

ここで、私が小学校の頃の先生の「言葉」を思い出したのでご紹介します。その先生は、

>「 教室は"間違える"ところである 」


と教えてくれました。そして、その先生は手をあげた生徒をさしたあとに責めたりとがめたりするようなことはしませんでした。思い返せば「感謝」「応援」に近い姿勢で生徒と向き合っていた印象が残っています。

私はこれにより、いわゆる**”手をあげて発言する”**ことに躊躇しなくなりました。それまでは、


>間違っていたらどうしよう
間違いをとがめられたらどうしよう

など、ありがちな感情を抱きそういった思いが浮かびよほど完璧に正解を持っていないと発言をできないことがありました。しかし先生のこの言葉およびその後の先生の態度や姿勢により意見を率直に述べられるようになりました。

このエピソードも１つのヒントになったら幸いです。

# 「2. 3. 8.」の別視点： やり方を知らない

>「2.  タスク分解しないで、仕事をし始める」
「3.  進捗の見える化をしない」
「8.  仕組み化して効率化を図らない」

これらの手法は様々な事に有用な方法です。しかしながら、**その具体的なやり方そのものを知らない且つ経験していない・慣れていないがゆえ**に行えていない、ということもあるかもしれません。

人に何かの行動をしてもらいたい場合に、まずそれを**知っていないと行動できません**。そして、知識を得た上で経験しパターン（汎化）のようなものを自身で確立できのちに、自発的に行動できるようになっていきます。

**日本海軍、名将・山本五十六**さんの非常に有名な言葉が残されています。

>やってみせ、
言って聞かせて、
させてみせ、
ほめてやらねば
人は動かじ

まずは相手にその行ってもらいたい行動のやり方を知っているか確認し、知らないのであれば、**自らやってみせ**た上で**教え**、そして**経験**してもらいましょう。

その結果にダメ出しのみをするのではなく、うまくできたところはきちんと**褒め**、至らなかった点に対して**客観的なフィードバック**をし、何が足りなかったのかを自ら気づいてもらうように周りはサポートしていくとよいでしょう。

# まとめ

いかがでしたでしょうか。

「できないエンジニア」へ何か助けになる事はないか？という点において、そのエンジニアの周囲の人々が何かできないか？の視点を加えてみました。

エンジニアが社会人として日々過ごしていく時に、改善することを自分自身だけ行うではどうにも変われない事もあります。そんな時に周囲の人は「**そのエンジニア自身や、おかれている現在の環境（現環境）**」にフォーカスしてみましょう。

その**エンジニア自身の事**については、見えているところと見えていないところは１００％わかりません。いわゆる「**裏腹**」はわかりずらいものです。できるだけ相手を理解できるように、**関係構築**を作っていき、**現環境**については、**周囲の人がそれぞれ内省したり視野を広げて観察する**ことからはじめ、環境を考えていくという事が必要なのかもしれない・・・と気づくかもしれません。
Pythonのthreading.Timerをfor文の中で使った際に起こった問題

## 発生した問題

Pythonには非同期処理を行うためのthreading.Timerクラスがあるが、これをfor文の中で使った際に意図しない挙動になってしまうことがあった。例として、以下のようなスクリプトを考える。

```wrong_timer.py
import threading

notifications = [[3, 'first notification'], [5, 'second notificaton']]

for n in notifications:
  t = threading.Timer(n[0], lambda: print(n[1]))
  t.start()
```

notificationsは通知のタイミングと内容を含むリストのリストであり、これをfor文で回してそれぞれ指定した秒数後に通知内容を出力する、という処理を意図している。

以下のような出力を想定している。()内の数字は実行してから何秒後に出力されたかを示す。

```
first notification (3)
second notification (5)
```

しかし実際には以下のようになる。

```
second notification (3)
second notification (5)
```

こうなってしまう原因と解決方法をこれから説明する。

## 原因

上記のように両方の出力が"second notification"になってしまう原因は、threading.Timerに渡した第2引数の関数オブジェクトの評価が、宣言時ではなく実行時に行われるということである。ここでは1回目のループで `lambda: print('first notification')` を渡しているつもりでいるが、実際には`lambda: print(<nへの参照>[1])` が渡されている。そのため、実行時、3秒後にはfor文はすでに回り切っているため変数nはnotifications[1]を参照しており、結果として`lambda: print('second notification')`が実行されてしまうのである。

これはPythonに限らず非同期処理をする場合によくあるミスで、値を渡しているつもりが実際には参照を渡しているために、実行時にfor文の最後のループで代入されている要素を全ての非同期処理が参照してしまうという問題である。

## 解決策

上記のように、非同期処理に対して参照を渡してしまっていることが原因なため、代わりに値を渡すようにすれば良い。幸いthreading.Timerは第3引数に渡したリストを実行時の実引数としてくれるため、以下のようにすれば良い。

```correct_timer.py
import threading

notifications = [[3, 'first notification'], [5, 'second notificaton']]

for n in notifications:
  t = threading.Timer(n[0], print, [n[1]])
  t.start()
```

こうすると期待通りの結果になる。

```
first notification (3)
second notification (5)
```
inDesignで箇条書きのレベルについて

箇条書きでレベルを変えて、箇条書きの中に箇条書きを作るためには、レベルという機能を利用するということまでは調べることができたが、その方法を自分が思い込みで勘違いしていたことからはまってしまったので同じところで止まっている人のために、メモを残します。


https://www.youtube.com/watch?v=aq6iJH7-Ftk
や
https://www.dtp-transit.jp/adobe/indesign/post_2114.html
や
 初心者からちゃんとしたプロになる
 InDesign基礎入門
という書籍を見てもよくわからなかった。


箇条書きのレベルとは

1.昨日の夕食
　　(1)ご飯
　　(2)たくあん
　　(3)ハンバーグ

2.今日の夕食
　　(1)パン
　　(2)シチュー
　　(3)ミルク

3.明日の夕食
　　(1)ピザ
　　(2)サラダ
　　(3)コーラ

みたいな感じにしたい。


まず普通に番号を振らずにinDesignに書き込む

![スクリーンショット 2022-02-21 14.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/03b8b994-4789-c6ee-544f-c7e736c8f301.png)


そして箇条書きの設定を各段落スタイルで定義した
![スクリーンショット 2022-02-21 14.15.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/da5196c9-d69c-47ea-fc9e-c772dc2ff809.png)

大見出しとしたのが
1.昨日の夕食

小見出しとしたのが
(1)ご飯


それぞれの段落スタイルのところの設定画面は
大見出しが
![スクリーンショット 2022-02-21 14.18.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/d36af88d-1120-7c03-d876-71be8f9ae7a4.png)


小見出しが
![スクリーンショット 2022-02-21 14.17.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/240b050d-2ffa-f251-8673-8ad3df000cc2.png)


これを各行に適用した結果が
![スクリーンショット 2022-02-21 14.19.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/c1c7d921-5e0d-4637-dc6b-9e9845134c58.png)


小見出しが連続してしまって
6行目のパンの部分を(1)にしたいのに連続してしまっている。

ここがうまくいかなくてはまってしまった。


これの解決法が、
![スクリーンショット 2022-02-21 14.22.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/45ad4887-4b79-e8c7-c88d-d90fea70553d.png)

わざわざ箇条書きのリストのところを別で作っていたところだった。
段落スタイルも「大見出し」「小見出し」をそれぞれ作り
その中のリストも　大見出しと小見出しでスタイルを変えたいことから、違うリストを作らないといけないと思ってしまった。

ここの部分が、箇条書きの中に小さい箇条書きを作る場合、それぞれの中で箇条書きの番号をリセットしたいならば、リストは同じにして
レベルのみを変える必要があったということ。

同じリストでもレベルを変えれば自動番号スタイルを変更できるので、リストを揃えることで解決した

![スクリーンショット 2022-02-21 15.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/5cd717db-37a2-95b2-3f22-4aee98308c23.png)

「小見出し」に設定したい段落スタイルの箇条書きのリストを、「大見出し」の段落スタイルの箇条書きに設定した[大見出し]と同じリストにし、
レベルのところだけを2に変えて、設定したい自動番号スタイルを設定すればうまくいった
『現在、ファイルを開くことができません。』の対処法

# 症状

Google ドライブやGoogle Apps Scriptなどにアクセスしようとしたときに、

>現在、ファイルを開くことができません。
>アドレスを確認して、もう一度試してください。

と表示されてアクセスできない。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704144/a216078e-400b-247c-4ea7-3be0594d1396.png" width="500">





# 原因

**複数のGoogleアカウントでログイン**していることが条件で発生するようです。
※ 複数アカウントでログインしても問題ない場合もあります。

# 対処法

Windows10（Chrome, Firefox）での対処法のみ掲載していますが、考え方はMacOS (Safari)でも同様かと思うので参考になれば幸いです。

### 対処法1. ゲストモードで閲覧 [Google chrome]

これが最も簡単です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704144/c87b6b33-ee5b-6aa2-dea7-57abb7d6dd77.png" width="600">

### 対処法2. シークレットウィンドウで閲覧 [Google chrome]

これで閲覧可能になる場合もあるようですが、私の環境ではダメでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704144/807d2f35-51bb-182a-d7eb-1448eeb811a1.png" width="250">

### 対処法3. 全てのアカウントから一旦ログアウト [Google chrome]

以下の通り、一旦全てのアカウントからログアウトします。
その後、どれか1つのアカウントでログインして再度アクセスします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704144/d4f35393-a97f-389e-c140-d867223a0338.png" width="300">

症状が改善しない場合は、再び全てログアウトします。
再度、別のアカウントでログインしてアクセスします。
（いずれかのアカウントで開くことができます）

### 対処法4. シークレットウィンドウで閲覧[Firefox]

対処法2.と同様です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704144/8c257d81-c508-d16a-bae6-ad8ee04f4ce4.png" width="200">
GfGa

専用計算機のメモ

試行錯誤の記録として将来の自分のために保存しておく。

# pyenv

普段のpyenvの設定(https://qiita.com/KoheiQiita/items/3fa3251046132246169a)
に、以下を加えるとうまくいく。

```
$ echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
```

参考　https://blog.serverworks.co.jp/2021/05/12/233520

# conda 周辺の試行錯誤

```
$ nano /home/nbody06/.pyenv/pyenv.d/exec/pip-rehash/conda
```

/home/nbody06/.pyenv/bin

```
$ nano ~/.pyenv/shims/conda 
```
これらを編集すると、以下のエラーが出る。

```
$ conda info --envs 
  File "/home/nbody06/.pyenv/pyenv.d/exec/pip-rehash/conda", line 7
    [ -n "$PYENV_DEBUG" ] && set -x
                      ^
SyntaxError: invalid syntax
```

参考　https://stackoverflow.com/questions/39884499/conda-command-will-prompt-error-bad-interpreter-no-such-file-or-directory

いずれもうまくいかない。


変更せずにOKっぽい　/home/nbody06/.pyenv/versions/anaconda3-5.2.0/etc/dbus-1


最初の２行変更　/home/nbody06/.pyenv/versions/anaconda3-5.2.0/etc/fish/conf.d

２箇所だけディレクトリ名変更　/home/nbody06/.pyenv/versions/anaconda3-5.2.0/etc/fonts/fonts.conf 


setenv _CONDA_EXE "/home/nbody06/.pyenv/versions/anaconda3-5.2.0/bin/conda"
setenv _CONDA_ROOT "/home/nbody06/.pyenv/versions/anaconda3-5.2.0"

/home/nbody06/.pyenv/versions/anaconda3-5.2.0/bin

https://qiita.com/Senple/items/3d7c229c942ce54e2bb4

# git

下記の方法でもうまくいかない。
https://fumidzuki.com/knowledge/187/

どうやら、ローカルにインストールして、それを移動するという原始的な方法以外はうまくいかない。


# GRAPE library

GRAPE usage

GRAPEはCで書かれているので、C++で読み込むためには以下が必要。

https://stackoverflow.com/questions/3329159/including-c-headers-inside-a-c-program

https://stackoverflow.com/questions/21521333/including-c-headers-in-a-c-namespace-is-it-a-standard-behavior/21521529

https://isocpp.org/wiki/faq/mixing-c-and-cpp
MAMPで「Open WebStart page」が押せない場合

これで解決できます。
簡単に言えば、MAMPのデータベースのポート番号を
初期値から変更していたために起きているものです。

なので、データベースのPORTを8889にすればOKです！

https://unity-yuji.xyz/mamp-open-webstart-page-not-active-php/
pcdファイルの可視化

前回はbagファイルからpcdファイルへ変換した
今回は，pcdファイルの中身を見てみよう
任意の場所に新たにフォルダを作成し，pcd_write.cppとCMakeLists.txtを作成する

```C++
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main(int argc, char **argv)
{
    pcl::PointCloud<pcl::PointXYZ> cloud;

    // Fill in the cloud data
    cloud.width =10;
    //表示する数？
    cloud.height = 1;
    cloud.is_dense = false;
    cloud.points.resize(cloud.width * cloud.height);
    //point cloudの大きさを指定
    for (size_t i = 0; i < cloud.points.size(); ++i)
    {
        cloud.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }

    pcl::io::savePCDFileASCII("1645410112.408859474.pcd", cloud);
    //pcdファイルは各自で変更
    std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;

    for (size_t i = 0; i < cloud.points.size(); ++i)
        std::cerr << "    " << cloud.points[i].x << " " << cloud.points[i].y << " " << cloud.points[i].z << std::endl;
    return (0);
}
```

```
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(pcd_write)

find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (pcd_write pcd_write.cpp)
target_link_libraries (pcd_write ${PCL_LIBRARIES})
```

保存したら，

```
mkdir build 
cd build 
sudo cmake ..
sudo make 
sudo ./pcd_write
```
上から順に実行するとx,y,zの情報が表示される

ここからが問題ってばよ！！
x,yだけが欲しいからzをうまく削除できるようにならないと
pcdファイルを点群で見る
```java
pcl_viewer <pcdfile> <ps 数字> <-fc R,G,B>
//<ps 数字>で点の大きさを指定
//<-fc R,G,B>で点の色を指定　 例）255,255,255は白
```
# オプション

|オプション|結果|
|:----:|:----:|
|-bc r,g,b| 背景色|
|-fc r,g,b| 点群色 |
|-ps X| 点のサイズ(1~64) |
|-opaque X|点群の不透明度(0~1)|
|-ax n|軸の有効にし，nにスケーリング|
|-ax_pos X,Y,Z|軸が有効になっている場合は，x,y,zの位置を空間にする|
|-cam (＊)|指定されたカメラ設定を初期ビューとして使用する|
|-multiview 0/1 |自動マルチビューポートレンダリングを有効/無効にする|
|-normals 0/X|すべてのX点のサーフェス法線を線として表示することを無効/有効にする|
|-normals_scale X|通常の単位ベクトルサイズをXに変更する|
|-pc 0/X|すべてのX点の主曲率の線としての表示を無効/有効にする|
|-pc_scale X|主曲率ベクトルのサイズをXに変更する|

# 参考
http://manpages.ubuntu.com/manpages/bionic/man1/pcl_pcd_viewer.1.html
Tomcatを強制的に終了する方法

./shutdown.sh を実行してもTomcatが終了できない場合は、

```ps -A | grep java```

または

```lsof -i -P | grep 8080```

を実行する。

表示されたプロセスIDを指定してkillする。

```kill -9 プロセスID```

または

```kill -15 プロセスID```

これでTomcatを終了できます。