OmniAICreator/Qiita-1.07M huggingface dataset:
【Java】文字列を指定文字で分割する

指定された正規表現で文字列を分割する時は、splitメソッドを使用します。

##split

###指定の正規表現で文字列を分割する

```java:split.java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {

        String str1 = "レタス かぼちゃ きゅうり";
        String str2 = "いちご,りんご,キウイ";
        
        //空白区切り
        String[] split1 = str1.split(" "); 
        for ( int i = 0; i < split1.length; i++ ) { 
          System.out.println(split1[i]); 
        } 
        
        //カンマ区切り
        String[] split2 = str2.split(","); 
        for ( int i = 0; i < split2.length; i++ ) { 
          System.out.println(split2[i]); 
        } 
    }
}
```

```:結果
レタス
かぼちゃ
きゅうり
いちご
りんご
キウイ
```
ngx_mrubyでリダイレクタを作る

この記事は
===

* しょぼいHTTPリダイレクタをngx_mrubyで作ってみたのでメモです

やりたかったこと
===

* ある内部向けサイトと外部向けサイトの２つのサイトがありました
* 下記のような感じでおなじリダイレクタにアクセスしてるんだけど拠点によって振り分け先を変えたかったです
  * 社内 => リダイレクタ => 内部向けサイト
  * 社外 => リダイレクタ => 外部向けサイト
* 内部向けサイトはIPで縛ったりしているので、ProxyではなくRedirectorで実装したかったです

それAWSでできない？
===

* 最初はAWSの設定で適当にやろうとおもっていたのですが、調べた限りにはできなかったです
* ALBの場合
    * 対応してる条件： ホスト名が一致する場合またはパスが一致する場合
    * 可能な処理処理： リダイレクト
* WAFの場合
    * 対応してる条件： ソースIPが一致する場合
    * 可能な処理処理： ブロック
* ていう感じで、ソースIPが一致する場合リダイレクトっていう処理はできそうでできませんでした

そこで
===

* できそうでできないAWSにむしゃくしゃしたので面舵を180度振り切って、[ngx-mruby](https://github.com/matsumotory/ngx_mruby)を使って、上記のリダイレクタをスクラッチで作ってしまえ！と思い立ちました
* ちなみに下記の案も頭をよぎりましたが、却下しました
  * 普通のnginx.confでRewrite地獄を頑張る・・・地獄はいやだ
  * rails立ててredirect_toとかで適当にコーディングする・・・後々セキュリティfix取り込んで保守するのとか(ry

やり方
===

ecsでやります
---

* 最初からngx-mrubyが動く状態のdocker imageが公開されていることがわかったので、ecsで行くことにしました
* 別に普通のecsなので諸々割愛


dockerイメージの準備
===

* 作者様謹製の[Dockerfile](https://github.com/matsumotory/docker-ngx_mruby)をcloneしてきます

```
git clone https://github.com/matsumotory/docker-ngx_mruby.git
```

Dockerfile
---

* DockerfileはそのままでOKです

```Dockerfile:Dockerfile
FROM matsumotory/ngx_mruby:master
MAINTAINER matsumotory

#
# matsumotory/ngx-mruby image supports ONBUILD for below commands.
#
# ONBUILD ADD docker/hook /usr/local/nginx/hook
# ONBUILD ADD docker/conf /usr/local/nginx/conf
# ONBUILD ADD docker/conf/nginx.conf /usr/local/nginx/conf/nginx.conf
```

* ここのコメントに書かれている通り、docker/*の下にある各種ファイルがdocker build時に勝手にイメージに取り込まれます

nginx.conf
---

* こんな感じにして、全アクセスを```mruby_content_handler```に振り分けます
* ここで指定している```redirect.rb```がmrubyのリダイレクタの書かれたファイルです

```docker/conf/nginx.conf
user daemon;
daemon off;
master_process off;
worker_processes 1;
error_log stderr notice;
#access_log /dev/stdout;

events {
    worker_connections  1024;
}

http {
    access_log /dev/stdout;
    server {
        listen 80;

        location ~ ^/.*$ {
            mruby_content_handler /usr/local/nginx/hook/redirect.rb;
        }
    }
}
```

mrubyコード
---

* mrubyのコードはこんな感じです
* さいしょからそれっぽいクラスが定義されていて各種情報の受け取りとかリダイレクト処理とかできます
* いい感じに[Class説明のドキュメント](https://github.com/matsumotory/ngx_mruby/tree/master/docs/class_and_method)も準備されてて感謝です

```ruby:docker/hook/redirect.rb
INTERNAL_IPS = [
  "localhost"
]
PRIVATE_URL = 'https://private.example.com'
PUBLIC_URL = 'https://public.example.com'

r = Nginx::Request.new
path = r.unparsed_uri
header = r.headers_in

source_ip = header['X-Forwarded-For']
source_ip ||= Nginx::Connection.new.remote_ip

if INTERNAL_IPS.include?(source_ip)
  Nginx.redirect("#{PRIVATE_URL}#{path}", Nginx::HTTP_MOVED_PERMANENTLY)
else
  Nginx.redirect("#{PUBLIC_URL}#{path}", Nginx::HTTP_MOVED_PERMANENTLY)
end
```


普通にbuild
---

* buildしてrunします
* 普通にローカルで動きます

```
docker build -t nginx-mruby-redirect .
docker run -d nginx-mruby-redirect
```


* ちなみに```docker exec```してこのmrubyコードを書き換えると再起動等一切なしで反映されます
* めっちゃデバッグしやすくてちょっと感動した


デプロイすると
===

* ecsの設定もろもろして、デプロイしてみたら普通に動きました！

終わりに
===

* 想像よりもだいぶお手軽にできました！
* gem使おう等するとbuildからやり直しっぽくて、docker image作るところからになりそうだったのでスキップしたけどそのうちやってみたい。
Java8 Stream API 練習

現場を離れて久しいのでJava8練習中。

Java6っぽいJava8を書くことは可能だし、プログラマーの最低レベルに合わせるとそうなってしまう現場も多々あることは承知の上だが、便利なものはどんどん取り入れて改善していくべきだという考えは今も変わりません。

クソコードを生み出してしまったので恥ずかしながら公開。

```java:
// テストデータをたくさん作りたい場合とかを想定してください。
// 悪い例
List<MyObject> objs = Stream.of(1, 2, 3, 4, 5).map(i -> {
    MyObject myObj = new MyObject();
    /* いろいろやる */
    return myObj;
}).collect(Collectors.toList());

// 良い例
// IntStream#range() だと5が出ないので注意
List<MyObject> objs = IntStream.rangeClosed(1, 5).mapToObj(i -> {
    MyObject myObj = new MyObject();
    /* いろいろやる */
    return myObj;
}).collect(Collectors.toList());
```

コレクションの変数名を複数形（-s, -es）にするのがマイブーム。xxxListみたいな命名にしちゃうとハンガリアンっぽくて気持ち悪いし、型がListじゃなくなる可能性だってあるよなって、かれこれ５年くらいずーっともやもやしていたところでした。

Perlみたいな書き方ができないものかな～と、かれこれ30分くらい試行錯誤していました。Stream#of()の引数を 1 .. 5 とか書いてみたけど、まあ動くわけがない。PerlじゃなくてJavaなんだから。

```perl:
# 注：Perlみたいな書き方
my @array = (1 .. 5);
```

そういえばPerlってまだ現役のところあるんですかね？

ストラッツやめろキャンペーンと同時期にPerlアプリ廃止案件がどっさり来て結構てんやわんやでしたね。リプレースしたいけど設計書がない上に、リバースエンジニアリングできる技術者も滅多にいないんだそうで。

かくいう自分も、最近はちょっとしたことは全部Pythonにやらせていますが。Perl書く方が得意なんですが、インターネットから切り離された環境だとCPANが使えないのが不便で……
C#がPDFドキュメントを圧縮する

PDFドキュメントは、私たちの日常のオフィスでよく使用されている文書で、PDFドキュメントが多くて、転送と送信には不利です。この文章は、C#を使用することによって、C#を使用するために、PDFファイルを圧縮したPDFファイルをどのように使用するかを紹介します。

Spire.PDFには、主に2つの圧縮方式があります。1つは圧縮ファイルの内容を圧縮して、もう一つは圧縮ファイルの中の画像で、その中の圧縮画像はまた画像の品質と直接圧縮の2つの異なる方法に分けられます。注意しなければならないのは、異なる文書の圧縮効果については、主にpdfの内容自体が比較的大きいのか、ドキュメントには文字が多いか、画像の多い効果が異なるのか、自分の文書によって相応する圧縮方式を選択することができます。

以下のコードを使用する前に必要：

1. ダウンロード[Spire.PDF](https://www.e-iceblue.com/Introduce/free-pdf-component.html)，また、インストール経路からSpire.pdf.dllをアプリケーションに引用する
2. 名のスペースを引用する：

```
using System.Drawing;
using Spire.Pdf;
using Spire.Pdf.Exporting;
using Spire.Pdf.Graphics;
```
圧縮内容

```
// PDFドキュメントをロードする
PdfDocument doc = new PdfDocument("Test.pdf");
 //禁用incremental update
doc.FileInfo.IncrementalUpdate = false;
 // PDFドキュメントの圧縮レベルを設定
doc.CompressionLevel = PdfCompressionLevel.Best;
//ファイルを保存する
doc.SaveToFile("Compressed.pdf");
```
![Compress content.png](https://qiita-image-store.s3.amazonaws.com/0/278784/e57ea8b0-f2a1-ce69-0c9c-0a12d5c0493e.png)

画像を圧縮する

方法1：画像の品質を低減する

```
// PDFドキュメントをロードする
PdfDocument doc = new PdfDocument("Image.pdf");
//禁用incremental update
doc.FileInfo.IncrementalUpdate = false;
 //すべてのページについて
foreach (PdfPageBase page in doc.Pages)
{
    //ページの画像を抽出する
    Image[] images = page.ExtractImages();
 
    if (images != null && images.Length > 0)
    {
        //すべての画像を遍歴する
        for (int j = 0; j < images.Length; j++)
        {
            Image image = images[j];
 
            PdfBitmap bp = new PdfBitmap(image);
 
            //画像の品質を下げる
            bp.Quality = 20;
             //圧縮後の画像で元ドキュメント中の画像を入れ替える
            page.ReplaceImage(j, bp);
         }
    }               
}
 
//ファイルを保存する
doc.SaveToFile("Output.pdf");
```
![compress image1.png](https://qiita-image-store.s3.amazonaws.com/0/278784/9a03e598-d0a2-a91b-7ed2-d1543ea9e28b.png)

方法2：画像を直接圧縮する

```
// PDFドキュメントをロードする
PdfDocument doc = new PdfDocument("Image.pdf");
//禁用incremental update
doc.FileInfo.IncrementalUpdate = false;
 
// PDFページ
foreach (PdfPageBase page in doc.Pages)
{
    if (page != null)
    {
        if (page.ImagesInfo != null)
        {
            foreach (PdfImageInfo info in page.ImagesInfo)
            {
                //画像を圧縮する
                page.TryCompressImage(info.Index);
            }
        }
    }
}
 
//ファイルを保存する
doc.SaveToFile("Output1.pdf");
```
![compress image 2.png](https://qiita-image-store.s3.amazonaws.com/0/278784/3308b184-5137-9b39-3bd1-f8ecd455d7bb.png)
数値範囲に気をつけよう【Pythonの数値計算】

#まえがき
計算過程に巨大すぎる数字を使わないように気をつけようという話です。
#算数の話をしましょう
logの定義を確認しましょう。底をeとして

```math
\mathrm{log}(e) = 1
```
ですね。同様に

```math
\mathrm{log}(e^2) = 2
```
```math
\mathrm{log}(e^x) = x
```
です。では以下の式はどうでしょうか。

```math
\mathrm{log}(1 + e^x)
```
これはソフトプラス関数といいまして、機械学習のなんやかんやで使用されるものです。これは
$e^x >> 1$の時

```math
\mathrm{log}(1 + e^x) \simeq x
```
というように、xが十分に大きいときに1はほぼ無視できます。
#実装してみよう
```python
import numpy
def softplus(x):
    return numpy.log(1 + numpy.exp(x))
```
適当に数字を試してみます。

```python
print(softplus(0)) # 0.6931471805599453
print(softplus(1)) # 1.3132616875182228
print(softplus(2)) # 2.1269280110429727
print(softplus(100)) # 100.0
```
$x = 100$の時点で$e^x$は十分に大きいみたいですね。
# 何が問題か？
さらにxを大きくしてみましょう。


```python
print(softplus(1000)) # inf
```
想定される返り値は1000のはずですが、inf(無限大)という値が返ってきました。
#数値範囲
x = 100の時点で、$(1 + e^x)$はすごいことになっています。
$(1+e^{100}) = 2.6881171\times 10^{43}$

さらにこれを10乗した値が$(1+e^{1000})$。
最終的な計算結果は1000でも、途中でこんな異常な数字が出てきたらpythonの扱える範囲を超えてinfとして扱われてしまいます。
infのlogをとってもinf。これではいけません。

#改善策
要するに巨大な数字が計算途中に入らないようにすればよい。
元の式を変形してみましょう。

```math
\mathrm{softplus}(x) = \mathrm{log}(1 + e^x)\\
=\mathrm{log}(e^x(e^{-x} + 1))
\\
= \mathrm{log}~e^x + \mathrm{log}(e^{-x} + 1)\\
= x + \mathrm{log}(e^{-x} + 1)
```
これなら$x \geq 0$の範囲でinfをとることはありません。
逆に$x < 0$の範囲ではinfをとってしまうので

```math
  \mathrm{softplus}(x) = \begin{cases}
    x + \mathrm{log}(e^{-x} + 1) & (x \geq 0) \\
    \mathrm{log}(1 + e^x) & (x < 0)
  \end{cases}
```
というように場合分けしてやればいいわけです。
#実装してみよう

```python
import numpy
def softplus(x): # max(0, x) 0かxか、大きい方を採用する関数
    return max(0, x) + numpy.log(1 + numpy.exp(-abs(x)))

print(softplus(-1000)) # 0.0
print(softplus(0)) # 0.6931471805599453
print(softplus(1)) # 1.3132616875182228
print(softplus(1000)) # 1000.0
```
問題なく計算できました。
#まとめ
計算過程に巨大な数字が出るとinfを吐いてしまう。工夫して回避しよう。

『機械学習のエッセンス』という本を参考にしました。引き続きこの本についてまとめていきます。
前回:桁落ちに気をつけよう
https://qiita.com/NNNiNiNNN/items/af550e9f1c72aadd2577
次回:数理最適化問題
https://qiita.com/NNNiNiNNN/items/57e409e5dbcfac9897ec
wordでredmineのチケットへのハイパーリンク

word文書中にハイパーリンクでredmineのチケットのアドレスを指定した場合、
（例えば、"https://mng.abcd.co.jp/redmine/issues/1000" )
クリックするとredmineのトップページの表示止まりになってしまいます．
チケットが表示されるようにするにはどういった対応が必要なのか、ご存知の方ご教示ください．
エフェメラルポートの変更

iptablesなどでポートを制限したいがエフェメラルポートを利用するプログラム(UPnP等)がある場合、エフェメラルポートの設定をし直すことでiptablesの設定をしやすくすることができる。

方法は下記リンク

https://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
[忘備録] awkコマンドをすぐ忘れるので個人用まとめ(随時更新)

#集計
## 行の足し算
```
#### ファイル
cat /path/to/file
1
2
3
#### コマンド
awk '{a += $1} END {print a}' < /path/to/file
#### 結果
6
```

### 複数列ごとの集計
```
#### ファイル
cat /path/to/file
1    11
2    22
3    33
#### コマンド
awk '{a += $1; b += $2} END {print a, b}' < /path/to/file
#### 結果
6    66
```
FileMakerで動的値一覧を試す。


 自己紹介はマイページに譲るとして、現在テスト作成しているもので、動的値一覧が未だによくわかっていない感覚派。
今回は、こうしたら動いた！　というものでそれが実際に合理的かは不明。
でも、動いたからいいよね！　理論で始めています。間違っていたら随時訂正します。

さて、今回は勤怠管理システムとして自身がどの業務にどれぐらい時間を費やしているのか把握したいので、プロジェクトタスク管理を作ります。
サブタスクは日報用に時間を記入するようにしています。
現在がサブタスクの画面になります。

![スクリーンショット 2019-01-31 16.21.05.png](https://qiita-image-store.s3.amazonaws.com/0/242982/19171546-0cde-f4fb-2cb7-87e1f2a6e561.png)

プロジェクト選択して、その中からタスクを選択していきたいので、そのように動くよう設定します。
サブタスクを「_PK」で結んでいるのは、同日の他のサブタスクがないのかを確認する為です。

![スクリーンショット 2019-01-31 13.23.22.png](https://qiita-image-store.s3.amazonaws.com/0/242982/35be8112-b7eb-d59e-afe3-1208b0895521.png)

あとは別に繋げたタスクに紐づけて終わり。
「A11」は完全に表示用です。

![スクリーンショット 2019-01-31 13.23.46.png](https://qiita-image-store.s3.amazonaws.com/0/242982/dfd7d7a5-1797-6696-ef93-21c86e2edfe9.png)

このように書くとProjectが不要なのかもしれませんがー。
次の機会に試してみましょう。
rails grapeを使ったAPI作成

grapeを使ってAPIを作成したので、備忘録として記事にする

##環境
macbook pro
Majavo
rails 4.2.4
ruby 2.1.0

##grepのinstall 
Gemfileに以下を追加した後、bundle install 

```Gemfile
gem 'grape'
```

##ディレクトリ構造
以下のようなディレクトリ構造にする
ディレクトリ構造がきちんとなっていないとうまくできないので
出来るだけ、このまま行った方が良いです。

app
├apis
│ 　├api
│ 　　├──root.rb
│ 　　└ver1
│ 　　　├ Tests.rb
│ 　　　└ root.rb

## Path等の設定
config/routes.rbに以下を追加

```routes.rb
mount API::Root => '/'
```

config/application.rbに以下を追加

```application.rb
config.paths.add File.join('app','apis'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'apis', '*')]
```

api/root.tbに以下を追加

```api/root.rb
module API
	class Root < Grape::API
		#http://localhost:3000/api
		prefix 'api'
		format :json

		mount API::Ver1::Root
	end
end
```

api/ver1/root.rbに以下を追加

```api/ver1/root.rb
module API
	module Ver1
		class Root < Grape::API
			#http://localhost:3000/api/ver1
			format :json

			mount API::Ver1::Tests
		end
	end
end
```

##APIの作成

```Tests.rb

module API
	module Ver1
		class Events < Grape::API
			resource :tests do

				#POST /api/tests
				desc 'create event'
				params do 
					requires :Title, 		type: String ,	desc:'into title'
					requires :document, 		type: String, 	desc:'body'
				end

				
				post :create do
					Event.create(
						title: params[:title],
						document: params[:body],

						#返り値
						present :hash_id ,hash_id
					end

				
			end
		end
	end
end
```

##まとめ
今回はPOSTのみですが、GETなどを送りたいのであれば公式で確認ください
https://github.com/ruby-grape/grape
Swift4,Xcode10対応：UIWebViewを使って、記事を表示させてみよう！

#プログラミング初心者でも簡単に作れる記事一覧アプリ作成
今回は、プログラミング初心者に向けて、自分の好きな記事を一覧で表示するアプリの作成方法について解説していきます。

-環境-
・Xcode10
・Swift4

コードについては以下のgithubを参照してください。
https://github.com/YukiNagai1016/WebViewSample

完成図
<img width="352" alt="スクリーンショット 2019-02-25 14.42.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/4c8f4536-7d1b-dc04-3af1-78ded068d5c7.png">


##UIWebViewを用いてURLから記事を表示
###ViewController.swiftに以下のようにコードを書いて行きます。

以下のように、使う変数と表示させたい記事のタイトルとURL(文字列として)を配列に格納して宣言します。
<img width="897" alt="スクリーンショット 2019-02-25 14.47.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/dfc8cdd9-a204-4838-2f5f-3f10bd7fa48b.png">

次に、ViewDidLoad関数の中に以下のように書いていきます。
<img width="890" alt="スクリーンショット 2019-02-25 14.49.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/fc4bffe1-6730-0eab-ff27-c3850578d167.png">
<img width="895" alt="スクリーンショット 2019-02-25 14.50.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/911c0125-5362-776d-2672-c9c44b76797a.png">

その下にTableViewに関する決め事を書きます。
今回は、TableViewはViewController.swift内でUITableViewクラスのインスタンスを作り、実装しています。なので、ストーリーボード上で関連付け等の作業は必要ありません。
<img width="890" alt="スクリーンショット 2019-02-25 14.51.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/b31e1858-cc71-0430-f9f3-be673e369983.png">


最後にWebViewに関する決め事を以下のように書きます。主に「ロード開始時にアニメーションを表示する、」「ロード終了時にWebViewを表示する」、「WebView内で前の記事に戻ったり、進んだりできるようにする」の3つを実装しています。
<img width="898" alt="スクリーンショット 2019-02-25 14.55.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/237258/9c031db9-bdc5-f9ab-4980-6a3814c4f4fc.png">

以上で完成です！ロード中のアニメーションに関しては、Githubのリポジトリ内のサンプルに入れてあるので、参照してみてください！

#GithubURL
今回のアプリを以下のリンクからダウンロードできます。
https://github.com/YukiNagai1016/WebViewSample
focus,blur,change,focusin,focusout,click,mousedown,mouseupといったイベントリスナーの発火順序

毎回どの順序で発火するのかよくわからなくなって、発火順序を調べている気がするので作った。

[check input Event order CodePen.io](https://codepen.io/isdh/pen/rRBGYJ)
Brainf*ckコード メモ

#はじめに
この記事は、僕が2018年の夏から秋にかけてBrainf*ck言語にハマっていた頃に書いたソースコードを載せたものです。
大したものは、作っていないですが何かの役に立てれば幸いです。
#自己紹介
```brainfuck:自己紹介
++++[>++++<-]>[<++++>-]++++[<++++>-]<--.-----.------.++.>++++[>++++<-]>[<++>-]<.>>++++[<<<---->>>-]<<<---.>.>++++[<<++++++++>>-]
<<-----.>>++[<<---->>-]<<.>.>>++++[<<<---->>>-]<<<---.>.<+++>>++++[>++++<-]>[<<<++>>>-]<<<.>+..[-]<[-]
```
これは、[僕のTwitterのトプ画にあるソースコード](https://twitter.com/ss02jp)です。
実行すると、「NICE 2 ME 2 U!!」と出力されます。
#フィボナッチ数列
```brainfuck:Brainfuck
++++[>++<-]>[>++++++>++++++>++++++<<<-]>>
.
>+
.
[
[<+>>+<-]
<<
[<+>>-<-]
>.
[>+<-]
>>
[<<+>>-]
<<<<
[>+<-]
>>>
]
```
フィボナッチ数列を出力するプログラムです。
(ですが、桁上がりが対応できてないので、8が最大でその後は…)
#足し算(1桁+1桁)
```brainfuck:Brainfuck
++++[>++<-]>[>++++++<-]>>
>,
>,
<<+>>[<<+>>-]<<-
>
[-<+>]<<
[>-<-]
>.
```
足し算をするプログラムです。
こちらも、桁上がりには対応出来ていませんが…
#引き算(1桁-1桁)
```brainfuck:Brainfuck
++++[>++<-]>[>++++++<-]>>
>>,
<,
<+>>[<<+>>-]<<-
>
[-<->]<<
[>+<-]
>.
```
引き算をするプログラムです。
ただ、符号対応が出来てなかったりします。
#掛け算(1桁×1桁)
```brainfuck:Brainfuck
++++[>++<-]>[>++++++>>>>>++++++<<<<<<-]>>
>,
>>,
>
[<-<<->>>-]
<
[
<<
[<+>>+<-]
>
[<+>-]
>-
]
<<<<
[>+<-]
>.
```
掛け算をするプログラムです。
これも、桁上がりには対応してないです。
#割り算(1桁÷1桁)
```brainfuck:Brainfuck
++++[>++<-]>[>++++++>>>>>++++++<<<<<<-]>>
>,
>>,
>
[<-<<->>>-]
<<<
[
<+
>>>
[<<->+>-]
<
[>+<-]
<
]
<<
[>+<-]
>.
```
割り算をするプログラムです。
ただ、小数に対応してないです。
#論理演算OR
```brainfuck:Brainfuck
++++[>++<-]>[>++++++<-]
>>
,[>+<-]
<[>+>-<<-]
,[>>+<<-]
>[>->+<<-]
>[<+>[-]]
>[<<+>>-]
<<.
```
論理演算のORのプログラムです。
入力2つに対して、どちらも0だった場合のみ0を出力します。
#論理演算AND
```brainfuck:Brainfuck
++++[>++<-]>[>++++++<-]
>>,
<[>->+<<-]
>
[,
>[<-<+>>-]
<[<+>[-]]
<[>>+<<-]
>
]
>[<<+>>-]
<<.
```
論理演算のANDのプログラムです。
入力2つに対して、どちらも同じ入力だった場合に1を出力します。
#論理演算NOT
```brainfuck:Brainfuck
>>++[>++++<-]>[<++++++<++++++<++++++>>>-]
<<+<->>
>>,
<<[>+>-<<-]
>>[<<+>>[-]]
<<
[<<[>>+<<-]>>.>[-]<[-]]
>[+[<+>-]<.>]
```
論理演算のNOTのプログラムです。
入力1つに対し、0だった場合に1を、それ以外は0を出力します。
#LOOP(qが入力されるまで)
```brainfuck:Brainfuck
>>>+++++[<++++++>-]<[<++++<++++>>-]+++++++[<-<->>-]
<
[
>,
[<->>+<-]
<[>+<-]>
[
[<+>-]
>[<+>-]
<<[>>+<<-]
>[-]
<<[>+>+<<-]
>>[<<+>>-]
]
>[-]
<<
]
```
ループのプログラムです。
入力がqでなかった場合、ループします。
Apacheとdjangoを連携させたいがNo module named プロジェクト名 とでてしまう

apache経由でdjangoにアクセスすると、
Internal Server Error。

ログを確認すると、

```
No module named プロジェクト名
```

という感じででている。
試しに直接、

```
python wsgi.py
```

と叩いてみてもやはりモジュールが見つからないと怒られる。

泣きながら、

wsgi.pyに


```python
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..')
```

を追記してみたところなんとか動いた。

これで正しいのかどうかわからないがこれでいいのだ。

最終的なwsgi.pyは、

```python
import os

from django.core.wsgi import get_wsgi_application
from dj_static import Cling

import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..')


os.environ.setdefault("DJANGO_SETTINGS_MODULE", "projectname.settings")


application = Cling(get_wsgi_application())
```

こんな感じ。
deviseを使って新規登録とログインを同一ページにまとめる

##やりたいこと
facebookみたいなページ遷移せずタブで切り替える
新規登録・ログインページを作りたい。

##やってみた結果

```（ログイン側）sessions.new.html
  <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
    <div class="title">LOGIN</div>
    <div class="input">
       <%= f.label :ユーザーネーム %><br />
       <%= f.text_field :username ,autofocus: true %>
       <span class="spin"></span>
    </div>

    <div class="input">
       <%= f.label :password %><br />
       <%= f.password_field :password, autocomplete: "current-password" %>
    </div>

    <%= f.submit "Log in", :class =>"btn" %>

    <div class="pass-forgot">
      <%= render "devise/shared/links" %>
    </div>

  <% end %>
      <div class="material-button alt-2"><span class="shape"></span>
      <%= render "devise/registrations/new" %>　<!-- 新規登録はrenderで呼び出し -->
```
```（新規登録）_new.html
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<div class="title">REGISTER</div>
  <%= devise_error_messages! %>
    <div class="input">
       <%= f.label :ユーザーネーム %><br />
       <%= f.text_field :username ,autofocus: true,  autocomplete: "username" %>
    </div>
    <div class="input">
       <%= f.label :Email %><br />
       <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
    </div>
    <div class="input">
        <label for="reregpass">Password</label>
        <%= f.password_field :password, autocomplete: "new-password" %>
    </div>
    <div class="input">
       <%= f.label :RepeatPassword %><br/>
       <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
    </div>

    <% end %>
```
余計な部分は削除してますが概ね上記のように記述して実行。
新規登録時はユーザー名、パスワード、アドレスを入力、
ログイン時はユーザ名とパスワードのみ入力、の仕様。







結果・・・



**Found 2 elements with non-unique id**


上記のようなエラーメッセージが出てうまく動作しない。
（入力内容があっていてもログインできない）

調べたみたところ、deviseを使う際に入力する
`<%= f.text_field :username ,autofocus: true,  autocomplete: "username" %>`
この記述によって出力されるid（id=usernameと勝手に入る）が重複しているためエラーが発生する模様。
（上記で`2 elements`となっているのは、入力内容が被っているユーザー名とパスワードの２つ）

#解決方法
```（ログイン側）sessions.new.html
<head>
<script>
    $(function() { $('input').removeAttr('id')});
    $(function() { $('form').removeAttr('id')});
</script>
</head>
```
jQueryを利用して上記のように記述し、
`<body>`読み込み前に`form` `input`タグがもつid要素を外せばOK

これだけ！
「character-level CNNでTwitter陰キャを見つける」を追試したいけどわからないことがいろいろ

character-level CNNでTwitter陰キャを見つける
https://qiita.com/ymmtr6/items/f0274fa46db7cd7fd28d



```
$ git clone  https://github.com/ymmtr6/character-level-cnn-twitter

$ pip install requests requests_oauthlib
```

tweetをUnicode符号位置に変換
モデル作り
データの読み込み
学習
判別

陰キャ推定β
http://www.milktea.tech/gin/

10分待っても結果が来ない。ひとまずUP

１時間経ちましたが、画面に変化なし。一旦中断して再始動。
次は２時間待ってみる。

## CNN
character-level CNNでクリスマスを生き抜く
https://qiita.com/bokeneko/items/c0f0ce60a998304400c8

##Twitter
Python で Twitter から情報収集 (Twitter API 編)
https://qiita.com/Salinger/items/020b670466a9835c94bb

Twitterアプリケーションの作成（Consumer key、Consumer secret、Access token、Access token secretの確認方法）

Twitterアカウントとパスワードでログイン
https://apps.twitter.com/app/new

登録後Consumer key、Consumer secret確認

「Settings」

Application TypeをRead and Wtire

「Create my access token」

Access tokenとAccess token secret


Twitter のデータ取得、情報発信
https://dev.twitter.com/rest/public

GET search/tweets 
https://dev.twitter.com/rest/public/search

Twitter API 制限
https://dev.twitter.com/rest/public

app auth 
https://dev.twitter.com/oauth/application-only

＃文書履歴(document history)
ver. 0.01 初稿 20190225　昼
ver. 0.02 ２時間待ち 20190225 夕方
parquet-tools　使ってみた、使用コマンド履歴

parquetファイルをローカルにて簡単に確認できるツール、parquet-toolsを試してみた。
s3などでも簡単parquetファイルをみれたりするが、データ型などの確認などを行う機会も多いと思うので、
そういった場合に非常に有用なツール

Parquet-toolsインストール方法
2019/02/24試行

1段階目 maevenのインストール
wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
1
tar xzvf apache-maven-3.3.9-bin.tar.gz
1
2
$ ./apache-maven-3.3.9/bin/mvn -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T16:41:47+00

2段階目　parquet-tools のビルド
git clone https://github.com/apache/parquet-mr.git
cd ./parquet-mr/parquet-tools/

↓
ビルド実行
mvn clean package -Plocal

ビルドされたjarは
./target
すなわち
/Users/ユーザー名/parquet-mr/parquet-tools/targetに吐き出されている。
執筆当時はparquet-tools-1.12.0-SNAPSHOT.jarだったが、バージョンは変わっている可能性があるので、lsで確認してビルド実行をする必要あり。

コマンドとしては
java -jar ./parquet-tools-1.6.0.jar
の後に
・　　cat (中身の確認)
・　　head (ヘッダの確認)
・　　schema (スキーマの確認)
・　　meta (メタ情報の確認)
とオプションをうつことで中身の確認ができる

例えばcatを使う時は
java -jar ./parquet-tools-1.6.0.jar cat test.parquet
のようなコマンドを実行する。
ShiftJISファイルをWinMergeしているのにエンコーディングエラーが表示される場合の原因確認方法

# はじめに

この記事で取り扱う事象はWinMergeに限った話ではなく**ShiftJIS**と**CP932**の違いによって発生するものであり、私がたまたまWinMergeで遭遇しただけなので、場合によっては他の現象の原因確認にも応用が効くものである。

つまり何が言いたいかっていうと、文字コード問題はマジで徒労ということである。

# 参考になる記事

@egg_chicken さんの以下の記事がとても参考になり、解決の糸口になった。多謝
https://qiita.com/egg_chicken/items/53f1a5922487a572eaf4


# 何がおきたか？

とあるふるーいアプリケーションから出力されたCSVファイル（**ShiftJIS**）をWinMergeで比較しようとしたら、『エンコーディングエラーにより情報が失われています。』とエラーが表示されたとユーザーより相談された。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/335e3591-7218-17ca-8773-170070b44a44.png)
※画像はWinMerge2.12.4.20+jp-20 のもの。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/9f0314df-85cb-e31f-0ff6-124a0c2863a3.png)
※2019年2月現在最新のWinMerge2.16.0.7では上記のように表示される。

# なぜおきたか？

## WinMergeのマージ前動作

WinMergeはエンコードを揃えるため、ファイルをShiftJIS(**CP932**)で開きなおし、エンコーディングを行っている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/9af568e4-fb73-690e-c728-1ec1451472a3.png)

例えばUTF-8のテキストをWinMergeに放り込むと、見事に文字化けし、同様のエラーが表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/3bb42cca-ea3a-eef6-ea60-b591a984ec88.png)
これは上記のエラー原因を調べている時に知ったことだが、プラグイン等を使うことで、これを吸収することができる。例えばExcelファイルを比較するなんていうこともできる。

## では今回のケースはどうか？

この **CP932** に開き直す動作を取った時にエンコーディングに失敗し情報が欠損すると、上記のエラーが表示される。ただし、その該当箇所がどこであるかはWinMergeではわからない。

全体が文字化けしていれば、ファイル全体のエンコーディングによるものであるとわかるが、今回は元のファイルも CP932と同意（**だと思っていた**）である **ShiftJIS** であり、一見すると問題の無いファイルでエラーが発生しているような状態だった。

検索してもOfficeファイルを比較した場合の例などしか無く、調べるうちに文字コード問題の深淵へ足を踏み入れていくのであった・・・。

# 今回の原因 ShiftJIS≒CP932

今回WinMergeを通したファイルは **ShiftJIS** で作成されたファイルで、一見するとWinMerge上でも問題なく表示されており、エラー文の通りのエンコーディングエラーによる情報損失は発生していないように見受けられる。

ただ、このファイルを サクラエディタ で開き、 **CP932** で保存すると原因の箇所が炙りだされた。
※サクラエディタに限らず、CP932で保存できるエディタなら確認できると思いますが、今回はサクラエディタで説明します。

## サクラエディタでSJISファイルをCP932で保存する。

通常の名前をつけて保存ダイアログではコードページ（CP）のエンコード形式は表示されない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/7ac67880-fcce-c4cf-9c14-648ee38aeb5e.png)

今回問題が発生したファイルを何度SJISで保存し直してもWinMergeでのエラーは解消しなかったが、文字コードセットの **CP** にチェックをいれると、以下のようにCP932が選択できるようになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/086f5c8b-41dc-e72a-950e-133249b58964.png)

そしてCP932で保存をするとWinMergeで怒られていた内容と同じようなことを言われる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89777/de381eb6-2a71-fe86-a7aa-fa3060f4cce0.png)

ただし、WinMergeと異なるのは、このままキャンセルを選択すれば、原因となっている箇所へジャンプができるという点だ。
あとは、該当箇所を削除するなり、もとのアプリケーションを訂正するなりすれば、WinMergeでのエラーも解消する。

# まとめ

* WinMergeはファイルを **CP932(ShiftJIS)*** に変換して比較をしている。
* **CP932** と **ShiftJIS** は≒（ニアイコール）の関係であり、相互変換をした場合に情報が欠落する場合がある。
* サクラエディタでCPのチェックを入れいると、文字コードをコードページ指定で選択でき、保存することができる。
Google Hangouts Chat にpythonで画像付きメッセージを投稿


## 画像付きでGoogle Hangout Chatに投稿する
[前回](https://qiita.com/Fortinbras/items/48d908181558e4b08b6f)の続き。
Google Hangout Chatは、人間の投稿のほかにBOTでのテキスト投稿が可能なので、例えば日経平均前場後場の値を定期的に投稿したり、例えば[新規上場会社の有価証券届出書がEDINETに提出されたものを定点観測](https://qiita.com/Fortinbras/items/00a0a137a6d7bf1bb0ed)して、Google Hangout Chatのチャットルームに定期実行で投稿したりしているのだが、Google Hangout Chatは、テキスト投稿だけでなく**card**形式の投稿も可能であり、画像を付けて投稿することも可能。

参考↓
https://qiita.com/Shota_Fukuda/items/7cd94126b578fad81d27
https://qiita.com/nagase/items/5f2ea033cf91ad9b9309


[この記事](https://qiita.com/nagase/items/5f2ea033cf91ad9b9309)によると**<font color=red>1つのwidgetsに紐づけできるのは1種類のコンポーネント</font>**とのことなので、以下スクリプトのように、sectionsの下に2つのwidgetsを用意して、1つはimageを(click先のURLリンクを指定)、もうひとつはTextParagraphを紐づけして、画像とテキストを合わせて投稿してみた。

```python:test.py

import requests
from json import dumps

#webhook
webhook_url = 'https://chat.googleapis.com/v1/spaces/ABCDE1234/messages567FGHIJKLMN89OPQRSTU0'

bot_message= {
  "cards": [
    {
      "sections": [
        {
          "widgets": [
            {
              "image": {
                "imageUrl": "https://example_fugafuga.net/fox.jpg",
                "onClick": {
                  "openLink": {
                    "url": "https://example.com/12345678/"
                  }
                }
              }
              
            }
          ]
        },{
          "widgets": [
            {
             "textParagraph": {
                "text": "<b>きつね</b><br>｢<font color=\"#ff0000\">おきつねさま</font>｣"
              }
              
            }
          ]
        }
      ]
    }
  ]
}

ret = response = requests.post(
           webhook_url,
           data=dumps(bot_message)  
           )

print(ret) # 成功：Response [200] / 失敗：[400]

```
・画像はネット上のURLを指定
・textparagraphのテキストは、文字の色を変更したり改行したりすることが可能。[詳細](https://developers.google.com/hangouts/chat/reference/message-formats/cards)はこちら。

※投稿イメージ↓
![20190225.png](https://qiita-image-store.s3.amazonaws.com/0/91974/cc5eda4e-232e-09fb-27a7-3f70f804beea.png)

## 想定される利用用途
　[GUILD社の中の人](https://speakerdeck.com/goando/dezaintokomiyunikesiyondegai-shan-surudetafalseux)が言及しているが、Webメディア等のKPI数値をダッシュボードで定点観測するだけだと、チームでのコミュニケーションがなかなか促進しないため、ダッシュボードからKPI数値をグラフ化したファイルを生成し、SlashやGoogle Hangout chat等に定期的に吐き出すBOTみたいなものを用意するというのはありますね。

※参考
デザインとコミュニケーションで改善するデータのUX (via.**GO ANDO at.GUILD**)の38ページ目↓
![image20190221.png](https://qiita-image-store.s3.amazonaws.com/0/91974/429bbcc1-35b0-a34e-b30f-88ebf533f8a3.png)
　例えばGoogle Analyticsなどは、Re:dashなどのダッシュボードのソース元に設定できて、Re:dashはSlashと連携できるらしいので、上のイメージ図のように、週次のPV推移の棒グラフをSlackに吐き出して、チーム内で共有しつつ、やんややんや(喧々ごうごう侃々諤々)ディスカッションしてPDCAを回すといったことも可能。なのだがRe:dashやSlackなどイケてるITベンチャーが使うツールを用意しなくても、Google Hangout chatでも同じ様に、KPI数値をグラフ化した画像を定期実行で投稿することは可能かと。

続く...
【コピペ用】JSで外部ドメインのリンクに強制的に `target="_blank"` を付け、ついでに `rel="noopener"` もつける

外部で更新しているメディアサイトで、文中のリンクが別タブで開いたり開かなかったりして気になったので、JSによって外部ドメインのリンクは強制的に別タブで開かせるようにしました。

ただ、`target="_blank"` はそのままだとあぶないらしいです。（ e.g. [target="_blank"には気をつけよう] (https://qiita.com/Apprentice_engineer/items/5db19a6d9bd4e7978aec)）
`rel="noopener noreferrer"`をつけよう！という流れなので、併せて rel属性 にも対応しました。

```js
/*
 * 外部ドメインのリンクは強制的に `target="_blank"` を付け、
 * さらに `rel="noopener noreferrer"` もつける
 */

var i, links, linksLength;
links = document.links;
i = 0;
linksLength = links.length;

while (i < linksLength) {
  if (links[i].hostname !== window.location.hostname) {
    links[i].target = '_blank';
    links[i].rel = 'noopener noreferrer';
  }
  i++;
}
```

```js
// ES6 で書く場合
let i, links, linksLength
links = document.links
i = 0
linksLength = links.length

while (i < linksLength) {
  if (links[i].hostname !== window.location.hostname) {
    links[i].target = '_blank'
    links[i].rel = 'noopener noreferrer'
  }
  i++
}
```

```coffeescript

# coffee-script で書く場合
links = document.links
i = 0
linksLength = links.length
while i < linksLength
  if links[i].hostname != window.location.hostname
    links[i].target = '_blank'
    links[i].rel = 'noopener noreferrer'
  i++
```
【備忘録】ElastiCacheをマルチAZに変更する

開発用で作成したt2.microのデータを残しつつマルチAZ化しようとした時にちょっとつまづいたので備忘録を作成

###作成済みクラスターのマルチAZ化

作成済みクラスターをマルチAZ化するためには下記の手順で新しいクラスターを立ち上げる

- 対象クラスターのバックアップを取る
- 作成したバックアップからレストアする。その際下記に気をつける
    - ノードタイプをt2系以外にする。
    - レプリケーション数は1以上
- レストアされたクラスターを選択し、「変更」ボタンを押す
- ポップアップ内でマルチAZのradioボタンの「はい」を選択し、「変更」ボタンを押す


以上
桁落ちに気をつけよう【Pythonの数値計算】

#まえがき
二次方程式の解き方は覚えていますか？

```math
a x ^2 + b x + c = 0
```
の解は

```math
x = {-b \pm \sqrt{b^2 - 4ac}\over 2a}
```
ですね。
これをPythonで解いてみましょう。
解の公式をそのまま出力するものが以下の関数です。

```python
import numpy
def qeq(a, b, c):
    return((-b + numpy.sqrt(b**2 - 4 * a * c))/(2 * a),
    (-b - numpy.sqrt(b**2 - 4 * a * c))/(2 * a))
```
例えば

```math
x^2 + 5x + 6 = 0
```
を計算すると

```python
print(qeq(1, 5, 6)) # -2.0, -3.0
```
という答えが出ますね。
#何が問題になるのか
```math
x^2 + 1.000000001 x + 0.000000001 = 0
```
という二次方程式を考えてみましょう。

```math
x = -0.000000001, -1
```
の二つが解となります。
同様の関数で計算してみると・・・？

```python
print(qeq(1, 1.000000001, 0.000000001)) 
# -1.0000000272292198e-09, -1.0
```
(-1.0000000272292198e-09は
-0.0000000010000000272292198のこと。)
9桁目でずれが生じてしまいました。
有効数字8桁はちょっと少なすぎ。
# 桁落ちとは？
有効数字という概念があります。
ざっくりいうと小数の取り扱い時に計算の正確さを保証できる桁数のこと。
1.001なら有効数字4桁、
1.000でも有効数字4桁。

1は有効数字1桁、
0.001も有効数字1桁。

ここまでいいでしょうか。

ここからが問題。

```math
1.001 - 1.000
```
の有効桁数は？
4桁から4桁を引いたんだから、 4桁！って言いたいところですが、

```math
= 0.001
```
で1桁。これが桁落ちです。
桁落ちは極めて近い数同士での引き算で起こります。例えば、

```math
2.001 - 1.000 = 1.001
```
なら4桁のまま。
# 何がダメだった？
今回の場合は

```math
-b + \sqrt{b^2 - 4ac}
```
ここが問題。
-bは-1.000000001、$\sqrt{b^2 - 4ac}$は0.999999999...
合わせて0.000000002くらい。

二つの値が近すぎたため、9桁の有効数字が失われました。
これで解の有効数字は8桁あったということは、元は有効数字が17桁ほどあったということでしょうか。
#解決策
計算方法を変えてみましょう。
足し算では桁落ちは起こらないので、解の一つはそのまま解の公式で求めることができます。
$(i)b\geq 0の時$

```math
x = {-b -\sqrt{b^2 - 4ac}\over 2a}
```

$(ii)b< 0の時$

```math
x = {-b +\sqrt{b^2 - 4ac}\over 2a}
```
もう一つの解を求めるために、以下の公式が役に立ちます。

```math
a x ^2 + b x + c = 0
```
の解を$\alpha, \beta$とすると

```math
\alpha \beta = {c \over a}
```
証明は省略。
これでもう一つの解を求めることができますね。
#実装してみよう
```python
import numpy # numpy.sign()という関数を使う。引数の正負を判断する。
def qeq(a, b, c):
    alpha = (-b - numpy.sign(b) * numpy.sqrt(b**2 - 4 * a * c))/(2 * a)
    beta = (c / a) / alpha
    return(alpha, beta)
print(qeq(1, 1.000000001, 0.000000001))
# (-1.0, -1e-09)
```
桁落ちがなくなったので正確な値が計算できました。
# まとめ
値が極めて近い数字同士を引き算すると情報が失われ、精度が落ちる。なんとか工夫して回避しよう。

『機械学習のエッセンス』という本を参考にしました。引き続きこの本についてまとめていきます。
前回：丸め誤差に気をつけよう
https://qiita.com/NNNiNiNNN/items/42107479407d9bb14419
次回：計算過程に気をつけよう
https://qiita.com/NNNiNiNNN/items/2f17f874f8a234bd10ad
Unityでスワイプ操作


##実装コード
iOSネイティブのスワイプジェスチャと似た挙動の実装です。移動距離が一定以上になると、指を離さなくても、スワイプ判定が走ります。PC/スマホ対応。

```c#:main.cs
//判定距離
private var swipeBorder = 40;
//スワイプの方向
enum SWIPE_DIR {
	RIGHT,
	LEFT,
	NONE
}
//左右スワイプの更新と取得
SWIPE_DIR GetSwipe(){
	if(Input.GetKeyDown(KeyCode.Mouse0)){
		touchStartPos = Input.mousePosition;
		isSwipeStart = true;
	}
	if(Input.GetKey(KeyCode.Mouse0) && isSwipeStart){
		var dirX = Input.mousePosition.x - touchStartPos.x;
    	var dirY = Input.mousePosition.y - touchStartPos.y;
		if(Mathf.Abs(dirY) < Mathf.Abs(dirX)) {
			if(swipeBorder < dirX){
					isSwipeStart = false;
					return SWIPE_DIR.RIGHT;
			} else if (-(swipeBorder) > dirX){
				isSwipeStart = false;
				return SWIPE_DIR.LEFT;
			}
		}
    }
	return SWIPE_DIR.NONE;
}
```
##使用例
```c#:main.cs
void Update () {
	var swipeDir = this.GetSwipe();
	if(swipeDir == SWIPE_DIR.RIGHT) {
		this.prev();
	} else if(swipeDir == SWIPE_DIR.LEFT) {
		this.next();
	}
}
```
世界最小のindex.htmlの作成方法

## TL;DR
自己満足。SEOなんてなかった、いいね？

## 1: 空のhtmlファイル
bodyとかheadタグすら存在しない、HTMLファイルと呼べるのか怪しい代物を読み込ませる

```html:index.html
```

**中身はない**。
このHTMLファイルをChromeで開くと、こうなる。

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

このように、空の`head`/`body`タグが生成される。
ということは、ここにjsかなにかで書き込んでやれば世界最小のhtmlファイルが実現することになる。

## 2: javascriptコードの追加
そこで、以下のように書き加える

```html:index.html
<script src=.js></script>
```

<font color="#888">
本当はsrc="a"とかでもいいのだが、その場合サーバー側でheaderを指定してJavascriptファイルだと教えてやる必要がある(はず)。
もしかしたらそもそもできないかもしれない。
</font>

**-------------3/29 追記-------------**
以下の記載でいけました。特にヘッダー指定もいりませんでした。
コメントありがとうございます。

```html:index.html
<script src=a></script>
```

閉じタグの省略はできないみたいです(実行してくれない)
**-------------追記ここまで-------------**


さて、これでjsファイルを読み込めたので後はjs側でゴリゴリ描写すればいいことになる。
最近の自分の好みとして`Riot`を多用しているので、これを使う。


```javascript:.js
// .js
import riot from "riot";

// tag import
import "./app.tag";
import "./html.tag";

// mount
// ※1 DOMが読み込まれてからでないとbodyタグがmountできない
window.addEventListener("DOMContentLoaded", () => {
    riot.mount("*")
});
```

```html:html.tag
<head>
    <title>hoge</title>
    <!-- yieldタグを用意することで、riotが用意する
         cssを挿入できるようにする -->
    <yield/>
</head>
<body>
    <app/>
</body>
```

## 3: DOM生成のタイミング
上記コードのコメント※1にも記載したが、`head`タグと`body`タグは生成されるタイミングが異なるようである。

これは上記`.js`ファイルの先頭にbreakpointを設置し、コードの実行とDOMの状況を追うとわかる。

1. `html`と`head`が生成される
2. `head`の中に`script`が押し込まれる
3. `script`の中身の実行
4. `body`の生成

という実行順序のようなので、`riot.mount("*")`をそのまま記載すると何もマウントされない。

そこで、`window.addEventListener("DOMContentLoaded")`を使用する。
これによって、上記4のbodyタグ生成後にmountが可能になる。

## 4: 世界最小のindex.html

![](https://i.imgur.com/8psHHZd.png)
実行してる様子

![](https://i.imgur.com/QDbqbe8.png)
view-sourceを開いた様子


`parcel`でbuildしてるのでファイル名が少し冗長だが、それ以外は文句なしに空っぽである。

もはやここまで来たら`index.html`の存在自体が不要な気もするが、さすがにそれはできなそうなのでここらで妥協。


ちなみに、firefox, edge, IE11でも動く。
こんなクソみたいなHTMLファイルでもちゃんと同一の解釈がされてるあたりは感動すら覚える。

![](https://i.imgur.com/A6MW0yc.png)
IE11での動作確認


## 5: 欠点と総括
言うまでもないがSEOがお葬式になる(google botはjavascriptも実行できるらしいが)。
あと環境依存なところがあるので、万人受けさせたいコンテンツには絶対に合わない。

でも`react`とか`riot`とか使うならどうせ似たようなHTML(笑)になるのはほぼ確定だし、いっそここまで極端にしてしまうのもありかもしれないですね。

```html:index.html
<!-- author:hoge / repository:@arika0093/minhtml -->
<script src=.js></script>
```

とかなってたらかっこいい感じしますよ(当社比)。
Go言語の変数定義

Goの変数定義の書き方はいくつかがあります。
Goの変数定義は柔軟性があります。


#単独変数の定義
##初期値なし変数
定義：var 変数名 変数型
例：

```go
var s string
```

##初期値あり変数
定義： var 変数名 変数型 = 値
例：

```go
var s string = "私の性別は男です。"
```

値から型を推測できるので、変数型を省略して書くことも可能です。
定義： var 変数名 = 値
例：

```go
var s = "私の性別は男です。"
```

varキーワードは嫌な場合は、varを省略して書くことも可能です。
定義：変数名 := 値
例：

```go
s := "私の性別は男です。"
```

#複数変数の定義
##初期値なし変数
定義：var 変数名1,変数名2,...変数名n 変数型
例：

```go
var s1, s2, s3 string
```

##初期値あり変数
定義： var  変数名1,変数名2,...変数名n  変数型 =  値1,値2,...値n 
例：

```go
var s1, s2, s3 string = "s1です。", "s2です。", "s3です。"
```


エラー例：

```go
var s1, s2, s3 string = "stringです。"
```

値から型を推測できるので、変数型を省略して書くことも可能です。
定義： var  変数名1,変数名2,...変数名n =  値1,値2,...値n 
例：

```go
var s1, s2, s3 = "s1です。", "s2です。", "s3です。"
```

varキーワードは嫌な場合は、varを省略して書くことも可能です。
定義：変数名1,変数名2,...変数名n :=  値1,値2,...値n 
例：

```go
s1, s2, s3 := "s1です。", "s2です。", "s3です。"
```


エラー例：

```go
var s1, s2, s3 := "s1です。", "s2です。", "s3です。"
````

#まとめて変数定義
定義：上記の単独変数と、複数変数の組み合わせ
var (
　　変数名１ 変数型 = 値
　　変数名２ 変数型
　　変数名３ = 値
　　変数名４, 変数名５ 変数型 = 値
　　変数名６, 変数名７ 変数型
　　変数名８, 変数名９　= 値
 )

例：

```go
var (
		s1         string = "s1です。"
		s2         string
		s3               = "s3です。"
		num1, num2 int16 = 1, 2
		num3, num4 int32
		num5, num6 = 5, 6
	)
```

エラー例：（省略式の「:=」を使う）
var (
　　変数名　変数型 := 値
)

以上
pkill では, プロセスコマンド名の 15 文字分しかマッチングに考慮されない

pkill でプロセスを, コマンド名で終了させたいと思いましたが,

```
runner-bora-dora-muda-ari-bbb-ccc-ddd.sh
```

みたいに長い名前をシェルススクリプトにつけて実行しておき(pgrep で判定できやすくするため), `pkill ccc-ddd` でマッチさせて pkill させてもなぜか終了してくれなく, つらい日々を送ってきました.

## pkill では 15 文字分しか考慮されない

https://linux.die.net/man/1/pkill

> The process name used for matching is limited to the 15 characters present in > the output of /proc/pid/stat. Use the -f option to match against the complete > command line, /proc/pid/cmdline.

マニュアルを確認してみたところ, オプションなしだと `/proc/pid/stat` 出力に対する 15 文字分しか考慮されないことがわかりました.

## 解決策

`-f` オプションを使う
iOSでSVGの高さが長くなる時の原因

イラレで書きだした場合のSVGのコードは
svg height="XXXpx"
とキャンバスサイズも付与されるので「height="XXXpx"」を削除する。

参考
https://qiita.com/watakushi/items/d5676792b164af37c811
「風が吹けば桶屋が儲かる」的にsystemdのシーケンスをメモる

systemdの起動シーケンスのメモ。

## 前提

- Amazon Linux 2を使っている。
- RunLevelは 3 にしている。
- 動的生成ユニットに関しては割愛。

## systemd の起動シーケンス

1. systemd が起動する。
2. systemd が起動すると、　`/etc/systemd/system/default.target` が呼ばれる。
3. default.target が呼ばれると `/etc/systemd/system/default.target` の **After** に記述された内容に従い、
    4. ユニット basic.target が起動され
    5. ユニット rescue.service が起動され
    6. ユニット rescue.target が起動される。
7. After で示されたユニットの起動が終わると、ディレクトリ `/etc/systemd/system/default.target.wants` 下のユニットが順に呼ばれる。

## 解説

### 1. systemd が起動する

　Linuxが立ち上がった時に、initスクリプトが実行されて `/sbin/init` が実行される。
`/sbin/init` はすでに `systemd` のシンボリックリンクになっているので、結果的にはこれが読み込まれる。

```shell-session
$ ls -l /sbin/init 
lrwxrwxrwx 1 root root 22  1月 15 03:30 /sbin/init -> ../lib/systemd/systemd
```

### 2.　`/etc/systemd/system/default.target` が呼ばれる

Unit の定義は２ヶ所で行われている。

| ディレクトリ       | 目的    |
|:---------------|:-------|
| /etc/systemd/system/下      | 管理者がカスタマイズする内容 |
| /usr/lib/systemd/system/下  | システムのデフォルト        |

同じファイル名のものがあった場合には `/etc/systemd/system/` のほうが優先される。
どちらのディレクトリにも `defaukt.target` ディレクトリは存在するのだが、このルールのために `/etc/systemd/system/default.target` のほうをsystemdは処理する。
そしてこの `/etc/systemd/system/default.target` は、RunLevelに応じた実体のシンボリックになっている。RunLevelが3（Multi-Userモード）の場合は、次のようになっている。

```
$ ls -l /etc/systemd/system/default.target
lrwxrwxrwx 1 root root 41  2月 23 19:39 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target
```

結果的に、 `/usr/lib/systemd/system/multi-user.target` が処理される。

### 3. `/etc/systemd/system/default.target` の After に記述された内容に従い

`[Unit]` 項目では、いくつか定義を記述できます。
After は、順序関係の定義の１つで、記述された他ユニットの実行の後に実行する、という意味になる。（Beforeはその反対になる）

なお、 `default.tareget` には Require、 Conflict といった定義もされている。Requireは当ユニットの実行に必須な依存関係を、Conflict は同時に実行してはならない同時実行制限を記述している。

#### 4. basic.target が起動

実体は `/usr/lib/systemd/system/basic.target` 。

#### 5. rescue.service が起動

実体は、` /usr/lib/systemd/system/rescue.service`。

#### 6. rescue.target が起動

実体は、`/usr/lib/systemd/system/rescue.target`。

### 7. `/etc/systemd/system/default.target.wants` 下のユニットが順に呼ばれる

このディレクトリの下に、default.target が起動させたいユニットのシンボリックリンクが張られている。


## 参考サイト

[『Linux女子部 systemd徹底入門』 - SlideShare](
https://www.slideshare.net/enakai/linux-27872553)
[『Systemd メモ書き』 - Qiita](https://qiita.com/a_yasui/items/f2d8b57aa616e523ede4)
Pulumiのstackをpromptに表示する

Pulumiで複数stackがあると現在のstackはどれが選択されているか忘れることがある。
こういう場合はpromptに出てると便利なので設定してみた。

現状pulumiコマンドで高速に現在のstackを取得する方法はないが、cliでは保持しているので、どこかに設定を持っているはず。

調べてみると、 `~/.pulumi/workspaces/[YOUR_PROJECT_NAME]-[HASH]-workspace.json` に以下のような設定があった。

```json:*-workspace.json
{
  "stack": "[YOUR_STACK_NAME]"
}
```

こいつを取得すればよさそう。
問題はファイル名がハッシュになっていることだが、ソースを読むとPulumi.yamlのあるパスをsha1にしたもののようだ。

```go:pulumiのソース
// https://github.com/pulumi/pulumi/blob/ad78f3ef59f846b6e23d3726e76bb2de0cee9a4d/pkg/workspace/workspace.go#L173
// pw.projectはディレクトリ
uniqueFileName := string(pw.name) + "-" + sha1HexString(pw.project) + "-" + WorkspaceFile
```

なのでopensshかなんかでPulumi.ymlのあるディレクトリのフルパスを変換するとハッシュになる。

```bash:シェル
# 現在のディレクトリにあるPulumi.yamlからcurrent stackを取得
# macosで動作確認
cat ~/.pulumi/workspaces/$(cat Pulumi.yaml | grep name: | sed -e 's/name: //g')-$(echo -n "$(pwd)/Pulumi.yaml" | openssl sha1)-workspace.json | grep stack | sed -e 's/.*"stack": "\(.*\)".*/\1/' | sed -e 's/^.*\///'
```

これをシェルのPS1に設定すると現在のstackがpromptに出せる :smiley:
メモ 初心者がUbuntu 18.04.2 LTS に Javaの環境構築と日本語化をやってみた。

初めての投稿です。
プログラミングスクールでruby on railを学んだ程度の知識ですが、linuxに興味を持ち、色々試行錯誤しています。

今回はJavaの環境構築とエディターであるeclipseのインストール+日本語化を行ってみます。

まず初めに、コマンドを打ちます。


java -version


↑Javaが入っているか確認します。
(もし入っていたらJavaのインストールは終了です)

次にこのコマンドです。
PPAの追加です。
(※PPAとは？→ パーソナル・パッケージ・アーカイブの略で、Appストアみたいな物の様です。)


sudo add-apt-repository -y ppa:webupd8team/java
sudo apt-get update


java8をインストールします。


sudo apt-get install oracle-java8-installer oracle-java8-set-default


以上でJavaはインストール出来ました。
rubyやruby on railsよりも手こずらなかった様な気がします(無知だからですが...(笑))


後は、使う設定をしました。

◯Oracle (SUN) JDK を使うように設定する
sudo update-java-alternatives  --jre -s java-8-oracle
sudo update-java-alternatives  --jre-headless -s java-8-oracle
sudo update-java-alternatives  -s java-8-oracle

sudo update-alternatives --config java 
↑
※/usr/lib/jvm/java-8-oracle...の行に設定されていることを確認

update-java-alternatives -l 


これで使えるようになりました。

テキストエディタで「test.java」ファイルを作り(hello java等、サンプルコードを書いてみてください)
コマンドプロントで↑のあるディレクトリまで行き、

javac test.java 

と打ち込む。

コンパイルされると「test class」というファイルが出来上がるので、
再度、コマンドプロントにて「java test」と打ち込む。

これで動けばOKです。



次に、eclipseを入れました。

まずは失敗方法から。
最初に「ubuntuソフトウェア」(Aのマークでamazonっぽいマークの物です)からeclipseをインストールしたのですが、
これだと日本語化に必要なファイルが探し出せず失敗に終わりました。

ですので、公式サイトからZIPファイルをダウンロード+解凍してインストールします。

公式サイト：https://www.eclipse.org/
右上の方にオレンジ色のダウンロードボタンがあります。特に何も選択せずにlinux用のファイルがダウンロード出来ました。

解凍したら、インストーラーの指示通りに進めて下さい。(丸投げですみません)

↓
↓
↓

出来ましたね(^^) インストーラーを開発してくれる方に感謝します。

では最後に日本語化をします。
linuxでは直接変更を加えなければなりません。

Pleiades公式URL：http://mergedoc.osdn.jp/

ここからですね、
「Pleiades all in one」 ではなく、「Pleaides プラグイン」　の　LINUX用　のファイルをダウンロードして下さい。
（「インストーラーは用意されていません。zip を解凍して readme.txt を参照し、手動で Pleiades を配置し、設定ファイルを編集してください。」と書いてあるやつですね）

解凍したら、readmeを読みながら色々やります。日本語でとても分かりやすいです。(Pleiadesさんありがとう御座います)

eclipse-java-2018-12-eclipseのディレクトリで、
先ほどダウンロードしたファイルの中に「features」と「plugin」というものがあるのでコピーペーストして下さい。

最後に、
同じディレクトリ内にある「eclipse.ini」の中を少し加えます。
一番最後の行に

-Xverify:none
-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar


を加えて保存するだけです。意外と簡単にできました。
これも全て見えないところで天才エンジニアが尽力して下さるお陰です。

以上、初心者が環境構築をするメモでした。
誰かの参考になれば幸いです。
公式ドキュメントを翻訳してみる話

#はじめに

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている<@kento_o>です。
今回は、公式ドキュメントを翻訳してみました。

#公式ドキュメント
勉強したてホヤホヤのこちらの2つ。

[Docker公式ドキュメント](https://docs.docker.com/)
[Kubernetes公式ドキュメント](https://kubernetes.io/docs/home/)

この2つを、Firefoxのアドオンである[Google Translator for Firefox](https://addons.mozilla.org/ja/firefox/addon/google-translator-for-firefox)
に翻訳してもらいました。

#翻訳結果(Docker)

![Screenshot from 2019-02-25 12-02-52.png](https://qiita-image-store.s3.amazonaws.com/0/320820/5f1b2302-45cd-86e5-5f15-91a30ef8f9b1.png)




#翻訳結果(Kubernetes)
![Screenshot from 2019-02-25 12-02-36.png](https://qiita-image-store.s3.amazonaws.com/0/320820/e6499631-c694-cd09-b9fe-0e53a3ceac6c.png)




Dockerは素っ気なく翻訳されましたが、Kubernetesはデザインそのままに翻訳されていますね……。
使用している技術の差ですかね。

#英語読解
プログラミング学習を始めて、英語の勉強を本気でやってこなかったことを後悔しました。
Memriseや大学の多読用ペーパーバッグなどを最大限活用して、語学能力を伸ばしていきます。


#最後に
Pythonの勉強を並行して開始しました。
ワクワクです。ワクワクもんです。
EclipseでConsolasが使いたいっ！

## 追記 (2020.01.14)

[536562 – Now, using font "consolas", Chinese comment display unnormal. It is normal Before](https://bugs.eclipse.org/bugs/show_bug.cgi?id=536562)
↑ EclipseのBug TicketのStatus が ~~"REOPENED"(再開)~~ 
2019.11.21 update で "VERIFIED FIXED"(検証済み)になってたよ。

早速2019-12版のEclipseをPleiadesで使用。
使ってみた感じ、文字化けは見かけないので、直った…のかな(o^―^o)ﾆｺ

---

**※ 本稿はレジストリを変更するものなので、行う際は自己責任でお願いします。**
-
Javaの開発でEclipse の `Pleiades`を使用している。
しかし、Eclipseにコードネームが付かなくなってきた頃から、
フォントに**`Consolas`**を使用していると**`コメント内の日本語フォントが文字化ける`**ようになった。。。

原因は何？
-
Webで調べたら、`Consolas`が日本語フォントに対応していないことによるものらしい。
(特にPCを変更した等なかったので、それ以前のEclipseで文字化けしなかった理由がわからない(;-∀-))

対応してみよー！
-
```
 <<フォントの文字化けを直す方法>>
その1. 使用するフォントを`Consolas以外`にする
その2. レジストリを操作し、Fontlinkで日本語フォントに紐づけ
```


レジストリをいじるのはなるべく避けたかったので他のフォントを探したりもしたが、
やはり、Consolasに勝るフォントはなかなかない。

仕方なく"その2"の方法をとることにした。

色々試したが、なかなかしっくりこなく、
最終的にこちらのサイトで紹介されているので落ち着いた。

+ [欧文フォントを日本語に対応させる](http://tm.root-n.com/misc:consolas)

また、Eclipseは Consolasに対応させる日本語フォントに**`Microsoft Sans Serif`**を
参照しているそうなので、こちらにも同じ設定を追加した。

+ [[Eclipse] Eclipse: Consolas + メイリオ の ClearType 表示](http://monado.dtiblog.com/blog-entry-128.html)

Fontlinkでやったことまとめ
-
レジストリ変更手順は、上記の**[欧文フォントを日本語に対応させる](http://tm.root-n.com/misc:consolas)**のサイトを参考されたし。

* Consolas の設定を新規に作成し以下を設定

```
MEIRYOKECONSOLE.TTF
```

* Microsoft Sans Serif の最初に以下の行を追加

```
MEIRYOKECONSOLE.TTF
MEIRYO.TTC,Meiryo UI,128,102
```

ちなみに、`MEIRYO.TTC,Meiryo UI,128,102`の数値部分はスケーリングで、文字の大きさを設定するためのもの。
`128`は日本語はこの数値が固定らしい。
`102`は数値が大きいほど文字が小さくなり、小さいほど文字が大きくなる。
【参考】[[Windows] FontLink SystemLink の設定値の数字について](http://monado.dtiblog.com/blog-entry-127.html)

レジストリを変更するのでPCの再起動が変更する度に必要になるが、
自分の好みに調整するといいと思う。


[参考] プログラミング用のいろんなフォント
-
代替として使えるフォントがないか調べたときに見つけた、
自分が"見やすい"と感じたフォントをリストアップしておく。
・[Fira Code](https://qiita.com/shuntksh/items/1995e87fe5c1ac88296f)
　　【参考】[コーディング用フォント「Fira Code」を使おう](https://qiita.com/shuntksh/items/1995e87fe5c1ac88296f)
・ [IPAフォント](https://ipafont.ipa.go.jp/old/)
・ [Myrica M](https://myrica.estable.jp/)
・ [meiryoKe](http://web1.nazca.co.jp/nzkchicagob/m6x9801/mrktb1bs5.html)


2019.04.19 追記）結局のところ
-
* Eclipseの2バイト文字対応にバグがあるらしく、コメント部分にいろんなフォントが入り混じっているような感じになります。

![コメント文字化け.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293828/a782bfb9-2adb-8ae1-6f17-253eb7f70024.png)　
「コンストラクタ」の横のアスタリスクのとこ...
まぁ、日本語が見えなくなる訳ではないので、とりあえず様子見ようと思います。

* Eclipseは大丈夫でもサクラエディタがガタガタだったので、IPAフォントとfontlinkしました。

参考：[minttyでConsolas+IPAゴシックで日本語を表示する](https://sgry.jp/blog/2017/07/17/4735/)
[JavaScript]クリップボードを使ったコピーとペースト

Ctrl+CやCtrl+V以外(ボタンのクリックなど)でテキストのコピー&ペーストを実装したい場合、いくつか方法がありますが、ブラウザによって違いがあったりしてややこしいのでまとめました。

# コピー

## 文字を選択させる方法

1. テキストエリアの文字を選択
2. Ctrl+Cを押す

という流れをJavaScriptで行う方法でクリップボードに書き込むには以下のようにします。
これなら、ブラウザ問わずできるはずです。

```js
var textarea = document.getElementsByTagName("textarea")[0];
// 文字をすべて選択
textarea.select();
// コピー
document.execCommand("copy");
```

## ClipboardEvent.clipboardDataを使う方法

ClipboardEvent.clipboardDataを使えば、コピーのイベントが発生したタイミングで、任意の文字を書き込むことができます。
ただし、IEには使えません。IEなど知らぬという声が聞こえますが。

```js
var str = "コピーする文字";

var listener = function(e){
    
    e.clipboardData.setData("text/plain" , str);    
    // 本来のイベントをキャンセル
    e.preventDefault();
    // 終わったら一応削除
    document.removeEventListener("copy", listener);
}

// コピーのイベントが発生したときに、クリップボードに書き込むようにしておく
document.addEventListener("copy" , listener);

// コピー
document.execCommand("copy");
```

## window.clipboardDataを使う方法(IEのみ)

IEでは、window.clipboardDataを使う方法があります。

```js
if(window.clipboardData){
    window.clipboardData.setData("Text" , str);
}
```

## Async Clipboard APIを使う方法

一部のブラウザでは、Async Clipboard APIを使って書き込みができます。([ブラウザ対応状況](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API#Browser_compatibility))

```js
if(navigator.clipboard){
    navigator.clipboard.writeText(str);
}
```

# ペースト
コピーはなんとかいけましたが、ペーストの方はすべてのブラウザに対応するのが現状難しそうです。

## execCommand("paste")を使う方法

execCommand("paste")は、セキュリティの問題からか効かないブラウザが多いです。
使える場合は、

1. テキストエリアにフォーカスを当てる
2. Ctrl+Vを押す

という流れをJavaScriptで行う方法があります。

```js
var pasteArea = document.getElementsByTagName("textarea")[0];
pasteArea.focus();
document.execCommand("paste");
```

## window.clipboardDataを使う方法(IEのみ)

IEでは、window.clipboardDataを使う方法があります。

```js
var text = window.clipboardData.getData("Text");
pasteArea.textContent = text;
```

## Async Clipboard APIを使う方法

Async Clipboard APIに対応しているブラウザでは、以下のようにできます。

```js
if(navigator.clipboard){
    navigator.clipboard.readText()
    .then(function(text){
        pasteArea.textContent = text;
    });
}
```

## Ctrl+Vしたときにテキストを取得する方法

ちなみに、Ctrl+Vするなどしてペーストのイベントが発生した時に、クリップボードのテキストを取得するには以下のような方法があります。ただし、IEでは使えません。

```js

function getClipBoardText(e){
    e.preventDefault();

    var clipboardData = e.clipboardData;

    if(clipboardData != null){
        
        var text = clipboardData.getData("text/plain");
        console.log(text);
    }
}

document.addEventListener("paste" , getClipBoardText);
```

# 参考
・[クリップボードとのやりとり - Mozilla | MDN](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard)
・[ClipboardEvent.clipboardData - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData)
・[JavaScript からクリップボードを扱える Async Clipboard API がそろそろ見えてきました](https://qiita.com/grapswiz/items/c9cfa986a8fe3cc6b41a)
・[Clipboard API - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)
・[JavaScript まとめ - クリップボード操作](http://cya.sakura.ne.jp/js/clipboardData.htm)