OmniAICreator/Qiita-1.07M huggingface dataset:
今からでも遅くない!! JenkinsをUbuntuにインストール

# いきさつ

私の家には安鯖があるんですが、Xeon & RAM 32GBと結構高性能なのにまるで活用されていません。これは宝の持ち腐れで終わりかねないですね。ちょうど開発したいサービスが3個くらいあるので、DevOpsを取り込んだ開発をしたいと思い、今さらですが安鯖にJenkinsを入れていきます。


# 環境

いつものようにOSの環境を載せておきます。

```:terminal
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.2 LTS
Release:	    18.04
Codename:	    bionic
```


# Jenkins インストール

公式ドキュメントに沿ってインストールしていきます。

- 参考
    - [（公式ドキュメント）How To Install Jenkins on Ubuntu 18.04 | Linuxize](https://linuxize.com/post/how-to-install-jenkins-on-ubuntu-18-04/)

```bash
sudo apt update -y
sudo apt install -y openjdk-8-jdk
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update -y
sudo apt install -y jenkins
```

## 動作確認

`systemctl` コマンドを打ちましょう。4行目のように `active(excited)` になっていれば成功です。

```terminal:terminal
$ systemctl status jenkins
● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; generated)
   Active: active (exited) since Mon 2019-09-23 21:43:49 JST;
     Docs: man:systemd-sysv-generator(8)
    Tasks: 0 (limit: 9460)
   CGroup: /system.slice/jenkins.service

Sep 23 21:43:47 VM-Ubuntu-Server systemd[1]: Starting LSB: St
Sep 23 21:43:47 VM-Ubuntu-Server jenkins[195303]: Correct jav
Sep 23 21:43:47 VM-Ubuntu-Server jenkins[195303]:  * Starting
Sep 23 21:43:47 VM-Ubuntu-Server su[195356]: Successful su fo
Sep 23 21:43:47 VM-Ubuntu-Server su[195356]: + ??? root:jenki
Sep 23 21:43:47 VM-Ubuntu-Server su[195356]: pam_unix(su:sess
Sep 23 21:43:48 VM-Ubuntu-Server su[195356]: pam_unix(su:sess
Sep 23 21:43:49 VM-Ubuntu-Server jenkins[195303]:    ...done.
Sep 23 21:43:49 VM-Ubuntu-Server systemd[1]: Started LSB: Sta
```

## Ubuntuの再起動時に自動で起動

`systemctl enable jenkins` をしておくとOSが再起動しても自動で `systemctl start jenkins` をやってくれます。

```terminal:terminal
$ sudo systemctl enable jenkins
jenkins.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable jenkins
```


# Jenkins アンインストール

Jenkinsを削除する方法も載せておきます。

```terminal:terminal
$ sudo systemctl stop jenkins  # まずJenkinsを止めます。
$ systemctl status jenkins  # 止まったか確認しましょう。OUTPUTは途中から省略
● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; generated)
   Active: inactive (dead) since Mon 2019-09-23 22:00:30 JST;
     Docs: man:systemd-sysv-generator(8)
$ sudo apt-get remove --purge jenkins  # Jenkinsを削除します。OUTPUTは省略
$ systemctl status jenkins  # ちゃんとアンインストールされたか確認しましょう
Unit jenkins.service could not be found.
```


# 雑談

JenkinsなどのOSSの公式ドキュメント、非常にわかりやすいですね。
正直、インストールするだけなら中学生レベルの英語力でも問題なさそうです。
ウチのCTOが言っていました。エンジニアがグローバルで働く上で必要な力の一つはドキュメントを書く力だと。
Qiitaへの投稿を通じてドキュメントの能力も伸ばしていきたいですね。
新規購入した端末のGoogle Playでダウンロードが保留されて困った

Google Playで、アプリの更新ができなくて、困っていました。
次も、同じことで困らないようにメモしておきます。

### 現象

すべての更新対象のアプリが「**ダウンロードを保留しています**」の状態になります。
再起動・キャッシュのクリアなどを試しても、解決できませんでした。

### 今回の解決策

上記現象になる原因は、他にもあるかもしれませんが、
今回は、Androidを買ってから、**セットアップを完了していない**状態で利用を始めたことが原因でした。
セットアップを完了すると、「**ダウンロードを保留しています**」の状態のアプリの更新処理が進みました。
scanner

##scannerについて

###intのscanner

```java

System.out.print("〇〇：");            
int 〇〇 = scanner.nextInt();

```

###Stringのscanner

```java

System.out.print("〇〇");            
String 〇〇 = scanner.next();

```

###doubleのscanner

```java

System.out.print("〇〇");            
double 〇〇 = scanner.nextDouble();
Windows10でVirtualBOX上でCentOSを動かす（初心者）。まず、64bit選ばせてくれない対策あたりから。

#目的
**Windows10**のノートPCにて、**VirtualBOX**を用いて**CentOS**を動かそうとしている。
**わたしは、この手の作業は、非常に苦手。**
VirtualBOXは、6より5が安定しているという情報を見かけたので、
VirtualBox-5.2.32-132073-Win
をインストール。

#64bitが選べない対策
使いたいOSを選ぼうとすると、
32bitのOSしか選択候補に出てこない。

どうも、
BIOSにて、
**「Intel Virtualization Technology」が「Disable」**
になっているのが原因らしい。

以下の記事を参考にした。
https://did2memo.net/2015/07/10/virtualbox-64-bit-os/

類似の記事、結構あり。

**上記をenableにしたら解決**

#まとめ

重複するような内容の記事を書く意味はないかもしれないが。。。
2019年に、このような状態に出会って、解決したという情報を残す意味は、
わずかにある気がしたので、記載。
Terraformで1つのセキュリティグループに複数のルールを設定する

# やりたいこと
下記画像のように、1つのセキュリティグループに対して2つ以上のルールを設定する。
これをTerraformでやりたい。
<img width="966" alt="スクリーンショット 2019-09-23 21.27.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154121/cd689ca3-2fd8-e2dd-d1cc-db2b872ac38b.png">

例えば、Webサーバー用のセキュリティグループを作成し、80番ポートと443番ポートへのインバウンドを設定するなどといったことである。

# Terraform実装
## aws_security_groupを書く
まずは1つのセキュリティグループに対し、80番ポートへのインバウンドルールを追加してみよう。
下記のように、 `aws_security_group` の中に `ingress` を指定することで、セキュリティグループとインバウンドルールを作成できる。

```security_group.tf
# web_serverというセキュリティグループを作成し、そこに80番ポートのインバウンドルールを追加する
resource "aws_security_group" "web_server_sg" {
  name        = "web_server"
  description = "Allow http and https traffic."
  vpc_id      = "xxxxx" # デフォルトvpcのID

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }
}
```

さらに `web_server` セキュリティグループに対して、443番ポートへのインバウンドルールも追加してみよう。
上で書いた `web_server_sg` にもう一つ `ingress` を追加したら良いんじゃない？となるだろう。
下記のような感じ。

```security_group.tf
resource "aws_security_group" "web_server_sg" {
  name        = "web_server"
  description = "Allow http and https traffic."
  vpc_id      = "xxxxx" # デフォルトvpcのID

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }

  # このように、2つ目のingressを書きたい
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [
      "0.0.0.0/0"
    ]
  }
}
```
しかし、 **このやり方だとエラーになってしまう**。
1つの `aws_security_group` の中に `ingress` は1つしか書けないのである。

## aws_security_group_ruleを使おう
もちろん「Terraformを使うときには1つのセキュリティグループに対して1つのルールしか設定できない」という制約はなく、解決策はバッチリ用意されている。
`aws_security_group_rule` リソースを使おう。

今回の場合だと、下記のように書く。

```security_group.tf
resource "aws_security_group" "web_server_sg" {
  name        = "web_server"
  description = "Allow http and https traffic."
  vpc_id      = "xxxxx" # デフォルトvpcのID
  # ここにingressを書かず、ルールはaws_security_group_ruleを使って定義する
}

# 80番ポート許可のインバウンドルール
resource "aws_security_group_rule" "inbound_http" {
  type        = "ingress"
  from_port   = 80
  to_port     = 80
  protocol    = "tcp"
  cidr_blocks = [
    "0.0.0.0/0"
  ]

  # ここでweb_serverセキュリティグループに紐付け
  security_group_id = "${aws_security_group.web_server_sg.id}"
}

# 443番ポート許可のインバウンドルール
resource "aws_security_group_rule" "inbound_https" {
  type        = "ingress"
  from_port   = 443
  to_port     = 443
  protocol    = "tcp"
  cidr_blocks = [
    "0.0.0.0/0"
  ]

  # ここでweb_serverセキュリティグループに紐付け
  security_group_id = "${aws_security_group.web_server_sg.id}"
}
```

このように `aws_security_group_rule` を使い、web_serverセキュリティグループに紐付けたいルールを2つ作成する。
それらのルールの中で「どのセキュリティグループに紐付けるか」を指定する。
もっと多くのインバウンドルールやアウトバウンドルールを作成したい場合は、同じように `aws_security_group_rule` を増やしていくだけである。

こうすることで、Terraformを使用し、1つのセキュリティグループに対して2つ以上のルールを設定することができる。

# 公式サイト
* [aws_security_group](https://www.terraform.io/docs/providers/aws/d/security_group.html)
* [aws_security_group_rule](https://www.terraform.io/docs/providers/aws/r/security_group_rule.html)
Next.js 9でSSR

#はじめに
ReactでSSR（Server Side Rendering）フレームワークとしてNext.jsは有名です。

#Next.jsの新しい特性
- Built-in Zero-Config TypeScript Support: Build your application with increased confidence, thanks to automatic TypeScript support and integrated type-checking.
- File system-Based Dynamic Routing: Express complex application routing requirements through the file system without the need for a custom server.
- Automatic Static Optimization: Create ultra-fast websites that leverage Server-Side Rendering and Static Prerendering by default without compromising on features.
- API Routes: Quickly build back-end application endpoints, leveraging hot-reloading and a unified build-pipeline.
- More Production Optimizations: Applications are more responsive than ever thanks to in-viewport prefetching and other optimizations.
- Improved DX: Unobtrusive, ease-of-use improvements to help you develop at your best.

出典：https://nextjs.org/blog/next-9

#デモプロジェクト作成してみる
## インストール
フォルダー「nextjs-demo」を作成し、`npm init`を実行後、`npm install --save next react react-dom`を実行

## package.jsonファイル修正
```package.json
"scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
}
```
## pagesフォルダーにファイル作成
./pages/index.jsファイルに

```index.js
function Home() {
    return <div>ようこそ。</div>
}

export default Home
```

## next.js起動
`npm run dev`

## アクセス
http://localhost:3000

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/abaf7cf3-40a5-0e03-2ce5-e7e2d7f8c7f7.png)

これで一番シンプルのページができました。

#Typescriptに変更
`npm install --save-dev typescript @types/react @types/node`
`mv pages/index.js pages/index.tsx`
`npm run dev`

これでTypescript形式でもアクセスできます。

typescriptも自動インストールのようですが、私のPCはエラーがあって手動でインストールしました。

#Router
Next.jsはpagesディレクトリのファイル、サブディレクトリのファイルをアクセスできます。

URLのpathにパラメータを渡したい場合は、正規表現の感じで動的にマッピングする必要があります。
このニーズでも問題ありません。

express.jsではよくある「/xxx/:id」の形式は、next.jsは「pages/xxx/[id].js」を作成して対応できます。

##サンプル：　/mypage/:userId
pagesディレクトリに「mypage」フォルダーを作成し、「mypage」の中で「[userId].js」のファイルを作成

```[userId].js
import React from 'react';
class MyPage extends React.Component {
    static async getInitialProps({ query }) {
        const { userId } = query

        return { userId }
    }

    constructor(props) {
        super(props);
        this.state = {
            userId: props.userId
        }
    }

    render() {
        return (
            <div>
                URLのPathからuserId: {this.state.userId}
            </div>
        )
    }
}

export default MyPage
```

##アクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/a2825495-ddff-d405-e9db-a40696843bae.png)

[userId].jsのコードの結果を正しく表示されました。

これでURLとファイルの作成はもっと理解しやすくなります。

簡単にデモをやってみました。

以上
pythonで使うコマンドをまとめる

#pythonでよく使うコマンドをまとめる

##調べる系
####pythonのバージョンを調べる

```
$python --version
```

####pythonのインストール先を調べる

```
$which python
```

##venvによる仮想環境の作成
Homebrewを使って仮想環境を作成する。
仮想環境を作成するディレクトリで実行する。

####venvによる仮想環境の作成・有効・無効

```
`仮想環境の作成`
$python -m venv `仮想環境`

`仮想環境を有効化`
$ source 仮想環境/bin/activate

`仮想環境を無効化`
$ deactivate
```

####ライブラリのインストール
pipを使ってインストールする

```
`インストール`
$pip install インストールするライブラリ

`仮想環境に何をインストールしたかを確認`
$ pip freeze -l

`インストールしたライブラリのアップデート`
$ pip list -o | awk '{print $1}' | xargs pip install -U
```


##参考
・【2019年版】Pythonインストール・Mac編【長く安全に使える環境構築】(https://basicincome30.com/python-install-mac)
【JavaScript】重複を取り除くにはSetオブジェクトを使おう

#はじめに


プログラミング歴3ヶ月の素人が書いています。（間違っていたらご指摘ください）


* JavaScriptのSetオブジェクトについて


上記についてまとめます。


#今回の目的

重複する値を含む配列を、重複のない配列に変換します。
その際に、Setオブジェクトを活用します。



#Setオブジェクトについて

Setオブジェクトは、**重複のない**コレクションです。


```javascript
const set1 = new Set([1, 2, 3, 4, 5]);
```

上記のように`new Set()`して作成します。

**Setの中身は一意であることが保証されています。**


#重複を含む配列からSetオブジェクトを作成する

```javascript
const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
 
const setNums = new Set(numbers)

//{2, 3, 4, 5, 6, 7, 32} <= Setオブジェクト
```

重複を含む配列からSetオブジェクトを作成しました。
重複していた値がなくなっています。


#Setオブジェクトを配列に戻す

```javascript
const uniqueNums = Array.from(setNums)

// [2, 3, 4, 5, 6, 7, 32]
```

`Array.from()`を利用することで、重複のないSetオブジェクトから配列を改めて作成できました。


#まとめ

配列をSetオブジェクト化することで、まるで重複を取り除くような処理が可能です。
配列にまた戻して利用することもできます。
TypeScript:Node.jsのhttpパッケージでリバースプロキシを立てる

TypeScriptでNode.jsのhttpパッケージを用い、リバースプロキシを立てる方法を説明する。

まず、次が、リバースプロキシを立てるサンプルコードになる。

```ts
import http, {IncomingMessage, ServerResponse} from 'http'

// ターゲットとなるHTTPサーバ
const serverPort = 4000
const server = http.createServer((req: IncomingMessage, res: ServerResponse) => {
    res.end('OK')
})

server.listen(serverPort)

// リバースプロキシ
const reverseProxy = http.createServer((requestFromClient: IncomingMessage, responseToClient: ServerResponse) => {
    const options = {
        hostname: '127.0.0.1',
        port: serverPort,
        path: requestFromClient.url,
        method: requestFromClient.method,
        headers: requestFromClient.headers,
    }

    const requestToServer = http.request(options, (responseFromServer: IncomingMessage) => {
        responseToClient.setHeader('X-Proxy', 'Node.js Proxy')
        responseToClient.writeHead(responseFromServer.statusCode || 500, responseFromServer.headers)
        responseFromServer.pipe(responseToClient, {end: true})
    })

    requestFromClient.pipe(requestToServer, {end: true})
})

reverseProxy.listen(8000)
````

## 解説

リバースプロキシの仕組みは単純で、ポート8000番でリバースプロキシがHTTPリクエストを受け付け、それをポート4000番のHTTPサーバに送信、HTTPサーバからレスポンスが返ってきたら、それをリバースプロキシがクライアントに渡すという流れになる。

```ts
const reverseProxy = http.createServer((requestFromClient: IncomingMessage, responseToClient: ServerResponse) => {
    // ポート8000番でリバースプロキシがHTTPリクエストを受け付け
    // それをポート4000番のHTTPサーバに送信、
    // HTTPサーバからレスポンスが返ってきたら、
    // それをリバースプロキシがクライアントに渡す処理。
})

reverseProxy.listen(8000)
````

今回最初に示したサンプルコードでは、レスポンスに`X-Proxy`ヘッダーを追加するようになっているが、上の処理内容次第では、送信先のURLを変えたり、ロギングしたりすることができる。

## 参考文献

* [HTTP | Node.js v12.10.0 Documentation](https://nodejs.org/api/http.html)
* [javascript - How to create a simple http proxy in node.js? - Stack Overflow](https://stackoverflow.com/questions/20351637/how-to-create-a-simple-http-proxy-in-node-js)ln
phpinfo()をコマンドラインで呼び出したいのです

# 事の顛末
PHPで調査することがあって、php.iniの場所を確認したかったのですが、どこにあるのかわかりません。。phpinfo()で出力されるということなので、phpinfo()を実行したい・・・。おや?、Apacheから呼び出さないとダメですか??? コマンドから直接実行できませんか???

# こうすればいいらしい
```
php -r 'phpinfo();'
```
今回は、php.iniの場所を確認したかったので、こうしました。

```
php -r 'phpinfo();' | grep php.ini
```
ひとまず、解決。

# ところで -r パラメータってなんですか?
やり方はわかったのだけれども、パラメータの意味が分からないとキモチが悪いので、[マニュアル](https://www.php.net/manual/ja/features.commandline.options.php)で確認。
-r の解説を見てみると

> -r \<code>        Run PHP \<code> without using script tags <?..?>

ふむふむ、スクリプトタグ無しで、コマンドラインからコードが実行できると。

> -r --run このオプションにより、コマンドラインのみで PHP の実行ができるようになります。 PHP の開始および終了タグ (<?php および ?>) は不要で、これらを付けると パーサエラーとなります。

なるほど、長い形式では --run ってことですね。イメージつきました。

# -i (--info) があるではないですか
ググったときに、最初の方で見つけたのが -r パラメータだったので、その時は -r で解決してしまったのですが、もうちょっとよく見てみると、  -i とか --info とかありますね。

```
php -i
php --info
```

ちなみに、[マニュアル](https://www.php.net/manual/ja/features.commandline.options.php)には

>このコマンドラインオプションは、phpinfo() をコールし、 結果を出力します。PHP が正しく動作していない場合、 php -i を実行し、情報テーブルの前または中に 出力されるエラーメッセージを調べることをお勧めします。 CGI モードの場合、 出力が HTML 形式で行なわれるため 量がかなり多くなることに注意してください。

と記載されているので、こちらで用は足りていたみたい。。。でも、-r でコマンドから phpinfo() に限らず、phpコードが実行できることは勉強になりました!!

# 参考文献
[phpinfoの内容をコマンドラインで確認する](https://qiita.com/bitarx/items/074a5ad49af6561f6b3b)
[基礎だけど実は大切!!phpinfo関数を使ってPHPの設定内容を理解しよう](https://www.sejuku.net/blog/49565)
ディレクトリ直下の git 管理していないディレクトリをまとめる


```bash
mkdir "{FullPath}/no-git"
find "{FullPath}" -name "*" -type d -mindepth 1 -maxdepth 1 -print0 -exec sh -c "cd {} && git remote -v || mv \"{}\" \"{FullPath}/no-git\" " \;
```
k3dで永続ボリューム(PersistentVolume)を使う

## やること、わかったこと

- 永続ボリューム上にファイルを作成して、Podを再作成してもちゃんと残っていることをチェック
- minikube,microk8sなど他のk8sと違いはなさそう
- ただ、今のところDynamicProvisioningが対応していないよう

## 参考
https://github.com/rancher/local-path-provisioner


## k3d起動

```
k3d create
```

## kubetclコマンドを実行できるように環境変数をセット

```
export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"
```

## kubectlコマンド実行できるか確認

```
kubectl cluster-info
```

### 出力結果

```
Kubernetes master is running at https://localhost:6443
CoreDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```

## ストレージ検証セットをデプロイ

```
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
```

## podがデプロイされているか確認

```
kubectl -n local-path-storage get pod
```

### 出力結果

```
NAME                                    READY   STATUS    RESTARTS   AGE
local-path-provisioner-848fdcff-k8vdm   1/1     Running   0          2m18s
```

## ログも確認

```
kubectl -n local-path-storage logs -f  local-path-provisioner-848fdcff-k8vdm
```

### 出力結果 

```
time="2019-09-23T07:19:05Z" level=debug msg="Applied config: {\"nodePathMap\":[{\"node\":\"DEFAULT_PATH_FOR_NON_LISTED_NODES\",\"paths\":[\"/opt/local-path-provisioner\"]}]}"
time="2019-09-23T07:19:05Z" level=debug msg="Provisioner started"
```

## PVとPVCをデプロイ

```
kubectl create -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pvc.yaml
kubectl create -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pod.yaml
```

## デプロイされているか確認

```
kubectl get pv
kubectl get pvc
```

## ファイルを作成する

```
kubectl exec volume-test -- sh -c "echo local-path-test > /data/test"
```

## podを削除

```
kubectl delete -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pod.yaml
```

## podを再作成

```
kubectl create -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pod.yaml
```

## catでファイルを確認 

```
kubectl exec volume-test cat /data/test
```

### 出力結果
Podを消してもpv上のファイルは保持されていることがわかりました

```
local-path-test
```

## pvとpvcを削除（後片付け）

```
kubectl delete -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pod.yaml
kubectl delete -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/examples/pvc.yaml
```
妄想プロダクト室「CUSHION LABEL」のプロトタイプ

![cushion-label.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/f5719cad-7e0d-a882-310a-086521939851.jpeg)



# つくったモチベーション
ハッカソンで、”座る”体験をハック！




# 「CUSHION LABEL」概要
クッションから届ける音楽レーベル。
↓デモ動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【Cushion Label】<br>座ると音楽が聞けるクッション！<br>（動画は音なしでわかりにくい、、、）<a href="https://t.co/N2NrYb5zSZ">https://t.co/N2NrYb5zSZ</a></p>&mdash; taichi (@MakingEmo) <a href="https://twitter.com/MakingEmo/status/1176148457884532738?ref_src=twsrc%5Etfw">September 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

↓画面
【立ち上がり】
<img width="375" alt="custom – 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/7e44561b-f64c-18b6-13df-152cb2f7cab8.png">

【聞きたい音楽の情報を入力】
<img width="375" alt="custom – 3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/adc0c548-5a61-099d-3c8e-43eb9367ca99.png">

【音楽を再生】
<img width="375" alt="custom – 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/5a2bde23-a5d8-d663-9c31-3258a079eaf8.png">

## 技術・素材
- LINE Things LIFF
- javascript
- html/css
- obnize
- 圧力センサー
- クッション　
- Amper music api（今回は静的にmp3のファイルを複数用意し、jsにて出し分け）

## 構成図
![cushion-label-architecuture.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/77c040b0-b201-69f5-51aa-d39f0c791cb4.jpeg)
異性表示をenumで実装してみた

# enumを使って異性表示を実装

Railsでマッチングアプリを作成していたのですが、ユーザー一覧を異性のみ表示させたいと思いました。

そこで、以前の公開・非公開設定でも使ったenumを使用して、実装しました。

ざっとした実装方法の流れは、Userテーブルにenumのカラムを追加し、ユーザー一覧で条件分岐させるといった感じです。

それではやり方を書いていきたいと思います。

## 前提条件
既にdeviseが導入されている環境であることを前提とします。

Ruby version 2.5.1
Rails version 5.2.3

参考記事：https://madogiwa0124.hatenablog.com/entry/2017/12/24/222156


## sexカラムをUsersテーブルに追加

sexカラムをUsersテーブルに追加します。

enumでカラムを追加するので、型はinteger型となっています。

```ターミナル.
rails g migration add_sex_to_users sex:integer
```
```migrationfile.
class AddSexToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :sex, :integer
  end
end
```
記述を確認したら、rake db:migrateをします。

## Userモデルにenum記述

sexカラムに男性を選んだ時と女性を選んだ時に対応した、それぞれ番号を保存させる記述をする。

```model/user.eb
  enum sex: { man: 0, woman: 1}
```
男性を選択した時には0、女性を選択した時には1が保存されます。

これでカラムを追加するための準備が完了です。

次にビューの方で実際にカラムが保存させる記述を行います。


## ビューに性別選択のラジオボタンを追加

ビューの方で、性別選択のラジオボタンを追加します。

今回は、新規登録時に性別を保存させたいので、devise導入時に作成されたdevise/registrations/new.html.erbに下記のコードを追加します。

```new.html.erb
<div class="sex-field">
    <%= f.label :Sex %><br />
    <%= f.label :man  %>
    <%= f.radio_button :sex, :man %>
    <%= f.label :woman  %>
    <%= f.radio_button :sex, :woman %>
</div>
```
また、deviseでは、paramsで送られてきた値をapplication_controllerで許可設定をしなけらばいけないので、permitの記述のところに:sexを加えます。

```application_controller.rb
class ApplicationController < ActionController::Base

  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :avatar, :profile, :sex])
  end

end
```
これで、新規登録ボタンが押された時に、性別のカラムに数値が保存されるようになりました。

あとは、ユーザー一覧のビューの方で条件分岐させるのみです。

## ユーザー一覧で異性のみを表示

まずコントローラーの方では、whereメソッドを使って、現在ログインしているユーザー以外をActive Recordからとってくるコードを記述します。

ここでは、ページネーションを実装しているので5件ごとにユーザーページを作成し、最新で登録されたユーザーが最初に来るような記述をしています。

```users_controller.rb
  def index
    @users = User.where.not(id: current_user.id).page(params[:page]).per(5).order("created_at DESC")
  end
```

そして、ユーザー一覧の、users/index.html.erbにif文で条件を加えます。

users/index.html.erbのビューでは、部分テンプレートを使っています。

```users/index.html.erb
<div class="main users-index">
  <div class="container">
    <h1 class="users-heading">ユーザー一覧</h1>
      <%= render 'user', users: @users %>     
    <%= paginate(@users) %>
  </div>
</div>
```

部分テンプレート元で、@usersはusersという変数に入れているので、users.で記述が可能です。

条件文は、一番上に加えます。

```
<% if current_user.sex != user.sex %>
  <div class="card-group user-card-group">
    <%= image_tag user.avatar,class:"user-avatar"%>
    <div class="card-body user-card-body" %>
      <h4 class="card-title user-card-title">
        <%= user.name %>
      </h4>
      <p class="card-text">プロフィール：
        <%= user.profile%>
      </p>
      <div class="button_wrapper"> 
        <button class="btn btn-red100_rsd btn-block">
          <%= link_to "#{user.name}さんのページに移動する", "/users/#{user.id}",class:"button-a"%>
        </button> 
      </div>
    </div>
  </div>
<% end %>
```

これで、異性表示の完成です。


# enumを使えば異性表示は簡単にできる

異性表示は、enumを使って番号で性別を管理することによって簡単に実装できるので、マッチングアプリやSNSアプリを作成している型はぜひ参考にしてみてください。
Python×Automagica：社員紹介記事を自動収集した話

# はじめに
###■背景
当社はベンチャーということもあり、人の入れ替わりが比較的多い。
また、社員は基本的に客先に常駐しており、案件が異なると全く顔を合わせないこともある。
「お互いに顔と名前が一致しない」という事態が多々起きていることを経営層が問題視し始めた。

一方で、入社時にはSNSに自己紹介記事を載せるが、色んな話題が飛び交っている内に古い記事は参照しにくくなっていた。

###■目的###
そこで、今いる社員の名簿を元に、`Automagica`にて、記事のURLとスクショを自動収集するプログラムを作成し、出力結果を共有することで問題解決を図った。

###■捕捉
なお、`Automagica`自体については、先人達の記事を参照されたい。
[記事１：Automagica : ベルギー発Oakwood Technologies BVBA製のRPAの日本語解説](https://qiita.com/hirohiro77/items/4ae03d1dfd7c353dc9e3)
[記事２：automagicaことはじめ](https://qiita.com/eriho/items/9f9d887f380b64beaee7)
[記事３：Python×業務効率化 Automagicaでブラウザを自動で動かしてみた](https://qiita.com/k_mayo_beam/items/0dd5bc768a1f8dd421fc)

# 作ったもの
###■インプット
社員の氏名をリスト化したテキストファイル
###■プロセス
１、Chromを起動
２、記事検索ページに遷移し、「社員の氏名　自己紹介」で記事を検索
３、検索結果の最上位記事のリンクをクリック
４、該当ページのURLをURLリストに格納、及び、該当ページをスクショ保存
５、２～４を社員リストの分だけ繰り返し
６、URLリストをテキストファイルとして出力

###■アウトプット
・各社員紹介ページのスクショ
・各社員紹介ページのURL

# コード
一部は社内情報の為マスキング。

```python:search_shain_article.py
from automagica import *
import time

#SNSの検索窓のxpath
xpath_SerachText = '//*[@id="Pagesearch_999"]/div/div/div/div/label/input'
xpath_SerachButton = '//*[@id="Pagesearch_999"]/div/div/div/div/button'
xpath_LoginID = '//*[@id="id"]'
xpath_LoginPass = '//*[@id="pass"]'

#ログイン情報
LoginID = 'LOGIN_ID'
LoginPass = 'LOGIN_Pass'

#URL格納リスト
url_list = []


#Chromeを起動してウィンドウ位置と大きさ調整
browser = ChromeBrowser()
browser.set_window_position(0, 0)
browser.set_window_size(1000, 600)

#SNSを立ち上げてログイン
browser.get('https://www.XXXXXXX.com')
browser.find_element_by_xpath(xpath_LoginID).send_keys(LoginID)
browser.find_element_by_xpath(xpath_LoginPass).send_keys(LoginPass)
time.sleep(1)
ClickOnPosition(200, 500)

#インプットファイルの行数分繰り返す
for ShainName in open("meibo.txt", "r"):

    #改行コードを削除
    ShainNameRstrip = ShainName.rstrip('\n')

    #SNSで検索ページを開く
    browser.get('https://www.XXXXXXX.com/YYYYYY')

    #検索する内容
    content = '社員紹介記事　' + ShainNameRstrip

    #検索窓を探して内容を検索
    browser.find_element_by_xpath(xpath_SerachText).send_keys(content)
    browser.find_element_by_xpath(xpath_SerachButton).click()

    #検索結果の最上位のリンクをクリック
    time.sleep(3)
    ClickOnPosition(500, 200)

    #スクショ保存、URL格納
    time.sleep(3)
    filename = ShainNameRstrip + '.png'
    browser.get_screenshot_as_file(filename)
    URL_content = ShainNameRstrip + ' ' + browser.current_url
    url_ist.append(URL_content)    

#リストに書き出し
WriteListToFile(url_list, 'URLlist.txt')

#ブラウザを閉じて終了
browser.close()
```
#結果
###スクショ達
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269083/35448a8e-d6a2-4c9c-fea0-c78fa34b2766.png)
これをばら撒くことで、顔と名前とどんな人かを全員で共有出来た（はず）。
Herokuにデプロイしても、｢Heroku | Welcome to your new app!｣のメッセージが表示される

#概要
railsチュートリアルやっててHerokuデプロイしたけど「Hello　World!」が出ずに｢Heroku | Welcome to your new app!｣のメッセージが表示される。

#原因
以前デプロイしたリポジトリにデプロイしてた。

#対処
下記のコマンドに heroku create した時のURLを挿入し実行

```
$ git remote set-url heroku 新しいherokuのgitリポジトリURL
Vue+docker-compose 環境構築

## 環境構築 メモ
```dockerfile:Dockerfile
FROM node:8-alpine

WORKDIR /app

RUN apk update && \
    npm install -g npm @vue/cli &&\
    npm install yarn  #今回はyarnを使用
```
```docker-compose:docker-compose.yml
version: '3'
services:
  vue_app:
    build: ./docker
    ports:
      - 9000:9000
    volumes:
      - ./app:/app
    stdin_open: true
    tty: true
    command: /bin/sh
```

```shell:Workspaceにて
$ docker-compose build #build
$ docker-compose up -d
$ docker-compose exec {アプリ名} sh
# yarm add vue
# yarn global add @vue/cli
# vue ui -H 0.0.0.0 -p 9000  # cliのGUIツールを起動
                             #localhostではアクセスできないから注意
```
ブラウザで ”http://localhost:9000” と入力し表示できれば成功

> 参考記事　
[dockerについて](https://qiita.com/salvage0707/items/b77a742bad76b9191744)
[vueの設定について](https://qiita.com/akagire/items/ed3bdcf29c07f9970f8f)
[cliの使い方について](https://kawadev.net/docker-vue-bulma/)
TypeScript:Node.jsのhttpパッケージでHTTPサーバを立てる

TypeScriptでNode.jsのhttpパッケージを使ってHTTPサーバを立てる方法を紹介する。

## インストールが必要なもの

httpパッケージはNode.jsのビルトインモジュールなので、特にnpmで何か入れないといけないということはない。

## HTTPサーバを立てる最低限のコード

```ts
import http, {IncomingMessage, ServerResponse} from 'http'

const server = http.createServer((req: IncomingMessage, res: ServerResponse) => {
    res.end('OK') // レスポンスボディが「OK」になる
})

server.listen(4000) // 4000番ポートで起動
```

このコードをJavaScriptにコンパイルし、実行すると4000番ポートでHTTPサーバが起動する。

起動したサーバに対して、httpieでHTTPリクエストを送信する:

```bash
$ http localhost:4000
```

出力結果:

```http
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 2
Date: Mon, 23 Sep 2019 11:51:54 GMT

OK
```


## 参考文献

- [HTTP | Node.js v12.10.0 Documentation](https://nodejs.org/api/http.html#http_class_http_server)
kotlin staticメソッドと定数

# kotlinのstaticメソッド
kotlinではstaticメソッドはありません。ただしCompanion Objectsという仕組みを使えば実現できます。

```kotlin
class Foo {
    companion object {
        fun staticMethodTest() {
        }
    }
}

fun main() {
    Foo.staticMethodTest() //実行可能
}
```
# kotlinの定数
constを指定することでコンパイル時定数 (compile time constants) としてマークすることができます。
以下の場合どちらの値も参照可能です。

```kotlin
class Foo {
    companion object {
        val TEST_VAL1 = 1
        const val TEST_VAL2: Int = 2
    }
}


fun main() {
    println("TEST_VAL1 = ${Foo.TEST_VAL1}")
    println("TEST_VAL2 = ${Foo.TEST_VAL2}")
}
```
実行結果

```
TEST_VAL1 = 1
TEST_VAL2 = 2
```
ただしJavaでアクセスする場合にconstを指定している場合はFoo.TEST_VAL2でアクセスでき、constを指定していない場合はgetTEST_VAL1()という呼び出し方になります。
constを指定することによって以下のメリットがあります。

- コンパイル時定数となるので、パフォーマンスが良くなる。
- Javaとの相互運用性が保てる
Rails5でcookieの中身を見る方法

# 環境

- Rails 5.2.3
- Ruby 2.6.3

# 必要な情報

- cookieの値
- secret_key_baseの値
- encrypted_cookie_salt と encrypted_signed_cookie_salt はデフォルト値と想定
  - encrypted_cookie_salt (salt) = '`encrypted cookie`'
  - encrypted_signed_cookie_salt (signed_salt) = '`signed encrypted cookie`'

# コマンド

```ruby
def verify_and_decrypt_session_cookie(cookie, secret_key_base)
  cookie        = CGI::unescape(cookie)
  salt          = 'encrypted cookie'
  signed_salt   = 'signed encrypted cookie'
  key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
  secret        = key_generator.generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len]
  sign_secret   = key_generator.generate_key(signed_salt)
  encryptor     = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)

  encryptor.decrypt_and_verify(cookie)
end

cookie = 'cookie value comes here'
secret_key_base = 'secret_key_base value comes here'
verify_and_decrypt_session_cookie(cookie, secret_key_base)
```

# 参考URL

https://stackoverflow.com/questions/41474176/how-to-decrypt-a-rails-5-session-cookie-manually
Firebaseについて調べました！

**Firebase**という言葉をよく目にするので、
調べたものを簡単に自分用にも記載します。

##Firebaseってなに？

公式サイト：https://firebase.google.com/?hl=ja

Webアプリケーションやモバイルアプリケーションのバックエンドで行う機能を提供する、
クラウドサービス。
**→バックエンド側の処理をFirebaseが代行してくれる！**

バックエンドの処理を代行することで開発にかかる時間、手間の省略が可能で、
コスト節約にも繋がる。

つまり、簡単かつ効率的にアプリ作成ができるようになるということ。


・・・すごいな！

##メリットは？
上記にもあげたように、
**Firebase**にはアプリ開発において必要となるバックエンドの機能をほぼほぼ備えているので、
（公式サイトURLのプロダクトページにも記載あります。）

認証機能を使って簡単にログイン機能を実装できたり、
アクセス解析だって簡単にできるようになったりします。

開発コストを抑えたい人は取り入れるべきものだと考えた方が良い気がしました。


##最後に
Qiita内にもとても分かりやすくまとめてくれている方がいるので、
自分でも実際に使用してみようと思います。

グーグルアカウントがあれば、ログインが可能なので
始め方も比較的簡単で取っつきやすいなと感じました。

また、自分でも導入してみた結果なども追記で記していければなと思います。
Fortran 愛好家に贈る f2py で動かす matplotlib の調理法

# はじめに
世の中はpythonである。でもそれだけがいいとは思はない。一番速いコンパイラーはFortranなのだ。数値計算ならFortranの方が手っ取り早く世界最速のオブジェクトを吐く。
でも、グラフィック表示は苦手で、Pythonのmatplotlib Libralyを横目で見てため息をつく諸兄は多いはずだ。

ここに、世界一簡単だと思う方法で、Fortranの出力をMatplotlibに表示する方法を述べる。

# Fortran Program

``` sin.f90

       subroutine plot(n,x,a)
       integer, intent(in) :: n
       real(8), intent(out) :: a(n),x(n)
       do i = 1, n
        x(i) = i
        a(i) = sin((2*3.1415926/n) * i)
       end do
       end subroutine
```
宣言文の類を抜くと5行のプログラムである。これが読めないのにこの記事を読んでいる人がいたら不可解である。

# Python Script

``` plot.py
#! /usr/bin/python3
import sin
import matplotlib.pyplot as plt

x, y = sin.plot(1024)

plt.plot(x,y)
plt.show()
```
宣言を除くと3行。これぐらいは勘弁してほしい。しかも、x-y plotの範疇ならいじる必要はない。

# Link & Run

では実行しよう。
先ず、

``` shell
f2py -c sin.f90  -m sin -lm
```
これで、Fortran ProgramはPython ModuleにCompileされる。
で、実行。

``` shell
python3 plot.py
```
# お仕舞
Pythonアレルギーがちょっとは後退しただろうか。この先はmatplotlibのマニュアルを見て、うまくやってほしい。
Fortranの方はお任せするので活用していただければ幸いである。
ES2015からの変数

ES2015では変数の宣言として『var』の他に『let』という命令が増えました。
構文の書き方はvarと同じです。

```js
let hoge;
```

見た目はvarと同様ですが、varとletには明確な違いがあります。

#### 重複の禁止

letで変数を宣言した場合は同一の変数名の宣言は許可されずエラーを吐き出します。

<br>

```js
let hoge = 'ほげ';
let hoge = 'ホゲ';

// Uncaught SyntaxError: Identifier 'hoge' has already been declared


var huga = 'ふが';
var huga = 'フガ';

//  後から宣言したスクリプトに上書きされるhuga の中身は『フガ』
```

<br>

####  値の変更が許可されない定数

ES2015ではletの他にも値の変更が許可されない『定数』が実装されました。
宣言のしかたは下記となります。

```js
const TAX =1.08;
```

記述の仕方はvatやletと同様です。
C言語でa == 1 && a == 2 && a == 3をtrueにしてみたい

# C言語でa == 1 && a == 2 && a == 3をtrueにしてみたい

こちらを見てやってみました。
[https://qiita.com/tyu_ru_cpp/items/bec5ef79f351c17397a5](https://qiita.com/tyu_ru_cpp/items/bec5ef79f351c17397a5)

```.cpp
#include <iostream>
#define a (++value)
int value = 0;
int main() {
	std::cout << (a == 1 && a == 2 && a == 3);
	return 0;
}
```

結果

```
1
```

以上です。


※追記
出力部分以外もC++になってしまってますが、やっつけでこんな感じです


```.cpp
#include <iostream>
class A {};
bool operator ==(A&, int) {
	return true;
}
int main() {
	A a;
	std::cout << (a == 1 && a == 2 && a == 3);
	return 0;
}
```
RailsでActiveRecord::Base.connection.select_allを実行した時のSQLのエラーを分類する

RailsでActiveRecord::Base.connection.select_allを実行した時、SQLに誤りがあればActiveRecord::StatementInvalidの例外が発生します。

例えば存在しないSQLでfromが抜けている場合は以下の様な例外となります。

```ruby
select_all("select * hoge;") # fromが抜けている
```

```sql
PG::SyntaxError: ERROR:  syntax error at or near \"hoge\"\nLINE 1: select * hoge;\n                 ^\n: select * hoge;
```

`SyntaxError` や `syntax error at or near "hoge"` の情報を取得したかったので、正規表現で無理やり取得してみました。

`/PG::(.*):\sERROR:\s(.*)/`

- 1つめの`(.*)`にて、エラー種別を取得
- 2つめの`(.*)`にて、エラー詳細を取得

```ruby
err_type = e.message[/PG::(.*):\sERROR:(.*)/, 1]
# => "SyntaxError"
err_msg = e.message[/PG::(.*):\sERROR:(.*)/, 2]
# => " syntax error at or near \"hoge\""
```

その後エラーの種類によってハンドリングするような処理を作ってみました。

```ruby
    begin
      result = connection.select_all(sql)
    rescue ActiveRecord::StatementInvalid => e
      reg_pattern = /PG::(.*):\sERROR:\s(.*)/
      err_type = e.message[reg_pattern, 1]
      err_msg = e.message[reg_pattern, 2]
      case err_type
        when "UndefinedColumn"
          raise "カラム名が定義されていません."
        when "UndefinedTable"
          raise "テーブル名が正しくありません."
        when "SyntaxError"
          raise "SQLの構文に誤りがあります.\n(#{err_msg})"
        else
          raise "SQLの構文に誤りがあります.\n(#{err_msg})"
      end
```

多分もっといいほうがあると思いますが、参考になればと思います。
おすすめのPCとスマホ間のメモ連携方法

# 目的

PCとスマホ間のメモを連携するにあたって、PCでのエディタ、オンラインストレージを一元化することである。

PCでのテキストエディタ、メモの保存先、スマホでのテキストエディタを分離することでこれを実現する。

また、これらの分離によりPCでのエディタ、オンラインストレージ、スマホでのエディタの切り替えが容易になるため、将来の拡張性を高めたい方にもおすすめである。

それぞれ何を選んだのかと、必要な設定を説明する。

# 環境

## PC

macOS Mojave バージョン10.14.1

## スマホ

iOS 12.4.1

# PCでのテキストエディタ

VScodeを採用した。

理由は、メモ以外にもコーディングなどで使用できる多機能エディタであるためである。

# メモの保存先

Google Driveを採用した。

理由は、Google Driveは多様なファイル形式を保存できるオンラインストレージであり、他のGoogleサービスや他のサービスとの連携に強いためである。

# スマホでのテキストエディタ

PWEditorを採用した。

理由は、Google Driveと連携できるためである。

同じGoogleのサービスであるGoogle Documentを使用したかったが、txtやmdファイルを編集することができないためこちらを選択した。

ちなみにDropBoxやiCloud Driveとの連携もできる。

# 必要な設定

## VScode

* 特になし。

## Google Drive

* [Googleの「バックアップと同期」で大事なデータを自動保存！ | フォームズのブログ](https://blog.formzu.com/google_backup_and_sync)を参照。
 * この手順を実行すると、`/Users/ユーザ名/Google ドライブ/`配下に同期したフォルダが保存される。PCでファイルを編集したい時はこのフォルダ内のファイルを編集すればOKである。
 
## PWEditor
* [スマホのテキストエディタとGoogle Driveを駆使して、いつでもどこでもブログを書く方法！ | BLOGSTAR](https://mypace-life.com/?p=904)を参照。
swaggerからOpenApi GeneratorでSpringのコードを自動生成

# OpenApi Generatorでコードを自動生成
OpenApi Generatorはswaggerから自動生成できてとても便利なのですが、色々設定が面倒そうで後回しになっていました。
今回使ってみたら意外に簡単だったので、記事にしておきました。

## docker image
今回、調べてみるまではOpenApi generatorはgithubからプロジェクトをpullしてmavenでビルドして・・・という風に面倒なイメージがありましたが、dockerを利用すると簡単にswaggerからコードを自動生成できるようでした。
使い方はswaggerの置いてあるディレクトリまで移動して以下のコマンドを実行します。(swaggerファイル名はswagger.yamlとしております)

```
$ docker run --rm -v $PWD:/local \
  openapitools/openapi-generator-cli generate \
  -i /local/swagger.yaml \
  -g kotlin-spring \
  --additional-properties useBeanValidation=true \
  -o /local/out 
```

使用しているオプション

* -i -> 使用するswaggerファイルを指定
* -g -> 生成するファイルを指定(今回はkotlin-spring)
* --additional-properties useBeanValidation -> バリデーションを付与([他にもいろいろパラメータがあるようです](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/kotlin-spring.md))
* -o -> 出力先のフォルダを指定

すごい簡単でした・・・
他にも色々カスタマイズできるようなので、色々試してみたいですね。

# 参考
こちら、参考にさせていただいた資料です。
[平静を保ち、コードを生成せよ](https://speakerdeck.com/akihito_nakano/gunmaweb34)
[openapi-generator docker](https://github.com/OpenAPITools/openapi-generator#16---docker)
NetBeansのボタンやアイコンが、高解像度のディスプレイで小さすぎる件と、その解決策

# 概要

高解像度のディスプレイで、NetBeansのボタンやタブの文字が、
「小さすぎて読めない！！」（ハ○キルーペ）問題への対応方法をメモします。
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/143f8d27-caae-39d5-b010-3b7b30a9b37b.png)

なお、NetBeansとはJavaのIDEです。
WEBアプリケーション（JSF）の勉強をする際に触り、「小さすぎて読めない！！」問題に直面しました。
調べたものの、解決策になかなかたどり着かなかったため、Qiitaにて記録しておきます。



# 解決策手順
## 検証環境

- Surface Pro4（ディスプレイ12.3インチ・解像度2736 x 1824）
- NetBeans IDE 8.0.2 (Build 201411181905)


## 手順

ポイントは、以下のconfファイル内の一行です。

- C:Program Files\NetBeans 8.0.2\etc\netbeans.conf

```conf:
<前略>
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=false -J-Dsun.zip.disableMemoryMapping=true"
<後略>
```

`-J-Dsun.java2d.dpiaware=false` を 
`-J-Dsun.java2d.dpiaware=true`  に変更してください。
すなわち、変更後は以下のようになります。

```conf:
<前略>
netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true"
<後略>
```

## 再起動
NetBeansを再起動すると、ボタンのサイズ等が大きくなり、見やすくなります。
![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/557d19a7-514d-112e-aceb-cf7389af7f39.png)
![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341404/6a290cb1-337c-e21c-855b-49503c1786eb.png)
※しかし、解像度はそのまま拡大表示されるため、アイコン等はどことなくギザギザしてしまいます。


# 参考文献

下手な英語で探して、やっと見つけました。こちらもご参照ください。
[HiDPI with Eclipse and NetBeans - JAXenter](https://jaxenter.com/netbeans/hidpi-with-eclipse-and-netbeans)
RiderでWSLのGitを設定する

結論だけ書くと、[VScode・WSL・Git導入](https://qiita.com/Philosophistoria/items/48c4779739e6fafc63e0)に書かれているように `wslgit.exe` を導入することで設定が可能です。

## wslgitの導入

wslにインストールされたアプリをwindowsから利用するには、２つをバイパスするアプリやバッチがあれば操作可能です。
私の場合は参考にした記事に書かれている　[andy-5/wslgit](https://github.com/andy-5/wslgit/releases) を使用します。
上記ページから `wslgit.exe` をDL後、適切なところに配置します。

## Rider側の設定

Settingsを開き、`Version Control > Git` を選択。
`Path to Git executable` に `wslgit.exe` を指定します。

![2019-09-23_20h04_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83495/2f7f1fa8-5d17-4f14-9e92-12a8366168b5.png)

横にある `Test` ボタンを押して、下記のようにgitのバージョンが取得出来たら設定完了です。

![2019-09-23_20h11_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83495/ef61104b-cb19-ce39-9771-89f0ef84e8d6.png)

これでWSLのGitがRiderで使えるようになると思います。

## 注意

自分の場合はGit自体はWSLで操作をして、差分の表示用だけにRiderとGitを連帯させています。
なので、RiderでGitの他の機能を使用する場合はこの設定だけだと不十分な可能性もあるので、ご了承ください。
react font-awsome with React



- install

```javascript
npm i --save @fortawesome/react-fontawesome @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons
```

- 表示

```javascript:import&表示
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCoffee } from '@fortawesome/free-solid-svg-icons'


 <FontAwesomeIcon icon={faCoffee} />
```

## ここからが肝

欲しいアイコンをどう探すか？

例だと`faCoffee`とかいている


- アイコンの探す場所は下記
- 
https://fontawesome.com/icons/home?style=solid



試しに`<i class="fas fa-home"></i>`これを見てみる

`faCoffee` ← `fa-coffee`なんじゃないかと思って

`faHome`でやって見たら、、、、表示された。
template要素の使い方、知ってます？

# template要素？
template要素（タグ）は、html5から追加された要素です。
名前が示すとおり、テンプレートのようにページ内で繰り返し表示したい内容を`<template>...</template>`内に書いておき、JavaScriptと組み合わせて使います。

## 書くだけでは表示されない
htmlの他要素とは違い、htmlファイル内に以下のように書くだけでは、ブラウザで表示されません。
template要素内に書いたコンテンツは、隠れたDOMとして扱われレンダリングされないためです。
**ブラウザで表示するためには、JavaScriptを使います。**

```html
<template id="template">
  <p>テンプレート</p>
</template>
```

# 基本的な使い方

## htmlでテンプレートを作成
テンプレートとして使いたい内容を```<templae>...</template>```内に書き、表示エリアを用意します。

```html:html
<!-- テンプレートとして表示したい内容 -->
<template id="template">
  <p>テンプレート</p>
</template>

<!-- テンプレート表示エリア -->
<div id="container"></div>
```
この時点では、template要素内に書いた内容はブラウザには表示されません。

## JavaScriptで表示
template要素内の内容をブラウザに表示するには、JavaScriptを使います。
必要な処理は、３つだけです。

1. template要素を取得
2. 取得したtemplate要素の内容を複製
3. DOMに追加

```javascript:javascript
// template要素を取得
var template = document.getElementById('template');

// template要素の内容を複製
var clone = template.content.cloneNode(true);

// div#containerの中に追加
document.getElementById('container').appendChild(clone);
```
テンプレートの表示内容に、配列の値を挿入したいなど、加工が必要な場合は「3. DOMに追加」の前に処理します。

まとめると以下のようになります。

```html
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>template要素の使い方</title>
</head>
<body>
  <!-- テンプレートとして表示したい内容 -->
  <template id="template">
    <p>テンプレート</p>
  </template>

  <!-- テンプレート表示エリア -->
  <div id="container"></div>

  <script>
    // template要素を取得
    var template = document.getElementById('template');

    // template要素の内容を複製
    var clone = template.content.cloneNode(true);

    // div#vcontainerの中に追加
    document.getElementById('container').appendChild(clone);
  </script>
</body>
</html>
```

# 加工する

## 配列のデータを挿入
table要素の行（`<tr>...</tr>`）をtemplate要素で生成するサンプルです。
複製したtemplate要素に、配列のデータを挿入し、ループ処理でtable要素に追加します。

```html
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>templateタグの使い方</title>
</head>
<body>
  <!-- テンプレートとして表示したい内容 -->
  <template id="template">
    <tr>
      <th class="date"></th>
      <td class="weather"></td>
    </tr>
  </template>

  <!-- テンプレート表示エリア -->
  <table id="container" border="1">
    <tr><th>日付</th><th>天気</th></tr>
  </table>

  <script>
    // データ
    var arr = [
      {"date":"09/17", "weather":"晴れ"},
      {"date":"09/18", "weather":"曇りのち雨"},
      {"date":"09/19", "weather":"曇りのち晴れ"}
    ];

    // template要素を取得
    var template = document.getElementById('template');

    for(var i =0; i < arr.length; i++){
      // template要素の内容を複製
      var clone = template.content.cloneNode(true);

      // 複製したtemplate要素にデータを挿入
      clone.querySelector('.date').textContent = arr[i].date;
      clone.querySelector('.weather').textContent = arr[i].weather;

      // div#containerの中に追加
      document.getElementById('container').appendChild(clone);
    }
  </script>
</body>
</html>
```

# 参考
https://developer.mozilla.org/ja/docs/Web/HTML/Element/template
flex-box よく使うやつ React


## レイアウト

Appコンポーネントの中に、
Header、Main、FooterBarが含まれている状態


```css
構成

App
  Header
  Main
  FooterBar

#App
display: flex;

#Header
flex: 1;

#Main
flex: 8;

#FooterBar
flex: 1;

```


## アイテムの整列

```
# ItemList
display: flex;
 justify-content: space-around;

ItemList
  Item
  Item
  Item
  Item 
```
Project Euler 025を解いてみる。「1000桁のフィボナッチ数」

# Project Euler 025
[025](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2025)
>フィボナッチ数列は以下の漸化式で定義される:
F<sub>n</sub> = F<sub>n-1</sub> + F<sub>n-2</sub>, ただし F<sub>1</sub> = 1, F<sub>2</sub> = 1.
最初の12項は以下である.
F<sub>1</sub> = 1
F<sub>2</sub> = 1
F<sub>3</sub> = 2
F<sub>4</sub> = 3
F<sub>5</sub> = 5
F<sub>6</sub> = 8
F<sub>7</sub> = 13
F<sub>8</sub> = 21
F<sub>9</sub> = 34
F<sub>10</sub> = 55
F<sub>11</sub> = 89
F<sub>12</sub> = 144
12番目の項, F<sub>12</sub>が3桁になる最初の項である.
1000桁になる最初の項の番号を答えよ.


->[次の問題](https://qiita.com/radiol/items/509e67ddb5c2de6ea6fd)


## 考え方
シンプルにフィボナッチ数列を順番に出力し、1000桁(10<sup>999</sup>)より大きくなるポイントまでループさせました。
フィボナッチ数列を生成するgeneratorは[002](https://qiita.com/radiol/items/3ca9add958f8833ab4ed)で作っていましたが、このときは有限なループとしていたものを無限ループするように変更しました。
フィボナッチ数列の一般項にlog10なんかして計算したらもっと簡単にできるんでしょうか…

```Python:math_functions.py
def fibonacci_generator() -> int:
    """fibonacci数列を返すgenerator
    Returns:
        int: fibonacci数列を順に返す
    """
    last_result = 0
    result = 1
    while True:
        yield result
        result, last_result = result + last_result, result
```


## コード
for文とfibonacci_generatorで無限ループを行い、1000桁を超えたところでループを抜けるようにしました。
Javaではループ内で宣言した変数(iやfibonacci_num)はループ外から参照できなかったですが、Pythonは関係なく参照できるんですね。

```Python:euler025.py
def main():
    n = 1000  # 1000桁になるのは
    end_point = 10 ** (n - 1)  # 1000桁以上になったら終了
    # enumurateを使いループの何番目かを取得
    for i, fibonacci_num in enumerate(fibonacci_generator()):
        if fibonacci_num > end_point:
            break
    print(f'{n}桁となるのは第{i+1}項')  # iは0から始まるので+1


def fibonacci_generator() -> int:
    """fibonacci数列を返すgenerator
    Returns:
        int: fibonacci数列を順に返す
    """
    last_result = 0
    result = 1
    while True:
        yield result
        result, last_result = result + last_result, result
        

if __name__ == '__main__':
    from time import time as t
    st = t()
    main()
    print(t() - st, 'sec')
```
paizaで実行できるようにmath_funcitonsの関数部分も1つのコードに入れました(paizaで自作の関数をimportする方法よくわからない)

[paiza](https://paiza.io/projects/new)にて実行
`結果
1000桁となるのは第4782項
0.0007300376892089844 sec
`
VSCodeでgo toolsのコマンドがみつからない。

## 事象

VSCodeでgo toolsのコマンドを実行すると、コマンドがみつからないと怒られる。

```
command 'go.test.cancel' not found
```

尚、ターミナルからは `go env`で`GOPATH`や`GOROOT`の設定が確認できていて、そこに必要なtoolsは存在している。

# 原因と解決

どうやら、VSCodeがGOPATHを正しく認識できていないようだった。
[ターミナルからVSCodeを起動](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)すると、GOPATHやGOROOTの環境情報を取得できるようなので、それで起動してみよう。

```
code .
```

ターミナルから起動すると下記のメッセージが出力されたのでインストール。
toolsの再コンパイルが必要だったようだ。

```
goroot (/Users/****/.goenv/versions/1.12.0) is different than before (/users/****/.goenv/versions/1.12.0), a few Go tools may need recompiling
```

必要なtoolsがGOPATH配下にインストール/更新され、再コンパイルされた。

```
Installing 17 tools at /Users/****/go/1.12.0/bin
  gocode
  gopkgs
  go-outline
  go-symbols
  guru
  gorename
  dlv
  gocode-gomod
  godef
  goreturns
  golint
  gopls
  gotests
  gomodifytags
  impl
  fillstruct
  goplay

Installing github.com/mdempsky/gocode SUCCEEDED
Installing github.com/uudashr/gopkgs/cmd/gopkgs SUCCEEDED
Installing github.com/ramya-rao-a/go-outline SUCCEEDED
Installing github.com/acroca/go-symbols SUCCEEDED
Installing golang.org/x/tools/cmd/guru SUCCEEDED
Installing golang.org/x/tools/cmd/gorename SUCCEEDED
Installing github.com/go-delve/delve/cmd/dlv SUCCEEDED
Installing github.com/stamblerre/gocode SUCCEEDED
Installing github.com/rogpeppe/godef SUCCEEDED
Installing github.com/sqs/goreturns SUCCEEDED
Installing golang.org/x/lint/golint SUCCEEDED
Installing golang.org/x/tools/cmd/gopls SUCCEEDED
Installing github.com/cweill/gotests/... SUCCEEDED
Installing github.com/fatih/gomodifytags SUCCEEDED
Installing github.com/josharian/impl SUCCEEDED
Installing github.com/davidrjenni/reftools/cmd/fillstruct SUCCEEDED
Installing github.com/haya14busa/goplay/cmd/goplay SUCCEEDED

Reload VS Code window to use the Go language server
All tools successfully installed. You're ready to Go :)
```

これで問題は解決した。

# その後

goenvでgoのバージョンを切り替えてVSCodeを起動した際、必要な時は「toolsをインストール/更新してください」とメッセージが出てきた。
`code .` で起動しなくてもGOPATHやGOROOTの変更を読み込んでいるように見える…

VSCode側からtoolsのインストール/更新のお知らせがなかったが必要そうな場合、ターミナルからVSCodeを起動してみよう。
pythonによる同一フォーマットのCSVファイルのマージ処理

# 概要

複数のCSVファイルをマージする必要があり、そのためのツールを作ったので記事にまとめました。
分割ダウンロードしかできなくてまとめて一本にしたいときなどに使えるかと思います。


## 必要なもの

* python 3.7.2
* pandas

今回はexeも作ったので使いたいだけならpython自体不要です。

## 公開場所

[github](https://github.com/snowpff14/etcresource)で公開しています。

## 使い方

* inputディレクトリ内にマージしたいCSVファイルを格納
* `fileMerge.py`を実行する。

## ソースの説明

以下の処理がマージ処理の核の部分になります。
取得したファイルの１つ目からカラムの情報を取得して、
ファイル内のCSVをpandasのconcatメソッドで結合しています。
エンコードは外だしにして設定できるようにしてあります。

```python
        datas=pd.DataFrame(columns=dummy.columns)
        for file in files:
            log.info(str(file)+'開始')
            dataTemps = pd.read_csv(file, encoding=encodeType, dtype='str',engine='python')
            datas=pd.concat([datas,dataTemps])
            log.info(str(file)+'終了')

```

## 活用方法

システムによっては一括でCSVとして取得できず月ごとの結果になってしまうところで
このツールを使えば簡単に一つにまとめられるかなと思います。
またアプリに組み込むのも必要な部分だけ移植も可能かと
Bitbucket→GitHub 移行 その2～GitHub～

Mercurial 使いが Git を使い始め、GitHub にお世話になりはじめた記録です。

[その1](https://qiita.com/chimatter/items/41f69aa87138538bd524) で、Mercurial リポジトリを Git リポジトリに変換する方法を記録していました。

* [x] [リポジトリ変換](https://qiita.com/chimatter/items/41f69aa87138538bd524)
* GitHub ←今ここ
* [x] [CIまわり](https://qiita.com/chimatter/items/d77d509d1ec83e29b348)
* (ほかあるかな…？)

今回やる内容は Qiita にも色々と記事が投稿されているものですので、あまり参考になる部分はないかもしれません。

# GitHub にプッシュする

## SSH

やることは以下のとおりです。

1. 鍵の生成
2. GitHub への公開鍵の登録
3. 接続先の登録

GitHub のドキュメント ([GitHub に SSH で接続する](https://help.github.com/ja/articles/connecting-to-github-with-ssh)) があります。
こちらを参考にして勧めていきます。
ただし、ssh-agent については無視します。

参照先と重複しますが、実行したコマンドや注意点を記載していきます。
(~~とはいえ、もはやうろ覚えなので、付け加えることは無いような…~~)

### 鍵の生成

参考: [新しい SSH キーを生成して ssh-agent に追加する](https://help.github.com/ja/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)

```
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```

パスフレーズは空白で。 (推奨するわけではありません)
ファイル名は適宜変えます。 (id_rsa_github にしました)

~/.ssh に id_rsa や id_rsa.pub ファイルが作成されます。 (今回は id_rsa_github.pub ができました)

### GitHub への公開鍵の登録

参考: [GitHub アカウントへの新しい SSH キーの追加](https://help.github.com/ja/articles/adding-a-new-ssh-key-to-your-github-account)

上記の参考リンクに従い、GitHub の設定ページで公開鍵の方を登録します。
id_rsa.pub (ファイル名を変更している場合も、.pub の方) を使います。

### 接続先の登録

~/.ssh/config に GitHub を登録します。
これをやっておかないと、うまく接続できませぬ。

```
Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github
  User git
```