OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelでどれだけ関数があるか調べたい時にBashでやったこと

**このプロジェクトに関数がいくつあるか知りたい** ってこと無いですか？ないですか。僕はありました。

Laravelのプロジェクトなんですけど、パブリックな関数がいくつあるのか知りたかったんですね。PhpStormのプラグインだったり、色々と探したんですが、なんか欲しい情報を簡単に出せるのがありませんでした。

最近shell（bash）の書き方を覚えたばかりなので、使って書いたほうが早そうという結論に。

# 前提

- Bashで書いてます。shell初心者です。
- コメントアウトも拾っちゃいます。
- 文字列とかも拾っちゃいます。
- とにかく `public function` って文字列は無差別に拾います。
- 行数カウントです。
- プロジェクトルートから実行するのを想定。

# ワンライナー

```bash
$ result_file="class_analysis"; [[ -f "$result_file" ]] && rm "$result_file"; touch "$result_file"; targets=("Services" "Repositories"); for target in "${targets[@]}"; do ls -1 app/"$target"/ | grep ".*Interface.php" | while IFS= read file; do echo "app/$target/$file,$(grep -c "public function" "app/$target/$file")" >> $result_file; done; done;
```

# 分解

まずは出力先ファイル名を設定。

```bash
$ result_file="class_analysis";
```

出力先ファイルが既に存在する場合は、削除しちゃいます。

```bash
[[ -f "$result_file" ]] && rm "$result_file";
```

新規で出力先ファイルを作ります。

```bash
touch "$result_file";
```

今回は「すべてのディレクトリ」ではなく、ある程度絞って数を見たかったため、ディレクトリをある程度絞りました。
プロジェクト的に重要なロジックが詰まっている以下の2つを対象としています。

```bash
targets=("Services" "Repositories");
```

対象ディレクトリで回して行きます。

```bash
for target in "${targets[@]}"; do
```

`app` 配下のファイルを1ファイル1行で表示し、パイプで出力を次の処理へ渡す。

```bash
    ls -1 app/"$target"/ |
```

今回対象のプロジェクトではInterfaceを具象クラスと同じディレクトリに格納していたため、Interfaceだけ見ればいいや、ということでインターフェースだけで絞り込みました。
Interfaceという文字列で `grep` した結果を、またまたパイプで次の処理へ渡します。

```bash
    grep ".*Interface.php" |
```

1ファイルずつ回して `public function` という文字列を含む行数を抜き出して、カンマ区切りでファイル名とともに `echo` して、その結果を出力先ファイルに追加。

```bash
    while IFS= read file; do
        echo "app/$target/$file,$(grep -c "public function" "app/$target/$file")" >> $result_file;
    done;
```

ループお終い。

```bash
done;
```

以上

# あとがき

上記、ニーズに合わせてカスタマイズして使っていただければと。
ファイルの `grep` 周りをもうちょっときれいにできる気がしてる。
外部キー設定をしたモデルに対してpresenceのバリデーションは不要と知った話

#概要
アソシエーションを組んだモデルを一度に登録する際に、不要なバリデーションを組んでいたために、エラーメッセージが二重に表示された。

#結論
rails5からは、belongs_to: で外部キーに設定している場合は自動でnilは許可しないバリデーションが設定されるので、バリデーションの記述は不要。

#詳細
商品出品機能を実装していた際に、バリデーションによって登録ができなかった時にエラーメッセージを表示するよう実装を行っていました。
itemモデル（商品）にimageモデルとcategoryモデルをassociationを組んで、同時に登録を行えるようにしていました。

1. gem rails-i18nをinstall
1. エラーメッセージを日本語翻訳

すると、エラーメッセージが表示されたのは良かったのですが、
[![Image from Gyazo](https://i.gyazo.com/ad5c0c6c4dac3814cfbd73d601baa8f0.png)](https://gyazo.com/ad5c0c6c4dac3814cfbd73d601baa8f0)

__カテゴリーのエラーメッセージが2つある。。。__

自分なりに仮説を立ててメンターへ質問。
[![Image from Gyazo](https://i.gyazo.com/8f1f87902aa0ce5f79fefd81818e4d93.png)](https://gyazo.com/8f1f87902aa0ce5f79fefd81818e4d93)

原因は最終行の__validate :category_id__でした。
__belongs_to：＿＿で外部キーとして設定しているモデルに対してはバリデーションは不要とのこと。

後々自分で調べてみると、rails5からは外部キーに設定すると自動でnilは許可しないバリデーションが設定されるとのこと。
（参照：https://pikawaka.com/rails/validation）

今まで考えたこともなかったけど、当たり前、、、？なのか？？
頭がこんがらがってきた、、、。

今まで複数のモデルを一度に登録させることがなかったため、今回初めてこのような問題に直面したと思います。
VSCodeでmarkdownのときのみ、行末trimをしない設定

# 目的
VSCodeでmarkdown以外は、行末のスペースをtrimし、markdownではtrimしない設定。
→markdownは行末スペース2つで改行の意味があるので、trimしてほしくない。

# 設定方法
1. コマンドパレットを開いて、settings.jsonを開いてください。
2. 下記の設定を追加してください。

```json
{
    // ・・・前略・・・
    // 通常は、行末をtrimする
    "files.trimTrailingWhitespace": true,

    // ・・・中略・・・
    "[markdown]": {
        // markdownは 行末の半角スペース2つで改行なので、消さないようにする
        "files.trimTrailingWhitespace": false,
        //  スペースは ・ で表示される
        "editor.renderWhitespace": "boundary"
    },
    // 言語ごとの特定の設定をしない場合は、
    // "files.trimTrailingWhitespace": true, が継承されている
    // ・・・後略・・・
}
```


"editor.renderWhitespace": "boundary"  のみの場合、行末にスペースが入っているか見にくいので、[Trailing Spaces](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces)をインストールすると見やすくなります。

この記事のmarkdownファイル
![スクリーンショット 2020-09-20 11.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202/7fe6a168-fb21-96ac-ee94-e0c1d75cc43b.png)


補足
タブ1つごとに色が変わっているのは、[indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)の機能です。
Apache2+WSGI+Flaskを動かす

#環境

* さくらVPS（Ubuntu 18.04.2）
* Python 3.6.9
* Apache2

#設定
設定ファイル

```
/var/www/html/flask
- Hello.py
- test.wsgi
/etc/apache2/sites-available
- wsgi.conf
```
まずはスクリプト本体。

```python:Hello.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello'

if __name__ == '__main__':
    app.run()
```
そしてWSGIファイルを作る。

```python:test.wsgi
import sys, site

sys.path.insert(0, '/var/www/html/flask')
from Hello import app as application
```
Apache側の設定。

```
# wsgi.conf
<VirtualHost *:80>
serverName （契約したサーバのIPアドレス or ドメイン名）

WSGIDaemonProcess test user=（Pythonを実行するユーザ名）  group=（そのユーザのグループ） threads=5
WSGIScriptAlias / /var/www/html/flask/test.wsgi

<Directory /var/www/html/flask>

WSGIProcessGroup test 
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On

Require all granted

</Directory>
</VirtualHost>
```
#サーバの再起動
wsgi.confを有効にする。

```
$ sudo a2ensite wsgi
```
そしてApacheの再起動。

```
$ sudo service apache2 restart
```
これでサイトにアクセスすれば"Hello"が表示されるはず。

#参考にしたもの
* [PythonのFlaskを初めて触ってから３０分で本番環境にデプロイ+ HTTPS通信まで完成
](https://qiita.com/yoshizaki_kkgk/items/3cd785b4a670deec0685)
* [Apache上でFlaskを動かすまで（Apache2+wsgi+Flask）
](http://www.wanna-continue.com/entry/apache2%2Bwsgi%2Bflask#wsgi%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90)
* [Ubuntu環境でApache WSGI flaskなWebアプリケーションを構築する
](https://lifeinprogram.com/2019/08/18/post-992/)
LINEのAPIで友だち登録している「全てのユーザー」にメッセージを送る方法

#なぜ書いたのか
ユーザーIDを指定してメッセージを送る方法しか知らなかったので、以下の手順を踏む必要があると考えていた。
1. 友だち登録したユーザーのユーザーIDを取得
2. ユーザーIDをDBかテキストファイルに保存
3. 保存したユーザーIDを全て使用してメッセージを送信

これらの実装をするには、webhookの設定をしたりDBを作ったりしないといけないのでめんどくさかった。
そこで公式のリファレンスを流し見してたところ、**ブロードキャストメッセージ**というものがあるらしく、
これを使えばわざわざユーザーID識別して一斉送信するような機能は必要なく、**アクセストークンの指定だけ**で全てのユーザーにメッセージを送ることができるので早速実装してみた。

#使うもの

line-bot-sdk

```:インストール手順
pip install line-bot-sdk
```

- 公式GitHub
https://github.com/line/line-bot-sdk-python

- 公式リファレンス
https://developers.line.biz/en/reference/messaging-api/#send-broadcast-message


```python:概要

# 関数の説明
broadcast(self, messages, notification_disabled=False, timeout=None)
Send push messages to multiple users at any time.

#　使用例
line_bot_api.broadcast(TextSendMessage(text='Hello World!'))
```

#例
```python
from linebot import LineBotApi
from linebot.models import TextSendMessage

# トークン設定
LINE_CHANNEL_ACCESS_TOKEN = os.environ.get("LINE_CHANNEL_ACCESS_TOKEN")
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)

#実行
line_bot_api.broadcast(TextSendMessage(text='Hello World!'))
```

これだけ

必要に応じてmessageに入れる値をFlexMessageにしたりできる

```python
from linebot import LineBotApi
from linebot.models import TextSendMessage, FlexSendMessage

# トークン設定
LINE_CHANNEL_ACCESS_TOKEN = os.environ.get("LINE_CHANNEL_ACCESS_TOKEN")
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)

# メッセージ設定
message = {
        "type": "flex",
        "altText": "test"
        #中略
}

obj = FlexSendMessage.new_from_json_dict(message)

#実行
line_bot_api.broadcast(messages=obj)
```
GitBashの"stdout is not a tty"で怒られないように

#はじめに
1年ぐらい悩んでいましたが、たった今、対策が見つかりましたのでご報告します。

#現象
GitBashでリダイレクトやパイプを使った時に、こんなメッセージが出てうまくいきません。

```
$ python bin/regression.py > out.txt
stdout is not a tty
```

毎回これが出る度に回避策を考える日々。

### 回避策(例)

 - less が使えず、流れるメッセージを見つめ、見たいところでCtrl-Cで強制終了。その後スクロールバーをつかって見たいところを調整。
 - リダイレクトできないため、プログラムでファイルに出力するコードを書く。もしくはDOSコマンドプロンプトを起動し、実行する。


[Git Bashのttyで怒られないように](https://qiita.com/amanoese/items/7b237e8703c3b4c7f001) も試したんですがうまくいかないんですよ。

#対応

(A) 本腰入れて調べてみました。するとこんな話を見つけました（参考文献参照）

**コマンドに拡張子をつける**

(自分) それだけ？ うそやろ。根拠ねーじゃん。

(A) いい？　じゃぁ、やってみるよ。（コマンドを実行）

```
$ python.exe bin/regression.py > out.txt
```

(自分) え、うそっ、動いてる。まじかよ。パイプはどうなってるっーーーー!!!？

(A) （コマンドを実行）

```
$ python.exe bin/regression.py | less
```

(自分) げ、出た。スペースで次のページ行けるよぉ。すげー。

(自分) 根拠？どーでもいいじゃん。動きゃいいんだよ！

#参考
https://stackoverflow.com/questions/40680812/mysql-git-bash-winpty-mysqldump-stdout-is-not-a-tty-and-stdin-is-not-a-tty/44727575#44727575
Rust: Rocket で Redis のデータを読む

Redis に次のようにデータが入っている時のデータを読みます。

```text
$ redis-cli
127.0.0.1:6379> keys *
1) "t1857"
2) "t1859"
3) "t1855"
4) "t1853"
5) "t1858"
6) "t1854"
7) "t1856"
8) "t1851"
9) "t1852"
127.0.0.1:6379>
```

プロジェクトの作成

```bash
cargo new redis-cities --bin
cd redis-cities
```

次のファイルを作成します。

```text:Cargo.toml
[package]
name = "backend"
version = "0.1.0"
edition = "2018"

[dependencies]
rocket = "0.4.5"

[dependencies.rocket_contrib]
version = "0.4.5"
default-features = false
features = ["redis_pool"]
```

```text:Rocket.toml
[global.databases]
cities = { url = "redis://127.0.0.1:6379" }
```

```rs:src/main.rs
// --------------------------------------------------------------------
/*
	redis-cities/src/main.rs

					Sep/20/2020
*/
// --------------------------------------------------------------------
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;

use std::io::Cursor;

use rocket::request::Request;
use rocket::response::{self, Response, Responder};
use rocket::http::ContentType;

use rocket_contrib::databases::redis::{self, Commands};

// --------------------------------------------------------------------
#[database("cities")]
struct CitiesDbConn(redis::Connection);

struct Cities {
  destination: String,
}

// --------------------------------------------------------------------
impl<'r> Responder<'r> for Cities {
  fn respond_to(self, _: &Request) -> response::Result<'r> {
    Response::build()
      .sized_body(Cursor::new(format!("{}", self.destination)))
      .header(ContentType::new("text", "plain"))
      .ok()
  }
}

// --------------------------------------------------------------------
#[get("/api/<id>")]
fn lookup(conn: CitiesDbConn, id: String) -> Option<Cities> {
	match conn.get(&id) {
	Ok(value) => Some(Cities {destination: value}),
	Err(_e) => None,
	}
}



// --------------------------------------------------------------------
fn main() {
  rocket::ignite()
  .attach(CitiesDbConn::fairing())
  .mount(
    "/",
    rocket::routes![lookup]
    )
  .launch();

}

// --------------------------------------------------------------------
```

コンパイル

```bash
cargo build
```

サーバーの実行

```bash
cargo run
```

テスト

```text
$ curl http://localhost:8000/api/t1851
{"date_mod":"1956-6-9","name":"福井","population":53921}
```
M5Atom(Arduino)とPubNubでMQTTのサンプル #ヒーローズリーグ #protoout


MacからM5デバイスにメッセージ送信を行います。

> ちなみに、[M5Stackハッカソン](https://mashupawards.connpass.com/event/188452/)の会場よりお送りしております。

MQTTのパブリッシュはHTTPリクエストでもええやんと思ったりもするので今回は排除。

## PubNub

https://www.pubnub.com/

BaaSサービスですが、MQTTブローカーを持ってくれてます。(わかる人はMilkcocoa的なものだと思ってください。)

### PubNubの鍵

`Publish Key`と`Subscribe Key`の二つのキーを使います。`Secret Key`は今回使いません。

> ![](https://i.gyazo.com/154816f045cecc2be0b43f53a672d085.png)

## M5Atom(Arduino)側

### 事前準備

* ESP32に書き込めるように準備
* https://github.com/knolleary/pubsubclient をインストール

### PubNubの設定 

サブスクライブだけさせてます。

クライアントIDの箇所を書き換えますが、`PUBLISH_KEY/SUBSCRIBE_KEY/CLIENT_ID`という並びで作成します。

`PUBLISH_KEY`と`SUBSCRIBE_KEY`は先程の値ですが、`CLIENT_ID`は適当な文字列で大丈夫です。

実際には以下のような雰囲気の値を設定します。

```
pub-c-xxxxxxxxxxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/n0bisuke
```

ここまでが接続情報です。後はトピック名というチャットのルームID的なものを適当に指定すればOKです。

```ino
#include <WiFi.h>
#include <PubSubClient.h>
 
const char* ssid = ""; //Wi-FiのSSID
const char* password = ""; //Wi-Fiのパス
const char* mqttServer = "mqtt.pndsn.com";
const int mqttPort = 1883;
 
WiFiClient espClient;
PubSubClient client(espClient);
 
void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
  Serial.print("Message:");
  for (int i = 0; i < length; i++){
    Serial.print((char)payload[i]);
  }
  Serial.println();
  Serial.println("-----------------------");
}
 
void setup(){
  Serial.begin(115200);
  WiFi.begin(ssid, password);
   
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");
 
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
 
  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");
    if (client.connect("pub-c-xxxxxxxxxxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/n0bisuke")){ //クライアントID
      Serial.println("connected");
    }else{
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }

  client.subscribe("m5topic"); //トピック名 適当でOK
}
 
void loop(){
  client.loop();
}
```

これで書き込み、M5Atomを起動させるとSubscribeして待機してくれます。

## mosquittoのCLIでPublishを試す

ではM5Atomにメッセージを送ってみます。

インストールがまだの人はインストールから

```bash
$ brew install mosquitto
```

Publishしてみる

```bash
$ mosquitto_pub -h mqtt.pndsn.com \
-t 'PUBLISH_KEY/SUBSCRIVE_KEY/トピック名' \
-i 'PUBLISH_KEY/SUBSCRIVE_KEY/CLIENT_ID' \
-m '送りたいメッセージ'
```

という送り方になります。

実際にはPubNubの場合はこんな感じになります。

```bash
$ mosquitto_pub -h mqtt.pndsn.com \
-t 'pub-c-xxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxx/m5topic' \
-i 'pub-c-xxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxx/n0bisuke' \
-m 'ohayougozaimasu'
```

Macから送信し、M5Atomで受け取る形です。

Arduino IDEのシリアルモニタにこんな感じの表示がでれば成功です。

```
-----------------------
Message arrived in topic: m5topic
Message:"ohayougozaimasu"
-----------------------
```

## 所感

* PubNubけっこう使いやすくなってきてる
* M5Atomが二回に一回Wi-Fiをつかめないのでリスタートしてるけどなんだろうか
SwiftUIでborderの角を丸くする方法(cornerRadius)

# はじめに :qiitan: 
どうもSwiftUI大好きエンジニアです :hushed: 
今回ご紹介するSwiftUI tipsはborderの角を丸くする方法です。
簡単なのですが、ちょっと素直にできなかったのでメモとして残しておきます :baby_chick: 

実行環境: Xcode12 iOS14

# 素直に実装してみる :dog2: 
## サンプルのView

```swift
struct ContentView: View {
    var body: some View {
        Text("マリオ")
            .font(.largeTitle)
            .bold()
            .padding()
    }
}
```

![スクリーンショット 2020-09-20 1.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/e01ee3bf-a3f4-6768-68b7-7db34586e472.png)

マリオさんです。

## borderを単純につけてみる

```swift
struct ContentView: View {
    var body: some View {
        Text("マリオ")
            .font(.largeTitle)
            .bold()
            .padding()
            .border(Color.red, width: 4)
    }
}
```

![スクリーンショット 2020-09-20 1.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/0e97ac54-e270-f57c-2281-a25815737ec0.png)

だいぶ角が尖っています。荒々しいですね :baby: 

## borderを丸めてみたい（失敗）

```swift
struct ContentView: View {
    var body: some View {
        Text("マリオ")
            .font(.largeTitle)
            .bold()
            .padding()
            .border(Color.red, width: 4)
            .cornerRadius(16) // ← failure
    }
}
```

![スクリーンショット 2020-09-20 1.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/e5505551-873a-5721-10b6-02c7afeb5662.png)

borderごと削られてしまいました :anguished: 
# 角を丸める（結論） :pear: 


以下のように`RoundedRectangle`を`overlay`しましてoverlayしたRoundedRectangleを`stroke`メソッドを使ってborderにするとborderに角を丸くすることができます。


```swift
struct ContentView: View {
    var body: some View {
        Text("マリオ")
            .font(.largeTitle)
            .bold()
            .padding()
//            .border(Color.red, width: 4) 削除する
            .overlay(
                RoundedRectangle(cornerRadius: 16)
                    .stroke(Color.red, lineWidth: 4)
            )
    }
}
```

![スクリーンショット 2020-09-20 1.28.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/a1221efb-f67f-1f05-264c-52b529c756f5.png)
だいぶ角が取れて丸くなりましたね、もう怖くないです!

# 結論 :closed_book: 
**borderの角を丸くしたい場合はborderを使わない**


# 余談 :wastebasket: 
Xcode11 beta6までは以下のようにborderメソッドでcornerRadiusを指定することができていたようですが、なぜかdeprecatedになったみたいです。
どうしてですかね？知っている方教えてください :bow: 

```swift
.border(Color.purple, width: 5, cornerRadius: 20)
```

以下のように実装すると点線とかにできて面白いです :laughing: 

```swift
struct ContentView: View {
    var body: some View {
        Text("マリオ")
            .font(.largeTitle)
            .bold()
            .padding()
            .overlay(
                RoundedRectangle(cornerRadius: 16)
                    .stroke(Color.red, style: StrokeStyle(lineWidth: 4, dash: [8]))
            )
    }
}

```

![スクリーンショット 2020-09-20 2.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/d34e142d-eb23-56ef-a08d-2ea8c0c27b47.png)


# 参考 :bow_tone1: 
[SwiftUI Tip: Drawing a Border with Rounded Corners for Buttons and Text](https://www.appcoda.com/swiftui-border/)

# 宣伝
SwiftUIで作ったアプリをたくさん公開しているので是非使ってみてください！
https://apps.apple.com/jp/developer/ryo-tsudukihashi/id1320583602?l
ツイッターやってますので、是非フォローしてください
https://twitter.com/tsuzuki817
【Java】例外処理の練習【Exception】

#対象
初学者向けです。
「例外処理って何？」というレベルの内容です。

#整数をゼロで割ってエラーを発生させてみる

```java:Main.java
public class Main {

	public static void main(String[] args) {
		int a = 5;
		int b = 0;
		System.out.println(div(a,b)); // ここでエラーが発生	 
        System.out.println("終了します");
	}

	static int div(int a, int b) {
		return a / b;
	}

}
```

コンパイルエラーは発生せず、コンパイルできます。
そして実行。

```:実行結果
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Main.div(Main.java:19)
	at Main.main(Main.java:9)
```

#エラーが発生している行で処理が終わる

```java
System.out.println(div(a,b));
```
という部分で

```
java.lang.ArithmeticException: / by zero
```

このエラーの後に

```java
System.out.println("終了します");
```
という処理があるにもかかわらず一行上のエラーが発生している部分で処理が終わっています。

プログラムが強制終了していることになるので、**「エラーが発生したらこうしてね」**という処理を書く必要があります。これが例外処理。


#例外ってなに？
エラーのことです。単純にエラーだと考えて差し支えないと思います。厳密には、というか人によって捉え方が違ってくるものらしいので、とりあえず例外処理はエラー処理だと考えておけば大丈夫。

#例外処理の書き方try~catch

```java:Main.java

	public static void main(String[] args) {
		int a = 5;
		int b = 0;
		try {
			System.out.println(div(a,b));
		} catch(Exception e) { // エラーをeというオブジェクトで受け取る（オブジェクト名はなんでも良い）
			System.out.println("0で割っています！");
			System.out.println(e); // eを出力
		} finally {
			System.out.println("終了します");
		}
	}

// エラーが発生しそうな計算。エラーがある場合はExceptionクラスにエラー情報を渡す。
	static int div(int a, int b) throws Exception {
		return a / b;
	}

}
```

```java
try{
エラーが予測される処理
} catch (Exception e) {
エラーが発生した場合の処理
} finally {
エラーが発生してもしなくてもする処理
}
```

エラーが予測される処理を書く場合に、そこで終了させず、エラーが発生したらcatchの部分エラーが発生した場合の処理をする。これで処理が止まることなく最後まで動いてくれるというもの。

実際実行してみると

```：実行結果
0で割っています！ // エラーが発生した場合の処理
java.lang.ArithmeticException: / by zero // エラーメッセージ
終了します // finallyまで実行されている
```
【Selenium】ヘッダーとフッター無しで印刷(無理矢理)【Python/ChromeDriver】

#ブラウザ操作してますか？
毎日同じブラウザ操作してませんか？

そんなブラウザ操作はSeleniumに任せましょう！

Google Chromeの印刷はデフォルトで ヘッダーとフッター が表示される設定になっています。
印刷に日付もURLもいらないし……
でも設定できる項目ないし、多分……

PyAutoGui使ってキーボード操作して無理矢理変更したれ！

そんな一連の流れになります。

(実行中はマウスもキーボードも触らないように)
(ヘッドレスモードでは使えません)
(Mac環境では試していません) 

#ヘッダーとフッター無しで印刷(無理矢理)


```python:sample.py

from selenium import webdriver

import time
import pyautogui as pgui

driver = webdriver.Chrome("chromedriver.exe") #chromedriver.exe読み込み

#
#
#該当ページまでの処理
#
#

pgui.hotkey('ctrl','p')
time.sleep(3)

for loop in range(9):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

for loop in range(5):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

for loop in range(3):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

```
適宜`wait`や`sleep`を入れて調整しましょうー
通常使うプリンターに設定されているプリンターで印刷されます。

#解説
```python:sample.py
from selenium import webdriver
```
Seleniumライブラリを読み込みます。

```python:sample.py
import time
import pyautogui as pgui
```
遅延を入れる為の``time``モジュールと
キーボード操作の為のモジュールを読み込みます。


```python:sample.py
driver = webdriver.Chrome("chromedriver.exe") #chromedriver.exe読み込み

#
#
#該当ページまでの処理
#
#
```
chromedriverを起動して操作しましょう。

```python:sample.py

pgui.hotkey('ctrl','p')
time.sleep(3)

for loop in range(9):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

for loop in range(5):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

for loop in range(3):
    pgui.press('tab')
    time.sleep(.5)

time.sleep(.5)
pgui.press('enter')
time.sleep(1)

```
CTRL+Pが印刷のショートカットです。

あとはタブキーで移動して ヘッダーとフッター の所でエンターを押してチェックを外します。

またタブキーで印刷ボタンに移動して、印刷ボタンをエンターで印刷が開始されます。

アナログ的でシンプルな方法です。

#おまけ
PyAutoGUIは優秀でPCの自動操作が可能です。

マウスカーソルも操作できます。
仕事しているフリ？え？なんて？

```python:sample.py
import pyautogui as pgui

#マウスカーソルをいまの位置から右に100px上に100pxの位置にを1秒かけて移動します。
pgui.move(100, -100, 1)

#moveをmoveToにすると座標での指定も可能です。
#秒は省略することもできます。瞬間移動。
#Noneを使うこともできます。
pgui.moveTo(300, None)

#クリックできます。loopで回すとクッキーを量産できますね。
pgui.click() 

```
詳しく知りたい方はドキュメントを読んでみてください。
https://pyautogui.readthedocs.io/

ありがとうございました！
GitLabをdockerで立てる

CICDツールGitLabをdockerで立てるメモ

# GitLabについて
https://www.gitlab.jp/

- GitLab Inc.が開発したgitリポジトリサービス/ツール（GitHub的なもの）
- SaaS版と、自身でセットアップする「`self-managed GitLab`」がある
- ソフトウェアはMITライセンスのOSS
- 無償の`CE（Community Edition）`と有償の`EE（Enterprise Edition）`がある
- EEはCEより機能が豊富。self-managed GitLabでCEを使う想定でも、EEをインストールしておくのが推奨されている（あとでアップグレードが楽なので）

参考）
・ CEとEE
https://www.gitlab.jp/install/ce-or-ee/ 

・ SaaS版の機能比較
https://about.gitlab.com/pricing/saas/feature-comparison/

# self-managed GitLab　セットアップ

- 公式のインストール方法たたくさんある
    - 各種OSに直接インストール（yum/rpmなど）
    - HELMでKubernetesにインストール
    - dockerでインストール
    - 各クラウドサービス（AWS/GCP/Azule）を利用

　https://about.gitlab.com/install/

クラウドサービス利用は、マネージドGitLabがあるわけではなく、例えばAWSならEC2/RDS/ELB/S3/Elasticache/IAMなどを組み合わせてGitLabをしっかり作りこむ

https://docs.gitlab.com/ee/install/aws/

# dockerセットアップ

- 公式のdockerイメージがdocker Hubで公開されている

　　https://hub.docker.com/r/gitlab/gitlab-ee

- docker / docker-compose / docker swarm それぞれの手順がある

　　https://docs.gitlab.com/omnibus/docker/

- 例えばdockerの場合はこんな感じ

```
sudo docker run --detach \
  --hostname gitlab.example.com \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  gitlab/gitlab-ee:latest
```

# dockerでGitLab起動

- 公式のイメージでdocker runするだけだが、起動には多少時間がかかり、すぐにアクセスしても下記エラーとなる。

<img width=300 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/163665bb-47ab-0c29-ac1c-751a9c5fe47c.png>

- 数分待てばログインできるようになる。初回アクセス時は、管理者（root）のパスワード設定から

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/b98af6dc-b2ef-472b-3bfb-a33dda0b6530.png>

- rootパスワードを設定すると、下記ログイン画面に切り替わるので、usernameをroot、パスワードは先ほどのやつでログイン。

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/0a0959aa-3842-19df-ae9d-683329fdfd2f.png>

- 下記トップ画面に

<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/c1cc05f2-4fa0-38c5-fd63-de4dcc184dc5.png>
Google Earth Engineで虹色トラック

#概要

Google Earth Engineで、虹色トラックを探してみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6aff6417-1126-f023-74cc-f97358a2edbd.jpeg)


#サンプルコード


```
var po = ee.Geometry.Point(140.425, 37.793);
Map.centerObject(po, 15);
function maskS2clouds(image) {
	var qa = image.select('QA60');
	var cloudBitMask = 1 << 10;
	var cirrusBitMask = 1 << 11;
	var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(qa.bitwiseAnd(cirrusBitMask).eq(0));
	return image.updateMask(mask).divide(10000);
}
var dataset = ee.ImageCollection('COPERNICUS/S2').filterDate('2018-01-01', '2018-06-30').filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)).map(maskS2clouds);
var rgbVis = {
	min: 0.0,
	max: 0.3,
	bands: ['B4', 'B3', 'B2'],
};
Map.addLayer(dataset.mosaic(), rgbVis, 'RGB');



```

以上。
【Laravel】Collectionのtakeメソッド

##はじめに
今回もLaravelのCollectionのメソッドについてまとめたいと思います。

##takeメソッドで指定した件数だけデータ取得する
Collectionの中から特定の件数だけを取得することができます。

```php:
$collection = collect(['赤', '青', '黄', '緑', '白',]);
$chunk = $collection->take(3);
print_r($chunk->toArray());
```

実行結果は下記になります。

```
Array
(
    [0] => 赤
    [1] => 青
    [2] => 黄
)
```

先ほどは正の数でしたが負の数を用いていて実装すると、後ろから指定した数の値を取得することができます。

```php:
$collection = collect(['赤', '青', '黄', '緑', '白',]);
$chunk = $collection->take(-2);
print_r($chunk->toArray());
```
実行結果は下記になります。

```
Array
(
    [4] => 白
    [3] => 緑
)
```

##おわりに
いかがでしたでしょうか。
takeメソッドでは負の数も用いることができるので必要な時があれば試してみてください。
画面上の戻るボタン

http://rikisha-android.hatenablog.com/entry/2014/04/04/202207




```kotlin
    override fun onCreate(savedInstanceState: Bundle?) {
..
        //戻る
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home ->{
                finish()
                return true
            }
            else -> return super.onOptionsItemSelected(item)
        }
    }
```
【自分用メモ】Docker Desktop for WindowsのCPUs設定についての小ネタ

こちらを参考にさせて頂きました。
[Docker Desktop WSL 2 バックエンド — Docker-docs-ja 19.03 ...](https://docs.docker.jp/docker-for-windows/wsl.html)
[WindowsでDocker環境を試してみる - Qiita](https://qiita.com/fkooo/items/d2fddef9091b906675ca)
[Docker Desktop for Windows （参考訳） - Qiita](https://qiita.com/zembutsu/items/0a66e9a3fb078e1c90ae)

※こちらの記事はDocker Desktop Community 2.3.7.0(Windows)以前の情報になります。

私の環境は以下になります。
Microsoft Windows [Version 10.0.19041.508]
Windows 10 Pro バージョン 2004 64bit
Intel Core i5-3340M 2.70GHz
RAM 16GB
Fujitsu LIFEBOOK P772/G

VScode Version: 1.49.1 (user setup)以前の情報です

※本日確認したところ、VSCodeで「VSCode Remote Development」の拡張機能を有効にした状態で、Docker Desktop for Windowsを起動してもCPU使用率は一桁台で安定していました。

[Windows Subsystem for Linux のリリース ノート](https://docs.microsoft.com/ja-jp/windows/wsl/release-notes#build-20175)
上記サイトに「WSL2 VM の既定のメモリ割り当てを、ホスト メモリの 50% または 8 GB のどちらか少ない方になるように調整します」との記載がありますので、それで改善されたのかもしれません。
以前、WSL2を有効した状態でVSCodeの拡張機能のRemote Developmentを有効にしたところ、CPU使用率が100%近くを維持する現象がありました。その際に、WSL2のCPUの割当率を下げようとしたところ、ResoucesタブにCPUsの項目が見当たらないことに気づきました。
そのため、備忘録として残したいと思います。

#結論
Generalタブの「Use the WSL 2 based engine」のチェックをつけるかつけないかということみたいです。
WSL2は動的にリソースを割り当てるそうですので、設定を行う必要がないということだと思います。

スクリーンショット

#「Use the WSL 2 based engine」チェックをつけた場合
※ResourcesタブのProxiesとNetworkの項目はかわりないようです。
![WS000710.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/2877da87-be72-0d8c-a62b-6e944f26dccc.jpeg)
![WS000712.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/ec7a52c0-7d69-588e-a09b-deb6395ea5bd.jpeg)
![WS000713.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/ea8e5dd7-7491-9503-9b6a-fe1218a43bca.jpeg)
![WS000714.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/eca96056-c00e-ea71-cda6-af4f40dddc11.jpeg)

#「Use the WSL 2 based engine」チェックをつけなかった場合
※ResourcesタブのAdvancedの中にCPUsの設定項目がありました。
![WS000707.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/cdad68f8-3efc-6987-d7ff-14b768eb1712.jpeg)
![WS000708.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/a4d0b3d6-c082-a8b9-eba3-064dcb0350df.jpeg)
![WS000709.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/f7451c42-f88a-d6ca-5f02-786da6293493.jpeg)
![WS000726.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/7bb40907-2465-27d6-0565-d3aba145fd3a.jpeg)
![WS000727.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80258/3ca00436-e381-8b0f-b959-c9d8f5e9b3fc.jpeg)
サイバーセキュリティ経営ガイドライン

応用情報技術者平成29年春期 午前39

経済産業省とIPAが策定した"サイバーセキュリティ経営ガイドライン(Ver1.1)"の説明はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a3c521f4-537d-2c1c-e1a6-4f3f31221ca1.png)

１、サイバーセキュリティ経営ガイドラインは、
サイバー攻撃から企業を守る観点で、経営者が認識する必要のある「3原則」、及び経営者が情報セキュリティ対策を実施する上での責任者となる担当幹部（CISO等）に指示すべき「重要10項目」をまとめたものです。具体期には、経営者のリーダーシップの下での体制整備と対策の進め方、社会やステークホルダーに対する情報開示のあり方などが取りまとめられています。


２、
・情報セキュリティ方針の説明
経営者が，情報セキュリティについて方針を示し，マネジメントシステムの要求事項を満たすルールを定め，組織が保有する情報をCIAの観点から維持し，継続的に見直すためのプロセス及び管理策を体系的に規定したもの

・COBITの説明
事業体のITに関する経営者の活動を大きくITガバナンス(統制)とITマネジメント(管理)に分割し，具体的な目標と工程として37のプロセスを定義したもの
　　・COBIT（英: control objectives for information and related technology）とは、情報システムコントロール協会 (ISACA)とITガバナンス協会 (ITGI)が1992年に作成を開始した情報技術 (IT) 管理についてのベストプラクティス集（フレームワーク）である。COBIT はマネージャ、監査人、ITユーザーに一般に通じる尺度や判断基準、ビジネスプロセスやベストプラクティスを提供して情報技術を利用して得られる利益を最大化するための補助とし、企業内の適切なITガバナンスや内部統制の開発の補助となる。


・サイバーセキュリティ基本法の説明
世界的規模で生じているサイバーセキュリティ上の脅威に関して，企業の経営者を支援する施策を総合的かつ効果的に推進するための国の責務を定めたもの


参照：
https://www.ap-siken.com/kakomon/29_haru/q39.html

COBIT
https://ja.wikipedia.org/wiki/COBIT
ssh-agent による公開鍵認証と SSH Agent Forwarding による多段ログイン

ssh で公開鍵認証を使用し、デフォルトの秘密鍵(~/.ssh/id_rsa)以外でログインする場合は `-i` オプションで秘密鍵を指定する必要があるが、ssh-agent を使うことで指定が不要になる。さらに SSH Agent Forwarding 機能を使うと、秘密鍵をローカル PC に置いたまま、ログイン先のサーバーからさらに別のサーバーにログインすることもできる。

![概要](https://hirose-public.s3-ap-northeast-1.amazonaws.com/qiita/2021/04/10/66f14702-33a7-44e4-ac09-d5f25a906c68.png)

## ssh-agent

### 秘密鍵の登録

 1. ローカル PC で ssh-agent を起動する。macOS では自動的に起動するので不要。

    ```shell
    eval `ssh-agent`
    ```

 2. ローカル PC の ssh-agent に秘密鍵を登録する。ファイル名を省略するとユーザーのデフォルト秘密鍵(~/.ssh/id_rsa)が登録される。

    ```shell
    ssh-add xxxx.pem
    ```

### SSH ログイン

ssh-agent が起動していれば、毎回 `-i` オプションで秘密鍵を指定する必要なくログインすることができる。複数の鍵を登録してある場合は、それぞれの鍵で試行される。そのためあまり多くの鍵を登録すると Too many authentication failures となりサーバーから拒否される場合があるので注意。

```shell
ssh <user>@<host>
```

## SSH Agent Forwarding

### サーバー設定

踏み台とする SSH サーバーで、Agent Forwading 機能が有効になっている必要がある。
デフォルトで有効になっているかもしれないので、確認する。

```
# /etc/ssh/sshd_config
AllowAgentForwarding yes
```

### ログイン

踏み台サーバーへのログイン時に `-A` オプションをつけることで、ログイン先のサーバーからもローカルの ssh-agent に登録した鍵が使用されるようになる。さらにその先からも多段にログインしたい場合はその都度 `-A` オプションをつければ良い。

```shell
ssh -A <user>@<host>
```

### 設定

毎回 `-A` オプションをつけるのが面倒な場合は、接続元のホストで以下のように設定しておく。

```
# ~/.ssh/config
Host server1.example.com  (接続先のホスト名)
  ForwardAgent yes
```

### Git over SSH

Git など SSH 経由でアクセスする場合も自動的に ssh-agent に登録した鍵が使用される。

```shell
git clone git@<host>:<user>/<repos>.git
```

### 別ユーザーに切り換える

別ユーザーに切り換えても ssh-agent を維持するには環境変数を保持する必要がある。sudo に -E オプションをつけて実行する。

```shell
sudo -E git clone git@<host>:<user>/<repos>.git
```
【Vue.js】クリック処理　@click 

##【ゴール】
![画面収録 2020-09-20 9.12.12.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620689/e3c120a5-d668-6c5e-4ddf-2c145c374bd7.gif)



Vue.jsを用いてクリック処理を実施 

##【環境】
`mac catarina 10.156`
`Vue.js v2.6.12`


##【実装】

```html:index.html
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <p>{{number}}</p>
  <button @click="increaseNumber">増やす</button>
</div>
.
.
.
<script>
  new Vue({
    el: '#app', //対象を取得
    data: {
      number: 0  //numberをセット
    },
    methods: {
      increaseNumber: function(){
        return this.number += 1;  //numberに対して、１ずつ加えていく
      }
    }
  })
</script>
```

##【まとめ】
■　htmlでは、{{}}でvuejsのデータを表示
■　vuejsでは@click等の便利なディレクティブが多数ある

##【オススメ記事】

■ 【Vue.js】 IF文・For文　条件分岐、繰り返し処理
https://qiita.com/tanaka-yu3/items/0ccf9a11525331b764de

■ 【node.js】ルーティング設定ホーム画面表示させる。
https://qiita.com/tanaka-yu3/items/1c8859e16070e67d73c0

■ 【node.js】 node.jsインストール 芋っていたけど、簡単だった件...
https://qiita.com/tanaka-yu3/items/739db5ffed24a8d9ae4b
kubernetesでinitコマンドを試す


## initコンテナ
- 環境ごとに変わるコマンドなどを実行させる
- ボリュームをマウントしてから出ないと実行できないコマンドなどを実行させる
- Pod起動後に必要なコマンドを実行させる

## initコンテナのyamlファイル
- myserviceとmydbを２秒毎に待ち受けて、見つかれば処理終了

```myapp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
```

### 起動

```
kubectl apply -f myapp.yaml
```

### 確認

```
kubectl get -f myapp.yaml 
```

serviceもdbもいないのでまだREADYになっていない

```
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          3m15s
```

## serviceを作成する
```service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
```

### 起動

```
kubectl apply -f service.yaml
```

### 確認

```
yuta:~ $ kubectl get -f myapp.yaml 
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          6m15s
```

## ログ確認コマンド

```
kubectl describe -f myapp.yaml
```

```
kubectl logs myapp-pod -c init-myservice
```

## 参考
https://kubernetes.io/ja/docs/concepts/workloads/pods/init-containers/
githubを使うまで

# GitHubにアカウントを作る
https://github.com/

# PCにGitをインストールする

- windows の人
https://git-scm.com/download/win からインストール

- mac の人
[homebrew](https://brew.sh/index_ja) が入ってない人はインストール

```
brew install git

// Summaryにあるところにパスを通す（バージョンによって違う）
export PATH="/usr/local/Cellar/git/2.5.0/bin:$PATH"

git --version
// バージョン確認ができたらインストールがうまく言っているので ~/.bash_profile に exportの文を追記
```

# Forkをインストール
https://git-fork.com/

1. インストールしたGitを選択
2. Forkにgithubのアカウントでログイン

# Git を使ってみよう

参考サイト
- [サル先生のGit入門](https://backlog.com/ja/git-tutorial/)

## 一から作るときの手順
1. Githubでリポジトリを作成
2. Forkからclone

## 既存のプロジェクトをバージョン管理する手順
1. バージョン管理したいディレクトリをForkで開く（自動でgitの設定ファイルが作成される）
2. 今あるファイルをステージング・コミットする
3. Githubでリポジトリを作成して、Forkでリモートに設定
4. Forkからプッシュ
VagrantでCentOS8環境を構築し sync_folder しようとしたらエラーが出たので解決した

# sync_folderで発生したエラーと解決策

Vagrantfileの定義に`sync_folder`を指定してphpのCodeIgniterを使ったシステム開発をしようかなと思ったら、エラーが出てしまった。

以下はVagrantfileの定義です。

```config:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/8"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end
  config.vm.provision :shell, :path => "./provision.sh", :privileged => true

  config.vm.synced_folder "./codeigniter", "/var/www/html/codeigniter"
end
```

`vagrant up`すると最後のほうで赤文字で以下のエラーが出ていました。

```shell-session:vagrantupで出たエラー
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

/usr/sbin/rcvboxadd setup

Stdout from the command:

VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 
4.18.0-193.19.1.el8_2.x86_64.

VirtualBox Guest Additions: Look at /var/log/vboxadd-setup.log to find out what 
went wrong


Stderr from the command:

modprobe vboxguest failed
The log file /var/log/vboxadd-setup.log may contain further information.
```

このエラーメッセージが指摘しているように`/var/log/vboxadd-setup.log`のファイルの中身を見てみます。
`vagrant ssh`で起動したCentOSにアクセスし、ログを確認します。

```shell-session
less /var/log/vboxadd-setup.log

Building the main Guest Additions 6.1.12 module for kernel 4.18.0-193.19.1.el8_2.x86_64.
Error building the module.  Build output follows.
make V=1 CONFIG_MODULE_SIG= CONFIG_MODULE_SIG_ALL= -C /lib/modules/4.18.0-193.19.1.el8_2.x86_64/build M=/tmp/vbox.0 SRCROOT=/tmp/vbox.0 -j1 modules
Makefile:978: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel".  Stop.
make: *** [/tmp/vbox.0/Makefile-footer.gmk:117: vboxguest] Error 2
Could not find the X.Org or XFree86 Window System, skipping.
modprobe vboxguest failed
```

このエラーの中で重要な部分は、

```shell-session
please install libelf-dev, libelf-devel or elfutils-libelf-devel
```

で、libelf-devなどの依存関係がインストールに失敗するのでなんとかして。ということらしいです。
試しに`dnf -y install libelf-dev`としてみると、そんなの無いよと怒られました。

調べてみると、`elfutils-libelf-devel`というのに変わっているようなので、これをインストールしてみます。

```shell-session
dnf install -y elfutils-libelf-devel
```

いったんCentOSから抜けて`vagrant reload`を実行します。
これでsync_folderのエラーが解消できました。
MacのAlacrittyで日本語が文字化けする


# はじめに

これまでAlacrittyの日本語がきちんと動いていたのですが
ふとしたタイミングで動かなくなり、日本語がすべて`????????`と表示されました。

# 修正内容

Alacrittyでは、`$LANG`変数で日本語であることを示さないと文字化けしてしまうようです。

そのため、bashであれば.bashrcなどに

```bash
export LANG=ja_JP.UTF-8
```

と記述すればよいです。

僕はfishを使っているので
`~/.config/fish/config.fish`に

```bash
set LANG ja_JP.UTF-8
```

を追記しました。

これで、日本語がきちんと描画されるようになりました。


ただし、alacrittyの設定ファイルできちんと日本語フォントを設定しないといけないので、ご注意ください。
SSL/TLS通信シーケンス

応用情報技術者平成29年春期 午前37

A社のWebサーバは，サーバ証明書を使ってTLS通信を行っている。PCからA社のWebサーバへのTLSを用いたアクセスにおいて，当該PCがサーバ証明書を入手した後に，認証局の公開鍵を利用して行う動作はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/07c93b8b-e27a-24a9-b0b1-e3a80f34748a.png)

１、サーバ証明書は、
TLS暗号化通信の開始に先立ち、サーバからクライアントに送られる公開鍵に対する電子式の証明書で、認証局(CA)と呼ばれる第三者機関によって発行されています。サーバ証明書には、認証を受けた公開鍵が含まれていて、その信頼性を担保するために認証局のディジタル署名が付されています。

２、SSL/TLS通信シーケンス
　・公開鍵で認証局のディジタル署名を検証
サーバ証明書を提示された利用者は、暗号化通信の開始に際し「認証局の公開鍵」を使用してサーバ証明書に付された「認証局のディジタル署名」を検証します。ディジタル署名の検証に成功したならば、同封されている公開鍵が正当であり、かつ、改ざんされていないことが保証されます。
　・共通鍵の共有と通信
SSL/TLSでは公開鍵の検証後、その公開鍵を使って通信相手と共通鍵を共有します（RSA方式の鍵交換の場合）。そして、以降はその共通鍵を使用して暗号化通信を行います。


詳細は下記を参照：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/f08c57c3-1bee-f189-6f51-4688594c2ad6.png)


注意点は：
１）、サーバからクライアントに送られる公開鍵は付されるので、必ず信用できる。
　　　※これが前提ですね。普通は、手動（メールとか）で付されるでしょう。

２）、公開鍵は、
　　　・認証局のディジタル署名　を検証する　
　　　　⇒サーバーの正当性を検証するため

　　　・暗号化通信用共通鍵生成用データを作成　
　　　　⇒公開鍵、秘密鍵の役割は、サーバの認証と通信用共通鍵の生成ですね。
　　　　　今後の互いの通信用は一時の共通鍵ですね、都度変わると思います。
　
　　　・その共通鍵データを暗号化してサーバに送信

　　　・通信用共通鍵を生成

３）、サーバの秘密鍵は
　　　・クライアントから来た共通鍵データを復号する
　　　・共通鍵生成用データを共有
　　　・通信用共通鍵を生成

参照：
https://www.ap-siken.com/kakomon/29_haru/q37.html
PyTorchでRGBとHSVを微分可能な形で変換する

意外と見つからなかったので、[HSV色空間 - Wikipedia](https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93)に書いてある式をもとに実装しました。

ただRGBとHSVを変換するだけなら他のライブラリ（PIL、OpenCVとか）でもできますが、それでは微分できないので、ニューラルネットの内部に組み込むことができません。
そこで、PyTorchの関数のみを使ってRGBとHSVを相互に変換する関数を書きました。

**2020-10-31 追記**
よく調べてみたら[kornia](https://github.com/kornia/kornia)という便利なライブラリがあるようです。
korniaはコンピュータービジョン系の処理をPyTorchを使って微分可能な形で実装したライブラリで、そこにRGB-HSVの変換もあります。
多分korniaの実装のほうがいろいろ良いので、korniaを使いましょう。


# コード

``` color_convert.py
import torch


def rgb2hsv(input, epsilon=1e-10):
    assert(input.shape[1] == 3)

    r, g, b = input[:, 0], input[:, 1], input[:, 2]
    max_rgb, argmax_rgb = input.max(1)
    min_rgb, argmin_rgb = input.min(1)

    max_min = max_rgb - min_rgb + epsilon

    h1 = 60.0 * (g - r) / max_min + 60.0
    h2 = 60.0 * (b - g) / max_min + 180.0
    h3 = 60.0 * (r - b) / max_min + 300.0

    h = torch.stack((h2, h3, h1), dim=0).gather(dim=0, index=argmin_rgb.unsqueeze(0)).squeeze(0)
    s = max_min / (max_rgb + epsilon)
    v = max_rgb

    return torch.stack((h, s, v), dim=1)


def hsv2rgb(input):
    assert(input.shape[1] == 3)

    h, s, v = input[:, 0], input[:, 1], input[:, 2]
    h_ = (h - torch.floor(h / 360) * 360) / 60
    c = s * v
    x = c * (1 - torch.abs(torch.fmod(h_, 2) - 1))

    zero = torch.zeros_like(c)
    y = torch.stack((
        torch.stack((c, x, zero), dim=1),
        torch.stack((x, c, zero), dim=1),
        torch.stack((zero, c, x), dim=1),
        torch.stack((zero, x, c), dim=1),
        torch.stack((x, zero, c), dim=1),
        torch.stack((c, zero, x), dim=1),
    ), dim=0)

    index = torch.repeat_interleave(torch.floor(h_).unsqueeze(1), 3, dim=1).unsqueeze(0).to(torch.long)
    rgb = (y.gather(dim=0, index=index) + (v - c)).squeeze(0)
    return rgb
```


# 使い方
`rgb2hsv`と`hsv2rgb`はどちらも画像のミニバッチ（NCHW形式）の画像を入力とします。
H（色相）の範囲は0から360までです（範囲外はループします）。
RGBとSVの範囲は0から1までです。
djangoを用いてWEBアプリケーション開発　～開発環境構築～

# はじめに
WEBアプリケーションに興味があり簡単に作成することができる、WEBアプリケーションフレームワークの一つである、djangoを使用して簡単な投票WEBアプリケーションのチュートリアルをチャレンジしました。

## 環境
- windows 10
- python 3.7.1
- VScode

## 環境を整える（インストールするもの）
- pythonはインストール済み前提
- pipをインストールする
- Djangoをインストールする
- virtualenvをインストールする

## インストール
### pipインストール
- pipとは・・・各種パッケージのインストールを簡単にするツールです。
- pipをダウンロード(コマンドプロンプトにて実施、以下cmd)

~~~
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
~~~
コマンドを実施したディレクトリにget-pip.pyが格納される。※デフォルトだとユーザ配下

- pipのインストール

~~~
python get-pip.py
~~~
「Successfully installed...」と表示されていれば、インストールは完了です。

### virtualenvインストール
- virtualenvとは・・・仮想環境を動かすためのソフトウェアです。今回はDjangoを仮想環境で動かします。
- virtualenvをインストールする

~~~
pip install virtualenv
~~~
- 仮想環境を作成する

どこでもよいですが、あらかじめ「Python」フォルダを用意しておきます。
今回はCドライブ直下に作成します。作成したら、cmdにてディレクトリに移動します。

~~~
cd C:\Python
~~~
移動したら、仮想環境を作成します。

~~~
virtualenv env1
~~~
作成が完了したら、「env1」のディレクトリに移動します。

~~~
cd env1
~~~
移動したら、仮想環境を有効化します。

~~~
Scripts/activate
~~~
有効化すると、以下のように表示されます。

~~~
(env1) C:\Python\env1>
~~~

### Djangoインストール
- Djangoのインストールを行う。

仮想環境が有効化の状態になっていることを確認してから実行してください。

~~~
pip install django
~~~
「Successfully installed...」と表示されていれば、インストールは完了です。

- Djangoが正常にインストールされていることの確認

~~~
pip freeze
~~~
下記のようにDjangoとその他関連ソフトウェアのバージョンが出力されます。

~~~
asgiref==3.2.10
Django==3.1
pytz==2020.1
sqlparse==0.3.1
~~~

- コマンドプロンプトを抜ける
上記で、確認ができたら一旦、コマンドプロンプトを終了します。

仮想環境を無効化します。

~~~
deactivate
~~~

コマンドプロンプト終了します。

~~~
exit
~~~

## Djangoの動作確認
- 正常に動作することの確認(cmdで実施)

ディレクトリに移動します。

~~~
cd C:\Python\env1
~~~
> 移動したら、仮想環境を有効化します。
> Scripts/activate

有効化したら、対話モード(インタプリタ)にします。

~~~
python
~~~
立ち上がったら、Djangoをインポートします。
次のコマンドをそれぞれ入力して、1行ごとにEnterキーを押します。

~~~
>import django
>print(django.get_version())
~~~

次のような形でDjangoのバーションが表示されていれば、動作確認完了です。

~~~
3.1
~~~

次回からVScodeを使用していきます。
[djangoを用いてWEBアプリケーション開発　～開発その１～](https://qiita.com/sunachi/private/297a6ac5546aab6aa1d4)  **>>>**

## 参考資料
- https://udemy.benesse.co.jp/development/web/django.html
- https://docs.djangoproject.com/ja/3.1/intro/tutorial01/
- https://python.keicode.com/devenv/virtualenv.php
Angular Observer patternについて

# 概要
 AngularにおけるRxJSを利用したObserver patternはRxJSの基礎であると共に、躓きやすいポイントの一つです。
 大体書いた直後とかは何やっているか理解できるけど、しばらくたって同じコードを見ると「Subjectって何やってるんだっけ?」「subscribeがどこにも見当たらないんだが?」「Observer? Observable?」みたいな状態なってしまい、それを何回も繰り返してしまいます(サンプル数1)。
 このドキュメントを通して、**Anbularでの**Observer patternにおける登場人物が何をやっていて、お互いにどういう風に関連しあっているのかを整理をして行きたいと思います。

# Observer pattern?
 Observerパターンとはデザインパターンの一種です。[wikipedia](https://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3#:~:text=Observer%20%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%EF%BC%88%E3%82%AA%E3%83%96%E3%82%B6%E3%83%BC%E3%83%90%E3%83%BB%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%EF%BC%89,%E3%82%8F%E3%82%8C%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%AE%E4%B8%80%E7%A8%AE%E3%80%82)で書かれているのは「プログラム内のオブジェクトのイベントを他のオブジェクトへ通知する処理」とのこと。自分はこの説明を聞いたとき具体的に何ができるのか今一想像できませんでした。
それよりも私は[publish/subscriber pattern](https://ja.wikipedia.org/wiki/%E5%87%BA%E7%89%88-%E8%B3%BC%E8%AA%AD%E5%9E%8B%E3%83%A2%E3%83%87%E3%83%AB)の一部と言われたほうがイメージがしやすかったです。

## publish/subscriber
publish/subscribeとは「メッセージの送信者(publisher)が特定の受信者（subscriber）を想定せずにメッセージを送るようプログラムされたものである。」とwikipediaにあります。プログラムに限らずこのモデルは様々な所で利用されており、メーリングリストなどは一番有名なpublish/subscribeer patternの利用用途ですね。
Observer patternはその中でpublisherが管理しているオブジェクトの変更の通知をsubscriberが購読(subscribe)するという特殊な用途の一つなのではないかなと考えています。

# 全体図
このObservable patternでデータがどのように流れるかの概略図は以下になります。
![こんな感じで動いているように見える](https://storage.googleapis.com/zenn-user-upload/9zsz3nu84ojx09ayfam55yh8zdvm)
Publisherが監視しているObjectに変更があった場合にひとつのPublisherから複数のSubscriberに「データがAからBに変わりましたよ」というデータが一方的に流れるようなデータの流れをします。
これはデータを取得したいSubscriberはポーリングなど積極的にデータの変更を検知する努力をする必要がなく、ただSubscriberは口を開けて待っているだけでPublisherが「AからBに変更したよ」という情報を送ってくれることになります。やばいですね。

では一体どうやって実現しているのでしょうか。
上の図よりももうちょっと内部実装よりな図が以下になります

![内部でどう動いているか](https://storage.googleapis.com/zenn-user-upload/1bou7ieulv5oq5rucstkccx7vmwj)

この図を元にデータの受け取り側(Subscriber)と送り側(Publisher)が何をしているのか見ていきましょう。

## Subscriber(Consumer)は何をしているの?
登場人物その1。Subscriberは最終的にPublisherから値を受け取りたいのです。
そのためには以下の2ステップを踏みます。
1. **observer**を定義
2. そのobserverをpublisherに登録(購読)

### observerとは
observerとは`next()`, `error`, `complete()`を実装した関数を持つオブジェクトです。
`next`は変更検知したというデータを受け取ってPublihserが実行するハンドラーで、例えばこのnextハンドラーを通じてSubscriberAが持っているObjectに変更を反映させるということもできます。
`error`はなにかエラーが発生したときに実行するハンドラー(実装は任意)
`complete`は実行が完了したときに実行されるハンドラー(実装は任意)

この定義したハンドラーは値の変更が通知されたときにSubscriberがその値をどうしたいのかが定義されています。

### observerをPublisherに登録する(購読する)
定義したobserverはPublihserに登録します。
Angular(RxJS)でよく見る`subscibe(observer)`がまさにその購読処理になります。

## Publisherは何をしているの?
登場人物その2。PublisherはSubscriberが登録したハンドラーを監視しているオブジェクトの変更をトリガーに実行します。RxJSではObservableというインスタンスのsubscirbe関数にSubscriberが定義したobserverを渡すことで実現します。

### Observableとは
Observableは以下のことをしてくれます。
- データを流す
- そのデータを流したときに実行する関数(observer)を登録する。
#### データを流す
このデータの流れは色々な所から取得することができ、それはhttpリクエストだったりとか、イベントだったりとか、またRxJSならSubjectを利用すれば`next`関数でデータを流すこともできます

Publisherは以下のことをします。
- 監視対象のオブジェクトの変更を検知
- 登録されているSubscriberのハンドラーを実行する。
	- この登録される関数はいくつでも登録可能なので1対Nの通信(一方的にデータを垂れ流すだけですが)が可能
		- 1はPublisherでNはSubscriber。


# Angularにおける実装
TBD
なんか文章量も多くなってきたし、別で書くかも
Elasticsearchで「circuit_breaking_exception」に出会った

##環境
Amazon Elasticsearch 7
JVMヒープ 40%

##事の顛末

Elasticsearchで、凡そ大量データを一気に集計・整列するAPIを作成し、テストを行ったところ、
以下のようなエラーレスポンスが帰ってきた。


```"root_cause": [
    {
        "type": "circuit_breaking_exception",
        "reason": "[request] Data too large, data for [] would be larger than limit of [8998512230/8.3gb]",
        "bytes_wanted": 10464007168,
        "bytes_limit": 8998512230
    }
]```

普通に初めて見るエラーだったので面食らう。


##どんなエラーか

ざっくり「OutOfMemory一歩手前」みたいなイメージらしい。
本格的にOutOfMemoryになってGCが頻発、システムダウン、、みたいな事を防ぐ為に、
「キャパの身の丈に合わないリクエストは拒否しますよ～。」
という機能で、Elasticsearch 7 ~追加された機能のよう。
目的は理解。


引用:
・https://www.elastic.co/jp/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker
・https://www.elastic.co/guide/en/elasticsearch/reference/current/circuit-breaker.html


##対処の選択肢

結局OutOfMemoryの対策とそこまで相違なさそうなので、以下対策を考えた。

①ノード数を増やす。
②インスタンスタイプを強化。
③JVMヒープ割合を40%より大きくする。

各選択肢を検討してみたのだが、
まず①、②はインスタンスを増やすため、コストがかかる。
なので、出来れば設定値を変えるだけで済む③を採用したい。


##どう解決までもっていったか

負荷試験を行い、他機能に影響が無い事を担保した上で、各署と調整しJVMヒープの割合を40%から50%まで上げることで、上記エラーが解決した。

③の方法を取る懸念としては、JVM以外のメモリ領域が小さくなってしまうことだ。
JVMヒープを上げることで、他処理に影響が出てしまう可能性があった。

何にしても影響調査は必須だろうと思う。


##まとめ

半分備忘録。

実際にシステムダウンしちゃう前にこうして止めてくれるのは便利。
けど、挙動的にはエラーを返してきて、データが表示されない事に変わりはないので、
確実に防ぐべきエラー、という温度感で考えてよいかと思う。
vuejsのwatchで複数の値を監視したい！！！

#初めに
Vuejsのwatchはとても便利で値の変化を監視することができます。

#実現したかったこと
- watchで2つの値を監視したい。

とのことで、僕は最初に

``` test-case1.vue
<template>
 <div>
  <input type="number" v-model="numberObj1">
  <input type="number" v-model="numberObj2">
  <p>{{ tashizan }}</p>
 </div>
</template>
<script>
 data() {
  return {
   numberObj1: '',
   numberObj2: '',
   tashizan: ''
  }
 },
 watch: {
  numberObj1 & numberObj2 () {
   this.tashizan = this.numberObj1 + this.numberObj2;
  }
 }
</script>
```
便利なVuejsだしこれで行けるやろ！ってどこかで思ってました。
そんなに世界は甘くはなかった。これでは行けなかった。

#結論

```sample.vue
<script>
(省略)
 computed: {
  MathObject() {
   return [this.numberObj1,this.numberObj2];
  }
 },
 watch: {
  MathObject (val) {
   this.tashizan = this.numberObj1 + this.numberObj2;
  }
 }
</script>

```
この方法で複数の値を監視することができました。
サンプルコードは短いからみやすいですけど、実業務になってくるとコードが長くなってくるのでこの<b>MathObject</b>に何があるか分からないため、computedまで確認する必要性があるみたいです。
他の方とコードを共有している場合はコメントアウトなどを利用して変数を書いてあげると親切かもしれませんね。
symfony4リレーションしているEntityのFormType設定

#FormBuilderへ追加
```
$builder->add('user', UserType::class);
```
#Twig
```
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
```
##Entityに存在しないフィールドをFormに追加する場合
```
->add("inputName", TextType::class, array("mapped"=>false, "data"=>'初期値', "label"=>false))
```