OmniAICreator/Qiita-1.07M huggingface dataset:
【OpenRPA】初心者向け操作説明書～その２．レコーディング編～

OpenRPAの操作説明です。

# はじめに

今回は、レコーディング機能を使ってみます。
レコーディング機能とは、操作を記録して自動的にワークフローを作る機能です。

なおレコーディング機能だけで完璧なワークフローを作るのは厳しいです。
ほとんどの場合、あとで手動でプロパティ設定が必要になります。

「アクティビティ自分でイチから配置するのはめんどくさいから、レコーディングである程度作って細かいところは手動で設定しよう！」くらいの感じで考えると良いです。
（Excelでマクロ作るときに、「マクロの記録」で大まかな流れを作るのに似てるかも。）

今回はレコーディング機能の使い方ということで、特にプロパティは編集しません。
それはまた次回に。

# 前準備

メニューの[設定]から、「記録中オーバーレイ」をONにしておきましょう。
OFFでもいいんですが、ONにしておくとレコーディング中にカーソルの当たっているところの色が変わるので、わかりやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/388c000a-35cf-090b-9dbf-0d9dc015e707.png)

# 例題

電卓を叩くだけ、という簡単なワークフローを作ってみます。

## １．電卓を起動

まず、最初に電卓を起動しておきましょう。

## ２．アプリケーションを開くアクティビティを追加する

新しいワークフローを作成すると、１つのSequenceがあると思います。
その中に「アプリケーションを開く」アクティビティを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/52248e99-b81e-6f4a-3d3b-d979263a6034.png)

## ３．起動するアプリケーションの選択

次に、アプリケーションを開くアクティビティの箱から、「要素を選択」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/f94ba6f0-23e9-b3e2-1225-259fe74a5596.png)

すると、OpenRPAのウィンドウが非表示になります。
そのまま電卓のウィンドウをクリックしましょう。

電卓のウィンドウをクリックすると、このようにエラーの:exclamation:も消え、タイトルが「電卓」と変わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/9f1d573c-e9cf-e894-b18f-00d35c43b30b.png)

## ４．レコーディングの開始

「アプリケーションを開く」アクティビティを選択した状態で、メニューの[一般]から「記録」を押すと、レコーディングが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/ef1b9d90-0b08-d860-d362-14be33a41c4d.png)

## ５．レコーディング

電卓で、「5」「+」「8」「=」ボタンを順番に押しましょう。
※記録中はちょっと重たくなるかもしれません。ゆっくりやりましょう。

前準備で書きましたが、「記録中オーバーレイ」をONにすると、マウスカーソルが当たっているところの色が変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/c0893326-9dd1-ef0e-4b53-a112bec52159.png)

全ての操作が終わったら、キーボードの「ESC」キーを押すとレコーディングが終了します。
ワークフローを見ると、操作が記録されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/f6b4b31c-7836-4f31-f7c5-524070806145.png)

## ６．動作確認

では、記録用に起動した電卓を終了し、ワークフローを保存し、F5キーでワークフローを実行してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/49355c12-2afc-da8f-db76-2b2ec65be491.png)

自動的に電卓が起動して計算されましたね！
おや？電卓が起動したままですね。最後に電卓を終了するようにしてみます。

## ７．アプリケーションのクローズアクティビティを追加する

ワークフローの一番最後に、「アプリケーションのクローズ」アクティビティを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/8344cb69-461d-dd0b-a16d-072da60c4bca.png)

あとは、「アプリケーションを開く」アクティビティと同じように、「要素を選択」を押して電卓ウィンドウをクリックします。
これで最後に電卓が終了するようになりました！

# おわりに

今回はここまでです。
次回は、レコーディングしたものを編集してみようかと思います。
AWS IoT検証メモ⑦ : AWSIoTを使ってみて便利だって点と気を付けるべきこと

#  AWS IoT Coreを使ってみて便利だった点と気を付けるべきこと
 AWS IoT Coreを使ってみて便利だなと思った機能や運用するときに気を付けないとなって思ったことを記載していきます。

- 証明書の管理
- デバイスのマスタ情報管理
- Topicに対する接続制限数
- IoTShadowを使ったデバイス上で実行しているプログラムの変数切り替え

## 証明書の管理
デバイスに割り振る証明書はデバイスの出荷時等に事前に組み込んで出荷を行いたいが、デバイスの数が多ければ一台一台に証明書の発行を手動で行うのは中々面倒です。  
FleetProvisioningを利用することで、SDKでの認証処理を行うコードとAWSのルート証明書等の最低限の認証情報等をプライベートgit等を利用して配信することでデバイスの証明書自体はデバイスと AWS IoT Core間で自動で生成して配信させることができます。  
デバイス証明書の情報がデバイスと AWS IoT Core間でのみ保持されるので証明書を手動で管理して外部に漏洩する等といったリスクも減らすことができると考えます。  




## デバイスのマスタ情報管理
デバイスの管理を行う上で、管理者が管理するデバイスの一覧情報とプログラム側で使うデバイスの情報がバラバラになると情報の更新などを行った際に2か所に変更を加えるのは手間なので一元管理できそうな方法を考えてみました。

deviceIDの設定をユニークな値(デバイスのHostNameやNIC等)に設定することで、そのdeviceIDと紐づいた補足情報をDynamoDBなどに保存し、IoTRule内で送られてきたデータに対するデバイスの管理情報(設置位置や連絡先等)の情報を紐づけて次の処理に連携させることができます。
また逆にデバイス状態をdynamoDBに紐づけて保存することで、デバイスの接続が切断された等の障害が起きた際にもDB内のデバイス状態を更新することができます。

こうすることでデバイスに関する情報が1ヶ所のDynamoDBに集約されて、稼働してるデバイスの情報などをDynamoDBから確認できるようになります。


## 大量のデバイスへの同時送信について
 AWS IoT CoreのTopic1つに対して接続できるデバイスの数には制限があります。
（デバイスへの1秒間のPublish制限は20000メッセージ）
同じデータを大量のデバイスに纏めて送信したい場合は、
パフォーマンス的にも1つのTopicから集中して大量のデータを送信させるより
複数トピックを設定して1Topic辺りの接続数を分散した方がいいようです。


## IoTShadowを使ったデバイス上で実行しているプログラムの変数切り替え

遠隔地に置くデバイスの場合、デバイス内のコードを直接書き換える作業は困難な場合があるため、変数の値を最初にIoTShadowに保存されている内容を取得し、その値をデバイス上の変数として利用することでIoTShadowを更新した際にデバイス内の処理を切り替えることができます。
メインプログラムの処理結果などに応じてデバイス側で実行されているプログラムを切り替える必要などがある場合には、デバイス側の処理はデータの送信など必要な処理のみを実装しておいて、メインプログラムで処理した結果から何かデバイス側でのアクションが必要な場合はIoTShadowの内容を更新し、デバイスはそのShadwの内容を基にまた処理を繰り返すといった実装がIoTShdowを利用することで実行できるようになります。


例）デバイス内で繰り返しているデータ取得の頻度などを AWS IoT CoreCore上から変更する場合

- デバイス側で30分に1回取得しているデータを、異常があった場合は1分に一回取得するように自動で変更する
- 変更後、異常が30分検知されなかった場合は再度取得頻度を30分に一回に変更する。
- デバイス内で繰り返しを行う制御等のsleepの値がIoTShadowに保存されている。(デフォルトは30分)

 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/05a3d536-2ca5-50bd-9345-cc43d34a0a03.png)

処理の流れ

1. ①~⑥の流れで、デバイスからIoTコアへ送られてきた値をLambda等のメインロジックに送る 
- デバイスからのデータをLambda上で処理し、センサーの値に異常が合った場合、⑦でIoTShadowの変数値を変更する(30分->1分)
- デバイスはIoTShadowからShadowの変更通知を②>①の経路で受け取り、変更された値に変数値を変更する。
- デバイス側の変数が書き換わる為、1分に一回センサーの値が①～⑥の経路で送信される
- lambda側で30分間再度異常が検知されなかった場合は、shadowの値を変更する(1分->30分)
- デバイスはIoTShadowからShadowの変更通知を②>①の経路で受け取り、変更された値に変数値を変更する。

IoTShadow等をうまく活用すれば、複数台のデバイスのロジックを一回の操作で変更できるため
デバイスの試験等を行う際に活用するととても便利かと思います。




---
[ AWS IoT CoreCore検証内容一覧へ](https://qiita.com/tomzono/private/eaa786b6a1889351c752)
自分用メモ: Box, Rc, Cell, Arcの使い分け

この内容のメモ: https://users.rust-lang.org/t/confused-between-box-rc-cell-arc/10946

## Q `Box`, `Rc`, `Cell`, `Arc`の違いってなに？

## A

Box<T>はシングルオーナーの場合。 (再帰的な構造を持つ型で利用する. 例: 木構造とか
Rc<T>は複数の所有者のためのものです。
Arc<T>は複数の所有権を持ちますが、スレッドセーフです。
Cell<T>はCopy型の「内部変異性」のためのものです；つまり、&Tの後ろで何かを変異させる必要がある場合です。
RustでYAMLをパースする

# はじめに

ローカルのYAMLファイルを読み込んでいい感じにパースしてくれるライブラリはないかなと思って探したら[yaml-rust](https://github.com/chyh1990/yaml-rust)があったので試してみました。

# やってみた

```shell
cargo new yaml-example
cd yaml-example
```

`Cargo.toml`の`dependencies`に`yaml-rust`を追記する

```Cargo.toml
[dependencies]
yaml-rust = "0.4"
```

適当なyamlファイルをつくる

```sample.yaml
foo:
  - list1 
  - list2
bar:
  - 1
  - 2.0
```

yaml-rustのReadmeを参考にパース処理を書いてみる

```src/main.rs
extern crate yaml_rust;
use yaml_rust::{YamlLoader, YamlEmitter};
use std::fs;

fn load_yaml(path: &str) -> Vec<yaml_rust::Yaml> {
    let f = fs::read_to_string(path);
    let s = f.unwrap().to_string();
    let docs = YamlLoader::load_from_str(&s).unwrap();
    docs
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let path = "./sample.yaml";
    let docs = load_yaml(&path);
    let doc = &docs[0];
    // Test
    assert_eq!(doc["foo"][0].as_str().unwrap(), "list1");
    assert_eq!(doc["bar"][0].as_i64().unwrap(), 1);
    assert_eq!(doc["bar"][1].as_f64().unwrap(), 2.0);
    assert!(doc["INVALID_KEY"][100].is_badvalue());
    // Dump the YAML object
    let mut out_str = String::new();
    {
        let mut emitter = YamlEmitter::new(&mut out_str);
        emitter.dump(doc).unwrap();
    }
    println!("{}", out_str);
    Ok(())
}
```

実行してみる

```shell
cargo build
cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/yaml_rust`
---
foo:
  - list1
  - list2
bar:
  - 1
  - 2.0
 ```

できた。

# おわりに

`Yaml::Loader`はマルチドキュメントファイルをサポートしているのでドキュメントが1つのYamlの場合でも `let doc = &docs[0];` のように配列で返ってきています。

パース後のデータは普通にHashMapになっているので便利。シンプルでよさげ。
djangoでtemplateを使用する。

```views.py
class HelloWorldView(TemplateView):
    template_name = 'hello.html'
```
template_nameでテンプレートの名前をしてする。テンプレートの場所は
settings.pyで指定する。


```settings.py
BASE_DIR = Path(__file__).resolve().parent.parent
```
settings.pyのファイルのパスの親フォルダのさらに親フォルダ。manage.pyが入っているディレクトリ。

```settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```
'DIRS': [BASE_DIR / 'templates']の部分でBASE_DIRのtemplatesフォルダを
指定している。

```views.py
from django.contrib import admin
from django.urls import path
from .views import helloworldfunction, HelloWorldView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('helloworld/', helloworldfunction),
    path('helloworld2/', HelloWorldView.as_view()),
]
```
クラスの場合はas_view()メソッドを書く。
Sprockets::Rails::Helper::AssetNotPrecompiled in *** が出たので解消法をメモ

■環境
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]
Rails 6.0.3.5

■状況
①viewからCSSを読み込むため、headタグに以下を追記
<%= stylesheet_link_tag 'index', media: 'all', 'data-turbolinks-track': 'reload' %>

②app/assets/stylesheets/ディレクトリにindex.cssファイルを手動で生成
③ビューファイルを開くと「Sprockets::Rails::Helper::AssetNotPrecompiled in ***」というエラーが出る。

■対処法
①config/initializers/assets.rbファイルに以下を追記
Rails.application.config.assets.precompile += %w( index.css )

②サーバを再起動(ctrl+C → rails s)

★2021/03/22ここまで
DjangoとReactで作成したアプリにDockerを組み込む


##Dockerとは
一言で言うと<strong>コンテナ型のアプリケーション実行環境</strong>のこと。
DockerがあればどのPCからでも、簡単にそのアプリを実装できる環境を構築することができる。

##今回やること
前回私が開発したアプリにDockerを組み込んで環境構築を容易にしていく。

そのアプリの開発記事↓
[DjangoとReactでPDCAアプリを作る その1](https://qiita.com/kenshow-blog/items/0c3d8fa91dd94b4e9fe0)


##作業の流れ

1.requirements.txtの作成

2.Django用Dockerfileの作成

3.nodejs用Dockerfileの作成

4.docker-composeの作成


##requirements.txtの作成

完成したアプリのディレクトリ下で以下のコマンドを実行するとそのアプリでインストールしたライブラリをrequirements.txtにまとめることができる

```
pip freeze > requirements.txt
```

なお、アプリ開発を行うにあたって``Virtualenv``を使って、専用の開発環境を準備した方が良い。
そうしてから取り組めば、そのアプリ開発でインストールしたライブラリだけをrequreiments.txtに落とし込むことができる。

virtualenvについての記事↓
[venv: Python 仮想環境管理](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)


##Django用Dockerfileの作成

```dockerfile
# pythonの基本的な環境をubuntuで構築している↓↓
FROM ubuntu:18.04
RUN apt-get -y update \
    && apt-get -y upgrade \
    && apt-get install -y locales curl python3-distutils \
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install -U pip \
    && mkdir /code \
    && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8
# ↑↑


# 作成したrequirementsをコンテナ側へcopy
COPY ./requirements.txt /requirements.txt

# コンテナ側でアプリに必要なライブラリをインストール
RUN pip install -r /requirements.txt

# アプリを置くためのディレクトリを作成
RUN mkdir /workapp

# 起動時に最初に開かれるディレクトリを設定
WORKDIR /workapp

# 作成したアプリをコンテナ側へcopy
COPY ./workapp /workapp
```

##nodejs用Dockerfileの作成

```dockerfile
FROM node:10.13-alpine
```

##docker-composeの作成

###docker-composeとは、
dockerでこのコンテナを立てる際に使うであろうdockerコマンドを1つのファイルにまとめてくれるツール

```yml
version: '3'

services:
  app:
    build:
      context: .
    tty: true
    stdin_open: true
    ports:
      - "8000:8000"
    # コンテナ側から実際の環境側にあるアプリを参照する
    volumes:
      - ./workapp:/workapp
    command: >
      sh -c "python3 manage.py migrate &&
             python3 manage.py runserver 0.0.0.0:8000"
    depends_on: 
      - react
  react:
    build:
      context: .
      dockerfile: "./Dockerfile-nodejs"
    volumes:
      - ./work_react:/work_react
    command: >
      sh -c "cd work_react && npm start"
    ports:
      - "3000:3000"
```

dockerを起動してアプリディレクトリ下で、以下のコマンドを実行する

```
docker-compose up
```

これで無事、djangoとReactで開発したアプリにDockerを組み込むことができた🎉


##今後の展望
今回は、DBをsqliteのままにしてDockerを組み込んだので、次回は、postgresSQLを用いて組み込めるようにしたい。
また、nginx等のwebサーバーも用いて、開発現場さながらのDockerコンテナを作成したいと考えている

ここまで読んでくださりありがとうございました🙇‍♂️🙇‍♂️


また、Twitterでも日々の積み上げや、プログラミング学習についてのツイートをしておりますので、よかったらフォローと応援の程よろしくお願いします！🙇‍♂️

Twitterアカウント↓
[健将@WEBエンジニア×明大生](https://twitter.com/kenshow_study)
PluginError [SyntaxError]: Unexpected token '.' in /project/filename.ejs while compiling ejs

フォーマットを関数コール形式にする修正が必要になった。

`<% include ./head.ejs %>` 
↓
`<%- include('./head.ejs') %>`


```shell
# search
<% include( )([\w|\.|\/]*) %>
# replace
<%- include('$2') %>

# file to include 
*.ejs
```


```
PluginError [SyntaxError]: Unexpected token '.' in /project/filename.ejs while compiling ejs

If the above error is not helpful, you may want to try EJS-Lint:
https://github.com/RyanZim/EJS-Lint
Or, if you meant to create an async function, pass `async: true` as an option.
    at new Function (<anonymous>)
    at Template.compile (/project/node_modules/gulp-ejs/node_modules/ejs/lib/ejs.js:662:12)
    at Object.compile (/project/node_modules/gulp-ejs/node_modules/ejs/lib/ejs.js:396:16)
    at handleCache (/project/node_modules/gulp-ejs/node_modules/ejs/lib/ejs.js:233:18)
    at Object.exports.render (/project/node_modules/gulp-ejs/node_modules/ejs/lib/ejs.js:423:10)
    at DestroyableTransform._transform (/project/node_modules/gulp-ejs/index.js:24:28)
    at DestroyableTransform.Transform._read (/project/node_modules/gulp-ejs/node_modules/readable-stream/lib/_stream_transform.js:177:10)
    at DestroyableTransform.Transform._write (/project/node_modules/gulp-ejs/node_modules/readable-stream/lib/_stream_transform.js:164:83)
    at doWrite (/project/node_modules/gulp-ejs/node_modules/readable-stream/lib/_stream_writable.js:409:139)
    at writeOrBuffer (/project/node_modules/gulp-ejs/node_modules/readable-stream/lib/_stream_writable.js:398:5) {
  __safety: undefined,
  _stack: undefined,
  plugin: 'gulp-ejs',
  showProperties: true,
  showStack: false,
  fileName: '/project/filename.ejs'
}
```
初学者のプログラミング　rescue_from

##rescue_from
*例外処理から救出するクラスメソッド。例外クラスを指定し、withオプションで例外発生時に実行するアクションを指定する。

##記述例
```ruby
class LoginFailed < StanderdError
end
```
```ruby
class ApplicationController < Application::Base
 rescue_from LoginFailed, with: :login_failed

 def login_failed
  render template: "shered/login_failed", status: 401
 end
end
```
こうすることでlogin_failedメソッドを定義し例外発生時のアクションを指定している。また、次のように各アクションの任意のタイミングで例外を発生させることで、同じ「login_failed」の処理へ以上することができる。
*status: 401*　ステータスコードを指定、401はログイン時などに、情報の入力違いなどを理由とした認証エラー。

```ruby
class LoginController < ApplicationController
 def create
  @user = User.where(name: params[:id], password: [params:password]).find
  raise LoginFailed unless @user
 end
end
```

##まとめ
複数のコントローラーに跨った例外的な処理、例えばログインの失敗や権限によるアクセス制限などを実装する際に使用する。

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
Expo SDK39をejectしてAsyncStorageの内容が消えた時の対象法

Expo sdk39のReact-native アプリをejectしたら、AsyncStorageの内容がクリアされる問題に遭遇しました。

#原因
Expo下で参照されるAsyncStorageのデータ保存場所と、Eject後のAsyncStorageの保存場所が異なることから発生する問題のようです:frowning2:

https://github.com/expo/expo/issues/2805



#解決方法　※2021年3月22時点
今回は@react-native-community/async-storageを使ってやってます。
iexplorer等のツールを利用して保存元のファイルがどこにあるのか
確認して保存元のファイル名を変更すると問題なく引き継がれます。

例：expoでの保存先が**RCTAsyncLocalStorage**の場合

```RNCAsyncStorage.m
static NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1"; 　//保存先
static NSString *const RCTOldStorageDirectory = @"RNCAsyncLocalStorage_V1";　//保存元
```

```RNCAsyncStorage.m
static NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1"; 　//保存先
static NSString *const RCTOldStorageDirectory = @"RCTAsyncLocalStorage";　//保存元
```

https://github.com/react-native-async-storage/async-storage/blob/master/ios/RNCAsyncStorage.m
Bundlerについて

# はじめに
初学者です。間違いあればご指摘いただきたいです。

### 参考
[Bundler概要]
(https://qiita.com/hisonl/items/162f70e612e8e96dba50)
[Bundlerの使い方]
(https://qiita.com/oshou/items/6283c2315dc7dd244aef)
[Bundlerとは？]
(https://qiita.com/io_fleming/items/14626a9cff44bc87e7db)

# Bundlerとは？
- プロジェクト内で使うRubygemsを管理する仕組みのこと。


- gemは手動で個別にインストールする事ができる。が、様々なgemを組み合わせて使っていくと**「バージョンの組み合わせ」によっては上手くいかない**などの問題が出てくることがある。
- 複数人、複数環境で開発を行う場合、各々の環境で使うライブラリの名前やバージョンを合わせる必要がある。

- 上記2点の問題を解決できるのがBundler。
手動でgemをインストールするよりも、gem同士の互換性を保ってくれるBundlerでインストールする方が便利。

# Bundlerのインストール
まず初めに、Bundlerもgemの１つです。
つまり、インストールの必要があるってことですね。

- Bundlerは手動インストールします。

```ruby:ターミナル
gem install bundler
```
- 導入されたか確認します。バージョンが表示されるかを確認してください。

```ruby:ターミナル
bundler -v
```

# Bundlerの使い方
- **Gemfileを作る**

```ruby:ターミナル
bundle init
```
上記のコマンドでGemfileの雛形が作成されます。

- **使いたいgemをGemfileに記述する**
　
  - インストールしたいGemパッケージを記述後、bundle installを実行することで、自動的に調べて全部インストールしてくれます！

# Bundlerのコマンド

- **bundle init** ・・・・Gemfileを生成する
- **bundle install**・・・Gemfileに書かれたGemパッケージをインストール
- **bundle exec**・・・・Bundlerでインストールされたgemパッケージを使用してコマンドの実行
- **bundle list**・・・・・インストール済みのgemパッケージの一覧を表示
- **bundle update**・・・インストール済みのgemパッケージのバージョンを更新

# Gemパッケージの保存先
bundle installと実行すると、
rbenvを利用していた場合、/Users/ユーザー名/.rbenv/versions/バージョン名/lib/ruby/gems/...に保存されます。

もしこの保存先を変更したい場合、

```ruby:ターミナル
bundle install --path <フォルダ名>
```
と打つと、指定したフォルダの下に保存することが可能です。

ちなみに２回目以降は、保存先を記憶してくれているので `% bundle install` と打つだけで大丈夫です。
Elasticsearch 6.xでupdate時に配列に値を追加する方法

ぐぐるとscriptで```+=``` を使う方法ばかりでてくるんですが、 Elasticsearch 6.x だと動かなかったので Elasticsearch 6.xで動く方法をメモしときます。

方法だけ先に書くと下記でいけました。

```
"script": "ctx._source.フィールド名.add(追加する値)"
```

# 例


サンプルマッピング

```
PUT sample
{
  "mappings":{
    "sample":{
      "properties":{
        "years":{
          "type": "integer"
        }
      }
    }
  }
}
```

データ登録

```
POST sample/sample/1
{
    "years" : [2000]
}
```

アップデートで2021を追加

```
POST sample/sample/1/_update
{
  "script" : "ctx._source.years.add(2021)"
}
```

結果確認

```
GET sample/sample/1
{
  "_index": "sample",
  "_type": "sample",
  "_id": "1",
  "_version": 2,
  "found": true,
  "_source": {
    "years": [
      2000,
      2021
    ]
  }
}
```
Xplenty-Consoleの使い方

今回の記事では、Xplenty X-Consoleの使い方について解説します。X-Consoleとは何か、どのように機能するのか、そしてデータパイプラインをデバッグするためにどのように活用することができるのかについて紹介します。


#X-Console
Xplentyのプラットフォームは、プログラミングの知識が1つもない人でも使うことができます。しかし、コーディングに精通しているユーザーは、特定のシチュエーションでプラットフォームの機能を最大化させることができます。それが、Xplenty X-Consoleです。X-Consoleは、データパイプラインの関数をテストするためのツールで、関数の返す結果を本番前にレビューすることができます。
 
#X-Consoleの使い方
##1. X-Consoleの起動方法
Xplentyのパッケージデザイン画面を開くと、ETLデータパイプラインのビジュアルが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/891bf303-8805-1c96-ccf3-9f5959ec724a.png)

XplentyダッシュボードからX-Consoleにアクセスするには、Selectコンポーネントからアクセスする方法と、スタンドアロンでアクセス方法があります。

スタンドアロンのX-コンソールにアクセスするには、画面の右下隅にあるパイプラインの視覚的表現を探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/640b3700-d8d0-9f6d-f8fe-c7f4f8270463.png)

Selectコンポーネント内からX-Consoleにアクセスするには、式エディタの「X-Console」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/823aac54-4412-580c-0459-518becb0a84b.png)


##2. CONCAT関数の動作検証
例えば、CONCAT関数の結果を確認するために以下のようなコマンドをX-Consoleで実行することができます。
`field1 ='hello' `
`field2 ='world' `
`CONCAT(field1, field2)`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/99fe6f75-e22a-d552-38d9-392d6b7a67d2.png)
結果は、「helloworld」という文字列が返ってくるのを確認することができます。

##3. JSON文字列の動作検証
以下のようなJSON文字列から姓と名、性別を取得する。
`[{
	"label": "FIRST NAME",
	"value": "Taro",
	"key": "first_name"
}, {
	"label": "LAST NAME",
	"value": "Yamada",
	"key": "last_name"
}, {
	"is_required": "required",
	"datatype": "text",
	"label": "GENDER",
	"value": "Male",
	"key": "gender"
}]`

**1.最初に改行なしで、文字列として変数にセットする。**
`field1='[{"label":"FIRST NAME","value":"Taro","key":"first_name"},{"label":"LAST NAME","value":"Yamada","key":"last_name"},{"is_required":"required","datatype":"text","label":"GENDER","value":"Male","key":"gender"}]'`

*もともとはBag型として扱われるデータですが、文字列型として変数にセット。

**2.文字列型のテキストを引数にJsonExtractScalarで該当部分を取得できるか検証**

`JsonExtractScalar(field1,'$.[0].value’)`  > Taro
`JsonExtractScalar(field1,'$.[1].value’)`  > Yamada
`JsonExtractScalar(field1,'$.[2].value’)`  > Male
SQLを学んでみた④(DBMSの処理の原則)

実務でSQLやDBについて理解していないといけないと思い勉強を始めました。
その内容をまとめます。


## 処理の流れ

あんまり深く考えてなかったのですが、DBからデータを取り出したり、更新したりするときの処理の流れを理解しようと思いました。
DBMSさんがどうやって仕事をしているのかという話です。

例えば以下のような命令をDBMSさんにしたとします。

```
SELECT * FROM 管理簿
```

そのとき

#### DBMSさんは1行ずつ順番に処理をして、条件に一致するものを表示している

のです。


もう1個例えを出します。
以下のようなDBがあったとします。


| 名前         | 値段        |
|:-----------:|------------:|
| リンゴ        | 300         |
| バナナ       | 400         |
| イチゴ       | 500         |

で、これを`消費税込みの値段に更新したい`とした場合は以下の命令を出します。

```
UPDATE 家計簿
SET 値段 = 値段 * 1.1
```

そうした場合DBMSさんは1行ずつ`値段 * 1.1`をしてその結果を表示してくれているのです。

DBMSさんは命令をもらうと必ずどれか1行に注目し処理をしているということです。
素晴らしいですね。


## SQLで使う演算子

じゃあその処理では演算子をどのように使うんだろうと調べました。

以下の記事を参考にさせて頂きました。
[演算子を使って計算しよう](https://rfs.jp/sb/sql/s02/02-17.html#:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%A8%E3%81%AF%E3%80%81%E6%BC%94%E7%AE%97,%E8%A8%98%E5%8F%B7%E3%81%8C%E3%80%81%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%A7%E3%81%99%E3%80%82)

>![スクリーンショット 2021-03-18 14.20.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/35dc4d40-70d2-11de-d77d-d9d89b11e292.png)

記事ではこのよう紹介されていました。


じゃあ数値だけじゃなくて例えば日付とかを足したり引いたりできるのかなと思って調べてみました。

| 算術演算子    | 例           | 処理内容               |
|:-----------:|:------------:|:---------------------:|
| +           | 日付 + 数値    | 日付を数値の分だけ進める   |
| -           | 日付 - 数値    | 日付を数値の分だけ戻す    |
| -           | 日付 - 日付    | 日付と日付の差の日数を取得 |

なるほど。
勉強になりました。
djangoメモ

views.pyの書き方

```views.py
from django.http import HttpResponse


def helloworldfunction(request):
    returnobject = HttpResponse('<h1>hello world</h1>')
    return returnobject
```

```urls.py
from django.contrib import admin
from django.urls import path
from .views import helloworldfunction

urlpatterns = [
    path('admin/', admin.site.urls),
    path('helloworld/', helloworldfunction),
]
```
VSCodeでLaravel Sailで作成したプロジェクトのテストが実行できるようにする

Laravel Sailで作成したプロジェクトだと`./vendor/bin/sail test`コマンドでテスト実行できますが、テストコードの実装中はメソッド単位でテストしたいので、VSCodeの拡張機能を利用してみました。

## 前提

[こちら](https://qiita.com/kai_kou/items/bfea0281689b3d376812)の手順で手元にLaravel Sailで作成したプロジェクトがクローンされており、Dockerコンテナが実行されている環境となります。

今回の手順は[GitHubリポジトリ](https://github.com/kai-kou/laravel-sail-sample-projects/tree/use-phpunit)でも確認できます。

## VCodeに拡張機能をインストールする

こちらの拡張機能が利用できます。

PHPUnit - Visual Studio Marketplace
https://marketplace.visualstudio.com/items?itemName=emallin.phpunit

プロジェクト直下に`.vscode/settings.json`ファイルを作成することでワークスペースごとにVSCodeの設定が切り替えできるので、そのファイルに拡張機能の設定を追加します。

```json:.vscode/settings.json
{
    "phpunit.command": "vendor/bin/sail exec laravel.test",
    "phpunit.phpunit": "vendor/bin/phpunit"
}
```

PHPUnit - Visual Studio Marketplace
https://marketplace.visualstudio.com/items?itemName=emallin.phpunit

VSCodeでプロジェクト単位の拡張機能を設定する - Qiita
https://qiita.com/k_bobchin/items/717c216ddc29e5fbcd43


### `docker-compose.yml` の編集とコンテナ再起動

VSCodeの拡張機能からDockerコンテナ内でテスト実行する場合、対象となるソースファイルを絶対パスでパラメータ指定されます。そのため、コンテナ内でPHPUnitが絶対パスが参照できないと実行できないので、`docker-compose.yml`を編集します。

```yaml:docker-compose.yml(一部)
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.0/app
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
        volumes:
            - '.:/var/www/html'
+           - '$PWD:$PWD'
(略)
```

`laravel.test`コンテナの`volumes`に`'$PWD:$PWD'` を追加して、絶対パスが参照できるようにしました。

`docker-compose.yml`を編集したらコンテナを再起動します。

`docker-compose.yml`を編集したらコンテナを再起動します。`sail restart`コマンドだと追加した設定が反映されないので`stop`してから`up -d`します。

```console
> ./vendor/bin/sail stop
> ./vendor/bin/sail up -d
```

## 動作確認

拡張機能のインストールと設定ができたらプロジェクトに含まれているテスト(`tests/Feature/AuthenticationTest.php`)を実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/9bd13e55-e420-6fe0-6806-c0cb462eb349.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/15d9f738-3ad4-0eac-6f3b-73e82e615ed4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48549/f21665c3-4e50-d03a-8af4-524240f2e3e1.png)

無事にDockerコンテナ内でテストが実行できました。
やったぜ

## 参考

PHPUnit - Visual Studio Marketplace
https://marketplace.visualstudio.com/items?itemName=emallin.phpunit

VSCodeでプロジェクト単位の拡張機能を設定する - Qiita
https://qiita.com/k_bobchin/items/717c216ddc29e5fbcd43
初学者のプログラミング　resourcesとresource

##resourcesとresource
一人のユーザーから見て複数のリソース(フリマアプリの商品など)に対しては、resources(複数形)でルーティングを設定し、そのユーザー自身のプロフィールなど、１つしかないリソースに対してはresource(単数形)を使用する。これにより*REST的なルーティングの定義が可能となる。

*RESTについてはこちら(一覧表の中に記載あり)
https://qiita.com/sumitaryosuke/items/c9618a4afd8d2677ae50

##記述例
```ruby
config/routes
Rails.application.routes.draw do
  get "/books/:id" => "books#show"
  delete "/books/:id" => "books#destroy"
  resources :publishers
  resource :profile
end
```

```terminal
                          GET    /books/:id(.:format)                                                                     books#show
                          DELETE /books/:id(.:format)                                                                     books#destroy
               publishers GET    /publishers(.:format)                                                                    publishers#index
                          POST   /publishers(.:format)                                                                    publishers#create
            new_publisher GET    /publishers/new(.:format)                                                                publishers#new
           edit_publisher GET    /publishers/:id/edit(.:format)                                                           publishers#edit
                publisher GET    /publishers/:id(.:format)                                                                publishers#show
                          PATCH  /publishers/:id(.:format)                                                                publishers#update
                          PUT    /publishers/:id(.:format)                                                                publishers#update
                          DELETE /publishers/:id(.:format)                                                                publishers#destroy
              new_profile GET    /profile/new(.:format)                                                                   profiles#new
             edit_profile GET    /profile/edit(.:format)                                                                  profiles#edit
                  profile GET    /profile(.:format)                                                                       profiles#show
                          PATCH  /profile(.:format)                                                                       profiles#update
                          PUT    /profile(.:format)                                                                       profiles#update
                          DELETE /profile(.:format)                                                                       profiles#destroy
                          POST   /profile(.:format)                                                                       profiles#create
```
本来、個別に識別すべきユーザープロフィールだが、ログインユーザーに紐づいているため、URIにidの絞り込みが必要なくなっている。また、個別のリソースとなるため、一覧表示の「index」も定義されていない(リソースが一つのため一覧表示できない)。また、resourcesと同様に、onlyオプションを利用して、特定のアクションのみ定義することもできる。

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
可読性の良い実装①【関数化ってどうやるの】

# きっかけ

こんな実装は嫌だ

```
function A() {
    ・・・ // 前半は実装
    ・・・

    b = B() // 後半はまるっと別関数
    return b
}

function B() {
    ・・・ // 前半は実装
    ・・・

    c = C() // 後半はまるっと別関数
    return c
}

function C() {
    ・・・
    ・・・

    return c
}
```

# 考え方

学校の国語で学んだ「章」と「段落」をイメージすると良い

# 例

```
function A() {
    // やること①
    //   やること①-1
    //   やること①-2
    //   やること①-3

    // やること②
    //   やること②-1
    //   やること②-2
    //   やること②-3

    // やること③
    //   やること③-1
    //   やること③-2
    //   やること③-3

    return
}
```

↓

```
function A() {
    // やること①
    AB()

    // やること②
    AC()

    // やること③
    AD()

    return
}

// やること①
function AB() {
    // やること①-1

    // やること①-2

    // やること①-3
}

// やること②
function AC() {
    // やること②-1

    // やること②-2

    // やること②-3
}

// やること③
function AD() {
    // やること③-1

    // やること③-2

    // やること③-3
    AD3()
}

// やること③-3
function AD3() {
    // ・・・
}
```

# メリット
- レビュー依頼の分割がしやすく、かつ、レビュー品質が上がる
- UnitTestも書きやすいと思う
- 実装を途中で他の人に投げる時も、依頼しやすいはず

## レビュー依頼例
1. 処理の流れが正しいか確認

    ```
    function A() {
         // やること①

         // やること②

         // やること③

         return mock
    }
    ```

    ```
    function UnitTestA() {
        // 正常系
        a = A()
        assert a mock
    }
    ```

2. やること①の処理の流れが正しいか確認

    ```
    function A() {
         // やること①
         b = AB()

         // やること②

         // やること③

         return mock
    }

    function AB() {
        // やること①-1
        // やること①-2
        // やること①-3
        return mock
    }
    ```

    ```
    function UnitTestAB() {
        // 正常系
        b = AB()
        assert b mock
    }
    ```

3. やること①-1を実装

    ```
    function AB() {
        // やること①-1
        ・・・
        ・・・
        ・・・

        // やること①-2
        // やること①-3
        return mock
    }
    ```

    ```
    function UnitTestAB() {
        // やること①-1でreturnするケース(エラーとか。)
        b11 = AB()
        assert b1 error11

        b12 = AB()
        assert b1 error12

        // 正常系
        b = AB()
        assert b mock
    }
    ```

4. やること①-2を実装

    ```
    function AB() {
        // やること①-1
        ・・・

        // やること①-2
        ・・・
        ・・・
        ・・・

        // やること①-3

        return mock
    }
    ```

    ```
    function UnitTestAB() {
        // やること①-1でreturnするケース
        ・・・

        // やること①-2でreturnするケース
        b21 = AB()
        assert b1 error21

        b22 = AB()
        assert b1 error22

        // 正常系
        ・・・
    }
    ```

4. やること①-3を実装

    ```
    function AB() {
        // やること①-1
        ・・・

        // やること①-2
        ・・・

        // やること①-3
        ・・・
        ・・・
        ・・・

        return b
    }
    ```

    ```
    function UnitTestAB() {
        // やること①-1でreturnするケース
        ・・・

        // やること①-2でreturnするケース
        ・・・

        // やること①-2でreturnするケース
        b21 = AB()
        assert b1 error21

        b22 = AB()
        assert b1 error22

        // 正常系
        ・・・
    }
    ```

# デメリット

- 「1関数100行以内」とかコーディング規約に行数制限がある場合には、別途工夫が必要(継承とか・・・)
【定期実行】XserverでのCron設定

契約しているXserverでプログラムを定期実行し、Twitterのbotを作成しました。

その際に設定したことを備忘録としてまとめておきます。

定期実行したいファイルを作成してある状態から記述します。

# 1. ファイルをXserver上に配置
まずはXserver上にファイルを配置します。このファイルを実行するとTwitterのAPIを通してツイートされるようになっている状態のファイルです。

自分はWindowsならFFFTP、Macならcyberduckを使いますが、Xserverはブラウザからでもファイル管理ができます。

`public_html`以下の任意の場所に置きましょう。
# 2. ファイルのパーミッションを設定
これができていなくて引っかかることが多いと思います。
FTPソフトからでもブラウザからでもいいので、実行したいファイルのパーミッションを755にします。
書き込みは自分だけ、それ以外は誰でものパーミッションです。
755と入力してもチェックボックスで入力してもOK
![スクリーンショット 2021-01-10 2.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574728/2dbe595b-b233-4571-d3a7-86dca6dd9574.png)
# 3. Cronを設定
Xserverのサーバー管理パネルにログインします。

アカウント -> Cron設定
![スクリーンショット 2021-01-10 2.51.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574728/5f4d942c-0335-2acb-052f-ab86942c2765.png)

Cron設定追加タブから追加します。
![スクリーンショット 2021-01-10 2.53.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574728/849c42e9-1702-4a03-0311-eec706fe23f2.png)

上の画像の例は毎日21時0分に実行するCron設定です。

## 分、時間、日、月、曜日
### アスタリスク(*)
「毎～」のときに使います。（毎月、毎日、毎時など）
試してないですが、おそらく「分」を(*)にすると毎分実行されると思うので気をつけましょう。

### 複数指定したいとき
コンマ(,)区切りで指定します。
0分と30分に実行したいときは`0, 30`と指定します。

### 曜日
曜日の数字は以下のように指定します。
0＝日曜日
1＝月曜日
2＝火曜日
3＝水曜日
4＝木曜日
5＝金曜日
6＝土曜日
7＝日曜日

月木で実行したいなら`1, 3`と指定します。

## コマンド
コマンドには定期実行させたいコマンドとファイルを指定します。
hoge.phpを定期実行させたいときは以下のようになりますが、これだとダメです。

```
php7.2 hoge.php   // phpバージョン7.2のコマンドでhoge.phpを実行する
```
php以外の言語でももちろんOKです（インストールされている場合は）

### 絶対パスを指定すること
コマンドもファイルも絶対パスを指定します。（コマンドは絶対パスじゃなくても良いかも）
先程の例だと以下のようになります。（hoge.phpがpublic_htmlの直下にある場合）

```
/usr/bin/php7.2 /home/サーバーID/ドメイン名/public_html/hoge.php
```

コマンドの絶対パスはネットで調べれば出ると思います。
ファイルの絶対パスは`public_html`の絶対パスが`/home/サーバーID/ドメイン名/public_html/`なのでそこから考えましょう。
または、実行したいファイルと同じ場所に`echo __DIR__`と書いたファイルを置いてブラウザからそのファイルにアクセスすると、そこの絶対パスが表示されます。

# 以上
本当はAWSとかで作りたいんですが、せっかくXserver契約してるから、、、とこっちばっか使っちゃいます。
アクセサが便利なのでまとめてみる件【Laravel 8系】

##とにかくforeachとif文でやれたけど…
今回は実務で初めて知ったLaravelの便利な使い方をまとめていきます。

どんなことを実務でやったのかというと例えば

```PHP
class UserController extends Controller
{
    public function index()
    {
         $users = User::all();
         return view('users.index', compact('users'));
    }
}
```
というコントローラがありviewでUserを一覧で表示するみたいなことは
割と良くやることかなと思います。

```PHP
@foreach ($users as $user)
    {{ $user->name }}さん
    {{ $user->email }}
    続く…
@endforeach
```
そんなときに今回のUserのDB情報には権限(role)カラムがあって
管理者(1)と編集者(2)と言った1か２の値を持っていて
それに対して自分は下記の実装を行った

```PHP
@foreach ($users as $user)
    {{ $user->name }}さん
    {{ $user->email }}
    @if ($user->role === 1)
        管理者
    @else 
        編集者
    @endif
@endforeach
```
上記の実装は別になにか悪いわけではない
ただ今回の案件では上記のようなコードが他に２〜３箇所書くことになっていて
共通箇所があるならまとめようとレビュワーから言われて
初めてアクセサのことを知ったのが今回の記事の経緯です！

##一体何をするのか
実際のコードを書く前に
レビュワーからは
>共通箇所があるならまとめよう

の他にも言われてアクセサを使用することに至った。
>ifの条件で'1'と書かれてそれが管理者に繋がる意図がviewだけではわからない

最近良いコードについての記事を見ている自分からしたら
まさにわからないですね！と前のめりで共感した。
さっそくコードを書いてみよう

今回はUser絡みの対応なので
UserModelで下記のようなコードを書く

```PHP
class User extends Model
{
    public const ADMIN = 1;
    public const EDITOR = 2;
    public const ROLENAMES = [
        self::ADMIN => '管理者',
        self::EDITOR => '編集者'
    ];

    public function retriveRoleNameAttribute()
    {
        return self::ROLENAMES[$this->role];
    }
}
```
と言った感じに
対象のmodelに`get{Attribute}Attribute`メソッドを作成する
`{Attribute}`はアクセスするカラムのアッパーキャメルケースの名前です。
今回は`retrive{RoleName}Attribute`としてます。

これを先程のviewで使用します。

```PHP
@foreach ($users as $user)
    {{ $user->name }}さん
    {{ $user->email }}
    {{ $user->role_name }} // 管理者or編集者が表示される
@endforeach
```

ふぁ〜！！！
if文が無くなってめっちゃすっきりしましたね。
また、権限を返していることも明確にわかるのでこれはいい
便利すぎる。
今後必要なときにはしっかりと使っていくようにします。

最後までありがとうございます。LGTM押してくれるとうれしいです！
誤っている点やもっといいやり方などありましたらコメント頂けるとありがたいです！


###参考
[laravel.jp](https://readouble.com/laravel/8.x/ja/eloquent-mutators.html)
elmをdockerでmakeする

# codesimple/elm

いつからあったのか分からないが、手持ちの環境にelmをインストールしなくてもdockerで開発できる環境が整うので試してみた。

https://hub.docker.com/r/codesimple/elm/

## コマンド
使い方は簡単で自分の開発環境で以下コマンドを実行するだけ。

```shell
docker run  --rm -it -v $(pwd):/code -w /code -e "HOME=/tmp" codesimple/elm:0.19 make src/Main.elm --output=main.js
```

make意外にもinitとかinstall、reactorもelmコマンドがそのまま入っているのでお気軽。

```shell
There are a bunch of other commands as well though. Here is a full list:

    elm repl    --help
    elm init    --help
    elm reactor --help
    elm make    --help
    elm install --help
    elm bump    --help
    elm diff    --help
    elm publish --help
```

## Github Actionsでgithub.ioにデプロイ

せっかくなのでこのdocker imageを使って、以前elmで作ったぷよぷよゲームをGithub Actionsで自動デプロイしてみる。

[コードはここ](https://github.com/m-masataka/elm-puyo/blob/master/.github/workflows/github-io.yml)

1. masterでmake
2. 生成物とその他もろもろの必要なファイルを/tmp/codeに退避
3. github.io用のブランチにチェックアウト
4. 退避したファイルで色々上書きしてcommit&push

```yml
name: Deploy Github.io

on:
  push:
    branches: [master]

jobs:
  deploy:
    runs-on: ubuntu-latest
    container: codesimple/elm:0.19

    steps:
      - uses: actions/checkout@v2

      - name: Install dependencies
        run: elm make --output=main.js src/Main.elm

      - name: saving data
        run: cp -r ./ /tmp/code
      
      - name: install git
        run: apk add git

      - name: git setting
        run: |
          git config --global user.email "email"
          git config --global user.name "name"
      
      - uses: actions/checkout@v2
        with:
          ref: gh-pages

      - name: copy files
        run: |
          cp /tmp/code/main.js ./main.js
          cp /tmp/code/src/main.css ./src/main.css
          cp -r /tmp/code/api ./api
          cp /tmp/code/index.html ./index.html

      - name: Commit files
        run: |
          git add .
          git commit -m "update" -a
          git push origin gh-pages
```

ちゃんと動き出した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520924/8746b1e3-1016-65fb-7c13-cbcae626e085.png)

[demo](https://m-masataka.github.io/elm-puyo/)

<img width="300" alt="795a92ae-119e-9ee0-1699-569e525ae843.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520924/795a92ae-119e-9ee0-1699-569e525ae843.png">

## 感想
elmの開発環境はもともと構築が簡単だけど、さらに楽に開発できてとても助かった。
個人的にはdockerでreactor立てておくだけで簡単にローカルお試し環境ができるのが最高。

github actionsはめちゃめちゃ便利。
[elm-games](https://github.com/rofrol/elm-games "elm-games")のdemoとかはgithub.ioを使って公開している人が多かったので一度やってみたかった。
【SwiftUI】背景をタップしてキーボードを閉じる

# これはなに

`extension` などの切り分けをせずシンプルに実装する。

## 実装

```swift:ContentView.swift
var body: some View {
    ZStack {
        Color.black
            .edgesIgnoringSafeArea(.all)
            // ここから
            .onTapGesture {
                UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
            }
```

おわり(´・ω・｀)
Laravel と MessagePack で遊ぶ

## 動作環境

- Mac OS X 10.15.7
- Laravel 7.x|8.x
- rybakit/msgpack 0.8
- msgpack-tools 0.6

## プロジェクトの作成

```sh
composer require rybakit/msgpack
```

## レスポンスの作成

`routes/web.php`

```php
use MessagePack\Packer;

Route::get('/example.mp', function () {
    $value = (new Packer())->pack([
        'id' => 1,
        'name' => 'John Doe',
        'age' => 18,
    ]);
    return response($value)->header('Content-Type', 'application/x-msgpack');
});
```

## ターミナルで確認

```sh
brew install msgpack-tools
php artisan serve
```

```sh
curl http://localhost:8000/example.mp | msgpack2json -d
```

## レスポンスマクロの作成

```sh
php artisan make:provider MessagePackResponseServiceProvider
```

`app/Providers/MessagePackResponseServiceProvider.php`

```php
namespace App\Providers;

use MessagePack\Packer;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class MessagePackResponseServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Response::macro('mpac', function ($value) {
            return response((new Packer())->pack($value))->header(
                'Content-Type',
                'application/x-msgpack'
            );
        });
    }
}
```

`config/auth.php`

```php
return [
    'providers' => [
        # ...
        App\Providers\MessagePackResponseServiceProvider::class,
    ],
];
```

`routes/web.php`

```php
Route::get('/example.mp', function () {
    return response()->mpac([
        'id' => 1,
        'name' => 'John Doe',
        'age' => 20,
    ]);
});
```

## ターミナルで確認

```sh
curl http://localhost:8000/example.mp | msgpack2json -d
```

## Model を渡せるようにする

`toArray()` があれば変換しておくと Eloquent Model もそのまま渡せる。

```php
Response::macro('mpac', function ($value) {
    if (method_exists($value, 'toArray')) {
        $value = $value->toArray();
    }
    return response((new Packer())->pack($value))->header(
        'Content-Type',
        'application/x-msgpack'
    );
});
```

## 資料

- https://readouble.com/laravel/8.x/ja/responses.html#response-macros
初学者のプログラミング　HTTPメソッド

出てくるたびになんだっけ？ってなるので一覧表にまとめておきました！

##HTTPメソッド一覧表
|メソッド名|実行する内容|
| - + - |
|GET|指定した*リソースの表現をリクエストする(レスポンスを求める)。使用するリクエストはデータの取り込みに限る。|
|HEAD|GETと同じレスポンスを求めるが、レスポンス本文がない。|
|POST|指定したリソースに実態を送信するために使用するメソッドで、サーバー上の状態を変更したり、副作用が発生したりすることをがよくある。|
|PUT|対象リソースの現在の表現の全体を、リクエストの*ペイロードで置き換える。|
|DELETE|指定したリソースを削除する。|
|CONNECT|対象リソースで識別されるサーバーとの間にトンネルを確立する。|
|OPTIONS|対象の通信オルションを示すために使用する。|
|TRACE|対象リソースへのパスに沿ってメッセージのループバックテストを実行する|
|PATCH |リソースを部分的に変更するために使用する。|

*リソース...保存したデータなどを指している
*ペイロード...付加情報(ヘッダやトレーラ)を除いたデータ本体のこと

参照元
MDN Web Docs
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods
weblio 
https://www.weblio.jp/content/%E3%83%9A%E3%82%A4%E3%83%AD%E3%83%BC%E3%83%89

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
要素の位置の指定について

要素を任意の位置に配置する方法について記事を書きたいと思います。

### 要素の配置方法
■positionプロパティ
positionプロパティとは指定した要素の配置方法を決めることができるプロパティ。

|値との組み合わせ|説明|
|-------------|----|
|position: relative;|現在の位置を基準に相対的な位置を決める|
|position: absolute;|特定の地点を基準に絶対的な位置を決める(デフォルトの基準はウィンドウ左上)|
|position: fixed;|要素を指定した位置に固定する|
また、positionプロパティはtop、bottom、left、rightというプロパティとセットで使うことが多い。

■top/right/bottom/leftプロパティ
positionプロパティを指定した要素に、基準（上、下、右、左）の距離を指定することができる。

### 絶対位置
ブラウザの左上を基準としてとる位置のことを、絶対位置という。
position: absolute;を適用された要素はブラウザの左上が位置の基準になる。

### 相対位置への要素の配置
ある要素が、他の要素との関係の上に成り立つ位置のことを相対位置という。
親要素にposition: relative;を設定すると、子要素の基準は親要素の左上となり、相対位置をとる。
子要素にposition: absolute;を付与した際、親要素にposition: relative;を付与すると位置の
基準となる。

### まとめ
・positionプロパティとは指定した要素の配置方法を決めることができるプロパティのこと。
・positionプロパティを指定した要素に、top/right/bottom/leftプロパティを用いることで、基準（上、下、右、左）の距離を指定することができる。
・親要素にposition:relative;を指定することで、position:absolute;を指定した子要素の基準の位置 　を親要素に指定できる。
pi picoでmicropython その15

#概要

picoでmicropythonやってみた。
pioアセンブラで、ws2812、やってみた。

#サンプルコード

```
import array
import time
import rp2
from machine import Pin
@rp2.asm_pio(sideset_init = rp2.PIO.OUT_LOW, autopull = True, pull_thresh = 24, out_shiftdir = rp2.PIO.SHIFT_LEFT)
def ws2812():
   label("loop")
   out(x, 1)
   nop().side(1)
   jmp(not_x, "tugi")
   nop()
   nop()
   nop().side(0)
   label("tugi")
   nop().side(0)
   nop()
   jmp("loop")
sm = rp2.StateMachine(0, ws2812, freq = 5_000_000, sideset_base = Pin(17))
sm.active(1)

def main():
   global sm
   NUM_LEDS = 7
   ar = array.array("I", [0 for _ in range(NUM_LEDS)])
   for i in range(7 * NUM_LEDS):
      for j in range(NUM_LEDS):
         r = j * 100 // (NUM_LEDS - 1)
         b = 100 - j * 100 // (NUM_LEDS - 1)
         if j != i % NUM_LEDS:
            r >>= 3
            b >>= 3
         ar[j] = r << 16 | b
      sm.put(ar, 8)
      time.sleep_ms(90)
   for i in range(24):
      for j in range(NUM_LEDS):
         ar[j] >>= 1
      sm.put(ar, 8)
      time.sleep_ms(10)
main()

```

以上。
初学者のプログラミング　フックで処理を差し込む

##フック
コールバック処理のようにコントローラーが実行するアクションの前後に処理を差し込むこと
##フック一覧
| フック名|処理が実行されるタイミング|
| - + -|
|before_action|Actionの実行前
|after_action|Actionの実行後(正常にActionが実行された場合のみ呼び出す)
|around_action|Actionの前後

##フックの記述例
```ruby
class BooksController < ApplicationController
  protect_from_forgery except: [destroy]
  before_action :set_book, only: [:show, :destroy]
  around_action :action_logger, only [:destroy]

  #略#

  private

  def set_book
    @book = Book.find(params[:id])
  end

  def action_logger
    logger.info "around-before"
    yeild
    logger.info "around-after"
  end
end
```

beforeフックでset_bookメソッドを、aroundフックでaction_loggerメソッドを呼び出している。またaroundフックではメソッド側でフックによる処理のタイミングを考慮する必要があり、around-beforeの際はyeildによってアクション側に処理を戻す必要がある。
##まとめ
アクションの前に実行したい処理にはbeforeで、後に実行したい処理の場合はafterで記述し、前後の両方で実行したい処理の場合はaroundで記述する。

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
【React】Reactで同じモーダルを使ってURLを振り分ける

## 前提
以下のように同じモーダルウィンドウを使って新規登録、ログイン、ログアウトの処理を実装したい
![recommended-books-2-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/c6b31aa3-a260-c0a2-7d61-97a8fbeedd4a.gif)

## 結論
navigationを使うことで対応。

## 実装内容

### ①モーダルを開く処理をLinkごとに分ける

以下のように、新規登録・ログイン・ログアウトそれぞれモーダルを開くためのメソッドを切り分ける。
ここは引数を使うと楽な気がするが一旦このまま進める。

```jsx
// 新規登録・ログイン・ログアウトでモーダルの表示を分けるために別メソッドとして定義
  openSignUpModal() {
    this.setState ({
      showModal: true,
      content: 'SignUp'
    })
    this.props.history.push("/users/sign_up");
  }

  openSignInModal() {
    this.setState ({
      showModal: true,
      content: 'SignIn'
    })
    this.props.history.push("/users/sign_in");
  }

  openSignOutModal() {
    this.setState ({
      showModal: true,
      content: 'SignOut'
    })
    this.props.history.push("/users/sign_out");
  }

  // モーダルを閉じる。contentは空文字列にリセット
  closeModal() {
    this.setState ({
      showModal: false,
      content: ''
    })
    this.props.history.push("/");
  }
```

### ②各モーダルを開くためのリンクにそれぞれのメソッドを設定する

```jsx
<HeaderLink onClick={this.openSignUpModal}>
  新規登録
</HeaderLink>
<HeaderLink onClick={this.openSignInModal}>
  ログイン
</HeaderLink>
<UserModal show={this.state.showModal} close={this.closeModal} content={this.state.content} signIn={this.successToSignIn}/> {/* stateのcontentでログインと新規登録を分岐 */}
```

ログアウトボタンはログインしているときのみ表示

```jsx
<HeaderLink onClick={this.openSignOutModal}>
  ログアウト
</HeaderLink>
<UserModal show={this.state.showModal} close={this.closeModal} content={this.state.content} signOut={this.successToSignOut}/> 
```

こうすることで各ボタンごとにstateの更新処理を分け、URLも別々にnavigationできる。
そしてstateの値に応じてモーダルの表示内容を切り替えることで快適なnavigationを実現



### 参考

navigationについて
https://qiita.com/TsutomuNakamura/items/34a7339a05bb5fd697f2#navigate
k8sな開発環境であると便利なTelepresenceをCentos7にInstallする

# Telepresence

Telepresenceはk8sを利用した開発時に開発マシンにinstallしていると便利なもので、指定したk8s上のpodをproxy podに置き換えて、k8s上のpodへの通信をlocalのコンテナに、localのコンテナからの通信をproxy podからk8s上に返すことができるツールです。

Telepresence: https://www.telepresence.io/

# TelepresenceをCentOS7にinstall
install手順は公式の[ここ](https://www.telepresence.io/reference/install)に書いてあるのですが、CentOS7用の手順がありません。検索すると[これ](https://gist.github.com/hamdifourati/b69850bc07f8e3a599a228d4c404f88b)がでてきますが微妙に動かないのでinstall手順を以下に整理しました。

- 作業ディレクトリ作成

install作業中にgit cloneコマンドを実行してtelepresenceリポジトリを落としてきたりするので作業用ディレクトリを作って作業します。

```
mkdir telepresence
cd telepresence
```


- telepresence_centos7.sh作成
コマンドを順番に実行しても良いのですがinstallスクリプトをtelepresence_centos7.shとして作成してinstall作業を進めます。以下の内容でtelepresence_centos7.shを作成してください。

```sh
#!/bin/bash
set -ex

yum update -y

# install python3.6
yum -y install yum-utils
yum -y groupinstall development
yum install -y https://repo.ius.io/ius-release-el7.rpm
yum -y install python36u
#echo "`python3.6 -v` installed."
# python 3.6 installed

# install system dependencies
yum install -y git torsocks sshfs conntrack
git clone https://github.com/datawire/telepresence.git && cd telepresence

# force the install to use python3.6
sed -i "s/python3/python3.6/" install.sh
env PREFIX=/usr/local ./install.sh
echo "Telepresence `telepresence --version` installed!"
```

- install実行

```
bash telepresence_centos7.sh
```

最後に`Telepresence 0.109-16-g601cad6-dirty installed!`などと出力されれば成功です。`telepresence`コマンドが使えるようになっているはずです。
【jquery,js】指定したURLを開く [window.open,location.href] [js14_20210322]

####  <font color='orange'>処理の概要</font>


##### 処理のフロー：
　(1)テキストボックスのURLを取得する
　(2)指定の方法でURLへアクセスする
※遷移出来ない場合は、デフォルトでサーバエラーとなる

####  <font color='orange'>画面イメージ</font>


#####画像１
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/c25e5bbb-1c02-3209-3682-2a990394aa93.png" width="400px">
補足）それぞれ指定のボタンを押下するとテキストボックス内にあるURLに別タブや別ウィンドウで遷移します。

####  <font color='orange'>ソースコード</font>
```html:index.html
<body>
	<div class="inputtext" id="container">
		<input type="text" id="urlInput" value="https://www.google.co.jp/" ><br>
		<input type="button" id="urlMoveButton" value="URLの移動をする"><br>
		<input type="button" id="urlTabOpenButton" value="別のたぶを開く"><br>
		<input type="button" id="urlWindowOpenButton" value="別のウィンドウを開く">
	</div>
</body>
```

```javascript:main.js
$(function() {
    $("#urlMoveButton").click(function(){
        var urlMoveText = $("#urlInput").val();
        location.href = urlMoveText;
    });

    $("#urlTabOpenButton").click(function(){
        var urlOpenText = $("#urlInput").val();
        window.open(urlOpenText, "_blank");
    });

    $("#urlWindowOpenButton").click(function(){
        var urlOpenText = $("#urlInput").val();
        window.open(urlOpenText ,null, 'width=500, toolbar=yes , menubar=yes,scrollbars=yes');
    });
});
```


####  <font color='orange'>ポイント</font>
html：
(1)特になし
js：
(1)window.openはオプションの指定方法で新しいタブ、またはウィンドウを指定することが出来る

####  <font color='orange'>参考資料</font>
JavaScript(仕事の現場でサッと使える！デザイン教科書)　p102
Macのhttpdでコンテンツはどこに置いたらいいのか調べた

#httpdを起動する
```terminal
$ sudo apachectl start
```
#ポートを確認する
```terminal
$ grep Listen /usr/local/etc/httpd/httpd.conf 
# Listen: Allows you to bind Apache to specific IP addresses and/or
# Change this to Listen on specific IP addresses as shown below to 
#Listen 12.34.56.78:80
Listen 8080
```
ここで、http://localhost:8080 にアクセスして起動したことを確認します。
#どのhttpdが動いているのか調べる
```terminal
$ ps ax | grep httpd
53739   ??  Ss     0:00.16 /usr/local/opt/httpd/bin/httpd -k start
53741   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53742   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53743   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53744   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53745   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53747   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
53778   ??  S      0:00.00 /usr/local/opt/httpd/bin/httpd -k start
54954 s005  R+     0:00.00 grep httpd
```
#どのhttpd.confが使われているのかを調べる
```terminal
$ /usr/local/opt/httpd/bin/httpd -V | grep SERVER_CONFIG_FILE
 -D SERVER_CONFIG_FILE="/usr/local/etc/httpd/httpd.conf"
```
#コンテンツの置き場所を調べる
```terminal
$ grep DocumentRoot /usr/local/etc/httpd/httpd.conf 
# DocumentRoot: The directory out of which you will serve your
DocumentRoot "/usr/local/var/www"
    # access content that does not live under the DocumentRoot.
```

というわけで、/usr/local/var/wwwにおけば良いことがわかる。