OmniAICreator/Qiita-1.07M huggingface dataset:
コマンドラインで medium.com に投稿できるツールを作りました #golang #medium

# リポジトリ
https://github.com/knsh14/medium-cli

# 使い方
3つのサブコマンドがあります

* init
* create DIR
* push DIR

## init
名前通りイニシャライズするためのコマンドです
ホームディレクトリに `medium.toml` というファイルを作成します。
作られたら `user.token` に自分の Integration Token を書き込んでください。
このトークンは https://medium.com/me/settings の Integration Token の項目で取得できます。
workspace が init を叩いた時のカレントディレクトリになっているので、気になる人は編集してください。このディレクトリを基準にして次のコマンドは動作します。
ここを git 管理しておくと都合がいいのではないでしょうか

## create DIR
workspace に指定されたディレクトリの中に DIR で指定された名前のディレクトリを新規に作成します。
その中に info.toml と content.md を作成します。
info.toml にはタイトルとか諸々設定してください
初期には書いてないけど、Licenseとかも設定できます。
分けた理由は 文章を書く markdown ファイルに余計な情報をもたせたくなかったから。
もしかしたら以下の書式のほうが良かったかもしれないけど、パースするのが大変になりそうだし、別ファイルに分けたほうが色々見やすくていいと思ってます。

```
title = hoge
tags = [aa, bb, cc]
---
# header
...
```

## push DIR
DIR で取った名前のディレクトリの中の内容で medium に投稿します。
一応投稿する前に必要なものはチェックするけど、値が入っているかくらいしか見てないのでもう少しちゃんとチェックしないとなーとは思っています。
CreatePost API を叩く前に token からわかるユーザ情報を取得する API を叩いているんですが、毎回叩くのは効率が悪くてやめたいですね。
初回に叩いた時の情報を init で作成したファイルに書き込んでおけばいい気がしています。
投稿に成功すると最後に URL が出るようにしてあるのでコピーしてアクセスして下さい。


# 動機
もう少し長い文章を書こうと思ってサービスを色々探していたところ medium は良さげなサービスだなと思って登録してみました。
けどいかんせんブラウザで Markdown を使って書く方法がわからなかったので長い文章は書きづらいなーって思って放置していました。
ただ最近長い文章を書きたいことが増えてきたので思い切って自分好みのツールを作るようにしました。


# medium API への文句
* username と userID が違うの割りと厳しいですね。
    * medium には以下の3つのユーザを表す情報があってもう少し楽に投げたい
        * userID => ハッシュっぽい真にユーザを特定するためのもの。変更不可、ブラウザからは調べる方法がない
        * username => knsh14 のようなメンションを飛ばしたりするような場合に使われる感じのユーザ名。他のユーザとかぶらなければ変更可
        * user => kenshi kamata のような名前 変更可、かぶってもOK
* integration token だけで動作するようにできたのは楽だった
    * ただこれで使えるAPIが少なすぎてちょっと厳しい
FinalIK(VRIK)でワープ移動時に足が伸びてしまう問題の解消方法

# :gear: 環境
## :tools: 開発環境
* **Unity5.5**
  * 5.6にはRectTransformとCanvasのバグがあったので使ってないです
* **OculusRift**
* **PhotonNetwork**

## :package: Asset
* [**FinalIK(有償）**](https://www.assetstore.unity3d.com/jp/#!/content/14290)
* [**Unity-chan（無償）**](http://unity-chan.com/) ※2017/6/12現在アセットストアのはバージョンが古かったので公式からダウンロードするのがいいと思います
* [**Oculus Utilities for Unity 5（無償）**](https://developer.oculus.com/downloads/package/oculus-utilities-for-unity-5/)
* [**PhotonUnityNetwork（無料プランもあります）**](https://www.assetstore.unity3d.com/jp/#!/content/1786)

# :mount_fuji: やりたかったこと
* **Unity-chan**をOculusRiftで手と頭のトラッキングをして、コントローラーで**ワープ移動**（VRでよくある移動先をコントローラーで指し示して一瞬で移動する方法）できるようにする
* またアナログスティックで前後移動と左右の回転もできるようにする
* トラッキングはOVRCameraRigをつかって問題なく動作できた
* Unity-chanにはFinalIKの**VRIK**、PhotonViewとPhotonTransfromViewのコンポーネントをアタッチしてPhotonViewでPhotonTransformViewをObservedComponentsに入れていた
* それをネットワーク上で同期させたい

# :scream: 問題
## 現象
* Unity-chanをA地点からB地点にワープさせるとA地点に**足が地面にくっついたままびよーんと伸びてしまう**

# :alembic: 解決方法
## 足が伸びてしまう問題の解消
* リファレンスに載ってないのでVRIKのスクリプトから処理を追っていくと、**IKSolverVR** にReset関数が用意されており以下のようにコメントされていたのでこれを使うことで解消した

> Resets all tweens, blendings and lerps. Call this after you have teleported the character.

* ローカルでは移動処理後に `Reset()` を呼び出すと自然な動きになった

## ネットワーク上で互いに移動すると足が伸びてしまう問題の解消
* はじめは自身のワープ処理後にRPC経由で `Reset()` を呼び出したが、同期がうまくあわないのか（？）うまくいかなかった
* `PhotonTransformView` を使うのをやめて、`PhotonView` の `OnPhotonSerializeView` で `Transform` を同期し、Updateの `!PhotonView.isMine` の中で同期を行うように変更し、その中で移動距離に応じて、アナログスティック移動とワープ移動を理由、ワープ移動内でのみReset処理を呼び出した

```C#
    void Update() {
        if (photonView.isMine) {
          // do anything
        } else {
            float distance = Vector3.Distance(transform.position, currentPosition);
            if(distance > 1.0f) {
                transform.position = currentPosition;
                VRIK ik = GetComponentInChildren<VRIK>();
                if (ik != null) {
                    ik.solver.Reset();
                }
            } else {
                transform.position = Vector3.Lerp(transform.position, currentPosition, Time.deltaTime * 5);
            }            
            transform.rotation = Quaternion.Lerp(transform.rotation, currentRotation, Time.deltaTime * 5);
        }
    }

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
        if (stream.isWriting) {
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        } else {
            currentPosition = (Vector3)stream.ReceiveNext();
            currentRotation = (Quaternion)stream.ReceiveNext();
        }
    }
```

* ちなみにMonoBehaviorのUpdateの中で `Reset()` 呼んだらどうなるか試してみましたが、足とかが常に軸回転してしまうのでやめたほうがいいです :stuck_out_tongue_winking_eye:

うまい方法がほかにあればご教授いただけるとうれしいです:smiley:
馬鹿の一つ覚え: Linuxユーザ管理

#### ユーザ番号やグループ番号を指定した新規アカウント作成
```
# groupadd -g 9742 dave    # まずグループ作成
# tail -n1 /etc/group    # 確認
dave:x:9742:
# useradd -g 9742 -u 9742 dave    # ユーザ作成
# tail -n1 /etc/passwd    # 確認
dave:x:9742:9742::/home/dave:/bin/bash
# ls -ld /home/dave    # ホームディレクトリを確認 (Debian系で作られていなかったらmkdir and chown)
drwx------ 3 dave dave 92 Mar 24 23:10 /home/dave
# passwd dave    # 初期パスワードの設定
# id dave
uid=9742(dave) gid=9742(dave) groups=9742(dave)
```

#### ユーザに管理者権限を付与
```
# usermod -aG wheel dave    # アカウントdaveでloginしてsudoできることを確認 (Red Hat系)
# usermod -aG sudo dave    # アカウントdaveでloginしてsudoできることを確認 (Debian系)
# gpasswd -a dave sudo    # コマンドgpasswdを使う場合
# grep -e wheel -e sudo /etc/group    # 確認
# gpasswd -d dave wheel    # グループwheelから削除
```

#### ホームディレクトリの変更
```
# usermod -d /net/gpfs/home/dave dave
# tail -n1 /etc/passwd    # 確認
```

#### ホームディレクトリを作らずにアカウント作成
```
# useradd -M -g 9742 -u 9742 dave
```

#### 新規グループを作成しユーザを追加
Linuxに新規グループtigressをグループ番号21212で作成し、既存ユーザaliceとbobおよび新規ユーザcarolとdavidの4つを追加してみる。

```
$ sudo groupadd -g 21212 tigress
$ sudo groupadd -g 21203 carol
$ sudo useradd -g 21203 -u 21203 carol
$ sudo groupadd -g 21204 david
$ sudo useradd -g 21204 -u 21204 david
$ sudo usermod -aG tigress alice
$ sudo usermod -aG tigress bob
$ sudo usermod -aG tigress carol
$ sudo usermod -aG tigress david
$ grep tigress /etc/group
tigress:x:21212:alice,bob,carol,david
```

#### グループからユーザを削除
ユーザbobをグループwheelから削除してみる。

```
$ sudo gpasswd -d bob wheel
```
#### ユーザアカウントの最終ログイン日時
```
$ lastlog -u bob
Username         Port     From             Latest
bob              pts/1    fortigate        Mon Sep 17 13:46:00 +0900 2018
```

#### ユーザアカウントの削除 (CentOS, Ubuntu)
ユーザbobを削除。グループも同時に削除される。

```
$ sudo userdel -fr bob
```

#### sudoの警告メッセージを常に表示
```
$ sudo vi /etc/sudoers.d/privacy
$ sudo cat /etc/sudoers.d/privacy
Defaults	lecture = always
```
カラム名をメソッドとして実行できる概念

## カラム名をメソッドとして実行できる、とは

Railsコンソールで以下のコードを実行してみる。

```rb

@blog = Blog.new #=> #<Blog id: nil, title: nil, content: nil, created_at: nil, updated_at: nil>
@blog.title = "aaa" #=> "aaa"
@blog.title #=> "aaa"

```

`カラム名がそのままメソッドになっている` ことは上記コードを見ればなんとなくわかるだろう。
当たり前のように実行しているが、この概念を本当に理解しているか？
特に２行目の `@blog.title = "aaa"` の `=` を `代入` と勘違いしてる人が多いのではないか？

## カラム名をメソッドとして実行できる概念を理解する

そこで今回はActiveRecordの機能を除き、以下５つのコードを正常に実行できるようなblogモデルにそっくりのクラスを、ライブラリなしで作成していく。

```rb

@blog = Blog.new("aaa", "bbb") #=> #<Blog:0x007fe748e000b0 @title="aaa", @content="bbb">
@blog.title #=> "aaa"
@blog.content #=> "bbb"
@blog.title = "aaa" #=> "aaa"
@blog.content = "bbb" #=> "bbb"

```

まず１行目を見ると以下を把握できる

* Blogというクラスがある
* newメソッドを実行した時点で引数が２つある
* `@title` , `@content` というインスタンス変数を用いて、Blogクラスのインスタンスに代入している

従って以下のように実装できる

```rb

class Blog
  def initialize(title, content)
    @title = title
    @content = content
  end
end

```

次に２行目と３行目に着目する

* `@blog` の中にはBlogクラスのインスタンスが入っている
* titleというインスタンスメソッドがある
* contentというインスタンスメソッドがある

```rb

class Blog
  def initialize(title, content)
    @title = title
    @content = content
  end

  def title
    return @title
  end

  def content
    return @content
  end
end

```

Rubyではreturnを省略すると、そのメソッドの最後の行がreturnされる。
ここではtitle, contentというメソッド内は１行しかないので、そのままreturnを省略する。

```rb

class Blog
  def initialize(title, content)
    @title = title
    @content = content
  end

  def title
    @title
  end

  def content
    @content
  end
end

```

で、問題の４行目と５行目。
これは `@blog.titleへの代入` ではないので勘違いしないように気をつけよう。

```rb

@blog.title = "aaa"

```

上記のコードを以下に書き換えてみよう。

```rb

@blog.title=("aaa")

```

このようにすると `@blog.title代入` ではなく `title=` という名前の `インスタンスメソッドを実行している` ということがわかる。
５行目も同じだ。


最終的に以下のようになる。

```rb

class Blog
  def initialize(title, content)
    @title = title
    @content = content
  end

  def title
    @title
  end

  def title=(title)
    @title = title
  end

  def content=(content)
    @content = content
  end
end

```

## Railsにおいてはどこに定義されているのか

Railsのblogモデルを見ると以下のようになっている。

```rb

class Blog < ApplicationRecord
end

```

上記コードを見ると `def title` や `def content=(content)` のような記述は見当たらない。
ではどこに定義されているのか？
それは `ActiveRecord::Base` である。

ActiveRecord::Baseが動的に `title` や `content=` というメソッドを生成している。

```rb

class Blog < ApplicationRecord
  # def title
  # end

  # def title=(title)
  # end

  # def content
  # end

  # def content=(content)
  # end
end
PostgreSQLで外部許可


DBを入れると必ず行う許可的な設定を毎回調べるのは面倒なので、ざっくりとまとめてみました。


postgres.conf
listen_addresses = "[IPアドレス]"

Ex.全外部アクセスを許可する（あんまりやることはないけど）

```
listen_addresses = '*'
```

pg_hba.conf

```
host  DB名  ユーザ名  接続を許可するIPアドレス    trust
```

Ex1. 全IPからのアクセスを許可する（パスワードなし）

```
host  all  all  0.0.0.0/0    trust
```

Ex2. Alexというユーザ名でPostgresデータベースに対してローカルIPからのアクセスを許可する（パスワード認証）

```
host  Postgres  Alex   192.168.0.0/16    password
```


もっと細かい話は以下のURLを参考にしてください。
要望があればExあたりに追加しようかな。

参考文献：
https://ameblo.jp/jyokke/entry-10586621928.html
https://www.postgresql.jp/document/8.4/html/auth-pg-hba-conf.html
http://hacknote.jp/archives/6016/
シンプルなAWS Lambdaのデプロイ管理

AWS Lambdaのデプロイ管理についての記事が、Serverlessなど他のアプリを使ったものが多かったのですが、AWSのコマンドだけでシンプルに実現する方法を考えました。

フローとしては、GithubにコードをPushすると、CIがシェルをたたき、CloudFormation経由でLambdaにデプロイするというふうになっています。（私の場合はCIはCircleCIを使っていますが、なんでも大丈夫だと思います）

CIがたたくシェルはこんな感じです。当方Rubyを使っているので、erbコマンドでyamlファイルに書くLambdaの環境変数を、ベタで書かずCIの環境変数で指定できるようにしています。（erbはrubyをインストールしてたら使えるはず）

```bash:deploy.sh
#/bin/sh

erb template-base.yml > template.yml
zip hoge.zip hoge.py
aws cloudformation package --template-file ./template.yml --s3-bucket "S3バケット名" --output-template-file ./packaged-template.yml
aws cloudformation deploy --template-file ./packaged-template.yml --stack-name "cloudformationスタック名" --capabilities CAPABILITY_IAM
```

```yaml:template-base.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  Hoge:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: 'hoge'
      Runtime: 'hoge'
      Role: 'hoge'
      CodeUri: 'hoge.zip'
      Environment:
        Variables:
          ACCESS_KEY_ID: <%= ENV['AWS_ACCESS_KEY_ID'] %>
          SECRET_ACCESS_KEY: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
```
Gitブランチに対応するRedmineチケットを開く

うちのチームでは、Gitのブランチに対応するチケットの番号を含めるようにしています。

こんな風に： `feature/123456-fix-edit-form-validation`

そのため「あれっ？不具合があるのはどの項目のことだっけ？」と思った時は、チケットもすぐ見つけれるんですが、その時にブラウザでRedmineを開いてコミット番号を入力するのは時間の無駄。

なので、こんなスクリプトを使っています（`~/bin/redmine` などに保存してください）。

```bash
#!/bin/bash
BRANCH="$(git branch 2>/dev/null | grep '^\*' | sed -e "s/^* //")"
ISSUE_BASE_URL="https://【うちのRedmineのホスト名】/issues"
if [[ "$BRANCH" =~ ^feature/([0-9]+)-.*$ ]]; then
  open "${ISSUE_BASE_URL}/${BASH_REMATCH[1]}"
else
  echo 'Branch name does not match [feature/123456-some-description]' >&2
  exit 1
fi
```
秘伝のgit alias

いろんなところからパクった秘伝のgit aliasです。

```text:.gitconfig
stat = status
com = commit
wip = "!f () { git commit -m \"WIP $1\"; };f"                                   # WIPでコミット
wipc = "!f () { git commit -m \"WIP $1 [ci skip]\"; };f"                        # WIPでコミット(ci skip)
fix = "!f () { git commit -m \"Fixup $1\"; };f"                                 # Fixupでコミット(あとでrebaseする)
recom = commit --amend --no-edit                                                # 再commitします。コミットメッセージ変更しません
recom-reword = commit --amend                                                   # 再commitします。コミットメッセージ変更します
con = consistent -i -t
chk = checkout
chk-fork = "!f () { git checkout -b ᛝ`git cbran`+$1; };f"                       # master以外のブランチからブランチを切るとき
diffh = diff HEAD
diffhh = diff HEAD^                                                             # 最後にcommitしたファイルとの差分が見たいときに
diffc = diff --cached                                                           # add したものとHEADの差分を見たいときに
bran = branch
bran-backup = !git branch ဓ`git cbran`-backup                                   # 現在のブランチをバックアップ
cleanbran = checkout --orphan                                                   # 親コミットのないブランチを作成
cbran = rev-parse --abbrev-ref HEAD                                             # カレントブランチの名前を取得
cancel = reset --soft HEAD^                                                     # 最後のコミットを取り消し
cpush = !git push origin `git cbran`
cpull = !git pull origin `git cbran`
fpull = !git fetch origin `git cbran` && git reset --hard origin/`git cbran`    # 現在の状態を無視して強制的にpull
retag = "!f () { git tag -d $1;git tag $1&&echo Create tag \\'$1\\'; };f"       # tagの付け直し
mrg = merge --no-ff
slog = log --pretty=format:'%C(yellow)[%ad] %C(green)%h %Creset: %s' --date=iso # 1 commit 1行でlogを表示します。
slog-name = log --pretty=format:'%C(yellow)[%ad] %C(green)%h %Creset: %C(blue)%an %Creset: %s' --date=iso
delete-brans = !git branch --merged | grep -v \\* | grep -v 'master\\|release' | xargs -I % git branch -d % # master, release以外のマージ済みのbranchをすべて削除します。
```

### 参考

http://qiita.com/tkengo/items/5bae50fb7531d5a6bbcf
http://qiita.com/Yinaura/items/30992f25b87f76af3ba2
http://gutch.hatenablog.com/entry/2014/05/17/155840
Visual Studio / WPF | CSharp > プロパティ > set時に数値かどうかのチェックを行う > TryParse使用 > 一部失敗

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

string型Mynumberに対して数値ではない場合にsetしないようにしてみる。

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _170612_t1540_isNumeric
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var data = new List<myList>();
            data.Add(new myList { Mynumber = "314" });
            data.Add(new myList { Mynumber = "pi" });
            data.Add(new myList { Mynumber = "2718" });
            uxMyNumbet.ItemsSource = data;
        }
    }

    public class myList
    {
        private string mynumber;
        public string Mynumber { get { return mynumber;  }
            set {
                if (Int32.TryParse(value, out Int32 wrk) == false)
                {
                    return;
                }
                mynumber = wrk.ToString();
            }
        }
    }
}

```

```MainWindow.xaml
<Window x:Class="_170612_t1540_isNumeric.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_170612_t1540_isNumeric"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox x:Name="uxMyNumbet" Height="250"
                 DisplayMemberPath="Mynumber"/>
    </Grid>
</Window>

```

![2017-06-12_15h55_49.png](https://qiita-image-store.s3.amazonaws.com/0/32870/c9795fc6-38a9-47af-f664-8bb9bc056594.png)

数値でない("pi")ところは""になってしまった。
CMSP 21期　現地入り「序」報告

#CMSP 21期　現地入り **序**
####*<br>この報告書を見て、達成してほしい目標！！*　
> 現地入り「序」でやったことがわかる！
 現地入り「序」の熱が伝わる！

---
##現地入りの目標

- 暮らしに入り込む"ために"ふり切る。
- まちの人のやりたいこと、やりたかったことを聞く。

##活動のアウトライン

【タイムスケジュール】
《一日目》
7:00到着
8:00～9:30イントロ（岡ちゃん挨拶、事務所使い方、イントロ、現地入りの目的/目標）
10:00~12:00 中沢浜散歩(オカダ同行) あきふみさん
13:00~17:00 お手伝いⅠ  (あるちゃん and しげこさん)
17:30～19:00 黒崎温泉＆メシ＆振り返り
19:00~20:00 21期ダイアローグ(オカダjoinを検討)
20::15~？？  現地組とダイアローグ
飲み会 

《二日目》
7:00起床
8:00～8:30 今日の動き確認
9:00～12:00 お手伝いⅡ  （たまこさん、きよしさん）
12:00~13:30 おひるごはんと振り返り 
13:30～16:00 お手伝いⅢ    （1.もとこさん  2.ひろこさん）
16:30～17:30 黒崎温泉＆メシ＆振り返り
17:30~18:30  まとめワーク (まキリストの更新
以降現地組ダイアログ（？）

21:00出発

##現地入りの良かったこと。改善点。　

<details><summary><strong>まちのためになったと思った瞬間</strong></summary>
"（お手伝いを）次もまたお願いという声があった。"　-こうへい<br>
" ごみ捨て場で話しかけられた。 "  -りょーいち<br>
" 畑作業をお手伝いして「○○がいて早く終わったよ〜」と言ってくれたこと。-みきちょす　 <br>
 <details><summary>*でた議論*</summary>
アイデアを提案するよりも前にその人のことをもっと知りたい！<br>
⇨まずは自分たちの<strong>思いを伝える</strong>ことから始めること！そうすると、中沢浜の人も思いを伝えてくれて、お互いの関係も深まっていくよ！　
</details></details>
 <details><summary><strong>チャーターってこれじゃない？</strong></summary>
 "たま子さんが、僕たちがひろ子さんの家でお手伝いしている時に、「ひろ子さんの家でも手伝いしてるの？」と言って、家に顔を出しに来た！ =  *町/人/循環* " -Ko-hei <br> 
"風呂掃除とか、畑仕事とかを一緒にできた = *住む* " - Ryo-ichi <br>
"お手伝いを一緒にやりながらフレンドリーに話せ</dたこと = *ふわりと浮かび上がる* " - Miki-chos<br>
"私たち、広田の人、中沢浜全体で*翼*じゃない？" - Miki-chos</details>

<details><summary><strong>改善点 </strong></summary>
"広田の人の心の芯に届く「やりたい」に届いたのかがわからない。。。" - Ryo-ichi<br> 
"積極的に行動できなかった、、だから次は思いを伝えていきたい！！" - Miki-chos<br> 
"（手伝いの時「これやりましょうよ！」「もっとできますよ！」という提案は言えたが、）何を言えばいいかわからず、そういうお手伝いの提案数は少なかった！ "　- Ko-hei <br> 
<details><summary>*でた議論*
</summary> 手伝いに関しても、その人が一体何を望んでいるんだろう、とか考えないといけないから頭使う。<br> 広田の人が **本当は** 何をやりたいのか、っていうのを聞くのも、関係性を深めて段階的に、のほうがいいのかな？<br> 
⇨前回の20期では、大学生が出し物をすることで、結果的に広田の人の「みんなで集まって楽しみたい」という思いが実現できた。広田の人にやりたいことを聞いていく、ことも大事だが、こうやって一緒に何かを実現していくことで「やりたい」が現れることもあるのではないか？<br><p>**"CMSPが「やりたい」の入り口になる！というのでもいいのでは？"**</details></details>

##次の現地入りのヒントになるかな？

 <details><summary><strong>祭の話</strong></summary>　
中沢浜でお祭りをやりたい。その理由は、広田の人から「祭りをやりたい」という声があったからと、町の人と楽しみたいからで、それが実現すると、広田の人の「やりたい」が実現できるかも！</details> 
<details><summary><strong>豆腐屋の話</strong></summary>
次の現地入りで、中沢浜の道路を通っておすそ分けでもらったものとかを配っていく屋台をやりたい！そのきっかけは、東京で豆腐屋を見たからで、豆腐屋のような昔ながらの屋台というのは、伝統を引き継ぎながら新しい風物詩、文化を創っていけるアイデアじゃないかと思ったこと！屋台をすると、広田では昔魚を小学生が売って歩く行商という制度があったらしいから、広田の人も懐かしんでくれるのでは！　</details> 
 <details><summary><strong>地域性の話</strong></summary>長野妙子さんから聞いた話だが、「広田の独自のものっていうのは、ズバリ**地域性**なんじゃないか？」という。つまり、部落ごとに文化も性格も宗教も違うらしい。これはアイデアにつながるのではないか？</details> 
 <details><summary><strong>７日間がアクションプラン</strong></summary>７日間をアクションプランみたいな感じにして、現地入り中から、町の人たちと準備していけるといいかも！その理由は、もっと多くの「やりたい」を実現できるからで、その結果、21期からたくさんの”入り口”が生まれるのではないか！</details> 

###以上！！
Office 365のデスクトップアプリケーションをバッチファイルで修復

# Office 365のデスクトップアプリケーションをバッチファイルで修復

## 能書き
Office 2013ってよく壊れません?
インストールされている台数が多いというのもあるけど、週に数回ほどOfficeが不調だという問い合わせがくるので、その都度Officeの修復を案内しています。
Officeの修復は結構優秀なようで、問い合わせの7〜8割はこれで直る。
でも修復の手順が地味に面倒くさい。

 1. コントロールパネルのプログラムのアンインストールを開く
 1. Microsoft Office ProPlusを選択して変更
 1. 修復方法を選ぶ
 1. 修復開始

ということでお手軽に実行できるようにバッチファイルにしてみました。

## コード
```bat:officererepair.bat
@echo off

net session >nul 2>&1
if %errorLevel% == 2 (
    echo 管理権限で実行されていません。
    echo 右クリックして「管理者として実行」で実行してください。
    echo.
pause
exit /b
)

set PARM=scenario=Repair culture=ja-jp ForceAppshutdown=True RepairType=QuickRepair DisplayLevel=True

for /F delims^=^"^ tokens^=2 %%a IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail - ja-jp" /v ModifyPath') DO SET C2R=%%a
if defined C2R (
start "" "%C2R%" %PARM%
)
```
Office 2013/2016、32bit/64bit対応。

## 解説
Officeの修復は、OfficeClickToRun.exeに修復パラメータを付けて実行することで開始されます。
しかし、OfficeClickToRun.exeの場所はOfficeのバージョン等で異なるため、バッチファイルにフルパスで書くわけにもいきません。
ではどうやってパスを取得するか。

答えはレジストリにありました。
日本語版のOffice 365 ProPlusの場合は`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail - ja-jp`の`ModifyPath`に、フルパスと修復パラメータが格納されています。
例えばこんな感じ。
```"C:\Program Files\Common Files\Microsoft Shared\ClickToRun\OfficeClickToRun.exe" scenario=repair platform=x64 culture=ja-jp
```
バッチファイルでレジストリの値を扱う場合、`reg query`コマンドで返った文字列を`for /F`で抜き出して変数に格納します。
今回の場合は`for /F`のオプションで`"delims=" tokens=2"`と指定したいところですが、オプション自体がダブルクォートで括られているため、delimsに`"`を指定できません。
ダブルクォートで括る代わりに、ホワイトスペースと記号をエスケープ記号`^`でエスケープすることにより、区切り文字として`"`を指定できるようにしています。
```for /F delims^=^"^ tokens^=2 %a in ('reg query "HKEY...```

修復モードは`set PARM=`の行で設定しています。
`RepairType`に`FullRepair`を指定すればオンライン修復になります。

OfficeClickToRun.exeは管理者として実行する必要があります。
一般ユーザ権限で実行しても何も起きないので、バッチファイルの頭の方で管理者として実行されているかチェックしています。
GitHub PR を local に fetch して checkout する

# どうするの
`pull/<ID>/head`を fetch すればよい。意外と簡単。Fork ベースの PR を採用している場合はよく使うかも。ということで alias も用意する。

```bash
$ git fetch origin pull/<ID>/head:pull/<ID>
$ git checkout pull/<ID>
```

# Git Alias
```bash
# .gitconfig 内
[alias]
copr = "!f(){ git fetch origin pull/$1/head:pull/$1 && git checkout pull/$1;};f"
```
# 使い方
```bash
$ git copr <Pull Request ID>
```
# 参考
https://help.github.com/articles/checking-out-pull-requests-locally/
Scratchで体験するゲームプログラミングのための物理シミュレーション3 (中高生向け)

# このページのURL

## https://goo.gl/ZQiY2m

# 今日の目標

「ペンギンの冒険II」の作成。

![ペンギンの冒険II](https://qiita-image-store.s3.amazonaws.com/0/155441/5b004deb-fc8b-0756-f448-d2482baf6702.png)

- キャラクターがジャンプしてブロックを登っていく。
- 上矢印でジャンプ、左右の矢印で横方向に移動。
- ある高さ以上まで登ればクリア。
- ブロックから落下するとゲームオーバー。

完成版:
[https://scratch.mit.edu/projects/163557672](https://scratch.mit.edu/projects/163557672/)

# やってみよう1: キャラクターとブロックを配置

- 好きなキャラクターを選んで配置しよう。
- 好きなブロックを選んで配置しよう。

# やってみよう2: 変数の準備

次の3つの変数を用意しよう。

- 速さX
- 速さY
- 高さ

# やってみよう3: 上矢印でジャンプ

次のようにしてジャンプの動きを表現しよう。

- 上矢印キーを押すと「速さY」が増える。
- 一定の時間ごとに、一定量ずつ「速さY」を減らしていく。
- 一定の時間ごとにキャラクターが「速さY」ずつ移動。
- 一定の時間ごとに「高さ」の値を「速さY」ずつ変える。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/155441/6fe771a8-d9bc-fcce-c79d-03dd3dd567ae.png)

# やってみよう4: ブロックの上で止まる

- キャラクターがブロックに触れたら「速さY」をゼロにする。
- キャラクターがブロックに触れている場合、「速さYを減らしていく」処理を行わない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/155441/c390e356-23c6-b833-3e24-24ae6c7417ef.png)

# やってみよう5: 左右の矢印で横方向の移動

次のように横方向の動きを表現しよう。

- 右矢印キーを押すと「速さX」が増える。
- 左矢印キーを押すと「速さX」が減る。
- 一定の時間ごとに「速さX」を0.8倍する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/155441/8d4f8b23-8244-acc2-ecdb-33460f4b6aba.png)

# やってみよう6: 背景が縦方向に動くように

キャラクターが上方向にずっと登っていくゲームを作りたいので、ここではキャラクターではなく、背景(ブロック)が動くようにしたい。そこで、次のようにする。

- キャラクターではなく、ブロックが一定時間ごとに反対方向に動くようにする。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/155441/9b073acf-72ff-adbe-e94a-81af6c691720.png)

# チャレンジ1: ブロックが次々と現れる

次のように書き換えてみよう。

- ブロックが一定時間ごとに上から現れるようにする。
- ヒント: 「クローン」を使う。

# チャレンジ2: ブロックの消滅

次のように書き換えてみよう。

- キャラクターがジャンプしてブロックが画面下についた場合、そのブロックを消す。
- キャラクターが落下してブロックが画面上部についた場合、ブロックを消す。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/155441/3a419ce1-e815-3100-2e1c-ea1d6edef228.png)

# チャレンジ3: ゲームクリア・ゲームオーバー

以下の判定を書き加えれば、ゲームは完成です。お疲れさまでした。

- 「高さ」がある値以上になったら、ゲームクリアとして表示する。
- 「高さ」がある値以下になったら、ゲームオーバーとして表示する。
Visual Studio / WPF > IDE > プロジェクトのコピー

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

作成したプロジェクト(ソリューション)を元に、別プロジェクトを用意するには。

https://stackoverflow.com/questions/884255/visual-studio-copy-project
などを見ると、コピーしてprojファイルなどを書き換えるなど。簡単ではない。

Templateを作るという案もある。

とりあえず以下とした。

- 新規ソリューションを作成
- 既存の.xaml.csファイル、.xamlファイルを新規ソリューションに追加
- xaml.csファイルのnamespaceは新規ソリューションのnamespaceに書き換える
- xamlファイルの以下の[namespace]を新規ソリューションのnaemspaceに書き換える
    - x:Class="[namespace]"
    - xmlns:local="clr-namespace:[namespace]"

App.xamlとApp.xaml.csについては内容を一部上書きすることになりそう。

プロジェクトが大きくなるとこの方法ではうまくコピーできないかもしれない。
【Git】git tutorial for beginner

# This document is for BEGINNERS!!

# 1. 【Git command flow】
Git flow is below.
You **MUST** remember this.

```sh
# check your status
1. git status

# upload modified file to staging area
2. git add .

# commit changes
3. git commit -m "commit massage"

# check your commit log
4. git log
（If you want to **exit** type q.）
```
<img width="500" alt="スクリーンショット 2017-06-12 14.30.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/136499/723126fb-6d00-a00c-a2ec-0c72b397d2f1.png">
（"blue" is git command）

# 2. 【Output】 ```git status``` command
This chapter shows input/output of ```git status```.

1. not git repository
1. nothing to change
2. pre-add(need to add)
3. pre-commit(need to commit)


### (1). not git repository
<img width="435" alt="スクリーンショット 2017-06-12 12.46.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/136499/b6e8821c-fea6-04af-5ada-5f777da02ce5.png">

This output says "Not a git repository".
You may be in different directory or have not initialized git. Check current directory.

``` sh
# check current directory command
pwd
```

If you are in the correct position to track git, you should type initialize command.

```sh
git init
```

### (2). nothing to change
<img width="340" alt="スクリーンショット 2017-06-12 13.28.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/136499/83f5b84f-48c7-2e9d-9f74-2e5bdf4f0037.png">

This output says "nothing to change".
There are two following possibilities.
(1) You already commited the changes.
(2) You haven’t saved local file changes.

Check your local file!!

### (3). pre-add
<img width="508" alt="スクリーンショット 2017-06-12 11.17.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/136499/7e552795-7f5e-1fc0-47b8-e79069753c66.png">

This output says "Local file is modified. Need to add or stash".
If you want to track local file, you should add the files.

```sh
# "." means all-file
git add .
# or
git add file-name
```

### (4). pre-commit
<img width="372" alt="スクリーンショット 2017-06-12 13.10.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/136499/45e521fe-c5e8-c39a-af56-b79c897a3889.png">

This output says “Your changes are already added for staging”..
So you should commit your changes.

```sh
# "-m" means message
git commit -m "your change log message"
# or
git commit
```


# 3. 【Other commands & settings】
### **[command] add remote**
If you want to add remote repository, you should type this command.

```sh
# add remote repository
git remote add origin remote-repository path
# For example
#  git remote add origin git@bitbucket.org:banaoh/toy_app.git
```

### **[command] delete remote**
If you don't want to add wrong remote repository, you should type below.

```sh
# check your set remote path
git remote -v

# if the path wrong
git remote rm origin
```

### **[alias] shortcut git command**
If you get stress to type full command, you set alias.
"alias" are like shortcut :).

```sh 
vim ~/.gitconfig

# and

[alias]
    st = status
    ci = commit
    co = checkout
```
MarshalJSONを実装する

`encoding/json` パッケージのMarshalJSON処理を実装する方法をメモ
このメソッドを実装すると、構造体をJSONに変換する際に、変換結果を変更することができる。

今回やりたかったのは、空のStructがプロパティとして埋め込まれている場合、そのプロパティは `omitempty` が効かない。

下記の場合、`Group`　構造体が `User` 構造体に埋め込まれているが、`omitempty` しても意味がない。

``` go
type (

	Group struct {
		Name string `json:,omitempty`
	}

	User struct {
		Group 		Group 		`json:",omitempty"`
		Name 		string 		`json:",omitempty"`
		Age			int			`json:",omitempty"`
		UpdatedAt 	time.Time 	`json:",omitempty"`
	}

)

func main() {
	u := User{
		Name: "Hoge太郎",
		Age: 31,
		UpdatedAt:time.Date(2017, 6, 1, 1, 0, 0, 0, time.UTC),
	}

	userJson, _ := json.Marshal(u)
	fmt.Println(string(userJson))
}

```

出力結果

```
{"Group":{"Name":""},"Name":"Hoge太郎","Age":31,"UpdatedAt":"2017-06-01T01:00:00Z"}
```

`omitempty` されず `"Group":{"Name":""}` が出力されてしまっている。
場合によっては害を及ぼす。

この場合、`json.Marshaler` を `User` 構造体に実装させ、`MarshalJSON` JSON用の構造体をメソッド内で再定義する。
ただし、全てのプロパティを定義するのは面倒なので、オリジナルの構造体を埋め組むが、エイリアスとして組み込まなければMarshalJSONメソッドが無限ループに陥ってしまう。

``` go
type (

	Group struct {
		Name string `json:,omitempty`
	}

	User struct {
		Group 		Group 		`json:",omitempty"`
		Name 		string 		`json:",omitempty"`
		Age			int			`json:",omitempty"`
		UpdatedAt 	time.Time 	`json:",omitempty"`
	}

)

// JSON化処理を変更する（encoding/json.Marshalerを実装）
func (u User) MarshalJSON()([]byte, error){
	type Alias User
	// 全く新しい構造体を定義
	// 全てのプロパティを定義するのは面倒なので、オリジナルの構造体を埋め組む
	// ただし、エイリアスとして組み込まなければMarshalJSONメソッドが無限ループに陥ってしまう
	return json.Marshal(&struct {
		Alias
		Group bool `json:",omitempty"`
	}{
		Alias: (Alias)(u),
	})
}

func main() {
	u := User{
		Name: "Hoge太郎",
		Age: 31,
		UpdatedAt:time.Date(2017, 6, 1, 1, 0, 0, 0, time.UTC),
	}

	userJson, _ := json.Marshal(u)
	fmt.Println(string(userJson))
}
```

出力結果

```
{"Name":"Hoge太郎","Age":31,"UpdatedAt":"2017-06-01T01:00:00Z"}
```


この方法を応用して、日付のフォーマットを変更したり、追加でプロパティを増やしたりもできる。
Angularで実行するテストを選択する方法

やぬてつです。

この記事ではTypeScript/Angularでjasmineの利用をターゲットとしています。

みなさんは開発が進んできて、だんだんテストの数も時間も増えてきていると思います。
「もう少し早くテストできないかなー」とか「この辺のテストだけでいいんだけどなー」って思うこと有りますよね。

そこで、jasmineのドキュメントを調べたらテストを選択できるオプション？のような物がありました。
※正確にはオプションではなくてそれぞれメソッドのようです。


## 任意のテストを除外してテストを実行する方法

[xdescribe](https://jasmine.github.io/api/2.6/global.html#xdescribe) 及び [xit](https://jasmine.github.io/api/2.6/global.html#xit) でテストを記述する

```typescript
xdescribe('HogeComponent', () => {
  it('is test 1', () => {
    expect(true).toBeTruthy();
  });

  it('is test 2', () => {
    expect(true).toBeTruthy();
  });

  it('is test 3', () => {
    expect(true).toBeTruthy();
  });
});

describe('PiyoComponent', () => {
  ...
});
```

HogeComponent以下のテストを無視して、他のテストを実施します。


```typescript
describe('HogeComponent', () => {
  it('is test 1', () => {
    expect(true).toBeTruthy();
  });

  xit('is test 2', () => {
    expect(true).toBeTruthy();
  });

  it('is test 3', () => {
    expect(true).toBeTruthy();
  });
});

describe('PiyoComponent', () => {
  ...
});
```

HogeComponent is test 2だけを無視して、他のテストを実施します。


## 任意のテストを実行する方法

[fdescribe](https://jasmine.github.io/api/2.6/global.html#fdescribe) 及び [fit](https://jasmine.github.io/api/2.6/global.html#fit) でテストを記述する

```typescript
fdescribe('HogeComponent', () => {
  it('is test 1', () => {
    expect(true).toBeTruthy();
  });

  it('is test 2', () => {
    expect(true).toBeTruthy();
  });

  it('is test 3', () => {
    expect(true).toBeTruthy();
  });
});

describe('PiyoComponent', () => {
  ...
});

```

HogeComponent以下のテストだけをテストします。


```typescript
describe('HogeComponent', () => {
  it('is test 1', () => {
    expect(true).toBeTruthy();
  });

  fit('is test 2', () => {
    expect(true).toBeTruthy();
  });

  it('is test 3', () => {
    expect(true).toBeTruthy();
  });
});

describe('PiyoComponent', () => {
  ...
});

```

HogeComponent is test 2だけをテストします。


## 考え方を変えるとこんな感じ

- describeに `x` をつけると`xdescribe`以外のdescribeを実行
- describeに `f` をつけると`fdescribe`のみを実行

- it に `x` をつけるとその`xit`以外のitを実行
- it に `f` をつけるとその`it`のみ実行

## まとめ

`x`とか`f`を利用して効率的に開発を行っていきましょう！
【テンプレ】ejs x express


## ejsの特殊タグ

|記述|意味|
|---|---|
|<% %>|JS処理|
|<%= %>|キー名に指定した値(エスケープあり)|
|<%- %>|キー名に指定した値(エスケープなし) htmlタグに使用|

## expressのルール

- メインのファイルはapp.js
- テンプレートファイルは/views以下に配置


## ミニマムコード

```javascript:app.js
const express = require('express');
const ejs = require('ejs');
const app = express();

// テンプレートエンジンの指定
app.engine('ejs', ejs.renderFile);

app.get('/', (req,res) => {
  // render(template, template上の特殊タグ)
  res.render('index.ejs',{
    contents: '<p>express rendering</p>'
  })
})

const server = app.listen('1234', () => {
  console.log('server start');
})
```

```ejs:index.ejs
<body>
  <%- contents %>
</body>
```

## POST処理

[body-parser](https://github.com/expressjs/body-parser)を使う

```javascript:app.js
const express = require('express');
const ejs = require('ejs');
const bodyParser = require('body-parser');
const app = express();

app.engine('ejs', ejs.renderFile);
// body-parserの初期化
app.use(bodyParser.urlencoded({
  extended: true
}))

// get
app.get('/', (req,res) => {
  // getはqueryで取得できる
  console.log('--- GET ---');
  console.log(req.query.name);
  console.log(req.query.age);
  res.render('index.ejs',{})
})

// post
app.post('/', (req,res) => {
  // body-parserにより、POSTパラメータ = req.body
  console.log('--- POST ---');
  console.log(req.body.name);
  console.log(req.body.age);
  res.render('index.ejs',{})
})

const server = app.listen('1234', () => {
  console.log('server start');
})
```

```ejs:index.ejs
<a href="/?name=hoge&age=20">GET</a>
<form action="/" method="post">
  <button type="submit" name="button">POST</button>
  <input type="text" name="name" value="fuga">
  <input type="text" name="age" value="30">
</form>
```

## express-generator

テンプレを一発でつくる
http://expressjs.com/ja/starter/generator.html



> 参考
[テンプレートエンジンEJSで使える便利な構文まとめ](http://qiita.com/y_hokkey/items/31f1daa6cecb5f4ea4c9)
Visual Studio / WPF > 確認ダイアログ > アイコン表示 | デフォルトボタン

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

以下の機能を持つ確認ダイアログを表示する。

- アイコン (?や!など)
- デフォルトボタン

http://www.wpf-tutorial.com/dialogs/the-messagebox/

MessageBox.Show()で処理するようだ。

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _170612_t1213_messageDialog
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void uxConfirm_Click(object sender, RoutedEventArgs e)
        {

            string msg = "";
            msg += "Is it OK?" + "\r\n";
            msg += "Away team" + "\r\n";
            msg += "1. Janeway" + "\r\n";
            msg += "2. Tuvok" + "\r\n";
            msg += "3. Chakotay";

            MessageBoxResult res = MessageBox.Show(msg, "Confirmation", MessageBoxButton.OKCancel, 
                MessageBoxImage.Question, MessageBoxResult.Cancel);
            switch (res)
            {
                case MessageBoxResult.OK:
                    // OKの処理
                    break;
                case MessageBoxResult.Cancel:
                    // Cancelの処理
                    break;
            }
        }
    }
}
```

```MainWindow.xaml
<Window x:Class="_170612_t1213_messageDialog.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_170612_t1213_messageDialog"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button x:Name="uxConfirm" Content="確認" Height="28" Width="100"
                Click="uxConfirm_Click"/>
    </Grid>
</Window>

```

![2017-06-12_13h09_33.png](https://qiita-image-store.s3.amazonaws.com/0/32870/63435c11-71b8-91f6-e6d3-58a44a357851.png)

### 検索用キーワード

C++ Builderのメッセージボックスと関連した検索キーワード。

- mtInformation
- mtConfirmation
Visual Studio / WPF > System.Environment.NewLineのPLATFORM_UNIXが消えたタイミング > .NET Framework 4.6

http://qiita.com/7of9/items/976186b00d2986dddb73
において気になったSystem.Environment.NewLineのPLATFORM_UNIXが消えたタイミング。

https://github.com/Microsoft/referencesource/commits/master/mscorlib/system/environment.cs

上のソースを参照して、.NET Framework 4.6の時点にはPLATFORM_UNIX対応がないことが分かった。
Visual Studio / WPF > System.Environment.NewLineとsting.Format()を使って複数改行の文字列を用意する > "\r\n"の代わりにSystem.Environment.NewLineを使う意味は.NET 4.6.1以降はなさそう

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

複数改行がある確認ダイアログを用意しようとしていた。

```csharp
            string msg = "";
            //パターン1
            msg += "Is it OK?" + System.Environment.NewLine;
            msg += "Away team" + System.Environment.NewLine;
            msg += "1. Janeway" + System.Environment.NewLine;
            msg += "2. Tuvok" + System.Environment.NewLine;
            msg += "3. Chakotay";
```

IntelliSenseにより入力は楽だが、将来ソースを見た時に「この長ったらしいのは何だ」と思いそう。

以下のようにした。

```csharp
        private void uxConfirm_Click(object sender, RoutedEventArgs e)
        {

            string msg = "";
            //パターン1
            //msg += "Is it OK?" + System.Environment.NewLine;
            //msg += "Away team" + System.Environment.NewLine;
            //msg += "1. Janeway" + System.Environment.NewLine;
            //msg += "2. Tuvok" + System.Environment.NewLine;
            //msg += "3. Chakotay";

            // パターン2
            msg = string.Format("{1}{0}{2}{0}{3}{0}{4}{0}{5}",
                System.Environment.NewLine,
                "Is it OK?", // 1
                "Away team",
                "1. Janeway",
                "2. Tuvok",
                "3. Chakotay"
                );
            MessageBoxResult res = MessageBox.Show(msg, "Confirmation", MessageBoxButton.OKCancel, MessageBoxImage.Question);
        }
```

途中に改行を二回入れる場合など簡単に変更できる。

![2017-06-12_12h07_22.png](https://qiita-image-store.s3.amazonaws.com/0/32870/31ff3b77-5c1c-bbfe-393e-60ab2c7c6358.png)


### System.Environment.NewLine

https://msdn.microsoft.com/ja-jp/library/system.environment.newline(v=vs.110).aspx
`System.Environment.NewLine`でなく`\r\n`で済ますと将来困ることがあるかどうか。

https://stackoverflow.com/questions/1015766/difference-between-n-and-environment-newline
answered Apr 5 '14 at 8:34
aloisdg
によると.NET 4.6.1からはPLATFORM_UNIXの"\n"を返す処理がなくなっている？
http://referencesource.microsoft.com/#mscorlib/system/environment.cs,63a04833d43dd9d3

System.Environment.NewLineを使う意味は.NET 4.6.1以降はなさそう。
base58とは

# base58

base64と同様にバイナリを文字列として扱えるようにするエンコード方式
base58はマッピングが扱うデータにより異なるので事前にマッピングを確認する必要がある

bitcoinやrippleにおいてはアドレスや公開鍵、秘密鍵を人間が扱える形式に変換するときに用いられる


# bitcoin base58 alphabet

123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

# ripple base58 alphabet

rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz
Certbot（Let's Encrypt）、すごくない？

書く意味あるのか？ってほどの内容ですが、自分へのメモ書きとSSL/TLS証明書の発行や設定で苦しんでる人に届けばという切なる願い。

## 背景
Wordpressでブログ的なサイトを作ったのですが、ログイン画面が暗号化されないHTTP通信でした。ログイン画面だけHTTPSを使う、ということもできるようですが、面倒なのでサイトごとTLS通信を行うようにしました。
そこで、有名なLet's EncryptのCertbotというサービスを使いました。なんと、証明書の発行からApacheの設定ファイルの書き換えなど全部自動でやってくれるのです！便利すぎか！

## 参考リンク
[Let's Encrypt公式サイト](https://letsencrypt.org/)
[Certbot](https://certbot.eff.org/)

## Prerequisite
サーバーの契約、DNSサーバー、Webサーバーの設定などは済んでいる前提での手順です。

## 手順
OSとWebサーバー毎に手順が説明されているので、とてもわかりやすいです。
### 1. 公式サイトへ
[Certbot](https://certbot.eff.org/)を訪れ、自分のサーバーのOSとWebサーバーのソフトウェアの種類を選択

### 2. 手順に従う
あとはそのページの手順に従うだけです！笑

## 注意点
簡単すぎませんか...?
なお、注意点ですが、SSL/TLSの証明書は３ヶ月で期限が切れる用ですので、更新をお忘れなく。なお、certbotさんはcronを使って自動更新を行ってくれる設定も用意してくださってるようです。Ubuntu 16.04 with apacheの場合は
```$ certbot renew --dry-run```
で更新を自動化のテストをしておくと良いでしょう。

※追記）他のOSの場合は少々勝手が違うようなので、Certbotのチュートリアルでご確認下さい。
naming > link > C++ メンバ変数の命名規則 | C#

## C++

C++ のライブラリを読むときに見るところ
http://qiita.com/pink_bangbi/items/b59c828c7526c5225f14
を読んでいて以下の部分を見つけた。

> あとは違反ではないのですが、メンバ変数で _xxx という風に _ から始まる名前を使っている書き方もちょっと気になったりします。
>
>メンバ変数名であれば問題はないんですが、グローバルスコープだと違反になったりとややこしいので xxx_ という風に末尾に _ をつける事が多いですね。

メンバ変数の命名の候補としては以下に列挙されている。
http://isoparametric.net/entry/20070725/1185327261

自分は過去のコードとの継続性により「m_value」派。
(学習用の自作コードを除く)。

## `C#`

C#のコードでは`m_`を付けていない。このあたりはそのうちコーディング規約を整理して検討する予定。

###link1
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members
> Names of Properties
...
> Names of Fields
...
For example, do not use "g_" or "s_" to indicate static fields.

###link2
.net Naming Conventions and Programming Standards - Best Practices
http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

###link3
[コントロールの命名ガイドライン](https://ja.stackoverflow.com/questions/4431/%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E5%91%BD%E5%90%8D%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3)
Hiroshi Yamamotoさんの回答が参考になります。
RecyclerViewにElevationを設定して影をつける方法

RecyclerViewに、```android:elevation``` を設定するだけでは影は表示されません。親のViewGroupに、```android:clipToPadding="false"``` を追加すると影が表示されます。
RecyclerViewの```android:background```は透過でない必要があります。

```xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:clipToPadding="false"
    android:gravity="center"
    android:padding="32dp">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:name="com.example.elevation.ItemFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_light"
        android:elevation="2dp"
        app:layoutManager="LinearLayoutManager"
        tools:context="com.example.elevation.ItemFragment"
        tools:listitem="@layout/fragment_item" />

</RelativeLayout>
```

単純にCardViewで囲ってやっても良いかもしれません。

```xml
<android.support.v7.widget.CardView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:cardCornerRadius="4dp"
     app:cardUseCompatPadding="true">

     <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:name="com.example.elevation.ItemFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="LinearLayoutManager"
        tools:context="com.example.elevation.ItemFragment"
        tools:listitem="@layout/fragment_item" />

</android.support.v7.widget.CardView>
```

**(参考)**

- [android - How to properly set elevation value to recyclerview? - Stack Overflow](https://stackoverflow.com/questions/33412771/how-to-properly-set-elevation-value-to-recyclerview)
- [material design - Android "elevation" not showing a shadow - Stack Overflow](https://stackoverflow.com/questions/27477371/android-elevation-not-showing-a-shadow)
- [Elevation & shadows - Material design - Material design guidelines](https://material.io/guidelines/material-design/elevation-shadows.html#elevation-shadows-elevation-android)
TRUNCATE TABLE …等 の DDL で「ORA-54: リソース・ビジー…(ORA-00054: resource busy...)」が発生する際の小技(Oracle Database)

以下のように TRUNCATE TABLE …文 や ALTER TABLE …文 を実行すると、
ORA-54エラー(リソース・ビジー) が 発生することがあります。
＃十中八九トランザクションが走ってるケースやね彡(ﾟ)(ﾟ)

```sql
SQL> TRUNCATE TABLE TBL_A;
TRUNCATE TABLE TBL_A
               *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


SQL> ALTER TABLE TBL_A DROP (C2);
ALTER TABLE TBL_A DROP (C2)
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
```

そう云う場合は DDL_LOCK_TIMEOUTパラメータ を セッション単位で
変更して DDL を実行すると、パラメータの秒数分待機してくれるやで彡(ﾟ)(ﾟ)

```sql
ALTER SESSION SET DDL_LOCK_TIMEOUT = 1000000;

Session altered.

※待たされる。
TRUNCATE TABLE TBL_A;
```

トランザクションが完了すると、待機していたDDL文が実行されます。

```sql
※TRUNCATE文の続き
Table truncated.
```

マニュアルも見とくやで彡(^)(^)
> Oracle Databaseリファレンス 12cリリース2 (12.2) E72905-02
DDL_LOCK_TIMEOUT
http://docs.oracle.com/cd/E82638_01/REFRN/DDL_LOCK_TIMEOUT.htm#GUID-72D43EF8-F7AF-4011-8D64-73ABC4FB2154
wwdc2017で気になったことまとめ

# WWDC2017
家にいました。来年は行きたいです。気になるとこだけ書きます。

# 新Safari
今年秋ごろに新OS「High Sierra」が出るそうです。それに伴いSafari 11も発表されました。

[Safari 11.0](https://developer.apple.com/library/content/releasenotes/General/WhatsNewInSafari/Safari_11_0/Safari_11_0.html)
>Web conferencing. Implements peer to peer conferencing with the WebRTC standard.
Metrics. Test your code using new tools for measuring code and network performance.
WebAssembly. Your web apps are smaller and load faster when written with the new WebAssembly format.
New WKWebView APIs. Your apps can now capture snapshots, handle custom URL schemes, more effectively manage cookies, and implement web content filtering.

新機能がいろいろついていますが、一番の目玉はやはり**WebRTC対応**になったことじゃないでしょうか。いままでiOSでWebRTCをやるにはアプリを作るしかなかったのですが、これがmobile Safariでも動く様になり、ネイティブアプリを作る必要が弱まりました。まだ実物をさわれていないのでパフォーマンスや、使い勝手の部分は未知ですが、非常にポジティブなリリースだと思います。


参考
[Safari に WebRTC がきてどうなるのか](https://medium.com/shiguredo/safari-%E3%81%AB-webrtc-%E3%81%8C%E3%81%8D%E3%81%A6%E3%81%A9%E3%81%86%E3%81%AA%E3%82%8B%E3%81%AE%E3%81%8B-e993cef0cc89)

# ARKit
Pokemon Goでぐっと身近になったAR技術ですが、Appleからも公式のリリースがありました。
iOS11から使えるようで**ある程度の大きさの平面を認識して、そこにオブジェクトを配置する**ことが楽にできる様になります。
OpenCV使ったり、自作したりいろいろなアプローチがあったんですが、動作が不安定だったりインターフェースが複雑で使いにくいことが多かったので嬉しいです！今後これを使ったアプリは増えそうですが、既存サービスに組み込むのはなかなかイメージしにくいですね。知育系やゲーム系、イベント系アプリはシナジーがありそうなので増えそうな印象を受けました。

参考
[[iOS 11] Apple 純正の AR フレームワーク「ARKit」について理解する #WWDC17](http://dev.classmethod.jp/smartphone/iphone/understanding-arkit/)

# iPad Pro
10.6インチモデルが追加されて、パフォーマンスが上がって、smart keyboardもJIS配列モデルが増えました。
正直用途が全く思いつかないんですが、欲しい・・・
何で欲しいのか自分でもわからない、信仰心としか言いようがない。はい、買います。

# 公式カメラアプリでQRコード読みとり追加
日本ではあまり日の目を見ていないQRコードですが、**中国やインド**では非常に身近にQRコードがあります。小売りやローカルな屋台などでも使われることが多く、リアルtoアプリのチャネルとして非常に注目されています。

いままでサービス側が店舗に設置依頼をがんばってして、デバイス置いてもらって、それを管理して来たのが、webからサービス利用してもらってQR発行して、それをお客側のデバイスで読みとってもらうという構造になるのが面白いですね。


参考
- [中国では屋台でもスマホの「QRコード決済」がつかわれる。紙幣で払ったら「決済アプリ」でお釣りがきたことも。現地の日本人に聞いた、中国の決済アプリ事情。](https://note.mu/marketing/n/n1170a9e58d41)
- [日本では失速も… 中国で「QRコード」が異常な人気](http://www.sankeibiz.jp/smp/macro/news/170410/mcb1704100606001-s4.htm)
- [中国でQRコードを利用したローテクなハイテク詐欺事件が発生](https://the01.jp/p0004905/)
- [インド政府QRコード決済を推進](http://www.isijapan.co.jp/single-post/2017/02/28/%E3%82%A4%E3%83%B3%E3%83%89%E6%94%BF%E5%BA%9CQR%E3%82%B3%E3%83%BC%E3%83%89%E6%B1%BA%E6%B8%88%E3%82%92%E6%8E%A8%E9%80%B2)

# 開発関連
- アプリ上でレビューを催促するポップアップを今後は規制
- SiriKitのアップデート
- 画像解析のVision Framework
- Xcode9が神アップデート

ってとこですかね、一番高まったのはXcode9でした。開発環境が便利になるのはサイコーなんですが、最近Androidも触ってて、正直Android Studioのほうがサイコーってなっているので、喜びが薄いです。

参考
- [Apple、アプリ上でレビューを催促するポップアップを今後は規制](http://iphone-mania.jp/news-171112/)
- [秋リリースのiOS 11新機能発表まとめ](http://ascii.jp/elem/000/001/495/1495488/)
- [API Diffsから見る iOS 11 の新機能 #WWDC17Add Star](http://d.hatena.ne.jp/shu223/20170606/1496710194)

# 全体的に・・・
今年はポジティブな発表が多かったけど、GoogleI/Oよりは盛り上がりは少なかった気もする。新しい AppleTVを期待してたのですが、Amazon Prime Video見れるよ〜ってだけだったのでとても悲しい。

これから基調講演の動画をほいほい見続ける作業を開始します:point_up:
App ServiceのcakePHPでbakeするときのポイント

私はこのやり方しかわかりませんでした・・・。

cakePHPを使うにあたって、やっぱりbakeを実行したいなぁと思ったとき。
App Service上のコンソール(Kudaなど)で動きませんでした。

よくよく見てみると、database.php内の記述は、Webサーバからアクセスされる前提で記述されており、
Azureが自動で提供してくれる接続文字列を利用した接続情報となっています。

このため、bakeで実行しようにも、databaseがありませんよ。的なエラーが出力されてしまい実行できません。

そこで、私がとった行動は、databaseへの接続情報をいつも見ている形式で出力してやろうと考えました。
webroot配下に「phpinfo()」を出力するphpファイルを用意して、databaseへの接続情報を確認しました。
そして確認した接続情報をdatabase.phpへ記述してあげました。

今のところこれで動いています・・・。

開発環境としてApp Serviceを利用しようとしなければこんなこと起きないのでしょうねぇ。
Azure アドバイザーで検知されたら。

Azureのアドバイザーを利用しているとLinux VM毎に「OS の脆弱性の修復 (Microsoft による)」が検出されることがあります。
実行日時はマチマチで、対応しても「対応してないよ、まだ検査してないからだけど。」と言われることもしばしば。
[OverView](https://docs.microsoft.com/ja-jp/azure/advisor/advisor-overview)曰く1時間おきに検査していると書かれていましたが、対応しても解消済みにならなかったり、翌日なったりします。

そんな中。

言ってることはわかるけど、結局どうしてほしいのかわからないこともあります。

そんなときは、脆弱性規則の診断の詳細画面に表示される、アドバイザーが実行したコマンドをroot権限で実行してみましょう。
例えば、こんな感じでコマンドが表示されるはずです。
![20170612_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/186204/1c63966d-3812-a332-2e9a-b3af52865f29.png)

それを、VM上で実行するとこんな感じです。
![20170612_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/186204/3018edd7-1d83-89b2-79d5-0d36e28d6322.png)

良きように設定してくれるようです。

いたちごっこかもしれませんが、その時だけでも脆弱性が無いにこしたことはないかなと。
GKEでkubectlコマンドを使おうとしたら「ログインしてね」って怒られたときの謝り方

# Kubernetes で怒られた(´・ω・`)
GoogleContainerEngine（GKE）ちゃんと初めてのデートをしていました。途中で「Serviceの一覧を確認したほうがいいよ」と助言された（by参考資料）ので、次のコマンドを実行しました。

```:わたし
kubectl get services
```
ﾀｰﾝｯ!!

```:Kubernetes
error: You must be logged in to the server (the server has asked for the client to provide credentials
```

おこらりた(´・ω・`)


# どうやら、gcloud の設定が足りていなかったようです。

```
$ gcloud config set project PROJECT
$ gcloud config set compute/zone ZONE
$ gcloud config set container/cluster CLUSTER_NAME
$ gcloud container clusters get-credentials CLUSTER_NAME
```
* PROJECT: Project ID
* ZONE: Compute Engine ゾーン
* CLUSTER_NAME: クラスターの名前（GKEダッシュボードから確認可能）

設定の確認

```
$ gcloud config list
```

これでKubernetesちゃんも機嫌をなおしてくれました！めでたしめでたし


# 参考
[【kubectl】The connection to the server localhost:8080 was refused と叱られる](http://otiai10.hatenablog.com/entry/2016/04/07/061601)
[公式：(オプショナル) gcloud のデフォルトを設定](https://cloud.google.com/container-engine/docs/before-you-begin#gcloud_1)