OmniAICreator/Qiita-1.07M huggingface dataset:
[Elm] 関数合成を理解する

## モチベーション
- `|>` は使えるけど `>>` がいまいち使いこなせない
- なんとなくで `.member >> .id` とか使ってるけど、もやもやする



## パイプと関数合成の違い

### 図で違いを見てみる

パイプは、一つ処理をしてその結果を次の処理に渡して〜という実行を繋げていく。

![](https://i.imgur.com/WtUNeMo.png)

関数合成は、複数の処理を処理を1つにまとめて一気に実行する。

![](https://i.imgur.com/MFhZskI.png)


### コードで違いを見てみる

ここではサンプルとして、ユーザーが18才以上かどうかで出力メッセージを分ける関数の実装を考えてみる。

```elm
type alias User =
    { name : String
    , age : Int
    }

user1 : User
user1 =
    { name = "Yuna"
    , age = 22
    }

user2 : User
user2 =
    { name = "Taro"
    , age = 15
    }

helloMessage : Bool -> String
helloMessage isAdult =
    if isAdult then
        "ようこそ！"

    else
        "未成年は入れません。"
```

まず、パイプを使った実装が `hello1` 。
以下のように順々に処理が流れていると捉えることができる。

1. userのageを取ってくる
2. 1の結果（userのage）を18以上かチェック
3. 2の結果（18以上かどうか）をhelloMessage関数に渡し、出力テキストを振り分ける

```elm
hello1 : User -> String
hello1 user =
    user |> .age |> (<=) 18 |> helloMessage
    -- 向きを逆にしても内容は同じ
    -- helloMessage <| (<) 18 <| .age <| user
```

型を見てみてみよう。
パイプの実装は以下のようになっている。

```elm
(|>) : a -> (a -> b) -> b
```

これを`hello1`に当てはめてみると、以下の図のようになる。
![](https://i.imgur.com/ADWvtq7.png)


次に、関数合成を使った実装が `hello2` 。
こちらの場合は、上記の1, 2, 3の処理を全てまとめて、「userのageを取ってきて18以上かチェックして出力テキストを振り分ける」関数として捉えることができる。

```elm
hello2 : User -> String
hello2 user =
    (.age >> (<=) 18 >> helloMessage) user
    -- 向きを逆にしても内容は同じ
    -- (helloMessage << (<=) 18 << .age) user
```

型を見てみよう。
関数合成の実装は以下のようになっている。

```elm
(>>) : (a -> b) -> (b -> c) -> a -> c
```

これを`hello2`に当てはめてみると、以下の図のようになる。
![](https://i.imgur.com/hYyczWv.png)


さらに関数合成では以下の `hello3` ように書ける。

```elm
hello3 : User -> String
hello3 =
    .age >> (<=) 18 >> helloMessage
```

この場合では、`user`を引数に取っていない。この書き方がElm始めた時からすごい不思議だったんだけど、一度わかったら全然難しいことじゃなかったよ〜
関数の捉え方がわかると、これはすぐに理解できると思う。`hello1`, `hello2`は「userを受け取ってStringを返す関数」として捉えているのに対し、`hello3`は「User -> Stringという値」として捉えている。関数型言語でよく出てくる全ての関数は値だ〜みたいなのはこういうことなんだなぁと、Elmで初めて関数型言語を学んでしっくりきた。ちなみにこの書き方は、Haskellではポイントフリースタイルと言われている。



## 関数合成の実開発での使われ方

プロダクトの実開発では、やたらめったら関数合成が使われている訳ではなく、基本はパイプラインが多い。ただ、関数を値として扱える性質から、関数合成でまとめた関数を別の関数の引数に渡したり、パイプラインの途中の処理で使ったりといった用途で活躍しているように思う。
あと関数合成を使うと短くスマートに書けるので、単純にかっこいい！
ただ、Elm初心者、関数型言語初心者には、パイプラインの方がコードを追いやすいと思う。上級者・初心者とも関数合成に対する理解レベルを合わせて利用する、関数合成は乱用せず基本的にパイプラインを使うようにするなど、チームのガイドラインを設けてもいいかも？



## まとめ

- パイプも関数合成も、同じ処理が書ける。順にやるかまとめてやるかの違い。
- パイプも関数合成も、向きを逆にしても処理の内容は変わらない。
- 関数合成を使うと複数の処理を1つの関数としてまとめられる。
- Elmでは関数は値にもなるので、関数合成でまとめた関数を別の関数の引数に渡したりすることができる。ポイントフリースタイル化もできる。
- 初心者にはパイプの方がコードを追いやすいので乱用は禁物かも。
【Swift】構造体とJSONの変換方法（JSONEcoder,decoder）

API通信する際に構造体をJSONに変換してリクエストしたりまた逆に、APIから受け取ったJSONのレスポンスを構造体に変換したい時があります。

そこで、今回はJSONDecoer,JSONEncoderを用いて構造体とJSONの変換方法を備忘録として記載します。（Qiita初投稿なので、緊張してます）

### バーション
Xcode10.2.1、Swift5.0.1

# JSONEncoder（構造体→JSON）
```swift
// Human構造体
struct Human:Codable {
    var id: Int
    var name: String
    var hobby: String
}

// Humanのインスタンス生成
let hogeMan1 = Human(id: 1, name: "ほげ君", hobby: "プログラミング")
print(hogeMan1)
// -> "Human(id: 1, name: "ほげ君", hobby: "プログラミング")"

// JSONEcoder（構造体→JSON[Data型]）
let hogeManJsonData = try! JSONEncoder().encode(hogeMan1)
print(hogeManJsonData)
// -> "59 bytes"

// Data型→String型にキャスト
let hogeManJsonString = String(data: hogeManJsonData, encoding: .utf8)!
print(hogeManJsonString)
// -> "{"id":1,"name":"ほげ君","hobby":"プログラミング"}"
```
### ポイント
* EncodeとDecodeを行うため、構造体に`Codeble`を継承する
* JSONEncoderの`戻り値はData型`なので、必要に応じてString型にキャストする

>Codable = Encodable + Decodable
[引用：【Swift】Codableについて備忘録](https://qiita.com/s_emoto/items/deda5abcb0adc2217e86/)

# JSONDecoder（JSON→構造体）
```swift
// JSON[String型]定義
let jsonString = "{\"id\":2,\"name\":\"ほげほげ君\",\"hobby\":\"ボルダリング\"}"

// String型→Data型にキャスト
let jsonData = jsonString.data(using: .utf8)!
print(jsonData)
// -> "62 bytes"

// JSONDecoder（JSON→構造体）
let hogeMan2 = try! JSONDecoder().decode(Human.self, from: jsonData)
print(hogeMan2)
// -> "Human(id: 1, name: "ほげ君", hobby: "プログラミング")"
```
### ポイント
* JSONDecoderの`引数はData型`なので、String型のJSONはData型にキャストする必要がある

# まとめ
上記で紹介したコードのまとめです。

```swift
import UIKit

// Human構造体
struct Human:Codable {
    var id: Int
    var name: String
    var hobby: String
}

// JSONEncoder--------------------------------------------------
// Humanのインスタンス生成
let hogeMan1 = Human(id: 1, name: "ほげ君", hobby: "プログラミング")
print(hogeMan1)

// JSONEcoder（構造体→JSON[Data型]）
let hogeManJsonData = try! JSONEncoder().encode(hogeMan1)
print(hogeManJsonData)

// Data型→String型にキャスト
let hogeManJsonString = String(data: hogeManJsonData, encoding: .utf8)!
print(hogeManJsonString)

// JSONDecoder--------------------------------------------------
// JSON[String型]定義
let jsonString = "{\"id\":2,\"name\":\"ほげほげ君\",\"hobby\":\"ボルダリング\"}"

// String型→Data型にキャスト
let jsonData = jsonString.data(using: .utf8)!

// JSONDecoder（JSON→構造体）
let hogeMan2 = try! JSONDecoder().decode(Human.self, from: jsonData)
print(hogeMan2)
```

以上になります。
もし不明点や間違い等があればコメントくださいm(_ _)m
[Rails]stringからenumに変更する

stringで保存されたデータをenumに変更します。

# enumの設定
ゴールとなるenumの設定。

```ruby:Reservation.rb
class Reservation < ApplicationRecord
	enum status: { applied: 0, accepted: 1, cancelled: 2, completed: 3 }
end
```

# migrationの設定
元データは、`Reservation.status`にstringで`'applied','accepted','cancelled','completed'`が入っています。

以下のようなマイグレーションで、カラム型をStringからIntegerに変更し、データも移行するところまで一括で行います。

```ruby:
class ReservationStatusConvertToEnum < ActiveRecord::Migration[6.0]
  # データベース操作の際にコールバックを呼ばないよう、テーブルを使うだけのTmpモデルを作る
  class TmpReservation < ApplicationRecord
    self.table_name = :reservations
  end

  def change
  	# 元データのカラム名を変更
    change_table :reservations do |t|
      t.rename :status, :old_status
    end

    reversible do |dir|
      dir.up do
      	 # 新しくenum用のintegerカラムを追加
        add_column :reservations, :status, :integer, null: false, default: 0
        # テーブル情報をリセットする
        TmpReservation.reset_column_information
        # stringで持っていた名前をenumと同じ順でarrayにし、旧データをインデックス番号で取る
        TmpReservation.find_each do |tr|
          tr.status = %w(applied accepted cancelled completed).index(tr.old_status)
          tr.save!
        end
        # 旧データを捨てる
        remove_column :reservations, :old_status
      end

	  # upの逆
      dir.down do
        add_column :reservations, :old_status, :string
        TmpReservation.reset_column_information
        TmpReservation.find_each do |tr|
          r = Reservation.find(tr.id)
          tr.old_status = r.status
          tr.save!
        end
        remove_column :reservations, :status
      end
    end
  end
end

```

参考：　[Rails Migration, converting from string to enum | stack overflow](https://stackoverflow.com/questions/35163804/rails-migration-converting-from-string-to-enum)

# Scopeの修正
条件をSQL形式で書いてしまっているところは、enumに変換後に期待するデータが取ってこれなくなりますので、修正します。

```ruby
scope :applied_reservations, -> { where("status = 'applied'") } # NG
scope :applied_reservations, -> { where(status: 'applied') } # OK

```
Docker + Laravel で躓いていた点

Laravel を触ってみよう、ということで Mac 上の Docker に入れてみようとしましたが、躓いた点があったためメモ。
Laravel は初めてですし、Docker もちょっと触った程度なので、非常につまらないつまづきです。

ちなみに Dokcer のイメージは、以下のを使用

### PHP 用コンテナ

```
FROM php:7.1-apache
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libmcrypt-dev \
  && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv mcrypt
```

### MySQL 用コンテナ

```
FROM mysql:5.7
COPY ./my.cnf /etc/mysql/conf.d
```

いずれも、
`cat /etc/issue`
`Debian GNU/Linux 9 \n \l`



## 1. artisan が実行できない。

Voyager を入れようと思って、
`php artisan voyager:install`
とコマンドを打つと、
`Could not open input file: artisan`
と出てしまいました。ええ？と思ったのですが、artisan はプロジェクトのルート（artisan ファイルが置かれているディレクトリ）で実行しないといけない、というだけでした。

## 2. Laravel から MySQL につながらない

Laravel をインストールし終えて http://localhost/ が表示されるようになり、プロジェクト用のデータベースを作成し、次に `php artisan migrate` しようとしたのですが、
`SQLSTATE[HY000] [2002] No such file or directory`
と出てしまい、失敗します。
`.env` の DB_HOST の値を、 `localhost`, `127.0.0.1`, MySQL のコンテナ名に変えるなどしてみますが、いずれもダメ。

### 原因と対応
Mac のターミナルから `php artisan migrate` のコマンドを打っていたのが原因でした（それだけ >_<）。
`docker exec -it PHPのコンテナ名 /bin/bash` でコンテナにログインして、 laravel プロジェクトのルートディレクトリから `php artisan migrate` する必要がありました。

ちなみに、 試行錯誤の中、DB_HOST 名を以下のように指定した場合のメッセージをそれぞれ書き出してみます。

### localhost の場合
`SQLSTATE[HY000] [2002] No such file or directory`

### 127.0.0.1 の場合
`SQLSTATE[HY000] [2002] Connection refused`

### MySQL のコンテナ名の場合
`SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known`

### MySQL コンテナのIPアドレスの場合

`SQLSTATE[HY000] [2002] Operation timed out`
※ コンテナのIPアドレスは `docker exec -it MySQLのコンテナ名 /bin/bash` でログインして、 `cat /etc/hosts` で確認できます。

## 3. localhost/admin が Not Found

Voyager のインストールも終わって、いざ http://localhost/admin にアクセスしたのですが、 Not Found。
うーん、と思ったのですが、 apache の mod_rewrite が有効になっていないだけでした。
`/etc/apache2/mods_available/rewrite.load` を `/etc/apache2/mods_enabled` に移してコンテナを再起動すればOKでした。

## 終わりに

問題が、Laravel にあるのか Voyager にあるのか Docker にあるのか、Docker なら docker-compose.yml にあるのか確認すべき箇所がたくさんあって難儀しました。

少しでも参考になれば幸いです。自身は、そのうちまた同じところでつまづきそう。
Mac GitHubのリモートリポジトリをブラウザで開く便利コマンド

GitHubのURLをコマンドですぐ開けたら便利だなと思って調べてみました。
方法としては `open` コマンドと `hub` コマンドを使う場合の二通りあります。

## 1. openコマンド

### HTTPSプロトコルの場合

```shell-session
open $(git config remote.origin.url)
```

シンプルに書けます。

### SSHプロトコルの場合

```shell-session
open https://github.$(git config remote.origin.url | cut -f2 -d. | tr ':' /)
```

SSHプロトコルでリモートリポジトリを設定していると `git@github.com:` から始まるので置換してます。また、HTTPSプロトコルでもこのコマンドはそのまま使えます。

### alias設定

`~/.bash_profile` 等に下記コードを追記します。

```
alias gh="open https://github.$(git config remote.origin.url | cut -f2 -d. | tr ':' /)"
```

## 2. hubコマンド

[hub](https://github.com/github/hub)コマンドをインストールします。

```shell-session
brew install hub
```

`hub browse` コマンドでGitHubのリモートリポジトリのURL

```shell-session
hub browse
```

## 参考

- [igrigorik/github.bash](https://gist.github.com/igrigorik/6666860#gistcomment-913229)
- https://github.com/github/hub#git-browse

## 関連記事

- [Mac Git 初期設定](https://qiita.com/ucan-lab/items/aadbedcacbc2ac86a2b3)
- [Mac GitHub SSH接続設定](https://qiita.com/ucan-lab/items/e02f2d3a35f266631f24)
react-native-snap-carouselを使ってみる


## やりたいこと

* ReactNativeの画面にカルーセルを入れたい（広告バナーでの利用をイメージ）

![スクリーンショット 2019-09-29 10.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/4186db74-47af-3078-c336-c5d281b14770.png "スクリーンショット 2019-09-29 10.45.44.png")


## 準備

[react-native-snap-carousel](https://github.com/archriss/react-native-snap-carousel)を使ってみます。loopやautoplayとかできて便利そう。

```bash
npm install --save react-native-snap-carousel
```

## 実装

めんどいのでApp.jsに全部書いてみます。

### App.js

```js:App.js
import React from 'react';
import { StyleSheet, Text, View, Dimensions, SafeAreaView, TouchableHighlight, Image, Linking } from 'react-native';
import Carousel, { Pagination } from 'react-native-snap-carousel';

export default class App extends React.Component {

    state = {
        data: [
            { title: 'a', url: 'http://www.bluecode.jp/images/A.png' },
            { title: 'b', url: 'http://www.bluecode.jp/images/B.png' },
            { title: 'c', url: 'http://www.bluecode.jp/images/C.png' },
            { title: 'd', url: 'http://www.bluecode.jp/images/D.png' },
            { title: 'e', url: 'http://www.bluecode.jp/images/E.png' },
        ],
        activeSlide: 0,
    }
   
	
	//カルーセルの中身
    _renderItem = ({ item, index }) => {
        return (
            <TouchableHighlight
                onPress={() => Linking.openURL(item.url)}
            >
                <Image source={{ url: item.url }} style={{ width: '100%', height: '100%' }} />
            </TouchableHighlight>
        );
    }

    render() {
        return (
            <SafeAreaView style={{ height: 240 }}>
                <Carousel
                    data={this.state.data}
                    renderItem={this._renderItem}
                    itemWidth={Dimensions.get("window").width * 0.6}
                    sliderWidth={Dimensions.get("window").width * 1.0}
                    // containerCustomStyle={{ flex: 1, backgroundColor: "#eee" }}
                    onSnapToItem={index => this.setState({ activeSlide: index })} //for pagination
                    loop
                    autoplay
                />
                <Pagination
                    dotsLength={this.state.data.length} //dotの数
                    activeDotIndex={this.state.activeSlide} //どのdotをactiveにするか
                    containerStyle={{paddingVertical:15}} //デフォルトではちと広い
                />
            </SafeAreaView>
        );
    }
}

```
PostgreSQLメモ

個人的なメモ帳を整理していたら出てきたので、共有したいと思います。
**※ この内容は新しくもなく、かつ試した程度のただのメモ書きです。**

## 一時的なループ

大量データ投入などに使える

``` sql
CREATE TABLE public.hoge
(
    test1 bigint NOT NULL,
    test2 bigint NOT NULL
);

do $$
  begin
    for i in 1..10 loop
      for j in 1..10 loop
        insert into public.hoge(test1, test2) values (i, j);
      end loop;
    end loop;
  end;
$$;

DROP TABLE public.hoge;
```

## PREPAREの利用
###準備
PREPARE文で作成する

``` sql
PREPARE hoge_sql(integer, int)
AS
insert into public.hoge(test1, test2) values ($1, $2);
```

### 実行
EXECUTE文で実行

``` sql
EXECUTE hoge_sql(1);
```

### 削除
一度作るとfunctionとして残るので、なるべく終わったらDEALLOCATEで削除する。

``` sql
DEALLOCATE PREPARE hoge_sql;
```
統計検定2級を受験してみようと思う

#　思い立ったが吉日
ちょうど帰省して、することもない秋の穏やかな日。
今までの仕事の成果を資格試験という形で残しておくのもいいなぁと思い、どういうふうに準備したらよいのか、まずは調べてみることにしました。
せっかく調べたので今後の役に立つといいなぁと思います。

##日程確認
まずは、統計検定のサイトでスケジュールを確認。
直近だと以下のスケジュールのようです。
2019年　11月24日(日)
個人申込 ：9月4日～10月11日

一応、申し込み期間内ではあるものの、もっと便利な
CBT方式試験があります。
東京で会社からも近い有楽町の会場を選んでみると、ほぼ毎日受験可能となっています。
https://apply.odyssey-com.co.jp/center/list2.php?id=13&examtype%5B%5D=55

私の場合、CBT方式試験のほうが都合がよさそう。

##勉強準備
まずは統計検定のサイトを見てみると、こちらの公式本が紹介されていました。
http://www.tokyo-tosho.co.jp/books/978-4-489-02227-2/

あと、過去の問題と解説も公開されているので確認してみます。
http://www.toukei-kentei.jp/about/grade2/

うーん。問題を読む限りではちょっと難しそう。

Qiitaでも受験された方の受験記を見てみました。
https://qiita.com/okoppe8/items/6caca7ab6509edf0c497


こちらの「統計学の時間」というサイトがおすすめされていました。https://bellcurve.jp/statistics/course/
Gitのコミット日時を上書きする２つの方法

## コミット日時を上書きしたい

Gitのコミットの、差分とコミットメッセージは維持しつつ、コミット日時を書き換えたいことが稀にある。
こないだあったのは、テストのためにローカルホストの日時を未来に変更したままでコミットしてしまい、「未来のコミットになってますよw」という指摘がコードレビューで出たとき。

## 普通にamendしても上書きされない

通常のamendでは日付は書き換わらない。

```
$ GIT_PAGER= git log -1
commit 64c414eaa5084c765c79d2e061ced3d5724d00dd (HEAD -> master)
Author: foo <foo@example.com>
Date:   Sun Sep 29 09:59:00 2019 +0900

    an example
$ date
日  9 29 10:02:03 JST 2019
$ git commit --amend
[master 8f3cf01] an example
 Date: Sun Sep 29 09:59:00 2019 +0900
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename a => b (100%)
$ GIT_PAGER= git log -1
commit 8f3cf018573ad002c906e00bfa2facd38fc276ca (HEAD -> master)
Author: foo <foo@example.com>
Date:   Sun Sep 29 09:59:00 2019 +0900

    an example
```

これは、コミットには２つの日付 AuthorDate と CommitDate が記録されており、amendでは CommitDate の方が更新されるからである。実際、CommitDateの方は更新されている：

```
$ GIT_PAGER= git log -1 --pretty=fuller
commit 8f3cf018573ad002c906e00bfa2facd38fc276ca (HEAD -> master)
Author:     foo <foo@example.com>
AuthorDate: Sun Sep 29 09:59:00 2019 +0900
Commit:     foo <foo@example.com>
CommitDate: Sun Sep 29 10:02:08 2019 +0900

    an example
```

## 方法1: reset-authorオプション

お手軽なのは reset-author オプションを使うこと。以下のようにするとAuthorDateが現在日時になる

```
$ git commit --amend --reset-author
```

その名の通り、Authorもリセットされてしまうので、そうしたくない場合には使えない。
ちなみに reset-author オプションと一緒に author オプションを指定するとエラーになる。

```
$ git commit --amend --reset-author --author "foo <foo@example.com>"
fatal: Using both --reset-author and --author does not make sense
```

また、この方法だと、現在日時とすることしかできない。

## 方法2: dateオプション

date オプションで日時を指定するとそれが AuthorDate に設定される。例えば現在日時とするには

```
git commit --amend --date $(date --iso-8601=seconds)
```

日時の値を自分で設定すれば任意の日時にすることも可能。ただしこれで設定されるのは、AuthorDateであり、CommitDateの方は現在日時になる。CommitDateも合わせたい場合は、その後でgit rebaseのcommitter-date-is-author-dateオプションを使えば良い。

```
$ GIT_PAGER= git log -1 --pretty=fuller
commit 96fdf18c0d2580dacf6447d2669124684327de63 (HEAD -> master)
Author:     foo <foo@example.com>
AuthorDate: Mon Sep 30 06:14:11 2019 +0900
Commit:     foo <foo@example.com>
CommitDate: Sun Sep 29 10:14:11 2019 +0900

    an example
$ git rebase HEAD~ --committer-date-is-author-date
Current branch master is up to date, rebase forced.
First, rewinding head to replay your work on top of it...
Applying: an example
$ GIT_PAGER= git log -1 --pretty=fuller
commit c7fa00c0231b4a5505bd6fae2460dc8a65d08eb1 (HEAD -> master)
Author:     foo <foo@example.com>
AuthorDate: Mon Sep 30 06:14:11 2019 +0900
Commit:     foo <foo@example.com>
CommitDate: Mon Sep 30 06:14:11 2019 +0900

    an example
```

## 二つ以上前のコミットを対象にするには

`git rebase -i` で対象コミットをeditとして、amend commitの際に上で説明したいずれかの方法を使えば良い。

## 確認した環境

```
$ git --version
git version 2.19.1
$ date --version
date (GNU coreutils) 8.29
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie.
```
AWS Batchについて調べてみた。

ECSでバッチ処理を作成したことがあります。
そこで、”AWS Batch”が気になったため、調べてみました。
今頃。。。

#ブラックベルトより
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/

AWS Batch
①フルマネージドのバッチ処理実行システム（ECSを使用している）
②ジョブとして登録したアプリケーションやコンテナイメージをスケジューラから実行

##1.システム管理者が使用するジョブ管理システム
夜間バッチのような、予めジョブの起動や順序を定義し、ジョブの実行・管理するシステム
##2.システム利用者が使用するジョブ管理システム
ユーザが任意に投入したジョブをキューイングして、リソース状況に合わせて効率よく実行するシステム

★AWS Batchは、"2."らしい。大規模なスケール、ジョブの依存定義が可能なマネージド並列分散処理基盤。
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-aws-batch/10

#一番の疑問

###スケジュール起動型のバッチ処理にAWS Batchは向いているのか？

Ans.
肝心のスケジュール起動は出来なく、あくまでもジョブキュー系の処理をするためのもの
大規模データのバッチ処理みたいな使い方を想定されたサービスで、cron代わりといった用途には向かないとの事。

であれば、やはりスケジュール起動系は、下記かな。

①Amazon ECSのScheduleTask
②Lambda（スケジュール起動）※①より制約多し（メモリ、CPU、言語、処理時間15分）

なので、軽微なバッチ処理しか作らないのであれば、管理も簡単なLambdaもありかと思います。
RHEL7 apache httpd proxy設定整理

#参考URL
https://httpd.apache.org/docs/current/mod/mod_ssl.html

#構成
・ネットワーク構成
client ⇒[https]⇒ proxy ⇒[https]⇒ server

・証明書構成
proxy用-CA ①
├ proxy用-サーバ証明書 ②
└ proxy用-秘密鍵 ③

server用-CA ④
├ server用-サーバ証明書 ⑤
└ server用-秘密鍵 ⑥

・ソフトウェア構成
client
└ Windows

proxy
├ RHEL7.5
└ apache 2.4(httpd-2.4.6-80.el7.x86_64)

client
├ RHEL7.5
└ apache 2.4(httpd-2.4.6-80.el7.x86_64)

#設定
抜粋して記載
##Client
proxy用-CA ①をインストール

##Proxy
``` /etc/httpd/conf.d/ssl.conf
ProxyRequests off
SSLProxyEngine on
SSLProxyVerify require #proxy⇒serverのサーバ認証無視させない

ProxyPass / https://server01b.rhel.local/
ProxyPassReverse / https://server01b.rhel.local/

SSLCertificateFile /root/ssl.crt #proxy用-サーバ証明書 ②
SSLCertificateKeyFile /root/ssl.key #proxy用-秘密鍵 ③
SSLProxyCACertificateFile /root/ca.crt #server用-CA ④
```
##Server
``` /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /root/ssl.crt #server用-サーバ証明書 ⑤
SSLCertificateKeyFile /root/ssl.key #server用-秘密鍵 ⑥
```

SSLProxyCACertificateFile を忘れそうだったので、メモ。

#ReverseProxy構成にて、X-Forwarded-Forの値によって接続拒否設定
2.2系での手法

```http.conf
<Location "/">
  SetEnvIf X-Forwarded-For '172.16.0.40' deny_ip
  SetEnvIf X-Forwarded-For '172.16.0.41' deny_ip
  order deny,allow
  deny from env=deny_ip
</Location>
```

2.4系での手法

```http.conf
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 172.0.0.0/8
<Location "/">
    <RequireAll>
    Require all granted
    Require not ip 172.16.0.40
    </RequireAll>
</Location>
```




#ReverseProxy構成、Virtualhostの理解
```http.conf
<VirtualHost Proxy01:443> ※リッスンホスト名:Port番号
  ServerName hogehoge.co.jp:443 ※リクエストURL名:Port番号
  :
  <snip>
  :
</VirtualHost>

<VirtualHost Proxy01:443> ※リッスンホスト名:Port番号
  ServerName usausa.co.jp:443 ※リクエストURL名:Port番号
  :
  <snip>
  :
</VirtualHost>
```
最新の Ruby を Mac にインストールする方法

Ruby のバージョン管理（ 使い分け ）には [rbenv](https://github.com/rbenv/rbenv) を使うのが、定番のようですが、

基本的に、最新のものしか使わないのであれば、[Homebrew](https://brew.sh/) でインストールして、管理してしまうというのもアリなのではないでしょうか？

仮に、特定のバージョンの Ruby 環境が必要になった場合には、[Docker](https://www.docker.com/) を利用するのがオススメです。

https://qiita.com/normalsalt/items/9c10b2e046a5c103f626

Docker さえ使いこなせれば、どんな環境でも必要に応じて使い分けられますからね。

```
% docker run --rm ruby:2.7.8 ruby --version
ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [aarch64-linux]
```

:::note info
ちなみに、M2 MacBook Pro[^1] にプリインストールされていた Ruby のバージョンは、以下の通り。

[^1]: [MacBook Pro (14-inch, 2023)](https://support.apple.com/kb/SP889?locale=ja_JP)・macOS Ventura 13.3.1

```
% ruby --version
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin22]
```

次の PATH にあるようなので、一応、覚えておきましょう。

```
% which ruby
/usr/bin/ruby
```

もしかすると、何らかのエラーを解決するために、デフォルトのものを使うように気を遣わなければならない場合などもあるかもしれません。
:::

というわけで、次の記事で「 最新の Git を Mac にインストール 」した時と同様に、

https://qiita.com/normalsalt/items/f200ba50363ebfd46df0

次のコマンドを実行して、インストールしておけば、

```
% brew install ruby
```

以後、バージョンを上げる際には、次のようなコマンドを実行するだけで、簡単にアップグレードできます。

```
% brew upgrade ruby
```

:::note info
Homebrew のインストールについては、公式サイトを参照してください。

https://brew.sh/

今回、利用した Homebrew のバージョンは、以下の通りです。

```
% brew --version
Homebrew 4.0.16
Homebrew/homebrew-core (git revision 15bc37bb1ce; last commit 2023-02-17)
Homebrew/homebrew-cask (git revision b17568b22a; last commit 2023-02-17)
```

ちなみに、次のコマンドを実行すれば、Homebrew 自体をアップデートできます。

```
% brew update
```
:::

インストールを実行した時の出力にもある通り、次のコマンドを実行するなどして、PATH を通すこともお忘れなく。

```
% echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc
```

これで、ターミナルを再起動するか、新しいウィンドウを開くか、あるいは、次のコマンドを実行するなどして、設定を更新すれば、

```
% source ~/.zshrc
```

新しいバージョンの Ruby が、利用できるようになっているはずです。

```
% ruby --version
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
```

:::note info
インストール時の出力には、以下のような（ コンパイラ向けの ）設定についても書かれていたので、念の為、ここにメモしておきます。

```
For compilers to find ruby you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/ruby/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/ruby/include"
```
:::
rails 条件付きでバリデーションを効かせる

#こういうときはバリデーション効かせないで欲しい
ってときの対応。



通常のバリデーションは以下の感じ

```ruby

class User < ApplicationRecord
    validates :name, presence: true
    validates :email, presence: true, length: {maximum: 255},
                      uniqueness: { case_sensitive: false}
    validates :password, presence: true, confirmation: true
    has_many :questions

```

#<font color="Blue">どういう状況で使う？</font>
例えばSNSログインの場合、twitterでやろうとするとemailの値が取得できない（2019/08/10現在）のでバリデーションが効くとエラーになる。。。
###⇨「SNSログインの際に取得するuidカラムに値が入っていないときは通常のログインとみなしてバリデーションを効かせたい。」時

`if`や`unless`で条件を指定して、目的の項目へ追加する。

```ruby

class User < ApplicationRecord
    validates :name, presence: true
    validates :email, presence: true, length: {maximum: 255},
                      uniqueness: { case_sensitive: false}, unless: :uid?  #email取れないからこんな感じ
    validates :password, length: {minimum: 6}, presence: true, confirmation: true, unless: :uid? #パスワードもSNSログインと別管理ならこんな感じ
    has_many :questions

```

#callbackに対しても指定可能
以下はバリデーション用のヘルパーを定義してそのヘルパーの中で`unless`を使い処理をするかしないかを判定している。

```ruby

class User < ApplicationRecord
    validates :name, presence: true, length: {maximum: 50}
    #以下でヘルパーを呼び出す
    before_save :email_downcase
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :email, presence: true, length: {maximum: 255},
                      format: { with: VALID_EMAIL_REGEX },
                      uniqueness: { case_sensitive: false}, unless: :uid?  #こんな感じ
    validates :password, length: {minimum: 6}, presence: true, confirmation: true, unless: :uid? 
    has_many :questions
    
    #email用にヘルパーを定義
    def email_downcase
        unless uid?
            self.email.downcase!
        end
    end

```

とりあえず、こんなけ。
サーバを公開するにあたっての種類等（オンプレ・クラウド・レンタル）

#サーバー種別
※備忘録やメモとしての記事となります。

サーバエンジニアとして働いていると稼働システムの中にも
様々な種別のサーバ、(またはAWS等のクラウド)がある事を認識します。

仕事をしているうちに用語としては耳に入ってくるものの、
意味を理解していない物も多々あり、調べてみました。

#どこにサーバを設置するか
運用保守の観点から、どこにある、どんなコンピュータにサーバソフトウェアをインストールするかというのは、サーバの拡張性や運用の管理のしやすさに関わる大きな問題です。

今現在様々な形態のコンピュータが存在しますが、どれを使用するにもメリットとデメリットがあります。

①運用形態
・オンプレミス＝自社運用
・クラウド＝クラウドサービス事業者が運用
・レンタルサーバ

②設置場所
・自社設置＝トラブルシューティングしやすい
・データセンタに設置＝場所の制約がない

#どんなサーバを設置するか
物理サーバの種類　ラック型・タワー型・ブレード型

仮想化の導入　　仮想サーバ・物理サーバ

ハードウェアスペック　CPU/メモリ/ストレージ/NIC

OSの種類　Linux/Windows

サービスの提供形態　アプライアンスサーバ(単機能)・汎用型

#メリット・デメリット

■オンプレミス型とクラウド

・オンプレミス型
メリット
思いどおりの構成が組める
既存のシステムと連携しやすい
トラブルの状況が把握しやすい

デメリット
設備を自分たちで調達しなければならない
コストがかかる
実運用まで時間がかかる

・クラウド型
メリット
設備の調達や構築に時間が掛からない
サーバーのスペックを適宜変更できる

デメリット
クラウド事業者が提供する範囲内でしか構成が組めない
トラブル発生時にクラウド事業者に依存しやすく、トラブルシューティングしにくい

■設置場所

・自社
メリット
サーバーに障害が起きた時、素早く対応できる

デメリット
電源設備や空調設備を自前で確保する必要がある

・データセンター
メリット
電源設備・空調設備・耐震設備等
全てが最初から揃っている

デメリット
郊外型の場合トラブルがあってもすぐに対応しにくい

・サーバの仮想化

メリット
物理的なサーバの台数を減らし、設置スペースを削減できる
サーバの電力消費を減らせる
システム管理者が管理しやすい

デメリット
ハードウェア処理をエミュレートしているのでパフォーマンスは劣化する
gitignoreが無視される原因と対策

## 背景

Python勉強中。
学習用コードのバージョン管理にgitを使おうと、Visual Studio Code上のターミナル（PowerShell）にて、
[gitignore.io](https://gitignore.io/)を利用して.gitignoreファイルを作成した。

```powershell:PowerShell
git ignore Python > .gitignore
```

しかし こうかが なかった。
なぜか、キャッシュファイルであるはずの`*.pyc` が平然とステージ待ちしている。
.gitignore ファイルでは除外指定をしているはず。

```shell:.gitignore
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

#以下略
```

おかしい。

### 環境

- Windows 10
- Visual Studio Code 1.38.1
- git 2.13.2.windows.1

## 原因と対策

### すでにgit管理になっている

ググるとよくこれが出てくる。
対象ファイルが既にgit管理対象になっているケース。
キャッシュクリアすることで解決するらしい。

```shell-session
$ git rm -r --cached .
```

しかし、今回は一度もコミットしておらず、そもそも「さあこれから管理しよう」という段階での問題…。

### .gitignoreの文字コードがUTF-16

今回のケースはこれだった。
どうやらPowerShellでリダイレクトして作成したテキストファイルは文字コードが**Unicode（UTF-16LE）**になるらしく、gitが認識してくれなかった模様。
VSCodeで一度開き、UTF-8として保存し直すことで、正しく認識してくれるようになった。

## 参考ページ

[.gitignore 設定が反映されない場合の対応](http://darupo.hateblo.jp/entry/2014/09/10/003326)
最新の Git を Mac にインストールする方法

M2 MacBook Pro[^1] にプリインストールされている [Git](https://git-scm.com/) のバージョンが、微妙に低かったので、

[^1]: [MacBook Pro (14-inch, 2023)](https://support.apple.com/kb/SP889?locale=ja_JP)・macOS Ventura 13.3.1

```
% git version
git version 2.39.2 (Apple Git-143)
```

以前、M1 MacBook Pro[^2] でやったのと同様にして、最新のものをインストールすると共に、

[^2]: [MacBook Pro (13-inch, M1, 2020)](https://support.apple.com/kb/SP824?locale=ja_JP)・macOS Big Sur 11.2.3

一応、本記事もリライトしてみました。

次のコマンドを実行し、[Homebrew](https://brew.sh/) で管理できるようにしておけば、

```
% brew install git
```

以後、バージョンを上げる際には、次のようなコマンドを実行するだけで、簡単にアップグレードできます。

```
% brew upgrade git
```

:::note info
Homebrew のインストールについては、公式サイトを参照してください。

https://brew.sh/

今回、利用した Homebrew のバージョンは、以下の通りです。

```
% brew --version
Homebrew 4.0.16
Homebrew/homebrew-core (git revision 15bc37bb1ce; last commit 2023-02-17)
Homebrew/homebrew-cask (git revision b17568b22a; last commit 2023-02-17)
```

ちなみに、次のコマンドを実行すれば、Homebrew 自体をアップデートできます。

```
% brew update
```
:::

ただし、インストールした直後だと、新しい方の Git は、まだ認識されていないかもしれないので、ターミナルを再起動するか、新しいウィンドウを開くか、

あるいは、次のようなコマンドを実行するなどしてみてください。

```
% exec $SHELL -l
```

これで、改めてバージョンを確認してみれば、ちゃんと新しくなっているはずです。

```
% git version
git version 2.40.1
```

:::note info
ちなみに、PATH が通っていることを確認するため、例えば、次のようなコマンドを実行すると、

```
% echo $PATH
/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin
```

前の方に `/opt/homebrew/bin` が含まれているでしょうか？

もし、自分で PATH を追加しなければならない場合には、例えば、以下のようにして、設定を更新する必要があります。

```
% echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc
% source ~/.zshrc
```

また、現在、どこの PATH にある `git` コマンドを使うようになっているか知りたいなら、次のコマンドを実行してみてください。

```
% which git
/opt/homebrew/bin/git
```
:::
plunkerでvue その36

#概要

plunkerでvueやってみた。
練習問題やってみた。

#練習問題

スネークゲームを設置して

#参考したページ

https://qiita.com/miyauchoi/items/f753e5fa0209ab2034dd

#成果物

http://embed.plnkr.co/fcOo3VltiOqsexYdrBFF/

以上。
mkdir コマンドのよく使うオプションまとめ

CentOS 7 で確認。mkdir のバージョンは GNU coreutils 8.22。

### 親ディレクトリも一緒に作成
```
-p
```

ディレクトリがすでに存在する場合は何もしない。

### 作成するディレクトリのモードを指定
```
-m <モード>
```

モードの指定方法は `chmod` と同じ。

### 作成するディレクトリの SELinux コンテキストをデフォルトにする
```
-Z
```

### 作成したディレクトリを表示
```
-v
```
Mac に Docker をインストールする最も？簡単な方法

公式ドキュメントを見てみると、Mac[^1] に [Docker Desktop](https://www.docker.com/products/docker-desktop/) をインストールする方法についても、色々と書いてありますが、

[^1]: ちなみに、今回の動作環境は「 [MacBook Pro (14-inch, 2023)](https://support.apple.com/kb/SP889?locale=ja_JP)・macOS Ventura 13.3.1 」です。

[https://docs.docker.com/desktop/install/mac-install/](https://docs.docker.com/desktop/install/mac-install/)

やはり、[Homebrew Cask](https://formulae.brew.sh/cask/) を利用するのが、とりあえずは、楽で良いと思います。

アプリをインストールする際、ディスクイメージファイル（ dmg ）や、パッケージファイル（ pkg ）を、わざわざ Web サイトからダウンロードしてくるのは、

これを機に、卒業してしまうというのはどうでしょうか？

インストールの方法は、非常に簡単で、次のコマンドを実行するだけです。

```
% brew install --cask docker
```

:::note info
Homebrew のインストールについては、公式サイトを参照してください。

https://brew.sh/

今回、利用した Homebrew のバージョンは、以下の通りです。

```
% brew --version
Homebrew 4.0.16
Homebrew/homebrew-core (git revision 15bc37bb1ce; last commit 2023-02-17)
Homebrew/homebrew-cask (git revision b17568b22a; last commit 2023-02-17)
```

ちなみに、次のコマンドを実行すれば、Homebrew 自体をアップデートできます。

```
% brew update
```
:::

無事、インストールが完了したら、アプリを起動してください。

何やら初期設定が選択できるようだったので、以下のように選んでみました。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109175/da4fdf09-2b6f-160b-850a-35cea55c8b51.png">
この設定なら、`/usr/local/bin` に CLI がインストールされるとのことなので、PATH を追加しなくても、すぐに使えるはずです。

次のようなコマンドを実行すれば、バージョンが確認できます。

```
% docker --version
Docker version 23.0.5, build bc4487a
```

もちろん、[Docker Compose](https://docs.docker.com/compose/) も、ちゃんと利用可能になっているようですね。

```
% docker compose version
Docker Compose version v2.17.3
```

:::note info
ちなみに、Homebrew Cask でインストールした「 アプリ自体のバージョン 」は、次のようなコマンドで確認することができます。

```
% brew list --cask --versions docker
docker 4.19.0,106363
```
:::

そして、最低限、リソース（ 使用するメモリやディスクなど ）の割り当て設定は、確認・調整しておきましょう。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109175/09b87f74-f964-bd3e-12b1-f53bc05a7ed5.png">
また、VirtioFS[^2] を有効化すれば、ホストと Docker VM 間のファイル同期（ バインドマウント ）のパフォーマンスが向上するらしいので、気になったら調べてみることをお勧めしておきます。

[^2]: macOS 12.5 以降で利用可能とのこと。
.NETCore3.0がリリースされたのでVisualStudio2019からBlazorを作成してAzureにアップしてみる

# はじめに
[.NET Core 3.0](https://docs.microsoft.com/ja-jp/dotnet/core/whats-new/dotnet-core-3-0)がリリースされたので、プレビュー版ではない[Visual Studio 2019](https://docs.microsoft.com/ja-jp/visualstudio/releases/2019/release-notes)から[Blazor](https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-3.0)を[Azure](https://azure.microsoft.com/ja-jp/)にアップできるか試してみた。

# 環境

1. Visual Studio 2019 Community Version 16.3.0
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/61e9070b-799f-4ac1-5a74-184faa360774.png)

ちなみに、Azure側はまだ[.NET Core 3.0](https://docs.microsoft.com/ja-jp/dotnet/core/whats-new/dotnet-core-3-0)をサポートしていない模様。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/d196323c-91b5-b6f2-cf83-71f7a2c109c7.png)

# Blazorで試すテンプレートについて
今回は**Blazorサーバーアプリ**と**Blazor WebAssembly App**を試す。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/9671d7b1-5261-fb50-e6e4-61cceb6024c3.png)

# Azure側の環境
**Blazorサーバーアプリ**と**Blazor WebAssembly App**ともにリソースグループは新規作成で作り、ホスティングプランは日本に変更して作成する。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/54eabe86-2492-e3ee-8053-3636f2419f04.png)
この辺りは任意で。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/a080a425-c3de-4d49-e82e-f06a61005759.png)

# Blazorサーバーアプリ編
新規作成でBlazorサーバーアプリを選択し、何もせずそのまま発行まで進むと、警告が出て、無理矢理デプロイするとエラーになってしまった。

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/fd7bd854-4af1-1782-1e8f-d1f2ab30672e.png)

## 回避策
今まで同様、配置モードを自己完結にすれば動作するようだ。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/702ef6b1-67aa-ce84-532f-f22dcd65a715.png)

実際に動いた画面
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/c29de7be-0adb-bcde-ee79-44dc2b1a2448.png)

# Blazor WebAssembly App編
特にエラーなくアップできたが、こちらはターゲットフレームワークがnetstandard2.0になっている（前から）

![99.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/edba7874-0727-c044-de3a-9fd2dc6f67ab.png)


これでプレビュー版が削除できる！
[Ruby]Google News RSSからニュースを取得してJSONで返す

# はじめに

趣味で作っているWebアプリケーションでニュースAPIを叩きたくて調べてみました。
日本語のニュースを取得できるAPIは、[newsAPI(日本語版)](https://newsapi.org/s/japan-news-api)などがありますが、取得方法`everything`に対応しておらず、`top-headlines`だと20件のみしかとってきてくれないようです。

取得方法`everything`はエラーになります。

```terminal
$ curl 'https://newsapi.org/v2/everything?country=jp&apiKey={YOUR_API_KEY}'
{"status":"error","code":"parameterInvalid","message":"The country param is not currently supported on the /everything endpoint."}
```

一方、`top-headlines`は取れますが、20件までしか取得できないです。

```terminal
$ curl 'https://newsapi.org/v2/top-headlines?country=jp&apiKey={YOUR_API_KEY}' 
{"status":"ok","totalResults":30,"articles":[{"source":{"id":"engadget","name":"Engadget"},"author":"Ittousai","title":"速報：マイクラアースは10月配信開始、アーリーアクセスの事前登録を受付 #MinecraftEarth - Engadget 日本版","description":"マイクロソフトが基本無料のスマホAR版マインクラフト Minecraft Earthの...(略)
```

なので、category指定とかもできますが、どのカテゴリも2, 3件しかない状態なので、使いづらいなと思っていました。

大量のニュースを取得できて、かつカテゴリ指定や検索ができるAPIがないかなと思っていたのですが、なさそうなので、タイトルの通りGoogle News RSSからとってきてJSONで返すAPIを自作すればいいのかなと思いました。

# コード

試しで書いてみたら取得することができました。
クエリストリングでカテゴリや検索ワードを指定できるみたいです。
ここでは一旦カテゴリだけ指定してみます。

```news_to_json.rb
# frozen_string_literal: true

require 'rss'
require 'active_support'
require 'active_support/core_ext'

category = ARGV[0]
base_url = 'https://news.google.com/rss/search'
query_string = "?hl=ja&q=#{category}&hl=ja&gl=JP&ceid=JP:ja"

rss = RSS::Parser.parse(base_url + query_string)
news_hash = Hash.from_xml(rss.to_xml)
news_json = news_hash.to_json

puts news_json

```

```command
$ ruby news_to_json.rb health

{"rss":{"version":"2.0","xmlns:content":"http://purl.org/rss/1.0/modules/content/","xmlns:dc":"http://purl.org/dc/elements/1.1/","xmlns:itunes":"http://www.itunes.com/dtds/podcast-1.0.dtd","xmlns:trackback":"http://madskills.com/public/xml/rss/mod...(略)
```

# おわりに

こんな感じのAPI自作して、フロントエンドで呼び出せばWebで便利に使えるのかなと思いました。
ただ、Google News RSSはニュースの画像を返してくれないので、画像が欲しい場合はスクレイピングして、OGP画像のリンクを取得する。OGPがなければフロントエンドでデフォルトの画像を表示する、といった実装が必要そうです。

スクレイピングは、[【rails】urlからサイトの情報を引き出す。【スクレイピング】](https://qiita.com/koji-ro/items/4886dda6d287c7f2dc1b)を参考に、`<meta property="og:image">` をとってくればできそうです。
【Rails】 controller内で共通の処理をメソッド化してbefore_actionで呼び出す

# 環境
rails 5.2.3
ruby 2.5.1

# 概要
コントローラー内で共通の処理を書いていたら、メンターにメソッド化しましょうと言われたので、脱・初心者を目指し、備忘録。

# メンターレビュー前

```hogehoge_controller.rb
class hogehogeController < ApplicationController

  def new
    @user = User.find(params[:user_id])
    @evaluation_all = Evaluation.group(:seller_id).size[@user.id]
    @evaluation = Evaluation.new
  end


  def create
    @user = User.find(params[:user_id])
    @evaluation = Evaluation.new(evaluation_params)
    if @evaluation.save
      redirect_to introduction_user_path(@user.id), notice: "評価が送信されました"
    else
      redirect_to introduction_user_path, notice: "評価が正常に送信できませんでした。もう一度行ってください。"
    end
  end

  private

  def user_params
    params.require(:user)
  end

  def evaluation_params
    params.require(:evaluation).permit(:rating, :comment).merge(buyer_id: current_user.id, seller_id: @user.id)
  end
end
```
指摘されたのはこの部分。

```
@user = User.find(params[:user_id])
```
同じ記述が２回出てきていますね。
この@userの処理は共通のものなので、分けましょう、と言われたわけです。

またこの処理は外部から呼び込まれる必要はないので、private以下に追記します。

```
private
  def set_user
    @user = User.find(params[:user_id])
  end
```
こうすることで、呼び出しがクラス内部に限定されるんですね。

privateについてはこちらの記事が勉強になりました。ありがとうございます。
[Ruby の private と protected 。歴史と使い分け](https://qiita.com/tbpgr/items/6f1c0c7b77218f74c63e)

さて、あとは各メソッドが実行される時に呼び出されると善きですね。

そんな時は　**before_action**を使います。

```
class EvaluationsController < ApplicationController

  before_action :set_user, only: [:new, :create]

  def new
    hogehoge...
```

before_action [メソッド名],[おぷしょん]

onlyは、どのメソッドが呼ばれた時にbefore_actionを実行するのかを示し、
expect は、指定したメソッドが呼ばれた時は実行しません。


今回は、newとcreateの実行前にやってほしい処理ですからこうします。

```
 before_action :set_user, only: [:new, :create]
```


# メンターレビュー後

...というわけで直したのがこちら

```hogehoge_controller.rb
class EvaluationsController < ApplicationController

  before_action :set_user, only: [:new, :create]

  def new
    @evaluation_all = Evaluation.group(:seller_id).size[@user.id]
    @evaluation = Evaluation.new
  end


  def create
    @evaluation = Evaluation.new(evaluation_params)
    if @evaluation.save
      redirect_to introduction_user_path(@user.id), notice: "評価が送信されました"
    else
      redirect_to introduction_user_path, notice: "評価が正常に送信できませんでした。もう一度行ってください。"
    end
  end

  private

  def set_user
    @user = User.find(params[:user_id])
  end

  def user_params
    params.require(:user)
  end

  def evaluation_params
    params.require(:evaluation).permit(:rating, :comment).merge(buyer_id: current_user.id, seller_id: @user.id)
  end
end
```
【Unity】私流 はじめてのゲーム開発の流れ

# 動機
「Unity 入門」等で調べるとブロック崩しやシューティングゲームの作り方やサンプルプロジェクトがあります。ただプログラミング初心者がサンプルプロジェクトを見ても、**実際にどうやってここまで作るのか想像がつかない**と思います(私はそうでした)。
そこでプログラミング初心者の方に向けて、**Unityでのゲーム開発の流れがなんとなくわかる記事**を書こうと思いました (本記事では作り方・使い方について書きませんので**必要に応じて調べてください**)。
なお、本記事は面クリア方式のゲームを想定して書いています。

また記事の下部に「よく使われる言葉の説明」と「ウィンドウの説明」を記載しました。

# はじめてのゲーム開発の流れ

1. 各種フォルダ作成
2. シーン作成
3. プレイヤーを作る
4. ステージを少しだけ作る
5. 敵を数体作る
6. ステージと敵をプレハブにして、ステージを長くしていく
7. 新しいステージを作りたいなら新しいシーンを作って 2 に戻る
8. 十分にステージができたら、メニュー画面を作ってシーン遷移を行う
9. タイトル画面を作る
10. オプション画面を作る

## 1. 各種フォルダ作成
下図は私が軽く作ったものですが「unity フォルダ構成」で検索して調べた方が理解が深まります。
![フォルダ構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/f970ae26-3507-4ba2-e24d-50bd71eac1a6.png)

## 3. プレイヤーを作る

2. プレイヤーとなる Playerオブジェクト をシーンに生成・配置
3. Playerオブジェクト をプレハブ化
4. Player.cs(Playerコンポーネント)をScriptsフォルダ内に作成
5. Playerオブジェクトのプレハブ にPlayerコンポーネントを追加
6. 「Unity プレイヤー」等で検索して出てきたプログラムをPlayer.csの中に書いて動してみる

## 4~7. ステージ制作の流れ

1. シーン作成
2. Playerオブジェクトのプレハブ を配置
3. 壁や敵などのプレハブ作成
4. コンポーネントを (作って) プレハブに追加
5. プレハブ配置

**その後**
プレハブにもっとコンポーネントを追加するなら4に戻る
そのプレハブの配置が済んだら3に戻る
シーンが完成したら1に戻る

# よく使われる言葉の説明

**Scene (シーン)**
沢山のオブジェクトの配置情報を保存するファイルです。
<details>
UIやプレイヤーをマネージャーシーンに配置して、ステージシーンを加算する形を取れば、ステージクリア型のゲームを楽に作れます。
</details>
**GameObject (ゲームオブジェクト)**
シーン上に配置するモノです。機能を追加できます。

**Component (コンポーネント)**
オブジェクトに追加する機能を指します。
<details>
カメラやライト、物体の描画や音声、物理演算や当たり判定など、標準で用意されているコンポーネントは沢山あります。
実際のゲーム開発では、プレイヤーや敵の動きなどの用意されていないコンポーネントはプログラムを書いて作ることになります。
(Transform コンポーネントはオブジェクトに最低限必要なコンポーネントで、オブジェクトの位置・回転・拡縮情報を記録しています)
</details>
**Prefab (プレハブ)**
シーン上のオブジェクトを設計図化したものです。

**Instance(インスタンス)**
プレハブを元に生成したオブジェクトを指します。
<details>
プレハブをヒエラルキー上に配置すると「オブジェクト名 (Clone)」という名前のインスタンスが生成されます。
実際のゲーム開発では、床や壁, 敵や弾, 落ちているアイテムやエフェクトなど、あらゆるオブジェクトをプレハブにして、シーン上にインスタンスとして配置することでステージを作っていきます。
プレハブ本体に変更を加えると全てのインスタンスに反映されるので、仕様変更が楽になります。
</details>

# ウィンドウの説明
ウィンドウは自分の使いやすいように配置しましょう。主に使うウィンドウを左から説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/59fbc02a-b3c0-c792-e804-2080b4f478b7.png)

**シーン**
開いているシーンファイルを見たり編集したりできます。画像左上の各アイコンを押すと操作モードが変わります。
**ヒエラルキー**
シーン上に配置されているオブジェクトが一覧になっています。
**プロジェクト**
プロジェクトのフォルダ構成を見たり編集したりできます。
**インスペクタ**
ヒエラルキー上でオブジェクトをクリックすると、オブジェクトのコンポーネントが見られます。コンポーネントは編集できます。

# アドバイス
Unityではじめてゲーム開発するなら**小規模な3Dゲーム**がおすすめです。3D向けの方が情報量が多く(私感)、また3Dにある機能も2Dでは存在しない場合があります。2Dゲームを作りたい場合も簡単な3Dゲームを一度作ってUnityの仕様を把握してから挑むと良いでしょう。
[SwiftUI]型消去を利用した任意のViewをPresent(sheet)する手法

SwiftUIでは、モーダル表示をするために`sheet`というメソッドを利用します。

```swift
struct ContentView: View {

    @State var isPresented: Bool = false

    var body: some View {
        VStack {
            Button("present") {
                self.isPresented.toggle()
            }
        }
        .sheet(isPresented: $isPresented) {
            Text("Presenting")
        }
    }
}
```

しかし、この`sheet`メソッドは後勝ちで実装を保持するため複数回呼ぶと最後のsheetだけが有効になります。

この挙動を回避するには`sheet(item:content:)`を利用します。
これは`Binding<Identifiable>`を受け取り、それをもとにViewを返す方法です。

この挙動に関する解説は

[@1amageek SwiftUIのsheetを出し分ける](https://qiita.com/1amageek/items/e90e1cfb0ad497e8b27a)

をお読みください。

上記記事では、`Identifiable`と`View`の性質をenumに持たせ
`.sheet(item: self.$presentation) { $0 }`
のように遷移させています。こうすることで、親Viewは複数の要素を管理する必要もなくなり、分岐のロジックをもつ必要もなくなります。

しかし、この手法はViewが遷移先がどこで管理されているかを知る必要があり、また遷移先は`presentation`で宣言された型に限定されます。

`Identifiable`と`View`の性質を持たせつつ、より柔軟に遷移先を制御する方法を考えてみました。


実装は、次のように型消去を用いて具体的な型を作ります。

```swift
struct AnyIdentifiableView: View, Identifiable {
    typealias ID = AnyHashable
    private let _id: ID
    var id: ID {
        return _id
    }
    
    private let _body: AnyView
    var body: some View {
        _body
    }
    
    init?<V>(view: V?) where V: View & Identifiable {
        guard let view = view else { return nil }
        self._body = AnyView(view)
        self._id = view.id
    }
}
extension Identifiable where Self: Hashable {
    public typealias ID = Self
    public var id: Self { self }
}
```

`AnyIdentifiableView`は、`Identifiable`と`View`の性質を持つ構造体です。
実態は`init?<V>(view: V?) where V: View & Identifiable`で受け取ったViewになります。
`Identifiable`と`View`はそれぞれ`AnyHashable`と`AnyView`に分解されて保持されました。
`Identifiable`はHashableに準拠した型に限り、protocol extensionによってidを自動的に実装します。
これで、`View & Identifiable`を自由に入れる事ができる型が出来ました。

そして、`AnyIdentifiableView`は具体的な型なので、特に複雑なことをせずに`@State`で宣言できます。


```swift
struct ContentView: View {

    @State var presentation: AnyIdentifiableView? = nil

    var body: some View {
        VStack {
            Button("present") {
                self.isPresented.toggle()
            }
        }
        .sheet(item: self.$presentation) { $0 }
    }
}
```

ViewModelが複数ある場合でも、`View, Hashable, Identifiable`に準拠した型を渡せば柔軟に遷移する事が出来るようになりました。

```swift
viewModel1.$presentation.map({ AnyIdentifiableView(view: $0) }).assign(to: \.presentation, on: self)
viewModel2.$presentation.map({ AnyIdentifiableView(view: $0) }).assign(to: \.presentation, on: self)
```
Pythonの平方根どれが早いか

## はじめに
Pythonの平方根でどの方法が早いかを試しました。
計測方法が間違っていない場合、mathが一番早いです。
みんな兢プロでは、`math.sqrt(n)`を使おうな!
でもタイプ数や速度的に、`n ** 0.5`でもいいと思ってます。

**追記: 環境によって速度の差異があるので、話半分に聞いてください。**

## 環境
* Google Colaboratory
* Python 3.6.8

## 試した方法
* n ** 0.5
* pow(n, 0.5)
* math.sqrt(n)
* numpy.sqrt(n)
* sympy.sqrt(n)
* scipy.sqrt(n)

```py

import math
import numpy as np
import sympy
import scipy

n = 12345678910
```

```py

%timeit -r 3 -n 1000 n ** 0.5
# 1000 loops, best of 3: 136 ns per loop
%timeit -r 3 -n 1000 pow(n, 0.5)
# 1000 loops, best of 3: 183 ns per loop
%timeit -r 3 -n 1000 math.sqrt(n)
# 1000 loops, best of 3: 70.7 ns per loop
%timeit -r 3 -n 1000 np.sqrt(n)
# 1000 loops, best of 3: 930 ns per loop
%timeit -r 3 -n 1000 sympy.sqrt(n)
# 1000 loops, best of 3: 1.27 µs per loop
%timeit -r 3 -n 1000 int(scipy.sqrt(n))
# 1000 loops, best of 3: 7.7 µs per loop
```

## テストコード
[gist: sqrt.ipynb](https://gist.github.com/ikura1/db74a868b5ba0c57870bfd64fed93af0#file-sqrt-ipynb)
EC2でunicorn接続した際に`ArgumentError: Already running on PID〜`エラーになった時の対処法

##はじめに
EC2で次のようにunicorn接続を行った際に起こり、接続できなかったので、そのエラー理由と対処法を備忘録として残しておきます。

```
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ bundle exec unicorn_rails -E development -c config/unicorn/development.rb -D
master failed to start, check stderr log for details
```

##このエラーは何か？？
`check stderr log for details`（詳細はstderrlogを確認するように）とあるので調べてみると以下のような結果が出ました。ここで注目するのが`Already running on PID:17739`となります。unicornは接続する度にプロセスIDが割り当てられます。そのため、このエラーは以前に行ったunicorn接続のプロセスが残っており、それが実行中のため再度接続できません、という意味です。

```
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ sudo vi log/unicorn.stderr.log
bundler: failed to load command: unicorn_rails (/var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/bin/unicorn_rails)
ArgumentError: Already running on PID:17739 (or pid=/var/www/twitter_clone_2019/shared/tmp/pids/unicorn.pid is stale)
  /var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:207:in `pid='
  /var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:139:in `start'
  /var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn_rails:209:in `<top (required)>'
  /var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/bin/unicorn_rails:23:in `load'
  /var/www/twitter_clone_2019/vendor/bundle/ruby/2.6.0/bin/unicorn_rails:23:in `<top (required)>'
```

##エラー対処法
unicornを再起動させたり、停止させたい場合は、動作中のプロセスに対して`kill`というシグナルを送信することででプロセスを停止させることができます。`ec2-user 17978`等がプロセスになります。これらの動作中のプロセスを停止させた後、grepと書かれているプロセスのみ残っていればOKです。これで、unicorn接続を改めて行うことが可能となります。

```
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ ps aux | grep unicorn  #プロセスの確認
ec2-user 17978  5.4  7.3 776516 74064 ?        Sl   14:14   0:00 unicorn_rails master -E development -c config/unicorn/development.rb -D
ec2-user 17985  0.0  6.6 776516 66500 ?        Sl   14:14   0:00 unicorn_rails worker[0] -E development -c config/unicorn/development.rb -D
ec2-user 17986  0.0  6.6 776516 66500 ?        Sl   14:14   0:00 unicorn_rails worker[1] -E development -c config/unicorn/development.rb -D
ec2-user 18020  0.0  0.0 119484   896 pts/1    S+   14:14   0:00 grep --color=auto unicorn
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ kill 17978  #プロセスの停止
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ ps aux | grep unicorn　#再度プロセスの確認
ec2-user 18023  0.0  0.0 119484   936 pts/1    S+   14:16   0:00 grep --color=auto unicorn　
```
上記の方法だと、毎回停止させるプロセス番号の確認が必要となりますが、以下の方法だと確認作業を省略することができます。`-3`は中止シグナルとなっており、バッククオート内で実行されているプロセスを停止させることができるコマンドです。

```
[ec2-user@ip-10-0-0-133 twitter_clone_2019]$ kill -3 `cat shared/tmp/pids/unicorn.pid`  #unicorn.pidがあるpathをバッククオートで囲む
```


##参考資料
https://wa3.i-3-i.info/word11040.html
https://qiita.com/Coconew5/items/2f4ba976e58da9c1ec22
https://www.k-tanaka.net/unix/kill.php
セレクタ 属性値指定

#セレクタの属性値指定

|       書式       |       説明      |
|:-----------------|:------------------:|
| E[attr]          | 一つの属性名を指定する |
| E[attr="value"]  | 完全に一致する属性値を指定する |
| E[attr^="value"] | 先頭が完全に一致する属性値を指定する |
| E[attr$="value"] | 最後尾が一致する属性値を指定する |
| E[attr*="value"] | 部分的に一致する属性値を指定する |
| E[attr~="value"] | 属性値を空白記号で区切り、単語のうち一つと完全一致する値を指定する |
React PWAやってみた

# 完全に参考にしてます
https://qiita.com/YIPG/items/47f9d025a32effdadcad

# react-create-appでプロジェクトを作る
まずはプロジェクトを作る

```
npx create-react-app test
cd test
npm start
```

create-react-appを利用するだけで実はPWA対応ができている。。。

# オフライン対応
src/index.jsをちょいと修正する

```js
serviceWorker.unregister();
// ↓
serviceWorker.register();
```

# アイコンの設定
してもしなくてもいいが、アプリっぽくするために試しにやってみる。

ここの紹介されているサイトを利用して、一気にアイコンを作る。
参考：https://qiita.com/shisama/items/d4d0b24980beaea57231

そして、出来上がったmanifest.jsonのiconsの部分を書き換える。

がしかし、iosのsafariではうまく表示されないため、
google様が提供し始めたこれを使うと、うまいこと大体のブラウザのフォーム画面追加で、
アイコンが表示される。
参考：https://github.com/GoogleChromeLabs/pwacompat

```html
<link rel="manifest" href="manifest.json" />
<script async src="https://cdn.jsdelivr.net/npm/pwacompat@2.0.9/pwacompat.min.js"
    integrity="sha384-VcI6S+HIsE80FVM1jgbd6WDFhzKYA0PecD/LcIyMQpT4fMJdijBh0I7Iblaacawc"
    crossorigin="anonymous"></script>
```

# スプラッシュ
気分が乗ってきたのでスプラッシュもやってみる。
と思ったが、google様のスクリプトのおかげで、うまいことlinkを差し込まずともよしなに対応してくれていた！
神や。。。

# manifest.json
結果こんな感じでいけてます。

```json
{
  "nape": "hellow! ribery!",
  "short_name": "!!ribery!!",
  "start_url": ".",
  "icons": [
    {
      "src": "images/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "display": "standalone",
  "theme_color": "#4682b4",
  "background_color": "#ffffff"
}
```

# まとめ
今後、webアプリを作るにあたって、アプリの工数を削減できる手段の一つになるかもしれない！
cronバックアップ

# 本番でcrontabが消えた
 crontab -e と crontab -rは隣のキーだからね・・・

## バックアップをとろう
### そもそも実体はどこにあるのか
```
/var/spool/cron/xxx
```
### cronでバックアップ
```
#####################################
# cron バックアップ
#####################################
0 4 * * 1 cp -apr /var/spool/cron/xxxx /cron_bkup/
```

## 復旧
バックアップディレクトリにある"root"をテキストで開けばフルバックアップされています
/var/spool/cron/rootを入れ替えても同じ。

## 備忘録
git管理＋ファイルdeployも考えたけどてっとりばやかったのでコレでいいや。
Sequelizeのwhere句でbetweenを使う方法

#環境
Node,js + Express + MariaDB
Sequelize V5
#若干ハマった
Sequelizeにおいて、オペレータの使用方法は、バージョンによって差異があるようです。
前は、($文字列)のエイリアスを設定することで、オペレータを使用していましたが
V5では非推奨となっていて
現在はSequelize.Opから提供されるSymbolオペレータを使用することが推奨されているようです。



```
const Sequelize = require("sequelize")
const Op = Sequelize.Op
router.get("/user",(req,res,next)=>
  {
    models.user.findAll(
    {
      where:{birth:{[Op.between]:["2019-09-09","2019-09-10"]}}
    })
  }
)
```
#悲しみ
適当に検索してたら、文字列オペレータを使った方法がかなり出てきて戸惑いました。
リファレンス最強ですね。

Sequelizeリファレンス : https://sequelize.org/master/manual/querying.html