OmniAICreator/Qiita-1.07M huggingface dataset:
とある教育サービスにおけるCREというロールのお話

この記事は[Classi Advent Calendar 2019](https://qiita.com/advent-calendar/2019/classi) 2日目の記事です。

Classiでは2019年8月にCREチームが発足しました。その立ち上げからジョインしたエンジニアの @kozy4324 がお届けします。ClassiにおけるCREとはどういったエンジニアリングチームなのか、エンジニアリングで何に取り組んでいるのか、またその魅力についてこの記事でお伝えできればなと思います。

# まずCREって何？
**C**ustomer **R**eliability **E**ngineering: 顧客信頼性エンジニアリング、2016年にGoogleがGoogle Cloud Platform（パブリッククラウド）事業で発表した比較的新しい専門職です。
https://cloudplatform-jp.googleblog.com/2016/10/google-cre.html

名前の通り、顧客の信頼性にフォーカスした課題に取り組むエンジニアリングチームと私は解釈しています。具体的に何に取り組むのかはそのサービスや顧客（ユーザー）によって決めるべきと考えていますので、まずClassiがどういったサービスなのかを説明させてください。

# Classiはどんなサービス？ ユーザーは誰？
Classiは**学校教育のICT活用を支援するクラウドサービス**です。
https://classi.jp/

ユーザーは大きく3パターンに分かれます。

- ICTを活用して校務を効率化したり新しい学びを生徒へ届けたいと考えている**学校の先生**
- 教育を享受する**学校の生徒**
- その生徒の**保護者**

# CRE≠カスタマーサポートエンジニア
Classiのサービスは先生への校務支援という側面があります。ICTをこれから導入していくという学校もまだまだ多いため、カスタマーサポートを通じてサービスを利用する上での不安・不満の解消やトラブルシューティングは顧客信頼性という観点で重要な業務になっています。

ただしカスタマーサポート業務がCRE業務の全てではありません。ClassiではCRE業務の一部と位置付けられています。

# ユーザーの改善要望からの価値提供
カスタマーサポートへはユーザーからの声や改善要望が多く集まってきます。その内容を精査しブラッシュアップをしてプロダクト開発チームへ連携することもカスタマーサポートには期待されています。

ここでCREは、**自分たちでプロダクトコードを修正しリリースすることでより早くユーザーに価値提供が出来ると判断される場合は自分たちで手を動かすこと**としています。

つまりClassiのCREはプロダクト開発エンジニアと同様にコードを修正し、プルリクエストを作成してリリースまでを行っています。

# リアクティブな施策とプロアクティブな施策
カスタマーサポート業務やユーザーの改善要望を受けてプロダクトを改善することは言わばインシデントが発生してから対応する受動的（リアクティブ）な対応です。

そもそもカスタマーサポートに問い合わせが来る前に不満解消・サービス改善ができないか、問い合わせ自体を無くすことができないのか、といった**能動的（プロアクティブ）な施策を実現することが本当の顧客信頼性を獲得するという意味で重要になる**と考えています。

それを実現するには問い合わせの蓄積データはもちろん、顧客属性データやサービス利用データといった情報も掛け合わせた高度なデータ分析や予測モデルの構築といったものが必要であり、ClassiのCREとしてはそういった領域にもチャレンジするつもりでいます。

# SaaS事業におけるカスタマーサクセスの重要性
Classiのビジネスはクラウドサービスという形で提供されるSaaS事業であり、月額の利用料を頂く形でサービス提供をさせてもらっています。このビジネスモデルにおいてはユーザーに長くサービス利用してもらいLTV（顧客生涯価値：取引期間中に顧客が企業にどれだけの利益をもたらすのかを算出したもの）を最大化することがとても重要になってきます。

このLTVを最大化するというミッションを持つのはカスタマーサクセス部門であり、Classiでもカスタマーサクセスチームはすでに存在します。

このカスタマーサクセスチームのエンジニアリングサポート、および顧客信頼性という観点からのLTV最大化はCREが担うべき領域であり、業績に大きく貢献できる部分です。**CREの業務や成果は業績に強く関連付けられ、事業成長へのコミットを強く実感することができます**。

# ClassiのCREの魅力
- ユーザーに近いところで声を聞きながらユーザーの課題解決に取り組める（**ユーザーファースト！**）
- ユーザーの改善要望を起因に価値提供までをスピード感持って取り組める（**アジリティ！**）
- Classiのプロダクト・技術領域に幅広く携われる（**ゼネラリスト・フルスタック指向！**）
- データ分析や予測モデル構築といった領域にもチャレンジ（**データサイエンス！**）
- 業務や成果が業績に強く関連付けられ、事業成長へのコミットを実感できる（**明確な事業貢献！**）

# ClassiのCREに求めること
ここまで色々書いてきましたが、自分自身4ヶ月前まではCREはもちろんカスタマーサポートやカスタマーサクセスの実務経験があるわけではありませんでした。比較的新しいロールではありますし、実際にやるべきことも明確に定義されているわけでもありません。

Classiのバリューの1つにこういったものがあります。

> **Unlearn & Learn**
> 既存の知識を外す勇気。「学び方」を学び続けよう。失敗してもいい。
> 新しい学びに挑戦しよう。

これまで学んできた知識を活かしつつ、けれどもそれが足枷とならないように柔軟に新しいことも学び、まだまだ出来ていないことに積極的に取り組む、そんなチャレンジ精神がClassiのCREには必要ではないかなと感じています。

# まとめ
CREというロール、やりがいがあって楽しいです（まとまっていない！）
この記事を読んで少しでもCREというロールに興味を持ってくれる方がいらっしゃれば幸いです。

反面、私自身まだまだ悩み事も多いので以下のような方を募集してます。ぜひ意見交換をお願いしたく。

- CRE興味が湧いてこれからチャレンジしたくなった
- CRE取り組んでいるけど同様に悩みごとが多い
- CRE完全に理解した（理解してる）

以上、[Classi Advent Calendar 2019](https://qiita.com/advent-calendar/2019/classi) 2日目の記事でした。
明日は@tetsuroitoさんです。
プログラミング未経験者向けにRubyワークショップをやった話

[【島根県内学生限定】初心者向けプログラミング講座](https://connpass.com/event/148105/)を実施する機会をもらったので、
そこで、やったこと、わかったこと、次にやることをまとめて残しておく（YWT）。

# 用意した題材
[当日資料](https://scrapbox.io/ruby-newbie-bootcamp/)
[ソースコード](https://github.com/enokizako/ruby-newbie-bootcamp)


# やったこと(Y)

1. プログラミングとはなにかを伝える
2. チームで取り組む楽しさを伝える
3. 参加者に次のステップを伝える

今回は題材として、Railsを使わない素の状態のRubyを使用。
島根県が推しているということもあるけど、県内にしっかりしたコミュニティがあること、学生の間は授業やイベントで触れる機会が多いことが大きな選定理由。

もし、職業としてのソフトウェアエンジニアに進むなら、遅かれ早かれ複数言語に触れることになるだろうし、県外に出ると「じゃあ、Rubyできるんでしょ？」と聞かれることもそれなりにあるので、触れたことがあるのは無駄にはならない(と思う)。

プログラミングの初期に学んでもらいたいこと様々あるけど、今回はプログラミングが目的達成のための道具という観点から、手ごろな課題に対して手持ちの武器（知識）をひねくり回して解決することを第一に。
ずっと以前に、勉強会で体験した[Devnomi](http://xpfriend.com/DevNomi/#/start)を下敷きにして「ポーカーの役判定プログラムをつくる」「みんなでひとつの画面をみながらキーを叩く人間を交代しながら」「用意されたテストコードをクリアする」というかたちで企画した。

コードを書くこと自体は、孤独にやらざるをえない場合も多いけど、同じようなレベルの人間が集まってわいわいやる楽しさを通して、学ぶことでレベルアップしていき、できることが増えるという正のフィードバックがあるということを体験してもらいたかった。

ちょっと前とはまた状況が変わったようで、情報関係の学生であっても自分のパソコンを持っていないことも多いので、無料のクラウドIDE[Paiza Cloud](https://paiza.cloud/ja/)とGitHubを組み合わせることで、ワークショップ後も持ち帰って再現したり、続きに取り組めるようにすることで、エコシステムの一端に触れつつ、今後プログラミングに触れる際の足掛かりとしてもらうことを期待。


# わかったこと(W)

1. 講座資料に[ScrapBox](https://scrapbox.io/?lang=ja)がとても便利
2. モブプロはチーム学習として有効
3. 未経験者には構造化の話がもっと必要

講座の資料作成は、ScrapBoxがとっても便利だった。全体の構成を粗くきめておきつつ、細部を思いつく都度作り込んでいくというやり方で資料作成をするのにぴったり。後からの推敲もとてもやりやすい。簡単なプレゼンテーション機能もついているので、資料＝プレゼンテーションにもなり、最初にURLを共有すれば完全にペーパーレスで実施することができる。
加えてワークショップなので手を動かしてもらうシーンも多いのだけど、説明にスクリーンショットを追加したかったらGyazoと連携した画像の貼り付けで一発だし、シンタックスハイライトは完璧とはいわないけど、サンプルコードも組み込みやすく、臨機応変に資料を改変＆共有するのには、ものすごく便利だった。

今回は初心者向けとターゲットを設定していたけど、次のイベントにつなげるという目的があるため、割と難しめのハードルをぶつけて、そこをチームで会話、協力しながら超えてほしいという期待を参加者にぶつけてみた。
これがうまくいった部分、いかなかった部分はあったけど、チームの中で議論しながらつくることを強制するやり方は、ある程度機能しており、事後アンケートでもチームだからついていけたという感想も得られた。学習については、とっかかりができればある程度ひとりでも進めることができるが、推進力＝楽しさや好奇心というモチベーションは、体験や仲間がいることで得やすくなってくれると考えた。

とはいえ、サポートで各チームをまわっていると、比較的初歩の部分のとっかかりでつまづいたり、苦労していたので、導入部分のステップをもっと小刻みにしたり、例題を増やして理解度をサポートする小さな階段、をもっとつくるべきだったと痛感した。
参加者アンケートでは配列、ハッシュあたりから理解に苦労したという話もあったが、加えてチームで議論を進めるためには、メソッドの分割とか構造化のあたりの設計よりをもうちょっと丁寧にやらないといけなかったと感じた。


# 次にやること(T)

主に課題、資料のブラッシュアップの観点で、３つ。まだまだ改善の余地はいろいろある。

1. 構造化の観点の追加
2. シンプルなアルゴリズムの実装例題
3. よりよく書く観点の追加

「この部分をプライベートメソッドとして切り出して」とか、モノシリックなメソッドではなく、ある程度構造化するという考え方について、今回思い切り抜けてしまっていたので、ここは本当に簡単な例題を用意するなり対策が必要だった。
また、初歩のアルゴリズムの例題もなにかあったほうがスムーズだった。カードの並び替えにしても、たしかにEnumerableのsort使えば確かに一発なんだけど、いったんべったべたな実装でバブルソートを実装してみて、それを少しずつ改善して読みやすくして、最終的にはこの便利メソッド使って、と漸進的に進化させることを体感してもらったほうがよかった。
外のワークショップでもほとんどの場合、やりたいことから逆算して、必要なものを調べながら学ぶという方法をとっているのだけど、未経験者向けにやるということから、もっと足がかりとなるとなる材料が必要だった。これは、当日その場で出したような直接的なサンプルより、もっと抽象度をあげたアルゴリズムの形で例題を事前にこなすよう、１日目のインプット時間の使い方を変えた方がよかった。


# 参考サイト、当日持ち込んだ書籍等
- [(DevNomi) ポーカーのコアライブラリ](https://github.com/ototadana/poker-core)
- [Rubyとは](https://www.ruby-lang.org/ja/)
- [るりまサーチ](https://docs.ruby-lang.org/ja/search/)
- [ゼロからわかる Ruby 超入門](https://gihyo.jp/book/2018/978-4-297-10123-7)
- [スラスラ読める Rubyふりがなプログラミング](https://book.impress.co.jp/books/1118101124)

# イラスト素材
- [IllustAc](https://www.ac-illust.com/)
押さえておきたいTCP/IPの基礎

この記事は[チームラボエンジニアリングアドベントカレンダー](https://qiita.com/advent-calendar/2019/team-lab-engineering)8日目の記事です。

---

TCP/IPを学ぼうとすると、知っておくべき範囲が広く、様々な用語の略称が登場するため理解するのに時間がかかります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251081/58838bf6-de51-0019-aca2-75fa73750503.jpeg" width=70%>

そこで、図を交えて最低限の情報に絞って整理してみようと思います。  

## そもそもTCP/IPとは何か

TCP/IPという単語を分解すると

- TCP
- IP

となります。一見、TCP(Transmission Control Protocol)とIP(Internet Protocol)の2つのプロトコルを指すように見受けられ、実際その認識で正しい場合もあるようです。しかし、多くの場合は**インターネットを構築するためのプロトコル群**を指します。

## プロトコルって何？

プロトコルは簡単に言えば**通信の約束事 = 通信の仕様**です。昔のコンピュータはメーカーごとにプロトコルが異なり、同じメーカー機器同士での通信しかできませんでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251081/e2c9a2dc-d45f-213d-f87c-18b49b8fb6f6.jpeg" width=50%>

しかし、TCP/IPがデファクトスタンダードとなってからは、TCP/IPが共通の約束事になり、自由な通信が可能になりました。今世界中のコンピュータネットワークが接続できているのは、TCP/IPが共通の約束事になっているからです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251081/bc4ab2ee-5ddf-5a36-bb0e-41114f185ba9.jpeg" width=50%>

## TCP/IPの階層

TCP/IPはインターネットのために開発されたプロトコル群です。TCP/IPの階層モデルは、OSI参照モデルとは少し異なります。

![TCP_IP-Page-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251081/47c5b9d2-1a15-976f-776b-a56f67d6120c.jpeg)

## 各階層の役割

TCP/IPの階層図を見ると、各階層にプロトコルが分けられているのがわかりますね。各階層、各プロトコルには明確な役割があり、この仕組みはアプリケーションの設計にも似ています。

### アプリケーション層
アプリケーションプログラムの中で実現されています。今あなたがこの記事を実際に目で見れているのは、アプリケーション層のプロトコルであるHTTPS(HyperText Transfer Protocol Secure)を使って、アプリケーションであるWebブラウザがHTML(HyperText Markup Language)というデータフォーマットを受信し、WebブラウザがHTMLを解釈してページを表示しているからです。この仕組みは、どのWebブラウザ(Chrome,Firefox,Edge,Safari・・・)でも共通です。

### トランスポート層
アプリケーション層では、アプリケーションプログラムの**中**の通信であることに対して、トランスポート層は、アプリケーションプログラムの**間**の通信を実現しています。コンピュータ内では様々なアプリケーションが存在するので、どのアプリケーション同士の通信なのかを識別する必要があります。識別にはポート番号が使われ、代表的なプロトコルとしてTCPとUDPがあります。

- TCP(Transmission Control Protocol)・・・コネクション型(通信相手と接続が確立した状態で通信する)プロトコルです。接続が確立していて、データが届いたかどうかのチェックも行われるため、通信相手へのデータ到達性が保証されます。

- UDP(User Datagram Protocol)・・・コネクションレス型(一方的にデータを送信する)プロトコルです。相手にデータが届いたかはチェックしていないので信頼性はありませんが、TCPに比べてデータの送信効率が良いので、動画配信などのデータ量の多い通信に向いています。

### インターネット層
この階層の役割は、データを最終的な通信相手に届けることです。トランスポート層では、どのアプリケーションかを識別することはできますが、地球上のどのコンピュータ宛に通信するのかは識別できません。通信相手の識別は、インターネット層にてIP(Internet Protocol)を使って実現しています。IPではIPアドレスを使って通信相手を識別します。

### ネットワークインターフェース層
ネットワークインターフェース層では、データリンクを利用して通信を行うためのインターフェースの役割があります。実際に通信を行う際の物理的な機器同士の接続ですので、OSI参照モデルの物理層と合わせて1つの層として扱われる場合もあります。

- データリンク・・・MACアドレスを使ってホストやルーター同士の通信をするための仕組みです。インターネット層では最終的な通信相手だけに着目しており、実際にどんな経路で通信するかは知りません。実際の通信ではデータリンクを利用してルーター(経路制御機器)を辿っていき、最終的な通信相手と通信できます。通信機器ごとにMACアドレスが割り当てられており、送信側ホストからルーターへ、さらに次のルーターへとMACアドレスを使って次々とデータの送り先を判別、転送していきます。

かなり簡単にデータリンクについて書きましたが、データリンクについて調べ出すと奥が深くて沼にハマるのでご注意ください。

## 通信の流れを図示してみる

![TCP_IP-Page-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251081/7335b78a-874c-7d31-566c-2b94b1f66129.jpeg)

## しっかり学ぶならこの本がおすすめ

マスタリングTCP/IP 入門編
出版: オーム社
共著: 井上直也・村山公保・竹下隆史・荒井透・苅田幸雄

入門編と書いてありますが、かなり情報量は多く読み応えがあります。僕みたいなWebエンジニアの場合、IPの分割と再構築処理や、パケットの中身はどうなっているか等の知識は業務に直接結びつかないかもしれませんが、コンピュータネットワーク登場の背景は興味深かったですし、IPアドレスの仕組みの話、CIDRの話はAWSに触れる上で役に立つと思いました。ネットワークに興味ある人にオススメです。
[The Go Programming Language Specification] Channel

# Channel
Golangのspecificationの日本語訳と、ちょっとした遊びぐらいのコードを載せていく感じで進めようと思うので、
すでにGolangでコードを書いている人にはつまらないかもしれないです

また、間違っている部分があればぜひご指摘いただけると嬉しいです🙇‍♂️

#### 想定する読者層
- Golang初めてそこまで期間が経っていない
- 英語の公式読むの辛い
    - https://golang.org/ref/spec

## Channel Types
本記事は公式のドキュメントを参考にしています
- https://golang.org/ref/spec#Channel_types

用途としては、goroutine同士の値のやりとりを行えるようにすることで並列処理を実装することです

### Channelの宣言
Channelとは並列実行を可能にする機能を持った型です。Channelは受信と送信の2つの機能によって成り立ち、初期化されていない時の値はnilになります。

```golang
var c chan int
```
https://play.golang.org/p/76gK6AIqxfF

### 受信と送信のChannelの宣言
受信と送信を分けるには `<-` を使い、以下のようにします
chan<- type はtype型の受信用のchannelを作り
<-chan type はtype型の送信用のchannelを作ります

```golang

var rc chan<- int // 受信用
var sc <-chan int // 送信用
```
https://play.golang.org/p/3txeE5q5nDe

### 一般的な宣言方法？
私自身は以下のようなchannelの宣言をしたことがなく、後述するmake関数を使った初期化をよく使うため、このような宣言方法もあるよという程度にしておきます（varを使った宣言をすることのメリットが分かれば追記しますね）

```golang

var ch chan<- chan int
var ch_1 chan<- <-chan int
var ch_2 <-chan <-chan int
var ch_3 chan (<-chan int)
```
https://play.golang.org/p/omJ7Dr87szy

### Channelの初期化
Channelの初期化はgolangのbuilt-in関数であるmakeを使用します
typeは型、sizeはint型でchannelの容量を指定します。

```golang
make（chan type, size）
```

sizeを指定しないで初期化した場合は0で初期化されます

```golang
c := make(chan int, 10) // len=0, cap=10
ch := make(chan int) // len=0, cap=0
```
https://play.golang.org/p/YuDFktgsHjM

nil Channelは通信の準備ができていないので注意です（varで宣言した時などがそれにあたります）

### サンプルプログラム
goroutineと、channelの送受信のサンプルプログラムです。
#### 一つのgoroutine

```golang
package main

import (
	"fmt"
)

func main() {
	c := make(chan int, 1)
	go receive(c)

	result := <-c
	close(c)
	fmt.Println(result) // 10
}

func receive(ch chan<- int) {
	ch <- 10
}
```
https://play.golang.org/p/fhU192bY6z2

#### 複数のgoroutineを使用した場合

```golang
package main

import (
	"fmt"
)

func main() {
	c := make(chan int, 1)
	go receive(c)
	go receive(c)

	fmt.Println(<-c)
	fmt.Println(<-c)
	close(c)
}

func receive(ch chan<- int) {
	ch <- 10
}
```
https://play.golang.org/p/ftrNWSD90vD

#### エラーが発生する場合
make(chan type, size) にて初期化した時のsizeを超える受信があった場合にはエラーが発生します

```golang
package main

import (
	"fmt"
)

func main() {
	c := make(chan int, 1)
	go receive(c)
	go receive(c)

	fmt.Println(<-c)
	fmt.Println(<-c)
	fmt.Println(<-c) // error
	close(c)
}

func receive(ch chan<- int) {
	ch <- 10
}
```
https://play.golang.org/p/LGhENuShFP1

参考になりそうなプログラムを思いついたら追記していきます
Progate Pythonやってみた

Pythonコードを業務で使い始めて早１年。

同僚にPythonを教える機会があるので、
一通り基礎を復習する気持ちで取り組んでみた。

Progateでクラスの定義、継承を学ぶことができた。
リストの内包、lambda関数とか便利な書き方があるのに、
それを教えてくれないのはちょっと不親切な気もしました。

ただPythonを一から学ぶ人にはよいと思います！
操作性もよく、間違ってる部分を見つけやすい。

ざっくりとした概要は下記のとおりです。

Python Ⅰ
和差積商、変数、論理和、論理積、条件分岐

Python Ⅱ
繰り返し分(for,while)、リスト、辞書型

Python Ⅲ
関数

Python Ⅳ
クラス
クラスの定義、インスタンス、クラスの中で関数を定義(インスタンスメソッド)

Python V
クラスの継承
初心者)備忘録）スクレイピングとCSVへの出力

###準備
[こちらの記事](https://qiita.com/hoger/items/89131f5e0bef7cd21fa6)を参考にスレイピング用のコードを完成させる

###ソースコード
```Python
import urllib.request
import urllib.error
from bs4 import BeautifulSoup
import csv
import numpy

l_cap_name = []

url = "https://scrapethissite.com/pages/simple/"
headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'
           }
request = urllib.request.Request(url=url, headers=headers)

try:
    response = urllib.request.urlopen(request)
except urllib.error.HTTPError as e:
    print('HTTPError: {}'.format(e.code))
except urllib.error.URLError as e:
    print('URLError: {}'.format(e.reason))
else:
    for term in BeautifulSoup(response, 'lxml').find_all('span', class_='country-capital'):
        l_cap_name.append([term.string])

print(l_cap_name)


with open("l_cap_name.csv", "w", encoding="utf-8") as f: 
# encoding="Shift-jis"だと'Brajilia'の部分でunicodeencodeerrorが出ました

    writer = csv.writer(f, lineterminator="\n")  # writerオブジェクトの作成、改行記号で行を区切る

    writer.writerows(l_cap_name)
```

作成したCSVファイル

```CSV
Andorra la Vella
Abu Dhabi
Kabul
St. John's
The Valley
Tirana
Yerevan
Luanda
None
Buenos Aires
Pago Pago
Vienna

---中略---

Mata-Utu
Apia
Pristina
Sanaa
Mamoudzou
Pretoria
Lusaka
Harare
```
ちなみに、作成したCSVファイルを読み込むときは

```Python
with open('l_cap_name.csv', "r", encoding="utf-8") as r:
    readers = csv.reader(r)
```
開発用Macの基本セットアップメモ

新Macに開発環境を構築するためのメモです。
※OSのバージョンにより、インストール途中にエラーが出る場合があります。その際にエラーメッセージでググればヒントが得られます。


# Xcode
Xcode：アップルの統合開発環境（IDE）。
後のHomebrewをインストールするのに必要です。

## App StoreからXcodeをインストール
インストールした後にライセンスに署名してインストールを完了させる。
`$ sudo xcodebuild -license accept`

## XcodeのCommand Line Toolsをインストール
`$ xcode-select --install`
git など開発系のコマンドがインストールされる。

**★一旦Macを再起動**

# Homebrew
Homebrew：Mac用パッケージマネージャー。
インストールすればコマンド一つでアプリをインストールできるようになる。インストール時の人為ミスや以後のパッケージのメンテナンス手間を省ける。
http://brew.sh/index_ja.html
https://github.com/Homebrew/homebrew/tree/master/share/doc/homebrew#readme

## Homebrewをインストール
```
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

備考：

+ ディフォルトのインストール先（現時点）：`/usr/local/Homebrew`
+ ディフォルトのコマンドの実行パス：`/usr/local/bin`
+ `/usr/local/Homebrew`でなくインストール先を変えた場合は、コマンドの実行パスを通す必要があります。   
例）bシェルの場合

```
$ vi ~/.bash_profile`
export PATH=＜実際のパス＞
```


## Homebrew Caskをインストール
Homebrew Cask：dmgファイルやpkgファイルになっているものを含めてGUIアプリをコマンド一つでインストールできるHomebrewの拡張機能。
`$ brew install cask`


# Mac開発に必要or便利なアプリをインストール
```
$ brew install imagemagick composer wget
$ brew cask install slack visual-studio-code atom coteditor docker sourcetree sequel-pro cyberduck google-chrome firefox skype teamviewer gyazo avast-security google-japanese-ime
```
GUIアプリのディフォルトインストール先：`~/Applications`
※Catalinaの場合、セキュリティエラーにより、`brew cask`でインストールしたアプリが開けないものがあります。一旦`~/Applications`からアプリをダブルクリックして、「開く」ボタンで開けます。
駄目な場合は、https://github.com/microsoft/vscode/issues/74782

# その他
## 隠しファイルをFinderに表示
```
$ defaults write com.apple.finder AppleShowAllFiles -boolean true
$ killall Finder
```


## プリンターの設定
システム環境設定＞プリンタとスキャナ＞「＋」で追加
GitHub Actions で Deno を使う

Deno (ディノ) Advent Calendar 14日目の記事です.

今日は GitHub Actions で Deno を使う方法を紹介します. GitHub Actions で Deno を使うには [denoland/setup-deno](https://github.com/denoland/setup-deno) という Action を使います.

(Update(2022/11/27): denolib/setup-deno から denoland/setup-deno に更新しました)

# 使い方

使い方はとても簡単で, action の step で `denoland/setup-deno@v1` を指定すれば, ホスト環境に `deno` コマンドがインストールされます.

```yml
jobs:
  hello:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: denoland/setup-deno@v1
        with:
          deno-version: v1.x
      - run: deno run https://deno.land/std/examples/welcome.ts
```

(実際にはさらに `on` プロパティでトリガーをセットする必要があります.)

複数の Deno バージョンでマトリックステストをしたい場合は以下のようにして実現できます.

```yml
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        deno: [v1.x, v1.25]
    name: Deno ${{ matrix.deno }} sample
    steps:
      - uses: actions/checkout@master
      - name: Setup Deno
        uses: denoland/setup-deno@v1
        with:
          deno-version: ${{ matrix.deno }}
      - run: deno run https://deno.land/std/examples/welcome.ts
```

# Recap

今日は setup-deno を使って GitHub Actions 環境に Deno をインストールして使う方法を紹介しました.
Julia1.3をMacに導入

# 本日は

- カレンダーが空いていたので書きます．
- MacでJuliaをインストールする方法です．

# まずは，インストールしますか

- まずは Julia 自身をダウンロードすることになります．各プラットフォームでJuliaを導入する方法が公式ページ [Platform Specific Instructions for Official Binaries](https://julialang.org/downloads/platform.html) で紹介されています．
  - ざっくりいうと Julia をインストールしてパスを通すことで使えるようになります．

- https://julialang.org/downloads/ に移動します．現時点では Julia の安定版で最新は `v1.3.0` です．機能が逐次追加されていきますので必要に応じてバージョンアップしていきましょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/689d8fc9-e00e-fd60-9111-99980eb8b6c2.png)

- 私はMacを使っているので macOS 10.8+(.dmg) の行にある `64-bit` のリンクを選びます．32/64どっち選べばいいの？わからん！！って場合は64bitの方を選べば良いです．
- 自分のパソコンはどうやら Linux に該当するんだけれど x86,ARMどっちを選べばいいんだ？と思うかもしれません．ラズベリーパイ, Jetsonという言葉を知らない場合は `x86` の行の `64-bit` を選べばOKです．

# Macの場合

Qiita書いているPCが Mac なのでその場合にのみ書きます． dmg がダウンロードされて自然と下記の画面が見ええてくるでしょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/6821e55b-c4a7-f86d-ea18-10af0bcf0652.png)

`Julia-1.3.app` のアイコンを `Application`　にドラックアンドドロップします．
Finder を開いて横にショートカットとしてでている（はず）の `Application` を押します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/08cc60cc-86a7-a1cb-b2c3-56dc80a0cf11.png)

そうすると `Julia-1.3.app` が見えるはずです．`Julia1.1.app`,`Juliaa1.2.app` は私には見えていますが，皆さんには見えていません．よくわからない？まぁまぁ，進みましょう．

## Julia の起動（初回だけ）
`Julia-1.3.app` を右クリックして `Open` をクリックします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/d0d8259b-23b8-6c71-83bf-7e11c7de7a16.png)

AppleのOSのセキュリティが厳し目なので次のように三角びっくりマークがでますが `Open` をクリックします．この警告は初回だけでます．次回以降はでてきません．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/7881e4ce-97f5-30bc-54f8-9777375951f1.png)

`Open` をクリックするとターミナルが開いて下記のような julia の AA（アスキーアート） が出現します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/7439da6a-0ff0-4b96-ea59-4a5403ab789b.png)

は〜 真っ黒の画面＋緑色も文字がでます．これは terminal.app が自動で起動したからです．一旦ここでは閉じましょう．

## Julia の起動（２回目以降）

[スポットライトの機能](https://support.apple.com/ja-jp/HT204014) を用いて `terminal.app` を起動します．


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/b3947319-cf92-0986-5d34-269a9564057b.png)

そうすると再びターミナルがでてきますので

```
/Applications/Julia-1.3.app/Contents/Resources/julia/bin/julia
```

をターミナルに貼り付けましょう．貼り付けた結果が下記のようになります.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/19affd1f-2bfc-f846-9e3c-58bcbe108474.png)

今回は警告マークがでずに済みました．めでたい．あとは 

```console
% echo $SHELL
/bin/zsh
```

を確認し `~/.zshrc` に Julia のパスを追加します．

```:~/.zshrc
export PATH="/Applications/Julia-1.3.app/Contents/Resources/julia/bin:$PATH"
```

これで Julia のパスが通ったので `julia` でJuliaを呼び出せます．

```zsh
% source ~/.zshrc
% julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.3.0 (2019-11-26)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |
```

よし，とりあえず，Juliaが入りました．これでJuliaで遊べますね．
Azureでサーバレス 、監視はどうする？ 試して分かった、7つのこと

本記事は、はてなブログに移行させていただきました。
[移行先](https://yktm31.hatenablog.com/entry/2020/04/01/232043?_ga=2.172693482.877729591.1585750300-1214914263.1580825888)
VSCodeのCode Runner一時対策

明日からRust三昧になります。

Code Runnnerは再生ボタン押すだけでいい感じにプログラムをコンパイルして動かしてくれるツールです。めちゃくちゃ便利です。競プロとかでいいんじゃないでしょうか。

そんなCode Runnerですが、どうもVSCodeのデフォルトのターミナルがwslになってしまったらしく、バグるようになりました。すでに[issue済み](https://github.com/formulahendry/vscode-code-runner/issues/282)でおいおい対応すると思いますが、それまでの間setting.jsonを編集してデフォルトターミナルをコマンドプロンプトにする方法を載せておきます。

## 環境
Code RUnner 0.9.15
Microsoft Windows [Version 10.0.18362.476]
VSCode 1.40.2

１ 左下の設定を開く

![スクリーンショット (102).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/0bb4da29-a7cc-f231-580a-67397f77653d.png)

２ 設定をjsonで開く

![スクリーンショット (103).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/f8e01797-56d3-14f7-a255-469e0c540484.png)

３ "terminal.integrated.shell.windows": "C:\\Windows\\System32\\cmd.exe"にしてターミナルをcmdにする
![スクリーンショット (104).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/1869f56a-9537-6017-038b-530a58ae9b09.png)
【AWS EC2】自動デプロイ設定後に、修正ファイルを再デプロイする手順

①まずデスクトップアプリでgithubのmasterに編集ファイルをpushしてマージする。

②EC２でログインして該当ディレクトリまで移動

EC2にログイン

```
$ cd .ssh
$ ssh -i chat-space.pem ec2-user@[生成したElastic IP]
```
アプリまで移動

```
$ cd /var/www/app/
```

③②の位置でマスターをpull

```
$ git pull origin master
```
これで変更がEC2サーバー上にきたか確認

④念の為プロセスを切る

```
$ ps aux | grep unicorn
$ kill プロセス番号
```

⑤ローカルで自動デプロイする。

```
$ bundle exec cap production deploy
```

⑥デプロイしたIPで確認
AndroidでViewModelのLiveDataをアプリケーションで共有する

## 概要

AndroidでViewModelに保持したLiveDataの値をアプリケーションで共有したい場合のメモ

## 方針

本来の仕様では起動中のActivityのインスタンスとViewModelが1対1で対応するため、
Activityのインスタンスが変わってしまったり、異なるActivityのインスタンスからLiveDataをobserveしても、
変更検知ができません

```kotlin
class MyActivity : AppCompatActivity() {
  private val userViewModel: UserViewModel by lazy { ViewModelProviders.of(this).get(MyViewModel::class.java) }
  override fun onCreate(savedInstanceState: Bundle?) {    
    userViewModel.user.observe(this, Observer<User>{ user ->
      // OtherActivityでの変更は検知できない
    })
  }
}

class OtherActivity : AppCompatActivity() {
  private val userViewModel: UserViewModel by lazy { ViewModelProviders.of(this).get(MyViewModel::class.java) }
  override fun onCreate(savedInstanceState: Bundle?) {    
    userViewModel.user.observe(this, Observer<User>{ user ->
      // 変更検知できる
    })
    // データの更新を実行
    userViewModel.fetch()
  }
}
```

`ViewModelProvider.Factory` を継承したクラスを作成し、
ViewModelのクラスの名前で `ViewModelProviders` から取得するViewModelが
一意になるようにすることでアプリケーション内でLievDataを共有できるようにしました。

## 実装したコード

`ViewModelProvider.Factory` を継承した `ViewModelFactory` というクラスを作成

```kotlin
class ViewModelFactory: ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (ViewModel::class.java.isAssignableFrom(modelClass)) {
            val key = modelClass.toString()
            return if(hashMapViewModel.containsKey(key)){
                getViewModel(key) as T
            } else {
                val vm: T?
                try {
                    vm = modelClass.newInstance()
                } catch (e: IllegalAccessException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InstantiationException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                } catch (e: InvocationTargetException) {
                    throw RuntimeException("Cannot create an instance of $modelClass", e)
                }
                addViewModel(key, vm)
                getViewModel(key) as T
            }
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }

    companion object {
        val hashMapViewModel = HashMap<String, ViewModel>()
        fun addViewModel(key: String, viewModel: ViewModel?){
            viewModel?.let {  hashMapViewModel.put(key, it)
            }
        }
        fun getViewModel(key: String): ViewModel? {
            return hashMapViewModel[key]
        }
    }
}
```

## 使い方

LiveDataをアプリケーション内で共有したいときのみ、
下記のようにViewModel生成時に `ViewModelFactory` を渡してあげればOK

```kotlin
class MyActivity : AppCompatActivity() {
  private val viewModelFactory: ViewModelFactory = ViewModelFactory()
  private val userViewModel: UserViewModel by lazy { ViewModelProviders.of(this, viewModelFactory).get(MyViewModel::class.java) }

  override fun onCreate(savedInstanceState: Bundle?) {    
    userViewModel.users.observe(this, Observer<List<User>>{ users ->
      // LiveDataがアプリケーション全体から参照できるようになる
    })
  }
}
```
構築したSerumでリンク先の追加と記事投稿をする方法

[前回](https://qiita.com/mocamocaland/items/fd6af9f4582972f0f1f6) Serumの環境構築を書いたので
今回はその後のリンクページ追加と投稿方法について解説します。

そういえば最近Serum v1.3.0 がリリースされたようです。
https://twitter.com/d57pub_/status/1199884140755091456
https://twitter.com/d57pub_/status/1199694257239420933


# 投稿方法

```
$ mix serum.gen.post -t {title} -o {file_name} -g {tag}
```
* {title}, {file_name}, {tag}のところはそれぞれ任意のタイトル、ファイル名（testPostでつけると2019-12-01-testPost.mdになります）タグ名を入れて下さい。
* タグ名は入れてなくても投稿は可能


# リンクページを追加

```
mix serum.gen.page -t {title} -o {file_name}.md 
```

* {title}と{file_name}と記述したところは任意のタイトルとファイル名をつけて下さい。
* 拡張子は.md, .html, .html.eexが使用できます。
* リンクの表示方法は後日追記します。



構築さえできればリンクページ、投稿は簡単に行えます。
是非試してみて下さい。



参照先
https://dalgona.github.io/Serum/docs/mix-tasks.html#serum.gen.page
rails6.0ではsend_dataでファイル名を明示的にエンコードしなくても文字化けしなくなってる


タイトルの通り、rails6.0以前では`send_file`でファイルダウンロード機能を実装しているとIE, edgeの場合にファイル名が文字化けしてしまうので、明示的にエンコード処理をして対策を行う必要がありました。
rails6.0ではこの対応が不要になるコミットがされています。

# rails6.0以前の場合

これだと、IE、edgeの場合にファイル名が文字化けしてしまいます。

```ruby
data = "XXX"
filename = "サンプルファイル.txt"
send_data(data, filename: filename)
```

その為、以下の様に明示的にエンコードしてあげる必要がありました。

```diff
data = "XXX"
filename = "サンプルファイル.txt"
+ encorded_filename = ERB::Util.url_encode(filename)
- send_data(data, filename: filename)
+ send_data(data, filename: encorded_filename)
```

# rails6.0では

詳細はPRに書いてありますが、上記のエンコード処理をrailsがしてくれる様になったので、
明示的にエンコード処理は不要になりました。
また、rails6.0以前のアプリの為にバックポートgemも用意されています。(PR内に書かれています。)

https://github.com/rails/rails/pull/33829

現在rails5系で動いていて、明示的にエンコードしているアプリでは
railsバージョンアップ後は不要な処理になるので忘れずに削除しましょう。
SmallTalk - Conway's Law

>
1967
The system being produced will tend to have a structure that mirrors the structure of the group that is producing it, whether or not this was intended.

想要做一個大而無用的產品，就找個幾百人、而且人愈多愈好、階層愈多好，那你就成功了一半。

http://jonathanspeaking.blogspot.com/2010/11/conways-law.html

https://towardsdatascience.com/effective-microservices-10-best-practices-c6e4ba0c6ee2
一時テーブルが存在していたら削除する

# 一人アドカレ

| 日 | ポスト |
|:--:|:-----:|
|  1 | [一時テーブルが存在していたら削除する](https://qiita.com/sotoattanito/items/10e65399caf34fae3017) |
|  2 |       |
|  3 |       |
|  4 |       |
|  5 |       |
|  6 |       |
|  7 |       |
|  8 |       |
|  9 |       |
| 10 |       |
| 11 |       |
| 12 |       |
| 13 |       |
| 14 |       |
| 15 |       |
| 16 |       |
| 17 |       |
| 18 |       |
| 19 |       |
| 20 |       |
| 21 |       |
| 22 |       |
| 23 |       |
| 24 |       |
| 25 |       |

# 一時テーブルが存在していたら削除する

この記事は自身のブログを書き直したものです。

## 課題

SQL Server Management Studio上で一時テーブルを使ったクエリをテストしているとき、テスト前に毎回一時テーブルを手動で削除するのが面倒。テスト実行時に一時テーブルが存在していたら削除して作りなおすようにしたい。

## 準備
### 実行環境

 * SQL Server 2017 Standard
   * SQL Server 2008 R2 Express, 2012 Standardでも確認した。
 * SQL Server Management Studio 2017

### サンプルデータ

fruitsテーブル

|ID|Name|Price|
|:--:|:----:|:-----:|
|1|apple|100|
|2|apple|120|
|3|orange|50|
|4|orange|40|
|5|apple|80|
|6|orange|60|
|7|banana|120|
|8|banana|150|

## 解法

OBJECT_ID関数を使って一時テーブルが存在するかどうか調べて、存在するなら削除する。

関数の2つ目の引数'U'は、検索するデータベースオブジェクトとしてユーザー定義のテーブルを指定するってことのよう。


```sql
IF OBJECT_ID( N'[tempDB]..[#totalPrice]', N'U' ) IS NOT NULL
  BEGIN
    DROP TABLE [#totalPrice];
  END

SELECT
    [Name]
  , SUM( [Price] ) AS [Total]
INTO
  [#totalPrice]
FROM
  [fruits]
GROUP BY
  [Name]
ORDER BY
  [Name];

SELECT * FROM [#totalPrice];
```
SELECTクエリの結果は省略。

これでもう次のようなメッセージを見てがっくりすることはない。

> メッセージ 2714、レベル 16、状態 6、行 1
> データベースに '#totalPrice' という名前のオブジェクトが既に存在します。

## 感想

クエリを繰り返す時は便利。1,2回流して終わりのクエリだといちいち打つのはだるい。
ただし、Management Studio上でエラーが出ているとき（構文エラーなど）に実行してもエラーが先に出てしまって、肝心のクエリは実行されないので注意。
そういうときはエラーを先に修正したり、 `IF OBJECT_ID( N'[hogeTbl]', N'U' )` のブロックだけを実行して一時テーブルの削除だけをしたりと、都合の良いように対応する。

## 参考

 * [https://msdn.microsoft.com/ja-jp/library/ms190328(v=sql.105).aspx:title]
Deno にコントリビュートする (2)

<!--
想定読者:
- Deno に興味がある一般の人
- Deno に興味を持っているけど, 本体を clone してビルドする気はない人
- OSS になんでもいいからコントリビュートしてみたい気持ちはあるけど, 何をしていいのかわからない人
-->

Deno (ディーノ) <img src="https://raw.githubusercontent.com/kt3k/drafts/master/assets/deno.png" width="20"> Advent Calendar 9日目の記事です.

昨日の記事では Deno 本体にコントリビュートする方法を解説しましたが, Deno 本体に PR を投げることだけがコントリビュートではありません. 本記事では Deno 本体以外で Deno にコントリビュートする方法を紹介します.

# Deno のホームページ

[Deno のホームページ][hp]のソースコードは以下のコマンドで clone 出来ます.

```sh
git clone https://github.com/denoland/deno_website2.git
```

Deno のホームページは一般的な React プロジェクトです. 通常の React プロジェクトと同様に実行することが出来ます.

```sh
cd deno_website2
yarn
yarn start
```

デザインで気になった点, 表現で気になった点など, [ホームページ][hp] で気になった点を修正して, PR を投げてみましょう. またホームページの [issue](https://github.com/denoland/deno_website2/issues) もあるため, そちらを解決するのもおもしろいかもしれません.

# アイコン

@hashrock さんが下の Deno のアイコンをコントリビュートしたことは Deno コミュニティの中では有名です. 公式ドキュメントの中でも使われています.

<img src="https://deno.land/images/deno-circle-thunder.gif" />

@tanakaworld さんの下の Deno アイコンも公式アイコンとして Deno コミュニティに受け入れらています. 公式ドキュメントや, カンファレンスでの発表資料などで使われています.

<img src="https://deno.land/images/deno_logo_4.gif" />

画力に自信のある人はこういうコントリビュートの仕方もあります.

# 3rd パーティライブラリ

https://deno.land/x/ という URL に行くと Deno の 3rd party モジュールが列挙されています. ここは Deno のための (とても小さな) npm のようなページで, Deno で書かれた任意のライブラリはここに載せることが出来ます.

このリストに自分のライブラリを追加したい場合は [こちらの JSON ファイル](https://github.com/denoland/deno_website2/blob/master/src/database.json)に対して PR を投げて, 自分のライブラリの情報を追加してください. Deno エコシステムに貢献したことになります. なお, ここに載せられるための条件はかなりゆるくて, 相当特殊なライブラリや, 作った本人以外必要としていないようなものでも, ほぼリジェクトされることはありません. 勇気をもって PR を投げてみましょう. (ただし, 標準ライブラリにすでにある機能と全く同じ機能や, あまりにも自明なものなどは, なぜそれが必要なのか, という議論になる場合もあります.)

# コードリーディング

コードリーディング記事をまとめることも立派なコントリビュートです.

日本語では過去に以下のようなコードリーディング記事が上がってきています.

- [Deno をよむ(1)](https://blog.bokuweb.me/entry/2019/01/11/102706) by @bokuweb
- [deno_code_reading.md](https://gist.github.com/mizchi/31e5628751330b624a0e8ada9e739b1e) by @mizchi
- [Dive into Deno：プロセス起動からTypeScriptが実行されるまで](https://blog.leko.jp/post/code-reading-of-deno-boot-process/) by @L_e_k_o
  - 上の改訂版が Denobook 02 第5章でよめます.

Denobook 02 の Leko さんの記事が最も最新の内容に近いですが, それ以降も微妙に変わってきているため, 上記を踏まえた最新のコードリーディング記事が出てくると, Deno コミュニティに大きく貢献したことになります. また, エントリポイント/イベントループとは別の箇所 (deno_typescript や, ts で実装されている API, tools 周りなど) に焦点を当てたコードリーディング記事なども面白いかもしれません.

# チャットに参加

https://deno-ja-slackin.herokuapp.com

上の URL から, deno の日本コミュニティの slack に参加できます. #random チャネルなどで Deno に対する質問/意見/感想を述べてコミュニティのメンバーと会話をしてみましょう. コミュニティの活動を盛り上げることも立派なコントリビューションと言えるでしょう.

# wiki を読む/更新する

Deno 日本コミュニティは [scapbox](https://scrapbox.io/deno-ja/) に各種 tips を蓄積しています. scrapbox の更新も大切なコントリビューションの1つです.

# まとめ

今日は本体にコントリビュートする以外での Deno にコントリビュートする方法を紹介しました.

明日は @syumai さんの Wasm を動かす話です.

[hp]: https://deno.land/
Monacaのデバッグ方式色々

この記事は[Monaca Advent Calendar 2019 - Adventar](https://adventar.org/calendars/4135)、1日目の記事になります。

Monacaでは、アプリの表示確認やデバッグに際して様々な方法が存在します。あまりにも多いので、どれが最適なのか分からない人も多いことでしょう。

そこでデバッグ方式別に向き不向きを紹介します。

## 1. Web IDEのプレビュー

<img width="1532" alt="ScreenShot_ 2019-12-01 23.31.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8944bfa0-5b14-379c-94c7-fe8a282567c0.png">


Web IDEを使って開発する際に最もよく使うのがプレビューでの表示確認でしょう。この方法は最も手軽な一方、アプリとの機能差もあるので注意が必要です。

- 表示はHTTPSで行われます
  - MonacaアプリはHTMLファイルをfile://で読み込むので、URLスキームがアプリと異なります
- CORS制限があります
  - プレビューではCORS制限があるので、リソースの取得に際して制限があります。CORS制限のないAPI、JSONPなどを使う必要があります
- ブレークポイント、コンソールはWebブラウザの開発者ツールのものが利用できます
- プラグインは利用できません
  - プラグインが動く前提で作っているとエラーが出てしまうので、何らかの回避策が必要です

## 2. Monacaデバッガー

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/66c1604d-d4d5-cf5d-3ce5-ad81e1ddc1a8.png)


MonacaデバッガーはApp Store、Google Playで配布されています。Web IDEでのプロジェクトやLocalKit、Monaca CLI内でのプロジェクトもMonacaデバッガー上で確認できます。

- いくつかのプラグインは元々組み込まれています
  - プラグインを使っていると、Monacaデバッガーで動くのにデバッグビルドでは動かないといったエラーが出ることがあります
- USBデバッグはできません
  - iOSと母艦をUSBケーブルで繋いでSafariのインスペクタを使うような操作はできません
- 独自に追加したプラグインは利用できません
- [Charles](https://www.charlesproxy.com/)を使えばネットワーク接続内容をモニタリングできます

## 3. カスタムビルドデバッガー

独自のプラグインを組み込んだMonacaデバッガーを作成します。独自のプラグインを使いつつMonacaアプリを開発する際には、カスタムビルドデバッガーを活用しましょう。

- プラグインはプロジェクト標準のものと独自に組み込んだものだけになります
- プッシュ通知のプラグインなどは動作しない場合があります
- USB接続でデバッグできます
  - ブレークポイントを差し込むこともできます
  - ネットワーク監視もできます

## 4. デバッグビルド

ある程度開発が進んできたらデバッグビルドに進みます。

- リリースビルドと変わらない使い勝手です
  - この状態で正しく動いていないと、リリースは難しいでしょう
- アプリ内課金、プッシュ通知などはリリースビルドと異なります
- USBデバッグできません
  - デバッグビルドではUSBケーブルを接続したデバッグは利用できません
- [Charles](https://www.charlesproxy.com/)を使えばネットワーク接続内容をモニタリングできます

## 5. シミュレータビルド

<img width="648" alt="ScreenShot_ 2019-12-01 23.32.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/1e816546-170a-6ebb-e4ef-37c01d93dd00.png">


iOSシミュレータ上で動作するように作られたデバッグビルドです。デバッグビルドと同等の機能ですが、証明書などの設定が不要です。macOSのiOSシミュレータ上で利用できます。

## 6. Localkitの開発者ツール

Localkitでは開発者ツール相当のインスペクタが利用できます。Web IDE上での開発者ツール相当の使い方ができます。

- プラグインのコードは動作しません
- ブレークポイントが利用できます
- ネットワークの監視もできます

## 7. Monaca CLIでのプレビュー

Monaca CLIではWebブラウザからのプレビューが可能です。これはMonaca IDEのプレビュー同等です。

## まとめ

Monacaのデバッグ方法は意外と多いので、最適なものを選ぶようにしてください。個人的には以下の順序がいいかと思います。

1. (Web IDEの場合) Web IDEの開発者ツール / （LocalKitの場合）LocalKitのインスペクタ / （Monaca CLIの場合）Webブラウザの開発者ツール
2. 独自のプラグインを使い始めた場合：カスタムビルドデバッガー
3. リリース前の動作確認：デバッグビルド
4. リリースビルド
RemoteJSでリモートブラウザのデバッグをする

# はじめに

Webサービスの開発をしていると、要件によっては様々なデバイス、ブラウザをサポートしなければならないことがあります。動作確認時や不具合の検証をする際は、それらのブラウザの開発ツールなどを使用してコンソール上のメッセージやDOMを確認することと思いますが、そのような手法が使えないケースも存在します。

モバイル端末における動作を確認したいけどケーブルが無い、検証対象のブラウザが機器に組み込まれたものである、などのパターンがそれに該当することでしょう。そして、そのような場合の動作確認は決して容易ではありません。SentryやRollbarといったバグトラッキングを使用して細かく情報を送信するという方法も考えられますが、インタラクティブな情報取得はできないため、何度もトライアンドエラーを繰り返すことになってしまう可能性もあります。

そこで解決策の1つになり得るのが [RemoteJS](https://remotejs.com) です。

# RemoteJSとは

RemoteJSは、動作検証をしたいブラウザとの間でセッションを確立することで、対象のブラウザでJSコードの実行といった操作を行うことが可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/8e1c4040-490b-8a20-efe2-be76c2aee61f.png)

RemoteJSを使用することで、以下のようなことが実現できます。

- ブラウザでの任意のJavaScriptコードの実行
- スナップショットの取得
- 発生したイベントの監視

また、これらの機能は無料で利用することが可能です。

それでは、以下のセクションで使い方を見てみましょう。

# 使い方
## セッションの確立

RemoteJSを利用するには、 [トップページ](https://remotejs.com/) の「Start Debugging」のボタンをクリックします。これによって、エージェントをインストールするためのコードが含まれたモーダルが表示されるので、必要なものをコピー&ペーストして使用します。

このモーダルでは、 `Tag`、`JavaScript`、`Bookmarklet` のいずれかを選択することが可能であり、それぞれ次のように利用します。

| 種類 | 用途 |
|---|---|
| Tag | Webページ(HTMLファイル)に埋め込むことが可能な `script` タグです。このscriptにより、必要なJavaScriptコードのダウンロードと実行が行われます。以下に示すいずれの方法も使えない場合などに有用です。 |
| JavaScript | 検証対象のブラウザのコンソールで実行するJavaScriptコードです。コードをコンソールから実行するだけなので、非常に簡単に検証を開始することができます。 |
| Bookmarklet | ブラウザのブックマークレートとして使用可能なコードです。 | 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/38425ccb-9484-20e4-268a-be6499f6aa20.png)
*モーダルの表示例*

## RemoteJSによるデバッグ

上述したいずれかの方法で検証対象のブラウザとのセッションを開始すると、RemoteJSのデバッグ機能が利用可能となります。ここではいくつかの機能を見てみましょう。

### JavaScriptコードの実行

RemoteJSの画面下部のエリアでは、任意のJavaScriptコードを実行することができます。例えば、以下のような `button` 要素の状態を確認したいとしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/7a924d1e-5265-79d4-0d87-889715c0826b.png)

そのために、以下の `querySelector` を実行して要素を取得してみます。

```javascript
document.querySelector('button.start-button')
```

すると、次のように対象のブラウザにおけるコードの実行結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/b41a6119-2701-b318-725d-6aae4e443e1d.png)

さらに、次のようなコードをRemoteJSから実行すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/823e839e-8362-2eeb-d87b-6518fa75ad83.png)

ブラウザ側の表示結果も変更されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/27b20271-f2f4-4d92-fd76-fa517f2e9417.png)

このように、RemoteJSを利用することで、ローカルブラウザのコンソールを使用した場合とほぼ同等のインタラクションが可能となります。これによって、特定のオブジェクトの値の確認や、任意のイベントをトリガーさせることもでき、問題の特定に役立ちます。

### スナップショット

RemoteJS上部のエリアからはスナップショットを撮影することも可能であり、リモートブラウザでの表示内容を確認することもできます。

# 最後に

この記事では、RemoteJSを利用することでデバッグが困難な端末、ブラウザでリモートデバッグする方法を紹介しました。通常の開発ツールや、バグトラッキングシステムを利用したトラブルシュートが最も一般的な不具合の原因究明方法となると思いますが、それらの手段が利用できない時の手段として、RemoteJSを選択肢に入れておくと良いかもしれません。
勉強記録　7日目 〜マクロで定義する関数より、inline関数を使おう〜 - Effective C++ 第3版 -

#　はじめに

Effective C++ 第3版の2項7ページから勉強していきます。
今回は、「マクロで定義する関数より、inline関数を使おう」についです。

# Effective C++ 第3版 - 2項　#defineより、const, enum, inlineを使おう -

## マクロで定義する関数より、inline関数を使おう

### マクロで定義する関数の問題点

 #defineを使って定義するマクロは、関数のように働きますが、関数呼び出しのオーバーヘッドがありません。(呼び出し時間が少ない)
しかし、#defineを使ってマクロを定義する場合、注意する必要があります。
以下に、#defineのよくない利用方法を示します。

```cpp
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b));
```

これは、与えられた2つの引数のうち大きい方を引数にして関数fを呼び出すマクロです。
注意点1つめとして、このようなマクロを書くときには、仮引数を丸カッコで囲まないといけません。
しかし、正しく丸カッコをつけても、次のようなコードが書かれれば、困ったことになります。

```cpp
CALL_WITH_MAX(++a, b);  // aが2回インクリメントされる
CALL_WITH_MAX(++a, b + 10);  // aが1回インクリメントされる
```

上のコードでは、関数fが呼び出される前にaが何回インクリメントされるかは、引数によって変わってしまいます。

なぜか？

```cpp
CALL_WITH_MAX(++a, b);  // aが2回インクリメントされる
```

では、マクロから関数fに与えられる引数は、

```cpp
(++a) > (b) ? (++a) : (b)
```

のようになります。
そのため、(++a) > (b) が True ならインクリメントが2回行われてしまう。

この問題を解決するためにインライン(inline)関数を用います。
インライン関数とは、「in line（行中に）」という言葉が示しているとおり、関数の中身をその部分に埋め込みます。
そのため、インライン関数は、呼び出しにかかる時間が普通の関数を短い利点を持つ。
マクロと違う点は、テキストが置き換わるわけではないということと、戻り値と引数に型があるということです。

インライン関数を用いて、先ほどの「与えられた2つの引数のうち大きい方を引数にして関数fを呼び出す」処理を書くと、

```cpp
inline void callWithMax(const T& a, const T& b) {
  f(a > b ? a : b);
}
```

のようになります。
このインライン関数を呼び出す処理は、

```cpp
callWithMax(++a, b);　 　　　// aが1回インクリメント
callWithMax(++a, b + 10);　 // aが1回インクリメント
```

のようになります。
インライン関数を用いることで、仮引数を丸カッコで囲む必要もなく、引数を複数回評価されるといった心配もなくなります。

以下に今回、勉強でしようしたコードと実行結果を示します。

### サンプルコード

```cpp
#include <iostream>

#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b));

void f(const int& x) { std::cout << __func__ << " : value = " << x << std::endl; }

template <typename T>
inline void callWithMax(const T& a, const T& b) {
  f(a > b ? a : b);
}

int main(int argc, char* argv[]) {
  std::cout << "2_inline_define.cpp" << std::endl;
  int a = 5;
  int b = 0;
  CALL_WITH_MAX(++a, b);  // aが2回インクリメントされる
  std::cout << "a : " << a << std::endl;
  std::cout << "b : " << b << std::endl;
  CALL_WITH_MAX(++a, b + 10);  // aが1回インクリメントされる
  std::cout << "a : " << a << std::endl;
  std::cout << "b : " << b << std::endl;

  std::cout << "\n############################################\n" << std::endl;

  a = 5;
  b = 0;
  callWithMax(++a, b);  // aが1回インクリメント
  std::cout << "a : " << a << std::endl;
  std::cout << "b : " << b << std::endl;
  callWithMax(++a, b + 10);  // aが1回インクリメント
  std::cout << "a : " << a << std::endl;
  std::cout << "b : " << b << std::endl;
}
```

### 実行結果

![2_inline_define.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367151/998c844a-f451-c83d-046b-ad0c3f2776c1.png)


## 参考文献

・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0
Xcode11.0の画面収録につまずいた

# はじめに
Xcode の シミュレータではターミナルで下記のコマンドを実行すると画面収録ができます。

```
xcrun simctl io booted recordVideo test.mov
```

しかし、Xcode11.0 で実行すると下記のようなエラーが表示されます:scream:

```
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=22):
Selected interface does not suport video recording.
Invalid argument
```

`simctl` コマンドについては下記の記事に詳しく書いてありました。

* [simctlコマンドを使ってみる](https://qiita.com/tamaki/items/02eb43253193b950b08f)

# 対応
## Xcodeのパスを確認する
複数バージョンの Xcode をインストールしていたのでとりあえず指定のパスが正しいか確認します。

ターミナルで下記コマンドを実行します。

```
xcode-select -p
```

他の Xcode が指定されていた場合は下記コマンドでパスを修正します。

```
sudo xcode-select -s <Xcodeのパス>
```

もう一回実行！！

```
xcrun simctl io booted recordVideo test.mov
```

再び同じエラー:scream:

## UUIDを指定してみる
画面収録のコマンドは下記のような構成になっています。

```
xcrun simctl io <対象のシミュレータのUUID> recordVideo <保存先パス> 
```

`booted` にしていたところを UUID を指定してみます。

ターミナルで下記コマンドを実行し、起動中のシミュレータの UUID を取得します。

```
xcrun simctl list | egrep '(Booted)'
```

結果は下記のようなもの

```
iPhone 11 Pro Max (AAAAAAAA-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Booted) 
Phone: iPhone 11 Pro Max (AAAAAAAA-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Booted)
```

UUID を指定して実行！！

```
xcrun simctl io AAAAAAAA-XXXX-XXXX-XXXX-XXXXXXXXXXXX recordVideo test.mov
```

はい、同じエラー:scream:

## リリースノートを見てみる
Xcode のリリースノートを確認してみます。

発見！！！

[Xcode11リリースノート](https://developer.apple.com/documentation/xcode_release_notes/xcode_11_release_notes#3319215)

ここに

>Video recording of the iOS 13, tvOS 13, and watchOS 6 simulator through xcrun simctl io <UDID> recordVideo returns an error instead of recording video. (50625716)

とあります。

iOS13 では無理な模様！！iOS12 とかのシミュレータならいけるのかもしれません。（通信環境が劣悪なので他のシミュレータをダウンロードできず確認できませんでした...）

# 結論
Xcode11.0 では iOS13 のシミュレータで画面収録はできない模様。

Xcode11.2.1 ではできたのでバージョンを上げるか Quick TimePlayer を使いましょう！！ 

# さいごに
リリースノートって大事ですね:satisfied:

今まであんま見たことなかったんですがこれからはちょこちょこ確認するようにします...

とりあえず今回のように画面収録できなかった時は Quick TimePlayer と [PicGIF Lite](https://apps.apple.com/jp/app/picgif-lite/id844918735?mt=12) で GIF を作成してるのですが皆さん Qiita に GIF あげる時とかなに使ってるんですかね？
大学の研究室で Qiita organization を作成した話

この記事は「[DSL Advent Calendar 2019](https://qiita.com/advent-calendar/2019/muroran-it-dsl)」の 4 日目の記事です。

Organization を検索した限り，当時初めて[^1]の大学の 1 研究室で [Qiita Organization](https://qiita.com/organizations) を作成した話です。

[^1]: 当研究室調べ。


# TL;DR
[Qiita:Support: Organizationの作成方法](https://help.qiita.com/ja/articles/qiita-org-create) を参考に進めるだけです！
大学の研究室でも無事作成できました。


# きっかけ
元々，研究室では技術的な内容を共有するために [Knowledge](https://information-knowledge.support-project.org/ja/) を導入していました。
しかし，この研究室の特徴として「学生によって研究のドメインが違う」ということがありました。
そのため，「パソコンのセットアップやインストール記事以外はほとんどアクセスがなく，それらの記事も一年に一回や二回しか使わない」，「情報が更新されない」，「大学卒業後は閲覧できない」，「大体，何かしようと思ったら Knowledge 調べても見つからない」という状態でした。
Knowledge にある内容でもみんなまず初めにするのはウェブ検索という状態です。
改めて確認したときには年間投稿数が5未満…。
そりゃ，どんどん離れていきます。

課題解決のためには，「ウェブ検索でヒットする」「書く意欲を削がない」「書くきっかけを作る」「定期的に支払いが発生しない」ものである必要があります。
しかも，可能なら研究室の記事が一覧で見られると幸せです。
そこで，Qiita Organization を作成することになりました。


# なぜ Qiita Organization だったのか
Qiita Organization であれば，運用の上ではアカウントの紐付けと解除以外，メンテナンスフリーであり，ウェブに公開が原則のためウェブ検索でヒットします。
ウェブ公開されているため，大学卒業後も参照でき，研究室外の方からの反応がもらえます。
また，Qiita には編集のリクエストやコメント機能，トラックバック的な機能などがあり，情報がアップデートされやすく，新しい情報に触れやすくなります。


# 実際の登録フロー
1. 事前調査
2. 指導教員に確認をとる
3. Qiita に問合せ，登録を行う
4. 研究室のメンバーを紐付ける

## 事前調査
Organization の登録団体の確認や，登録方法を確認しました。
登録されている団体は以下の通りでした。

1. 企業
2. 企業の部署（研究所）など
3. 大学

大学の研究室での登録は確認できないという結果に…。
しかし， [Qiita:Support: Organizationの作成方法](https://help.qiita.com/ja/articles/qiita-org-create) を確認したところ，そこまで厳しい条件ではなかったし，組織の単位に関する条件はなかったので，とりあえず進めることに。

## 指導教員に確認をとる
現状のシステムの新規アカウント発行を終了し，新しく Qiita 上で研究室名を公開して活動することになるので，まずは教員に確認を取りました。
これは難なくクリア。

## Qiita に問合せ，登録を行う
教員からの OK が出ましたので，[Qiita:Support: Organizationの作成方法](https://help.qiita.com/ja/articles/qiita-org-create) に従い進めていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59163/f33618ce-3663-2b58-0750-5fed32c5f193.png)

送信から 1 時間程度で登録の際の条件と必要なもの（サポートページの内容と同様），ロゴ・ヘッダー画像の送信方法とOrganization 入稿用の Google Form のリンクが送られてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59163/1e09293b-0c3d-3b77-5a59-094394c0b436.png)

今回は 2 日ほどで無事登録されました！
Organization のメンバー追加の方法などもメール連絡くるので，それに従い進めるとできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59163/564183b2-de4a-0cd0-adbf-989aa33a1ab5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59163/fb29bcf5-1788-8896-bf96-bd8543b7ef05.png)

その後，スラグの変更をお願いしましたが，こちらも 1 時間程度で変更していただきました🙇　（スラグは Qiita の方で決められ，設定から変更できないです）


# 思わぬ効果
突然投稿が爆発的に増えるわけではないですが，今回アドベントカレンダーに参加することになりました。
これにより投稿する文化が根付くといいですが，もう卒業間近な件。


# 今後の課題
メンバーが卒業した際，紐付けを解除すると Organization ページから消えてしまいます。
しかし卒業後も残しておくと，Organization ページに卒業後の投稿も反映されます。
現状としては，卒業後も残しておき，Organization ページに多少ノイズが入っても研究室としての知見は取っておこうと思っています。
（残しておくことで縦のつながりが生まれると嬉しいですが，諸般の都合で難しいでしょう…

あと，例えばですがパソコンのセットアップ記事であれば，「ラボ内 Wiki のパスワードページのリンクとかを貼りたいけど，メンバー以外には関係ないため一般の方からはリンクを見えなくしたい…！」みたいなことはできないため，閲覧者側が気づいて Wiki に当たる必要があります。
現状としてはラボ内 Wiki からの片方向リンクで諦めているので解決できると嬉しいです。
gmusicapiの認証サンプル

完全に自分用の技術メモ(´・ω・｀) 

[gmusicapi](https://unofficial-google-music-api.readthedocs.io/en/latest/)はPythonからGoogle Play Musicを操作するGoogle非公認のライブラリです。Google Play Musicを操作するにあたっては認証が不可欠なのですが、その認証APIがやや複雑というか、少なくとも自分は時間を溶かしたので、サンプルを供養がてらQiitaに残しておきたいと思います。__ちなみに稼働を確認した環境については、Pythonのバージョンは3.7、gmusicapiのバージョンは12.1.1になります。__

```python
import gmusicapi

# 前提: このファイルは初回起動時には存在しない。
CREDENTIAL_FILE = '/path/to/mobileclient.cred'

api = gmusicapi.Mobileclient()
if not os.path.exists(CREDENTIAL_FILE):
    api.perform_oauth(CREDENTIAL_FILE)
api.oauth_login(gmusicapi.Mobileclient.FROM_MAC_ADDRESS, CREDENTIAL_FILE)
```

# 初回起動時に必要な作業について

初回起動時、すなわち`CREDENTIAL_FILE`が存在しない場合、次のようなメッセージがコンソール(標準出力)に表示されると思います (セキュリティ上の関係から、一部マスキングしています)

```
Visit the following url:
 https://accounts.google.com/o/oauth2/v2/auth?client_id=XXX&redirect_uri=XXX&scope=XXX&access_type=offline&response_type=code
Follow the prompts, then paste the auth code here and hit enter: 
```

このURLではアクセスコードの発行を行います。ブラウザを起動し、処理を進めていくと、最終的に以下のような画面でアクセスコードが発行されます。このトークン文字列をコピーして、先ほどのコンソールに入力すると、処理が先に進んでいくはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/e216451b-7ada-671b-2d21-202badda5daa.png)

# 解説

初回起動時、つまり`CREDENTIAL_FILE`が存在しない状態で、サンプルを実行すると、`api.perform_oauth`が実行されます。上記の対話型メッセージを出力しているのがこのAPIで、標準入力経由でアクセスコードを受け取ると、第1引数のファイル(ここでは`CREDENTIAL_FILE`)に情報を記録します。

`api.oauth_login`は第2引数のファイル(ここでは`CREDENTIAL_FILE`)から情報を受け取り、認証を実施します。初回起動以降、つまり`CREDENTIAL_FILE`が存在する状態では、`api.perform_oauth`は実行されず、`api.oauth_login`が直接実行されますが、認証情報は初回起動時に`CREDENTIAL_FILE`に記録済み。したがって、初回起動以降は、上述したようなブラウザ作業を実施する必要はありません。
【Heroku】デプロイ時の"Missing encryption key to decrypt file with."を乗り越える

はじめてのHerokuデプロイ。
下記のQiita記事にならって進めていました。

[【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】]("https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39")
（丁寧にまとめていただき、本当にありがとうございます。）

おかげさまで順調に進み、デプロイ間近でわくわくしていたところ以下のエラーと遭遇しました。

```ターミナル
Missing encryption key to decrypt file with. Ask your team for your master key and write it to ~~~~~~/config/master.key or put it in the ENV['RAILS_MASTER_KEY'].
```
要するに、"復号するためのキーが見つからない"ということです。
# なぜ？
と、思いましたが、たしかにそうですね。

GitHubと連携してデプロイを試みていましたが、リモートリポジトリに`master.key`はありません。通常はgitignoreの監視下なのでGitHubにはあがっていないはずです。そのため、これを別途読み取らせる工程が必要です。

# 解決策
ということで、ちょっと迷いましたが一手で解決することができました。

```ターミナル
heroku config:set RAILS_MASTER_KEY=`rake secret`
```

以上のコマンドを実行したあとで、ようやくデプロイが通るようになりました。
# 参考
stackoverflow：[Ask your team for your master key and put it in ENV[“RAILS_MASTER_KEY”] on heroku deploy]("https://stackoverflow.com/questions/44298334/ask-your-team-for-your-master-key-and-put-it-in-envrails-master-key-on-herok")
上の質問と回答をもとに解決することができました。ありがとうございます。
# さいごに
以上、初心者による初心者のためのQiita…でした。解決策がシンプルすぎて戸惑ったので残しておきます。今後はじめてデプロイに臨まれる方の参考になれば幸いです。
クリスマスといえばxsnow

初めて，Qiitaに記事をアップしてみます．
#初めに
なぜ今xsnowを紹介しようと考えたかというと，20年前のワークステーションでは処理が重く動作せず，研究室で動かすと叱られたものです．しかし，最近のPCであれば動かしても問題ないのではないかと考えます．
また，仕事の中で雪のシミュレーションが求められ，そういえばxsnowはどんなコードなのだろうと思い，今回簡単にまとめることにしました．
FreeBSDとは直接関係はありませんが，インストールでPortsから行なうことができることなど参考になればと考えます．
#インストール
今回は，コードも確認したため，portsを使いました．
次のパスにMakefileがありますので，makeします．
<div>
/usr/ports/x11/snów
</div>
#使用方法
使用方法は，manコマンドで全てのオプションなど確認いただきたいのですが，今回は少しだけ紹介します．
<div>
-snowflakes 降雪する雪の量を設定します．1000が最大です．
-santa サンタの表示サイズを設定します．0から3までの数字を入力します．
-santaspeed　サンタの移動速度を設定します．
</div>

#コードで勉強になること
コードは1500行程度なので比較的簡単に確認することができます．

まず，ヘッダファイルのxsnow.hから見ます．

最初に，定数の宣言があります．例えば，MAXSNOWFLAKESの値を変更すれば表示する雪の数を多くすることができると考えます．

>define MAXSNOWFLAKES 1000     /* Max no. of snowflakes */
>define INITIALSNOWFLAKES 100  /* Initial no. of snowflakes */

雪の粒子の構造体を次のように作成しています．座標だけでなく．xStep，yStepにより速度量も持っています．そして雪が有効なのか表示されているのかなどのフラグをもっています．

>typedef struct Snow {
    int intX;
    int intY;
    int xStep;    /* drift */
    int yStep;    /* falling speed */
    int active;
    int visible;
    int insnow;
    int whatFlake;
} Snow;

そのほかリソースなどの宣言が書かれています．

次に，snow.cを見ます．
最初Xウィンドウ表示に関わる処理がありますが，今回はスルーします．
次の箇所で，最初に雪の座標の初期化を行なっています．
>for (i=0; i<maxSnowflakes; i++) InitSnowflake(i);

そして，次の箇所でサンタの初期化も行います．
>ResetSanta();

while(!done)の無限ループの中で，次のように雪の座標計算とサンタの座標計算を行い，
その後画面に表示するという単純なプログラムです．

>for (i=0; i<maxSnowflakes; i++) UpdateSnowflake(i);

>if ((RunCounter % SantaUpdateFactor) == 0) UpdateSanta();

特に，UpdateSnowFlake関数内の処理は業務で参考になりそうです．

#最後に
クリスマスまでまだ日はありますが，xsnowを動かしてみてはいかがでしょうか．
M5Stackプロジェクトに貢献してみた

何故か取れてしまった2019年M5Stackアドベントカレンダー1日目！

というわけでM5Stackアドベントカレンダーが始まりました！

今回は、M5Stackプロジェクトに貢献してみた話をしてみようと思います。

# 事の発端
今年の7月にM5Stackを触る回を実施した時に、Arduinoを使ったことがある人が少なかったので、UIFlowを使って遊んでみることにしました。

UIFlowは、ブロックプログラミングとMicroPythonでコードが書ける環境で、M5Burnerでイメージを書き込むことで作業ができるようになります。

UIFlowでのプログラミングは私も初めてだったのでドキュメントを眺めつつ作業をしていたのですが、眺めていると幾つかの画像が表示されていませんでした。

言語を切り替えてみると、表示されたりされなかったりしたたため、正しいパスに直してプルリクエストを作成して見ました。

内容は JPG を　jpg に直しただけというシンプルなものでした。

https://github.com/m5stack/UIFlow_doc/pull/2

![スクリーンショット 2019-12-01 23.16.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12680/54aa67ce-d14e-7427-bafe-6cfeaf9131cc.png)

というわけで、無事マージされてコントリビュートすることが出来ました。

![スクリーンショット 2019-12-01 23.18.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12680/0f73e4ba-8dc9-087e-1dff-d42e36b5de2a.png)


# まとめ

準備していたおもちゃがWindowsアップデートで間に合わなくなったので、ちょっとだけ世界を良くしてみたという話をしてみました。

M5Stackは今なお開発が進み続けているプロジェクトなので、こういう細かいところでの貢献をするチャンスがたくさんあると思います。

皆さんも何か見つけたらコントリビュートしてみてはいかがでしょうか。