OmniAICreator/Qiita-1.07M huggingface dataset:
【全てのアプリ開発者に贈る】React Native いろいろ触ってみた【目次】

[ローラハウス](http://laurahouse.net)では、iPhone登場以降、たくさんのスマートフォンアプリ開発を行なってきました。SwiftもKotlinも大好きです。そんな我々が、気になっているのが、[React Native](https://facebook.github.io/react-native/)。本当に日々の開発に使えるのか色々触ってみることにしました。感触としては痒いところに手が届かない感じはありますが、使えるかもしれないなと感じています。これまでさんざん裏切られてきたマルチプラットフォーム環境から考えると、かなりいい感じです。最近は、[Flutter](https://flutter.io/)とかもあるけど、エコシステムが出来て来ている React Native に魅力を感じます。

調査に当たって、日本語の情報が系統的にまとめられているものが、ほとんど存在しない、あっても情報が古かったりという事があったので、記事を書いて公開することにしました。また記事を書くに当たって、次のことを意識しました。

- 記事は出来るだけシンプルに一つのことについて説明するように。
- GIFアニメーションでどんな事が出来るのか一目でわかるように。
- サンプルコードを用意してGithubに公開。メンテナンス可能に。

価値ある情報として蓄積していきたいので、記事とサンプルコードは最新の環境で有効な情報であるようにメンテナンスしていきたいと思いますし、この目次記事には今後も記事を追加していきます。また、記事の編集リクエスト、サンプルコードのプルリクエストもお待ちしています。

ネイティブアプリ開発の皆さんも、また、Javascriptな皆さんにも、役立つ記事であることを願っています。

# お願い
各記事はメンテナンスされて、削除されたり、新たに書き直されたりする事もあると予想しています。ストックされる場合は本記事に対して行なってくれると混乱が防げると思います。

# 環境

#### 【React Native】 開発環境の構築とアプリ作成最初の一歩
なにはともあれ、環境構築して、React Nativeの世界に触れてみましょう。
https://qiita.com/keneo/items/aaa5946bfa4d10353302

#### :sparkles::new::sparkles:【React Native】 Expoを使えば審査なしにアプリ更新出来てウハウハなのか？
React Nativeを採用するなら、Expo も使いたい気分ですよね。実際のところどうなんでしょうか。
https://qiita.com/keneo/items/625c7623d0dfb0cf0c6c

# ユーザーインターフェース

#### 【React Native】NativeBase導入
React Native の標準のUIは若干垢抜けない感じです。ネイティブアプリっぽいものが作りたいなら、「NativeBase」がお勧めです！
https://qiita.com/keneo/items/d3a36d973c0b89829aa9

#### 【React Native】NativeBaseのテーマを設定してみる
NativeBase には統合的に配色を管理する仕組みが用意されています。プラットフォーム（iOS, Android）固有の配色や、マテリアルデザインもこれでOK!
https://qiita.com/keneo/items/a03d8f28ceb584bc3ff6

#### 【React Native】React Navigation を使ってみる（画面遷移編）
画面遷移を行うためのライブラリの一つである「React Navigation」の紹介です。
https://qiita.com/keneo/items/b62ddcab0e35ce792b67

#### 【React Native】React Navigation を使ってみる（タブバー編）
React Navigation ではタブバーの表示も可能です。
https://qiita.com/keneo/items/647d53d293470ae2b7f6

#### 【React Native】NativeBaseのListを使ってみる
アプリ開発で一番使うといっても過言ではないのはリスト表示。ここでは、NativeBase のネイティブアプリライクなリストと、セルの再利用などについて記述しています。
https://qiita.com/keneo/items/8f47e0c6a2d8e3cb1c10

#### 【React Native】Image picker を使ってみる
カメラロールと、カメラ撮影の簡単な画像選択ができる「Image picker」を使ってみましょう。
https://qiita.com/keneo/items/cb853bcfd85b282e6cf6

# アーキテクチャー

#### 【React Native】React Redux って覚えるの面倒だけど使うしかないよね
Reactと同時に語られることの多いRedux。ReactNativeでも必要となってきます。用語とか難しいけど、実は大したことではないんです。
https://qiita.com/keneo/items/514ffc98102d95162f00

#### 【React Native】React Redux で通信処理をViewから独立させよう
私の場合、通信処理をどこに書いたら良いか、最初全然わかりませんでした。Reduxを導入すると、Viewから分割できてスッキリとかけます。
https://qiita.com/keneo/items/fa31ac15cda215926392

#### 【React Native】Realmでローカルデータベース
Webアプリと違って、ネイティブアプリはローカルデータベースが必要な事多いですよね。定番のRealmを使ってみましょう。
https://qiita.com/keneo/items/2460fa20c2dbbb61bac1
【React Native】Realmでローカルデータベース

# ローカルにデータベース？
ネイティブなモバイルアプリを作成する場合、SPAを含むWebアプリと違って、ローカルへの情報の永続化が必要となる場合があります。あなたのアプリをネイティブアプリにする一つの理由であるかもしれません。

# Realm とは
https://realm.io/

Realm Database は、モバイルアプリで従来使用していたSQLite や Core Data といったデータベースの代替として開発されました。モバイルアプリをターゲットにゼロから設計されたため、非常に高速で使い方もとても簡単です。React Nativeでも使用する事ができるので、使ってみましょう。

# 前提ライブラリ
本記事は、「NativeBase」の導入を前提としています。一からプロジェクトを作成する場合には、以下の記事を参考に環境作成してください。
[【React Native】NativeBase導入](https://qiita.com/keneo/items/d3a36d973c0b89829aa9)

# インストール
```
$ npm install realm --save
```

# 使用方法
```js
import React, {Component} from 'react';
import { FlatList } from "react-native";
import { Container, Header, Left, Body, Right, Title, Content, List, ListItem, Text } from 'native-base';
import Realm from 'realm'

type Props = {};
export default class App extends Component<Props> {
  constructor(props) {
    super(props);
    this.state = { realm: null };
  }

  componentWillMount() {
    Realm.open({
      schema: [{name: 'Person', properties: {key: 'string', name: 'string'}}]
    }).then(realm => {
      realm.write(() => {
        var current = new Date();
        realm.create('Person', {key: current.toString(), name: 'daisuke'});
      });
      console.log(realm);
      this.setState({ realm });
    });
  }


  render() {
    const displayItem = this.state.realm ? this.state.realm.objects('Person') : [] 

    return (
      <Container>
        <Header>
          <Left />
          <Body>
            <Title>Realmサンプル</Title>
          </Body>
          <Right />
        </Header>
        <Content>
        <FlatList
          data={displayItem}
          renderItem={({item}) =>
            <ListItem>
              <Text>{item.name}</Text>
            </ListItem>
          }
          keyExtractor={item => item.key}
        />
        </Content>
      </Container>
    );
  }
}
```

一番簡単にRealmでデータベースへの読み書きを実現してみました。プログラムの再起動（リロード）時にレコードが追加され、リストに表示されます。

## スキーマ
```js
{schema: [{name: 'Person', properties: {key: 'string', name: 'string'}}]}
```
上記のような形で、「Person」テーブルに「key, name」という２つのプロパティを持つレコードを定義しています。

# 動作の様子
![ios.gif](https://qiita-image-store.s3.amazonaws.com/0/22218/d84afe44-d607-2252-ec88-d53f7549bca2.gif)

# リポジトリ
本記事で作成したものは以下で公開していますので、参考にしてください。
https://github.com/k-neo/ReactNativeCourseRealm
【React Native】Image picker を使ってみる

# react-native-image-picker
画像、動画を選択する「Image picker」のライブラリを使ってみようと思います。

https://github.com/react-community/react-native-image-picker

# 前提ライブラリ
本記事は、「NativeBase」の導入を前提としています。一からプロジェクトを作成する場合には、以下の記事を参考に環境作成してください。
[【React Native】NativeBase導入](https://qiita.com/keneo/items/d3a36d973c0b89829aa9)


# インストール
```
$ npm install react-native-image-picker  --save
```

# 権限の付与
ネイティブアプリを作成する際にも行いますが、ライブラリ、カメラへのアクセスにはユーザの許可が必要であり、その旨をアプリとして宣言しておく必要があります。プロジェクト内にあるiOS、Androidのそれぞれのネイティブプロジェクトに設定を記述する必要があります。

## iOS

Info.plist に以下の情報を追加します。

```xml
    <key>NSPhotoLibraryUsageDescription</key>
    <string>$(PRODUCT_NAME) would like access to your photo gallery</string>
    <key>NSCameraUsageDescription</key>
    <string>$(PRODUCT_NAME) would like to use your camera</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>$(PRODUCT_NAME) would like to save photos to your photo gallery</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>$(PRODUCT_NAME) would like to your microphone (for videos)</string>
```

## Android

AndroidManifest.xml に以下の情報を追加します。

```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```

# アプリ作成

```jsx
import React, {Component} from 'react';
import { Container, View, Header, Left, Body, Right, Button, Title, Text, Thumbnail } from 'native-base';

type Props = {};
export default class App extends Component<Props> {
  constructor(props) {
    super(props);
    this.state = {
       image: null,
    }
  }

  showPicker = () => {
    let ImagePicker = require('react-native-image-picker')

    let options = {
      title: '画像を選択',
      storageOptions: {
        skipBackup: true,
        path: 'images',
      },
    }

    ImagePicker.showImagePicker(options, (response)  => {
      if (response.didCancel) {
        console.log('User cancelled image picker');
      } else if (response.error) {
        console.log('ImagePicker Error: ', response.error);
      } else {
        console.log(response.uri)
        this.setState({image: response.uri})
      }
    });
  }

  render() {
    return (
      <Container>
        <Header>
          <Left />
          <Body>
            <Title>メイン</Title>
          </Body>
          <Right />
        </Header>
        <View>
          <Button small iconRight  transparent primary onPress={this.showPicker}>
            <Text>画像の選択</Text>
          </Button>
          {this.state.image && <Thumbnail square large source={{uri: this.state.image}} />}
        </View>
      </Container>
    );
  }
}
```
#　動作の様子
## iOS
![ios.gif](https://qiita-image-store.s3.amazonaws.com/0/22218/b5e80f48-e17b-fbbf-170b-8d0de1d166d1.gif)

## Android
![android.gif](https://qiita-image-store.s3.amazonaws.com/0/22218/6927a9cc-119f-efb8-025a-dec8d0487674.gif)

# リポジトリ
本記事で作成したものは以下で公開していますので、参考にしてください。
https://github.com/k-neo/ReactNativeCourseImagePicker
【React Native】React Navigation を使ってみる（タブバー編）

# 環境構築
[React Navigation を使ってみる（画面遷移編）](https://qiita.com/keneo/items/b62ddcab0e35ce792b67) と同様のライブラリを使用します。

# アプリ作成

## App.js

```js:App.js
import React, {Component} from 'react';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
import { Icon, MaterialIcons } from 'native-base';

import Main from './screens/Main'
import Push from './screens/Push'
import Modal from './screens/Modal'
import List from './screens/List'

const MainNavigation = createStackNavigator(
  {
    Main: { screen: Main },
    Push: { screen: Push },
  },
  {initialRouteName: 'Main', headerMode: 'none'}
)
const HomeNavigation = createStackNavigator(
  {
    MainNavigation: { screen: MainNavigation },
    Modal: { screen: Modal },
  },
  {initialRouteName: 'MainNavigation', mode: 'modal', headerMode: 'none'},
)

const ListNavigation = createStackNavigator(
  {
    List: { screen: List },
  },
  {initialRouteName: 'List', headerMode: 'none'}
)

const TabNavigation = createBottomTabNavigator(
  {
    Home: { screen: HomeNavigation,
      navigationOptions: () => ({
        tabBarIcon: ({tintColor}) => (
          <Icon type="FontAwesome" name="home" style={{color:tintColor}} />
        )
      }),  
    },
    List: { screen: ListNavigation,
      navigationOptions: () => ({
        tabBarIcon: ({tintColor}) => (
          <Icon type="FontAwesome" name="th-list" style={{color:tintColor}} />
        )
      }),
    },
  },
  {
    tabBarOptions: {
      activeTintColor: '#444444',
      inactiveTintColor: '#cccccc',
    },
  },
  {initialRouteName: 'Home'}
)

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <TabNavigation />
    );
  }
}
```

* 全体のルーティングを定義します。具体的には「BottomTabNavigator」、「StackNavigator」を使用して画面を定義しています。
* 通常の画面遷移を行う２つのグループをタブで切り替えて使用する場合を想定しています。。（BottomTabNavigator と、StackNavigator をネストさせています）
* 画面構成は以下の通りです。
  * メイン画面 （Main.js）
  * プッシュ表示される画面 （Push.js）
  * モーダル表示される画面 （Modal.js）
  * タブ切り替えで表示される画面 （List.js）

## Main.js

「React Navigation を使って見る（画面遷移編）」と同じものを使用します。


## Push.js

「React Navigation を使って見る（画面遷移編）」と同じものを使用します。

## Modal.js

「React Navigation を使って見る（画面遷移編）」と同じものを使用します。

## List.js

```js:List.js
import React, {Component} from 'react';
import { Container, Header, Left, Body, Right, Title } from 'native-base';

type Props = {};
export default class List extends Component<Props> {
  render() {
    return (
      <Container>
        <Header>
          <Left />
          <Body>
            <Title>リスト</Title>
          </Body>
          <Right />
        </Header>
      </Container>
    );
  }
}
```

*タブ切り替えで表示される画面を定義しています。

# 動作の様子

## iOS
![ios.gif](https://qiita-image-store.s3.amazonaws.com/0/22218/a64f6b39-1e50-1ca0-075e-eea93d0e03bf.gif)

## Android
![android.gif](https://qiita-image-store.s3.amazonaws.com/0/22218/ae1504cd-1f44-e274-1193-f5579ac72b77.gif)

# リポジトリ
本記事で作成したものは以下で公開していますので、参考にしてください。
https://github.com/k-neo/ReactNativeCourseReactNavigationTabbar
【React Native】NativeBase導入

# NativeBase
NativeBase は React Native で使用できるUIコンポーネントです。 iOS/Android それぞれに適切なUIを提供し、汎用性のあるコンポーネントを簡単に導入できます。

https://github.com/GeekyAnts/NativeBase

# 環境構築

作成したプロジェクトに対して以下のコマンドでNativeBaseを導入します。

```
$ npm install native-base --save
```

以下のようなメッセージが出てインストールが完了します。

```
┌────────────────────────────────────────────────────────────────────────────────────────────┐
│ NativeBase 2.0 has been succesfully installed!                                             │
│ Run `node node_modules/native-base/ejectTheme.js` to copy over theme config and variables. │
│ Head over to the docs for detailed information on how to make changes to the theme.        │
└────────────────────────────────────────────────────────────────────────────────────────────┘
```

※ 公式サイトなどではこれでOKのはずですが、以降の作業でうまくいかなかったので、下記コマンドを再度実行することで、インストールが最終的な完了状態となるようです。

```
$ npm install
```

続いて、以下のコマンドで NativeBase が iOS/Android プロジェクトに「リンクが必要」であることを指定します。

```
$ react-native link
```

参考："react-native link" は何をするか
https://qiita.com/lazyppp/items/8d5969cd9a5b53587e18

# アプリ作成
App.js を以下のように書き換えて NativeBase のコンポーネントが使用可能なことを確認します。（「Headerコンポーネント」でiOSでのナビゲーションバー、Androidでのアプリバーを表示してみます）

```js
import React, {Component} from 'react';
import { Container, Header, Left, Body, Right, Button, Icon, Title } from 'native-base';

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <Container>
        <Header>
          <Left>
            <Button transparent>
              <Icon name='arrow-back' />
            </Button>
          </Left>
          <Body>
            <Title>タイトル</Title>
          </Body>
          <Right>
            <Button transparent>
              <Icon name='menu' />
            </Button>
          </Right>
        </Header>
      </Container>
    );
  }
}
```

# iOS
<img width="375" alt="ios.png" src="https://qiita-image-store.s3.amazonaws.com/0/22218/fa1a5775-c28f-4a46-7fb4-f2219782fac0.png">

# Android
<img width="375" alt="android.png" src="https://qiita-image-store.s3.amazonaws.com/0/22218/c3310d0b-af83-c382-b5f1-c80902983030.png">


# リポジトリ
本記事で作成したものは以下で公開していますので、参考にしてください。
https://github.com/k-neo/ReactNativeCourseNativebase
並列計算におけるメモリリークの回避（python）

# はじめに
強引な解決策なので悪しからず。メモリリークの原因特定をしたいならば一番下のリンクが参考になる。

# 症状
強化学習を行っている際に、次のようなコードを用いてデータ生成を並列化した。時間が経つと子プロセスのメモリ使用量がどんどん増え、最終的にはメモリ上限に達し、計算できなくなった（ちなみにメモリは24GB）。ループの中身のメモリリークを調べたが原因が特定できなかった。なお、生成するデータ数には上限を設けており、このデータでメモリがあふれることはないものとする。

```mp.py
import multiprocessing as mp
import time
N_PROCESS = 10

# この関数がメモリリークを起こす
def do_something(queue):
    while True:
        # データ生成

if __name__ == "__main__":
    queue = mp.Queue(maxsize=10000)
    for _ in range(N_PROCESS):
        p = mp.Process(target=do_something, args=(queue))
        p.start()
    while True:
        time.sleep(10)
        # queueの読み込み、学習など
```

# 対策
子プロセスで行っていた無限ループを一定回数のループに変更し、終了した子プロセスを再度立ち上げることで同じ内容を実現。子プロセスが走っている間はメモリが増えるが、終了時に子プロセスのメモリはリセットされるため、際限のない増大は抑えられた。

```mp.py
import multiprocessing as mp
import time
N_PROCESS = 10
N_LOOP = 100

def do_something(queue):
    for _ in N_LOOP: # 無限ループを避ける
        # データ生成

if __name__ == "__main__":
    queue = mp.Queue(maxsize=10000)
    processes = []
    for _ in range(N_PROCESS):
        p = mp.Process(target=do_something, args=(queue))
        p.start()
        processes.append(p)
    while True:
        time.sleep(10)
        # 終了したプロセスは再度立ち上げる
        for i in range(N_PROCESS):
            if not processes[i].is_alive():
                processes[i].terminate()
                processes[i] = mp.Process(target=do_something, args=(queue))
                processes[i].start()
        # queueの読み込み、学習など
```

# 参考：メモリリークの調査で使ったもの
- tracememlock（[公式](https://docs.python.jp/3/library/tracemalloc.html)や[qiita記事](https://qiita.com/shunsukeaihara/items/05a4cd38f61f8a6fffa3)参照）
- object graphs（[マニュアル](https://mg.pov.lt/objgraph/)参照）
JUCEのString::formatted()は使うべきではない

String::formatted()が便利なので使っていたのだが、macOS/iOSで問題なく動いていたプロジェクトを出来心でWindowsでもビルドしてみたら見事に動かなかった。原因を調べたら、String::formatted()を使って作ったStringの中身がめちゃくちゃで、まるで文字列になってない。ちょっと検索してみたら、

2008年の時点でこう言ってるし、
https://forum.juce.com/t/using-string-formatted-with-s/2921

そもそもAPIの説明でI don't like itと言っていた。なんだよ…。
https://docs.juce.com/master/classString.html

まぁとにかくプラットフォームによって動いたり動かなかったりなので使うべきではない。代替策は << を使うとか + を使ってくっつけるとか。

String::formatted("%s %d", text, integer);

は、

String(text) + String(" ") + String(integer);

とか。

String::formatted("%3.2f", floatValue);

は、

String(floatValue, 2);

など。
HLSライブストリーミング配信環境を最速で立ち上げる

# TL;DR

先人がdocker imageを用意してくださっているので、それを利用させていただくだけです。

* https://hub.docker.com/r/alfg/nginx-rtmp

以下の記述は上記のページのUsageに書いてあるものと全く同じです。

# 予め用意しておくもの

* docker環境
* [OBS](https://obsproject.com/)
* [ffmpeg](https://www.ffmpeg.org/)

# 手順

dockerイメージをpullしてきてコンテナを立ち上げます。これでnginx-rtmp-moduleが組み込まれたnginxが起動します。

```
$ docker pull alfg/nginx-rtmp
$ docker run -it -p 1935:1935 -p 8080:80 --rm alfg/nginx-rtmp
```

# 動作確認

OBSで配信を試してみます。

* 「ソース」欄から配信に利用する映像キャプチャデバイスを追加します。
* 「コントロール」欄で「設定」→「配信」を選んで、配信サーバの設定をします。例えば以下のように指定します。
  * 配信種別を「カスタムストリーミングサーバー」
  * URLをrtmp://localhost:1935/stream
  * ストリームキーを hello
* 最後に「コントロール」欄から「配信開始」を押すと、配信が始まります。

そしてffmpegで試しに再生してみます。

```
$ ffplay -fflags nobuffer http://localhost:8080/live/hello.m3u8
```

とすれば、手元の映像キャプチャデバイスで取り込んだ映像が画面に出つつ、端末にはm3u8ファイルやtsファイルを順次ダウンロードしてきている様子が映し出されるはずです。
AWS OpsWorks のデバグ

チラ裏。[AWS OpsWorks](https://aws.amazon.com/jp/opsworks/) を使ってインスタンスへの chef (または puppet) 適用を自動で行うことができる。できるのは良いのだが、失敗した時に理由を追うのに困るのでログの場所、および簡単な再実行方法をメモ。

# cloud-init のログおよび再実行

いきなり蛇足: OpsWorks だけでなく、cloud-init (UserData) を使って起動時になにか処理をしている場合、cloud-init のログも見るべし。

```
/var/log/cloud-init.log
```

cloud-init の再実行ついては以前 [cloud-init のスクリプトを reboot せずに再実行するには](https://qiita.com/sonots/items/e60261ea28c61e322631) に書いた。

# OpsWorks のログ

OpsWorks のログは、終われば AWS コンソールから見れるが、進行中はすぐに反映されないので、インスタンスに ssh してログを tail -F で追う。

OpsWorks Chef の場合のパスはこちら。

```
sudo tail -F /var/lib/aws/opsworks/chef/yyyy-MM-dd-hh-mm-ss-..log
```

[AWS OpsWorks Stacks のライフサイクルイベント](https://docs.aws.amazon.com/ja_jp/opsworks/latest/userguide/workingcookbook-events.html) のそれぞれでログファイルが分かれているようだが中を見てみないとどれがどれか分からない。

* setup
* configure
* deploy

先頭行に `Command: setup with` のように setup か configure か deploy かなどが書いてあるので、どのログファイルがどのイベントに対するものなのかはそこをみればわかる（ような気配がする)

```
$ less /var/lib/aws/opsworks/chef/yyyy-MM-dd-hh-mm-ss-..log
[2019-01-15T19:55:07+09:00] INFO: AWS OpsWorks instance xxx-xxx-xxx-xxx, Agent version 4033-20181126114950, Command: setup with id xxx-xxx-xxx-xxx
...
...
```

# OpsWorks Agent のログ

OpsWorks Agent が実行した chef コマンドのログなどはこちら

```
/var/log/aws/opsworks/opsworks-agent.process_command.log
```

このログを chef-client で grep すると、chef-client を手動実行するためのコマンドが取れるので、うまく attribs.json などを見つければ、それで何度も試行錯誤できるようになる。例えばこんなの。

```
env HOME=/root sudo /opt/aws/opsworks/current/bin/chef_command_wrapper.sh -s /opt/chef/bin/chef-client -j /var/chef/runs/xxx-xxx-xxx-xxx/attribs.json -c /var/chef/runs/xxx-xxx-xxx-xxx/client.rb -L /var/chef/runs/xxx-xxx-xxx-xxx/chef.log
```

これに `-o` オプションで runlist を追加すれば実行できる。

cookbooks は標準では以下のパスにあるので、一時的に弄りたい時はそこをいじる。

```
/var/chef/cookbooks/
```

attributes は -j オプションで指定されている attribs.json に書いてあるので、一時的に弄りたい時はそこをいじる。

# 参考

以下のページがとても参考になりました。Thanks.

* [Opsworks Tips - Qiita](https://qiita.com/okuda_h/items/65c653e39d02a0a66bd6)
* [AWS OpsWorks(™)のCustom Cookbooksレシピ開発役立ちメモ - Qiita](https://qiita.com/sawanoboly/items/147f550878477ff7723e)
外部のjupyter notebookを家からリモートする

# やりたいこと
研究室のパソコンで起動しているjupyter notebookを家から操作したかったのだ．

# 環境
ホスト（jupyterを起動しているPC）：Ubuntu16.04
リモートサーバ：Centos7
クライアント：Windows10

# やってみた

ひとまず，ローカル環境からjupyterへのリモート接続ができる状態にする．[（参照）](https://qiita.com/syo_cream/items/05553b41277523a131fd)

クライアントPCでWSLなりterminalを開いて，sshポート転送を行えばおわり．
私の場合だとこんな感じです．

`ssh -l ユーザ -i id_rsa グローバルIPアドレス -L 53389:ホストPCのIPアドレス:8888`

これでブラウザを起動して，`localhost:53389`を指定すれば，jupyterできた！！
vue + vue-cli3 + typescriptをie11対応する

* プロジェクトの作成
vue createで作成されたプロジェクトが対象。
TypeScriptも設定しておく。

```
vue create vue-ts-example
```

* es5で出力
es2017のライブラリとかを読み込んでおく

```tsconfig.json

    "compilerOptions": {

      "target": "es5",
      "lib": [ "es2017", "dom"],
      ...
```

* promiseとか使う場合は、polyfillsの設定が必要

```babel.config.js

module.exports = {
    presets: [
        ['@vue/app', {
            polyfills: [
                'es6.promise',
                'es6.symbol'
            ]
        }]
    ]
}

```

* babel-polyfillを出力する

``` vue.config.js
module.exports = {
    configureWebpack: (config) => {
      config.entry = ["babel-polyfill", "./src/main.ts"]
    },
    // node_modules以下にIE11非対応のライブラリがある場合、それもtranspileの対象とする
    transpileDependencies: ["vue-context"],
  }
  
```

* main.tsでbabel-polyfillをimportする

```main.ts
import 'babel-polyfill';
```
【初投稿】MySQL8.0のパスワード変更方法

#初投稿
今回が初投稿だが,わからないことや気になったこと･調べたことをメモしていく感じでQiitaを使っていこうと思う.


#MySQL
開発でパスワードの変更をしようと思ったが,うまくできなかった.
調べたら出てきたが,たどり着くのに時間がかった.

ネットで調べると,おそらくバージョンが古いMySQLのコマンドにたどり着いた.
8.0に関してはあまりたどり着かなかった.最初からバージョンをしていればよかった.


```sql:例
SET PASSWORD = PASSWORD('some password')
SET PASSWORD FOR user = PASSWORD('some password')
```


###パスワードの変更方法
パスワードを __null__にしたいとき

```sql:MySQL8.0

UPDATE mysql.user SET authentication_string=null WHERE User='root';
```
 


他にも使ったコマンドをメモ
###passswordの設定を見たいとき
```sql

mysql> SHOW VARIABLES LIKE 'validate_password%';
```

##まとめ
こんな感じでゆるくメモを投稿していく.  
  
参考リンク:
[Markdown記法一覧](https://qiita.com/oreo/items/82183bfbaac69971917f)
ドキュメント生成時に`No such file or directory @ rb_sysopen - doc/rdoc/created.rid`となった時の対処法

ググっても対処法が出てこなかったので記録。

`RDoc: 6.0.4`


```console
Errno::ENOENT: No such file or directory @ rb_sysopen - doc/rdoc/created.rid
```
と出て、ドキュメント生成ができなくなった。


プロジェクト直下の`doc`以下のファイルを下記コマンドで全削除したら表題のエラーは解消され、ドキュメント生成ができるようになった。


```console
rm -rf ./doc
```
Google Home から Dynalist に追加

Google Home や Google Assistant を使えば、音声だけでアラームをセットしたり、スケジュールを作成できたりと便利ですが、現在は残念ながら TODO リストには対応していません。そこで Web API を提供している [Dynalist](dynalist.io) に、 Google Home （Google Assistant）から IFTTT 経由でアイテムを追加できるようにしましょう。

# Dynalist の設定

**新しいアイテムを追加するアイテム（Inbox）を設定する**

新しいアイテムを追加するためのアイテムを選び、メニューから "Set as inbox" を選びます。詳しくは [Capture stuff to your inbox](https://blog.dynalist.io/inbox-capture/) を参照してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/19529/e53f2b23-e3c4-4155-6c5f-f735806cf497.png)


**Dynalist の API Secret を作成する**

API Secret は [Dynalist Developer page](https://dynalist.io/developer) から取得できます。

# IFTTT レシピ

**if "Google Assistant"**

`Say a phrase with a text ingredient` を使用し、以下のパラメータを設定します。

- Phrase: `to do リストに $ と追加`
    - 他にも `to do リストに追加 $` などのフレーズを登録しておくと便利です。
- Language: `Japanese`



**then "Webhooks"**

以下のパラメータを設定します。詳細は [API リファレンス](https://apidocs.dynalist.io/#send-to-inbox) を参考のこと。

- URL: `https://dynalist.io/api/v1/inbox/add`
- Method: `POST`
- Content Type: `application/json`
- Body: `{"token": "YOUR SECRET TOKEN", "index": 0, "content": "{{TextField}}"}`
    -  `index` を `0` に設定するとリストの先頭に、`-1` に設定するとリストの最後に追加される

![image.png](https://qiita-image-store.s3.amazonaws.com/0/19529/52c29a4a-b24d-c756-0d19-6bb41d82fa49.png) ![image.png](https://qiita-image-store.s3.amazonaws.com/0/19529/cb7a4291-ac92-529b-8d1c-7eb5b8fd311e.png)
CSS値の「initial」「inherit」「unset」「revert」の違い

一言で言うとプロパティの初期化になるのですが、
それぞれが異なる動きをします。
自分のまとめも兼ねて投稿します。

#これは何？
CSSの値のキーワード
プロパティに対して、初期値・継承値をセットします。
この為、プロパティをリセットしたい時に使用できます。

##使いたい場面
- ABテスト等で特定のstyleを消したい時。
- CSSフレームワークを使用する際に、特定のstyleを消したい時。
- 急ぎ（障害対応等）でstyleを設定したい、かつ複数のセレクタが入り混じって何だか分からない時に、一旦styleを消してしまいたい時。

基本的には「初期値・継承値をセット」なのですが、それぞれ異なる働きをするので、注意が必要です。

#各プロパティ
##initial
そのstyleのプロパティの初期値又は規定値を設定する。初期値に戻したい時に使用できる。
ここでの初期値は、ブラウザーのスタイルシートで指定された値ではありません。
使用する場面としては、場面としてはABテストやhot-fix等でしょうか。
IE11は未対応。
https://caniuse.com/#feat=css-initial-value

##inherit
プロパティの計算値を、明示的に継承することを指定することができます。
私個人としては、あまり使った事がないです。
何か便利な使い方がありそうですが。。

##unset
プロパティをリセットし、親からの継承された場合は継承値、それ以外は初期値を設定します。MDNの例が分かりやすいと思います。
使いどころとしては、何かの子要素にstyleが設定されていた時に、親要素のstyleを継承させたい場合に使うかと思います。
場面としてはABテストやhot-fix等でしょうか。
IE11は未対応。
https://caniuse.com/#feat=css-unset-value

##revert
ユーザーエージェントのstyleをセットします。プロパティそのものの初期値ではありません。

# 参考
https://developer.mozilla.org/ja/docs/Web/CSS/inherit
https://developer.mozilla.org/ja/docs/Web/CSS/initial
https://developer.mozilla.org/ja/docs/Web/CSS/unset
https://developer.mozilla.org/ja/docs/Web/CSS/revert
v-modelを使わずに子コンポーネントへinputのvalueを渡す方法

## 基本的なv-model
```vue
  <input v-model="message">
  <div>{{`message is ${message}`}}</div>
```

## v-modelを使わずに入力された値を子コンポーネントに渡したい

`input` タグの入力値を `data()` に書き、子コンポーネントにバインドさせます。

```ParentComponents.vue
<template>
  <input @input="message = $event.target.value">
  <ChildComponents :message="message"/>
</template>

<script>
import ChildComponents from "~/components/ChildComponents";

export default {
  components: { ChildComponents },
  data() {
    return { message: "" };
  }
}
</script>
```

子コンポーネントでは親から受け取った`message`をpropsに書きます。

```ChildComponents.vue

<template>
  <div>{{ `message is ${ message }` }}</div>
</template>

<script>
export default {
  props: { message: String }
};
</script>
```

これで `message is [入力された値]`が表示されます。
フォームのバリデーションとかで使いそう。

## つまり
```vue
<input v-model="message">
````

これと下記は同じでした。

```vue
<input
  v-bind:value="message"
  v-on:input="message = $event.target.value">
```

参考：[コンポーネントで v-model を使う](https://jp.vuejs.org/v2/guide/components.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A7-v-model-%E3%82%92%E4%BD%BF%E3%81%86)

【補足】
今回の場合の`v-bind:value`と`v-on:input`は、`v-model`の **syntax sugar** / **糖衣構文** といいます。
教えてくれた @konojunya さんありがとうございます^^
AWS カスタマーアグリーメントの変更

AWSは米国企業であるため、たとえ東京リージョンにアカウントを作成したとしても、契約の準拠法はワシントン州法になります。

日本法への変更方法
-
* 契約変更に関する料金
費用は無料

* 契約変更に要する時間
マネジメントコンソールからいつでも変更可能。即適用されます。

* 注意事項
AWS アカウント単位での変更が必要です。

### AWS　Artifactを開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/319276/c541746b-5e5a-a773-d2e6-67e634589dd1.png)

### 規約を確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/319276/20ac6e01-9008-4231-7102-b595161f321e.png)

### アクティブになればOKです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/319276/57885127-7a1d-9e86-25b8-4964fd89c293.png)


関連リンク
-
* AWS カスタマーアグリーメント
https://aws.amazon.com/jp/agreement/

* 日本準拠法に関する AWS カスタマーアグリーメントの変更: AWS Artifact
https://aws.amazon.com/jp/blogs/news/how-to-change-aws-ca-by-artifact/
[WIP] Express で Shift_JIS な文字列を UNICODE にする

そのうち完全に理解したら書き足します。たぶん。

## やりたいこと

- Node.js v8 ~
- Express
- POST でリクエストボディに Shift_JIS な文字列が詰まってる
- 文字列を JavaScript で処理したいので UNICODE にしたい

## やりかた

```app.js
const express = require('express')
const bodyParser = require('body-parser')
const encoding = require('encoding-japanese')

const PORT = process.env.PORT || 3000

const app = express()

app.use(bodyParser.urlencoded({ extended: true }))

app.post('/', (req, res) => {
  const decoded = encoding.urlDecode(req.body.message)
  const buffer = Buffer.from(decoded)
  const str = encoding.convert(buffer, {
    to: 'UNICODE',
    from: 'SJIS',
    type: 'string'
  })
})

app.listen(PORT, () => {
  console.log(`Listening on port ${PORT}`)
})
```

です。

## 参考

- [JavaScript における文字コードと「文字数」の数え方 | blog.jxck.io](https://blog.jxck.io/entries/2017-03-02/unicode-in-javascript.html)
CognitoIDプールを使ってゲストユーザ（未認証ユーザ）に一時クレデンシャルを発行する

# CognitoIDプールを使ってゲストユーザ（未認証ユーザ）に一時クレデンシャルを発行する

## 前提

* 認証とかどうでもいいんだけど、ユーザにとりあえず一時的にクレデンシャルを発行したい時用とする。
* クライアントはjavascript（aws-sdk）とする。

## 準備

### CognitoIDプールを作成する

1. Cognitoの"フェデレーティッドアイデンティティ"のページを開く
2. "新しい ID プールの作成"ボタンを押す
3. ↓にチェックいれて（それ以外は適当でOK（認証しないので））、"プールの作成"
![image.png](https://qiita-image-store.s3.amazonaws.com/0/299475/6312bea7-e0f5-ec0a-db7a-8427689356f0.png)

4. Cognitoが認証した時と認証しなかった時に返すロールの設定画面に行く。特に変更なしで"許可"する。
※ここで設定するロールのクレデンシャルが返却される
5. これでCognitoIDプールが作成される。

### aws-sdk準備

1. [CDNのページ](https://cdnjs.com/libraries/aws-sdk) から最新版のリンク取得する
2. 下記の内容のHTMLを用意

```html:hoge.html
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aws-sdk/2.388.0/aws-sdk.js"></script>
</html>
```

## 実際にクレデンシャルを発行してみる

### chromeのコンソールを使ってCognitoする

1. 作成したHTMLを開く。
2. 開発者コンソールを開いて下記を入力  
※この時、Networkを開いておくとCognitoにリクエストを飛ばしているのが分かる

```javascript:consoleに直接入力する
AWS.config.region = 'ap-northeast-1'; //重要

a = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'ap-northeast-XXXXXXXXXXXXXXXXXXXXXXX' //※
});
// ※Cognitoの"フェデレーティッドアイデンティティ"のページ
// > サイドメニューの「ダッシュボード」
// > 右上の方にある「IDプールの編集」
// > "ID プールの ID" に表示されているIDを設定する。（ARNではない）

a.get(); 
// ↑、エラーハンドリングする場合、
// 参考ページ（APIGatewayのIAM認証付きのAPIをJavascriptから叩く）に記載されているjs参照

dir(a); //中身確認用
```

※ちなみにリクエストの内訳は、

```
※リクエスト先は全て、https://cognito-identity.ap-northeast-1.amazonaws.com/

1発目：よくわからん。リクエストにOPTIONSを使っている
2発目：identityPoolIdをパラメータにして、identityIdを取得する
3発目：identityIdをパラメータにして、クレデンシャル情報を取得する
```

という感じ

### 結果確認

aの中身を見るとクレデンシャルが取得できていることが分かる。
※下記に値が入っている（下記の情報以外にも色々入ってる）

```javascript
a.accessKeyId
a.sessionToken
a.secretAccessKey
```

この後、Cognitoの"フェデレーティッドアイデンティティ"のページを開き、作成したCognitoIDプールのページを開くと、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/299475/14ca7320-b9c1-5731-509d-a5fb495ec3e6.png)
認証されていないアクセスがカウントアップされていることが確認できる。
※IDブラウザを開くと、アイデンティティIDが分かる

## 備考

### 一時クレデンシャルを使ったリクエストの注意

[一時クレデンシャルを使ったリクエストの注意](https://qiita.com/k_hoso/private/2a975a73a77e80746867)


## 参考
* [APIGatewayのIAM認証付きのAPIをJavascriptから叩く](https://qiita.com/Fujimon_fn/items/5197e2e3db6de9a68401)
の **"Cognito UnauthUserのCredentialでAPIを叩くJavascriptのコードを書く（完成）"** のところのjavascript
* [AWS.CognitoIdentityCredentialsのaws-sdk公式](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityCredentials.html)

## 関連
* [CognitoIDプールを使った独自認証、認証後STSを使った一時クレデンシャルの返却まで](https://qiita.com/k_hoso/items/4eca4103fb04e0ca07d4)
git push heroku masterでのエラー!!(Ruby on Railsチュートリアル)

#git push heroku masterでのエラー(Ruby on Railsチュートリアル)

##はじめに
Ruby on Railsチュートリアル実施時に詰まった場所です。

```ruby:terminal
$ git push heroku master
```
Herokuにpushする。

```ruby:terminal

remote:        In Gemfile:
remote:          sqlite3
remote: 
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !     Detected sqlite3 gem which is not supported on Heroku:
remote:  !     https://devcenter.heroku.com/articles/sqlite3
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !       Push rejected to gentle-escarpment-12983.
remote: 
To https://git.heroku.com/gentle-escarpment-12983.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/gentle-escarpment-12983.git'
```

エラーをはきます。(ログからsqlite3のgemがうまくいってなさそう・・・)

##解決方法
以下にsqlite3を追加。

```ruby:Gemfile
group :development, :test do
  # Use sqlite3 as the database for Active Record
  gem 'sqlite3'
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end
```

以下にpgを追加。

```ruby:Gemfile
group :production do
  gem 'pg', '0.20.0'
end
```

これで再度、以下を実施でHerokuへのpushは完了。

```ruby:terminal
$ bundle install --without production

$ git push heroku master
```

##参考
https://qiita.com/MosamosaPoodle/items/7149aa66f1c087472777
AngularJS currency filter で金額がマイナスの場合の既定の書式を変更する

タイトル通り、`currency filter` の既定の書式を変更する方法について記載します。
フィルターを自作する方法も考えられますが、紹介する方法が一番手間が少ない対応方法になるため、
個別にフォーマットしたい箇所がある場合でも、自作フィルターと併用するとよいと思います。

以下の issue にやり方が記載してあります。動作が確認できたため、まとめておきます。
https://github.com/angular/angular.js/issues/12870#issuecomment-180785981

# 実現方法

書式設定例：**\--99,999** 

```ts
angular.module(
  …
  )
  .run(["$locale", ($locale: ng.ILocaleService) => {
    let currencyPatterns = $locale.NUMBER_FORMATS.PATTERNS[1];
    currencyPatterns.negPre = "\u00a4-";
    currencyPatterns.negSuf = "";
  }])
```

書式設定例：**(\99,999)** 

```ts
angular.module(
  …
  )
  .run(["$locale", ($locale: ng.ILocaleService) => {
    let currencyPatterns = $locale.NUMBER_FORMATS.PATTERNS[1];
    currencyPatterns.negPre = "(\u00a4";
    currencyPatterns.negSuf = ")";
  }])
```

# 解説
マイナス表記用のプレフィックスとサフィックスが定義されていて、
フィルターではプレフィックスとサフィックスで囲んでいるだけなので、
簡単に上書きできるようになっている。

## マイナス表記用のプレフィックスとサフィックスの定義
* https://github.com/angular/angular.js/blob/b4f5377a2f7590cbda7b1bf7448ce8836565dee2/src/ngLocale/angular-locale_ja-jp.js#L114-L115

```js
$provide.value("$locale", {
"NUMBER_FORMATS": {
    "PATTERNS": [
      {
        "negPre": "-",
        "negSuf": "",
      },
}
```

## マイナス表記の書式を決定している箇所
https://github.com/angular/angular.js/blob/b4f5377a2f7590cbda7b1bf7448ce8836565dee2/src/ng/filter/filters.js#L348-L350

```js
if (number < 0 && !isZero) {
  return pattern.negPre + formattedText + pattern.negSuf;
}
```
ld: library not found for -lssl で mysql2が Mac OS Mojave でインストールできなかった時のメモ

新しくMacbookを購入してmysql 0.4.10 をインストールする際にエラーが出たので解決方法をメモとして残します。

#### エラー

```
ld: library not found for -lssl
linker command failed with exit code 1 (use -v to see invocation)
```


#### 解決法
XCodeをインストール後、下記コマンドを走らせると治りました。

```
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/opt/openssl/lib/
```
pip3 installしたらCould not find a version that satisfies the requirementとなったときの対応方法

# 事象 : PyYAMLをインストールしようとしたら怒られた
```bash
$ pip3 install pyyml
Collecting pyyml
  Could not find a version that satisfies the requirement pyyml (from versions: )
No matching distribution found for pyyml
```

## 原因 : ライブラリ名は`pyyml` ではなくて `PyYAML` だから
すごく残念な原因でした。

## 対応方法 : ライブラリ名を正しく書く
```bash
$ pip3 install PyYAML
Collecting PyYAML
  Downloading https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz (270kB)
    100% |████████████████████████████████| 276kB 1.1MB/s 
Installing collected packages: PyYAML
  Running setup.py install for PyYAML ... done
Successfully installed PyYAML-3.13
```
Slay the Spire Mod開発入門(2) 開発環境構築編

# はじめに

本章では自分自身でModのjarを作成する方法について、あらかじめ作成したサンプルを使って説明していきます。

# Modのjarが満たすべき要件

Modのjarは以下のファイル群を含んでいる必要があります

* Modの名前やバージョンや作者情報を表す ```ModTheSpire.json``` ファイル
* ```@SpireInitializerMod``` アノテーションで修飾されたModのエントリポイントクラスファイル
* カードやレリック等を表すクラスファイル
* 画像や音声, 言語ファイルを表す resourceファイル群

具体的には以下のような構成となります。

```
ModTheSpire.json
com/qiita/ykojim/Main.class
com/qiita/ykojim/MyCard1.class
com/qiita/ykojim/MyCard2.class
assets/img/card1.png
assets/img/card2.png
assets/loc/CardStrings.json
```

# ビルド環境の作成とビルドの実行

前述の要件さえ満たせればjarはどのように作成しても構わないのですが、ここではJDKとmvnwを使用することとします。

* JDKをインストール
* Githubの https://github.com/kojim/StSModStudy リポジトリをclone
* SteamのSlay the Spireディレクトリ(デフォルトは```C:\Program Files (x86)\Steam\steamapps\common\SlayTheSpire```)から ```desktop-1.0.jar``` をclone先のlibディレクトリにコピー
* ```mod001``` ディレクトリにて ```mvnw.cmd package``` を実行

これにより clone先ディレクトリのtargetサブディレクトリに```StsModStudy.jar```が作成されます。
SweRV ISS by Western Digital (2)

久々にISSのgit cloneと実行をさせたら動きませんでした。
[記事(1)](https://qiita.com/TSV/items/82a38bdf5335fa06a09e)で記載した頃からISSの仕様が変わっているようです。

https://github.com/westerndigitalcorporation/swerv-ISS.git

#新しい実行方法

$./whisper --newlib test3
hello world
Target program exited with code 0
Retired 1853 instructions in 0.00s  11954838 inst/s


ログ出力
$ ../whisper --newlib --log test3
\#1 0 0001008c 00004197 r 03         0001408c  auipc    x3, 0x4
\#2 0 00010090 fb418193 r 03         00014040  addi     x3, x3, -0x4c
\#3 0 00010094 81418513 r 0a         00013854  addi     x10, x3, -0x7ec
\#4 0 00010098 86c18613 r 0c         000138ac  addi     x12, x3, -0x794
\#5 0 0001009c 40a60633 r 0c         00000058  sub      x12, x12, x10
\#6 0 000100a0 00000593 r 0b         00000000  addi     x11, x0, 0x0
\#7 0 000100a4 278000ef r 01         000100a8  jal      x1, 0x278
\#8 0 0001031c 00f00313 r 06         0000000f  addi     x6, x0, 0xf
\#9 0 00010320 00050713 r 0e         00013854  addi     x14, x10, 0x0
\#10 0 00010324 02c37e63 r 00         00000000  bgeu     x6, x12, 0x3c
\#11 0 00010328 00f77793 r 0f         00000004  andi     x15, x14, 0xf
\#12 0 0001032c 0a079063 r 00         00000000  bne      x15, x0, 0xa0
\#13 0 000103cc 00279693 r 0d         00000010  slli     x13, x15, 0x2
\#14 0 000103d0 00000297 r 05         000103d0  auipc    x5, 0x0
\#15 0 000103d4 005686b3 r 0d         000103e0  add      x13, x13, x5
(略)


インタラクティブモード
$./whisper --interactive test3
whisper> s
\#1 0 0001008c 00004197 r 03         0001408c  auipc    x3, 0x4
whisper> s
\#2 0 00010090 fb418193 r 03         00014040  addi     x3, x3, -0x4c
whisper> s
\#3 0 00010094 81418513 r 0a         00013854  addi     x10, x3, -0x7ec
whisper> s 10
\#4 0 00010098 86c18613 r 0c         000138ac  addi     x12, x3, -0x794
\#5 0 0001009c 40a60633 r 0c         00000058  sub      x12, x12, x10
\#6 0 000100a0 00000593 r 0b         00000000  addi     x11, x0, 0x0
\#7 0 000100a4 278000ef r 01         000100a8  jal      x1, 0x278
\#8 0 0001031c 00f00313 r 06         0000000f  addi     x6, x0, 0xf
\#9 0 00010320 00050713 r 0e         00013854  addi     x14, x10, 0x0
\#10 0 00010324 02c37e63 r 00         00000000  bgeu     x6, x12, 0x3c
\#11 0 00010328 00f77793 r 0f         00000004  andi     x15, x14, 0xf
\#12 0 0001032c 0a079063 r 00         00000000  bne      x15, x0, 0xa0
\#13 0 000103cc 00279693 r 0d         00000010  slli     x13, x15, 0x2
環境を汚さずに、いかにしてちょっとしたメモを取るか

## はじめに
ちょっとしたことをメモしておきたいことってありませんか？

例えば、仕事中に
「来週までに資料を仕上げてね」みたいなお願いをされた時とか、
「XXを終えた後△△をやる」みたいな自分の中のその日の計画を残しておくとか。


小さなことって、個人的にどこにどうメモすればいいのかすごく迷います。


## メモの手段

そもそもメモの手段ってどう言うのがあるのか、思いついた範囲でざっくり考えてみました。

### テキストエディタでメモを取る

ある程度体系だったことを記録したい時はまずテキストエディタでメモをとります。

あくまで肌感ですが、エンジニアの方であればテキストエディタを使うことが一番多いんじゃないかと感じます。
勉強会に行くと、 `vim` や `atom` でメモを取られてる方が多い印象です。



### Mac標準のメモアプリ

ファイルで管理するほどでもない内容をメモしたい場合によくメモアプリになぐり書きします。

自身のショルダーハックの経験的には、Dockのメモアプリが起動状態になっていらっしゃる方はまちまちいらっしゃる印象で、同じ用途で使われてらっしゃる方は多いかもしれないです。

### 付箋を使う
自分のデスクに付箋を貼る方もいらっしゃると思います。



## メモの悩み
上の手段は、どれも自分にとってイマイチでした。



ちょっとしたメモを取るとき、テキストエディタでファイルにを作るのが大袈裟な時があります。あとファイルが増えてきて管理しきれず、埋もれてしまったり。


メモアプリの方ですが、たった数行のメモを取る場合でも、新規にメモが作成されてしまいます。小さいことをいちいちメモアプリに残そうとすると、すぐにどうでもいいメモまみれになってしまいます。。

付箋に至っては紙を消費してしまいます。

と、こんな感じで、「ちょっとしたことをメモする時」のベストプラクティスを考えていました。


## ターミナルにメモ残そう

そこで、ファイルを作らず、ターミナルでメモを管理できればと思い、CLIを作りました。

メモを残します。

```terminal
$ imemo s "xxの対応はxxチームの仕様fix待ち"
----------------------------------------------------------------------------------
| 1| xxの対応はxxチームの仕様fix待ち                                              　　　　　　　|
----------------------------------------------------------------------------------
memo saved!

$imemo s "「今週中に発表資料を一旦提出する」"
----------------------------------------------------------------------------------
| 2| 「今週中に発表資料を一旦提出する」                                           　　　　　　　　　　　　　|
----------------------------------------------------------------------------------
memo saved!
```

メモを開きます。

```terminal
imemo a
----------------------------------------------------------------------------------
| 1| xxの対応はxxチームの仕様fix待ち                                              　　　　　　　|
| 2| 「今週中に発表資料を一旦提出する」                                               　　　　　　|
----------------------------------------------------------------------------------
```

メモを消します。

```terminal
$imemo d 1
----------------------------------------------------------------------------------
| 1| xxの対応はxxチームの仕様fix待ち                                                  |
----------------------------------------------------------------------------------
memo deleted!
```

メモを編集します。

```terminal
$ imemo e 1
>> 発表資料は急遽明後日までに作ることになった
----------------------------------------------------------------------------------
| 1| 発表資料は急遽明後日までに作ることになった                                           |
----------------------------------------------------------------------------------
memo edited!
```

とりあえず、「余計なファイルを作らずにちょっとしたメモを取る」は達成できました。。



インストールはこちらです。

```terminal
brew tap kcwebapply/imemo
brew install imemo
```

ソースはここです。
https://github.com/kcwebapply/imemo



## 終わりに

こんなの入れなくても、`vim`の拡張とか他の方法でもっといいものはいくらでもあります。

もし自分と同じような悩みをお持ちの方がいらっしゃれば、是非一度お試しくださいmm
RailsでFormObjectをつかったお問い合わせメール

#はじめに
FormObjectなるものがあるらしく使ってみたくなったのでFormObjectをつかってお問い合わせメール機能を作成してみた。

#FormObjectとは
activemodelの機能を使って実際にモデルとして存在するもの以外にもバリデーションをつかうことらしい

#作っていく

```
rails new contact_form
rails g controller contacts new
rails g mailer inquiry
```

として

routes.rbに

```ruby 
resource :contact
```

を追加

app以下にformsフォルダを作成してそこにcontact_form.rbを作成


中身を

```ruby 
class ContactForm 
    include ActiveModel::Model 

    attr_accessor :email,:title,:body 

    validates :email, presence: true 
    validates :title, presence: true 
    validates :body, presence: true 

    def save
        return false if invalid?
        InquiryMailer.send_mail(email,title,body).deliver_now
    end 
end 
```

こうする。

activemodelをincludeしていることでvalidatesが使えたりする

saveはContactForm.saveの時に実行されて、もじemail,title,bodyがなかったらreturn falseされる感じになってる。

```ruby 
ContactForm.new(......)
```

みたいにするのでattr_accessorで使う値を指定してあげないといけない


次にmailerを作っていく


```ruby 
class InquiryMailer < ApplicationMailer

    def send_mail(email,title,body)
        @email = email 
        @title = title 
        @body = body 

        mail(subject: 'お問い合わせ', to: 'mysite@gmail.com', from: email)
    end 
end
```

あとはviews/inquiry_mailerの中にsend_mail.html.erb,send_mail.txt.erbを作成してあげればOK

controllerはこんな感じ

```ruby 
class ContactsController < ApplicationController

  def new
    @contact = ContactForm.new(email: params[:email],title: params[:title],body: params[:body])
  end

  def create 
    @contact = ContactForm.new(email: params[:email],title: params[:title],body: params[:body])
    if @contact.save 
    else 
      render :new 
    end 
  end

  private 

  def contact_params
  end 

end
```

なぜかストロングパラメータ使おうとしたらエラーでてめんどくさいからそのまま値をいれた。

最後にview

```erb 

<% if @contact.errors.any? %>
    <% @contact.errors.full_messages.each do |msg| %>
        <%= msg %>
    <% end %>
<% end %>

<%= form_with url: contact_path, local: true do |f| %>
    <%= f.label :email %>
    <%= f.text_field :email %>
    <%= f.label :title %>
    <%= f.text_field :title %>
    <%= f.label :body %>
    <%= f.text_field :body %>
    <%= f.submit %>
<% end %>
```

activemodelの機能が使えるのでエラーも表示できる。

これがform_objectの強みなんだと思う。

おわり。
flexboxの"order"がややこしかったので図解してみた

## やったこと
- flexboxについて調べ学習した
- orderプロパティについて分かりづらかったのでこれだけ図解でまとめた

参考：[order使用例](http://guide.withabout.net/guide/gp332/459917/flexbox.html#f5)

## orderプロパティとは
-  個別のアイテムの順序を指定出来る
- アイテムはデフォルトでは0の値を取り、正や負の整数値を設定する👈重要❗

### 前提
1~10の要素についてCSSのみで並べ替えを行う
#### 基本html
```html
<div class="samplebox" id="flex1">
		<p class="p1">ボックス<strong>①</strong></p>
		<p class="p2">ボックス<strong>②</strong></p>
		<p class="p3">ボックス<strong>③</strong></p>
		<p class="p4">ボックス<strong>④</strong></p>
		<p class="p5">ボックス<strong>⑤</strong></p>
		<p class="p6">ボックス<strong>⑥</strong></p>
		<p class="p7">ボックス<strong>⑦</strong></p>
		<p class="p8">ボックス<strong>⑧</strong></p>
		<p class="p9">ボックス<strong>⑨</strong></p>
		<p class="p0">ボックス<strong>⑩</strong></p>
	</div>
```

#### 例１
![スクリーンショット 2018-07-29 23.12.24.png](https://256interns.storage.googleapis.com/images/images/000/000/568/normal/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2018-07-29_23.12.24.png?1532873578)

```css

例１　　”row”で並べ、orderは特に何も指定しない
#flex1 {
    display: flex;
    flex-direction: row;
}
```

#### 例２
![スクリーンショット 2018-07-29 23.13.12.png](https://256interns.storage.googleapis.com/images/images/000/000/569/normal/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2018-07-29_23.13.12.png?1532873778)

```css

例２　　単純な逆順であれば”row-reverse”を使う
#flex2 {
    display: flex;
    flex-direction: row-reverse;
}
```

#### 例３
![スクリーンショット 2018-07-29 23.46.52.png](https://256interns.storage.googleapis.com/images/images/000/000/573/normal/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2018-07-29_23.46.52.png?1532875661)

```css
例３　 ８番目の要素（p8）のみ−１とする
#flex3 .p8 {
    order: -1;
}
```
★並べられた要素はデフォルトが”０”で、ひとつの要素を−１とすると、それが一番先頭になる（ややこしい）

#### 例４

![スクリーンショット 2018-07-30 0.07.17.png](https://256interns.storage.googleapis.com/images/images/000/000/574/normal/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2018-07-30_0.07.17.png?1532877000)


```css

例４　２つの要素（p4,p6）を指定し、それぞれ１，２とする
#flex4 .p4 {
    order: 1;
}
#flex4 .p6 {
    order: 2;
}
```

★例によって０以上の整数にした要素は末尾に移動する。元の順序も残るからか、１、１の指定でも４→６の並びになる挙動を確認できた（追記：正しくは同順の場合HTML記述順になる）
[サンプルページ](http://guide.withabout.net/guide/gp332/459917/flexbox.html#f5)ではなぜか１０、１１指定だった(?_?)

#### 例５
![スクリーンショット 2018-07-30 0.19.55.png](https://256interns.storage.googleapis.com/images/images/000/000/575/normal/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2018-07-30_0.19.55.png?1532877620)

```css
例５　　　　　　１〜１０で任意の整数を当て並べ替える（寧ろ分かりやすい😃）
#flex5 .p5 {
    order: 1;　<=0でも可
}
#flex5 .p2 {
    order: 2;
}
〜〜　　中略　　〜〜
#flex5 .p1 {
    order: 9;
}
#flex5 .p6 {
    order: 10;
}
```

### 所感
いわゆる配列のインデックスとは考え方が違うので、ややこしかった。
なんとなく数字を入れればそれっぽく動くが、きちんと理解しないと後で困ると思った。
実際にorderで自由に並べ替えるメリット、使い所はどういう所なのかはピンと来なかった。

### 追記
使い所として、HTMLで読み込ませる順序とレスポンシブ対応に便利とのこと👉[なるほど❗](http://guide.withabout.net/guide/gp332/459917/flexlayout-a.html)
Webを支える技術（自習）

20181121
## やったこと
「Webを支える技術」を読む

### 出てきた用語を調べる🔎

- バルクアップデート　👉　変更箇所も変更無い箇所も全て送信する​
- パーシャルアップデート　👉　変更箇所のみ送信する
- バッチ 処理 ​ 　👉１リクエストに複数の処理をいれたり、まとめて処理すること
- 排他制御
   - 悲観的ロック😢　
　更新対象のデータを取得する際にロックをかけ、他のトランザクションから更新されないようにする
   - 楽観的ロック😁
　更新対象のデータがデータ取得時と同じ状態であることを確認してから更新する
心拍数データに１か月間日記を付けてみた

# はじめに
近年、様々な企業が生体データを取ろうとしているが、
実際に<b>どういった情報が生体データ（特に心拍数）に現れるのか</b> 疑問に思った。
そこで、mi bandを購入し、自分の心拍数データに日記を付けて検証してみることにした。

## 仮説
心拍数データは、運動量だけでなく、ストレスも取れるのではないか。
（書いたコードが動かない時とかストレスすごいし、心拍数上がってる気がする…）

## ゴール
・心拍数に現れやすい項目を検証する。
・安定した生活を送るための改善点を見つける。

# 検証方法
※対象期間：2018/11/22～2018/12/21

1.mi bandのデータを用いて（SQLite形式）、以下の項目を毎日作成。

日付|曜日|時間帯|分|心拍数|睡眠開始|睡眠終了|深い眠り|浅い眠り|歩数|
|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|

2.毎晩、心拍数が90以上の時に何があったかをコメント列に記載。
※参考）心拍数平均：71（起床時平均：77、睡眠時平均：57）

日付|曜日|時間帯|分|心拍数|睡眠開始|睡眠終了|深い眠り|浅い眠り|歩数|コメント|
|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|:-----|
12/3|6|20|10_19|76|12/3 11:58|12/3 7:36|227|199|7759|	
12/3|6|20|20_29|102|12/3 11:58|12/3 7:36|227|199|7759|集計がうまくいった|

3.1ヶ月分の結果を集計。
（普段日記は付けないので、集計するときに改めて振り返ると面白かった）

# 集計結果
## 心拍数に現れる項目検証
### 心拍数降順
期間内で心拍数が高かったものは、以下が主だった。
・運動
・楽しいとき
・慌てた時
→結果、<b>動いた時</b> なのでは…

```python:code
# df：全期間マージしたデータ
df[['comment','hr']].sort_values('hr',ascending=False)[:10]
```

```python:結果
comment	hr
フィットネス	141
フィットネス	140
フィットネス	136
フィットネス	135
飲み会中	134
フィットネス	133
MTG開始前急ぐ	130
帰宅時	128
居酒屋移動で急ぐ	122
アポでミス	118
```

##### 余談
・ある1日のコードが動かない時の心拍数は69,コードが動いた時は102であった。
　イライラ/焦りは心拍数に出ていなそう…。

## 生活改善用検証
ここからは結果のみ
### 日付別平均心拍数
10-18時における、1日の平均心拍数を集計。（平日は移動がなく、休日は起きているであろう時間帯）
・旅行
・ディズニー
・出張
が上位3日であった。
→<b>環境が普段と違う</b> と、刺激が多く、心拍数が高くなる？

### 曜日別平均心拍数
集計対象の時間帯を変更（終日、業務時間内、起床時間全て）すると、心拍数の高い曜日が変動したため、信ぴょう性はなし。
ただし、<b>水曜日だけは全てにおいて最低</b> であった。
→水曜日は週の半ばだから気が緩む？もしくは、実は予定が入りづらいなどもあるのかも？

### 時間帯別平均（平日）
仕事がある平日で検証。
<b>移動時間＞ご飯時間＞会社/家にいる時</b> の順番で綺麗に並んでいた。
→電車にも乗っていることを考えると、移動時間に関しては、ストレスも影響している可能性あり？

### 睡眠時間,深い眠り別平均
睡眠時間が長い順に３分割すると、長いほど10-18時の心拍数は低い。
深い眠りも同様の傾向が見られた。
しかし、データを細かく見ると例外も多く見られたため、言い切れず。

# 結論
心拍数では、<b>基本運動の結果が出てしまう</b> ため、上昇した理由の読み解きは困難だった。。
やはり、運動量を取れるのが強みになりそう。
（後から考えると当たり前すぎる…）

日々の心拍数を下げるには、移動を減らし、日常の環境に居続けること。（＋水曜？）
<b>在宅勤務は平穏な生活を送るために有効では？</b>

# 最後に
あくまで個人の結果です。
特に新しい結果は出ませんでした。。
ストレス計測に、体温データも簡単に取れるなら触ってみたいな。
twitter始めました。[@monokeshi6](https://twitter.com/monokeshi6)
Webを支える技術(リソース指向アーキテクチャ設計ほか)

20181118
## やったこと
Webを支える技術を読む
- HTTPステータスコード
- HTTPヘッダ
- データ形式
- リソース指向アーキテクチャ設計（読み取りアプリ）


## リソース指向アーキテクチャ設計手順

①提供するデータの特定

②データをリソースに分ける

③リソースにURIをつける

④クライアントに提供するリソース表現を選択（HTML,　JSON,　CSV，YML，PNGなど）

⑤リンクとフォームを利用してリソース同士を結びつける

⑥イベントの標準的なコースを検討する

⑦エラーについて検討



## RESTfulなWebサービスの性質 

- アドレス可能性
- 接続性（リソースにリンクでアクセス）
- ステートレス性
- 統一インタフェース
   これら4つの性質を備えたものがリソース指向アーキテクチャ 

## まとめ

リソース指向設計では、
ER図におけるエンティティと属性の関係やクラス図における各クラスと属性の関係は無く、単純に個々のリソースがあり、それの結びつき（リンク）を考える。

結びつきは実際のイベント（操作順）のシナリオから設計されるものと理解した。