OmniAICreator/Qiita-1.07M huggingface dataset:
複数のサイズの違う画像をWebサイトに表示させる

# はじめに
Webサイトを作成しているとき、「様々な画像を載せたい！」ってなったとき、画像を整えて表示させる方法について記事を書きたいと思います。
ただ単純にWebサイトに画像を表示させたいなら以下のようにすればできると思います。
※画像はサンプルのものを使用しています

```sample1.html
<img src=./img/2.jpg border='0'>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120727/9a69446a-5408-55cf-ccef-7ea866b50a27.png)

# サイズの違う複数の画像を表示させるときの問題点
サイズの違う複数画像を並べて表示させると以下のようになり、見た目も思わしくないです。

```sample2.html
<img src=./img/1.jpg border='0'><br>
<img src=./img/2.jpg border='0'><br>
<img src=./img/3.jpg border='0'><br>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120727/776cb711-7f95-ce52-e86b-6b6f9d3dfd9f.png)

# サイズを同等にして表示させると...
同じサイズにするためにwidthとheight属性で調節しますが、無理やりサイズを変更したため、画像が潰れて表示されてしまいました。

```sample3.html
<img src=./img/1.jpg width='640' height='360' border='0'><br>
<img src=./img/2.png width='640' height='360' border='0'><br>
<img src=./img/3.jpg width='640' height='360' border='0'><br>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120727/ea9862a9-7914-32f5-8b92-d52e056964e4.png)

# 画像調整プログラム
画像は縦と横の比になっていますので、縦の長さに合わせた横の長さにしないといけません。
なので、
###height：width=360:X
で計算して画像のサイズを調整するプログラムを作成しました。
※ついでに画像かどうか判別するプログラムも作成しました。

```img_tool.php
<?php
//画像が出力できるか判定　画像ない場合は「No Image」出力
function img_judge($img){

    $extension_list = array(".jpg", ".jpeg", ".JPG", ".JPEG", ".jpe", ".jfif", ".pjpeg", ".pjp", ".png", ".gif");//画像拡張子

    foreach ($extension_list as $extension){
        //当確の拡張子があればそのままブラウザに出力
        if (strpos($img, $extension) !== false){
            return $img;
        }
    }

    return 'img/noimage.png';


}

//画像のサイズを変更
function img_size($img){
    //「No image」の場合
    if($img == 'img/noimage.png'){
        return "width='640' height='360'";
    }
    
    //画像のサイズ情報を取得
    $image = getimagesize($img);
    if($image){
        //heightのサイズを360pxに固定し、それに合わせた比率のwidthのサイズを設定(height：width=360:X)
        $width = floor(360 * $image[0] / $image[1]);
        //widthのサイズが640pxを超えていたら640pxに固定
        if($width > 640){
            $width = 640;
        }
    }else{
        return "width='640' height='360'";
    }

    return "width='".$width."' height='360'";
}
?>
```

# 画像調整プログラムを使って表示
heightの長さを固定にさせて画像を表示させますと、元の画像サイズに合わせてサイズが調節できています。

```sample4.php
<?php
require_once "img_tool.php";
?>
<img src=<?php echo img_judge("./img/1.jpg"); ?><?php echo img_size("./img/1.jpg"); ?> border='0'><br>
<img src=<?php echo img_judge("./img/2.png"); ?><?php echo img_size("./img/2.png"); ?> border='0'><br>
<img src=<?php echo img_judge("./img/3.jpg"); ?><?php echo img_size("./img/3.jpg"); ?> border='0'><br>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120727/05df24c9-a6e7-134c-34ba-59528d665ac1.png)

# 余談
そこまで大したことないと思いますが、サイトの印象も大分変わるのではないかと思います。
また、widthの長さを固定にさせる場合もプログラムを書き換えて使って下さい。
[GitHub:img-output](https://github.com/Dhikigame/img-output/tree/master)
JavaScriptでJSONを扱う時のメモ

### JSONとは
JavaScript Object Notationの省略がJSON。
ちなみにNotationとは、『記法』という意味。
JavaScriptオブジェクト構文の記法をベースに作られている為、JavaScriptという文言を含んでいる。
テキストベースのフォーマットでデータ構造を表現している。

### JSONをパース(parse)するとは？
JSONを扱っていてよく耳にするのが、『パース(parse)する』という表現。
結論から言うと、この意味は『JSONを解析する、JSONを読み込む』といったニュアンスで使われます。

### JavaScriptでの利用
JavaScriptでJSONを扱う場合は、ビルドイン関数を利用できます。
JSON形式の文字列とJavaScriptを相互変換のための関数は以下の二つ。

- parse
- stringify

#### JSON→JavaScriptオブジェクトにする
JSONをJavaScriptオブジェクトに変換するには、parseを使う。
参考は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)

```javascript
// 基本構文
JSON.parse(text[, reviver])

const json = '{"result": true, "count": 30}';
const obj = JSON.parse(json);

console.log(obj.result);
console.log(obj.count);
```



#### JavaScriptオブジェクト→JSON
JavaScriptのオブジェクトをJSONに変換するには、stringfyを使う。
参考は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)

```javascript
// 基本構文
JSON.stringify(value[, replacer[, space]])

const obj = {result: true, count: 30};
const json = JSON.stringify(obj);

console.log(json);
```


#### 参考
- [JSONの利用](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/JSON)
【超単純メモ】コンピュータがどうやって動くのか

エンジニアになるために日々修行をしているのですが、「そもそもコンピュータってどうやって動くんだっけ？」と思い、勉強した事をここにアウトプットしようと思います。

拙いメモですが、アウトプットは大事だと聞いたので…スモールステップでいきたいと思います。

なお、当記事は著書[「コンピュータはなぜ動くのか」](https://www.amazon.co.jp/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B%EF%BD%9E%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A8%E3%82%A2%EF%BC%86%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A8%E3%82%A2%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98%EF%BD%9E-%E7%9F%A2%E6%B2%A2-%E4%B9%85%E9%9B%84/dp/4822281655)を元にしております。


# コンピュータの主な構成要素

コンピュータは主に3つの構成要素で成り立っています。

- CPU
- メモリ
- I/O

## CPU
コンピュータの頭脳とも言われるところ。
「計算」と呼ばれているものは、ここで行われている。

具体的に言うと、
- メモリに書かれたプログラムを実行
- メモリやI/Oに書かれたデータをCPUが処理し、メモリやI/Oに出力する

といった事を行なっている。

## メモリ
データを保存する場所。

しかし、電源が切れると消える。(消えないメモリもある)
メモリは「机の上」に例えられる。いわばCPUにとっての作業スペース。
ハードディスクは電源が切れても消えないので「机の引き出し」に例えられる。

## I/O
CPUとその他ハードウェア(キーボードetc)の入出力の仲介を行う。


## 図に表すとこんな感じ
<img width="1009" alt="スクリーンショット 2018-11-20 21.35.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/231086/f55dea21-9c4c-3e0a-37db-7f13cc26ea92.png">

厳密にはこんな単純な線で繋がっている訳ではなく、複数のピンで繋がっており、
アドレス指定やデータ転送を行なっている訳なのですが、簡略化して作成しました。

## 終わりに
実際に記事にしようと思うとこんなに苦労するんですね…
まだまだわからない事だらけですが、少しずつアウトプットしようと思います。

合っていないところやアドバイスなどございましたら、どんどん言ってください。
Scratch スクリプトを別のスプライトにコピーする

* スプライトを複製することで実現していましたが、ちゃんと方法があったのでメモ

# やり方1 (バックパックを経由する)

* [バックパック](https://ja.scratch-wiki.info/wiki/%E3%83%90%E3%83%83%E3%82%AF%E3%83%91%E3%83%83%E3%82%AF) 
  * 使用方法はリンク先を見てください 

> プロジェクトのエディタ内でスプライトやスクリプトをドラッグ&ドロップにより簡単に保存できるものである。
バックパックには、背景を除くすべての要素をコピーできる。 

* ポイント :bulb: 
  * サインインした状態でないと使えないようです :sob: 
  * 初期状態(?)だとわかりづらいかもしれません。
     * 画面の右下にある `バックパック　　▲` の領域をクリックしてください


# やり方2 (直接ドラッグ＆ドロップ)

* コピーしたいスクリプトを対象のスプライトめがけてドラッグ＆ドロップしてください
  * 例） [Scratchキャット](https://ja.scratch-wiki.info/wiki/Scratch%E3%82%AD%E3%83%A3%E3%83%83%E3%83%88)のスクリプトを[ゴボ](https://ja.scratch-wiki.info/wiki/%E3%82%B4%E3%83%9C)にコピーする

![aaa.gif](https://qiita-image-store.s3.amazonaws.com/0/268273/31e776ca-e32d-20cc-b8f0-902582e0b863.gif)

* ポイント :bulb: 
  * こちらはサインインしてなくてもOK :smile:
cordovaプラグインとOpenWeatherMapで天気予報

#１．Pluginインストール
```terminal
$ cordova plugin add cordova-plugin-geolocation
```
#2.Plugin動作確認
```javascript
var onSuccess = function(position){
console.log
             ('Latitude: '          + position.coords.latitude          + '\n' +
              'Longitude: '         + position.coords.longitude         + '\n' +
              'Altitude: '          + position.coords.altitude          + '\n' +
              'Accuracy: '          + position.coords.accuracy          + '\n' +
              'Altitude Accuracy: ' + position.coords.altitudeAccuracy  + '\n' +
              'Heading: '           + position.coords.heading           + '\n' +
              'Speed: '             + position.coords.speed             + '\n' +
              'Timestamp: '         + position.timestamp                + '\n');
};
```
<img width="311" alt="スクリーンショット 2018-11-20 20.39.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/280251/2c5c4816-d749-a20a-eed5-bd2bc2bc5d39.png">
成功例です（RHEMS技研での座標）

| 　　　項目　　　　 | 意味 | 
|:-----------|------------:|:------------:|
| Latitude       | 緯度       | This         |
| Longitude     | 経度      | column       |
| Altitude       | 高度       | will         |
| Accuracy         | 正確さ          | be           |
| Timestamp       | UNIX時刻     | center       |
＊UNIX時刻は１９７０年１月１日０時０分からの経過時間

#3.OpenWeatherMap
[OpenWeatherMap](https://openweathermap.org/)は、開発者向けにAPIを無料で提供しているサイトです（有料プランあり）
今回は無料プランをつかってやっていきます
#４.実際に使ってみる


```javascript
$(function(){
        var apikey = '**************';
		var lon = position.coords.longitude ;
		var lat = position.coords.latitude ;
		var url = `https://api.openweathermap.org/data/2.5/weather?lon=` + lon + `&lat=` + lat + `&units=metric&APPID=` + apikey;
		$.ajax({
			url: url,
			dataType:`json`,
			type: `GET`,
		})
		.done(function(data){
			console.log(data)
			
		})
		.fail(function(data){	
			console.log("failed");
		});
	});
```

###成功例
<img width="777" alt="スクリーンショット 2018-11-20 20.55.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/280251/be9fd18e-ab98-34f9-515d-caa53a9e3647.png">

###説明
スマホやPCで位置情報を取り、APIkeyと一緒にOpenWeatherMapに渡して、JSONで取得するという流れです
units=metricは温度の単位をケルビンから摂氏に変えるものです
Ajaxを使うときは下の一行をheadに追加しましょう
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
```
console.logのvisibilityは視界（単位はメートル、何メートル先まで見えるかみたいな）

今回はCordovaのプラグインを使ったので座標を指定して使ったが、都市の名前を使って天気予報を受け取る事もできる
Powershell が遅かったので早くした（ハッシュ生成、ファイル書き込み）

# はじめに

*こんにちは、のんびりエンジニアのたっつーです。*
*[ブログ](https://www.fast-system.jp/)を運営しているのでよろしければ見てください。*

powershell を使って大量にファイルを処理していたのですが、あまりにも遅くて高速化を行ったのでその時の改善内容を残しておきます、誰かのお役に立てればよいです。

powershell 自身の問題およびコマンドの実行の遅さが原因なのかなと感じました、対策としては.NETオブジェクトを利用するのが一番良い結果が出ていると思います。

# ハッシュの生成

## 変更前

- hash.tmp に生成したい文字列を格納
- certutil コマンドで生成したハッシュ値を $hash に格納

```
Write-Output "文字列" | Set-Content hash.tmp
$hash = (certutil -hashfile hash.tmp MD5)[1..1]
```

>（Get-FileHashコマンドがあるけどツッコミは無しで）

## 変更後

- ＄md5, $utf8 オブジェクトを事前に生成
- $hash にハッシュ値を格納

```
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$utf8 = new-object -TypeName System.Text.UT8Encoding

for ...
   $hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes("文字列")))
   $hash = $hash.Replace("-", "").ToLower()
```

# ファイル書き込み

## 変更前

- Write-Output で出力した内容
- パイプで受け取り、Add-Content でファイルに出力

```
Write-Output "文字列" | Add-Content hash.log -Encoding Unicode
```

## 変更後

- 事前に $file オブジェクトを生成
- $file の WriteLine を使ってファイルに出力

```
$file = New-Object System.IO.StreamWriter("hash.log", $false, [System.Text.Encoding]::GetEncoding("unicode"))

for ...
   $file.WriteLine("文字列")

$file.Close()
```

# 参考

- http://tech.guitarrapc.com/entry/2013/07/22/010759
- https://yomon.hatenablog.com/entry/2014/07/05/132818
- https://stackoverflow.com/questions/10521061/how-to-get-an-md5-checksum-in-powershell
- https://qiita.com/sukakako/items/ede96f6227f010a0f328

*よければ ブログ「[初心者向けUnity情報サイト](https://www.fast-system.jp/)」の方にも色々記載しているのでぜひご参照いただければと思います。*
統計の入門１

# はじめに
統計学を学び始めたばかりの筆者が学んだ統計学を学んだ順に書く．
まずは基礎の基礎．
Pythonとともに．

```python
import numpy as np
import scipy as sp
```

# 1. 平均値（期待値）

```python
sp.mean(data)
```

# 2. 標本分散

分散とは「データが平均値からどれほど離れているか」を表す指標．  
データサイズが小さいと標本分散の期待値は母分散より小さくなる．

```python
sp.var(data, ddof = 0)
```

# 3. 不偏分散

標本分散の持つ「分散を過少に見積もってしまうバイアス」をなくしたもの．  
一致性と普遍性を持ち，母分散を推定できる．

```python
sp.var(data, ddof = 1)
```

# 4. 標準偏差

分散は単位が2乗されており扱いづらいことから平方根をとって標準偏差として扱う．

```python
sp.std(data, ddof = 1)
```

# 5. 中央値

データを昇順に並べたときにちょうど真ん中に来る数値．
平均値は外れ値の影響を大きく受けるが，中央値は外れ値に頑健．

```python
sp.median(data)
```

# 6. 四分位点

データを照準に並び替えたときに下から25%にあたる点．

```python
from scipy import stats

stats.scoreatpercentile(data, 25)
```

# 7. 共分散

2種類のデータの関係性を示す指標．
共分散が

 - 0より大きい：片方の変数が大きい値をとればもう片方も大きくなる
 - 0より小さい：片方の変数が大きい値をとればもう片方も小さくなる
 - 0ちょうど：変数同士に関係性が見られない

```python
# データの取り出し
x = data["x"]
y = data["y"]
# サンプルサイズ
N = len(data)
# 平均値
mu_x = sp.mean(x)
mu_y = sp.mean(y)

# 共分散
cov = sum((x - mu_x) * (y - mu_y) / N
```

# 8. 分散共分散行列

複数の変数において，分散と共分散の一覧を行列の形式でまとめたもの．

```python
sp.cov(x, y, ddof = 0)
```

# 9. ピアソンの積率相関係数

共分散を最大値1，最小値-1に標準化したものとみなせる．
共分散は最大値や最小値がわからない．それでは使いにくいため，-1~+1の範囲に入るように補正する．

```python
# 分散の計算
sigma_x = sp.var(x,ddof = 1)
sigma_y = sp.var(y,ddof = 1)
# 相関係数
rho = cov / sp.sqrt(sigma_x * sigma_y)
```

# 10. 相関行列

複数の変数において相関係数の一覧を行列の形式でまとめたもの．

```python
sp.correct(x, y)
```
[small tips] realmを使ったプロジェクトにkotlinをインポートしたらMediatorが生成されなかった話

小ネタですが、Androidプロジェクトにkotlinをインポートしたところ、realm初期化時にクラッシュしてしまう現象が発生しました。

結果としては、gradleを変更したところ、解決しました。
しかし、ここに到るまでに中々原因らしい原因が分からず、大分ハマってしまいました。
（ググっても似たような問題が少ない）

以下、詳細です。

※ 11/21 13:10 gradleの記載に誤りがあったので修正しました。
 @sato-shin さん、ありがとうございます！

## 環境
・AndroidStudio　： 3.2.1
・gradle　：　gradle-4.6-all.zip、com.android.tools.build:gradle:3.2.1
・realm　：　io.realm:realm-gradle-plugin:5.1.0（少々古いのは気にしない）
・kotlin　：　1.3.10

## 発生した問題

```ruby:RealmException
Caused by: io.realm.exceptions.RealmException: Could not find io.realm.XxxxxMediator
        at io.realm.RealmConfiguration.getModuleMediator(RealmConfiguration.java:377)
        at io.realm.RealmConfiguration.createSchemaMediator(RealmConfiguration.java:351)
        at io.realm.RealmConfiguration$Builder.build(RealmConfiguration.java:826)

```

下記の様にrealmを初期化した際に発生します。

        Realm.init(context);
        RealmConfiguration config = new RealmConfiguration.Builder()
                .name(zzzzz)
                .schemaVersion(zzzzz)
                .modules(new Xxxxx())
                .migration(zzzzz)
                .build();

この時のgradleは以下。

```ruby:build.gradle(Project)
buildscript {
    ext.kotlin_version = '1.3.10'
    repositories {
        mavenCentral()
        google()
        maven { url 'https://maven.google.com/' }
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        xxxxx
        classpath "io.realm:realm-gradle-plugin:5.1.0"
        xxxxx
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
```
```ruby:build.gradle(Module)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'realm-android'
xxxxx
```



## 解決方法

gradleを以下の様に修正します。

```ruby:build.gradle(Module)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'  // 参考：https://realm.io/docs/java/5.8.0/
apply plugin: 'realm-android'
xxxxx
```

## ・・・ん？　アプリが上手く動作しないぞ・・・？

どうやら、上記の対策では不十分で、芋づる式にkaptを必要とする依存関係が出てきました。
発生したエラーは省略しますが、最終的には以下の設定になりました。

```ruby:build.gradle(Module)
dependencies {
-    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
+
+    def bkCompilerVer = '8.8.1'
+    annotationProcessor "com.jakewharton:butterknife-compiler:${bkCompilerVer}"
+    kapt "com.jakewharton:butterknife-compiler:${bkCompilerVer}"


-    annotationProcessor 'org.parceler:parceler:1.1.10'
+
+    def parcelerVer = '1.1.10'
+    annotationProcessor "org.parceler:parceler:${parcelerVer}"
+    kapt "org.parceler:parceler:${parcelerVer}"


     annotationProcessor "com.google.dagger:dagger-compiler:${daggerVersion}"
+    kapt "com.google.dagger:dagger-compiler:${daggerVersion}"
+    kaptTest "com.google.dagger:dagger-compiler:${daggerVersion}"
}
```

## 終わりに
同じ問題に苦しむ人が少しでも減ることを願っています。
テーブルに適用されているインデックスとそのカラムを調べる方法

Azure SQL Database に[自動チューニング](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-automatic-tuning)というのがあって、たくさんクエリーを投げると、パフォーマンスを改善するインデックスを特定し、自動で作成してくれる。ある程度はエンジニアで試行錯誤しながら事前にインデックスを作成できるが、それだけでなく、実際に運用に投入してから実際によくつかわれるクエリから勝手に作ってくれる。

かなり便利なんだけど、いったいどのカラムにどういったインデックスを作成してくれたのかを知りたくなったので、調べてみた。

SQL Serverではデータベースやデータベースサーバーに関する情報を提供するカタログビューというものがあり、その中にインデックスやテーブルの情報を持つビューがある。
それらを組み合わせることで、インデックスの名前とそれに関連するカラム名の一覧を取ることができる。

## 実際に使ったクエリ

```sql
SELECT
    indx.name    -- インデックス名
    , clmns.name -- インデックスのカラム名
FROM sys.index_columns AS indx_clmns
JOIN sys.indexes AS indx 
    ON indx_clmns.object_id = indx.object_id AND indx.index_id = indx_clmns.index_id
JOIN sys.columns AS clmns
    ON indx.object_id = clmns.object_id AND indx_clmns.column_id = clmns.column_id
WHERE indx.object_id = OBJECT_ID('dbo.users')
```



## 参考

* [Azure SQL Database - 自動チューニング | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-automatic-tuning)
* [カタログ ビュー (TRANSACT-SQL) | Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-catalog-views/catalog-views-transact-sql?view=sql-server-2017)
Ubuntu を Trusty (14.04 LTS) から Bionic Beaver (18.04.1 LTS) にあげたら Let's Encript の証明書の更新ができなくなった話

# 背景

[コレ](https://qiita.com/UedaTakeyuki/items/03322c4a5dff878ee01c)をしたくて Python3.6 が必要になり、Python のバージョンを上げるよりも Ubuntu のバージョンあげてしまうほうが楽だよな（実際、そのとおりなところが Ubuntu のいい所と Python の嫌なところなんですが）、という大胆な手抜きを行った所、掲題の件、痛い目にあいました
つきましては、ささやかながらも同様のご経験をされた方のお役に立つこともあるかもしれぬと思い、本稿を上梓させていただきました次第です

# 現象
```bash:
Requesting to rerun ./certbot-auto with root privileges...
Error: couldn't get currently installed version for /opt/eff.org/certbot/venv/bin/letsencrypt: 
```
Can't get currently version とか言われてます
ううむ、Ubuntu あげたのが悪かったか

# 対応
ダクダクって[文献1](https://yoshinorin.net/2018/09/10/letsencrypt-cannot-update/)を見つけ、書かれているとおりに ***certbot*** をインストール、ただし、かかれているように既存の certbot-auto を消したりはしませんでした（相変わらず怠惰）

```bash:
sudo apt install certbot
```

再度ためしてみると

```
ueda@scw-app1:~$ sudo certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/barcodelogger.uedasoft.com.conf
-------------------------------------------------------------------------------
Attempting to parse the version 0.27.1 renewal configuration file found at /etc/letsencrypt/renewal/barcodelogger.uedasoft.com.conf with version 0.23.0 of Certbot. This might not work.
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The requested apache plugin does not appear to be installed
Attempting to renew cert (barcodelogger.uedasoft.com) from /etc/letsencrypt/renewal/barcodelogger.uedasoft.com.conf produced an unexpected error: The requested apache plugin does not appear to be installed. Skipping.
```

apache plugin が見当たらないとの御宣託

で、さらにダクダクって[文献2](https://pandanote.info/?p=1225)をみつけ、書かれている通り ***python3-certbot-apache*** をインストール

```bash:
ueda@scw-app1:~$ sudo apt install python3-certbot-apache
```

再度、***renew*** をためしたら、今度はうまくいきました

# 感想
クリス・アンダーソン（TED の方じゃなくて、ロングテールの方の）がちょっと前に「私の人生の 1/3 は Python のバージョンの不一致に費やしている」ってツイートしてた[^1]のですが、大袈裟じゃないかも

[^1]: そう tweet してた記憶があるのですが、今、リンク貼ろうとおもって探したらみつけられませんでした。どうもすみません

# references
- 文献1: [Let's Encryptで証明書を更新できなくなったので再インストールして再発行した](https://yoshinorin.net/2018/09/10/letsencrypt-cannot-update/)
  - 16.04 から 18.04 にあげたら更新できなくなったというご報告
  - この記事のおかげで助かりました、ありがとうございました
- 文献2: [Let’s encryptの証明書の更新がうまくいかないと思ったら、Python3対応のApache pluginがインストールされていなかった件](https://pandanote.info/?p=1225)
   - こちらの記事のおかげで助かりました。本当にどうもありがとうございました
vbsの作法 その15

#概要

vbsの作法調べてみた。
定数調べてみた。


| 定数       |       値 |    内容    |
|:-----------------|:------------------|:------------------|
|vbOKOnly 	 |0 	| [OK]ボタンのみを表示します |
| vbOKCancel 	 |1 	| [OK]ボタンと[キャンセル]ボタンを表示します |
| vbAbortRetryIgnore 	| 2 |	 [中止]、[再試行]、および[無視]の３つのボタンを表示します |
| vbYesNoCancel 	| 3 |	 [はい]、[いいえ]、および[キャンセル]の３つのボタンを表示します |
| vbYesNo 	| 4 	| [はい]ボタンと[いいえ]ボタンを表示します |
| vbRetryCancel 	| 5 	| [再試行]ボタンと[キャンセル]ボタンを表示します| 
| vbCritical 	 |16 	| 警告メッセージアイコンを表示します |
| vbQuestion 	 |32 	| 問い合わせメッセージアイコンを表示します |
| vbExclamation |	 48 	| 注意メッセージアイコンを表示します |
| vbInformation |	 64 	| 情報メッセージアイコンを表示します |
| vbDefaultButton1 |	 0 	| 第1ボタンを標準ボタンにします |
| vbDefaultButton2 |	 256 	| 第2ボタンを標準ボタンにします |
| vbDefaultButton3 |	 512 	| 第3ボタンを標準ボタンにします |
| vbDefaultButton4 |	 768 	| 第4ボタンを標準ボタンにします |
| vbApplicationModal |	 0 	| アプリケーションモーダルに設定します。メッセージボックスに応答するまで、現在選択中のアプリケーションの実行を継続できません |
| vbSystemModal |	 4096 |	 システムモーダルに設定します。メッセージボックスに応答するまで、すべてのアプリケーションが中断されます |
|vbOK 	 |1 |	 [OK]ボタンが押された |
|vbCancel 	| 2 |	 [キャンセル]ボタンが押された |
|vbAbort 	| 3 |	 [中止]ボタンが押された |
|vbRetry 	| 4 |	 [再試行]ボタンが押された| 
|vbIgnore 	| 5 |	 [無視]ボタンが押された |
|vbYes 	| 6 	| [はい]ボタンが押された |
|vbNo 	| 7 	| [いいえ]ボタンが押された| 
| vbCrLf     | \r\n   | 改行  |
|vbLf| \n| ラインフィード|
|vbtab| \t| タブ|
|vbcr| \r| リターン|



以上。
python3でコードを自動実行する！

あなたはコードを書いてterminalをクリックコードを実行！またエディターをクリック！また・・・とかありませんか？
エディターにはスクリプト実行もありますが、モジュールの関連付けとちょっと面倒くさい！！
と私は思い、そこで自動実行のスクリプトを書こうと思い至ったわけです。

#　コード


ディレクトリ内のファイルを検索し、更新日を比較して更新されていたら比較ファイルが３０バイト以上のものを実行するようにしました。

現状のコードは無限ループにも対応してません。


```py

import os
import time
import re
import datetime
import subprocess as sp
# 実行コマンド
run_name = "python3"

class File_data:
    """ Get of data in the file """
    re_search = re.compile(".swp")

    def __init__(self):
        # ファイル名を取得
        self.file_name = [
            name for name in os.listdir() if (not re.search(name, "swp"))]
        # ファイルの名前と更新日時を辞書にする。
        self.file_time = {
            name: os.stat(name).st_mtime for name in self.file_name}

while True:
    # 比較用インスタンス
    data1 = File_data()
    time.sleep(5)
    # 比較用５秒後のインスタンス
    data2 = File_data()
    # ファイルを作成したときにエラーになるためファイルを作成したら戻る。
    if len(data1.file_name) != len(data2.file_name):
        time.sleep(1)
        continue
    for i in data2.file_name:
       # ファイルの更新日時に差異を検出
        if data2.file_time[i] != data1.file_time[i]:
           # ファイルが小さすぎると困るためサイズを最小指定
            if os.path.getsize(i) > 30:
                print(run_name, i)
                sp.call([run_name, i])


```
# あとがき
今回のコードだと無限ループだと上手くいきません。。
良いアイディアがありましたらお願いします。
Chrome DevTool の Network にクロスオリジンのCookieヘッダ等が表示されない件


ネタ元： [Chrome 67 - Cookies hidden in developer tools network tab](https://blog.ermer.de/2018/06/11/chrome-67-provisional-headers-are-shown/)

## 問題

CORS な設定がうまくいっていない場合にデバッグしたくてDevToolを開いてみたが、クロスオリジンなりソースのアクセスに対して Cookie 等のヘッダ情報が出てなくて辛い、なんとかしたい。

## 原因


最近の Chrome では "Site isolation" 機能が有効になっていてて、それが原因で、クロスオリジンでリソースにアクセスする際の Cookie 等のヘッダ情報が DevTool で確認できなくなっているらしい。


## 対処

以下のように、Site isolation 機能を無効化することで、クロスオリジンなリソースへのアクセスに対しても　Cookie 等のヘッダ情報をが確認できるようになる。

* `chrome://flags/#site-isolation-trial-opt-out`　を開く
* Site isolation trial opt-out が`Default`になっていると思われるので、`Opt-out`に変更
　　![image.png](https://qiita-image-store.s3.amazonaws.com/0/8219/e3d1489e-559d-6c3e-4383-d5ebd229a5fb.png)

* [ReLaunch Now] ボタンを押して　Chrome を再起動する

## 参考リンク

* [Chrome 67 - Cookies hidden in developer tools network tab](https://blog.ermer.de/2018/06/11/chrome-67-provisional-headers-are-shown/)
* [Site Isolation - The Chromium Projects](https://www.chromium.org/Home/chromium-security/site-isolation)
Laravel のクエリビルダで UPSERT を実装する

# Laravel のクエリビルダで UPSERT を実装する

マイグレーションファイル内で UPSERT を使いたかったが、なさげなので自分で実装した。

```php
public function up()
{
    // 多次元配列で UPSERT データを取得
    $seeds = $this->getSeedData();
    foreach ($seeds as $seed) {
        $record = \DB::connection('DB名')->table('テーブル名')->where('id', $seed['id']);
        $record->exists() ? $record->update($seed) : $record->insert($seed);
    }
}

private function getSeedData()
{
    return [
        ['id' => 1, 'memo' => '腰が'],
        ['id' => 2, 'memo' => '痛い'],
    ];
}
```

## Model ファイル内なら 

Eloquent でこういうことができるらしい

```php
// User モデル で id = 1 があったら第二引数で　UPDATE、なければ第二引数で INSERT
App\User::updateOrCreate(['id' => 1], ['hoge' => 1]);
```
DOM要素のスクリーンショットを撮る（２）pageres

DOM要素のスクリーンショットを撮る（DOM要素を画像に変換する）には幾つかの方法があるようですが、html2canvasはダメだったので、次にpageresを試してみました。

### npm install

`npm install pageres`します。

### コード

[DOM要素のスクリーンショットを撮る（１）html2canvas](https://qiita.com/pizyumi/items/c9a76a9d0cc545572adb)で作成したHTMLドキュメントのスクリーンショットを撮ってみることにしました。

```js
  new pageres({ format: 'jpg' })
    .src('http://localhost:3000/asset/test/test.html', ['1280x1024'], { selector: '.fitch' })
    .dest(__dirname)
    .run();
```

### 使ってみる

実際に使ってみます。

[DOM要素のスクリーンショットを撮る（１）html2canvas](https://qiita.com/pizyumi/items/c9a76a9d0cc545572adb)で作成したHTMLドキュメントをブラウザで表示すると下のようになります。

![fm11.jpg](https://qiita-image-store.s3.amazonaws.com/0/10969/b63c1c23-8201-238b-43e3-b4f96034df2f.jpeg)

そして、上のコードを実行すると、プログラムが格納されているフォルダに`localhost!3000!asset!test!test.html-1280x1024.jpg`という名称のJPEGファイルが生成されました。

このJPEGファイルは下のようなものでした。

![fm13.jpg](https://qiita-image-store.s3.amazonaws.com/0/10969/cc84597b-4b6e-b6e0-333d-b4256be21406.jpeg)

正しくスクリーンショットが撮れていることが分かります！
cssのアニメーションで、ヘッダー固定のアンカーリンクのズレを対応

#cssアニメーションだけで対応できる
※たまにただしく動かない？

```css:css
@-webkit-keyframes modify{
      0% { padding-top: ヘッダーの高さ; margin-top: -ヘッダーの高さ(マイナス); }
    100% { padding-top: 0; margin-top: 0; }
}
@keyframes  modify{
      0% { padding-top: 50px; margin-top: -50px; }
    100% { padding-top: 0; margin-top: 0; }
}

#セレクター:target {
    -webkit-animation: modify 0.1s;
    animation: modify 0.1s;
}
```
飛ばしたいアンカー先のセレクターを疑似要素:targetで指定
atcoder ABC61 C問題

ベルマンフォードを使わないと解けない問題だったので、解法をメモ

https://beta.atcoder.jp/contests/abc061/tasks/abc061_d

問題は、重み付き有効グラフで条件から、負のコストがあるのでダイクストラが使えず、ワーシャルフロイドもTLEに確実になるため使えない。そこで、ベルマンフォードを使いこの問題を解いていく。
まずベルマンフォードについてであるが基本的な方針はd[i]を始点から頂点iまでの最短距離とし、
for(int j;j <　頂点数;j++){
d[i] = min(d[j] + cost)
}
として最短距離を更新していく。雛形は下の通りである


```java

int V;          //頂点数
int E;          //辺数
Edge[] map = new Edeg()[V];     //グラフの作成
int d[] = new int[V];       //最短距離
 
		
		for(int i = 0;i < m;i++){
			v[i]=new Edge();
			v[i].from=sc.nextInt();
			v[i].to=sc.nextInt();
			v[i].cost=sc.nextInt();		
		}

		dis = new long[n+1];
		Arrays.fill(dis, INF);				//初期化
		dis[1] = 0;

		long ans = 0;
		int count = 0;
		
		while(true){
			boolean update = false;
			for(int i = 0;i < E;i++){
				if(dis[v[i].from]+ v[i].cost < dis[v[i].to]){
					dis[v[i].to]=dis[v[i].from]+v[i].cost;
					updata= true;
				}
			}
			if(!update){				//更新なかったら抜ける
				break;
			}
					
		}
		
```

この問題では、「ゴールまでの最大値を求めよ」となっているので、あらかじめコストをマイナスで読み込むことでベルマンフォードを適用できるようにしている。また、閉路の検出のために、カウンターをつけ、ベルマンフォードでは、whileループがへんの数しか繰り返さないことを利用し、カウンターが辺の数になった時、ゴールまでの最短距離が更新されているか否かでinfかどうかを判定している。
CloudFormationがまだ、ECS FARGATEのタスクeventsのtarget定義をサポートしていない件 => されました。

# CloudFormationがまだ、ECS FARGATEのタスクeventsのtarget定義をサポートしていないんですよね・・・。
でもある程度、自動化したいですよね。

※2018/11/20　現在

# 2019-09-12　現在　サポートされてました！！！！

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-ecsparameters.html

※英語ページのみ。日本語ページには反映されていない。

## サンプル
```
  ECSS3SyncTaskSchedule:
    Type: AWS::Events::Rule
    Condition: CreateS3SyncResources
    Properties:
      State: ENABLED
      ScheduleExpression: cron(0 16 * * ? *)
      Name: "適当な名前" 
      Targets:
        - RoleArn: "eventsで使うロール" 
          EcsParameters:
            TaskDefinitionArn: "タスク定義のARN" 
            TaskCount: 1
            LaunchType: FARGATE
            NetworkConfiguration:
              AwsVpcConfiguration:
                Subnets:
                  - "利用するsubnet1" 
                  - "利用するsubnet2" 
```


よって下記の内容は過去です。


## （以下は過去記事）代替案
CloudForamtionでイベントを作成した後、AWS CLI でターゲットだけ更新する

### 詳細
#### 1. jsonを準備する（ファイル）
サンプル
※以降 <文字列> は適当な内容に上書きください。 

```json:sample.json
[
        {
            "RoleArn": "arn:aws:iam::<アカウントID>:role/<ロール名>",
            "EcsParameters": {
                "TaskDefinitionArn": "arn:aws:ecs:ap-northeast-1:<アカウントID>:task-definition/<タスク定義名>",
                "TaskCount": 1,
                "LaunchType": "FARGATE",
                "NetworkConfiguration": {
                  "awsvpcConfiguration": {
                    "Subnets": [
                      "<subnetID>",
                      "<subnetID>"
                    ]
                  }
                }
            },
            "Id": "<ターゲットID>",
            "Arn": "arn:aws:ecs:ap-northeast-1:<アカウントID>:cluster/<クラスタ名>"
        }
]
```

#### 2. CLIコマンドで更新する
`aws events put-targets --rule <ルール名> --targets file://sample.json`


#### ■AWSリリース履歴
対応要望はたくさん来ているようなので、下記サイトをフォローすると良いらしいです。
https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/ReleaseHistory.html

以上です。
vagrant up/vagrant haltを自動化

# 目的
ローカル環境で開発をする際、いちいちpowershellを開いてディレクトリ移動してコマンドを打つのが面倒なので、batファイルを実行するだけでvagrantが起動したりシャットダウンするようにしたい。

# 環境
OS:windows10

# 起動版batファイル作成

```start.bat
cd (vagrantファイルのあるディレクトリ)

vagrant up
```

batファイルを実行するだけでコマンドプロンプトが立ち上がり、vagrantが起動するようになりました。
ちなみに最終行の先頭にcmd /kを記述すると、コマンドプロンプトが自動で閉じなくなります。

# 終了版batファイル作成

```close.bat
cd (vagrantファイルのあるディレクトリ)

vagrant halt
```

これで単純だけど少しめんどくさい作業を自動化することができました。

# 少し機能追加してみる
vagrantの起動や終了のみでもよいのですが、ついでなので起動時によく使うアプリも自動で立ち上げてくれるようにし、終了時には使っていたアプリを閉じるようにしてみます。

## 起動版
起動にはstartかcallを使います。

```start.bat
cd (vagrantファイルのあるディレクトリ)

vagrant up

start (起動させたいアプリ)
# call (起動させたいアプリ)
```

## 終了版
終了版はタスクリストから終了したいアプリを検索し、
アプリが起動していたときのみtaskkillを実行させるようにします。

```close.bat
tasklist | find (終了したいアプリ`rgb(255,0,0)`) > NUL

if not errorlevel 1 (
taskkill /IM (終了したいアプリ)
)

cd (vagrantファイルのあるディレクトリ)

vagrant halt
```

# おまけ(windows起動時にvagrantも立ち上げる場合)
作成したbatファイルをスタートアップフォルダに入れるだけでwindows起動時に実行してくれます。
スタートアップフォルダはwindowsキー+Rを押して「shell:startup」と検索すれば出てきます。
201811現在のzshのdockerコマンド補完について

# ネットでは
dockerのzsh補完として有名なレポジトリである[felixr/docker-zsh-completion](https://github.com/felixr/docker-zsh-completion)があるが、実はもうメンテされていない。
めでたい事に、本家の[docker/cli](https://github.com/docker/cli/blob/master/contrib/completion/zsh/_docker)に吸収されたようだ。

> Deprecation notice: This repository is not kept up-to-date any more. Please, switch to the ZSH completion from Docker directly.

余談だが、zshの性として1枚の補完ファイルにするのが必須のため、3000行を超えるとんでもない巨大なファイルに成長していることが印象的・・・。

# 使い方

普通にfpathに入れたければ`fpath`配下におけば良い
例えば`~/.zsh/completion`を新たに`fpath`として設定しようとすれば、

```bash
$ mkdir -p ~/.zsh/completion
$ curl -L https://raw.githubusercontent.com/docker/cli/master/contrib/completion/zsh/_docker > ~/.zsh/completion/_docker
$ fpath=(~/.zsh/completion $fpath)
$ exec zsh
```

とでもすればいい。

# 前みたいにzplugで設定したい。

前みたいに単体で管理されてないため`docker/cli`ごと持ってくる必要あると思うが、一応レポジトリ、そしてzplugとして管理したいのであれば無理やりやればいいと思う。

```bash
zplug "docker/cli", use:"contrib/completion/zsh/_docker"
```

`lazy:true` は設定しておく事をオススメしたい。
東京都の私立大学に在籍する障害者はどれだけ支援を受けられるか

# 東京都の私立大学に在籍する障害者はどれだけ支援を受けられるか

## 法的整備

- 2016/04/01施行の「[障害者差別解消法](http://www8.cao.go.jp/shougai/suishin/law_h25-65.html)」では、「事業者」に対しては「努力義務」に留めているが、
- 2018/10/01施行の「[東京都の差別解消条例](http://www.fukushihoken.metro.tokyo.jp/shougai/shougai_shisaku/sabetsukaisho_yougo/kaisyoujourei/sabetsu_kaisho_jourei.html)」では、事業者に対して「義務」とされている

## 事業者とは?

「東京都の差別解消条例」の第二条の二で「事業者」を定義。

```
事業者 法第二条第七号に規定する事業者のうち、都の区域内において商業その他の事業を行う者をいう。
```

「法第二条第七号」は、「障害者差別解消法」の次の規定を指す。

```
事業者　商業その他の事業を行う者（国、独立行政法人等、地方公共団体及び地方独立行政法人を除く。）をいう。
```

この事業者には、「学校法人」（私立大学など）も含まれるようである。

## 補助金は?

「[日本学生支援機構](https://www.jasso.go.jp/gakusei/tokubetsu_shien/guide_kyouzai/guide/kyotsu/kyotsu_hojokin.html)」に、次の記事がある。

```
障害のある学生を受け入れる大学等を対象に、
経常的経費に対する補助として日本私立学校振興・共済事業団が交付する私立大学等経常費補助金の一般補助において、
次により算定される額を加算しています。＜平成25年度＞

｛（障害のある学生の数×1,600千円）＋（障害のある学生に対する具体的配慮の取組数×400千円）｝×5/10×増減率（定員充足率等の状況により学部等ごとに131%～1％）

※	予算額との兼合いから、算定結果に一律の圧縮率を乗じることがあります。
※	参考：「私立大学等経常費補助金取扱要領・配分基準」
```

確認してみると、確かに、「[私立大学等経常費補助金](https://www.shigaku.go.jp/s_haibunkijun.htm) 」の「平成29年度 取扱要領・配分基準」の45ページに数字が記載されている。

## 合理的配慮をどう勝ち取れるか?

合理的配慮の合意形成のプロセスが、最終的な砦となる。

合理的配慮は「負担が重すぎない範囲」で対応するわけで、何をもって「負担が重すぎないのか」という合意形成が必要となる。

内閣府の「[合理的配慮提供における合意形成プロセス](http://www8.cao.go.jp/shougai/suishin/tyosa/h27kokusai/h3_3_5.html)」に少し記事があるが、日本におけるプロセスについては調べていないが、「[相談窓口](http://www8.cao.go.jp/shougai/suishin/sabekai.html)」はある。

最終的には、私立大学における私立大学等経常費補助金の「 **補助金の使われ方** 」がキーになると思うのだが、障害者はどこまで知る（開示要求する）ことができるのだろうか？
Google Cloud Functions/Pythonで引数のメソッド補完をしたい

2018年7月にGoogle Cloud FunctionsでPython 3.7がサポートされました（2018/11現在β版）。Flaskの関数を実装するだけでWeb APIが1個作れるので、特に小規模なサービスや小さな処理（Pub/Subからキックされる処理など）を書くにはもってこいのサービスだと言えます。

# Cloud Functionsの引数のメソッド補完ができなくて不便

ところで、Cloud Functionsの処理を書く際に、引数のメソッド補完が効かないのが個人的に気になりました。

具体的には、下記のような関数を書いた場合に`request`のメソッド補完が効きません。

```python
def hello_world(request):
    request_json = request.get_json()
    if request_json and 'message' in request_json:
        name = request_json['message']
    else:
        name = 'World'
    return 'Hello, {}!'.format(name)
```

この`request`の型は`flask.Request`なのですが、Cloud Functionsでは関数だけをポンと書く形になるので、補完が効かないのは当然といえば当然です。

# 解決策

この問題の解決策ですが、doccommentで型を明示した上でPyCharmを使うと無事補完が効くようになります。

```python
def hello_world(request):
    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>.
    """
    request_json = request.get_json()
    if request_json and 'name' in request_json:
        name = request_json['name']
    else:
        name = 'World'
    return 'Hello {}!'.format(escape(name))
```

もしくは下記のように指定することもできます。

```python
def hello_world(request):
    """
    :type request: flask.Request
    """
    request_json = request.get_json()
    if request_json and 'message' in request_json:
        name = request_json['message']
    else:
        name = 'World'
    return 'Hello, {}!'.format(name)
```

当初Emacs+Jediで同じことをやろうとしていたのですが、挫折してPyCharmに頼ることにしました…。

## PubSub用functionの場合

Pub/Subからキックされる関数についても次のように書くことで補完が効くはずです。ただし、私の手元には`google.cloud.functions.Context`が`pip install`されていないので補完が効きません。まだbetaだから公開されてないってことなんですかね…？

```python
def hello_pubsub(data, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.
    Args:
        data (dict): The Cloud Functions event payload.
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """
    import base64
    if 'data' in data:
        name = base64.b64decode(data['data']).decode('utf-8')
    else:
        name = 'World'
    context
    print('Hello {}!'.format(name))
```
ゲーム分析とUnityへの実装を探る

# はじめに
みなさんこんにちは。
今日でなんとAdvent Calendarが22日目ということ残り少なくなってきましたね。
関東Unityメンターのじゅんじゅんです。
普段からゲームを作ったり、ゲームの企画を重点的に考えていたりしています。

## 今日の記事について
今日は普段頭で考えている、
**「ゲーム企画・分析についてと分析した結果どのようなサイトを見れば実装できそうなのか」** ということを書いていきます。
これをみて、ゲームを作っていくヒントや新たな視点になってくれればと嬉しいです。

## どう分析していくか
実際リリースされているゲームを大きく2つに分けて、それらに当てはめてどこが面白いのか？どこをユーザーがついついやっちゃってしまうのかというのを分析していこうと思います。

【ゲームを構築する2つの要素】
- ゲームシステム・・・一番メインで遊んでもらいたいのかというゲームの軸の分析
- ゲームサイクル・・・どこを一番ユーザーに遊んでもらいそのサイクルが面白いかどうかの分析

他に沢山ありますが、今回はこの2つに実際落とし込んで分析していきます。
もし、それ以外になにか書きたいことがあれば書いていこうと思います。


## 【ゲーム】ポケモンGO
今回はポケモンGOをもとにゲームを分析していきます。
### ゲームシステム
![スライド1.JPG](https://qiita-image-store.s3.amazonaws.com/0/125038/94ae496f-96d0-1e96-be81-c3cf56899004.jpeg)


実際にフリックしてなにか得るというのがうまく出来ており、そこにゲームプレイの上手下手が出るようなゲームシステムになっている。
例えば、

- きのみを与えてポケモンを捕まえやすくしたり、
- モンスターボールを回転させることでカーブボール投げられるようになっていたり、
- うまく当てられるとGreatなどの評価を得られ捕まえやすくするなど

操作はたったのスワイプだけですが、スワイプしているだけで何故か楽しいという状況を作り出すことが出来ている。
私はゲームのなかでユーザーが一番多くするアクション自体(今回だとフリック操作)が気持ちよくかつ面白くかつプレイヤーの操作によって上手下手が出るような仕組みが出来ているゲームは好きなので企画する時はそこを重要視している。

### ゲームサイクル
![スライド2.JPG](https://qiita-image-store.s3.amazonaws.com/0/125038/e5549990-2c21-2bc3-73bc-065b41fe4268.jpeg)

ポケモンGOというゲームはポケモンを捕まえるためにゲームのサイクルが回っているといっても過言ではない。

①　ポケモンを捕まえるとレイド戦に行けるようになる。
②　しかし、レイド戦に行ってポケモンが弱ければすぐ負けてしまうので、強化したい。
③　しかし、ポケモンを強化するためにはポケモンを捕まえて、アメを集める必要がある。
(ポケモンを強化する方法としては、ポケモンを捕まえることによって強化用のトークンを得られる)

このサイクルをすることで、ポケモンを種類を集めつつ強化されたポケモンも得られるので、ユーザーにとっても満足感を味わうことが出来てもっとゲームしてみたいというような仕組みになっている。

ゲームではこのサイクルがうまくゲームシステムに噛み合いつつ、このサイクルがどれだけ気持ちよくできるのかというのも大事になってくることがすごくわかる。

### unityで実装するには?
ポケモンGOのゲームシステムを作るには

- ARで表示しつつ、ポケモンを表示
- フリック操作
- ボールを投げる

【AR】
最近ではARでオブジェクトを表示させる方法がたくさんあり、
おすすめなのは
ARkit・・・https://alaki.co.jp/blog/?p=2896
ARCore・・・https://unity3d.com/jp/partners/google/arcore

これら２つはマーカーを必要とせず自然と平面と3次元空間を把握することができる

【フリック】
次にフリック操作は
https://qiita.com/pilkul/items/e8864882b3f7e59b05e3
この記事が優秀かなと

【投げる】
最後はボールを投げるのは、フリックの方向をとって
Addforceで力を加えて上げれば行けると思います。
https://docs.unity3d.com/ja/2017.4/ScriptReference/Rigidbody.AddForce.html

多分これらを組み合わせれば作れると思います。

## まとめ
実装するのは企画が決まれば簡単だが、企画はゲームシステムを考えたり、ゲームサイクルを考えなければならなくなおかつそれらが面白くなければならないという少し大変な仕事ですが、全て噛み合ったときは作るのが楽しいし、早く人にやってもらいたくて実装も頑張れちゃうという最高の開発サイクルができますね。

この記事を見て少しでもゲームの見方やゲームの作り方の参考にしてもらえればと思います。

次は23日目！明日の記事をたのしみにしていきましょう！
ではではこの辺で...

最後まで見てくださってありがとうございます。
OculusGoのコントローラ入力とキャラクター移動

# 概要

OculusGoでのキャラクター移動関連についてまとめる。

# 初期設定

- [UnityではじめるOculus Go VRアプリ開発 (Mac OS) - Qiita](https://qiita.com/shiruco/items/435bce396c42f764e4ae) をやる
- AssetStore で Oculus Integration の追加
- MainCamera を削除し、OVRCameraRig を追加する
- OVRCameraRig の子にキャラクターを配置

# コントローラの入力について  

入力の受け取りは下記の通り。

```csharp
// 押下げた瞬間
OVRInput.GetDown

// 押上げた瞬間
OVRInput.GetUp

// 押している間
OVRInput.Get
```

キーコードは下記の通り。

```csharp
// トリガー
OVRInput.Button.PrimaryIndexTrigger

// 戻るボタン
OVRInput.Button.Back

// タッチパッド
OVRInput.Button.PrimaryTouchpad

// タッチパッドに触れている
OVRInput.Touch.PrimaryTouchpad

// タッチされた座標 (Vector2)
OVRInput.Axis2D.PrimaryTouchpad
```

例えば、トリガーを押した瞬間に何かしたければ下記のようになる。

```csharp
if (OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger)) {
    // 処理
}
```

# 移動の仕組みについて

タッチパッドの入力を検知したら、どの部分が押されたかを取得する。
その後、押された部分によって移動方向を確定する。

1. タッチパッド入力検知
2. タッチされた座標を取得
3. 上下左右のどの部分が押されたかを判定
4. 上下なら移動量、左右なら回転量を取得
5. 取得した移動量と回転量を OVRCameraRig に追加する

入力検知は下記の通り。

```csharp
if (OVRInput.Get(OVRInput.Button.PrimaryTouchpad) { }
```

タッチされた座標の取得は下記の通り。

```csharp
Vector2 pt = OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad);
```

上下左右のどの部分が押されたかの判定は下記の通り。

```csharp
// 方向を enum で定義しておく
public enum ControllerDirection {
    Front,
    Right,
    Back,
    Left,
    None
}

// 移動座標を取得するメソッドを用意
private ControllerDirection FetchDirection(Vector2 pt) {
    if (pt.x < -0.5 && -0.5 < pt.y && pt.y < 0.5) {
        return ControllerDirection.Left;
    }
    if (pt.x > 0.5 && -0.5 < pt.y && pt.y < 0.5) {
        return ControllerDirection.Right;
    }
    if (pt.y < -0.5 && -0.5 < pt.x && pt.x < 0.5) {
        return ControllerDirection.Back;
    }
    if (pt.y > 0.3 && -0.5<pt.x && pt.x<0.5) {
        return ControllerDirection.Front;
    }

    return ControllerDirection.None;
}
```

移動量と回転量の取得は下記の通り。

```csharp
// キャラの移動量を取得
public Vector3 FetchMoveVector(Vector2 pt) {
    switch (FetchDirection(pt)) {
        case ControllerDirection.Front:
            return new Vector3(0, 0, 0.5f * Time.deltaTime);
        case ControllerDirection.Back:
            return new Vector3(0, 0, -0.5f * Time.deltaTime);
        default:
            return new Vector3(0, 0, 0);
    }
}

// キャラの回転量を取得する
public float FetchMoveAngle(Vector2 pt) {
    switch (FetchDirection(pt)) {
        case ControllerDirection.Right:
            return 30f;
        case ControllerDirection.Left:
            return -30f;
        default:
            return 0f;
    }
}
```

取得した移動量と回転量の追加は下記の通り。

```csharp
// 移動量の追加
Camera.transform.Translate(FetchMoveVector(pt));

// 回転量の追加
float angle = _characterMoveCalculator.FetchMoveAngle(pt);
Camera.transform.rotation *= Quaternion.Euler(0, angle, 0);
```

# まとめ

移動と回転の仕方の正解はイマイチ分かっていない為、間違い等があれば指摘して頂けると幸いです。
(SD)第六弾 SAPー訓練「受注伝票一覧１」

:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)
#１．ゴールのイメージ　
#１．１選択画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185058/22431ff6-517b-e14f-e13c-e9ccfe2d3de6.png)

#１．２一覧画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185058/786914ef-d836-ade5-4825-50515f2bca70.png)

#２．機能分解
##２．１選択画面ー選択条件
##２．２受注一覧
##２．３在庫照会（TrCd:BMBC）
##２．４所要量一覧（TrCd:MD04）

#３．技術分解
##３．１Report
##３．２ALV/GUI
##３．３BatchInput/BDC
##３．３ダウンロード

#４．サンプル
```ruby:ABAP

```
:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)
故障してそうなディスクからデータを取り出す方法(ddrescue)

# 背景

ハードディスクから異音が聞こえ(約5年稼動しっぱなし)はじめました。
特に重要データがあるわけでもなかったので冗長化していない。
が、念のためバックアップを取ろうと思った今日この頃。
そこでddrescueなるものを最近知ったので使ってみました。

公式マニュアルは下記
[GNU ddrescue Manual](https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html)

# 対象読者

* 壊れかけのHDDからデータをバックアップしたい人

※物理障害のおきているHDDを修復するわけではありませんので注意！

# ddrescueとは

> GNU ddrescue（グヌー　ディーディーレスキュー）は、主に不良セクタのあるハードディスクドライブ (HDD) からのデータの救出に使われる、UNIX上で動作するフリーソフトである。macOSでも動作する。開発者はAntonio Diaz（アントニオ・ディアス）。

[wiki](https://ja.wikipedia.org/wiki/Ddrescue)より引用

長々と書いてあるが要約すると不良セクタのあるHDDからのでデータの救出に使われるツールです。

コピー用のツールにddは有名です。しかしddコマンドは不良セクタのある媒体からの読み出しが苦手であり、ストールなどが発生したりする。そもそも正常媒体を想定したコマンドなので当然といえば当然。

その点ddrescueでは不良セクタに当たるとその箇所をマークしスキップしてコピーを行う。
スキップした箇所は最後に再度読み込むといった形で処理を行う。

このときコピーのログはファイルに残るので途中で処理が中断した場合でも前の場所から再開することができる。

また、fillモードという動作モードもありデバイスの特定の箇所をあるパターンで埋めつくすといった事も出来る。
(ddとの違いは「不良箇所のみ」といった範囲指定が出来る点である)

# ddrescueメリット

メリットは以下3点

* 不良セクタを発見したらスキップし、不良セクタの位置がログに出力される
*  一旦全部書き出した後、ログに残った不良セクタだけを再度処理してくれる
* どのファイルが不良セクタの被害を受けたかが分かる


# 使い方/オプション

|オプション|概要|
-----------|----
-f         |上書き※ターゲットが物理ディスクでは必須
-n         |リードエラーを無視
-v         |詳細表示
-r         |不良セクタの再読み込み回数
-d         |ダイレクトアクセス(キャッシュを介さずにアクセス)

コマンドイメージは下記のようになります。

``` bash
$ ddrescue -f -d -r1 -v /dev/sda /dev/sdb logfile.log
```


# 導入/実行

``` bash
# インストール方法は下記.GNU版を入れるためパッケージ名は「gddrescue」
$ sudo apt-get install gddrescue

# 実行.オプションは下記を参照してください.
$ ddrescue -r 3 /dev/sdc /dev/sde rescue.log

Press Ctrl-C to interrupt
Initial status (read from logfile)
rescued:         0 B,  errsize:       0 B,  errors:       0
Current status
rescued:   500107 MB,  errsize:       0 B,  current rate:   110MB/s
   ipos:   499466 MB,   errors:       0,    average rate:   120MB/s
   opos:   499466 MB

```

# まとめ

壊れかけのHDDからデータを救い出す方法を記載しました。
ただし完璧で救えるわけでは無いので注意が必要です。
そもそも壊れかける以前に壊れても良いように冗長化ないし、
バックアップは普段から取りましょうってお話ですね。
(学生時代そんなお金は無かった。。。)
（高）第三弾 SAPー訓練「購買依頼～」

![MM.png](https://qiita-image-store.s3.amazonaws.com/0/185058/4cb9306b-24ec-1d2a-9c8d-e80e26d45b65.png)

#購買依頼
TrCd:ME51N（登録）　ME52N（変更）　ME53N（照会）
       ⬇️
#見積依頼
TrCd:ME41N（登録） ME42N（変更） ME43N（照会)
       ⬇️
#購買発注
TrCd:ME21N（登録） ME22N（変更） ME23N（照会）

#供給元一覧
TrCd:ME01（登録） ME02（変更） ME03（照会）

#購買情報マスタ
TrCd:ME11（登録） ME12（変更） ME13（照会）



#購買分納契約
TrCd:ME31L（登録） ME32L（変更） ME33L（照会）

#購買基本契約
TrCd:ME31K（登録） ME32K（変更） ME33K（照会）





Table:
EBAN（購買依頼）　EBKN（購買依頼情報）
[Python] OpenPyXLのadd_imageでExcelオープン時にエラーが出る場合の対処法

OpenPyXLを使ったExcelへの画像貼り付けでExcelファイルの修復エラーが出た際に難儀したのでその対処方法を残します。

# サンプルコード
```bash
～～～
img = px.drawing.image.Image("sample.xlsx")
ws.add_image(img,'A1')
wb.save('sample.xlsx')
```

# エラー
```bash
'sample.xlsx'の一部の内容に問題が見つかりました。可能な限り回復しますか？ブックの発行元が信頼できる場合は、「はい」をクリックしてください。
```

# 対処法
OpenPyXLのバージョンを確認する。

```bash
>pip show openpyxl
Name: openpyxl
Version: 2.5.1
Summary: A Python library to read/write Excel 2010 xlsx/xlsm files
Home-page: https://openpyxl.readthedocs.io
Author: See AUTHORS
Author-email: charlie.clark@clark-consulting.eu
License: MIT/Expat
Location:
Requires: jdcal, et-xmlfile
Required-by:
```

OpenPyXLのバージョンが低いと上記のエラーが出ます。
最新バージョンのOpenPyXLをインストールすることで上記エラーを回避できます。

```bash
>pip install openpyxl==2.5.9
```
PHPと死のvendor PHP案件でvendorを魔改造するバッドノウハウに対抗する


# この記事は [闇の魔術に対する防衛術 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/yami) の4日目の記事です。

昨日は　@teradonburi さんの [Headless CMSとWordPressの囚人](TODO) でした。

# TL;DR
forkしたリポジトリをcomposer.jsonにrepositories を追加する

# 愚痴

引き継いだ案件やよく分かってない開発者がvendor以下のライブラリを書き換えてgitに突っ込んできた事って有りませんか？
私は年1,2回あります。composer update とか出来なくて困る。アップデート後コンフリクトすると大変
そんな死んだvendorを解放するための防衛術を教えます。

# 本題

ライブラリを改変したいときってどういう時でしょうか

- バグがある
- 機能が足りない
- ~~エラるので取りあえず　try catch を埋める　（←やめて~~

思いつく限りでよく遭遇するのはこんな感じです。
バグがある場合は素直に該当ライブラリをforkしてプルリクを送りましょう。
機能が足りない場合も、forkしてプルリクするのがいいですが、プロジェクトの方針によって採用されない機能だったり
メンテナンス期間のバージョンには取り入れてもらえない事もあるでしょう。
また、バグ修正もそうですが、ノーメンテリポジトリの場合はマージされることはないでしょう
~~（そもそもそういうライブラリは採用しない）~~

そんな時、どうすれば良いか。

1. 魔改造したライブラリをgithubにアップする
2. composer.json に repositories を追加する [方法はこちら](https://qiita.com/mokemokechicken/items/d3a3944bfa999c2582b7)
3. repositoriesに書いた方が優先して読み込まれる。同名でも自分で登録した物が利用される
4. できれば魔改造したライブラリはfork元にアップデートを追従させる

という感じでオレオレライブラリとして公開して対応しましょう！

もちろん、できれば

- サポート切れのライブラリは使わない（フレームワークとか特に）
- ノーメンテっぽいライブラリは避ける

ことを先にやった方が良いと思います！

明日は @neutron63zf さんの 投稿です！
Watson Discovery操作 基本編　-APIによる関連度学習

# 前提
IBM Watson™ Discovery サービスでは関連度学習の機能を使用して、自然言語照会の関連性を改善することができます。Discovery ツールまたは Discovery API のいずれかを使用して、学習させることができます。ここでは、APIを使用した関連度学習について記載します。

# 準備作業
最初に以下の情報を用意します。

- username/password：Discoveryサービス資格情報から取得
- environment_id/collection_id：Discoveryのcollection画面から取得
- natural_language_query：学習させる検索文（”XXについて教えて”etc）
- document_id：評価するドキュメントのID
- relevance：関連性を示す整数値

relevanceフィールドは以下についても参照してください。
>[API を使用した結果関連性の改善](https://console.bluemix.net/docs/services/discovery/train.html#api-)
>>・relevance: 照会とトレーニング・データとの相対的な関連性を示す、0 から 100 までの範囲の整数。値が大きいほど、関連性が高くなります。値 0 は照会への関連性がないことを示し、値 100 は照会への絶対的な関連性を示します。

>>注: relevance パラメーターの範囲は、最大の柔軟性を確保にするために 0 から 100 になっていますが、例のスコアリングを単純化するためにもっと小さい範囲を使用できます。0 から 4 までを標準範囲にしたり、範囲全体を使用するものの 20 ずつの増分 (0、20、40、60、80、および 100) のみを使用するようにしたりできます。Discovery ツールは、関連性スコア 0 を使用して関連性なし を表し、10 で関連性あり を表します。Discovery ツールと API の両方を使用して文書のスコア付けを行うことを計画しているか、または、API から始めてツールに移行することを計画している場合は、この 0 および 10 の関連性スコアを使用してください。

# コマンドの実行

準備作業で用意した情報を以下のコマンドに反映して実行します。

```rb
curl -X POST -u "{username}":"{password}" -H "Content-Type: application/json" -d
'{
  "natural_language_query": "{natural_language_query}",
  "examples": [
    {
      "document_id": "{document_id}",
      "relevance": "{relevance}"
    }
  ]
}' "https://gateway.watsonplatform.net/discovery/api/v1/environments/{environment_id}/collections/{collection_id}/training_data?version=2018-10-15"
```

コマンド実行例

```rb
curl -X POST -u "username":"password" -H "Content-Type: application/json" -d
'{
  "natural_language_query": "XXについて教えて",
  "examples": [
    {
      "document_id": "adaf50f1-2526-4fad-b670-7d6e8a42e6e6",
      "relevance": 10
    },
    {
      "document_id": "63919442-7d5b-4cae-ab7e-56f58b1390fe",
      "relevance": 0
    }
  ]
}' "https://gateway.watsonplatform.net/discovery/api/v1/environments/{environment_id}/collections/{collection_id}/training_data?version=2018-10-15"
```

上記の例では、コマンド中に検索文と文書に対する評価を入れていますが、Windowsで日本語を入れてコマンドを実行すると、文字化けしてしまうため、curlコマンドの「-d」の中身を別ファイルで作成してコマンドを実行することで文字化けを無くせます。

以下のようなjsonファイルを用意します。

```json:training.json
{
  "natural_language_query": "XXについて教えて",
  "filter": "text:criminology",
  "examples": [
    {
      "document_id": "adaf50f1-2526-4fad-b670-7d6e8a42e6e6",
      "relevance": 10
    },
    {
      "document_id": "63919442-7d5b-4cae-ab7e-56f58b1390fe",
      "relevance": 0
    }
  ]
}
```

Windows環境で実行するコマンド

```rb
curl -X POST -u “{username}”:“{password}” -H “Content-Type: application/json” –d @{ファイル名} "https://gateway.watsonplatform.net/discovery/api/v1/environments/{environment_id}/collections/{collection_id}/training_data?version=2018-10-15"
```

注: curlコマンドの内容は更新される可能性があるので必要に応じてAPIリファレンスの「Add query to training data」の情報を参照するようにしてください。
[APIリファレンス](https://console.bluemix.net/apidocs/discovery)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/318053/8a95dfe5-0e8e-7053-8e56-73b988786172.png)

# 参考情報
[APIリファレンス](https://console.bluemix.net/apidocs/discovery)
[API を使用した結果関連性の改善](https://console.bluemix.net/docs/services/discovery/train.html#api-)
Scrapbox の ランダム機能がサービス性質を表していて、素晴らしすぎる。(UI/UX/サービス設計)

# 例

右側のRandomボタンを押すと、さくっと高速に他のページに飛べる。

触ってみなければ実感できないかも。

[ScrapBox はじめました – 稲浦悠馬 YumaInaura - 稲浦悠馬 いなうらゆうま Yuma Inaura](https://scrapbox.io/yumainaura/ScrapBox_%E3%81%AF%E3%81%98%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F_%E2%80%93_%E7%A8%B2%E6%B5%A6%E6%82%A0%E9%A6%AC_YumaInaura)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/9cb21da0-41db-a320-490d-94fd9f95931a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/4782605f-39e4-9abc-fa34-08752d94b53b.png)

# どこがすごいの？

「スクラップボックス」というサービス設計を完全表現している感じがした。

# サービスイメージ

その名の通り、たくさんの雑然としたものたち入っている箱がある。ランダムジャンプ機能はその箱から「ガサゴソ」ってして、1枚を引き抜くイメージ。


# link

- [scrapbox yumainaura - Google Search](https://www.google.co.jp/search?q=scrapbox+yumainaura&oq=scrapbox+yumainaura&aqs=chrome..69i57j69i60l3j69i64.2727j0j7&sourceid=chrome&ie=UTF-8)









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
クリスマスなのでdocomoの雑談対話APIでお話ししてみた（検証）

# 趣旨
前からdocomoのAPIが気になっていて、なおかつ #学生LT のアドベントカレンダーの記事も書いてなかったので採用しました。
今回使用するのはNTT docomoが提供している雑談対話API。詳しくは[これ](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4_usage_scenario#tag01)参照。
なお今回はアドベントカレンダー企画として対話をするだけの記事←!?になりますので、やり方は後日書きます。

# 今回の設定

### フォーマット設定↓
今回はこっちからの発言は以下のように
`おはようございます`

システムから返ってくる発言は
> おはよう

これで書こうかと思います

### ストーリー設定↓
クリスマスの今日はぼくの誕生日でもある。今日はネットで知り合った彼女と初めて会う日だ。このまま告白できればいいんだけどなぁ...。

### 設定一覧↓
設定はクリスマスが誕生日の高校２年生という設定で行く。そのほかは適当に決めた
ぼくは彼女歴０なので話す言葉が思いつかなかったので適当に考えた言葉を発言しています笑

|key|value|
|:--|:----|
|nickname|Keitan|
|nicknameY|けいたん|
|sex|男|
|bloodtype|A|
|birthdateY|2001|
|birthdateM|12|
|birthdateD|25|
|age|17|
|constellations|山羊座|
|place|東京|
|mode|dialog|

## 注意
今回はシステムが言ってきた文章には合わせずに話が逸れてもそのまま進みます。

# いざ実戦

`はじめまして`
>お役に立てるよう、がんばります。

`ぼくに会っての印象はどうですか？`
>ご想像にお任せします。

`ここで話すのも寒いのでどこか行きませんか？`
>それは、それは！　さっき、お腹について話しましたよね？Keitanさん、笑える映画で気分を変えてもいいし、泣ける映画でとことん泣いてみるのもいいですよ。

`どこに行きたい？`

>泣で寝ますよねー

`じゃあレストランでも行こうか`
>自分の好みのレストランを見つけておくと、友だちと食事のときも困らないよね。

**(レストラン着)**

`好きなもの頼んでいいよ`
>友だちはいいですよねー

**(食事中)**

`先に食べていいよ`
>泣で寝てますか？

`今言うのもだけど実はぼく今日が誕生日なんだよね`
>2月29日生まれの人は4年ごとに誕生日会をやるのかな。

`一人ぼっちで辛い`
>一人ぼっちで泣くそうですよ

`でも君がいるから今年は一人じゃないよ！`
>一人ぼっちがいいですね

`急なんだけど大事な話いい？`
>私も大好きです！

`ぼくと付き合ってください！`
>今度やってみます


# 検証結果
先に告白されました。
現実の彼女を作りましょう。
link_toでPOST指定する時にパラメーターを渡す方法

# link_toで値を渡して、methodも指定したい時
メソッドを指定してviewからcontrollerに値を渡すときに

```rb
<%= link_to "hoge", controller "users", action "update", user_id: 1, method: :post %>
```

このコードだとmethod: :postを上手く読み取ってもらえず、なぜかリクエストがGETになってしまった。

そのため

```rb
<%= link_to "hoge", {controller: "users", action: "update", user_id: 1}, method: :post %>
```

このようにメソッドだけ括弧で分けてあげると無事に動作しました。
分けてあげないとmethod: :postもパラメーターと勘違いされちゃうんですね


名前付きルートの場合の記述の仕方がまだ分かっていないため、どなたかコメントで教えて頂けたら嬉しいです。