OmniAICreator/Qiita-1.07M huggingface dataset:
Oculus Quest にハンドトラッキングが来ました

Oculus Quest にハンドトラッキングが来ましたが、まだ来てない人もいるみたいで、どうやってやるのと聞かれたので、参考資料です。

一月も経てば、当たり前になっているのだろうな～。いい世界が来る。


# Oculus Quest でハンドトラッキングを有効にする方法
1. ソフトウェアアップデートかけます。すでに①と同じバージョン、あるいはそれ以上なのであれば、作業不要です。2に進んでください。そうでない人は、下の写真の②のボタンが押せるのであれば、押して更新しましょう。バージョンは12未満だし、ボタンを押せないという人は、充電した状態にして、コントローラーも見える位置に置いて、一晩待ってみましょう。夜に更新が走る可能性があります。
![ソフトウェアの更新とバージョン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/5e4f3beb-b17f-dace-813c-7dafa099ee26.jpeg)

2. （更新出来たら）ハンドトラッキングの設定が出てくるので、On にしてください。
![ハンドトラッキングが出てくる.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/1a2876ab-dcee-2cd4-441b-55753253eb48.jpeg)

# ハンドトラッキングの様子
## 選択、スクロールできる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ソフトウェアップデートで、Oculus Quest のハンドトラッキング来た！ <a href="https://t.co/QFfb8gNULR">pic.twitter.com/QFfb8gNULR</a></p>&mdash; machidyo (@machidyo) <a href="https://twitter.com/machidyo/status/1204943443069263872?ref_src=twsrc%5Etfw">December 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
## けっこう精度高い
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">けっこう精度高く握れる。 <a href="https://twitter.com/hashtag/OculusQuest?src=hash&amp;ref_src=twsrc%5Etfw">#OculusQuest</a> <a href="https://t.co/DzG8YOfMWi">pic.twitter.com/DzG8YOfMWi</a></p>&mdash; machidyo (@machidyo) <a href="https://twitter.com/machidyo/status/1204943596035571714?ref_src=twsrc%5Etfw">December 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 重なると消える
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">両手重ねると消えちゃう。トラッキングが怪しくなると、危なくなる前に消しているのかな。<br><br>動画にはないけど、結構広い範囲でトラッキングできる。ただ早い手の動きはちょっと無理のよう。<a href="https://twitter.com/hashtag/OculusQuest?src=hash&amp;ref_src=twsrc%5Etfw">#OculusQuest</a> <a href="https://t.co/M5MNRbaOS0">pic.twitter.com/M5MNRbaOS0</a></p>&mdash; machidyo (@machidyo) <a href="https://twitter.com/machidyo/status/1204943906137231360?ref_src=twsrc%5Etfw">December 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# そして
来週には SDK が出るとか。早く開発したいですね！
フロントエンドでDDDLikeなアーキテクチャを導入したときに困ったこと・対策（検討中も含む）

# 前提のアーキテクチャ
<img width="650" alt="スクリーンショット 2019-12-09 21.18.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220683/2daeb7de-0a87-368b-4ccd-5b00df6820d9.png">

### Presentation
表示を担う

### Repository
外部との接続を担う。

### Usecase(Application)
Repository層、Store層とのコネクション。
Repository層からとってきたデータをStoreに保存する。
ビジネスユースケースを記述。

### Entity
モデル。(DDDに置けるドメインモデリング)

### Query
Store層から取り出したデータを編集して取り出す。

## 開発言語,フレームワーク
Typescript, Angular


# 困ったこと・対策
## Presenation編
### Componentしていくが、再利用性がないものもComponent化していくのか迷った。

#### 例
- 「Google検索」、「I'm Feeling Lucky」と書かれているButtonは再利用性があるので、Component化しよう。
- Googleのロゴはコンポーネント化するのか迷う
<img width="725" alt="スクリーンショット 2019-12-09 21.26.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220683/8013811b-6804-df7a-b756-1a7fe48208f2.png">

#### 対策
一つの画面がもつComponentと再利用性があるComponentに分けた。

```
├── modules
    ├── GoogleLogoComponent
└── pages
    ├── GoogleLogoComponent

```

> 参考
https://tech.bitbank.cc/designsystem-theory-practice/


## Entity編
### Entity、値オブジェクトを記述するとき、巷で流行っているような記述はフロントエンドではコスパが悪い、、？

```typescript

export class ValueObject {
  private _value: string;
  constructor(value: string) {
    this._value = value;
  }

  get getValue(): string {
    return this._value;
  }

  set setValue(value: string) {
    this._value = value;
  }
}
```

上記のように、一つのオブジェクトを表現するのにもこの記述がかかる。
そのくせ、基本的にフロントエンドでは**一つのドメインオブジェクトにおけるドメインロジックが少ないことが多い**（扱うもので異なる）


#### 対策
記述をinterfaceにとどめた。Validationなどの記述は同じファイルにfunctionとして記述。

```typescript
export interface ValueObject {
  value: string;
}

export function isExist(value: ValueObject): boolean {
  return this.value ? true : false;
}

```


### 値オブジェクトに関してはカプセルかする必要あるのか
例
UserIdのような値オブジェクトは、storeなどのライブラリと相性が悪い。
(`userId: string | number`を想定してることが多い)

```typescript
export interface UserId {
  value: string;
}
```

#### 対策
uidのような値オブジェクトはライブラリとの相性の悪さを勘案して、typeでstringと同列な型とした。
これによって、引数を表す時などに、可視化はできるようになった。

```typescript
export type UserId = string;
```

## Query

### query処理が煩雑になりがち。
ただapiからfetchしたJsonDataを使ってqueryを処理するのは難しくなりがち。

### 対策
正規化することで、RDBのようにquery処理を記述することができる。

> 参考
https://www.slideshare.net/ayatas0623/reduxstate-129830690


## Store

### storeの分割単位はPage単位？ドメインオブジェクト単位？？？
一つのpageでは、複数のドメインオブジェクトを扱うことが多い。したがって、ドメインオブジェクト単位でのStoreの設計だと、扱うStoreも多い。対してPage単位でStoreを構成することで、Storeの扱いがPageのなかの限定的になるが、扱いやすくなる。

### 対策
現状ドメインオブジェクト単位にしています。ただ、これといった明確な理由はないのでベストプラクティスを模索中です、。

> 参考
https://qiita.com/oi5u/items/4e2c5bc1d546be1b1c5d


## Usecase


### データ取得するのはどこの責務？
データ取得する場所は使っているフレームワーク、ライブラリなどで結構別れたりする。例えばVue.jsの場合はVuexをStoreで使ったりすることが多いが、Vuexのアクションでは非同期処理が勧められている。

> 参考
https://vuex.vuejs.org/ja/guide/actions.html

つまり、Presentationで発火し、ActionをDispatch。そこで非同期でAPIを発火させ、ミューテーションに値を送る形になっている。ただ、ライブラリで勧められているならまだしも、StoreでRepositoryを扱うのはどうかと疑問に思った。

### 対策
InitializeUsecaseとして、Usecase層で処理を行う。

```typescript
export class InitializeUsecase {
  constructor() {}

  exec() {
   const repository = new EntityRepository()
   const entity = repository.fetch()
   const store = new Store()
   store.dispatch(entity)
  }
}
```



# 最後に
自分がフロントエンドDDDをする際に困ったところをかいつまんでまとめました。誰かの参考になりますと幸いです。
wordpress導入しかた

##wordpressとは？？
wordpressとは簡単にいうと、専門的な知識がなくとも誰でも簡単にサイト管理や記事投稿ができるため、世界中のサイトのおよそ4分の1はWordPressで構築されていると言われています。ここでいう専門的な知識とは、HTML/CSSやPHPなどのWeb関連技術が無い人のことをいう。便利ですよね！！！便利ということはざっくりではあるとは思うのですがお分かりいただけていただけたかと思います。

##wordpress機能紹介

- HTMLタグづけや見栄えが編集できる
- 画像の投稿、削除
- ブログコメントの管理
- アクセス数の確認
- 編集できるユーザ権限管理 etc......

がある。

##wordpressの主な使われかた
これは、もちろんユーザーがどう使いたいかによるが、大半は下記の通りである。

- ブログ
- コーポレートサイト（会社のサイトのこと）
- 飲食店のサイト
- スポーツーチームのサイト

などがwordpressで使われている。
先ほども記載しましたが、この世のwebサイトの約４割はwordpressでできている。なのでwordpressを覚えるえていくことは特しかないです。


また、wordpressはありがたいことに、最低限のSEOがなされているので検索上位に上がりやすいというメリットも兼ね備えている。

つまり、SEOとは“Search Engine Optimization”の略で、検索エンジンに向けてWebサイトを最適な状態に近づけることを意味します。
読み方は「エスイーオー」で、直訳して「検索エンジン最適化」とも呼びます。
では、wordpressの便利さに少しわかったところでwordpressを導入してみましょう！！！！！！！！！！




##worpress導入手順

１、公式サイトからダウンロード<a href="https://ja.wordpress.org/download/">(worpress)</a>
2、ダウンロードしたzipファイルを解凍
３、解凍したファイルをhtdocs配下に移動
４、phpMyadminでDB作成
５、ブラウザからローカルホストにアクセス
６、初期設定
７、ユーザー名はrootと記入　パスワードは空欄
８、サイトのタイトルは自分の好きな名前
９、パスワードは自分の好きなパスワード
１０、ユーザー名も自分の好きな名前


初期設定を進んでいくとwpーconfig.phpを作ってくださいとエラーが起きるのでそこでターミナルを用意して、

sudo chmod -R 777 .

をターミナルに入力する。これでwordpress内にwpーconfig.phpが追加されているはずです。

これでサイトの方へ進んでいけばアカウントができます。
wordpressを自分好みのサイトにアレンジしてしまいましょう！！！！！

##最後に
wordpressは使えれば自分の作ったサイトをwordpress内に追加してそれを使うことも可能ですし、プラグインなども使用すれば自分独自のwordpressアカウントを作れたりしてとても楽しいので是非この機会に作ってみてはいかがでしょうか？？？
wordpressで自分好みにアレンジしてしまいましょう！！！！！
ESLint設定ファイルまとめ✨


[ESLintの設定ファイル](https://eslint.org/docs/user-guide/configuring)が
それぞれ何を設定しているのかイマイチ把握してなかったのでまとめました
必要であればテンプレートとしてお使いください💁‍♀️
([個別のルール](https://eslint.org/docs/rules/)までは記載してません)

```javascript:eslintrc.js
module.exports = {
  // Environments (構成情報)
  // ==============================

  // ESLintを処理するプロセッサの指定
  // https://eslint.org/docs/user-guide/configuring#specifying-processor
  parser: '@typescript-eslint/parser',

  // ECMAScriptのバージョンやJSXなどのパーサのオプションを指定
  // https://eslint.org/docs/user-guide/configuring#specifying-parser-options
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 2020,
    sourceType: 'module'
  },

  // Globals (eslintが実行中にアクセス可能にするグローバル変数)
  // ==============================

  // 環境に依存するグローバル変数を定義
  // https://eslint.org/docs/user-guide/configuring#specifying-environments
  env: {
    // ブラウザのグローバル変数
    browser: true,
    es2020: true
  },

  // 個別のグローバル変数
  // https://eslint.org/docs/user-guide/configuring#specifying-environments
  globals: {},

  // Rules (ESLintのルールの設定)
  // ==============================

  // サードパーティのプラグインによって定義されたルールや環境、または構成を使用する場合に指定
  // https://eslint.org/docs/user-guide/configuring#configuring-plugins
  plugins: [
    'react',
    'standard',
    '@typescript-eslint',
  ],

  // サードパーティやESLintが推奨するベースのルールを設定
  // https://eslint.org/docs/user-guide/configuring#using-eslint-recommended
  // https://eslint.org/docs/user-guide/configuring#using-eslint-recommended
  extends: [
    // ESLintの推奨する一連のルール
    // 'eslint:recommended',
    // reactの推奨ルール
    'plugin:react/recommended',
    // eslint-config-standardルール
    'standard',
    // typescript-eslintで対応できるeslintの推奨する一連のルール
    // 'plugin:@typescript-eslint/eslint-recommended',
    // typescrip-eslinttの推奨する一連のルール
    'plugin:@typescript-eslint/recommended'
  ],

  // 個別で定義するルール
  // https://eslint.org/docs/user-guide/configuring#using-the-configuration-from-a-plugin
  // https://eslint.org/docs/rules/
  rules: {},

  // 特定のファイルグループで設定するルール
  // https://eslint.org/docs/user-guide/configuring#disabling-rules-only-for-a-group-of-files
  // overrides: {},

  // 各ルールが実行させる時の補助共有設定
  // https://eslint.org/docs/user-guide/configuring#adding-shared-settings
  settings: {
    react: {
      version: '16.3'
    }
  },

  // ESLintを適応しないファイルやディレクトリを指定 (v6.7.0以上)
  // https://eslint.org/docs/user-guide/configuring#ignorepatterns-in-config-files
  ignorePatterns: ['node_modules/']
}
```

間違い、誤字脱字などあればご指摘いただけるとありがたいです
アプリを使わずにiPhoneで写真を撮る方法

#はじめに
アロハ！
　今回は、ネイティブアプリを使わずにiPhoneで写真を撮る方法を書きます。
一般的にiPhoneで写真を撮る方法は、おそらく３つあります。
１つ目は、Appleがプレインストールしている「カメラ」アプリ。
２つ目は、誰かが作ったカメラ系アプリ。Swiftで書いたり、Objective-Cで書いたり。私も以前、「お天気カメラ」というアプリをAppStoreでリリースしていました。（数年前に公開停止しました。）
お天気カメラで写真を撮ると、位置情報から<a href ='https://openweathermap.org/'>openweathermap.org</a>のAPIを叩いて、気象情報を取得して、写真にオーバーレイして保存できるものでした。懐かしい・・・。
３つ目は、Safariを使う方法です。今回は、このお話です。
アプリを入れずに写真を撮って、サーバーへ送ったりできるので、いろんな使い道があります。例えば、文字が書かれた看板を撮影し、OCRで読み込んで、翻訳するといったことにも使っています。東京都内の某店舗にご協力いただいて、絶賛実験中（NFCやQRも対応）です。インバウンド旅行者の方に商品を深く理解してもらいつつ、スタッフの方の働き方改革に役立てようというものです。
##ご注意
　動画を静止画にする方法なので、期待するほど美しくない場合があります。手振れの影響も大きいかもしれません。OCRには十分使えますが。

#大きな方針
・HTML5+Javascript+CSSでコーディング
・iPhone版Safariを使用（ChromeなどSafari以外のブラウザでは動かないようです。）
・少なくともiOS13系で動かす

#具体的にどうするの？
ずばり、HTML5のgetUserMedia()を使います。iPhoneのメインカメラで撮影する場合の例です。
インカメラを使いたい場合は、camera.jsの設定を
```facingMode: 'environment', ```から
```facingMode: 'user',```
に変更してください。

``` html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>CAMERA</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no" />
  <link rel="stylesheet" type="text/css" href="camera.css" />
</head>
<body>
  <div id="main">
    <button id="btn_shot" onclick="func_shot()">撮影</button>
    <div id="video_frame">
      <video id="video" autoplay playsinline></video>
      <script src="camera.js"></script>
      <canvas id="myCanvas"></canvas>
    </div>
  </div>
</body>
</html>
```

``` javascript:camera.js
const medias = {
	audio: false,
	video: {
    	facingMode: 'environment', //メインカメラ
		width: { min: 1024, ideal: 1920, max: 2436 },
		height: { min: 776, ideal: 1080, max: 1125 }
	}
};
const video = document.getElementById("video");
const promise = navigator.mediaDevices.getUserMedia(medias);

promise.then(function(stream){
	/* 成功 */
	video.srcObject = stream;
})
.catch(function(err) {
	/* エラーをハンドル */
});

function func_shot(){
	var canvas = document.getElementById('myCanvas');
	var ctx    = canvas.getContext('2d');
	var width  = video.offsetWidth;
	var height = video.offsetHeight;
	canvas.setAttribute('width' , width);
	canvas.setAttribute('height', height);
	ctx.drawImage(video, 0, 0, width, height);
	//画像をJPEGにしたいとき（これをformでPOSTしたりすればいいです）
	var imageData = canvas.toDataURL("image/jpg");
}
```

```css:camera.css
#video{
	width: 100%;
}
```
これら3つのファイルをウェブサーバーにおいて、iPhoneのSafariでアクセスすると動画が表示されます。
「撮影」ボタンを押すと、動画の下に静止画が描画されます。
この静止画は、jpeg形式でimageDataに入れていますので、もしサーバーへ送りたければformに入れてPOSTすればいいです。
httpsにしないと動かないかもしれないのでその場合は、<a href="https://letsencrypt.org/">Let’s Encrypt</a>などを使ってください。

#おわりに
そもそも、なぜHTML5でカメラが使えるのか？不思議に思われたかもしれません。一つの理由としては、WebRTC（Web Real-Time Communication）というリアルタイム通信（テレビ会議）を実現しようとして開発されたからです。ですので、そういう用途でも使えます。NAT越えとか大変そうですが・・・。

よいクリスマス＆新年をお迎えください。
マハロ！
Portの確認とプロセス削除

### portの確認

```
lsof -i :9998
```

### プロセス確認

```
ps -efwww
```

### プロセス削除

```
・削除
kill 11111

・強制削除(プロセスが実行中で削除できない場合)
kill -9 22222
```
ZOZOTOWNのメールマガジンの仕組みについて

この記事は[ZOZOテクノロジーズ #2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/zozo_tech2) 13日目の記事になります。
昨日は、@banjun さんの「[watchOS 6の騒音レベルとともにライブを振り返る ~ 心拍数もあるよ ~](https://banjun.hatenablog.com/entry/2019/12/12/000000)」でした。

#はじめに
私はZOZOテクノロジーズの中でMA(マーケティングオートメーション)というプロダクトに所属しています。
その中で主に担当しているのがZOZOTOWNのメールマガジンになります。日々配信するメールマガジンの内容の実装、配信処理の実行、配信したメールの効果検証などの業務を行うチームにいます。

今回はその日々私が携わっている業務のうちの「配信するメールマガジンの内容の実装」についてお話したいと思います。

#ZOZOTOWNのメールマガジンについて
ZOZOTOWNのメールマガジンはご存じの方もいるかと思いますが、同じコンテンツを配信しても、個人個人で掲載アイテムが異なっています。つまり、**パーソナライズ**した状態で配信しています。

例えば、以下の図のように「タイムセール開催中」というコンテンツを配信する際も、配信対象のユーザーが異なれば掲載されるアイテムがまったく異なります。
ZOZOTOWNのメルマガ、やたらと自分が欲しいなと思っていたアイテムをレコメンドされるな～なんて思っている方もいるのではないでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360050/8e579d2a-2979-73b6-d460-ea90e0235063.png)

#どう実現しているか
上図のように**パーソナライズした状態でメルマガにアイテム表示**をするために、我々は一体何をやっているかと言うと、現状は**SQLを使用したルールベースでアイテムの選定**を行っています。

例えば、ユーザーの閲覧情報を使用して`「〇回見たアイテム」`とか、お気に入り情報を使用して`「〇日前までにお気に入りしたアイテム」`とか。

上記のようなルールをもとに、ユーザー毎にどのアイテムをどんな順番で何件掲載するかを集計し、画像や価格などのアイテム情報を取得します。これらをSQLで表現しています。
ルールについては、今までの流入率やCVRの実績をもとに決めたり、配信したあとも効果検証の結果をもとに微調整するなどして、`ユーザーにより"刺さる"アイテム選定ロジック`を日々検討しています。

検討しているのはアイテムの掲載ロジックだけではなく、配信セグメント(誰に送ればいいか)についてや、ユーザーの好きそうなブランドを拾ってきたり、実施する企画によってさまざまなパターンのSQLを作成しています。

ここ最近はAIや機械学習を使って過去の実績に基づいてルールベースからモデルベースへ移行するという考えも出てきていますが、現状我々のチームでは上記のようにRDBとSQLを利用してパーソナライズを実現しています。
![Qiita用.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360050/69bfcc40-6ee3-314e-441d-d089a520ede0.png)

もちろん、この現状がベストだとは思っておらず、さらにユーザーとのコミュニケーションをより良いものにするための施策を検討するような業務も行っています。
CRMやMAに興味のある方で転職をお考えの方は是非我々のチームに応募してきて欲しいな…とメンバーは常に熱く思っております…！

話を聞いてみたい！という方は是非Wantedlyのページへ
[MA基盤上で施策企画・実装ができるエンジニア大募集！](https://www.wantedly.com/projects/331224)

もしくは8割くらいサッカーの話しかしていない私のTwitterでも可です
[ちはおのTwitter](https://twitter.com/_sa_chi_03)

#おわりに
他のアドベントカレンダーと比較して、そこまで技術的な話でなくて申し訳ないのですが、日々ユーザーに配信されているZOZOTOWNのメールマガジンはどのような仕組みで内容を編集し、配信されているのかを超簡単にざっくり説明してみました。


明日は@kotatsu360さんの記事になります！是非読んでみてください！
【React Native】react-native-fbsdk 導入時 エラー (android)

### 「The SDK has not been initialized」エラー解決
SDKの初期化がされていませんというエラーです。

##＞環境

```
    "react-native-camera": "^0.13.0",
    "react-native-fbsdk": "^0.7.0",
```

![initialized error.png](https://qiita-image-store.s3.amazonaws.com/0/170662/ff2249c9-499d-64e9-27e2-7ed9db131acb.png)


##＞エラー内容

```
The SDK has not been initialized, make sure to call FacebookSdk.sdkInitialize() first.
sdkInitialized
    Validate.java:143
<init>
    AppEventsLogger.java:950
<init>
    AppEventsLogger.java:940
newLogger
    AppEventsLogger.java:452
initialize
    FBAppEventsLoggerModule.java:117
doInitialize
    ModuleHolder.java:198
markInitializable
    ModuleHolder.java:86
notifyJSInstanceInitialized
    NativeModuleRegistry.java:125
run
    CatalystInstanceImpl.java:385
handleCallback
    Handler.java:751
dispatchMessage
    Handler.java:95
dispatchMessage
    MessageQueueThreadHandler.java:31
loop
    Looper.java:154
run
    MessageQueueThreadImpl.java:194
run
    Thread.java:761
```

##＞修正内容
下記を追加
FacebookSdk.sdkInitialize(getApplicationContext()); 

```
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
        FacebookSdk.sdkInitialize(getApplicationContext());  // <- 追加
    }
```

##＞参考URL
https://tylermcginnis.com/installing-the-facebook-sdk-into-a-react-native-android-and-ios-app/
Javascriptでテーブルの特定列の表示・非表示を切り替える

# 実装したいもの

HTMLのテーブルで、チェックボックスを用いて、列ごとに値の表示・非表示を行いたい。

- [x] 住所
- [x] 年齢

|氏名|住所|年齢|
|:-:|:-:|:-:|
|山田|東京|20|
|佐藤|神奈川|24|
|渡辺|大阪|18|

たとえば、上記テーブルで「住所」の列だけを、非表示になるようにしたい。

- [ ] 住所
- [x] 年齢

|氏名|年齢|
|:-:|:-:|
|山田|20|
|佐藤|24|
|渡辺|18|

こんな感じ。

# コード

以下のようにコードを記述する。テーブルはPHPで出力していてもよい。

```sample.html
<body>
<input type="checkbox" id="address_check" onclick="checkbox_cell(this,'address_display')" checked="checked">住所
<input type="checkbox" id="age_check" onclick="checkbox_cell(this,'age_display')" checked="checked">年齢
<table>
 <tr>
  <th>氏名</th>
  <th id="address_display">住所</th>
  <th id="age_display">年齢</th>
 </tr>
 <tr>
  <td>山田</td>
  <td>東京</td>
  <td>20</td>
 </tr>
 <tr>
  <td>佐藤</td>
  <td>神奈川</td>
  <td>24</td>
 </tr>
 <tr>
  <td>渡辺</td>
  <td>大阪</td>
  <td>18</td>
 </tr>
</table>
</body>
```

```sample.js
window.onload = function(){
var array = ["address","age"];
    for(var j=0;j<array.length;j++){
        var id = array[j] + "_display";
        var obj = array[j] + "_check";
        var CELL = document.getElementById(id);
        var TABLE = CELL.parentNode.parentNode.parentNode;
        for(var i=0;TABLE.rows[i];i++) {
            TABLE.rows[i].cells[CELL.cellIndex].style.display = (document.getElementById(obj).checked) ? '' : 'none';
        }
    }
}
function checkbox_cell( obj,id ){
    var CELL = document.getElementById(id);
    var TABLE = CELL.parentNode.parentNode.parentNode;
    for(var i=0;TABLE.rows[i];i++) {
        TABLE.rows[i].cells[CELL.cellIndex].style.display = (obj.checked) ? '' : 'none';
    }
}
```
## 注意点
- 先にJavascriptを読み込んでおく。
- `checked="checked"`は消しても動作する。必要に応じて使い分ける。


# 参考サイト

https://q.hatena.ne.jp/1192623624
Railsのログにcookieの値を出力する

# Railsのログにcookieの値を出力する

`config.log_tags`を使ってログ情報追加する。

`rails new`するとデフォルトで`config/environments`配下の環境別ファイルに記述されている設定値。

RailsGuideより
> config.log_tags: 次のリストを引数に取ります（requestオブジェクトが応答するメソッド、requestオブジェクトを受け取るProc、またはto_sに応答できるオブジェクト）。これは、ログの行にデバッグ情報をタグ付けする場合に便利です。たとえばサブドメインやリクエストidを指定することができ、これらはマルチユーザーのproductionアプリケーションをデバッグするのに便利です。

requestオブジェクトを受け取るProcを指定できるので、以下の様に`lambda`を指定する

```diff:config/environments/production.rb
Rails.configuration.log_tags = [
  :request_id,
+  lambda { |req| req.cookies["_hoge_session"] }
]
```
未経験からのプログラミング学習記録　vol.1

<h2>はじめに</h2>
<ul>
<li>今年の５月に前職を退職。元はファッション屋、ものづくりをする仕事をしたいと思っていたところでプログラミングと出会う</li>
<li>夏から独学で勉強しつつ職業訓練校に１０月から通い始める</li>
<li>そもそもHTMLとは、から始まるパソコン初心者レベル</li>
<li>職業訓練校の感想や自分で取り組んだことを記録</li>
<li>これはあくまで自分の記録用で感想はあくまで個人の意見</li>
</ul>
<h2>１ヶ月目　HTML5・CSS3</h2>
<p>取り組んだこと</p>
<ul>
<li>progate</li>
<li>ドットインストール</li>
<li>部分模写</li>
<br>
<li>一番はじめはやっていることがどういう意味があるのかもわからなかった。
progateは2周してなんとなく理解。ただ実際のWEBサイトはどうなっているのかわからなかったのでコードを見ながら実際に写してみた。時間もかかったしわからない部分もあったが全体がどう出来上がっていくのかがイメージ出来、なんとなく理解が早くなった気がする。</li>
<li>学校はかなり丁寧な教え方で説明に時間をかけることが多かったので家ではどんどん手を動かしてみた。ただ便利なツールやググって出てこないちょっとした疑問は聞くことができたのでよかった。個人的にはパソコン自体の仕組みやツールに疎い部分があったので助かった。</li>
</ul>

<h2>２ヶ月目　javaScript</h2>
<p>取り組んだこと</p>
<ul>
<li>progate</li>
<li>ドットインストール</li>
<li>Udemy [HTML/CSS/JavaScript] フロントエンドエンジニアになりたい人の Webプログラミング入門</li>
<li>↑現在ここ</li>
<li>学校ではjavaScriptの基礎文法には深く触らずjQueryライブラリの引用の仕方などのみ</li>
</ul>

<h2>さいごに</h2>
個人的には職業訓練校のカリキュラム自体は初心者の中の初心者の私にとってはすごく助かる部分が多い。ただ学校によっての違いはあるとは思う。（事前に説明会に行ってみた）たまたま講師の方がフリーランスで仕事もしているので現場の情報など参考になることも。
自分の場合それでも家での予習復習も合わせて毎日７、８時間はパソコンに向かっていると思う。かなり亀のスピードではあるが今年も残りわずか頑張ろう。
Selenideを用いてブラウザ自動操作環境を5分で作成してみる

#はじめに
この記事は[エムスリーキャリア Advent Calendar 2019 13日目の記事です。](https://qiita.com/advent-calendar/2019/m3c)
この記事ではSelenium WebDriverのラッパーである[Selenide](https://selenide.org/index.html)を使ってブラウザ操作をサクッと試してみます。

#対象読者
 - とりあえずブラウザの自動操作を試してみたい人
 - JavaでUIテストを書いてみたい人
 - ブラウザ操作を行うツールを作成したい人


#開発環境の準備
それではまず開発環境の準備から始めていきます。
IDEにはeclispeを使用します。
[https://mergedoc.osdn.jp/](https://mergedoc.osdn.jp/)よりJava Full Editionをダウンロードし、任意の場所に解凍します。
![eclipse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116611/012c93a4-7776-21f1-10fd-74f194d0d1b1.png)


解凍が完了したら、eclipse.exeを起動します。

#selenideの準備
次にGradleプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116611/0c48b56f-f448-de65-3760-309e04d9ed8b.png)

プロジェクトが作成されたらbuild.gradleに以下の一文を追加します。

```java

testCompile 'com.codeborne:selenide:5.5.1'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116611/34438fd5-c200-4d6e-71f9-c51d89c676e3.png)

以上で環境の準備は完了となります。

#実行
最後にGradleプロジェクトを作成した際に/[プロジェクト名]/src/test/java/[プロジェクト名]/LibraryTest.javaが作成されているので、元々の処理をコメントアウトし、以下のように書き直します。

```java

/*
 * This Java source file was generated by the Gradle 'init' task.
 */
package selenideSample;

import static com.codeborne.selenide.Selenide.*;

import org.junit.Test;

public class LibraryTest {
    @Test public void testSomeLibraryMethod() {
//        Library classUnderTest = new Library();
//        assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
      	  open("https://www.yahoo.co.jp/");
    }
}

```

さて、いよいよ実行します。
LibraryTest.javaのファイルを右クリックし、JUnitテストを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116611/c8b3bf12-cffd-0cba-f8b8-1eaf4a588717.png)

実行が成功すると新しくchromeが起動され、Yahooの画面が表示されることを確認できます。(一定時間が経過するとブラウザは自動的に閉じられます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116611/91aa6da0-675a-3528-56d2-ce9429637f1c.png)

#後書き
コード上でブラウザ操作実現する環境が簡単にできました。
今回は指定したURLを開いただけでしたが、他にもテキストボックスへの入力やプルダウンの選択、チェックボックスのチェックなど一般的なブラウザ操作全般をコードで記述できるのでとても便利です。
私は業務では大量のテストデータをブラウザ上から作成するときなどに活用しています。
selenideは[公式リファレンス](https://selenide.org/javadoc/current/com/codeborne/selenide/Selenide.html)も充実しているので是非ご活用いただければ幸いです。

#参考
https://selenide.org/quick-start.html
https://qiita.com/tatesuke/items/589e30ab9b3dc7037e26
[C#] Span<T>構造体からref Tを取得する方法の違い

普通に使う分には`ref span[0]`が良さそう。


| メソッド                              | `IsEmpty == true`          | `ReadOnlySpan`の場合     |                            |
| ------------------------------------- | -------------------------- | ------------------------ | -------------------------- |
| `ref span[0]`                         | `IndexOutOfRangeException` | 不可(`ref readonlyは可`) |                            |
| `Span<T>.GetPinnableReference()`      | `Unsafe.AsRef<T>(null)`    | 不可(`ref readonlyは可`) | IntelliSenseでは出てこない |
| `MemoryMarshal.GetReference(Span<T>)` | `Unsafe.AsRef<T>(null)`    | 可                       |                            |
PHPExcelでcellごとに加工する

# はじめに
*これは、[いえらぶアドベントカレンダー](https://qiita.com/advent-calendar/2019/ielove)用に投稿したものです。*

- 文系エンジニア
- 入社1年目

とかいうプログラミング初心者が、特に下半期によくやったPHPExcelを使う案件で困ったことと見出した解決方法について書きます。
ググってもなかなか出てこなかった内容なので、同じ課題を抱えている人の参考になれば幸いですし、もしここ間違ってるよ、こうやったほうがいいよ、というものがあればコメントをいただけますと、めちゃくちゃ喜びます。

# 案件の経緯

あるとき、とあるクラウドサービスがありました。

そのサービスには、契約書をExcelで出力できる機能がありました。

出力した契約書には、契約内容が自動で入力されていました。

あら、なんて便利なんでしょう。

しかし、クライアントは言いました。

**「もっと使えるようにしてほしい」**
※もちろん、盛ったうえでの意訳です。


# 本題

要望が多岐にわたっていたので、いろいろやったんですが、
そのなかでもセルの加工に悩まされました。

例えば、「このセルの色を変えたい！」となったとき、
「PHPExcel 色 変更」とかで調べます。

そこででてきたコードがこちら

```php

$sheet->getStyle( 'A1' )->getFill()->setFillType( PHPExcel_Style_Fill::FILL_SOLID )->getStartColor()->setARGB( 'FFFFCCCC');

```

参考：https://elearn.jp/phpexcel/cell/setfilltype.html

ふむふむ、なるほど。

なんかシートを取得して、文字列でセルを指定して加工するんだね。

おっしゃ！！！やったろ！！！！

そして、確認した既存のソースコードがこちら。

```php

// シートから行を取得してループ
foreach ($sheet->getRowIterator() as $row) {
    // 行からセルを取得してループ
    foreach ($row->getCellIterator() as $cell) {
        // 取得したセルを加工する関数へジャンプ！
        $this->editCell($cell);
    }
}
/* ※関数名やコメントアウトは変えてます。 */
```

・・・。

シートのまま加工するんじゃないんか！！！

さっきググったやつと違う！！！！

文字列でセルの指定なんかできなくないか！？！？

というわけで、他のサイトも探してみました。

しかし、探しても探しても`$sheet->`からそのまま加工するやり方ばかり、、、

`$cell->`から始まる加工方法が全然でてきません。


# 結論

いろいろ検索して、試してみて、トライアンドエラーを繰り返していたので、結論に至った経緯をはっきり覚えているわけではありませんが、、、

`var_dump`を加工した社内の独自関数を使って、objectの中をみたり
トライアンドエラーのなかでも、「目的は果たせなかったけどここは使える気がする」みたいな学びをしつつ、少しづつPHPExcelの理解を深めました。

そして出た結論。

**`PHPExcel_Cell`の中にあるメソッドで使えそうなものを探せばセルごとに加工できる。**

よく考えれば、`インスタンス化したクラス(オブジェクト)の中にあるメソッドを->で使えるよ`っていう基本のところを理解したうえで、
`ライブラリの深部までじっくり読む`っていうことをすればどうってことなかったんですね。

自分はまだ初心者だし、そんなところ見ても分からないっていう先入観から、避けてしまっていました。

**ビビらずにやってみる**というのができていればもっと早く解決できたかもしれません。

まあ、やりたかったことの中には、そこまでわかってもやり方が分からず、先輩にパスしてしまったものもあるんですが、、、


# さいごに
最初は、きちんとcellごとに加工する方法まで書こうと思っていたのに、あんまり会社のソースコード公開するのもどうなんだろ～と思っていたら一般論みたいな結論になっていました。
釣りみたいなタイトルですみません。
釣ろうと思ったわけではないです。

そんな感じで、私は社内でPHPExcelに詳しい人トップ8くらいには入れたのではないかと思います。(大きくでたのか小さくでたのかわからない)

これからも、このライブラリの使い方わかんね～～～～！！！！！ってなったときは、Google先生に頼りつつも自分でどうにかするようにしたいですね。
google-maps-services-jsにてGeocoding APIがiOSで動作しない場合の対応


# 背景

[事故マップ](https://jikomap.site)というサービスを個人開発で最近始めました。

![スクリーンショット 2019-12-12 23.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200963/5dbc586a-a0b1-9ded-6235-e3aa031f6cc0.png "スクリーンショット 2019-12-12 23.31.11.png")



マップを任意の場所にジャンプさせるために検索フォーム設けています。

ここでユーザーが入力したキーワードをGoogleMaps Geocoding APIにかけて
そのキーワードに対応する緯度経度を取得してMapを移動させるようにしています。


また、このGeocoding APIを利用するためにGoogle謹製の[google-maps-services-js](https://github.com/googlemaps/google-maps-services-js)を使っていました。


# 遭遇した問題

実際のコードではこのような感じでリクエストを処理していました。

``` Vue.js
const googleMapsClient = require("@google/maps").createClient({
  key: "API key XXXXXXXX",
  Promise: Promise
});


findLatLng() {
  googleMapsClient
    .geocode({
      address: this.searchWord // ユーザーが入力したキーワード
    })
    .asPromise()
    .then((response) => {
      console.log(response.json.results);
    })
    .catch(err => {
      console.log(err);
    });
}
```



macOS、Androidでは上記コードでレスポンスを取得する事ができていたのですが、
何故かiOSだけ次のようなエラーが出て必ず処理が失敗してしまいました。

``` TypeError: Request header field User-Agent is not allowed by Access-Control-Allow-Headers. ```

# 原因

いろいろ調べてみましたが、正確な原因はわかりませんでした。

しかし、別のモジュールを使ってみたところうまくいったので
google-maps-services-jsの何らかの不具合の可能性が高いです。

# 対応

実際、[vue2-geocoder](https://github.com/PDERAS/vue2-geocoder)を使ったところ、iOSでもレスポンスを取得できるようになりました。

ちなみにvue2-geocoderは中でXMLHttpRequestを使ってリクエストを投げているだけの非常にシンプルな作りになっています。

vue2-geocoderでの処理例

``` Vue.js
findLatLng(evt) {
    evt.preventDefault()

    var self = this
    var addressObj = { address_line_1: this.searchWord }
    Vue.$geocoder.send(addressObj, response => {
        console.log(response)

        if (response.status == 'ZERO_RESULTS') {
             console.log("no result");
        } else {
             console.log(response.results[0]);
        }
    })
}
```
Haskellで逆ポーランド記法の計算機を作る

# はじめに

[いなたつアドカレ](https://qiita.com/advent-calendar/2019/allinatatsu)の十二日目の記事です。

Haskellで逆ポーランド記法の計算機をつくってく記事です

# 環境構築(Docker)
```
$ docker run -itd --name haskell -v $PWD:/haskell -w=/haskell haskell
```

# はろわ

とりあえずコマンドライン引数を出力します。

環境構築(Docker)

```
$ docker run -itd --name haskell -v $PWD:/haskell -w=/haskell haskell
```

```rpn.hs

import System.Environment

main :: IO ()
main = do
    args <- getArgs
    putStrLn $ args !! 0  -- リストの0番目
```

getArgsでコマンドライン引数をargsに束縛し、 putStrLnで出力、改行を行っています。
Haskellではリスト内の値を「!!」を挟みindex番号で指定することでアクセスすることができます。

つまり、argsというリストの先頭を出力するといった内容になっています。

```
$ runghc rpn.hs hello
hello
$ runghc rpn.hs Hello World
Hello
$ runghc rpn.hs "Hello World"
Hello World
```
通常空白でくぎれ、リスト的に値が別れてしまうが、ダブルコーテーションで囲むことで、空白を無視して、一つにまとめることができます


## 計算する
```hs
calc :: String -> Double
calc = head . foldl folding [] . words
    where   folding (x:y:ys) "+" = (y + x):ys
            folding (x:y:ys) "-" = (y - x):ys
```

文字列を畳み込んで計算させる部分を作成しました。
foldlが左からの畳み込みで、foldingはに引数の計算にあたる関数です

これで、逆ポーランド記法での計算(足し算、引き算)ができるようになりました。

次回これを拡張していきます。
こんなメソッドまで？ブロックを受け取るRubyのメソッドたち

# 動機

この記事はもともと[LegalForceさんで行われたイベント](https://legalforce.connpass.com/event/154895/)のために調べ物をしていたのでそれを再利用したものです。
私はRubyの最大の強みの一つはブロックの表現力だと思うのですが、この記事ではそんなブロックを（実は）引数に受け取るメソッド群を紹介したいと思います。

# 本編

## 但し書き

今回はコアクラス（`String`, `Array`, `Hash`）のみに絞って紹介しています。
明らかにブロックを受け取ると思われるもの（例：each系のメソッド）などは除外されています。
その他、明らかに使い途がないと個人的に思われたものも除外しています。

## String

### String#gsub

個人的に意外だったものの筆頭は、`gsub`と`gsub!`がブロックを受け取ることです。以下のように使います。

```ruby
'hoge'.gsub(/[aiueo]/) {|match| match * 2 } # => hoogee
```

これはかなり便利そう。

### String#match, Regexp#match

`match`は正規表現に対して呼ぶのが王道な気はしますが、どちらもブロックを受けることができます。

```ruby
str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
str.match(/^(.+) (.+)/) {|match| puts match[2] }
# "elit."が出力される
```

### String#scan

存在自体を知らない人も多いであろう`scan`メソッド。`match`の同じようなブロックの使い方ができます。

```ruby
str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
str.scan(/\w+/) {|word| print "*#{word}*"}
# "*Lorem**ipsum**dolor**sit**amet**consectetur**adipiscing**elit*"が出力される。
```

## Array

### Array.new

今知ったのですが、`Array.new`はブロックを受けることができるようです。

```ruby
Array.new(3) {|index| index ** 2} # => [0, 1, 4]
```

いつ使うんだろ…

### Array#count

メジャーなメソッドである`count`も実はブロックを受け取ります。

```ruby
ary = (0..10).to_a
ary.count {|e| e.even? } # => 6
```

これはとてもRuby的で綺麗だと思います。

### Array#fetch

`Hash#fetch`と比べると使う機会は少ないですが、配列にも`fetch`メソッドがあります。

```ruby
ary = (0..10).to_a
ary.fetch(100) {|i| puts "#{i} is out of range" }
# "100 is out of range"が出力される。
```

### Array#index

ブロックがtrueを返す最初のインデックスを返します。こんなものあるんだ…

```ruby
ary = (0..10).to_a
ary.index {|i| i.odd? } # => 1
```

### Array#to_h

`to_h`ってブロック受け取れるんだ…！

```ruby
ary = (0..10).to_a
ary.to_h # => TypeError
ary.to_h {|e| [e.to_s, e ** e]} # => {"0"=>1, "1"=>1, "2"=>4, "3"=>27, "4"=>256, "5"=>3125, "6"=>46656, "7"=>823543, "8"=>16777216, "9"=>387420489, "10"=>10000000000}
```

何かに使えそう。

## Hash

### Hash#merge

これもすごく便利だと思ったやつで、ハッシュ同士を合体させるときにキーがコンフリクトしたものの処理をブロックで行うことができます。

```ruby
h1 = {a: 1, b: 2}
h2 = {b: 3, c: 4}
h1.merge(h2) {|key, old, new| old + new} # => {:a=>1, :b=>5, :c=>4}
```

### Hash#to_h

最初はよく意味がわからなかったのですが、`Hash#to_h`はブロックを受け取るとキーバリューペアをブロック引数として返り値の配列を新しいハッシュとすることができるようです。

```ruby
{foo: 42}.to_h {|k, v| [k.upcase, v * 2]} # => {:FOO=>84}
```

これは実質`map`しているということなのでしょうか…

# まとめ

今回はコアクラスに絞ってブロックを受け取るメソッドを紹介しました。他にももちろんまだまだあるので、ぜひご自身で調べてみてください。
gRPCでオンラインポーカーを作った話

ここ何ヶ月か合間の時間を見繕って勉強がてらgRPCとgoでオンラインポーカーを作っていたのでご紹介してみる（ソースがあれですみません。。

* proto  
https://github.com/admogh/online-porker-protos  
* server  
https://github.com/admogh/online-porker-server
* client(go)  
https://github.com/admogh/online-porker-clients

Dockernizeしていないのでそのままですが多分諸々入れればローカルで動作するようになっています。
# 仕様
* ポーカーのルール的には古いクローズドなファイブカードドローで（ただし現状ベッティング要素なし）、4人プレイ専用で、単純に1人ずつカード交換をします。
* 他のクライアントからの接続がない場合Wait後残りのプレイヤーをNPCとしてゲームが開始されます。
* 基本的にクライアントが何もしないとサーバ側で自動的にタイムアウトしたとみなして処理を進めていきます。
* リクエスト的には以下があります（詳細は [proto](https://github.com/admogh/online-porker-protos/blob/master/protos/porker.proto) を御覧ください) 

| rpc     | 概要 | サーバ | クライアント |
|---------|---------|---------|---------|
| SignUp | 登録 | 新規登録時に名前を設定しないと自動的に名前が決められてレスポンスに返します | レスポンスの名前をデータベースに保存します。 |
| ChangeName | 名前変更 | 二回目以降で違う名前で実行した時にサーバへ変更のリクエストがされます。 | |
| SignIn | ログイン | | |
| Join | 部屋に参加 | 部屋のIDと名前を返します。 | |
| Start | ゲームスタート | game_id（一ゲームを一意に表すID）、クライアントのIDおよび他プレイヤーのIDと名前を返します。また最初の手番となるプレイヤーのIDとクライアント用の5枚のカードを返します。 | |
| Change | カード交換（自分用) | |
| Draw | カード交換（他人用) | 他のプレイヤーのカード交換をリクエストします。順番が違う場合エラーを返します。また、他のプレイヤーの入力待ちの場合一定時間Wait後に結果を返します。 |
| Open | カードオープン | すべてのプレイヤーの交換後のカードをレスポンスとして返します。またポーカーの役と結果としてのランクを返します。 | すべてのプレイヤーの交換が終わった段階でリクエストします。各プレイヤーのカードの役とランクを表示し、誰が勝者かを表示します。 |
| End | ゲーム終了 | プレイヤーの入力に応じてゲームを続けるか終えるかをリクエストします。サーバはリクエストに応じて次のゲームのためのリフレッシュ処理、または終了処理を行います。すべてのプレイヤーがOpenResponseを受け取るまでWaitします。 | |

# 構成/アーキテクチャ
<img width="609" alt="スクリーンショット 2019-12-12 20.31.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147303/6f6e13d6-db4d-2c97-7305-f45e4066c828.png">

* クライアントはsqliteにユーザデータ（現状名前とID）を保存します。
* サーバはSignUpしたユーザ情報（現状名前とID）をMySQLに保存します。
* サーバはredisにゲームに利用する情報を保存して使います。  
https://github.com/admogh/online-porker-server/wiki/Redis-Keys

# デモ
![porker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147303/50a813b0-efa2-5a65-0569-de6388e6f7ac.gif)

上がサーバで下がクライアントになります（たまたま最後にストレートがでた。

# gRPCについて
gRPCを使った実装ははじめてではなかったですが、今回改めて一から設計・実装をやってみて、gRPCが担保してくれるところはあるにしても、サーバとクライアントとのインタフェースを考えるのはやはりいつも大変だなと感じました（よりリアルタイムなオンラインゲームを作ろうとした時には、protoで表現できる領域が少なくなって、もっと実感することが多いかもしれないです）。
実際今も完成形ではありませんが、最後までprotoをフィックスさせることができませんでした。

今回は結局使いませんでしたが、streamingを使ったprotoも検討していました（途中まで実装していた）。今回は1ターンで終わりなので必要性がないという判断に至ったのですが、本質的にストリーム処理として必要なものなのかということを考えるのが判断のポイントになるように思いました。

サーバとクライアントとのインタフェースを考えていると悩む場面も少なからずありましたが、protoについて、リクエストがサーバに必要なものであり、レスポンスがクライアントにとって必要なものであると意識すること、protocで生成される利点を活かして共通に使われるような機能を組み込むこと（今回であればポーカーの役など）がよいように思いました。

# その他
* NPCの機能は必須項目として実装しましたが、やはり考えることは増えます。設計次第なところはあると思いますが、NPCを完全にPCと同じものとして扱うのは他にかかるコストが増えていく気がしてバランスが求められるように思いました。
* 正直現状色々足りてないし、バグもあります。gRPC的にちゃんとエラーコードを適切なものとして返すことも必要です。  
https://github.com/admogh/online-porker-server/issues

# 最後に
ここまで読んでいただいてありがとうございました。
最近ボードゲームをやっていてアプリ化して遊べないかなとかぼんやりと考えることがあるのですが、このようなことに興味ありましたらお気軽にご連絡ください。一緒に何かを考えましょう。
https://twitter.com/admonow
ハッシュ値（PHP）

##ハッシュ値とは
元のデータ数に関係なく、一定の長さ、また、同じ値を送ると同じハッシュ値がかえってくる値

例：aaa →　ハッシュ化 → 17592735928795jewitjw
再度aaaをおくっても、同じになる。aをおくると、データの文字数は変わらない違う値が返ってくる

## phpで文字列をハッシュ化

```:php
sha256(); //ハッシュ化関数
sha256(uniqid(mt_rand(), true)); //安全の高い一意なハッシュ値
```
##ハッシュ関数の優秀度

md5 < sha1 < sha256(md5の倍)
優秀度が低いほど、簡単に生成できてしまう。

md・・・出力128bitのアルゴリズム
sha・・SSL、SSHなどで用いられる暗号化アルゴリズム

##参考にさせていただいた記事
[PHPでユニークなIDを生成する](https://kakakakakku.hatenablog.com/entry/20081016/1224154493)
[暗号化とハッシュ化に関する基本的な事柄まとめ](https://qiita.com/chroju/items/3ddae568206b8bc3d8f9)
Eclipseのm2eで操作するmavenのバージョンの確認の仕方について

# はじめに
Eclipseで使ってるmavenのバージョンってdefaultだと何使ってるか知りたかったので今回それを簡単にまとめます。
・・・どこに書いているのかとかなかなかわからなくて結構難航しました。

# 環境
Eclipse Version: 2019-09 R (4.13.0)
[2019/12/12現在、2019-09をこっからダウンロードした](https://mergedoc.osdn.jp/)

## Eclipseに梱包されているmavenのバージョンの確認の仕方について
`Eclipseメニュー > ウインドウ(W) > 設定(P) > Maven > インストール`
こんな画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/dee17577-c136-8889-c585-3e6096a50b9f.png)

EMBEDDEDの詳細がデフォルトのバージョンっぽいですね。これは3.6.1ですね。mavenの最新バージョンとか使いたい場合はここを切り替えてあげればビルドが通りそうですね。追加からmaven選択してあげて切り替えればバージョン違うのにきりかえてmavenプロジェクトの更新も可能でした。

ちなみに、1.13.0・・・の後ろの数字はm2eプラグインのバージョンですかな？？なんだろう？

でもm2eのバージョンってEclipseの以下の操作で見れるのが正しいんじゃなかったかな？
`Eclipseメニュー > ヘルプ(H) > Eclipse IDEについて(A) > Mのアイコン`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/188d9b4e-e0f7-5cde-ec84-94de0b3cf505.png)

ここみるとm2eのバージョンは`Version: 1.4.2.20190530-0057`ってなってる。
じゃあ1.13.0って何なんだろ？m2eのバージョン表記ではないのか？

Eclipse難しい。
ubuntuで起動時にbusyboxとなり肝を冷やした話。

##概要
ubuntu18.04を使って開発をしていて、PCがハングしまして、強制終了（ポチッと）しました。
再起動したところ、

```
/dev/sda2 contains a file systems with errors, check forced.
Inodes that were part of a corrupted orphan linked list found.
```

と出て、ubuntuが起動しなくなりました。
書いたコードはプッシュしておらず、gitには

```
last commit 5 hours ago
```

となっており、５時間の作業結果が飛んだのは痛すぎる、、、、
と思っていたのですが、

```
(initramfs)_
```

のプロンプト画面に対して、

```
fsck /dev/sda2
```

このとき下のようなたくさんエラーの修復を行いますか？というふうに聞かれるので、全てyで答えます。

```
> group descriptor checksums are invalid. Fix<y>?
> Pass 1: ...
...
> Pass 5: ...
> Block bitmap differences : ...
> Fix<y>?
> Free blocks count wrong for group #1 ...
> Fix<y>?
```

全ての修復が終わると、
```exit```とコマンドに入力してエンターを押すことで再起動が始まり、なんとかまたubuntuを起動できました。


よかった。。

おわり。
[Spring MVC] パス変数の受け渡し方について

Springでのパス変数の受け取り方、リダイレクト先への渡し方メモ
## パス変数を受け取る方法
```java
// (1)
@GetMapping("{name}")
public String detail(@PathVariable String name) {
    return "detail";
}

// (2)
@GetMapping("idol/{name}")
public String idolDetail(@PathVariable("name") String idolName) {
    return "idol/detail";
}

// (3)
@GetMapping("unit/{unitId}/idol/{idolId}")
public String idolDetail(@PathVariable("unitId") Integer unitId, @PathVariable("idolId") Integer idolId) {
    return "idol/detail";
}
```
パス内に含まれる値をメソッドの処理内で利用したい場合は、Mappingアノテーション内の受け取りたい値が入る箇所をパス変数（`{変数名}`）の形式とし、それに対応する引数に`@PathVariable`を指定する。

(1) パス変数名と実際に利用する変数名が同じ場合は`@PathVariable`のvalue属性を省略できる。
(2) 変数名が異なる場合は`@PathVariable`のvalue属性にパス変数名を指定する。
(3) 複数も可。

## パス変数をリダイレクト先へ渡す方法
```java
// (1)
@PostMapping("idol/{name}/update")
public String update(@PathVariable String name) {
    return "redirect:/idol/{name}";
}

// (2)
@PostMapping("redirect")
public String redirect(RedirectAttributes redirectAttributes) {
    redirectAttributes.addAttribute("name", "大崎甜花");
    return "redirect:/idol/{name}";
}
```

(1) 
一度パス変数として受け取った変数はそのままリダイレクト先へ渡すことができる。
上記のコードの場合、`/idol/幽谷霧子/update`へPOSTリクエストを送ると結果としてリダイレクト先のURLは`/idol/幽谷霧子`となる。
(2)
RedirectAttributesの`addAttribute`メソッドを利用して追加した変数がリダイレクト先のパス変数に含まれる場合はそのままパス変数として展開される。
上記の場合だとリダイレクト先のURLは`/idol/大崎甜花`となる。

(2)は別で値を入れる必要がないなら単純な文字列結合などでも良いかもしれない。

## 参考
[公式リファレンス](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-redirecting-passing-data)
[Spring MVC コントローラの引数](https://qiita.com/MizoguchiKenji/items/2a041f3a3eb13274e55c)
[Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発](https://www.amazon.co.jp/dp/B01IEWNLBU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
JQuery 文末を常に一行改行(空の場合はそのまま）


```:JQuery
if(text){
	text = text.replace(/\n{0,}$/,"\n\n");  
}
```

if(text)・・・JS中身の文字があるなら
https://qiita.com/_Hammer0724/items/3d21ef84813ee82e8252

####正規表現
$　　　・・・末尾
{0,}　　・・・0個以上
０以上の開業文字列を、1行開けた状態にする。
【Vue】不完全形態のWebページを表示させなくする方法(v-cloakディレクティブ)

## はじめに
コンパイル**完了後**にページを表示することで、不完全なWebページをユーザーに見せないようにする方法です。

**Vue.js**で`v-cloak`ディレクティブを活用していきます。

[Vue.js 公式ドキュメント](https://jp.vuejs.org/v2/api/index.html#v-cloak)

## 環境
```yaml
- OS: macOS Catalina 10.15.1
- zsh: 5.7.1
- Vue: 2.6.10
```

## 結論：コード

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <link rel="stylesheet" href="./style.css">
    <title>Title</title>
  </head>
  <body>
    <div id="app" v-cloak> # ここにv-cloak
      {{ message }}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="main.js"></script>
  </body>
</html>
```

```css:style.css
[v-cloak] {
  display: none;
}
```

```javascript:main.js
var app = new Vue({
  el: '#app',
  data: {
    message: "This is v-cloak directive."
  }
})

```

## 補足：`v-cloak`とは？
[公式ドキュメント](https://jp.vuejs.org/v2/api/index.html#v-cloak)によると、

> このディレクティブは関連付けられた Vue インスタンスのコンパイルが終了するまでの間残存します。

とのこと。

コンパイルが終了するまでの間残存する
↓
コンパイルが終了すると消えてくれる
↓
`display: none;`が消えて描画されるようになるということですね:point_up:

※今回のコードで、もし`v-cloak`を使わなかったら、`{{ message }}`という**Mustache**がコンパイル前の不完全な状態で一瞬表示されてしまうことになります。

## アレンジ：コンパイル後ふぁっと表示させる
CSSを少しいじって、コンパイル後に**フェードイン**で表示するようにしたコードです。

```html:index.html(変更なし)
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <link rel="stylesheet" href="./style.css">
    <title>Title</title>
  </head>
  <body>
    <div id="app" v-cloak>
      {{ message }}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="main.js"></script>
  </body>
</html>
```

```css:style.css
@keyframes cloak-in {
  0% { opacity: 0; }
}

#app {
  animation: cloak-in 1s;
}

[v-cloak] {
  opacity: 0;
}
```

```javascript:main.js
var app = new Vue({
  el: '#app',
  data: {
    message: "FADE IN..."
  }
})

```


## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

これまで中途半端な状態を見せたくない要素にはCSSで時間を数秒遅らせて表示するようにしていました。

`v-cloak`を使って**コンパイル完了後**というタイミングを指定出来れば、ユーザーの通信速度や端末のスペックに応じて表示されて便利ですね:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
[API — Vue.js](https://jp.vuejs.org/v2/api/index.html#v-cloak)
[基礎から学ぶ Vue.js | mio |本 | 通販 | Amazon](https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-Vue-js-mio/dp/4863542453/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6vue&linkCode=qs&qid=1576160622&sourceid=Mozilla-search&sr=8-1)
【画像処理100本ノックに挑戦】Q.3. 二値化

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.3. 二値化

> 画像を二値化せよ。 二値化とは、画像を黒と白の二値で表現する方法である。 ここでは、グレースケールにおいて閾値を128に設定し、下式で二値化する。
> y = { 0 (if y < 128)
     　　255 (else) 

まだ簡単！

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	for(int j=0; j<height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			y = (y < 128 ? 0 : 255);
			ppm2(i, j, 'r') = y;
			ppm2(i, j, 'g') = y;
			ppm2(i, j, 'b') = y;
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```
![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/95b84ddf-d746-d5db-706d-ac2d40bfe063.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/bac7052c-0771-80ff-efa2-233731a01aa5.png)
Emacs27で追加されるタブ機能について

# はじめに
そろそろリリースが予定されているEmacs27では、待望(？)のネイティブ実装のタブ機能が追加されます。
Emacs26で追加された行番号表示のネイティブ実装といい、最近はユーザ作成のパッケージをネイティブ実装する流れが多いですね。
Emacs27では2種類のタブ機能が追加されるので、それを今回はご紹介したいと思います。

# Emacs27で追加される2つのタブ機能

Emacs27では、以下の2つが追加されます。

- tab-bar-mode
- tab-line-mode

それぞれ詳細にご紹介します。

## tab-bar-mode (frameに設定されるタブ)
tab-bar-modeでは、frameに対してタブが設定されます。 `M-x tab-bar-mode` でモードを有効化する他、 `C-x t 2` でタブをあたらしく作ることができます。

frameに対してタブが設定されるので、タブを切り替えるとwindow一式が切り替わります。

![tab-bar-mode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34657/0bfa9b00-240f-a885-bc99-94cf7ec5b153.gif)

プリフィックスはデフォルトでは、 `C-x t` で、windowの切り替えに似た感じで、 `C-x t o` でタブを切り替えることができます。
また、タブ名はデフォルトではフォーカスされたwindowのバッファ名ですが、 `C-x t r` で、タブ名を設定することができます。上のGIFでは、それを使ってひとつめのタブを、 tab-1と命名しています。

tab-bar-modeはelscreenとかescreenとかの、screen系パッケージの挙動に似ていますね。

## tab-line-mode (windowに対して設定されるタブ)
tab-line-modeは、windowに対してタブが設定されます。 `M-x tab-line-mode` でカレントwindowに対してタブが設定される他、`M-x global-tab-line-mode` ですべてのwindowに対してタブが設定されます。

デフォルトではキーバインドは特に設定されていないみたい。

windowに対して設定されるタブなので、バッファの一覧が追加されていき、それらを切り替えることが可能です。

![tab-line-mode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34657/c79bfe7b-c370-6b2e-cba3-3497bb218467.gif)

# まとめ
簡単ですが、emacs27で追加されるタブ機能について紹介しました。
これまでタブパッケージだと、tabbar.elをはじめ、tab-line-modeに近いバッファを切り替えるタブが多く、それってあまり意味ないなあと思って使ってなかったのですが、tab-bar-modeはおもしろいですね。

結構日々新しいメソッドなりfaceなりがコミットされている状況なので、HEAD民としては実際使ってみて、おもしろい機能があればまたご紹介したいと思っています。
Viewport固定幅のようにHTMLのスケールを変える

レスポンシブにコンテンツ全体の幅を変えたくて作りました。

https://codepen.io/tsunet111/pen/xxbOrjN

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="tsunet111" data-slug-hash="xxbOrjN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Scalable container">
  <span>See the Pen <a href="https://codepen.io/tsunet111/pen/xxbOrjN">
  Scalable container</a> by Tsuneaki Hasekura (<a href="https://codepen.io/tsunet111">@tsunet111</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

- ウインドウの幅をみて、それに対応してコンテンツのスケールを変える
- スケールを変えると、余白ができてしまうので、そのぶんだけマイナスのマージンを設定する

といったことをやっています。
【画像処理100本ノックに挑戦】Q.2. グレースケール化

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.2. グレースケール化

> 画像をグレースケールにせよ。 グレースケールとは、画像の輝度表現方法の一種であり下式で計算される。
>Y = 0.2126 R + 0.7152 G + 0.0722 B

まだまだチュートリアルって感じですね。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	for(int j=0; j<height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			ppm2(i, j, 'r') = y;
			ppm2(i, j, 'g') = y;
			ppm2(i, j, 'b') = y;
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/ae973aa3-6d2f-1f9b-02bc-03cdbfde4937.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/149d057c-76e2-99e4-9cea-7090f3776abf.png)
Microsoft Learn 13日目

*2019/12/16 タグ編集。

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/13 は
**Core Cloud Services - Azure portal を使用してサービスを管理する**
 - Azure portal のダッシュボード
 - 演習 - ダッシュボードをカスタマイズする
 - パブリックおよびプライベート プレビュー機能へのアクセス

を受講。以下、簡易メモ。

# Core Cloud Services - Azure portal を使用してサービスを管理する
## Azure portal のダッシュボード
### ダッシュボードとは
Azure portal に表示される UI タイルのカスタマイズ可能なコレクション。
JSON ファイルとして保存される。
つまり、他のコンピュータ間でアップロードしたりダウンロードしたり、Azure ディレクトリのメンバーと共有したりできる。

以後、ダッシュボードの操作説明なのでメモ略。

## 演習 - ダッシュボードをカスタマイズする
演習項目なので、メモ略。
OpenSiv3D Linux版をVimで

# はじめに
この記事は[Siv3d Advent Calendar 2019](https://qiita.com/advent-calendar/2019/siv3d)18日目の記事です。

# 今回やること
OpenSiv3D Linux版はCMakeを使ってビルドを行います。
Vimmerの私はプロジェクトの作成、ビルド、実行を全部Vimからできれば便利だと思い、プラグインを作成しました。
それがこちらになります。
https://github.com/higashi000/opensiv3d.vim

※プラグインの名前がnamespace的にやばいので新しい名前が決まり次第すぐに変更します。

# 補完の話
前もって書いておきますが、このプラグインでは補完はサポートしません。
というのも、vim-lspやcoc.nvim、LanguageClient-neovimといったプラグインを使ってlspを使えば簡単にOpenSiv3Dの補完ができるからです。

それぞれのプラグインのオプションにルートディレクトリの指定のオプションがあるので、そちらでプロジェクトをビルドした際に吐かせる`compile_commands.json`を読み込むようにするだけです。

sample(vim-lsp)

```vimscript
if executable('ccls')
  au User lsp_setup call lsp#register_server({
      \ 'name': 'ccls',
      \ 'cmd': {server_info->['ccls']},
      \ 'root_uri':{server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'compile_commands.json'))},
      \ 'whitelist': ['c', 'cpp'],                                                                                                                                               
      \ })
endif
```

# 実装したい機能
- プロジェクトの作成
- CMakeLists.txtへビルド対象のソースファイルを追加
- ビルド(cmake, make)
- 実行

# 実装できた機能
実行以外の機能は実装しました。

# 使い方
## OpenSiv3Dをビルド
まずはOpenSiv3Dをgit cloneしてきます。
その後、ビルドし、cloneしてきたリポジトリごと、`.cache`に配置します。
下記コマンドのようにディレクトリを作成、ビルドしてください。

```
$ git clone https://github.com/siv3d/OpenSiv3d ~/.cache/OpenSiv3D
$ cd ~/.cache/OpenSiv3D
$ git checkout linux
$ mkdir Linux/Build
$ cd Linux/Build
$ cmake -DCMAKE_BUILD_TYPE=Release -GNinja ..
$ ninja
```

## プロジェクトの作成
```
$ mkdir TestProject
$ cd TestProject
```
等でプロジェクトのディレクトリを作成、移動してください。

- `OpenSiv3DInit`

というVimコマンドがあるのでプロジェクトディレクトリ直下で実行するとそのディレクトリにプロジェクト(CMakeLists.txt、resources、src)が作成されます。

ここでresourcesが存在しない等のエラーが出た場合は`.cache`下に配置したOpenSiv3Dのディレクトリの名前等が間違っている可能性があります。

## プロジェクトのビルド
プロジェクトがあるディレクトリでvimを開き、
- `OpenSiv3DBuild`
を実行すると`cmake`と`make`が実行されます。

## ビルド対象ソースコードの追加
追加したいソースコードを開いた状態で
- `OpenSiv3DSourceAdd`
を実行することで追加できます。

# このプラグインの今後
名前を変えます。
この名前を保持し続けるのは他のプラグインのnamespaceとの衝突を招くため、なるべく早く(年内には)新しい名前を決めて変更します。

また、まだまだ未完成なのでこれからより完成度を高めていきたいです。
Dvorak配列を１年間使用してみて

こちらは[GEEK Inc. Advent Calendar 2019](https://adventar.org/calendars/3921) 12日目の記事です。

## はじめに

Dvorak配列を使い始めてから約１年が経過したので、その感想とそれまでにしたことなどをまとめてみました。

## Dvorak配列
![2560px-KB_United_States_Dvorak.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240345/00da8402-f93d-d660-515e-069c5e2936bc.png)
>
「打鍵の誤りを低減して、入力速度を向上させ、入力従事者の疲労を軽減する」ことを目的に、英文でアルファベットの出現頻度と相関性を分析し、英文入力に特化して設計された。
>　　　　　　　　　　　　　　　　　　　　　　[Wikipedia](https://ja.wikipedia.org/wiki/Dvorak%E9%85%8D%E5%88%97)より引用


## 環境
macOS Mojave
Karabiner-Elements 12.8.0
google日本語入力

## したこと
* **修飾キー押下時はQWERTY配列に**
コピーペーストなどのショートカットは以前と同じように使いたかったのでAlt,Command,Controlを押してる間はQWERTY配列になるようにしました。

* **google日本語入力のRomajiTableを変更**
ローマ字入力のことは考えられていないのでデフォルトのままだと若干打ちづらいです。
そのため か行をCでも打てるように、きゃをcya、ちゃをchaで打てるように変更しました。

* **キーの配置を変更**
個人的にFキーが使用頻度に比べて打ちづらい位置にあったのでZキーと交換しました。

* **Dvorak配列とQWERTY配列をショートカットキーで切り替えられるように**
Karabiner-ElementsのProfilesにDvorak配列とQWERTY配列を設定しています。
Karabiner-ElementsからCLIが提供されているので、こちらを用いてProfilesを切り替えることができます。  
**手順**
下記ファイルを`~/.config/karabiner/assets/complex_modifications/`以下に置きKarabiner-Elementsの設定画面でCmplex modifications->Rules->Add ruleから`profilesを切り替える`を各Profilesごとに選択すると設定できると思います。
こちらは一例ですので変更して下さい。

```json
{
  "title": "profilesを切り替える",
  "rules": [
    {
      "description": "profilesを切り替える",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "l",
            "modifiers": {
              "mandatory": ["command"],
              "optional": ["any"]
            }
          },
          "to": [
            {
              "shell_command": "[ $('/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli' --show-current-profile-name) = 'dvorak' ] && '/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli' --select-profile 'qwerty' || '/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli' --select-profile 'dvorak'"
            }
          ]
        }
      ]
    }
  ]
}
```


* **自作キーボードを作った**  
ErgoDashを作成しました。  
Karabiner-Elementsなどの外部ツールを使わず、どのPCでも同じキーマップが使えるというのはとても良いですね。  
別のキーボードやキースイッチも試してみたいです。

## 良かったこと

* **タイピングが楽**  
一番のメリットはやはりコレだと思います。  
ホームポジションからほぼ動かないので、打鍵が非常に楽です。  
また左右交互に打つため、片方に負担が集中しません。  
タイピング中の煩わしさやストレスも感じなくなりました。


## 悪かったこと

* **自分のpcを他人が使えない**
pcを人に貸す際、わざわざ配列を切り替えなくてはなりません。
前述したようにショートカットキーでQWERTY配列に戻してから貸すようにしています。

* **QWERTY配列が使えなくなる**
自分以外のpcを使う際に、タイピング速度がかなり遅くなります。
一時期両方使うようにしていたのですが、どっちも中途半端に打てなくなったので辞めました。

## 今後したいこと
SHIFT+数字の記号が打ちづらいので、symbolキーを設定してsymbol+英字で入力できるようにしたいです。

***


[GEEK Inc. Advent Calendar 2019](https://adventar.org/calendars/3921) 次回（12/14）はデザイナーチームの金箱さんです！