OmniAICreator/Qiita-1.07M huggingface dataset:
rbenvをホームディレクトリ以外にインストール

# 概要

Linuxの場合、rbenvはGithubの[README](https://github.com/rbenv/rbenv/blob/master/README.md)含めてホームディレクトリにインストールすることを前提に手順が記載されていることが多いです。
個人的にホームディレクトリ以外にインストールして利用しようと思ったのですが、その際に少し工夫が必要だったため、その方法を記載しています。

# 環境

* Amazon Linux 2
* kernel 4.14.72-73.55.amzn2.x86_64
* bash 4.2.46
* git 2.14.5
* rbenv 1.1.2

# rbenvインストール

今回は例として`/opt`配下にインストールする方向で進めていきます。

```bash
# git clone https://github.com/rbenv/rbenv.git /opt/rbenv
```

ログイン時にPATHの読み込みと`rbenv`のセットアップを行うように設定を行います。

ログインユーザ全体に反映させたい場合は`/etc/profile`に記載します。
ただし、直接同ファイルを修正するよりも、`/etc/profile.d`配下に`*.sh`ファイルを作成するほうが好ましいため、今回は`/etc/profile.d/rbenv.sh`を新規作成して記載する方針とします。

その際に、環境変数`RBENV_ROOT`に**今回インストールしたrbenvのパスを定義**してあげます。

```bash
# cat << EOF > /etc/profile.d/rbenv.sh
export RBENV_ROOT=/opt/rbenv
export PATH="\$RBENV_ROOT/bin:\$PATH"
eval "\$(rbenv init -)"
EOF
```

シェルを再起動して上記設定を読み込ませます。
rbenvのバージョンが表示されれば完了です。

```bash
# exec $SHELL -l
# rbenv -v
rbenv 1.1.2-2-g4e92322
```

次にrubyインストールのために`ruby-build`を`rbenv`のプラグインとしてインストールします。

```bash

# mkdir -p "$(rbenv root)"/plugins
# git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```

ここまでくれば、あとはいつも通りにrubyをインストールすればOKです。
※rubyインストール前に必要なコンパイラなどもインストールしておきます。

```bash
# yum -y install bzip2 gcc openssl-devel readline-devel zlib-devel
# rbenv install -l
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
  1.8.6
（中略）
# rbenv install 2.6.3
```

`rbenv local <ruby version>`を実行すれば各々のディレクトリでRubyのバージョンを切り替えることができます。

```bash
$ pwd
/home/<user>
$ rbenv local 2.6.3
$ rbenv version
2.6.3 (set by /home/<user>/.ruby-version)
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
$ 
```

# 補足

`rbenv`コマンドは環境変数`RBENV_ROOT`を明示的に指定していないと現在ログインしているユーザのホームディレクトリ配下を`rbenv`のrootディレクトリと定義するようです。
https://github.com/rbenv/rbenv/blob/master/libexec/rbenv

```bash:rbenv（抜粋）
if [ -z "${RBENV_ROOT}" ]; then
  RBENV_ROOT="${HOME}/.rbenv"
else
  RBENV_ROOT="${RBENV_ROOT%/}"
fi
export RBENV_ROOT
```

# 参考

* https://github.com/rbenv/rbenv
* https://github.com/rbenv/ruby-build
RaspberryPi3 でPHPが使えなくなってしまったのでメモ

なぜかラズベリーパイでPHPが急に使えなくなってしまったのでメモ。

# 症状
PHPで構築したページを開いてもソースコードがテキストになって出てきてしまった。
# 環境
* RaspberryPi3
* Apache
* PHP7

# 解決法
ネットで調べたところ同じ症状が出ている人は数人いたが解決法を試してもうまく解決しなかった。
ってことでもし解決しなーいっていう人がいるかもしれないからメモ

```shell
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo a2enmod php7.0
```
この3つを実行したあとapacheを再起動!
きっとPHPが動くようになってるはず....
# 参考
https://twitter.com/jun50_scratch/status/1116940314231492608
※参考ってよりこれをQiitaに書いただけ(本人了承済み)
宛先と文面のリスト（CSV）からメールを自動送信


個々の宛先のメアドと宛先毎の文面を格納したリストを使ってメールを自動送信するプログラムを作りました．
動機は，講義の際にGoogle formを使って収集した質問やコメントに対して，一人ひとりに返答してあげたいなと思ったので．

質問を収集する際にメアドと名前を入力してもらってるので，それをGoogle formからCSVで落として，表計算ソフト上で返答を作成．
以下のようなCSVファイルにしました．

なお，名前については，あらかじめ苗字と下の名前を表計算ソフトで切り分けてます．

|メアド(row[0])|  名前(row[1])  | 質問文(row[2]) | 返答文(row[3]) |
|:-----:|:-------:|:-------:|:-----------:|
| address1 | name1 | comment1 | response1 |
| address2 | name2 | question2 | response2 |
| ・・・|・・・|・・・|・・・|

このCSVファイルを一行ずつ読み込んで，メールを作ってgmailで送信していきます．

パスワードやメアドをべた書きするプログラムなので，セキュリティ的には最悪ですが
まあ，個人的に利用する分にはよいのではと思います．

```python:SendMailbyCSV.py
import smtplib
import csv
from email.mime.text import MIMEText
from email.utils import formatdate

FROM_ADDRESS = '***********@gmail.com' #ここにメアド
MY_PASSWORD = '************' #ここにパスワード   


def create_message(from_addr, to_CC, to_addr, subject, body):
	msg = MIMEText(body)
	msg['Subject'] = subject
	msg['From'] = from_addr
	msg['CC'] = to_CC
	msg['To'] = to_addr
	msg['Date'] = formatdate()
	return msg


def send(from_addr, to_addrs, msg):
	smtpobj = smtplib.SMTP('smtp.gmail.com', 587)
	smtpobj.ehlo()
	smtpobj.starttls()
	smtpobj.ehlo()
	smtpobj.login(FROM_ADDRESS, MY_PASSWORD)
	smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
	smtpobj.close()


if __name__ == '__main__':
	csv_file = open("./response.csv","r", encoding="ms932", errors="", newline="" )
	f = csv.reader(csv_file, delimiter=",", doublequote=True, lineterminator="\r\n", quotechar='"', skipinitialspace=True)
	header = next(f)
    
	for row in f:
		to_addr = row[0]   # メアド
		subject = '〇月〇日の講義での質問・コメントへの返答'
		body    =  row[1] + "さん\n"\
                   "\n"\
                   "\n"\
                   "こんにちは、経済学部の藤野です。\n"\
                   "\n"\
                   "〇月〇日の講義では質問・コメントの入力ありがとうございます．\n"\
                   "入力された質問・コメントについて、以下の通りに返答しますね。\n"\
                   "\n"\
                   "＜入力内容＞\n"\
                   + row[2] +"\n"\
                   "\n"\
                   "＜返答＞\n"\
                   + row[3] + "\n"\
                   "\n"\
                   "拝\n"\
		msg = create_message(FROM_ADDRESS, "******＠******", to_addr, subject, body) #2つ目の引数で大学の公式アドレスをCCに入れておく．
		print(body) #確認のため，メール送信内容を画面表示させる．
		send(FROM_ADDRESS, to_addr, msg)

```
【自分用備忘録】Cephのdeployを公式サイトを参照したら見事にはまったのでポイントを上げる

[公式サイト](http://docs.ceph.com/docs/master/start/)

OSはCentOS7.6を使用した。
# 心構え
失敗したらエラーの内容をよく見るのだ
めげない心
エラー吐いたらきちんとログをたどればたどりつける。
英訳に疲れたらChromeの翻訳機能を使う。
[error]という画面を見たら記載されていることをよーくみるのだ。

# step 1: Preflight
デプロイの画像にある通りノード3つに対してadmin-nodeからデプロイを行うので最低3台のマシンが必要。
管理を楽にするのに私は4台使った。admin-nodeについては仮想環境でも大丈夫。
![ditaa-b490c5d9d3bb6984503b59681d08337aff62e992.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293379/1790bcc6-8ed7-8659-5a38-4daa4292cf6b.png)

令和元年5月6日現在、デプロイはv13(Mimic)でデプロイされる。最新版のv14(Nautilus)はデプロイ後にアップデートすることで利用可能になる。

デフォルトのpythonでは何もできない
` yum -y install python2-pip`
でインストールする。
# Step 2: Storage Cluster
sudoつけるなとか、rootでやるなと書いてあるけれどもsudoつけないとpermission deniedになるので結局rootでやるのが一番楽。

OSが入ったディスクはOSDとして使えないので、別のディスクを付ける必要がある。

<font color="Red">ホスト名の変更を必ず事前にやっておく！！！</font>
keyringsの名前がnode名@localhostになるためファイルが見つけられなくなる

失敗したら
`ceph-deploy purge {ceph-node} [{ceph-node}]
ceph-deploy purgedata {ceph-node} [{ceph-node}]
ceph-deploy forgetkeys
rm ceph.* `
を実行してStep2からやり直す。

ceph-deployコマンドを行うときはadmin-nodeも入れることを忘れない。

---
取り急ぎここまで。
Shader入門① オブジェクトの色を変えてみる

## Shaderとは
陰影処理を行うためのプログラムのこと

## Shaderを書く前に
エディタによってはShader用のextensionがあるのでインストールしておくと楽にShaderを書くことができます。
お使いのエディタで調べてみましょう。

Unity上では4種類のShaderを作成することができます。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/a2c5666a-16d1-9560-6a10-b02267612738.png)

## Surface Shader
ライティングやシャドウを簡単にいい感じにしてくれるShader

![shader2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/34060278-1ddb-2f6d-651c-b36140007bb1.png)


## Unlit Shader
ライティングを反映しないShader
![shader3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/2e3ddd2a-b645-eb5a-c06a-b44e49e77480.png)


## Shader言語
### HLSL
`High Level Shading Language`の略称
マイクロソフトによって開発されてDirectXで使われてきた。
後述のCg言語と似ている。

### Cg言語
NVIDIAによって開発された。
C言語をベースとした文法。

### GLSL
`OpenGL Shading Language`の略称
OpenGLで使われてきた。
C言語をベースとした文法。

### ShaderLab
UnityではShaderLabというHLSL、Cg言語をラップしたようなもので記述される。

## Shaderを書いてみる
オブジェクトの色を青くする最低限のShaderを書いてみる。

```c:sample.shader
Shader "Custom/sample1"
{
    SubShader
    {
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = float4(0, 0, 1, 0);
        }
        ENDCG
    }
}

```

解説

```c:sample.shader
Shader "Custom/hoge/sample1" // Unity上から参照するパスのようなもの。Shader毎のグルーピングに使える
{
    SubShader
    {
        CGPROGRAM // プログラムの内容はCGPROGRAM～ENDCGの中に記述していく
        // #pragmaはどの関数がsurfaceなのかを明示している
        #pragma surface surf Standard

        struct Input
        {
            float2 uv_MainTex;
        };

        // surfaceシェーダー関数を定義している。関数名は自由につけることができる
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = float4(0, 0, 1, 0); // RGBAでBを1にしているのでオブジェクトは青くなる
        }
        ENDCG
    }
}

```

尚、Cg言語で扱えるデータ型については下記を参照
https://ja.wikipedia.org/wiki/Cg_(プログラミング言語)#データ型

## Properties
Shaderにはプロパティを定義することができ、Unityエディタ上から編集することができるようになります。

```c:sample.shader
Shader "Custom/hoge/sample1"
{
    Properties {
        // カラープロパティを定義。デフォルト値は黒
        _Color("Color", Color) = (0, 0, 0, 0)
    }
    SubShader
    {

        // SubShader内でプロパティをメンバ変数として定義
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Albedo = _Color;
            
        }
        ENDCG
    }
}
```

Colorというプロパティが設定されていますね。

![shader.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201127/ab4cc401-adb1-6719-56c9-6559a1bc8698.png)

定義できるプロパティは下記を参照
https://docs.unity3d.com/ja/current/Manual/SL-Properties.html
#python の #正規表現 で 置換結果をコールバック的関数で柔軟に指定する例

```py
import re

def some_callback(match):
    return match.group(1) + " is " + match.group(2)

print(re.sub(r'(\w+) (\w+)', some_callback, "Alice Liddell"))
# Alice is Liddell
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1657








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
kusanagi でアップロードサイズ変更


KUSANAGIのデフォルトのファイルアップロードサイズは、１６MB となってます。

##もっと大きいサイズをアップロードする場合、nginxの場合は、３箇所必要です。

- php.ini
- /etc/nginx/nginx.d/saite_name.conf

/etc/php7/php.ini
post_max_size = 16M
upload_max_filesize = 16M

あとは、
- /etc/nginx/nginx.d/sitename.conf

ここにも16M
って記述があります。
client_max_body_size


そして、kusanagiを再起動
kusanagi restart

# これでOK


参考にしたサイト
https://webtomoblg.net/wordpress/wp-uploadsize/
フィードバック・ループ(Create Feedback Loops)を構築する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/431158d1-720f-34ce-65d7-c8d8eb67c723.png)

こちらの本を読んでパターンを1つずつまとめ
個人的に実践可能そうなものから

## アプレンティスシップ・パターンとは
アプレンティスシップとは徒弟制度のことで、よく起きる問題への共通の解決策に実際なっているものをパターン化したもの

### アプレンティスであるということは
**今まで行ったことや今やっていることをより良く、さらに賢く、もっと速く行う方法が常にあるという態度を基本的に持つこと**

## 前提
- あなたの曖昧で暗黙の知識を他の人々が共有できると、安易に思い込まない事
- パターン同士は結びついているので、あるパターンを既に知っているという事は未知のパターンを辿る事ができる
- 優れたプログラマになる方法を教えるのではなく、優れたプログラマになるための学び方を教える

## フィードバック・ループを構築する(Create Feedback Loops)とは
行動に対して検証できる仕組みと習慣をつけましょうということ

## 傾向
無意識の無能に苦しんでいてスキルが無いことに気付けず自他を正しく評価できない

## 問題
自己評価は持っている能力に対する相対的なものにすぎず客観性に欠ける
自分の仕事を省みる(Reflect as You Work)を活用しても過去の分析にしか役立たない

## 解決方法
自身に対する客観的な外部データを定期的に収集する仕組みを作る

## ポイント
- 早い段階で頻繁かつ効果的に行うことで自分の無能さを少なくとも認識できる
- フィードバックとはTDDやインタラクティブなプログラミングの実行環境、コードレビューやペアプロも該当する
- フィードバックには「強化」(必要な活動を増やす)と「バランスを取る」(不要な活動を減らす)の2種類がある
- 自身の知識レベルを擁護せず、教えられやすくなることに努める

## 行動
- 測定可能で影響を与えられるものをみつける
- その数値を記録する
- その数値の変化が何を伝えようとしているのか自問する
- 変化を加えた効果を理解するためにその数値(他の数値も含め)が使用できるかを考える

## 関連パターン
- 自分の仕事を省みる(Reflect As You Work)
- 白帯(The White Belt)

## 書籍情報
Dave H. Hoover (著), Adewale Oshineye (著), 柴田 芳樹 (翻訳), アプレンティスシップ・パターン
https://amzn.to/2UCKF9D

## 雑感
数値で自身をみつめる習慣が大事そう
aws cloud9を軽く触ってみた結果をまとめてみる

###初めに
はじめまして。raqwelと言います。
普段は新卒として入った都内のITベンチャーでSREとして働いています。
業務中で気になった技術やらなんやらを休みの日に調べたり試したりすることが増えてきたので、
備忘録がてらまとめて見たいと思い、qiitaに投稿しようと思いました。

###やったこと
今回はaws cloud9を軽く触ってみたので、自身が感じたメリデメ等をまとめようかと思います。
cloud9に関しては↓を見ていただけると良いかと思います。

- [AWS Cloud9 コードを記述、実行、デバッグできるクラウドベースの統合開発環境(IDE)](https://aws.amazon.com/jp/cloud9/)

簡潔に述べると、awsが提供しているクラウドIDEで、
awsアカウントとブラウザとネット環境があればどこでもコーディングできるものです。
最近だと東京リージョンに来たことがちょっとしたニュースになりました。

- [AWS Cloud9 が東京リージョンに対応しました](https://aws.amazon.com/jp/blogs/news/aws-cloud9-tokyo/)

実際にはこちらの方が行ったことをなぞるような形で手を動かしました。
https://qiita.com/icck/items/7705ef6871e261d6535e
この場を借りてお礼申し上げます。

###実際に触ってみた感想
実際に触ってみた感想を以下にメリデメで書いていきます。
あくまで個人の意見なので、その点配慮して見ていただけたら幸いです。

####メリット
- ブラウザがあればどこでもコーディングできる
- ペアプロが容易なため、手戻りの発生を抑えられる
- セットアップの容易さ
    - cloud9で実際に開発しようとしたとき、基本的には以下のステップを行うだけで簡単に用意できます。しかもcloud9自体は**無料**で使えます。
 
```markdown:setup
    1. コンソールを開いて、
    2. cloud9を選択して、
    3. Create Environmentをクリックして、
    4. Name（作業環境名）とDescription(環境の説明)を入力して、
    5. そのまま進めて「Create environment」を押して、
    6. 少し待つ。
```


- 対応言語が豊富
    - node.js, python, js, java, Go等々、数多くの言語に対応しています。
        - https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/language-support.html
- localstackとかのモック化したawsサービスを用意せずともそのまま連携できる。
    - ローカル開発環境でawsのサービスを用いた機能を開発しているとデバッグするのに大変です。
    - その際によく用いられるのは、fakes3やlocalstack等のawsのサービスをモックしたようなものです。
    - もしawsが新たなサービスを発表しそれを用いるとなった時や、なにかがあって配布が中止されてしまった時に、まだlocalstackが使えなくなってしまうケースが考えられます。
    - しかし、aws cloud9はaws上のサービスなので、他のサービスと連携した際のデバッグ、テストができます。これによって実際のawsのサービスを用いて開発ができます。
        - https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/credentials.html

#####デメリット
- 普段利用しているIDEからの移行コストが高そう
    - 特に中〜大規模のプロダクトに関して移行が厳しい印象。
        - 実際に全員が使える様になるまでの学習コスト
        - 複数人が同じenvironmentで触った時の動作が重くならないか・・・
        - ~~開発者全員分のawsアカウントを用意し無くてはならない。ということは組織的にアカウント管理が抜けもれなく土壌が備わっているか・・・~~ IAMユーザの間違いでした。（@tokusyuさんありがとうございます！）
            - https://aws.amazon.com/jp/cloud9/faqs/#Environment_Sharing
- gitのGUIがない
    - 自分はいつもIDE付属のGUIでgit操作を行っています。
        - その方が直感的に理解、操作がしやすいためです。
    - しかし、cloud9にはGUI機能が見当たりませんでした。（もしかして見逃してるかもしれません）
    - git操作を普段からコマンドで行っている方は問題ないと思いますが、GUIを利用する人の事を考えると、どちらも用意してある環境が欲しいな〜と思ってしまいます。

###まとめ
今回はawsがリリースしたクラウドIDE「aws cloud9」を触ってみました。
実際触ってみて感じたのは、中〜大規模のプロジェクトがIDEからcloud9に移行するのは結構大変そうな印象を受けました。
しかし、セットアップの容易さ、対応言語の多さ等を考えると、個人や小規模のプロジェクトの開発にはむしろ使えるのではないかと感じました。
今後、どのようにアップデートしていくかが気になります。

というわけで以上です。
初記事なので至らぬ点が多いかと思いますが、温かい目で見ていただけたら幸いです。
#python でテキストを URL エンコード / デコードする例

```
>>> import urllib.parse
>>> encoded = urllib.parse.quote("<code>a</code>\ndagadga")
>>> encoded
'%3Ccode%3Ea%3C/code%3E%0Adagadga'
>>> decoded = urllib.parse.unquote(encoded)
>>> decoded
'<code>a</code>\ndagadga'
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1656








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[React] 動的に追加したコンポーネントのパラメータを変更しても更新されない

# note

React初心者です。

# 環境

```
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.0"
  },
```

# 概要

## 期待する動作

ボタンをクリックすると、時計が1つ増える。時計に表示する文字列は、各コンポーネントではなく、Appが管理する。時計は1秒ごとに更新される。

## 実装

下にあるコードを見たほうが早いと思いますが、簡単に説明。

Windowという名前のコンポーネントがある。`props.text`を表示する以外のことは何もしない。

Appは、`text`と`windows`というステートを持っている。
textには、時刻を文字列にしたものが格納されていて、`setInterval`で1秒ごとに更新される。
`windows`は、Windowコンポーネントが格納された配列である。

画面上のボタンをクリックすると、`state.windows` に Windowコンポーネント を追加する。
Appの`render`の中に`this.state.windows`を表示する部分があるので、`state.windows` に要素を追加した時点で画面が更新されるはず。

# 起きる問題

動的に追加されたWindowたちの文字列が変化しない。

Appの`render`に直接書いたWindowは更新されているのが分かる。

<!-- more -->

# codesandbox

https://codesandbox.io/s/oq6nk3wn16?fontsize=14

念のため、ブログにもコードを記載します。

```javascript
import React from "react";
import ReactDOM from "react-dom";

class Window extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <pre>{this.props.text}</pre>;
  }
}

class App extends React.Component {
  constructor(prop) {
    super(prop);
    this.state = {
      text: "",
      windows: []
    };
    setInterval(() => {
      this.updateText();
    }, 1000);
  }
  updateText() {
    this.setState({
      text: new Date(Date.now()).toString()
    });
  }
  addWindow() {
    this.setState({
      windows: this.state.windows.concat([<Window text={this.state.text} />])
      //windows: this.state.windows.concat([() => <Window text={this.state.text} />])
    });
  }
  render() {
    return (
      <div className="App">
        <Window text={this.state.text} />
        <hr />
        <div>
          {
            this.state.windows
            //this.state.windows.map(e => e())
          }
        </div>
        <hr />
        <div>
          <button
            onClick={() => {
              this.addWindow();
            }}
          >
            addWindow
          </button>
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```

# 原因と解決策

上記のコードの、コメントアウト部分が、自分なりの解決策です。

下のように、domを直接配列に入れてしまっているのが間違い。おそらく、現時点での`this.state.text`を含むレンダリング済みのデータが格納されてしまっている。

```
    this.state.windows.concat([<Window text={this.state.text} />])
```

`this.state.text` が変化したら再構築されて欲しいはずなので、配列にはdomを返す無名関数を格納するようにして、

```
    this.state.windows.concat([() => {return (<Window text={this.state.text} />);}])
```

`render()` 側で無名関数を呼んで、domをレンダリングする。

```
        <div>
          { this.state.windows.map(e => e()) }
        </div>
```

これで期待通りの動作はするようになった。

# 原因と解決策（追記：2019/05/06）

`state`にはコンポーネントを入れず、コンポーネントに渡す引数を保持させた方が良いとのコメントがありました。

この方法ならば、`state`も最小限の大きさになり、可読性も上がりそうです。
配列にはキーワードや連想配列を格納するようにして、

```
    this.state.windows.concat(["Window"])
```

`render()` 側でキーワードに応じてレンダリングするdomを分岐する。

```
        <div>
          { this.state.windows.map(type => 
              (type == "Window") ? (<Window text={this.state.text} />) :
                                   (<p>{this.state.text}</p>))
          }
        </div>
```
iPhoneで撮影した画像(*.HEIC)をjpgやpngに一括変換する

# iPhoneで撮影した画像(*.HEIC)をjpgやpngに一括変換する

環境： macOS Mojave (10.14.4)

## 一個の場合
以下で出来ます。

```
$ sips --setProperty format jpeg input.heic --out output.jpg
```

ただこれ、ワイルドカード使えないんですよね(´・ω・｀)

## 複数の場合
最新版のImageMagickを使って一括変換できます。

```
mogrify -format jpg -quality 80 *.HEIC
```

### ImageMagickでエラーが出た時の対処法
ImageMagickで変換できるかテスト

```
$ mogrify -format png *.HEIC
mogrify: no decode delegate for this image format `HEIC' @ error/constitute.c/ReadImage/556.
```
エラーが出た。バージョンを確認する。

```
$ convert -version
Version: ImageMagick 7.0.8-24 Q16 x86_64 2019-01-18
```
若干古い
ImageMagickを入れ直します。

```
$ brew reinstall imagemagick                                かなり時間がかかる
$ convert -version
Version: ImageMagick 7.0.8-43 Q16 x86_64 2019-05-03         新しくなった
```
このバージョンでは成功しました(｀･ω･´)ゞ

### サンプル集
#### pngへの変換
```
$ mogrify -format png *.HEIC
```
iPhoneで撮影した画像ですとファイルサイズは8MBほどになります。

#### jpegへの変換(品質80%)
```
$ mogrify -format jpg -quality 80 *.HEIC
```
品質を落としてjpegに変換するとファイルサイズは2MBほどになりました。


#### jpegへの変換(品質80%、画像サイズ縮小)
```
$ mogrify -format jpg -quality 80 -resize 25% *.HEIC
```
さらに画像サイズが大きいので縦ｘ横ともに1/4のサイズにすると約110KBになりました。画像サイズは1008x756。


## まとめ
一括変換する時はImageMagickが便利です(｀･ω･´)ゞ
ImageMagickなのでUbuntuでも使えると思います。
Alfresco6.1をCentOS7に構築する

# Alfresco?
ECM(コンテンツ管理サービス)の1つ
OSSで提供されている。検索エンジンはSolr。Community版だと無償。
使いがってを見るのに入れてみる。

# 環境
2019/1に6.1がリリースされた模様。
6系からコンテナ管理に移管したと記載があり。以下で構築。
- Windowsマシン上にVirtualBox+Vagrant
- CentOS7.6
- Alfresco6.1

# 構築
AlfrescoのCommunity版のインストール方法および資材は以下。
[Alfresco Communiry](https://www.alfresco.com/thank-you/thank-you-downloading-alfresco-community-edition)

### Centos7インストール
Vagrant、VirtualBoxのインストールは省略。
任意のディレクトリ内で以下実施。

```sh
vagrant init centos/7
```

Vagrantfile編集
xx.xx.xx.xxはIPアドレス

```vim
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "xx.xx.xx.xx"
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
    vb.memory = "4096"
  end
end
```

起動

```
vagrant up
vagrant ssh
```

#### SSH接続エラーになった場合
.vagrant\machines\default\virtualbox\private_key
のセキュリティタブからVagrantから作られたユーザ以外を外すと上手くいった。
複数ユーザいるのがVagrant的に気に食わないらしい。

sshのエラー確認したい場合は以下を実行

```
vagrant ssh-config
```

### Centos７環境整理
#### 日本語化
```
yum update
yum reinstall -y glibc-common
timedatectl set-timezone Asia/Tokyo
localectl set-locale LANG=ja_JP.UTF-8
localectl set-keymap jp106
localectl set-keymap jp-OADG109A
```

## git、docker、docker-composeインストール
git

```
yum install git -y
```

docker

```
yum install docker
systemctl start docker
systemctl enable docker
```

docker-compose

```
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```

### Alfrescoインストール
資材を落としてきて、docker-composeにまかせて起動するだけ。
割とダウンロードに時間かかったので気長に。

```
git clone https://github.com/Alfresco/acs-community-deployment.git
cd acs-community-deployment/docker-compose
docker-compose up -d
```

# 接続
```
ホーム：http://xx.xx.xx.xx:8080/share
全文検索エンジン(Solr)： http://xx.xx.xx.xx:8083/solr
API:http://xx.xx.xx.xx:8082/alfresco
```
デフォルトパスはadmin/admin
日本語化もされている模様。
![alfresco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139625/3f01caa2-08be-eee4-a50c-1ebb49d409cb.png)

# トラブルシュート
## Officeのファイルをプレビューすると文字化け発生
Officeファイルをアップロードしてプレビューを見ると文字が豆腐状態に。
プレビューは登録時にPDFファイルを作成し、それを表示することで実現しているらしいが、
日本語フォントが無いためプレビュー作成時に失敗しているらしい。
alfresco-content-repository-community、alfresco-shareのコンテナにipaフォントを入れて再起動することで解決。


フォントのインストール

```bash
docker exec -it <コンテナID> /bin/bash
yum install ipa-gothic-fonts ipa-pgothic-fonts
exit
```

Alfrescoを再起動

```bash

docker-compose stop
docker-compose restart
```
php-master-changes 2019-05-05

今日は typo の修正があった！

# 2019-05-05
## cmb69: Fix typo
- https://github.com/php/php-src/commit/a760c79f1e3a4766de92973179972335ee38b1cc
- [7.4~]
- ext/ffi で、エラーメッセージの typo の修正
Gulp v3 から v4 にバージョンアップしたときに「Task never defined: ...」と言われたら

v3 では動作してたのに v4 で次のようなエラーが出たら、

```
AssertionError [ERR_ASSERTION]: Task never defined: manifest
```

v4 では、タスクの宣言が明確に先に行われないといけないみたいです。

もし[`requireDir`](https://www.npmjs.com/package/require-dir)を使っていたら、タスクの依存関係に合わせてディレクトリを作り替えるか、 `requireDir` をやめてひとつひとつ依存関係順に`require`しましょう。

- before

```js
requireDir('./tasks')
```

- afeter

```js
// minimum tasks
require('./tasks/clean')
require('./tasks/fonts')
require('./tasks/images')
require('./tasks/locales')
require('./tasks/manifest')
require('./tasks/pages')
require('./tasks/scripts')
require('./tasks/styles')
require('./tasks/version')

// wrapped up
require('./tasks/build')

// packaging
require('./tasks/pack')
require('./tasks/default')
```



# 参考

https://zzz.buzz/2016/11/19/gulp-4-0-upgrade-guide/
Minecraft Skript 基礎編 Part.3

#on damageについて・・・
`on damage`というイベントではこれまで紹介してきた`player`が使えなくなる。

と、いうのも`on damage`というのは殴った側、殴られた側という関係がある。

この時に`player`を違うと判定できないため、ここで使うのは殴った側が`attacker`で殴られた側が`victim`という関係になる。

では簡単にコードを書いてみましょう。

#コードを書いてみる・・・
```:test.sk
on damage:
    broadcast "殴った人:%attacker%  殴られた人:%victim%"
```
これでイベントが実行されたら殴った人の名前と殴られた人の名前が表示されることになる。

次は[コチラ](https://qiita.com/meoto2408/items/938a1035998ca80ee59e)

前は[コチラ](https://qiita.com/meoto2408/items/3a822b4caaf8f87e1e2a)
ETHのアカウントを作る

#概要
Ethreumのアカウントをweb3.jsを使って作成します

#作り方

```
mkdir create-eth-account
cd create-eth-account
touch create.js
```

次にweb3をインストールします

```
npm i --save web3
```

あとはcreate.jsファイルを以下のように編集します

```:create.js

const Web3 = require('web3');

const networks  = {
    main: 'wss://mainnet.infura.io/ws/v3/',
    ropsten: 'wss://ropsten.infura.io/ws/v3/',
    kovan: 'wss://kovan.infura.io/ws/v3/',
    rinkeby: 'wss://rinkeby.infura.io/ws/v3/'
};

//InfuraのAPI-KEY
const apiKey = 'YOUR-API-KEY';

//ここではどのネットワークでも良い
const network = networks.rinkeby;

const getWeb3 = () => {
    const provider = network + apiKey;
    const web3 = new Web3(provider);
    return web3;
}

const createAccount = async() => {
    const web3 = getWeb3();
    const account = web3.eth.accounts.create();
    console.log(account);
}

createAccount();
```
あとは以下を実行すればアカウントが作れます

```
node create.js
```

こんな感じで表示されます

<img width="520" alt="スクリーンショット 2019-05-06 13.54.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326169/4a38c2fb-57eb-3699-1d4c-ecebc405537b.png">
Utuntu 19.04 に Docker CE をインストールする

# Docker-CE を Ubuntu 19.04 にインストールするメモ

基本は [Dockerのweb](https://docs.docker.com/install/linux/docker-ce/ubuntu/) のインストール手順でOKなはずですが、
2019/05/06現在、対応バージョンに disco 19.04 は含まれていないため、そこだけ注意が必要です。

## 古いバージョンが入っていれば削除

```shell
$ sudo apt-get remove docker docker-engine docker.io containerd runc
```

## aptのパッケージのアップデートをします。

```shell-session
$ sudo apt-get update
```

## 必要なパッケージをインストールします。

```shell-session
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
```

## Dockerの公式GPG鍵を追加します。

```shell-session
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

fingerprintの確認もします。

```shell-session
$ sudo apt-key fingerprint 0EBFCD88
    
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]
```

## Dockerリポジトリの追加

公式サイトには以下のように記載がありますが、discoはまだ対応していないため、Dockerのリポジトリを引けません。

```shell-session
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

cosmic のリポジトリを引くことで代用します。

```shell-session
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   cosmic \
   stable"
```

```/etc/apt/sources.list``` に以下のように追記してもOKです。

```
deb [arch=amd64] https://download.docker.com/linux/ubuntu cosmic stable
```

## インストール

最新版をインストールする場合は以下のように。

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

## 動作確認

```shell-session
$ sudo docker version
Client:
 Version:           18.09.5
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        e8ff056
 Built:             Thu Apr 11 04:44:15 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.5
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       e8ff056
  Built:            Thu Apr 11 04:10:53 2019
  OS/Arch:          linux/amd64
  Experimental:     false
```

一般ユーザでdockerを使う場合はユーザをdockerグループに入れる必要があります。

```shell-session
$ sudo usermod -aG docker ${USER}
```

グループ追加を反映させるために一度ログアウトします。

```shell
$ docker version
Client:
 Version:           18.09.5
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        e8ff056
 Built:             Thu Apr 11 04:44:15 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.5
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       e8ff056
  Built:            Thu Apr 11 04:10:53 2019
  OS/Arch:          linux/amd64
  Experimental:     false
```
macOS High SierraのクリーンインストールUSBを作る方法

# 手順（一部未検証です、検証されたらコメントもらえると嬉しいです！）
- どうにかしてmacOS High Sierra以下のマシンを見つける（macOS MojaveだとHigh Sierra以下のダウンロードができない。。）
- [このリンクからダウンロード](https://itunes.apple.com/us/app/macos-high-sierra/id1246284741?ls=1&mt=12)
- ただ手に入るのが19MBのstubなので、続けるをクリックしてダウンロードする
- **再起動はしない！（再起動するとインストールされてしまいます）**
- SIPを切る（[参考](https://support.intego.com/hc/ja/articles/115003523252-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%95%B4%E5%90%88%E6%80%A7%E4%BF%9D%E8%AD%B7-System-Integrity-Protection-SIP-%E3%81%AE%E7%84%A1%E5%8A%B9%E5%8C%96)）
- （ここから未検証）Macintosh HDにある`macOS Install Data`フォルダをUSBメモリあたりにコピー
- `Install macOS High Sierra`に入れる
- `createinstallmedia`コマンドで作成

# 参考
https://www.macworld.co.uk/news/mac-software/impossible-download-old-macos-3684588/
https://apple.stackexchange.com/a/307118/307666
https://discussions.apple.com/thread/8376868
https://support.intego.com/hc/ja/articles/115003523252-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%95%B4%E5%90%88%E6%80%A7%E4%BF%9D%E8%AD%B7-System-Integrity-Protection-SIP-%E3%81%AE%E7%84%A1%E5%8A%B9%E5%8C%96
「Firefox」でインストール済みアドオンが利用不能 の対処

## なんかGW中に。。。
ブラウザ開いたら、なんかアドオン死んでる。以下のニュースあり。

「Firefox」でインストール済みアドオンが利用不能になる問題が発生中
https://forest.watch.impress.co.jp/docs/news/1182954.html

「Firefox」v66.0.4が公開 ～アドオンが利用不能になる問題を修正
https://forest.watch.impress.co.jp/docs/news/1182988.html

## 対処
・前提
Centos7.6
（どうせrepoの更新に時間かかるし自力でやる）
※windowsとかMacは素直に最新入れ直せば良いかも

```bash
wget https://download-installer.cdn.mozilla.net/pub/firefox/releases/66.0.4/linux-x86_64/ja/firefox-66.0.4.tar.bz2 
tar xvf firefox-66.0.4.tar.bz2
su -
mkdir /usr/local/firefox6604/ -p
mv firefox /usr/local/firefox6604
ln -s /usr/local/firefox6604/firefox /usr/local/bin/.
```
```bash:/usr/share/applications/firefox.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Firefox
Comment=Firefox 66.0.4
Path=/usr/local/bin
Exec=/usr/local/bin/firefox
Icon=/usr/local/firefox6604/browser/chrome/icons/default/default128.png
Categories=Application;
Version=1.0
Type=Application
Terminal=false
```

## 所感
Mozillaは、なぜ5年の中間証明書を作成したのか？
そして、期限まで放置したのか。問い詰めたい。
これからも、Chromeの対抗馬として期待します。
VSCodeのRemote WSLのpython環境

## 概要
私用のThinkPadのSSDを大きいものに換装したついでに環境構築をやりなおしてます。
vscodeの拡張Remote WSLを試してWindows版のpythonを使わないpythonローカル環境メモ。
過去に一度wsl上のpythonをどうにかwindows側のvscodeで認識させようとしましたが途中で挫折しました。
しかし、Remote WSLのおかげでやりたかっとことがさらっとできてしまいました。すごい。

## 手順

### wslを有効にする
https://qiita.com/Aruneko/items/c79810b0b015bebf30bb
私はUbuntu18.04を入れました。

### vscode insidersを入れる
https://code.visualstudio.com/insiders/
現状remote wslの機能がinsidersの方でしか試せないようです。
なんか既存のvscodeとは分離されてインストールされました。
緑のvscode。

### remote development拡張をいれる
vscode insidersを起動して「Remote Development」という拡張をいれました。
Remote WSLも一緒に入りました。
Remote SSHとかも試したいですね。Git Bash用にかいたconfigとかも認識しててすごい。

入りましたらvscode insidersの左下の><みたいなマークを押せばwslに接続されます。
terminalもwslに勝手になってるすごい。

### python拡張をいれる
拡張検索で「python」といれ一番上のやつを入れました。
wsl-installとかでててどうやらwsl用のものが入れられるようです。すごい。

### wsl上にpython環境をつくる
[こちら](https://qiita.com/Nimimal/items/72c2e2a6a566d1f5d2a2#wsl%E7%89%88debianubuntu%E3%81%A7pyenv%E3%81%8C%E5%8B%95%E3%81%8F%E3%81%BE%E3%81%A7)を参考にさせていただきpyenvをいれました。
作業はvscode上のterminalで行いました。
(やたらaptで時間かかったので国内のミラーリポジトリを使うように最初に設定すればよかったかも)
pyenvだけ入れてpython3.7.3をbuildしました

pipenvはやめてpoetryをいれました 。

```
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
source $HOME/.poetry/env
```

```
poetry new --src test
cd test
python -m venv .venv
poetry add -D pylint
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287793/706779bd-7022-8502-3a23-992508eeffc3.png)
Data Guard スタンバイ・インスタンスでできること

昨日までにActive Data Guard環境でDMLやPL/SQLブロックのリダイレクト機能を検証しましたが、Data Guardスタンバイ・インスタンス上で実行できる操作について簡単に検証しました。

プライマリ・インスタンスからの受信したREDO情報を適用した状態のスタンバイ・インスタンスは、MOUNTステータスになっているか、Read-Only状態でOPENステータスになっています。

```
SQL> SELECT STATUS FROM V$INSTANCE;

STATUS
------------
OPEN

SQL> SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;

DATABASE_ROLE    OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY WITH APPLY

```

上記状態のスタンバイ・インスタンスで、実行可能なSQL文をいくつか確認します。


# ALTER DATABASE
プライマリ・インスタンス上で実行されたALTER DATABASE FORCE LOGGING文や、ALTER DATABASE FLASHBACK ON文は、スタンバイ・インスタンスに伝播しません。このため、Data Guard全体で同一性を保つためにはスタンバイ・インスタンス上でも再実行する必要があります。

- プライマリ・インスタンス上で実行

```
SQL> ALTER DATABASE FLASHBACK ON;

Database altered.
```

- スタンバイ・インスタンス上で実行

スタンバイ・インスタンスではFLASHBACK設定が有効になっていないことがわかります。

```
SQL> SELECT FLASHBACK_ON FROM V$DATABASE;

FLASHBACK_ON
------------------
NO
SQL> ALTER DATABASE FLASHBACK ON;

Database altered.
```

ALTER DATABASE FORCE LOGGING文も同じようにプライマリ・インスタンスとスタンバイ・インスタンス上では独立した設定が可能です。

- プライマリ・インスタンス上で実行


```
SQL> ALTER DATABASE FORCE LOGGING;

Database altered.
```

- スタンバイ・インスタンス上で実行

```
SQL> SELECT FORCE_LOGGING FROM V$DATABASE;

FORCE_LOGGING
---------------------------------------
NO

SQL> ALTER DATABASE FORCE LOGGING;

Database altered.
```

# CREATE GLOBAL TEMPORARY TABLE
Oracle Database 18cからは、スタンバイ・インスタンス上でGLOBAL TEMPORARY TABLEの作成もできるようになっています。スタンバイ・インスタンス上で実行されたCREATE GLOBAL TEMPORARY TABLE文は、プライマリ・インスタンスに伝播して実行されます。この機能がOracle Database 19cではDML Redirectにつながったのではないかと思っています。特にこの機能のための設定は不要です。テーブルの作成だけでなく、データの格納やテーブルの削除も行うことができます。

```
SQL> CREATE GLOBAL TEMPORARY TABLE temp1(c1 NUMBER, c2 VARCHAR2(10)) ON COMMIT PRESERVE ROWS;

Table created.

SQL> INSERT INTO temp1 VALUES (100, 'data1');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM temp1;

        C1 C2
---------- ----------
       100 data1

SQL> DROP TABLE temp1;

Table dropped.
```

スタンバイ・インスタンスで作成したテーブルはプライマリ・インスタンスでも確認できます。

```
SQL> SELECT TABLE_NAME, TEMPORARY FROM USER_TABLES WHERE TABLE_NAME='TEMP1';

TABLE_NAME                     T
------------------------------ -
TEMP1                          Y
```

# CREATE PRIVATE TEMPORARY TABLE
PRIVATE TEMPORARY TABLEはOracle Database 18cの新機能で、セッション実行中のみ有効なテーブルです。このテーブルはセッション間のみ有効なので、プライマリ・インスタンスには伝播しません。

```
SQL> CREATE PRIVATE TEMPORARY TABLE ora$ptt_temp1(c1 NUMBER, c2 VARCHAR2(10)) ON COMMIT PRESERVE DEFINITION;

Table created.

SQL> INSERT INTO ora$ptt_temp1 VALUES (100, 'temp1');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> DROP TABLE ora$ptt_temp1;

Table dropped.
```
Python 3.7 ではGeneretor で StopIteration を使うと RuntimeError になる

次のコードはPython 3.7で実行すると RuntimeError になります。


```python
def tentimes():
    i = 0
    while True:
        if i == 10:
            raise StopIteration
        yield i
        i = i + 1


for i in tentimes():
    print(i)
```

```console
0
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-1-20f0585f0e57> in tentimes()
      4         if i == 10:
----> 5             raise StopIteration
      6         yield i

StopIteration:

The above exception was the direct cause of the following exception:

RuntimeError                              Traceback (most recent call last)
<ipython-input-2-ade91eb5a83d> in <module>
----> 1 for i in tentimes():
      2     print(i)
      3

RuntimeError: generator raised StopIteration
```

これは[組み込み例外 — Python 3.7.3 ドキュメント](https://docs.python.org/ja/3/library/exceptions.html#StopIteration) に記述があり、[PEP 479 -- Change StopIteration handling inside generators](https://www.python.org/dev/peps/pep-0479/) がデフォルトで有効化されているためです。

同様のコードは次のように修正すると動きます。

```python
def tentimes():
    i = 0
    while True:
        if i == 10:
            return
        yield i
        i = i + 1


for i in tentimes():
    print(i)    
```

```console
0
1
2
3
4
5
6
7
8
9
```

[Pythonのイテレータとジェネレータ - Qiita](https://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09)の記事にあるような実装で `raise StopIteration` しても RuntimeError にはなりません。

```Python
class MyRange(object):
    def __init__(self, start, end):
        self._i = start
        self._end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self._i == self._end:
            raise StopIteration
        value = self._i
        self._i = self._i + 1
        return value

my_range = MyRange(0, 10)
for i in my_range:
    print(i)
```

```console
0
1
2
3
4
5
6
7
8
9
```
AVSpeechSynthesizerでの初回音声読み上げが遅いのを直す

iOSで音声読み上げをする時のコード。

```swift
import AVFoundation

class SpeechViewController: UIViewController {
    private let synthesizer = AVSpeechSynthesizer()

    private func speech(_ text: String) {
        // 初回のみ0.1~2秒遅れて読み上げられる
        let utterance = AVSpeechUtterance(string: text)
        synthesizer.speak(utterance)
    }
```

ただこれだと初回の読み上げのみ0.1~2秒遅れて読み上げられる。
2回目以降は遅延なく読み上げられる。
なので`viewDidLoad`で空文字を1回読んでおく。

```swift
import AVFoundation

class SpeechViewController: UIViewController {
    private let synthesizer = AVSpeechSynthesizer()

    override func viewDidLoad() {
        super.viewDidLoad()

        // 空文字を読んでおく
        let utterance = AVSpeechUtterance(string: "")
        utterance.volume = 0
        synthesizer.speak(utterance)
    }

    private func speech(_ text: String) {
        // 遅延なく読み上げられる
        let utterance = AVSpeechUtterance(string: text)
        synthesizer.speak(utterance)
    }
```
Dockerではじめる『Everyday Rails - RSpecによるRailsテスト入門』

## 概要
Railsチュートリアルも完了し、さて次は何をしようかと思案していたところ、
『Everyday Rails - RSpecによるRailsテスト入門』がゴールデンウィークセール中でしたので、これはと思い購入。
[Everyday Rails… Aaron Sumner 著 et al. [Leanpub PDF/iPad/Kindle]](https://leanpub.com/everydayrailsrspec-jp)
Railsチュートリアルに引きづつき、Dockerで環境を構築。

## 環境
PC：MacBookPro
docker for mac

## 環境構築
### RSpec用のコンテナ準備
まずは、ターミナルで適当なフォルダを作成して、カレントディレクトリに移動。

```shell
mkdir myRspec && cd $_
```
続いてDockerコンテナを起動。

```shell
$ docker container run -it --name myRspec -p 3000:3000 -v `pwd`:/myapp  ruby:2.4.6 /bin/bash
```
内容について軽く補足
*  `-it` 　: 標準入出力を繋げる。要するにターミナルで起動したコンテナを操作できるようにする。
*  `--name` 　: 名前付け。あるとわかりやすい。
*  `-p 3000:3000`　: ホストとなるOSとDockerイメージのポートを繋げる。
*  ```-v `pwd`:/myapp```　: ホストのカレントディレクトリと、Dockerのmyappディレクトリを同期させる。
  　 （同時にコンテナ内のルート直下にmyappディレクトリも作成される）
* `ruby:2.4.6`　: 引っ張ってくるDocker Image。サンプルアプリはRuby２.４なので今回はタグで2.4.6を指定。
* `/bin/bash`　：実行するコマンド。

ターミナルの最初の部分が`USERnoMacBook-Pro:~`から`root@:(12文字の英数字)`に変わっていたら成功。
そのまま、次のコマンドを実行。

```shell
$ apt update
$ apt install -y nodejs
```

#### Githubからサンプルアプリケーションをクローン
サンプルアプリケーションはGitHubにあります。
https://github.com/everydayrails/everydayrails-rspec-2017
クローンの手順はやったことがなかったので、ググりながら進めます。

```shell
$ git clone https://github.com/everydayrails/everydayrails-rspec-2017.git
```

`everydayrails-rspec-2017`というディレクトが作成され、コードが取得できました。
まずは`cd everydayrails-rspec-2017/`でディレクトリに移動。
この状態では、Masterブランチのみ取得している状態です。
ここから2章開始の状態にするために、本文に従ってブランチを切り替えます。

```shell
$ git checkout -b my-02-setup origin/01-untested
```

これで、ソースコードの準備が整いました。先述の通り、ホストの myRspecディレクトリはmyappディレクトリと同期しています。
ホストPCのmyRspec下の`everydayrails-rspec-2017`をVSCodeでひらけば、そのまま開発環境として利用できます。
ただし、Railsコマンドの実行などは、Dockerコンテナを動かしているターミナルからでないと使えません。

#### 仕上げ
ターミナルで最後の仕上げです。

```shell
$ bundle install
$ bin/rails db:create:all
$ bin/rails db:migrate RAILS_ENV=development
```

これで準備完了のはずです。ターミナルに`rails s`と入力し、ブラウザから`http://localhost:3000/`に接続してみます。

![スクリーンショット 2019-05-06 12.49.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262172/f652605b-1757-5763-8bf4-d3d2629afa80.png)

問題なく動いているようですね。それでは勉強開始！

### 参考
* [DockerでRailsチュートリアル（環境構築編） - 桜色HelloWorld](https://rikka-rt.hatenablog.jp/entry/2018/10/27/153658)
* [GitHub にアップされているブランチをローカルに取り込む](http://tomoyamkung.net/2014/03/14/git-checkout-branch-from-remote/)
外部決済代行業者にアプリ内課金をさせることができるか

スマホアプリ（iOS/Android）で有料会員のみに一部コンテンツへのアクセスを可能とさせる場合、通常はApple/GoogleにてI/Fが用意されているアプリ内課金の仕組みで実装するのが正攻法と考えられる。

しかし、例えばAmazonのPrime videoなどではアプリ内課金の仕組みは利用されておらず、外部ブラウザにて会員登録をさせる仕組みとなっている。これらの仕様はiOS/Androidそれぞれのディベロッパーポリシー等に違反しないのか、その解釈を調べてみた。

# まず結論

下記条件であれば、アプリ内課金を利用しなくても（外部の決済代行業者を利用しても）良いと考えられる。

* 有料会員の特典は、アプリ外でも利用できる（アプリ内のみのコンテンツではない）
* 決済画面はアプリ内WebViewよりは、ブラウザアプリで表示させたほうが良い。

# 判断理由（iOS）

App Store Reviewガイドライン（https://developer.apple.com/jp/app-store/review/guidelines/#in-app-purchase）によると

> 3.1.5（a）Appの外部で使用する商品やサービス：ユーザーがAppの外部で使用する商品やサービスをAppで購入できるようにする場合、そうした商品の支払いにはApp内課金以外（Apple Payや クレジットカードなど）の方法を使用する必要があります。

とある。つまり、

* アプリケーションの「内部」で使用する商品やサービス: App内課金での支払いで実装
* アプリケーションの「外部」で使用する商品やサービス: App内課金以外の方法での支払い（クレジットカード支払いなど）で実装

と考えられる（参考：https://inside.pixiv.blog/danbo-tanaka/4749）。
有料会員の特典適応範囲がアプリ内のみであるとみなされた場合、リジェクト対象となる恐れがある。

# 判断理由（Android）

デベロッパーポリシー（https://play.google.com/intl/ja/about/developer-content-policy-print/ ）では下記と定義されています。

> デベロッパーは、Google Play からダウンロードされた別のカテゴリのアプリ内でプロダクトを提供する場合、支払い方法として Google Play アプリ内課金を使用しなければなりません。
ただし、以下の場合を除きます。
・物理的なプロダクトのみの支払い
・そのアプリ以外で消費できるデジタル コンテンツに対する支払い（他の音楽プレーヤーで再生できる曲など）

つまり、基本的な考えはiOSと同じと考えられます。
BlenderのモデルをUnityに取り込む方法

手順1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403926/d7f6af85-8d3f-bbc2-574a-01575d4bd4e3.png)

手順2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403926/04b8a2f4-503f-6a4e-fb56-e8aba12fa9fe.png)
selected　Object：　エクスポートしたい物体。
Forward：BlenderとUnityの座標系が違うので、BlenderのY方向が前と違って、Unityの前方向はZ。
Up：UnityのUpはY方向。

Apply　transform：チェックするこで、global座標系での変換は自動にLocal座標系に応用する。手動で変換するのもOK。

以上で取り込む完了。
--------------------------------------------------------------------------

手動方法：
Apply　transformは実験中の機能なので、不安定になるかもしれません。
手順1　
物体の変換をすべて0にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403926/6d2f8508-41eb-9ce1-727e-65495d7b2525.png)

手順2　edit Modeのしたで全ての面を選択して、変換する。
Oracle 起動エラー「ORA-214」

今朝スケジュール再起動したオンプレミスのOracleサービスが起動に失敗していました
対応方法についてメモ

## 現象
- サービスの再起動を行っても解決しない
- エラーログを確認すると以下のエラー

```
ORA-214 signalled during: alter database mount exclusive...
```

## 環境
- Windows Server 2008R2
- Oracle 11.2.0.1

## 対応
### ①制御ファイルの置換え
#### ORA-214について
- ORA-214のエラーは、複数の制御ファイル間での不整合が原因のエラーのようです。
- 制御ファイルとはoracleの物理構成を保存したファイルで、複数のドライブなどに冗長化されることが推奨されてますが、この時の複数ファイル間で不整合が発生した場合にORA-214が発生するようです
- この現象は以下のような状況で発生するようです
  - ファイルのコピー操作時のミス
      - バックアップから復旧した際にドライブごとのバックアップ時刻が違った
  - ハードウェアの障害で制御ファイルが破損した
      - DBが異常停止した
      - ディスクが破損した

#### 置換え方法
- SQLｺﾏﾝﾄﾞでCTLファイルのパスを確認
  - 私は sqlplus で実行しました
  - 下記の出力のファイルが制御ファイルになるので、


```
>> sqlplus / as sysdba

SQL> SELECT VALUE FROM V$PARAMETER WHERE NAME = 'control_files';

VALUE
--------------------------------------------------------------------------------

F:\ORADATA\<サービス名>\CONTROL01.CTL, C:\ORACLE\FLASH_RECOVERY_AREA\<サービス名>\CONTROL02.CTL
```

- ファイルを置き換える
  - 前の手順で確認したCTLファイルのうち、古い時刻のものを念のためバックアップしておく
  - 新しい時刻のCTLファイルを古い時刻のディレクトリにコピーし、古い時刻の元々のファイル名にリネームする

```
>> rename F:\ORADATA\<サービス名>\CONTROL01.CTL F:\ORADATA\<サービス名>\CONTROL01.CTL.back
>> copy C:\ORACLE\FLASH_RECOVERY_AREA\<サービス名>\CONTROL02.CTL F:\ORADATA\<サービス名>\CONTROL01.CTL
```

- ｻｰﾋﾞｽを再起動し、動作すればOK

**今回の私の場合は```ORA-01033：Oracleの初期化またはシャットダウン中です。```のエラーが発生し、解決しませんでした.**

### ② リセットログからの　Database オープン
データベースのステータスを確認すると、マウントまではいっているようですが、オープンできていないようです
おそらく制御ファイルがまだおかしいようですので、まずはリセットログからの復帰を実施します

```
>> sqlplus / as sysdba

SQL>shutdown immediate
SQL>startup mount
SQL>alter database open resetlogs;
```

**今回は```ORA-01033：Oracleの初期化またはシャットダウン中です。```のエラーが発生し、解決しませんでした.**

### ③リカバリの実行
リセットログからも復帰が出来ないようです。
仕方ないので、リカバリを実施して起動するようにします。

```
>> sqlplus / as sysdba

SQL>shutdown immediate
SQL>startup mount
SQL>recover database using backup controlfile;
　　  ORA-00279: 変更: 363383(08/09/02 10:46:35で生成)にはスレッド番号: 1が必要です。
　　  ORA-00289: 検討すべきログ・ファイル: D:¥ORA817¥ORADATA¥ORA817¥archive¥arch1_335.dbf
　　  ORA-00280: 変更: 363383(スレッド: 1)は順序番号: 335に存在します。
　　  ログを指定してください: {<RET>=suggested | filename | AUTO | CANCEL}

##### ここでREDOログのファイルパスを指定する #####

SQL>alter database open resetlogs;
```

REDOログのファイルパスは次のSQLコマンドで確認します

```
SQL> SELECT MEMBER FROM V$LOGFILE;

MEMBER
---------------------------------------

F:\ORADATA\<サービス名>\REDO03.LOG
F:\ORADATA\<サービス名>\REDO02.LOG
F:\ORADATA\<サービス名>\REDO01.LOG
```

**これで復帰しました。**
分かりそうで分かっていないVue.jsワード

## DOM（Document Object Model）
「JavaScriptでhtmlの要素を操作するための仕組み」
Webページは文書であり、HTMLを操作することで表示されます。
そのHTMLをJavaScriptを用いて操作することができる仕組みのこと。

## データバインディング
「データと描画を同期する仕組み」
JavaScriptのデータを変えるだけで描画内容も一緒に変わる仕組みのこと。

### こんなかんじ
①Vue.jsでデータを表示

```
<!DOCTYPE html>
<html>
<body>
<div id="app">
    <h1>{{ message }}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Mt.everest!'
        }
    })
</script>
</body>
</html>
```
<img width="426" alt="スクリーンショット 2019-05-06 12.28.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348630/8914883f-6e4f-4e2a-e080-3c53d11f238e.png">

②コンソールからデータを変更
<img width="426" alt="スクリーンショット 2019-05-06 12.29.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348630/d746ef57-2b4d-23fe-a7bd-9972c948bd93.png">

③データを変更したタイミングで画面が変更される
<img width="426" alt="スクリーンショット 2019-05-06 12.29.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348630/df21091e-3c2b-175c-c9d6-13e2f7e370b9.png">
plunkerでjor1k その２

#概要

plunkerでjor1kやってみた。
linuxプログラミングしてみた。

#サンプルコード


```
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
	int i;
	for (i = 1; i < argc; i++) 
	{
		printf("%s%s", (i == 1 ? "" : " "), argv[i]);
	}
	putchar('\n');
	exit(0);
}

```


#結果

コンパイルエラーとなる。

```
~ $ cat main.c                                                                  
#include <stdio.h>                                                              
#include <stdlib.h>                                                             
                                                                                
int main(int argc, char * argv[])                                               
{                                                                               
         int i;                                                                 
         for (i = 1; i < argc; i++)                                             
         {                                                                      
                 printf("%s%s", (i == 1 ? "" : " "), argv[i]);                  
         }                                                                      
         putchar('\n');                                                         
         exit(0);                                                               
}                                                                               
                                                                                
~ $ gcc main.c                                                                  
/tmp/cccDMhHm.s: Assembler messages:                                            
/tmp/cccDMhHm.s:61: Error: operand out of range (1073741797 not between -3355443
2 and 33554431)                                                                 
~ $ 
```

```
~ $ uname -a                                                                    

Linux openrisc 4.16.0+ #10 Fri Jun 1 12:21:48 UTC 2018 openrisc GNU/Linux       
```

#調査

こちらだと、成功する。https://cs-education.github.io/sys/#VM

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f7d5874d-8fcc-993a-d14a-b4c87d88bc67.png)


以上。
中２になったからPythonでAI作ってみることにしたぞ

#AIをつくろうと思ったきっかけ
　最近、様々なところでAIについて話題になっていて、使われる機会も多くなっています。しかし、実際にAIの仕組みを知っていたり実際に作れる人はそんなにいないと思います。自分ぐらいの世代だと今後社会に出たときにどうせAIと付き合うことになるので、今からそういう事を学んどいた方が、今後有利になるのではないかとと考えました
#これからについて
 　自分は中一の時にPythonをいじってたので比較的AIについて学びやすい環境だと思います。しかし、入門書とかを見た感じ独学で進めていくには、ハードルが高そうなのでQiitaを使ってアウトプットしながら勉強していくことにしました。
 　また、いろいろ分からないことが出てくると思うのでこれからの記事で意見をもらえればと思っています。次回から実際に記事を書いていきます。あと、中学生のうちにプログラミング関係でお金を稼いでみたいと思っています。
 　これからよろしくお願いします。
今更ながらSlackBotを作ってみた：Slash Commands

前回に引き続き、SlackBotをカスタマイズしていきます。
　[今更ながらSlackBotを作ってみた](https://qiita.com/poruruba/items/ac147fbf0de92f6fad42)

今回は、スラッシュコマンドです。
Slackには、/で始まるコマンドがたくさん用意されていますよね。
そこに、独自のコマンドを付け加えることができ、それをSlackBotが処理できるようになります。

前回の環境をそのまま使います。まだの方はぜひご参照ください。


（参考情報）
slack api：Slash Commands
　https://api.slack.com/slash-commands

# SlashCommandsを作成する

Setting－Basic Information のページを表示し、Slash Commandsを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/5c7e7376-6101-b2f2-78a6-1c6dfdf63c3f.png)

それでは、「Create New Command」ボタンを押下しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f068ae42-6937-8d3c-5c29-ce754f2fc355.png)

「hi」という呼びかけに対して、あいさつ文と一緒にエコーバックするコマンドを作ってみましょう。例えば、以下のような感じで作成してみました。

・Command：/hi
・Request URL : 立ち上げたサーバのエンドポイントをフルパスで指定します。/testbot-cmdの方です。
・Short Description：やあ
・Usage Hint：呼びかけに応答します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ea0aeb25-cc36-c7d8-1ddb-1c1ca1b4bdff.png)

「Save」ボタンを押下します。
インストール済みのアプリを更新する必要がありますので、click hereのリンクをクリックします。あるいは、Setting－Install Appを選択して、「Reinstall App」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/7c96b62a-fc60-30be-3ec9-e055f38051f7.png)

すると、以下のような確認ページが表示されるので、「許可する」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/38a64f23-b042-1e47-bc4a-17642d74207f.png)

これで、Slack側の準備ができました。

#サーバ側の準備

次は、サーバ側を準備します。

すでに実装してあるコードに以下を追記します。

```controllers\slack_testbot\index.js
//・・・
app.command(async (body, web) =>{
    if(body.command === '/hi'){
        var hour = new Date().getHours();

        var greeting = 'こんにちは';
        if( 5 <= hour && hour <= 9 )
            greeting = 'おはよう';
        else if( 18 <= hour && hour < 5 )
            greeting = 'こんにちは';

        var message = {
            text: greeting + '！' + (body.text ? (' ' + body.text + " です。") : '')
        };
        app.responseMessage(body.response_url, message );
    }
});
//・・・
```

app.commandに関数を登録しておくと、コマンドが入力されたときにコールバックされてきます。

レスポンスメッセージを返す方法として、以下の3種類があります。

・Confirm your receipt of the payload. ： 受信できたことを知らせるのみ
・Do something useful in response right away. ： すぐにレスポンスメッセージを返す。
・Do something useful in response later. ： 後でレスポンスメッセージを返す。

slack-utils.jsでは、「後でレスポンスを返す」 方法をとっています。
body.response_urlに後で返す先のURLがあります。それを使って、app.responseMessageを呼び出してメッセージを返しています。

レスポンスメッセージの詳細は、前回同様以下を参考にしてください。

slack api：Reference Message payloads
https://api.slack.com/reference/messaging/payload

#動作確認

こんな感じでできました。

入力中。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/807d3f49-c03e-9bac-36cd-d29017d8eb54.png)

応答を受信。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/b699ece6-5c65-73b1-509d-3bd556f68246.png)

SlackBot用にユーティリティslack-utils.jsを用意しておいたので、わりと簡単に実装できるようになったのではないかと思います。

以上
Vue.jsでアンカーの中にリンクしない領域を作る

[Bootstrapのカード](https://getbootstrap.com/docs/4.0/components/card/)のようなデザインで全体をリンクにしてボタンだけリンクさせたくないことがありました。

やり方は簡単で[イベント修飾子](https://jp.vuejs.org/v2/guide/events.html#イベント修飾子)を使うだけです。

``` html
<a href="http://example.com/">
  ここはリンク
  <div @click.prevent="log">これはハンドラー</div>
  <div @click.prevent>これはイベントなし</div>
  ここもリンク
</a>
```

これだけです。