OmniAICreator/Qiita-1.07M huggingface dataset:
DockerでWordPressの開発環境を構築する

#ゴール
DockerでWordPress実行環境を構築、通常の開発が出来る状態をゴールとします。

#なぜこの記事を書いたか
Docker公式サイトをはじめいくつか同じような事を解説しているサイトがありましたが、個人的に下記の点が足りませんでした。

・画像(Media)がアップロード出来ない。

・PhpMyAdminなどのコンソールでDB(MySQL)にアクセス出来ない。

・ファイル同期出来ない(ホストPC(本体)とゲストPC(Docker container)でマウントの設定が出来ていない。)

これらがクリアー出来ていないと開発/運用に支障があるので色々調べた結果をまとめました。

#前提環境
・mac OS X 10.9.5
・docker-compose を使える。

#構築手順
1.プロジェクト フォルダを作成。
今回は下記のパスに「docker_wp」というフォルダを作成。
/Users/user/develop/docker_wp/

2.ターミナルで移動

```Bash
cd /Users/user/develop/docker_wp/
```


3.書き込み権限のあるWordPress用Docker image を作成
(このステップを行う事でMediaのアップロードが可能になります。)

・下記内容でDockerfileを作成。

```Bash:dockerfile
FROM wordpress:latest

RUN usermod -u 1000 www-data \
    && groupmod -g 1000 www-data
```

「FROM wordpress:latest」として最新のWordPress用imageを元にしています。

・下記コマンドでimageを作成

```Bash
docker build -t wordpress:auth .
```

「wordpress:auth」でimageの名前とタグを指定しています。

実行後「docker images」コマンドで正常にimageが作成されているか確認します。

4.下記内容でdocker-compose.yml を作成。

```Bash:docker-compose.yml

version: '2'

services:
   db:
     image: mysql:5.7
     ports:
       - "3306:3306"     
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
     privileged: true

   wordpress:
     depends_on:
       - db
     image: wordpress:auth
     ports:
       - "80:80"
     restart: always
     working_dir: /var/www/html
     volumes:
       - /Users/user/develop/docker_wp/:/var/www/html/
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_PASSWORD: wordpress
     privileged: true
volumes:
    db_data:
```

赤字の部分に注目して頂きたいのですがdbのportを指定する事でPhpMyAdminなどの外部からの接続が可能になります。
またDBのvolumesを指定する事でホストPC（mac）とdockerコンテナー間のファイル同期が可能となります。

5.コンテナー作成〜稼働

```
docker-compose up -d
```

完了後、「docker ps」にて作成したコンテナーが動いているか確認します。
このように2つのコンテナーが起動していればOKです。

```
>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5a9d3770ee0d        wordpress:auth      "docker-entrypoint.sh"   3 minutes ago       Up 3 seconds        0.0.0.0:80->80/tcp       dockerwp_wordpress_1
3980a9064e38        mysql:5.7           "docker-entrypoint.sh"   3 minutes ago       Up 5 seconds        0.0.0.0:3306->3306/tcp   dockerwp_db_1
```

5-2. wp-config.php のDB接続情報を修正する
上記の docker-compose.yml の例でいくと下記の通りに設定します

```
define( 'DB_NAME', getenv_docker('WORDPRESS_DB_NAME', 'wordpress') );
define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'root') );
define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'wordpress') );
```


6.ブラウザからアクセスする
下記でwordpressの設定画面が表示されます。

```
http://localhost
```

ここまでくれば環境構築は無事完了です！

7.DBにアクセスする
今回はSequel Proでアクセスします。

8.クリーンアップ
開発が完了した時などDockerを終了する時は下記コマンドでコンテナーを削除します。

```
docker-compose down
```

コンテナーを削除してもDBデータは残っています。
下記コマンドでDBデータも全て削除可能です。

```
docker-compose down --volumes
```

<参考サイト>
https://docs.docker.com/compose/wordpress/

http://qiita.com/suin/items/3a0361102af83d0b69aa
SSL証明書について、何回調べても忘れてしまうので自分でまとめた。

## SSL証明書について、何回調べても仕組みについて忘れてしまうので、対策として。
以下の流れで学習をする。自分の言葉で言い換えることで、格段に記憶に定着するようになる。
1. 初心者向けの記事をひととおり読んで、分かった気になる。
2. これが分かりやすいという図を探す。
3. 自分の言葉で認証の流れを言い換えてみる。（2で見つけた図を見ながら行うと良い。）

(Ex.)元の文 https://www.cybertrust.ne.jp/sureserver/basics/ssl1.html
> WebサーバとWebブラウザの間では以下のような流れでＳＳＬ暗号化通信が開始されます。
> （１）	SSL暗号化アルゴリズムの合意（SSL暗号化仕様交渉）
> WebブラウザとWebサーバ間の両者が使用できる一番安全なSSL暗号化の仕様を決めます。
> （２）	SSLサーバ証明書提示
> WebサーバはWebブラウザへSSLサーバ証明書を送信します。Webブラウザは受信したSSLサーバ証明書を確認します。
> （３）	共通鍵の元データ交換・共通鍵の生成
> Webブラウザは共通鍵の元となるデータを作成し、SSLサーバ証明書の公開鍵で暗号化してWebサーバへ送信します。
> 両者は同じ元データを使用し、共通鍵を生成します（全く同じものを生成します）。
> （４）	SSL暗号化通信開始 
> 以降、実際のデータのSSL暗号化通信が開始されます。

図は [Webセキュリティ覚書 : "HTTPS" 編 [ 初学者向け ]](https://qiita.com/Tsutou/items/cea87dbab0f3d0080422) も参考にした。

(Ex.)自分の言葉で言い換え
　1. 利用者(Webブラウザ)がWebサーバと通信したい。
　2. 安全にやりとりをするために、暗号化の方法を決める必要があるので、決める。
　3. Webサーバは利用者へ「公開鍵付き証明書」を送る。※1
　4. 利用者は貰った「公開鍵付き証明書」を元に、共通鍵を作成する。※2
　5. 利用者はさらに作成した共通鍵をWEBサーバの公開鍵で暗号化して「暗号化共通鍵」を作成し、WEBサーバに送る。
　6. WEBサーバは自分の秘密鍵で受け取った「暗号化共通鍵」を平文に戻す。（WEBサーバは共通鍵を手に入れる）
　7. 以上で、両者が同じ共通鍵を持つことになるので、それを用いて暗号化通信を行う。

#### ※1 そもそもWEBサーバから送られた「公開鍵付き証明書」が偽物であった場合に備えた仕組み
##### 認証局( CA => Certificate Authority )
公開鍵が本物であるかどうか、それを判断し証明するために認証局は存在します。
つまり、クライアントとサーバーが双方信頼する第三者機関がその立場に立ってくれます。

#### ※2 共通鍵って？
共通鍵暗号方式では、暗号化する際の「鍵」と復号する際の「鍵」は同一のもの（共通の鍵）を使います。 「共通鍵」情報は公開されておらず、送信側と受信側のみで共有されているのが特徴です。
初心者向け｜Microsoft Flowを使ってみる（4）フォルダにZIPが置かれたら、自動的に展開（解凍）する

#はじめに
- Microsoft Flowを使ったシンプルなフローの作り方をまとめていきます。
- これからFlowにチャレンジしてみようと考えている初心者向けです。

#設計

##このフローの利用シーン
※シーンは特にありません。別記事「メールの添付ファイル（ZIP)を自動ダウンロード＆自動展開する」に続きます。

#フローの作り方

##作業時間
5～10分

##（1）Flowの上部メニューで「マイフロー」→「一から作成」を選ぶ
![flow3.png](https://qiita-image-store.s3.amazonaws.com/0/242229/5ad81b7c-8fa2-e8ab-300a-394e746b4f04.png)

##（2）「多数のコネクタやトリガーを検索する」を選ぶ
![flow4.png](https://qiita-image-store.s3.amazonaws.com/0/242229/8c200b61-a4d4-d990-8134-4eaab54d3400.png)

##（3）フロー名を設定。トリガーを選ぶ
![flowD1.png](https://qiita-image-store.s3.amazonaws.com/0/242229/30766ff0-6f24-d42a-44d2-587c6f863f27.png)

**フロー名**
分かりやすい名前を付けてください。

**トリガー**
行動の起点を設定します。

(a)OneDriveにZIPファイルが置かれたら、
(b)自動的に展開（解凍）する。
(a)が起点です。トリガーとしては「OneDrive for Business」を選びます。

##（4）「OneDrive for Business - ファイルが作成されたとき（プロパティのみ）」を選ぶ
![flowD2.png](https://qiita-image-store.s3.amazonaws.com/0/242229/6d02c171-e429-a855-364d-e825f54fddfe.png)

##（5）「OneDrive for Business - ファイルが作成されたとき（プロパティのみ）」の詳細
![flowD3.png](https://qiita-image-store.s3.amazonaws.com/0/242229/4f578c9e-c60a-88f1-2034-ea1d2ef4a3d0.png)

**フォルダの指定**
トリガーの対象となるフォルダを指定します。
今回は「/download/」とします。

**条件**
ZIPファイルを判定するため、「条件の追加」を選びます。

##（6）「条件」の設定
![flowD4.png](https://qiita-image-store.s3.amazonaws.com/0/242229/68e36b20-0cfc-ab9d-73ae-7dcec9f12061.png)

**条件**
「条件の追加」を選ぶと、はい・いいえの2択を作ることができます。

値の選択：表示名
条件：次のもので終わる
値：.zip

**はいの場合**
.zipで終わる表示名だった場合のアクションを追加します。

##（7）「OneDrive for Business」を選ぶ
![flowD5.png](https://qiita-image-store.s3.amazonaws.com/0/242229/b3bfe16c-fb0d-9eb6-8275-3ba1de32af79.png)

##（8）「OneDrive for Business - フォルダーにアーカイブを展開します」を選ぶ
![flowD6.png](https://qiita-image-store.s3.amazonaws.com/0/242229/b4290a06-eb71-79dd-5c71-eb2a25801efc.png)
ZIPの展開（解凍）を行います。

##（9）「OneDrive for Business - フォルダーにアーカイブを展開します」の詳細
![flowD7.png](https://qiita-image-store.s3.amazonaws.com/0/242229/e6afb5cc-21e8-012e-1a32-5d4d125456fb.png)

ソース アーカイブ ファイルのパス：/download/を指定します。
宛先フォルダー パス：今回は「/expand/」と指定しました。
上書きする：はい

**実行されると**
/download/フォルダにZIPファイルが置かれると、
展開（解凍）が実行され、/expand/フォルダに配置されるようになります。

**フローの保存**
最後に保存して終わりです。

#注意事項
- Microsoft Flowはfree版だと「5分間でチェック」となり、最大5分に1回実行されます。（ZIPファイルを/download/に置いたあと、しばらく放置しておいてください）
メモ）Gitリセットをリモートに強制プッシュしたい。

http://blog.roundrop.jp/show/37

どこまで戻すか決める
git logしてコミット履歴を確認

まず git log してコミット履歴を確認します。
以下のような感じのものが出てきます。

$ git log
commit 61ea04eed2b4a4edc265c53827c5b05eb0de64cf
Author: hogehoge <fugafuga@example.com>
Date:   Fri Aug 31 12:06:43 2012 +0900
　
    Update pom.xml
　
commit d7589cfeddb10d36500ea7b9aea45ce470c01e0e
Author: hogehoge <fugafuga@example.com>
Date:   Thu Aug 30 13:44:43 2012 +0900
　
    Update readme.md
　
commit 464afea34504d42c4ea02b770fd425457b5e9b94
Author: hogehoge <fugafuga@example.com>
Date:   Thu Aug 30 13:28:02 2012 +0900
　
    first commit
　

戻りたい時点のcommitのハッシュ値をメモる

戻りたい時点のコミットのハッシュ値をメモります。
例えば上記の例で、一番下のfirst commitに戻りたい場合は、

commit 464afea34504d42c4ea02b770fd425457b5e9b94
Author: hogehoge <fugafuga@example.com>
Date:   Thu Aug 30 13:28:02 2012 +0900
　
    first commit
　


の「464afea34504d42c4ea02b770fd425457b5e9b94」がハッシュ値となります。

git reset —hardする

いよいよ禁断の git reset —hard します。

$ git reset --hard ハッシュ値


上記の例では、

$ git reset --hard 464afea34504d42c4ea02b770fd425457b5e9b94


となります。

戻した結果をpushする

戻した結果をpushします。
-fをつけつつハッシュ値をつけて強制pushします。

$ git push -f origin ハッシュ値:master


上記の例では、

$ git push -f origin 464afea34504d42c4ea02b770fd425457b5e9b94:master
組込みC > 0x89と0xAAの合成 > wrk = vals[0] << 8 | vals[1]; > 0xFFFF89AA > 計算途中が符号付き16ビット(short)になり、そこで負数になる + 符号拡張により先頭がFFFFになる

```txt:動作環境
組込みC (16bit)
```

```c
...
unsigned char vals[] = { 0x89, 0xAA };
unsigend long wrk;

wrk = vals[0] << 8 | vals[1]; // MSB + LSB
```

wrkの値が`0xFFFF89AA`となる。左ビットがF埋めされる。

以下だとF埋めされなかった。

```
wrk = (unsigned long)vals[0] << 8 | vals[1];
```

以下でもF埋めされない。`(unsigned long)`がないとF埋めされる。

```
wrk = (unsigned long)vals[0];  // ここでいったんwrkに入れないと0xFFFF89AAのように上位側がFとなる
wrk = wrk << 8 | vals[1];
```

右シフト演算の場合、算術シフトにより符号ビットが付くというのは聞いたことがある。
[シフト演算](http://wisdom.sakura.ne.jp/programming/cs/cs7.html)
> そこで、右シフトをする時は空ビットは符号ビットで初期化されます

しかしながら、上記は左シフト演算である。

左シフト演算した値が、暗黙の型変換で「マイナス(かsigned型)」と認識して、F埋めされた状態になるのだろうか。


### 謝辞

@shiracamus さんのコメントにて動作の仕組みが理解できました。

情報感謝です。

@SaitoAtsushi さんのコメントにて仕様(C99)に関する情報を紹介いただきました。

情報感謝です。

@nakataSyunsuke さんにアイデアをいただき、そのコードを@SaitoAtsushi さんに実装いただきました。

情報感謝です。
どこから来たのか、遷移元のページを判定させる


## 対象
- OS 10.13.3
- Xcode8
- Swift 3

##やったこと
遷移元のページを判定して、画面に表示するものを変えたいので、色々と調べ下記のことがわかりました。忘れないうちに備忘録になります。

```move.swift
let count = (self.navigationController?.viewControllers.count)! - 2
        if (self.navigationController?.viewControllers[count] as? [遷移元のContlloer名]) != nil {
			　　該当のページでない場合の処理
                } else {
                該当ページある場合の処理
        }
```

##わかったこと
なんとなくだけど、わかったのは、「.viewControllers.count」で２つ前に戻ることがポイントらしい。それを元に比較させた感じだと思う

## 参考
ほぼ、こちらの方の方法を参考にさせてもらいました。
[swiftで遷移元のviewcontrollerのインスタンスを取得する方法](https://qiita.com/amato/items/f0340c0f2db4c9aac152)
俺言語 その21

#概要

俺言語をやってみた。
avrにアセンブラで実装してみた。
ROM化してみた。

#環境

avr studio 4
attiny85 1mhz
tera term
usb-serial

#写真
![image](https://qiita-image-store.s3.amazonaws.com/0/18104/d7309a8a-1857-889d-ca56-2914bef54933.png)


#拡張
変数「^」の導入
?=^　でソースリストエンドポイントを表示。
^=32 でソースリストエンドポイントを変更。

変数「%」の機能拡張
%=0 で、eepromに、フラグを書き込む。自動起動となる。

リストの機能変更。
0で、ソースをリスト表示するが、同時にeepromに書き込む事にした。

#プログラムの手順

以下を打ち込む。

```
10 a=0
20 a=a+1
30 ?=a
40 #=a<10*20

```

eepromに書き込む。

```
0
```

フラグを書き込む。

```
%=0
```

以上。
twitterのapiを使ってrailsからtweet

# 作りたいモノ

railsのアプリ上でtwitterログインした後にそのtwitterアカウントでrailsからtweet

# twitterのomnioathでtwitterログインを実装

twitterのapiは基本的にはomnioath認証されているアカウントを通してじゃないと行えない。

https://qiita.com/To_BB/items/01863aa50d628c069b64

omniauthはココに乗っているやり方で実装

# twitter apiのkey取得

https://developer.twitter.com/en/docs/basics/getting-started

```
Get started: Build an app on Twitter
Twitter’s API platform includes numerous endpoints to help you build an app and solution on Twitter. Our basic endpoints are available for free. As your app or solution needs grow, you’ll also find enterprise APIs that include increased levels of access.

Get started with the basic REST and Streaming APIs
Twitter’s basic REST and Streaming APIs enable free access to numerous endpoints. To get started, you must first create an app.

1. Create an app
To use an endpoint, you must create an app and use our OAuth-based authorization system. Visit apps.twitter.com to create one.

2. Start using the endpoints!
Once you’ve setup your account, accessing the endpoint is super simple. Check out the documentation and API reference for additional details about each endpoint. There are many libraries and utilities in different programming languages that can help you to get started.

Have a question? There’s a good chance our community has an answer for you. Visit our developer forums to review topics, ask questions, and learn from others.
```

上記のようにまずはappアカウントを作成し、keyを発行しないといけない。気をつけないといけないのがpermissionでデフォルトはread onlyなので書き込みも許可する。

# twitter gemをinstall

http://www.rubydoc.info/gems/twitter

twitterのapiを利用するためのgemがあるのでそれをinstall。

# controller作成

https://programming-beginner-zeroichi.jp/articles/64

ここからはこの記事を参考にした。twitter gemにメソッドがあるのでそれを使っていく。そのメソッドを使う前にbefore_actionでkeyの情報を渡している。

```post_controller.rb
class ArticlesController < ApplicationController
  before_action :twitter_client, only: [:create]

  def create
    @post = Post.new(content:params[:content],title:params[:title],user_id:params[:user_id])
    if @post.save
      @client.update("テスト")
      redirect_to root_path
    end
  end
  private
  def twitter_client
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key = "自分のConsumer Keyを選択"
      config.consumer_secret = "自分のConsumer Secretを選択"
      config.access_token = "自分のAccess tokenを選択"
      config.access_token_secret ="自分のAccess token secretを選択"
    end
  end
end
```

# Could not authenticate you.がでたら

なんか何回かkeyをregenerateしないとエラーが出る。Could not authenticate you.とでたらregenerateしてみよう。
CentOS でデフォルトゲートウェイの設定を確認・変更する

サーバーの再起動を行った際などにネットワークが繋がらない場合、デフォルトゲートウェイの設定に問題があることがあります。

その場合、以下のようにして確認することができます。

```
$ route
```

出力された結果の default の項目がデフォルトゲートウェイの設定になります。
もし正しくないものだった場合は以下のようにして変更します。

```
route del default gw ****
route add default gw ****
```

起動する度に同じ設定にしておきたい場合は ifcfg-eth0 の GATEWAY 項目を編集する必要があります。

```
$ vi /etc/sysconfig/network-scripts/ifcfg-eth0
$ service network restart
```
PyMieScatt > Mie_ab() > nmax = np.round(2+x+4*(x**(1/3))), MieS1S2()にもある

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

Numpy実装による球粒子の光散乱コードPyMieScatt関連。

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py

```
def Mie_ab(m,x):
```

```
nmax = np.round(2+x+4*(x**(1/3)))
```

この式は一体どこから来た?

@ 重松清さん その日の前に

> "僕たちはいまどこにいる？
僕達は、これから、どこに向かう？
ずっとこの二つしか考えてなかった。それだけでじゅうぶんだとも思っていた。
僕達はどこから来た？
「明日」を断ち切られてしまって、初めて、その問いのかけがえのなさに気づいた。"

PDF: [MATLAB Functions for Mie Scattering and Absorption](https://omlc.org/software/mie/maetzlermie/Maetzler2002.pdf) by Christian Mätzler
2.2 Mie efficiencies and cross sections
> For this number Bohren and Huffmann (1983) proposed the value

```math
n_{max} = x + 4 x ^{1/3} + 2 ...  (p.477)
```


Bohren C.F. and D. R. Huffmann, "Absorption and Scattering of Light by Small Particles", John Wiley, New York, NY (1983)


~~持っている本の中の記載を探したが見つからなかった。
Kindle版も持っていたかと思うが、数式の間違いだらけで参照しない方がいいだろう。
(3年程度たって修正されたかどうか)~~

> 検索が使用できません
申し訳ありません。この本では、検索がまだ使用できません。後でももう一度お試しください。

(追記 2018/03/14)
HC van de HulstのLight Scattering by Small Particlesを間違って読んでいた。。。 この本の電子版の数式間違いはどうなっているだろうか。

### Bohren and Huffmann (1983)

p477
Appendix A
Homogeneous Sphere

> Thus, series in BHMIE are terminated after NSTOP terms, where NSTOP is the integer closest to 

>```math
x + 4 x^{1/3} + 2
```

> A similar criterion was used by Wiscombe, who was guided by a suggestion by Khare and extensive computations.

関連しそうな論文は以下 (@ arxiv.org)。Wiscombeのcriteriaが掲載されている。
[Effect of finite terms on the truncation error of Mie series](https://arxiv.org/pdf/1202.5904.pdf)

```math
N = x + 4.05 x ^{1/3} + 2
```

### MieS1S2()
(追記 2018/04/01)

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py#L354

```
nmax = np.round(2+x+4*np.power(x,1/3))
```

MieS1S2()においても同じ式が使われている。

式だけ関数に切り出して、その関数に式の説明(と参考文献)を入れると、実装者以外の人にも分かりやすくなるだろう。
Numpy > [np.append(x, 0.0) for x in g1] 

```txt:動作環境
ideone Python3 (python 3.5)
```

https://github.com/bsumlin/PyMieScatt/blob/master/PyMieScatt/Mie.py
のMieQ()の下記は何をしているのだろうか?

`g1 = [np.append(x, 0.0) for x in g1]`

試してみた。

https://ideone.com/1keYxT

```py
import numpy as np

g1 = [3.14, 1.59, 2.65, 3.58]
print(g1)
g1 = [np.append(x, 0.0) for x in g1]
print(g1)
```

```txt:run
[3.14, 1.59, 2.65, 3.58]
[array([ 3.14,  0.  ]), array([ 1.59,  0.  ]), array([ 2.65,  0.  ]), array([ 3.58,  0.  ])]
```

2列にしたうえで、追加された列に0.0を入れているようだ。

### link

- [numpy.append](https://docs.scipy.org/doc/numpy/reference/generated/numpy.append.html)
以前Couseraで提出した課題を見られない？ Switch Sessionsすれば良い！

Courseraでコースを受けて、課題を提出した。受講期間が終わってしまうと、提出したクイズや課題（Jupyter Notebook等）を見られなくなってしまった。*Switch Sessions* すれば見られるので、そのやり方をメモしておく。

1. [Coursera](https://www.coursera.org/) ホームページを開く

2. 右上にある自分のアイコンをクリックして、"My Courses"をクリックする。
![スクリーンショット 2018-03-13 6.25.28.png](https://qiita-image-store.s3.amazonaws.com/0/36973/ea1067b8-9530-5760-42e3-f50246b3de29.png)

3. 受講期間が終了したコースは、デフォルトでは表示されない。**MORE**の文字列を探してクリック！ 
![スクリーンショット 2018-03-13 6.28.04.png](https://qiita-image-store.s3.amazonaws.com/0/36973/b2e8d473-2ff1-2bb8-a414-6ec550f23f82.png)

4. *Switch Sessions*をクリック
![スクリーンショット 2018-03-13 6.36.41.png](https://qiita-image-store.s3.amazonaws.com/0/36973/4811a4d4-2d5e-c5ec-0771-123a7bf28bdc.png)

5. 進行中のコース期間の横に表示される*Join*をクリック
![スクリーンショット 2018-03-13 6.37.48.png](https://qiita-image-store.s3.amazonaws.com/0/36973/edc045f7-2262-256e-412d-e5b556238890.png)

これで自分がコースを受講している状態になり、以前提出したクイズや課題を見られるようになるはず。
TensorFlow > difference  > Transfer learningとFine tuning

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

Transfer learningとFine tuningを同じようなものとして扱っている例を見て気になった。

[What is the difference between transfer learning and fine tuning? @ Quora](https://www.quora.com/What-is-the-difference-between-transfer-learning-and-fine-tuning)

回答より抜粋の上、訳してみる。
訳が難しい部分は元の英語で記載する。

### by Chomba Bupe

> Transfer learningは学習したrepresentationsを別の問題にtransferすることだ。例として、事前学習したconvNetからのfeaturesを線形SVMを改良する(power)ために使うことができる。そのような場合、事前学習モデルは固定したまま、linear SVM weightsを更新することができる。
>
> 一方で、Fine tuningはただ単に精巧な(fine)調整を行いさらなるパフォーマンスの改善を行うことだ。例として、Transfer learningの間、事前学習モデルを動的(unfreeze)にしてそれにより手近なタスクをより最適化させることができる。

...

以下のように思われる。

- Transfer learning: 学習内容を別のモデルから転移する
- Fine tuning: 精巧な調整を行う

Quoraには他にも色々回答があり、**両者が異なること**が記載されている。

「Transfer learningによりFine tuningする」という使い方はできるように思われる。

### by Alex Ekkis
(追記 2018/03/14)

> ...
Watch the following video snippet in which Andrej Karpathy and Andrew Ng, two luminaries in the field of machine learning, use the terms “transfer learning” and “fine-tuning” interchangeably, just to indicate how similarly the terms are used in practice (and in academic papers).

こちらの回答ではinterchangeablyとして大御所が使用しているとのこと。
pg_restore の バージョン 9.6 を使いたい


Heroku の dump file のフォーマットが変わって, 古い `pg_restore` の バージョンがサポートされなくなった。

https://devcenter.heroku.com/articles/heroku-postgres-import-export

> If you are using an old version of pg_restore, you may see an error such as pg_restore: [archiver] unsupported version (1.13) in file header when you try to run pg_restore. Please make sure that you are using pg_restore version 10.3, 9.6.8, 9.5.12, 9.4.17, and 9.3.22 or up. You can check the version of your pg_restore by running pg_restore --version.

とのこと。

バージョンのチェックは以下の様にして行う。

````
$ pg_restore --version
pg_restore (PostgreSQL) 9.3.5
````

入れたつもりもないのに `pg_restore`が使える PHPer の人は、 OSX 用の PHP のバイナリに付属しているものを使っているのかも知れない。

````
$ type pg_restore
pg_restore is hashed (/usr/local/php5/bin/pg_restore)
````

Mac で Postgresを使っている人で、 `Postgres.app` を導入している人は、 `/Applications/Postgres.app/Contents/Versions/latest/bin/pg_restore` を使うと良い。

https://postgresapp.com/documentation/cli-tools.html

````
$ /Applications/Postgres.app/Contents/Versions/latest/bin/pg_restore --version
pg_restore (PostgreSQL) 10.3
````

現時点最新の 2.1.3 バージョンで 上記のように 10.3 バージョンが利用可能
connpassにログインして指定したグループに参加するスクリプト

Twitterのタイムラインをぼーっと眺めていたらみんな熱心に勉強会などのイベントに行っているので自分でもキャッチアップしたかったのだけど、なんか楽にやる方法はないだろうか。というのを最初に思った。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">フォローしてる人が行った勉強会の発表資料を自動でニュースにするサイトを作りたい</p>&mdash; laiso@3/31深セン〜4/2東京 (@laiso) <a href="https://twitter.com/laiso/status/972735355496665088?ref_src=twsrc%5Etfw">March 11, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

と思いたってconnpassのサイトをみていたところ、通知設定で「グループイベントに新しい資料が追加された時」という項目があったので、グループに参加さえしていればメールで資料のアップデートを知ることができるとわかった。

しかしグループに参加するためにイベントの開催やアクティビティをチェックしないといけないのがめんどうくさい。そこで、アクティブなイベントを開催しているグループで自分が興味ありそうなものならどんどん資料の更新を通知してもらうように、フォローワーの参加イベントのグループに自動で参加して、資料追加をwatchしようと決めた。

だがconnpassにはAPIがあるがイベント検索用で、OAuth認証してユーザーのデータを操作するような口はなかった。
[APIリファレンス \- connpass](https://connpass.com/about/api/)

なので、スクレイピングをすることにして方法を検討していたところ、JSを実行させないとうまくいきそうにないことがなんとなくわかった。
Seleniumでやろうかなと思っていたが、検索したところブラウザオートメーション系のPuppeteerという故PhantomJSのような便利なものがあってそれを利用した。

[Puppeteerを使用したHeadless Chromeの操作 \- VASILY DEVELOPERS BLOG \| VASILYテックブログ](http://tech.vasily.jp/entry/puppeteer)

中身はこんな感じ

```js
puppeteer.launch({headless: !isDebug})
    .then(async browser => {
        const page = await browser.newPage()

        if (isDebug) await page.setViewport({width: 1980, height: 800})

        const n = await page.goto('https://connpass.com/login/')
        await page.type('input[name=username]', username)
        await page.type('input[name=password]', password)
        await page.click('#login_form button[type=submit]')

        await page.waitForSelector('#personalMenu')

        await page.goto(eventUrl)
        await page.click('.GroupMembershipButton')

        if (isDebug) await page.waitFor(3000)
        browser.close();
    })
```
CLIにしておいた： https://github.com/laiso/connpass-group-join

イベントやグループ情報を収集する部分も別途書けば望むものができそうだ。ということで安心した。
Laravel API Resource についてのあれこれ


基本の API Resource。単一の `Message` モデルを整形してくれる。

````
<?php
namespace App\Http\Resource;

use Illuminate\Http\Resources\Json\JsonResource;

class MessageResource extends JsonResource {

	public function toArray($request){
		return [
			"message" => $this->message,
			"message_at" => $this->message_at,
		];
	}

}
````

単一の Eloquent モデルを使って Resource を new して使えるし、

````
$route->get("/message/{id}",function(Message $message){
	return new MessageResource($message);
}); 

````

複数の Eloquent モデルをラップして使うことも出来る。

````
$route->get("/messages",function(){
	return MessageResource::collection(Message::all());
}); 
````

レスポンスボディの下層に混ぜることも可能

````
$route->get("/message/{id}",function(Message $message){
	return [
		"message" => new MessageResource($message)
	];
});
````

## Collection 


基本のコレクションリソース

````
<?php
namespace App\Http\Resource;

use Illuminate\Http\Resources\Json\ResourceCollection;

class MessagesCollection extends ResourceCollection {

	public function toArray($request){
		return $this->collection;
	}
}
````

コレクションのコンストラクタには コレクションのみが渡せる。

````
$route->get("/messages",function(){
	return new MessagesCollection(Message::all());
}); 
````

コレクションリソースはちょっとややこしい。

直接コレクションリソースを返却した場合、`data` キーの中に `toArray` の値が展開される。
上記の例では `data` キーがルートに生えて、その中に `message` が並ぶ。


````
$route->get("/messages",function(){
	return [
		"messages" => new MessagesCollection(Message::all())
	];
}); 
````

上記のように、レスポンスのサブ要素として コレクションを利用した場合 `data` キーはつかない。

そのまま `messages` キーの中に `message` が並ぶ。

もちろん、コレクションリソースの中で値を変換できる。

````
<?php
namespace App\Http\Resource;

use Illuminate\Http\Resources\Json\ResourceCollection;

class MessagesCollection extends ResourceCollection {

	public function toArray($request){
		return MessageResource::collection($this->collection);
	}
}
````

自動的に付与される `data` キーの名前は `static` の `$wrap` で変更できる。

````
<?php
namespace App\Http\Resource;

use Illuminate\Http\Resources\Json\ResourceCollection;

class MessagesCollection extends ResourceCollection {

	static public $wrap = "messages";

	public function toArray($request){
		return MessageResource::collection($this->collection);
	}
}

````
pythonでifの条件にorを使うときの注意

# elif, elseまで行かない...

pythonというかプログラミングを初めて数ヶ月，気づくのにかなり時間がかかったので同じようにハマった方の役に立てばと投稿です．

###間違った例

```py
    if a == 'hoge' or 'fuga':
        print('coffee')
    else:
        print('tea')
```

このコードでは`a`に何を代入しても`coffee`と出力され，`else:`は無視されます．

私が意図した条件は`aの値が'hoge'か'fuga'なら'caffee'を出力`なんですが，実際pythonでは`aの値が'hoge'か，もしくは，文字列'huga'が空でないか`と解釈されてしまいます．
if文において，条件が文字列のみの場合は，空でなければ`True`，`''`という風に空なら`False`になるから，`条件1 or '文字列'`では常に`True`になるわけですね．なので，

###正しい例

```py
    if a == 'hoge' or a == 'fuga':
        print('coffee')
    else:
        print('tea')
```

たったこれだけです．．．
これで，`a`に`hoge`や`fuga`以外を代入すると，`tea`と表示されます．

今回，例では`or`を使ってますが，当然，`and`などでも同じようなミスで意図しない挙動が起きると思いますのでご注意を!
Jasmineによるテスト対象の関数内に関数内未定義の変数があったときの対処方法

当記事におけるJavaScriptのコードは、クライアントサイドで動くことを想定されているものとします。

Jasmineのversionは `3.0` 以上とします（3.0未満に関しては特に動作を確認してないため）。

関数内にglobal変数が入っている場合にテストを行う事態に遭遇し、そのときにおこなった方法の備忘録です。

# 通常の場合

JavaScriptで以下の関数をテストしたいとします。


```js:calc.js
...

function add(x, y){
  return x + y;
}

...
```

このとき、`add` 関数に対するテストは以下の様に書くことができます。

```js:calc-spec.js
describe("calcのテスト", function() {
  it("1 + 2 は 3", function() {
    expect(add(1,2)).toBe(3);
  })
});

```

テスト対象のjsの関数がこのようになっていればいいのですが、レガシーコード（テストがないコード）に触れていると、関数内に関数内で未定義の変数が入っている場合があります。

# 関数内に未定義の変数がある場合

さて、以下のような関数があったとします。

```js:calc.js
...

function add(x, y){
  return (x + y) * coef;
}

...
```

この`coef`という変数ですが、`add`関数の内部では定義していません。

簡略化してますが、実際のところ、いろんな歴史的な経緯により、100行くらいの関数内の各所に `coef` のような変数が埋まっていて、困った経験はあるのではないでしょうか？


この関数に対するテストとして以下の様なコードを試しに書いてみます。

```js:calc-spec.js
describe("calcのテスト", function() {
  it("1 + 2 は 3", function() {
    const coef = 0.1;
    expect(add(1,2)).toBe(0.3);
  })
});
```

そして、jasmineを実行してみると、

```
ReferenceError: coef is not defined
```

となり、動きません。これは当然で、 `coef`のスコープが、it内の範囲しか適用されず、`add`関数では未定義となるためです。

テストを正常に動かす方法として以下の様にすれば動きます。

```js:calc-spec.js
describe("calcのテスト", function() {
  it("1 + 2 は 3", function() {
    coef = 0.1;
    expect(add(1,2)).toBe(0.3);
  })
});
```

この`coef`ですが、window直下のオブジェクトとして定義されています。

この副作用として、 `1 + 2 は 3` というテストケース以降のテストにおいては、 window直下に `coef` は定義されてままの状態になってしまいます。

実際のテストにおいては、 `window.coef` ということを明示しておくと、可読性が高いかと思います。

```js:calc-spec.js
describe("calcのテスト", function() {

  it("1 + 2 は 3", function() {
    window.coef = 0.1;
    expect(add(1, 2)).toBe(0.3);
  })

});

```
Qiita:Team PlantUML diagrams

Qiita:Team で [PlantUML](http://plantuml.com/) の図が作成されるようになりました。コードと図を二度手間で記述していたので、書く方も読む方もノイズがなくなり嬉しい対応です。

* [Qiita:Team のニュース](https://teams.qiita.com/news/plantuml-and-copy-latest-article/)

記述方法は [PlantUML & GitLab](https://docs.gitlab.com/ee/administration/integration/plantuml.html) と同じ ``` に plantuml を記述します。
リアルタイムに図が作成されるのでストレスなくコードの記述ができますね。

![https://gyazo.com/8c83c916e3810861b3be5d76c11dcc5a](https://i.gyazo.com/8c83c916e3810861b3be5d76c11dcc5a.gif)

Qiita には未対応ですが要望が多ければ対応されるかも
その時はこのコードが図で表示されてるはず :satisfied:

```plantuml
Bob -> Alice : hello
Alice -> Bob : Go Away
```

# Tips

Qiita の PlantUMLの図は SVG で保存されています。 画像のアドレスは `data:image/svg+xml` のスキームです。なので Qiita:Team の認可は有効にならないので、画像のアドレスの公開すると誰でも参照することができますよ。
PsychoPyのCoderが見えないバグ

いつも通りPsychoPyを使おうとしたらCoderが透明になってて困った。
たまたま直し方を見つけたので共有します。

#Coderが見えない
![02.png](https://qiita-image-store.s3.amazonaws.com/0/242747/43cf710b-455e-4ebd-4ac9-590885e7fe8e.png)
Windowsのアップデートをかけたら突然Coderが透明になってしまった。

#原因 : 最小化されていた
![04.png](https://qiita-image-store.s3.amazonaws.com/0/242747/a34fc125-e4b8-ea2d-0208-c990065058f4.png)
タスクバーから透明なCoderのウィンドウを右クリックして最大化を選択


![05.png](https://qiita-image-store.s3.amazonaws.com/0/242747/bbc5e4e2-5783-aec2-52a0-4ef47f3c1730.png)
Coderのウィンドウが表示できました。


以上です。ありがとうございました。
【PHP】引数の二種類の NULL 許容型の宣言方法とその違い

## PHP 7.0 から使える型宣言について

PHP 7.0 から関数の引数や戻り値の型宣言が出来るようになりました。

例えば、次のように関数を宣言すると、引数の `$name` は 文字列型 (string) として受け取ることを強制できます。この引数に文字列型として受け取れない値を渡すとエラーが発生するようになります。

```php
function dumpName(string $name) {
    var_dump($name);
}
```

型宣言を活用することで、意図しない型の引数が渡される可能性を考慮せずに関数の実装をできるようになります。想定されることが少なく済むほどコードも単純化し、品質の向上に繋がります。

型宣言の制約を上手く活用することがソフトウェアの品質向上への近道と言えます。

## NULL 許容型の宣言方法

さて、この便利で頼もしい型宣言の機能ですが、上記のコード例のままだと引数に NULL を渡した場合にエラーとなります。

NULL も渡せる引数型の宣言をするには次の二通りの方法があります。

### 1. デフォルト値を代用した宣言方法

引数のデフォルト値の指定を代用することで NULL 許容型を表現できます。
引数に NULL を渡した場合でもエラーになることはありません。
この宣言方法は PHP 7.0 から使えます。

```php
function dumpName(string $name = null) {
    var_dump($name);
}
```

### 2. 専用の nullable 型宣言による宣言方法

型名の前に `?` を追加することで NULL 許容型として宣言できます。
例えば `?int` とすると整数型か NULL のどちらかを受け入れるようになります。
この宣言方法は [PHP 7.1 から使えます] (http://php.net/manual/ja/migration70.new-features.php#migration70.new-features.scalar-type-declarations)。

```php
function dumpName(?string $name) {
    var_dump($name);
}
```

## 両者の宣言方法の違い

上記の二種類の宣言方法には違いがあります。
それは（そのままですが）デフォルト値があるかどうかです。

一つ目の `dumpName(string $name = null)` の宣言の場合、引数に何も渡さなくても `$name` にデフォルト値である NULL が設定されるためエラーにはなりません。

二つ目の `dumpName(?string $name)` の宣言の場合、引数に何も渡さなかった場合は引数不足で以下のようなエラーが発生します。

> Fatal error: Uncaught ArgumentCountError: Too few arguments to function dumpName()

## 両者の宣言方法の使い分け

関数としてデフォルト値が無いほうが自然な設計になる場面では `?` を使った宣言をし、
デフォルト値として null が必要な場面では `$var = null` といった宣言をすると良いでしょう。
webpack で babel-runtime を使おうとしてハマったメモ

polyfill を使うために `babel-loader` から `babel-plugin-transform-runtime`, `babel-runtime` を利用しようとしたらハマったのでメモ。

# 1. 正しく動作する導入手順

```shell
npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime
```

以下はどちらか 1 つ。

```json:.babelrc
{
  "plugins": ["transform-runtime"],
  "ignore": ["node_modules"]
}
```

```json:package.json
...
  "babel": {
    "plugins": ["transform-runtime"],
    "ignore": ["node_modules"]
  },
...
```

# 2. ハマった理由

`node_modules` ディレクトリに Babel が影響していたから。
`babel-plugin-transform-runtime` のドキュメントには `node_modules` のことが書かれていなかったので気が付きませんでした…。

webpack 側の設定で `exclude` することでも対処できますが、webpack 4 で設定ファイルなしで使っているときなども考えると、Babel 側で `ignore` する方が良いような気がします。

参考「[webpackでbabel際はnode_modulesをexcludeし忘れるべからず - Qiita](https://qiita.com/haribote/items/73ede4fcdf9c942f1c4f)」
参考「[babel-plugin-transform-runtime · Babel](https://new.babeljs.io/docs/en/babel-plugin-transform-runtime)」
ド・モアブルの問題

```math
\begin{align}
&~~~歪みのないコインを10回投げたときに，表が3回以上連続して出る確率は？\\
\\
&~~~n投して表が3回以上連続「しない」場合の数をa_n通りとすると，\\
&下表より，\\
&~~~~~~a_n=a_{n-1}+a_{n-2}+a_{n-3}~~~~~~ \cdots①\\
\end{align}
```
|1投目|2投目|3投目||
|---|---|---|:---|
|裏|||残り$n-1$枚なので，${a_{n-1}}$通り|
|表|裏||残り$n-2$枚なので，${a_{n-2}}$通り|
|表|表|裏|残り$n-3$枚なので，${a_{n-3}}$通り|
|表|表|表|3回連続してしまっている|
```math
\begin{align}
&~~~そして，a_1=2，a_2=4，a_3=7なので①より，\\
&a_4=13，a_5=24，a_6=44，a_7=81，a_9=274，a_{10}=504\\
&したがって答えは，\frac{2^{10}-504}{2^{10}}=\frac{520}{1024}=\frac{65}{128}
\end{align}
```
GPAを計算するプログラムを書こうとした話

自分の在学している某大学で先日成績開示がありました。講義をあまりよく聞いておらずテストの数日前に火の車のごとく猛勉強（という名のゴリ押し）をしてなんとか無事単位の味を噛みしめることができました。

それはそうとして、気になるのは成績評価の指標であるGPAです。いちいち電卓打つのも面倒だしアプリを入れるのもネットを使うのもなあ。というわけで今まで勉強してきたショボい知識をフル活用してGPAを計算してくれるプログラムを作ろう！と言う流れになりました。~~PC開いてプログラム実行するほうがよほど面倒だろ~~

#GPAってなによ

自分で調べてください。

#１作目

とりあえずコードを見てください。

```ruby:gpa-calc.rb
puts "履修単位数を入力してください"
ln = gets.to_i

puts "GPA計算を行います。"

i = 1.0 #単位数1.0の科目からスタート
sum = 0

while i < 4.0 #1教科ごとの単位数の最大が（某大学では）3.0
   puts "単位数#{i}の教科について計算します。"

   puts "秀の科目数"
   s = gets.to_i

   puts "優の科目数"
   a = gets.to_i

   puts "良の科目数"
   b = gets.to_i

   puts "可の科目数"
   c = gets.to_i

   puts "不可の科目数"
   d = gets.to_i

   sum = sum + (s*4 + a*3 + b*2 + c)*i
   i = i + 1.0
end

gpa = sum / ln

puts "あなたのGPAは%.2fです。" % gpa
```

単位数1.0の科目から順に各成績ごとに個数を打ち込んで計算する力押し方です。ぶっちゃけCで組める。Rubyっぽい要素がそんなにない。実行するとこんな感じ。

```
履修単位数を入力してください
22
GPA計算を行います。
単位数1.0の教科について計算します。
秀の科目数
0
優の科目数
1
良の科目数
1
可の科目数
1
不可の科目数
0
単位数2.0の教科について計算します。
秀の科目数
1
優の科目数
3
良の科目数
2
可の科目数
1
不可の科目数
1
単位数3.0の教科について計算します。
秀の科目数
0
優の科目数
0
良の科目数
1
可の科目数
0
不可の科目数
0
あなたのGPAは2.18です。
```

成績はサンプルで適当に組みました。自分のではないです。見にくいですがちゃんと実行できていますね。どことない「Ｃ言語でいいよな」感。

#2作目

Ruby感を出したい！な２作目。

```ruby:gpa-calc.rb
puts "履修単位数を入力してください"
ln = gets.to_i

puts "GPA計算を行います。"
puts "秀 優 良 可 不可  の順番に取得した単位数を入力。"

a = 0
sum = 0
i = 1.0
suml = 0

while i < 4.0
  puts "単位数#{i}の科目について計算します。"

  s, a, b, c, d = gets.split(" ").map!{|n| n.to_i} #Rubyっぽい

  sum = sum + (s*4 + a*3 + b*2 + c) * i
  suml = suml + (s+a+b+c+d) * i.to_i #今までの合計
  i = i + 1.0
end

if suml > ln
  puts "入力した単位数が履修単位数を超えています。"
else
  gpa = sum / ln
  puts "あなたのGPAは%.2fです。" % gpa
end
```

説明するより出力見たほうが早いと思います。

```
履修単位数を入力してください
22
GPA計算を行います。
秀 優 良 可 不可  の順番に取得した単位数を入力。

単位数1.0の科目について計算します。
0 1 1 1 0

単位数2.0の科目について計算します。
1 3 2 1 1 

単位数3.0の科目について計算します。
0 0 1 0 0
あなたのGPAは2.18です。
```

出力にある通り、各単位数の科目で、左から順に秀・優・良・可・不可の個数を半角スペース区切りで入力するとGPAが出ます。

while内２行目の説明です。１作目と同じく秀・優・良・可・不可のそれぞれに変数を割り当てる必要がありますが、わざわざ５個puts置くのもなあと感じたので１行で５個一気に入力してしまいます。

```
s, a, b, c, d = gets
```

ただこれだけだと、何を入力してもそれ全体がString型の文字列になってsに格納されてしまい、a以降には何も入りません。

検証と出力

```Ruby:main.rb
s, a, b, c, d = gets #3 0 2 4 0   と入力
p s
p s.class
p a
p a.class
```

```
3 0 2 4 0
"3 0 2 4 0\n"
String
nil 
NilClass
```

aがnilになっていて、オブジェクトがないことがわかります。そしたら次に、入力された文字列を特定の文字に従って分割して配列に格納して返す`String#split`を使います。今回は半角スペースを使ったのですがまあ何でもいいです。すると...

```Ruby:main.rb
s, a, b, c, d = gets.split(" ") #3 0 2 4 0   と入力
p s
p s.class
p a
p a.class
```

```
3 0 2 4 0
"3"
String
"0"
String
```

あらかじめ変数を複数設定してあるので、１つの変数ごとに配列の要素が１個ずつ、String型で入っていることがわかります。なお、変数の指定を１つだけにすると、その変数にArray型の配列そのものが返されます。あとは、String型を`to_i`メソッドで変換するだけです。変換も一気にやっちゃおうということで、配列の各要素を順番にブロックに渡して評価し、その結果で要素を置き換える`Array#map!`を使います。要素そのものを変えたいので破壊的メソッドです。これで、全部の要素を変換出来ました。

```Ruby:main.rb
s, a, b, c, d = gets.split(" ").map!{|n| n.to_i}
p s
p s.class
p a
p a.class
```

```
3 0 2 4 0
3
Integer
0
Integer
```

あとは、オプションとして打ち間違いか何かで最初に入力した履修単位数より多くなってしまったらエラーになります。他の例外処理やエラーも時間があったら付け足したい。

#終わりに

プログラムをはいよっと渡すだけにしたかったのに長々と説明してしまいました。稚拙なプログラムですが、もし需要があったら自由に使ってもらって構いません。また、加筆修正や間違いの指摘も受け付けてます。最後まで読んでいただきありがとうございました。
引数で使う　＊ ＊＊　について

http://iatlex.com/python/arg_kwargs/

・あとクラスはそのあたいになにか引き数を代入することで、発揮する関数みたいなものという認識かな
例えば、intクラスはそれに代入すると機能発揮

クラス例えばintみたいなやつでそこに値を入れることでそれがobjectとなる、そしてそのobjectの関数をしようすることはobject.functionとなる　それがもともと組み込まれてるものなら__とつく

関数でdef min(*args,key=None)って書いたら、関数に引き数が渡されなかったらデフォでNone

https://docs.python.jp/3/library/functions.html#sorted

・formatについて
formatをしようすることで１０進数から２進数にすることができたが、print format(255, '016b')のようにbの前に016をつかけることで、0000000011111111のように0を付け足した結果になる理由が不明。
調べてもわからなかった。
http://kaworu.jpn.org/python/Python%E3%81%A72%E9%80%B2%E6%95%B0%E3%82%92%E6%89%B1%E3%81%86
Arduinoなどのマイコンでサクッと負電圧をつくる（チャージポンプ回路）

# はじめに
電子工作をしていると、たまに負電圧（マイナスの電圧）が欲しくなるときがあります。
しかし正負電源というものをきちんと用意するには、ACアダプタを2つ用意したり、トランスを用いたりとなかなか大変。
ちょっとLCDを使いたいだけ、という場合にはコストが高すぎます。

そこで、チャージポンプ回路というものを使って、最小限の外付け部品で負電圧を生成し、
ダイオードやコンデンサの品種・容量を変えたときの出力の変化について実験を行いました。

# 原理
割愛します。以下のリンクが詳しいです。
http://www.epii.jp/articles/note/electronics/charge_pump

# 回路
基本的なチャージポンプによる電圧反転回路です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/ea0cfe37-c8d6-7bf0-23ec-0c95d083c9a1.png)

LTSpiceでシミュレーションしてみます。
入力は5V/10kHzの矩形波です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/c44054cb-5eac-6584-535d-a5477d946ccb.png)

ちゃんと負電圧が出ています。平均で-4.3Vほど。
-5Vが出てこないのは、ダイオードによる電圧降下のためです。

# 準備
### 部品
今回用意したのは以下の部品です。全て秋月で手に入るものです。

* ダイオード
    * 1N4148 - 汎用の小信号ダイオード。定番。
    * BAT43 - 小信号用ショットキーダイオード。今回のような用途には一番ピッタリかも。
    * 11EQS03L - 30V/1Aと少し大きめの整流用？ショットキーダイオード。BAT43よりVfが下がることを期待。
* コンデンサ
    * 積セラ 1uF/50V Y5V特性
    * 汎用電解コン 10uF/16V
* 負荷抵抗
    * 金属皮膜 1kΩ

### スケッチ
Arduinoのスケッチは以下の通りです。超簡単。
任意の周波数の矩形波を出力する `tone()` という関数を使っています。
以下の例では3番ピンから10kHzの矩形波を出力しています。

```c++

#define PIN 3
#define FREQ_HZ 10000

void setup()
{
    pinMode(PIN, OUTPUT);
    tone(PIN, FREQ_HZ);
}

void loop() {}
```

# 実験
ばしばし結果を載せていきます。
特に断りがない場合、負荷抵抗はすべて1kΩで、グラフの縦軸は見やすさのため反転させています。
測定は安物テスターで行いました。

まずはダイオード別の比較から。
ダイオード以外の条件は、C1とC2がそれぞれ積セラ1uF、周波数は10kHzです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/167c9e9f-bb84-5212-c260-6d0f17dd31bb.png)

期待通り、11EQS03Lが最も良い結果を残しました。
1N4148はちょっと厳しい結果ですね。小さくともショットキーダイオードを採用するのが良いと思われます。

次はコンデンサを変えたときの比較です。
C1は1uFの積セラのまま、C2を10uFの電解に変えたときの動作を見てみます。
ダイオードはBAT43で、周波数は10kHzです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/0b6f7952-29df-2993-e801-b3e6396b30cd.png)

あまり変わりませんね・・・
本当は、電解よりも積セラの方が周波数特性が良いため、積セラが良い結果を残すことを期待していたのですが、
そもそも容量が1uFと10uFで違うため、無意味な比較だったかもしれません。

次は周波数を変えたときの比較です。
ダイオードはBAT43、コンデンサはそれぞれ積セラ1uFです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/7ff9a604-bdb9-60bc-16eb-0639d2917af0.png)

1kHz, 4.7kHz, 10kHz, 47kHz, 65.535kHzと5種類の周波数を試しましたが、47kHzで限界の様子です。
ちなみに65.535kHzという周波数は、 `tone()` 関数での最大値です。

最後は負荷抵抗を変化させたときの比較です。
333, 500, 1000, 2000, 3000Ωと中途半端な値ですが、手元に1kΩの抵抗しか無かったためです。ご了承ください。
ダイオードはBAT43、C1は積セラ1uF、C2は電解10uF、周波数は62.5kHzです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/6fbf9fbf-b532-449b-1d6b-245dbb74cd9e.png)

3kΩ負荷のときに-4.33Vまで出ました。およそ1.4mAの出力電流です。

# まとめ
ちょっと負電圧が欲しいときはチャージポンプが便利！
音声信号を通すアナログスイッチ・マルチプレクサなんかにも使えます。

# おまけ
使用ピンが1つ増え、部品は3つ増えますが、以下のような回路を組むと出力を増強出来ます。
位相反転した2系統の矩形波で、絶え間なくC2を充電するイメージです。
シミュレーション結果を見てみると、冒頭のそれと比較してリップルが小さく、電圧が高く（低く）なっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/5ac92a26-73ac-3806-2679-3e350d285452.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148726/13215644-363b-1743-f0ed-8cbd3f27df49.png)
新卒でも３週間でできるnpmモジュール

npmモジュールを作成したら意外とダウンロードの伸びが良かったので、調子に乗って、参考になったサイトや詳細をまとめて投稿いたします。

## まずはこれ
[3分でできるnpmモジュール](https://qiita.com/fnobi/items/f6b1574fb9f4518ed520)
[3時間でできるnpmモジュール](https://qiita.com/cognitom/items/75736e27cc7de151a7d5)
- npmアカウントの作成
- npmモジュールの御膳たて（各ファイルの準備）
- mochaを用いたテスト

## １週間目：環境構築
mochaを用いたテスト  
３時間でできるnpmモジュールで紹介されていますが、もう少し噛み砕きます。  
npmモジュールとして公開する前に、動作確認するためのモジュールです。  
導入は、下記コマンドを打ったのち、

```bash
npm i mocha
```
package.jsonで下記のように記述し、```npm run test```を打てば動作します。

```json
{
  "scripts": {
    "test": "mocha -R spec"
  }
}
```
他に設定は不要だが、testディレクトリ配下にmain.jsを作成し、このjsに処理を書いていく必要がある。

```
test
｜＿main.js
```
main.jsでの動作確認ができたところで、  
cliのモジュールならルートディレクトリ直下（任意）のindex.js、  
gruntのプラグインならtasksディレクトリ配下のsample.jsに処理を書き写してアップすることになる。

cliなら[binの設定](https://qiita.com/takayukioda/items/a149bc2907ef77121229),gruntならkeywodsの設定が必要。

```
my-module
  |--tasks
  |   |_sample.js <-grunt
  |
  |--test
  |  |_main.js <-mochaによるテスト
  |
  |--index.js  <-cli
  |--package.json
〜〜〜〜〜〜〜
〜〜〜〜〜〜〜
```

## ２週間目：実装
とりあえず、main.jsに記載していく。  
Node.jsのリファレンスとしては、[このサイト](https://nodejs.org/api/fs.html)にかなりお世話になっていく。一応、[日本語リファレンス](http://www.w3big.com/ja/nodejs/nodejs-fs.html) もあるがオススメしない・・・   
何を作るかによるが、filesystem, path, streamあたりを使用したモジュールが最初は作成しやすいのではないでしょうか。  
Node.jsは、非同期での処理を繋げていくことで軽量なモジュールを作成できることが特徴らしいです。

- [ファイル一覧を取得する](https://qiita.com/_shimizu/items/f08eaacdbcdce0204e36)
- [[Node.js]指定したパス配下（サブディレクトリ含む）のファイル一覧を取得する](https://kuroeveryday.blogspot.jp/2018/03/recursive-directory-search-with-nodejs.html)
- [matchメソッドから正規表現をマスターする！](https://www.sejuku.net/blog/25583)

## 3週間目：公開
1.[grunt pluginとして公開する場合](https://qiita.com/fnobi/items/5590e7e92b4f2bd81d04)、package.jsonのkeywodsにgruntpluginと追加しましょう。
また、対象ディレクトリなどユーザーに任意に推定してもらうところは、下記のようにgrunt.initConfigにて登録し、grunt.config()で取得します。
※Gruntfile.jsは、あくまでユーザが任意で設定するものなので、公開するだけなら作成しなくて良い。sample.js内にgrunt.initConfigを記載する必要もない。

```Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    search: {
      dir: 'dist'
    }
  });
  // プラグインのロード
  grunt.loadNpmTasks('class-search');

  //タスクの登録
  grunt.registerTask('default', ['class-search']);
};

```

```sample.js
module.exports = function (grunt) {

  grunt.registerTask('class-search', function () {
    const fs = require('fs');
    const path = require('path');
    const dirPath = grunt.config('search').dir;
   }
}
```

2.CIツールの一つであるTravis CIを使用するなら、３時間でできるnpmモジュールが参考になりますが、１点注意事項があります。

```.travis.yml
language: node_js
node_js:
  - 0.10
```
このように記載されていますが、nodeのバージョンが古く、mochaが正常にビルドせず、travis ciを通過できません。

```
SyntaxError: Use of const in strict mode.
```
 `- 0.10`　を別の新しいバーションに変更しましょう。


3.[初めてのnpm パッケージ公開](https://qiita.com/TsutomuNakamura/items/f943e0490d509f128ae2)
「npmに公開」らへんからとても参考になります。（バージョンの上げ方知らずに手動でpackage.jsonのversion変更してた・・・）


https://www.npmjs.com/package/class-search
他にも参考にしたサイトは思い出し次第追記していきます。
Sparkのリクエスト受付時の流れ

## はじめに

SparkFrameworkに関する情報です。

基本的な情報は下記を見てください。

http://sparkjava.com/


## Requestを受信したときのシーケンス

Sparkがリクエストを受け付けたときの処理のシーケンス図を作りました。
ソースを読んでいて色々わかったこともあので、メモを残します。


### Sparkのイメージ

実際のシーケンス図の前に、公式ページに載っている内容から想定するシーケンス図を張っておきます。

![spark_frame.png](https://qiita-image-store.s3.amazonaws.com/0/237238/cdee4ea0-84c0-a842-551c-d81b69c024d6.png)



### 実際のシーケンス

![spark_request.png](https://qiita-image-store.s3.amazonaws.com/0/237238/18cb7bf6-0aed-9d1b-df8e-fc2f733d698b.png)



## わかったこと

### Routeインスタンス

利用者が独自に実装するクラスとして、Route、Filter、ExceptionHandlerがありますが、
これらは最初にSparkに設定したインスタンスを利用し続けます。

従ってスレッドセーフな作りにする必要があります。


### URLに複数マッチしたときの挙動

Route、Filter、ExceptionHandlerのそれぞれによってマッチ処理に違いがあるため、注意が必要です。


#### Route

Routeは1番最初にマッチしたものが実行されます。
評価は定義された順に行われます。

実行例は下記のとおりです。


サンプルプログラム

````java:
public static void main(String[] args) {
  get("/hello", (request, response) -> "hello");
  get("*", (request, response) -> "*");
}
````

上記のプログラムに対し、http://localhost:4567/hello にアクセスしたときの表示結果は下記のとおりです。

````
hello
````

#### Filter

beforeFilter、afterFilter、afterAfterFilterは、マッチしたものすべてが実行されます。
実行順序は定義された順になります。


サンプルプログラム

````java:
public static void main(String[] args) {

  before((request, response) -> {
    System.out.println("before 1");
  });

  before("/hello", (request, response) -> {
    System.out.println("before 2");
  });

  get("/hello", (request, response) -> "hello");
    System.out.println("hello");
    return "hello";
  });
  
  after((request, response) -> {
    System.out.println("after 1");
  });

  after("/hello", (request, response) -> {
    System.out.println("after 2");
  });
  
  afterAfter((request, response) -> {
    System.out.println("afterAfter 1");
  });

  afterAfter("/hello", (request, response) -> {
    System.out.println("afterAfter 2");
  });
}

````

上記のプログラムに対し、http://localhost:4567/hello にアクセスするとコンソールには下記が表示されます。

````console:
before 1
before 2
after 1
after 2
afterAfter 1
afterAfter 2
````


#### ExceptionHander

ExceptionHanderは、定義されたExceptionに一番近いもののみ実行されます。

サンプルプログラム

````java:
public static void main(String[] args) {

  get("/hello", (request, response) -> {
    if (true) {
      throw new RuntimeException();
    }
    return "hello";
  });

  exception(Exception.class, (exception, request, response) -> {
    System.out.println("Exception");
  });

  exception(RuntimeException.class, (exception, request, response) -> {
    System.out.println("RuntimeException");
  });
}
````

上記のプログラムに対し、http://localhost:4567/hello にアクセスするとコンソールには下記が表示されます。

````console:
RuntimeException
````


### haltメソッドが利用できる箇所

haltメソッドを呼び出すと、HaltExceptionがthrowされます。
仕様なのか考慮もれなのかわかりませんが、HaltExceptionが処理される場所は限られており、
有効でない場所があります。

haltメソッドが有効なのは下記です。

BeforeFilter、AfterFilter、Route


下記は利用しても、想定通りの動きはしません。

AfterAfterFilter、ExceptionHandler
Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (番外編)


# Node-REDコンテナのリポジトリに、IBM Cloud gitリポジトリを設定する方法

これまで、３つの記事で、GitHubを利用して解説を進めてきましたが、IBM Cloud が提供するGitLabリポジトリを利用するケースでの補足資料です。

* [Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (1/3)](https://qiita.com/MahoTakara/items/86c0d1072d1cd34187d5)
* [Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (2/3)](https://qiita.com/MahoTakara/items/605b1e32ddf22fb7b910)
* [Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (3/3)](https://qiita.com/MahoTakara/items/8cfa4d0be22277869084)
* [Node-REDが動作するコンテナをビルドして Kubernetes で実行するまでを解説 (番外編)](https://qiita.com/MahoTakara/items/2529c4a66519fb459e5d)


Node-RED v0.18 Gitリポジトリとの連携で、GitHubのアカウントとパスワードを利用しました。しかし、IBM Cloud の GitLabのリポジトリhttps://git.ng.bluemix.net/ を利用するには、IBM Cloud にログインする必要があり、少し仕組みが違うので、その方法についてみていきます。


下記の様にGit repository URL、Username, Passwordの取得方法について、解説していきます。

![スクリーンショット 2018-03-13 0.01.36.png](https://qiita-image-store.s3.amazonaws.com/0/42829/ae8980cf-57ca-a66f-fc17-4ff9f752bfc1.png "スクリーンショット 2018-03-13 0.01.36.png")


## プロジェクトの作成とHTTPSアクセス

次のグリーン色のメニュー・バーの真ん中あたり「+」マークをクリックすると、プロジェクト（GitHubのリポジトリ）作成の画面が表示されます。この画面で、Project Name をインプットして、 Visibility Level をPrivate として「Create Project」をクリックして実行します。

![スクリーンショット 2018-03-13 0.49.44.png](https://qiita-image-store.s3.amazonaws.com/0/42829/274bcdbc-d27e-2cc1-36d7-143a6e8a9d75.png "スクリーンショット 2018-03-13 0.49.44.png")

これで生成されたプロジェクト名のNode-RED-Proj-3の下部分 SSH と HTTPSを切り替える部分があります。 この選択をHTTPSとする事で、HTTPSから始まるURLが表示されます。これが、リポジトリのURLとなります。

![スクリーンショット 2018-03-13 0.54.27.png](https://qiita-image-store.s3.amazonaws.com/0/42829/950ce5cf-75ab-4484-ad07-5e3bf5af4ebc.png "スクリーンショット 2018-03-13 0.54.27.png")



## IBM Cloud GitLab からのユーザーIDとパスワードの取得

### ユーザーIDのピックアップ

ユーザーIDは、次の図の様に、右端のメニューを表示してフルネームの下に「@takara9」となっている部分の@マークを除いた部分です。

![スクリーンショット 2018-03-13 0.10.25.png](https://qiita-image-store.s3.amazonaws.com/0/42829/4008bf0a-c833-7c70-8619-0df77de77eba.png "スクリーンショット 2018-03-13 0.10.25.png")

### アクセス・トークンの生成

パスワードは、IBM Cloud にログインする時のパスワードではなく、Access Tokens から専用にジェネレートします。次の様に左端メニューバーの上から４番目のアイコン Access Tokensを選択します。

![スクリーンショット 2018-03-13 0.08.04.png](https://qiita-image-store.s3.amazonaws.com/0/42829/28fd2995-bf5f-c446-ad7e-f19f30ea2dd1.png "スクリーンショット 2018-03-13 0.08.04.png")

アクセス・トークンを生成するには、Nameにトークンの名前, Expires at 有効期限の日付, Scope の二つの項目にチェック　をセットして、「Create personal access token」をクリックして、トークンを生成します。


![スクリーンショット 2018-03-13 0.15.59.png](https://qiita-image-store.s3.amazonaws.com/0/42829/19648393-e7d5-3fca-8993-397c49b862fb.png "スクリーンショット 2018-03-13 0.15.59.png")

生成されたトークンは、一度だけしか表示されませんので、メモ帳にコピペして保存しておきます。　このトークンをパスワードとして利用します。


![スクリーンショット 2018-03-13 0.16.18.png](https://qiita-image-store.s3.amazonaws.com/0/42829/ce23dc84-2bfc-e6ee-d010-2044206dea8a.png "スクリーンショット 2018-03-13 0.16.18.png")



## プロジェクトメンバーの場合

プロジェクトに他のメンバーを追加して、そのユーザーがGitにアクセスするには、次の例では、@takaraのユーザーIDで、上記の同様の操作を行う事で、アクセスできる様になります。

![スクリーンショット 2018-03-13 0.44.44.png](https://qiita-image-store.s3.amazonaws.com/0/42829/5788f50c-112d-ac15-603c-6ec7457a56f4.png "スクリーンショット 2018-03-13 0.44.44.png")



以上です。


# 参考資料
* [Bluemix git リポジトリの使い方のメモ](https://qiita.com/MahoTakara/items/bb0a645391c61b438599)
pythonでjsonファイルからの値取得

## pythonでjsonから値を取り出す。

たとえば、[TwitterAPI](https://apps.twitter.com/)で使うkeyたちをjsonファイルで管理したい。

こんな感じのjsonファイルを作成する。

```json:config.json
{
    "api_key": {
        "CONSUMER_KEY": "xxxxxxxxxx",
        "CONSUMER_SECRET": "xxxxxxxxxx",
        "ACCESS_TOKEN": "xxxxxxxxxx",
        "ACCESS_TOKEN_SECRET":"xxxxxxxxxx"
    }
}
```

下記のようにすると、jsonから値を取り出せる。

```python:app.py
# モジュールのインポート
import json

# ファイルを開く
json_file = open('config.json', 'r')
# JSONとして読み込む
json_obj  = json.load(json_file)

#　値の取り出し
CONSUMER_KEY        = json_obj['api_key']['CONSUMER_KEY']
CONSUMER_SECRET     = json_obj['api_key']['CONSUMER_SECRET']
ACCESS_TOKEN        = json_obj['api_key']['ACCESS_TOKEN']
ACCESS_TOKEN_SECRET = json_obj['api_key']['ACCESS_TOKEN_SECRET']
```

個人の趣味とかだと設定値系はついつい直書きしてしまうので、ちゃんと外だしするくせをつけたい。
ヴィエトの等式

```math
\begin{align}
&\frac{\sqrt{2}}{2}\cdot\frac{\sqrt{2+\sqrt{2}}}{2}\cdot\frac{\sqrt{2+\sqrt{2+\sqrt{2}}}}{2}\cdot\dots\\
&=\frac{2}{\pi}\\
\\
\sin x&=2\cos\frac{x}{2}\sin\frac{x}{2}\\
&\sin\frac{x}{2}=2\cos\frac{x}{4}\sin\frac{x}{4}なので，\\
&=2\cos\frac{x}{2}\cdot2\cos\frac{x}{2^2}\sin\frac{x}{2^2}\\
両辺&をxで割って，\\
\frac{\sin x}{x}&=2^n\cos\frac{x}{2}\cos\frac{x}{2^2}\dots\dots\cos\frac{x}{2^n}\cdot\frac{\sin\frac{x}{2^n}}{\frac{x}{2^n}}\\
n\to &\inftyのとき，\frac{\sin\frac{x}{2^n}}{\frac{x}{2^n}}\to1\\
した&がって，\frac{\sin x}{x}を表す無限級数は，\\
\frac{\sin x}{x}&=\cos\frac{x}{2}\cos\frac{x}{2^2}\cos\frac{x}{2^3}\dots\dots\\
x=&\frac{\pi}{2}のとき，\\
\frac{\sin\frac{\pi}{2}}{\frac{\pi}{2}}&=\frac{2}{\pi}=\cos\frac{\pi}{4}\cos\frac{\pi}{8}\cos\frac{\pi}{16}\dots\dots\\
{\cos}^2\frac{\theta}{2}&=\frac{1+\cos\theta}{2}より，\\
0\leqq\theta&\leqq\piのとき，\cos\frac{\theta}{2}=\frac{\sqrt{2+2\cos\theta}}{2}\\
\cos\frac{\pi}{4}&=\frac{\sqrt{2}}{2}\\
\cos\frac{\pi}{8}&=\frac{\sqrt{2+\sqrt{2}}}{2}\\
\cos\frac{\pi}{16}&=\frac{\sqrt{2+\sqrt{2+\sqrt{2}}}}{2}\\
\dots\dots\\
ゆえに，&\frac{2}{\pi}=\frac{\sqrt{2}}{2}\cdot\frac{\sqrt{2+\sqrt{2}}}{2}\cdot\frac{\sqrt{2+\sqrt{2+\sqrt{2}}}}{2}\cdot\dots
\end{align}
```
Node.jsをとりあえず動かしてみた

[前回の記事](https://qiita.com/Purindle/items/978d8403398e75018734) の通り環境構築をしたので、
さっそくNode.jsを使って何かしら動かしてみた。

# 1. Node.jsでHello World!
下記のファイルを作成する。
`vim hello.js`

```hello.js
var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World!');
}).listen(3000);
```
listenに指定するのはポート番号。
1024以下にする場合、root権限があれば実行できるが、
何かあった時にすべて乗っ取られて危険なのでやめておくべき。
※つまり、ポート番号80などを指定したい場合、工夫が必要。

# 2. hello.js 実行
下記コマンドを叩く。
`node hello.js`

ブラウザででアクセス。
例：`http://153.126.204.61:3000/`
Hello World!と表示される。

コンソールで `[Ctrl] + [C]` を押すと停止できる。

# 3. まとめ
nginxなどのWebサーバーを使わずとも、
ブラウザからのアクセスをNode.jsによって受け付け、
レスポンスを返すことが出来た。

ちなみに、`systemctrl stop nginx` でnginxを停止できる。
Webサーバーを止めていても、「hello.js」を動かしている間は、
ブラウザからのアクセスを受け付けられる。