OmniAICreator/Qiita-1.07M huggingface dataset:
新しい Microsft Edge の試し方

# はじめに
Microsoft 社のブラウザ Edge の新しい Ver が試せるようになってもう数か月が経ちましたね。
今更ながら、使ってみて知ったいくつかの機能などについて触れようかと思います。

# インストール
install の仕方に関してはあまり詳しく話さないので、他の記事などを参考にしつつ入れてみてください。
[インストール用のリンク](https://support.microsoft.com/ja-jp/help/4501095/download-the-new-microsoft-edge-based-on-chromium)

# とりあえず起動してみた
個人的にはサクサク動くし使いやすいです。私はこれまで Google Chrome ユーザで Legacy の Edge はあまり使い慣れてなかったのですが、新しい Edge は Chrome と似た使い勝手に感じました。（Edge Legacy のペンで直接 Web ページのメモを作れる機能は結構気に入ってました。）
開発者ツール（windowsであれば F12キー) も使えます。

# 検索エンジンの変更方法
初期設定の検索エンジンは Bing が使用されています。私は別に Bing でも構わないのですが、「宗教上の理由でどうしても○○が良い」と言う方は、
[1]右上の3点のあるメニューボタン
[2]設定
[3]プライバシーとサービス
[4]アドレスバー
の順に画面を進めると以下の画像の場所にたどり着き、検索エンジンを変更できるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/bcde8e57-a699-d89a-75cc-192b8d155f06.png)

# 拡張機能をつかってみた
Chrome でもおなじみであった拡張機能は New Edge でも使えます。先と同様にメニューボタンを押して、「拡張機能」を選びましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/39c68ae3-c560-7ec8-2f03-395aeff72979.png)
こんな感じで、キーボードショートカットを自由に割り振ることもできます。
ついでに、個人的に好みで開発者など関係なく使えそうな拡張機能を 3 つほど紹介しておきます。

- [ワンクリックURL短縮](https://microsoftedge.microsoft.com/addons/detail/kdkfhkkjfbdociajhapijlkhljpailjl)
    - その名の通り URL を短縮してくれる拡張機能
    - ショートカットに登録しといて起動するだけで短縮 URL になる
- [OneNoe Web Clipper](https://microsoftedge.microsoft.com/addons/detail/oogbnpmeihfgnccdnmmlgicknopghhma)
    - Microsoft の純正製品である OneNote に Web ページ全体を画像として保存
    - Edge Legacy であった機能に近いことが可能
    - 画像として読み込むため、リンクなどは無効化されるので注意。
- [Quick QR Code](https://microsoftedge.microsoft.com/addons/detail/ejmdialfkbfpindcfdnlknmpnbbgnpjc)
    - 開いているページへのリンクを QR コードにしてくれる拡張機能
    - 画像として保存などしたい場合はその後別タブで開いてあげる
    - SNS などのページを紹介する時によく使います

他の拡張機能は[このサイト](https://microsoftedge.microsoft.com/addons/category/EdgeExtensionsEditorsPick?hl=ja-JP)から探してみましょう。

# Collection
ブックマークのようでブックマークでない、Collection 機能の紹介です。
右上にあるコレクションボタンか、メニューボタン→コレクション でも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/42780b3c-8fb3-4adc-9de4-36b8442c671f.png)

Collection を1つ選ぶと画像のように、そのcollection内に保存んしたURLやメモが出てきます。残ながら現在はcollection何に階層構造にして別のcollectionを入れることはできなさそうですね。

また、面白い機能として、全部コピーや、外部へのエクスポートがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/349af15a-5c17-d9b8-751b-cb44079a0464.png)

「全部コピー」は、複数の URL を他の人に紹介する時なんかに、一括して共有できるのが便利かなと感じました。「全部開く」は良く見ますが全部コピーはあまり見ない気もしますね。
ちなみに、「Excel に送信」を選ぶとこんな感じでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/c4c8f0e5-ea06-2890-5cc1-0c0670e6cf82.png)

OneDrive 上に保存されていますね。directoryを掘り下げたcollection機能のがないのは、このエクスポート機能もなんらかの影響を与えているかもしれないですね。知らないですけど。

# もっと色々ありそう
ぱっと思い浮かんだ機能はある程度ここに書いてみましたが、もっと色んなことができるんだろうかと思います。追跡防止機能なんかもありますが、私はこれは最初に設定してから変更してないので、参考になるようなことは特に言えそうにないです。**逆に、おすすめの機能や、拡張機能があれば教えていただきたいです！**ぜひ、いろいろな機能を使って快適なブラウザライフを送ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/65388c0e-d807-90da-0e51-4e1962b368cd.png)
MySQL 文字を含む数値列を数値順に並び替える

## 概要

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">文字列のカラムをちゃんと数字順でorder byするには、、、キャスト、、、？_(:3」∠)_<br><br>C1<br>C10<br>C100<br>C12<br>C13</p>&mdash; mell (@mell_1022) <a href="https://twitter.com/mell_1022/status/1257561652003663873?ref_src=twsrc%5Etfw">May 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

困っている人がいたので助けたいなと思いました。

## テーブル

```sql
CREATE TABLE company (
  company_code VARCHAR(255)
);

INSERT INTO company
VALUES
  ('C1')
  , ('C10')
  , ('C100')
  , ('C12')
  , ('C13')
;
```

## 並び替える

```sql
SELECT company_code FROM company ORDER BY company_code;

C1
C10
C100
C12
C13
```

普通に並び替えすると文字列として並び替えてしまいます。

## 数値として並び替える

```sql
SELECT company_code FROM company ORDER BY LENGTH(company_code), company_code;

C1
C10
C12
C13
C100
```

数値として並び替えてくれます。
LENGTH 関数を使って、まずは文字数で並び替えてあげると上手くいきます。

## 参考

- https://www.dbonline.jp/mysql/function/index29.html
Swift：NSNibでCustom Viewを取得

- `CustomView.xib`を作る
- `CustomView.swift`を作ってCustomView: NSViewクラスを作る
- xibのViewのCustom ClassにCustomViewを設定する

```swift:読み込み方
let nib = NSNib(nibNamed: "CustomView", bundle: Bundle.main)!
var topLevelArray: NSArray? = nil
guard
    nib.instantiate(withOwner: nil, topLevelObjects: &topLevelArray),
    let results = topLevelArray as? [Any],
    let item = results.last(where: { $0 is CustomView }),
    let customView = item as? CustomView else {
        // failed to load
        return
}
customViewゲット
```

```swift:CustomViewの例
class CustomView: NSView {
    
    @IBOutlet weak var label: NSTextField!
    @IBOutlet weak var imageView: NSImageView!
    
    // 初期化はここで行う
    override func awakeFromNib() {
        super.awakeFromNib()

        label.stringValue = "Hello World"
        imageView.image = NSImage(imageLiteralResourceName: "Sample")
    }
    
}
```
Ubuntu 20.04 Server インストールとディープラーニング設定

タイトルの通りです。

LXCのコンテナ内からディープラーニングする場合は [ホスト側での作業](https://qiita.com/kakinaguru_zo/items/5ed24876656d047de465#%E3%83%9B%E3%82%B9%E3%83%88%E5%81%B4%E3%81%A7%E3%81%AE%E4%BD%9C%E6%A5%AD) を行った後に、コンテナ内で下記の作業を `apt-get install nvidia-headless-440` を除いて行うとよい。

# インストール
1. http://cdimage.ubuntu.com/ubuntu-server/focal/daily-live/current/focal-live-server-amd64.iso からインストールDVDをダウンロードし、USBスティックかDVDに焼く
2. インストーラーで日本語を選べないが、キーボードの配置を選ぶ項目が最初から２番めくらいにあるため必ず「Japanese」を選ぶ。そうじゃないと後で辛い。それ以外はデフォルトの選択肢を選んでおけばよい。以下の作業は全部rootで行う（sudoを使うなど）

# サーバー起動後の設定

```config:/etc/apt/apt.conf.d/00myconf
APT::Default-Release "focal";
APT::Install-Recommends 0;
APT::Get::Purge 1;
```

3. 余計なパッケージが入らないように上記のファイルを作る
1. 時刻（タイムゾーン）がおかしいので　`dpkg-reconfigure tzdata` でタイムゾーンを設定する
2. (内蔵の時計が日本時間ではなくUTCなら `timedatectl set-local-rtc true` する)
4. focal-proposed がデフォルトで有効になっているので `/etc/apt/sources.list.d/proposed.list` を編集する。またfocal-backportsも有効なので、要らなければ `/etc/apt/sources.list` を編集する。
5. `/etc/fstab` を編集してマウントオプションに `noatime,lazytime` を付けておくとアクセスが少し速くなる。仮想環境で動作しているなら `discard` を付けても良い
6. 言語パックが全く入っていないので `apt-get install language-pack-en language-pack-ja` でインストールする
7. いらないパッケージ（ cloud-guest-utils
cloud-init	
cloud-initramfs-copymods
cloud-initramfs-dyn-netconf
eatmydata	
lxd-agent-loader
plymouth
plymouth-theme-ubuntu-text
snapd など）を `apt-get purge` で削除する。その後に `apt-get --purge autoremove` する

# NVIDIA ドライバなどのインストール
1. GUIを用いずNVIDIA GPUを用いた計算だけサーバーにさせる場合 `apt-get install nvidia-headless-440` をインストールする。GUIも用いる場合代わりに `nvidia-driver-440` をインストールする。440 よりも新しいドライババージョンが必要なら https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa から準公式ドライバーをインストールする。NVIDIAのウェブサイトから持ってきては絶対にいけない
2. `nvidia-smi` は　`apt-get install nvidia-utils-440` で入る。ドライバのバージョンと揃えること

# Python3 の最低限のインストール
1. `apt-get install python3-pip python3-setuptools python3-wheel python3-numpy python3-yaml python3-six python3-future python3-requests python3-matplotlib python3-pil python3-h5py python3-graphviz python3-pydot`

# Pytorch インストール
PyTorch は内部にCUDAライブラリなどを含みGPUがある場合も無い場合も同じパッケージで動作するので `pip3 install torch torchvision` とすればよい

# TensorFlow インストール
## CUDA ライブラリインストール
Google のTensorflowは内部にCUDAライブラリを含んでいないため、動作させるためには自分でCUDAライブラリをインストールする必要がある。TensorFlow 2.1, 2.2あたりはCUDA 10.1 をインストールする必要があり、たまたま Ubuntu 20.04 の標準アーカイブに入っているから `apt-get install nvidia-cuda-dev libgomp1` とすればよい（libgomp1 はtensorflowが用いる）

## libcudnn のインストール
1. `wget https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/libcudnn7_7.6.5.32-1+cuda10.1_amd64.deb`
2. `dpkg -i libcudnn7_7.6.5.32-1+cuda10.1_amd64.deb`

## TensorFlow が依存するPythonパッケージのインストール
`apt-get install  python3-scipy  python3-sklearn python3-skimage python3-opencv   python3-protobuf python3-termcolor python3-wrapt python3-werkzeug  python3-markdown python3-google-auth python3-cache-tools python3-requests-oauthlib`

## TensorFlow のインストール
`pip3 install tensorflow-gpu`
ExpressのAsync Errorのハンドリング

## 問題点: `async`でリクエストハンドラを定義して処理中に例外が発生してもハンドリングできない

たとえば、`http://localhost:3333/notfoundroute`のように存在しないルートにアクセスしたら、`ステータスコード:404`、ボディコンテンツに`Route not found`を返したい場合において、以下のコードを実装したとする。

```ts
import express, { Request, Response, NextFunction } from "express";

const app = express();

app.get("/hi", (req, res) => {
  res.send("Say hi");
});

// 問題の箇所
// ここで例外を発生させる
app.get("*", async (req, res) => {
  throw new Error("Route not found");
});

// エラーを扱うためのハンドラ
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  return res.status(404).send(err.message);
});

app.listen(3333, () => console.log("Listenin on port 3333"));
```

**しかし、実行結果としては、レスポンスが返ってこない**。

```
curl -v localhost:3333/notfoundroute
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3333 (#0)
> GET /notfoundroute HTTP/1.1
> Host: localhost:3333
> User-Agent: curl/7.64.1
> Accept: */*
>
```

サーバ側のログ出力も以下のようになっていて、Promiseを上手く扱えていない。

```
(node:11743) UnhandledPromiseRejectionWarning: Error: Route not found
...
(node:11743) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11743) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```

## 解決策1: `next`で例外をラップする。

問題の箇所を以下のように変更する。

```ts
...

app.get("*", async (req, res, next) => {
  next(new Error("Route not found"));
});

...
```

実行結果は、期待した結果が得られている。

```
curl -v localhost:3333/notfoundroute
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3333 (#0)
> GET /notfoundroute HTTP/1.1
> Host: localhost:3333
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 15
< ETag: W/"f-f4JcZAomq7bAiiL2cdorz+qCRSw"
< Date: Tue, 05 May 2020 07:00:15 GMT
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
Route not found* Closing connection 0
```

## 解決策2: `express-async-errors`パッケージをインポートする。

必要なパッケージをインストールする。

```
yarn add express-async-errors
```

問題の箇所は変更しなくてもよいが、`express-async-errors`をインポートする。

```ts
import express, { Request, Response, NextFunction } from "express";
import "express-async-errors";
...

app.get("*", async (req, res) => {
  throw new Error("Route not found");
});

...
```

こちらも実行結果は、期待した結果が得られている。

```
curl -v localhost:3333/notfoundroute
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3333 (#0)
> GET /notfoundroute HTTP/1.1
> Host: localhost:3333
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 404 Not Found
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 15
< ETag: W/"f-f4JcZAomq7bAiiL2cdorz+qCRSw"
< Date: Tue, 05 May 2020 07:00:15 GMT
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
Route not found* Closing connection 0
```
Visual Studio CodeによるSpring Boot2 Webアプリ開発　HelloWorld作成編

#はじめに
Visual Studio CodeでSpring Boot2のWebアプリ開発をしていきます。
以前[こちら](https://qiita.com/t_skri/items/24d0d353771735b453f7)で作成したHelloWorldのSpring Boot版です。

#開発環境構築
[こちら](https://qiita.com/t_skri/items/b16cd5a8868398ca0fc2)を参考に開発環境を構築して下さい。
Maven、Tomcatは不要です。
拡張機能の「Spring Boot Extension Pack」を追加します。
![springex.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/ecf34820-40e7-bcc0-0936-a7c22fb48878.jpeg)

#環境
OS:Windows 10 Pro 64bit
Editor:Visual Studio Code 1.44.2
JDK:AdoptOpenJDK 11.0.6+10 x64

#ひな型作成
Visual Studio Code上でも出来ますが、spring initializr([https://start.spring.io/](https://start.spring.io/))でも作成出来ます。
今回はこの様にしました。
![springinit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/92f24b66-ab86-f959-cd07-83064af142f7.jpeg)

作成したひな型を「D:\JAVA\Project」に展開します。

#Controllerの作成
「D:\JAVA\Project\bootSample1\src\main\java\com\example\bootSample1\web\controller」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

##RootController.java

```java:RootController.java
package com.example.bootSample1.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RootController {

    @GetMapping("/")
    public String root() {
        // "redirect:"を先頭につけるとリダイレクトになる
        return "redirect:hello/index";
    }

}
```

##HelloController.java
```java:HelloController.java
package com.example.bootSample1.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/hello")
public class HelloController {

    @GetMapping("/index")
    public String indexGet() {
        return "hello/index";
    }
    
}
```

#Viewの作成
「D:\JAVA\Project\bootSample1\src\main\resources\templates\hello」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

##index.html

```html:index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Hello World</title>
    </head>

    <body>
        <h1>Hello World</h1>
    </body>
</html>
```

#動作確認
「F5」キーを押して実行します。
[http://localhost:8080/](http://localhost:8080/)
にアクセスして下さい。
自動で[http://localhost:8080/hello/index](http://localhost:8080/hello/index)にリダイレクトされることを確認して下さい。

以下のページが表示されればOKです。
![springbootHello.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/a0a60b19-13c3-ce21-e442-af3bbdb06c7f.jpeg)

#まとめ
ControllerとViewは前回の非Bootのサンプルと全く同じです。
前準備がいらないのがBootの便利なところです。
Jenkins+KubernetesでPodの起動に失敗する場合、「Inbound TCP Agent Protocol/4 (TLS encryption)」のチェックが外れているか確認する


# エラー現象
以下のようにJenkinsジョブでPodの生成まで行われるが、
ジョブの実行にはいかず、延々とPod生成が繰り返し行われる。

```shell
Created Pod: default/sample-app-7z8w4-7gqpr
[Normal][default/sample-app-7z8w4-7gqpr][Scheduled] Successfully assigned default/sample-app-7z8w4-7gqpr to caltago
[Normal][default/sample-app-7z8w4-7gqpr][Pulling] Pulling image "sample/app"
[Normal][default/sample-app-7z8w4-7gqpr][Pulled] Successfully pulled image "sample/app"
[Normal][default/sample-app-7z8w4-7gqpr][Created] Created container scrapy
[Normal][default/sample-app-7z8w4-7gqpr][Started] Started container scrapy
[Normal][default/sample-app-7z8w4-7gqpr][Pulled] Container image "jenkins/jnlp-slave:4.0.1-1" already present on machine
[Normal][default/sample-app-7z8w4-7gqpr][Created] Created container jnlp
[Normal][default/sample-app-7z8w4-7gqpr][Started] Started container jnlp
Created Pod: default/sample-app-7z8w4-b0mzh
[Normal][default/sample-app-7z8w4-b0mzh][Scheduled] Successfully assigned default/sample-app-7z8w4-b0mzh to caltago
[Normal][default/sample-app-7z8w4-b0mzh][Pulling] Pulling image "sample/app"
[Normal][default/sample-app-7z8w4-b0mzh][Pulled] Successfully pulled image "sample/app"
[Normal][default/sample-app-7z8w4-b0mzh][Created] Created container scrapy
[Normal][default/sample-app-7z8w4-b0mzh][Started] Started container scrapy
[Normal][default/sample-app-7z8w4-b0mzh][Pulled] Container image "jenkins/jnlp-slave:4.0.1-1" already present on machine
[Normal][default/sample-app-7z8w4-b0mzh][Created] Created container jnlp
[Normal][default/sample-app-7z8w4-b0mzh][Started] Started container jnlp
Created Pod: default/sample-app-7z8w4-08cp2
```

# 原因
JenkinsSlave設定の「Inbound TCP Agent Protocol/4 (TLS encryption)」が未チェックになっていたため。
(どうもJenkinsのUpdateで引き継がれなかったっぽい?)

## kubectl logs

```shell
INFO: Server reports protocol JNLP4-connect not supported, skipping
May 05, 2020 6:49:46 AM hudson.remoting.jnlp.Main$CuiListener error
SEVERE: The server rejected the connection: None of the protocols are enabled
java.lang.Exception: The server rejected the connection: None of the protocols are enabled
        at hudson.remoting.Engine.onConnectionRejected(Engine.java:825)
        at hudson.remoting.Engine.innerRun(Engine.java:767)
        at hudson.remoting.Engine.run(Engine.java:518)
```

## エラー発生時の設定状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46533/c8fdfada-961e-8195-d0bd-f0d066648676.png)

## エラー解決時の設定状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46533/54b9fb37-ddab-fe16-8e99-1c8f48f782dd.png)
Flaskのデータベースの設定

# はじめに

ここでは、Flaskのデータベース関連の設定の基本について解説します。
データベースは、SQLiteを利用するものとします。


# スキーマの設定

テーブルの定義は以下のようにします。

```sql:schema.sql
DROP TABLE IF EXISTS user;

CREATE TABLE user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT UNIQUE NOT NULL,
    password TEXT NOT NULL
);
```



# データベース用の関数

データベース関連の関数は以下のようになります。

```python:db.py
import sqlite3

import click
from flask import current_app, g
from flask.cli import with_appcontext


def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect(
            current_app.config['DATABASE'],
            detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row

    return g.db


def close_db(e=None):
    db = g.pop('db', None)

    if db is not None:
        db.close()


def init_db():
    db = get_db()

    with current_app.open_resource('schema.sql') as f:
        db.executescript(f.read().decode('utf8'))


@click.command('init-db')
@with_appcontext
def init_db_command():
    """Clear the existing data and create new tables. """
    init_db()
    click.echo('Initialized the database.')


def init_app(app):
    app.teardown_appcontext(close_db)
    app.cli.add_command(init_db_command)
```


# まとめ

ここでは、データベース設定の基本について解説しました。
次回は、アプリケーションの設定について取り上げる予定です。
PyODE チュートリアル 1

###PyODEのサンプル実行例
[本家 PyODE 様サイト](http://pyode.sourceforge.net/) の「Tutorial 1」を実行してみました。

・[「Tutorial 2」の実施記事はこちら](https://qiita.com/emuai/items/63be99c31db4aa9dfbb2)
・[「Tutorial 3」の実施記事はこちら](https://qiita.com/emuai/items/840c776f146ac12ac416)


この「Tutorial 1」は１個のオブジェクトに初速を与えて様子を見るだけです。
「PyODEの動作確認」くらいの意味合いで、リザルト表示も標準出力への値表示だけです。

本記事では、Matplotlib でプロット表示を追加してみました。

コード（全部）
---
↓ 本家のコードにMatplotlib プロット呼び出しと、プロット用配列作成を足したものです

```python:Tutorial-1_plot.py
# pyODE example 1: with MPL-plot
    
import ode

# Create a world object
world = ode.World()
world.setGravity( (0,-9.81,0) )

# Create a body inside the world
body = ode.Body(world)
M = ode.Mass()
M.setSphere(2500.0, 0.05)
M.mass = 1.0
body.setMass(M)

body.setPosition( (0,2,0) )
body.addForce( (0,200,0) )

# Do the simulation...
total_time = 0.0
dt = 0.04

import numpy as np
nt = 100
txyzuvw = np.zeros( (7,nt+1) )
tn=0
while total_time<2.0:
    x,y,z = body.getPosition()
    u,v,w = body.getLinearVel()
    print( "%1.2fsec: pos=(%6.3f, %6.3f, %6.3f)  vel=(%6.3f, %6.3f, %6.3f)" % \
          (total_time, x, y, z, u,v,w) )
    if tn <= nt:
        txyzuvw[0][tn]=total_time
        txyzuvw[1][tn]=x
        txyzuvw[2][tn]=y
        txyzuvw[3][tn]=z
        #txyzuvw[4][tn]=u
        #txyzuvw[5][tn]=v
        #txyzuvw[6][tn]=w

    world.step(dt)
    total_time+=dt

    tn += 1

end_tn = tn

import matplotlib.pyplot as plt
# MPL-Plot 
plt.plot( txyzuvw[0][0:end_tn], txyzuvw[2][0:end_tn], label='Vertical position')
plt.xlabel('time [s]')
plt.ylabel('Vertical position [m]')
plt.savefig('./y.png')

```
↑　20200506:　スタートの位置記録できてなかったの修正

結果
---
　(あらかじめnumpyとmatplotlibをインストールしてください。)
実行すると......
![y.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469875/39957ef4-a6ff-f620-fd6c-321f8337f0c4.png)

↑　このグラフ画像(PNG)がカレントに保存されます。
垂直方向（Y座標）に放りなげた物体の高さの時間変化です。
Flutterのユニットテストで入力と出力にリストを使用してパターンを網羅する

Flutterのユニットテストで入力と出力にリストを使用してパターンを網羅する方法です。
ところでこの「入力と出力にリストを使用してパターンを網羅する」方法の呼び方がわからず、うまくググれません。
なんという名前なんでしょうか？Data Driven Test?

具体的な方法は以下の通り。
入力と出力を一度リストにして、そのリストを比較するという単純なものです。

```dart
bool isOdd(int input) {
  return input % 2 == 1;
}

void main() {
  group('isOdd', () {
    test('pattern', () async {
      final inputs = [0, 1, 23, 42];
      final expects = inputs.map((input) => isOdd(input));
      expect(expects, [
        false, //0
        true, //1
        true, //23
        false, //42
      ]);
    });
  });
}

```

なんだかStreamとexpectAsync*あたりを使ってうまいことやるお作法があるのかもしれませんが、今は理解できなかったので、この方法を使用してテストしています。
https://github.com/dart-lang/test/blob/master/pkgs/test/README.md
AWS Amplify エラー対処 Could not find a declaration file for module './aws-exports'.

# 発生した問題
ファイル上ちゃんと存在するのに。`aws-exports` 見つからないとエラーが出る。
恐らく Typescript のエラーである。

```
Could not find a declaration file for module

    14 | import Amplify from "aws-amplify";
    15 | import "@aws-amplify/ui-vue";
  > 16 | import awsExports from "./aws-exports";
       |                        ^
    17 | Amplify.configure(awsExports);
    18 | 
    19 | new Vue({
```

#対処法

`aws-exports` を ts ファイルにしてあげれば良い。

ファイル名
`aws-exports.ja` → `aws-exports.ts` 

あと、キャメルケースにしないと怒られるのでケバブケースを使わないように注意


```typescript:キャメルケース
import AwsExports from "./aws-exports";
```


```typescript:ケバブケース
import aws-exports from "./aws-exports";
```
【Ruby・初心者】二次元配列とは・ループを使った処理自分用


##二次元配列とは？
配列の中に配列を作ること。

##Array.newメソッド
配列を作成できる。

###要素が5こ、初期値が1という配列を作成する。

```
n = Array.new(5,1)
p n  # >= [1,1,1,1,1]
```

###

###Array.newメソッドとmapメソッドの組み合わせ
要素が5こ、[7,7,7,7]という配列を要素にする。

つまり、
・要素は5こ。
・配列の中の配列の数が4こ
・配列の中の配列の値は4。

```
 n = Array.new(5).map{Array.new(4,7)}
 p n  #=<[[7, 7, 7, 7], [7, 7, 7, 7], [7, 7, 7, 7], [7, 7, 7, 7], [7, 7, 7, 7]] 
```
※Array.new(5){ Array.new(4, 7) }と.mapを省略することも可能です。

##each_with_indexメソッド

```
enemies = ["スライム", "モンスター", "ゾンビ", "ドラゴン", "魔王"]
enemies.each_with_index do |e,i|
    puts "#{i}番目の#{e}が現れた！"
end
```


##mapメソッド

新しい配列を作るメソッド。

```
numbers = [12, 34, 56, 78, 90]
numbers2 =numbers.map do |item|
    item * 3  #各要素を3倍にして新しい配列を作成する。
end
p numbers2 #>=[36,102,168,234,270]
```
AWSでEC2を作成する

[前回](https://qiita.com/r_saiki/items/573f5b8659152936b912)はVPCを作成したので、次はWebサーバー用にEC2を作成する。
#EC2作成
マネジメントコンソールでEC2を検索。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/c222fe1f-bbcf-caf0-294a-164fe3803ee6.png)
インスタンスメニューからインスタンスの作成を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/b539fa03-bcfc-9f92-00c8-35158d45ea3b.png)

##AMIの選択
最初はAMIを選択する。AMIはAWSが用意しているOSのテンプレートのようなものである。
左側のメニューから、どこからAMIを選択するかを選べる。
今回はクイックスタートのAmazonLinuxを選択する。AmazonLinuxには、AWSを使うにあたって、一通り必要なソフトが入っているらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/a7d17d85-2beb-3a1c-7e7f-9263c899da47.png)

##インスタンスタイプの選択
インスタンスタイプはサーバーマシンのスペックのような感じです。無料枠で使えるt2.microを選択して、インスタンスの詳細の設定を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/d2451027-b7fa-3d50-81cb-248d13b085a1.png)

##インスタンスの詳細の設定
今回は以下のような構成で設定した。

ネットワーク：自分で作成したvpcネットワークを指定
サブネット：自分で作成したpublicなサブネットを指定
自動割り当てパブリックIP：有効に指定
キャパシティの予約：無し
他はデフォルト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/de0b57c1-b19c-da03-6a2a-9d8bde4cbe48.png)
デフォルトのまま。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/6a8d1a73-09be-1514-373c-9ba52d707c83.png)
プライマリIPに前回設定したパブリックネットワークアドレス内のプライベートアドレスを指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/cd4a9fa9-d8e0-2400-55e2-ee7ae453fd15.png)
ストレージの追加を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/b5c1db21-36b8-9b1e-b811-04dfefd1b6d5.png)

##ストレージの追加
デフォルトのまま。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/5dbf8099-a27e-f696-2bf3-136ecf301f6c.png)

##タグの追加
以下の値でタグの追加し、セキュリティグループの設定を選択。
キー：Name
値：Webserver
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/6a1d5686-21a2-d22b-af11-3cf427db61e9.png)

##セキュリティグループの設定
警告が出るが、後でSSHは設定するので、デフォルトのままで確認と作成を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/7aaf9179-4f7f-3a73-0aca-4a0d8e982f78.png)

#EC2起動
作成後の画面で起動ボタンを選択すると、キーペアを求められる。キーペアはインスタンスにアクセスするために使われる。
名前を設定してダウンロードする。
pemファイルがダウンロードされるので、任意の場所に保存する。その後、インスタンスの作成を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/b7a8e195-0c3e-ed8b-595d-865c65fcaac4.png)
起動後画面の一番下のインスタンスの表示を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/0361f4b6-8f73-117a-0a74-acac85a579ed.png)
インスタンスが正常に起動していることを確認！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/4d7c17d2-5507-7823-8af6-14c534fde382.png)
#終わりに
次回はSSHで繋いで、作成したEC2をWebサーバーにするために設定していく！
[SSH接続でEC2に接続する](https://qiita.com/r_saiki/items/cc1d7ed9864ce07501f2#ssh%E6%8E%A5%E7%B6%9A)
ゼロから始めるLeetCode Day16 「344. Reverse String」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day15 「283. Move Zeroes」](https://qiita.com/KueharX/items/edf03e6ac08feeac3198)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

# 問題
[344. Reverse String](https://leetcode.com/problems/reverse-string/)

与えられた配列の文字列を反転させて返すという問題です。
>Example 1:
Input: ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]

>Example 2:
Input: ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]

# 解法

余りにもPythonの組み込み関数に頼ってしまったので簡単なものを列挙しました。

```Python
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        return s.reverse()
# Runtime: 208 ms, faster than 82.72% of Python3 online submissions for Reverse String.
# Memory Usage: 18.3 MB, less than 5.81% of Python3 online submissions for Reverse String.
```


```Python
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        return s[::-1]
```

```Python
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        return ''.join(reversed(list(s)))
```

Pythonの組み込み関数は便利ですね。
もっと良い解答があれば追記します。
【WordPress】環境構築から各機能の実装

# まずはここから wordpressのインストール
エックスサーバーでWordPressを始める8ステップ
https://saruwakakun.com/html-css/wordpress/xserver

1時間で出来る最強のWordPress環境構築
https://qiita.com/ryuta69/items/dbb0db5cf7099b7a7cc4

# メールの設定
指定したSMTPサーバーを使ってメールを送信できるようにするWP Mail SMTPプラグイン
https://design-plus1.com/tcd-w/2019/03/wp-mail-smtp.html

# 問合せ機能 Contact Form 7
【簡単】Contact Form 7（WordPressお問い合わせフォーム設置）の使い方徹底解説
https://www.kagoya.jp/howto/wordpress/contact-form-7/

【公式ドキュメント】Contact Form 7
https://contactform7.com/ja/

Contact Form 7で確認画面と完了画面（サンクスページ）を追加する方法
https://haniwaman.com/contact-form-7-add-page/

# 投稿とは別フォーマットの投稿 カスタム投稿タイプ
## カスタム投稿タイプとは
自分で投稿タイプをカスタマイズできる機能です。

例えば、通常の投稿はブログとして使い、それ以外にも「商品の紹介」や「ポートフォリオ」、「更新情報」などテンプレートとしてカスタム投稿タイプを利用することができます。

つまり、通常の投稿記事とは形式や目的の違う記事を書きたい場合に効果的な機能です。

WordPressでカスタム投稿タイプを作成する方法【初心者向け】 より引用
https://techacademy.jp/magazine/2842

---
WordPressでカスタム投稿タイプを作成する方法【初心者向け】
https://techacademy.jp/magazine/2842

カスタム投稿タイプでカテゴリーとタグを追加して一覧でも表示させる方法
https://296.co.jp/article/52551120182310

# オリジナルテンプレート デザイン当て込み
【テーマ自作】WordPress オリジナルテーマの作り方と基本
https://webst8.com/blog/wordpress-theme-howto-make/

WordPress Popular Postsで人気記事を表示する方法
https://bazubu.com/how-to-add-popular-posts-23487.html

WordPress：前後記事へのナビゲーションにアイキャッチ画像を表示
http://pressstocker.com/postnavi-eyecatch/

非推奨のquery_postsを使わずget_postsでカスタム投稿タイプの一覧を表示させる
https://irec.jp/wordpress/custom-post-type/get_posts-custom-post/

---
こちらもどうぞ
【Laravel】環境構築から各機能の実装
https://qiita.com/SyogoSuganoya/items/8a73167566dd7b36de26
Chromebook 上で Cloud Foundation Toolkit (CFT) のインストール

Chromebook の Linux ターミナルを使って、[Cloud Foundation Toolkit (DM)](https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/dm/docs/userguide.md#installing-the-cft) による Infrastructure as Code 環境セットアップに関する備忘録。
# CFT best practice
* config ファイルは、まとめて一つにするのではなく、コンポーネントごとに分けて作っておく

# Chromebook Linux ターミナル上での作業
複数の config ファイル (yaml) を指定して、依存関係に従い順番に適用されるようにするには、個別の gcloud deployment-manager コマンドで都度実行するのではなく、cft を使うのがベターということで、まずは [CFT をインストール](https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/dm/docs/userguide.md#toolkit-installation-and-configuration)する。

手順に従いインストールすすめようとするといきなり以下のようなエラーがでる。

```ruby:erro
$ sudo make cft-prerequisites
python3 -m pip install -r requirements/prerequisites.txt
/usr/bin/python3: No module named pip
Makefile:26: recipe for target 'cft-prerequisites' failed
make: *** [cft-prerequisites] Error 1
```

リンク先のインストールガイドには *python2.7* と書いてあるが、最新のコードでは python3 を使うことになっているので、Chromebook linux ターミナルで python3 の PIP をインストールする。

```ruby:teminal
sudo apt install python3-venv python3-pip
```
【UE4：BehaviorTree】自作Service追加

C++でService追加しようとして
BTService継承したクラスを作成したらなんか怒られてエラー出た

```:error
"public: virtual void __cdecl IGameplayTaskOwnerInterface::OnGameplayTaskActivated(class UGameplayTask &)"
...
```

ググっても日本語記事出てこないUE4辛い

プロジェクト名（○○.Build.cs）で生成されているファイルにモジュール追加する必要があるらしい

```
PublicDependencyModuleNames.AddRange(new string[]
{
　...
　"AIModule", ←これ
　"GameplayTasks",　←これ
});
```

ビルドしなおしてエラー消えました
dockerのエラーでdocker再起動で直ったケース


##dockerのエラーでdocker再起動で直ったケース

メモ書きとして残しておきます。

このエラーはdockerの再起動で直った

```
 $ docker-compose up -d
Creating network "portal_default" with the default driver
Creating php-test2 ... 
Creating db-test2  ... 

ERROR: for php-test2  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for db-test2  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for php  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

ERROR: for db  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
```

こちらもdockerの再起動で直った

```
[portal]
 $ docker-compose up -d
Creating network "portal_default" with the default driver
Creating db-test2 ... 
Creating db-test2  ... error
WARNING: Host is already in use by another container

ERROR: for db-test2  Cannot start service db: driver failed programming external connectivity on endpoint db-test2 (96997666310c6553455669041dad035c75833a9cfCreating php-test2 ... done
Creating nginx-test2 ... done

ERROR: for db  Cannot start service db: driver failed programming external connectivity on endpoint db-test2 (96997666310c6553455669041dad035c75833a9cfa836ebe6179f7c2570b6d3f): Bind for 0.0.0.0:3306 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
```
Nuxt.js + axios – 静的JSONファイルでAPIレスポンスをモックする例 (  static json file like mock )  ( #Nuxt #Vue )

モック用のライブラリなど入れずに手軽に json ファイルを使いたい場合


static/users.json

```json
[
  {
    "id" : 1,
    "name": "Alice"
  },
  {
    "id" : 2,
    "name": "Bob"
  },
  {
    "id" : 3,
    "name": "Carol"
  }
]

```


pages/axios-assets-json.vue


```vue
<template>
  <div>
    <h1>
      assset API
    </h1>
    <h2>Users</h2>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.id }} - {{ user.name }}
      </li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  async asyncData({ $axios }) {
    const users = await $axios.$get('/users.json')
    // OR
    // const users = await $axios.$get('http://localhost:3000/axios-assets-json')
    return { users }
  }
}
</script>

```

http://localhost:3000/axios-assets-json

![image](https://user-images.githubusercontent.com/13635059/80937567-a1006500-8e10-11ea-9ec7-8bc97cee737a.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3136











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Rails5】Devise + OmniAuth のTwitter認証で「OAuth::Unauthorized」エラーの対処法

##「OAuth::Unauthorized」エラーに遭遇

こちらの記事を参考にDeviseとomniauth-twitterの設定中にエラーに遭遇。

参考
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)


```text:開発環境
ruby > 2.6.5
rails > 5.2.4.2
devise > 4.7.1
```

一通り設定後、localhostのログイン画面で「Sign in with Twitter」をクリックするとエラーが。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628830/6d89a494-cfa3-a7ca-5160-fd96041c88d2.png)


##原因は「Callback URL」

`OAuth::Unauthorized`でひたすらググると
「Callback URL」に関する記事が複数ヒット。
どうやらTwitterのAPI仕様変更があったらしく、Callback URLを書き換える必要があるらしい。

アプリ側のCallback URLをこのように変更。

```text:Callback_URL
http://192.168.10.2:3000/users/auth/twitter/callback
http://localhost:3000/users/auth/twitter/callback
```
なぜ２つ必要なのかわかりませんが、今回はこれで動きました。


##まとめ
Twitterに限らず、APIは仕様変更が頻繁に行われるので要注意ですね。
ローカル環境ではうまく動きましたが、本番環境に移行するときはまたエラーを吐くのでは？とドキドキしています。
Netlifyのキャッシュのデフォルト設定とその変更方法

Netlifyのキャッシュについて詳しく調べる機会があったのでメモ。このページに全部書いてあった。[Better Living Through Caching](https://www.netlify.com/blog/2017/02/23/better-living-through-caching/)

## Netlifyのキャッシュのデフォルト設定
自分で何か設定をしなくても、Netlify側でデフォルトで設定されているキャッシュ設定がある。レスポンスヘッダを見れば一目瞭然だが、設定されているのは以下。

-  Cache-control
-  ETag

それぞれについて見ていく。

### Cache-control

デフォルトは```public, max-age=0, must-revalidate```となっている。これの意味するところは、

- public: キャッシュ可能なコンテンツであることを示す
- max-age: キャッシュが有効とみなされる期間
- must-revalidate: リクエストのたびにオリジンサーバーにキャッシュコンテンツの陳腐化を確認する必要がある

この設定により、**ブラウザはコンテンツをキャッシュすることはできるが、そのキャッシュの保存期間に関わらず、利用してよいかどうかを毎回サーバーに問い合わせて確認する必要がある**という設定になる。```no-store```に近い感じもするが、こちらはキャッシュ自体を許可しない。

毎回サーバーに問い合わせるならキャッシュの意味なくね？と思うかもしれないが、キャッシュが有効とみなされた場合はコンテンツをダウンロードする必要がなく、レスポンスボディをほぼ0にできる（ステータスは304 Not Modified）。

コンテンツのダウンロード時間はファイルのサイズによってはかなり長くなるので、このキャッシュ戦略は非常に意味がある（実際、体感的にも大きな差がある）。

参考：[HTTP キャッシュ](https://developer.mozilla.org/ja/docs/Web/HTTP/Caching)

### ETag
では、どのような条件下でキャッシュの利用が許可されるのか、それを判断するのがETagである。
ETagはコンテンツのなんらかのパラメータにハッシュ関数を適用した値で、バージョン識別子のようなもの。
ETagが同じであればそのコンテンツは変更されていないことを意味するし、異なっていればコンテンツが更新されたことを意味する。
NetlifyサーバーからのレスポンスヘッダにはこのETagが含まれており、次回以降のリクエスト時にIf-None-MatchフィールドにETagの値をセットして送信する。

Netlifyでは、上記のCache-controlとETagの設定を組み合わせることにより**コンテンツが更新（デプロイ）されるまで、ブラウザキャッシュを利用する**というキャッシュ戦略がデフォルトで設定されていることになる。

参考：[ETag](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/ETag)

## キャッシュ戦略の変更

上記のキャッシュ設定を変更したい場合は、リポジトリにカスタムヘッダを指定するファイルを置くことで対応する。```_headers```という名前のファイルを作成し、公開ディレクトリの直下に配置すればOK。

参考：[Custom headers](https://docs.netlify.com/routing/headers/#syntax-for-the-headers-file)

### キャッシュ設定の仕様（不具合？）

Branch DeployやPull Request作成時にプレビュー環境のビルド&デプロイが走ると、Production環境のキャッシュがクリアされる。Production環境のレスポンスに含まれるETagの値は変更されておらず、リクエストヘッダのIf-None-Matchの値とも一致しているにの関わらず、200 OKでレスポンスが返ってくる。プレビュー環境がビルドされる際に、サーバー側に保存されている他の環境のETagもクリアされている？
Ruby on Rails チュートリアル 第２章②

○この記事の要点
「第2章　Toyアプリケーション」の途中から最後まで実施内容メモ
思ったことなどのメモ

○内容
■モデルの作成続き
（１）scaffoldジェネレータを利用したマイクロポストリソースの作成
　rails generate scaffold Micropost content:text userid:integer
（２）データベースのマイグレート
　rails db:migrate
ここまですると、routesファイルが更新され、マイクロポストのWebアプリケーションが動作する
（３）contentに文字数制限を設定する
　app/models/micropost.rb
  validates :content, length: { maximum: 140 }
（４）Micropostsとユーザの紐づけ
　１．app/models/user.rb　に　has_many :microposts
　※ユーザは複数のマイクロポストを持っている
　２．app/models/micropost.rb　に　belongs_to :user
　※マイクロポストはユーザーに所属する

Railsのconsoleでユーザーとマイクロポストの関連付けを確認するところでうまくいかなかった。

```ruby:エラー
2.6.3 :009 > first_user.microposts
  Micropost Load (0.3ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ?  [["user_id", 1], ["LIMIT", 11]]
Traceback (most recent call last):
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: microposts.user_id: SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ?)
```

対処：micropostsにuser_idなんてカラムがない。ということだったので、DBのマイグレートでスペルミスってたっぽい。よく見たら、micropostsのuser_id⇒useridで作成していた。削除方法をググって再作成。。。

削除：rails destroy scaffold "Micropost"
再作成：
rails generate scaffold Micropost content:text user_id:integer
rails db:migrate
rails servere

Webアプリ起動したらエラー

```ruby:エラー
ActiveRecord::PendingMigrationError
```
キーワードでググったら、rails db:migrate:reset　しろとのこと。
実行後、rails db:migrate　を実行したら
Webページが開いた！登録したユーザなどは消えた。rails db:migrate:resetで消えるらしい。あと、141文字以上のバリデーションチェックとかも消えた

Railsのconsoleでの
first_user.microposts　結果も正しく返ってきた。

■継承の階層（説明）
UserモデルとMicropostモデルはいずれも、ApplicationRecordというクラスを継承している。
UsersコントローラとMicropostsコントローラはいずれもApplicationControllerを継承している。
継承により、そのクラスファイルがよく利用する標準の機能を別途用意せずにも役割をこなしてくれる。

```ruby:継承
# モデル
class User < ApplicationRecordclass
class Micropost < ApplicationRecord
#コントローラ
class UsersController < ApplicationController
class MicropostsController < ApplicationController
```
■アプリケーションのデプロイ
$ git status
$ git add -A
$ git commit -m "Finish toy app"
$ git push
$ git push heroku
$ heroku run rails db:migrate

HerokuサーバでWebページが動作することを確認して終了。

■ScaffoldでWebアプリを作成した際の良い点、悪い点
良い点：簡単。雰囲気を味わえる。
悪い点：機能が少ない。セキュリティの仕組みが全くない


■感想
・スペルミスというあるあるの発生で少し時間がかかった。削除から再実行を自分で調べて実施したが、マイグレートのところで少し躓いた。マイグレートでは、バージョン管理？的なことをやっているっぽく、整合しなくなるとエラーになるようだ。
・ここにきて少しSQLを感じた。今回だと、ユーザテーブルとマイクロポストテーブルをuser_idでリレーションしているが、外部キーを設定した記憶がないが、自動で設定されている？
・最後は継承。Java時代から便利だと思っていたが、Railsでももちろん使われている。遠い将来全てが継承でコーディングしなくてよくなる未来が来る！？
CocoaPodsを使う

Swiftでcocoapodsを使う機会があったので、後のために忘備録として。。

##cocoapod のインストール
ターミナルを開き
`$ sudo gem install cocoapods`

##cocoapod をプロジェクトに追加する
`pod init`

##cocoapodに追加するライブラリを追加する
`$ vi Podfile`
で追加するライブラリをファイル内に記入
```記入例： pod 'ライブラリ名'```

`$ pod install`

##インストール時の注意点
ライブラリによっては、warninngが出ることがあるので、バージョン指定がある場合は、必ずpod install前に記入すること。
NSKeyValueObservationはinvalidateしよう！

## 経緯
`AVPlayer`の`rate`をKVOで監視する実装を行い、`NSKeyValueObservation`はメンバ変数に持たせました。
解放は、`NSKeyValueObservation#invalidate`に下記のコメントがあったため、メンバ変数を持っているクラスの解放に任せることにしました。

invalidate() will be called automatically when an NSKeyValueObservation is deinited

ところが、リリースしてみると、スタックトレースに下記を含むようなクラッシュが多発しました。
開発時やテストフライトでの動作確認も行っておりましたが、再現はできませんでした。

KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED

## 解決
Appleのいうことは信じずに、メンバ変数を持っているクラスの`deinit`で`NSKeyValueObservation#invalidate`を明示的に行うように変更したところ、発生しなくなりました。
【Rails】Dockerによる環境構築でビルドする際に出たエラーメモ

##始めに
Docker Composeを使用してRailsの開発環境を構築する際、ビルドコマンドを実行した時点でエラーが出たので、そのメモです。

##環境
Docker for Mac
Docker Eingine : 19.03.8
docker-compose : v3

##エラー箇所
１：Rails開発環境用の作業ディレクトリを作成。
２：ディレクトリ内にRails実行環境用のイメージ作成用のDockerfileの作成と内容の記述。
３：Gemfileの作成と内容の記述。
４：中身が空のGemfile.lockファイルを作成。
５：docker-compose.ymlファイルを作成と内容の記述。
__６：ymlファイルで定義した内容のビルドコマンド実行　⬅︎ココ__

##内容

__実行コマンド__

```
$ docker-compose run web rails new . --force --database=postgresql
```
<br>

__エラー内容__

```
docker.errors.TLSParameterError: 
Path to a certificate and key files must be provided through the client_config param. 
TLS configurations should map the Docker CLI client configurations. 
See https://docs.docker.com/engine/articles/https/ for API details.
[20623] Failed to execute script docker-compose
```
<br>

__解決方法__

```
$ eval $(docker-machine env -u)
```
　　➡︎上記のコマンドを実行し、再度ビルドコマンドを実行すると成功しました。

##まとめ
どうやら、Dockerを起動するには環境変数を一旦デフォルトの状態に戻してから起動する必要があるらしいです。
正直、何故なのかはいまいちわかっていないので課題です。


##参考
http://docs.docker.jp/machine/reference/env.html
https://docs.docker.com/engine/security/https/
https://github.com/docker/for-win/issues/2706
https://gitmemory.com/issue/docker/for-win/2706/490941530
mod_wsgi 500 Internal Server Errorの対処法

#背景
ApacheをDjangoに接続しようとして設定したところ、Internal Server Errorに遭遇する。
![ss19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117020/44bb2709-11c8-808d-497a-4d3747690f70.png)

関連記事：[Django + Apache with mod_wsgi on Windows Server 2016](https://qiita.com/hiro-jp/items/5bdc11dada4e0fccf97f)

#環境
- Windows Server 2016
- Apache 2.4 + mod_wsgi
- Django 3.0

#調査
Apacheのエラーログを見てみる（自環境では`C:\Apache24\logs\error.log`にある）。

```error.log
※日時は邪魔なので消しました。
[wsgi:error] [pid 7288:tid 1272] [client ::1:62535] mod_wsgi (pid=7288): Failed to exec Python script file 'D:/apps/shibtest3/shibtest3/wsgi.py'.
[wsgi:error] [pid 7288:tid 1272] [client ::1:62535] mod_wsgi (pid=7288): Exception occurred processing WSGI script 'D:/apps/shibtest3/shibtest3/wsgi.py'.
[wsgi:error] [pid 7288:tid 1272] [client ::1:62535] Traceback (most recent call last):\r
～～中略～～
[wsgi:error] [pid 7288:tid 1272] [client ::1:62535] ModuleNotFoundError: No module named 'shibtest3'\r
```

⇒ WSGIモジュールが、Djangoアプリ「shibtest3」モジュールを発見できていない（らしい）。

参考：[Apache2 mod_wsgi, 500 Internal Server Error](https://stackoverflow.com/questions/5713689/apache2-mod-wsgi-500-internal-server-error)

#対処法
DjangoアプリへのPATHを通す。

```python:wsgi.py
"""
WSGI config for shibtest3 project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
"""

import os
import sys  # ←追加

from django.core.wsgi import get_wsgi_application

sys.path.append('D:/apps/shibtest3') # ←追加

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'shibtest3.settings')

application = get_wsgi_application()
```

#結果
動いた。
![ss20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117020/b3e396e5-7cde-d0c5-8ecd-39b4a7e03722.png)
Mac でGoogle Public DNSを使ってネット接続を爆速にする方法

#今日のテーマ
Google が提供している無料のパブリックDNSサービス Google Public DNS を使うと、インターネットの接続速度の高速化が見込めるらしいということで導入してみる

###DNSとは？
インターネットでは、相手と通信するときに「IPアドレス」と呼ばれるアドレスを利用する。しかし、IPアドレスは数字だけで構成されているので、人にとってはわかりにくい。そこで、人が覚えやすいものとして考案されたのが「ドメイン名」。ドメイン名（「keichan.com」のような文字列）をIPアドレスと紐付けることにより、ドメイン名がわかれば相手との通信が可能になる。この仕組みを「DNS」（ドメイン・ネーム・システム）と呼びます。

「DNSサーバー」は、ドメイン名をIPアドレスに変換する役割を持つが、利用しているDNSサーバーが遅い（ドメイン名からIPアドレスを検索するのが遅い）場合、それだけ時間がかかってしまう。つまり、「ネットが遅い！」と感じることになるそうな

##ではこのDNSサーバーの部分を改善すればWebサイトの表示が速くなるのでは？

###ということで調べました。

### パブリックDNSサーバー
DNSサーバーは、通常誰に対しても反応するものではないが、パブリックDNSサーバーは誰からの問い合わせにも答えるのが基本であるそうな。そのぶん、その他の**DNSサーバーに比べて非常に高速に処理できるような仕組みを採用しており、ページを開く速度が大きく改善する**ことがあるとのこと。

## これだ！　
### 代表的なパブリックDNSサーバー
無料で利用できるパブリックDNSは数多くあるが、ここでは信頼性の高い代表的なサービスを3つご紹介。
「Google Public DNS」は、Googleが提供するDNSサーバー。設定するIPアドレスは、「8.8.8.8」と「8.8.4.4」になっており覚えやすい。膨大な情報量を持っており、応答速度が高速で安全性が高いのがポイント。
「Cloudflare」は、新興のDNSプロバイダ。アクセス時のIPアドレスなどのログを残さないのが大きな特徴で、非常にセキュアなサービス。また、サーバーの応答速度もトップレベルで、非常に高速なのが魅力のひとつになっている。
「Quad9」は、セキュリティ性能が高いのが大きな特徴のサービス。ウイルスなどを検知して、不正なサイトへのアクセスをブロックするといった機能を利用できるので、安全性を重視するなら利用したい。

## 今回はGoogle Public　DNSが汎用性が高いそうなので導入してみます。

##Mac で Google Public DNS を利用する
「環境設定」 » 「ネットワーク」へと進み、ネットワークサービスが一覧で表示されていると思いますので、Google Public DNS を使いたいサービスを選択し、詳細ボタンをクリックします。

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

###「DNS」のメニューを選択します。
[![Image from Gyazo](https://i.gyazo.com/89876be9e73a4be4042fe7a21083ea51.png)](https://gyazo.com/89876be9e73a4be4042fe7a21083ea51)

「DNSサーバ」欄に
8.8.8.8
8.8.4.4
の2 つのアドレスを追加します。

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

これで設定は完了です。

##きっとこれで表示スピードが改善されているはず

おしまい
golangでkubernetes APIにアクセスする


## 事前条件

- 利用できるkubernetesクラスタがある（参考: [GNU/Linuxにkindを使ってkubernetesをセットアップする](https://qiita.com/yendo0206/items/30a81f51cfc37b4b74e1)）
- goがインストールされている（参考: [GNU/Linuxにgoenvでgolangをセットアップする](https://qiita.com/yendo0206/items/33689cccd926e0162a2a)）
  - go modulesが利用できる（go v1.13以降ならデフォルトで利用できる）

## Kubernetes APIにアクセスするコードを用意する

Kubernetes APIにアクセスするには[client-go](https://github.com/kubernetes/client-go)を使います。この場合client-goを使うコードを1から書いてもよいですが、[kyaml2go](https://kyaml2go.prasadg.dev/)を使うと、yamlファイルからclient-goを利用するコードを生成してくれます。書くのが面倒なkubernetesのオブジェクトのコードも自動的に生成してくれます。これらのコードを参考にclient-goのリファレンスを参考にコードを修正したりして、再利用するとよいと思います。

namespaceのyaml

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: sample-namespace
```

kyaml2goで生成された上記namespaceをcreateするコード

```go
// Auto-generated by kyaml2go - https://github.com/PrasadG193/kyaml2go
package main

import (
	"fmt"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"os"
	"path/filepath"
)

func main() {
	// Create client
	var kubeconfig string
	kubeconfig, ok := os.LookupEnv("KUBECONFIG")
	if !ok {
		kubeconfig = filepath.Join(homedir.HomeDir(), ".kube", "config")
	}

	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		panic(err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}
	kubeclient := clientset.CoreV1().Namespaces()

	// Create resource object
	object := &corev1.Namespace{
		TypeMeta: metav1.TypeMeta{
			Kind:       "Namespace",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name: "sample-namespace",
		},
		Spec: corev1.NamespaceSpec{},
	}

	// Manage resource
	_, err = kubeclient.Create(object)
	if err != nil {
		panic(err)
	}
	fmt.Println("Namespace Created successfully!")
}
```

ソースコードを収めるディレクトリを用意して、そこに`main.go`ファイルを作成し、先程のコードを記載します。

```bash
$ mkdir client-go-sample
$ cd client-go-sample
$ vi main.go
```

## モジュールのインストールとビルド

単純に`go get`では正しく依存関係が解決できません。対象となるkubernetesのバージョンに合ったclient-goなどのモジュールをインストールする必要があります。以下は、kubernetesのバージョンが1.14.10の場合です。kubernetesのバージョンが1.17より新しいかどうかで[タグの指定の仕方](https://github.com/kubernetes/client-go/blob/master/INSTALL.md#add-client-go-as-a-dependency)が異なります。

```bash
$ go mod init client-go-sample
$ go get # エラーが出ますが、気にしなくて良いです。
$ go get k8s.io/client-go@kubernetes-1.14.10
$ go get k8s.io/api@kubernetes-1.14.10
$ go get k8s.io/apimachinery@kubernetes-1.14.10
```

ビルドして、コマンドを実行してみます。意図したnamespaceが作成されることが確認できます。

```bash
$ go build
$ ./client-go-sample 
Namespace Created successfully!
$ kubectl get namespaces sample-namespace 
NAME               STATUS   AGE
sample-namespace   Active   22s
```
試験に出るAWS:SAAでしょう 第６夜

前回お伝えした、[Udemyでの勉強](https://www.udemy.com/course/aws-associate/)の方では
IAMでのセキュリティポリシーの設定を行いました

試験で合格するという目標ではありますが
ついつい忘れがちなのは、AWSでサーバ構築してよと言われたときに
この知識があれば役立つ、仕事として成立する、ということですよね

は〜どうでしょうでも観てリラックスしたい


# 受験生諸君(自分)!!

[これ↓](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X/ref=sr_1_1?adgrpid=54919691884&dchild=1&gclid=EAIaIQobChMIvaDenJqw6AIVhqmWCh3eZA7YEAAYAiAAEgKc0fD_BwE&hvadid=338533795365&hvdev=c&hvlocphy=1009301&hvnetw=g&hvqmt=b&hvrand=758814098125985146&hvtargid=kwd-475022447197&hydadcr=4072_10899412&jp-ad-ap=0&keywords=aws+%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88&qid=1584953072&sr=8-1)をもとに勉強しています
![51DY+M37OIL._SX352_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/e2f66413-a969-0d5c-f127-69d3cdfb9b9c.jpeg)

# 第6夜はこれを覚えよう！

### EBSの拡張・変更
- EBSボリュームの変更作業をした場合　　　　必要があるので注意

### 容量拡張
- 　　　　　はできるが　　　　　はできないので　　　　という方法を検討する

### ボリュームタイプの変更
- ４つの現行世代タイプ間での　　　　　が可能

### 可用性・耐久性
- EBSは内部的に　　　　　　に複製が行われているため、　　　　　　が発生しても利用者が意識することはない
- EBSには　　　　　機能もあるため、定期的に　　　　　　することで必要な時点に戻れる

### セキュリティ
- EBSは、　　　　　　を　　　　　するオプションがある
- 暗号化されるのは　　　　　だけでなく、　　　　　　　も暗号化される

### EFS
- EFSは、　　　　　で　　　　　　　から同時にアクセス可能
- 　　　　　　さえあれば、特別なツールをインストールしなくていい
- 　　　　　　を選択して使う必要がある

### EFSの構成要素
- EFSは　　　　　、　　　　　　、　　　　　　　の３つの要素で構成されている
- EFSはファイルが作成されると同時に　　　　の　　　に保存される
- 作成したファイルにアクセスするには、AZごとにサブネットを指定して　　　　　を作成する

### EFSのパフォーマンスモード
- EFSには、　　　　モードと　　　　　モードの２つのパフォーマンスモードがある
- パフォーマンスモードは　　　　　　　できないので、先にどちらのモードを使うかCloudWatchの　　　　　　というメトリクスを参考にする

### EFSのスループットモード
- EFSには、　　　　　モードと　　　　　モードの２つがある
- どちらのスループットモードを使うかはCloudWatchの　　　　　　　というメトリクスが参考になる

---

せっかくのGWですが、外出を自粛するという時期なので
勉強でもするかと思い、書いているわけですが
ちょっといきなり詰め込みすぎたかもと思い始めていますので
次回の記事はもっと期間があくかもしれません

**第5夜の答えは第7夜で！！**

## 第5夜の答えはこちら！

### ストレージサービスの分類とストレージのタイプ
- 5つのストレージサービス、EBS、EFS、S3、Glacier、AWS Strage Gateway、がある
- ブロックストレージはデータを物理的なディスクにブロック単位で管理するEBSがブロックストレージ
- ファイルストレージはブロックストレージ上にファイルシステムを構成して、ファイル単位で管理するEFSがファイルストレージ
- S3と、Glacierは、ファイルに任意のメタデータを追加してオブジェクトとして管理するオブジェクトストレージ

### EBS
- AWSが提供するブロックストレージサービス
- EC2のOS領域として利用したり、追加ボリュームとして複数のEBSをEC2にアタッチできる
- RDSのデータ保存用にも使用する

### EBSのボリュームタイプ
- EBSボリュームタイプはSSDタイプで２種類、HHDタイプで２種類ある

### 汎用SDD（gp2）
- EBSの中で最も一般的、EC2のデフォルトボリュームタイプ

### プロビジョンドIOPS（io1）
- EBSの中で最も高性能、RDSやEC2でデータサーバを構成する場合や、高いスループットが求められるときに利用する

### スループット最適化HDD（st1）
- ログデータに対する処理やバッチ処理のインプット用ファイルなど、大容量ファイルを高速で読み取るときなどに利用する

### Cold HDDｍ（sc1）
- 最も低コストで利用頻度は少ないため、アーカイブ領域の用途に適している

### ベースライン性能とバースト性能
- プロビジョンドIOPS以外は、ストレージの容量に応じてベースライン性能がある
- 処理量の一時的な増加に対応可能なバースト性能があるが、一時的な処理として、これに頼ってはいけない