OmniAICreator/Qiita-1.07M huggingface dataset:
Chromeで開いているタブのURLをコマンドラインから取得する(macOS)

AppleScriptを使って書いているので、macOS でしか動きません。
とりあえず`zsh 5.8 (x86_64-apple-darwin19.6.0)` と `GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)` での動作を確認しています。

```bash
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.6
```

### 現在開いている Chrome の window の数を取得する

```sh
osascript -e 'tell application "Google Chrome" to get number of windows'
```

### window で開いているタブの数を取得する
```sh
osascript -e 'tell application "Google Chrome" to get number of tabs in window 1'
```

### タブの URL を取得する
```sh
osascript -e 'tell application "Google Chrome" to get URL of tab 1 of window 1'
```

## よしなに書いてみる

```sh
#!/bin/sh

tell_chrome='tell application "Google Chrome"'

num_win=$(osascript -e "$tell_chrome to get number of windows")

for (( i=1; i<=num_win; i++ )); do
    num_tab=$(osascript -e "$tell_chrome to get number of tabs in window $i")
    echo "[$num_tab tabs in window $i]"
    for (( j=1; j<=num_tab; j++ )); do
        url=$(osascript -e "$tell_chrome to get URL of tab $j of window $i")
        echo "\t$url"
    done
    echo
done
```

```:実行結果
[2 tabs in window 1]
        chrome://newtab/
        https://qiita.com/

[1 tabs in window 2]
        file:///Users/hoge/huga/index.html
```

### ちなみに

```sh
open -a "Google Chrome" https://qiita.com
```

これでChromeを直接開くことができます。

## 追記

### アプリの起動
```sh
osascript -e 'tell application "Google Chrome" to activate'
```

### アプリの終了
```sh
osascript -e 'tell application "Google Chrome" to quit'
```

### window を閉じる
```sh
osascript -e 'tell application "Google Chrome" to close window 1'
```

### すべての window を閉じる
```sh
osascript -e 'tell application "Google Chrome" to close every window'
```
【ROS】複数PCでの通信：rostopic echoが表示されない

# はじめに
リモートPC、ラズベリーパイの2つのPC間でROSの通信をしようとしてうまくいかなかったので同じ事象にあった方の助けになればうれしいです。
あくまで自分の環境の話なので参考にならないこともあるかと思いますがご容赦ください。

# 環境
リモートPC、ラズベリーパイともに以下の環境です。

| 項目 | バージョン |
|:-:|:-:|
| Ubuntu | 16.04 |
| ROS | Kinetic |

# 結論
2つのPCの環境変数の`ROS_MASTER_URI`と`ROS_HOSTNAME`を正しくセットする。
※`ROS_IP`を使わなかったらうまくいった

`ROS_MASTER_URI`は、リモートPCのアドレス(http://アドレス:11311)(**共通**)
`ROS_HOSTNAME`は、追加する方のPCのIPアドレス(**PCごとに違う**)

## 具体例
ここで、リモートPCのIPアドレスは`192.168.100.100`
ラズベリーパイのIPアドレスは`192.168.100.101`とします。

`~/.bashrc`に以下を追記します。

リモートPC

```shell
export ROS_MASTER_URI=http://192.168.100.100:11311
export ROS_HOSTNAME=192.168.100.100
```

ラズベリーパイ

```shell
export ROS_MASTER_URI=http://192.168.100.100:11311
export ROS_HOSTNAME=192.168.100.101
```

# 起きた事象
解決策は違いましたが、この記事や、
[ROS 複数台での通信時の問題点：rostopic list 見えるが rostopic echo 見えない
](https://qiita.com/aecs4to55/items/30640c32995b64ca3a68)

英語ですが、このエラーにも遭遇しました。
[External ROS node can't communicate with simulink
](https://jp.mathworks.com/matlabcentral/answers/476036-external-ros-node-can-t-communicate-with-simulink)
[Communication error between two nodes on two distributed machines](https://answers.ros.org/question/34064/communication-error-between-two-nodes-on-two-distributed-machines/)
上記記事内の、
>` "ERROR: Communication with node[http:192.168.122.1:40426/] failed!"`

このエラーです。

## 事象の具体例
ラズベリーパイ内で`cmd_vel`トピックにpublishする`raspi_vel`ノードがあったとします。
まず最初に、以下の設定で、リモートPCでroscoreを立ち上げ、ラズベリーパイで`raspi_vel`ノードを立ち上げます。

リモートPC

```shell
export ROS_MASTER_URI=http://192.168.100.100:11311
export ROS_IP=192.168.100.100
```

ラズベリーパイ

```shell
export ROS_MASTER_URI=http://192.168.100.100:11311
export ROS_IP=192.168.100.101
```

その後、リモートPCのターミナルで、以下のコマンドを実行したところ、何も出ませんでした。

```shell
rostopic echo /cmd_vel
```

しかし、以下のコマンドを実行すると、`cmd_vel`は表示されます。

```shell
rostopic list
```

また、以下のコマンドを実行しても。`raspi_vel`ノードは表示されます。

```shell
rosnode list
```

しかし、以下のコマンドを実行すると、[この記事](https://jp.mathworks.com/matlabcentral/answers/476036-external-ros-node-can-t-communicate-with-simulink)にあるようなエラーが出ました。

```shell
rosnode info raspi_vel
```

```shell:実行結果
Node [/raspi_vel]
Publications: 
 * /rosout [rosgraph_msgs/Log]
 * /cmd_vel

Subscriptions: 
 * /topic

Services: 
 * /raspi_vel/get_loggers
 * /raspi_vel/set_logger_level


contacting node http://IPアドレス:43126/ ...
ERROR: Communication with node[http://IPアドレス:43126/] failed!
```

※ちなみに、ラズベリーパイのターミナルで`rostopic echo /cmd_vel`を実行すると表示されました。

# おわりに
ややこしかったので、
`ROS_IP`や`ROS_HOSTNAME`について何かわかったら追記します！
playwright-pythonではwaitForNavigationの代わりにexpect_navigationを使う

## in JS

Playwright(JS)だと、画面遷移を待つには、

* waitForNavigationを、画面遷移が発生するようなイベントの前に仕掛ける
* 画面遷移が発生するようなイベントのあとで、waitForNavigationの結果を待つ

というのが定石。

```js
const navigationPromise = page.waitForNavigation();
await page.click('input[type="submit"]'); // 画面遷移が発生するようなイベント
await navigationPromise;
```

あるいはもっと単純に

```js
await Promise.all([
  page.waitForNavigation(),
  page.click('input[type="submit"]'),
]);
```

こう書く。

## in Python

さて、[playwright-python](https://github.com/microsoft/playwright-python)のSync API(async/awaitを使わない方のAPI)で、こういう処理どうやって書けばいいんだろう？

（バージョン0.170.x 時点での）正解は

```py
with page.expect_navigation():
  page.click('input[type="submit"]') # 画面遷移が発生するようなイベント
```

なんて簡単。


waitForなんとか系のメソッドはだいたい同じで、with文と `expect_****` のメソッドで囲うだけで、いい感じに非同期処理をやってくれる。ステキだ。
([内部実装的には、asyncioのFutureを使ってるっぽい](https://github.com/microsoft/playwright-python/blob/30946ae3099d51f9b7f355f9ae7e8c04d748ce36/playwright/_impl/_event_context_manager.py#L21)）
Java基礎　ファイルの読み書き

## FileWriter、FileReaderを使ってファイルを読み書きする

まずファイル名を指定し、Fileオブジェクトを生成します。
それをもとにキャラクタストリームである「**FileWriter**」「**FileReader**」を使って、char単位で読み書きを行います。

ちなみにキャラクターストリームを使用すると、文字コードが自動的に変換されるので、ファイルが保存されているOSの文字コードを意識することなく入出力を行えます。

以下のコードは、「text.txt」というファイルを生成し書き込みを行ったのち、
そのファイルの中身を読み込んで出力しているというプログラムです。

```Main.java
import java.io.*;

public class Main {
	public static void main(String[] args) {
		try (FileWriter text1 = new FileWriter(new File("text.txt"));
				FileReader text2 = new FileReader(new File("text.txt"))) {
			text1.write("こんにちは。");
			text1.flush();
			int i = 0;
			while ((i = text2.read()) != -1) {
				System.out.print((char) i);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


```
「こんにちは」と書き込んだあとに**flush()メソッド**を使用していますが、これは呼び出した瞬間に強制的にファイルへ書き込みを行うよう命令する処理を意味します。

一つ前に実行している**write()メソッド**はデータの書き込みを要求しますが、このメソッドを呼び出したすぐにファイルに書き込まれるとは限りません。このプログラムでは、最初に書き込んだ文字を読み込んで出力したいため、必ず読み込み前に書き込みが行われているように強制的な書き込みを命じています。


また、while文の中では、FileReaderクラスの**read()メソッド**を使用してファイルに書き込まれている文字を一文字ずつ取得しint型で返しています。read()メソッドは1回実行するたびに1文字読み込みを行い、ファイルの終わりに達すると-1を返すため、その条件を判定文に入れています。

read()メソッドで取得したint型の情報を文字として出力するためには、char型への明示的なキャストが必要なため、キャスト式を書いてchar型に変換しています。


このような処理を行い、ファイルの読み書きを行うことができます。

次回はBufferedReader,BefferedWriterクラスや、シリアライズ等について記載できたらと思います。
VSCodeで利用するTypeScriptのバージョンを変更する

## 前書き
create-react-appでApp.tsxファイルを開くと`'--jsx' フラグが指定されていないと、JSX を使用できません。`というエラーが出たため、VSCodeで利用しているTypeScriptをバージョンする必要があった。
せっかくなのでグローバルなTypeScriptのバージョンもアップグレードし、グローバルと同じバージョンをVSCodeで利用することにした。

## TypeScriptをバージョン指定インストールする

リリースされているTypeScriptのバージョンを[npmのTypeScriptページ](https://www.npmjs.com/package/typescript)から確認し、以下のコマンドを実行する。

```
 $ npm i -g typescript@{利用したいバージョン}
```

例えば4.1.3が利用したい場合は以下のように実行する。

```
 $ npm i -g typescript@4.1.3
```

## VSCodeで利用するTypeScriptのバージョンを設定する

1. VSCodeを開いて左下の歯車マークをクリック
1. [設定]をクリック
1. 検索欄に「typescript tsdk」と入力
1. 「Typescript: Tsdk」という項目の「setting.jsonで編集」をクリック
1. setting.jsonが開くので「"typescript.tsdk":」の項目を以下のように編集

```
"typescript.tsdk": "{グローバルなnpmのpath}/typescript/lib"
```

例えばグローバルなnpmのpathが`/usr/local/lib/node_modules`の場合、以下のように記述する。

```
"typescript.tsdk": "/usr/local/lib/node_modules/typescript/lib"
```


### グローバルなnpmのpathを確認する

以下のコマンドを実行する。

```
npm root -g 
```
例えばmacの場合は以下のように出力される。

```
/usr/local/lib/node_modules
```

## VSCodeで利用するTypeScriptのバージョンを変更する

1. VSCodeで適当なTypeScriptファイルを開く
1. 右下に表示されるTypeScriptのバージョンをクリック
1. 「TypeScriptのバージョンを選択...」をクリック
1. 「VS Codeのバージョンを使用」に表示されているバージョンが利用したいバージョンであることを確認してクリック
1. 右下に表示されるTypeScriptのバージョンが変更さたことを確認して完了


## 参考
・[Reactアプリ作成時にエラー"'--jsx' フラグが指定されていないと、JSX を使用できません。"が発生する場合の対処](https://qiita.com/mth1209/items/54c8f335022cec6dc5c8)
JavaScript【基本文法】～Part３～

#初めに
今回はJavaScriptの中で、自分が大事だと思った**配列メソッド**について書いていきたいと思います。
#目次
###・map()
###・filter()
###・findIndex()

##map()
`map`メソッドを使う事で新しい配列を作る事が出来る。

入力

```javascript
const obj = {
    "size": {text: "big"},
    "shape": {text: "square"},
    "num": {text: "many"}
};

const Array = Object.keys(obj).map(key =>{
    let value = obj[key]
    value['id'] = key
    return value
});
console.log(Array);
```
結果

```javascript

[
  { text: 'big', id: 'size' },
  { text: 'square', id: 'shape' },
  { text: 'many', id: 'num' }
]
```

##filter()
`filter`メソッドを使う事で条件に合う要素を抽出する事が出来る。


入力

```javascript
const obj = [
    {id: "size", text: "big"},
    {id: "shape", text: "square"},
    {id: "num", text: "many"}
];
const Result = obj.filter(object =>{
    return object.id === "shape"
});
console.log(Result);
```
結果

```javascript

[ { id: 'shape', text: 'square' } ]
```
##findIndex()
`findIndex`メソッドを使う事で要素の何番目かを知る事が出来る。


入力

```javascript
const obj = [
    {id: "size", text: "big"},
    {id: "shape", text: "square"},
    {id: "num", text: "many"}
];
const Index = obj.findIndex(object =>{
    return object.id === "shape"
});
console.log(Index);
```
結果

```javascript
1
```
##参考記事
https://www.youtube.com/watch?v=VBuBGqPGALg
【備忘録】Dart/Flutterの静的解析のエラー avoid_single_cascade_in_expression_statementsについて

# avoid_single_cascade_in_expression_statements
- [ドキュメント](https://dart-lang.github.io/linter/lints/avoid_single_cascade_in_expression_statements.html)

## 意味
- 式文では単一のカスケード用法の使用を避ける
- expression: 式
- statement: 文
- expression_statements: 式文

## 概要

```dart
// こういった用法を避ける、だってカスケードの使い方として間違っている
cake..bake();

// こうする
cake..bake();
```

### 式文について
- [こちらが参考になりました](https://www.notion.so/satomi/Write-Blog-1a93d0c003b847f3ad48748e6b23fdff#fcd0923a52174d4187f42e4a95251884)

### 本来カスケード用法はこう使う

```dart
// 本来カスケードはこう使う
cake
  ..bake()
  ..putStrawberryOnTheTop()
  ..eat();
```
【備忘録】Dart/Flutterプロジェクトでの静的解析によるLintルールについて

## 概要
Dart/Flutterのプロジェクトでコードの静的解析を行うには、 `analysis_options.yaml` を設定します。

コードの静的解析については[こちら](https://dart.dev/guides/language/analysis-options)が参考になります。

また、Dart/FlutterでのLintルールは、[こちらに一覧が記載されています。](https://dart-lang.github.io/linter/lints/index.html)

VSCodeやAndroid Studioで、静的解析によるエラーに遭遇しても、じゃあどうしたらいいのか、すぐにわからないことが度々あるので、こちらにそれを記載していきます。

ただ、本来は各IDEで適切なpackageを設定するか、[こちらのLintルール一覧](https://dart-lang.github.io/linter/lints/index.html)で検索するのが適切な解決策かなとは思います。

## ルール

### avoid_function_literals_in_foreach_calls
*AVOID using forEach with a function literal.*
*関数リテラルでforEachを使うことは避ける*

[ドキュメント](https://dart-lang.github.io/linter/lints/avoid_function_literals_in_foreach_calls.html)

シーケンスの反復処理においては、for文をもちいる。

```dart
// この使い方は避けること
dogs.forEach((dog) {
  .....
});

// for文にする
for (var dog in dogs) {
  .....
}

// この様な書き方はOK
dogs.forEach(print);
```


### avoid_init_to_null
[ドキュメント](https://dart-lang.github.io/linter/lints/avoid_init_to_null.html)
*nullを使って初期化しない*
*Dartでは、明示的に初期化されていない変数やフィールドは、自動的にnullに初期化されます。
このため、nullを使って初期化することは冗長であり、不要です。
また、Dartには、初期化されていないメモリという概念はありません。*

```dart
// nullで初期化してはいけない
int somethingNumber = null;

// こうする
int somethingNumber;
```

https://qiita.com/colorrabbit/items/287b9a866ef782a15ebe


### avoid_single_cascade_in_expression_statements
- [ドキュメント](https://dart-lang.github.io/linter/lints/avoid_single_cascade_in_expression_statements.html)
- 式文では単一のカスケードを避ける

```dart
// こういった用法を避ける、だってカスケードの使い方として間違っている
cake..bake();

// こうする
cake..bake();

// 本来カスケードはこう使う
cake
  ..bake()
  ..putStrawberryOnTheTop()
  ..eat();
```

https://qiita.com/colorrabbit/items/c03a5eb9ecb2b23469a4

### implicit_dynamic_variable
*変数の型を明示的にする*

```dart
// 変数（_createdAt）の型が明示的になっていない
final _createdAt = data['createdAt'];

// こんな感じにする
final _createdAt = data['createdAt'] as DateTime;
```

↑のようにするか、解析オプションファイルから implicit-dynamic を削除する

https://qiita.com/colorrabbit/items/7efd86faacfcd35a6e74


### unnecessary_lambdas
- [ドキュメント](https://dart-lang.github.io/linter/lints/unnecessary_lambdas.html)
- `DON'T create a lambda when a tear-off will do.`
    - `tear-offが可能な場合は、ラムダを作成しないでください。`
    - つまり、`メソッドに渡された引数と同じ引数でメソッドを呼び出す関数がある場合、呼び出しをラムダでラップしないようにしましょう`、ということ
    - tear-offとは、メソッドと同じパラメータを取り、それを呼び出すクロージャのこと


```dart
// ダメ、よくあるやり方
listItems.forEach((eachList) {
  print(eachList);
});

// こうする、便利
listItems.forEach(print);
```

### curly_braces_in_flow_control_structures
- [ドキュメント](https://dart-lang.github.io/linter/lints/curly_braces_in_flow_control_structures.html)
- `DO use curly braces for all flow control structures.`
    - `すべてのフロー制御構造に中括弧を使用してください`

```dart
// if文の際、 {} を省略せずにちゃんと書く
if (todayIsApril) {
  print('Spring has come!');
} else {
  print('Please wait for Spring.');
}

// こうしちゃダメ、JSなどに慣れているとやりがちかもしれません
if (todayIsSummer)
  return print('Too hot!');

// 例外: これはOK、else文がないif文で、bodyが1行の短文の場合
if (isAutumn) return '🌰';
```

## その他
- 今後随時追記していきます

## 参考
- [Effective Dart: Usage](https://dart.dev/guides/language/effective-dart/usage)
- https://medium.com/flutter-jp/analysis-b8dbb19d3978
Amazon SQSとは

## 勉強前イメージ

似たようなS*Sサービス。。。
正直良くわからない・・・

## 調査

### Amazon SQSとは

Simple Queue Serviceの略で、フルマネージドのキューイングサービス。
キューイングとは異なるソフトウェア間でデータの送受信する手法の一つで、
ソフトウェア間を直接データを渡すのではなく、第三者経由でデータを渡すことで、送信側と受信側が好きなときに処理を行うことができます。
そのキューイングができるサービスがSQSになります。

### 前提知識

登場する言葉が3つ、以下があります。

- プロデューサー : メッセージをSQSに送信するアプリケーションのこと
- コンシューマー : SQSからメッセージをポーリング(取りに行く)アプリケーションのこと
- メッセージ : 送受信されるデータのこと

上記を図解したものが以下になります。

![2021-01-14 1 Untitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/4141d738-ee1f-4442-31dd-1e7c9e76cf72.png)

### キュータイプ

SQSにはアプリケーションの要件に合わせて2つのキュータイプがあります。

- 標準キュー
- FIFO キュー

2021-01-14 3 Untitled Diagram.drawio - diagrams.net - Google Ch

#### 標準キュー

- スループットは無制限
- 配信順序はベストエフォートで保証されない(順番が前後する可能性がある)
- メッセージは最低1回配信する(複数回配信される可能性がある)
	- 複数回同じメッセージが受け取っても悪影響出ないような構成にする必要がある
- FIFOキューに比べて安価

#### FIFO キュー

FIFOとはFirst In, First Outの略で、先入れ先出しの意味

- スループットは1秒あたり300件のメッセージ処理
- 配信順序は保証される(順番が前後しない)
- メッセージは必ず1回のみ配信(複数回配信されない)

このキューは、配信順序や処理回数が重要な場合に使用されます。

### SQSで出来る主な設定

- 可視性タイムアウト : コンシューマーがメッセージを受信してから可視性タイムアウトの間、他のコンシューマーなどにキューを配信しない
- 配信遅延 : コンシューマがメッセージを処理するより先にキューができたときにどのくらいの時間、キューの送信を遅延させるか
- メッセージ受信待機時間 : メッセージ取得を指定時間だけ待機する
- メッセージ保持期間 : キューに登録されたメッセージは明示的に削除処理を行われない限りデフォルトで4日間保持
- 最大メッセージサイズ : キューのメッセージサイズの指定

![2021-01-14 2 Amazon SQS - Google Chrome 2021-01-14 23.05.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/dff2cc20-34de-a9a1-c87e-087c5e87a0cb.png)


### Amazon SNSとの違い

- Amazon SQS

コンシューマはSQSをポーリングして、キューがあれば取得します

![2021-01-14 4 SQSUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/d3870869-39ed-7cf7-486c-ae30d2952f95.png)

- Amazon SNS

SNSはコンシューマーを確認せず、とりあえずメッセージを送るプッシュ式です。

![2021-01-14 4 SNSUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/5de360eb-c5e1-eb8e-2823-d938a9ff055a.png)


## 勉強後イメージ

キューのサービスもあるのか・・・
確かにアプリケーションが組み合わさってたらキュー送りたいけど！！！ってなるか

## 参考

- [AWSのSQSとは？SQSの用語や特徴について詳しく紹介していきます！](https://www.fenet.jp/aws/column/aws-beginner/299/#%E3%80%8C%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%80%8D%E3%81%A8%E3%81%AF%EF%BC%9F)
- [AWS SQSを使ってお手軽にメッセージキューイング（MQ）をしよう！](https://style.potepan.com/articles/11671.html)
- [AWS再入門ブログリレー SQS編](https://dev.classmethod.jp/articles/relay_looking_back_sqs/)
- [【AWS】Amazon Simple Queue Service(SQS)について解説します。](https://www.acrovision.jp/service/aws/?p=2910)
- [【AWS】楽々SQS解説〜5分で理解〜](https://qiita.com/UpAllNight/items/7c5022661a1eadc8a88a)
GreengrassのLocal connection detectionの設定をCloudformationから設定する

凄いニッチですが、詰まったので残しておきます。

Greengrass(`V2`でなく`V1`)で、 `Core connectivity information` という設定項目があります。

項目としては以下から選択する形になります。

- Automatically detect and override connection information
- Manually manage connection information


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/9bc43891-d9a9-3af9-408a-ea44d0c7c37f.png)

これをどうやってCloudformationやAPIで設定するかを探していたのですが、どこを探しても項目が見つかりません。そんな時に以下のURLを見つけました。

https://forums.aws.amazon.com/thread.jspa?threadID=264237


引用すると以下のコマンドでできます。 `arn:aws:lambda:::function:GGIPDetector:1` というLambdaを登録するという意味です。

```sh
aws greengrass create-function-definition-version --function-definition-id <function-definition-id> --functions '[
    {
        "FunctionArn": "arn:aws:lambda:::function:GGIPDetector:1",
        "Id": "<your-id>",
        "FunctionConfiguration": {
            "Pinned": true,
            "Timeout": 3,
            "MemorySize": 32768
        }
    }
]'
```

ホントにと思ったのですが、確かに以下のように定義してデプロイすると `Automatically detect and override connection information` が有効になっていることが確認できました。

Greengrass GroupのLambdaの項目を見ても該当の `GGIPDetector` というLambdaは見えないので、内部的に利用されるようです。まさか設定にLambdaを登録する形とは思っていませんでした。


```yaml
#省略
 FunctionDefinitionVersion:
    Type: "AWS::Greengrass::FunctionDefinitionVersion"
    Properties:
      FunctionDefinitionId: !GetAtt
        - FunctionDefinition
        - Id
      DefaultConfig:
        Execution:
          IsolationMode: GreengrassContainer
      Functions:
        - Id: GGIPDetector
          FunctionArn: "arn:aws:lambda:::function:GGIPDetector:1"
          FunctionConfiguration:
            Pinned: "true"
            MemorySize: "32768"
            Timeout: "3"
#省略
```
SQLServerのDB復元バッチ作った

# がいよう
業務でたくさんやるから、バッチ化したんだけど俺しか使わないから、ここに書くわ。。。
僕のこと見てくんないっ！ひどい！😠

# やっていること
基本的にコマンドを叩いているだけだからそんなエッセンスはないんだけど、一応、ポイントがある

* リストア前にオフラインしている
* デタッチはコマンドでやるとうまくいかない😤データベースが使用中なんだってさ

###### これだけは注意！！
対象のデータベース用の.bakを置いていないと危険だよっ
空のデータベースをぶっこんで空っぽのデータベースになるから！
一応これを流す前にバックアップをしよう！！自己責任だぞ🤧
バックアップバッチも作ってんだけど、めんどくさいから他の人のサイトを見てねーー
* [SQL Serverのバックアップコマンドでデータベースバックアップ
](https://itlogs.net/sql-server-backup-command/)

# Windowsバッチとかで書いとけばできるお
``` powershell
@set /P SERVER_NAME="input the database server name>>>>"
@set /P LOGIN_USER="input a login user>>>>"
@set /P PASSWERD="input a passwerd>>>>"
@set /P RESTORE_BAK="input the path .bak file for restore"
@set LOG_PATH=.\restore.log

@echo ---------------------
@echo 接続先：%SERVER_PATH%
@echo ログイン：%LOGIN_USER%
@echo パスワード：%PASSWERD%
@echo bakファイル元：%RESTORE_BAK%
@echo ---------------------
pause

@echo make a database offline...
sqlcmd -S %SERVER_PATH% -U %LOGIN_USER% -P %PASSWERD% -Q "alter database %SERVER_NAME% set offline with rollback immediate" >> %LOG_PATH%

@echo restore a database...
sqlcmd -S %SERVER_PATH% -U %LOGIN_USER% -P %PASSWERD% -Q "restore database %SERVER_NAME% from disk='%RESTORE_BAK%'" >> %LOG_PATH%

pause

```
# 排他アクセス制限
* 排他アクセスでデータベースを復元できねえことがある
* そういう場合は、オフラインかデタッチをする→復元
* デタッチコマンドが上手くいかないからオフラインしているわけ

# 参考
* [SQL Serverのバックアップコマンドでデータベースバックアップ
](https://itlogs.net/sql-server-backup-command/)
* [【SQL Server 2012】バッチ(コマンドプロンプト)でリストア](http://itdiary.info/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/post-114/)
* [RESTORE ステートメント (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/restore-statements-transact-sql?view=sql-server-ver15)
「コードに思いを込める」ということ

##リーダブルコードを読んだ
　[書籍:リーダブルコード](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)
　プログラムが何であるかも不明だった頃、先輩方に強くお勧めされ中の一つであった「リーダブルコード」。有名な本。
「読みなさい…そしてアウトプットするのです‼」と言われていた。
　
　当時は書くこと読むことに必死すぎて、読まずに放置し、3年半の月日が経過してしてしまった。…積読です。
　当時よりは人のコードを読んだり、自分の書いたコードを書いたりする経験を積んだ今、改めてプログラムを書く上で大切にしなければならない事を学ぶために本を開いた。
　そして、最も心に残った「第12章コードに思いを込める」という部分について感想を書きたいと思う。

##感想
　各章の内容の全てが、「コードに思いを込める」章に繋がってるのではないだろうか。
　「分かりやすい」「美しい」「誤解されない」「相手の立場になって書く」
そんなコードを書いていきましょう!!と序章から何回も言っているからだ。
　
> 誰かに複雑な考えを伝えるときは、細かいことまで話しすぎると
> 相手を混乱させてしまう。
> 自分よりも知識が少ない人が理解できるような
>「簡単な言葉」で説明する能力が必要だ。
> 自分の考えを凝縮して、最も大切な概念にすることが必要となる。
> これは誰かに理解してもらうだけでなく、
> 自分の考えをより明確にすることにもなる。

　もう、これでグッときた。
プログラミングに限らずあらゆる状況で必要になる考え方。

「自分の概念」を「簡単な言葉」で伝える為には、
自分で書いたコードを深く理解していなければならない。

　自分の書いたコードは自分のものだけれど、一生そのコードを見てあげられる訳ではなく、将来の誰かが触るかも知れない。
　そんな時に、何やら複雑で難解な書き方をしてはいけないから、まず人に説明できる内容かどうかを確認する必要がある。

　この本を勧めてくれた先輩方は、コードレビューをよくしてくれる方々でした。
　コードレビューって少し怖いけど（私は）、
　「ここどんな意味なの？」「なんでこうなってるの？」
　「これ、書いてるけど意味わかってんの？」←笑
　など色々言われて、突っ込まれた所がことごとく説明できなかったりした。

　逆に、完全に理解した時は、誰かに説明したくなる。
　
　説明したくなるコードを書きたくなった。
　
　数か月後の自分の為に。
　まだ見ぬ将来の誰かの為に。
MavenにJava 8を使用するように指定

毎回検索するので、メモ。
参考サイト：
https://www.codeflow.site/ja/article/maven__how-to-tell-maven-to-use-java-8

★★★★★
Eclipse を使用する場合、プロジェクトを右クリック→Maven→プロジェクトの更新
を行わないと反映しないので、注意！
★★★★★

```xml:pom.xml
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
		<maven.compiler.target>${java.version}</maven.compiler.target>
		<maven.compiler.source>${java.version}</maven.compiler.source>
	</properties>
```

```xml:pom.xml
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
　　　　　　　　　　　<source>${java.version}</source>
　　　　　　　　　　　<target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
```
Cannot open include file: 'fbxsdk.h': No such file or directoryが出てしまったら

割とハマってしまい、色々調べた為、自分へのメモも兼ねて、Qita記事を残しておきたいと思います。

# 発生環境
UnrealEngine 4.26

# エラーが発生
UnrealEngineのプラグインを書いていた時の事です。
以下のビルドエラーが発生しました。
ヘッダーファイルの名前から分かる通り、DirectX系のファイルのリンクエラーとなります。
その上、発生しているファイルは、作成しているプラグイン内ではなく、エンジンコードでした。

```
Cannot open include file: 'fbxsdk.h': No such file or directory
```

# 調査開始
調査したところ、Epic Games Launcherからインストールしているエンジンには、DirectX系のライブラリは、パッケージジングされており、新しく追加したC++のソースコードをビルドする際には含まれない事が分かりました。

# 対応方法
### 1.Githubのエンジンをビルドする
Githubで公開されているエンジンは、ビルドが必要である為、パッケージングされていません。
その為、追加したC++をビルドする際にインポートされます。

### 2.FBXモジュールを追加する
4.19のバージョンから、DirectX系のライブラリ用のモジュールが用意されました。
PrivateDependencyModuleNamesに、FBXモジュールを追加する事で、DirectX系のライブラリがインポートできます。

```
PrivateDependencyModuleNames.Add("FBX");
```

ローレベルな事をやっているコードを使用する時に発生するかもしれません。
私の場合は、FbxImporterで発生しました。

# 参考URL
https://answers.unrealengine.com/questions/393802/how-to-fix-the-fbxsdkh-missing-to-compile-project.html
Swift 特定日の0時を取得

```
// 今日の日付を取得
let today = Calendar.current.date(byAdding: .day, value: 0, to: Calendar.current.startOfDay(for: Date()))
```

byAddng: 日にちや時間などを指定する
value: valueに指定された分ずれる
startOfDay(): 基準となるDate型を指定する
つまり、
startOfDay(for: Date()))のDate()を基準にvalueで指定された分ずれた日を取得する。

Dateやvalueを調整して特定日の0時を取得する。
例えば7日後を取得する場合はvalueに7を指定する。

```
// 7日後の日付を取得する
let 今日から7日後 = Calendar.current.date(byAdding: .day, value: 7, to: Calendar.current.startOfDay(for: Date()))
```
sphinxを使ってみる

Sphinxを使って簡単なドキュメントを作成してみました。
SphinxはreSTというマークアップ言語を利用して、HTML、PDFなどのドキュメントをジェネレートできるプログラムです。

論文を書くときに利用する、Texぽい感じでした。

今回利用した環境は以下です。
* macOS Big Sur 11.2
* sphinx 3.4.3
* pip3 19.2.3

# sphinxのインストール

```
# pip3 install sphinx
```

# sphinxプロジェクトの作成

```
% sphinx-quickstart
Sphinx 3.4.3 クイックスタートユーティリティへようこそ。

以下の設定値を入力してください（Enter キーのみ押した場合、
かっこで囲まれた値をデフォルト値として受け入れます）。

選択されたルートパス: .

Sphinx 出力用のビルドディレクトリを配置する方法は2つあります。
ルートパス内にある "_build" ディレクトリを使うか、
ルートパス内に "source" と "build" ディレクトリを分ける方法です。
> ソースディレクトリとビルドディレクトリを分ける（y / n） [n]: y

プロジェクト名は、ビルドされたドキュメントのいくつかの場所にあります。
> プロジェクト名: TEST
> 著者名（複数可）: Araya
> プロジェクトのリリース []: 0.0.1

ドキュメントを英語以外の言語で書く場合は、
 言語コードで言語を選択できます。Sphinx は生成したテキストをその言語に翻訳します。

サポートされているコードのリストについては、
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language を参照してください。
> プロジェクトの言語 [en]: ja

ファイル /Users/araya/Desktop/work/source/conf.py を作成しています。
ファイル /Users/araya/Desktop/work/source/index.rst を作成しています。
ファイル /Users/araya/Desktop/work/Makefile を作成しています。
ファイル /Users/araya/Desktop/work/make.bat を作成しています。

終了：初期ディレクトリ構造が作成されました。

マスターファイル /Users/araya/Desktop/work/source/index.rst を作成して
他のドキュメントソースファイルを作成します。次のように Makefile を使ってドキュメントを作成します。
 make builder
"builder" はサポートされているビルダーの 1 つです。 例: html, latex, または linkcheck
```

## 以下のようなファイル構成でプロジェクト学生されました。

```
% tree
.
├── Makefile
├── build
├── make.bat
└── source
    ├── _static
    ├── _templates
    ├── conf.py
    └── index.rst
```

# HTMLドキュメントのジェネレート

```
% make html
% open ./build/html/index.html
```

**ブラウザで開くと以下のようになります。**

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74622/950e4348-ecc4-b42b-a316-d7ce1459ebbe.png)|
|:--|

# PDFドキュメントのジェネレート

```
$ make latexpdf
$ open build/latex/test.pdf
```

**プレビューで開くと以下のようになります。**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74622/0c4e3867-cb86-0dd9-a147-01cb397e6427.png" width="400">


# 作成できるドキュメントの種類
こちらにまとまっていました。
https://www.sphinx-doc.org/ja/master/man/sphinx-build.html
プレインテキストやXMLなどいろいろありますね。
そうだ、SQLを勉強しよう④

#はじめに
比較・論理演算子以外の演算子についてまとめました。

###BETWEEN演算子

値1以上、かつ値2以下の行のみを検索します。

```sql
式 BETWEEN 値1 AND 値2
```

##IN演算子
値に一致する行のみ、検索してくれます。

```sql
式 IN (値1, 値2)
```
値に一致しない行のみ検索してくれます。

```sql
式 NOT IN (値1, 値2)
```

###ANY演算子・ALL演算子

```sql
式 IN (値1, 値2)
式 基本比較演算子 ANY (値1, 値2)
式 基本比較演算子 ALL (値1, 値2)
```

具体例

```sql
3000 IN (3000, 1000)
2500 < ANY (3000, 1000)
500 < ALL (3000, 1000)
```

上の例で言うと…

|||
|---|---|
|IN|右辺の<font color=red>どれか</font>と<font color=blue>一致</font>なら真|
|ANY|右辺の<font color=red>どれか</font>より小さければ真|
|ALL|右辺の<font color=red>全て</font>より小さければ真|
xcode swift 個人的によく使うショートカットメモ

随時更新予定

<h1>表示/非表示系</h1>
<dl>
    <dt>
        command + 0
    </dt>
    <dd>
        左のファイル一覧を表示/非表示
    </dd>
    <dt>
        option + command + 0
    </dt>
    <dd>
        右のプロパティいじるやつを表示/非表示
    </dd>
    <dt>
        command + shift + y
    </dt>
    <dd>
        下のデバッグを表示/非表示
    </dd>
    <dt>
        option + command + control + Return
    </dt>
    <dd>
        対応するソースコードを表示/非表示
    </dd>
    <dt>
        command + shift + l(エル)
    </dt>
    <dd>
        objectライブラリを開く(超使う)
    </dd>
</dl>


<h1>ソースコード系</h1>
<dl>
    <dt>
        command + i
    </dt>
    <dd>
        インデントを整える
    </dd>
</dl>

<h1>実行系</h1>
<dl>
    <dt>
        command + b
    </dt>
    <dd>
        ビルドする
    </dd>
    <dt>
        command + r
    </dt>
    <dd>
        ビルドして実行する
    </dd>
    <dt>
        command + shift + k
    </dt>
    <dd>
        クリーンビルドする
    </dd>
    <dt>
        command + .(ドット)
    </dt>
    <dd>
        停止する
    </dd>
    <dt>
        F6
    </dt>
    <dd>
        ステップオーバー
    </dd>
    <dt>
        F7
    </dt>
    <dd>
        ステップイン
    </dd>
</dl>
Spring Boot の application.properties に環境変数をセットする例

## 概要

- Spring Boot の application.properties に環境変数をセットする例を示す

## 動作確認環境

- macOS Catalina + Java 11 (AdoptOpenJDK 11.0.10+9) + Spring Boot 2.4.2 + bash or zsh

## 環境変数をセット可能な application.properties の例

左側にプロパティのキー、右側にプロパティの値を記述する。
環境変数をセットしたいプロパティの場合は、右側に \${環境変数名} または \${環境変数名:デフォルト値} のフォーマットで記述する。

```application.properties
sample.first=XXXXXXXX
sample.second=${UPPER_UNDERLINE_CASE:XXXXXXXX}
sample.third=${lower.dot.case:XXXXXXXX}
```

## 環境変数をセットして Spring Boot を起動するコマンド例

環境変数 UPPER_UNDERLINE_CASE に "Hello, World" をセットして Spring Boot を起動する例。

```
$ UPPER_UNDERLINE_CASE="Hello, World" java -jar sample.jar
```

環境変数 lower.dot.case に "Hello, World" をセットして Spring Boot を起動する例。

```
$ env lower.dot.case="Hello, World" java -jar sample.jar
```

環境変数 UPPER_UNDERLINE_CASE に "Hello, World" をセットして Spring Boot を起動する例。

```
$ export UPPER_UNDERLINE_CASE="Hello, World"
$ java -jar sample.jar
```

環境変数 SAMPLE_FIRST に "Hello, World" をセットして Spring Boot を起動する例。
Spring Boot の Relaxed Binding 機能 (緩いバインディング) により SAMPLE_FIRST という環境変数で sample.first プロパティの値をセットできる。

```
$ SAMPLE_FIRST="Hello, World" java -jar sample.jar
```

環境変数ではないが、プロパティ sample.first に "Hello, World" をセットして Spring Boot を起動する例。
プロパティ名の前にハイフン2つを付ける。

```
$ java -jar sample.jar --sample.first="Hello, World"
```

## 参考資料

- [application\.propertiesの設定を環境変数を用いてlocal起動とDocker起動で切り替える \- Qiita](https://qiita.com/SSM3G/items/40bac2fc47c6b80884e8)
- [SpringBootのapplication\.properties内で環境変数を使う \- Qiita](https://qiita.com/teruq/items/caff10149b145234c909)
- [【 env 】コマンド――環境変数を指定してコマンドを実行する：Linux基本コマンドTips（175） \- ＠IT](https://www.atmarkit.co.jp/ait/articles/1801/18/news016.html)
- [【 export 】コマンド――環境変数やシェル変数を設定する：Linux基本コマンドTips（174） \- ＠IT](https://www.atmarkit.co.jp/ait/articles/1801/12/news015.html)
- [2.7.6. 緩いバインディング \- Spring Boot の機能 \- リファレンスドキュメント](https://spring.pleiades.io/spring-boot/docs/2.4.2/reference/html/spring-boot-features.html#boot-features-external-config-relaxed-binding)
- [2.1. コマンドラインプロパティへのアクセス \- Spring Boot の機能 \- リファレンスドキュメント](https://spring.pleiades.io/spring-boot/docs/2.4.2/reference/html/spring-boot-features.html#boot-features-external-config-command-line-args)
非同期処理(GCD)を実現する[Swift]

#非同期処理とは
実行中に別の処理を止めない処理のことを非同期処理と言います。
#GCD(Grand Central Dispatch)
GCDはC言語ベースで書かれている低レベルAPI群で、CPUのコア数や負荷などに応じて自動的に処理を最適化してくれます。僕たちが行うことはタスクを`キュー`というデータ構造に追加することだけです。予め用意されたコア内のスレッドの中から空いているスレッドにタスクを振り分けてくれるらしいです。
##GCDのキュー
GCDのキューはディスパッチキューと言います。
タスクの実行方式より2つに分類できます。
__1.直列ディスパッチキュー__
実行中の処理を待ってから次の処理を実行します。
__2.並列ディスパッチキュー__
実行中の処理を待たずに次の処理を実行します。
##キューの所得方法
既存のディスパッチキューを使う方法と新規のディスパッチキューを生成する2種類の実装方法があります。
まず、既存のディスパッチキューを使う方法から説明します。
###既存のディスパッチキューを使う
GCDはディスパッチキューとして1つメインキュートと複数のグローバルキューをすでに準備してくれています。
_ありがてぇ〜_
しかし、ディスパッチキューの種類はすでに決められています。
メインキューはメインスレッドでタスクを実行する`直列ディスパッチキュー`で、グローバルキューは`並列ディスパッチキュー`です。globalメソッドの引数qosは、 DispatchQoS.QoSClass型の列挙型です。qosはQuality of Serviceの略なので、優先度を指定しています。(調べてみてください)

```swift
import Dispatch
//mainキューを所得
let queue=DispatchQueue.main
//グローバルキューを所得
let queue=DispatchQueue.global(qos: .default)
```


###新規のディスパッチキューを使う
DispatchQueue型をインスタンス化する時に、引数を指定することで新たにディスパッチキューを生成することができます。labelはディスパッチキューの名前をqosは優先度を列挙型で指定します。attributesは直列ディスバッチキューか並列ディスバッチキューかを指定します。__引数を省略すると直列になり、.concurrentにすると並列になります。__

```swift
import Dispatch

let queue=DispatchQueue(
                 label: "NewQueue",
                 qos: .default,
                 attributes: [.concurrent])
```
##キューにタスクを追加する
キューにタスクを追加していくには,DispatchQueue型のasync(execute:)メソッドを利用します。
コアライブラリのFoundationにThreadクラスがあり,isMainThreadプロパティの値を見ることで、処理がメインスレッドかどうかを確認することができます。needsIndefiniteExecutionをtrueにすることで、メインの実行が開始されてもグローバルスレッドでプロフラムを中断せずに継続にすることができます。今回はなくても実行できますが、通信などをするときはtrueにする必要があると思います。(多分。。。。。。。)

```swift
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution=true
let queue=DispatchQueue.global(qos: .default)
queue.async{
    if Thread.isMainThread{
       print("ここはグローバルスレッドです")
 }else{
       print("ここはグローバルスレッドではないです。")
    let queue=DispatchQueue.main
    queue.async {
        if Thread.isMainThread{
            print("ここはメインスレッドです。")
        }
    }
  }
}
```
#感想
むずい
卒論の代わりにflutter✖️firebaseでスマホアプリを作ってみたので振り返る。

今回は自分がスマホアプリを作った話を記事にしたいと思います。

# 作ろうと思った背景

自分は文系大学生なのですが、ゼミに入っておらずその関係で卒論を書かなくても卒業ができます。~~**（イージー大学生）**~~
2021年3月に卒業予定で、夏あたりから周りの友達が「卒論やばい〜😂」、「卒論どうしよう〜😅」と騒ぎ始めました。「俺は楽だぜっ！！」って思いつつも、自分の大学4年間の成果ってなんだろうってモヤモヤしてました。

学問自体は好きで面白かったのですが、通学に1時間半かかるのと授業がつまらなかったので行く気が起きず、効率よく単位をとることだけを考えて授業を受けていました。その代わりに1年生の終わりから興味のあったことを色々勉強して、効率（お金と時間）という観点からゼミには入らなかった次第です。(入ったんですけど、お金がかなりかかるゼミでやめました。そんな余裕のある家庭でもないので。)

色々勉強した中で一番ハマったのがプログラミングで途中だるくなったりもしましたが、独学期間２年、インターンも半年経験させて頂きました。また就活では、そんな経験も評価されて第一志望のIT企業に就職することもできました。

上記のような背景もあり、卒論の代わりに自分の大学生最後の成果物を作ろうと思った次第です。

# 使用技術とその理由

- flutter
- firebase

自分はWebのバックエンドが好きでwebアプリを大学２年生の時とかから作っていました。インターンの時もPHPでWebのバックエンド担当でした。

しかしながら、**「せっかくわざわざ思い立ってやるのに今までと同じことするのも違うんじゃないかな」、「どうせならこの際に知識を増やそう」**となんとなく思いまして、スマホアプリをやることにしました。

加えて、新しいものが好きなのでネイティブコードではなくflutter＆firebaseに触れてみようと思ったしだいです。両OSで作れるのも魅力ですね。

# アプリ概要

作ったアプリを一言でまとめると筋トレ記録アプリになります。

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504011/5323e3ce-a6ae-a8df-f22c-005c153560fa.png)

![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504011/937f3245-7b61-f3ab-e95f-2b8ad3a015a8.png)


自分は筋トレが趣味で、この１年間は週4でジムにいくことを継続していました。重量の記録を伸ばす上で「過去と現状の自分を正しく理解することが重要だな」とトレーニングしていて感じたので、それを達成できるようなアプリにしました。

上記のスクリーンショットに加えてタイマー機能、ストップウォッチ機能を備えています。

[コードはこちら](https://github.com/kk3939/trainning_memo_ver2)

# flutter✖️firebaseで作ってよかったところ

#### 両OSで起動するアプリを作れる点

当然ですが、クロスプラットフォームなので両方のOSで起動します。これはリソースが少ない時にはメリットになるでしょう。ちなみに開発はぼく1人で、二ヶ月で行いました。ただ、公開する時の作業が二倍なのはそれはそれでめんどくさいです。

#### 学習コストが少ない

これは人によって分かれるところかと思いますが、dartの言語仕様やflutterの仕組み自体はすごくわかりやすいと個人的に思いました。少しでもプログラミングをやったことがある人は挫折せずにできるかと思います。

# flutter✖️firebaseで作って難しかったところ

#### 英語と格闘しなければいけない

英語が苦手な人は難しいかもしれません。色々実装する上で、ドキュメントは言わずもがな海外のtech系のyoutubeまで見ました。まだまだ日本語の情報は他の言語と比較すると少ないです。

#### 内部でどう動いているのか理解するのに時間がかかる

自分が書いたコードではなく、flutter内部のレンダリングにおけるエラーが起きることがありました。その際は自分は二日間溶かしてエラーを解消しましたが、そういった部分の文献がまだ少ないのも事実です。


# 使ったライブラリ

状態管理にはproviderを使いました。

```
firebase_core
provider
firebase_analytics
firebase_auth
cloud_firestore
cupertino_icons
google_sign_in
intl
flutter_signin_button
gradient_app_bar
numberpicker
flutter_launcher_icons
flutter_native_splash
```

# 最後に

大学生活、webでもスマホでもアプリを作る経験をしたのでとても有意義なものになりましたが、裏を返せば専門性がないとも言えます。
なので今後は自分のフィールドを作ってもいいのかなと思いました。

**社会人がんばるぞい！！（笑）**
配列とオブジェクトの扱いについての考察

#配列とオブジェクトの出力についてまとめてみた
題材

```javascript

①　data[["a" , "b"]]
②　data["a" , "b"]
③　data{"a","b"}
```
上記の取り扱いについて


###①data[["a" , "b"]]//配列の中に配列が入っている。

```javascript

data[["a" , "b"]]
//呼び出す時は
console.log(data) //[["a" , "b"]]
console.log(data[0]) // ["a","b"]
console.log(data[1]) // undefined
```
###②data["a" , "b"] //基本の配列

```javascript

data["a" , "b"]
//呼び出す時は
console.log(data) //["a" , "b"]
console.log(data[0]) //a
console.log(data[1]) //b
```
上記①、②は変数名（data)か変数名にインデックスを使用して呼び出す（data[n])
また③のオブジェクトを配列に入れることも出来る

```javascript

data[["a" , "b"], {data3:"c"}, "d"]
上記の場合
console.log(data[0]) // ["a" , "b"]
console.log(data[1]) // {data3:"c"}
console.log(arr5[1].data3) // c
```
###③data{"a","b"} //オブジェクト

```javascript

data{"a","b"}
//波かっこはオブジェクトの書き方で上記のような書き方は出来ません。
// Uncaught SyntaxError: Unexpected token ','
//上記エラーになります。

data{"a":"b"}
という書き方で
console.log(data.a) //b
のようにオブジェクト名(data)とプロパティ名(a)を「.」で繋げて使用できます。
```
読解 モノリスからマイクロサービスへ（1章）

## 本ページについて

[モノリスからマイクロサービスへ
――モノリスを進化させる実践移行ガイド](https://www.oreilly.co.jp/books/9784873119311/)
2020/12 O'Reilly Japan より翻訳版が発売されました。

ざっとおさらいする様に、同書のポイントと関連する記事をまとめたリファレンス記事となります。
※ 以下、ポイント選出や参考Webリンクの結びつきは個人の見解であり、O'Reilly Japanおよび著者とは一切関係ありません。

## マイクロサービスとは

### ポイント１．独立デプロイ可能であること（1.1.1）

 * マイクロサービスの本質は**独立デプロイ可能であること**と定義している
 * 一方で、データベースの共有やサービス境界の発見など独立デプロイの道は平坦ではない
 * [参考：マイクロサービスアーキテクチャとそれを支える技術](https://knowledge.sakura.ad.jp/20167/)

### ポイント２．コンウェイの法則（1.1.2）

 * 「システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう」という法則のこと
 * 組織構造がビジネス視点で凝集していない場合、マイクロサービス化の恩恵を受けにくくなってしまう
 * [参考：コンウェイの法則と逆コンウェイの法則から組織構造を考える](https://medium.com/i35-267/%E3%82%B3%E3%83%B3%E3%82%A6%E3%82%A7%E3%82%A4%E3%81%AE%E6%B3%95%E5%89%87%E3%81%A8%E9%80%86%E3%82%B3%E3%83%B3%E3%82%A6%E3%82%A7%E3%82%A4%E3%81%AE%E6%B3%95%E5%89%87%E3%81%8B%E3%82%89%E7%B5%84%E7%B9%94%E6%A7%8B%E9%80%A0%E3%82%92%E8%80%83%E3%81%88%E3%82%8B-bf3f32ebb022)

### ポイント３．マイクロサービスは銀の弾丸ではない（1.1.4, 1.1.5）

 * マイクロサービス化することで複雑になる問題も存在する
 * [参考：マイクロサービス・アーキテクチャのメリット／デメリットまとめ](https://qiita.com/hhiroshell/items/f5d9c0de71f2a509350c)
 * [参考：マイクロサービスアーキテクチャとは何か](https://www.slideshare.net/yusuke/msa-share-02?next_slideshow=1)

### ポイント４．マイクロなサイズに拘らない（1.1.8）

 * あるサービスが「大きい」か「小さい」かは、人や状況に依存する
 * それよりも「自分達の扱えるサービス数はどれくらいか」「サービスの境界が良い感じになる分界点はどこか」に注力すべき
 * [参考：マイクロサービス　４つの分割アプローチ](https://www.slideshare.net/masuda220/ss-146325870)

## モノリスとは

### ポイント５．単一プロセスのモノリス（1.2.1）

 * すべてのコードが単一のプロセスとしてデプロイされているシステムのこと
 * 後続のモジュラーモノリス等と違い、モノリス内の構造化が出来ていないモノリスを指す
 * 現在人々が苦労しているシステムの大半はこのパターンに当てはまると予想される

### ポイント６．モジュラーモノリス（1.2.1）

 * 単一のプロセスが別々のモジュールで分割されたモノリスのこと
 * マイクロサービスの持つ技術課題を避けつつ既存システムの課題を解決する策として有効な場合がある
 * [Shopifyの成功事例が有名（参考：[翻訳] Shopifyにおけるモジュラモノリスへの移行）](https://qiita.com/tkyowa/items/ae9fa550237cb6f48318)

### ポイント７．分散モノリス（1.2.2）

 * 分散システムの欠点とモノリスの欠点の両方を持つとされるアンチパターン
 * 独立デプロイを守らずマイクロサービス同士が密結合になっていることで発生する
 * [参考：分散されたモノリスになってしまうマイクロサービス](https://www.infoq.com/jp/news/2016/03/services-distributed-monolith/)

### ポイント８．モノリス≠レガシー（1.2.4, 1.2.5）

 * モジュラーモノリスの成功例に代表される様にモノリスにも利点がある
 * モノリス即レガシーと決めつけず、何を得て何を失うかを理解する事が肝要
 * [参考：マイクロサービス化で得ること、失うこと](https://www.graat.co.jp/blogs/ck0nwv2m3ctzj0830xweica5d)

## 凝集と結合

### ポイント９．凝集（1.3.1）

 * 関連する機能と情報がどの程度集約されているか（分散してしまっているか）を表したもの
 * 凝集度が高ければ高いほど人間にとって判り易く良いとされる
 * [参考：凝集度と結合度について](https://www.affordd.jp/koha_hp/KeyWords/KW.Coupling.html)

### ポイント１０．結合（1.3.2）

 * コンポーネントやデータなどソフトウェアの複数の実装同士の結びつきを表すもの
 * 結合には複数のレベルがあり、なるべく結合レベルを低くすることが望ましい
 * [参考：凝集度と結合度：このコードのどこが悪いのか？](https://www.itmedia.co.jp/im/articles/0510/07/news106.html)

## ドメイン駆動設計

### ポイント１１．集約（1.4.1）

 * ドメイン駆動設計における複数のオブジェクト間の状態を矛盾させないための設計思想
 * マイクロサービスにおいても複数サービス間の状態が矛盾しない様に似た考慮が必要になる
 * [参考：リアクティブマイクロサービス入門（2/2）- 実現編](https://qiita.com/crossroad0201/items/e7d4bcb68979caa76abb)

### ポイント１２．境界づけられたコンテキスト（1.4.2）

 * 集約よりも大きな単位の組織境界を表したもの
 * この境界づけられたコンテキストをマイクロサービスの単位にする考え方がある
 * [参考：DDDの構成要素とマイクロサービスの単位をどう合わせるべきか](https://qiita.com/crossroad0201/items/32673d3e52e006205c48)
AtCoder 生活109日目

[前回](https://qiita.com/flandrescarlet237/items/762d821cd3a13cd6676a)

#109日目
今日は、灰色を2問と茶色2問を解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|AGC041|A|✕|34分14秒|
|ABC095|C|◯|10分46秒|
|ARC099|C|✕|135分16秒|
|ABC085|C|◯|16分30秒|


##[AGC041_A](https://atcoder.jp/contests/agc041/tasks/agc041_a)
```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll n,a,b;
    cin >> n >> a >> b;
    if((b-a)%2 == 0)cout << (b-a)/2 << endl;
    else cout << min(a-1,n-b) + 1 + (b-a-1)/2 << endl;
}

```

解くのにかかった時間：34分14秒
感想：AGCの灰色も素早く解けるようにしていきたい。


##[ABC095_C](https://atcoder.jp/contests/abc095/tasks/arc096_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int a,b,c,x,y;
    cin >> a >> b >> c >> x >> y;
    ll r = max(x,y);
    ll ans = 0;
    if((a+b) > 2*c){
        int z = min(x,y);
        ans += z*2*c;
        x -= z;
        y -= z;
    }
    cout << min((ans + x*a + y*b),c*2*r) << endl;
}

```

解くのにかかった時間：10分46秒


##[ARC099_C](https://atcoder.jp/contests/arc099/tasks/arc099_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n,k;
    cin >> n >> k;
    cout << (n + k - 3)/(k - 1) << endl;
}

```

解くのにかかった時間：135分16秒
感想：まさかここまで簡略できるとは思わなかった。


##[ABC085_C](https://atcoder.jp/contests/abc085/tasks/abc085_c)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll n,y;
    cin >> n >> y;
    for(int i = 0;i <= n;i++){
        for(int j = 0;j <= (n-i);j++){
            int k = n - i - j;
            if((i*10000 + j*5000 + k*1000) == y){
                cout << i << " " << j << " " << k << endl;
                return 0;
            }
        }
    }
    cout << -1 << " " << -1 << " " << -1 << endl;
}

```

解くのにかかった時間：16分30秒


###最後に
ABC以外の灰色diffも解けるようにしておきたい。
XMLHttpRequestについて

#XMLHttpRequestとは
ブラウザ上でサーバーとHTTP通信を行えるオブジェクト。
これにより<b>Ajax</b>を可能にすることができる。<br>※Ajaxとは非同期通信とダイナミックHTMLを組み合わせたもの

<br>
基本的には
1.XMLHttpRequestを代入してオブジェクトを作る
2.どのようなリクエストをするのかを指定する
3.読み込み時などの設定など
4.リクエストをする
という動きになる。
-----
##1.XMLHttpRequestを代入してオブジェクトを作る
変数を定義し、<b>「new XMLHttpRequest()」</b>を代入、
これでオブジェクトができる。

```javascript
const XHR = new XMLHttpRequest();
```
##2.どのようなリクエストをするのかを指定する
XHRに<b>openメソッド</b>を使い、<br>(第一引数 , 第二引数 , 第三引数)に<br><b>(HTTPメソッド , 送信先URL , 非同期通信するか否か)</b>を記述していく。

```javascript
// 例
XHR.open("GET", `/posts`, true);
```
##3.読み込み時などの設定など
そのときそのときによるが、今回はJsonで情報を受け取ることとし、レスポンスの形式を指定していく。
レスポンスの形式を指定するには<b>responseTypeプロパティ</b>をXHRにつかう。

```javascript
XHR.responseType = "json";
```
##4.リクエストをする
記述が揃ったらサーバーサイドへ送信の記述をする。
送信するときは<b>sendメソッド</b>を使う。

```javascript
XHR.send();
```
まとめるとこのような流れになる

```javascript
// オブジェクト作成
const XHR = new XMLHttpRequest();
// どのようなリクエストかを指定
XHR.open("GET", `/posts`, true);
// レスポンスの形式を指定
XHR.responseType = "json";
// リクエスト
XHR.send();
```
##その他プロパティ
###・statusプロパティ
HTTPステータスを取得する。

###・statusTextプロパティ
HTTPステータスをテキストで取得する。

```javascript
// HTTPステータスが200で無かった場合エラー文をアラートで表示する
if (XHR.status != 200) {
  alert(`Error ${XHR.status}: ${XHR.statusText}`);
}
```

###・responseプロパティ
レスポンスで<b>「responseType」</b>の値に応じて返却されたデータを取得する。

```javascript
//レスポンスとして帰ってきたpostのデータを取得している
const item = XHR.response.post;
```

###・onloadプロパティ
レスポンスなどの受信が成功した場合に呼び出されるイベントハンドラー。

```javascript
XHR.onload = () => {
  // 受信した時の処理
}
```

-----
JSについてはまだまだ理解していない部分が多いので引き続きアウトプットしていきます。
画像投稿でプレビューを表示させる

# はじめに
ユーザーのことを思ってアプリ制作をしようシリーズ第二弾です。
railsでアプリを作り始めたころは画像投稿をする際にファイルを選択した後、ファイル名だけが表示されていることに対してなにも思わなかったんですけど、ある程度経験を積んでいくうちにプレビューがないとすごく不親切なアプリになってしまうということに気がつきました。
なので今回はそのやり方をメモ程度に書き残します。

# 作るもの
### 画像選択前
![スクリーンショット 2021-02-08 15.21.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674324/f37a02b8-c0a7-175b-c5d8-0e53c04f4be7.png)

### 画像選択後
![スクリーンショット 2021-02-08 15.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674324/af896acd-f639-a606-1a22-7febf39c7a47.png)

このような感じです！
railsの投稿フォームに画像のプレビュー機能をつけていきます。

# 用意しておくもの
画像ファイル投稿用のフォームのみです。

```new.html.erb
<%= form_with model:@post do |f| %>
    <%= f.file_field :image %>
    <%= f.submit %>
<% end %>
```

こんな感じですね。

# 実装
### 流れ
1. 選択された画像ファイルを読み込む
2. 読み込んだ画像を投稿ファイルに出力する

以上です。
それではやっていきましょう！

## 1. 選択された画像ファイルを読み込む

選択された画像ファイルを読み込むにはJavaScriptを活用します。

```new.html.erb
<%= form_with model:@post do |f| %>
    <%# 変更箇所 %>
    <%= f.file_field :image, id:"pac-input"%>
    <%# ここまで %>
    <%= f.submit %>
<% end %>

<%# 追加箇所 %>
<script>
    let image = document.getElementById("pac-input");
    image.addEventListener("change", function(evt){
        let file = evt.target.files;
        let reader = new FileReader();
        reader.readAsDataURL(file[0]);
    },false);
</script>
<%# ここまで %>
```

この記述で画像ファイルの読み込みは完了です。

## 2. 読み込んだ画像を投稿ファイルに出力する

```new.html.erb
<%= form_with model:@post do |f| %>
    <%= f.file_field :image, id:"pac-input"%>  
    <%# 追加箇所 %>
    <div id="image"></div>
    <%# ここまで %>
    <%= f.submit %>
<% end %>

<%# 追加箇所 %>
<style>
    img{
        height: 300px;
        width: 400px;
    }
</style>
<%# ここまで %>

<script>
    let image = document.getElementById("pac-input");
    image.addEventListener("change", function(evt){
        let file = evt.target.files;
        let reader = new FileReader();
        reader.readAsDataURL(file[0]);
        // 追加箇所
        reader.onload = function(){
            let dataUrl = reader.result;
            document.getElementById("image").innerHTML = "<img src='" + dataUrl + "'>";
        }
        // ここまで
    },false);
</script>
```

ここまで来ると画像ファイルを選択したらその画像が`file_field`の下にでてきます。
ただ、このままでは投稿ボタンが表示された画像に隠れた状態になってしまう。
なので画像選択していない状態の時からfile_fieldの下にあらかじめスペースを作っておきましょう！

```new.html.erb
<%= form_with model:@post do |f| %>
    <%= f.file_field :image, id:"pac-input"%>  
    <div id="image"></div>
    <%= f.submit %>
<% end %>

<style>
    /* 追加箇所 */
    #image{
        background-color: rgba(241, 230, 220, 0.661);
        height: 300px;
        width: 400px; 
    }
    /* ここまで */
    img{
        height: 300px;
        width: 400px;
    }
</style>

<script>
    let image = document.getElementById("pac-input");
    image.addEventListener("change", function(evt){
        let file = evt.target.files;
        let reader = new FileReader();
        reader.readAsDataURL(file[0]);
        reader.onload = function(){
            let dataUrl = reader.result;
            document.getElementById("image").innerHTML = "<img src='" + dataUrl + "'>";
        }
    },false);
</script>
```

これで完成！
Githubで特定のフォルダのみcloneする方法

### 内容
本記事ではGithub（実際はgitリポジトリならどこでも）で特定のフォルダのみをcloneする
厳密にはcloneではないが、、、

#### 0. clone先のディレクトリ作成
```bash
# ディレクトリ作成
$ mkdir hoge
$ cd hoge
```

#### 1. git初期化
```bash
# git初期化
$ git init
```

#### ２. origin追加
```bash
# origin追加
$ git remote add origin piyo.git
```

#### 3. sparce-checkout有効化
```bash
# sparce-checkout有効化
$ git config core.sparsecheckout true
```

#### 4. sparse-checkout対象の設定
```bash
# sparse-checkout対象の設定
# sub_dir 部分はリポジトリのルートからの相対パス
# repository_root/sub_dir/subsub_dir/...のリポジトリツリーにおいて、sub_dirフォルダのみcloneしたい場合は、以下のように設定
$ echo sub_dir > .git/info/sparse-checkout
```

#### 5. sparse-checkout対象の設定
```bash
# sparse-checkout対象の設定
# sub_dir 部分はリポジトリのルートからの相対パス
# repository_root/sub_dir/subsub_dir/...のリポジトリツリーにおいて、sub_dirフォルダのみcloneしたい場合は、以下のように設定
$ echo sub_dir > .git/info/sparse-checkout
```

#### 5. originをpull
```bash
# originをpull
$ git pull origin master
```

以上

p.s. 少しググると、上記のやり方は古く新しいやり方があるそう・・・
Dart の final / const のシンプルな違い

## `final` vs `const`

`final` 指定した変数に値を格納できるのは一度だけ。一度格納したら変更できない。

```dart
final number = 1;
number = 2;
// -> Error: Can't assign to the final variable 'number'.
```

`const ` は以下3つの特徴を持つ。`const` は `compile-time constant` の略。

```dart
// 1. コンパイル時に計算できる値のみ格納できる
const datetime = DateTime.now();
// -> Error: Cannot invoke a non-'const' constructor where a const expression is expected.

// 2. コレクション型の値を変更できない
const hoge = [1, 2, 3];
hoge[0] = 4;
// -> Uncaught Error: Unsupported operation: indexed set

// 3. 評価時に再利用される
getConst() => [1, 2]; 
var a = getConst(); 
var b = getConst(); 
print(a == b);
// -> false

getConst() => const [1, 2]; 
var a = getConst(); 
var b = getConst(); 
print(a == b);
// -> true
```

## 参照

- [Const, Static, Final, Oh my!](https://news.dartlang.org/2012/06/const-static-final-oh-my.html)
ObsidianとGitHub、ハマりかけて夜が更ける

### 背景

ハマった（そして回復した）ので、記録しておく。

たしかにこの記事は素晴らしいんだけど　→　How I Put My Mind Under Version Control
https://medium.com/analytics-vidhya/how-i-put-my-mind-under-version-control-24caea37b8a5

ちょっと違っていて、行きつ戻りつしたので、失敗を含めて記録。

`.gitignore`の作成は省略。

```bash
$ git init
$ git add .
$ git commit -m "init"
```
まではよかった。

```bash
$ git remote add origin https://github.com/USER/REPO.git
$ git push -u origin master
```

がよくなかった。わたしの理解したところでは、２行ともよくない。

```bash
$ git remote -v /* これは現状を確認するコマンド */
$ git remote rm origin
```

として、originの指定を解除。
>git/githubでエラーメッセージが出て困ったとき、とりあえず前の状態に戻る方法（たち）
>https://qiita.com/hann-solo/items/33b6fd8314fc297839d7

に書いておいてよかった。困ったときのことはQiitaに書いとかなきゃだわ。

GitHubのリポジトリも、一旦削除して、登録し直した。気を取り直して

```bash
git remote add origin git@github.com:USER/REPO.git
git branch -M main
git push -u origin main
```

GitHubのインストラクション（readme.mdも.gitignoreも登録しないと、コマンド解説ページになってくれた）に従った。

たぶん

- `git@github.com:`式でないと「他人がプルリク送った」みたいになっていた
- GitHubのメインブランチ名が、`master`から`main`に変わった

のだと思われる。

ともかく、上記コマンドで全く問題なく登録完了。あとはObsidianのGit支援プラグインのインストールだな。

### Obsidian Git プラグイン

こちらはインストールして、ちょこっと設定したらすぐできた。`git`の設定ができていれば、あまりやることはない。

![SS 2021-02-08 23.20.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/a9db4b97-56b3-be22-6c29-8acfcf51fa8b.png)

設定したてなので、インターバルが10分になっているけど、まあ60分間隔ぐらいでいい気がする。


### 目次にもどる

[Obsidian｜使いかたの記録（目次） - Qiita][00]

[00]: https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4
rails　評価機能（数字のみ）

##はじめに
オリジナルアプリ制作過程で評価機能を作ったので健忘録として残します

##1.DBファイル

``` 
class CreateEvaluates < ActiveRecord::Migration[6.0]
  def change
    create_table :evaluates do |t|
      t.integer :speedy
      t.integer :kindness
      t.integer :frantically
      t.references :user, foreign_key: true
      t.timestamps
    end
  end
end
```

今回は早さ、親切さ、リピート、総合力の評価をしたかったので3つのカラムを用意しました。
でも総合力無いじゃんと思いましよね？わざわざ作らんでも四則演算できると思ってBDにはカラムとして用意はしませんでした


##2.controller
```
def show
  @evaluate = Evaluate.new
  @evaluates = Evaluate.includes(:user)
  @kindness = Evaluate.average(:kindness)
  @speedy = Evaluate.average(:speedy)
  @frantically = Evaluate.average(:frantically)
  @comprehensive = @kindness + @speedy + @frantically
  @posts = Post.includes(:user).order("created_at DESC")
end
```

注目していただきたいのは@kindness以降

average(:kindness)で、カラムkindnessの平均を割り出し、インスタンス変数に代入します
それを3つのカラム分行います
@comprehensiveは総合力として、平均を割り出し、代入したインスタンス変数を足しただけです
先ほども伝えた通り、DBで総合力は必要なかったと言う事です

※追記
上記の総合力を求めるコードのみだと、DBに何も登録されていない場合エラーが起きてしまいます
なのでIF文を利用して、各カラムに値がが入っていない場合に計算を行わないコードを記載します
↓

```
  if @kindness != nil && @speedy != nil &&  @frantically != nil
    @comprehensive = @kindness + @frantically + @speedy
  end
```
!=は==の逆で、〜ではないと言う意味となるので今回のコードは各カラムに空の値出ない場合に合計値を求めるようにすると言う内容になってます
##3.viws

```
      .UserStatus
        他のユーザーの評価（平均点）
        .UserStatus__Kindness
          = "親切度 : #{@kindness}"
        .UserStatus__speedy
          = "迅速さ : #{@speedy}"
        .UserStatus__frantically
          = "repeat : #{@frantically}"
        .UserStatus__comprehensive
          = "総合力 : #{@comprehensive}"
```

ビューにインスタンス変数を記述してあげればブラウザ上で表示されます

![スクリーンショット 2021-02-08 22.39.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672760/6e3b3ecc-d87a-0bb5-32e0-82b834b2ff14.png)