OmniAICreator/Qiita-1.07M huggingface dataset:
Craft CMS で前後のエントリを取得する（ストラクチャーの場合）

Craft CMS の詳細ページテンプレートで前後のエントリへのリンクを出力する場合、セクションタイプが `ストラクチャー` か `チャンネル` かで取得方法が異なる。

今回は `ストラクチャー` の場合のサンプルコードについて。

## 直前のエントリへのリンクを出力

```twig
{% set prevEntry = craft.entries().prevSiblingOf(entry).one() %}

{% if prevEntry %}
  <a href="{{ prevEntry.url }}">{{ prevEntry.title }}</a>
{% endif %}
```

エントリ詳細ページ向けのテンプレートであれば `entry` が現在のエントリにあたるため、 `.prevSiblingOf(entry)` で直前のエントリを取得できる。

該当するエントリが存在しない場合を想定し `{% if prevEntry %}` も定義する。

## 直後のエントリへのリンクを出力

```twig
{% set nextEntry = craft.entries().nextSiblingOf(entry).one() %}

{% if nextEntry %}
  <a href="{{ nextEntry.url }}">{{ nextEntry.title }}</a>
{% endif %}
```

直後のエントリの取得は `.nextSiblingOf(entry)` となる。
セットしている変数名が異なるものの、「直前のエントリ」の例と同じ内容。

## 参考

**Craft CMS のストラクチャーで親子関係のデータを取得する | BUN:Log**
https://bunlog.dreamseeker.dev/get-parent-child-relationship-data-with-craftcms

ストラクチャーで親子関係のデータを取得する方法は、こちらが参考になるかと。。。
ただし、Craft CMS 2.x 向けの内容のため、追って最新版を Qiita に投稿する予定。
最新？のスクショ事情

#はじめに
平成が終わろうとしているにも関わらずスクショエンジニアとしてスクショをとり続けている方に向けて、最新のスクショの取り方を共有します！

#スクショ
スクリーンショット、画面キャプチャ。
作業中の画面を画像として保存すること。

#環境
Windows10

#私のこれまでのスクショの取り方
これまで、以下のどちらかの方法でスクショを採取していました。

- mspaint.exeを立ち上げ、貼り付けて保存を繰り返す

Ctrl+n → Ctrl+v → Ctrl+s → 001(連番) → Enter！
という操作で流れるように保存できる領域まで到達しています。
現代でまったく役に立ちませんが…。

- winshotなどのツールを使って採取

もともと銀行のレガシーなインフラ案件をやっていたことが多かったため、フリーソフトや各種拡張は使わない、という文化が根付いており、なかなか重い腰が上がらない。
とか言いながら、2015年頃からyum installしまくり、pip installしまくり、gem使おう！な文化に変わりました。

#Windows10での最新スクショ！
本題はこちらです。
スクショについて調べていたら、もっと効率的な取り方があったのでご紹介。
なんでもWin8ぐらいからあったらしいです…。

その方法は、

```
Win + PrintScreen
```

これを押すと、スクショをとって、
`C:\Users\user\Pictures\Screenshots`
に保存してくれます。
なんと簡単な…。

で、さらにすごいのが、

```
Win + Alt + PrintScreen
```

これを押すと、スクショをとって、
`C:\Users\user\Videos\Captures`
に保存してくれます。
なんと…！！
(なぜVideos…？)

これがすごいのは、ファイル名がこうなること！
**無題 - メモ帳 2019_04_17 8_02_57.png**
**「やばいスクショ」を編集 - Qiita - Google Chrome 2019_04_19 8_15_36.png**
これは…！画面のタイトルっぽいのとタイムスタンプも一緒に取ってくれてる！
これ、すごいですよね！！
ね！！？

是非、これを使って効率的にスクショをとりましょう。
さっさとやるべきことをやって、時間を作りましょう。

#おまけ

以下のコマンドで画面キャプチャ動画もとることができました。

```
Win + g 
```

過去形なのは一時期使えなくなっていたためです。
今使っているPCで押してみると、それらしいのが起動しましたが、今使えるのかは試していません…。
以前は、これでajaxの動作を録画して、同僚に共有してたりしました。
興味のある方はお試しください！

#参考

こちらのサイトのコメント欄に、今回の方法が記載されていました。
記事の内容で、何について調べていたかは察してください。
すばらしい記事だと思います。
[101回死んだエンジニア - Excelでエビデンスとるな。こんにゃろう。](https://el.jibun.atmarkit.co.jp/101sini/2013/08/excel-11e8.html)

面白い記事を書く方ですよね。
楽しく読ませて頂いています。
UnityでWebGLビルドしたファイルをサーバへアップロードした時に出たJSON parse error

UnityでWebGLビルドを行い、サーバへアップロードして動作確認をしようとしたところ、以下のエラーが出ました。

```
Uncaught SyntaxError: Unexpected token < in JSON at position 1
    at JSON.parse (<anonymous>)
    at XMLHttpRequest.t.onload (UnityLoader.js:4)
```

調べても有力な情報が少なく困っていましたが、やっとこのエラーの原因がわかりました。
原因は、
**「パスが間違っていてjsonファイルを見つけられなかったから、もしくはサーバ上でjsonファイルが見つからなかったから」**でした。

UnityLoader.js内では、XMLHttpRequestを使用してjsonファイルを取得し、jsonをパースするという処理を行っています。

XMLHttpRequestのresponseTextを使用してサーバからjsonファイルの中身を取得しているのですが、ファイルが見つからないとjson形式ではないものを取得するようです。

そのため、JSON.parse()でエラーが発生したのでした。

エラーの解決方法ですが、以下の2点を調べれば良いと思います。

- jsonファイルへのパスを記述している箇所でパスが間違っていないか調べる
- Buildフォルダに生成されたjsonファイルがサーバ上にあるか調べる
C++ Builder 10.2 Tokyo > Indy > EIdReplyRFCError > デバッガ動作時 > try, catch以前にエラーになる > エラー回避設定とその解除

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
```

### 状況

- XE4で実装していたプロジェクトを10.2 Tokyoへ移植
    - 各種移植の対処をした
- デバッガで実行時にエラーが出る
    - FTP接続で相手先に該当ファイルまたはフォルダがない時
    - try, catchで捕まえる以前にIndyのエラーとなる
    - `「プロジェクトProject1.exeは例外クラスEIdReplyRFCError（メッセージ'File or Directory not found'）を送出しました。`


![2019-04-18_18h58_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/e6e9b21e-ca26-3387-2efd-59b444b9f228.png)


### IDEの設定変更

「デバッガ例外通知」において「この例外の種類を無視」を選択することで、デバッガ実行時のエラーは回避はできる。

### 設定変更の結果

設定変更の結果はツールのオプションに変更が加わる。

- ツールオプション > Embarcaderoデバッガ > 言語固有の例外

![2019-04-19_09h03_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/0798c832-55b1-4942-3e93-c20783a4495a.png)


解除したいときは上記の設定を削除すればよいだろう。

### XE4では?

XE4では同様のデバッガ動作時エラーは発生しない。
ツールの設定であるため、過去にツールの設定を変更してしまっている可能性はある。
EIdReplyRFCErrorという項目で言語固有の例外として登録されていないことは確認した。
高階関数と型パラメータを使って重複を取り除く

# はじめに
コップ本の勉強中で、理解が難しかったので実際に実装して理解していく。
今回やりたいことは、高階関数と、型パラメータを用いて、重複する処理を簡略化していく。

**結論→事前知識→リファクタリング**の過程という順に書いていく。

# 結論
### 素直に書いた場合
例えば、第一引数の値と第二引数の値を掛け算して、結果を返却する例を用いる。

```scala
object hoge {
  def main(args: Array[String]): Unit = {
    computeSomethingS("hoge")(2)
    computeSomethingI(3)(2)
    computeSomethingD(3.0)(2)

    def computeSomethingS(a: String)(b: Int): String = a * b
    def computeSomethingI(a: Int)(b: Int): Int = a * b
    def computeSomethingD(a: Double)(b: Int): Double = a * b
  }
}
```

複数の型を扱う場合は、上記のように書く必要があるかと思う。
**このコードの問題としては、Long型や、char型が増えた時などに関数を新しく定義してあげる必要がある。**

### 高階関数と型パラメータを用いた場合

```scala
object hoge {
  def main(args: Array[String]): Unit = {
    computeSomething("hoge")(_ * 2)
    computeSomething(3)(_ * 2)
    computeSomething(3.0)(_ * 2)

    def computeSomething[A](a: A)(f:A => A): A = f(a)
  }
}
```

# 事前知識

### 関数リテラルと、関数オブジェクト

scala以外の言語でもこんな感じの処理を見たことがあると思う。

```scala
args.foreach(arg => println(arg))
```

これを分解していくと・・・
foreachの中の```arg => println(arg)```は関数リテラルと呼ぶ。
argパラメータをprintlnに渡している。

関数リテラルの中身のみを取り出してみると以下のように書くことができる。

```scala

(str: String) => println(str)
```

この関数リテラルは実行時にオブジェクトとして存在するので、変数に代入することができる。
つまり、以下のように表現することができる。

```scala

var doPrint = (str: String) => println(str)
```

値としての関数（var ・・・）は、関数でもあるので以下のように呼び出すことができる。

```scala

doPrint("hello scala")
// output: hello scala
```

### 関数リテラルを引数として受け取る。
文字リテラルと同様に関数リテラルも引数に渡すことができる。

- 文字リテラルなら

```scala

  def returnArg(str: String):String = str

  returnArg("hello")
```


- 関数リテラルなら

```scala

  def computeSomething(f:Int => Int):Int = f(2)

  computeSomething((x: Int) => x + 3)
```

- advance

全ての引数が、1回のみ使われる場合は、引数の宣言を省略し、_ で表現することができるので、
簡略化した場合は、以下のように記述することができる。

```scala

  def computeSomething(f:Int => Int):Int = f(2)

  computeSomething(_ + 3)
```

# リファクタリングの過程

### 最初の例

```scala
object hoge {
  def main(args: Array[String]): Unit = {
    computeSomethingS("hoge")(2)
    computeSomethingI(3)(2)
    computeSomethingD(3.0)(2)

    def computeSomethingS(a: String)(b: Int): String = a * b
    def computeSomethingI(a: Int)(b: Int): Int = a * b
    def computeSomethingD(a: Double)(b: Int): Double = a * b
  }
}
```

### 高階関数を適用した

```scala

object hoge {
  def main(args: Array[String]): Unit = {
    computeSomethingS("hoge")(_ * 2)
    computeSomethingI(3)(_ * 2)
    computeSomethingD(3.0)(_ * 2)

    def computeSomethingS(a: String)(f:String => String): String = f(a)
    def computeSomethingI(a: Int)(f:Int => Int): Int = f(a)
    def computeSomethingD(a: Double)(f:Double => Double): Double = f(a)
  }
}
```

### 型パラメータを適用した

```scala

object hoge {
  def main(args: Array[String]): Unit = {
    computeSomething("hoge")(_ * 2)
    computeSomething(3)(_ * 2)
    computeSomething(3.0)(_ * 2)

    def computeSomething[A](a: A)(f:A => A): A = f(a)
  }
}
```

# 最後に

scala難しいけど、楽しい！！！！
特定期間のデータの入ったテスト用DBを作成する

## 利用背景
クエリのテストをする際に一時的な状況のデータでCRUDを行いたい時など。

## 方法
CREATE TABLE ... SELECT 構文を使用する

## 構文
```
CREATE TABLE test_table (SELECT * FROM master_table);
``` 

### 例
```
# 2019-04-01から2019-04-20の期間のデータだけが入ったテストテーブルを作成する
CREATE TABLE test_table (SELECT * FROM master_table WHERE created_at BETWEEN '2019-04-01' AND '2019-04-20');
```

## ポイント
1データベースのテーブル間だけでなくデータベース間でも作成できる

## 参考URL
https://dev.mysql.com/doc/refman/5.6/ja/create-table-select.html

## 雑感
なんでも再現環境を早く作れることが大事そう
Zabbixでアクセス権限が不足していてホストが自動登録されてないように見えていた件

# Zabbixで最初に作成される特権ユーザ以外を作成しログインしていたらホストのディスカバリからの自動登録が行われてなように見えた

## 前提条件
* Zabbixに接続している
+ Zabbix administratorsグループ権限を付与している

## 発生した事象
ホストの自動ディスカバリを実行してもホストが自動で追加されていないように見えていた。
ただし、なんてことはなく、作成したユーザに管理者権限が無かったので見えていなかった。
勝手に「Zabbix administrators」グループに所属すれば管理者権限が付与されると思いこんでしまっていた。

## 対策
管理者権限をユーザに付与した

## 最後に
勝手な思い込み（Windowsではadministratorsグループ権限が付与されれば確か管理者権限が付与されたはず）で
結構な時間をロスしてしまった。
目に見えないからといって、存在しないとは限らない！！
見えていないだけという可能性も忘れずに！
PHPと関連ライブラリのバージョンを上げたら、MySQLのCSV出力結果が途中で途切れるようになった

# PHP5系からPHP7系にバージョンを上げて、且つ古いPEARのモジュールを使い続けたら大量のMySQLの結果取得が途中で途切れるようになった

## 前提条件
* CentOS7（CentOS Linux release 7.6.1810 (Core)）
* php72-php-7.2.16-1.el7.remi.x86_64
* php72-php-mysqlnd-7.2.16-1.el7.remi.x86_64
* php72-php-pecl-mysql-1.0.0-0.17.20160812git230a828.el7.remi.x86_64


## 発生した事象
PHPからMySQLに繋いで大量データをCSVに出力するなんて、よくあるシチュエーションですが
PHPのバージョンを上げるまでは正常に動いていた処理が動かなくなった。
バージョンを上げるまでは正常に動作していたので、処理中に全結果を配列に保持するような方式はとっていないのは明らかなのに。

現象的には、データを大量に出力しようとした場合に途中までの出力で止まるといった
OutOfMemoryチックなのだが、何故か「**Fatal error: Allowed memory size of～**」が出力されない。


## 対応策
地道に（古いPEARモジュールもSVNに直接コミット、管理されていたのでその中まで）デバッグしていったところ
下記のネイティブな関数のコールでDB処理が中断されていた。
@がついているので、エラーメッセージが出ないのも理解できる。
ですが、今まで大丈夫ぶだったのに、バージョン上げてからこの関数が問題になった理由が分からない。

```
@mysql_query
```

ただ、調べていくうちに下記の事が分かった。
* mysql_query()はMySQL Client Library（libmysqlclient）を利用した関数でPHP7で削除されている
* MySQL Client Library（libmysqlclient）はMySQL側が提供している接続ライブラリ
* MySQL Native Driver（php-mysqlnd）を導入することで、同様の関数を引き続き利用出来る
* MySQL Native DriverはPHPの拡張モジュールでありメモリ管理はPHPに依存する

簡単にいうと、libmysqlclient は外部ライブラリなので、メモリ管理はlibmysqlclientで管理されるが
MySQL Native DriverはPHPのモジュールなので、メモリ管理はPHPで管理となる。


https://www.php.net/manual/ja/mysqlnd.overview.php
> 注意: メモリ使用量の報告
> MySQL Native Driver は PHP のメモリ管理システムを使っているので、 そのメモリ使用量を memory_get_usage() で追えます。 これは > libmysqlclient では不可能なことです。なぜなら libmysqlclient は C の malloc() 関数を使っているからです。

https://www.php.net/manual/ja/mysqlinfo.concepts.buffering.php
>
> 注意:
> 
> ライブラリとして libmysqlclient を使っている場合は、結果セットのデータを PHP の変数に代入するまで結果セットのメモリ利用量が PHP のメモリ制限にカウントされません。 mysqlnd の場合は、結果セットのメモリがすべて PHP のメモリ制限にもカウントされます。


mysql_query()という関数は結果セットを自動でバッファリングするため
大量のデータを扱うとPHPのメモリ制限に引っかかりやすい関数なのである。
https://www.php.net/manual/ja/function.mysql-query.php

一方、バッファリングしない関数（mysql-unbuffered-query()）も存在し
こちらを利用することで、メモリ枯渇なく全データにアクセスする事が可能である。
https://www.php.net/manual/ja/function.mysql-unbuffered-query.php


## 対応策
多量のデータ出力の場合のみ、**mysql_unbuffered_query()**が利用されるように変更した。
MySQLiに置き換えるような記載が多く見られますが、それらも内部的には**MySQL Native Driver**を読んでいるため
既存のソースに手を入れないで済むようにこのままとした。


## 最後に
昔から言われていますが「**@**」を付けて関数を呼ぶのは、やっぱり悪手でしょ！！
っと改めて思いました。
CentOS7でOpenSSLを利用しているときにSSLv2のClient Helloが受付られなかった時について

# CentOS7を利用して外部連携用にApacheでHTTPサーバを立てた時にHTTPS通信が受けられない事態が発生した
## 前提条件
* CentOS7（CentOS Linux release 7.6.1810 (Core)）
* Apache2（httpd-2.4.6-88）
* OpenSSL（openssl-1.0.2k-16）

## 発生した事象
外部連携先から正常にHTTP通信出来なかった。
アクセスログに何も表示されず、外部連携先ではエラー結果として下記のような文言が表示されたらしい
**Remote host closed connection during handshake**

以前からTLS1.0が利用されている事は認識していたので、プロトコル指定（SSLProtocol）でTLS1.0も許可しても結果は変わらず。
暗号化方式が一致しないのかと思い、暗号化方式（SSLCipherSuite）の設定を緩くしても結果は変わらず。

仕方が無いので、最後の手段でtcpdumpを利用したパケットキャプチャにて状況の把握を開始する。
結果としては、下記の結果につきるものだった。

```
SSLv2 Record Layer: Client Hello
```
えええ！！SSLv2ですか！！
とはいえ、ちょいと昔はTLSを利用していてもハンドシェイクは互換性のために
SSLv2の方式を許可する事が一般的だったらしいのですが、CentOS7に標準で導入されるOpenSSLではもう対応していないとのこと。


## 対応策
~~別途古いOpenSSLを導入~~
TLSで利用するモジュールをOpenSSLからNSSに変更したことで、SSLv2のハンドシェイクに対応できました。
以下はNSSの設定内容となります。
鍵をストアのようなところに格納して**NSSNickname**と**NSSCertificateDatabase**で指定するところ以外はOpenSSLの設定と同じようなものです。
※連携先とは接続元IPの制限をかけていて、一般に公開しているサービスではないのでで、全体的に脆弱な部分は目をつむる感じで。。。

```
Listen 14443
<VirtualHost *:14443>
    DocumentRoot {DocumentRoot}

    NSSPassPhraseDialog  builtin
    NSSPassPhraseHelper /usr/libexec/nss_pcache
    NSSSessionCacheSize 10000
    NSSSession3CacheTimeout 86400
    NSSRenegotiation off
    NSSRequireSafeNegotiation off

    NSSEngine on
    NSSCipherSuite +rsa_aes_256_sha
    NSSProtocol TLSv1.0
    NSSNickname {NSSNickname}
    NSSCertificateDatabase /etc/httpd/alias

</VirtualHost>
```

## 最後に
今回、CentOS5からCentOS7にサーバのバージョンを上げた事で、今まで接続出来ていた通信が接続不能となりました。
新しくなることで接続不能になる可能性は想定していましたが、設定レベルでどうにか出来ると高を括っていました。
でも、yumでインストール可能な基本パッケージだけでどうにか出来てよかった。

## その他
SSLv2を利用したハンドシェイクで正常に通信出来るかの検証のために、Java1.4を別途準備してHTTPS通信を実行した。
まさか、今更Java1.4を利用することが来るとは思わなかった。
古いものの検証には、古いものが必要なんですね。。。
NFS4をPacemakerでクラスタ構成にする際にフェイルオーバー時のクライアント側からの通信遅延について

# Pacemakerを利用したNFSサーバのクラスタリングで、クライアントのマウントがフェイルオーバー後に再接続するまで時間がかかる場合の設定見直しについて

## 前提条件
* CentOS7
* NFS4の形式でクライアントがNFSマウントしている
* Pacemakerを利用してNFSサーバがクラスタ構成となっている

## 発生した事象
クライアントがNFSマウントしたまま、NFSサーバがフェイルオーバーした際に
クライアント側のロック要求を90秒待つデフォルト設定があった
https://access.redhat.com/solutions/42868

## 対応策
「**nfsserver**」リソースに「**--grace-time {秒}**」オプションをつければよいとのこと
これで、ロック要求を待つ時間を短く出来る。

```
[hoge@nfs ~]$ sudo crm configure show res_NFSServer | cat
primitive res_NFSServer nfsserver \
        params nfs_ip=***.***.***.*** nfsd_args="--grace-time 10"
```

上記指定をすると、「**/etc/sysconfig/nfs**」が自動的に構成されて、結果として下記の行が追記され
ロック要求待ち時間設定が効くようになります。

```
[hoge@nfs ~]$ sudo cat /etc/sysconfig/nfs | grep "grace-time"
RPCNFSDARGS="--grace-time 10"
```

## 最後に
通常は「**/etc/sysconfig/nfs**」に設定すればいいのですが、
Pacemakerを利用していると、設定ファイル自体が書き換えられるとは思ってませんでした。
NFSサーバを構築して、フェイルオーバー時に挙動がおかしいと思ったらこの設定を見直してみてください。
プログラミング初心者がAtcoderに初挑戦してみた

# 始める前の自分のスペック

Hello Worldなどの初歩のコード書く→飽きる→HE(以下略)

# 一週間前からC++勉強してみた
[AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/APG4b)で解説見ながら問題を解いてました。
途中からハマってきて苦痛なく14まで進めることができました。もともと詰将棋が好きなので簡単なパズルを解いてる感じてした。
forやifなども書き続けるうちに覚えましたね。いままでは講座で解説された物を苦痛に耐えて一回書いてオシマイだったので、中々身につかずにいたのでこれは自分向きでしたね。

# そして初参戦
[AtCoder Beginner Contest 124](https://atcoder.jp/contests/abc124)に参加しました。
目標はA問題正解だったのですが、意外にもA,B,Cを解くことができました。Cは時間ギリギリだったけどw

# 反省
+ コードテストのページでコードを書いていたんですが}が少ないか多くなってエラーがでたがどの{がどの}て対応してるかわからなくて困った。次回ははVScodeで書くことにした。
+ [解説動画](https://www.youtube.com/watch?v=FRzpDCx17vw)で累積和やしゃくとり法を知る。定跡みたいな物みたいなので他の問題で練習して身につけておきたい。
+ 何度も使う文があるのでスニペットソフトで登録しておく。
地域区分データを #Power BI で活用しよう！

# 地域区分データとは？
都道府県を様々な区分で集約したものですね。
このサイトに要所毎に区分別けされてます。
[日本の地域分類](https://tools.m-bsys.com/data/area_classification.php)

これをPower BIに読み込んでみました。

# とりあえず読み込んでみましょ

1. データの取得をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/51019955-5fee-f9e3-c1c9-3763e5323ea8.png)

2. その他からWebを選択し、接続をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/8a42f914-a442-eca2-0074-993ccc442041.png)

3. Webから上記リンクのURLを入力しOKをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d000214d-4e22-7766-ce91-b8704d1ce896.png)

4. Table0にチェックをし、編集をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/0336c105-ef8f-8e04-341b-fe268494ef12.png)

5. Power Queryエディタが開きますので、Column2列を選択し、列の分割から区切り記号による分割をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/c587e574-6b40-17b4-bf71-69e9026076c2.png)

6. 自動的に区切り文字として　「、」が選ばれているので、区切り記号の出現ごとを選択し、OKをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/2373c427-2957-dd9a-3e0e-6cc3227a57b2.png)

7. Column1列を選択し、変換タブ/列のピボット解除から、その他の列のピボット解除をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1c7a0831-7239-518f-f24c-672c2ac9e992.png)

8. 属性列を選択し、右クリックから削除をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e688256f-c1a1-4d15-285d-815645b8567b.png)

9. Column1列を選択し、右クリックから名前を変更をクリックし、地域区分と変更します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1db22bde-8433-fb22-984c-bc481b8b63d7.png)

10. 値列の名前を都道府県と変更します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/caff9426-c510-8757-73b0-a0c03288491f.png)

11. ファイルから閉じて適用をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/428874ee-12c6-2172-a91d-d910b432871c.png)

これで、こんな感じでPower BI上で都道府県のデータを元に地域区分で集計することができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/847b9565-575b-2ac8-c56c-5cb803b5a184.png)
JavaScriptにおける2次元配列のスマートな初期化〜ゼロで埋める例

# はじめに

2次元配列はテーブルのようなものを表せるのでいろいろな場面で使用したくなることが多々あると思う。
そこで今回は**`JavaScript`で`NxM`の`2次元配列`を`ゼロ初期化`する`スマートな方法`をここにメモしておこうと思う。**

# やりかた

調べてみて最初に私がわかりやすさとかっこよさを兼ね備えていると思った方法がこちら。

```JavaScript:やりかたその１
let table = Array.from(new Array(N), () => new Array(M).fill(0));
```

こちらのやりかたも良いと思った。

```JavaScript:やりかたその２
let table = [...Array(N)].map(() => Array(M).fill(0));
```

ただなんかその理屈で行くとこのやり方もいけそうな気がする。

```JavaScript:やりかたその３
let table = Array.from([...Array(N)], () => Array(M).fill(0));
```

調べてみたら`from`は`map`とやっていることほぼ変わらないので好みの問題か。
`new Array()`っていう時代でもなさそうなので`やりかたその２`か`やりかたその３`が今風だと思われる。
**個人的には`やりかたその２`を推す感じになりそう。**(`map`は他言語でも結構メジャーなので)

ここで使用している`アロー関数`や`スプレッド構文`は**`ES2015`**の範囲になるが、
まあ使えない環境にみなさんいることはないだろう。
ESの開拓がどんどん進んでもっと書きやすくなったら追記していこうと思う。

# 参考元

[2次元配列の初期化（ES2015）](https://qiita.com/butchi_y/items/db3078dced4592872a9c)
↑の記事のコメント欄に記述されている内容を一部取り上げさせてもらった。感謝。

# さいごに

結論に個人的な推しを最初に書くべきか考えている。
なんか変だと感じたら`やりかたその１`と`やりかたその２`を入れ替えて書き直すかもしれません。
【C#】第1回「この機能作ったけどあんまり意味なかったな」選手権

# 最初の発想は・・・
1. この値はこの別の値と組になっているのが正しいことが証明されている配列がほしい。(例えば、UnityでGameObject(A)とGameObject(B)が空のGameObject(C)の子に設定されているオブジェクトが複数個あるときにどのオブジェクトがどのオブジェクトと組になっているのかが知りたい)
2. Dictionary<TKey, TValue>よりも柔軟性がある物が欲しい。
3. List<T>とタプルで作ろう。
そんな考えでできたのが以下の拡張メソッド。

```csharp:ListExtentions.cs
public enum LRSwitch{
    LEFT,
    RIGHT
};
public static bool TupleContains<TObject, TComponent, TValue>(this IList<(TObject, TComponent)> extList, TValue value, LRSwitch lr)
{
    if(lr == LRSwitch.LEFT)
   {
       return extList.Select(obj => obj.Item1).Any(item => item.Equals(value));
   }
   else if(lr == LRSwitch.RIGHT)
   {
       return extList.Select(obj => obj.Item2).Any(item => item.Equals(value));
   }
   else
   {
       return default;
   }
}

public static TComponent TupleContainsGetComponent<TObject, TComponent, TValue>(this IList<(TObject, TComponent)> extList, TValue value)
{
    return extList.First(obj => obj.Item1.Equals(value)).Item2;
}
```
- 1つ目の拡張メソッドはListの中にあるタプルの組1か組2の値を第3引数と比較して格納されていたら真偽値を返すだけの拡張メソッド。
普通にListにContainsメソッドにがあるけど、そのためにちょっと毎回この手のロジックを書くのがめんどくさかったのが伺える。
- 2つ目はタプルの組1の値と第3引数と比較して、その値が存在していたら組2の値を返す拡張メソッド。なんか複雑なことをしてそうでしてない感じ。・・・なんで作ったんだろう？多分存在するかどうかを確認しつつ値を返してほしかったんだろうね・・・

# 総評(自分でだけど)
見れば見るほど「Dictionary<TKey, TValue>でよくね？」という気持ちが溢れ出ています。
多分あとからどちらの数値にも値を代入するつもりがあったんだろうね・・・
でも、これで少しでもC#の拡張メソッドについて学べたのは良かったと思います。
レスポンシブサイトのコーディングについて

レスポンシブ対応サイトのコーディングについて個人的にまとめておきます。

基本的に必要なことは以下の２つです

- ①htmlでviewportの設定
- ②cssでmedia queryの設定

# viewportの設定

各htmlのheadタグ内に

```html
<head>
  ...
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
```

の記述をします。これはviewportの画面幅と初期拡大率を設定するものです。上記のように記述すると

- `width=device-width` で画面幅を各デバイス
- `initial-scale=1.0` で初期拡大率を100%に設定したもの

に設定されます。複雑に見えますがレスポンシブサイトを作る場合基本的には
上記のタグをそのまま挿入すれば良いです。

# media queryの設定

メディアクエリは画面の幅などの条件に対応して
コンテンツ描画が行えるようにするCSSの機能です。

記載方法は下記の通り

```css
@media screen and (max-width: 480px) {

/* ここに480px以下の場合だけ適用させたいCSSを記載します */

}
```

この機能を利用すると
例えば”画面サイズが480px以下の時だけカッコ内のCSSを適用する”のようなことことができます。
この機能を利用して

#### 「画面サイズが480px以上のCSS(PC用CSS)」を画面サイズが480px以下で適用されるCSS(SP用CSS)で上書きする」のがレスポンシブサイト作成の基本となります。


例　(divのwidth960pxを、画面幅480px以下の時に書き換えるCSS)

```css
div {
  width: 960px;
}

@media screen and (max-width: 480px) {
  div {
    width: 100%;
  }
}
```

# 【TIP】SP用CSSでwidthは固定pxではなく％を利用する

例えばviewportを設定した状態で
以下のCSSを適用するとdivのwidthがiphone(375px)以上の値になってしまうため画面内にdivが収まらなくなくなってしまう。
だからといって
@media screen and (max-width: 480px)で divを375pxにするわけにはいかない。
その場合375pxのスマホでは思い通りに見ることができるが、スマホには色々なサイズが存在するので
他の画面サイズのスマホでサイトを見た際に思い通りの表示とならない。

```css:ダメな例

div {
  width: 960px;
}

@media screen and (max-width: 480px) {
  div {
    width: 375px;
  }
}
```

なので、widthを%で上書きするのが一般的です。
これだと、色々なスマホサイズに対応できます。

```css:％で設定した例

div {
  width: 960px;
}

@media screen and (max-width: 480px) {
  div {
    width: 100%;
  }
}
```

# 【TIP】PCサイトでは表示させたいがSPサイトでは消したいもの

色々な方法があると思いますが、以下のようにCSSを記載し対応します。
このCSSを記載すれば、例えば「PCサイトでは表示させたいがSPサイトでは消したい要素」には
class="pc"をつけるだけで実現することができます。

```css:display
/* 画面サイズが480px以上の時 */
.pc {
  /* class="pc"が付いたものを表示する */
  display: block;
}

.sp {
  /* class="sp"が付いたものを非表示にする */
  display: none;
}

@media screen and (max-width: 480px) {
/* 画面サイズが480px以　以下の時 */
  .pc {
    /* class="pc"が付いたものを非表示にする */
    display: none;
  }

  .sp {
    /* class="sp"が付いたものを表示する */
    display: block;
  }
}
```
【備忘録】ウィンドウサイズに合わせてコントロールのサイズを変える【WPF】

かなりつまづいたので備忘録です。

#事象
まず、このようなアプリを作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/dd0e2907-107f-ae0a-c98c-aa83c58ce620.png)
この中央にあるListBoxを、ウィンドウのサイズに合わせてコントロールのサイズを変えたかったのですが・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/f8e2d150-df2e-1497-38d7-c9117fa10104.png)
このようにListBoxが下にくっつかない(サイズが変わらない)や、それより下のコントロールがくっつかない現象が発生しました。
通常、以下のようにすれば自動的にサイズ調整してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/159697af-4bd3-f906-7ae9-e043c64c4fed.png)

```xml
<ListBox Name="listBox1" Opacity="0.5" FontSize="16" TabIndex="3" Margin="10,10,10,13" Grid.RowSpan="7" Grid.ColumnSpan="3"/>
```

ですが、なぜかくっついてくれなかったので以下を試してみました。

#AnchorやDockを適応してみる
いわゆるWindowsFormsでいうAnchorやDockを適応してみます。
WPFにはAnchorなどのプロパティは存在しません。
そのため、ListBoxに以下を記述します。

```xml
<ListBox Name="listBox1" Opacity="0.5" FontSize="16" TabIndex="3" Margin="10,10,10,13" Grid.RowSpan="7" Grid.ColumnSpan="3" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
```

`Width` `Height`を`Auto`、
`HorizontalAlignment` `VerticalAlignment`を`Stretch`
で指定します。
そうすることで、外側のウィンドウの大きさに合わせてコントロールの大きさが変わるようになります。

###が、変化なし
これでも変化はなく、サイズを自動調整してくれませんでした。

#結局何がダメだったのか
今回のアプリは、Gridを使ってコントロールの位置を決めていました。
そこで私は、何もためらいもなく以下のようにGrid.RowDefinitionを指定してしまいました。

```xml
<Grid Margin="0,0,0,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
　　　　　　　　　　　　︙
```

このように、**固定**にしてしまったわけです。
つまり、50ピクセル固定にしてしまったので、それ以上大きくならなかったわけですね。
**はい、私の凡ミスです。**いや、知らなかっただけなんですけどね、冷静に考えれば確かにそれ以上大きくならないのは当たり前でしょうけど・・・。

#結論
`RowDefinition`を自動調整したいので、ListBoxで指定している7番目の行を`Star`にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/4fddfc2d-acfb-d0f7-2728-7d6d1e2526c7.png)

`Star`にすることでRowDefinitionが自動的にサイズ調整してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/6a607521-4990-85e0-91cf-a1e0912b1ae9.png)

#まとめ
コントロールのサイズを自動調整させたい場合は、

* 自動的にサイズ調整してほしい方向にある`C`みたいなアイコンをクリックしてくっつける
* `RowDefinition`を固定にせず、`Star`にする(Grid？に限る)

#参考サイト
* [ウィンドウの幅や高さに合わせてコントロールのサイズを自動調整したい (autosize=true) (WPFプログラミング)](https://www.ipentec.com/document/wpf-layout-autosize-tips)
* [[WPFへの道 vol.2] AnchorやDockはどうするの？](https://blogs.msdn.microsoft.com/ttanaka/2010/11/02/wpf-vol-2-anchordock/)
* [Grid コントロール](http://www.kanazawa-net.ne.jp/~pmansato/wpf/wpf_layout_grid.htm)

#おまけ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176021/3c2e2028-741a-9f32-a762-29795a2850ab.png)

背景描いた人はこの人です:coffee:→ @Chino_Kafuu
自分用勉強メモ1日目

メモ，日記程度につらつらと書いていく．

# MBA の Python 環境構築で躓いた

[[MacOS Mojave]pyenvでpythonのインストールがzlibエラーで失敗した時の対応](https://qiita.com/zreactor/items/c3fd04417e0d61af0afe)

pyenv の使い方とかをさくっと調べた．

[Python 2系と3系の共存](https://qiita.com/nakamura_hikaru/items/639204ee7c7c8cd51a90)


# CTFに挑戦
[2 Easy Cipher](http://ksnctf.sweetduet.info/problem/2)

これから少しづつ取り組んでみる．

# シーザー暗号
[Python で ROT13 (シーザー暗号) を書いてみる](https://blog.amedama.jp/entry/2015/10/13/213412)

pythonで実装してみた．
標準で実装されているので記述が楽．

```Python:caesar_cipher.py

import codecs
line = input('シーザー暗号を解く文字列を入力 -> ')
answer_str = codecs.decode(line, 'rot13')
print('answer: {}'.format(answer_str))
```
実行結果は以下の通り．

```
$ python caesar_cipher.py 
シーザー暗号を解く文字列を入力 -> Guvf vf n grfg.
answer: This is a test.
```
Gopherちゃんと友達になってみた (introduction)

# TL;DR
    - golangと仲良くなろうと頑張ってみました、というお話
    - 複数回に分けてやっていく予定です
    - 今回は「golangって何が得意な子なの？」について調べてみました

# ことの始まり
※ 注意：実際の事実とは異なる点がございます
※ 注意：この物語はだいたいフィクションです

~ ある日の会社にて ~

上司「ワイ君さ、ちょっといいかな」
ワイ「？はい、ええですけど」
上司「今のシステムとは別の構成で、全く新しいAPI作るんだったらなんの言語がいい？」
ワイ「えー、今ならgolangじゃないっすかね？」
ワイ（正直よお知らんけど）
上司「おかのした」

~ 後日 ~

上司「ワイ君さ、ちょっといいかな」
ワイ（またかいな）
上司「この前のあれ、どんな感じになるか具体的にちょっとまとめてよ」
ワイ「？」
上司「あれだよ、APIをgolangで作るってやつ」
上司「ワイ君が言ってたgolangでやることにしたから、モック作って」
ワイ「え」
上司「あっ、あとさ、メンバーに導入教育もしなくちゃいけないからそこらへんもいい感じによろしく」
ワイ（）

# Gopherちゃん、はじめまして

ワイ（golangって、なんとなーく流行ってるってことしか知らんなぁ）
ワイ（適当に答えてしまったけど、まっ、なんとかなるやろ）
ワイ（あ、そもそもgolangってAPIに向いとるんか確認してへんかったわ）
ワイ（まずはgolangってそもそも何者かっちゅーところから調べてみるか）

ワイ「とりあえず、[公式サイト](https://golang.org/)をぐぐってみるか」
![The_Go_Programming_Language.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318649/64280a6e-3271-625f-fc61-d15c5527bb7b.jpeg)

ワイ「えらいシンプルなサイトやな」
ワイ「Hello Worldもサイト内で試せるんか！」
ワイ「すごいな！（Worldだけなんか翻訳されてるけど）」
ワイ「イメージキャラクターもかわいいやん」
![gopher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318649/f11f8074-bfb9-b845-5fc5-a311cc6f08d0.png)

ワイ「はえー、チュートリアルも一通りできるんか」
ワイ「至れり尽くせりやな」
ワイ「でも今回は一旦おいとこ」
ワイ「まずは、この子が何が得意なんかってことを知らんとな」

# Goって何が得意な子？
ワイ「何が得意な子なんかちゃんと知っとかんと」
ワイ「go 言語仕様、っと（カタカタ）」
ワイ「これか」
つ https://golang.org/ref/spec
![The_Go_Programming_Language_Specification_-_The_Go_Programming_Language.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318649/3d984bff-9e3c-2a17-d2b0-7b4e7de7834b.jpeg)


ワイ「なんやえらい長いな...」
ワイ「ちょっとずつやってこ...」
ワイ「えーっと、まずはIntroductionやな」

```
Go is a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming. Programs are constructed from packages, whose properties allow efficient management of dependencies.
```

ワイ「英語力に不安が残るけど、ここで言いたいんは」
ワイ「**goはシステムプログラミングを考えて設計された汎用的な言語** っちゅーことと」
ワイ「**ごっつ強い型付け** と **ガベージコレクション** と **並列処理** を機能としてサポートしとる」
ワイ「んで、プログラムは **パッケージ** という単位で作られとって」
ワイ「そのおかげで、依存関係を楽に管理できる」
ワイ「ということやな」

ワイ「システムプログラミングっちゅーのが肝っぽいんやな」
ワイ「システムプログラミングってなんやろ」

# システムプログラミングってなんだろう

ワイ「システムプログラミングをぐぐってみよ」
ワイ「なんやはっきりしたのないなー」
ワイ「低レイヤーを指してるっぽいちゅーことしかわからんな」
ワイ「おっ、[Goならわかるシステムプログラミング](https://rpx.a8.net/svt/ejp?a8mat=2NDO5M+AABN1U+2HOM+BWGDT&rakuten=y&a8ejpredirect=http%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00q0724.2bo11c45.g00q0724.2bo12179%2Fa16020146334_2NDO5M_AABN1U_2HOM_BWGDT%3Fpc%3Dhttp%253A%252F%252Fitem.rakuten.co.jp%252Fbook%252F15681202%252F%26m%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fbook%252Fi%252F19368741%252F)言うのがあるやん」
ワイ「この本的には **OSの提供する機能を使ったプログラミング** をシステムプログラミングっちゅーことにしとるらしいな」
ワイ「OSの提供する機能 = 低レイヤーっちゅーことなんやな」
ワイ「まっ、ここらへんもgoの勉強進めていけばわかるようになるんやろうな、きっと」
ワイ「他は **ごっつ強い型付け** と **ガベージコレクション** と **並列処理** やったな」
ワイ「次は **ごっつ強い型付け** について調べてみよか」


（次回へと続く）
京都大学テキストコーパスがmacOSXで変換できない。

##はじめに
今までプログラムなんて触ったことがなかった人間が、研究で自然言語処理をやることになった。
JUMAN++を使って色々やるにあたって、京大のコーパスを使おうと毎日新聞のデータを用意したが、肝心の変換用perlスクリプトが動かない。
web上に情報が少なかったため、頑張った情報をまとめてみた。

###前提とか環境とか
- macOS Mojave 10.14.4
- Perl 5.18.2
- [京都大学テキストコーパス \- KUROHASHI\-KAWAHARA LAB](http://nlp.ist.i.kyoto-u.ac.jp/index.php?%E4%BA%AC%E9%83%BD%E5%A4%A7%E5%AD%A6%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%B3%E3%83%BC%E3%83%91%E3%82%B9)
    - 変換スクリプトファイル EUC-JP
    - 毎日新聞データ(mai1995.txt) Shift_jis

###どんな状況になったか。
以下のサイトを参考にしたが、エンコード関係のエラーが改善されない。
[satomacoto: Macで京都大学テキストコーパスの変換](https://satomacoto.blogspot.com/2013/01/mac.html)
ここでは、format.plとnum2KNP.plを書き換えればいいよ、と紹介されていた。
しかし、この通りスクリプトを書き換えてもエラーが出て先に進まない・・・。
最近Pythonを始めたばかりで、perlの事なんてなお解らない。

##次の一手
解らないなりに色々と試行錯誤してみた結果、参考になりそうなサイトもいくつか発見した。

[PerlでUTF\-8の文字コードを扱う](http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/old/perl/perl_utf.html)

とにかく、全てのファイルをUTF-8で扱うのが間違いない、気がする。
nkfを使って、スクリプトが入っている`/scr`以下を全て雑に書き換えてやった。
`nkf -wd *`
そもそも、初心者過ぎてnkfが解らなくてこれも苦労した

##スクリプトを書き換えると・・・
次に、format.plを下の様に書き換えた。元の文はコメントアウトしてある部分。

```perl:format.pl(old)
#use encoding 'euc-jp';
#use open IO => ':encoding(euc-jp)';
#use open ":std";
#binmode(STDERR, ':encoding(euc-jp)');
use utf8;
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
```
これでなんとか先に進めるようになったのだけど、次は`making KyotoCorpus (syn) ...`のあとから、
`converting 9512ED ...
Can't find 951201043-001 in ../dat/num/9512ED.org at ../src/num2KNP.pl line 45, <ORG> line 9043.`

とエラーが出てしまう。
もうよく分からないけど、変換された生成物であろう、*.orgを開いてみると、激しく文字化け・・・。
auto_convとにらめっこしてみると、
.orgファイルは*.allを変換したものみたい。
そしてそもそもの*.allが文字化けしている。
やっぱ元のテキストをshift-jisのまま扱ってるのがダメなのか？

##毎日新聞データをUTF-8に変換
nkfでutfに変換してみる。
`nkf -wd mai1995.txt > mai95.txt`

しかしこれでもダメ。

紹介されていたページでは、format.plとnum2KNP.plを書き換える、とあったけど、
やっぱり、\*\.allを生成しているスクリプトは別物だし、全部書き換えてやる必要があるっぽい。
**やってやる。**

##各スクリプトの書き換え
trans.plを以下の様に書き換える。

```perl:trans.pl
# use encoding 'euc-jp', STDIN => 'shift_jis';
use utf8;
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
```
mainichi.plも同じように

```perl:mainichi.pl
# use encoding 'euc-jp';
use utf8;
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
```
こちらは、下の方にある出力も書き変えてみた。

```perl:mainichi.pl
# open(OUT, '> :encoding(euc-jp)', "$base_dir/$current_month.all");
open(OUT, '> :utf8', "$base_dir/$current_month.all");
```
もうこの辺からやけくそ。とりあえず数打ちゃ当たる戦法をとる。

```perl:grepKNP.pl
use strict;
use Encode qw(decode);
# use encoding 'euc-jp';
use utf8;

---下の方もいじってみる---
# my $pattern = decode('euc-jp', $ARGV[0]);
my $pattern = decode('utf8', $ARGV[0]);
------
# open(DAT, '< :encoding(euc-jp)', $f) or die;
open(DAT, '< :encoding(utf8)', $f) or die;
```
基本的には同じことをしているだけ。
そもそもMarkdownでちょっと離れたところのコードを書くときはどうすればいいんだろう。

```perl:dupli.pl
# use encoding 'euc-jp';
use utf8;
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
```
```perl:tree.pl
use Encode qw(encode);
# use encoding 'euc-jp';
use utf8;
```
##動いた！！
これでなんとか動き出して、エラー無しで最後まで変換できたっぽい！
しかし、生成されたKNPファイルが正しく変換できたものなのか、それはまだ解らない・・・。

プログラマー初心者だけど、Qiitaのコミュニティには可能性を感じたので共有してみました。
色々と間違っている事もあるかと思いますので、是非ご指導いただけましたら幸いです。
よく使うPython開発環境構築(仮想環境anyenv、pyenv,pipenv)

# よく使うPython開発環境構築(仮想環境anyenv、pyenv,pipenv)

普段Python(Django)でWeb開発してます。
Dockerを使うのは一番モダンだと思いますが、今の自分はDockerワカラナイというのと、
小規模、個人開発で気軽で使いやすいpython開発環境は本記事のやり方だと思うのですぐに構築できるようメモを残そうと思う。
データサイエンスではAnacondaが主流なので、Web系でPythonを使う人向きだと思います。


## 超参考になった記事
anyenvまとめ
https://qiita.com/SUZUKI_Masaya/items/51366be1510f7fde7cdf
pyenvまとめ
https://qiita.com/SUZUKI_Masaya/items/7ba3fef9eb7c9603762a

2019年に向けてPythonのモダンな開発環境について考える
https://techblog.asahi-net.co.jp/entry/2018/11/19/103455

### なぜpipenvを使うのか


anyenvとpyenvを使って仮想環境を作成することでバージョン管理がやりやすくなる。
pipenvを使うとpipfile、pipfile.lockというファイルが作られる
requirement.txtの多機能版である。
RailsでいうGemfileようなもの。

pipfileがあればpipenv installするだけでインストールできる

ローカルを汚したくない人にもおすすめ

```zsh
# インストールしてpathを通す
$ anyenv install pyenv
$ exec $SHELL -l

$ pyenv install --list # インストールできるバージョンを確認
$ pyenv install 3.7.2 # Python3.7.2をインストール
# ディレクトリ内でPythonへのパスを3.7.2へ通すように設定する
$ pyenv local 3.7.2 
```

### venv環境をつくる

```zsh
# .venvにvenv環境のディレクトリを作る
$ python -m venv venv

# venvを有効化
$ source venv/bin/activate
(venv)$

# ※ 仮想環境の終了は
(venv)$ deactivate
```

```zsh
# pipインストールされているpypyを確認
$ python -m pip list
# 必要ならpipのアップグレード
$ pip install --upgrade pip setuptools
```

### pipenvをインストール
```
$ pip install pipenv
```

```zsh
# pythonのバージョン指定(Piofileが作られる)
$ pipenv --three # python3系
```

```zsh
# 外部ライブラリのインストール
$ pipenv install ライブラリ
```

``` zsh
# pythonのバージョンを指定してインストール
$ pipenv install --python 3.5

# キャッシュクリア
# pipfile.lockあたりのエラーが出た際、また妙にpipenv installが遅いときに
$ pipenv lock --clear

```

```zsh
# requirements.txt で一括インストールもできる
$ pipenv install -r requirements.txt
```

## あとがき
人によっては、パッケージングが過剰すぎる！と思うかもしれませんが、
そこはプロジェクトによって柔軟にしてください。
ICPのプライベートDocker RegistryにMacからdocker pushする

## なぜ投稿したか
基本的には、[Docker CLI の認証の構成](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.2/manage_images/configuring_docker_cli.html)を参照して実施すればよいのですが、ハマったところがいくつかあるので備忘も兼ねて投稿しました。

## 動作環境
[過去の投稿](https://qiita.com/yurak/items/d56575635bca0061155d)で構築した環境を使用しました。
簡素なレイヤー図は以下になります。


| Private Docker Registry |
|:-:|
| ICP |
| Ubuntu |
| VirtualBox |
| MacOS |

## ハマりポイント
### cluster_CA_domain がわからない
> cluster_CA_domain は、インストール時に config.yaml ファイルに設定された認証局 (CA) ドメインです。

何を設定したか（している）か覚えていなく、そもそも設定してないのでは、、、と思っていました。
>  CA ドメイン名を指定しなかった場合、デフォルト値は mycluster.icp です。

ちゃんと書いてありました。（見落とし）

### Docker for Mac の再起動がわからない
> Docker サービスを再始動します。

すごーく簡単でした。
画面右上のくじらアイコンから``Restart``です。
<img width="250" alt="スクリーンショット 2019-04-18 23.48.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232123/c4ec87d9-f56d-5640-4094-8bf62b112bd2.png">

## 結果
[ガイド](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.2/manage_images/using_docker_cli.html)を参考にしながら、loginします。

```
$ docker login mycluster.icp:8500
Username: admin
Password:
Login Succeeded
```

ICP のプライベート Docker Registry に Mac から docker push します。

```
docker push mycluster.icp:8500/default/docker_hub_id/wlp:v0.0.1
docker push mycluster.icp:8500/default/docker_hub_id/rabbitmq:v0.0.1
docker push mycluster.icp:8500/default/docker_hub_id/mysql:v0.0.1
```
GUIで確認できました。

## この接続ではプライバシーが保護されません エラーへの対応
[過去の投稿](https://qiita.com/yurak/items/d56575635bca0061155d)で構築した環境へ、Google Chrome からログインしようとすると、エラーが表示されます。
<img width="747" alt="スクリーンショット 2019-04-19 0.29.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232123/bdc24067-67c4-4f47-a615-d56200958972.png">

SSL通信なのですが、[独自の認証局(CA)](https://www.ibm.com/support/knowledgecenter/ja/SSBS6K_3.1.2/installing/create_ca_cert.html)を使用しているためです。
先ほどのCLIでキーチェーンに証明書を追加しました。
その証明書を信頼してあげると、上記エラーは解消します。

「Launchpad」 -> 「その他」 -> 「キーチェーンアクセス」 を開きます。
「キーチェーン」欄は"システム"、「分類」欄は"証明書"を選択します。
<img width="1191" alt="スクリーンショット 2019-04-19 0.41.24 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232123/baaa3697-cab5-b240-7a12-16899a8f6d1d.png">

「icp-router」をダブルクリックし、「信頼」の折りたたみを開きます。
「この証明書を使用するとき」は「常に信頼」にし、閉じます。
<img width="788" alt="スクリーンショット 2019-04-19 0.44.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232123/1ccbad6e-67ee-d71e-ed4f-4c01fca9930c.png">

ログイン画面をリロードすると、エラー画面は表示されなくなります。
Nexus Repository Manager 3で不要なSNAPSHOTバージョンをお掃除する

プロジェクトのビルド後の資材(jarやwarなど)を[Nexus Repository OSS](https://www.sonatype.com/nexus-repository-oss)を利用して管理しているのですが、Nexusを入れていたサーバのディスクが予想以上に使用されていて・・・「？？？」と思って使用量を調べたらNexusさんのディレクトリ配下が65Gと予想以上に使用していました。

# サイズが大きくなっていた理由は？

大量のSNAPSHOTバージョンがリポジトリに残り続けていたことが原因でした。SNAPSHOTバージョンは・・・・

```
...
foo-1.0.1-20190418.004411-24.jar
foo-1.0.1-20190418.004411-24.jar.md5
foo-1.0.1-20190418.004411-24.jar.sha1
foo-1.0.1-20190418.004411-24.pom
foo-1.0.1-20190418.004411-24.pom.md5
foo-1.0.1-20190418.004411-24.pom.sha1
...
````

という感じで、デプロイした日時でリビジョンが振られ、何も対策しないとリポジトリに残り続けてディスクを無駄遣いすることになります。

# SNAPSHOTバージョンのお掃除タスク

ちゃんとSNAPSHOTバージョンのお掃除タスクが用意されており、必要なSNAPSHOTバージョンだけをリポジトリに残しておくことができます。本エントリーでは具体的なタスクの登録方法などの説明は割愛しますが、「[Configuring and Executing Tasks](https://help.sonatype.com/repomanager3/configuration/system-configuration#SystemConfiguration-ConfiguringandExecutingTasks)」の「[Types of Tasks and When to Use Them](https://help.sonatype.com/repomanager3/configuration/system-configuration#SystemConfiguration-TypesofTasksandWhentoUseThem)」内に記載がある・・・

* タスク名：「Maven - Delete SNAPSHOT」
* タスク名：「Maven - Delete unused SNAPSHOT」

をタスクに登録すれば不要なSNAPSHOTバージョンを削除することができます。ただし・・・この段階では論理的に削除しているだけのようで、これらのタスクを登録しただけでは不十分な可能性があります。

# Blob storeのコンパクト化タスク

論理削除したデータを物理削除してBlob store(リポジトリのデータ格納先)をコンパクト化するためのタスクも用意されています。このタスクも登録しておけば、不要なSNAPSHOTバージョンを完璧にお掃除することができます。

* タスク名：「Admin - Compact blob store」

# まとめ

まとめではないですが・・・上記タスクを登録したらNexusが利用するディスク容量が「65G」から「3.5G」になったのでした :sweat_smile:

# 参考サイト

* https://help.sonatype.com/repomanager3/configuration/system-configuration
【UE4】BPノードの定義へ移動ができないときの対処

#はじめに
UnrealEngine4の機能でBPのノードをダブルクリックすると、
そのノードの中身がみることができますが、
C++プロジェクトなのに開かないことがあったのでその対処法を書いておきます。
UE4のバージョン：UE4.22.0を使用しています。
※.slnファイルは生成済みの状態です。

#問題点
このように適当なノードをダブルクリックしても、右下にC++Symbolを読み込み中と出てくるがVisualStudioが開かず、定義をみることができません。
![ブログ用2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/0215a16e-b7c6-5038-ca1f-f95e97abb774.gif)
「定義へ移動」を押しても同じです。
![ブログ用3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/d4f71b5c-e903-b738-e4f2-d7f3cf871dfb.gif)

#解決策
EpicGamesランチャーのEngineオプションから
![スクリーンショット (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/34eeb35b-7e57-0ce9-6cae-b5e386ed2b1f.png)
デバックに必要なエディタシンボルをインストールします。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/f071d1c4-4a4c-83b9-65e9-37eb970292f1.png)

これでダブルクリックするとVisualStudioが開くようになりました！
![ブログ用4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/5b1d0ac7-855d-2c0c-5b39-d55d2cc076e4.gif)

#ここで問題が・・・
Visual Studioが開いたのはいいのですが、コードファイルが見つかりませんとでて、
直接C++の関数にとんでくれませんでした・・・
![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398871/bae34936-bf26-97ff-1baf-d4e69e7462b5.png)
この問題の解決法はわからなかったです・・・
この現象を回避するにはパスをコピーして自力で調べるといった方法しかわからなかったです。
また解決案がわかり次第更新します！

#まとめ
意外と忘れているときが多いと思います。
とくに新しいバージョンをインストールするときに忘れていました。
#参考サイト
https://www.reddit.com/r/unrealengine/comments/9hiukv/help_unreal_engine_crashing/
動的な内容のtwitterシェアボタン作りましょうか。

参照: https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/parameter-reference1

なんかややこしいことやってる人が多いみたい。シンプルですよ。

## 完成形
![a.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13106/5517ea25-466f-7263-716d-8f0707594deb.gif)
![スクリーンショット 2019-04-19 0.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13106/e1e0d502-ea8a-dce9-f8fa-7875410fb965.png)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="pl" dir="ltr">ｃ ｂ ａ <br>ｃ ｂ ａ <br>ｃ ｂ ａ <br>ｃ ｂ ａ <br>ｃ 　ａ <br>ｃ 　　<br> <a href="https://t.co/YwBbLDAWX2">https://t.co/YwBbLDAWX2</a> <a href="https://twitter.com/hashtag/tategaki?src=hash&amp;ref_src=twsrc%5Etfw">#tategaki</a></p>&mdash; あんあん@ 野良犬 (@lovesaemi) <a href="https://twitter.com/lovesaemi/status/1118900921075847174?ref_src=twsrc%5Etfw">2019年4月18日</a></blockquote>


## htmlでボタン表示divとjs読み込み
スクリプト読み込みますー

```html
<div id="tweet-area"><!-- ここにボタンができる--></div>
<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
```

ポイントはasync属性をとること

## js

```javascript
// 任意のタイミングで呼べば狙ったとおりのテキストのボタンつくれる
// 引数増やしていろいろやってもよいですね。
function setTweetButton(text){
  $('#tweet-area').empty(); //既存のボタン消す
  // htmlでスクリプトを読んでるからtwttがエラーなく呼べる
  // オプションは公式よんで。
  twttr.widgets.createShareButton(
    "",
    document.getElementById("tweet-area"),
    {
      size: "large", //ボタンはでかく
      text: text, // 狙ったテキスト
      hashtags: "ハッシュタグ", // ハッシュタグ
      url: "//url" // URL
    }
  );
}
```

ogpタグとかいれてたらurlの表示もきれいにでるのでしょうね。

以上です。
アラームを複数設定できるようにしよう

時間を設定して、設定した時間に通知が行く機能を作っていました。
その中で、AlarmManagerの使い方を残したいと思います。

今回の実装は以下です。

```
val alarm = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(this, AlarmBroadCastReciever::class.java)
intent.putExtra("id", id)
intent.putExtra("title", title)
val pending = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT)

val info = AlarmManager.AlarmClockInfo(calendar.timeInMillis, null)
alarm.setAlarmClock(info, pending)
```

その中でも時間がかかったのが下記です。

```
val pending = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT)
```

####ハマりポイント①：requestCodeの扱い

getBroadCastの第2引数はrequestCodeを設定します。
最初はググったら真っ先に出てくる0を指定しました。
1つのアラームセットなら問題ないですが、複数アラームを設定すると、最新のアラームしか通知されませんでした。

これは、リファレンスにあるように、requestCodeが同じだと、同じPendingIntentとみなされているからでした。

>If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers

今回は違うアラームとして認識させたいので、違うrequestCodeを設定しないといけないというものでした。

####ハマりポイント②：flagsの扱い


第4引数はflagsを設定します。

こちらも同様に0を設定していました。
すると、更新しても通知で表示するtitleが更新されませんでした。

これは、FLAG_UPDATE_CURRENTをフラグに設定していなかったからでした。

こちらもリファレンスに記載がありました。

>Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent

つまりは、同じrequestCodeのPendingIntentが存在する場合、そのPendingIntentをつかうが、**Intentの値は更新する**のが、FLAG_UPDATE_CURRENTです。

上記ハマりポイントを解消することで、思っていた動作をするようになりました。
引数の値が何を表しているのか確認することも大切ですね。

#####参照

リファレンス--  https://developer.android.com/reference/android/app/PendingIntent
エンジニア目指したい新入生のみんなにオススメのエディタ

# はじめに
エンジニア志望の新入生のみんな！入学おめでとう！
やっぴー([@yanashi_masa](https://twitter.com/yanashi_masa))です。
詳細なプロフィールはこちら↓
https://scrapbox.io/yanashi/%E3%82%84%E3%81%A3%E3%81%B4%E3%83%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6


今日はエンジニアを目指して、色々な学校に入学した新入生のみんなにオススメのエディタを教えてあげるぞ！

※当記事は、あくまでも、弊学をベースに話しています。各々の事情で他エディタを使う場合は、以下スルーしても構いません。

# 本題
さて、1年生は様々なエディタを使うかもしれないが、僕は、このエディタをオススメしたい。
それは、





![vim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154610/160e506e-3303-2041-2309-00e0082bca55.png)

Vimだ！異論は認めぬ。

# インストール
- Windowsの場合

詳しくはこちらを参照してほしい→https://qiita.com/go12lim/items/0644f262cff619934e10

- MacOSの場合

Macの場合、もっともお手軽なのが、**Homebrew**を使ってインストールする事だ。
このHomebrewは、かなり重宝するので入れたほうがいい。
まずは、**AppStore**から**Xcode**をインストールする。
次に、Homebrewのインストールコマンドを[ここから](https://brew.sh/index_ja)コピー。
そして、**ターミナル**を開いて、コピーしたコマンドをペーストして実行する。

```
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

これで、Homebrewのインストールが完了した。
続いて、以下のコマンドを実行。

```
$ brew doctor
$ brew update
```

これで、準備が整った。
さぁ、Vimをインストールしてみよう。
以下のコマンドを実行してみよう。

```
$ brew install vim
```

これで、Vimのインストールは完了した。

では、Vimを立ち上げてみよう。以下のコマンドを実行。

```
$ vim
```
問題がなければ、Vimが立ち上がるはずだ。

# もっとも多く使う超重要キーコマンド
とりあえず、めちゃくちゃ使う超基本的コマンドを記載しておく。(異論が出るのはわかるが、~~ちょっとそこのVimmer黙ってて。~~)

`i` : 編集モード。これで、ファイルの編集が出来る。
`v` : ビジュアルモード。ファイルの文字をコピー&ペーストしたり出来る。
`Esc` : ノーマルモードに戻る。

- ノーマルモードでのキーコマンド
`:q` : vimを終了。
`:q!` : vimを強制終了。
`:w` : 編集したファイルを保存。
`:wq` : 編集したファイルを保存し、Vimを終了させる。

- ビジュアルモードでのキーコマンド
`yy` : 選択した文字列をコピー。
`p` : コピーした文をペースト。
`d` : 選択した文を削除。

とりあえず、これだけ覚えれば、Vimはある程度扱える。

# どうしても使えそうにない人たちへの救済措置
最悪、上記のコマンドが使えそうになかったら、
**Visual Studio Code**をインストールして、Vimプラグインを実装する事だ。
しばらくは、それで慣れておいた方がいいかも。

# 【上級者向け】vimrcを作成して、魔改造
vimrcとは、Vimの設定ファイルである。
このファイルを作成する事で、Vimを自分流に改造することができる。


- Windowsの場合

↓Windowsの場合、この記事を参照した方がいいかもしれない↓
https://vim.jp.net/setup_windows_setting.html

- MacOSの場合(以下、Macで説明)

vimrcの作成方法は、以下のコマンドを実行すれば良い。

```
touch ~/.vimrc
```

後は、以下のコマンドでVimを立ち上げて編集する。

```
vim ~/.vimrc
```

とりあえず、以下のように記入して、保存してみよう。

```
vnoremap <C-c> yy
vnoremap <C-p> p
```

ノーマルモードで保存&終了する。

```
:wq
```

もう一度、Vimを立ち上げると、vimrcの設定が反映される。

ちなみに、上記の設定で以下のように変更した。
`Ctrl + c` : 選択した文字列をコピー。
`Ctrl + p` : コピーした文字列をペースト。

詳しいことは、以下の記事を参照してほしい。

・mapとnoremapの違いについて
https://cocopon.me/blog/2013/10/vim-map-noremap/

・キーマッピングで使う表記一覧
http://kannokanno.hatenablog.com/entry/2013/05/05/130219

# Vimを好きになってほしい

最後に。
僕としては、Vimを好きになってほしい。
もう他のエディタなんていらないぜ！という状態にしてほしい。

ちなみに、僕は用途によって、Visual Studio Codeと併用している。
え？Visual Studio Code最強だって？
~~気持ちはわかるが、~~
魔改造して、自分流のエディタにする楽しみは、純粋なVimでしか味わえないよ...

是非、試してほしい。
7日間苦しんだGradleでコンパイルするとDOMA4019エラーになる原因

単純なソースなのにコンパイルできなくてイライラしてたが、結果なんてことのないエラーだった。
二度と起こさないように備忘録。

EclipseのDomaのプラグインで作ったら、ファイルを移さないとエラーになる。

```text: エラー内容
エラー: [DOMA4019] The file "META-INF/doma/sample/dao/TestDao/selectAll.sql" is not found in the classpath. The absolute path is "/Users/harutotanabe/Downloads/sample/build/classes/java/main/META-INF/doma/sample/dao/TestDao/selectAll.sql".
```

▼　サンプルコード

```java:Main処理
@SpringBootApplication
public class SampleApplication {

	public static void main(String[] args) {
		SpringApplication.run(SampleApplication.class, args);
	}

    @Autowired
    TestDao TestDao;

    @Bean
    CommandLineRunner runner() {
    	TestDao.selectAll();
        return null;
       }
 }
```

```java:Entity
@Entity
public class Test {
    public Integer id;
    public String test;
}
```

```java:Dao
@ConfigAutowireable
@Dao
public interface TestDao {

@select 
List<Test> selectAll();
}
```

```gradle:gradle
plugins {
	id 'org.springframework.boot' version '2.1.4.RELEASE'
	id 'java'
}

task copyDomaResources(type: Sync)  {
    from sourceSets.main.resources.srcDirs
    println 'SQLファイルのコピー元'
    println sourceSets.main.resources.srcDirs
    into compileJava.destinationDir
    println 'SQLファイルのコピー先'
    println compileJava.destinationDir
    include 'doma.compile.config'
    include 'META-INF/**/*.sql'
    include 'META-INF/**/*.script'
}

compileJava {
    dependsOn copyDomaResources
    options.encoding = 'UTF-8'
}


apply plugin: 'io.spring.dependency-management'

group = 'doma'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
    mavenCentral()
    mavenLocal()
    maven {url 'https://oss.sonatype.org/content/repositories/snapshots/'}
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	compileOnly 'org.projectlombok:lombok'
	compile group: 'org.seasar.doma.boot', name: 'doma-spring-boot-starter', version: '1.1.1'
	runtimeOnly 'org.postgresql:postgresql'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	annotationProcessor "org.seasar.doma:doma:2.24.0"
    implementation "org.seasar.doma:doma:2.24.0"
}
```

・EclipseのDomaプラグインでエンターだけおしてSQLファイルを作成するとJava配下にできてしまう。

▼　対応前（イメージ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/59ed2358-72f4-afe6-e33c-c8d0efb8cdc3.png)

これだとSQLファイルをコピーできない。コピー元がresourcesだから。。。
よって、META-INFフォルダをresourcesに移せばOK

▼　対応後（イメージ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/561788ad-1996-17a8-0ec2-be50c20fec48.png)
はじめてのC++【41日目】

# はじめに
 `C++20` とか `C++17` とか　どのようにして数字を決めているのかと思っていたが、西暦の数字だったんですね。なぜ11の次が14なのかと思っていたが疑問が解けた。あと、C++の更新って3年ごとなんですね。
## ロベールのC++
### 複数のtemplate
引数が２つのとき、それぞれ違う `typename` を指定しなければならない。
実際にやってみる。

```cpp:同じ型の引数
#include <iostream>

template <typename TYPE>
  TYPE xyz(TYPE x, TYPE y, TYPE z ){
    //std::cout << x + y + z <<std::endl;
    std::cout << x  <<std::endl;
    std::cout << y  <<std::endl;
    std::cout << z  <<std::endl;
  }

int main(){
  double a = 1;
  double b = 2;
  double c = 3;

  xyz(a,b,c);
}
```
```:実行結果
1
2
3
```
では、 `double c` を `int c` にしてみる。

```cpp:コンパイラエラー出る
#include <iostream>

template <typename TYPE>
  TYPE xyz(TYPE x, TYPE y, TYPE z ){
    //std::cout << x + y + z <<std::endl;
    std::cout << x  <<std::endl;
    std::cout << y  <<std::endl;
    std::cout << z  <<std::endl;
  }

int main(){
  double a = 1;
  double b = 2;
  int c = 3; //変更

  xyz(a,b,c);
}
```
```:コンパイルエラー内容
1.cpp: In function 'int main()':
1.cpp:16:12: error: no matching function for call to 'xyz(double&, double&, int&)'
   xyz(a,b,c);
            ^
1.cpp:4:8: note: candidate: template<class TYPE> TYPE xyz(TYPE, TYPE, TYPE)
   TYPE xyz(TYPE x, TYPE y, TYPE z ){
        ^
1.cpp:4:8: note:   template argument deduction/substitution failed:
1.cpp:16:12: note:   deduced conflicting types for parameter 'TYPE' ('double' and 'int')
   xyz(a,b,c);
            ^
```
解決方法

```cpp:解決策
#include <iostream>

template <typename TYPE_X, typename TYPE_Y, typename TYPE_Z> //3つ定義する
  void xyz(TYPE_X x, TYPE_Y y, TYPE_Z z ){
    std::cout << x + z <<std::endl;
    std::cout << x  <<std::endl;
    std::cout << y  <<std::endl;
    std::cout << z  <<std::endl;
  }

int main(){
  double a = 1.5;
  std::string b = "Hello World";
  int c = 3;

  xyz(a,b,c);
}
```
```:実行結果
4.5
1.5
Hello World
3
```
`std::string`　も試してみたが、無事実行できた。これは便利だな。

### templateの仕組み
temolateを宣言しただけでは、関数は作られない。引数を渡して初めて、その引数の型の関数が作られる。 `template` を宣言することを「インスタンス化」、作られた関数を `インスタンス`　という。（クラスみたい）

例えば、 `void xyz(TYPE_X x, TYPE_Y y, TYPE_Z z )`　をいろんな場所で使いたければ、ヘッダファイルを作る必要がある。

```cpp:1.h
#ifndef TEMPLATE_H
#define TEMPLATE_H
#include <iostream>
template <typename TYPE_X, typename TYPE_Y, typename TYPE_Z> //3つ定義する
  void xyz(TYPE_X x, TYPE_Y y, TYPE_Z z ){
    std::cout << x + z <<std::endl;
    std::cout << x  <<std::endl;
    std::cout << y  <<std::endl;
    std::cout << z  <<std::endl;
  }

#endif //#ifndef TEMPLATE_H
```
```cpp:2.cpp
#include "1.h"
#include <iostream>

int main(){
  double a = 1.5;
  std::string b = "Hello World";
  int c = 3;

  xyz(a,b,c);
}
```
なんとなくだけど、テンプレートってかなり便利そう
# 終わりに
明日は投稿できないかも
おやすみなさい。