OmniAICreator/Qiita-1.07M huggingface dataset:
php-master-changes 2018-08-29

internals の ML 復活していっぺんメール届いてきたんだけど、[公式 Web インターフェース](http://news.php.net/php.internals)の方がまだみたいで、[externals.io](https://externals.io/) もまだだめ

# 2018-08-29
## dstogov: Added check for "user" method
- https://github.com/php/php-src/commit/002aa307864b06b7ba9de8ed230326cf14e778b7
- ext/opcache の zend_optimize_script() で、ある分岐へ対象がユーザ定義関数かどうかのチェックを追加
- メソッドの静的変数テーブルの扱いをいじってる箇所だけれど、ぱっと見よく分からない
- 元々[たまに起きる use-after-free を修正する用に入れた](https://github.com/php/php-src/commit/b6e34eaf04c5fc692f7c1aff77647f4961c99748)コードみたい

## petk: Change some permissions from 755 to 644
- https://github.com/php/php-src/commit/409b5133cca5bc831a67121a9b7cafbfe0a6422b
- リポジトリ内で実行許可のいらないファイルが 755 とかになっていたのを修正

## dstogov: Perform run-time binding reusing HashTable bucket (without new bucket insertion).
- https://github.com/php/php-src/commit/cd9f0a22fc0fd51e86043246bb4e12d39becdcd9
- 実行時の関数/クラスのバインドで、ハッシュテーブルの bucket を使い回すよう修正

## dstogov: Allow opcache_compile_file() to perform compilation even if opcache is disabled.
- https://github.com/php/php-src/commit/03fc3d85d8a0624c7a1171576db9cf44575763b0
- ext/opcache で、opcache が無効化されていても opcache のコンパイル処理を呼んで実行できるよう修正

## petk: Implement [#64517](https://bugs.php.net/bug.php?id=64517): Add AC_ARG_PROGRAM macro
- https://github.com/php/php-src/commit/3748d8070ffd7750c73c327e212d6dc4fc76d427
- autoconf マクロ AC_ARG_PROGRAM を追加
- configure --help に --program-suffix/prefix の情報が追加される

## carusogabriel: Make more tests run on Linux
- https://github.com/php/php-src/commit/2f7003847d3b48ea89fdec2bd5388085cf6b4d0e
- 実行環境を windows に限定していたテストを Linux でも動くよう修正

## remicollet: Revert "Don't report mmap failure if it is expected"
- https://github.com/php/php-src/commit/8cc7e2a2df912d86f6b9dc3f3d40e5de1d93214b
- 先日の [mmap() の連続領域確保の修正](https://qiita.com/sj-i/items/934ba9ce871a926e6850#devnexen-support-fixed-address-mmap-without-replacement)について、remi でお馴染みの remicollet さんから「SEGV 出るよ」という報告があり revert

## remicollet: Revert "Support fixed address mmap without replacement"
- https://github.com/php/php-src/commit/a55bcaa14ddba2df0c0f9c7f4444fc9d9f6564fd
- ↑とあわせて revert

## weltling: Update NEWS
- https://github.com/php/php-src/commit/d21220d7f0549a840eeae1289e15f07c0dd9eed4
- NEWS に[昨日の ftruncate() のバグ修正](https://qiita.com/sj-i/items/aa2ca386327c4ac23235#weltling-fixed-bug-76803-ftruncate-changes-file-pointer)を記載
[C#]Rxでsubscribeされた場所を探す

Rxで拡張メソッドを書いてた時に困ったことについて記載します。
あまり一般的な話ではないので誰得感がありますが…


例えば以下の拡張メソッドがあるとします。

```csharp
static class Extensions
{
    public static IObservable<string> Filter(this IObservable<string> source, string v)
    {
        return source.Where(s => s == v);
    }
}
```

あんまり意味のない関数ですが単純に渡した文字列と等しい場合だけ後続に値を流す`IObservable`を作る関数です。
この関数を例えば以下のように使ってるとします。

```csharp
static void Hogehoge(IObservable<string> source)
{
    source.Filter("test")
        .Subscribe(s => Console.WriteLine(s));
}
```

`Filter`関数を使って`IObservable`を作った後に`Subscribe`しているだけです。

ここまでは特に問題がないのですがプログラムが巨大になっていく中で`Observable`に値を流しているはずなのに最終的な場所まで値がやってこないということが起こりました。

原因がよくわからず、仕方ないので値を流している部分からステップインで先に進んでいって途切れている場所を探すという手法をとることにしました。
そこでとても残念なことになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42193/fa9cf94a-c5d6-b118-c3fb-473fd3e95661.png)

この`Filter`を呼び出したのが誰なのかが全く分かりません。
スタックトレースも全く役に立ちません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42193/a35fb81a-247b-7c83-12e0-4913276912a7.png)

この状況で誰が`Filter`を呼び出したのか(=誰がSubscribe)しているのかをどうにかして探し出す必要がありました。
色々考えましたが最終的には以下のように`Filter`関数を改造しました。

```csharp
public static IObservable<string> Filter(this IObservable<string> source, string v)
{
    var st = Environment.StackTrace;
    return source.Where(s =>
    {
        Console.WriteLine(st);
        return s == v;
    });
}
```

`Filter`を実行したときのスタックトレースをキャプチャして表示することでどこから実行されたかが一目瞭然になりました。

## 最後に

もっといい方法があれば教えてください。
CentOS7でMySQL5.7のパスワードリセット

MySQLが異常終了した際に何故か今まで出来ていたログイン方法では接続ができなくなってしまった際に対応した際のメモ。**rootです。**

`mysql_secure_installation`で設定したパスワードや初期パスワードでも以下のエラーになった。

```
ERROR 1045 (28000): Access denied for user
```

[Change mysql root password on Centos7](https://stackoverflow.com/questions/33510184/change-mysql-root-password-on-centos7#answer-34207996)

オプションを設定して起動

```
systemctl stop mysqld

systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"

systemctl start mysqld

mysql -u root
```

更新

```sql
UPDATE mysql.user SET authentication_string = PASSWORD('再設定するパスワード') WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;
exit
```

更新（5.7.6以降では以下を推奨）

```sql
ALTER USER 'root'@'localhost' IDENTIFIED BY '再設定するパスワード';
exit
```

オプションをクリアして起動

```
systemctl stop mysqld

systemctl unset-environment MYSQLD_OPTS

systemctl start mysqld
```
cloud9 (node)でvue.jsの環境構築を行った際のメモ

cloud9にvue.jsをcliで環境構築した際の手順と遭遇したエラー

```
vue-cliのインストール
$ npm i -g vue-cli

$ vue init webpack アプリ名
([webpackの部分は他にも指定できる](https://qiita.com/h_plum/items/86b8a6a86ac0fea8a4d1)）

$ cd アプリ名
$ npm run dev
```

リンクがコンソールにでるのでアクセスする。

別タブでアクセスすると、警告ページが表示された。

調べたら何パターンか対処法があったのでメモ。
(最終的に警告のボタンを押したらなおったような気もする...)

[対処法１]
以下でセットアップした場合。
$ vue init webpack アプリ名

次のファイルがあるかと思うので修正する
/build/webpack.dev.conf.js

修正方法
https://terraria64.hatenablog.com/entry/2018/05/31/150602

[対処法２]
package.jsonのscriptsのdevを修正する

修正方法
https://forum.freecodecamp.org/t/how-to-run-vue-cli-webpack-template-on-cloud-9/159500/3


[対処法3]
以下でセットアップした場合。
$ vue init webpack-simple アプリ名

以下のファイルのDocumentRootを修正する
/etc/apache2/sites-enabled/001-cloud9.conf

修正方法
http://noifuji.hateblo.jp/entry/2017/12/14/111758

次のファイルは存在しないようだ...
/build/webpack.dev.conf.js


対処法を試すと、コンソールにhoge:8081とリンクが表示されるようになる...
hoge:8080でアクセスすると表示された。

とりあえず、忘れないようにメモ。
物体検出（ssd）で顔のきりとりを自動化したい。２

前回
https://qiita.com/mokoenator/items/4d106d682f1b4bc7d0e3
からの続き


#途中経過

普通はグラフを書いて過学習や！！とか書くんですかね。
イメージの数とepochでどんなかんじなのか？見てみたくなった。
画像内の黄色がアウター、ピンクがトップス、青がフェイス、明るい緑がパンツ、くらい緑がバッグ
いつもの　ぱくたそ
350イメージ19epoch
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/185049/4af0d1a3-6d70-e21b-a893-af86db19b434.jpeg)

1300イメージ11epoch
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/185049/85a96e98-d550-4f14-2b38-23b5cb4accf6.jpeg)

1300イメージ52epoch
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/185049/c4408f35-cc22-7ea3-16c9-a78c3ec118fe.jpeg)

1300イメージ81epoch
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/185049/91c090c4-99a3-8765-0b3f-e29cf8541196.jpeg)

イラスト屋1300イメージ81epoch　　拳がhat!
![7.jpg](https://qiita-image-store.s3.amazonaws.com/0/185049/0016aecb-b7fa-e4c4-9ed7-1d4215e8e06b.jpeg)

学習曲線
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/185049/dce2f2e1-e9e9-5542-d382-0caca2300acc.png)
lossの曲線。赤色が検証の線、赤色が学習の線。
ちょうど4日かかって120epochおわりました。学習につかった画像数は1300です。
80epochで過学習してる
NNだと0になるように目指すんですけど、SSDはどえらいでかい。
ssd300_pascal_07+12_loss_history.pngと比べてもこんなもんかと。。
VOCの学習うファイルが27000ファイルくらいなので、今の20倍頑張る必要がある。



#いろいろ分かったこと
ハード面
・とにかく重い。
・CPUの負担が大きいのでGTX1070Tiを0%~50%くらいしか使えない（画像数が多いとGPUの使用率は下がる）
・複数のGPUに割ることはできるけどモデルがCPUにいないので保存ができない（コールバックでのやり方がわからなかった）
・低速CPUでは複数のGPUに割るメリットがGPU熱の分散しかない（ハイスペックなCPUが使えれば・・・）
・CPUオンリーとGPUの比較をしてみた。画像1300枚で必要な1epochに必要な時間が
・・CPU i5 7500,GPU GTX-1070ti,メモリ 24Gで32分
・・CPU i7 7500U,GPUなし,メモリ 16Gで33時間（ノートPCです）
もう・・・話になりませんね。

・メモリのデュアルチャネルを舐めちゃダメだ！適当にメモリさしてたけど、挿し直したら１５％くらい早くなった。(´･ω･`)ん？ってことは、メモリ転送がボトルネックですか？？


ソフト面
・このモデル？SSDはマルチコア分ちゃんと働いてるっぽい（確証なし）
・アノテーションの過不足、ミスが多いので何度でも見直しが必要
・・とくに多いのが付けモレ、次が１枠に二つ付けてしまう「バッグ＋パンツ」みたいな。

・サイクルを早く回すために色々自動化する
・こまかくアノテーションフォルダを分けておくと精神的に楽
・こまかくわかれるので、学習コードを変えてられない。工夫する

・たまにlossが大きくなってとまってしまう・・・なんでだろ・・再実行すると普通に動く

・VoTTで見えないタグができたことがあり、保存できなくなった。JSONを直接開いて修正した。

精神面
・つらい…(´ω｀)
・つらい(´･ω･`)
・なんのためにやっているか？初心を思い出す(´・ω・｀)
・うまくいかないときは、うまくいかないのでツライ
・うまくいくと鳥肌級の感動が味わえる

#写真集めるのがつらい
顔さえ認識していればよかったはずなのに・・・・ファッションを区別することに注力することになるとは。
写真を集めるって結構つらいんです。
おなじ画像を落としてきちゃったりします。

で・・・動画を集めます。
車に積んだドライブレコーダー、フリーの動画、携帯とかに入ってる動画などなど。
これをopen cvで１秒１フレームで切り出して保存する。１分の動画なら６０枚出来上がる。
とりあえず洋服が動いているのでロバストは獲得できるんじゃないかと思う。


#教師データの作成サイクルを早くするために
教師データは宝！
教師データを大量に作るには・・・機械学習で作る！
１００枚学習して、次の１００を推論させ箱データをJSONに保存。
VoTTに読ませる。
（画像が入ったディレクトリと同じ名前.jsonで保存しておけばいい）
VoTTで人間が修正、追加を行う。
これを繰り返す。
これだけでかなり楽になるけど・・・それでも、まだ鬼畜。

ちなみに・・繰り返すたびに精度があるとおもうけど、壁がある。
画像が増える毎に学習時間も増える。

機械学習は生活サイクルに大きく影響するということが分かった…(´ω｀)
１：会社から帰る
２：１００枚を推定させる
３：教師データの作成（修正）
４：学習開始
５：別PCで画像あつめ、プログラムの見直し、ツール作成など
６：寝る
７：おきて学習を止めてデキを確認する
８：会社に行くのでPCを落とす

あたりまえだけど・・・確保できる時間しか学習ができない。
自分の環境では１０００枚くらいから、lossが下がらなくなってきた。
時間不足(´･ω･`)（５時間くらいしかない）

なので、会社に行く時間もPCを回すことになる。
けど・・そのうちまた壁がでてきてしまう！

少しでも時間が削れるなら、お金をかけて良いCPU,GPUを買った方が勝ちなんだと思う。

#感想
箱書きすぎて腕が痛くなるのでマウス変えようかな
(´･ω･`)

モデルは他人の物を利用してるけれども、一から作るって結構強いかもしれない。
教師データはたまるし、周辺のツールも作ったり試行錯誤の積み重ねが効いてる感じがします。
別のことに転用したい場合でも応用がきくので楽しいです。

つづき
https://qiita.com/mokoenator/items/d84226dc40d38448322e
Metatrader4プロセスが起動してなかったら、自動的に起動する仕組みを構築する

VPSサーバ上でMetatrader4を運用していると、WindowsUpdateや運用側のメンテナンス等でOSの再起動が発生し、思わぬことでMetatrader4が停止してしまうことがある。
EAを安定稼働させるため、Metatrader4のプロセスを定期的に監視し、プロセスが起動してなかったら自動的に起動する仕組みを考えた。

VPSサーバはWindows OSなので、まずはバッチプログラムでMetatrader4のプロセスを監視するプログラムを書いた。
簡単なプログラムだが、プロセスが起動してなかったら、自動的に起動する処理を実装した。

```
@echo off 
rem 
rem Metatrader4のプロセスをチェックし、
rem 存在していなかったらプロセスを起動
rem
rem                                                ぶしちゃ

rem ★起動させたいMT4の実行ファイル名とパスを設定★
set APP_NAME=terminal.exe
set APP_FOLDER=C:\Program Files (x86)\FXTF MT4\
  
rem プロセスが起動しているかどうかを、tasklist コマンドでチェック   
for /f %%i in ('tasklist /FI "IMAGENAME eq %APP_NAME%" 2^>^&1') do (  
    if /i %%i == %APP_NAME% (
        echo Metatrader4は既に起動済みです。
        goto ENDLOOP;
    )
)

rem 起動してなければ起動する
echo Metatrader4を起動します。
start " " "%APP_FOLDER%%APP_NAME%"

rem 起動済みであれば何もせずに終了
:ENDLOOP  
```


このバッチプログラムを、タスクスケジューラを使って定期的に実行してやれば、Metatrader4が停止しても、自動的に起動してくれるから安心。

＜参考：タスクスケジューラの使い方＞
https://qiita.com/Richard_Roe/items/44e16841f16ee40c6113
http://www.atmarkit.co.jp/ait/articles/1305/31/news049.html
Apache mod_proxy で HTTPS を含めたフォワードプロキシ

ちと、某所で mod_proxy による HTTPS の終了処理が意図通りにいかないという話があり、家で試してみたくてやってみました。

事象の再現にはいたりませんでしたが、色々と残しておこうと思います。

## 環境

プロキシサーバ

* CentOS 6
* Apache 2.2.15
* mod_proxy, mod_proxy_connect

クライアント

* CentOS 6
* wget 1.12

## フォワードプロキシの構築

HTTP プロキシのための mod_proxy と、HTTPS プロキシのための mod_proxy_connect をそれぞれ利用しました。

httpd.conf の設定は、主に下記の部分を変更。

```text:httpd.conf
Listen 80
Listen 443
・・・
<IfModule mod_proxy.c>
ProxyRequests On
ProxyVia On
AllowCONNECT 443 # 443 ポートで CONNECT メソッドを許可

<Proxy *>
    Order allow,deny
    Allow from all
</Proxy>
```

参考：https://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html

## wget での設定

~/.wgetrc に、プロキシサーバを指定してやるだけです。

```text:.wgetrc
http_proxy=http://xxx.xxx.xxx.xxx/
https_proxy=https://xxx.xxx.xxx.xxx/
```

## 試す

```text
$ wget http://www.google.com
$ wget https://www.google.com
```

## KeepAlive を無効にしてみたい

また、今回は Keepalive を無効にしたかったので、wget の man を見つつ、下記のコマンドも実行。

```text
$ wget --no-http-keep-alive http://www.google.com
```

しかし、パケットを見る限り、クライアントからのリクエストヘッダには `Connection` 属性は指定が無いものの、プロキシサーバからのリクエストヘッダに `Connection: Keep-Alive` と付いていました…

とりあえずプロキシサーバ側で何とかならないかな？　と思い、調べると[オプションがある](http://luozengbin.github.io/blog/2014-10-29-%5B%E3%83%A1%E3%83%A2%5Dapache%E3%81%A7backend%E3%81%A8%E3%81%AEkeepalive%E3%82%92off%E3%81%AB%E3%81%99%E3%82%8B.html)そうなので、設定。


```text:httpd.conf
<Proxy *>
    Order allow,deny
    Allow from all
    SetEnv proxy-nokeepalive 1
</Proxy>
```

パケットで確認したところ、プロキシサーバからのリクエストヘッダには `Connection: close` と付いていました。成功。
Webアプリを公開するなら

バイト疲労困憊　力を振り絞って　アドベントカレンダー n+1回目
大学内でWebアプリ公開方法の勉強会があったので、軽くまとめてみました。


## 1.ベアメタル　自宅サーバ
- **ISPからグローバルIPアドレスを取得**
**IPS**とは、サーバやネットワークの外部との通信を監視し、侵入の試みなど不正なアクセスを検知し攻撃を未然に防ぐシステム。

- **PCにOSとHTTPサーバをインストール**
Webサーバーの代表的な例としてApacheとNginxとIISが存在します。Webサーバソフトウェアの中でも、世界中で利用されているツールが「Apache」です。
- **ルータでネットワーク設定**
- **Webアプリケーションを開発、PCに配置**

## 2.レンタルサーバVPS: Virtual Private Server
- プロバイダーのサーバを定額で利用するものが多い
[レンタルサーバとプロバイダーの違い](https://webdirect.tanomail.com/alphamail/guide/provider.html)

- SSHでログインするものやFTPでファイルを受送信するものがある。
- 無料版もある
- 月数百円の有料サービスもある
- PHPは動くが、CGIは動かないものが多い
- PHPはHTMLにスクリプトを記述することでWebアプリケーションを構築する。JavaのJSPのようなもの。

<余談>

```
php -S localhost:8080
```
このコマンドを叩くだけで簡易サーバを起動することができたりする。

<こんなレンタルサーバーあった>
[【2018年版】無料レンタルサーバーおすすめランキング](https://xn--t8j4aa4ntgvb8c2dre1cxqka5g3fb2887p2be232esy9i.com/post-1137)
[SAKURA internet](https://www.sakura.ne.jp/)
## 3.クラウド laaS,PaaS,SaaS
- [AWS ](https://aws.amazon.com/jp/)(Amazon Web Service)
  - [Amazon EC2](https://aws.amazon.com/jp/ec2/)：IaaS, SSHでログインしてサーバを管理
  - [Elastic Beanstalk](https://aws.amazon.com/jp/elasticbeanstalk/)：PaaS, Warファイルをサーバにアップロードすれば、Webアプリケーションが起動

* [IBM Cloud(Bluemix)](https://www.ibm.com/cloud-computing/jp/ja/bluemix/)

* [Heroku](https://www.heroku.com/home)
PaaS, 多様な言語でwebアプリケーションを開発できる。
herokuコマンドを用いて、開発したwebアプリケーションをサーバーに配置できる。
制約550時間/月

##　癒やしコード(本記事の内容とは関係ないです)

```
import requests
import sys

print(('うまるを知りたいですか？＞はい'))
title = '干物妹!うまるちゃん'

url = 'https://ja.wikipedia.org/w/api.php'

api_params1 = {
    'action':'query',
    'titles':title,
    'prop':'categories',
    'format':'json'
}

api_params2 = {
    'action':'query',
    'titles':title,
    'prop':'revisions',
    'rvprop':'content',
    'format':'xmlfm'
}

categories = requests.get(url, params = api_params1).json()
page_id = categories['query']['pages']

if '-1' in page_id:
    print('該当するページがありません')
    sys.exit()
else:
    id = list(page_id.keys())
    if 'categories' in categories['query']['pages'][id[0]]:
        categories = categories['query']['pages'][id[0]]['categories']
        for umr in categories:
            print(umr['title'])
    else:
        print('保存できるページを検索できませんでした')
        sys.exit()

print('うまるの情報を保存しますか？＞はい')
user_responce = 'yes'

if user_responce == 'yes':
    data = requests.get(url, params = api_params2)
    with open(title + '.html', 'w', encoding = 'utf_8') as f:
        f.write(data.text)
```
このスクリプトの説明したかったのですが、眠気が、、、、。
実行するときは自己責任でお願いします。
では(⌒ー⌒)/

## 参考文献
[SSLとTLSの違いとは｜SAKURA internet](https://ssl.sakura.ad.jp/column/ssl_tls/)
[IPS｜IT用語時点e-Words](http://e-words.jp/w/IPS.html)
[グローバルIPアドレスとは｜クラウド・データセンター用語集](https://www.idcf.jp/words/global-ip.html)
[初心者でもできる！Apacheをインストールする方法](https://techacademy.jp/magazine/1846)
[[ためーる]レンタルサーバーとプロバイダー｜アルファメール](https://webdirect.tanomail.com/alphamail/guide/provider.html)
【Unity】Skyboxでレイマーチング

UnityのSkyboxシェーダーでレイマーチングをしてみました。

Skyboxシェーダーでは視線方向を`TEXCOORD0`で、カメラ位置を`_WorldSpaceCameraPos`を取得できるので、そのあたりを自分で計算せずにすぐにレイを飛ばすことができます。

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/61569/5f1b0218-dab7-f1ff-7029-792fc4d7df5e.gif)

Skyboxシェーダーの書き方自体は私が以前書いた記事を参考にしてください。
[【Unity】Skyboxシェーダーの書き方 \- Qiita](https://qiita.com/aa_debdeb/items/2739745b3ab1a003d767)

やっていること自体はよくあるレイマーチングなので説明は割愛します。

```Raymarching.Shader
Shader "Skybox/Raymarching"
{
	SubShader
	{
		Tags
		{
			"RenderType"="Background"
			"Queue"="Background"
			"PreviewType"="SkyBox"
		}

		Pass
		{
			ZWrite Off
			Cull Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			struct appdata
			{
				float4 vertex : POSITION;
				float3 rayDir : TEXCOORD0;
			};

			struct v2f 
			{
				float4 vertex : SV_POSITION;
				float3 rayDir : TEXCOORD0;
			};

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.rayDir = v.rayDir;
				return o;
			}

			float sphere(float3 pos, float radius)
			{
				return length(pos) - radius;
			}

			float3 repeat(float3 pos, float3 span)
			{
				return abs(fmod(pos, span)) - span * 0.5;
			}

			float getDistance(float3 pos)
			{
				return sphere(repeat(pos, 10.0), 1.0f);
			}

			float3 getNormal(float3 pos) {
				float d = 0.001;
				return normalize(float3(
					getDistance(pos + float3(d, 0, 0)) - getDistance(pos + float3(-d, 0, 0)),
					getDistance(pos + float3(0, d, 0)) - getDistance(pos + float3(0, -d, 0)),
					getDistance(pos + float3(0, 0, d)) - getDistance(pos + float3(0, 0, -d))
				));
			}

			float3 raymarch(float3 cameraPos, float3 rayDir)
			{
				float3 pos = cameraPos;
				for (int i = 0; i < 200; i++) {
					float d = getDistance(pos);
					pos += d * rayDir;
					if (d < 0.001) {
						return getNormal(pos) * 0.5 + 0.5;
					}
				}
				return 0;
			}

			fixed4 frag (v2f i) : SV_TARGET
			{
				float3 rayDir = normalize(i.rayDir);
				return fixed4(raymarch(_WorldSpaceCameraPos, rayDir), 1.0);
			}

			ENDCG
		}
	}
}
```
Swift Array型いろいろ

#環境
swift4

#初期化
空の配列の宣言

```swift
var array1 = Array()
var array2:Array<Int> = []
var array3:[Int] = []
var array4 = [String]()

var array5 = [] // 型宣言なしはエラー
```

同じ値を指定要素数分で初期化

```swift
Array(repeating: 初期値, count: 要素数)

var array = Array(repeating: 0, count: 5)
print(array)
// [0, 0, 0, 0, 0]
```

#値の変更
指定した場所の値を変更する

```swift
var array = ["Japan", "USA", "France"]
array[2] = "Brazil"
// ["Japan", "USA", "Brazil"]
```

#要素の削除
配列の順番を指定して要素を削除する

```swift
var array = ["Japan", "USA", "France"]
array.remove(at: 1) 
// ["Japan", "France"]
```



#番号を取得
配列の中に格納されている値の場所を返す

```swift
var array = ["s", "w", "i", "f", "t"]
array.index(of: "f") // 3
```

#型変換
配列→文字列

```swift
var arrayChara:[Character] = ["s", "w", "i", "f", "t"]
var arrayStr = String(arrayChara)
print(arrayStr)
// swift
```
Pythonで競プロに挑む日誌 vol.1 ~はじめの一歩~

# はじめに

製造業のハードウェア開発・製造に7年携わってきました。新たな刺激を求めてソフトウェア（というかプログラミング）に挑戦していきます。

# 目標
* AtCoder をはじめる
* 今年の10月内に茶色を取得する
* 年内に緑色を取得する
* [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

**参考サイト**
[AtCoder レート](https://atcoder.jp/post/14)
[AtCoderで緑色になりました。](https://asdf1.hatenablog.com/entry/2018/04/15/135055)
[AtCoder 灰色・茶色・緑色・水色になるまでやったこと](https://dynamis724.hatenablog.com/entry/2018/06/24/171903)

# 日誌の内容
その日に解いた問題の感想や困ったこと, 解決策, 気づきを記録します。
同じように挑戦しようとしている人の参考になれば幸甚です。

# 更新頻度
ほぼ毎日

----
さて、前置き長くなりましたが今日の日誌です。
# 本日の問題
### はじめてのあっとこーだー
https://beta.atcoder.jp/contests/abs/tasks/practice_1
一連の操作を把握するためだけの問題。コピペして提出するだけなので省略。

### ABC086A - Product
https://beta.atcoder.jp/contests/abs/tasks/abc086_a
**結果(0点)**

```NG.py
a, b = map(int, input().strip().split())
if (a+b) % 2 == 0:
    print("Even")
else:
    print("Odd")
```

**修正後（100点）**

```OK.py
a, b = map(int, input().strip().split())
if (a*b) % 2 == 0:
    print("Even")
else:
    print("Odd")
```
「a と b の和」ではなく、「a と b の積」を求める問題じゃん。。。
「問題文きちんと読みましょう」というありきたりなイージーミスをかましました。

# 明日やること
[ABC081A - Placing Marbles](https://beta.atcoder.jp/contests/abs/tasks/abc081_a) を解く。
QiitaのOrganization一覧をスクレイピングで取得する

# はじめに
気になる企業がQiitaのOrganization一覧に登録されているか探す場合、１ページに表示される件数は最大20件で、全部で29ページ（※）あります。QiitaのOrganization一覧はデフォルトで「1週間の活動量」が高い順にソートされますが、さすがに1ページずつ見るのは大変なので、スクレイピングして会社名とQiitaのOrganizationのURLを取得するプログラムを作りました。

![スクリーンショット 2018-08-29 00.43.08.png](https://qiita-image-store.s3.amazonaws.com/0/221759/31065a5a-8957-b1be-7474-0790190a5258.png)

（※）本記事執筆時点

## プログラム

- qiita_organizations.py

```python
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

# スクレイピングに必要なモジュールをインポート
import urllib.request as req
import sys
sys.path.append('/home/pi/.local/lib/python3.5/site-packages/')
from bs4 import BeautifulSoup
import time
import re

num = 1

# Organization一覧のurlを取得する関数
def urlget():
    url = "https://qiita.com/organizations?page="
    res = req.urlopen(url+str(num))
    data = res.read()
    text = data.decode("utf-8")
    soup = BeautifulSoup(text, "lxml") 
    org = soup.find_all(href=re.compile(r"^/organizations/"))
    for list in org:
        co = list.string
        href = list.attrs["href"]
        if co != None:
            print(co, "," "https://qiita.com"+href)

# 最後のページまでループ
while num < 30:
    urlget()
    num += 1
    time.sleep(1)
```

## 使い方

環境：Linux

- 標準出力

```bash
# python3 qiita_organizations.py
ShouldBee ,https://qiita.com/organizations/shouldbee
株式会社インフィニットループ ,https://qiita.com/organizations/infiniteloop
IoTLT ,https://qiita.com/organizations/iotlt
インフラ勉強会 ,https://qiita.com/organizations/infra-workshop
アイレット株式会社(cloudpack) ,https://qiita.com/organizations/cloudpack
株式会社Mewcket ,https://qiita.com/organizations/mewcket
株式会社ベーシック ,https://qiita.com/organizations/basicinc
リコーITソリューションズ株式会社 ,https://qiita.com/organizations/jrits
株式会社Fusic ,https://qiita.com/organizations/fusic
ウォーターセル株式会社 ,https://qiita.com/organizations/water-cell
株式会社ゆめみ ,https://qiita.com/organizations/yumemi
TIS株式会社 ,https://qiita.com/organizations/tis
株式会社エアークローゼット（airCloset） ,https://qiita.com/organizations/aircloset
RHEMS技術研究室 ,https://qiita.com/organizations/rhems-japan
ALIS Co., Ltd. ,https://qiita.com/organizations/alis
株式会社サイバーエージェント ,https://qiita.com/organizations/cyberagent
株式会社グロービス ,https://qiita.com/organizations/globis
株式会社ミライトデザイン ,https://qiita.com/organizations/miraito-inc
ピクシブ株式会社 ,https://qiita.com/organizations/pixiv
株式会社ムラサメ研究所 ,https://qiita.com/organizations/murasame
```

- CSVファイルに保存

```bash
# python3 qiita_organizations.py > qiita_organizations.csv
```

プログラム内でわざわざcsvモジュールをインポートしなくても、リダイレクトすれば簡単です。

- 作成されたファイルを確認

```bash
# wc -l qiita_organizations.csv 
572 qiita_organizations.csv
```
(1ページ20件 * 28ページ) + 29ページの12件で、572企業（※）が登録されているので、ピッタシです。

（※）本記事執筆時点

# さいごに
[Qiita公式ブログ（2018/8/28）](https://blog.qiita.com/day/2018/08/28/)でもちょうどタイムリーな話題になっていたましたが、QiitaのOrganizationの登録申請が増えているようです。

どのような会社なのか判断材料として、QiitaのOrganization一覧はいいですね。
就職活動中の学生、転職活動中のエンジニアにどうぞ。

[Git](https://github.com/Brutus03/Qiita)はこちら。
Vue CLI 3 で PWA のアプリつくって GitHubPages で公開

## 概要

- Vue CLI のバージョン 3 が出て，PWA とかを簡単に入れられるようになったので試しました
- GitHub Pages に上げるだけだと [ガイドにも書いてある](https://cli.vuejs.org/guide/deployment.html#github-pages) のですが，PWA への対応もしてみました

## 準備

### Vue CLI 3 を入れる
- 2.x が入っているときは一度アンインストールしてから `@vue/cli` をインストール
    - 詳しくは [Vue CLI のガイド](https://cli.vuejs.org/guide/) を参照
- 書いた時点での Vue CLI のバージョンは 3.0.1 です


### プロジェクトを作る
1. `$ vue create pwa-sample` を実行（`pwa-sample` は任意のプロジェクト名）
2. `Please pick a preset` と表示されるので，`Manually select features` を選択
3. 下のような画面になるので， PWA を選択しておく（スペースで切替） 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/209425/a0090acf-174a-540b-91c4-193574e18d68.png)
4. 後は好きな設定でプロジェクトを作成する

## GitHubPages への対応
１. ルートディレクトリに `vue.config.js` を作成し，次を記述

```vue.config.js
module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/pwa-sample/'
    : '/',
  outputDir: 'docs',
};
```

２. `/public/manifest.json` のパスを相対パスに修正

```manifest.json
{
  ...
  "icons": [
    {
      "src": "./img/icons/android-chrome-192x192.png", //ここ
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "./img/icons/android-chrome-512x512.png", //ここ
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "./index.html", //ここ
  ...
}
```

３. ビルドする（`npm run build` or `yarn build`）
４. GitHub に Publish する
５. GitHub の Publish 先のリポジトリの Settings の GitHub Pages の Source の項目を None → master brunch /docs folder に変更


## まとめ

GitHub Pages への対応として `manifest.json` のパスを修正する以外は、基本的に Vue CLI が全部やってくれます。CLIすごい:laughing:
テスト項目書を書くときのポリシー

# テストケースの範囲

今日、テスト仕様書を書くときに、テスト範囲が分からない。
この項目はどっちなのか？同じテストケースが被っていてよいのか
というような質問を受けた。

だが、その質問は根本的に間違っている！と思ったので、図解してみる。
![Scrum_test.jpg](https://qiita-image-store.s3.amazonaws.com/0/283248/f39d5d65-a2a1-afcf-23f8-919c044407dc.jpeg)


要するにだ。先の質問は完全なるテストケース100％が分かっていて、どのテスト項目書に振り分けるのか、という質問だ。
しかし、**100％のテストケースは神しか知らない。**

だから、「振り分けることなんてできない。」が答えだ。

システム開発は、不確実性へ立ち向かう仕事である。
その為の施策として、複数の視点や前提からテスト項目を洗い出しリストアップするのだ。

おおざっぱに言うと
90％の単体テスト　×　90％の結合テスト　⇒　未テスト率1％という感じだ。

# テスト項目書の種類
テスト項目書の種類、および意味の定義はプロジェクトによりマチマチだ。
正解を定めている非営利団体などもない。
参考に、私が経験してきたプロジェクトでのテスト項目書の視点・前提を書いておく。

・単体テスト　＝　プログラマ視点
・結合テスト　＝　開発チーム視点
・総合テスト　＝　ユーザ視点
・ユーザテスト　＝　ユーザ視点（簡略化。デモ向け。）
・モンキーテスト　＝　ウキキッー！！（つまり、何度も同じボタンを押したり、注意書きの内容と逆のことをしたり思いつくまま激しく操作。項目書は作らない。）
SoundPoolで「Sample 1 not READY」と出た時の対応

# はじめに
SoundPoolを使って音楽を再生する時、

```Kotlin:
val id = soundPool.load(context, R.raw.hoge1, 1)
soundPool.play(id, 1.0F, 1.0F, 0, 0, 1.0F)
```

のように、音楽ファイルを読み込んでから再生します。

しかし、以下のようにWarningが出て、音楽が再生されない場合があります。

```Bash:
W/SoundPool: sample 1 not READY
```

Warningが出てしまう原因は、`soundPool.load()`による音楽ファイルの読み込みが完了していないためです。

# 対策
`soundPool.load()`の完了を待つには、`soundPool.setOnLoadCompleteListener`を使います。
loadが完了するとこのリスナーが呼ばれる仕組みです。

```Kotlin:
val id = soundPool.load(context, R.raw.hoge1, 1)
soundPool.setOnLoadCompleteListener { soundPool, sampleId, status ->
    // status = 0 でロード成功したことを表す
    if (status == 0) {
        soundPool.play(sampleId, 1.0F, 1.0F, 0, 0, 1.0F)
    }
}
```

　
　
　
また、複数の音楽ファイルを読み込む場合は個別処理ができます。
「いつでも再生できるよ」とユーザーに通知してあげることもできます。

```Kotlin:
val firstId = soundPool.load(context, R.raw.hoge1, 1)
val secondId = soundPool.load(context, R.raw.hoge2, 1)
soundPool.setOnLoadCompleteListener { soundPool, sampleId, status ->
    if (status == 0) {
        when (sampleId) {
            firstId -> soundPool.play(sampleId, 1.0F, 1.0F, 0, 0, 1.0F)
            secondId -> Toast.makeText(this, "READY secondId", Toast.LENGTH_SHORT)
        }
    }
}
```

これで安全に音楽ファイルを再生することができます！
PythonでXMLのタグを外す

タグ単位で削除するやり方はすぐ見つかったのですが、
タグ部分を削除して内部のテキストだけを残すやり方がなかなか見つからなかったのでメモ。

正規表現で削除するのは改行とか面倒そうだし、さすがにXMLParserがあるだろうということでやめました
ドキュメントを探した結果、以下のように行うのがよさそうです。

```python:strip_tags.py
import xml.etree.ElementTree as ET
import codecs

tree = ET.parse('data.xml')
root = tree.getroot()
notags = ET.tostring(root, method='text')
notags = notags.decode('utf8')

with codecs.open('notags.txt', 'w', 'utf8') as f:
    f.write(notags)
```

実行例

```xml:data.xml
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
```

```notags.txt

    
        1
        2008
        141100
        
        
    
    
        4
        2011
        59900
        
    
    
        68
        2011
        13600
        
        
    
```

改行やスペースはそのまま残ります。
必要に応じて適宜再変換をかければよさそうです。
上記ではrootを指定しているので、全体についてのタグ以外テキストが取れますが、
root以外のelementを指定すればそのタグ内のテキストだけが取れます。

思っていたとおり標準モジュールでできたのですが、
リファレンスに詳細が書かれていないので見つけるのに時間がかかりました。


参考
https://docs.python.jp/3/library/xml.etree.elementtree.html
xml.etree.ElementTree.tostringの項目に

>method は "xml", "html", "text" のいずれか(デフォルトは "xml") です。

と書いてあるがそれぞれ設定したらどうなるのかは書かれていない。。。
glogでDebug用ログ出力の関数を作るときの注意点

## 結論

以下のように、`DEBUG`環境変数が設定されているときに、ログ出力するような関数を定義した場合は、glog.XxxDepth(例ではglog.InfoDepth)を使いましょう。


```go
package main

import (
	"flag"
	"fmt"
	"github.com/golang/glog"
	"os"
)

func DebugLog(v interface{}) {
	if os.Getenv("DEBUG") != "" {
		glog.InfoDepth(1, fmt.Sprintf("%#v", v))
	}
}

func main() {
	flag.Set("stderrthreshold", "INFO")
	flag.Parse()
	os.Setenv("DEBUG", "1")
	DebugLog("hoge") // ここが20行目
	DebugLog("fuga") // ここが21行目
}
```

出力結果は以下のようになります。

```
I0829 22:47:11.932758   24176 main.go:20] "hoge"
I0829 22:55:36.233685   24681 main.go:21] "fuga"
```

出力場所として、`main.go:20` `main.go:21` が情報として含まれていますね。多くの場合、`DebugLog("hoge")`や`DebugLog("fuga")`が記述されている行数を出力して欲しいので、意図通りとなっています。


## InfoDepthの代わりにInfoを使うとどうなるのか

以下のように `Info関数`を使うとどうなるかを示します。

```go
package main

import (
	"flag"
	"fmt"
	"github.com/golang/glog"
	"os"
)

func DebugLog(v interface{}) {
	if os.Getenv("DEBUG") != "" {
		glog.Info(fmt.Sprintf("%#v", v))  // ここが12行目
	}
}

func main() {
	flag.Set("stderrthreshold", "INFO")
	flag.Parse()
	os.Setenv("DEBUG", "1")
	DebugLog("hoge")
	DebugLog("fuga")
}
```

出力結果は以下のようになります。

```
I0829 22:57:00.569297   24777 main.go:12] "hoge"
I0829 22:57:00.569872   24777 main.go:12] "fuga"
```

はい、`hoge` の出力も `fuga`の出力も`main.go:12`として出力されてしまっています。つまり `glog.Info`を呼び出している箇所ですね。これが `InfoDepth`を使う理由となっています。
事前バインディングと実行時バインディングでWithの挙動が変わる事例

VBAのWithステートメントにオブジェクトを指定したときの話です。

指定したオブジェクトが事前バインディングされている場合、実行時バインディングされている場合、で挙動が変わる事例があったため、備忘録として残します。

# 確認環境

Windows 10 Pro 64bit
Microsoft Excel 2016 64bit

# サンプル

動作としては、一時ファイルを作成、`TextStream`として開き、その後削除するコードです。

## 事前バインディングの場合

`TextStream`を明示的に`Close()`していませんが、`End With`のステートメント実行時に参照が解放され、ファイルを削除できます。

実行には`Microsoft Scripting Runtime`の参照設定が必要です。

```vb:EarlyBinding
'require Microsoft Scripting Runtime
Private Sub SampleEarlyBinding()
    Dim fso As Scripting.FileSystemObject
    Set fso = VBA.CreateObject("Scripting.FileSystemObject")
    
    Dim tempFilePath As String
    tempFilePath = fso.BuildPath(VBA.Environ$("TEMP"), fso.GetTempName())
    
    With fso.CreateTextFile(tempFilePath)
        'ファイルを開いているので削除できない
        'Call fso.DeleteFile(tempFilePath, Force:=True)
    End With
    
    '事前バインディングなら削除できる
    Call fso.DeleteFile(tempFilePath, Force:=True)
    
End Sub
```

## 実行時バインディングの場合

基本的には先ほどのコードの`fso`の型宣言を`Object`に変更しただけです。

このコードを実行すると、コメントアウトされていない
`Call fso.DeleteFile(tempFilePath, Force:=True)`
の行でエラーが発生します（ファイルへの参照を解放できていない）。

この時、このプロシージャ内で参照を解放する方法はなさそうです。
プロシージャを抜ければ問題なく削除できるようになります（参照が解放される）。

```vb:LateBinding
Private Sub SampleLateBinding()
    Dim fso As Object 'As Scripting.FileSystemObject
    Set fso = VBA.CreateObject("Scripting.FileSystemObject")
    
    Dim tempFilePath As String
    tempFilePath = fso.BuildPath(VBA.Environ$("TEMP"), fso.GetTempName())
    
    With fso.CreateTextFile(tempFilePath)
        'ファイルを開いているので削除できない
        'Call fso.DeleteFile(tempFilePath, Force:=True)
    End With
    
    '遅延バインディングではエラーになる
    Call fso.DeleteFile(tempFilePath, Force:=True)
    
    '手動削除用（デバッグ時にCtrl+F9で実行行を変更可能）
    Call VBA.Shell("explorer.exe /select," & tempFilePath, vbNormalFocus)
    
End Sub
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/142842/47d6c708-6122-5fb0-e03c-521fc150e25f.png)

## 参考：`With`を使用しない場合

実行時バインディングでも、以下のように一行で記述した場合は問題なく参照を解放できます。
`Call fso.CreateTextFile(tempFilePath).Write("Hello!")`


```vb:NoUseWith
Private Sub NoUseWith()
    Dim fso As Object 'As Scripting.FileSystemObject
    Set fso = VBA.CreateObject("Scripting.FileSystemObject")
    
    Dim tempFilePath As String
    tempFilePath = fso.BuildPath(VBA.Environ$("TEMP"), fso.GetTempName())
    
    Call fso.CreateTextFile(tempFilePath).Write("Hello!")
    Stop 'BreakPoint ファイル存在確認用
    Call fso.DeleteFile(tempFilePath, Force:=True)
End Sub
```
【PHP】配列で渡された引数のエンコードが正しいかどうかチェックする

文字エンコードを行うユーザー定義関数`cken()`についての備忘録。

0. mb_check_encode()を使ってエンコードチェックをsamapA.phpに定義
1. foreach文で配列から値に$valueを取り出し、もし入っていた値が配列なら`impode()`を使って値を1個の文字列に連結しておいてから、`mb_check_encoding()`
2. エンコードが不一致の場合、$resultにfalseを代入してforeach文の繰り返しをブレイクする。
3. 最終的に$resultが初期値のtrueのままであれば、文字エンコードは正しく、途中でfalseが代入されていれば文字エンコードが一致していないことになる。

```samapA.php
// 
<?php 
function cken(array $data) {
  $result = true;
  foreach ($data as $key => $value) {
    if (is_array($value)) {
      $value = implode("", $value);
    }
    if (!mb_check_encoding($value)) {
      $result = false;
      break;
    }
  }
  return $result;
}
```

```php
// 表示用
<?php
require_once("./util.php");
$utf8_string = "こんにちは";
$sjis_string = mb_convert_encoding($utf8_string, 'Shift-JIS');
$encoding = mb_internal_encoding();
if (cken([$sjis_string])) {
  echo '配列の値は、' , $encoding, 'です。';
} else {
  echo '配列の値は、',$encoding, 'ではありません。';
}
```
PHP+cURLで、Qiitaに記事を投稿するプログラム

PHPで、Qiitaに記事を投稿したく、いろいろな記事を参照していたのですが、こちらの参考記事がそのままではうまく動作しませんでした。

- [PHPでQiita api v2を触ってみる \- Qiita](https://qiita.com/leafia78/items/a252a09bbdf31bf770f4)

あれこれ試行錯誤したらできました。以下、はまりやすいポイントとともに。

## SSLでの通信にする必要がある

記事では `http://qiita.com/api/v2/items`にアクセスしている例があるのですが、いつからなのか `https` でなければ投稿ができないようでした。

## Windowsの PHPで、SSLに cURLでアクセスするには証明書が必要

`https` にアクセスすると、次のようなエラーメッセージが表示されます。

```
SSL certificate problem: unable to get local issuer certificate
```

原因としては、証明書が存在しないためだそうで、`php.ini` の `curl.cainfo` に、証明書（.crt）ファイルを指定する必要があります。筆者の場合は、別途インストールしていた Gitに内蔵されていた証明書を指定して凌ぎました。

```
curl.cainfo = c:\Program Files\Git\usr\ssl\certs\ca-bundle.crt
```

## tagsの指定方法が変更され、Versionの指定ができるように

結果的に、これは投稿の成否とは関係なかったのですが、tagsには Versionsが指定できるようです。これがないから投稿ができないのかと思ったのですが、結果的には不要だったようです。

書き方としては以下の通り。タグのバージョンとはなんでしょう・・

```
    'tags' => array(array("name"=>"Ruby", "versions"=>array("0.0.1"))) //タグ
```

これでようやく投稿ができるようになりました。プログラム全文は以下。

```
<?php
$json = [
    'title' => 'テストです', //タイトル
    'body' => '#markdown', //本文
    'private' => true, //限定公開か否か
    'tags' => array(array("name"=>"Qiita", "versions"=>array("0.0.1"))) //タグ
];
$curl = curl_init('https://qiita.com/api/v2/items');

$option = [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>json_encode($json),
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer 1ee5ae2f694640a395d35dd7f71bfa24aaba2605', //アクセストークン
        'Content-Type: application/json',
    ],
];
curl_setopt_array($curl, $option);
$result = curl_exec($curl);
$errno = curl_errno($curl);
$error = curl_error($curl);

curl_close($curl);
var_dump($result);
```
Atomで正規表現を使って置換


必ず正規表現オプションを有効にすること
<img width="604" alt="スクリーンショット 2018-08-29 22.13.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/163778/388c002b-3ebe-b868-3929-56341296500b.png">
## 行末にカンマを追加したい
```
11111,22222,33333
44444,55555,66666
```
以下の様に入力する。
実行すると以下の様になる。
<img width="617" alt="スクリーンショット 2018-08-29 22.14.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/163778/ab6f7774-b494-9fed-b305-767437ed3032.png">

```
11111,22222,33333,
44444,55555,66666,
```

## 改行を無くしたい
```
11111,22222,33333,
44444,55555,66666
```
以下の様に入力する。
実行すると以下の様になる。
`¥n`と入力してもダメなので注意。
<img width="600" alt="スクリーンショット 2018-08-29 22.16.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/163778/23a0529c-189c-eedc-f707-0b8ba30ee7ed.png">

```
11111,22222,33333,,44444,55555,66666
```
Python3で対象のWebページの画像ファイルを一括ダウンロードするスクリプトをサクっと作ってみた

# 概要

Python3で対象のWebページ内に埋めこまれているimgタグのsrcをクロールしてローカルマシンにダウンロードするツールを作ってみた

# 背景

とある作業にて、対象のWebページ内で表示されている画像をまとめてダウンロードする必要があったが、全てを右クリック→保存の作業をやるにはアホらしかった(画像数が100を超えていた)為、Python3でCLIから一括ダウンロードするスクリプトを作ってみた

# 実装

## 完成系

![web-static-downloader.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/113654/30c13856-f657-b0d9-7b12-8f84987a5430.gif)


## ソース

[Github](https://github.com/bakira-tech/web-static-downloader)

## 解説

- BeautifulSoup自体は以前触ったことあったので調べながらで5分ほどで動くものが完成 
- 細かいパターンはテストや動作確認していないので正常系以外(src属性のしていが特殊な場合etc...)では動かないかも？
- 処理の内容としては以下

1. 対象URLのHTML要素を取得
2. HTMLの中からセレクター指定で対象の要素配列を取得
3. 2の要素をループ処理
    1. 対象のsrc属性が絶対パスならそのまま対象リストに追加し、相対パスなら絶対パスに整形の上対象リストに追加
4. 対象リストをループ処理
    1. 指定のフォルダにダウンロード

## 今後

- 少し手を加えれば画像以外(JavaScriptやCSSファイル)もまとめて落とせるように出来そうなので気が向いたらやってみたい
- セレニウム的な感じで画面をまたいだ一括ダウンロードも出来るようにしたい

## 20180914追加

スクレイピング対策を入れているサイトの場合、ヘッダー情報をしっかり指定しないとスクレイピング時に403などで弾かれる可能性があったので、任意のヘッダーを指定出来るようにしました。

```diff
+ #Custom Header
+ HEADERS = {
+     "Cache-Control": "no-cache",
+     "Connection": "keep-alive",
+     "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
+ }
...
- response = urllib.request.urlopen(target).read()
+ request = urllib.request.Request(target,None,HEADERS)
+ response = urllib.request.urlopen(request).read()
```

※詳しいソース差分[はコチラ](https://github.com/bakira-tech/web-static-downloader/pull/2/files)

# 終わりに

皆様どうぞお好きに改造してみてくださいw
Pythonでツイッターでよく見るやつ作ってみた

# Pythonでツイッターでよく見るやつ作ってみた

## はじめに
Progateでやっと３つ目の授業が終わりdefとかなんかを昨日覚えたので早速何か書こうと思いました！ひよっこプログラマーなりに色々考えたのでザーッとみてみてください！
今回はPythonを使って僕が最近ツイッターでよく見る『イクイクのホモ』とか『ゴツゴツのアハン』を自動変換？してくれるようなプログラムを書いてみました。
わからない方の為に少し説明すると、元は『ホクホクのイモ』や『アツアツのゴハン』ていう文を頭の文字をそれぞれ入れ替えるというものです。僕自身ルーツを知ってるわけではないのですが、シュールで面白いので"すこ"。


## 開発環境
* Python3

（のみだったと思います…
このコードはコレがないと書けないはずだよっていうのあったら教えてくださいまし。）

##やること
`input`で形容詞？と名詞？を受け取ります。
この時、形容詞は4文字かつ1,2文字目と3,4文字目が同じものを受け取るようにします。
そして、受け取った文字列の先頭を交換して`print`
以上です

```python:changer.py
# -*- coding: utf-8 -*-

hiragana = "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん"
katakana = "ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴ"


def availability_judge(adjective,noun):
    if all([ch in katakana or ch in hiragana for ch in adjective and noun]):
        return True
    else:
        print('！！！ひらがなかカタカナのみで入力してください！！！')
        return False

def even_character(adjective):
    if len(adjective) == 4:
        return True
    else:
        print('２文字の擬音を２回繰り返す４文字の形容詞にしてください')
        return False

def mirror_judge(adjective):
    first_half_length = adjective[0:2]
    latter_half_length = adjective[2:4]
    if first_half_length == latter_half_length:
        return True
    else:
        print('２文字の擬音を２回繰り返す４文字の形容詞にしてください')
        return False

def conjunction(number):
    lists = ['な','の','で','か','に']
    return (lists[number])


adjective = input('擬音語で形容詞を入力してください（パクパク、ぐるぐる）:')
print('な: 0')
print('の: 1')
print('で: 2')
print('か: 3')
print('に: 4')
selected_number = int(input('接続助詞を半角数字で選んでください:'))
noun = input('ひらがなかカタカナで名詞を入力してください:')

if availability_judge(adjective,noun):
    if even_character(adjective):
        if mirror_judge(adjective):
            n = 1
            adjective_first_character = adjective[n-1]
            noun_first_character = noun[n-1]

            changed_adjective = (adjective.replace(adjective_first_character, noun_first_character))
            changed_noun = (noun.replace(noun_first_character, adjective_first_character))

selected_conjunction = conjunction(selected_number)

print(changed_adjective + selected_conjunction + changed_noun)
```


## 終わりに
`def`を使いたいが為に考えたプログラムですが乱用みたいになってしまいました。使い方があってるのかもわかっていないのですが、作動しているのでOKですwwww
せっかくのPythonなので、みやすく書きたかったのですがいかがでしょうか？実はエラーの処理や例外もガバガバで入力する側が気を使わなきゃいけないプログラムです。次の課題は『欲している条件以外の入力があったら警告文を出してやり直しさせる』ですね。
初めてのpythonにしては頑張ったと思っていますが、誰得なコードなので達成感に掛けますね。
３分でいいので使ってみてあげてください〜！
以上、Pythonでツイッターでよく見るやつ作ってみたでした！
ぽやしみ〜( ˘ω˘ ) ｽﾔｧ
素人がWebアプリケーション制作の過程を書いてみる

## きっかけ

最近Web技術（HTML5/CSS/Javascript）を使ったアプリケーションが増えてきたので興味があったのと、ちょうど趣味の中でこんなアプリがあったらいいなというのが出てきたので、勉強を兼ねて実際に作成に取り掛かってみました。
今後作成過程での備忘録等を載せていく予定です。

## 作成するアプリケーションのイメージ

今回制作するアプリケーションは、種々の情報の相関関係を可視化するネットワークグラフを作成するツールを作る予定です。見た目はWindowsアプリケーションライクにメニューバーやN-ペイン、タブなどの基本機能を搭載したいです。ちなみに有名どころで言うとMaltego[^1]、Neo4J[^2]、Elastic stack graph[^3]あたりになるかと思います。
一部オープンソースのものがあったりするのですが、制限がかかっているケースも多いためせっかくなら自作してみようと思い立ちました。

## Webアプリケーションの構成
### Webフレームワーク

今回Webアプリケーションについては、Windowsアプリケーションライクで作成することから、SPA（Single Page Application）を作成する方向で進めて行きます。サーバサイドは最低限のページ、REST-API、DBがあればよいので、手軽でPythonに慣れているということから、WebフレームワークにFlaskを、RDBにはSqlite3を使用します。
他のでざっと見たところ下記のほうなフレームワークがあります。（フレームワークの名前だけでも数十とあり、どれを選ぶかというところから悩みますね。。。）

| 名前　| 所感 |
|:-----:|:--|
|  django | Pythonのフレームワーク。MVC（Model-View-Controller）ベース。フレームワークに乗っ取って簡単にベースのファイル、モデル、データベースまでの一連のシステムを構築可能。HTMLはテンプレートエンジンであるJinja2記法を活用。|
|  flask  |  Pythonベース。djangoをさらに簡素化したイメージ。DBの構築は自分で構築する必要ある。 |
|  ReactJS |  クライアントサイドJavascriptのフレームワーク。View寄りの機能を提供。 |
|  Ruby on Rails  | Rubyのフレームワーク。MVCベース。コマンドによりフレームワークとベースのファイル、モデルを作成可能。WebサーバはWEBrickを使用。  |
|  CakePHP |   PHPのフレームワーク。上記と同様MVCベース。 |


### FlaskによるWebサービス起動まで
まずはpython2にて、Flaskのインストールを実施。

```shell
$ pip install flask
```

その後、下記の通りファイルを作成し、ファイルの中身を記載

```
    root-directory -- app.py 
                   |- templates -- index.html
```

```python:app.py
from flask import Flask, render_template

app = Flask("__name__")

# /直下へのアクセス
@app.route("/")
def root():
    return render_template("index.html")

# Webサーバの起動
if __name__ == "__main__":
    app.run(debug=True)
```

```html:index.html
Hello :)
```
あとはapp.pyを引数runserverをつけて実行するだけ。

```shell
$ # python app.py runserver
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
```
無事起動完了しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/115330/d8606a70-61e2-ea50-880b-8227f00f523c.png)


まずはここまで。次回以降どんどん機能拡張していきたいですね～　:)

[^1]: [Maltego](https://www.paterva.com/web7/buy/maltego-clients/maltego-ce.php) : paterva社の関係グラフ分析用の可視化ツール
[^2]: [neo4J](https://neo4j.com/) : グラフ構造のDBを持つ可視化ツール
[^3]: [Elastic stack graph](https://www.elastic.co/jp/products/stack/graph) : Elastic社のツール。グラフ機能。
個人的に使うショートカットキー備忘録

## Mac
|ショートカットキー  |内容  |
|---|---|
|Option + Command + H + M|全てのウインドウを同時に最小化|




## Saferi

|ショートカットキー  |内容  |
|---|---|
| Command + t | 新規タブを開く |
| Command + Option + b | お気に入りを表示・非表示 |
| Command + Opttion + f | アドレスバーにカーソルを移動 |
| Option + ↑ ↓ | 1画面分スクロール |
| Control + tab | 次のタブに移動 |
| Control + Shift + Tab | 前のタブに移動 |

## Rubymine

|ショートカットキー  |内容  |
|---|---|
| Command + Shift + o | ファイルの検索 |
| Command + Shift + f | ファイルの内容の検索 |
| Command + Shift + a | アクションを探す |
| Command + B | 定義もとに飛ぶ |
## Keynote
|ショートカットキー  |内容  |
|---|---|
|Command + Shift + P  |発表者ノートの表示・非表示  |
|Command + Option + P  |スライドの再生  |
|Option ＋ Command ＋ T  |ツールバーの表示・非表示  |
|Option ＋ Command ＋ 0 | ウインドウ内のスライドに合わせる |
|Command ＋ 0  |実際のサイズに戻す | 
| Command + Option + Shift + V | スタイル無しで貼り付け |



## 参考
[MacのためのKeynote: Keynote for Mac のキーボードショートカット]
(https://support.apple.com/kb/PH24313?viewlocale=ja_JP&locale=en_US)
[個人的によく使う、RubyMineのショートカットいくつか]
(https://qiita.com/mnuma/items/1c0e4c54b070e0a2307b)
[【翻訳】絶対見逃せない！RubyMineのショートカット10選]
(https://qiita.com/jnchito/items/6eda2cd54038ffa829ef)
[RubyMineで覚えておきたい、たったひとつのショートカットキー]
(https://qiita.com/spring_aki/items/6216d877f6808e0c98d3)
[MacのSafariで使える便利なキーボードショートカットまとめ]
(https://uxmilk.jp/38787)
[Mac Safariのブックマークをキーボードショートカットで操作する方法]
(http://inforati.jp/apple/mac-tips-techniques/internet-hints/how-to-open-bookmark-of-mac-safari-browser-with-keyboard-shortcut.html)
[Macユーザーが絶対に覚えておくべき20のキーボードショートカット一覧【最新保存版】]
(https://matome.naver.jp/odai/2138612139607002701)
Ubuntu 16.04.5 LTS の virtualhostの設定 + php + postgresql + laravel メモ

```bash

root@ubuntu adduser ubuntu
root@ubuntu sudo passwd ubuntu
root@ubuntu gpasswd -a ubuntu sudo
```
```bash

local@mac ssh-keygen -t rsa -f ./id_rsa
```

```bash
ubuntu@ubuntu mkdir ~/.ssh
```

```bash
local@mac scp ~/id_rsa.pnb IPアドレス:~/.ssh
```

```bash
ubuntu@ubuntu sh-add ~/.ssh/authorized_keys
ubuntu@ubuntu cat ~/id_rsa.pub >> ~/authorized_keys
ubuntu@ubuntu chmod 600 authorized_keys 
ubuntu@ubuntu chmod 700 .ssh/
```

```bash
local@mac ssh -i ~/id_rsa ubuntu@IPアドレス
```

```bash

root@ubuntu vim /etc/ssh/sshd_config
```


```vim

PermitRootLogin yes を PermitRootLogin no に修正する
```

```bash

root@ubuntu /etc/init.d/sshd restart
```

```bash

ubuntu@ubuntu mkdir /home/ubuntu/public_html
```

```bash

ubuntu@ubuntu chmod -R 755 /home/ubuntu/public_html
```

```bash

root@ubuntu vim /etc/apache2/sites-available/virtual.host.conf
```
```vim

<VirtualHost *:80>
    ServerName www.virtual.host
    ServerAdmin webmaster@virtual.host
    DocumentRoot /home/ubuntu/public_html
    ErrorLog /var/log/apache2/virtual.host.error.log
    CustomLog /var/log/apache2/virtual.host.access.log combined
    LogLevel warn
    <Directory "/home/ubuntu/public_html">
       Require all granted
    </Directory>
</VirtualHost>
```

```bash

root@ubuntu a2ensite virtual.host
```

```bash

root@ubuntu /etc/init.d/apache2 restart
```

```bash

ubuntu@ubuntu vim /home/ubuntu/public_html/index.html
```
```bash
root@ubuntu sudo add-apt-repository ppa:ondrej/php
```
```bash
root@ubuntu sudo apt-get update
```
```bash

root@ubuntu sudo apt-get install php7.2
```
```bash

root@ubuntu sudo apt-get -y install postgresql
```
```bash

root@ubuntu sudo apt-get -y install php7.2-common php7.2-cli php7.2-fpm hp7.2-dev php7.2-mbstring php7.2-zip php7.2-curl php7.2-gd php7.2-pgsql php7.2-xmlrpc php7.2-intl
```
```bash

root@ubuntu sudo apt-get -y install curl git unzip
```
```bash
ubuntu@ubuntu cd ~
ubuntu@ubuntu curl -sS https://getcomposer.org/installer -o composer-setup.php
ubuntu@ubuntu HASH=544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061
ubuntu@ubuntu php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
→Installer verifiedと表示される。
root@ubuntu sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
```
```bash

ubuntu@ubuntu composer create-project --prefer-dist laravel/laravel app
root@ubuntu sudo apt-get -y install nodejs
root@ubuntu sudo apt-get -y install npm
ubuntu@ubuntu npm install
```

参考URL https://qiita.com/kpkpkp/items/30abe1a68a3a4e8881ab
備忘録　アラート・アクションシート(swift編)


### いつも忘れてしまうので

（2020.8.12追加）
アクションシートの場合を追加。iPadの場合は、popoverPresentationControllerの設定が必須のようである。
これにより、iPadの場合はtargetViewに向かうように吹き出しが表示される。

```swift:iOS13
let actionSheet = UIAlertController(title: "アクション表示", message: "保存してもいいですか？", preferredStyle: .actionSheet)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: {
    (action: UIAlertAction!) -> Void in
    print("OK")
})
let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel, handler: {
    (action: UIAlertAction!) -> Void in
    print("Cancel")
})
actionSheet.addAction(cancelAction)
actionSheet.addAction(defaultAction)

if UIDevice.current.userInterfaceIdiom == .pad {
    actionSheet.popoverPresentationController?.sourceView = targetView
    actionSheet.popoverPresentationController?.sourceRect = targetView.bounds
}

present(actionSheet, animated: true, completion: nil)
```

```swift:iOS11（2019.1.6追加）
let alert = UIAlertController(title: "アラート表示", message: "保存してもいいですか？", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: {
    (action: UIAlertAction!) -> Void in
    print("OK")
})
let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel, handler: {
    (action: UIAlertAction!) -> Void in
    print("Cancel")
})
alert.addAction(cancelAction)
alert.addAction(defaultAction)
present(alert, animated: true, completion: nil)
```


```swift
let alert = UIAlertController(title: "アラート表示", message: "保存してもいいですか？", preferredStyle: UIAlertControllerStyle.Alert)
let defaultAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
    (action: UIAlertAction!) -> Void in
    print("OK")
})
let cancelAction = UIAlertAction(title: "キャンセル", style: UIAlertActionStyle.Cancel, handler: {
    (action: UIAlertAction!) -> Void in
    print("Cancel")
})
alert.addAction(cancelAction)
alert.addAction(defaultAction)
presentViewController(alert, animated: true, completion: nil)
```
ID(採番)生成戦略

## 概要
RailsでSNS系サービスを作る時に、タイムライン型でページネーションを実現するためにはというメモ。
通常通りソートして、カウンティングするだけでは解決できなかった話と、解決策の話です。

## 結論
結論から言うとUUID　version1のような時間型で衝突しないid生成がなされていればOK。
あくまでRailsから外れずコード管理のみで考えた時に時系列で並ぶulidの実装に落ち着きました。
https://github.com/ulid/spec

### 実装の提案
兎にも角にも実装例を見せないと始まらないので、以下に落ち着きました。
cursor型ページネーションの実装になります。
https://gist.github.com/penguinwokrs/45a7cfed3c31698da9b3e2409d83cffe
キモの解説ですが、UUIDをつけてUUID同士を比較して超過以降を抽出しているだけです。

```ruby
klass.where("`uuid` < '#{cursor}'") # cursorの部分もuuidです。
```
（...たったこれだけです...ulid...すごい...)


## 既存の問題
ツイッターのようなサービスでページネーション実装を考えた時に、作成時間を元にソートしてから20件ずつカウンティングすると、偶然にも同時刻でツイートされる可能性は大いにあるため、1ページ目と２ページ目に重複したツイート内容が出てくる可能性がある。
SQL的には、以下のような実装が対応として回避可能である。
[Pagination(ページネーション)がずれる、抜ける問題を解決する](https://qiita.com/marnie_ms4/items/1dc51042844c85c30550)

採用しなかった理由としては、以下の通りです。
* ミリ秒単位での制御が考慮されていない。
* SQL的にチューニングとメンテが厳しそう。（低コストでできる方法を実現させたかった）

## 参考文献
* [Facebook, Twitter, Instagram等がどうやってIDを生成しているのか まとめ](https://qiita.com/daisy1754/items/98a6e6b17d8161eab081)
* [Pagination(ページネーション)がずれる、抜ける問題を解決する](https://qiita.com/marnie_ms4/items/1dc51042844c85c30550)
* [UUID_SHORT](https://dev.mysql.com/doc/refman/5.6/ja/miscellaneous-functions.html#function_uuid-short)
* https://qiita.com/kawasima/items/6b0f47a60c9cb5ffb5c4


## 所感
大規模なサービスほどスケールする時にどうするかをすごく考えていて、参考なりますね。
MastodonはオープンソースとしてTwitterが作成したsnowflakeを採用していて良いと思ったが、実装をストアドプロシージャで管理していた。
snowflakeの実装はいいと思うが、専用サーバ用意したりストアドプロシージャは現代で考えるとコストが高く感じるのは自分だけだろうか。 :thinking: 

トレンド的にGraqhQLがプロダクトへ投入され始めているので、こちらの[EdgeとNode](https://qiita.com/bananaumai/items/3eb77a67102f53e8a1ad#%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%81%A9%E3%81%86%E6%89%B1%E3%81%86%E3%81%8B)も学んでいきたいところです。

P.S.
実装の提案で補足なのですが、headerの部分でgithubみたいに[RFC風](https://developer.github.com/v3/guides/traversing-with-pagination/)に則りやりたかったが、APIを利用する開発陣営との折り合いがつかず、独自実装になりました。

* RFC 5988 "Web Linking": https://tools.ietf.org/html/rfc5988