OmniAICreator/Qiita-1.07M huggingface dataset:
ストップウォッチをつくった

最近、[ドットインストール](https://dotinstall.com/)で勉強しているのですが、
復習と理解の促進のために、アウトプットしておきます。

[JavaScriptでストップウォッチを作ろう](https://dotinstall.com/lessons/stop_watch_js_v6)

##作り方の手順
1. まずHTMLで骨子をつくる。
2. CSSでデザインをある程度整える。
3. JavaScriptで<b>機能を作りこむ</b>。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655368/f7674950-8f60-6db0-c4ce-3bfedcb8b60a.png)
画像はつくったストップウォッチ。


下記に<b>ストップウォッチを作るのに必要な機能のメソッド</b>をまとめておきます。


##メソッド一覧
- padStart()
- setTimeout()
- clearTimeout()
- Date.now()
- Substring()
- classList.add()


###padStart()
結果の文字列が指定した長さになるように延長する。
ストップウォッチの時間表示部分は00:00,000だったため、ここに使用。

```js:001.js
     const m = String(d.getMinutes()).padStart(2,'0');
     const s = String(d.getSeconds()).padStart(2,'0');
     const ms = String(d.getMilliseconds()).padStart(3,'0');
```


###setTimeout()
ある処理を一定時間後に実行する
下記では10m秒後にcountUp()を実行します


```js:002.js
     timeoutId = setTimeout(() => {
         countUp();
     }, 10);
```

###clearTimeout()
タイマーは起動すると動きっぱなしなので停止させる
setTimeout()の返り値をclearTimeout()の引数にわたす

(この部分ちゃんと理解していないので要再勉強)



```js:002.js
 clearTimeout(timeoutId);
     }, 10);
```

###Date.now()
規定時間からの経過時間を返す



###Substring()
文字列の中の指定された範囲の部分文字列を返す




###classList.add()
他にclassList.remove()やclassList.contains()など
button要素のときはdisabledプロパティを利用できた
しかしdiv要素では使えないので、クラスをつくりこのメソッドをつかう

```js:002.js
 function setButtonStateStopped(){
    start.classList.remove('inactive');
    stop.classList.add('inactive');
    reset.classList.remove('inactive');

 }
```
```html:index.html
      <div class="btn" id="start">Start</div>
      <div class="btn" id="stop">Stop</div>
      <div class="btn" id="reset">Reset</button>
 }
```



##つくった感想



ドットインストールを使うと、１つ１つのレッスン時間が短いですし、
気軽にメソッドを網羅できるので楽チンだな～と思います。

０からプログラミングをやる人にはおすすめできないですが、
ある程度の知識があるけどWebサービスを一人で作れるレベルじゃないという人にはドットインストールがおすすめです。

（０からプログラミングをやりたい人はProgateがいいそうです。ネット情報ですが)
Javascript 勉強メモ② クラス、メソッド、静的メソッド、継承

昨日から今日にかけて勉強したメモ。
これを学んでできるようになったこと。

●同じ処理をしたいときにわざわざcopy&pestしなくても、まとめることができる。
→クラス作成のメリット。フォーマットみたいなもの

●同じようなクラスだけども少し処理が違う（例えば表示したい文字列に日時だけを足したいとか）ときに、同じ処理を書かなくても、クラスが作れちゃう。しかもコード少なめ。
メリット：コード量が減らせるし、その分ミスも格段に減る。エラーが出たときに見るところが少なくて済む。

●インスタンス化しなくても良いメソッド
・デメリット：引数として情報を渡すことができない。→インスタンス化しないため
・メリット：インスタンス化しなくても呼び出したいときに呼び出し可能


```javascript
'use strict';

{
  //クラスは同じようなプロパティやメソッドを何度も使う場合に便利
  //フォーマットのようなもの
  class Post {
    constructor(text){
      this.text = text;
      this.likeCount =  0;
    }
      show(){
        console.log(`${this.text} - ${this.likeCount}likes`);
      }

      like(){
        this.likeCount++;
        this.show();
      }
      //static メソッドはインスタンス化しなくてもクラス名.メソッドで呼び出すことができる (ex.Post.showInfo())
      static showInfo(){
        console.log('Posts class version 1.0');
      }
    }
  class SponsorPost extends Post{ //継承はextends method
    constructor(text,sponsor){
      super(text);//親クラスのconstructorを使うにはsuper(引数);
      this.sponsor = sponsor;
    }
    show(){
      super.show();  //親クラスのメソッドはsuper.method()で呼び出し可能
    // console.log(`${this.text} - ${this.likeCount}likes`);
        console.log(`...sponsored by ${this.sponsor}`);
      }

      // like(){
      //   this.likeCount++;
      //   this.show();
      // }
      //static メソッドはインスタンス化しなくてもクラス名.メソッドで呼び出すことができる (ex.Post.showInfo())
      // static showInfo(){
      //   console.log('Posts class version 1.0');
      // }
    }
  const posts = [
      new Post('JavaSciptの勉強中...', 12),
      new Post('プログラミング難しい',20),
      new SponsorPost('現場雑用が劇的に減らせる','hanad.j')
  ];

  posts[0].like();
  posts[0].show();
  posts[1].show();
  posts[2].show();
  posts[2].like();

  Post.showInfo();
}
```
tailwindcss入門メモ

# この記事の目的

tailwindを始めるにあたってのメモ

# tailwindcssとは-utilityfirstとは-

bootstrapとかだとbtnクラスなどがあってcomponentに対してclassがあったりするがtailwindcssではcomponentに対してあるのではなくutilityを抽象化したものでできている。例えばpaddingをp-1としてpaddingを0.25remでいい感じにしてくれるなど。

htmlにかく、classの量は多くなってしまうがcssをそこまで書かずにclassをつけていけばcssをいろいろ調整してくれる。

# 導入

https://tailwindcss.com/docs/installation/

npmで落とす。上記でスムーズにできるはず

## rails6での導入

「rails6+tailwindcss2の設定」
https://qiita.com/you8/items/f0306ed17f8990407988

# layoutの考え方

## 基本

基本の考え方は下記

- containerで全体を内包
- 中をgrid（ https://tailwindcss.com/docs/grid-column ）で並べる。bootstrapと同じようにrowで内包し、要素を並べることもできる。
- もしPCなどでサイドバーを出す場合、layoutをこれ（ https://tailwindcss.com/docs/top-right-bottom-left ）で出し分ける

## breakpoint

breakpointのdocuments
https://tailwindcss.com/docs/breakpoints/

```javascript
// tailwind.config.js
module.exports = {
  theme: {
    screens: {
      'sm': '640px',
      // => @media (min-width: 640px) { ... }

      'md': '768px',
      // => @media (min-width: 768px) { ... }

      'lg': '1024px',
      // => @media (min-width: 1024px) { ... }

      'xl': '1280px',
      // => @media (min-width: 1280px) { ... }
    }
  }
}
```

## gridでcardを並べたい場合

```html
<div class="grid grid-cols-6 gap-4">
  <div class="col-span-6 sm:col-span-4 md:col-span-3 lg:col-span-5 xl:col-span-2..."></div>
  <div class="col-span-3 sm:col-span-2 md:col-span-3 lg:col-span-1 xl:col-span-4..."></div>
  <div class="col-span-3 sm:col-span-2 md:col-span-3 lg:col-span-4 xl:col-span-2..."></div>
  <div class="col-span-6 sm:col-span-4 md:col-span-3 lg:col-span-2 xl:col-span-4..."></div>
</div>
```

defaultのカラムをcol-spanで指定してこのサイズ以上の横幅の場合、カラムを変えたいというときはsmなどで指定。

## カラムの横幅調整をしたい場合

https://tailwindcss.com/docs/width/#fluid-width

```css
  <div class="flex mb-4">
    <div class="w-1/2 p-2 bg-gray-400 text-center">.w-1/2</div>
    <div class="w-1/2 p-2 bg-gray-500 text-center">.w-1/2</div>
  </div>
```

上記のようにw-に分数をくっつけて横幅を指定する。そのdivをさらにflexのdivで囲む。
【IntelliJ IDEA】ソースコードを保存したときにローカルでの変更箇所のみフォーマットする方法

## やりたいこと
cmd + s を押下したときに、以下を一括で実行できるようにしたい

- 不要なimport文を削除
- import文の順序を整理
- リポジトリにチェックインしていない変更箇所のみ
- コードを保存する

## 環境
- IntelliJ IDEA 2020.1.2 (Ultimate Edition)
- macOS 10.15.4

## 方法

#### フォーマットの設定
cmd + opt + shift + l を押下して「Reformat File dialog」を表示
Scopeを「Only VCS changed text」に設定して、Optionalの「Optimize imports」をチェックして、「Run」を押下
<img width="354" alt="dialog" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/c76ce5d1-7595-d05f-faa5-7706db89c31e.png">

「Only VCS changed text」はバージョン管理されているプロジェクトかつローカルに変更がある場合のみ設定できるので、グレーアウトされている場合は、バージョン管理されているプロジェクトかどうか、ローカルに変更があるかどうかを確認する。

#### macroの登録
Editor -> Macros -> Start Macro Recordingを押下して、その後以下を実行

- cmd + shift + l (reformat file)
- cmd + s (save All)

<img width="677" alt="start macro recording" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/b7534d99-3d1f-ce8e-95dc-b667048bff09.png">

Editor -> Macros -> Stop Macro Recordingを押下、その後、macroに名前をつけて保存
<img width="486" alt="スクリーンショット 2020-06-14 9.43.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/08a80dda-2533-aa11-e91f-e772824253b6.png">

#### Keymapの設定
Preferences -> Keymap -> Macros -> 保存したmacroをクリック -> Add Keyboard Shortcut
「cmd + s」を入力してOK
<img width="306" alt="スクリーンショット 2020-06-14 9.45.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160829/758941ed-9410-5a79-2f1b-064e7861295d.png">
Pandasで計算するときはNumpyに変換すると高速だった

組み込みでデータロガーみたいな製品を開発したときに、簡単にデータ操作できるようにPandasを使ったのですが、演算処理が重くなるところは `.values` 属性でNumpyデータに変換してから演算すると爆速だったのでメモ。

## 実験

### データ定義

```python
import pandas as pd
import numpy as np

data= np.random.rand(1000000)
s = pd.Series(data)
```

Jupyter上で、`%%timeit` で実行時間を計測。


### その1: 100万件のデータ積算

コード|結果|速度比
---|---|---
s.sum() | 6.38 ms ± 49.4 µs per loop　| 1
s.values.sum() | 462 µs ± 8.75 µs per loop |  13.8 倍
data.sum() | 442 µs ± 12.9 µs per loop | 14.4 倍

`.values`を入れるだけで13倍以上に速くなった。素のNumpyでの演算と遜色ないレベル。

### その2: データ抽出演算

コード|結果|速度比
---|---|---
s[s > 0.5] | 12.3 ms ± 554 µs per loop　| 1
s[s.values > 0.5] | 11.8 ms ± 23.4 µs per loop　| 1.04 倍
s.values[s > 0.5] | 6.04 ms ± 28.7 µs per loop |  2.04 倍
s.values[s.values > 0.5] |5.95 ms ± 26.1 µs per loop | 2.07 倍
data[data > 0.5]| 5.96 ms ± 45.7 µs per loop | 2.06 倍

`.values`を入れるだけで2倍に速くなった。素のNumpyでの演算と同等レベル。
「その1」の結果と比べると大したことはない印象です。


ところが・・・
データ件数を1000件にして同じテストをしてみると、驚きの結果が。

```python:データ1000件
data2 = np.random.rand(1000)
s2 = pd.Series(data2)
```

コード|結果|速度比
---|---|---
s2[s2 > 0.5] | 1.16 ms ± 12.1 µs per loop　| 1
s2[s2.values > 0.5] | 1.06 ms ± 2.16 µs per loop　| 1.09 倍
s2.values[s2 > 0.5] | 77.7 µs ± 1.5 µs per loop |  149 倍
s2.values[s2.values > 0.5] |4.89 µs ± 172 ns per loop | 237 倍
data2[data2 > 0.5]| 3.81 µs ± 33.9 ns per loop  | 304 倍

`.values`を入れた演算だと200倍以上に速くなっています。素のNumpyの結果と比べると、Pandasの遅さが際立ちます。
データ件数が少なくなった分、Pandasでの演算オーバーヘッドの影響が大きくなるためと思われます。

## まとめ

ここで実験した以外でも、Numpyで同じ演算ができる場合は、ほぼすべて `.values` でNumpyデータを取得して演算したほうがかなり速くなります。
演算結果をPandasオブジェクトに戻す必要があるような場合には、その変換処理の時間だけ余計にかかりますが、それを考慮してもNumpyに変換したほうが速いことが多いでしょう。

時間的には大した差はないように見えますが、1msでも処理時間を削減したい組み込みシステムではこの差の積み重ねがかなり効いてきます。

とはいえ、**同じ演算でもNaNの扱いなどPandasとNumpyで処理が違う場合もありますので注意が必要です**。
自分も最初は何も考えずにNumpy演算に置き換えたら動かなくなってしまって苦い経験をしました。やはりPandasでの演算の方が何かと便利にできています。この便利さがPandasの遅さの原因でもあります。
また、Seriesならまだよいですが、DataFrameになると記述が冗長になり可読性は低下しますし、バグの原因になりかねません。

TPOに応じて使い分けることになりそうです。
Next.jsで多言語対応したときの強制再描画とSSGを保つベストプラクティスが分からないメモ

## 概要

[GitHubのリポジトリ](https://github.com/hibohiboo/create-now)に[Issue:Question](https://github.com/hibohiboo/create-now/issues/1)が来ていたので答える。
[Next.jsをRosettaで多言語対応(i18n)して型に気を付けたメモ](https://qiita.com/hibohiboo/items/2824fc2030ef3b91c479)関連。


### Q1. なぜ強制的に再描画する必要があるのですか？

> 1) Why we need to force rerender in useEffect?

```ts
  useEffect(() => {
    if (locale) {
      i18n.locale(locale)
      i18n.set(locale, activeDict)
      activeLocaleRef.current = locale
      // force rerender
      setTick((tick) => tick + 1)
    }
  }, [locale, activeDict])
```

#### A1. renderメソッドがprop, state以外のものから読み出す場合(今回の場合、i18n)は再描画を行う必要があるからです。

([参考: forceUpdate]([forceUpdate](https://reactjs.org/docs/react-component.html#forceupdate)))

`forceUpdate`はテスト以外では非推奨のため、`state`を更新する処理を入れて再描画しています。
ただ、`setTick`しなくても動作は変わっていないように見えました。
不要な処理の可能性もあると思います。

### Q2. routerやlinkで使っている言語を検出するおススメの方法などはありますか？

`getStaticProps`と`getServersideProps`で行う方法だと可能ですが、毎回これを読み込む必要があります。

> You have ideas or recommendations on how to do language detection and integration it with next router & links?  I need to have language param in url. Ex.: http://site.com/en/
Currently I put all my page files inside pages folder in folder with dynamic name [lng]
Inside page we will receive lng as parameter inside { params } field in getStaticProps and getServersideProps and we use that variable to import needed lngDict, then return lng and lngDict to be available as pageProps, used as I18n provider that wraps our pages in _app.tsx

`next-i18n-next`と同様の動きにしたいのですが、これだとSSGにならなくなってしまいます。
`getInitialProps`を使用しているためです。
`next/router`と`next/link`をラッピングする必要があると思うのですが……

> Code files to analize: https://gist.github.com/7iomka/924dc3cdd2a752b25a7ae28f856fc030
I want to achieve the same behavior as when using next-i18n-next, but it realization breaks SSG because they used getInitialProps inside _app
I think that it’s necessary to make my own wrapper-components over next/router and next/link

#### A2. 今は思いつかないです。

もし、これを読んだ方でよい方法を思いついた方/知っている方はコメントしていただけると嬉しいです。

## 参考


[forceUpdate](http://js.studio-kingdom.com/react/component_api/force_update)
[forceUpdate](https://reactjs.org/docs/react-component.html#forceupdate)
GoでWebスクレイピング


# 事前準備
以下のコマンドで、ライブラリをインストールしてください

```bash:
go get -u github.com/PuerkitoBio/goquery
```
# 使い方
やり方の手順として以下の手順でやります。
1. URL情報の抽出
2. プログラムを書く
3. 実行


## URL情報の抽出
まず、スクレイピングしたいURLを決める必要があります。
今回は、Amazonの本検索でISBMの検索をしたときに一番最初に来たデータからタイトルを抽出するようにします。
日経Linux 2020 7月のISBMは4910071930709のため**4910071930709**で検索します。

[検索URL](https://www.amazon.co.jp/s?k=4910071930709&i=stripbooks)

ブラウザのF12などをおして、デベロッパツールでタイトル部分のHTML情報を調べましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425374/a90f9ab0-a625-88a5-a2d2-33fe3e5505dc.png)

上記図を見ますと、タイトルの部分の情報で使われているCSSの情報は**.a-size-medium.a-color-base.a-text-normal**ということがわかります。
これをキーワードに検索をかけましょう

## Goのコードを書く

以下のように記載します。

```golang:main.go
package main

import (
	"fmt"

	"github.com/PuerkitoBio/goquery"
)

func main() {
	isbm := "4910071930709"
	url := "https://www.amazon.co.jp/s?k=" + isbm + "&i=stripbooks"
	doc, err := goquery.NewDocument(url)
	if err != nil {
		fmt.Println(err.Error())
	}
	doc.Find(".a-size-medium.a-color-base.a-text-normal").Each(func(i int, s *goquery.Selection) {
		if i == 0 {
			fmt.Println(s.Text())
		}
	})
}
```
プログラムの順序を簡単に説明しますと以下の順序になります。
1. スクレイピング対象のURLを決める
2. URLからデータを持ってくる
3. 「**.a-size-medium.a-color-base.a-text-normal**」クラスのデータを抽出する
4. 一番初めに抽出したデータ内のテキストのみ出力する


# 実行結果
実行すると以下のような結果が得られます。

```bash:
$ go run main.go
日経Linux（リナックス） 2020年7月号
```


なお、<a></a>などの使用されている、**href=**の結果を取得したいときは、
`urldata := s.Attr("href")`
などと記載すると取得することができます。
datadogにpython, DogStatsD経由でMetricsを送り込んでみる

# はじめに
datadogとはSaaS形式のサーバの運用監視ツールです
監視対象の各種サーバから各メトリクスをdatadogに送ることにより、
ブラウザ上で様々な分析ができます。

datadogは、各サーバのリソースやアプリケーションの実行回数・TATをdatadogに送信してくれるエージェントを提供してくれていますが、今回この記事ではpythonで特定の値をdatadogに送信し続けるスクリプトを作ってみようと思います。

データベースの特定のテーブルのデータ量を送り続けるとか、シェルスクリプトの実行回数を送るなど、活用用途はいろいろ考えられると思います。

# 前提
python3を利用

# Metricsを送り込むスクリプトの作成

DogStatsDサーバ経由でMetricsを送り込んでみます

## datadogライブラリのインストール

`pip3 install datadog`

## サンプルスクリプト

```sample.py
import random
from datadog import initialize
from datadog import statsd

#   まずは初期化
options = {
    'statsd_host':'127.0.0.1',
    'statsd_port':8125
}

initialize(**options)

#   tagと値を作る
tags = ['version:1', 'application:web']
value=random.randint(0, 100)

#   metricのset
metric="myapp.testdata.set"
statsd.set(metric, value, tags=tags)
#   metricのgauge
metric="myapp.testdata.gauge"
statsd.gauge(metric, value, tags=tags)
```

## 解説
```sample前半.py
options = {
    'statsd_host':'127.0.0.1',
    'statsd_port':8125
}

initialize(**options)
```

まずは初期化です。DogStatsDサーバのアドレスとポートを指定します。
デフォルトはUDP:8125です。

```sample後半.py
#   tagと値を作る
tags = ['version:1', 'application:web']
value=random.randint(0, 100)

#   metricのset
metric="myapp.testdata.set"
statsd.set(metric, value, tags=tags)
#   metricのgauge
metric="myapp.testdata.gauge"
statsd.gauge(metric, value, tags=tags)
```
Metricsを送信するときは下記のいずれかのメソッドを使う必要があります。

| メソッド名 | 解説 |
|:---------|------------------:|
| set()    | メソッドをコールした回数が送信される |
| gauge()  | メソッドで値を送信する |

用途に応じて選んでください。
一見してわからない方は感覚的にわかるよう次の項で説明します。

## サンプルスクリプト結果

サンプルスクリプトではsetメソッドとgaugeメソッドを両方ともコールしています。
このスクリプトを１分ごとにコールし続けた結果をdatadogにて表示してみます。

![datadog_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/bebd6e34-1ade-c69d-1481-e99da20e70c3.png)

setメソッドは１分に１回コールされていることをカウントしているため、値１が毎分継続しており、gaugeメソッドはランダム値(0〜100)が送信され続けていることがわかるかと思います。

# 最後に

- set()メソッドはスクリプトの実行回数などをに利用
- gauge()メソッドはデータ量の変化などを記録するのに利用

こんな使いわけができればよりデータの可視化ができるのではないでしょうか？
UbuntuにDockerを入れる

#はじめに
dockerのインストール方法には３種類ある。
1 Dockerリポジトリーを使う方法
2 debパッケージを使う方法
3 スクリプトを用いてインストールする方法

#2のリポジトリーを使う方法
##パッケージの更新
```
sudo apt-get update
```
##必要なソフトウェアのインストール
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
```

##GPGキーを追加
GPGキーとはGNU Privacy Guardという暗号化ソフトで生成される公開鍵である。
https://xtech.nikkei.com/it/article/Keyword/20091204/341579/

```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
```

#dockerエンジンをinstall

```
sudo apt-get install docker-ce docker-ce-cli containerd.io
```

正常にinstallできたかの確認

```
sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/


```



#参考
https://docs.docker.com/engine/install/ubuntu/
FirebaseからPush通知を送る（CloudFunctionsを使って）

FirebaseCloudMessaging（以下「FCM」）は、iOS/Android/Webでプッシュ通知を送ることができるFirebaseのサービスになります。（しかも無料です！）

配信設定画面は、わかりやすいGUIになっているため、導入後の運用をエンジニア以外でもできるようになっています。

 * 配信設定画面
<img width="628" alt="スクリーンショット 2020-06-14 7.47.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/487bd755-b9a0-edde-94ee-a4546a6b3db7.png">

もちろん、プッシュ開封率などの効果計測も行えますし、Firebaseの他サービス

 * FirebaseAnalutics（アナリティクス）
 * FirebasePredictions（ユーザー行動の予測）

と連携すれば、特定の行動を起こしたユーザーにだけ配信することや特定の行動を起こしそうなユーザーにだけ配信することなどができます。

管理画面経由などはよくありますので、「CloudFunctions」にてユーザーを指定してプッシュ通知を送る方法を記載致しました。
ユースケースとしては、

 * 掲示板などで発言に、「いいね」や「コメント」がついた時に、発言者だけにプッシュ通知を送る
 * 所属しているグループメンバーだけにプッシュ通知を送る

などになるかと思います。

##得られるもの
「CloudFunctions」から個別ユーザーへプッシュ通知を送る方法


##導入
「Firebase導入」「FCM導入」「FirebaseCLI/CloudFunctions導入」については、下記を参照してください。

 * サービスにFirebase導入
    * [iOS](https://firebase.google.com/docs/ios/setup?hl=ja)
    * [Android](https://firebase.google.com/docs/android/setup?hl=ja)
    * [Web](https://firebase.google.com/docs/web/setup?hl=ja) 
 * FCM導入
    * [iOS](https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ja)
    * [Android](https://firebase.google.com/docs/cloud-messaging/android/client?hl=ja)
    * [Web](https://firebase.google.com/docs/cloud-messaging/js/client?hl=ja) 
 * [FirebaseCLI/CloudFunctions導入](https://qiita.com/tdkn/items/2ed2b01f2656fc50da8c)

##内容
```index.js
const admin = require('firebase-admin');
const functions = require('firebase-functions');

admin.initializeApp(functions.config().firebase);

//  URLから「CloudFunctions」呼び出し
exports.pushSubmitFromURL = functions.https.onRequest((request, response) => {

  const token = "FCMToken";
  const payload = {
          notification: {
            title: "プッシュタイトル",
            body: "内容",
            badge: "1",             //バッジ数  
            sound:"default"         //プッシュ通知音
          }
        };
        
  pushToDevice(token,payload);
  
});

//  アプリから「CloudFunctions」呼び出し
exports.pushSubmitFromApp = functions.https.onCall((request, response) => {

  const token = "FCMToken";
  const payload = {
          notification: {
            title: "プッシュタイトル",
            body: "内容",
            badge: "1",             //バッジ数  
            sound:"default"         //プッシュ通知音
          }
        };
        
  pushToDevice(token,payload);
  
});

//  FCM部分
function pushToDevice(token, payload){
  // priorityをhighにしとくと通知までが早くなります
  const options = {
    priority: "high",
  };

  admin.messaging().sendToDevice(token, payload, options)
  .then(pushResponse => {
    return { text: token };
  })
  .catch(error => {
    throw new functions.https.HttpsError('unknown', error.message, error);
  });
}


```

呼び出しの際のGET/POSTの引数で端末から取得できるFCMトークンを渡せば、その端末だけにプッシュ通知ができます。

以上になります。
Firebaseホント便利ですよね。

足らないこと、間違い等ありましたら、コメントもしくは、@gurensouen
にご連絡いただけますと幸いです。

それでは、良き開発生活を。
【エラー対処法】Swift-could not find storyboard named "Main"

## はじめに
本記事は、プログラミング初学者の筆者が直面したエラー内容について、どうにか解決できた対処方法を備忘録として記述したものである。
## エラーの表示
いつも通りSwiftの学習で、シミュレーターを立ち上げようとビルドした際、下記のような見慣れないエラーが表示された。（大焦り）
「Could not find a storyboard named 'Main' in bundle NSBundle」

筆者>え？なにこれ、怖い。

## エラーの意味を考えてみる
Could not find a storyboard named 'Main' in bundle NSBundle
→「Main」って名前のstoryboardが見つかりません。

筆者>そうゆうことね、英文簡単で助かったわ。
...ってなんで俺のstoryboardないねん。

## 思い当たる節
自分の画面を見渡せど、原因が分からない。
しかも、storyboardは存在するし、なにを言っているのだXcodeさんよ。。。

【5秒後】
storyboard...あっ。一回間違えて消して、作り直したわ。(原因)
実はこれが原因で、初期設定では、Xcodeが"Main"と名付けられたstoryboardに対応する設定であり、その"Main"を消してしまったため、新たに作成したstoryboardを設定する必要があったのだ。

## 筆者がやったこと
①：info→key→Main storyboard file base nameのValueを新しく作ったstoryboardの名称へ変更。(ここではStoryboard。デフォルトではMainになっている。)
②：①と同画面のApplication Scene Manifest→...→Storyboard NameのValueを新しく作ったstoryboardの名称へ変更。

【①、②について下記画像参照】
<img width="953" alt="スクリーンショット 2020-06-14 午前8.48.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/23304096-19dd-948c-fbfe-566ea58193ab.png">

③General→Development info→Main Interfaceを新しく作ったstoryboardの名称へ変更。(ここではStoryboard。デフォルトではMainになっている。)

【③について下記画像参照】
<img width="950" alt="スクリーンショット 2020-06-14 午前8.53.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/4e41fe39-597d-5345-3d88-98aaec469c44.png">




## 結果
修正後ビルドを起動すると、エラーなくシミュレーターが立ち上がった。
ふぅ、助かった。
express-generator で jade を pug に差し替える方法がわからなかったハナシ

# express-generator インストール後の jade の脆弱性表示を何とかしたいという記事です

## 経緯
```bash:install 
sudo npm install express-generator -g
express somefolder
cd somefolder
express somefolder
```

上 コマンドを叩いたあとで
![Clipboard01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647892/9f101073-977d-6727-4c46-9e31ce6bb03e.png)

っていうのが出てやだなと思っていた。
詳しくは省くけど、結局

```bash:
npm audit fix
```

は全然効かなくて、でも express-generator 使ったのはじめてだし、
きける先輩もいないし（っていうか、node 案件受けてないのかもしれない。ビビり過ぎ）

っていう状態。

## 原因の推測
調べてみると jade というものが古いというのが原因らしいのだけど、
jade って .Net MVC でいうところの Razor みたいなやつっぽい。
で、その jade が pug というパッケージに変わっているのが原因なのかな。
~~いずれexpress-generator に対策が入って治るもんだろうと思う。過渡的な症状なんだろう。~~すでに治っていた

## 対策

### 1.生成からオプションを指定しなおしてやり直す。
```bash:
express --view=pug myapp
cd myapp
npm install
```
→
![Clipboard05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647892/9d12e6eb-6702-6815-f09e-2a5ae1b366a1.png)

## 結論

方法を模索していたところ、もうすでに解決済みのネタだった。
まだ、Web上のドキュメントリソースが追い付いていないのではないかと思う。
基本的にexpress というコマンドを見つけたら、 express --view=pug と読み替えておいた方がいいかもしれない。

ただ、やっぱり脆弱性メッセージは出るもののseverity は low だし当初の目的は達成したのでまいっかって感じ。
PYNQ-Z1 > Vivado >  [BD 41-238] Port/Pin property FREQ_HZ does not match between /clk_wiz_0/clk_in1(125000000) and /clk_125MHz(100000000)

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
Vivado v2019.1 (64-bit)
```


### Block Design

![コメント 2020-06-14 082548.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/01360271-b178-c31b-47e6-e8decdb0dc63.png)

左側のclk_125MHzはMake Externalで作成した。

clk_wiz_0の設定は以下のようにManualとして125MHzに設定している。

![コメント 2020-06-14 082845.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/98a0cd86-5ff5-08a7-6f58-cd4576aaf44a.png)



### エラー

Design Rule Checkで以下のエラーとなった。

> [BD 41-238] Port/Pin property FREQ_HZ does not match between /clk_wiz_0/clk_in1(125000000) and /clk_125MHz(100000000)

clk_125MHzのピン設定が100MHzになっていたので125MHzに変更した。
エラーは出なくなった。

![コメント 2020-06-14 082845.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/90449368-97fc-4a05-fcba-1fbaf6753e75.png)
Ubuntu + Apache + SSL + デジタル証明書 （2.SSL編）

作業日：2020年6月

[Ubuntu + Apache + SSL + デジタル証明書 （1.Apache編）](https://qiita.com/azumabashi/items/3aeb1ca2d2d214947467)
[Ubuntu + Apache + SSL + デジタル証明書 （2.SSL編）](https://qiita.com/azumabashi/items/2c53d5783af0dcf2c2a7) ←本編です。
[Ubuntu + Apache + SSL + デジタル証明書 （3.デジタル証明書編）](https://qiita.com/azumabashi/items/f9675469914b759d1e0c)

Apache2でTLS/SSLを利用するには、mod_sslモジュールが必要となるのでmod_sslを有効にします。

```
$ sudo a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  systemctl restart apache2
```

default-sslサイトを有効にします。

```
$ sudo a2ensite default-ssl
Enabling site default-ssl.
To activate the new configuration, you need to run:
  systemctl reload apache2
```

Apacheを再起動してここまでの設定を有効にします。

```
$ sudo systemctl restart apache2
```
httpsプロトコルが有効化されていることを確認しておきます。

```
$ ss -atl
State    Recv-Q    Send-Q        Local Address:Port         Peer Address:Port
LISTEN   0         128           127.0.0.53%lo:domain            0.0.0.0:*
LISTEN   0         128                 0.0.0.0:ssh               0.0.0.0:*
LISTEN   0         128                       *:http                    *:*
LISTEN   0         128                    [::]:ssh                  [::]:*
LISTEN   0         128                       *:https                   *:*
```

ファイヤウォールの設定を変更してTTL/SSL（443番ポート）を開きます。

```
$ sudo ufw allow 'Apache full'
Rule added
Rule added (v6)
```

Apache Fullとなったことを確認します。

```
$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 80/tcp                     ALLOW IN    Anywhere
[ 2] 22/tcp                     LIMIT IN    Anywhere
[ 3] Apache Full                ALLOW IN    Anywhere
[ 4] 80/tcp (v6)                ALLOW IN    Anywhere (v6)
[ 5] 22/tcp (v6)                LIMIT IN    Anywhere (v6)
[ 6] Apache Full (v6)           ALLOW IN    Anywhere (v6)
```

[Ubuntu + Apache + SSL + デジタル証明書 （3.デジタル証明書編）](https://qiita.com/azumabashi/items/f9675469914b759d1e0c)に続きます。
Python超初心者の超初心者のためのPython #関数2

環境
windows7　（Mac Book Pro 16inch欲しい）
Visual Studio Code
chrome
python ver3.8.3

この記事はプログラミング初心者かつPython初心者に向けて記述します。

##関数その2

[前回](https://qiita.com/Macchino5/items/c403a2a997a0247adc96)は
####変数=関数(引数)
で終わりました。
しかし、このまま関数を進めても理解が深まらないままになる恐れがあるのでここでストッピします。

今日引っ張り出したるものは、初学者でも避けては通れない関数、これです

```Python:func.py
print('Hello World')
#Hello World
```

そう、この`print(  )`も関数なんです。しかも`○○料理`と`変数名`が無くても食材を入れたら調理してくれます。

この`print関数`の事をPythonでは`組み込み関数`といいます。
Pythonではどのくらいの数があるのでしょう？
[Python公式サイト:組み込み関数の種類と使い方](https://docs.python.org/ja/3.7/library/functions.html#built-in-functions)に種類と使い方が載っています。
思いのほか沢山ありますが、学習を進めていく中で覚えて行くと思いますので、無理に覚える必要はないです。

ここから少しややこしくなるのですがトリビア的に覚えておいて下さい。とてもプログラミング的思考で個人的に好きな考え方です。

###`print関数`は戻り値を返さない
通常関数は戻り値を返して変数に代入します。
しかし`print関数`は

```python:func.py

print('Hello World')
#Hello Worldとプリントするだけで戻り値はない

```

戻り値は無いと言いますが、実は`print関数`も`戻り値`をけなげに返してるんです。
何を`戻り値`として返してるのか？それは
##None
ノネと読むのでは無くノンです。つまり`無い`を`戻り値`として返してるんです。
Aさん「Bさん、貸した金を返してよー」
Bさん「Aさん、ゴメンよー。0円返すよー」
つまりこんな不毛なやり取りをしているんです。
だから戻り値は無い。という訳です。

fin
【機械学習】kaggleについて調べてみて

cloud dayでkaggleに関する動画があり、kaggleを知る
↓
何かの技術かと思ったらぜんぜ違う。
https://www.codexa.net/what-is-kaggle/
＝＝＝
Kaggleでは、企業や政府などの組織とデータ分析のプロであるデータサイエンティスト/機械学習エンジニアを繋げるプラットフォームとなっています。単純なマッチングではなく、Kaggleの最大の目玉とも言える「Competetion（コンペ）」がKaggleの特徴の一つです。
＝＝＝
↓
機械学習の基本を学ぶことが必要みたいだけど、
twitterにも関連のつぶやきをしている人は多いので、
そのへんもみてみる。
RealSenseでSkeleton Trackingできるらしい

RealSenseを持ってるけどKinect持ってないのでSkeleton Trackingはできないかぁ～と諦めかけていたところ、なんとRealSenseで[Skeleton Tracking SDKが使える](https://dev.classmethod.jp/articles/skeleton-tracking-sdk-by-cubenos-tutorial-windows/)と聞いて。


#インストール
https://www.intelrealsense.com/skeleton-tracking/
ここの右側「Quick Start」から始める。

※なぜかGmailが受付されない。Yahoo mailはOK。

今回はpythonで試す。
[この記事](https://dev.classmethod.jp/articles/skeleton-tracking-sdk-by-python/)によると、python 3.8は未対応らしい。
ので、
#仮想環境を作る
仮想環境は、これで作成。
https://www.python.jp/install/windows/venv.html

環境ができたら
```python
py -3.7 -m venv py37env
```
で3.7で実行できるようにする。
```python
python estimate-keypoints.py -o C:\tmp\output01.jpg C:\Users\ユーザー名\Downloads\画像名.jpg
```

でけた！

![output01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559550/90066521-a87f-27be-546d-6f3127f4aaaf.jpeg)
※大好きなアーティストSawa Angstromとテクニカル集団SPEKTRAのコラボオンラインLIVEのもよう(2020/06/13)[YouTube](https://youtu.be/Yurm7MoLQVc)

次はRealSenseで取得したリアルタイム映像でやってみたい。

これ、TouchDesignerに埋め込めないかなぁ。
もしくは外部連携でもこのトラッキング画がTDで読み込めたら、いろいろできそう…。と夢膨らまし中。
比較演算子 論理演算子（アウトプット）

#比較演算子

```
>= 以上
<= 以下
> よりも上
< よりも下
=== 等しい
```

#論理演算子

```
&& かつ　両方の条件を満たした場合
|| または　どちらかの条件を満たした場合
! 条件の成否を反対にする(満たしている場合に満たしていない、満たしていない場合満たしている)
```
初心者によるプログラミング学習ログ 344日目

#100日チャレンジの344日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
344日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>344日目　3h<br>・ポートフォリオ作成<br>・前につくった課題サイトをいじる<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1271900595960475648?ref_src=twsrc%5Etfw">June 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Rubyでチンチロゲームを作る 　最終回　レビューを受けての改善

# レビューをもらおう
　前回の記事で一応は全体のコードは仕上がった。しかし、まだまだアラが多い。そういうわけで、自分が所属しているオンラインサロンでコードレビューをしてもらった。けっこうたくさんの指摘があったので、ひとつずつ対応していった。

# 指摘事項一覧

#### 文法関連
+ Rubyのインデントは半角スペース2つ
+ 単純な比較は==を使用する/thenも必要なし
+ 変数展開を使ったほうがいい

+ ファイル名がわかりにくい（`transfer_money` -> `player.rb`へ）

#### メソッドの移動
+ サイコロを振る/お金をかけるのはplayerの中にいれたほうがいい
　（playerの行動であるため）

+ `check_win_lose`や`transfer_money`メソッドはPlayerのメソッドではないかも


#### 読みやすくする

+ `main.rb`はゲームの流れの単位でメソッド化すると全体がみやすくなる
+ 同じ内容が複数ある箇所はまとめる(`strength_relationship`など)
+ `roll_dice`の引数をなくす
+ メッセージを出す場所と処理する場所を別にする


#### その他改善
+ メソッドの戻り値が文字列なのはよくない
　定数または列挙子を使用

+ 班長の賭け金の設定がもったいない（所持金に応じて賭け金を変える）

+ 演算子で勝敗やお金の移動ができるといい。

多すぎ！！！

　

# 指摘事項の対応1：文法関連
　やっていこう。まずは文法関連だが、これはわりとすぐに改善できた。インデントの修正はVSCodeの場合は楽にできた。以下の記事を参考にした。

　[VSCodeでインデントのスペース数を変更する](https://qiita.com/Sinhalite/items/c25bb6efabddcefaf010)

　変数展開はこんなこと。こんなふうにするとすっきり書ける。

```ruby
dice_hand = '通常の目(' + uniq_value.to_s + ')'
↓
dice_hand = "通常の目(#{uniq_value.to_s})"
```

対応したissueのURL
https://github.com/kyokucho1989/ruby-game/issues/13


# 指摘事項の対応2: メソッドの移動とか
　これはもろもろがんばった。まずは勝敗判定や、賭け金の移動を行うのがPlayerではおかしいとのことだったので、あらたにGameクラスを作成した。そのGameクラスが勝敗判定や賭け金の移動を行う。

　また、それを行うのはクラスメソッドでやることにした。gameクラスは状態を持っていないためだ。（これも指摘された）

# 指摘事項の対応3: 読みやすくする
　文章を出力させるのもひとつにまとめた。`message.rb`をあらたに作成し、そこから全てのメッセージが出るようにした。こうすることで、文章を修正する時に楽になる。いいね！


# 指摘事項の対応4: その他

+ メソッドの戻り値が文字列なのはよくない（定数または列挙子を使用）
　
これが難しかった。たしかに文字列で返すと、ちょっとしたタイプミスでバグが生じる。ちょっとがんばることにした。

　あらたに `module-hand-game.rb`　を作成し、役と勝敗結果を定数にした。

```ruby
module Match
  WIN  = '勝ち'
  LOSE = '負け'
  DRAW  = '引き分け'
end
```

参照するときはこんなかんじ。いいね！

```ruby
if(my_hand_rank > opponent_hand_rank)
      Match::WIN 
     elsif(my_hand_rank == opponent_hand_rank)
      Match::DRAW
     else
      Match::LOSE
     end
```

「演算子で勝敗やお金の移動ができるといい。」は対応できなかった。むずい。


# おわりに
　Rubyだけでこんなにプログラミングができるのが楽しかった。Railsを含めていろいろやると、環境構築のエラーなどでやる気がそがれがち。はじめはRubyだけでなんか作った方が単純に力がつく気がする。

　いつかこれで教材を作りたいなぁ。おわり。
　完成したコードはこちらにあります↓
https://github.com/kyokucho1989/ruby-game
お手軽にDataWeaveをブラウザで実行する方法

Muleアプリケーションでデータ変換処理を実装する言語「DataWeave」の便利ツールを紹介します。

DataWeaveで実装した変換処理部分の動作だけを確認したい場合に、Anypoint StudioやDesign CenterでMuleフローを作りPostman等でデータを送信して確認するのは非常に面倒です。

ローカルで [DataWeaveをコマンドラインから実行する](https://qiita.com/shunkosa/items/3f8da54946bf737e10dd) 方法もありますが、Windowsに対応していなかったりCUIなので入力データもDataWeaveスクリプトも少し長くなるとファイルで扱う事になりまだ面倒です。

それならばと、ブラウザを使ってDataWeaveの動作を確認できるWebアプリケーションをMuleで自作しました。
[GitHub - DataWeavePlayground](https://github.com/yamamoWorks/DataWeavePlayground)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34119/9eb05253-0fef-8758-a2e3-de244a1b0074.png)

**しかーし！**

先日の[MuleSoft Connect Digital](https://connect.mulesoft.com/)の「DataWeave: Powerful data transformations with less code」セッションにて、ブラウザでDataWeaveを実行する**神ツール**が紹介されていたので、ここでも紹介したいと思います。

## dw-playground
dw-playgroundはMuleSoftの中の人（たぶん）である[machaval](https://hub.docker.com/u/machaval)さんが公開しているツールです。
Webアプリケーションでブラウザを使ってDataWeaveの動作を確認でき、しかも**Anypoint Studioと同じような入力補助まで付いています**。
なお、ソースコードの公開やアプリ単位での配布はなくDockerイメージとして公開されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34119/802c8f7d-a86e-1a27-a16a-4ef393108cf7.png)


## セットアップ
Docker自体のセットアップ手順は省きます。
Docker Hub [machaval/dw-playground](https://hub.docker.com/r/machaval/dw-playground)からイメージをpullします。

```docker
docker pull machaval/dw-playground
```
私がやった時は上記では上手くいかず`docker pull machaval/dw-playground:2.3.1-SNAPSHOT`でpullしました。

アプリはコンテナ内で8080ポートで起動するので適当なポートをマッピングしてコンテナを起動してください。

```docker
docker run --name dw-playground -p 8000:8080 machaval/dw-playground:2.3.1-SNAPSHOT
```

## 使い方
INPUT EXPLORERで入力値となるpayloadやvarsの中身を定義します。
SCRIPT EXPLORERでスクリプトを定義します。関数などを定義した外部ファイルも追加可能です。
入力値やスクリプトが変更されるとリアルタイムでOUTPUTが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34119/6bc76684-773a-cb0e-fb75-0eb1a7d239d8.png)

## 余談
Windows 10 May 2020 UpdateでGAしたWSL2（Windows Subsystem for Linux）とDocker for Windowsの組み合わせでサクッとコンテナを起動して試せるのは素晴らしいですね。
RESTful APIの学習がてらLINEスタンプ作った

最近実務でAPIに触れる機会が多いので、
RESTful APIってなんなの？ってことを学習するついでに
LINEスタンプ作ってみました。

# まず成果物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514870/0968486d-6136-0e7c-7c61-9ffd83162aa0.png)

https://store.line.me/stickershop/product/12190418/ja?ref=lsh_stickerDetail

※クソ適当に作ったのでサイズも全てバラバラです。
※[LINE Creators Studio](https://creator.line.me/ja/studio/)
※携帯のアプリで作れます(僕は携帯で寝ながら作りました。)

今回参考にさせていただいたのがこちらの記事です。
[RESTful APIのHTTPステータスコード設計](https://qiita.com/NagaokaKenichi/items/eb85b5fbb719d60c6627)
※あくまで上記の記事を個人的に解釈して表したものになります。

# RESTful APIって何？

まずこちらの記事を読んでみました。
[RESTful APIとは何なのか](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)
[https://blog.api.rakuten.net/jp-restful-api/](https://blog.api.rakuten.net/jp-restful-api/)
[0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)

- アドレス可能性(Addressability)
 - 提供する情報がURIを通して表現できること。全ての情報はURIで表現される一意なアドレスを持っていること。
- ステートレス性(Stateless)
 - HTTPをベースにしたステートレスなクライアント/サーバプロトコルであること。セッション等の状態管理はせず、やり取りされる情報はそれ自体で完結して解釈できること。
- 接続性(Connectability)
 - 情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができること。
- 統一インターフェース(Uniform Interface)
 - 情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)を利用すること。

この4つの原則に従っていることが大前提ということはわかるし、
意味もなんとなくわかりますが、

### 「世の中で提供されてるAPIって基本RESTfulなんじゃないか？」

という疑問が拭えなかったので、アンチパターンについて調べてみました。

[RESTアンチパターン](https://www.infoq.com/jp/articles/rest-anti-patterns/)

こんなAPIってあるの？って思ってしまいましたが
きっとあるんでしょう・・。

# 学習してみて
記事で調べてると、そりゃそうだろって思うことがほとんどでしたが、
自分で開発してみないとわからないことが多そうな感じだったので、

>・RESTの制約
　★プログラミング言語はリソース指向ではないので、URIとマッピングするコードは汚くなりがち

※[0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)参照

一回自分でAPI設計をして開発してみようと思いました。

[WebAPIについての説明](https://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47#%E8%87%AA%E5%89%8D%E3%81%AEwebapi%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)

こちらがかなりわかりやすく実装していそうだったの、こちらを参考に実装をしてみようと思います。
JavaをSDKMANでバージョン管理する

## 背景

Oracle Javaも商用利用が有償化したらしいし、GUIでインストールしたり面倒だったので、なんとなくJavaScriptの`nodenv`みたいにCLIでJavaもバージョン管理できるようにしたいなと思って調べてみました。

## `xxxenv`みたいなJavaのバージョン管理ツールはないのか?

`jenv`なるものがありました。
ただ、Java自体は自力でインストールする必要があるらしく、あくまで`jenv`はバージョン切り替えツールという位置付けっぽいようでした。

`nodenv`みたいにインストールもバージョン切り替えもできるのがいいなぁ。

## SDKMAN

インストールもバージョン切り替えもできるもので探すと、[SDKMAN](https://sdkman.io/)というのがありました。
以下を参考にインストールしました。
[#Java: vol1: 【 java・JDKバージョン管理 ベストプラクティス 】](https://qiita.com/locona_0810/items/f4c0141ca02a191ede52)

ちなみに今回はAdoptOpenJDKのJava 8をインストールしようとしましたが、`list`には2つ出てきました。

```zsh
% sdk list java
```

- `8.0.252.j9-adpt`
- `8.0.252.hs-adpt`

調べてみるとJVMが違うらしい。
[AdoptOpenJDKのダウンロード及びインストール](https://www.javadrive.jp/start/install/index6.html)

`j9` = OpenJ9
> Eclipse OpenJ9 は Eclipse コミュニティーの JVM です。低メモリ使用量と高速起動用に設計されたエンタープライズクラスの JVM であり、 IBM の JDK で使用されています。

`hs` = HotSpot
> HotSpot は OpenJDK コミュニティの JVM です。 現在最も広く使用されている JVM であり、 Oracle の JDK で使用されています。

という意味らしいので、今回は無難に従来のOracleと同じ`hs`にしてみました。
(OpenJ9の方がエンタープライズ向けで高機能ってことかな。将来的にはこっちの方がいいのかな?)


## Oracle Javaをアンインストール

こちらを参考でいけたと思う。。。(うろ覚え)
[MacでのJavaのアンインストール方法](https://www.java.com/ja/download/help/mac_uninstall_java.xml)


### Oracle Javaをアンインストールしたら、例のダイアログが表示されてしまう！

IntelliJ IDEAを起動する度に`"java"コマンドラインツールを使用するには、JDKをインストールする必要があります。`みたいなダイアログが`sdkman`でJavaインストール後も表示され続けてしまいました。

対策は、`File > Invalidate Caches / Restart`でダイアログが表示されなくなりました。
[JDKs installed with SDKMAN are not selectable in the IntelliJ IDE](https://stackoverflow.com/questions/59180226/jdks-installed-with-sdkman-are-not-selectable-in-the-intellij-ide)


## 確認

```zsh
% java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.252-b09, mixed mode)
```

また、IntelliJ IDEAで従来のJavaプロジェクトをRunできました。
とりあえず大丈夫そうです。


## 今後の課題

これでAndroidの開発環境も移行できていたと思ってたら、Android StudioにはJDKが同梱されているみたいですね。
こいつの正体は何だろう。Androidはまた必要になったら考えたいと思います。

```zsh
/Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home/bin/java -version
openjdk version "1.8.0_242-release"
OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
OpenJDK 64-Bit Server VM (build 25.242-b3-6222593, mixed mode)
```
Qiita Contributions Portfolio (Auto Generated)

#  私の Qiita ポートフォリオ

※この記事は自動生成です。

[hassaku_63](https://qiita.com/hassaku_63) が投稿した記事を集計し、サマリを表示しています

## Pickups

Articles sorted by likes









|Likes|Article|
|:---:|:---|
|102 likes|[Excel方眼紙で手順書作るのやめ隊 - AWS/GitHub/CircleCI/mkdocs でドキュメント管理- ](https://qiita.com/hassaku_63/items/83daf4dac111f0b5390f)|
|36 likes|[AWSソリューションアーキテクト プロフェッショナル 合格メモ](https://qiita.com/hassaku_63/items/8e12cfbd4fbc5aa4c49a)|
|31 likes|[VSCodeでエディタ画面とターミナル間のフォーカスを楽して移動したい](https://qiita.com/hassaku_63/items/4d14d949c3ce9edd9909)|
|14 likes|[[Python/pandas] DataFrameの欠損値をカウントする](https://qiita.com/hassaku_63/items/2c2c2cb01901bbffec0b)|
|11 likes|[[AWS Amplify][AppSync] API_KEYによる認証を使っている場合に発生しうる "Error: No credentials" 問題の対処](https://qiita.com/hassaku_63/items/4070c47c06920fef9683)|

## Frequent tags









|Count|Tag|
|:---:|:---:|
|Python|19|
|AWS|17|
|PyConJP|4|
|serverless|3|
|ServerlessFramework|3|
|Qiita|3|
|機械学習|3|
|EC2|3|
|自然言語処理|2|
|word2vec|2|


# Appendix: About this article

This article is generated by;

- Serverless Framework
- AWS
    - Step Functions
    - Lambda
    - SQS
    - DynamoDB
    - etc

This article will updates everyday, probably...

I'm going to share with you an article that explains the source code and the architecture of this auto-generation system .... sometime.
(自分用)Flask_1(起動、基本構造、ルーティングの基本、テンプレートの基本)

# 項目
1. Flaskの起動
2. Flaskの基本的な構造
3. ルーティング追加
4. テンプレートの基本(呼び出し,pyファイルからhtml操作,html内でpythonを書く)

# 1.Flaskの起動
- `cd <ディレクトリ名>`で作業したディレクトリに移動しておく
- `FLASK_APP=<作業したpyファイル名> flask run`で起動
- 変更を常に反映したい場合は`FLASK_APP=<作業したpyファイル名> FLASK_ENV=development flask run`で起動
- localhostの5000の奴で確認

# 2.Flaskの基本的な構造
```python
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello World!"
```
これが一番基本的な`Hello World`を返すやつ

- `from flask import Flask`の説明は割愛
- `app = Flask(__name__)`は`name`と言うFlaskのインスタンス[^1]をappと言う変数に入れている
- `app.route("/")`で`http://~~/`ってアドレスを指定する、このアドレスの時に下の動きするよって感じ。<br>
基本このrouteって奴で色んな動き呼び出す
- `def ~~ "Hello World"`はどう動くかの関数

[^1]: 作業したファイルの作業内容みたいなもん、Flaskで作ったもの=Flaskのインスタンス

# 3. ルーティング追加
- 新しく`@app.route("/任意のアドレス末尾")`を作ってその下に作業すればOK<br>
直でブラウザで確認したい時は上のローカルホスト5000の末尾に`/~~`って入れてね

# 4. テンプレートの基本
- テンプレートを使う事でpythonとhtmlとかを良い感じに一緒に動かせる

```python

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def hello_world():
    return render_template("index.html")

@app.route("/second")
def second():
    return "second"
```

- `import flask`の後に`render_template`をつけておく
- ルート内関数のreturnに`render_template("<入れたいhtmlファイル>")`ってやる事で、htmlファイルを呼び出せる

## 4-2.pyファイル側からhtmlにデータを渡す
```python

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def hello_world():
    name = "Flask"
    return render_template("index.html", name_value = name)

@app.route("/second")
def second():
    return "second"
```
- `index.html`の後に有る`name_value = name`とは、`name_value`の中に`name`の内容を入れると言う事

```html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <p>{{name_value}}</p>
</body>
</html>
```
- html側で`{{pyで作った変数(合ってる?)}}`と書く事で、pyファイル側からhtmlに入力することが出来る。<br>
二重かっこで変数名`{{~~}}`

## 4-3.html側でpythonを書いてみる
```html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    {% if name_value %}
        <p>{{name_value}}</p>
    {% else %}
        GOGOGO!!!
    {% endif %}
</body>
</html>
```
- html内でpythonを書く時は`{% ~~ %}`と書く[^2]
- 今回はpy側で`name_value`の変数が用意されてれば`name_value`の内容を動かす、違うならGOGOGO!!!<br>
最後の`{% endif %}`を付ける理由として、html内でのpython操作はインデントを認識していないため、endifを付けないと終わりが判断出来ないから

[^2]: pythonと"パーセントが似ているから?わりかしありそう"

# 5.終わりに
- 取り敢えずの基本だけ
- 次はサーバ接続関係まで出来れば良いかもね
Neo4j: Cypher チートシート

[Neo4j による Cypher の公式リファレンス](https://neo4j.com/docs/cypher-manual/current/)

初心者が Cypher を容易に使うためのチートシート

## Node 作成

```
CREATE ([in_query_name]:[Label] { [anykey: anyvalue],... }), ...
RETURN [in_query_name], ...

// 実例
CREATE (a_san:Person { name: "Aさん", 所属: "開発部" }), (b_san:Person { name: "Bさん", 所属: "経理部" })
RETURN a_san, b_san
```

## Relationship 作成

### 例１: ２つの Node を明示して連結
```
MATCH (a_san: Person), (b_san: Person)
WHERE a_san.name = "Aさん" AND b_san.name = "Bさん"
CREATE (a_san)-[r:知っている]->(b_san)
RETURN r
```

### 例２: 外部キーを使って連結

```
MATCH (p:Product),(c:Category)
WHERE p.categoryID = c.categoryID
CREATE (p)-[:PART_OF]->(c)
```

### 例3: 連結テーブルを使って連結 ( HasAndBelongsToManyケース )

```
LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/order-details.csv" AS row
MATCH (p:Product), (o:Order)
WHERE p.productID = row.productID AND o.orderID = row.orderID
CREATE (o)-[details:ORDERS]->(p)
SET details = row,
    details.quantity = toInteger(row.quantity)
```

## Node の Index

### 例：Product Labelの categoryID Propertyにインデックスを貼る場合

```
CREATE INDEX ON :Product(categoryID)
```

### Index を確認する

```
CALL db.indexes
```

## Fulltext Index（全文検索インデックス）

### Fulltext Index を付ける

```
CALL db.index.fulltext.createNodeIndex("nameAndDescription",["Thing","Person","Product"],["name", "description"])
```

### Fulltext Index を確認する

```
CALL db.index.fulltext.queryNodes("titlesAndDescriptions", "matrix") YIELD node, score
RETURN node.title, node.description, score
```

### Fulltext Index を削除する

```
CALL db.index.fulltext.drop('nameAndDescription')
```

※ 実行しても(no changes, no records) とか出るので一見成功しているかわかりにくい

## Node の選択

```
MATCH (a_san: Person), ...
WHERE a_san.name = "Aさん" [AND ...]
RETURN a_san, ...

// ex
MATCH (a_san: Person), (b_san: Person)
WHERE a_san.name = "Aさん" AND b_san.name = "Bさん"
RETURN a_san, b_san
```

### datetimeの比較

```
WHERE n.start > datetime("2010-01-01T00:00:00+0900")
```

### 全ての Node, Relationsを削除

```
MATCH (n) DETACH DELETE n
```

※ 注意：Nodeに Relationshipがある場合はNodeの削除はできないので、 DETACH が必要
※ データが多くて削除が遅い場合は、[全てのデータを削除する](https://qiita.com/euonymus/items/82260dbbda4df7c2f68f) の記事参照

## CSVのImport

```
LOAD CSV WITH HEADERS FROM "http://data.neo4j.com/northwind/products.csv" AS row
CREATE (n:Product)
SET n = row,
  n.unitPrice = toFloat(row.unitPrice),
  n.unitsInStock = toInteger(row.unitsInStock),
  n.unitsOnOrder = toInteger(row.unitsOnOrder),
  n.reorderLevel = toInteger(row.reorderLevel),
  n.discontinued = (row.discontinued <> "0")
```

## Propertiesの明示方法

### Float 型にする

```
n.unitPrice = toFloat(row.unitPrice),
```

### Integer 型にする

```
n.unitsInStock = toInteger(row.unitsInStock),
```

### Boolean 型にする

```
n.discontinued = (row.discontinued <> "0")
or
n.discontinued = toBoolean(row.discontinued)
```

### datetime 型にする

```
n.start = datetime("2010-01-01T00:00:00Z")
```

### timestamp 型にする

```
n.startedtime = timestamp(row.startedtime)
```
JavaScript でネストしたJsonをパースする

# 最初に
今回はネストしたJsonの特定の「key」を指定して抽出する方法を展開します。
## ターゲット
今回のJsonデータさんです。

```json:test.json
{
  "test": {
     "word": "テスト"
   }, 
　"user": [{
     "id": 520, 
     "name": "Test"
   }]
}
```
## 抽出作業

```javascript:test.js
var testJson = {
  "test": {
     "word": "テスト"
   }, 
　"user": [{
     "id": 520, 
     "name": "Test"
   }]
};

//「"word": "テスト"」を抽出する
var extractionWord = testJson.test.word;
//「"name": "Test"」を抽出する
var extractionId = testJson.user[0].name;
//コンソール出力
console.log(`抽出結果：___word抽出：${extractionWord }___name抽出：${extractionId }`);

```

↓コンソール画面

```console
抽出結果：___word抽出：テスト___name抽出：Test
```

# 最後に
めちゃくちゃ簡単な抽出方法でした。
特定のKeyを全部抽出とかになるともっといい方法があると思います。
今回はあくまで特定のKeyの情報（value）を抽出してくるという簡単な方法でした。
Neo4j: 全てのデータを削除する

Neo4j ではデータが大きくなると全てのデータが網目のようにお互いに Relation を貼るため全データの一括削除を行いたい場合にデータ量に応じて指数関数的に遅くなり10万を超えるレコードだと待てないくらいおそくなります。

そういう場合は、単純にファイルシステム側からデータファイルを消してしまうのが早いです。

# 普通に Cypher で Delete する

Neo4j の Cypher で普通に Node を全て削除するには、まず全ての Relation を解除して、それから削除する必要があります。

```
MATCH (n) DETACH DELETE n
```

※ DETACH が重要

これだと Node と Relation が多い場合に著しく遅いです。

# ファイルを直接削除する

- Neo4j を停止する
- Neo4j をインストールしたフォルダから data フォルダの中を削除する

Mac に brew install した Neo4j の場合のパス

```
/usr/local/var/neo4j/data
```

Neo4j Desktop for Mac の場合のパス

```
~/Library/Application Support/Neo4j Desktop/Application/neo4jDatabases/database-xxx/installation-x.x.x/data
```
CA.sh がいつの間にか無くなっている

# CentOS 8 で CA 構築用のシェルスクリプト が無くなっている
* クライアント証明書の発行にこのシェルスクリプトを使っており、CentOS 8 でも同じように認証局を立てようとしたが、無くなっていることに気づく

## CentOS 7 では、確かにあった

```
sh-4.2# cat /etc/redhat-release 
CentOS Linux release 7.8.2003 (Core)

sh-4.2# openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

sh-4.2# rpm -ql openssl | grep /etc/pki/tls/misc/CA
/etc/pki/tls/misc/CA
```

# OpenSSL の 1.0.2 まではある様子
* https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/apps/CA.sh

## 1.1.0 からなくなっている
* https://github.com/openssl/openssl/tree/OpenSSL_1_1_0-stable/apps

# どうやら、 CA.pl に一本化された？
* 1.1.0 以降も、 CA.pl は build して生成できるようになっていそう
* CentOS 8 の openssl-perl パッケージにもいる

```
sh-4.4# cat /etc/redhat-release 
CentOS Linux release 8.1.1911 (Core) 

sh-4.4# openssl version
OpenSSL 1.1.1c FIPS  28 May 2019

sh-4.4# rpm -ql openssl-perl | grep /usr/bin/CA.pl 
/usr/bin/CA.pl
```

# とりあえず、1.0.2 の CA.sh をダウンロードして使うことにする
* とはいえ、1.0.2 はもうサポート期限が切れてはいる
  * https://www.openssl.org/policies/releasestrat.html  
    `Version 1.0.2 is no longer supported.`
  * [https://ja.wikipedia.org/wiki/OpenSSL#バージョン履歴](https://ja.wikipedia.org/wiki/OpenSSL#%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%B1%A5%E6%AD%B4)

* CA.pl の使い方は、また機会があれば調べる
  * 解説してるサイトとかあればコメントください
Javaの基本

##　はじめに
これは自分メモです

##　出力の仕方

``` kane.java
System.out.println()
```
（）内にリテラルを入力することで出力できる

``` kane.java
System.out.println("Hello!")
```
文字列の場合""(ダブルクォーテーション)で囲む

``` kane.java
System.out.println("Hello!");
```
**しっかりセミコロンをつける**


System.out.println()というのは、()の中身を出力（表示）せよ」という「命令」

## print(), println() の使い方


``` kane.java
System.out.print("バナナ");
System.out.println("バナナ");
```

print() は末尾に改行は付きませんが、println() は自動的に末尾に改行を挿入します。



## 終わりに
ほんとはもっと書けることがあったが理解があいまいのでやめました。
次回はコンパイラとインタープリタの違いを自分の言葉で書けたらな..と
Neo4j: propertyにユニーク制約を設置する

スキーマレスなグラフデータベースである Neo4j の Node に対して、その Property ごとにユニーク制約を持たせる方法を記述します。

# ユニーク制約の例
Country Label のついた Node に name property をつけて、同一名の国は作成できないように制約をつけたい


# ユニーク制約の設定方法

Neo4j は本来スキーマレスなので、 Country Label をつけたとしても、そこに name property があるかどうかもわかりませんし、同じ名前でそれをつける事もできます。

ユニーク制約をProperty につけるには、Constraint という機能を使います。

Constraint はあらかじめ設定しておく事で Query 実行時に効果を発揮します。

## Country Labelにおいて、name property がユニークになるConstraintの作成例

```
CREATE CONSTRAINT ON (country:Country) ASSERT country.name IS UNIQUE
```

## 自分が設定したConstraintを一覧確認

```
call db.constraints
```

## 上で作成したConstraintを削除

```
DROP CONSTRAINT ON (country:Country) ASSERT country.name IS UNIQUE
```


# 制約
- 複数のLabelをまたいで制約をつける事はできません！！
- 複数のLabelを跨ぎたい場合は共通のLabelを作って常にそのLabelを付加する事で対応します