OmniAICreator/Qiita-1.07M huggingface dataset:
テスト管理者として大事な事~コミュニケーション編~

※本内容では、下記の内容を定義しています。
・タイトル　→　ゲーム名
・開発 → ゲーム開発チーム



#はじめに
前回は「[テスト項目の改修](https://qiita.com/tani_inat/items/9b966346c24009928277)」について、自分の体験ベースで共有させていただきましたが
今回は、**「開発側とのコミュニケーション」**についてお話させていただければと思います。

担当になった当時、私は開発側の人が**大大大嫌い**でした。
しかし、それから数年経った今では、自分の担当しているタイトルと開発が**No.1**だと思えるくらい**大大大好き**です。
なぜそんな手のひら返しが起きたのか...
**今回も私の体験ベースで感じたことを書くので、生暖かい目で読んでやってください**

#当時の地獄のような状況
自分が今の担当タイトルを持った時期が、年末年始で開発もQAもてんやわんやだった時に急遽担当となったのでした。

その時の開発側の空気はまぁ最悪
**・「何でこの障害はQAで検知出来ないの？」
・「QAなのに仕様知らないんですか？」
・「障害減らないのはQAが悪いからだ！」**
という「新しく来たテスト管理者のあいつは使えない」という状況が続きました。
**開発や周りへの苛立ちと悔しさで、家に帰って風呂場で泣いていた程でした。**

#自分のこと、QAの事を知ってもらう
開発側から色々言われるのはしょうがない、**何故なら当時障害が確かに多かったから！**
このままではいかん...と一念発起。まずは自分の考えを変えてみようと思いました。
**・QA体制の再構築
・担当タイトルを好きになる
・開発側の意を酌む**
この3つを意識してコミュニケーションをとったらどう変わったのか！
#QA体制の再構築
前回の記事では「テスト項目の属人化」について書きましたが
実は担当者の属人化もあり、なんというかまぁ...言葉を選ぶと負の遺産だらけでした。

何が問題かというと、ナレッジ・検証方法などの知見すべてが**テスト管理者しか知らず
テスターまで情報が降りてきていなかった**のです。
![20181221_171929.png](https://qiita-image-store.s3.amazonaws.com/0/328167/337228fc-e9db-45dc-2daf-367862eea1f7.png)
しかもナレッジをまとめた資料すらないまま退職となってしまい、だれも情報を知らない状態に...
これではアカンとして取った対策は、それはとてもシンプルでした。
**・テスターに情報を伝える
・開発側との連携をテストリーダーにお願いする
・テストリーダーが開発環境の操作を出来るように、開発側にツール作成の依頼・botの操作方法を教えてもらう**

開発とのブリッヂ業務やテスト設計で時間がとられれしまうため、一部作業をテスターに依頼し、コミュニケーションを取れる環境を構築
この結果、テスターにも情報が降りてくるようになり、テスト管理者とテスターの連携内容も強化・認識齟齬も減少しました。
![20181221_190109.png](https://qiita-image-store.s3.amazonaws.com/0/328167/e1674f9c-036f-aa91-48cc-14bd1bb6b2a9.png)
これが一番苦労した部分かもしれません。

#担当タイトルを好きになる
その名を通り自分の担当タイトルを好きになるようにしました。
これも簡単！**とにかく担当タイトルをプレイすること！**
何故これをやろうと思ったかというと、開発側も自分が作った施策を業務の為もあったと思うのですが、単純に**「自分のタイトルが好き」**という理由でプレイしていたからでした。
**「すっげぇプロ意識！」**と思った私も、仕様を覚える為に始めました。

**1日必ずゲームを触る
イベントを1か月間本気でプレイする
無理のない課金をする。**
この3つを自分ルールにおいてプレイした結果、**定常施策での仕様把握、影響範囲の考察が可能になる、〇〇円の総額課金達成**になりました。
仕様を知らないと、**開発側が確認してほしい箇所や意図が理解できず、認識の齟齬から障害のリスクが高くなってしまう**と考えてプレイしていたのも大きかったと、自分の中で感じています。

#開発側の意を酌む
開発者も人間です。
人間なので実装遅延もするし、不具合を作りこんでしまう事もあります。
**「何故実装が遅れているのか？QA中に不具合が多発するのか？」**
ネガティブな状況でも、**「何故今こういう状況になっているのか」**を考え、現状の打開策と次回へ向けての改善を相談・提案をしてきました。

結果、デバッグツールの拡充を行ってもらい、**テスト時に発生していた設定依頼待ちの工数を削減**と**QA時に発生していた不具合件数の件数を削減**することが出来、費用削減とフリーデバッグが出来る時間が増え、リリース後の障害も減り品質が高くなりました。
#最後に
コミュニケーションに正解はなく、相手の気分や状況次第で変わったりと大変ではあります。
しかし一つだけ分かったことは**「努力した部分を人はちゃんと評価してくれている」**という事でした。

結果、開発側から「今の体制になっているのはありがたい」と感謝の言葉をもらったり、プライベートでご飯を食べに行く仲になったりと、あの頃とは打って変わって良好な関係を築けています。
**まずは失敗しても、自分の熱意と考えを相手に伝え、相手が渋ったら一緒に打開策を考える**
これを意識してみるのもいいかもしれません。
文系の私の基本情報技術者試験の勉強法

# はじめに
平成30年度春季試験で合格することができました。
自分が文系大学出身のド文系のため、文系の方向けに勉強法だったりいろいろ書いていきたいと思います。

# 勉強法に入る前にいろいろ書かせてくれ
### 当時のわたしのスペック
+ 社会人2年目なりたて
+ 業務でjavaやSQLはちょこちょこつかっている
+ ド文系（これ大切）
+ 情報系の勉強は社会人になってから
+ 基本情報受けるのは平成30年度春季試験が初

###使っていた参考書だったり
+ [かんたん合格 基本情報技術者教科書 2019年度](https://www.amazon.co.jp/%E5%85%A8%E6%96%87PDF%E3%83%BB%E5%8D%98%E8%AA%9E%E5%B8%B3%E3%82%A2%E3%83%97%E3%83%AA%E4%BB%98-%E3%81%8B%E3%82%93%E3%81%9F%E3%82%93%E5%90%88%E6%A0%BC-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E6%95%99%E7%A7%91%E6%9B%B8-2019%E5%B9%B4%E5%BA%A6-Kouryaku/dp/429500507X/ref=zg_bs_502776_8/357-7237300-1623300?_encoding=UTF8&psc=1&refRID=H86AP5WPT2PPNWX0C1D6)
これの2017年度版を使っていました。
結構やさしい書き方をしているので、とっつきやすくオススメです。
文系の学部に通っていて情報系の勉強したことないけど、内定先の企業に基本情報の勉強しといた方がいいよって言われた学生さんとかに良い本だと思います。

+ [かんたん合格 基本情報技術者過去問題集 平成30年度秋期](https://www.amazon.co.jp/%E5%85%A8%E6%96%87PDF%E3%83%BB%E5%8D%98%E8%AA%9E%E5%B8%B3%E3%82%A2%E3%83%97%E3%83%AA%E4%BB%98-%E3%81%8B%E3%82%93%E3%81%9F%E3%82%93%E5%90%88%E6%A0%BC-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E9%81%8E%E5%8E%BB%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%B9%B3%E6%88%9030%E5%B9%B4%E5%BA%A6%E7%A7%8B%E6%9C%9F/dp/4295003735/ref=sr_1_1?s=books&ie=UTF8&qid=1545320583&sr=1-1&keywords=%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E3%80%80%E5%95%8F%E9%A1%8C%E9%9B%86)
これは参考書が同じシリーズだったので買ったのですが、解説がとても優しいです。
試験前日だったりはこれの解説読んで午後問の勉強をしていました。
+ [基本情報技術者試験ドットコム](https://www.fe-siken.com/s/)
通勤時間だったり合間合間に対策ができます。
午前の対策に使っていました。

### 基本情報技術者試験の対策開始時期
2017年の11月ごろから焦り始めました。
焦り始めて参考書はぱらぱら見ていたけど本格的に勉強をはじめたのはだいたい12月だったと思います。
今更ですが、春の試験の対策を12月にやりはじめるのってギリギリだったなあと。。。。
ちょろっと勉強して合格できる人もいるとは 思いますが、合格に自信のない方は本当に早めに対策をした方が良いと思います。(当たり前のこと言いましたね)

# いよいよ勉強方法
午前と午後で分けて説明していきます。

## 午前問題
午前問題は選択形式ですが、
暗記していける問題と計算しなきゃいけない問題があるので、わたしが行なっていたそれぞれの勉強方法を書いていきます。

### 暗記系
+ 参考書を読む
+ 読んだ章に関する問題を基本情報技術者ドットコムで解く

これを繰り返します。
参考書を全部読み終わっても、また最初の章に戻って繰り返します。

それでも覚えられない単語などはノートに書き出して、意味まで書いておくと頭に入ってくるので良いです。

### 計算系
わたしは計算系とても苦手なので、二進数から結構苦戦しました。
計算系の問題はこんな流れで勉強をしていました。

+ とりあえず考える
+ 理解できない場合人に聞く
+ 聞いて教えてもらった内容を理解する
+ 教えてもらったことを人に教える(アウトプットする)

考えてもわからないものは人に助けてもらいましょう。
教えてもらいましょう。
わたしの場合なのですが、計算系の問題は解説を見ても？？？？？となることがとても多く、
人に教えてもらってやっと理解していました。

ただ、理解しただけでは忘れてしまうことが多いので、アウトプットをすると良いです。

よく友達と基本情報の勉強会をしていたのですが、教えてもらったことをわたしが人に教えるということがありました。
意識はしていませんでしたが、それがアウトプットになっていたんだなーと思います。
ありがたい話ですね、、、

## 午後問題
午後は問題集で過去問を解いて、
解説を読んでっていうのを繰り返していました。

午前と違って過去問をやるくらいしかやってないのですが、過去問を解くときには

+ 本番同様に時間制限を設ける
+ わからない問題はとばす
+ 問題文は一回読んで理解するようにする

とか気をつけていました。

時間が足りなくなって解ききれないは本当にもったいないので、なるべく本番と同じ時間で解き切れるように訓練ってイメージでやっていました。

# 最後に
結局は自分に合った勉強の仕方が一番だとは思うのですが、少しでも参考にしていただけたら嬉しいです！
NEMのノードに確実に接続する方法

NEMのノードに照会しにいって、数秒待たされて。。。なんだよ、落ちてるのかよ？もしかして解体？
と思ったことありませんか？僕はあります。

NEM財団がノードを提供してくれてはいるのですが、これはNEMWalletデフォルト設定でもあり、
正直レスポンスが遅いです。表示に3秒かかると50%のユーザーが離れると言われているWebの世界ではこれは致命的です。

というわけで今回は、NEMのノードに素早く確実に接続する方法について考えてみました。
まずはノードリストを取得する方法。

```js:getNodes()
function getNodes(){

	var d = $.Deferred();
	$.ajax({url: "https://s3-ap-northeast-1.amazonaws.com/xembook.net/data/v3/node.json" ,type: 'GET',timeout: 1000}).then(
		function(res){
			let nodes;
			nodes = res["http"];
			d.resolve(nodes);
		},
		function(res){
			d.resolve(["alice2.nem.ninja","alice3.nem.ninja","alice4.nem.ninja","alice5.nem.ninja","alice6.nem.ninja"]);
		}
	);
	return d.promise();
}
```

jQueryというライブラリを使用しています。もっとも普及しており初心者のかたでも分かりやすいライブラリです。
出来る人はもっと高級なライブラリにも置き換えて読んでいただけるかと思います。
Promiseを使っていないのはIEを使っている人がまだ多そうだからです。

ます、https://s3-ap-northeast-1.amazonaws.com/xembook.net/data/v3/node.json

にアクセスしています。このファイルが取れた場合は優良ノード一覧が nodesに格納されます。

おかげ様で優良ノード情報はver3を迎えました。ver2も引き続き動きます。
改良点は以下の通りです。

- ハッシュでのトランザクション参照に対応しているノードも一覧表示
    - "apositlle" : {} 参照 
- 最新バージョン情報の表示
    - "latest_version": 参照。この値が思ったよりも高い場合は、新バージョンが存在します。
- 最新バージョンとの互換性表示
    - "latest_compatible": 参照。この値がtrueの場合はバージョンアップしても互換性が保たれます。

優良と判定するための条件は以下の通りです。
http:1秒以内に3回のAPIコールに応答
https:3秒以内に3回のAPIコールに応答
apostille:8秒以内にblock hight 1 のデータを検索
これを1時間に1回の周期で行っています。

この優良ノード情報にアクセスできなかった場合、あるいは1秒経っても応答が無かった場合は、
やむなく財団のノード一覧をnodes変数に格納します。
latest_version や last_update が思った値でなかった場合も財団ノード情報を返すようにしましょう。

次に取得したnodes変数を元にアクセスします。

```js:connectNode()
function connectNode(nodes,query2){

	var d = $.Deferred();
	let targetNode = nodes[Math.floor(Math.random() * nodes.length)] + ":7890";
	var res = $.ajax({url:  "http://" + targetNode + query2 ,type: 'GET',timeout: 1000}).then(

		function(res){
			d.resolve(res);
		}

	).catch(
		function(res){
			return getNemAccountData();
		}
	);
	return d.promise();
}
```
先ほど取得した、優良ノード一覧nodesからランダムに1つ取り出し、非同期通信を行います。ここでタイムアウト値を設定しておきます。
接続に失敗した場合、あるいはタイムアウト値を超えた場合は呼び出し元関数(この場合はgetNemAccountData(),後述します)を再度コールしてやり直します。connectNodeをコールしてはいけません。jQueryの中で失敗判定フラグが立っているようで、次に接続に成功したとしても何も反応しなくなります。

では最後にどうやって使うかを見てみましょう。

```js:getData()

var getNemAccountData = function(){
	var res = getNodes()
		.then(function(nodes){

			account_get_address_query = "/account/get?address=" + address;
			return connectNode(nodes,account_get_address_query,connectNode);
		}).then(function(result){
			console.log(result);
		});
	return res;
}
```

getNemAccountData-> getNodes() -> then() -> connectNode() -> then() -> console.log()
といった流れになります。
優良ノード情報を取得し（失敗すれば財団ノード情報）、接続試行（失敗すれば最初からやり直し）、最後に結果出力となります。

Deferredの説明などもう少し詳しいこともしたいのですが、それはまた後日に。
（このやり方がマスターできれば、ネットワークタイムを取得してからトランザクション発行、モザイクの小数点情報を取得してから単位計算などいったことも簡単にできるようになります。）

明日も引き続きよろしくお願いします。
良いプロダクトバックログについて考えてみるイブ

# はじめに
クリスマスイブ、ということは今年もあと少しとなります。
本業では大規模開発のマネージメントをしています。サブシステムやチーム単位では厳密にスクラムではないものの、イテレーティブな開発を試していく動きも(少しずつではありますが)あったりします。そこで良いプロダクトバックログとはなんだろうかと少し考えてみました。

# TL;DR
プロダクトバックログは永遠にβ版

## 重複を気にしないで書く
たとえばあなたがプロダクトオーナーになったとしましょう。まっさらな状態からプロダクトバックログを作っていきます。きっと周囲の人の頭が良ければ良いほど、MECE(もれなく、だぶりなく)であることを求めてくるかもしれません。
しかし、はじめから「もれなく、だぶりなく」というのは、なかなか難しいものです。重要なのは「もれなく」です。はじめのうちは重複はおそれず、必要だと認識したものを次々と書いていきましょう。

## 形容詞、形容動詞は使わない
抽象的なアイディアが思いつくこと自体はよくあることです。
しかし、実際に開発していくチームのメンバーと認識がずれやすい表現は避けたほうが賢明です。
キレイな~ など形容詞、形容動詞を使うのはなるべく控えるべきでしょう。
要求事項が不明瞭になり、エンジニアとのハレーションも増えてしまうかもしれません。

## 必ず受け入れ条件を書く
これも前項と似ている話です。スクラムに詳しい方ならAcceptance Criteria というと伝わるでしょうか。受け入れる人によって基準が変わっては困ってしまいます。エンジニアはAcceptance Criteriaを目指して実装していきます。基準が明確ならば、ストレスもきっと少ないでしょう。

## INVESTで整形する
ある程度量がたまってきて、展望が見えてきたら書いたものは放置せず、整えていくことが大事です。その際には「INVEST」というものを意識するとうまくいくかもしれません。
Indecent --- 依存しない(少ない)
Negosietable ---　交渉可能
Valuable --- 価値がある
Estimate --- 見積もり可能
Size -- 手頃なサイズ
Test --- 検証可能

サイズと依存は対立しますが、迷った時はサイズを小さくする方を選ぶのがセオリーのようです。見通しが立てやすいためです。

## プロダクトバックログは比較で見積もる
さあ、実際に開発していくとして、当然あなたはどれくらいかかるものかが気になります。
大事なことは何のために見積もるのかです。事前に一つ一つのアイテムについてエンジニアが勘と経験でxxx時間かかると見積もったものがどこまで正しいのか、正直あなたにはわかりません。
それよりもベロシティを計測しましょう。開発チームの生産量を見える化したほうが効率的で正確かもしれません。比較で見積もるというのは、たとえば一番小さなアイテムを1としてそれ以外がいくらくらいになるか、で見積もっていきます。スプリント x ベロシティで生産量を出していけば、リソース計画も立てることは可能です。


## Undoneもきちんと積む
いざ実際に開発を始めるとリリースの際に完了(Done)できなかったものも出てくるでしょう。
そういう時は無理せず、焦らずきちんと積み残し(Undone)としてのせることが肝心です。
たとえば、成果物定義の中で作らなければならないドキュメントがあったとして、様々な都合上該当スプリントのリリースから外した場合、きちんとバックログに積んでいかないと、どんどん形骸化してしまいます。イテレーティブな開発 = 早くリリースできるではありません。チームのベロシティを可視化しながら、ゴールを目指すことが目的なはずです。Undoneは保守的に消化しましょう。

## プロダクトバックログは永遠にβ版
イテレーティブな開発をしているということはマーケットの中でいろいろな挑戦を繰り返しているということだと思います。マーケットへの提供価値もプロダクトの機能も試行錯誤の中で変わっていくとすればプロダクトバックログもまた永遠にβ版として、定期的Refinementすることが大事になっていくでしょう。

プロダクトバックログにはあなたのプロダクトオーナーとしてのスタンスが表現されていると言えるかもしれません。

## 最後に
つらつらと書いてしまいましたが、メリークリスマス！
Cyclic property animator in Native View subclass (e.g. Flashing ImageView)


We show a method by which native View behavior can be overridden and a property changed in a cyclic sequence. For demonstration, we subclass an ImageView and set its alpha property to cycle between two defined values continuously

First, we define the subclass programmatically

```kotlin

// required constructor signature
class FlashingImageView(context: Context, attrs: AttributeSet?, defStyleAttr: Int): ImageView(context, attrs, defStyleAttr) {

    // define the upper and lower limits to the alpha property
    enum class Alphas(val value: Float) {
        upper(0.25f),
        lower(0.0f)
    }

    // time duration between upper and lower limits 
    val duration: Long = 700L
    
    // required constructor signatures
    constructor(context: Context) : this(context, null)

    // post a runnable which will start the flashing sequence when this
    // ImageView is ready
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {
        this.post(object: Runnable {
            override fun run() {
                this@FlashingImageView.startAnimation()
            }
        })
    }

    // define the starting property value and start the flashing sequence
    fun startAnimation() {
        this.setAlpha(Alphas.lower.value)
        this.step()
    }

    // this runnable restarts each step in the flashing sequence
    val runnable = object: Runnable {
        override fun run() {
            this@FlashingImageView.step()
        }
    }

    // swap the target property value for the animation and start 
    // an animation that will call our runnable on completion 
    fun step() {
        val newAlpha = if(this.alpha.equals(Alphas.lower.value))
            Alphas.upper.value
        else
            Alphas.lower.value

        this.animate()
                .alpha(newAlpha)
                .setDuration(duration)
                .withEndAction(runnable)
    }
}
```

This subclass can be utilized in XML layout as follows:

```xml
<path.to.FlashingImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/image"
/>
```

Note: it is recommended to switch off this type of continuous animation when it is not needed, not only to save CPU, also to avoid errors if attempting to use the Layout Inspector in Android Studio.
【git入門】git cloneした後、手元のブランチを既存のリモートブランチ名で作成したらgit pushがうまくいかなくなった

git初心者の頃、正しくgit pullをしなかったがために、git pushがうまくいかなくて困った時のメモです。
#【事象】
git初心者の頃、僕は進めていたタスクがmergeまで一段落する度に、local環境を綺麗にするためしプロジェクトのディレクトリごと削除していました。そして、ある日、 再度同じリポジトリを修正することになったため、git cloneし、手元のlocal環境にて、以前作業していたものと同じ名前でブランチを"作成"し、pushしようとしたらfailしました。
#【解決】
git cloneで持ってくる際に、 `既存のブランチを指定` してcloneしてくることで問題なくpush ができました。
#【ダメだった時】
**当時やったことをコマンドラインで。**

```
既にmerge済みのブランチ(merged-001)を修正することとなり作業開始
# git clone URL
# git checkout -b merged-001
色々修正
# git add 対象ファイル
# git commit -m "チケット××の〇〇を修正しました！"
# git push origin merged-001
```
| 項目 | 値 |
|-----------|------------|
| 既存のブランチ名 | merged-001 |
| プロジェクト名 | deb-packages |
**激おこメッセージ**

```
[root@localhost deb-packages]# git push origin feature/merged-001
To https://user@example.com/SRE/deb-packages.git
 ! [rejected]        feature/merged-001 -> feature/merged-001 (non-fast-forward)
error: failed to push some refs to 'https://user@example.com/SRE/deb-packages.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
[root@localhost deb-packages]# 
[root@localhost deb-packages]# 
```
#【解決した時】
git cloneの際に、以前作業してブランチを指定してcloneすることで解決しました。

```
ブランチを指定してcloneする書き方。
git clone -b <指定したいブランチ名name> "リポジトリURL"
```

**解決の際やったことをコマンドラインで。**

```
# git clone -b feature/merged-001 "https://user@example.com/SRE/deb-packages.git"
タスクの修正追加等
# git addとかそういうやつ。
# git push origin feature/merged-001
```

#【詳細】
git pushに失敗した時は、リモートからmasterを新たにcloneし、修正をかけてpushしようとしていました。しかしそれだと、既に上がっているMergeRequestに記録されている各 `commitのハッシュ値` と、現在の作業のcommitのものが異なってしまいます。そのため、ブランチの名前は同じでも、別々のブランチを無理に統合しようとしてると判断されるのだそうです。そして、結果、rejectされてしまっていたのですね～。

#《参考》
Gitのコミットハッシュ値は何を元にどうやって生成されているのか
　- Mercari Engineering Blog 
https://tech.mercari.com/entry/2016/02/08/173000
git-clone - Clone a repository into a new directory
https://git-scm.com/docs/git-clonehttps://git-scm.com/docs/git-clone
2.3 Git Basics - Viewing the Commit History
https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
５G通信ってすごいぞ〜っていう布教

#はじめに
この記事はロボP Advent Calendar 2018の21日目の記事です。

本当はセキュリティ記事を書こうかなと思ったのですが、もうちょっと勉強してから書きたいなと思い。。。
今回は５G通信技術について書いていこうと思います。まだまだ勉強中なので温かい目で見てください。

# ５Gってなにそれ美味しいの
実際に５G通信ってなんなの？っていうところです。
５G通信とは
- モバイルブロードバンドの高度化
- 超高信用度＆低遅延通信
- 大量のマシンタイプ通信　
といった要求に答えられるネットワーク技術です。
### モバイルブロードバンドの高度化
マルチウエアコンテンツやサービスにいつでもどこでもアクセスでき、通信速度を保ちつつ大きいサイズのデータのやり取りが可能に
### 超高信用度＆低遅延通信
高い信頼性、スループット、低遅延が担保された通信を実現。ピークデータレート１０Gbps以!
上！遅延１ｍｓ以下！！！！！！
### 大量のマシンタイプ通信　
大量の通信技術を搭載したデバイス接続を実現。同時接続端末の数を多くし、通信量あたりのネットワークコストを削減


**要するに、今までよりも利用者に合わせたネットワークを提供でき、大きい容量の通信を可能にし、なおかつ超高速で通信ができる。**

#体験してきた
実際に１２月６日にdocomo open house 2018に行って一足はやく５Gを体験してきました。
５Gもとんでましたよ！！
比較用として４G（LTE）のデータ
![IMG_0366.jpg](https://qiita-image-store.s3.amazonaws.com/0/316620/4c0783b8-5708-efbc-3472-754e1a0a2d56.jpeg)

会場で飛んでいた５G（Ericsson）
![IMG_0367.JPG](https://qiita-image-store.s3.amazonaws.com/0/316620/80386f70-8220-8fe9-4574-22593b7a5e56.jpeg)
めちゃくちゃ早いじゃないですか...。
５Gハンパない。。

## 実際５Gって何ができるの？
今まで４Gではできなかった　**大容量のデータを低遅延で届ける事ができる** :thinking:

例えば、ゲームなら、バイ○ハザードとかモンスター○ンターとか映像の解像度が高く操作性を求められるゲームがP○4などのデバイスを買わなくても、**いつでもどこでもサクサクプレイできる！** 
実際にNECさんのブース方で戦国無双を体験しました。キャラクターがぬるぬる動いて本当にすごかったです。
構成図いただきました。
![IMG_0258.JPG](https://qiita-image-store.s3.amazonaws.com/0/316620/9c99cbff-c19b-872d-a822-b2a0fd0f8e53.jpeg)
実際には四谷で動いているものを５G通信で会場までつないでいる感じです。
会場の端末では、ゲームの動作（キャラが動くとか）の処理は行わず、リアルタイムで四谷の方で通信を介してレスポンスを返している感じです。
今後、この技術によりゲーム機本体を買わなくても....

その他にも、自動運転技術・電車の安全確認装置・VRなど様々な分野で５Gは活躍します！！（詳しくはググって） 

# 終わりに
え？５Gはいつから日本で商用サービスを始めるかって？
**2020年にdocomoから正式にサービス開始します！**(プレサービスは２０１９年９月)
米国では？？？？
**2018年１０月からVerizonから商用展開を始め、２０１９年上半期に世界初５Gスマートフォン開始予定**
:thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: :thinking: ~~え、日本遅くね？~~


５Gはもう標準化は終わっており、いつどこで度の国が商用サービスを展開してもおかしくはないです！
この記事から５Gについて少しでも興味を持っていただけたら幸いです :wink: 

# 参考
http://docomo-rd-openhouse.jp/　
http://bizboard.nikkeibp.co.jp/houjin/cgi-bin/nsearch/md_pdf.pl/0000425733.pdf?NEWS_ID=0000425733&CONTENTS=1&bt=NC&SYSTEM_ID=HO
https://tech.nikkeibp.co.jp/atcl/nxt/mag/nc/18/022100027/052400005/
https://forbesjapan.com/articles/detail/20993

そして！！！一番の参考は！！！
ICR中村邦明先生の授業！！

ありがとうございました。
XEMBookからのクリスマスプレゼント！(xembook-catapult)

昨日はNEMのノードに確実に接続する方法を紹介しました。
これをXEMBookに組み込んでみましょう。

というわけで、まずはXEMMesssageに適用してみました。
XEMBook catapult検索のすごさを堪能してください（NEM/mijinのCatapultとは関係ありません）

http://xembook.net/xemmessage.html?address=NBZNQL2JDWTGUAW237PXV4SSXSPORY43GUSWGSB7

初期表示はいつもと同じ25件検索です。
そして、今回あらたに検索条件指定を追加しました。
あるいは、さらに読み込むリンクをクリックしてください。

なんということでしょう！
デフォルトでは25件ずつしか表示できないNEM API仕様ですが、
そんなことはお構いなしに一気に250件検索を行います。
アドレス部分に &bulk=20 などとしていすると 20台のノードに25件ずつ検索を行います。

表示時間のストレスもほとんど気になりません。
これ、全部オンチェーンへ検索かけてます。
途中でタイムアウトなどの失敗をしても、再度取りに行くので安定性も抜群です。
（再取得の場合はハッシュアクセスモードとなり、アポスティーユサーバに接続するので
表示にしばらく時間がかかります。）

ブロックチェーンは内部ロジックの高速化がよく話題になりますが、
例えばプライベートチェーンにスケールして秒間4000txを実現したとしても
ノードを参照するのに10秒以上もかかっていてはUXとしては疑問点が残ります。
こういう部分のパフォーマンスがユーザーのストレスに直接かかわってくることも覚えておくべきでしょう。

XEMBookではXEMBook-sdk プロジェクトと題して
内部に高速かつ高セキュリティのxembook-catapultを内包し、
これらの課題にこれからも挑戦しつづけます。

NEM1も面白いのでまだまだNEM1で遊びます。
来年もよろしくお願いします。
kaminariで `+`を使い配列化するとundefined method `page'が発生する

## はじめに
kaminariでページネーションを実装していた際、エラーで怒られたのをまとめます。

## 再現手順
kaminariを使ってページネーションを実装しようとする。
この場合は、新しいUserが先に来るように配列を並び替えて、

```ruby:xxx_controller.rb
new_user = User.where(flag: 0).order("created_at desc")
old_user = User.where(flag: 1).order("created_at desc")
@users = new_user + old_user
@users.page params[:page]
```

こんな感じで書くと、下記のような感じでエラーが発生する。

```
NoMethodError - undefined method `page' for #<Array:0x007f8dfd8f2518>:
```

---
**2018/12/22 追記**
@asm さんからご指摘頂きました！

```ruby
@users = User.where(flag: 0).or(User.where(flag: 1)).order("created_at desc")
@users.page params[:page]
```

このような書き方をすることによって、そもそも+によって`@users`が配列化しないので、より簡潔に書くことができます。


## 原因
kaminariのpageメソッドは、ActiveRecord::Relationオブジェクトを受け取ってActiveRecord::Relationオブジェクトを返す。

pageメソッドの中身はこんな感じ。

```ruby:active_record_model_extension.rb
# frozen_string_literal: true

require 'kaminari/activerecord/active_record_relation_methods'

module Kaminari
  module ActiveRecordModelExtension
    extend ActiveSupport::Concern

    included do
      include Kaminari::ConfigurationMethods

      # Fetch the values at the specified page number
      #   Model.page(5)
      eval <<-RUBY, nil, __FILE__, __LINE__ + 1
        def self.#{Kaminari.config.page_method_name}(num = nil)
          per_page = max_per_page && (default_per_page > max_per_page) ? max_per_page : default_per_page
          limit(per_page).offset(per_page * ((num = num.to_i - 1) < 0 ? 0 : num)).extending do
            include Kaminari::ActiveRecordRelationMethods
            include Kaminari::PageScopeMethods
          end
        end
      RUBY
    end
  end
end
```

`include Kaminari::ActiveRecordRelationMethods`してますね。
[GitHub - kaminari/kaminari](https://github.com/kaminari/kaminari/blob/master/kaminari-activerecord/lib/kaminari/activerecord/active_record_model_extension.rb)


コンソールで違いを見てみると、

前

```
pry(main)> new_user.class
=> User::ActiveRecord_Relation
```

後

```
pry(main)> user.class
=> Array
```

このようにオブジェクトが変わっていることがわかる。

## 解決方法
えー、Arrayに対してどうすればいいんだ、、、、
とうちひしがれてたら、しっかり解決策がありました。


```
@paginatable_array = Kaminari.paginate_array(my_array_object).page(params[:page]).per(10)
```
https://github.com/kaminari/kaminari#paginating-a-generic-array-object

なので、

```ruby:xxx_controller.rb
new_user = User.where(flag: 0).order("created_at desc")
old_user = User.where(flag: 1).order("created_at desc")
users = new_user + old_user
@users = Kaminari.pagenate_array(users).page(params[:page]).per(10)
```
のように書けば解決！！

## 参考
[kaminari/kaminari](https://github.com/kaminari/kaminari)
[kaminari徹底入門](https://qiita.com/nysalor/items/77b9d6bc5baa41ea01f3)
[【Rails】kaminariさんって配列もいけるんですね](http://www.cotegg.com/blog/?p=613)
Windows Server 2016で外部からのFTP接続するIPを限定したい。


#前提
・IIS、FTP接続可能な状態までセットアップ済。
・接続元は固定IPを持っている。

#環境
IIS 10.0
Windows Server 2016


#手順
サーバーマネージャーのツールからインターネットインフォメーションサービスマネージャーを起動する。

サイトからFTPサイトを選択する。


機能ビューから「FTP IP アドレスとドメインの制限」を開く。
<img width="1099" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/74659f72-a7ad-91d5-29d6-7db9a6c303dd.png">

右側の操作から機能設定の編集を選択する。
<img width="153" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/fd6c1e84-b18b-96af-08e5-ae9d8fba00dd.png">



IPアドレスとドメインの制限の設定の編集 ダイアログが開くと、デフォルトで「許可」になっているので「拒否」に変更してOKボタン。これで許可の設定していないものは接続ができなくなる。
<img width="405" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/e13d21ed-1af2-2f8e-4eaa-561457adea69.png">


右側の操作から許可エントリの追加を選択する。
<img width="151" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/0b883f67-394f-36fa-5b00-ab48951cc9c0.png">


接続したいグローバルIPアドレスを入力してOK。
<img width="325" alt="5.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/c16a595d-16b4-05f1-9ba1-bda3b383595c.png">

設定したIPが一覧に表示される。
<img width="660" alt="6.png" src="https://qiita-image-store.s3.amazonaws.com/0/92797/ef071c55-68c6-5489-17d5-f23cc15fca18.png">



以上で設定が完了。
からあげ描くなんて造作もねえことだよなあ

デザイナー恩田です。
エンジニアとは縁遠い人間ですが今回なぜか記事を書くことになりました。
今回は簡単に唐揚げを描く方法をご紹介します。誰得。

#　いいから唐揚げを描くんだよ！
![1.png](https://qiita-image-store.s3.amazonaws.com/0/329528/b55162ec-67ee-da6d-c654-f45fbdbf4f80.png)
土台となる線画と色ベースはこちら。うーんトイプードル感。
形は岩とかのゴツゴツした感じを意識するといいです。そんな感じ。
カップの書き方はメインではないので省きます。
これにあれこれ加えてからあげに見えるようにしていきます。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/329528/2e15304d-7c45-e23d-71ab-ee4ff01c0d8e.png)
形状を考えながらなんとなーく薄い影を入れて

![3.png](https://qiita-image-store.s3.amazonaws.com/0/329528/c4814673-6f1c-2816-095e-d75544ea165f.png)
立体感を出す黒っぽい色の影を入れて

![4.png](https://qiita-image-store.s3.amazonaws.com/0/329528/7ede4a8f-55ba-9fab-5052-c2f3ae11f053.png)
ハイライトを入れて完成……なんですが……
なーーーーんかギトギトしてるんだよなあ？

#　ディティールアップする！
18万円ほどのお金と簡単な一手間で唐揚げのディティールアップが可能です！

【からあげディティールアップのために必要でもないもの】
・olympus pen e-pl7　多分9万円くらい（購入時）
・ディズニー2パーク年間パスポート　￥89,000　

上記２点を持って舞浜へGO!

そして……

![kawaii!!.png](https://qiita-image-store.s3.amazonaws.com/0/329528/d8e7139f-262e-b0a1-733b-098689ab2ce3.png)

**ハイかわいいーーーー！！！！**

ミッキーのスクリーンデビュー90周年を記念して発売された
ポップコーンバケットなんですよこれ。
汽笛の部分が犬のおもちゃに入ってるようなピューピューいう笛になってます。かわいい。
洗うのがしちめんどくさいのだけが難点です。

この写真をどうするかというとですね、
![konohen.png](https://qiita-image-store.s3.amazonaws.com/0/329528/6face5a7-6128-2506-c622-9e763a154fad.png)
このへんを切り抜いて
![レイヤー-48.png](https://qiita-image-store.s3.amazonaws.com/0/329528/4e397735-4f58-6b1c-9d48-31ea714f36a7.png)
赤い色に変えて先ほど描いた唐揚げにレイヤーモード「ハードライト」で
重ねると
<img width="354" alt="スクリーンショット 2018-12-21 18.26.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/329528/26b4630e-aaba-4cee-429e-a03abc8c0a32.png">
岩肌のガサガサした質感が唐揚げっぽい！（画像左下の唐揚げ）

そんな感じで３つ全てにテクスチャを貼って、旗を刺したら

![kansei.png](https://qiita-image-store.s3.amazonaws.com/0/329528/67ff6c08-5cb0-872d-87e7-80024d03b792.png)

完成です。ね、簡単でしょ？

ちなみに唐揚げに重ねるテクスチャは別にディズニーで撮らなくてもいいし、
岩肌のフリー素材いろんな所にあるのでそれで十分です。

お粗末様でした。

### おまけ
<img width="362" alt="スクリーンショット 2018-12-21 18.04.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/329528/8fe959ee-4cf7-d8b1-2d4e-f85b6ab89a06.png">
唐揚げを描く工程でトイプードルを生み出すことも容易です。スゴイネー！


<HR>【使用（？）ツール】
 Adobe Photoshop CC 2019
 olympus pen e-pl7
 2パーク共通パス
CactiのSyslogプラグインのインストール後、"Report Rules"が表示出来ない件

# 事象の概要
Cacti 1.1.38 に[Syslog Plugin for Cacti](https://github.com/Cacti/plugin_syslog)(version 2.1)をインストール後に、`Report Rules`をクリックすると、`Internal Server Error`と表示される事象が発生してしまう。

![report_rules.png](https://qiita-image-store.s3.amazonaws.com/0/147072/4432e4a4-e503-797f-4203-4c55cb637f31.png)

# 原因
単純にSyntax Errorが発生しています。

```bash
php -q syslog_reports.php --debug --force-report
PHP Parse error:  syntax error, unexpected '(', expecting ')' in /usr/share/cacti/plugins/syslog/syslog_reports.php on line 596
```

# 解消方法
対象の箇所を修正する必要があります。

```bash
[XXXXXXXX cacti]# pwd
/usr/share/cacti
[XXXXXXXX cacti]# vim plugins/syslog/syslog_reports.php
```

596行目の、
`'enabled'  => array(__, 'syslog'('Enabled'), 'ASC'),`
↑この箇所を
`'enabled'  => array(__('Enabled', 'syslog'), 'ASC'),`
この様に修正します。

# 補足

次のVersionでは修正されるようです。

https://github.com/Cacti/plugin_syslog/commit/a4f05a2a8d9c9ae7dd7d637e69d1d6ad6a3fc3b8#diff-8d53b1dd642e94afdca5f6cf610c0e35
Adobe Max JapanでみたAdobeXDの進化

こんにちは。CVD部でディレクターを担当している@Takuya-Yamaguchiです。
この記事は[Photocreate Advent Calendar 2018](https://qiita.com/advent-calendar/2018/photocreate) の 22 日目です。

## Adobe Maxに行ってきました

2018年11月20日に開催された、[Adobe MAX Japan 2018](https://maxjapan.adobe.com/)で紹介していた、
AdobeXDの進化についてご紹介したいと思います。

## PhotoshopファイルがXDにインポートできるようになった

PhotoshopのファイルをXDで開くだけで使えるようになりました。もちろん、コピー&ペーストでも可能です。
これによりPhotoshopで作成したファイルをXDに取り込むことで、簡単にプロトタイピングができるようになりました。
Photoshopのレイヤー状態も保持したまま取り込みができるので修正も楽にできます。

またPhotoshopで作成したアセットは、Creative Cloud経由で取り込むことも可能です。
その為、アセットをPhotoshopで修正するとXD側にもその場で反映されるのです。
デザインに修正が入った時にも、膨大なページのデザインを変更する必要が無くなりました。

## xdプラグイン (サードパーティープラグイン)の登場

AdobeXDは、ユーザーから寄せられた声をもとに毎月のようにアップデートが繰り返されています。
ただし、毎月アップデートされる新機能は、多くのユーザーを対象とした内容になります。

Adobe XD Plugin API がリリースされ、プラグインが作成できるようになったことで、便利なプラグインがたくさん登場しました。

[Google Sheets for Adobe XD](https://googlesheetsforadobexd.impekable.com/)は、スプレッドシートからデータを取り込み、テキストや画像を展開できるプラグインです。アートボード上のデータを適用するグループを選択してから、プラグインのパネルを開いて、スプレッドシートのURLを指定すると、画像やテキストが一気に読み込まれます。ニュースアプリや一覧ページのUIを作成する時などに重宝しそうです。

xdプラグインは主に、以下のようなケースで利用されることを想定して作成されているようで、
すでに85個のプラグインがリリースされています。(2018/12/22現在)

> - 繰り返し作業を自動化する
> - アセットやデータを読み込みデザインに反映する
> - デザインを共有するために書き出す
> - デザイン要素の調整や確認を行う
引用：Adobe Blog

## 音声をトリガーとしたプロトタイプモードの実行

音声入力によるプロトタイプの実行が可能になりました。音声入力が、プロトタイプモードでクリックやタップをするのと同様に扱われます。特定の単語やフレーズを音声入力することでプロトタイプモードが実行されます。現在は英語しか利用できませんが、将来的には日本語も対応してくれるそうです。楽しみですね。
ただし、隣の席にも向かいの席にも、集中して作業に取り組んでいるメンバーが座っています。その状況の中で、自席に座りながら音声入力をするのは気恥ずかしい感じがします。

## レスポンシブリサイズ

UIデザインをする時に、複数のデバイスに対応するようにデザインすることはもはや当たり前になっています。
これまではスマートフォン版のデザイン、PC版のデザインなど、デバイス別に複数のUIをデザインする必要がありました。

今回搭載されたレスポンシブリサイズは、オブジェクトの位置や大きさの相対関係を理解して、オブジェクトグループ全体を拡大縮小することができるのです。しかもXDがオブジェクトの相対関係を理解して、自動的にUIを調整しくれるのです。これは凄いです。だいたい私が思う通りにレスポンシブしてくれます。
手動モードもあるので、背景は横幅100%のまま中のテキストだけ改行させる。といったような設定もできます。
まずはXDに自動でレスポンシブの動きを作ってもらい、その後個別に調整すると、作業がとても効率化されます。

## クラウドドキュメント機能

クラウドドキュメント機能は、XDのホーム画面に集約されて管理され、どこからでもアクセスすることが可能です。これにより自分で作成したファイル、他のユーザーから共有されたファイルの管理がしやすくなりました。
今後は複数人でXDを編集できるライブコラボレーション機能や、バージョン管理機能も追加されるようです。

## まとめ 

繰り返し作業や、単純な作業を自動化してくれる機能が数多く追加された為、よりヒトが取り組むべきクリエイティブに注力することができるようになりつつあります。将来的には、作成したUIデザインやレスポンシブの設定を理解して、自動でhtmlやcssを出力してくれるようになったら生産性が劇的に変わりそうです。(きっとそんな未来が来るのでしょう)

## さいごに

フォトクリエイトは約10億枚の写真データを保有しており、サービスサイトも多くの方にご利用頂いております。
新たな顧客体験を一緒に作っていける方の[応募をお待ちしております](https://recruit.photocreate.co.jp/entry/?utm_source=qiita&utm_medium=advc2018&utm_campaign=3e8cad95de1ba3581b05)

<!--
明日の記事は @kasai の [バッチ処理をAWS Batchにしたらバッチリだった話]() Photocreate Advent Calendar 23日目)です。
-->
【メモ】PCで電話リンクを無効にする

#JQUERY使用版

```javascript
$(function(){
  if(navigator.userAgent.indexOf('iPad') == -1 &&  navigator.userAgent.indexOf('iPhone') == -1 && navigator.userAgent.indexOf('Android') == -1){
    $("a").each(function(){
      var link = $(this).attr("href");
      if(link.match(/tel:/)){
        $(this).removeAttr("href");
      };
    })
  };
});

```

#脱じぇーくえりー版に書き換え

```javascript
document.addEventListener('DOMContentLoaded', function(){
  if(navigator.userAgent.indexOf('iPhone') == -1 && navigator.userAgent.indexOf('iPad') == -1 && navigator.userAgent.indexOf('Android') == -1){
    anchorTags = document.querySelectorAll('a');
    anchorTags.forEach(function(anchorTag){
      if(anchorTag.getAttribute('href').match(/tel:/)){
        anchorTag.removeAttribute('href');
      }
    });
  }
}, false);

```
VSCode で emmet を効かせて styled-components を書く

このチェックを ON にすると、tab 押下で使えるようになる！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130756/b8128ba7-668d-b3aa-749f-fda70c44aab4.png)


参考：https://github.com/styled-components/vscode-styled-components/issues/72#issuecomment-433040094
styled-components で IE 対応 Grid Layout をする

## autoprefixer 便利
autoprefixer っていう vendor prefix を自動で付けてくれるものがあって、gulp や webpack 経由で使えるっぽいのですが、これを使えば勝手に prefix を付けて IE も対応してくれるらしいです。
*（参照：https://qiita.com/tonkotsuboy_com/items/bce73685cd6b1ea511dc ）*

## でも styled-components で使いたいんじゃ
styled-components の内部でいつも vendor prefix を付けてくれている CSS プリプロセッサの stylis.js が Grid Layout 未対応らしい。
*（参照：https://github.com/styled-components/styled-components/issues/1184 ）*

でも最近 stylis.js も Grid Layout 対応したい旨の議論がまた出始めたのでそろそろ対応してくれるかもしれない。
*（参照：https://github.com/thysultan/stylis.js/issues/119 ）*

👉 **でも今やりたいんだわ！！！**

## 解決策: vendor prefix を素手で書く
https://autoprefixer.github.io/ から autoprefixer がどんな感じで css を parse してくれるのかっていう demo が使える。
今回僕が Grid Layout したいとこは一部分だけだったので、対象の CSS をこの demo parser に食わせて、吐かれた CSS を素手でコピペしました。

👉 **できた！！！！！**

※ ただし vendor prefix の style とそうでないやつの書く順番を間違えると動かなかったので注意。そういうものなんですかね

## 追記： autoprefixer 使えるのかもしれん？
autoprefixer を通す方法の中によく見たら [**CSS-in-JS**](https://github.com/postcss/autoprefixer#css-in-js) っていうのがあった。
[astroturf](https://github.com/4Catalyzer/astroturf) っていう loader を使えば styled-components 内の CSS も autoprefixer に parse してもらえるのかもしれない。
けど、styled-components が使ってる stylis.js と競合してしまわないかは心配なところ。
GASでMailの内容を読み取って処理したい時

# はじめに

Gmailに届いたメールをパースしてPDFに整形するサービスを作ったのですが、処理済みのメールを無視するのに少し手間取りました。ここでは現時点でベストと思う結論についてシェアしたいと思います。ちなみに、もちろんDBと連携するのが一番簡単ですが、外部との連携無しで検討した結果です。

# メールの取得方法

メールの取得は次のように行います。

```javascript
var threads = GmailApp.getInboxThreads(0,100);
var tlen = threads.length;

for (var i = 0; i < tlen; i++) {
  /* Do Something */
}
```

ここで取得出来るのはthreadであってmailでは無いのがポイントです。これが色々とややこしい事態を生み出しています。困った事に短期間で受信された同じタイトルのメールはthreadとしてバンドルされてしまうのです。例えば別のメールでも同じタイトルだと、まとめちゃうおじさんがどこからともなくやってきて、一つのthreadにまとめられてしまいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29999/ee481ec4-c0bd-be01-21e2-5b636718a23b.png)

さて、これを前提に色々と検討してみます。

# Archiveを使う

Archiveすると`getInboxThreads`で取得されません。次は公式から持ってきたArchiveの例です。

```javascript
var firstThread = GmailApp.getInboxThreads(0,1)[0];
firstThread.moveToArchive();
```

プログラムを見れば分かりますが、Archiveはthreadに対して実行します。従って、threadのメールを全て処理した後にArchiveする必要があります。この処理中に新しいメールがバンドルされたら、、、`firstThread.refresh()`が使えそうです。ややこしいですが。

ただ、やはりArchiveは使えません。何故かと言うと、Archiveしたthreadに新しいメールがバンドルすると受信箱に戻ってきてしまうからです（未練がましいですね）。そうするとまた`getInboxThreads`で取得出来てしまいます。従って、処理したいメールのタイトルが毎回違って、同じタイトルでメール受信する事がほとんどない場合は使えると思います。ただリフレッシュしないと問題は結構面倒だと思います（試してないですが）。

# 削除する

削除すれば`getInboxThreads`で取得されません。次のように行います。

```javascript
function deleteById(id) {
  const m = GmailApp.getMessageById(id);
  m.moveToTrash();
}
```

Archiveと違ってファイルに適用されるので、使いやすいです。ただし、moveToTrashしか出来ず、完全に削除するメソッドはありません。その為か新しいメールでバンドルされた場合はゾンビのように蘇ってきます。従って、同じ件名のメールがバンバン飛んでくる環境では使えません。また当然、メールを削除出来ない案件では使えません。

# ラベルを使う

これも案件によっては使えない可能性がありますが、今の所ベストな方法です。ここでは処理済みのメールに特定のラベルを付けます。ラベルはThreadに付けるので、メールが個別に持つメールIDをラベルに入れます。こうする事で、同じスレッド無いで処理ずみと未処理のメールを分ける事が出来ます。

```javascript
var threads = GmailApp.getInboxThreads(0,100);
var tlen = threads.length;

for (var i = 0; i < tlen; i++) {
  const messages = threads[i].getMessages();
  const mlen = messages.length;
  for (var j = 0; j < mlen; j++) {
    var m = messages[i];
    if (isValid(m)) {
       /* Do Something*/
       var label = GmailApp.getUserLabelByName("HOGE_" + m.getId());
       threads[i].addLabel(label);    
    }
  }
}
```

ただし、[labelの名前は２０００まで](https://www.en.advertisercommunity.com/t5/Advanced-Features/Maximum-number-of-labels/td-p/449237)という制限があるようです。前述した通り、受信する時間に間隔がある場合はbundleされませんので、ラベル付けから一日たったメールは"HOGE"という名前にしています。今の所はこれでうまくいっています。

# まとめ

要件が許せば削除が一番簡単です。私も別の個人プログラムでは採用しています。ただしthread bundle問題を回避するのはlabelしか思いつきませんでした。なお、labelを使う場合は、受信したアカウントから別のアカウントに転送してから処理しています。そうすればラベルを気にしなくて良いですし、件名でフィルタリングすればメールの件数も減りますので。

もしもっと良い方法があったらコメント頂けると嬉しいです。
Pandas: DataFrame と Series の numpy との対応

お恥ずかしい話ですが、しょっちゅう間違えるのでメモします。


* Series から values で np.array を作る時: 縦方向の一次元配列が返る。
    * 例: `[1,2,3,4,5]`
* DataFrame から values で np.array を作る時: 二次元配列だが、内側の配列は横方向。
    * 例: `[[1], [2], [3], [4], [5]]`
    * 間違い: `[[1,2,3,4,5]]`

特に DataFrame のインデクサがスカラの時 Series を返し、リストの時 DataFrame を返すので間違いやすい。
例えばこんな Pandas の表があるとします。


```python
import pandas as pd
sales = pd.DataFrame([
    ['apple'],
    ['orange'],
    ['mango'],
    ['melon'],
    ['banana']],
    columns=['name'])
sales
```




<div>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>apple</td>
    </tr>
    <tr>
      <th>1</th>
      <td>orange</td>
    </tr>
    <tr>
      <th>2</th>
      <td>mango</td>
    </tr>
    <tr>
      <th>3</th>
      <td>melon</td>
    </tr>
    <tr>
      <th>4</th>
      <td>banana</td>
    </tr>
  </tbody>
</table>
</div>



ここからカラムを選択する時、インデクサがスカラだと Series を得るので


```python
sales['name']
```




    0     apple
    1    orange
    2     mango
    3     melon
    4    banana
    Name: name, dtype: object



これを values すると shape (5, ) の一次元配列を得る。


```python
print('shape:', sales['name'].shape)
sales['name'].values
```

    shape: (5,)

    array(['apple', 'orange', 'mango', 'melon', 'banana'], dtype=object)



インデクサがリストだと DataFrame を得るので


```python
sales[['name']]
```




<div>

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>apple</td>
    </tr>
    <tr>
      <th>1</th>
      <td>orange</td>
    </tr>
    <tr>
      <th>2</th>
      <td>mango</td>
    </tr>
    <tr>
      <th>3</th>
      <td>melon</td>
    </tr>
    <tr>
      <th>4</th>
      <td>banana</td>
    </tr>
  </tbody>
</table>
</div>

これを values すると shape (5,1) の二次元配列を得る。

```python
print('shape:', sales[['name']].shape)
sales[['name']].values
```

    shape: (5, 1)

    array([['apple'],
           ['orange'],
           ['mango'],
           ['melon'],
           ['banana']], dtype=object)



`[['apple', 'orange', 'mango', 'melon', 'banana']]` では無いので注意!

別の言い方をすると次のような関係です。


```python
sales['name'].values == sales[['name']].values.transpose()[0]
```

    array([ True,  True,  True,  True,  True])
RedashのPythonデータソースで指定したクエリを実行する機能を実装してみた

この記事は[Redash Advent Calendar 2018](https://adventar.org/calendars/3299) 21日目です。
最近送ってみたRedashのPythonデータソース関連のプルリクについて書きます。

## Pythonデータソース
SQL1本で表現しづらいときなどにpandasでデータをゴニョゴニョできたりと、とても便利です。
なんでもできすぎてPythonデータソースが仕事をしすぎると保守が難しいクエリが生まれるという難点がありますが、基本的には便利です。

## Pythonデータソースで、 登録したクエリの実行結果を取得
Pythonデータソースで使える関数の1つ `get_query_result` は指定したクエリのキャッシュをとってきてくれます。
これもとても便利なのですが、Pythonデータソースをヘビーに使っていると定期実行させたいような性質のクエリで、キャッシュではなく最新のデータをとってきてゴニョゴニョしたい場面があります。

そこで、指定したクエリIDのキャッシュではなく、クエリを実行しその結果を返す関数を実装し、PRを送ってみました([#3132](https://github.com/getredash/redash/pull/3132))。業務で使っているRedashにはこの機能をマージして実際に使っています。

`execute_by_query_id(query_id, params)`
query_id: 実行するクエリのID
params: クエリに埋め込んでいるパラメータ  

以下のような日付指定で実行するSQLクエリを登録していたとして、

```sql
-- クエリID:1
select
    sum(revenue)
from
    sales
where
    date = {{date}} -- 日付をReadashパラメータ機能で指定
```

Pythonデータソースではこのように実行できます。

```python
# クエリID=1を実行
data = execute_by_query_id(1, {"date": "2018-12-21"})
```
## ユースケース
こんなユースケースを想定しています。  

**データ取得したいターゲットのIDをspreadsheetを書いてクエリを実行**
1. spreadsheetにモニタリングしたい何らかのマスタのidを書いておく
2. execute_query_by_idで1.のid群を取得
3. 2.の結果をexecute_query_idの `param` に渡し、指定したマスタのidでレポートデータを集計するクエリを実行

他にも実際の業務で、指定したクエリの実行結果をspreadsheetに転記するPythonクエリを作り、それをまた別のPythonクエリから実行するようなものが使われたりしています。  
深みにハマっていきそうな感じがとてもしますが、野良スクリプトがいろんな所に生息するよりはRedash管理下に置かれている方が便利というのもあります。

## さらに小ネタ
Pythonデータソースに `add_result_column`, `add_result_row` という実行結果として表示する列、行を追加する関数がありますが、
変数名 `result`　に `get_query_result` で取得できるものと同じ形式のdictを入れると `add_result_column`, `add_result_row` を使わずとも実行結果として列、行が表示されます。

## まとめ
RedashのPythonデータソースにありそうでなかった指定クエリ実行機能を実装しました。節度を守って使うと便利ではないかなと思います。マージしてもらえたら嬉しいです。  

## 最後に
2018-12-20に開催された[Redash Meetup 4.0.2-dev](https://redash-meetup.connpass.com/event/110549/)に参加させていただきました。
Redashの開発に関わられている方々から運用する中でのつらみや工夫の話を聞けて、とても勉強になりました！
初心者がJavaScript11行で爆速でドヤる方法〜画像オブジェクト認識編〜


たった11行です。

結論から言うと、
もうこれだけです。

```index.html
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script>
<script>
    const img = new Image();
    img.src = './cat.jpg';
    cocoSsd.load().then(model => {
        model.detect(img).then(predictions => {
            console.log('Predictions: ', predictions);
        });
    });
</script>
```

`index.html` というファイルを作成して
↑のコードをコピペ

適当な猫の画像を落としてきて
同じディレクトリに `cat.jpg` と保存
今回は[クリスマス猫](https://www.pakutaso.com/20181235354post-19080.html)を使用

そのディレクトリで以下のコマンドを実行します。

`$ python -m SimpleHTTPServer 3000`

起動方法はなんでもOKです。

- `$ php -S 127.0.0.1:3000`
- `$ npm install -g http-server && http-server -p 3000`

etc

ref: https://gist.github.com/willurd/5720255

実行後、
=> http://localhost:3000/
へアクセスしてコンソールを見れば

![Screen Shot 0030-12-21 at 6.03.46 PM.png](https://qiita-image-store.s3.amazonaws.com/0/45536/4134f5f1-1039-3f23-fa62-7465a9f8ea20.png "Screen Shot 0030-12-21 at 6.03.46 PM.png")

といった具合に画像の中にあるオブジェクト認識が実行されているのがわかります。

## 少しだけ解説

今回は、`coco-ssd` というオープンソースのオブジェクト認識モデルを使用しています。
=> https://github.com/tensorflow/tfjs-models/tree/master/coco-ssd

↑のGitHubにもある通り
NPM経由でも使用することができます

```
import * as cocoSsd from '@tensorflow-models/coco-ssd';
const img = new Image();
img.src = './cat.jpg';
const model = await cocoSsd.load();
const predictions = await model.detect(img);
console.log(predictions);
```

こっちだと6行ですね←

こちらを用いることで
人間(person)や自転車(bicycle),車(car)などなど
90種類のオブジェクト認識を実行することができます。
=> https://github.com/tensorflow/tfjs-models/blob/master/coco-ssd/src/classes.ts

## アメリカでは実に2/3のアプリが機械学習を取り入れている

近年、 ***"AIが〇〇しています"*** というサービスが増えてきましたが
アメリカでは実に2/3のアプリが機械学習を取り入れているとの結果がアンケートで出ているそうです。

[![Screen Shot 0030-12-21 at 6.20.23 PM.png](https://qiita-image-store.s3.amazonaws.com/0/45536/551699fa-e820-04c4-319b-f06b8f22fca9.png "Screen Shot 0030-12-21 at 6.20.23 PM.png")](https://twitter.com/yabaiwebyasan/status/1073417541618286592)
ref: https://twitter.com/yabaiwebyasan/status/1073417541618286592

(Google Developers ML Summitで聞いた話なのでソースのリンクなどはありませんがw)

機械学習はTensorFlowが2015年にオープンソースになって以来、
学習済みモデルがオープンソース上に転がっていたりするなど
どんどんサービスに組み込むハードルが下がってきています。

もはや、 ***"AIが〇〇しています"*** でどやれるような時代ではなくなってきてます。

「 ***まだAIやってないの？*** 」

の時代なのです

とはいえ、日本ではまだまだ機械学習はハードル高くて無理だなぁと思っているディベロッパーは多いはず。

是非、これを機に機械学習をサービスに取り入れてみてはいかがでしょう

余談ですが、こんな勉強会をやったりしてました。

[![Screen Shot 0030-12-21 at 6.23.55 PM.png](https://qiita-image-store.s3.amazonaws.com/0/45536/5810a03a-4746-2455-e08e-8bc08b974e8c.png "Screen Shot 0030-12-21 at 6.23.55 PM.png")](https://twitter.com/yabaiwebyasan/status/1075409847401603072)
ref: https://twitter.com/yabaiwebyasan/status/1075409847401603072

以前の勉強会資料もシェアしておきます。
=> [文系で数学ができなくてもお手軽に試せる機械学習ツール](https://drive.google.com/open?id=1bY996M9q3BYJ3n9UL6t0r94-siJYrho4)
C++ Builder XE4 > TeeChart > TChartのコピー > CloneChart(Dest,Origin:TCustomChart; AOwner:TComponent; ForceManualData:Boolean);

```txt:動作環境
C++ Builder XE4
TeeChart Lite v2013.08.130414 32bit VCL
```

### 処理概要

- TChartが二つある
- 片方のTChartの内容をもう片方にコピーしたい


### 実装

`CloneChart(Dest,Origin:TCustomChart; AOwner:TComponent; ForceManualData:Boolean);`
という関数があるようだ。

https://www.steema.com/support/viewtopic.php?f=3&t=13980

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    Chart1->Series[0]->XValues->DateTime = true;
    Chart1->BottomAxis->DateTimeFormat = L"nn:ss";

    TDateTime dt;

    dt = Now();

    double yval;
    for (int idx=0; idx < 10; idx++) {
        yval = (1+ idx) % 2;
        Series1->AddXY(dt, yval, "", clRed);
        dt = IncSecond(dt, 1);
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TComponent *cmpPtr = (TComponent *)Sender;

		   //  Dest,  Origin, AOwner, ForceManualData
	CloneChart(Chart2, Chart1, cmpPtr, false);
}
//---------------------------------------------------------------------------
```

### 動作例

ソフト起動直後
![2018-12-21_18h23_08.png](https://qiita-image-store.s3.amazonaws.com/0/32870/cf993dfd-587e-c785-d4e9-906d4f45687a.png)

Button1押下後
![2018-12-21_18h23_17.png](https://qiita-image-store.s3.amazonaws.com/0/32870/512a3a0a-2e75-5010-9601-64513749c1eb.png)


### 備考

- コピー先TChartには系列データの定義を追加していない
    - 系列データを定義しなくて良い
- TeeChartの公式ドキュメントを探したが、signatureの記載のみのページしか見つからず


### 検索用キーワード

- Copy
- Clone


### 関連

- [How to clone a chart if it has tools?](https://www.steema.com/support/viewtopic.php?t=14938)
shallowオプションでroutesを整える


今回は、shallowメソッドが非常に便利だったのでご紹介します。

#shallowオプションとは何か？
ルーティングの記述を複雑にせず、かつ深いネストを作らないという絶妙なバランスを保つことのできるオプションです！

では、具体的にはどのようなことか？

コードを交えて見ていきましょう。

#shallowオプションの使用前

```
resources :posts, only: %i(index show new create destroy) do
    resources :likes, only: %i(create destroy)
end
```
このようなroutesファイルがあったとします。

ネストしてますね。

では、このネストしているlikesのURLを確認してみます。


```
$rails routes -c likes
    Prefix Verb   URI Pattern                         Controller#Action
post_likes POST   /posts/:post_id/likes(.:format)     likes#create
 post_like DELETE /posts/:post_id/likes/:id(.:format) likes#destroy
```

destroyアクションの``/posts/:post_id/likes/:id(.:format)``って見づらいですよね？

それがshallowオプションを使えば、簡単に完結に解決します。

#shallowオプションの使用後
```
resources :posts, only: %i(index show new create destroy) do
    resources :likes, only: %i(create destroy), shallow: true
  end
```
では実際にshallowオプションを使用してみます。

これで、先程と同様にlikesのURLを確認してみると・・・

```
$ rails routes -c likes
    Prefix Verb   URI Pattern                     Controller#Action
post_likes POST   /posts/:post_id/likes(.:format) likes#create
      like DELETE /likes/:id(.:format)            likes#destroy
```

``/likes/:id(.:format)``に変わり、

shallowオプションを使う前のdestroyよりも、だいぶ見やすくなりましたよね！

しかもとっても簡単！

#親リソースで指定も可能

```
resources :articles, shallow: true do
  resources :comments
  resources :quotes
  resources :drafts
end
```

上記のように親リソースに直接shallowオプションを指定することも出来ちゃいます。

この場合だと全てのネストしたリソースが浅くなるそうです！

【参考記事】
https://railsguides.jp/routing.html
qiitaをスクレイピングしてAdvent Calendarの記事別いいね数を可視化する

### この記事について

年末、つまりアドベントカレンダーの季節ですね。
へーしゃでもアドベントカレンダーがそこそこ盛り上がっており、賑やかしのために各記事についたいいね数を可視化してslackに貼り付けてるので、それに使っているスクリプトをここに残しておきます。


### コード

モジュールのインポートから、qiitaのスクレイピングまで一気にやっていきます。

```.py
import pandas as pd
import datetime
import time
import re
import requests
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use('ggplot')
plt.rcParams['font.family'] = 'TakaoPGothic'


def extract_num_like(url):
    """
    qiita記事のURL + "/likers"(いいねしたアカウントの数が書いてあるページ)
    をスクレイピングし、いいね数を抽出する。
    """
    if re.search('https\://qiita\.com',url):
        res = requests.get(url + "/likers")
        soup = BeautifulSoup(res.content)
        num_likers = len(soup.find_all('h4',{'class':'UserInfo__name'}))
        time.sleep(5)
        return num_likers
    else:
        print(f'url not like qiita article. please confirm url: {url}')
        return 0

# まずはAdvent Calendarのtopページから記事一覧をとってくる
organization = "supership"
url = f"https://qiita.com/advent-calendar/2018/{organization}"
res = requests.get(url)
soup = BeautifulSoup(res.content)
# 担当者と記事のURLを抽出する
authors = [x.text.rstrip() for x in soup.find_all("a", {"class":'adventCalendarItem_author'})]
urls = [x.find('a').get('href') for x in soup.find_all("div", {"class":'adventCalendarItem_entry'})]

# 個別の記事のいいね数辞書
num_like_dic = {author: extract_num_like(url) for author, url in zip(authors, urls)}
```

続いて、さきほど作った辞書をpandas DataFrameにして、matplotlib(seaborn)に渡して可視化しましょう。
seabornはデフォの設定でグラフが良い感じになるので良いですね。

```.py
# 可視化するためにpandas DataFrameにする
df = pd.DataFrame.from_dict(num_like_dic, orient='index').sort_values(0,ascending=False).reset_index()
df.columns = ['担当者','いいね数']

today = datetime.datetime.today().strftime('%Y%m%d')
# 日次でデータをcsvで保存する想定なので、日付でsuffixをつけてcsv保存
df.to_csv(f'data/adcal_data_{today}.csv', index=False)

# いいね数がついているものに絞って可視化する
df = df[df["いいね数"] > 0]

# グラフ描画
plt.figure(figsize=(15,8))
plt.title(f'Advent Calnedar Watcher {today}')
sns.barplot(x='担当者', y='いいね数', data=df)
plt.xticks(rotation=90)
plt.savefig(f"Adcal_Watcher_{today}.png")
plt.show()
```

### 結果

こんな感じのグラフが書けました。
![adcal_watcher_20181221.png](https://qiita-image-store.s3.amazonaws.com/0/143008/19ae6a7a-1d1e-6cec-b419-92cb424c077e.png)
スマートウォッチ事情2018まとめ

# 2018年のスマートウォッチ概況

2018年は、去年頃から始まった時計メーカーや有名ブランドからの参入がさらに充実してきました。また、基本機能の要素をしっかり保持しつつも、低価格で購入できるスマートウォッチも出てきました。そして、よりデザインや用途を重視する流れに。

Apple Watchは画面が時計のサイズいっぱいに広がり、WearOS搭載スマートウォッチは完全に正円型が主流になりました。

ちなみに、フィットネス系用途のものはバンドタイプで独自OSが主流で、スマートウォッチとは明確に別れました。

# OSの最新バージョン

- watchOS 5.1.2 (Apple)
- Wear OS by Google 2.2 (旧：Android Wear)
- 他

# 形状

- Apple Watch は、やや縦長の長方形
- Wear OSは、正円型が主流（下部が欠けた円形は廃れました）

# 無線

- Bluetooth
- WiFi
- 3G 4G LTE
- NFC（日本モデルではFeliCaも）

# センサー

- 3軸加速度センサー、Gセンサー
- 3軸ジャイロセンサー
- 3軸地磁気センサー、電子コンパス
- 心拍センサー
- 光度センサー
- 気圧センサー

# 価格

- Apple Watch：25,000円 (Series 1の最安値) 〜 50,000円 (Series 4の最安値)
- Wear OS 搭載のスマートウォッチ：16,000円 〜 30,000円

# Wear OS 搭載のスマートウォッチ

## 2018年に発売されたWear OS 搭載のスマートウォッチ

- CASIO - WSD-F30
- Diesel - Full Guard 2.5
- Emporio Armani - Connected Matteo
- Gc Connect
- Fossil - Q Explorist (Gen 4)、Q Venture (Gen 4)
- Misfit - Vapor 2
- Mobvoi - Ticwatch S & E、Ticwatch Pro、Ticwatch C2
- Montblanc - Summit 2

## 2017年以前に発売されたWear OS 搭載のスマートウォッチのメーカー、ブランド

- Emporio Armani
- Fossil
- Hugo Boss
- Louis Vuitton
- Michael Kors
- Misfit
- Montblanc
- New Balance
- Nixon
- Tag Heuer
- Tommy Hilfiger
- Polar
- Samsung
- Asus
- Elephone
- Huawei
- LG
- Motorola
- Sony
- Verizon
- ZTE

# 詳細情報へのリンク集

- Apple Watch
    - Apple Watch - Wikipedia [en](https://en.wikipedia.org/wiki/Apple_Watch) [ja](https://ja.wikipedia.org/wiki/Apple_Watch)
    - watchOS - Wikipedia [en](https://en.wikipedia.org/wiki/WatchOS) [ja](https://ja.wikipedia.org/wiki/WatchOS)
    - [Apple Watchのモデルを比較する](https://www.apple.com/jp/watch/compare/)
- Wear OS (旧：Android Wear)
    - Wikipedia [en](https://en.wikipedia.org/wiki/Wear_OS) [ja](https://ja.wikipedia.org/wiki/Wear_OS)
駅メモを楽しむたった一つのcrontab

俺です。

macOSを使っている駅メモerの俺たちはこれで世界平和

```
$ brew install terminal-notifier
$ crontab -e
*/5 * * *  * /usr/local/bin/terminal-notifier -title "殴る時間だよ" -subtitle "猫パンツを忘れずに" -message ""
```

おわり
ActiveSupport::Duration と遊ぶ

# Duration は Duration

```ruby
15.minutes
=> 15 minutes
```

# Duration から Integer への変換

```rb
15.minutes.to_i
=> 900
```

# Integer から Duration の引き算

結果はDuration

```rb
60*60 - 15.minutes
=> -15 minutes、3600 seconds
```

# Integer から Duration の引き算 からの Integerへの変換

あたりまえたいそう‥。

```ruby
(60*60 - 15.minutes).to_i
=> 2700
```








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Xcodeショートカット 一覧

# Xcodeとショートカット
Appleが開発したmacOSやiOS向けのアプリケーション開発を行う統合開発ツール（IDE）です。
iOSアプリを開発している人であれば、誰もが使っていると思います。

日々開発を行なっている人が、さらに円滑に作業を行えるようなショートカットを紹介します。
また、自分も使いこなせるようにためになりそーなものを書いておきます。。。

## コード編

**コメントアウト**     ***Cmd + /***

カーソルが当たっている行もしくは、複数行に対してコメントアウトします。
コメントアウト解除の同様。

![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.amazonaws.com/0/179470/d0093228-0ec2-eb8b-2f48-df6e2b6b87ac.gif)


**インデント**     ***Ctr + i***

カーソルが当たっている行もしくは、複数行に対して最適なインデントをしてくれます。

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.amazonaws.com/0/179470/fad7164b-80bf-0f39-c247-87860a6c0619.gif)


**ファイル内検索**     ***Cmd + F***

現在、作業しているファイル内での文字列を検索します。
![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.amazonaws.com/0/179470/915e73bc-7ef6-693e-a815-4e1fd48aebca.gif)

※全文検索は、**Cmd + Shift + F** です。似てるので、覚えておきましょう！！
![ezgif.com-video-to-gif (3).gif](https://qiita-image-store.s3.amazonaws.com/0/179470/90cbae31-698b-8ecd-9452-d3ce9b41df95.gif)


**プロジェクト内検索**   **Cmd + Shift + O**

プロジェクト内でのファイル名から、メソッド、変数名を全て検索します。
![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.amazonaws.com/0/179470/a871820c-5c35-9cee-349c-69f17343a1b6.gif)

## デバック編

**ラン** **Cmd + R**

**ビルド** **Cmd + b**

**クリーン** **Cmd + Shift + k**



# 更新
まだまだあると思いますが、まとめきれていないため、逐次更新していきます。