OmniAICreator/Qiita-1.07M huggingface dataset:
Educational Codeforces Round 83 D. Count the Arrays : 組み合わせ

とてもとても面白い問題でした！こういう考察楽しい。
https://codeforces.com/contest/1312/problem/D

hitonanodeさんのSubmitがとても分かりやすくて参考になりました。
https://codeforces.com/contest/1312/submission/72804437

# 題意
a. n個の1以上の整数要素からなる配列が与えられる。また、正の整数mも与えられる。
b. この配列はあるi番目に最大となる値があり、その左側は(0から見て)単調増加であり、その右側は単調減少である。以下、ピーク、と呼ぶ。
c. この配列には1つだけ同じ数字のペアがある。
d. このような数列が何通りあるか？modで述べよ。


# 例
$n=4, m=5$のいくつかを考える。
- $[1,2,3,1]$
- $[1,4,2,1]$
- $[2,4,3,2]$

単調減少、単調増加が条件であり、以下のように、同じ値が続くのはNGである。
- $[2,2,3,1]$

また、題意より、以下のように、単調増加・減少区間がない数列もNGである。
- $[1,2,3,4]$
- $[4,3,2,1]$



# 問題を言い換える

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/606bf70d-c315-1a82-0946-a59607eba88d.png" width=50%>
上記はn=6でiが7のイメージ。(iはピークの値であり、mそのものではない(後述)

- あるピーク値iがある(図中黒の7)
- (その値は最大であるから) i-1以下の数字jを1つ選び、その値はピークの左右に配置される。(図中緑)
    - 単調増加区間、単調減少区間に同じ数字が2回以上は存在できないから

- jではないi-1以下の数字をn-3つ選ぶ(つまり、i-2個の中から3つ)(図中赤)
    - ピークの値kを1つとペアの数字jを2つ選んでいるのでnの長さの配列に入れないといけない要素はn-3つ。
   
- この選んだ数字をピーク値の右側に分配するか、左側に分配するかを選択する。(図中黄色)
    - 上記のようにピークの左右には最低1つの数字を入れないとならないが、これらの数字はすべて右側に入れても左側に入れても良い。なぜなら、ペアjを選択した時点ですでに左右に最低1つの数字があるため、左右の要素が最低1つは残る。

これらの計算をiが $(n - 1)$ から $ m $まで行えばよい。もし、iがn-2(以下)だとすると、数字を選ぶことが出来ない
    - 例: n=6で i=5なら$[1, 5, 4, 3, 2, 1]$
    - 例: n=6で i=4なら$[1, 4, 3, 2, 1, ???]$となってしまう

# 実装
$$ \sum_{i=(n-1)}^{m} (i-1) \cdot {}_{(i-2)}C _{(n-3)} \cdot 2^{(n-3)}$$
で終わり！すごい。

- $n,r$が$2 \cdot 10^{5}$程度のmodな$nCr$をforで回すので、逆元なり各種結果をキャッシュしておかないとTLEします。

```Python
# https://www.planeta.tokyo/entry/5195/
mod = 998244353

def cmb(n, r, p):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n - r] % p

p = mod
N = 5 * 10 ** 5  # N は必要分だけ用意する
fact = [1, 1]
factinv = [1, 1]
inv = [0, 1]

for i in range(2, N + 1):
    fact.append((fact[-1] * i) % p)
    inv.append((-inv[p % i] * (p // i)) % p)
    factinv.append((factinv[-1] * inv[-1]) % p)


n, m = map(int, input().split())
res = 0
import math
if n == 2:
    print(0)
else:
    for i in range(n-1, m+1):
        res += (i - 1) * cmb(i - 2, n - 3, mod) * pow(2, n-3, mod)
        res %= mod
    print(res)

```

# おまけ: NGアプローチ
言い換えをしないで整理しようとしたところ方向性を見失った。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/cdcd9475-d4c8-1dc6-869c-94c5f710aa61.png" width=50%>
春休みの宿題

#春休みの宿題一覧

春から情報科学研究科に進学するのでこの春休みに準備しなければいけないことをまとめておく。

##プログラミング言語

- [C言語本格入門](https://www.amazon.co.jp/C言語本格入門-基礎知識からコンピュータの本質まで-種田-元樹/dp/4774196169)
- [C++プログラミング〈Vol.1〉 (Computer Science Textbook)](https://www.amazon.co.jp/C-プログラミング%E3%80%88Vol-1〉-Computer-Science-Textbook/dp/489471115X)
- [C++プログラミング〈Vol.2〉 (Computer science textbook)](https://www.amazon.co.jp/C-プログラミング%E3%80%88Vol-2〉-Computer-science-textbook/dp/4894711168)
- [エキスパートPythonプログラミング改訂2版](https://www.amazon.co.jp/エキスパートPythonプログラミング改訂2版-Michal-Jaworski/dp/4048930613)
- [改訂2版 みんなのGo言語](https://www.amazon.co.jp/改訂2版-みんなのGo言語-松木-雅幸/dp/4297107279/ref=mp_s_a_1_1?keywords=みんなのGo&qid=1583850906&sr=8-1)
- [CUDA C プロフェッショナル プログラミング (impress top gear)](https://www.amazon.co.jp/CUDA-プロフェッショナル-プログラミング-impress-gear/dp/4844338919/ref=mp_s_a_1_6?keywords=cuda&qid=1583850993&sprefix=Cuda&sr=8-6)
- [現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/)

##Computer Science

- [Introduction to Theoretical Computer Science](https://introtcs.org/public/index.html)
- [並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング](https://www.amazon.co.jp/並行コンピューティング技法-―実践マルチコア-マルチスレッドプログラミング-Clay-Breshears/dp/4873114357/ref=mp_s_a_1_10?keywords=並列計算&qid=1583851224&sr=8-10)

##Information Science

- [グラフ理論入門](https://www.amazon.co.jp/グラフ理論入門-R-J-ウィルソン/dp/4764902966/ref=mp_s_a_1_1?keywords=グラフ理論入門&qid=1583851330&sprefix=グラフ理論&sr=8-1)
- [データベースシステム](https://www.amazon.co.jp/データベースシステム-北川-博之/dp/4274216055/ref=mp_s_a_1_1?keywords=データベースシステム&qid=1583851379&sr=8-1)

##開発ツール

- [Docker](https://www.amazon.co.jp/Docker-Adrian-Mouat/dp/4873117763/ref=mp_s_a_1_10?keywords=Docker&qid=1583851457&sr=8-10)


##Web Framework 

- [gin](https://github.com/gin-gonic/gin)

##Algorithm

- [AtCoder](https://atcoder.jp/)
- [Codeforces](https://codeforces.com/)
- [Cracking the Coding Interview: 189 Programming Questions and Solutions](https://www.amazon.co.jp/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/ref=mp_s_a_1_fkmr1_1?keywords=hacking+code+interview&qid=1583851745&sr=8-1-fkmr1)

##Block Chain

- [Ethereum](https://ethereum.org/)
- [現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発](https://www.udemy.com/course/go-fintech/)
【今日のアブストラクト】Label-Free Supervision of Neural Networks with Physics and Domain Knowledge【論文 ほぼ Google 翻訳 自分用】

1 日 1 回 (努力目標) 論文の Abstract を Google 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ Google 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Label-Free Supervision of Neural Networks with Physics and Domain Knowledge](https://arxiv.org/abs/1609.05566)

# Abstract

### 訳文

多くの機械学習アプリケーションでは, ラベル付きデータは少なく, より多くのラベルを取得するのは高価です. 入出力ペアの直接的な例ではなく, 出力空間を保持する制約を指定することによる, 教師ありニューラルネットワークの新しいアプローチを紹介します. これらの制約は, 既知の物理法則などの事前のドメイン知識から導出されます. 私たちは, 実世界およびシミュレートされたコンピュータービジョンタスクに対するこのアプローチの有効性を実証します. 畳み込みニューラルネットワークをトレーニングして, ラベルの付いたサンプルなしでオブジェクトを検出および追跡できます. このアプローチは, ラベル付きトレーニングデータの必要性を大幅に削減できますが, 事前の知識を適切な損失関数にエンコードするための新たな課題をもたらします.


### 原文

In many machine learning applications, labeled data is scarce and obtaining more labels is expensive. We introduce a new approach to supervising neural networks by specifying constraints that should hold over the output space, rather than direct examples of input-output pairs. These constraints are derived from prior domain knowledge, e.g., from known laws of physics. We demonstrate the effectiveness of this approach on real world and simulated computer vision tasks. We are able to train a convolutional neural network to detect and track objects without any labeled examples. Our approach can significantly reduce the need for labeled training data, but introduces new challenges for encoding prior knowledge into appropriate loss functions.
久々のvagrant up でこけた

![スクリーンショット (50).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288302/7c78c218-ee2b-c4cb-ae96-fe5b3295c4d5.png)


#やったこと
デバイスマネージャーを開いて、ネットワークアダプターの項目にある、
VirtualBox Host-only Ethernet　Adapter#2を削除

→vagrant reload

→添付画像のエラー＋VirtualBox Host-only Ethernet　Adapter#2だけでなく#3まで復活(ふぁ？)

手を変え品を変え調べると、、

検索ワード:
「Stderr: VBoxManage.exe: error: Failed to open/create the internal network 'HostInerfaceNetworking-VirtualBox Host-Only Ethernet Adapter #3' (VERR_INTNET_FLT_IF_NO_FOUND).」

ででできた
https://qiita.com/ExA_DEV/items/ae80a7d767144c2e1992
上記URLのサイトを参考にさせていただきましたところすぐ解決しました。ネットワーク関連のエラーは無知すぎるので勘弁👼

追記:
他のQiita投稿者様のように抜粋したコード
やエラー文を載せたいのですがどなたかご存知でしたらコメントなどで恐れ入りますが教えて頂きたいです！無知ですみません！
【Linuxコマンド】exportコマンド｜環境変数やシェル変数を設定する

>この記事では、《exportコマンド》について、
業務を通して学習した内容をまとめています。

- __exportコマンド とは…？__
- __exportコマンド の使い方__

こういった内容についてまとめています。

__※本記事は、自分で学習したことのまとめ用として書いています。
尚、解説で誤った点があれば、スローして頂ければ喜んでキャッチしますのでお願い致します。__

## 【概要】&ensp;exportコマンド とは…？

`export`コマンドは、環境変数やシェル変数を設定するコマンドで、

以下の２つの使い方があります。

1. &ensp;__『シェル変数』を『環境変数』に設定する__
2. &ensp;__指定した『環境変数』を削除する__

>Linux環境で使用する変数には、シェルからのみ参照できる…

>__『シェル変数』__

>と他のコマンドやプログラムからも参照できる…

>__『環境変数』__

>があります。

## exportコマンド の使い方

`export`コマンドの書式は、以下の通りです。

~~~
export [オプション] [変数名]
~~~

| オプション | 説明 |
| :---: | :--- |
| -n | 指定した環境変数を削除する。 |
| -p | エクスポートされている環境変数のリストを表示する。 |

それでは、先ほど紹介した２つの使い方の例題を見ていきましょう。

1. &ensp;__『シェル変数』を『環境変数』に設定する__
2. &ensp;__指定した『環境変数』を削除する__

### 使い方①：&ensp;『シェル変数』 を 『環境変数』に設定する

~~~
export [変数名]
~~~

例えば・・・

- シェル変数：&ensp;`greeting="Hello World"`

の場合は、下記のようになります。

#### --- 例題 ---

~~~shell
#!/bin/bash

greeting="Hello World"
export greeting
~~~

#### --- 実行結果 ---

シェルを実行したら、実際に環境変数`greeting`が登録されているか、確認してみましょう。

確認するには、`printenv`コマンドを使用します。

>設定されている環境変数の一覧が表示されてしまうため…
>`grep`コマンドと組み合わせて変数名を指定すると便利です。

~~~
$ . sample.sh
$ printenv | grep greeting
greeting=Hello World
~~~

---

### 使い方②：&ensp;指定した『環境変数』を削除する

『環境変数』を削除する場合は、`-n`オプションを使用します。

~~~
export -n [変数名]
~~~

例えば・・・

先ほど設定した環境変数の`greeting`を削除する場合は、下記のようになります。

#### --- 例題 ---

~~~sample.sh
#!/bin/bash

export -n greeting
~~~

#### --- 実行結果 ---

~~~
$ . sample.sh 
$ printenv | grep greeting
# 何も表示されない
~~~
Githubアカウントを個人と会社別々で運用したい時の設定

## はじめに

私用の端末１台で会社と個人のGithubアカウントを分けなければいけない時が過去にあったので、備忘録としてこの記事を書いていきます。

## 注意点

- sshでのクローンを想定しているのでhttpsでのクローンは割愛します。（というかわからん）
- 端末でSSHについて一切設定していない場合、`~/.ssh`ディレクトリが存在しませんがそこについては別な記事で触れようと思っているので今回は割愛します。
- あとは自己責任やで！

## 準備

### クライアント側

#### SSHキーの生成

`ssh-keygen`コマンドを使用して、個人と会社それぞれのGithubに登録するSSHキーを生成します。

`ssh-keygen`コマンドの使い方は[こちらの記事](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)をいつも参考にしてます。

別々に管理したほうがセキュリティ的にも安心できるので、分けた方が良いと思いますよ！

#### ~/.ssh/configの編集

ホスト別にSSHキーの参照先を変更しています。

この設定をすることでサブドメインでの判別が可能となり、URLで対象Githubアカウントを区別しています。

```shell
# 個人アカウント用
Host wannoko.github.com
	HostName github.com
	User git
	Port 22
	IdentityFile ~/.ssh/id_rsa
	TCPKeepAlive yes
	IdentitiesOnly yes

# 会社アカウント用（Googleにいる想定）
Host google.github.com
	HostName github.com
	User git
	Port 22
	IdentityFile ~/.ssh/google_rsa
	TCPKeepAlive yes
	IdentitiesOnly yes
```

### Github側

#### SSHキーの登録

個人と会社で使用するGithubアカウントそれぞれに、生成したSSHキーを登録してください。

## 実際の流れ

### クローンに利用するURLを書き換える

`Clone with SSH`からコピーしてきたURLを個人と会社別々で使用する時に書き換えます。

#### 個人の場合

`git@wannoko.github.com:{リポジトリ名}`

#### 会社の場合

`git@google.github.com:{リポジトリ名}`

### クローンする

`git clone`コマンドとかでクローンしてね！
【Laravel】assertSeeとassertSeeTextの違い

# 結論
assertSeeTextではHTMLタグをテストできません。

```php

// HTMLタグ
$response->assertSee('<title>タイトル</title>'); // OK
$response->assertSeeText('<title>タイトル</title>'); // NG

// テキスト
$response->assertSee('タイトル'); // OK
$response->assertSeeText('タイトル'); // OK
```

# 彼らから見えている世界
**assertSee**

```php

<li><a href="http://localhost">ホーム</a></li>\n
<li><a href="http://localhost/terms">利用規約</a></li>\n
<li><a href="http://localhost/tokutei">特定商取引法表示</a></li>\n
<li><a href="http://localhost/privacy">プライバシーポリシー</a></li>
```

**assertSeeText**

```php

ホーム\n
利用規約\n
特定商取引法表示\n
プライバシーポリシー\n
```

# 余談
指定したビューが返されたことをテストする場合は`assertViewIs`を使いましょう。
Dart (Flutter)でextentionを使う方法

こんにちは最近趣味でFlutterを書いている@glassmonkeyです。
Flutter歴3ヶ月ぐらいです。仕事でswiftちょっと書いています。

# はじめに
Dart2.7になって[Extention](https://dart.dev/guides/language/extension-methods)が使えるようになりました。今回は導入するにあたって少しハマるポイントがあったのでほぼ個人用メモです。

# Extentionとは
Dartにおける[Extention](https://dart.dev/guides/language/extension-methods)とは静的データ構造にメソッドを追加できます。
具体的にはこのように書けるようになります。

```dart

extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }
  // ···
}

"123".parseInt() // 123
```
スコープの問題やら多様すると管理がめんどうとか結構危険性は匂いますが、
外部処理をラッパーするなどには結構便利かなと思います。


# 導入してみよう
## 1. Flutterのバージョンをチェック

```bash

flutter --version
```

```
Flutter 1.12.13+hotfix.8 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 0b8abb4724 (4 weeks ago) • 2020-02-11 11:44:36 -0800
Engine • revision e1e6ced81d
Tools • Dart 2.7.0 
```

下記のようにDartのバージョンが2.7以上になっていることを確認する。
未満の場合はflutterのバージョンアップをご検討ください。

```
Tools • Dart 2.7.0
```

## 2. pubspec.ymlを書き換える
sdkのバージョン指定を明示的に2.7以上に上げる。 

```yml
environment:
  sdk: ">=2.7.0 <3.0.0"
```

プロジェクトセットアップ時はこの指定だったが、これだと動かなかった。
あまりわかってないので、詳しい方教えてください。

```yml
environment:
  sdk: ">=2.1.0 <3.0.0"
```



## 3 flutter cleanをする。
```
$ flutter clean
```

たぶんこれでビルドが通るはずです。



# おわりに
今回extentionを導入するといった小さい対応のための記事でしたが、誰かの助けになれば嬉しく思います。
多分これに限った話じゃないですが、[NNBD](https://qiita.com/Cat_sushi/items/44872ccc68604413f065])などのdartの新機能導入するときにはSDKの指定が忘れそうなので戒めとして覚えておこうと個人的に思ってはいます。

たまにFlutter関係のことぼやいていたりするので、[@glassmonkey](https://twitter.com/glassmonekey)をフォローしてくれると嬉しいです。
正規表現

##正規表現とは
特徴的なのは
電話番号のハイフンを取り除く(文字列の一部分を置換する)
パスワードに英数字８文字以上という制約を設定する(文字列が制約を満たしているか調べる)
メールアドレスからドメインの部分のみ抽出する(文字列の一部分を抽出する)
などがあります。
正規表現にはsubメソッドとmatchメソッドがあります。
##subメソッド
文字列の指定した部分を別の文字列に置き換えるためのメソッドです。
【例】ターミナル

```
$ irb
```
```
irb(main):001:0> str = "水を飲む"
=> "水を飲む"

irb(main):002:0> str.sub(/水/,"お茶")
=> "お茶を飲む"
```
操作したい文字列は/で囲みます。
##matchメソッド
引数に指定した文字列がレシーバの文字列にあるかを確認するためのメソッドです。ある場合は、指定した文字列がMatchDataオブジェクトの返り値になります。ない場合は、返り値としてnilになります。
【例】ターミナル

```
rb(main):001:0> str = "おはよう, おやすみ"
=> "おはよう, おやすみ"

irb(main):002:0> str.match(/おはよう/)
=> #<MatchData "おはよう">

irb(main):003:0> str.match(/こんにちわ/)
=> nil
```
##MatchDataオブジェクト
マッチした文字列等はMatchDataオブジェクトで返されます。MatchDataオブジェクトから文字列等を取り出してみます。
【例】ターミナル

```
irb(main):001:0> str = "おはよう, おやすみ"
=> "おはよう, おやすみ"

irb(main):002:0> md = str.match(/おはよう/)
=> #<MatchData "おはよう">

irb(main):003:0> md[0]
=> "おはよう"
```
##ハイフンの取り除きかた
subメソッドでは最初のハイフンしか置換されないのでgsubメソッドを使います。
【例】

```
irb(main):001:0> tel = '090-1234-5678'
=> "090-1234-5678"

irb(main):002:0> tel.sub(/-/,'')
=> "0901234-5678"

irb(main):003:0> tel.gsub(/-/,'')
=> "09012345678"
```
このgは、指定した文字が複数ある場合、その全てを置換します。
##パスワードに英数字の制約
【例】matchメソッドを使用します。

```
rb(main):001:0> pass = 'Hoge1234'
=> "Hoge1234"

irb(main):002:0> pass.match(/[a-z\d]{8,}/i)
=> #<MatchData "Hoge1234">
```
ここでは今までとかなり違う部分が出てきました。意味合いは
・[a-z]: 角括弧で囲まれた文字のいずれか1個にマッチ
・\d: 数字にマッチ
・{n, m}: 直前の文字が少なくともn回、多くてもm回出現するものにマッチ
・i: 大文字・小文字を区別しない検索
・.: どの1文字にもマッチ
・+: 直前の文字の 1 回以上の繰り返しにマッチ
##[a-z]
角括弧で囲まれた文字の１つがマッチするかをチェックしています。また、-で範囲を設定することができます。指定なので[a-z]だけではなく[a-c]みたいにもできます。
【例】

```
irb(main):001:0> 'dog'.match(/[a-c]/)
=> nil
irb(main):002:0> 'dog'.match(/[a-d]/)
=> #<MatchData "d">
```
となります。
##\d
\dは数字にマッチするので、[a-z\d]は「英数字のいずれか１つにマッチ」という意味になります。
【例】数字のみ抽出します

```
irb(main):001:0> 'abc 3 xyz'.match(/\d/)
=> #<MatchData "3">
```
##{n, m}
直前の文字が少なくともn回、多くてもm回出現するものにマッチします。例えば{4,8}は、直前の文字が少なくとも4回出現、直後の文字が最大8回出現にマッチという意味になります。
【例】

```
irb(main):001:0> '12345678'.match(/\d{4,6}/)
=> #<MatchData "123456">

irb(main):002:0> '123'.match(/\d{4,6}/)
=> nil
```
##i
大文字・小文字を区別しない検索します。iを付けない場合だと、[a-z]と小文字で記述しているので大文字にマッチしません。
【例】

```
irb(main):001:0> 'Dog'.match(/dog/)
=> nil

irb(main):002:0> 'Dog'.match(/dog/i)
=> #<MatchData "Dog">
```
##.
ハイフンやピリオドなど含めたどの１文字にもマッチします。
【例】

```
irb(main):001:0> 'abc'.match(/./)
=> #<MatchData "a">
```
##+ 
直前の文字が１回以上の繰り返しにマッチします。
【例】

```
irb(main):001:0> 'aaabbc'.match(/a+/)
=> #<MatchData "aaa">
```
.と+は何かしらの文字が１回以上繰り返すものにマッチします。例えばメールアドレスみたいに先頭に@を付けることで＠から始まり、何かしらの文字が１回以上繰り返すものにマッチします。
【例】

```
irb(main):001:0> mail = 'hoge@takashi.com'
=> "hoge@takashi.com"

irb(main):002:0> mail.match(/@.+/)
=> #<MatchData "@takashi.com">
```
aws ecr get-loginでポリシー不足でエラーが出力

記録としてメモしとく。

# やりたかったこと
AWS-CLI使って Amazon ECRにログインしたい。

# 前提
私の環境
- Windows10 Pro
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178016/27d74383-6c0f-5509-933a-3702918f60a3.png)
- AWS CLIインストール済　

```
> aws --version
aws-cli/1.16.313 Python/3.7.2 Windows/10 botocore/1.13.49
```

# 事象

```
PS C:\Users\taketakekaho> aws ecr get-login --region ap-northeast-1 --profile <profile> --no-include-email

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::XXXXXXXXXXXX:user/<profile> is not authorized to perform: ecr:GetAuthorizationToken on resource: *
```

なんかアクセス権的なものがないようでエラーが出る。

# 対処
このAmazonEC2ContainerRegistryPowerUserというポリシーが足りなかったらしい。以下のようにアタッチした所解消しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178016/49e2fe07-4f06-1a32-cba8-0b68c9d4ad32.png)

# というか…
情報探す中でたまたま読んだクラスメソッドさんの技術ブログ（[[アップデート]AWS CLI v2 で $ aws ecr get-login を使うときの注意点](https://dev.classmethod.jp/cloud/aws/aws-cli-v2-ecr-get-login-password/)）で **$ aws ecr get-login はv1でも非推奨** ということを初めて知った…気を付けよう。

# 参考

- [IAMの基本(ポリシー, ユーザー, グループ, ロール)](https://www.wakuwakubank.com/posts/476-aws-iam-basic/)
- [[アップデート]AWS CLI v2 で $ aws ecr get-login を使うときの注意点](https://dev.classmethod.jp/cloud/aws/aws-cli-v2-ecr-get-login-password/)
- [get-login](https://docs.aws.amazon.com/cli/latest/reference/ecr/get-login.html#get-login)
Ruby on rails で星を散らす

#はじめに
railsで、リロードする度に見え方が変わる星空を再現してみます
![star-sky.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481085/bef194a6-fe03-aad2-7337-fb5bff5f52ae.jpeg)

[作成したWebアプリ](http://fffbookmark.herokuapp.com/)にも採用しています。


#実行
最初に次のファイルを用意します。

```haml:index.html.haml
.sky
.stars
```

```css:star_sky.css
.sky{
background-color: #014; //黒っぽければなんでもいい
}

```

次に、星を表すオブジェクトを用意します。

```haml:index.html.haml
.sky
.stars
  .star
```

```css:star_sky.css
.sky{
background-color: #014; //黒っぽければなんでもいい
}

.star{
  border-radius: 50%;
  position: fixed;
  z-index: 0;
  -ms-filter: blur(6px);
  filter: blur(6px);
}

```

星が一つだけなのもおかしいので、複数表示させます。
また、リロードする度に、数が変わるようにもしてみます。
使用するのは`randメソッド`と`timesメソッド`です。

```haml:index.html.haml
.sky
.stars
  - number = rand(100..200)
  - number.times do
    .star
```

これだけだと、同じ場所にひたすら100個以上の`.star`が作られるだけです。
そのため、`times`で`.star`が一つ生成される度に、位置がランダムで指定されるようにします。
それにはCSSを適用すれば良いですが、CSSはHamlのコードにも直接指定できるので、これと変数展開を利用します。

```haml:index.html.haml
.sky
.stars
  - number = rand(100..200) //100から200までの間の数字をランダムで
  - number.times do
    - top   = rand(100)
    - left  = rand(100)
    .star{style: "top: #{top}%; left: #{left}%; height: #{size}px;}
```

次に星の色と大きさを指定します。
折角なので、全て違う色と大きさにしてみます。

```haml:index.html.haml
.sky
.stars
  - number = rand(100..200)
  - color  = ["red","blue","green","yellow","purple","white","pink","orange"]
  - number.times do
    - top   = rand(100)
    - left  = rand(100)
    - size = rand(10..20)
    - cnum = rand(0..7)
    .star{style: "top: #{top}%; left: #{left}%; height: #{size}px; width: #{size}px; background-color: #{color[cnum]}"}
```

これで完了です。
試しに画面をリロードしてみると、星の配置が変わると思います。
![star-sky2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481085/5e0fdd10-f18e-6a9a-3d8d-19780c8d2856.jpeg)



今回はほぼ`randメソッド`を利用しましたが、
頑張って数式を適用すれば、もっと幾何学的で美しい背景を作ることができそうです。
SE2 RACユーザーに朗報。SE2用の新たな高可用性ソリューションが近日リリース？

<font color="blue">追記：この機能は2020年5月にリリースされた。詳細は[こちら](https://qiita.com/yamada-hakase/items/9a40ab976ffeb8ca4207)。</font>

# SE2 RAC非サポートの衝撃

19cがリリースされたとき

**<font color="red">「19cからSE2 RACが非サポート」</font>**

と聞いて椅子から転げ落ちそうになったヒトは少なくないはずだ。

* [Oracle Database Standard Edition 19c の Oracle Real Application Clusters (RAC) のサポート終了](https://support.oracle.com/knowledge/Oracle%20Database%20Products/2561913_1.html)


なぜならば、19cはターミナルリリースで、現時点ではもっとも長いサポート期間が保証されているからだ。

当然SE2 RACユーザーにとっては寝耳に水で

**<font color="red">「これからどうすればいいのか？　18cは、いつまで使い続けられるのか？」</font>**

と考えたであろうことは想像に難くない。

19cと聞くと、ずいぶん新しい印象を持つかもしれない。しかし、
12cR2(12.2.0.1)
18c(12.2.0.2)
19c(12.2.0.3)→ターミナルリリース
なので、19cまでは同じ12cファミリーである。

# SE2向け高可用性ソリューションのアナウンス

このような状況のなか、2020年3月にSE2向けの高可用性ソリューションがアナウンスされた。

* [Announcing: Standard Edition High Availability(SE2向け高可用性ソリューションの提供予定)](https://blogs.oracle.com/oracle4engineer/column_se2ha)

詳しくはブログを読んでもらうとして、Oracle Clusterwareを使ったHAクラスタ・ソリューションのようだ。

日本でOracleデータベース用のHAクラスタというと、NEC CLUSTERPROやサイオスLifeKeeperが有名だ。新しいソリューションでは、これらが無くてもHAクラスタを組めるらしい。

ちなみにアメリカのOracleデータベース用HAクラスタでは、少し前まではVeritas Cluster Serverのシェアが高く、近年ではRAC One Nodeが一番使われているらしい（2018年のOOW San Franciscoで聞いた）。日本ではマイナーなRAC One Nodeなのに。

# Oracleデータベース以外もHAの対象にできる

ブログを読み進めると、Oracleデータベース以外もHAの対象にできるらしい。

> さらに、Oracle Clusterware用のOracle Grid Infrastructure Standalone AgentsをStandard Edition High Availabilityと併用して、Oracle WebLogicやApacheなどの特定のアプリケーションの完全なアプリケーションスタックのフェイルオーバーを管理できます。

実は、ずいぶん前からOracle Clusterwareで、いろいろなミドルウエアのHAクラスタが組めた。知る人ぞ知る機能だったのだけれど、作り込みが大変だった。知人でもOracleデータベースのHAクラスタを組んだという話を聞いたことがある。

また、その以前Oracle社のイベントで

* Oracle Linuxのサポート契約を結ぶと[Oracle Clusterwareが使える](https://docs.oracle.com/cd/E77565_01/e89918/ol7-lic-restricted.html)
* Oracle Clusterwareを使って、リーズナブルにOracle DB以外のクラスタを組んだ

という講演を聴いたことがある。

そして現在はいくつかのミドルウエアをサポートしている「[Oracle Grid Infrastructure Standalone Agents for Oracle Clusterware](https://www.oracle.com/database/technologies/xag-agents-download.html)」がリリースされている。知らなかった！

サポート対象アプリケーションはこちら。今後Oracleデータベースが追加されるのだろう。

> Supported applications: Oracle GoldenGate, Siebel, Apache, PeopleSoft, MySQL, JD Edwards, WebLogic and Oracle E-Business Suite

# リリース時期は？


> Standard Edition High Availability will be made available as part of a Release Update (RU) with Oracle Database 20c as well as Oracle Database 19c later this calendar year. More details will follow soon. 

19c用は2020年末までにはリリースされるようだ。

とはいえ、不安なのはマイグレーション方法。Data Pump Exportしないで移行できるならばいいけれど、すべて再構築＆Export/Importだとつらいものがある。これから導入するヒトはいいけれど。
JavaScriptでサイトの言語切り替え2

昔作った物の書き換えた物です

[JavaScriptでサイトの言語切り替え](https://qiita.com/metalgearsolid3love/items/856118faa1504fe26456)

```javascript
class Lang {
  lang;
  el;
  data;
  ctx;
  content;
  afterContent;
  address;
  constructor(obj) {
    this.el = obj.el || "body";
    this.data = obj.data || {};
    this.lang = obj.data.def || "en";
    this.address = obj.data.address || false;
    this.ctx = document.querySelector(this.el);
    this.content = this.ctx.textContent;
    this.afterContent = this.ctx.textContent;
    this.loads();
    return this;
  }
  run() {
    for (const key in this.data) {
      let val = this.data[key];
      const reg = new RegExp(`\%\{${key}\}`, "g");
      this.afterContent = this.afterContent.replace(reg, val[this.lang]);
    }
    this.ctx.textContent = this.afterContent;
  }
  loads() {
    if(location.hash) {
      this.lang = location.hash.split("#")[1];
    } else {
      this.lang = ((window.navigator.languages
        && window.navigator.languages[0])
        || window.navigator.language
        || window.navigator.userLanguage
        || window.navigator.browserLanguage).split("-")[0];
    }
    this.run();
    if(this.adress) history.replaceState("", "", `#${this.lang}`);
  }
}
```

使用方法

element はcssセレクター指定
(未指定body)

def は初期表示の言語
(未指定時en or 先に宣言したlangに合わせる)


adress は URLの後ろにセクターを付けるか
(未指定時false 指定時true)
trueのとき　○○.com/home#ja
\#ja の部分を変えるとその言語になる


```html
<div id="title">
  %{title} %{message}
  <div id="test">
    %{title}
  </div>
</div>

<div id="box">
  %{box}
</div>

<!-- 上記のコードを読み込む -->

<script>
new Lang({
  el: "#title", // element
  def: "ja", // default
  address: false, // adressbar
  data: {
    "title": {
      "ja": "タイトル",
      "en": "title"
    },
    "message": {
      "ja": "メッセージ",
      "en": "message"
    }
  }
});

new Lang({
  data: {
    "box": {
      "ja": "ボックス",
      "en": "box"
    }
  }
});
</script>
```
LINE Messaging APIのチャネルの新規作成

#LINE Messaging API
LINE Messaging APIはLINE Botを作るために必要となるため今回取得をしました。
作成はそこまで難しくはありませんが備忘録として書き残したいと思います。

####トップページにアクセスし「今すぐはじめよう」をクリック
![スクリーンショット 2020-03-10 22.41.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/9e395c9c-ecc1-18b3-8181-2c13bac17205.png)

####LINEビジネスIDにログインする
LINEアカウントでログインします。
初めてログインをする場合は名前などの登録を求められます。
![スクリーンショット 2020-03-10 22.41.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/0bdcd5c1-8eea-9628-04e2-8b0b9e005e03.png)

####Messaging APIのチャネルを新規作成する
空白を埋めて作成を押すと新規作成されます。
![スクリーンショット 2020-03-10 22.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/aa167592-c2cb-6c47-bc97-48bd5af1688d.png)

- アプリ名。1度決めると7日間は変更できないルールとなっています
- プロバイダーとはLINE botの提供者（あなた）のことです。
- 作成後、Messaging API設定タブに、このチャネルと友だちになるためのQRコードが表示されています。必要であればここで友達登録をすると便利です。

#おわり
以上でLINE Messaging APIのチャネルの新規作成が完了しました。
【Udemy Python3入門+応用】　56. クロージャー

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**

##■クロージャー
難しい内容になるので、今の段階では「こんなものがあるんだな」とわかればOK。

```python:closure
def circle_area_func(pi):
    
    # radiusを渡すと円の面積が返ってくる
    def circle_area(radius):
        return pi * radius * radius
    
    # circle_areaを返すだけで実行はしない
    return circle_area

# piを3としてcircle_area_funcに渡し、返ってきたcircle_areaをcal1に代入
cal1 = circle_area_func(3)
# piを3.14としてcircle_area_funcに渡し、返ってきたcircle_areaをcal2に代入
cal2 = circle_area_func(3.14)

# radiusを10としてcal1に渡し、結果をprint
print(cal1(10))
# radiusを10としてcal2に渡し、結果をprint
print(cal2(10))
```
```:result
300
314.0
```
クロージャーは、今回のように
初めに設定した引数(`pi`)を後々用途応じて使い分けたい(3とするのか3.14にするのか)とき
などに有効な手段なので、頭の片隅に置いておこう。
ORA-00988: パスワードが指定されていないか、または無効です。となった時の対応方法

- 環境
    - 接続先 : (RDS)Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
    - 接続元 : (EC2)Ubuntu 18.04 LTS(64ビット x86)
    - SQL*Plus: Release 12.2.0.1.0 Production

# 事象 : ユーザー作成時にパスワードで怒られた。
```sql
SQL> create user ponsuke identified by 'ponsuke' default tablespace USERS temporary tablespace TEMP profile DEFAULT;
create user ponsuke identified by 'ponsuke' default tablespace USERS temporary tablespace TEMP profile DEFAULT
                                  *
行1でエラーが発生しました。:
ORA-00988: パスワードが指定されていないか、または無効です。
```

## 原因 : パスワードをシングルクォーテーションで囲んでいるから
> パスワードに使用できる特殊文字
> 一重引用符  '
> [パスワードに使用できる特殊文字](https://docs.oracle.com/cd/E17327_01/doc.910/b54369/app_special_char.htm)

シングルクォーテーションは、パスワードに使える特殊文字でした。
なのでパスワードを囲む文字としては使えません。

> 次のパスワードは二重引用符で囲む必要はありません。
> ・アルファベット(aからz、AからZ)で始まり、数字(0から9)または特殊文字($、#、_)を含むパスワード。
> [Oracle Databaseの安全性の維持](https://docs.oracle.com/cd/E82638_01/dbseg/keeping-your-oracle-database-secure.html#GUID-451679EB-8676-47E6-82A6-DF025FD65156)

ということは、もし`"'ponsuke'"`と指定したら`ponsuke`ではなくて`'ponsuke'`というパスワードになっていました。

### 対応方法 : パスワードはダブルクォーテーションで囲むか、アルファベット始まりなら囲まない
```sql
SQL> create user ponsuke identified by ponsuke default tablespace USERS temporary tablespace TEMP profile DEFAULT;

ユーザーが作成されました。

```
Python　セイウチ演算子で複数行ラムダ

```python
def very_long_name_func(x):
    return x * 2

def func(x, y, z):
    return x + y + z

f = lambda i: (
    x := very_long_name_func(i),
    func(x, x, x)
)[-1]

for n in map(f, range(10)):
    print(n)

```
PHPのPDOで外部のデータベースサーバーを利用したいときの注意点と選択肢

PHPのPDOで外部のデータベースを利用するときに躓いたところをまとめました。

#データベースサーバーの話
レンタルサーバー付属のDBサーバーは無理
レンタルサーバー付属のDBサーバーを最初使おうとしたのですが、基本的にどのレンタルサーバーもリモートSQLには対応していません。
リモートSQLとは、そのDBサーバーが運用されているIPとは異なるIPやグローバルネットワーク経由でのSQL操作のことです。

セキュリティ的な理由で、多くのレンタルサーバー付属のDBサーバーはできません。

#DBサーバーの選択肢
月額固定費での運用を考えると、日本語環境だと以下の2つのDBサーバーがありました。

DBサーバー｜VPSならConoHa
https://www.conoha.jp/database/

データベースサーバー｜レンタルサーバーのカゴヤ・ジャパン
https://www.kagoya.jp/multi-plan/database/

どちらも、初期費用0円・月額500円です。

Conohaだと、VPSの契約も必須なようなことを書いてあるサイトもありましたが、データベースサーバーだけで利用可能です。

#固定IPからの利用だと問題なし

リモートSQLをするクライアントが固定IPアドレスであれば、どちらのDBサーバーを利用しても問題ありません。

#動的IPからの利用は大問題

カゴヤのDBサーバーは、リモートSQLのクライアントのIPアドレスを必ず指定する必要があります。
そのため、動的IPから利用する予定がある人は色々問題が発生します。

そのため、動的IPアドレスからの利用を予定している人はConohaのDBサーバーをおすすめします。

#PHPを動かすサーバーの問題

PHPからSQLを操作するときに、外部のデータベースを操作できるレンタルサーバーとできないレンタルサーバーがあります。

私が利用しているMixhostとXserverは、どちらもダメでした。

最終的に、海外のレンタルサーバーであるBluehostを利用しました。

いろいろセキュリティと利便性の案配が大変なんですね。

以上
おわおわり。
git add と git commit を連打する人は git commit -a で幸せになれます

```
$ git add index.html
$ git commit index.html
```
とコマンドするよりも、以下コマンドであれば一コマンドで済みます。

```
$ git commit index.html -a
```

Git では、`git commit` コマンドに `-a` オプションを指定すると追跡対象となっているファイルを自動的にステージしてからコミットを行います。
`git add` と `git commit` を連続でコマンドしている方はシンプルなショートカットを使っていきましょう。
bin/upgradeで管理しているRedashインスタンスをv8.0.0に無理やり上げる

# あらすじ

https://redash.io/help/open-source/admin-guide/how-to-upgrade-legacy

RedashはV8からDockerによるデプロイのみをアップグレード対象とするようになり`bin/upgrade`コマンドによる昔ながらのアップグレードができなくなりました。
なのでこのタイミングでモダンなデプロイ方法に式年遷宮すれば良いんですが、そうは問屋がおろしてくれない人向けに、`bin/upgrade` 相当のことを自前でやる方法を紹介します。

*ご利用は自己責任で計画的に！！！*

# 方法の概要

`bin/upgrade`の[コード](https://github.com/getredash/redash/blob/e552effd96d4184dbc904522400fa4e1ff4667da/bin/upgrade)を読んで同じことを自前でやるだけです

- 新バージョンのソースを固めたtarballを取ってくる
  - V8からはこのtarballが提供されなくなったので`bin/upgrade`が動かなくなっています
  - このtarballにはRedashのコードとビルド済のアセットが含まれてます
- 新バージョンのソースで`pip install -r requirements.txt`を実施
- 新バージョンのソースで`bin/run ./manage.py db upgrade`を実施
- `$REDASH_HOME/current`のシンボリックリンクを新バージョンに差し替え
- `supervisorctl`でRedashのプロセスを再起動

この手順を順次やってく感じです。

# アップグレード手順

## dockerイメージからアセットを取り出してRedashインスタンスに配置する

以下のコマンドを実行してV8のRedashのdockerイメージからアセットを取り出します

```bash
docker run -it -v /tmp/work:/tmp/work -w /app/client docker.io/redash/redash:8.0.0.b30340 /bin/bash -c "tar cvfz dist.tar.gz dist ; mv dist.tar.gz /tmp/work/dist.tar.gz"
```

アップグレードするRedashインスタンスにdockerが入ってればコレをインスタンス上で直で実行しましょう。なければローカルで実行してSCPか何かで`/tmp/work/dist.tar.gz`を転送しておきましょう。

以後はRedashインスタンス上に`/tmp/work/dist.tar.gz`が置いてある前提で進めます。

## Redashインスタンスでアップグレードを実行

Redashインスタンスにログインして`root`になって以下を実行していきます

ますはRedashを止めます

```bash
/etc/init.d/redash_supervisord stop
/etc/init.d/redash_supervisord status
```

GithubからV8のソースを持ってきて展開します

```bash
cd /opt/redash/　# $REDASH_HOME

curl -L https://github.com/getredash/redash/archive/v8.0.0.tar.gz -O
tar xvfz v8.0.0.tar.g
chown redash:root /opt/redash/redash-8.0.0
ls -al /opt/redash/redash-8.0.0
```

`.env`のシンボリックリンクを作ります

```bash
ln -s /opt/redash/.env /opt/redash/redash-8.0.0/.env
```

dockerから抜き取ったV8のアセットを展開します

```bash
cd /opt/redash/redash-8.0.0/client
tar xvfz /tmp/work/dist.tar.gz
ls -al /opt/redash/redash-8.0.0/client/dist
```

`pip install`と`db migrade`を実施します

```bash
cd /opt/redash/redash-8.0.0
# pipがchardetでコケたら以下を参考に
# https://stackoverflow.com/questions/49915951/cannot-uninstall-chardet
pip install -r requirements.txt
sudo -u redash bin/run ./manage.py db upgrade
```

currentのシンボリックリンクを差し替えます

```
ln -nfs /opt/redash/redash-8.0.0 /opt/redash/current
```

ここまで無事終わったら勝利は目前です、後はRedashを起動するだけ

```bash
/etc/init.d/redash_supervisord start
/etc/init.d/redash_supervisord status
```

Redashが無事起動してアクセスできれば作業は完了です。

無事起動しなかったら後は気合で頑張れ！！

# 終わりに

*ご利用は自己責任で計画的に！！！*


どのみち次のバージョンではPython2が全面的に切られるであろうから刹那の延命策です。
機械学習でInput contains NaN, infinity or a value too large for dtype('float64').というエラーが出たときの対処法

# 機械学習で「Input contains NaN, infinity or a value too large for dtype('float64').」というエラーが出たときの対処法

##エラーの原因
上のエラーに書いてある通りデータにNaNかinfかfloat64でないタイプのものが混じっている。文字列を含む列をpandasで以下のように書き、Naも埋めたのにエラーが出た。

```
df=df.drop(columns=df.select_dtypes(include='object').columns)
```
これでは列の中に一部含まれるfloat以外の値を変換することができないみたいだ。
そこでnumpyで使えるようにndarrayに変換した後、float以外の値になるやつをfloat型に変換させ、float型に変更不可能なものをNaとし、その後欠損値を変換した。

```
X = df.iloc[:, 1:].values
y = df.iloc[:, 0].values
for i in range(X.shape[1]):
    X[:,i]= pd.to_numeric(X[:,i], errors='coerce')
X1=np.nan_to_num(X)
```
これが正しい処理なのかはよくわからないが、とりあえずモデルを学習させるときのエラーはなくなった。
なにかいいやり方があったらコメントお願いします。
Win10 HomeのWSL2+DockerでGUIのROS1/ROS2をセットアップする方法

@karaage0703さんが「[Docker上でGUIのROS1/ROS2を一瞬でセットアップする方法](https://qiita.com/karaage0703/items/957bdc7b4dabfc6639da)」にて紹介してくださったDockerイメージ（[tiryoh/ros-desktop-vnc](https://hub.docker.com/r/tiryoh/ros-desktop-vnc)と[tiryoh/ros2-desktop-vnc](https://hub.docker.com/r/tiryoh/ros2-desktop-vnc)）がWindows 10 Home上のWSL2で問題なく動いたので紹介します。

[![Image from Gyazo](https://i.gyazo.com/78fb31319cffda8a219a0933c0afc316.png)](https://gyazo.com/78fb31319cffda8a219a0933c0afc316)

## 使い方（簡略版）

DockerがインストールされたWindows 10で以下のコマンドを実行し、Webブラウザで[http://127.0.0.1:6080](http://127.0.0.1:6080)にアクセスすると、Dockerコンテナ内にアクセスできるVNCクライアントが立ち上がります。

```shell
docker run -p 6080:80 --shm-size=512m tiryoh/ros2-desktop-vnc:dashing
```

## 環境

### OS

使用したOSはWindows 10 Home Insider Previewのバージョン2004、OSビルドは19564.1000です。

[![Image from Gyazo](https://i.gyazo.com/893c159d52f21ad336f187d3a7c95833.png)](https://gyazo.com/893c159d52f21ad336f187d3a7c95833)

WSL2のインストールについては@aki4000さんの「[Windows10 HomeとWSL2でdocker-composeができるようにする](https://qiita.com/aki4000/items/c26e3076c8cec9677415)」が大変わかりやすかったです。

### Docker

使用したDocker Desktop for Windowsのバージョンは2.2.2.0(43066)です。

[![Image from Gyazo](https://i.gyazo.com/7df8daf8dd871c450820d388796a9edd.png)](https://gyazo.com/7df8daf8dd871c450820d388796a9edd)

## 使い方

DockerがインストールされたWindows 10で以下のコマンドを実行します。

```shell
docker run -p 6080:80 --shm-size=512m tiryoh/ros2-desktop-vnc:dashing
```

初回起動時はWindowsのセキュリティ警告が出ました。

[![Image from Gyazo](https://i.gyazo.com/523705cf2ee531b7a42a6178d7c021bf.png)](https://gyazo.com/523705cf2ee531b7a42a6178d7c021bf)

アクセスを許可するとDockerコンテナ内でサーバが立ち上がるのを確認できます。

[![Image from Gyazo](https://i.gyazo.com/f0a55f08e3d3960cfc689e4905d77923.png)](https://gyazo.com/f0a55f08e3d3960cfc689e4905d77923)

Webブラウザで[http://127.0.0.1:6080](http://127.0.0.1:6080)にアクセスすると、VNCクライアント経由でターミナルを立ち上げたり、各種の操作ができます。Gazeboも起動できます。

[![Image from Gyazo](https://i.gyazo.com/78fb31319cffda8a219a0933c0afc316.png)](https://gyazo.com/78fb31319cffda8a219a0933c0afc316)

[![Image from Gyazo](https://i.gyazo.com/5a71a36dc9d6106ef794fbcb86af7e7f.gif)](https://gyazo.com/5a71a36dc9d6106ef794fbcb86af7e7f)


## 謝辞

このDockerfileは[@1222_takeshi](https://qiita.com/1222_takeshi)さんの「[GCP+Docker+GPUでrosを動かす (2) ~ VNCで動くDocker+ros環境の作成 ~](https://qiita.com/1222_takeshi/items/5214e86f58b7db3b93e1)」より着想を得たものです。

## 追記

より便利に使うための詳細についてはこちらに書きました。  
[ROS/ROS2のGUIをWebブラウザ経由でお手軽に試せるDockerfileを公開しました – Memoteki](https://memoteki.net/archives/2955)
Neural Network Consoleを使って画像判別

はじめまして！

駆け出しエンジニアのelemoiです！
エンジニアと言っていいのか、、、と言うレベルですが
いつかエンジニアとして胸を張りたい

今回は初めての投稿とテーマということで
 Sony Network Communications Inc.
が提供しているNeural Network Consoleを
使って画像判別を行なっていきます。

なぜこれをしようと思ったのかというと、、、
2020年3月4日〜2020年3月27日まで
コンテストを実施しているからです！！！！

https://nnc-challenge.com/

上記URLで詳細みれます。
ぜひご興味があれば参加を！！
今回は紹介投稿です！
今後技術的なものを投稿していきます！

ちなみに僕のテーマは3番の
『NNCで画像を学習し人の感情によって分類』
です！！
日常で構成を考えながら仕事していきたい！
GuardDutyの結果をEvent Bridge→SNSで通知する

# はじめに
[前回](https://qiita.com/Y-Suzaki/items/b78a4c1dc74e2fcd1d1c)、AWS LambdaからEvent Bridgeに通知してみました。
今回は、`GuardDuty`→`EventBridge`→`SNS（Email）`と連携させてみます。

最近業務でセキュリティ！セキュリティ！と叫ばれておりますが、そこまでまともにセキュリティ系のサービスを使っていなかったので、GuardDutyを触り始めたのが理由です。。

# 構築手順
## GuardDutyの有効化
AWSコンソールから`GuardDuty`を有効化しておきます。（初回の場合、30日間は無料です。）

## SNSの作成
Emailで通知が受け取れるように設定しておきます。
![sns.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428042/7ad98d4d-8e19-652f-278b-015f98601b99.png)

## EventBridgeの設定
### イベントバスの作成
`default`のイベントバスを利用するので不要です。
最初カスタムイベントバスにルールを作ってしまい、全然アラートが飛ばす悩みました、、、
~~ここでは[前回](https://qiita.com/Y-Suzaki/items/b78a4c1dc74e2fcd1d1c)作成した、`custom-application-event-bus`をそのまま使います。（無い方は任意の名前で作って下さい）~~
   
### イベントルールの作成

ルール名は任意でOK
![guard-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428042/733aa54c-b338-3828-4303-fa537467cf15.png)

カスタムパターンを選択し、イベントパターンに以下を入力します。
今回はSeverityがHighのものだけ通知するようにしています。Severityの定義は[こちら]
(https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_findings.html#guardduty_findings-severity)を参照。

```
{
    "source": [
        "aws.guardduty"
    ],
    "detail-type": [
        "GuardDuty Finding"
    ],
    "detail": {
        "severity": [
            { "numeric": [ ">=", 7 ] }
        ]
    }
}
```  

ターゲットには先ほど作成したSNS Topicを指定します。
![guard-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428042/e0e0cb54-9a2e-5e0b-c76c-1d687bcf33e9.png)

# GuardDutyにサンプルを作成し通知
## サンプル結果の作成
GuardDutyの検出を意図的に発生させるのは難しいため、サンプルで試します。
AWSコンソールのGuardDutyの画面で、「設定」→「結果サンプルの作成」を選択します。
（10数件ほどメールが来るのでご承知おきを。）

## メールの確認
SNS作成時に設定したEmailに以下のようなメールが届いていれば完了です！

```json
{
    "version": "0",
    "id": "0eef64b4-0f67-244d-400b-7677324fe2af",
    "detail-type": "GuardDuty Finding",
    "source": "aws.guardduty",
    "account": "xxxxxxxxxx",
    "time": "2020-03-10T13:50:01Z",
    "region": "us-west-2",
    "resources": [],
    "detail": {
        ・・・
        "severity": 8,
        "createdAt": "2020-03-07T13:34:05.589Z",
        "updatedAt": "2020-03-10T13:49:52.052Z",
        "title": "DGA domain name queried by EC2 instance i-99999999.",
        "description": "EC2 instance i-99999999 is querying algorithmically generated domains. Such domains are commonly used by malware and could be an indication of a compromised EC2 instance."
    }
}
```

# さいごに
セキュリティの検知をどの範囲で、どのような方法ですれば良いのか？はとても難しいと思います。
まずは、GuardDutyのような自動で検出してくれるサービスを有効にし、EventBridgeである程度必要なものに絞り込み、自分達に有用なアラートを取捨選択していければと思っています。
DVWA（XXS:stored）全レベルの脆弱性について

## 前提
- kali linux環境がある
- [DVWAのセットアップ済み](https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c)
- [初級レベル理解済み](https://qiita.com/KPenguin/items/dea8c81522f81b7bb1f3)

## 目標
- 脆弱性の理解を深める。

## 手順概要
- 大まかな挙動を把握する
- コードを見て脆弱性をみつける
- コードの脆弱性を攻撃する

## 内容
###挙動の把握
- ボタンを押すとPOSTリクエストが飛ぶ
- 文字列がDBに保存され、下部に転写される

### コードを確認
#### low
- 入力値がそのまま格納される。

```php:
<?php
$name    = trim( $_POST[ 'txtName' ] ); 
?> 
```

#### medium
- str_replace(a,b,c)は、cの中にaが入っていればbに置換する
- 今回の場合、`<script>`が入っていれば、"空"へ置換される

```php:
<?php
$name = trim( $_POST[ 'txtName' ] );  
$name = str_replace( '<script>', '', $name ); 
?> 
```

#### high
- mediumロジックは同じ
- ここでは正規表現を使ってさらに厳格にチェックしている。

```php:
<?php
$name = trim( $_POST[ 'txtName' ] );  
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name ); 
?>
```

#### impossible
- htmlspecialcharsはhtmlにとっての特殊文字をエスケープさせるので、タグの入力がエスケープされる。

```php:
<?php
$name = stripslashes( $name ); 
name = htmlspecialchars( $name ); 
?>
```

### 脆弱性を攻撃する
nameに入力するが、htmlで文字制限かかっているので、maxlengthを増やせば入力可能になる。
#### low
- 防御無しのため、ストレートに攻撃する。
- `<script>alert("low")</script>`
- 見づらいがscriptが埋め込まれている（下図）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/625b631b-fe24-ad16-5eab-6fa1004e88df.png)


#### medium
- 制限されているのは`<script>`という文字列だけなので一部変更すれば突破できる
- `<script >alert("medium")</script >`
- messageはエスケープされている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/4dfa4984-bbd4-bead-355c-0adf2172b3e7.png)


#### high
- mediumみたいに空白を開けても並びが"script"ならブロックされる。なので、script以外を使う。
- `<img src="#" onerror=alert("high")>`
- messageはエスケープされている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/8cf0d24d-4de9-a5c6-0447-d23823d8bd79.png)


#### impossible
- 無理っぽい
Git push で RPC failed が発生した場合の対処法

# 不具合の背景

それまで普通に使用していたが、ちょっと大きめの push をしようとした時にエラーが発生した。
ググると似たような事例があったのですぐ解決したが、エラーコードが若干違ったりしていたので、
今回の事例でも対応できたという記録の意味で残しておく。

# エラーの内容

```git:エラー
RPC failed; curl 56 recv failure
```

# 解決方法

git のプロンプトを開いて下記コマンドを入力すると成功した。

```git:コマンド
git config --global http.postBuffer 524288000
```

# 原因

バイナリデータがリポジトリに含まれていると起こることがあり、
git のバッファを増やすことにより解決することがあるようだ。
また、サーバー側に原因がある場合もあるようなので、確認できるならそちらを調べてみるのも良いかもしれない。

<参考>
[gitで大きいサイズのファイルを扱う時](https://qiita.com/akiko-pusu/items/2d65a54e9d2a6c7f9d13)
[git clone時にbufferが足りなくてエラーになった話](https://tree-tree-diary.hatenablog.com/entry/2018/09/26/012254)

また、上記コマンドを実行しても上手くいかない場合、再起動すると動いた事例もあった。

<参考>
[SourceTree、Gitでpull出来なくなったときのメモ2](https://www.proglad.tokyo/2018/04/sourcetreegitpull2.html)

# それでも解決しない場合

別リポジトリで上記対応をしても clone ができないものがあったが、
無線LAN から 有線LAN に変更すると clone できた。
通信速度が原因だったと思われるが参考までに。
herokuにmasterブランチ以外のブランチをデプロイする方法



herokuではmasterブランチにpushされたコードがアプリとして実行されるため、開発中のブランチ(task)をとりあえずherokuで動作させたいという場合には、以下のようにgit pushします。

```
# taskブランチをherokuのmasterにpushして動作させる
$ git push heroku task:master
```


 

参考
https://blog.knjcode.com/push-branch-to-heroku/
【Udemy Python3入門+応用】　55. 関数内関数

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**

##■関数内関数
#####◆使い方
```python:inner_function
def outer(a, b):

    def plus(c, d):
        return c + d

    r = plus(a, b)
    print(r)
    
outer(1, 2)
```
```:result
3
```
関数の中で、さらに新しい関数を定義することも可能である。
内側の関数(`plus`)を、外側の関数(`outer`)以外の場所で使わない場合、
関数内関数として記述してやるとよい。
CSS、SCSSファイルの読み込み

## CSSファイルの読み込み
rails newによってアプリケーションを作成した際にはapplication.cssに

```ruby
*= require_tree .
```
の記述がある。この記述によって同じディレクトリにあるcssファイルは読み込まれる。
またこのrequireはアセットパイプラインの仕組みによってファイルを読み込む。
アセットパイプラインはcssファイルやjavascriptファイルを一つにまとめて圧縮し処理速度をあげる仕組み。
アセットパイプラインはsprocketsと言うgemによって実装されている。

## SCSSファイルの読み込み
scssファイルはapplication.scssに@importを記述することでscssファイルをインポートする。
この@importはscssのメソッドであり拡張子をscss(application.scss)にしないと使えない。
application.scssからscssファイルをインポートするために使用するメソッドである。
【Udemy Python3入門+応用】　54. Docstringsとは

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■関数の説明の記述
#####◆関数内に記述する
```python:docstrings
def example_func(param1, param2):
    """Example function with types documented in the docstring.
    
    Args:
        param1 (int): The first parameter. 
        param2 (str): The second parameter.
    
    Returns:
        bool: The return value. True for success, False otherwise.
    """
    print(param1)
    print(param2)
    return True
```
一旦サンプルの関数を用意した。
このサンプルの説明書きとして、通常であれば説明する行の上にコメントアウトするが、
関数の場合は内側の先頭に書くのがお約束。

#####◆docstringsを呼び出す
```python:docstrings
def example_func(param1, param2):
    """Example function with types documented in the docstring.

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.
    """
    print(param1)
    print(param2)
    return True

print(example_func.__doc__)
```
```:result
Example function with types documented in the docstring.

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.
```
`.__doc__`のメソッドで、その関数のdocstrinsを呼び出せる。

#####◆docstringsを呼び出す2
```python:docstrings
def example_func(param1, param2):
    """Example function with types documented in the docstring.

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.
    """
    print(param1)
    print(param2)
    return True

help(example_func)
```
```:result
Help on function example_func in module __main__:

example_func(param1, param2)
    Example function with types documented in the docstring.
    
    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.
    
    Returns:
        bool: The return value. True for success, False otherwise.
```
`help`を使うことでも、docstringsを呼び出すことができる。
PHPで多次元連想配列を高速に検索する

# はじめに
データベースから取得した多次元連想配列に対して検索を行うとき、どのように処理するのが一番いいのか分からなかったので調べてみました。
ざっくり調べた限りだと`array_search` + `array_column`で実装するのが多かったんですが、計算量が O(n^2) になってしまうのでパフォーマンス的にどうなんだろうと思い、実際に測定してみました。

今回は以下の2パターンについて検証を行います。
1. `array_search` + `array_column` で検索する
2. 検索したいキーで連想配列を作り直してから検索する

# バージョン
PHP 7.2

# 検証コード
## 1. `array_search` + `array_column` で検索する
上述の通り計算量がO(n^2)になってしまうのでパフォーマンス的に不安がありますが、比較的シンプルに記述することができます。

```php
$size = 100;

// 検証用の配列を作成する
$array = [];
foreach(range(0, $size) as $i) {
    $part['hoge'] = 'key' . $i;
    foreach(range(1, 9) as $j) {
        $part[$j] = 'fuga';
    }
    $array[] = $part;
}

$time_start = microtime(true);

foreach (range(0, $size) as $i) {
    array_search('key' . $i, array_column($array, 'hoge'));
}

$time = microtime(true) - $time_start;
print($time * 1000 . 'ms');
```

## 2. 検索したいキーで連想配列を作り直してから検索する
こちらは計算量がO(n)になるのでパフォーマンスが良くなると考えられますが、配列を作り直す処理が必要なのと検索したいキーが重複している場合に使えないというデメリットがあります。

```php
$size = 100;

// 検証用の配列を作成する
$array = [];
foreach(range(0, $size) as $i) {
    $part['hoge'] = 'key' . $i;
    foreach(range(1, 9) as $j) {
        $part[$j] = 'fuga';
    }
    $array[] = $part;
}

$time_start = microtime(true);

// 検索したいキーで配列を再生成する
$mapping = [];
foreach($array as $a) {
    $mapping[$a['hoge']] = $a;
}

foreach (range(0, $size) as $i) {
    $mapping['key' . $i];
}

$time = microtime(true) - $time_start;
print($time * 1000 . 'ms');
```

# 測定結果
上のコードの`$size`を変えながら実行速度を測定しました。

| $size | 100  | 1,000 | 10,000 |
|---|---|---|---|
|1. `array_search` + `array_column` で検索する | 0.14ms | 16ms | 1886ms |
|2. 検索したいキーで連想配列を作り直してから検索する |0.02ms  | 0.19ms | 4.54ms |

# 結論
- 1,000レコード程度までならどちらを使ってもパフォーマンスに大きな差はない
- 10,000レコード以上なら速度がかなり低下するので、検索したいキーで連想配列を作り直して検索した方が良さそう
[Rust] f32 と f64 でコードを共有する

Rust で数値計算をしていて意外にハマるのが, `f32` と `f64` でコードを共有しようとしてもなかなかコンパイルが通らないという点です. 傾向と対策をまとめます.

# 戦略

まずそもそもコードを共通化と言ってもジェネリクスを用いた関数

```rust
fn some_calculation<T>(x: T) -> T {
    // ここを実装する //
}
```
を定義しようとしているのか, なんらかのトレイト `Foo` を `f32` と `f64` に実装しようとしているのか, という 2 パターンがあり得ます. 後者の場合は

```rust
macro_rules! impl_foo {
    ($t: ty) => {
        impl Foo for $t {
            fn foo(&self) -> Self {
                // ここを実装する //
            }
        }
    };
}
impl_foo!(f32);
impl_foo!(f64);
```

という感じでしょうか. 基本的にマクロなら難しいポイントはないのですが, ジェネリック関数では適切なトレイトを探したりしなければならずなかなか大変です. それならば, とマクロでふたつの関数を定義しようとすると, 残念ながら `concat_idents!` が関数名に使えず詰みます ([paste](https://crates.io/crates/paste) クレートを使うという手はあります).


# 値の取得

Rust は暗黙の型変換を嫌うため, 値を取得するだけでもなかなか手間です.

## 0 と 1

マクロ中なら展開後に数値リテラルが適切な型として解釈されるので単に `0.` や `1.` と書けば大丈夫です. 一方ジェネリック関数では `num-traits` のトレイト `num_traits::Zero`, `num_traits::One` を使うのが簡単です.

```rust
use num_traits::One;

fn get_one<T: One>() -> T {
    T::one()
}
```

もちろん次小節で述べるより一般的な方法を使うこともできます.

## 整数を変換

任意の整数が与えられてそれを浮動小数点数として計算に使いたいということは頻繁にあります. マクロ中では単に `as $t` とすれば良いので簡単です. 一方ジェネリック関数では案外クセがあって, `From` が使えればそれが簡単なのですが, 型によって使えたり使えなかったりします.

* `f32`: `From<u8>`, `From<i8>`, `From<u16>`, `From<i16>`
* `f64`: `From<u8>`, `From<i8>`, `From<u16>`, `From<i16>`, `From<u32>`, `From<i32>`

つまり一番使うと思われる `i32` については, `f64` は `From<i32>` ですが `f32` はそうでないのです. この違いは, `From<U>` は「情報喪失なし」に型変換できることを表すトレイトですが, `f32` では有効数字が足りず `i32` から変換することができないことに由来します.

ではどうするかというと, これも `num-traits` が適切なトレイトを提供してくれています: [`num_traits::FromPrimitive` です](https://docs.rs/num-traits/0.2.11/num_traits/cast/trait.FromPrimitive.html).

```rust
use num_traits::FromPrimitive;

fn get<T: FromPrimitive>(x: i32) -> T {
    T::from_i32(x).unwrap()
}

fn main() {
    let _: f32 = get(7);
}
```

ちなみに, `num_complex::Complex`, `num_rational::Ratio` ともに `Zero`, `One`, `FromPrimitive` です.

# 四則演算や関数

四則演算は std に `std::ops::{Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign, Div, DivAssign, Rem, RemAssign}` があるため, これを使えば大丈夫です. 書くのが面倒だという方は `num_traits::{NumOps, NumOpsAssign}` を利用してください.

一方, `sin` や `exp` などの数学関数は std ではトレイトとしては用意されていないため, `num_traits::Float` が必要です. このトレイトには `num_traits::Num` を通じて `PartialEq` や四則演算 `NumOps` などが含まれています (`NumOpsAssign` は入っていないため別枠で指定する必要があります). また `Float` には `PartialOrd` も入っています.

# まとめ

`f32` と `f64` に使えるジェネリック関数を定義する場合, トレイト境界として `T: Float + FromPrimitive` を指定すればたいていのことはできます. 必要に応じて `NumOpsAssign` を補ってください.

```rust
use num_traits::{Float, FromPrimitive};

fn one_plus_cos<T: Float + FromPrimitive>(x: T, n: i32) -> T {
    T::one() + ( x * T::from_i32(n).unwrap() ).cos()
}
```

# 参考文献

* [num-traits: 数値型の為のTraits](https://qiita.com/termoshtt/items/c24e7d67f3c4a9016a7b)
* [num-traits](https://crates.io/crates/num-traits)
初めてのGraphQL ~特徴・導入・簡単なクエリまで


最近Reactを学びはじめたこともあって同じFacebookが作ったGraphQLにも手を出してみました。
GraphQLの輪郭もわからない時は「NoSQLのクエリの弱さを独自の検索エンジンで全て解決してくれる魔法のクエリ言語」なんて思ってました。(浅はかなり)

> GraphQLを勉強しはじめて2日目で書いた記事なのであやふやなところや間違ってる点など多々あると思います...

## GraphQLとは
![](https://rightcode.co.jp/wp-content/uploads/2019/06/GraphQL.png)

実際のところはクエリとレスポンスの構造に対応関係を持たせることができたり、スキーマ設定によりエディタにおける補完や型チェックなどが行えたり、REST APIと違い処理によってGETエンドポイントを分ける必要がなく冗長化を防ぐことができたりと、いわばAPIのフレームワークのような印象を受けました。

イメージ図を作ってみました↓
![GraphQL流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407389/f1037748-1ca3-44f7-3224-153ef7a22817.png)

## インストール(導入)
今回はNodeベースのexpress + apollo + GraphQLでAPIサーバーをたてていきます。

```terminal
// プロジェクトフォルダを作成
$ mkdir first_graphql
$ cd first_graphql

// プロジェクトのセットアップ
$ npm init

// 必要なモジュールをインストール
$ npm i --save express apollo-server-express graphql

// index.jsを作成
$ touch index.js
```

## コードを書いていく
index.js

``` javascript
const express = require('express')
const { ApolloServer, gql } = require('apollo-server-express')
const app = express()

// GraphQL言語のschemaを使ったconstruct定義
// レスポンスするデータの型を設定しておく
const typeDefs = gql`
    type Query {
        firstQuery: String
    }
`

// schemaごとに取得ロジックを設定していく 
const resolvers = {
    Query: {
        firstQuery: () => "Hello,world!",
    },
}

const server = new ApolloServer({ typeDefs, resolvers })

server.applyMiddleware({ app })

app.listen({ port: 4000 }, () =>
    console.log(`Server ready at http://localhost:4000${server.graphqlPath}`)
```

## 動かしてみる
```terminal
$ nodemon index.js
//$ node index.jsでも可
```
動かしたら 
http://localhost:4000/graphql にアクセス！
<img width="1438" alt="スクリーンショット 2020-03-10 22.17.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407389/7f5a5b4f-1717-e7d0-eb84-95917f85648a.png">
こんな画面が出たらうまく立ち上がっています。
これはapolloサーバーが提供しているものでGraphQLへのクエリをGUIでテストすることができます。

## クエリを実行してみる
index.jsの↓の部分で設定したQueryを実行してみます。

```javascript
// GrapohQL言語のschemaを使ったconstruct定義
// レスポンスするデータの型を設定しておく
const typeDefs = gql`
    type Query {
        firstQuery: String
    }
`
// schemaごとに取得ロジックを設定していく 
const resolvers = {
    Query: {
        firstQuery: () => "Hello,world!",
    },
}
```

GUIの左側のエディタに以下の通り書いて実行してみましょう。

```
{
  firstQuery
}
```
右側の実行結果画面にこのように表示されればデータの引き出し成功です。

```
{
  "data": {
    "firstQuery": "Hello,world!"
  }
}
```

## 最後に
少し勉強してみるとGraphQLは決して魔法の言語などではなく、型の定義やデータ取得ロジックを自分でしっかり書いていかなければならないということがわかりました。

しかしながらGETエンドポイントを1つに集約できること、フロント側からの直感的なクエリを実装できること、TypeScriptのようにコード管理を容易にしてくれることなどなど...便利なことに違いはありません！

まだまだ勉強しはじめたばかりなのでこれからどんどん知識を蓄えていきたいと思います！

それでは！