OmniAICreator/Qiita-1.07M huggingface dataset:
単調増加数 (Ruby-alpha)


|問題|http://nabetani.sakura.ne.jp/hena/orde24tancho/|
|:--|:--|
|Ruby / **AIR-lang** / Python|https://qiita.com/cielavenir/items/6de720c9a12813c5f469|
|Perl / C / Crystal / D / Go|https://qiita.com/cielavenir/items/51f260519b62a3330234|
|**Ruby-alpha**|https://qiita.com/cielavenir/items/9048c60498a9385b25c0|

RubyKaigiの企業ブース(?)がネタ元です
http://tech.misoca.jp/entry/build-the-ruby-from-a-floppy-disk

## ビルド方法
上記URLも参考に…


```
curl ftp://ftp.ruby-lang.org/pub/ruby/1.0/ruby-0.49.tar.gz -LO
tar xf ruby-0.49.tar.gz
cd ruby
curl https://raw.githubusercontent.com/charliesome/historical-rubies/master/ruby-0.49.patch -LO
patch -p1 < ruby-0.49.patch
./configure
make CFLAGS="-Wno-return-type -m32" # clang is ok.
```

## 解答

- 繰り返しの構文が全く違う
- 後置if不可
- next不可
- 3項演算子はif-then-else-endで代用
- stdin/stdoutの明示が必要
- putsは改行を付与しない
- Bignumの除算が怪しいため、追加問題は解けません

```rb:tyama_henae24.rb0
#!/usr/bin/env ruby-alpha
#http://nabetani.sakura.ne.jp/hena/orde24tancho/
#https://qiita.com/Nabetani/items/928d6a94d83c21ef64d7

def comb(n,k)
	r=1
	for i in 0..k-1
		r=r*(n-i)/(i+1)
	end
	r
end

while $stdin.gets
	do a=$_.split(',').collect using e
		e.to_i-1
	end
	b=a[0]
	n=a[1]
	topdigit=1
	while !nil
		#b種類で作れるitopdigit桁の数
		x=comb(b,topdigit)
		if b<topdigit || x>n
			break
		end
		n-=x
		topdigit+=1
	end
	if b<topdigit
		$stdout.print("-\n")
	else
		topdigit-=1
		curnumber=0
		d=topdigit
		do topdigit.downto(0) using d
			curnumber+=1
			while !nil
				#b-curnumber種類の数で作れるd桁の数
				x=comb(b-curnumber,d)
				if x>n
					break
				end
				n-=x
				curnumber+=1
			end
			$stdout.print((curnumber+(if curnumber < 10 then 48 else 87 end)).chr)
		end
		$stdout.print("\n")
	end
	$stdout.flush
end
```
Firebase Analyticsイベントのデバッグ

##FirebaseAnalyticsのイベントをデバッグする
FirebaseAnalyticsのイベントは約１時間毎にバッチ処理にてサーバーに送信されます。
これは、端末のバッテリーやデータ使用量を抑えるための仕組みですが、リアルタイムでイベントが送信されないとデバッグできません。
このため、以下のコマンドをターミナルから実行します。

```
adb shell setprop debug.firebase.analytics.app アプリのパッケージ名
```
これにより、ほぼリアルタイムでイベントをサーバーに送信することができます。

以下のようにFirebaseConsoleのDebugViewにてイベントを確認することができるようになります。
<img width="400" alt="スクリーンショット 2018-05-31 0.25.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/46743/0b9ffc39-a8b7-95fb-6596-50c84180bb38.png">

##LogEventのサンプルCode

```kotlin
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                message.setText(R.string.title_home)
                trackingEvent(getString(R.string.title_home))
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_dashboard -> {
                message.setText(R.string.title_dashboard)
                trackingEvent(getString(R.string.title_dashboard))
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_notifications -> {
                message.setText(R.string.title_notifications)
                trackingEvent(getString(R.string.title_notifications))
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }
    
    private fun trackingEvent(name: String) {
        firebaseAnalytics?.logEvent(name,　null)
    }
```

##　参考
https://firebase.google.com/docs/analytics/debugview?authuser=2
ノートPCにUbuntu-17.10.1をインストールした

この前安価でDellのノートPCを買ったため、せっかくなのでLinux専用機にしてみたいと思い、
USBを使用してUbuntuを入れてみました。
その際の手順を書いておきます。

私でも出来たのでこの手順でやれば誰でもインストール出来るんじゃないかと思います。


# 必要なもの
・USB(4GB以上あれば良いと思います)
・PC(起動用USBを作る際とUbuntuをインストールする際に使用）

# 起動用のUSBを作る
１.まず起動用USBとして使うUSBをPC本体に差し込んだ後、
以下のURLにアクセスし、Ubuntu17.10.1日本語RemixのISOイメージを
PC上にダウンロードする。
https://www.ubuntulinux.jp/news/ubuntu1710-ja-remix

2.起動用USBメモリ作成ツール「Etcher」をダウンロードするため、
以下のURLにアクセスし表示されている「Download for Windows x64」をクリックする
https://etcher.io/

3.ダウンロードしたEtcherのファイルをダブルクリックして開くと
インストーラーが起動するので、ライセンス承諾の画面では「同意する」をクリックする。

4.インストールが完了すると自動でEtcherが起動するので、「Select Image」をクリックする。

5.イメージファイルの選択画面が表示されるので、手順1.でダウンロードしたISOのイメージを
選択します。

6.　1.で差し込んだUSBが表示されている事を確認し[Flash!]ボタンをクリックする。
※変更許可を求めるメッセージが上がってきたら「はい」をクリックしてください。

7. 作成作業が開始されるのでしばらく待つ...
   しばらく待って「Flash Complete!」のメッセージが表示されれば起動用USBメモリが完成です。


# ブートメニューから起動する
1.起動用USBメモリをPCに差し込んだ後、PCの電源を投入する。

2.投入してF12を連打するとブートオプションメニューが出てくるので、
　PCに差し込んだUSBを選択した状態でEnterキーを押す。
※ブート画面の出し方はPCの機種によって違うので、出し方が不明な場合は
　ググってみてください（すぐに分かると思います）

3.Ubuntuのインストール画面が出てくるので「Install Ubuntu」を選択しEnterキーを押す。


これでUbuntuのインストールは完了です。
何か不足点やこうした方がもっと効率的！みたいなのがあればコメントしていただけると嬉しいです。
WSL (Windows Subsystem for Linux) に仮想開発環境(anyenv)を構築する

# 概要

Windows10 には、Windows Subsystem for Linux (以後、WSL)を使うことで VMWare、VirtualBox、HyperVなどの仮想環境上にLinuxを構築しなくてもLinux 環境が利用できるようになりました。

python、ruby、nodejsなどはバージョンを切替えて実行可能な環境を構築できる ***envというツールがありますが、Linux, Mac などのunix環境でしか利用できませんでした (anaconda や nodist など Windows 環境でも利用可能なものももちらんありました)。

本ドキュメントでは、この WSL 環境に複数の仮想環境をまとめて管理できる [anyenv](https://github.com/riywo/anyenv) を使って Ruby、nodejsなどの複数開発環境をセットアップする手順について記載します。


# 前提

Windows10 に WindowsSubsystemForLinux (Ubuntu) がセットアップされていること。
WSL上の Bash を起動し以下のコマンドを実行すること。


# 事前準備

git をインストールします(インストールしている場合はスキップしてください)。

```bash
$$ sudo apt-get update
$$ sudo apt-get install git
```

# Install anyenv

gitを使って home 直下に anyenv をインストールします。

```bash
$$ git clone https://github.com/riywo/anyenv ~/.anyenv
```

Bash 起動時、anyenv が実行できるように環境変数を設定します。

```bash
$$ vi ~/.bashrc (エディッタなら何でも OKです)
最後の行に以下を追加

# anyenv setting
export PATH=${PATH}:${HOME}/.anyenv/bin
eval "$(anyenv init -)"
```
最後に Bash を再起動すると anyenv が実行できる状態になります。
動作確認のために以下のようにコマンドを実行し、ヘルプメッセージを表示することを確認します。

```bash
$$ anyenv --help
```

# Setup nodenv

anyenvでは、ruby、pythonなどいろいろな言語の仮想環境を管理できますが、ここでは nodejsの仮想環境 nodenv をセットアップしたいと思います。他の言語も基本的には同じ流れでセットアップできると思います。
セットアップは以下のコマンドを実行するだけです。

```bash
$$ anyenv install nodenv

<インストールバージョンの確認 (nodenv とバージョンが表示される)>
$$ anyenv versions
```

インストールされた nodenvを使って、特定のバージョンの nodejs をインストールしてみます。

```bash
<インストール可能なバージョン一覧を取得>
$$ nodenv install -l

<10.1.0 の仮想環境を構築する>
$$ nodenv install 10.1.0

<10.1.0 を通常使用する環境に設定する>
$$ nodenv global 10.1.0

<nodejs の動作を確認する>
$$ node --version
```

# nodenv の簡単な使い方


```bash
<インストール可能なバージョン一覧を取得する>
$$ nodenv install -l

<デフォルト versionを変更する>
$$ nodenv install <version>
$$ nodenv global <version>

<特定の開発環境だけバージョンを変更する>
$$ cd <特定の開発環境の root path>
$$ nodeenv install <version>    <-- インストール済なら skip
$$ nodeenv local <version>
```
VBAでWindowsAPIを使って、バイト配列を Base64変換

Base64の変換アルゴリズムは割とシンプルでオウンコーディングできる程度のものですが、実はWindows APIが　その機能を提供しています。
VBAで、これを使って、バイト配列をBase64に変換して文字列型変数に格納する方法を記します。

```vb:主となる関数
Private Declare PtrSafe Function CryptBinaryToString Lib "Crypt32.dll" Alias "CryptBinaryToStringW" ( _
    ByVal pbBinary As LongPtr, _
    ByVal cbBinary As Long, _
    ByVal dwFlags As Long, _
    ByVal pszString As LongPtr, _
    ByVal pcchString As LongPtr _
    ) As Long

Private Const CRYPT_STRING_BASE64 As Long = &H1&

'バイト配列をBASE64でエンコードしたUnicode文字列にする関数
'この関数にバイト配列を渡す際に、UTF-8変換したバイト配列を渡すのか
'SJIS変換したバイト配列を渡すのか、UTF16変換(無変換)したバイト配列を渡すのかで
'当然ながら出力される文字列が変わってきます。
Public Function CryptBytesToString(ByRef bData() As Byte) As String
    Dim pbBinary As LongPtr
    Dim cbBinary As Long
    If UBound(bData) = -1 Then
        Exit Function
    End If
    
    'バイト配列の先頭アドレス　と　長さを取得
    pbBinary = VarPtr(bData(0))
    cbBinary = UBound(bData) - LBound(bData) + 1
    
    Dim nBufferSize As Long
    '変換後文字列の長さを取得し、変換後文字列を格納するだけのバッファを用意
    If CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, _
                                0, VarPtr(nBufferSize)) Then
        CryptBytesToString = String(nBufferSize, vbNullChar)
        '必要な長さ分用意した空文字列バッファの先頭アドレス(StrPtr)から変換結果で上書き
        If CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, _
                                StrPtr(CryptBytesToString), VarPtr(nBufferSize)) Then
        End If
    End If
End Function
```

以下がテストコードです。
wikipediaのBase64の項目に載っている"ABCDEFG"を変換してみます。
wikipediaの変換結果は、ASCII文字列あるいはSJISとしてみた場合の"ABCDEFG"の変換結果です。
VBの"ABCDEFG"はUNICODE文字列ですので、Aは 0x41 ではなく、 0x41 0x00 という２バイトなので、このままいくと、Base64変換結果は wikipediaに載っているものと異なります。
以下のテストコードでは、これを避けるために、いったんSJISに変換して得られたバイト配列をBase64に変換しています。

```vb:テストコード
'上のコードの下に続けて、以下のコードを書いてください。
'Unicode文字列をSJISとみなして、Base64に変換する関数
Public Function String_To_SJIS_To_Base64_String(ByVal sValue As String) As String
    If Len(sValue) = 0 Then
        Exit Function
    End If
    
    Dim bSjis() As Byte
    'Unicode文字列をSJISのバイト配列にいったん変換
    bSjis = StrConv(sValue, vbFromUnicode)
    'SJISのバイト配列からBase64に変換
    String_To_SJIS_To_Base64_String = CryptBytesToString(bSjis)
End Function

'テストコード
Sub Main()
    Debug.Print String_To_SJIS_To_Base64_String("あ")
    Debug.Print String_To_SJIS_To_Base64_String("ABCDEFG")

End Sub

```
実行結果は以下の通りです。

```
gqA=
 
QUJDREVGRw==
```
【自己ノート】Docker

# Docker-compose
#### Build:
```
docker-compose up --build
```

#### Stop:
```
docker-compose stop
```

#### Container status
```
docker ps
docker ps -a
```
#### Remove Container
```
docker rm {container id|name}
docker rm -f
```

#### Check images
```
docker images -a
```
#### Remove image
```
docker rmi {image id|tag|name}
docker rmi $(docker images -a)
```
日付と時刻を分けて比較してはダメ

# はじめに
改善作業でテストをしていたところ、エラーになるべきところがすり抜けてしまった。
要件としては、処理を実行した際に登録したテーブルデータが、別テーブルデータより後で登録されている必要があり、それ以外ならエラーとするというもの。

後で登録されているかは更新日時を抽出条件とする。

# 原因
各テーブルの更新日時は、varchar2型で更新日付(yyyyMMdd)と更新時間(HHmmss)と分けた設計がされている。※改修作業なので文句は言えぬ。

以下のように日付と時刻をそれぞれ分けて比較していたため、翌日の午前中に処理を実行したことでUPDATE_TIMEの値が条件を満たさずエラーにならなかった。

```sql:例
-- TESTデータ
UPDATE_DATE:20180530 
UPDATE_TIME:103015
 
-- 抽出SQL
SELECT * FROM TEST
WHERE UPDATE_DATE >= '20180529' AND UPDATE_TIME >= '172010'
```

# 対応
日付と時刻を結合した上で比較するようにした。

```sql:例
SELECT * FROM TEST
WHERE UPDATE_DATE || UPDATE_TIME >= '20180529' || '172010'
```

# インデックスを効くようにする
【2019/02/27追記】
現在、OracleからPostgreSQLに移行作業中で性能検証をしている。
あるアプリケーションで大量データのテーブルに日時を条件にして抽出する処理があるが、PostgreSQLでは遅いことが分かった。
Oracleでは日時をダブルパイプ結合したインデックスを作成しており、これが効いているため速度上は問題がなかった。

試行錯誤した結果、UPDATE_DATEのみのインデックスを作成し、BETWEENの条件を追加することでインデックスが効くようになった。

```sql:例
SELECT * FROM TEST
WHERE 
UPDATE_DATE || UPDATE_TIME >  '20190218141435' AND
UPDATE_DATE || UPDATE_TIME <= '20190219141435' AND
UPDATE_DATE BETWEEN '20190218' AND '20190219'
```

## PostgreSQL専用なら行値式
以前もらったコメントでこのような場合には行値式が使えることが分かりました。
UPDATE_DATEとUPDATE_TIMEでインデックスを作成すれば、インデックスが効くようになります。

```sql:例
SELECT * FROM TEST
WHERE 
(UPDATE_DATE, UPDATE_TIME) >  ('20190218','141435') AND
(UPDATE_DATE, UPDATE_TIME) <= ('20190219','141435')
```

Oracle でも行値式を使用できるのですが等価(=、!=、IN演算子)のみで、> や <= といった範囲条件演算子は使用できません。よって、「ORA-01796: リストではこの演算子は使用できません。」のエラーになってしまいます。

SQLServerは未だに行値式をサポートしていません。

# 最後に
別問題で悩んでいたためテスト作業を中途半端に残した状態で、翌日にテスト作業をしたことで見つかった。
そのままやっていたら、気がつかないままテスト完了しリリース後にバグの報告を受けていたかもしれない。

そもそもコーディングレビューすれば指摘された可能性もある、一人作業なので甘い部分があった。
こんなことにコーディング時に気が付かなくなっているようではダメなんだよね。
日付跨いだテスト項目を入れてないとダメだったかもと反省ばかり。
XdomainのWordpressでドメイン変更

お名前.comでドメインを取得し、XdomainのWordpressに反映させようとして手こずったのでメモしときます。

基本的には下記サイトを参考にしました。
[XdomainでWordPressのアドレスを独自ドメインに移行する方法](http://www.inmyroom.club/archives/1006#i)

詰まったところとしては「earch and Replace for WordPress Databases Script」がエラーになってしまって動かず、１週間くらい四苦八苦していました。
最終的にはエクスポートしたsqlファイルを手動で書き換えていくという作業をして解決しました。
tomcatのcors設定に手こずった件

# 経緯
先日学校課題をReactを用いてAPIサーバとして作成していました。
学校としてはJavaを使用した課題だったため、やむを得なくServletとTomcatを用い制作していましたがFetchでクッキー等を扱った受け渡し処理をする盛大にハマって4日間ぐらい座学を挟んだので纏めておこうと思います。

# なぜハマったのか

![スクリーンショット (73).png](https://qiita-image-store.s3.amazonaws.com/0/199120/a1dd60bc-2caf-9366-bdb6-8eb2b84a1c9a.png)

このような形で、やり取りを試みたわけですがFetchAPIを検索し__credentials__が自分の頭では理解ができなかったのでハマってしまいました。


# そもそもCORSって？
[オリジン間リソース共有 (CORS) - __MDN web docs__](https://developer.mozilla.org/ja/docs/Web/HTTP/HTTP_access_control)
[CORS(Cross-Origin Resource Sharing)について整理してみた - __Developers.IO__](https://dev.classmethod.jp/etc/about-cors/)
[Cross-Origin Resource Sharing(CORS)を使用したHTTPリクエスト](https://blog.kazu69.net/2017/03/23/http-request-using-cors/)

こいった座学は得意じゃないのです。

> 同一生成元ポリシーをあえて無視する以上、悪意を持った第三者からの攻撃を受けるリスクが高くなる可能性があります。
> こうした状況の中で、より手軽に、より安全にクロスドメインアクセスを実現したいという要求に応えるために作られたのがCORSです。
> Developers.IO

詰まる話セキリュティ的にマズいのであえて制限をかけ、一部開放する形にしているらしいです。

HTTPプロトコルの__ヘッダー情報を書き換える__必要があるらしいです。

# 実践編　Tomcatを許可しよう。

## サーバー側

```java:FillterServlet.java
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest req = (HttpServletRequest) request;
	HttpServletResponse res = (HttpServletResponse) response;
	// 許可したいドメインの追加
	res.setHeader("Access-Control-Allow-Origin", "http://192.168.44.55:3000");
	// 認証情報やCookieのやりとりをする際にはCredentialsをTrueにする必要がある。
	res.setHeader("Access-Control-Allow-Credentials","true");
	// 実行可能なHTTPメソッドの追記
0	res.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, OPTIONS");
	// よくわからないけど追記
	res.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers"));
}
```

__注意点__
Fillterに記述するように書きましたが、本来はServletに記載すべき項目です。（HttpServletRequest,Responseのため）


## クライアント側

``` javascript:ajax.js
fetch(
  "URL",{
    // クロスドメインのため、modeをcorsに設定
    mode:'cors',
    // セッションなどを保持する
    credentials: "include"
    }
 }
)
```
### credentialsの設定項目
 - mit：決してクッキーを送信しない。
 - same-origin：URL が呼び出し元のスクリプトと同一オリジンだった場合のみ、クッキーを送信する。
 - include：クロスオリジンの呼び出しであっても、常にクッキーを送信する。

今回したい事は__include__による実装です。

## ここでハマりポイント

自分のしていた設定

```java:FillterServlet.java
res.setHeader("Access-Control-Allow-Origin", "*");

```

エラーログで流れますがワイルドカードは選択するとfetch側で弾かれます。
尚且つ
`res.setHeader("Access-Control-Allow-Credentials","true");`
を設定しておらず、永遠とクッキーが取得できないまま悶々としていましたが、こういったしょうもない部分でハマりますので座学はやっぱり結構大事だなと思いました。
javascriptで継続をつかってPromiseもどきを作ってみたかった

[Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)風のものをHaskellで学んだ[継続モナド](http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Cont.html)を生かしてつくってみたかった。

# 経緯
Promiseの実装が気になって[polyfillのコード](https://github.com/stefanpenner/es6-promise/)をよみました。

ざっくり読んだだけですが、
callbackの実行状態をステータス管理して、
処理が終わるまでsetTimeoutとかを使って待つような作りになっていて
以外に美しくない実装なのだなぁと思ってました。

そこで継続の概念をつかって、もっとシンプルにPromise風のものが作れないかやってみました。

目指すのは、callbackのメソッドチェーン化です。

# 定義
```javascript
class Cont{
    constructor(fn){
        this.runCont = k => fn(x => k(x));
    }
    then(fn){
        const run = this.runCont;
        this.runCont = k => run(a => {
            fn(a,x => k(x));
        });
        return this;
    }
}
```
# 実行
```javascript
new Cont((resolve) => {
    console.log("constructor:before");
    resolve(7);
    console.log("constructor:after");
}).then((a,resolve) => {
    console.log("then1:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve1:before");
        resolve(a+1);
        console.log("resolve1:after");
    }, 300);
    console.log("then1:after");
}).then((a,resolve) => {
    console.log("then2:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve2:before");
        resolve(a+1);
        console.log("resolve2:after");
    }, 200);
    console.log("then2:after");
}).then((a,resolve) => {
    console.log("then3:before");
    console.log("a = " + a);
    setTimeout(function() {
        console.log("resolve3:before");
        resolve(a+1);
        console.log("resolve3:after");
    }, 100);
    console.log("then3:after");
}).runCont(a => {
    console.log("runCont："+a);
});

```
resolveが次のthenの関数を実行してくれます。

##結果
```
constructor:before
then1:before
a = 7
then1:after
constructor:after
resolve1:before
then2:before
a = 8
then2:after
resolve1:after
resolve2:before
then3:before
a = 9
then3:after
resolve2:after
resolve3:before
runCont：10
resolve3:after
```
思ったとおりの順番で実行できてます。
うまくcallbackをメソッドチェーンで記述できているような気がします。

#感想
やりたいことがシンプルに実装できたと思います。

しかし、エラー処理とか、メモリリークとか、処理速度とか、使いやすさとか、
色々考えていくとこの実装では限界があるでしょうか？

そもそもPromiseがよくわかっていない気もしてきました。

今回の実装をもとに、もうちょっと作り込んで問題点を探っていきたいと思います。
いろいろご指摘いただけるとありがたいです。
DeepLearning 用 GPU 環境構築 (python framework 環境整備編)

## 前提
- Python 環境として Anaconda を使う
- [CUDA 関連のインストール](https://qiita.com/kattoyoshi/items/494238793824f25fa489)は完了している

## 構築するもの
- tensolflow 1.8 + gpu用仮想環境
- pytorch 0.4.0　+ gpu用仮想環境

両方の環境に一般的に機械学習で使うであろうパッケージも追加

【備考】: 
末尾に tensorflow 1.4 -> 1.5 にアップグレードした際の方法メモあり
末尾に tensorflow 1.5 -> 1.6 にアップグレードした際の方法メモあり

## Tensolflow 環境

作った環境と使用した conda コマンド

    conda create -n tensorflow-gpu python=3.6
    activate tensorflow-gpu
    conda install pandas matplotlib jupyter notebook scipy scikit-learn scikit-image h5py seaborn
    pip install opencv-python
    pip install tensorflow-gpu

- バージョン指定する場合は tensorflow-gpu==1.4 のように書く
- h5py は tf.Keras でチェックポイントを書き出す際に必要とされるライブラリ

動作チェック

- tensorflow は公式インストールガイドに記載された以下のコマンドでチェック(IPythonか何かを起動して実行してください)
- エラーが起きず、Session コマンド で gpu の情報が出力されればOK

```python
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
```

## pytorch 環境
pytorc のみのインストール手順は[公式ホームページ](https://pytorch.org/)にて説明があるので, バージョンが異なる場合はそちらを参照してください.

作った環境と使用した conda コマンド

    conda create -n pytorch python=3.6
    activate pytorch
    conda install pandas matplotlib jupyter notebook scipy scikit-learn scikit-image seaborn
    pip install opencv-python

    conda install pytorch cuda90 -c pytorch
    pip install torchvision

動作チェック

- 以下のコマンドで Ture が戻ってくればOK

```python
import torch;
print(torch.cuda.is_available())
```

## Appendix
【tensorflow 1.4 -> 1.5 の変更】  
tensolflow が 1.5 にバージョンアップしたので cuda 8.0, cuDNN v6 を cuda 9.0, cuDNN v7 を入れなおして
tensolflow の仮想環境で

    pip install -U tensorflow-gpu

を実行することで, 無事に tensorflow 1.5.0 がインストールされて gpu も認識された.   

【tensorflow 1.5 -> 1.6 の変更】  
tensolflow が 1.6 にバージョンアップした.  
tensofboard のパッケージ名が変更されているので、以下の順でアップグレードする必要がある.  

    pip uninstall tensorflow-tensofboard
    pip install -U tensorflow-gpu
Fortran環境を構築！Intel(R) Parallel Studio XE 2018 for Linuxを使おう！

# Fortran環境を構築
研究でFortranを使用したシミュレーションの解析を行うことになった．そのため，Fortranの環境構築の手順を記録に残す．Fortranの導入にあたって使用した環境は以下のとおりである，
・OS：ubuntu 18.04
・コンパイラ：Intel(R) Parallel Studio XE 2018 for Linux
Intel(R) Parallel Studio XE 2018 for Linuxは，学生であると非商用に限り，無料かつ期間制限なしで使うことができる．これには，FortranとC++の両方のコンパイラを含んでいる．
Linuxのコマンドで，Fortranの場合はifort，C++の場合はiccとうつことでコンパイルできる．それでは，Intel(R) Parallel Studio XE 2018 for Linuxの導入について説明していく．
(コンパイラはほかにもgfortranなどがあるが，Intel製だと安心感がある気がする．)

# ダウンロード
無料の非商用版のダウンロードページにアクセスする必要がある．
　まず，[Intelの日本語サイト](https://www.intel.co.jp/content/www/jp/ja/homepage.html)をアクセスする．下記に手順を画像で示す．
![1.png](https://qiita-image-store.s3.amazonaws.com/0/212276/e3c84eae-2932-0caa-fe82-02d210f2dff6.png)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/212276/b7aaebcd-c096-a563-0fbd-924fbf0481de.png)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/212276/b533bb3f-6fc5-80ae-35a6-9775357a7a2a.png)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/212276/192565d1-6382-8254-0dea-9b903a3452ce.png)
![5.png](https://qiita-image-store.s3.amazonaws.com/0/212276/c7b31d8e-cffd-8baa-8ade-886885f5b61b.png)
![6.png](https://qiita-image-store.s3.amazonaws.com/0/212276/f1237a7c-f7fe-724b-ef1a-a5949d336358.png)
![7.png](https://qiita-image-store.s3.amazonaws.com/0/212276/24dde349-809c-645e-9cc6-a1673cb07581.png)
![8.png](https://qiita-image-store.s3.amazonaws.com/0/212276/b17bbcba-cd9c-311a-77d9-d2190a4740b4.png)
![9.png](https://qiita-image-store.s3.amazonaws.com/0/212276/cb23ea80-b0a2-907c-68c1-f27c487cd9ba.png)

このように手順を踏み，登録を終える．そして，登録したメールアドレスにシリアル番号が添付されたメールが届く．そのシリアル番号はインストールの際に必要となる．その後，製品のダウンロードページに自動で移動する。そのダウンロードページでは，CPUアーキテクチャ別にファイルが分かれているので，適切なものをダウンロードする。

# インストール
　ダウンロードしたファイルを任意のディレクトリに置き，展開する．展開には，以下のコマンドを入力する．
$ tar xvzf [ダウンロードしたフォルダ名].tar.gz
コマンド「tar xvzf」は圧縮フォルダを展開して解凍することを意味している．
展開後のそのダウンロードしたフォルダ名でディレクトリが新規作成される．次に，そのディレクトリに移動する．

```
$ cd ディレクトリ名
```

その後，root権限でインストールスクリプトを実行する．
$ sudo ./install.sh
これで，インストールが始まるので，表示される手順通りインストールを進めていく．インストール直後にコンパイラを利用することができない．そのため，利用する前に設定スクリプトを実行する必要がある．つまり「.bashrc」に次の一行を加える．

```
source /opt/intel/compilers_and_libraries_2018.2.199/linux/bin/compilervars.sh intel64
```

上記のディレクトリは導入するバージョンによって異なる可能性があるので，「ompilervars.sh」のファイルがあるディレクトリを探し，記述する必要がある．
「.barshrc」に記述するコマンドを下記に示す．これはエディタを起動するコマンドである．

```
$ gedit ~/.bashrc
```

エディタが立ち上がれば，その最終行に先ほど述べた一行を書き込み，保存して閉じる．そして，下記のコマンドをうつ．

```
$ source ~/.bashrc
```

![16.png](https://qiita-image-store.s3.amazonaws.com/0/212276/c1cbb55a-1d0c-d941-1278-fd32ecc37d72.png)



書き込みが終われば，一度，ウィンドウを閉じ再起動する．そして，

```
$ ifort -v
```

とコマンドをうち，ifortのバージョンが表示されればインストール完了である．

![18.png](https://qiita-image-store.s3.amazonaws.com/0/212276/d3b1ecb2-864b-a065-edd3-d69defb865da.png)
アロー関数は this も arguments も持たない

ES6になって、アロー関数が導入されて 「いちいち function hoge() なんて書かなくていいんだ！」と単純に思っていました。
が、違うんですね。アロー関数はこれまでの関数と == ではないと気づいたのでメモ。
# 違いその１ -- アロー関数は this を持ちません
まずは普通の関数で書いた場合です。結果はエラーになります。  ※ strict モードのときです。
なぜなら、forEach　は this = undefined で関数を実行するからです。
```javascript
let kudamono = {
  title: "Fruits",
  fruits: ["Banana", "Apple", "Orange"],
  show() {
    this.fruits.forEach(function(fruit) {
      console.log(this.title + ': ' + fruit)
    });
  }
};
kudamono.show();
// Uncaught TypeError: Cannot read property 'title' of undefined
```
アロー関数の場合はどうでしょう。
```javascript
let kudamono = {
  title: "Fruits",
  fruits: ["Banana", "Apple", "Orange"],
  show() {
    this.fruits.forEach(
      fruit => console.log(this.title + ': ' + fruit)
    );
  }
};
kudamono.show();
// Fruits: Banana
// Fruits: Apple
// Fruits: Orange
```
こっちは上手くいきます。アロー関数は this を持っていないので、その外側の this（=この例だと kudamono ですね）になります。
# 違いその２ -- アロー関数は arguments を持ちません 
こっちはOKパターンから。通常の function で定義した場合は arguments をもっているので上手く動きます。
```javascript
function hoge(a, b, c) {
  for (let i of arguments) {
    console.log(i);
  }
} 
hoge(1, 2, 3);
// 1
// 2
// 3
```
一方、アロー関数の場合は arguments を持ちません。のでエラーになります。
```javascript
var foo = (a, b, c) => {
  for (let i of arguments) {
    console.log(i);
  }
} 
foo(1, 2, 3);
// Uncaught ReferenceError: arguments is not defined
```
# 結局何が便利？
だからなに？ と思いますが便利なときがあります。
それは、this, arguments を使って別の関数を呼び出すような場合です。
```javascript
function defer(f) {
  this.word = "World";
  return function() {
    setTimeout(() => f.apply(this, arguments), 1000)
  };
}
function hello(arg1) {
  console.log(`Hello ${this.word} ${arg1}!`);
}
let h = defer(hello);
h("Doraemon"); 
// Hello World Doraemon!
```
アロー関数なので、this も arguments も持ちません。
なので、setTimeout で実行される処理は、その外側の this, arguments が使われるので 「Hello World Doraemon!」 となります。
通常の関数で同じことをしようとすると、 this を束縛したり、 function() に引数の設定をしたりが必要になります。
難しいですが、要はアロー関数は、「自分ではコンテキストを持っていない」という点がポイントかと思っています。
今のコンテキストで、ある固まった処理がしたい、というときに便利なんですかね。
Pythonで転置行列を求める

##転置行列とは
線形代数で行列の転置行列を求めることがあります。勉強のためpythonのリストを使い計算してみます。自分の復習のため転置行列についてまとめます。

```math
X =
\begin{bmatrix}
11 & 12 & 13 & 14\\
21 & 22 & 23 & 24\\
31 & 32 & 33 & 34 \\
\end{bmatrix}
```
とした場合、転置行列は次のとおりです。

```math
 X^{\mathrm{T}}＝

\begin{bmatrix}
11 & 21 & 31\\
12 & 22 & 32 \\
13 & 23 & 33 \\
14 & 24 & 34 \\
\end{bmatrix}

```

要は、行の要素を列の要素に置き換えるわけです。
##リストを使った行列の考え方
Pythonでは行列は次のように2次元リストで表現することができます。つまり行単位にリストを作成し、そのリストをさらに外枠のリストに入れ込むわけです。

```
matrix = [
    [11, 12, 13, 14],
    [21, 22, 23, 24],
    [31, 32, 33, 34]
]
```
このため転置行列を求めるためには、1行目のリストから最後の行のリストまでの各行につき0番目（1列目）の要素を取り出してリストを作成し、次に1番目（2列目）、2番目（3列目）、3番目（４列目）と繰り返します。最後に、それぞれのリストをさらに外枠のリストに入れ込めばよいわけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/785fa28c-ead6-da86-04c3-2aea854a003f.png)

##2次元リストの処理
そこで、まず2次元リストの基本的な処理をまとめてみます。2次元リストの中の行（ここではvextorとします）を取り出すには、通常のfor文で回すだけです。

```python3:program1
"""
行列（二次元リスト）から要素（行）を取り出す
"""
matrix = [
    [11, 12, 13, 14],
    [21, 22, 23, 24],
    [31, 32, 33, 34]
]
for vector in matrix:
    print (vector)
```
このように、あっけなくできてしまいます。

```
[11, 12, 13, 14] [21, 22, 23, 24] [31, 32, 33, 34]
```
次に、ここで取り出した0番目（1行目）のリスト：vector_1（[11, 12, 13, 14]）に対し、0番目（1列目）の要素を取り出すために、[ ]を使います。

```python3:program2
"""
行列の0番目（1列目）の要素を取り出す
"""
vector_1 = [11, 12, 13, 14]
print(vector_1[0])
```
結果は11になります。

そして、転置行列を計算するためには、行列：matrixの0番目（1列目）からはじまり各列について、各行のその列にあてはまる要素を取り出してリストを作ればよいことになります。したがって、転置行列の初めの行を求めるプログラムは次のとおりになります。

```python3:program3
"""
行列（2次元リスト）から各行の初めの要素を取り出してリストにする
"""
matrix = [
    [11, 12, 13, 14],
    [21, 22, 23, 24],
    [31, 32, 33, 34]
]
tr=[]
for vector in matrix:
    tr.append (vector[0])
print(tr)
```
結果は次のとおりです。

```
[11, 21, 31]
```
##転置行列の作成
この例の場合には、元の行列（matrix）は4つの列があるので、program3のvector[0]を変数に置き換えた上で、for文を4回繰り返し、それぞれ求めたリストをさらに外枠の2次元リストに組み込めば完成です。

```python3:program4
"""
for文で転置行列を作成する
"""
matrix = [
    [11, 12, 13, 14],
    [21, 22, 23, 24],
    [31, 32, 33, 34]
]
tr = []
for i in range(4):
    tr_row = []
    for vector in matrix:
        tr_row.append(vector[i])
    tr.append(tr_row)    
print(tr)

```

結果は次のとおりです。

```
[[11, 21, 31], [12, 22, 32], [13, 23, 33], [14, 24, 34]]
```
上手くできました。

##NumPyを使い転置行列を作成する
もっとも、pythonのパッケージNumPyには、転置行列を計算するtメソッドがあります。

```python3:program5
"""
NumPyを使い転置行列を作成する
"""
import numpy as np
matrix = [
    [11, 12, 13, 14],
    [21, 22, 23, 24],
    [31, 32, 33, 34]
]
matrix_n = np.array(matrix)
tr = matrix_n.T
print(tr)
```
結果は次のとおりです。

```
[[11 21 31]
 [12 22 32]
 [13 23 33]
 [14 24 34]]
```
でも、これではリスト操作の勉強にはなりません。今度はリスト内包表記なども使ってやってみたいと思います。
PostgreSQLのCREATE VIEWで"*"を指定していても後で追加された項目は反映されない

タイトル通りでオチも何も無いなのですが、自分は勘違いしてしまっていたのでメモとして。

調べた所、[公式ドキュメント](https://www.postgresql.jp/document/9.6/html/sql-createview.html)に下記の記載がありました。

> 
```
CREATE VIEW comedies AS
    SELECT *
    FROM films
    WHERE kind = 'Comedy';
```
これはビューを作成した時点でfilmテーブル内にある列を持つビューを作成します。 ビューを作成するために*が使用されていますが、その後にテーブルに追加された列はビューには含まれません。

自動的に追従してくれると思っていたのですが、Viewを再生成する必要があるようです。
SAN値論理

# はじめに?

タイトル落ちです。
偶然タイトルを思いついてしまったので、勢いで記事にしてしまいました。

## `bool?`型の論理演算ってどうなるの?

C#で`bool?`型への論理演算はどうなるのかを試してみましょう。

- `!A` _(NOT)_
- `A&B` _(AND)_
- `A|B` _(OR)_
- `A^B` _(XOR)_

試す論理演算は上記の通りです。
_言語仕様に含意が無いのが残念(わがまま)_

## コード?

ネタ記事ですが、コードくらいは載せましょう……

```csharp:試したコード
class SanValueBoolean {
    public void Do() {
        var bools = new bool?[] { true, false, null };
        foreach (var b in bools) {
            LogicalNot(b);
        }
        var pairs = from b1 in bools from b2 in bools select (b1, b2);
        foreach (var (b1, b2) in pairs) {
            LogicalOperation(b1, b2);
        }
    }

    /// <summary>AND,OR,XOR</summary>
    void LogicalOperation(bool? left, bool? right) {
        Console.WriteLine($"{left.ToDisp()}\t& {right.ToDisp()}\t= {(left & right).ToDisp()}");
        Console.WriteLine($"{left.ToDisp()}\t| {right.ToDisp()}\t= {(left | right).ToDisp()}");
        Console.WriteLine($"{left.ToDisp()}\t^ {right.ToDisp()}\t= {(left ^ right).ToDisp()}");
    }

    /// <summary>NOT</summary>
    void LogicalNot(bool? value) {
        Console.WriteLine($"!{(value).ToDisp()}\t= {(!value).ToDisp()}");
    }
}

/// <summary>表示の補助</summary>
static class NullableExt {
    public static string ToDisp(this bool? b) => b?.ToString() ?? "NULL";
}
```

### 結果?

結果は以下のとおり。

```
!True   = False
!False  = True
!NULL   = NULL
True    & True  = True
True    | True  = True
True    ^ True  = False
True    & False = False
True    | False = True
True    ^ False = True
True    & NULL  = NULL
True    | NULL  = True
True    ^ NULL  = NULL
False   & True  = False
False   | True  = True
False   ^ True  = True
False   & False = False
False   | False = False
False   ^ False = False
False   & NULL  = False
False   | NULL  = NULL
False   ^ NULL  = NULL
NULL    & True  = NULL
NULL    | True  = True
NULL    ^ True  = NULL
NULL    & False = False
NULL    | False = NULL
NULL    ^ False = NULL
NULL    & NULL  = NULL
NULL    | NULL  = NULL
NULL    ^ NULL  = NULL
```

# まとめ?

以下の定義を与えると[クリーネの3値論理](https://ja.wikipedia.org/wiki/3%E5%80%A4%E8%AB%96%E7%90%86#%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%8D%E3%81%AE3%E5%80%A4%E8%AB%96%E7%90%86)になります。
SQLの論理型と同じような感じですね。

```csharp:含意(A⇒B)
bool? IMP(bool? left, bool? right) => !left | right;
```

この記事を読んで何か得るものがあるとすれば、以下の事実でしょう。__`null`が絡むすべての演算がの結果`null`になるわけではない__ということです。

```
False & NULL = False
True  | NULL = True
```

_以上、出オチ記事を最後まで読んでいただきありがとうございました。_
第8話 フルビッツの定理

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第8話です。

```math
\arg_n ⁡\max_{z:bilinear}[\sum_i^n x_i^2 \sum_i^n y_i^2 = \sum_i^n z_i^2 ]=8
```

これは、フルビッツの定理の「組成代数は実数、複素数、四元数、八元数だけである」を表す式です。
大カッコの中が組成代数の条件、そしてその最大が8なので答えは8です。

ちなみに、[フルビッツの定理](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AB%E3%83%B4%E3%82%A3%E3%83%83%E3%83%84%E3%81%AE%E5%AE%9A%E7%90%86_(%E6%9B%96%E6%98%A7%E3%81%95%E5%9B%9E%E9%81%BF))はいくつかあり、
今回の話題は合成代数とついているものになります。

まず、虚数は二乗すると-1になる数です。
しかし、二乗すると-1になる数は本当に1つだけなのでしょうか。
そこで、虚数が2個あることにしてみましょう。

```math
i^2=j^2=-1, \ i \neq j
```

さて、次の式が常に成り立つルールとします。
組成代数とは次の式のルールが成り立つ世界だと思って下さい。

```math
|a||b|=|ab|
```

これは何かというと、積によって大きさ(ノルム)が変わらない、ということを意味します。
基本的に大きさは原点からの距離を表します。

```math
|a+bi|=\sqrt{a^2+b^2}
```

これにそって、虚数が2つの世界を完成させていきます。
しかし、どうやっても次の式を満たすa,b,cがうまく定まりません。

```math
ij=a+bi+cj
```
2つの虚数同士を掛け合わせるとどうなるか、です。
この世界でどんな数でも$a+bi+cj$と表せるはずなので、当然この積も同様に表せないといけません。
ですが、$i \neq j$を満たしながら値を設定することができません。

そこで、次のようにします。

```math
ij=k
```

3つ目の虚数の導入です。しかも、こうすると辻褄が合う式が出来ます。
この、実数が1つに虚数が3つの世界を四元数(クォータニオン)といいます。

この四元数の計算式を解いていくと以下のことがわかります。

```math
\displaylines{
i^2=j^2=k^2=-1 \\ 
ij=-ji=k\\ jk=-kj=i\\ ki=-ik=j
}
```

2つの違う虚数を掛け合わせると別の1つの虚数になることがわかりました。
ところが、よく式を見てみると、$ij=-ji$となっています。
つまり、掛け算の順序を逆にすると答えが変わります。
これを交換法則が成り立たない、といいます。
交換法則が成り立つ世界だと、二元数…いわゆる複素数が限度なのです。

さて、さらに虚数は増やせないのでしょうか。
虚数が７つの八元数という世界もあります。
しかし、この世界は次の式のようなことが起こります。

```math
(ab)c \neq a(bc)
```

結合法則と呼ばれるものです。
交換法則が成り立たないものに行列がありますが、その世界でもこの結合法則は成り立っていました。
しかし、八元数では、結合法則が成り立たなくなります。

その次、十六元数というものもあるのですが、割り算(積に対する逆元)が自由にできなくなります。
次の式を見て下さい。

```math
ab=0,a≠0,b≠0
```

aもbも0ではないのに、掛け合わせると0になるものです。
実数の世界ではもちろん、複素数でもこれはありえません。四元数や八元数でも同様です。

では、次の式を見てみましょう。

```math
a≠0 ならば |a|>0 かつ a^2>0
```

二乗して0になるのは0だけ、というルールです。
掛け合わせると0になるということは、
「掛け合わせても大きさが変わらない」というルールを壊しています。
組成代数を満たさないので八元数が限度なのです。
WindowsにMinicondaインストール(2018年)JupyterLabはIE11サポート対象外

#環境
windows7 + IE11
conda 4.5.4
Python 3.6.5 :: Anaconda, Inc.
Jupyterlab Beta Release Series Version 0.32.1
#現象
タブにJupyterlabの文字が表示されるが、本文は空白で表示する。　
#対応
デフォルトのブラウザを換えたくないので、jupyter側のブラウザをFirefoxに変更する。
(参考)WindowsにMinicondaインストール(2018年)
https://qiita.com/FukuharaYohei/items/cf72049b2a97687037bb
(参考)Anaconda-Navigateから jupyter lab が使用できない
＞JupyterLab は、CSS 変数を使用しているので、それをサポートしていない IE 11+ や Edge 14 はサポート対象外。」
http://memopad.bitter.jp/blog/2017/11/27/anaconda-navigate%E3%81%8B%E3%82%89-jupyter-lab-%E3%81%8C%E4%BD%BF%E7%94%A8%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84/
PartialScript

```
#c.NotebookApp.browser = ''
import webbrowser
webbrowser.register('firefox', None, webbrowser.GenericBrowser('C:\\Program Files\\\Mozilla Firefox\\firefox.exe'))
c.NotebookApp.browser = 'firefox'
```
JDBCのお約束と書き方例

JDBCはJavaのAPIで、データベース処理(SQL文)を行うことができる。
java.sql (コア:J2SE), javax.sql (標準拡張:J2EE)などがある。


以下、java.sqlを利用した例。

# SQL文を決め打ちで実行して結果を表示する例

```java
import java.sql.*;

public class クラス名 {
   public static void main(String args[])
      throws SQLException, ClassNotFoundException { //例外処理 エラーページ表示用

      String drv = "oracle.jdbc.OracleDriver"; // Oracle JDBC (Type4) を指定
      String url = "jdbc:oracle:thin:@localhost:1521:データベース名"; // データベースのurl

      Class.forName(drv); // ドライバーをロードする
      Connection con =  DriverManager.getConnection(url, ユーザ名, パスワード); //データベースに接続


      Statement stmt = con.createStatement(); //問い合わせの準備
      String qry = "SQL文 例えば SELECT * FROM テーブル名"; // クエリの準備
      ResultSet rs = stmt.executeQuery(qry); // SQL文を実行して結果をResultSetで受け取る


      // ResltSetのデータを1行ずつ所得
      while(rs.next()){ // next()メソッドで1行ずつ指定し、テーブルが終わるとfalseを返す。
         String 列名1 = rs.getString("列名1");
         Int 列名2 = rs.getInt("列名");
         System.out.println(列名1 + "\t" + 列名2); // 表示
      }

      // データベースとの接続をクローズ
      rs.close();
      stmt.close();
      con.close();
   }
}
```


# 入力を受け取ってSQLを実行する例
入力を受け取ってSQL文に挿入したい場合は、SQL文の準備などの表記が変わる。

```java
import java.sql.*;

public class クラス名 {
   public static void main(String args[])
      throws SQLException, ClassNotFoundException { //例外処理 エラーページ表示用

      String drv = "oracle.jdbc.OracleDriver"; // Oracle JDBC (Type4) を指定
      String url = "jdbc:oracle:thin:@localhost:1521:データベース名"; // データベースのurl

      Class.forName(drv); // ドライバーをロードする
      Connection con =  DriverManager.getConnection(url, ユーザ名, パスワード); //データベースに接続


      String qry = "SQL文 例えば SELECT * FROM テーブル名 where 列名 = ? AND 列名 = ?";
                               // ?の部分に入力値が挿入される。左から1, 2 と番号で指定する。
      PreparedStatement ps = con.prepareStatement(qry); // 問い合わせの準備
      ps.setString(1, 入力1); // 1番目の?に入力を挿入。入力が文字列の場合。
      ps.setInt(2, 入力2); // 2番目の?に入力を挿入。入力が整数型の場合。
      ResultSet rs = ps.executeQuery(); // SQL文を実行して結果をResultSetで受け取る


      // ResltSetのデータを1行ずつ所得
      while(rs.next()){ // next()メソッドで1行ずつ指定し、テーブルが終わるとfalseを返す。
         String 列名1 = rs.getString("列名1");
         Int 列名2 = rs.getInt("列名");
         System.out.println(列名1 + "\t" + 列名2); // 表示
      }

      // データベースとの接続をクローズ
      rs.close();
      ps.close();
      con.close();
   }
}
```
GitHubで自動Commit/Pushをしてくれるシェルスクリプト(Mac)

#開発目的
　LaTexで書いたレポートをGitHubのリポジトリに追加していると，コミットするのがめんどくさかったので，コミット，プッシュを自動でしてくれるシェルスクリプトを作成しました．

#仕様
　起動時にコミットし，それ以降1時間間隔でコミット，3時間間隔でプッシュを行います．この間隔はシェルスクリプトを編集して変えることができます．プログラムの最初に指定するGitのパスを指定してください．

#ソースコード
GitHubにあるので部分的に機能の説明
コミット
プッシュの場合はgitコマンドを変更

```shell:auto_commit.sh
path="/Users/"
clear
cd $path
echo ""
echo $path
git add .
git commit -m 'auto commit'
echo ""
echo "wait 1 hour"
echo ""
```

プログレスバー

```shell:auto_commit.sh
:auto_commit.sh
A=0
while [ $A -le $C ]
do
  B=""
  for i in `seq 1 $C`
  do
  if [ $A -eq $i ]
  then
  B="$B>"
  else
  if [ $i -le $A ]
  then
    B="$B-"
    else
    B="$B "
    fi
  fi
done
```

#実行結果
```plaintext

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

wait 1 hour

 until commit...  [--------->                              ] 25 %
```

#GitHub
https://github.com/reo11/Git_Auto_Commit

`git clone https://github.com/reo11/Git_Auto_Commit.git`

#参考
定期的に自動でコミットさせるスクリプト
https://qiita.com/narikei/items/b4e1c035c778d4eb2fc9
シェル：プログレスバーの作り方
https://qiita.com/toyohama/items/aa093bf0352ea623c670
Windows 8.1でDocker ToolboxをインストールしてDockerを動かす

Dockerを使いたく自宅PCにDocker Toolboxをインストールしてみました。OSがWindows 8.1 64bitでProfessional版ではななかったため、Docker for Windowsは動かせず、Docker Toolboxにしています。
仕事で使っていますが、とても便利です。特に私のような**インフラ系に弱い人間には、すぐに環境つくれて重宝**します。
記事[「初心者用Docker基本コマンド一覧(新旧スタイル対応)」](https://qiita.com/FukuharaYohei/items/ef5cf790b5269e73cdb3)と[「【入門者向け解説】短時間で理解するDocker」](https://qiita.com/FukuharaYohei/items/1ec694eaf634ca14a51c)も投稿しました。

#前提条件確認
[公式サイト](http://docs.docker.jp/windows/step_one.html)を見ながら前提条件を確認しました。以下の2つです。
1. Windows7以上の64 bit OS
 Windows 8.1 の64bit だったので問題なし
2. CPUの仮想化が有効であること
 タスクマネージャーからCPUが仮想化有効かを確認。私の場合は、無効となっていましたのでBIOS設定で有効に変更しました。BIOSの設定変更の仕方は、機種によって大きく差があるので省略します。
![00.DockerPrerequistes01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/41fc66a0-45b8-a3f7-039d-9f39e8a6bd8f.jpeg)

#手順
##1. ダウンロード
[Install Docker Toolbox on Windows](https://docs.docker.com/toolbox/toolbox_install_windows/)からインストールファイルをダウンロードします。
![10.InstallDockerToolbox01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/9f4a3cbb-2780-8828-50fd-25e3b171461a.jpeg)

##2. インストール
[公式サイト](https://docs.docker.com/toolbox/toolbox_install_windows/)手順に従っています。
![10.InstallDockerToolbox01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/414fd2fe-d6a2-8282-8fa0-40c49ed97bfa.jpeg)
![10.InstallDockerToolbox02.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/fbc14934-2f92-14fa-443e-de68103f25ea.jpeg)
![10.InstallDockerToolbox03.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/318a8bf3-af8a-fea8-0de4-c9230d78ee37.jpeg)

ここで"Git for Windows"をOFFにしていますが、これが原因で後にエラーが出てしまったのでONにした方がいいです。
![10.InstallDockerToolbox04.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/8a435f8d-f8e4-fb9f-85cb-6c92029fe7de.jpeg)
![10.InstallDockerToolbox05.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/7a389b83-cd94-3e9f-31ac-db0dfa279669.jpeg)
![10.InstallDockerToolbox06.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/83d72bd9-2af4-86a4-8ac8-f3508bc990d8.jpeg)
![10.InstallDockerToolbox07.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/732a6419-39a1-b829-7524-be10a6975472.jpeg)
![10.InstallDockerToolbox08.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/b3a0cd12-9135-dca4-ab63-2f9ac84135bc.jpeg)

#3. 確認
デスクトップに作成されたショートカット"Docker Quickstart Terminal"をクリックします。
![20.RunDockerTerminal02.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/497ae988-37dd-33bf-1973-c4817416263d.jpeg)

Dockerが起動しました。
![20.RunDockerTerminal01.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/0331499c-bc1b-0cb1-4841-98cfcc713c77.jpeg)
Gradient Clipping x LSTM ( Batch Normalization, Zoneout ) の実装に関するメモ

##ポイント
* LSTMをベースに Gradient Clipping ( by norm ) を実装し、効果を検証。
* 効果を確認できず。今後、追加検証。

##レファレンス
[1. Recurrent Batch Normalization](https://arxiv.org/abs/1603.09025)
[2. Zoneout: Regularizing RNNs by Randomly Preserving Hidden Activations](https://arxiv.org/abs/1606.01305)
[3. Zoneout に関するメモ](https://qiita.com/takeshikondo/items/f0117a4b9620d072737d)




##検証方法
* Base (no regularization)、Base + Recurrent Batch Normalization、Base + Zoneout に適用し、効果を比較。
　　　　　 　 　         

##データ
MNIST handwritten digits

```python
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('***/mnist', \
                                     one_hot = True)
```

##検証結果
数値計算例：

* n_units = 100
* learning_rate = 0.01
* batch_size = 64
* zoneout_prob = 0.2

Base ( no clipping )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/43f8cb5c-29d2-b344-f564-ae4fb8b30430.png)
<br>

Base ( clip_norm = 0.5 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/2f28c3cf-1e13-d252-504b-aae87ed7c4b9.png)
<br>

Base ( clip_norm = 1.0 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/4047b30a-b89e-8699-95a8-2d4f4fc425f8.png)
<br>

Batch Normalization ( no clipping )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/2fb0a798-1003-0c01-b974-0d21fb2c05c8.png)
<br>

Batch Normalization ( clip_norm = 0.5 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/832508e1-33b0-3125-1840-fc137b51d1c7.png)
<br>

Batch Normalization ( clip_norm = 1.0 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/e9229619-d5b7-1e93-9906-ba3d9de956c2.png)
<br>

Zoneout ( no clipping )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/5bb339ad-49e0-540f-b0a0-c6155018638f.png)
<br>

Zoneout ( clip_norm = 0.5 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/168e0331-148f-8caa-6cd3-7c1f110590a0.png)
<br>

Zoneout ( clip_norm = 1.0 )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/de6d5fcb-8b57-2a84-f590-c23fe13e104b.png)

##サンプルコード
```python
  def training(self, loss, learning_rate, clip_norm):
    optimizer = tf.train.AdamOptimizer(learning_rate = \
                  learning_rate)

    grads_and_vars = optimizer.compute_gradients(loss)
    clipped_grads_and_vars = [(tf.clip_by_norm(grad, \
               clip_norm = clip_norm), var) for grad, \
               var in grads_and_vars]
    train_step = \
      optimizer.apply_gradients(clipped_grads_and_vars)

    return train_step
```
メモ: IOPSとは？

## TL;DR

`I/O per Second` の略。
ディスクが１秒当たりに処理出来るI/Oアクセスの数。


## 詳細

ディスク性能の指標となるものである。このIOPSは、データ転送時間と平均アクセス時間を足した数値である。一般的にこの数値が高ければ高いほど高性能なディスクであると考えられる。

## 参考

* [IOPSを理解する](http://tech.nikkeibp.co.jp/it/article/lecture/20070104/258117/)
* [ストレージのIOPS性能がアプリケーションに与える重要性](http://blogs.itmedia.co.jp/hatori/2017/03/iops.html)
Railsでの観察者効果

Rubyはメタプログラミングに秀でた言語ですが、メタプログラミングを多用したRailsなどでは、思わぬ挙動にハマることがあります。

# REPLコンソール

`irb`や`pry`、Railsの画面内に表示させる`web-console`など各種ありますが、入力したものをその場で実行するREPLコンソールは便利なものです…が、これが罠になった例がありました。

REPLコンソールでは、入力して実行したコードの結果を表示するのですが、表示のために`#to_s`、あるいは`#inspect`と言ったメソッドを実行します。通常であれば特に問題ない操作なのですが、ときにはそれで**オブジェクトが状態を変えてしまう**ことがありえます。

# メーラーと中身

Rails標準で搭載されているActionMailerですが、これもまた[黒魔術を多用した構成](https://qiita.com/fursich/items/bb75a06714bcad6a0afb)となっています。そして、メーラーを作成してREPLで評価すると、以下のようになります。

```ruby
> SomeMailer.some_method(args)
=> #<Mail::Message ....>  
```

実はこの時点で、もう罠にハマっています。

## 実際の動作

メーラーで作成したもののクラスは`ActionMailer::MessageDelivery`というものです。このクラスは、`delivery_now`など配信制御系のメソッドを除けば、内部で持つ`Mail::Message`への`Delegator`となっているので、`#inspect`を実行すればその瞬間にメール生成処理が走って、そのインスタンスの詳細を返しています。

さらに、このメールを`.deliver_later`しようとした場合、事前に`Mail::Message`を生成してしまっていると**エラーになります**。

# 結論

REPLで「結果を表示する」こと自体も1つの処理で、時にはそれが原因でオブジェクトそのものが挙動を変化させてしまうことすら、ありえます。挙動がドキュメントやコードで確認できるものについては、結果を鵜呑みにせず、資料を丁寧に追っていくほうが正解かもしれません。
Nuxt.js の layouts で style に scoped を指定しないとグローバルになる

# Nuxt.js の layouts ディレクトリでのレイアウト指定

pages ディレクトリに設置したファイルに laytout プロパティを指定することで
指定するレイアウトを切り替えることが可能となるが・・・

```vue:layouts/default.vue
<template lang="pug">
  div
    nuxt
</template>

<style lang="scss">
// sass-loader などを入れているとする
body: {
  color: white;
}
</style>
```

上記は pug や sass-loader などをインストールしておくことにより
Pug, scss が使用可能なものとします


```vue:pages/index.vue
<template lang="pug">
  div ホーム
</template>

<script>
export default {
  // layout を指定しなければ layouts/default.vue が使用される
};
```

## 複数の layout を定義しそれぞれに style を定義

下記のような複数種類の layouts, pages を用意することにより
page ごとに layout を切り替える実装をする

### 赤組

```vue:layouts/red.vue
<template lang="pug">
  div layout red
    nuxt
</template>

<style lang="scss">
body {
  background-color: red;
}
</style>
```

```vue:pages/red.vue
<template lang="pug">
  div Red
</template>

<script>
export default {
  // layouts/red.vue を指定
  layout: 'red',
};
</script>
```

### 青組

```vue:layouts/blue.vue
<template lang="pug">
  div layout blue
    nuxt
</template>

<style lang="scss">
body {
  background-color: blue;
}
</style>
```

```vue:pages/blue.vue
<template lang="pug">
  div Blue
</template>

<script>
export default {
  // layouts/blue.vue を指定
  layout: 'blue',
};
</script>
```

### 結果、赤組の勝ち

![result.jpg](https://qiita-image-store.s3.amazonaws.com/0/116435/6ab73b9e-adf9-ff2f-eb34-65a540027ccb.jpeg)

layouts に存在するもののうち
scoped 指定のないスタイルはプロジェクト単位で影響する模様

こちらは pages/red.vue で layouts/red.vue をやめても
pages で使用されていないからと言って読み込まれないわけではないようです

```vue:pages/red.vue
<template lang="pug">
  div Red
</template>

<script>
export default {
  // 指定を解除し layouts/default.vue を使用
  //layout: 'red',
};
</script>
```

# 結論としては style には layouts 配下でも scoped をつけましょう

というかデフォルトで scoped 扱いのほうがよいのでは・・・
ミニゲームを作ってUnityを学ぶ！  [ ひつじコレクション編 - イントロダクション ]

前回[「3Dマインスイーパー編」](https://qiita.com/YzRoid/items/0e708a561531bf0d384f)に続いて第3弾！
ゲーム作成の定番、ドットイート型ゲーム（の亜種）をお題にしました。



#Unity初心者の筆者
チュートリアルの[「玉転がし」](https://unity3d.com/jp/learn/tutorials/projects/hajiuni-jp)と[「シューティングゲーム」](https://unity3d.com/jp/learn/tutorials/projects/2d-shooting-game-jp)は完成した！
次はミニゲームを自作してUnityで出来ることを増やしていこう！

そんな経緯がありまして、後学のために開発したゲームっぽい何かの作り方を1から解説していきます。
＊使用言語はC#で解説内容は上記2点のチュートリアルが完了していることを前提としています。



# お題：ひつじコレクション
**どんなゲーム？**
たいへん、たいへ～ん！
ひつじさん達が森の中に入っていっちゃったみたい！
スライムに捕まらないように、なるべく多くのひつじさんを連れて帰ろう！


**スクリーンショット**
![action_sheep_0.jpg](https://qiita-image-store.s3.amazonaws.com/0/239877/c429ee75-05fc-ddd3-5363-41bb075f1854.jpeg)




**完成品をプレイ(PC専用 -- WebGL)**
[こちらから（少し読み込み時間があります）](http://yzroid.jp/unity/csg_action_sheep/app/index.html)

Enterキーを押してプレイ開始。

[W/A/S/D] プレイヤーの移動
[Backspace] リスタート

ひつじさんを連れて赤色のBOX内に到達するとポイントが獲得できます。
ひつじさんを一度に多く運ぶほど獲得ポイントが上昇しますが、連れているひつじさんが多いほどプレイヤーの移動速度が低下します。

＊TOP5に入るスコアはオンラインランキングに登録されます。


#作り方（更新中）
[**1. プレイヤーキャラクターの作成**](https://qiita.com/YzRoid/items/f98417dcadba57fdd515)
プレイヤーの制御・アニメーション・アニメーションイベント・ビヘイビアなどを設定します。

[**2. ステージの作成**](https://qiita.com/YzRoid/items/0e7f875566e494eafa95)
Resourcesフォルダからファイルを読み込んでステージを動的に生成します。

[**3. フォロワーを作成**](https://qiita.com/YzRoid/items/b4aed2c81dec59a9f6a2)
一定時間毎にひつじさんをポップアップさせます。

[**4. フォロワーに追従機能を実装**](https://qiita.com/YzRoid/items/75d4f8181b5f8a3ae5fa)
NavMeshの動的なBakeによってひつじさんをプレイヤーに追従させます。

[**5. ゴールエリアとスコアを実装**](https://qiita.com/YzRoid/items/f3533c9645ed943a13b4)
ステージ内にゴールとなるオブジェクトを設置し、スコアの概念を実装します。

[**6. チェイサーの作成**](https://qiita.com/YzRoid/items/b68dbeacbdfb61be8e8e)
プレイヤーの邪魔をする敵キャラクターを3種作成し、それぞれ異なる行動AIを実装します。

[**7. チェイサーとの当たり判定を実装**](https://qiita.com/YzRoid/items/69f6cc798a39091b81e8)
プレイヤーまたはひつじさんが敵キャラクターに当たったときの処理を実装します。

[**8. ミニマップを表示**](https://qiita.com/YzRoid/items/4f20f17302ba0c105a54)
画面下部にミニマップを表示し、視界の悪さを改善します。

[**9. ゲームの開始と終了**](https://qiita.com/YzRoid/items/ffffffb5f1511e846cbd)
シーンの流れを制御してゲームに開始と終了の概念を実装します。

[**10. UIの作成（1）**](https://qiita.com/YzRoid/items/9a8c7db065a868ace439)
ゲームに必要なUIを作成し、DotweenによるUIのアニメーションを実装します。

[**11. UIの作成（2）**](https://qiita.com/YzRoid/items/3da00ca14eaf09df354d)
引き続きその他UIを作成し、併せてゲームに時間制限を実装します。

[**12. パフォーマンスチューニングみたいなこと（1）**](https://qiita.com/YzRoid/items/8acd300a5a738e189450)
Tris, Verts, SetPassについてチューニングを行い、パフォーマンスを向上させます。

[**13. パフォーマンスチューニングみたいなこと（2）**](https://qiita.com/YzRoid/items/eb0ae06855274bd5398b)
引き続き、描画部分の修正を行います。

**14. オンラインランキングを実装**
ニフティクラウドMobaileBackendを使ってオンラインでのランキングを実装します。


#スクリプト
[ひつじコレクションのスクリプト（GitHub）](https://github.com/YzRoid/UnityActionSheep)

上記リンクより今回のスクリプトをダウンロードすることができます。
記事内ではどうしてもコードが飛び飛びになってしまって全体像が掴みずらいため、解説がわかりにくい場合なんかはこちらを見たら解決するかもしれません。

尚、こちらのコードは今回の解説用に書き直したモノではなく実際のWebGLアプリに実装されているコードのため、コメントアウトされた未使用のメソッドがあったり、そもそものメソッド名・フィールド名が異なる場合があるかもしれません。
その場合は記事の内容を優先してください。


<div><img src="http://unity-chan.com/images/imageLicenseLogo.png" alt="ユニティちゃんライセンス"><p>この作品は<a href="http://unity-chan.com/contents/license_jp/" target="_blank">ユニティちゃんライセンス条項</a>の元に提供されています</p></div>
<Br><Br>
初心者が話すUiPath　～初めてのUiPath～ 


今回は UiPath のシーケンス新規作成から、ダイアログの表示といった
簡単な内容をご紹介します！

・新規作成
・Message Box
・Input Dialog
・変数（ちょっとだけ）

# 新規作成してみよう

UiPathを起動しましょう。

起動すると、画像のようなウィンドウが開きますが、
一番上の「Continue Free」をクリックすれば大丈夫です。

<img width="955" alt="UiPath2-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/234754/ba586136-386a-d7f0-b92b-efb75149cc56.png">

とりあえず今回はシーケンスを作成しましょう。
Start＞Blank をクリックし、適当なファイルに適当なファイル名を付けて
作成します。

<img width="960" alt="スクリーンショット (19).png" src="https://qiita-image-store.s3.amazonaws.com/0/234754/2b0e3b6c-43f7-c26d-b039-2d21485ccb39.png">

これで「UiPath01」という新しいファイルにて、作業する環境が整いました。

自動的に「Main」という名前のシーケンスが作成されますが、
自分で新しく作ってみましょう。

左上の DESIGN＞New＞Sequence をクリック。

<img width="172" alt="UiPath2-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/234754/3b4c81f4-11e1-12af-c1cb-69f86d32ef28.png">

適当な名前（今回は「seqence01」にしました）を付けて作成！

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/1be5f20e-2a0f-a9a9-6388-d5ea4d6822a9.png)


# Message Box を表示させる
それでは早速遊んでみましょう♪

まずは下のような、指定の文字をダイアログに表記してみましょう。
　
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/6640523d-e963-548b-a8af-f2f6ac92701b.png)

## Message Box を見つける
左の Activities にて「Message Box」と検索してみましょう。
　
![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/9a3bd613-98ab-44ee-9368-3fcbbe034114.png)
　
マウスを合わせ、左クリックをした状態でシーケンス内に持っていき、
クリックをやめます。

![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/9bfe0df8-29d7-a364-b21b-8606f0c6822c.png)

（青い"！"はエラーが発生しているよのマークです。今はスルーで）
「Text must be quoted」と書かれた場所に「"ねこのここねこ"」と入力してください。
その後  RUN（もしくはF5）をクリックしてください。
すると、指定した文字がダイアログ上に表示されます。

## タイトルを変更しよう
Message Box を選択した状態で、Properties をご覧ください。
色々書かれていると思いますが、その中の「Title」にご注目。
こちらに何か文字を入れてみましょう。
Text 同様 "" で囲んでくださいね！

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/1079bfdb-3f60-372a-85b4-976de9851208.png)
（"ねこのここねこ"のままだと、ダイアログの大きさ的に
　タイトルが隠れてしまったので、中身を変えました）

ダイアログのタイトルが変更されました！

# 変数・Input Dialog を使ってみよう
下記のようなものを作ってみましょう。

① 商品の金額を入力する
② 税込価格を計算する
③ 税込価格をダイアログで表示する

## Input Dialog　（① 商品の金額を入力する）
Input Dialogを見つけてください。
先程と同様にシーケンス内に設置します。
（因みにダブルクリックで設置することも可能です☆）

Title には「"価格計算"」を、
Label には「"税抜価格を入力してください"」を入力してください。

Run をするとこうなります。

![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/307c9475-3b47-0ae6-f3d8-bc1ea3359d01.png)

しかし今入力しても何もならないので、その準備をします。

## 変数　（税込価格を計算する為の準備）
Input dialog を選択し、Properties＞Output＞Result にカーソルを合わせてください。
そこで「Ctrl + K」を押すと、下記のようになります。

![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/d851dd4a-9302-a112-9d60-999d587789fb.png)

こうすると変数が作成できます。

適当な変数名を入力し、Enter を押します。

変数は Variables から確認できます。
（シーケンスを選択している事）

![8.PNG](https://qiita-image-store.s3.amazonaws.com/0/234754/e305ce2a-2205-86c9-1029-e40168eab9a2.png)

勿論この場で変数を新規追加することも可能です。
灰色の文字になっている Create Variable をクリックすると作成可能です。

Name...変数名
Variable type...変数の型
Scope...この変数がシーケンス上で使用できる範囲（追々説明いたします）
Defaulut...初期値


　
　
　


さて、今回はここまでにしようと思います。
ダイアログで入力した数字を入れる変数を用意しました。
あとは計算して、それを表示させるだけです！
ちょっとやってみてください♪
ただ、変数の型に注意してください！
計算ができるのはInt型です。
このヒントを元に、挑戦してみてください。

最後までありがとうございました。