OmniAICreator/Qiita-1.07M huggingface dataset:
macでangular8で基礎を学ぶ

# AngularのTutorialをもとに学習する

## 端末情報
```
OS:macOS Mojave
バージョン:10.14.5
端末:MacBook Pro (13-inch,2017,Four Thunderbolt 3 Ports)
プロセッサ:3.1 GHz Intel Core i5
メモリ:8 GB 2133 MHz LPDDR3
```

## Angular情報
```
$ ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 8.0.3
Node: 12.3.1
OS: darwin x64
Angular: 8.0.1
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.3
@angular-devkit/build-angular     0.800.3
@angular-devkit/build-optimizer   0.800.3
@angular-devkit/build-webpack     0.800.3
@angular-devkit/core              8.0.3
@angular-devkit/schematics        8.0.3
@angular/cli                      8.0.3
@ngtools/webpack                  8.0.3
@schematics/angular               8.0.3
@schematics/update                0.800.3
rxjs                              6.4.0
typescript                        3.4.5
webpack                           4.30.0
    
$
```

### Angular Tutorial

URL:https://angular.io/tutorial

Angular CLI
コマンド：
ng new angular-tour-of-heroes
 [angular-tour-of-heroes]アプリプロジェクト生成
ng generate component heroes
 [heroes]コンポーネントを生成
ng serve --open
 アプリをビルドし、開発サーバーを起動し、ソースファイルを監視し、それらのファイルを変更したときにアプリを再構築
 --openフラグでブラウザ(http://localhost:4200/)を開く

### ng serve実行
```
$ ng serve --open
                                                                              u Date: 2019-06-30T14:07:24.785Z
Hash: 1f209a4a02fc394658fe
Time: 7508ms
chunk {main} main.js, main.js.map (main) 13.1 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 248 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 17.5 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.93 MB [initial] [rendered]
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
ℹ ｢wdm｣: Compiled successfully.

```

### 実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140346/ad6b81a8-2467-de75-b35f-dbdd11ddfa3f.png)

(値変更後)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140346/8559c4e7-3472-c87a-cea5-a6a1e55dcd45.png)

### git

URL:https://github.com/sfida11/angular-sumple
RxPYを使ってOpenCVするとき、asyncio使えば別スレッドからでもimshowできる

RxPY+OpenCVでimshowをするとき、asyncioを使えばsubscribeがメインスレッドじゃなくてもimshowすることができたのでメモとして残しておく。

> ＜2019年10月9日 追記＞
> タイトルに語弊がありました。imshow自体は別スレッドで使っているわけではないです。

## サンプルコード(失敗例)

下のコードはRxPYで画像処理を適用し、最後に画面に表示するためのプログラムです。
一見、問題ないように思いますが、このコードは最後の「show」関数がメインスレッドではない、別のスレッドで実行されるため、cv2.imshow関数でエラー終了してしまいます。

```python3
import cv2
import rx
from rx import Observable

def show(image):
    """
    動画を画面に表示する
    """
    cv2.imshow('res', image)
    cv2.waitKey(1)

def imgproc(image):
    """
    画像処理するプログラム (とりあえずここではグレースケールにするだけ)
    """
    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

video = cv2.VideoCapture(0)

# 1. 15FPSでインターバル
# 2. VideoCaptureからデータを取り出す
# 3. ちゃんと画像が取り出せた時だけ処理する
# 4. 画像だけを次のストリームに渡す
# 5. 画像処理を適用する
# 6. 結果を画面に表示する
Observable.interval(1 / 15 * 1000) \
    .map(lambda x: video.read()) \
    .filter(lambda data: data[0]) \
    .map(lambda data: data[1]) \
    .map(imgproc) \
    .subscribe(show)

# プログラムが停止しないように入力待ちする
a = input()
```

## asyncioを使う

asyncioはPythonで非同期するためのモジュールで、いわゆる「ノンブロッキング処理」を実現できます。
このasyncioに、「run_coroutine_threadsafe」という、別スレッドで実行されているイベントループに処理を渡すことができる関数があります。

これを使って、メインスレッドでイベントループを作成し、run_coroutine_threadsafeを使ってimshowを呼び出してやれば上記のようなPGでもimshowを実行することができる。

### サンプル

```python
import cv2
import rx
from rx import Observable
import asyncio

def imgproc(image):
    """
    画像処理するプログラム (とりあえずここではグレースケールにするだけ)
    """
    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

video = cv2.VideoCapture(0)
# イベントループを作成
loop = asyncio.get_event_loop()

async def show_coroutine(image):
    """
    asyncioで実行するために、GUI表示部分をコルーチン化
    """
    cv2.imshow('res', image)
    return cv2.waitKey(1) & 0xff

def show(image):
    """
    run_coroutine_threadsafeでコルーチン
    """
    future = asyncio.run_coroutine_threadsafe(show_coroutine(image), loop)
    key = future.result()
    if key == ord('q'): # qが押されたらループを停止する
        loop.stop()

Observable.interval(1 / 15 * 1000) \
    .map(lambda x: video.read()) \
    .filter(lambda data: data[0]) \
    .map(lambda data: data[1]) \
    .map(imgproc) \
    .subscribe(show)

# イベントループを開始する
loop.run_forever()
video.release()
loop.close()
```

ちなみに、RxPYにはAsyncIOSchedulerというスケジューラもあるので、
もしかするともっと上手く書くこともできるかもしれないです。
WordPressで設定を追加する方法

functions.php


add_action( "ほにゃらら", "setting_add" ,11, 1);
function setting_add( $wp_customize ) {
	$wp_customize->add_setting('うんぬん', array(
	   'default' => '',
	));
	$wp_customize->add_control( 'うんぬん', array('settings' => 'なんとか',
	    'label' =>'うんぬん',
	    'section' => 'base_section',
	    'type' => 'text',
	));
}

#参考
https://ja.wordpress.org/support/topic/wordpress-親テーマで設定されたカスタマイザーの項目を/
ストリームAPI(Collectorsクラス)

#ストリームAPIとは
ストリームAPIは、コレクションや配列などのデータソースを元にして集計操作を行うAPIである。本記事では、終端操作のひとつである__Collectors__クラスについて記述する。Collectorsクラスは、Collectorインターフェースを実装している。collect()メソッドはストリームから要素をまとめて１つのオブジェクトを取得できる。


#collect()メソッド
(1) ＜R,A＞ R __collect__(Collector＜? super T,A,R＞ collector)
(2) ＜R＞ R __collect__(Supplier＜R＞ supplier,BiConsumer＜R ? superT＞ accumulator, BiConsumer＜R,R＞ combiner)



#Collectorsクラスのメソッド
(1) Collector＜T,?,List＜T＞＞ __toList__()
(2) Collector＜T,?,Integer＞ __summingInt__()
(3) Collector＜T,?,Double＞ __averagingInt__()  

```java:Myclass.java
Stream<String> stream = Steam.of("aa","bb","cc");

//toListでストリームをリストにする
List<String> result1 = stream.collect(Collectors.toList());
System.out.print(result1); //[aa,bb,cc]

//summingIntはひとまとめにしたものの合計を出す
Integer result2 = stream.collect(Collectors.summingInt(x->x.length());
System.out.print(result2); //6

//averagingIntはストリームの平均値求める
Double result3 = stream.collect(Collectors.averagingInt(x->x.length()));
System.out.print(result2); //2.0
```

#まとめ
Colectorsクラスに関しては「ひとまとめにして実行処理する」というイメージを持つ.
あなたの型宣言、モダンですか？

#はじめに
**型**はプログラミングをやる上で必ず学ぶ基本的なシステムのひとつです。特にCやC++のような静的型付け言語では変数を定義するときに型を指定しなければならないので、まず最初に学ぶことになります。

「そんなんわかってるわ！初心者向けの説明かよ！」と思われる熟練者の方もいるかも知れませんが、あなたの型宣言はきちんとモダンなものになっていますか？

# stdint使ってますか？
突然ですが、```int```型が何バイトかあなたは即答できますか？

4バイトと答えられたあなたは勉強熱心です。じゃあ```long```は？```char```は？```unsigned long```は？

「そんなん8バイト、1バイト、8バイトに決まってるやんけ！」というみなさん、すごいです。私のようなぼんくらは覚えてられません。しかし今後16バイトや32バイトの整数型が必要になったらどうするんですか？```unsigned long long int```みたいな型を作るんですか？~~まあそれはジョークですが...。~~ジョークのようですがC99ではすでに準備されているそうです。やばい。

ともかく、これらの型名は古くからあるものですが、可読性がよくありません。```char```という名前にはどこにもそれが1バイトのシーケンスを表すという意味はありません。

それに、システムによってintなどの型の長さが変わる場合があります。RATLONALEの節を見てください。

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/inttypes.h.html#tag_13_19_06

16bitシステムではint型は16bit（2バイト）ですが、32bitでは32bit（4バイト）です。これは致命的です。

そこでモダンなC/C++には、統一的な命名ができるよう```stdint.h```という型システムが用意されています。

|サイズ|符号あり|符号なし|
|:--|:--|:--|
|8|int8_t|uint8_t|
|16|int16_t|uint16_t|
|32|int32_t|uint32_t|
|64|int64_t|uint64_t|

```unsigned int``` は長すぎて打つのに疲れます。```uint32_t``` のほうがしゅっとしてて的確なのでわかりやすいですね。

# やむを得ずintやcharを使う場合
## レガシーなライブラリがintやcharを要求する場合。
~~名前しかちがわないので、キャストしてやりましょう。~~

```c
//結局危険
int32_t nnn
legacy_func((int)nnn)
```

# よくわからないこと
* 同じgccでも、stdint.hをインクルードしなくても使えるときと、しないとエラーになることがあります。なぜでしょう。

# 参考サイト
* 2016年、C言語はどう書くべきか (前編)<br>https://postd.cc/how-to-c-in-2016-1/
Alibaba CloudのKMSを使ってみた

## KMSとは
AWSでもおなじみ(?)のKMSですが、Alibaba CloudにもKMSが存在します。
今回は、KMSを使ってOSSのバケット内に存在する平文のファイルを暗号化して別のバケットにコピーしてみます。
このKMSによって従来、別のパソコンなどで作った暗号化キーを使って暗号化、復号化を行ってきました。
その場合、キーの管理や漏洩対策を行う必要がありました。KMSはキーの管理をクラウド業者に任せてこちらは
暗号化と復号化の処理だけを記載するだけに集中できるようになります。

## 1.KMSを作る
まずは、Keyをつくります。こちらは Key Management Systemで、作成します。特にこの部分については説明はよろしいかと思います。

<img width="1139" alt="スクリーンショット 2019-06-30 22.20.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79473/2cbee2a7-d78b-455f-acaf-10e49edebfe7.png">

## 2.OSSにバケットを作成してファイルを設置する
こちらも説明は不要かと思います。GUIでポチポチとバケットが作成できます。今回は、日付のフォルダーを作成してその中に複数のファイルを設置します。ディレクトリ構造としてはいかのような形

```
hirabun
　└2019-04-01
 　　 └ file_01.txt
 　　 └ file_02.txt
 　　 └ file_03.txt
　└2019-04-02
 　　 └ file_01.txt
 　　 └ file_02.txt
 　　 └ file_03.txt
```
  
## 3.SDKを使った暗号化
今回は、Function Computeを使います。下記はそのままコピペで使えるようにしました。
フォルダー名が今回は日付になっていますが、基本的に

```
START_DAY  = datetime.strptime('2019-04-01', '%Y-%m-%d')
END_DAY  　= datetime.strptime('2019-04-02', '%Y-%m-%d')
```
の部分と

```
 for date in daterange(START_DAY, END_DAY):
  DATE_DIR = date.strftime("%Y-%m-%d")
```

の部分を変更すればいろんなディレクトリ名で使えます。

やっていることは単純で、ファイルを落として、上げるを繰り返しているだけです。


```
from datetime import datetime
import oss2
from datetime import timedelta
from oss2.crypto import AliKMSProvider
import tempfile

## 下記は個人の環境で書き直してください
REGION              = "ap-northeast-1"
CMKID               = "先程作成したCMKID"
OSS_ENDPOINT        = "oss-ap-northeast-1-internal.aliyuncs.com"
ACCESSKEYID         = "アクセスキー"
ACCESSKEYSECRET     = "シークレットキー"
SOURCE_BUCKET_NAME  = "hirabun"
DEST_BUCKET_NAME    = "ango"
START_DAY           = datetime.strptime('2019-04-01', '%Y-%m-%d')
END_DAY             = datetime.strptime('2019-06-01', '%Y-%m-%d')

##ここからはお決まりの書き方
auth = oss2.Auth(ACCESSKEYID, ACCESSKEYSECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, SOURCE_BUCKET_NAME)
new_bucket = oss2.CryptoBucket(auth, OSS_ENDPOINT, DEST_BUCKET_NAME, crypto_provider=AliKMSProvider(ACCESSKEYID, ACCESSKEYSECRET, REGION, CMKID))
###ここまで##

def main():
 for date in daterange(START_DAY, END_DAY):
  DATE_DIR = date.strftime("%Y-%m-%d")

  for obj in oss2.ObjectIterator(bucket, prefix=DATE_DIR):
    
    ##ファイルをローカルに落とす
    with tempfile.TemporaryDirectory() as dname:
      filepath = dname + "/" + obj.key.split('/')[1]

    #OSSへのアップロード先(ディレクトリ名/ファイル名)
     OSSKEY = DATE_DIR + "/" + obj.key.split('/')[1]
     bucket.get_object_to_file(obj.key, filepath)
    # ファイルアップロード
     new_bucket.put_object_from_file(OSSKEY, filepath)

def daterange(_start, _end):
  for n in range((_end - _start).days):
    yield _start + timedelta(n)
```

Alibabaのドキュメントは、AWSに比べまだまだ整理されていなく、情報も散らばっているという個人的な感想で、
調べたいときに説明が足りなく苦労する部分が大きいです。 :sob:
東京リージョンのマネージメントコンソールからInstanceConnectでSSHする際のIPレンジを調べるワンライナー

どうも、若松です。

先日ローンチされたInstanceConnect、すこぶる便利ですね。
純粋なSSHなので、SessionManagerのような環境変数が読み込まれない等がなくて快適です。
ただし、コマンド履歴のログは取れないのでトレードオフですね。

## コンソールからSSHする際に躓くIPレンジの許可
InstanceConnectは純粋なSSHのため、SGでIPレンジを許可してあげる必要があります。
許可するべきIPレンジは以下にありますが、探すのが面倒です。
https://ip-ranges.amazonaws.com/ip-ranges.json

そこで以下のBashワンライナーを駆使することで、許可すべきIPレンジを一発で出すことができます。(curlとjqを実行できることが前提です。)

```bash
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq '.prefixes[]' | jq 'select(.service == "EC2_INSTANCE_CONNECT" and .region == "ap-northeast-1").ip_prefix'
```

## ワンライナーの解説
### curl
curlコマンドを用いてWeb上のjsonをダウンロードしています。
このjsonはAWSが公開している、AWSが使用しているIPレンジの一覧です。
-s はダウンロード時間などの無駄な情報を出力しないようにするオプションです。

### 1個目のjq
1個目のjqでprefixesの中身を抜き出しています。
これを入れている理由は、次に行うselectで、配列を渡してしまうとjsonのトップレベルが帰ってしまうからです。

### 2個目のjq
ここで絞り込みを行っています。
絞り込み条件は以下です。

| 項目 | 値 |
| --- | --- |
| service | EC2_INSTANCE_CONNECT |
| region | ap-northeast-1 |

つまり、東京リージョンのInstanceConnectで使用されるIPレンジに絞っています。
さらに出力をip_prefixのみ指定することでIPレンジのみが出力されます。

2019/6/30時点では以下が出力されるはずです。

```
"3.112.23.0/29"
```

## まとめ
最初は公開されているIPレンジを全て許可しなくてはいけないのかと絶望しましたが、絞ってみると案外少なくてホッとしました。
ただ、このIPレンジは追加/変更される可能性があるので、本気でマネージメントコンソールからのSSHを運用に組み込みたい場合は、定期的にjsonの変更を監視し、SGの変更を自動化しておく必要があるかと思います。
php-master-changes 2019-06-29

この日はビルトインサーバが fork のある環境ではワーカプロセスを作れるようにする修正、メモリサニタイザ有効時は ifunc resolver を無効化する修正、cli で strcmp() が適切なのに memcmp() してた箇所を修正、Azure Pipelines の設定修正、不要な条件コンパイルの削除、php-config で ini に関する情報もとるようにする修正、finfo_file() が .tga の mime-type を誤っていた問題の修正、COM のコンストラクタのメモリリーク修正があった！

# 2019-06-29
## nikic: Disable ifunc resolvers if memory sanitizer is used
- https://github.com/php/php-src/commit/2c8819b89cd305ed5013c7470934f3c5576d9348
- メモリサニタイザ有効時は ifunc resolver を無効化するよう修正

## nikic: Use strcmp() in phpdbg_eol_global_update
- https://github.com/php/php-src/commit/45ab57339e4142953f3daf8615d9443c31dcdfa5
- [7.4~]
- sapi/cli で、strcmp() が適切な箇所で memcmp() してたのを修正

## nikic: Increase timeout of asan job on master
- https://github.com/php/php-src/commit/796dc564e2aac61b1584ecbb9e8ab3641c26de42
- Azure Pipelines の設定で、asan のジョブの timeoutInMinutes を 120 から 150 に

## petk: Remove HAVE_ERRNO_H from libgd
- https://github.com/php/php-src/commit/a014e50513599a59a0001ef0c0e4a187d97db9ff
- ext/gd で、libgd の HAVE_ERRNO_H の条件コンパイルの削除

## petk: Update changelogs [ci skip]
- https://github.com/php/php-src/commit/df4bb13c55b39babfafdaf992f5653148e97c84f
- [7.4~]
- NEWS、UPGRADING.INTERNALS の更新

## petk: Clean up files after the tests are run
- https://github.com/php/php-src/commit/57424f272c488d479e7caa9c7eb86247053fe883
- [7.4~]
- flock のテスト実行後に一時ファイルを掃除する修正

## krakjoe: add ini config details to php-config
- https://github.com/php/php-src/commit/2d5f277a2d7129c58dce46270768787c145e79fb
- [7.4~]
- [php-config](https://www.php.net/manual/ja/install.pecl.php-config.php) で、ini についての設定情報を追加

## krakjoe: implement support for workers in cli-server on platforms supporting fork
- https://github.com/php/php-src/commit/82effb3fc7bcab0efcc343b3e03355f5f2f663c9
- [7.4~]
- sapi/cli で、fork のある環境ではビルトインサーバがワーカプロセスを作れるよう修正
- PHP_CLI_SERVER_WORKERS で数を指定するもよう

## jdoubleu: Fix [#78183](https://bugs.php.net/bug.php?id=78183): finfo_file shows wrong mime-type for .tga file
- https://github.com/php/php-src/commit/855bbc88c94bd9317379ab67e96a7bfce2f7c195
- [7.2~]
- ext/fileinfo で、finfo_file() が .tga の mime-type を誤っていた問題の修正

## jdoubleu: Add tests from fix [#78183](https://bugs.php.net/bug.php?id=78183) from PHP-7.2
- https://github.com/php/php-src/commit/6cdeedb8de469388e378bd2292b89b725905fd18
- ext/fileinfo で、↑のテストケースを追加

## weltling: Fix typo
- https://github.com/php/php-src/commit/b92669094767e54af3ef833f51072d53a8c788c0
- [7.3~]
- ext/fileinfo で、テストの typo を修正

## cmb69: Fix memory leak in COM ctor
- https://github.com/php/php-src/commit/8357a696ab0b7aba4e3e147f48544c103ef9bf83
- [7.4~]
- ext/com_dotnet で、COM のコンストラクタのメモリリークを修正

## weltling: Fix magic data
- https://github.com/php/php-src/commit/02fc2fe8c91130035e4815059925781eea2d2554
- [7.4~]
- ext/fileinfo で、.tga 対応で magic データファイルの修正
視力が低いプログラマーのためのVSCodeの設定

私はどうも体調によって最適なフォントサイズが異なるようで，VSCodeの設定値をよく変えたくなるのでまとめる。

## 全体のフォントを大きくする
エディタ内の全体のフォントサイズを調整する。特に4Kディスプレイを使うときに重宝する。

![01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260124/c8a11904-390f-4f1b-5a0c-d71aa3b21946.gif)

### 準備
特になし。デフォルトで使える

### 方法
- 文字を縮小する（`Ctrl`と`-`（マイナス）を同時押し)
- 文字を拡大する（`Ctrl`と`=`（イコール）を同時押し)

※なぜ`Ctrl + =`で拡大になるかというと，USキーボードではプラス（+）が Shiftキーと`=`キーの同時押しだからです。さらに`=`は`-`の右横にあるので，このキー入力はUSキーボードなら自然なのですが，JISキーボードだともしかしたら入力しずらいかもしれません。

## コード部分のフォントだけ大きくする

![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260124/0167ca02-2d05-745f-fae5-991d18fe6672.gif)

### 準備
1. `Ctrl`と`,`（コンマ）を同時押しして設定画面を開く
1. 画面上部の`設定の検索`で ```mouse wheel zoom``` と入力して出てくる設定を☑する（準備完了）
    <img width="518" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260124/15491b9c-e321-492d-8ce9-3897de991568.png">

- もしくは，`setting.json`の最後に以下の一行を追加

    ```
    {
        （略）,
        "editor.mouseWheelZoom": true
    }
    ```

### 方法
`Ctrl`を押しながらマウスホイールを回す(chromeとかのブラウザと同じ)

## フォントを太くしたい
やるなら徹底的に。プレゼンや議事録でVSCodeをプロジェクターに映すときにも使えるかも。

![03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260124/ef6ea428-bb95-2d16-cc9d-e4b814a9191e.gif)

### 方法
1. `Ctrl`と`,`（コンマ）を同時押しして設定画面を開く
1. 画面上部の`設定の検索`で ```font weight``` と入力して出てくる数値を変更する

- もしくは`setting.json`の最後に以下の一行を追加

    ```
    {
        （略）,
        "editor.fontWeight": "800"
    }
    ```
Java8で イミュータブル（変更不可）なListオブジェクトの変換関数

なんかで使ったから、備忘録がわりに。

 ※ Java8 での実装。
➡︎Java9 以降では、もうちょっと短い書き方（java.util.List#of）があるっぽい。

```java

@SafeVarargs
public static <E> List<E> toConstList(E... data) {
    int length = (data == null) ? 0 : data.length;

    switch (length) {
    case 0:
        return Collections.emptyList();
    case 1:
        return Collections.singletonList(data[0]);
    default:
        return Collections.unmodifiableList(Arrays.asList(data));
    }
}
```
機械学習の特徴量エンジニアリングをしていて行き詰まったから、主成分分析して2項目の角度を求めて追加してみたらこれが意外と精度向上につながって驚いている

# はじめに

...とあるデータで機械学習をすることになり、それなりの精度にはなったものの、そこから精度があがらずに困っていたら、ふと思いついたので、軽い気持ちで試してみたのがタイトルのとおり。

ちなみに万能ではありません。
時系列で繰り返しが多いものに向いていて、離散的なものでは結果がでないような印象があります。

また、こういうことをやってはいけない場面もあると思いますので、ご利用は自己判断で...
もし、何か理論的に間違っているところなどがあれば、コメントでご指摘頂けると助かります。

以上、そんな感じでも良ければお試しください。

# やっていることの概要

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/5b65b350-5fec-3390-244e-fa85a4e2aa5e.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/e7136782-5058-77c3-c521-94258a5efdeb.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/c74c14d2-4d68-6535-e463-9dfe62168543.png)


# サンプルコード（追加前）

諸事情により実際のコードを示せませんので、処理内容は察して下さい。
以下のコードを使って学習と予測をしているとします。

```py:original.py
# ライブラリ読込
import pandas as pd
from sklearn import model_selection
from sklearn.ensemble import RandomForestRegressor

# 学習データ読込
df_train = pd.read_csv("train.csv")

# 学習用データ加工
X = df_train[df_train.columns[~df_train.columns.str.contains("y")]]
y = df_train["y"]

# 学習用と検証用に分割
X_train, X_valid, y_train, y_valid = model_selection.train_test_split(X, y, test_size=.2, random_state=42)

# モデル構築
model = RandomForestRegressor(random_state=42)
model.fit(X_train, y_train)
print(model.score(X_valid, y_valid))

# テストデータ読込
df_test = pd.read_csv("test.csv")

# 予測値の取得とCSV出力
y_pred = model.predict(df_test)
pd.DataFrame(y_pred).to_csv("pred.csv")
```

# 追加するコード

学習用データのXを求めたところで、以下のコードを追加してみました。

```py:
from sklearn.decomposition import PCA
import math

# 2つの値から角度を求めて、配列を返す関数
def make_radian_row(pca_result):
    rad = []
    for r in pca_result:
        rad.append(math.atan(r[0]/r[1]))

    return rad

# 主成分分析
pca = PCA(n_components=2)
pca.fit(X)

X["rad"] = make_radian_row(pca.transform(X))
```

# サンプルコード（修正後）

最初のコードに追加分を入れたら以下のようになりました。

```py:edited.py
# ライブラリ読込
import pandas as pd
from sklearn.decomposition import PCA
import math
from sklearn import model_selection
from sklearn.ensemble import RandomForestRegressor

# 2つの値から角度を求めて、配列を返す関数
def make_radian_row(pca_result):
    rad = []
    for r in pca_result:
        rad.append(math.atan(r[0]/r[1]))

    return rad

# 学習データ読込
df_train = pd.read_csv("train.csv")

# 学習用データ加工
X = df_train[df_train.columns[~df_train.columns.str.contains("y")]]
y = df_train["y"]

# 学習用と検証用に分割
X_train, X_valid, y_train, y_valid = model_selection.train_test_split(X, y, test_size=.2, random_state=42)

# 主成分分析
pca = PCA(n_components=2)
pca.fit(X_train)

# 角度データの追加
X_train["rad"] = make_radian_row(pca.transform(X_train))
X_test["rad"] = make_radian_row(pca.transform(X_test))

# モデル構築
model = RandomForestRegressor(random_state=42)
model.fit(X_train, y_train)
print(model.score(X_valid, y_valid))

# テストデータ読込
df_test = pd.read_csv("test.csv")

# 角度データの追加
df_test["rad"] = make_radian_row(pca.transform(df_test))

# 予測値の取得とCSV出力
y_pred = model.predict(df_test)
pd.DataFrame(y_pred).to_csv("pred.csv")
```

# 結果

80%後半台の精度が90%前半の精度になりました(^_^;)

さて、次は何しようかな。
ROSの環境変数設定が邪魔するとき

ROSの環境変数を自動的に設定するため、皆さん~/.bashrcに

```bash
source /opt/ros/kinetic/setup.bash
```
または

```bash
source 自分のcatkin_ws/devel/setup.bash
```

足しているよね？
普段はあまり問題無いが、たまにこれのせいで意図した動作をしてくれないときもある。自分が遭遇したオチをここに記録する。

# pythonモジュールimport失敗
たとえばvisualモジュールimportしたときにコケるよね？
自分の解決方法は２つがある：

* python起動前にpythonpathを上書きする

```bash
$ export PYTHONPATH=/usr/lib/python2.7/dist-packages:$PYTHONPATH
```
* 以下のコードを自分のpythonソースの先頭に追加

```python
import os,sys
sys.path = [''] + ['/usr/lib/python2.7/dist-packages'] + sys.path[1:]
```

# cmakeの時に目標のPKG_CONFIGにたどり着けない
CMakeListsに自分の環境あわせて以下のようにpkg_config_pathを追加：

```cmake

set(ENV{PKG_CONFIG_PATH} "/usr/lib/x86_64-linux-gnu/pkgconfig/:$ENV{PKG_CONFIG_PATH}")
```

# rtshellがnameserver見つからないとき
rosのnameserverがデフォルトport 15005を使うが、omniNamesがデフォルト2809を使用する。15005で探そうとすると見つからない。なので、以下のスクリプトを作成、sourceする

```bash
#!/bin/bash

unset RTCTREE_NAMESERVERS
export RTCTREE_NAMESERVERS="localhost:2809"
rtcwd localhost:2809/
source /usr/local/lib/python2.7/dist-packages/rtshell/data/shell_support
```

# choreonoidのrtm pluginをbuildするときバージョンで怒られる時
cmakeが先にros環境のopenrtm-aistを見つかるとバージョンが満たさないと怒られる。cmakeでmakefileを生成時に自分の環境に合わせてOpenRTM_DIRを定義するといい。例えばppa:hrg/dailyリポジトリでopenrtmをインストールする場合に以下のオプションをにつけると良い：

```bash
-DOpenRTM_DIR=/usr/lib/x86_64-linux-gnu/openrtm-1.1/cmake
```
# その他、思いついたら随時追加する

次回を待て！！
Java学習メモ（論理演算子）

Java Silverの勉強を始めたので、自分の忘備録としてUPします。
ざっくりとしたメモなので、詳細は記載してません。

論理演算子

&&演算子は、左の式でfalseの場合、右の式を評価しないので、変数bはインクリメントされない。

　int num1 = 10;
　int num2 = 10;
　if(10 < num1 && 10 < ++num2){
	num1++;
　}
　System.out.println(num1 + num2);

解：20
DBスペシャリスト不合格レポート

#はじめに
##この記事は？
データベーススペシャリスト試験(以下、DBスペシャリスト)の2019年春試験を受けて**不合格**だったため、忘備録として今回行った試験対策をまとめたものです。

##前提条件
私は今年の4月に新卒として就職し、SIerになりました。
昨年の春試験で応用情報技術者試験を取得して今回午前Ⅰが免除だったことに加え、在学中にDBに関する講義を受けていたことからDBスペシャリストを選択しました。
試験勉強を本格的に開始した3月時点では簡単なSELECT文が書ける程度の理解度でした。

#試験対策
##参考書

今回の試験対策には以下の参考書を用いました。
https://www.amazon.co.jp/dp/B07G319LVC
各技術要素の解説だけでなく、過去問の解説も充実していたためとても参考になりました。
(高校数学でチャート式派だった方は気に入るかと思います) 

##12月～2月
昨年の12月あたりから参考書をパラパラと流し読みし、2月には午前Ⅱと午後Ⅰの過去問を1,2年分解いて試験の雰囲気を掴みました。
この時点では午前Ⅱは3割程度、午後Ⅰは1割程度しか理解できておらず、本格的に対策が必要だと焦りが生まれました。

##3月
3月は中旬まで研究や引っ越し作業がかさみ、あまり対策が出来ませんでした。
下旬になってから各技術要素について理解できるまで解説を熟読し始め、3月の終わりには8割方読み終えていました。

##4月
4月の1,2週目は残った技術要素の熟読に加え、通勤時間を利用して午前Ⅱを解きました。
主に出勤時の電車内は大変混雑していたため、午前Ⅱはアプリを利用して解いていましたが、不正解だった問題を記録出来たため後々役立ちました。
2週目が終わった時点で10年分ほど取り組むことが出来ており、午後の正答率は7~8割程度となっていました。

また、2週目から午後Ⅰの過去問に着手しました。初めは全く理解が追い付かず、解説をひたすら読んで「なぜこの答えになるのか」を理解した上でもう一度同じ問題を解く、という流れで学習を行いました。

3週目の頭には、通勤中に午前Ⅱで不正解だった問題の再実施を行い、正答率を9割まで高めました。
また、この頃には午後Ⅱの問題も理解でき初め、ギリギリ6割を取れるようになっていました。

試験3日前からまとまった時間をとり、午後Ⅰと午後Ⅱを時間を計測しながら解きました。
午後Ⅰは7割程度安定して解けるようになってきましたが、午後Ⅱが想定通りの問題が来れば6割以上とれる、といった感じでした。

#試験結果
##スコア


| 試験区分 | スコア |
|:--------|-------:|
| 午前Ⅱ   | 96点|
| 午後Ⅰ   | 72点 |
| 午後Ⅱ   | 41点|

結果、不合格でした。

#振り返り
##反省点
**午前Ⅱに時間を割きすぎた**と感じました。
効率的に合格するためには午後Ⅰ、午後Ⅱの傾向からあらかじめ特化する分野を決めておき、それ以外の分野は午前Ⅱで8割前後を取れるくらいで留めておく必要があったかなと思います。

また、想定外だったのは午後Ⅱの問題構成でした。
私はいわゆるパン屋さんを選択しましたが、今までの傾向であれば大問が3問構成であり、大問1,大問2を中心に対策をしてきました。
しかし今回の構成は大問2問構成であり、大問1はまあまあ解けるけど大問2が全く分からない…といった状態でした。
また、特に対策を練ったリレーションシップで書かされる線が少なく、点の稼ぎどころを失った状態でした。

##良かった点

午前Ⅱの対策はやりすぎではありましたが、自信を持てるスコアが出せたと思います。
正直なところ過去問そのまんまの問題も複数あるため暗記してしまえば合格ラインは固いと思いますが、暗記ではなく解説を熟読したがゆえのスコアだったと思います。
(結果時間を割きすぎて不合格につながってしまったのですが…)

#おわりに

試験勉強を通じてDBに関する知識を深めることが出来たのが一番の収穫であると感じています。
現在の配属先でDBを触ることが多く、早速役に立っているのではと思います。

また、午後2に関して、試験間際にではありましたが問題の意味を理解できる瞬間が訪れました。
後は過去問に取り組んで問題文を読解する速度を向上させれば次は合格に手が届く、という確信が得られたことも収穫であったと思います。
Nginxにて秒間あたりのリクエスト数を制限する方法

担当した案件でNginxをリバースプロキシサーバとして利用した際にNginxにてバックエンドのサーバに流れる流量の制限を実施した際の

手法について記載する。

メインの設定ファイルであるnginx.conf内に「limit_req_zone」をhttp、server、locationディレクティブいずれかの配下に追加することにより、

設定することが可能となる。

 

以下の記載方法においては後段記載の内容となる。 

limit_req_zone $server_name zone=one:10m rate=10r/s;

 

$server_nameの部分は複数のバーチャルサーバのconf記載がある場合などに利用出来る。

例えば、別々のバックエンドサーバの振り分けに置いて流量を制限したい場合などに1サーバごとの設定として制限したい場合の記載方法である。

zone="one"の部分は、任意で名称を決めれる部分であり後述するバーチャルサーバごとのconf内でしてすることができる。

rate=10r/sの意味は秒間10リクエスト数にて制限する記載内容である。


参考にしたサイト
http://infra.hatenablog.com/entry/2014/01/27/224342
http://mogile.web.fc2.com/nginx/http/ngx_http_limit_req_module.html

基本的な設定
https://qiita.com/hclo/items/35f00b266506a707447e

全体のサンプル
https://www.nginx.com/resources/wiki/start/topics/examples/full/


nginx.confの記載例(httpディレクティブ内に以下を追記)

     limit_req_zone $server_name zone=one:10m rate=10r/s;


バーチャルサーバ向けconfの記載例(locationディレクティブ内に以下を追記、上記nginx.confにて定義したzoneを指定する                                   

     limit_req zone=one burst=10 nodelay;
Android StudioにGalaxyのエミュレーターを追加する

## 実行環境
OS：Windows10


### 手順1　ファイルのダウンロード

以下のサイトから欲しいエミュレーターをダウンロードしてくる。
[Galaxy Emulator Skin](https://developer.samsung.com/galaxy/emulator-skin#)


### 手順2　ファイルの保存
ダウンロードしてきたら.zip形式を解凍して、以下のフォルダ（ディレクトリ）にコピーする。
`Android Studio > plugins > android > lib > device-art-resources.`

Windowsの場合は恐らく
`C:\Program Files\Android\Android Studio\plugins\android\lib\device-art-resources`

### 手順3　Android Studioの起動

### 手順4　AVD Manager
上にFileやEdit、Viewなどが並んであって、その中にToolsというのが存在する。
そのToolsをクリックして、一番上に出てくるAVD Manegaerをクリック。

### 手順5　Create Virtual Device
一番最初に

`Create Virtual Device`

の文字が出てくるだろうから、それをクリック。

### 手順6　新規エミュレーターの作成


### 手順7　エミュレーターの設計
自分が使いたいGalaxyのエミュレーターの設定を行う

Galaxy S8 Plusの場合は以下のような形にしておけばよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189371/428b739b-767a-f8ff-0972-6497d1ecb8ed.png)


### 手順8 Skinの設定
手順7の画面で下の方にスクロールするとSkinを設定する項目があり、最初はNo Skinsになっている。
そこで、右側にある…をクリックして手順2で保存したフォルダをクリックする。

※No Skinsのクリックが中々反応しないことがあるっぽいです。私はなかなか反応しませんでした。

### 手順9　API LEVELの設定
手順8が完了するば、Nextで進むと以下のような画面が出てくる。

ここではAPIのレベルを決めるので、特にわからなければ、一番上の奴をインストールしておこう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189371/30750097-f823-0d82-647e-b7b6713e2316.png)

Acceptすることを忘れないように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189371/4ed132a9-097f-3e89-0aef-9ce33fc0e083.png)


### 手順10　あとはFinishだけ
GitBash で ワンライナー で JRE をつくる

いつかの誰かの役に立つかもしれないから備忘録。

いつか、カスタムランタイムを試しに作った時のワンライナー。

動作確認は各自でお願いします。
（いつか使う時が来たら、当方で確認し修正します。）

```shell
java --list-modules | sed 's/^\(.\+\)@.*/\1/' | tr -s '\r\n' ',' | sed 's/,$//' | xargs -I{} jlink --add-modules {} --output jre
```
まあこういうのは日本の流行り

https://qiita.com/hiro-hori/items/1cf28a6ac75db077c8f3
#これはミクロ経済学っぽい問題
大体ちきりんとかホリエモンとかネオリベラルで文化というものを知らない金勘定しかできない人格が欠落したタイプのやつはだいたい「〇〇はいらない」っていう。これが日本のトレンド。
さて今回の場合コメントはいらないという意見があるが、これは簡単に式で書くと、コメントがある場合のコードが太る限界損失MCcと、コメントがない場合にミスが発生する場合の限界損失MCn
MCn/MCn=<1ならコメントが必要であり、1より大きいならコメントを書いた方がよい。
限界費用でもいいが、コメントを書かないことによる被害は本人ではないケースが多いので、こうなる。
###TPO
たとえばこのQiitaにコメントも何もなしでコードを書いても、なんじゃそりゃということで全く相手にしないでしょう。なにか怪しいコードでウィルスなんじゃないかという疑いを抱かれてもおかしくありません。
つまりコメントが必要な場合とコメントを省略して可読性を犠牲にしても早くて容量が少ない場合と比較して人間は判断しているわけです。
これを日本人はすぐネチケットとか礼儀とか言いそうですが、そうではないです。比較して決定しているのでネチケットや礼儀ではないのです。

###言語

以下個人的な見解ですが、
VBAとかVBSとかPowerShellしかやっていないですが、これは全部必要です。
とくにVBSはコメントが必要です。
これはVBSとPowerShellが変数の型を宣言できないか、しなくていいというのが原因です。
TypeORMでIN句のWHERE検索がしたい

表題通りで、TypeORMにて以下のようなIN句をどう指定するかという話です。

`select * from posts where id in(1, 3, 5);` 

## 早速結論

```typescript
getRepository(Post)
        .createQueryBuilder("posts")
        .where("posts.id IN (:...ids)", { ids: [1, 3, 5] })
        .getMany()
        .catch(e => console.error(e));
```

上記の通り、parse側でスプレッドさせるように書けば `where` メソッドの第２引数に直接配列渡せます。
展開された結果、 `WHERE id IN($1, $2, $3)` のように個別にプレースホルダを作ってくれる感じですね。

## 環境

```json
  "typescript": "^3.4.3"
  "pg": "^7.11.0",
  "typeorm": "^0.2.17"
```
git for Windows の git grep でスラッシュ始まりの文字列を検索すると必ずヒットしなくなる

# 概要

- Git for Windows の `git grep` で、スラッシュから始まる文字列を検索すると、本来ヒットすべき文字列がヒットしなくなる
  - スラッシュから始まる文字列とは: `/`, `/fuga` など

# 環境

- git version 2.22.0.windows.1
- Terminal は mintty

# 再現手順

## 準備 1: テスト用のファイルを作る

```bash
$ echo 'hoge' > test.txt

$ echo '/fuga' >> test.txt

$ echo 'fo/o' >> test.txt

$ cat test.txt
hoge
/fuga
fo/o
```

## 準備 2: テスト用ファイルをステージさせる

```bash
$ git init .
Initialized empty Git repository in C:/dev/src/test-dir/.git/

$ git add test.txt
```

これで test.txt が `git grep` の対象となった。

## 本題: いろいろなキーワードで git grep してみる

### スラッシュなし: 想定通りヒットする

```bash
$ git grep 'hoge'
test.txt:hoge
```

### スラッシュから始まる: ヒットしない

```bash
$ git grep '/'
$

$ git grep '/fuga'
$
```

スラッシュを検索キーの冒頭にさえ入れなければ、想定通りヒットする。

```bash
$ git grep 'fuga'
test.txt:/fuga

$ git grep 'fo/'
test.txt:fo/o

# こういうのも OK
$ git grep '\/'
test.txt:/fuga
test.txt:fo/o
```

# 原因

https://github.com/git-for-windows/git/issues/2109
https://github.com/git-for-windows/build-extra/blob/master/ReleaseNotes.md#known-issues

スラッシュ始まりのパラメータを与えた場合、POSIX のパスを Windows で扱えるようにするため、文字列の変換が行われる模様。

例えば、

```bash
$ ll /git-bash.exe
-rwxr-xr-x 1 Tsubasa Ogawa 197609 152600  6月  8 15:14 /git-bash.exe*
```

ターミナル上では root 直下に git-bash.exe が置いてあるように見えるが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49525/87bd85ad-4aba-d4ed-cf3a-88131fcac8c0.png)

Windows 上のファイルシステムでは `C:\...` のようなドライブレターから始まるパスとなっている。つまり、スラッシュ始まりの文字列を渡すと `C:\...` のような prefix が付与されてしまう。

# 対策

公式がお勧めしているのは `MSYS_NO_PATHCONV=1` を用いる方法で、例のパス変換を無効化してくれる。

```bash
$ MSYS_NO_PATHCONV=1 git grep '/'
test.txt:/fuga
test.txt:fo/o
```

もしくは、スラッシュを 2 つ続ける方法もある

```bash
git grep '//'
test.txt:/fuga
test.txt:fo/o
```

# まとめ

- Git for Windows で `git grep` するときは、スラッシュ始まりのキーワードを使わないように注意
- もしどうしても使いたい場合、以下でパス変換を回避する
  - `MSYS_NO_PATHCONV=1` を使う
  - スラッシュを 2 つ続けて使う
  - エスケープする
WPF Tips - Custom Vision Serviceを（SDK使わずに）REST APIで使う

#概要
とある用事でCustom Vision Serviceのアプリを作ることにしたんですが、
先方のWindows 10のバージョンがわからなかったので、APIで実現した際の備忘録

#開発環境
- Visual Studio 2017 Community
- Windows 10 (1903)

#開発内容
Custom Vision Serviceを使って、画像を分類する。
ただし、学習まではCustom Vision ServiceのWebサイトで行う。
分析対象の画像はローカルPC上に複数枚あって、
アプリでCustom Vision ServiceのWeb APIを使って分析する。

#SDKで実現しなかったちょっとした理由
先にも書いたけど、Windows 10のバージョンがわからなくて、
SDKを使える環境かわからなかったのもあるんだけど、
Custom Vision Serviceで得られるURLをいちいち分解して
ProjectIDとかモデル名をAPI用に抜き出すのがどうかと思ったので。

Serviceで得られるPrediction-Keyを使って
そのままPOSTできた方がいいなー・・・と。

#実装内容
通信の部分だけ抜き出すとこんな感じ
※※※の部分は適宜変更してください。


```
    var client = new HttpClient();

    // ヘッダーにPrediction-keyを設定
    client.DefaultRequestHeaders.Add("Prediction-key", "※※※Custom Vision Serviceで取得したPrediction-key");

    var content = new MultipartFormDataContent();

    var fileContent = new StreamContent(File.OpenRead("※※※画像のフルパス"));
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = System.IO.Path.GetFileName(filename)
    };

    content.Add(fileContent);

    // POST送信
    HttpResponseMessage response = client.PostAsync("※※※Custom Vision Serviceで取得したEndPointURL", content).Result;
    if (response.StatusCode == HttpStatusCode.OK)
    {
        var body = await response.Content.ReadAsStreamAsync();

        var serializer = new DataContractJsonSerializer(typeof(PredictionResults));
        PredictionResults item = (PredictionResults)serializer.ReadObject(body);

        // ※※※保存処理
        SaveData(item);
    }
    else
    {
        // エラー発生時
    }

```

上記の中のPredictionResultsクラスは、Cognitive Serviceが画像分析した結果のJSONデータを
格納するための自作クラスです。
中身は以下のような感じ

```
namespace CustomVisionServiceTool
{
    [DataContract]
    public class PredictionResult
    {
        [DataMember(Name = "tagId")]
        public string TagId { get; set; }

        [DataMember(Name = "tagName")]
        public string TagName { get; set; }

        [DataMember(Name = "probability")]
        public double Probability { get; set; }
    }

    [DataContract]
    public class PredictionResults
    {
        [DataMember(Name = "id")]
        public string Id { get; set; }

        [DataMember(Name = "project")]
        public string Project { get; set; }

        [DataMember(Name = "iteration")]
        public string Iteration { get; set; }

        [DataMember(Name = "created")]
        public string Created { get; set; }

        [DataMember(Name = "predictions")]
        public PredictionResult[] Predictions;
    }
}

```
GANで使われていたPyTorchのモジュールについて調べてみた

# はじめに
KaggleでGANを使用するコンペがつい先日始まりました。

自分は画像系の機械学習をほとんど触れてこなかったので、
KaggleのKernelをベースに、PyTorchのモジュールについて勉強がてら少し調べてみました。

# モジュール
## torch.nn
ドキュメント: https://pytorch.org/docs/stable/nn.html

PyTorchのニューラルネットワークモジュールの大元のクラス。

## torch.nn.Module
モデルを作るときに必要な基本のクラス、
クラスで定義し、インスタンスでモデルを定義しているようです。

```python
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)
```

## torch.nn.functional
ドキュメント: https://pytorch.org/docs/stable/nn.html#torch-nn-functional

forward関数を定義するときに使われている。
torch.nn.Moduleで定義したModelクラス内で定義されるようです。

```python

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)
    def forward(self, x):
       x = F.relu(self.conv1(x))
       return F.relu(self.conv2(x))
```

## torch.optim
ドキュメント: https://pytorch.org/docs/stable/optim.html

その名の通り最適化アルゴリズムが実装されたパッケージです。

```python
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr=0.0001)
```

## torch.randn
ドキュメント: https://pytorch.org/docs/stable/torch.html#torch.randn

乱数のテンソルを返すようです。
ある例ではノイズの作成に活用されていました。

```python
noise = torch.randn(batch_size, nz, 1, 1, device=device)
```

## torch.full
ドキュメント: https://pytorch.org/docs/stable/torch.html#torch.full

第二引数で埋まった第一引数のサイズのテンソルを作成するようです。

```python
labels = torch.full((batch_size, 1), real_label, device=device)
```

# 終わりに
GANのコンペが始まったということで、これを機にGANについて学んでみたいと思います。
/tmp/配下のファイルを個別の設定内容に応じた削除削除方法について

/tmp/配下が削除されるロジックとしてはデフォルトで以下のような設定がある

（RHEL7のデフォルト設定）

 

/tmp/と/var/tmp/が自動的に削除される定義が記載されている設定ファイル

/usr/lib/tmpfiles.d/tmp.conf

 

設定内容としては以下となる。

v /tmp 1777 root root 10d

v /var/tmp 1777 root root 30d

 

削除されるロジックとしては以下の通りである。

 

①systemd-tmpfiles-clean.timer

enable

 

自動削除を実行するデーモンが有効化されていること

 

②/usr/lib/systemd/system/systemd-tmpfiles-clean.timer

[Timer]

OnBootSec=15min

OnUnitActiveSec=1d

上記の意味

OS起動から15分後

1日1回

 

②の設定内容によりsystemd-tmpfiles-clean.serviceが動作し、/tmp/と/var/tmp/配下を/usr/lib/tmpfiles.d/tmp.confの設定内容に応じて削除している

 

 

今回の案件の中で、個別に/tmp/配下にディレクトリを上記ロジックとは別の設定に応じた削除を実施して欲しいとの要件があり、以下を実装することにより実現した。

 

/usr/lib/tmpfiles.d/new.conf

v /tmp/hogehoge/delete 0755 root root 1d

 

上記設定により、/tmp/hogehoge/delete1dayのディレクトリ配下が1日で削除される

※注意

1dと設定されているが、ファイルの配置タイミングと削除するサービス軌道により前日分が削除された時間により最大で1日と23時間59分の差が発生する。

 

例えば、日時で起動するsystemd-tmpfiles-clean.serviceが起動されたあとに/tmp/hogehoge/delete1day/配下にファイルがアップロードされたケースの時、

翌日のsystemd-tmpfiles-clean.serviceが起動した際には1d経過したとは見なされないのでファイルの削除は行われないことに注意する。
travis-ciでgithub-pagesへの自動デプロイを行う

自分用メモ以外の何物でもないです。

# Travis CI
https://travis-ci.org/

# やったこと
- vue.jsで作成したSPAアプリをビルドし、github pagesにデプロイする。
- デプロイ先は、ブランチごとに以下のように変更する。（それぞれ別のgithub pagesのリポジトリを立てている）
    - master ：本番環境
    - feature/xxx ：開発環境

# JSのビルド
```travis.yml
language: node_js
node_js:
  - "6.11.5"           #利用するnode.jsのバージョンを指定。現在のバージョンをそのまま指定した。
before_install:        
  - npm i -g npm@4.0.5 #npmのバージョンを指定。
cache: npm
script:
  - npm run build      #ビルドスクリプトを指定。testを走らせると落ちるので（・・）
```
# Github pagesへのデプロイ
```travis.yml
deploy:
  - provider: pages
    repo: direboar/embriosupport-dev-page　 #デプロイ先のリポジトリを指定。
    target_branch : master　　　　　　　　　　
    skip_cleanup: true
    github_token: $GITHUB_TOKEN
    keep_history: true
    local_dir : ./gh_dist　　　　　　　　　　 #アップロードするディレクトリパスを指定。
    verbose : true
    on:
      all_branches: true
      condition: $TRAVIS_BRANCH =~ ^feature #featureで始まるブランチ名を対象とする。

  - provider: pages                         #複数並列で記載することで、ブランチごとに別のdeployを実施できる
    repo: direboar/embriosupport-prod-page
    target_branch : master
    skip_cleanup: true
    github_token: $GITHUB_TOKEN
    keep_history: true
    local_dir : ./gh_dist
    verbose : true
    on:
      branch: master
```
#### github tokenの設定
・Personal Access Tokenの発行
・発行したトークンをEnvironment Variablesに秘匿情報として設定
・Environment Variablesに設定した変数名を、travis.ymlに設定

ぶっちゃけ、手順は以下の通りやればよい。設定自体は簡単。
https://docs.travis-ci.com/user/deployment/pages/

# はまった点
## push先のURL
デフォルトの挙動では、local_dirに指定したディレクトリ自体はgithubpagesにアップロードされない。
いままではディレクトリ自体もアップロードしていたので、そのままではURLが変わってしまう。
仕方ないので、deploy前に実行するフックでディレクトリをコピーして対応した。

```travis.yml
before_deploy: | #普通にシェルがかける（　＾ω＾）
  mkdir gh_dist　
  mv ./dist ./gh_dist 
```
## エラーになったときのログがあんまりでなくて、解析に困る
pushに失敗したとき

```
Couldn't push the build to github.com/test_repo.git:gh-pages
```

ぐらいしかCIの画面には表示されない。
リポジトリ指定が間違っていたり、いろいろしていたらしいが、そのあたりの情報が出ない。
どこかにログが出ているのか？この辺りはまだ未確認なので、わかり次第追記。

##参考
https://qiita.com/hoshimado/items/4090d8e64beb8a7f95e1
https://poyo.hatenablog.jp/entry/2018/06/08/145255
vueでマテリアルデザインのボタンを追加したらページ全体のレイアウトが崩れた

ポエム。

自作のvueコンポーネントで、ボタンをクリックした時にメニューを出したくて [Vue Material](https://vuematerial.io/)というライブラリを使ってみた。
現在開発中のバージョンはbetaという事でバグってたので旧バージョンの0.8.1を使った。

メニューは無事出せたんだけど作成したvueコンポーネントを既存のページに組み込んだらレイアウトが崩れまくり。
何故かって言うとVue Materialがbodyとかaとか既存のあちこちで使ってるタグに対してスタイルを上書きしている。
こことか
https://github.com/vuematerial/vue-material-old/blob/master/src/core/stylesheets/base.scss#L38

```
ul:not(.md-list) > li + li {
  margin-top: 8px;
}
```

こことか。
https://github.com/vuematerial/vue-material-old/blob/master/src/core/stylesheets/typography.scss#L78

```
a:not(.md-button):not(.md-bottom-bar-item) {
  text-decoration: none;

  &:hover {
    text-decoration: underline;
  }
}
```


一箇所メニューを出したいだけであって、別にページ全体をマテリアルデザインにしようとは1ミリも考えてない。

vueコンポーネントはよく、このスタイルタグを設置して下さいーみたいな事書いてあるけど、それ全部やめてくんないかな。
vueファイルの中にscoped属性付けて書けばvueがいい感じにスコープ狭くしてくれるはずなのに。

1クリックでモジュールを追加。既存の処理には影響が無い事が保証される。UIでそんな世界は不可能なんかいな
プログラミング勉強記【2週目】2019/6/24 ～ 2019/6/30

#はじめに
初めまして、プロ猫と申します！
2019年2月頃からプログラミングを勉強しました学生です。
今までは主にWeb系の言語を勉強していたのですが、色々調べていくうちに機械学習に興味を持ち始め、Pythonの勉強を始めることにしました。
内容は曜日ごとに分けて書いていきます。**正直ただの記録用なので大したものではありません。温かい目でご覧ください。**
コメントやアドバイスなどいただけたらモチベにつながるのでよろしくお願いします！

#今週の内容
今週もPythonの基礎から学習しました。

#月曜日
風邪をひいたためお休み
#火曜日
- 辞書について学習(dictionary)
    - 記述方法 {}を使う
    - 要素の追加と削除方法
    - 要素の書き換え方法
    - 要素にアクセスする方法
 
#水曜日
- タプルについて学習(tuple)
    - 記述方法 ()を使う
    - 不変である。要素を変更できない。
    - count() index()
- set形につて学習(set)
    - 記述方法 set([])
    - 要素の追加方法 add()
        - 同じ要素は追加されない
 
#木曜日
- ブール型について学習(Booleans)
    - 真(True)、偽(False)

#金曜日
- テキストファイルの読み込みについて学習
    - 開く方法 open(ファイル名)
    - 読み込む方法
        - 全体を読み込む read()
        - 行ごとにリストとして読み込む readlines()
    - 閉じる方法 close()
- with文 →ファイルを閉じなくてもいい
 
```python:qiita.py
with open('text.txt') as f:
    #処理
```

#土曜日
- ファイルモード(mode)の種類について学習
    - **mode='r'** 読み込み
    - **mode='w'** 書き込み(新規作成、上書き)
    - **mode='a'** 追記
    - **mode='r+'** 読み込みと書き込み
    - **mode='w+'** 書き込みと読み込み
- テキストファイルの書き込みについて学習
上書き、新規作成の場合は mode='w' で write() を使う
 
```python:qiita.py
with open('text.txt', mode='w') as f:
    f.write('書きたい内容をここに書く')
```

追加の場合は mode='a' で write() を使う→内容が一番後ろに追加される
 
```python:qiita.py
with open('text.txt', mode='a') as f:
    f.write('書きたい内容をここに書く')
```

#日曜日
- 比較演算子について学習(==,!=,>,<,>=,<=)

#教材
- Udemy
    - [Complete Python Bootcamp: Go from zero to hero in Python 3](https://www.udemy.com/complete-python-bootcamp/)
- 書籍
    - [スラスラ読める Pythonふりがなプログラミング (ふりがなプログラミングシリーズ)](https://www.amazon.co.jp/dp/4295003867/ref=cm_sw_em_r_mt_dp_U_SzWdDb00RVEY7)

#最後に
Twitterやってるので良ければフォローよろしくお願いします！
https://twitter.com/pronekocode
【python3】VSCodeの設定メモ

# エディタで仮想環境のpythonを設定する。
仮想環境を設定し、pipで必要なモジュールをインストールし、VSCodeを立ち上げた。
すると、下の画像のように不要なエラーが出ていた。
![スクリーンショット 2019-06-30 0.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18086/a258f3fe-9b0d-edce-1d41-2cbfad2c72ec.png)

この不要なエラーを無くしたいので、エディタを設定する。
方法としては、下記の手順でエディタに仮想環境のpythonを認識させる。

## 方法
ターミナルでプロジェクトフォルダに移動し、仮想環境フォルダがあるディレクトリでVSCodeを起動する。

コマンドでVSCodeを起動する方法は[こちらの記事](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)を参考に設定していく。

そして、コマンドからVSCodeを起動後、コマンドパレットを開き（` Cmd + ↑ + p `）、 画像のように` >python:s`と入力し、 `Python:Interpreter` を選択する。

![スクリーンショット 2019-06-30 21.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18086/b24d4bf9-4e70-f1fa-eed3-67ab8d13e4de.png)

すると、どのPythonを選択するか候補が一覧で表示されるので、今回使用している一番下の仮想環境の設定を選ぶ。
![スクリーンショット 2019-06-30 21.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18086/c14f68ce-79f2-b882-5a11-63063e6cb1f2.png)

その後、エディタを確認するとエラーが無事に消えた。

![スクリーンショット 2019-06-30 0.28.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18086/6e2bfe01-47a5-1a20-e85a-8dd783fce05a.png)
[Vim] カーソル上の単語でvimgrep

皆さんvimgrep使ってますか？便利ですよねvimgrep。ただ、「*」みたいな単語検索が無くて不便だったので作りました。
# 概要
``` ~/.vimrc
nnoremap " *:vimgrep /<C-r>// **/*.{cpp,cu,h,hpp}
```
これで「"」を押せば一発でvimgrepが走ります。以下詳細。

#やりたいこと
たとえば、関数の引数を変えたので関数を呼んでいるところをすべて修正したいという状況が考えられます（void foo(int a)をvoid foo(int a, float b)に書き直したなど）。
同一ファイルであれば単語検索（*ないし#）を使えばいいんですが、大抵の場合コードが複数ファイルに跨っているので、vimgrepなりtabnewなりで虱潰しに直していく必要があります。とはいえいずれも手数が掛かってめんどくさいので、mapに登録して楽をしましょうというやつです。
というわけで、冒頭に書いた一行の各要素を解説していきます。

## vimgrep
``` vim
:vimgrep [word] {src1 src2 ...]
```
検索文字列（word）を列挙したファイル（sec1 src2 ...）から探して一覧を出力してくれます。便利。
vimgrepでググるといろいろ出てくるけど、下記がわりと簡潔でわかりやすい（個人の感想です）
https://qiita.com/tsumac/items/3972d5347a5f6e37ca09

ただデフォルトだと検索文字列もファイル名も全部手打ちで書かないといけなくてめんどくさいので、そこも自動化していきます。

## *
カーソル上の単語を検索するVim標準コマンドです。すごく便利。hjklの次に重要といっても過言ではない（言い過ぎ）

## /\<C-r>//
「*」はファイル内検索でしか無いので、vimgrepに持っていくには一工夫が必要です。
そこでレジスタというやつを使ってやります（CPUの話ではないです）

https://qiita.com/0829/items/0b3f63798b6910623efc
↑の9. にある通り、vimでの検索文字列は「"/」なる名前のレジスタに登録されています。
このレジスタを貼り付けるにはCtrl+rのあとに/（スラッシュ）を打てばよいです。

また、左右をスラッシュで括っているのは正規表現に対応するためです。
（*での検索は単語の開始と終了を表す正規表現（\<と\>）がついているので）

## \*\*/\*.{cpp,cu,h,hpp}
「**/」はカレントディレクトリから階層的にファイル探索する、という意味らしいです。たとえば、

```
src/hoge/*
src/hoge/fuga/*
src/include/foobar/*
```

この辺りがすべてヒットするということですね。これも便利。

また、「\*.{cpp,cu,h,hpp}」は拡張子が.cpp, .cu, .hまたは.hppのファイルを指します。bashと同じです。
Pythonの人なら\*.py、FORTRANの人なら\*.{f,f90}などど変えればよいですね。

# おまけ
併せて使うと便利そうな設定をいくつか書いておきます。

## Gitで管理されているソースコードを対象としてvimgrep
Vimのコマンドモードでは任意のシェルコマンドが走るそうなので、それを使えば小題のようなこともできます。

``` vim
:vimgrep [word] `git ls-list`
```

## :cn（次の検索結果への移動）の簡略化
vimgrepでの検索結果の移動には:cnを打つ必要がありますが、数が多くなってくるとこれもわりとめんどくさいです。
これの簡略化方法としては、
① :cnをmapに登録する

```~/.vimrc
nnoremap > :cn<CR>
```
② Quickfixを使う

``` ~/.vimrc
autocmd QuickFixCmdPost vigrep cwindow$
```
の②通りが考えられますが、どちらでもお好みで良いかと思います。

# 参考文献（再掲含む）
1. vimgrep & 検索と置換
https://qiita.com/tsumac/items/3972d5347a5f6e37ca09

2. vimのレジスタ
https://qiita.com/0829/items/0b3f63798b6910623efc

3. Vimのレジスタを使う
https://qiita.com/a4_nghm/items/d29b35f5d056ef5da0d9

4. 【vimめも】 10. マッピング
https://qiita.com/r12tkmt/items/b89df403f587216802f1

5. vimgrepとQuickfix知らないVimmerはちょっとこっち来い
https://qiita.com/yuku_t/items/0c1aff03949cb1b8fe6b
Raspberry Piで電子工作【LED + スイッチ】

#概要
Raspberry Pi（以下、ラズパイ）を使ってLEDの明るさを変えてみたり、スイッチでLEDをON/Offしてみたりといった簡単な電子工作を行いたいと思います。

#参考文献
日経BPラズパイマガジン2019年6月号

#環境
前提条件として、Raspbianインストール済みのラズパイを用意。
この記事で紹介するプログラムはPython3.7で動作確認を行なっています。

##ライブラリ
ラズパイから電子パーツを制御するために「pigpio」というライブラリを利用します。まず、常駐プログラムのpigpiodを動作させておく必要があります

```bash
sudo systemctl enable pigpiod
sudo systemctl start pigpiod
```

もし、pigpioがインストールされていない場合は、
``sudo apt-get install pigpio python-pigpio python3-pigpio``でインストールしてください。

上記のコマンドを１度実行しておけば、次のラズパイの起動時からは自動的にpigpioの常駐プラグラムが実行されます、

#サンプル１：PWMでLEDの明るさを変えてみる
チュートリアル等でよく見かけるLEDをチカチカさせるプログラムに少し手を加えてみました。以下のプログラムを実行するとON/OFFの２段階だけではなく、明るさを少しずつ変えていくことができます。

```python
import pigpio
import time

# 使用するGPIOピンの定義
PIN = [17, 27]

pi = pigpio.pi()
 
# GPIOピンの設定
for i in range(2):
    pi.set_mode(PIN[i], pigpio.OUTPUT)
    pi.write(PIN[i], pigpio.LOW)
    pi.set_PWM_frequency(PIN[i], 50)
    pi.set_PWM_range(PIN[i], 100)

# デューティー比が上限値もしくは下限値に達した場合に、増減を切り替えるための関数
def get_increment(duty, increment):
    if (duty == 5 and increment < 0)or (duty == 95 and increment > 0) :
        increment = increment * -1
    return increment    

# デューティー比の初期値
duties = [5, 95]
# デューティー比の増減幅
increments = [5, 5]

while True:
    for i in range(2):
        increment = get_increment(duties[i], increments[i])
        duty = duties[i] + increment
        pi.set_PWM_dutycycle(PIN[i], duty)
　　　　　# デューティー比と増減幅を上書き
        duties[i] = duty
        increments[i] = increment
        time.sleep(0.1)
```

# サンプル2：スイッチでLEDのON/OFFを切り替える
タクトスイッチを使ってLEDのON/OFFを切り替えてみたいと思います。今回スイッチの接続にプルアップ抵抗を使用しているため、入力値としては常時1、スイッチが押された時に0となります。

```python
import pigpio
import time

# 使用するGPIOピンの定義
LED_RED = 27  
LED_YEL = 17 
SW_RED = 22
SW_YEL = 23

# 現在のLEDの状態を保持する変数
red_state = 0;
yel_state = 0;

pi = pigpio.pi()

# GPIOピンの設定と初期化
pi.set_mode(LED_RED, pigpio.OUTPUT)
pi.set_mode(LED_YEL, pigpio.OUTPUT)
pi.set_mode(SW_RED, pigpio.INPUT)
pi.set_mode(SW_YEL, pigpio.INPUT) 
pi.set_pull_up_down(SW_RED, pigpio.PUD_UP) 
pi.set_pull_up_down(SW_YEL, pigpio.PUD_UP)
pi.write(LED_RED, pigpio.LOW)
pi.write(LED_YEL, pigpio.LOW)

while True:
    # スイッチのピンの読み取り
    sw_red = pi.read(SW_RED)
    sw_yel = pi.read(SW_YEL)
    # スイッチが押されたらLEDのON/OFFを切り替える
    if sw_red == 0:
        if red_state == 0:
            pi.write(LED_RED, pigpio.HIGH)
            red_state = 1
        else:
            pi.write(LED_RED, pigpio.LOW)
            red_state = 0
    if sw_yel == 0:
        if yel_state == 0:
            pi.write(LED_YEL, pigpio.HIGH)
            yel_state = 1
        else:
            pi.write(LED_YEL, pigpio.LOW)
            yel_state = 0
    time.sleep(0.5)
```
### 回路
最終的な回路はこんな感じになります

![IMG_20190630_212246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326104/c9d1e456-1de4-b4e3-74d1-7a8a2c84a690.jpeg)
TortoiseSVNの差分表示ツールとしてVSCodeを利用する

TortoiseSVN内蔵の差分表示ツールは背景が白なので、各種OS・アプリでダークモードに利用している人には目の負担が大きい
そのような場合に、VSCodeを差分表示ツールとして設定すれば、背景が黒になるため目の負担を軽減できる

# 設定手順
前提として、TortoiseSVNとVSCodeは既にインストールされているとする

エクスプローラで右クリックし、「TortoiseSVN」＞「設定」を選択する

「差分ビューアー」で、「異なるリビジョンのファイルの比較に使用するプログラムの設定」を「外部」に選択し、プログラムに以下を入力する
_※VSCode本体のディレクトリは異なる場合があるので、自分の環境に合わせて適宜修正する_

> C:\Users\ユーザ名\AppData\Local\Programs\Microsoft VS Code\Code.exe --wait --diff %base %mine

![TortoiseSVNとVSCode_設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/40185f2e-2dc7-98d8-a9db-18bb40f1b1ec.png)

「OK」をクリックすれば設定完了

# 差分表示手順
TortoiseSVNのログ画面から、差分を表示したいファイルをダブルクリックする
![TortoiseSVNとVSCode_ログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/5ba7fdb5-a8be-a250-286b-cad4167d9eb6.png)

VSCodeが起動し、差分が表示される
![TortoiseSVNとVSCode_diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125334/2df96f38-be04-cd82-f38f-a77e347fb0cd.png)

# その他
コンフリクト手動編集もVSCode内で実施したいが、その方法は現在調査中

# 参考
https://qiita.com/satokaz/items/55a3b076979e3f9d0e9b
2019/06/30 のTips

##1. lsusbコマンドを実行しても lsusb: command not found になる件

[参考にした記事](https://sorrelfolia.wordpress.com/2015/11/04/centos-7-lsusb%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)

しかし上手くいかなかったので別のやり方を探す

[参考にした記事2](http://www.gadgets-today.net/?p=1024)

##2. 結局GRUBって何よ????

[参考にした記事](https://wa3.i-3-i.info/word15559.html)

[参考にした記事2](https://eng-entrance.com/linux-bootloader)

[参考にした記事３](http://enakai00.hatenablog.com/entry/2015/11/27/152442)

##3. vi /etc/default/grub　で編集したら　E45: 'readonly' option is set (add ! to override)

[参考にした記事](https://qiita.com/shuthimaru/items/2334f63845d8b0d85bdd)

##4. ランレベルって???

[参考にした記事](https://qiita.com/takahirono7/items/8b971cd1cf2ddcfe0e04)

##5. Linuxのdateでの日時を変更したい

[参考にした記事](https://qiita.com/na0AaooQ/items/af6b853faf32c58c21d3)

##6. linuxのインストールの下準備のあれこれ

[参考にした記事](https://eng-entrance.com/linux-package-install)

[参考にした記事2](https://loups-garous.hatenablog.com/entry/20120912/1347470198)

##7. rpmの下準備

[参考にした記事](https://qiita.com/pa_pa_paper/items/f585c2c4aed3a8b77d57)

##8. Ping-tで201合格した人の話

[参考にした記事](https://hack-le.com/47281707-2/)

##9. stack over flowの使い方

[参考にした記事](https://qiita.com/anqooqie/items/46c2b28eb50c81b151f2)
初心者がconohaでVPSを借りてnginxでphpページを公開するまで -mariaDB・DBeaver編-

#mariaDBとDBeaverでデータベースを扱う

###1:最新のmariaDBをインストールする
```bash
#root権限で以下の作業を実行する
sudo -s

#aptの一覧にmariaDBを追加する
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

#aptの一覧の更新
apt-get update

#aptの一覧からmariaDBの最新のバージョンを確認(今回は10.4だった)
apt list|grep -i mariadb-server

#mariaDBをaptでインストール
apt install mariadb-server-10.4
```

###2:mariaDBのセットアップをする

```bash
#root権限で以下の作業を実行する
sudo -s

#mariaDBのセットアップを開始する
mysql_secure_installation
→基本的には[Y]または[Enter]でセットアップを進めてOK
→ただし、「New password」と「Re-enter new password」ではrootに設定したいパスワードを入力すること。

#文字コードを変更する
vi /etc/mysql/mariadb.cnf
→ character-set-server の値を utf8mb4 に

#DBeaverと繋がるように設定する
vi /etc/mysql/my.cnf
→ bind-address をコメントアウトする

#mariaDBを再起動して設定を反映させる
systemctl restart mariadb
```

###3:mariaDBのユーザーの追加と権限の設定をする

```sql
/*root権限で以下の作業を実行する*/
sudo -s

/*mariaDBにログインする*/
mariadb

/*DBeaverで利用するユーザーを追加する。*/
CREATE USER 'ユーザー名'@'%' IDENTIFIED BY 'パスワード';

/*ユーザーの権限を変更する*/
GRANT all ON *.* 'ユーザー名'@'%' IDENTIFIED BY 'パスワード';

/*mariaDBからログアウトする*/
QUIT
```
ユーザーの追加をする際にホストを```'%'```ではなく```'localhost'```にしてしまうと
DBeaverで接続できなくなります。

###4:DBeaverで接続する

https://dbeaver.io/
にアクセスしてDBeaverのインストーラーをダウンロード。
そしてインストーラーを起動して、ガイド通りにインストールしてください。

DBeaverを起動すると接続設定ウィンドウが開かれると思うので
まずはデータベースの設定を入力する。

入力し終わったら「ネットワーク」→「SSHTunnel」のタブに移動して
今度はSSHの設定を入力していく。

入力し終わったら接続テストをして完了！

###EX:DBeaverが接続テストエラーを吐く…

・```0 byte from 4```というようなエラーが出る場合は
mariaDBの設定ファイルである ```/etc/mysql/my.cnf``` の中の
```bind-address```をコメントアウトしていない可能性が高い。

・データベースに接続できなかったぜ！みたいなエラーが出る場合は
mariaDBのユーザー追加の時にホストを'%'にしていない可能性が高い。

#これでデータベースを扱える
…ハズ。
初心者はデータベースのユーザーのホスト指定が重要だなんて知らないので要注意！