OmniAICreator/Qiita-1.07M huggingface dataset:
不動産テックニュースを追うためのクローリング情報収集術

この記事は、[LIFULLその2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/lifull2)の7日目の記事です。

私は[LIFULL HOME'S](https://www.homes.co.jp/)のデータ分析の部署で働いています。そこできちんとした価値を提供するためには、「同じものが提供してもっと楽に実装したい」とか「このデータってこんな目的に利用できるんじゃないか」とか議論するには、ある程度は不動産業界の情報を追う必要があると感じています。

また、最近公開された最新版の[不動産テックカオスマップ](https://retechjapan.org/retech-map/)を見ても分かる通り、数多くの不動産テックサービスが現れてきています。全てではないにしても、ある程度は知っておくと便利です。例えば、いくつかのVRサービスが現れてきているとか。

いくつかIRサイトの更新通知等、いくつかの通知用のスクリプトを使い分けて、少しずつ「気付ける範囲」を広げています。そのクローラーの運用ノウハウ的なものを公開します。

似たような記事も少なく私自身「他の同業界のエンジニアはどう情報収集してるんだろう？」と不思議に思っていたので、同じことを感じているエンジニアの方もいるはずだと思って書きました。


## 定点観測するサイト

IRサイトや各種ニュースサイトを定点観測していて、ニュース一覧ページをクロール（RSS等のフィードが存在する場合はそちらを）クロールして通知しています。

詳しくはこちらの記事を読んでください。

https://qiita.com/ninomiyt/items/bf6c2e344daeaf5bf786

**不動産テック専門メディア SUMAVE**

https://www.sumave.com/

> スマーブは国内外の不動産テック（不動産とテクノロジー）の最新事例やニュースを幅広く知ることができるニュースメディアサイトです。

[リブセンス](https://www.livesense.co.jp/)さんが運営している国内外の不動産テック企業を扱っているWEBメディアです。自分の知らない企業が扱われていて、新しく知ることも多いです。

Twitterのフォロワーも100人弱程度しかいないのでちょっとビックリしています。

https://twitter.com/sumave_news



**市川 紘(Ko Ichikawa)さんのmedium**

https://medium.com/@coichikawa

> 事業開発・ファイナンス担当VP＠シリコンバレーの不動産テック企業。前職はリクルートのSUUMOで、営業→プロダクト→経営企画マネージャー→新規事業開発部長を担当。

海外の不動産テック。不動産分野は海外（特にアメリカ）のほうが進んでいると言われていて、社内の話を聞いて「ああ、海外で既に成功事例があって日本に輸入したがってるんだな」と気づくことも多いです。

**各社WEBサイトのIR情報**

これはちょっとここに書くには卑怯かもしれませんが、一番スピーディーに情報をキャッチすることができます。ついでに社内チャットに通知して広報しています。現在40~50社程度を通知しています。

競合サービス等の情報です。簡単な設定でRSSやサービスからチャットに通知できるようにして地道に追加していっています。自分の周囲で話題になっている企業や団体を、地道に追加していっています。

<img width="840" alt="スクリーンショット 2018-12-09 17.35.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/127762/a0e3fd6d-2b5f-dcaa-9cf9-01f0e7b662d8.png">

元々は個人用に使っていたのですが、当時の上司に勧められてチャット部屋を作って公開したところ、ちょっとした評判となりました。現在100人を超える大所帯な部屋になっていて、「このサービス気になるね」みたいなコメントや解説を入れてくれる方もいて勉強になっています。


## 各種ニュース媒体

各種ニュース媒体のフィードから、不動産関連のニュースだけフィルタリングして通知しています。一部を紹介するとこんな感じです。

* [日本経済新聞 電子版](https://www.nikkei.com/)
* [PR TIMES](https://prtimes.jp/)
* [CNET JAPAN](https://japan.cnet.com/)
* [TechCrunch Japan](https://jp.techcrunch.com/)
* [ダイアモンド・オンライン](https://diamond.jp/)
* …

これらのサイトは不動産関連以外のニュースも扱うため、膨大な量になります。そのためタイトル文字列でフィルタリングして使っています。

不動産関連であれば「```["不動産", "空き家", "マンション"…]```など、不動産関連の単語が含まれているかどうか」という簡単な判定で、それなりに精度良くフィルタリングできます。運良く単純な条件で判別できましたが、もし他の業界であればさらなる工夫（例えば機械学習関連だと新しい手法やサービスの辞書の整備や判定方法の更新などの作業）が必要かもしれません。

## GoogleアラートやSNS

各種SNSで話題になっている不動産関連ニュースも通知しています。こちらは主に定点観測サイトを追加するために運用しています。

こちらは「タイトルとURLをリツイート数の多い順にソート」して、ある程度俯瞰できるように工夫しています。


## 最後に

いかがだったでしょうか？

ただ、不動産が本業の弊社メンバーはさらに業界の動向をキャッチアップして「こういうサービスが必要なんじゃないか」と日々考えているのに対して、私はそこまで追う時間はなく、最低限議論するために「こういうサービスもあるんだ」という程度しかキャッチアップして（でき）いません。（プログラミングや技術の勉強も忙しく…っていうとちょっと言い訳がましいですが）

あと、（社内外問わず）経営層の方と話すると「その情報、一応公開されてるけどこんなのすみっこにしか書かれてないやつどうやって気づいたの？」って思うことありますよね。あれってどうやってるんでしょうか？

もし他に「自分はこうキャッチアップしてるよ」「この媒体抜けてるけどオススメだよ！」などがあればコメントください！
Firebaseの本番と開発環境の用意

# はじめに

アプリエンジニアの@daisuke0131と申します。
qiita投稿久しぶりで緊張しています。
この記事は、[Firebase Advent Calendar 2018](https://qiita.com/advent-calendar/2018/firebase) 9日目の記事になります。

前回の記事は、@takuchalleさんの[Firebase Hosting で自動で古いバージョンを削除する(今のところ)最善の方法](https://blog.takuchalle.me/post/2018/12/08/delete_old_vresions/)でした。私はまだFirebase Hosting触っていないですが今度使ってみようと思います。

私は、本業ではアプリ開発(ios/android)をメインでやっているエンジニアです。アプリエンジニアの為のFirestore入門本、[基礎から実施までCloud FirestoreによるiOSアプリ開発](https://daisuke0131.booth.pm/items/1034900)を執筆したので興味ある方は是非買ってください！一冊手元に置いておくと便利だと思います。

書籍を色々な方達に読んでもらったのですが、全体的には分かりやすいというフィードバックをもらっています。アプリ開発も楽しいですが、執筆も楽しいですね。分かりやすい入門書を書くことでCloud Firestoreの普及に貢献できれば嬉しいです。
今回は、フィードバックの中で追記して欲しいと要望のあったiOSアプリ開発時の本番と開発環境の用意方法に関する記事を書きたいと思っております。一般的なFirestoreのセットアップに関する詳細は書籍を参照してください。

# Firebaseとクライアント環境の本番と開発環境の用意

Firebaseのプロジェクトですが、以下にアクセスして
https://console.firebase.google.com/
本番用と開発用のプロジェクトをそれぞれ作成します。

通常プロジェクト作成後は、iOSアプリを作成するボタンよりGoogleService-Info.plistを取得してクライアント側のiOSプロジェクト内に配置して、次の初期化処理を呼び出すことでFirebaseのクライアント側セットアップが完了します。

```swift:AppDelegate.swift
FirebaseApp.configure()
```
引数なしのconfigureを呼び出すことでFirebase SDKは"GoogleService-Info.plist"を探して初期化を完了させます。

今回は、本番用と開発用のプロジェクトを分けたいので、開発用のプロジェクトで作成したplistを"GoogleService-develop-Info"として用意します。iOSアプリ開発では、プリプロセッサマクロのDEBUGオプションで本番、開発環境を分けることが多いと思いますのでそちらを使用してplistの読み込み先を変更します。コードにすると次のようになります。

```swift:AppDelegate.swift
#if DEBUG
    let filePath = Bundle.main.path(forResource: "GoogleService-develop-Info", ofType:"plist")
#else
    let filePath = Bundle.main.path(forResource: "GoogleService-Info", ofType:"plist")
#endif
let options = FirebaseOptions(contentsOfFile:filePath!)
FirebaseApp.configure(options: options!)
```
Firebaseとクライアント側の環境の分け方は以上で完了です。

# Firebase CLIの本番と開発環境の用意
次にFirebase CLI環境の本番と開発環境の用意方法についてです。
Firebase CLIはFirebase上のセキュリティルール、インデックス、Cloud Functionsなどのデプロイを簡易にするツールのことです。開発環境は次のinitコマンドを実行することで作成されます。

```
$firebase init
```
初期化コマンド実行後には.firebasercが生成されています。

```config:.firebaserc
{
  "projects": {
    "default": "firestoresample-xxxx"
  }
}
```
こちらのファイルを次のように書き換えることで本番(release)と開発(develop)環境を切り替えられるようになります。yourapp-production,yourapp-developはfirebaseのプロジェクトIDをそれぞれ設定してください。

```config:.firebaserc
{
  "projects": {
    "release": "yourapp-production", #本番環境
    "develop": "yourapp-develop" #開発環境
  }
}
```
上記の設定をしたあとに次のようにuseコマンドを実行することで本番、開発環境の切り替えが可能になります。

```
$ firebase use develop #開発環境に切り替える
Now using alias develop (yourapp-develop)
$ firebase use release #本番環境に切り替える
Now using alias release (yourapp-production)
```
以上でfirebase CLIで作成したコードを本番、開発環境で切り替えられる環境が作成できました。とっても簡単ですね。firebase、だぁーいすき！（ハズ◯ルーペ風）

#おわりに
書籍の執筆後に開発環境について聞かれることが多かったので、Advent Calendarの締め切りを利用して記事にさせてもらいました。Firestoreの勉強を初めて本番運用まで考え始めた段階で疑問になるところだと思うのでどなたかのお役に立てれば幸いです。こちらの内容は、Boothで販売中の[基礎から実施までCloud FirestoreによるiOSアプリ開発](https://daisuke0131.booth.pm/items/1034900)にも加筆してアップデートしたいと思っています。

明日は、@gremitoさんのFirebaseとUnityについて何かです。よろしくお願い致します。
google-services.jsonをproductFlavorsごとに切り替える方法

業務中に使うことがあったので、その備忘録。

### やりかた

`build.gradle`に以下のように記載する

```
    // GoogleServices.jsonの置き換え
    gradle.taskGraph.beforeTask { Task task ->
        if (task.name ==~ /process.*GoogleServices/) {
            applicationVariants.all { variant ->
                if (task.name ==~ /(?i)process${variant.name}GoogleServices/) {
                    def folderName = "置き換えたいgoogle-services.jsonがおいてあるfolder名"
                    // task.name.consains("xxx")でflavors名を取得して書き換えれる                    
                    copy {
                        from "${folderName}"
                        into "."
                        include "google-services.json"
                    }
                }
            }
        }
    }
```

これで`productFlavors`が切り替わるごとに`google-services.json`を置き換えることができる
MacでJupyter Notebook(Anaconda)を利用する手順

# はじめに
データ分析を勉強する際に、Jupyter Notebookを使用したので、環境構築(anaconda)の手順となります。

**Jupyter Notebookとは**
プログラムを実行し、実行結果を記録でき、主に数値計算・データ解析を行うときに使われるツール

## pyenvのインストール
```
# pyenvのインストール
brew install pyenv
````
**pyenvとは**
pythonのバージョンを簡単に切り替えることができるようにしてくれるツール
プロジェクトのワークスペースごとにpythonのバージョンを切り替えることが可能

## .bash_profileの修正
pyenvのPATHを通す。
.bash_profileに下記を追加

```
export PYENV_ROOT=\${HOME}/.pyenv
export PATH=\${PYENV_ROOT}/bin:\${PATH}
eval "\$(pyenv init -)"
```

保存したら、bash_profileの内容を適応
`source ${HOME}/.bash_profile`

## anacondaのインストール
```
# インストールするanacondaのバージョンを確認
pyenv install --list

# anacondaのインストール
pyenv install anaconda3-5.2.0
```

**anacondaとは**
Pythonディストリビューション
「Python本体」＋「各種データサイエンスライブラリ」などを色々まとめたPythonパッケージ
https://www.ossnews.jp/oss_info/Anaconda

## anaconda3利用の設定
```
# インストール確認
pyenv versions

# anaconda利用の設定
pyenv global anaconda3-5.2.0
```

- pyenv global
全体で利用するバージョンの設定

- pyenv local
特定のディレクトリ内のみバージョンを切り替えたいときに使える。
pyenv localが実行されると、実行されたカレントディレクトリに.python-versionというファイルが作成される。これはglobal設定よりも優先される。

# jupyter notebook起動
```
# 任意のディレクトリを作成
mkdir notebook

# 移動
cd notebook

# jupyter-notebook起動
jupyter-notebook
```

この画面が起動できれば、正しくインストールできています。
<img width="879" alt="スクリーンショット 2018-12-09 18.00.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/226008/5089d6f7-8ed8-e1b7-3c56-af6ba1a825e9.png">
ClickUp 高度なプロジェクト管理にも使える素晴らしいPJ管理ツール

![roberto-nickson-g-715417-unsplash.jpg](https://qiita-image-store.s3.amazonaws.com/0/300876/9632adf8-153c-6ddf-857a-bf6dc70d3c6a.jpeg)
https://unsplash.com/photos/5PQn41LFsQk 🎁 Thanks to [@rpnickson](https://twitter.com/rpnickson) for making this photo available freely on [@unsplash](https://twitter.com/unsplash)


:christmas_tree: :santa: Merry Xmas




プロジェクト管理ツールの中では久々(5年ぶりくらいでしょうか)に期待の大型ルーキーが現れました。

その名は ClickUp (クリックアップ)

![](https://qiita-image-store.s3.amazonaws.com/0/300876/bba01e4e-fe7d-e6c3-4814-9fb00f5a44de.png)

ClickUp | #1 Productivity Software
https://clickup.com/

実は既にClickUpについていくつか投稿済みですので、今回は改めてそれらをまとめてClickUpの紹介と致します。




# ClickUp


- [ClickUp というPJ/タスク管理ツール \- Qiita](https://qiita.com/szf/items/b5f2239a3880f030b2bf)
- [ClickUp におけるユーザー/チーム/ワークスペース等とタスクの関係 \(類似製品との比較あり\) \- Qiita](https://qiita.com/szf/items/0bdde46aa79ee06eac73)
- [ClickUp 公式アプリ / 他サービスとの連携 \- Qiita](https://qiita.com/szf/items/082abe049442bc79d17d)
- [ClickUp を本気で利用すべきか 長く使えるだろうか \- Qiita](https://qiita.com/szf/items/99d484554c49147a053c)
- [Asana\(Free plan\) から ClickUp \(Free\) への移行を検討する際の考慮点 \- Qiita](https://qiita.com/szf/items/312e177392b8a34f4d40)
- [ClickUp におけるガントチャート \- Qiita](https://qiita.com/szf/items/c4623a35d6c535d7ef4a)



Qiita tag: [ClickUp \- Qiita](https://qiita.com/tags/clickup)
シクシク素数アドベントカレンダー sed 編

# はじめに
同日公開の[合成数列の和アドベントカレンダー sed 編](/angel_p_57/items/f54b72e1ab5cae78207b)から色々流用して組みましたので、詳しくはそちらもご覧ください。
なお、こっちにはポエムはありません。

# ルール

* 数値に4か9を含む素数をシクシク素数と呼ぶことにします
  * 19とか41とか149とか。
* 標準入力として正の整数 N を与えたら N 番目までのシクシク素数を半角カンマ区切りで標準出力してください
  * 例 N = 9 の場合、`19,29,41,43,47,59,79,89,97`
* N は最大で 100 とします

# ソース

```sed:prime49.sed
# 数値を同じ文字数のXに変える
:Ln2x
 s/$/  9z8z7z6z5z4z3z2z1z0/
 s/^(.)(.* .*) [^ ]*\1([^ ]*)$/\2\3/
 s/X/XXXXXXXXXX/g
 y/z/X/
 /^ /!b Ln2x
s/[^X]//g
# 素数判定用の Y の塊と、数値の0～9をa～jに変換した文字列を用意
s/.*/Y & b/
:Lmain
 # 2加算処理
 s/^/YY/; T
 s/ (j*)j$/ b\U\1\Lb/; t Lup
 s/([^ j])(j*)j$/\U\1\2\Lb/; T Lnoup
 # 繰り上がり有り
 :Lup
 y/ABCDEFGHIJ/bcdefghija/
 b Lpost
 # 繰り上がり無し
 :Lnoup
 s/.$/\U&/; T
 y/BDFH/dfhj/
 :Lpost
 # 4,9 ( 対応する e,j ) の有無をチェック
 /[ej]/! b Lmain
 # 3以上の奇数で試し割りして素数判定
 s/YYY/YYY /
 :Ltry
  T; s/^(Y+) (\1+ )/\1\2/; t Lmain
  s/ YY/YY /
  /^(Y+) \1{4}/b Ltry
 s/ //
 # ホールドスペースに行毎追加
 H
 # 指定の個数たまるまでループ
 T; s/XX/X/; t Lmain
x
s/[XY ]//g
s/\n//
# 最後に数字に戻す
y/abcdefghij\n/0123456789,/
# ここで出力
```

# 出力例

```shell-session
$ sed -rf prime49.sed <<< 2
19,29
$ sed -rf prime49.sed <<< 10
19,29,41,43,47,59,79,89,97,109
$ sed -rf prime49.sed <<< 100
19,29,41,43,47,59,79,89,97,109,139,149,179,191,193,197,199,229,239,241,269,293,347,349,359,379,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,509,541,547,569,593,599,619,641,643,647,659,691,709,719,739,743,769,797,809,829,839,859,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1019,1039,1049,1069,1091,1093,1097,1109,1129,1193,1229,1249,1259,1279,1289,1291,1297,1319
```

# 解説
大体[合成数列の和アドベントカレンダー sed 編](/angel_p_57/items/f54b72e1ab5cae78207b)と似たようなことをやっています。

ただし、こちらは和ではなく抽出が主目的です。
そこで、`YYYYY`→`5`のような、文字列の長さ→数字の変換を毎回行うのではなく、別途数字のカウントアップを実装することにしました。それにより4,9が含まれているかどうかの判断を先に行います。

基本的なアイデアはこうです。

* 0～9の代わりにa～jの文字を使う
* カウントアップに伴い影響を受ける桁を大文字化し、後の変換対象を識別する
    * 繰り上がりがある場合、例えば12999→13001では`bcjjj`→`bdaab`になりますが、このように変換を行います
        * `bcjjj`
        * →`bCJJb`(最下位の変換+影響範囲の大文字化)
        * →`bdaab`(yコマンドによるA～I,J→b～j,aのスライド)
    * 繰り上がりがない場合、末尾のみを大文字化し、そののち+2相当の変換を行う ( yコマンドによるB,D,F,H→d,f,h,jのスライド )
* 繰り上がりにより桁数が増える場合、先頭に 0 に相当する a を予め追加しておく


なお、a～j の表現そのままホールドスペースに追加していきますので、最後に数字に戻してから出力します。

# 性能問題
ところで、sed の用いるExtended-REのエンジンがそれほど速くない上に、この問題では最大1319の素数判定を行うため、素数判定のループ回数が結構嵩みます。
…ということで、今回の実装では、入力100の時手元のPCで25秒、[ideone.com](ideone.com) でも9秒近くの時間を要しました。

まあ、高速化するだけなら、( 最大の素数が1319と分かってることもあり ) 色々手はあるのですが、実装の分かり易さを取り、今回は見送りました。

興味のある人は、色々と試してみても面白いかもしれませんね。
Rails プロジェクトでファイル保存時に自動的に rubocop --autocorrect してもらおう

この記事は、[グロービス Advent Calendar 2018](https://qiita.com/advent-calendar/2018/globis) の9日目の記事です。

こんにちは。3月から Globis の末席を汚しております motchang と申します。SAML とか OAuth2 とか OpenID Connect とかのサンプル実装の記事を書いていたのですが、ネタが被っていることに気が付いてしまったので軽い Tips 的な内容で失礼します。

### はじめに

みなさんの担当されている Rails プロジェクトには Rubocop が導入されているでしょうか？ Globis のプロジェクト Rails プロジェクトにはもちろん全プロジェクトに Rubocop が導入されており、CIで違反を検出する仕組みが動いています。

エディタの設定をすればインラインでスタイル違反を表示することが可能ですが、 go fmt を知ってしまっている我々にとっていちいち rubocop の警告に合わせたコードを書いたり、または手動で rubocop を実行したりスタイルを合わせるなんて世界には住みたくないですね。ですので、ファイルを保存するついでに `rubocop --autocorrect` をエディタにやってもらいましょう。

### パッケージのインストール

みなさんお使いのパッケージマネージャがあると思うので、ここでは一般的な方法だけ。パッケージマネージャに melpa を読み込ませます。

```elisp:init.el
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-initialize)
```

あとは `M-x package-list-packages` して rubocopfmt パッケージをインストールしましょう。

<img width="707" alt="スクリーンショット 2018-12-09 16.12.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/9811/7ef13e1f-6e17-a45c-6ca1-c15fe21fe100.png">

### 初期設定

インストールが終わったら `init.el` に 以下の hook を登録して、`M-x eval-buffer` しましょう。

```elisp:init.el
(add-hook 'ruby-mode-hook #'flymake-mode)
(add-hook 'ruby-mode-hook #'rubocopfmt-mode)
```

この状態で ruby のファイルを編集して `save-buffer` すると以下のコマンドが実行されます。開発中に違反すると思われる Lint/Debugger などのルールがあらかじめ無効になっているのがニクいですね。

```bash
bundle exec rubocop --stdin identity_provider_sample.rb 
                    --auto-correct 
                    --format emacs 
                    --except
                    Lint/Debugger,Lint/UnusedBlockArgument,Lint/UnusedMethodArgument,Style/EmptyMethod
```

![out.gif](https://qiita-image-store.s3.amazonaws.com/0/9811/b5ee7de0-2eaf-d343-7189-bb602f7efed9.gif)

### まとめ

`flymake` で頑張ろうと思っていたけどパッケージ入れたら全部終わった。

### その他

昔は「起動が重い」「メモリ食い過ぎ」などと言われて忌避されていた面もある Emacs ですが、2018年現在、Emacs を使っていて重いと感じるパソコンはあまり無いのではないでしょうか。また、Rails プロジェクトでの開発に限定した話では、 [robe-mode](https://github.com/dgutov/robe) というオムニ保管ツールがあり、これは裏で Rails console が動いているので Ruby の癖にしっかりメソッドや定数の定義位置にジャンプできるので RubyMine に匹敵するくらい便利です。ctag や gtag のタグジャンプでは味わえない利便性で、一度味わったらやめられません。<strike>重いから普段は使わないけど。</strike>みなさんも是非 Emacsian になりましょう :grinning: 

###
Hello WorldができたWebエンジニアの皆様へ。次はCRUDを目指してみよう！

# CRUD つまり?
<font color="#FF0000">「掲示板」</font>や<font color="#FF0000">「ブログ」</font>などのシステムです。

## 禁則事項
### Railsを使う場合
```scaffold``` と ```resource``` の使用は禁止です。
これから、CRUDシステムをわざわざ作る意義がなくなってしまうため。
[Rails初心者はscaffoldとresourcesを使うな](https://qiita.com/723ch/items/1829124158bd40f3698f)

### Rails以外を使う場合
Railsの```scaffold```などに代表されるようにCRUDやRESTFulの雛形自動的に作ってしまうような機能を使ってしまえば同様に、これから、CRUDシステムをわざわざ作る意義がなくなってしまうため、使用しない方が望ましいです。

## そもそもCRUDとは?
>CRUD（クラッド）とは、ほとんど全てのコンピュータソフトウェアが持つ永続性[1]の4つの基本機能のイニシャルを並べた用語。その4つとは、Create（生成）、Read（読み取り）、Update（更新）、Delete（削除）である。ユーザインタフェースが備えるべき機能（情報の参照/検索/更新）を指す用語としても使われる。

Wikipediaより。
詳しくはこちら [CRUD](https://ja.wikipedia.org/wiki/CRUD)

## 開発時間
目安は大体、1〜2週間ぐらいかなと思います。
人によって、物量によって、導入するツールによって変わってくると思います。

## なぜCRUDシステムを作るのか?
Webシステムにおいて、どのシステムを開発する場合においても基本となる機能を有したものがCRUDです。
ほとんどの場合、CRUDができればあとはそれらの組み合わせや応用をしていってシステムを作り上げていくことがほとんどになります。そのため、まずはCRUDを使ったサービスの開発を目指していけば、自然と新しく使うプログラミング言語やフレームワークを素早く習得するには非常に効果的です。

## 応用形
例えば、以下のような制約を加えていくことで様々な形で応用させることができます。
##### 応用例
[TypeScript](https://ja.wikipedia.org/wiki/TypeScript) + [Node.js](https://nodejs.org/ja/) + [Angular](https://angular.jp/) + [NestJS](https://nestjs.com/) + [TypeORM](https://github.com/typeorm/typeorm) + [MySQL](https://www.mysql.com/jp/)を使い、CRUDシステムを作成し、[Docker](https://www.docker.com/)を使いサーバーを立ち上げる。また、[Swagger](https://swagger.io/)を使い作成したAPIドキュメントを作成し、[PlantUML](http://plantuml.com/)で構造を図示する。
(↑は実際に私が最初のトレーニングを行うために立てた短期的な目標です)

##### 補足
上記の内容に[Redis](https://redis.io/)を追加したり、[Nginx](https://www.nginx.com/)を利用してリバースプロキシを実装したり、[webpack](https://webpack.js.org/)も使ってフロントエンドをコンパイルしてみたり、[Jest](https://jestjs.io/ja/)をいれてテストを追加したり、などただのCRUDシステムを作るだけですが、要件を追加していき、発展させることはできます。
また、簡単そうに見えますが、いざ実際にやってみるといろいろなことが実際に見えてこなかったものが見えてきます。。

# 背景
### 個人的なこと
最近、転職しました。転職先では上記の技術を中心に使うことになりました。
```TypeScript``` ```Angular``` ```NestJS``` などを使った開発はこれまで行ってきたことがなかったので、今回、これらを使用しての開発は初めてとなります。
<font color="#FF0000">いくら経験値を積んで、エンジニアとして熟練者となったとしても、新しい言語、フレームワークを利用して開発する場合はいつも初心者です。</font>
そして、新しい言語、フレームワーク、技術を使って開発することは、エンジニアをやっていれば、常に遭遇するため常に学び続けなければなりません。
その中で自身がいち早く新しいものを習得し、開発できるようになるために心がけていること、実践したことを紹介しようと思い、今回の記事を書きました。

## 本記事の目的
非エンジニア、あるいは新人エンジニアの方とよくお話しする中で、「プログラミングを勉強するためにはまず、どんなことをしたらいいか?」であったり、「Hello Worldはなんかできたけど次に何をやればいいんでしょうか?」みたいなことを質問されます。そのような方々へ新たな目標を設定する上での道しるべとなることが本記事の目的になります。

## いかに早く成長するために
私自身が早く成長するために心がけていることを2点を挙げてみます。

### 自分(チーム)に足りないもの(課題)を自分で見つけて、その解決策を自分で考える
どのような場合においても、常に自発的に考え、行動することは早く、成長するためには必要不可欠なことであると思います。私自身、早く成長することを目的としたため、このようなことを実践しました。

### 百聞は一見にしかず
いくら記事を読もうが、勉強会に参加して、セッションを聞こうが、技術書を読もうが、<font color="#FF0000">自ら手を動かして、苦悩しながら一つのものを作り上げていく方が圧倒的に理解が早いです。</font>適度に文章を読み終わったらそのあとは自分で実際に使ってみて何か作っていくことをおすすめします。

# 最後に
以上、やったことできたことを[Github](https://github.com/)などに公開し、人に見せて様々な意見をもらったり、記事にまとめてみたりすると、新たな発見があるので、ぜひやってみてください。
Vagrantの概要をまとめてみた

#Vagrantとは
Vagrantは仮想マシンを簡単に立ち上げることができる

ツールです。

さらに、仮想マシンを管理、操作するためのツールでもあります。

Windows、MacOS、Linuxで動作するので

ホストのOSに関わらず仮想環境を構築できます。

Vagrantはrubyで書かれていますが、

PHPやPython、Java、C#、JavaScriptなども対応しています。

#Box

Boxは仮想マシンのテンプレートで

テンプレートはWeb上にたくさん配布されています。

そのテンプレートを元に

自分に合った設定にして仮想マシンを初期化することができます。

CentOSやDebianなどOSを各自選択でき

ネットワーク設定やSSH環境の整備をしてくれるので

簡単に好みの仮想環境を構築することが可能です。

また、一つのテンプレートから複数の仮想マシンを作ることが可能です！

#Vagrantfile

VagrantfileはRubyファイルで

仮想マシンを設定できます。

例えば、

起動する仮想化マシン指定
ネットワーク設定
共有フォルダ設定
マシンスペック設定（CPUやメモリの割り当てなど）

などを設定できます。

簡単に自分の環境に適した環境を構築できる点が

Vagrantの長所だとわかります。

#まとめ
VagrantはデフォルトでVirtualBoxをサポートしています。

プラグインをインストールすることでVMwareやAWS(EC2)も対応できるので

必要に応じて様々なプラグインを取り入れていきたいところです。

#参考文献
[Vagrant + VirtualBoxでWindows上に開発環境をサクッと構築する](https://qiita.com/ozawan/items/160728f7c6b10c73b97e)
[VagrantとDockerについて名前しか知らなかったので試した](https://qiita.com/hidekuro/items/fc12344d36d996198e96)
[Vagrantのプラグイン、何入れてたっけ…。
](https://qiita.com/akiko-pusu/items/9b45b6b70878669e2e11)
optunaでPruningする時に早すぎる枝刈りをされないようにする方法

# 課題

[optuna](https://github.com/pfnet/optuna)でPruningを利用するときにデフォルトの設定だと、0step目でも遠慮なく枝切りされてしまう。
最初の数ステップはあまり差が起きない場合にこれは都合が悪い。


# 解決策

Prunerにn_warmup_stepsを設定する。

## 例

```
study = optuna.create_study()  # Create a new study.
```

本家のexampleでこう書いてある部分を。

```
study = optuna.create_study(pruner=ptuna.pruners.MedianPruner(n_warmup_steps=10))  # Create a new study.
```

こう設定します。(この場合は10stepまでは必ず実行するというものになります)
Swift UITableView忘れがちな設定

# UITableViewの忘れがちな設定
この記事は、[TECOTEC Advent Calendar 2018](https://qiita.com/advent-calendar/2018/tecotec) の９日目の記事です。

# あらすじ
iOSエンジニアを始めて2年と少し、一番触る機会の多いUITableViewの作るたびに「あれどうやるんだっけ？」とか「これどうしたらいいんだっけ？」とか毎回思うことが多いので備忘録がてら忘れがちな設定をまとめてみました。

開発環境：Xcode:10.1
開発言語：swift4.2

## UITableViewの上の隙間を消したい
StoryboardにてUITableViewを置いているViewControllerを選択し、
画像1のAdjustScrollViewInsetのチェックを外す

■画像1
![setting.png](https://qiita-image-store.s3.amazonaws.com/0/226381/496726f7-ba9d-0b51-316d-92e33a27eb5b.png)

## セルの下線（セパレータ）を消したい

・Storyboardで設定する場合
UITableViewを選択し、画像2のSeparatorの値をNoneに設定する。

■画像2
![スクリーンショット 2018-12-09 16.57.34.png](https://qiita-image-store.s3.amazonaws.com/0/226381/9912e214-0d43-e4f4-a680-27f0506abba0.png)

・ソースコードで設定する場合
tableViewにseparatorStyle = .noneを設定してあげる

```swift:sample.swift
    @IBOutlet weak var mTableVIew: UITableView!
  
    override func viewDidLoad() {
        super.viewDidLoad()
        mTableVIew.separatorStyle = .none
    }    
```

## セルの下線（セパレータ）の左端の隙間をなくしたい
デフォルトの設定のまま実行すると微妙な隙間が左側にできてしまうのでそれをなくす。

・Storyboardで設定する場合
UITableViewを選択し、画像3のSeparatorInsetをCustomに設定してLeftの値を0にする。

■画像3
![スクリーンショット 2018-12-09 17.15.19.png](https://qiita-image-store.s3.amazonaws.com/0/226381/06616b49-e4e5-e2a0-8995-3f1be414101c.png)

・ソースコードで設定する場合
tableVIewにseparatorInset = .zeroを設定してあげる

```swift:sample.swift
    @IBOutlet weak var mTableVIew: UITableView!
  
    override func viewDidLoad() {
        super.viewDidLoad()
        mTableVIew.separatorInset = .zero
    }    
```

## その他の忘れがちな処理
**・ カスタムセルを使用した時のセルの初期化**
　リサイクルされることを忘れてついやりがちな初期化忘れミス。下までスクロールして戻ってきた時に、あるセルで変更した背景色や、hiddenにしていたViewなどが表示される。一瞬「なんで！？」ってなるけれど、落ち着くと「あぁ初期化忘れか...」ってなるので気を付けたい。

**・ カスタムセルの高さを表示中に変更する時**
　アニメーションが入るので要注意。

```swift:sample.swift
    self.tableView.beginUpdates()
    // 動的に動かしたい処理
    self.tableView.endUpdates()    
```
UGUIで多重スクロールを作る

多重スクロールしたい！

少し調べたら、みんな大好きテラシュールブログに書いていましたが、
ちょっと違う部分もあるので、アドベントカレンダーの記事とさせていただきます。

##ためしにスクロールビューの中にスクロールビューを入れてみる
こうしてみると、親の方のスクロールビュー(以下、親)は反応せず、
子供の方のスクロールビュー(以下、子供)しか反応しなくなります。
これは、スクロールイベントが、子供で消費されてしまうため、
親にイベントが渡されないからです。
![advent2018_1.gif](https://qiita-image-store.s3.amazonaws.com/0/61227/220a077a-eb5c-819d-04a1-c355a62848b0.gif)


##親スクロールビューにイベントを渡す
子供で消費されるイベントを、親にも渡せれば、親が反応してくれます。
そのため、スクロールビュー(ScrollRect)を拡張し、渡されたイベントを親に通知する仕組みを作ることが考えられます。
[UnityのuGUIで階層構造を持ったスクロールビューを作る](http://tsubakit1.hateblo.jp/entry/2015/02/09/235951)
 
##既存のスクロールビューに追加で多重スクロールされるようにしたい
ここでScrollRectを拡張せずに、親へイベントを渡すことを考えてみます。

実は、子供で消費されてしまうイベントですが、
同ゲームオブジェクトにアタッチされているコンポーネントに関しては、
同じようにイベントを受け取ることができます。

ですので、子供が受け取っているイベントを別コンポーネント経由で親に渡せば、
既存のScrollRectを使って多重スクロールを実現することができます。

以下ソース

```CSharp:MultiScroller.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System.Linq;

public class MultiScroller : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler {
	[SerializeField]
	private IDragHandler[] m_parentDragHandlers;
	private IBeginDragHandler[] m_parentBeginDragHandlers;
	private IEndDragHandler[] m_parentEndDragHandlers;

	private bool isSelf = false;
	void Start () {
		m_parentDragHandlers = this.GetComponentsInParent<IDragHandler>().Where(p => !(p is MultiScroller)).ToArray();
		m_parentBeginDragHandlers = this.GetComponentsInParent<IBeginDragHandler>().Where(p => !(p is MultiScroller)).ToArray();
		m_parentEndDragHandlers = this.GetComponentsInParent<IEndDragHandler>().Where(p => !(p is MultiScroller)).ToArray();
	}
	
	public void OnDrag(PointerEventData ped)
	{
		foreach(var dr in m_parentDragHandlers)
		{
			dr.OnDrag(ped);
		}
	}
	public void OnBeginDrag(PointerEventData ped)
	{
		foreach(var dr in m_parentBeginDragHandlers)
		{
			dr.OnBeginDrag(ped);
		}
	}
	public void OnEndDrag(PointerEventData ped)
	{
		foreach(var dr in m_parentEndDragHandlers)
		{
			dr.OnEndDrag(ped);
		}
	}
}
```

※GetComponentでinterfaceを取得可能なので覚えておくと便利です。

これを使うとこうなります。
<img width="288" alt="advent2018.png" src="https://qiita-image-store.s3.amazonaws.com/0/61227/9e5573f2-c49c-4aaf-c65e-209564866a98.png">

![advent2018_2.gif](https://qiita-image-store.s3.amazonaws.com/0/61227/660a24fa-1a6f-e51a-105d-adab100d2ac9.gif)


##おまけ
この、別オブジェクトに直接イベントを渡してやる方式ですが、
応用すると、イベント周りの拡張がしやすくなります。
OpenModelicaで伝熱流動　redeclare packageの件

前回と前々回に試してみたSimpleFrictionを使ったIsolatedPipeの圧力損失評価モデルが私的にいま一つだったので、Modelica.Fluid.Pipes.StaticPipeを試してみました。
![static_pipe.png](https://qiita-image-store.s3.amazonaws.com/0/317126/6142ae46-f623-dcb8-0748-52f63269bc08.png)
Examplesを参考に上図のような構成に。
systemが必須かどうかは不明ですが、役に立ちそうなので入れてみました。
以下のように、流体をMediumで定義したみたところ、 Variable Medium not found in scope flow_test_old.のエラーでコンパイルできません。
model flow_test_old
  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater;
  Modelica.Fluid.Sources.MassFlowSource_T boundary(T = 320, m_flow = 1, nPorts = 1,Medium = Medium)
(後略)

流体の定義がまずいようなので、いろいろと試行錯誤してみたところ、今度は以下のようなエラーが。
component boundary contains the definition of a partial class Medium.
Please redeclare it to any package compatible with Modelica.Media.Interfaces.PartialMedium.
どうやらModelica.Media.Interfaces.PartialMediumを使えというエラーのよう。
そこで、さらに他のExamplesを参考に以下のように定義してみました。
model flow_test
  replaceable package Medium = Modelica.Media.Water.StandardWaterOnePhase constrainedby Modelica.Media.Interfaces.PartialMedium;
  Modelica.Fluid.Sources.MassFlowSource_T boundary(redeclare package Medium = Medium, T = 310, m_flow = 1, nPorts = 1)
(後略)

これで実行可能になりました。
モデルによっては、使えるMediumに制限があるのでしょうか。
Fortran77な私なので、redeclare packageが一般的なのかもわかりませんが、とにもかくにも動くようにはなりました。
Kuinでクロージャ

クロージャは関数を拡張した概念で、環境(スコープのようなもの)を持った関数のことです。と言っても関数型言語に触った人間でなければなかなか分かりづらい概念だと思います。

[Wikipedia - クロージャ](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3)

Java言語などではクロージャはクラスで実装されています。これに習ってクラスを使ってクロージャを作ってみましょう。

# 足し合わせを行うクロージャ

まずは、決められた数を足し合わせるクロージャです。

```increment.kn
; クロージャのインターフェース
class ClosureIntToInt()
	+func body(n: int): int
		ret 0
	end func
end class

; クロージャを生成する関数
func increment(delta: int): @ClosureIntToInt
	class Increment(@ClosureIntToInt)
		+var delta1: int
		+*func body(n: int): int
			ret n + me.delta1
		end func
	end class
	
	var res: Increment :: #Increment
	do res.delta1 :: delta
	ret res
end func

func main()
	var f: @ClosureIntToInt :: @increment(3)
	do dbg@print(f.body(1).toStr() ~ "\n")
	do dbg@print(f.body(3).toStr() ~ "\n")
	do dbg@print(f.body(5).toStr() ~ "\n")
end func
```

クロージャを生成する関数の外側にインターフェースを作るのがポイントです。Kuinにはインターフェースを作成する機能はないのでクラスで代用します。クロージャのメソッドを呼び出すことで計算を行います。

クロージャを生成する関数の中にクロージャクラスの定義を書きます。生成関数はクロージャクラスではなく、先ほどのインターフェースの参照を送出することでクロージャの実装を隠蔽します。具体的に言うと、`@increment(3)`で3を足し合わせるクロージャを生成するのですが、その値を保持する`delta1`フィールドにはアクセスすることができません。なぜならば、`increment`関数の外側で`Increment`クラスを指定することができないからです。試しに`main`関数内に`do dbg@print((f $ @Increment).delta1)`と記述するとコンパイルエラーになります。

クロージャによって**イミュータブル**(immutable)なオブジェクトを生成することができます。イミュータブルは「書き換え不能な」という意味です。Kuinでもイミュータブルなオブジェクトを作ることは可能なのです。

# カウントを行うクロージャ

次に、カウントを行うクロージャです。

```counter.kn
; クロージャのインターフェース
class ClosureVoidToInt()
	+func body(): int
		ret 0
	end func
end class

; クロージャを生成する関数
func counter(): @ClosureVoidToInt
	class Counter(@ClosureVoidToInt)
		+var cnt: int
		+*func body(): int
			do me.cnt :+ 1
			ret me.cnt
		end func
	end class
	
	var res: Counter :: #Counter
	do res.cnt :: 0
	ret res
end func

func main()
	var f: @ClosureVoidToInt :: @counter()
	do dbg@print(f.body().toStr() ~ "\n")
	do dbg@print(f.body().toStr() ~ "\n")
	do dbg@print(f.body().toStr() ~ "\n")
end func
```

プログラムを実行して結果を確認してみましょう。クロージャを呼び出すたびにカウント値が1つずつ増えていきます。

# 結論

Kuin言語でもクロージャを生成することが可能であることが分かりました。また、Kuinの入れ子構造と継承機能を使えばファイルスコープを使わなくともイミュータブルなオブジェクトを作ったりカプセル化を行うことが可能であることが分かりました。
Practical Object Oriented Design in Ruby - Chapter 2

Example 1 

```
def diameters
  wheels.collect {|wheel|
  wheel.rim + (wheel.tire * 2)}
end
```

```
# first - iterate over the array
def diameters
  wheels.collect {|wheel| diameter(wheel)}
end

# second - calculate diameter of ONE wheel
def diameter(wheel)
  wheel.rim + (wheel.tire * 2))
end
```

Example 2

```
def gear_inches
  # tire goes around rim twice for diameter
  ratio * (rim + (tire * 2))
end
```

```
def gear_inches
  ratio * diameter
end

def diameter
  rim + (tire * 2)
end
```
- Write code that is easily changeable.
- Isolate the behavior in a separate method. 


### Conclusion
- Expose previously hidden qualities
- Avoid the need for comments
- Encourage reuse
- Are easy to move to another class


```
class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, rim, tire)
    @chainring = chainring
    @cog = cog 
    @wheel = Wheel.new(rim, tire)
  end 

  def ratio
    chainring / cog.to_f
  end 

  def gear_inches
    ratio * wheel.diameter
  end 

  Wheel = Struct.new(:rim, :tire) do
    def diameter
      rim + (tire * 2)
    end 
  end 
end
```

- Proc
  - Wheel that can calculate its own diameter.
- Cron
  - Wheel can only exist in Gear.

#### The scene
Class bycicle want to have diameter to calculate bicycle’s wheel circumference.

Simply convert the Wheel Struct to an independent Wheel class and add the new circumference method likes below.

```
class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, wheel=nil)
    @chainring = chainring
    @cog = cog 
    @wheel = wheel
  end

  def ratio
    chainring / cog.to_f
  end

  def gear_inches
    ratio * wheel.diameter
  end
end
```

```
class Wheel
  attr_reader :rim, :tire

  def initialize(rim, tire)
    @rim = rim
    @tire = tire
  end

  def diameter
    rim + (tire * 2)
  end

  def circumference
    diameter * Math::PI
  end
end
```

## Summary
Changeable and maintainable object-oriented software begins with classes
that have a single responsibility.
[AndroidStudio3.2]キャッシュを消しても"default activity not found"が消えないときの対処法(Windows)

# AndroidManifest.xmlをなにもいじってないのに"default activity not found"のせいでビルドできないとき

AndroidManifest.xmlはなにもいじってないのに突然"default activity not found"が出て困ったので対処法をまとめておきます。

## やったこと
- メニューのBuild > Clean ProjectしてBuild > Rebuild Project
- メニューのFile > Invalidate Caches/Restart
-  C:\Users\username\ にある以下のフォルダを削除 -> AndroidStudio再起動
    -  .android
    -  .AndroidStudio3.2

私の場合、これでエラーが消えました。
めでたしめでたし。


参考
https://stackoverflow.com/questions/52640863/android-studio-3-2-default-activity-not-found
MAMA

MAのAdventCalendar初参加です、普段はMAが作りっぱなしのTogetterまとめにこっそりタグ付けたりして生きてます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15581/49e43267-0254-ff3e-4319-ebe5100603b4.png)

[MA\_2018に関連する24件のまとめ \- Togetter](https://togetter.com/t/MA_2018)


さてと、MAのアドカレが出来たらしいけどそれまでの日ががら空きなのでとりあえずエントリしてみましたよ

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">MAロスになってませんか？今年のMAの作品についての裏話など待ってます。<a href="https://twitter.com/hashtag/MA_2018?src=hash&amp;ref_src=twsrc%5Etfw">#MA_2018</a><br><br>MashupAwards2018 Advent Calendar 2018 <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://t.co/GsiqkKtNZh">https://t.co/GsiqkKtNZh</a></p>&mdash; MashupAwards (@mashupaward) <a href="https://twitter.com/mashupaward/status/1070768206124470272?ref_src=twsrc%5Etfw">December 6, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# MAをMAした

MA公式とTwitterをマッシュアップしてちょっとイイ感じのTogetterまとめを作ってみた

[MA2018 ヒーローズ・リーグ オレトクヒーロー 決勝審査会 オレトクまとめ \#MA\_2018 \- Togetter](https://togetter.com/li/1291543)


素材はこちら

- [ProtoPedia](https://protopedia.net/)
- [Mashup Awards \- YouTube](https://www.youtube.com/channel/UC87JSMaaTuY1Lkn4-5Xvhjw)
- [Twitter](https://twitter.com/)
- 他少々



# MAはMAしがいがありそう

ちょうど本日のエントリが [MA2018オレトクヒーロー部門 決勝審査会で発表してきたよ \| なにがでるか](https://awwa500.blogspot.com/2018/12/ma2018.html) でして、まさにMA得だとのことですね。素晴らしい。


> 彼は「次のMA2019にエントリーしたい」とヤル気満々で、次の作品についてあれこれアイデアを出していました。

イイハナシダナー


MAのコンテンツを使った作品ってのも良いのかも知れないななんて思いながら平成最後の今年は以上です

:christmas_tree: 良いお年を
Rubyでメニューバーを作る

ここではGladeとRuby/Gtkを使って、メニューバーを作ってみます。

## 完成イメージ
![fuga.gif](https://qiita-image-store.s3.amazonaws.com/0/144608/178d3d77-5239-4a79-bde2-b7c93043c7ce.gif)

## 準備
* gtk3のインストール
 * gem install gtk3
* gladeのインストール
 * Mac：  brew install glade
 * Ubuntu：  apt install glade
 * Win：  pacman -S なんちゃらglade

WindowsはMSYS2のpacmanで新しいバージョンのgladeをインストールできます。

## gladeの操作手順
gladeを起動します
1. 新しいプロジェクトを作成します。
![screenshot4.png](https://qiita-image-store.s3.amazonaws.com/0/144608/213f8aab-6b52-2010-a688-7f231dafe6b1.png)
2. トップレベルから GtkWindow を作ります。
![screenshot5.png](https://qiita-image-store.s3.amazonaws.com/0/144608/6ffa0afd-fa20-91b9-9e09-86aead97e8c7.png)
3. GtkWindowのIDを `win` に設定します。 
4. GtkWindowの中に、コンテナ > GtkMenuBar を配置します。
5. 配置したGtkMenuBarを右クリックしてEdit...を選択します。
（Macで右クリックが動かない場合は左下のアイコンからEditを選択（通常 ▼ の中にある））
6. メニューバーの編集の画面から[+]でメニューを追加していきます。今回は、型に標準を選択して、ラベルに都道府県名を入力しました。

![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/144608/24b333bc-05cb-69ff-452d-37969974e81f.png)

GtkMenuItemのシグナル"active"にハンドラーの名前を登録します。これはあとでRubyの同名のメソッドに接続します。ここでは "on_shimane_clicked" としました。

![screenshot2.png](https://qiita-image-store.s3.amazonaws.com/0/144608/07e93e0c-452f-bce6-d16c-0cc0a1b09072.png)

すべて終わったら、sample.glade などとして保存します。中身はXMLファイルです。
これはサンプルです。都道府県を全部手打ちするのは意外と面倒なのでおすすめしません。

※Gladeはやや不安定なようです。自分の使っている環境でクラッシュしやすいなと感じたら、中央のウィジェットはあまり触らずに左側のペインから部品を選択するようにすると落ちにくいです。

## Rubyのスクリプトを書く
こんな感じです。



```ruby
require 'gtk3'

def on_shimane_clicked
  puts "島根県が選択されました"
end

b = Gtk::Builder.new(file: "sample.glade")
w = b.get_object "win"
b.connect_signals{|handler| method(handler)}
w.signal_connect(:destroy){Gtk.main_quit}
w.show_all
Gtk.main
```

## 実行
```bash
ruby menu.rb
```

![fuga03d-47.jpg](https://qiita-image-store.s3.amazonaws.com/0/144608/fa5ba9c4-79c5-b134-15a0-e28e9e0ba0cb.jpeg)

```bash
島根県が選択されました
```

こんな感じでGUIポチポチでRubyでメニューバーを作成できます。
ちょっとした小物を作るときにどうぞ。

（おわり）
Django の簡単なプログラムを Heroku にデプロイ

次の Django のプログラムを Heroku にデプロイします。
[Django で簡単なページ遷移をする](https://qiita.com/ekzemplaro/items/6038954d0ed672d1c887)

他のサイトからのアクセスを許可するように、proj01/settings.py を修正します。

```text:proj01/settings.py
（省略）
ALLOWED_HOSTS = ['*']
（省略）
```

proj01 のフォルダーに次のファイルを作成します。
>Procfile
>runtime.txt
>requirements.txt

フォルダーの構造

```text
$ tree -L 1
.
├── app01
├── app02
├── db.sqlite3
├── home
├── manage.py
├── Procfile
├── proj01
├── requirements.txt
└── runtime.txt
```


```text:Procfile
web: gunicorn proj01.wsgi --log-file -
```

```text:runtime.txt
python-3.10.7
```

```text:requirements.txt
django
gunicorn
```

Heroku にアップロードします。

```bash
heroku login -i
git init
git add .
git commit -m "init"
heroku create p0485
heroku config:set DISABLE_COLLECTSTATIC=1
git push heroku master
```


ブラウザーで
https://p0485.herokuapp.com/
にアクセスしてデプロイを確認
![heroku_dec09.png](https://qiita-image-store.s3.amazonaws.com/0/179446/1e1befaf-a760-85a0-ad5a-ff7317f8b158.png)

コンソールで実行を確認する方法

```text
$ heroku ps
›   Warning: heroku update available from 7.60.1 to 7.66.0.
 ▸    Starting November 28th, 2022, free Heroku Dynos will no longer be
 ▸    available. To keep your apps running, subscribe to Eco or upgrade to
 ▸    another paid tier. Learn more in our blog
 ▸    (https://blog.heroku.com/new-low-cost-plans).
Free dyno hours quota remaining this month: 548h 27m (99%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): gunicorn proj01.wsgi --log-file - (1)
web.1: up 2022/11/08 11:52:00 +0900 (~ 1m ago)
```
Laravel5.7 + Stripe Checkoutで安全な実装のサンプル作った

## はじめに

以前社内で利用する目的で、缶コーヒー販売の決済システムをRailsで構築したので、それっぽいシステムをLaravelでより安全に実装してみました！

[![Image from Gyazo](https://i.gyazo.com/2d6ca35b76a646a930ff8eeccfcf9cad.gif)](https://gyazo.com/2d6ca35b76a646a930ff8eeccfcf9cad)

## そもそもStripeとは

2018年も終盤を迎える中、もはや決済システムのデファクトになりつつあるのがStripeです。ちょこっとした決済システムを構築するには必須の技術になるかと思います。その利点はなんといっても審査の必要がなくすぐにシステムの構築を始められるというところです。

詳しくは[公式サイト](https://stripe.com/)へ！

StripeでECサイトのような1回きりの支払いシステムをStripeで実装する方法は2つあります。

1. [Stripe Checkout](https://stripe.com/payments/checkout?locale=ja)を使う方法    
2. [Stripe Elements](https://stripe.com/payments/elements?locale=ja)を使う方法

UI/UXは気にせず、お手軽に便利に実装したい場合はCheckout, UIに柔軟に組み込みたい場合はElements
という感じの認識でひとまずは大丈夫だと思います。

今回はStripe Checkoutを利用してみました

## 安全な決済処理の図

![laravel-stripe-sample.png](https://qiita-image-store.s3.amazonaws.com/0/77973/d02c2ee2-980e-367d-89c3-8c1624ae13f4.png)

## 安全な実装のポイント

1. クレジットカードの情報はユーザとStripe間でやりとりさせる
2. Stripeへ支払う決済金額の計算ロジックは必ずUnitテストをかく
3. GitLabCIなどを利用してデプロイ時には必ずテストを通す

## 事前準備

1. Stripeに登録
2. テスト用のAPIキーを取得
3. サンプルの.envにAPIキーを設定

## 詳しい実装方法はサンプルをどうぞ！

https://github.com/NakanishiTetsuhiro/laravel-stripe-sample

社内の無人お菓子販売とかの集金業務が億劫になってる方などいましたら、是非このサンプルを参考にシステムを構築してみてください！

## さいごに

Advent Calendar初参加でしたが記事はいかがでしたでしょうか？
毎日Laravelを使っている人のいろいろな考え方に触れられてとても楽しいですね！
引き続きクリスマスまで楽しんでいきたいと思います。それではー！
XmlSerializerでシリアライズするとき、XML宣言や名前空間のプレフィックス宣言を入れたくない！

## 背景
`System.Xml.Serialization.XmlSerializer`クラスの`Serialize`メソッドで、何も指定せずにシリアライズすると、以下のようになります。

```XML:XML
<?xml version="1.0"?>
<outertag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <innertag someattribute="...">
```

１行目のXML宣言や、一番外側の要素（２行目）の名前空間のプレフィックスの宣言など、無くてもいいものが付加されます。

要件としてこれらが必要ないので、除去したい！

## XML宣言を付けずにシリアライズする
`XmlWriterSettings.OmitXmlDeclaration`プロパティを使います。

1. `XmlWriterSettings`クラスのインスタンスを作る
2. `OmitXmlDeclaration`プロパティを`true`にする
3. `XmlWriter#Create`メソッドに`XmlWriterSettings`クラスのインスタンスを渡して、`XmlWriter`クラスのインスタンスを作る
4. `XmlSerializer.Serialize`メソッドに`XmlWriter`クラスのインスタンスを渡す

```cs:C#
var serializer = new XmlSerializer(value.GetType());
var settings = new XmlWriterSettings // 1.
{
  OmitXmlDeclaration = true, // 2.
};

using (var writer = XmlWriter.Create(stream, settings)) // 3.
{
  serializer.Serialize(writer, value); // 4.
}
```

## 名前空間のプレフィックスの宣言を付けずにシリアライズする
`XmlSerializerNamespaces`クラスのインスタンスを使い、プレフィックスと名前空間の組がないことを明示的に指定します。

1. `XmlSerializerNamespaces`クラスのインスタンスを作る
2. 空のプレフィックスと空の名前空間の組を`Add`する（または、`XmlQualified.Empty`を要素として持つ`XmlQualified`の配列を、`XmlSerializerNamespaces`のコンストラクターに渡してもよい）
3. `XmlSerializer.Serialize`メソッドに`XmlSerializerNamespaces`クラスのインスタンスを渡す

```cs:C#
var serializer = new XmlSerializer(value.GetType());
var emptyNamespaces = new XmlSerializerNamespaces(); // 1.
emptyNamespaces.Add(prefix: string.Empty, ns: string.Empty); // 2.

using (var writer = XmlWriter.Create(stream))
{
  serializer.Serialize(writer, value, emptyNamespaces); // 3.
}
```

## 両方とも付けずにシリアライズする
それぞれ独立に働きますので、両方のコードを混ぜれば、両方が除去されます！

## 参考
[How can I make the xmlserializer only serialize plain xml?](https://stackoverflow.com/questions/1772004/how-can-i-make-the-xmlserializer-only-serialize-plain-xml "stackoverflow")

[XmlWriterSettingsクラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmlwritersettings "Microsoft")
[XmlSerializerNamespacesクラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.serialization.xmlserializernamespaces "Microsoft")
[XmlSerializerクラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.serialization.xmlserializer "Microsoft")
[XmlWriterクラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmlwriter "Microsoft")
CryptZombiesレッスン5(チャプター1~7)の自分なりのまとめ

# はじめに
この記事は私がCryptZombiesを進めていく上で自分なりにまとめたものです。
**前回の記事**
https://qiita.com/daichi77/items/a0e893706ff9419c66e1
**参考にしたサイト**
サイト名: イーサリアム上のDApp開発をゲームを作って学びましょう
URL: 　https://cryptozombies.io/jp/　
**この記事の問題文と答えについては上の参考にしたサイトから引用しています。**

# チャプター１ イーサリアム上トークン
## 要点
トークンはtransfer(address _to, uint256 _value) や balanceOf(address _owner) といった関数のスタンダードセットを実装しているものである。
トークンとは、誰がトークンをどれくらいを所有しているのかを記録するコントラクトと、ユーザーが自分のトークンを他のアドレスに送ることができるようにする機能のこと。
すべてのERC20トークンは同じ名前の同じ関数セットを共用している。よって違うERC２０トークンとやりとりすることも可能である。
新しいトークンのコントラクト・アドレスを入力するだけで、もうアプリは別のトークンを使えるようになる。例としてあげられるのは取引所など。
ゾンビは通貨のように0.023ゾンビと分けられないのでERC20トークンでゾンビを表すことはできない。
ゾンビを表すにはERC721トークンを使う必要がある。
C721トークン は、それぞれがユニークであると仮定され、分割出来ないので 相互に交換可能できない。
## 今回したこと(テスト)
importとかcontractの定義とかしただけ。

# チャプター２　ERC721規格と多重継承

```
contract ERC721 {
  event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);

  function balanceOf(address _owner) public view returns (uint256 _balance);
  function ownerOf(uint256 _tokenId) public view returns (address _owner);
  function transfer(address _to, uint256 _tokenId) public;
  function approve(address _to, uint256 _tokenId) public;
  function takeOwnership(uint256 _tokenId) public;
}

```
ERC721トークンを実装するためには上記のメソッドを実装しなければいけない。
**多重継承**

```
contract contract名 is contract1, contract2 {
}
```
これでcontract1と２を多重継承できる。

## 今回したこと
1. erc721.solをimport
2. ERC721を継承

# チャプター３　 balanceOf と ownerOf
## 要点
**balanceOf**

```
 function balanceOf(address _owner) public view returns (uint256 _balance);
```
この関数はアドレスを引数としてそのアドレスのトークン保有量を返すもの。
**ownerOf**

```
function ownerOf(uint256 _tokenId) public view returns (address _owner);
```
この関数はトークンID (この場合ゾンビのID)を受け取り、その所有者の addressを返す。

## 今回やったこと
1. balanceOf関数(ownerのゾンビの保有数を返す)を実装
2. ownerOf関数(ゾンビのオーナーを返す)を実装

# チャプター４ リファクタリング
## 要点
メソッド名が被ってしまったときなどにbalanceOfなどを変更してはいけない。これを変更してしまうと他のトークンとのやりとりができなくなるので、自分で作った方のメソッド名を変更しなくてはならない。
## テスト(今回やったこと)
ownerOfをonlyOwnerOfに変更

# チャプター５ トランスファーのロジック

## 要点 
ERC721は２つの異なるトークン移転法を持つ。
一つ目はtransfer関数二つ目はapproveとtakeOwnershipを使う方法。
transfer関数はトークンの送り手が関数を呼び出すケース、takeowneship関数はトークンの受け手が関数を呼び出すケースである。

## 今回したこと(テスト)
1. _transfer関数の定義
2. ownerZombieCount(_to)を+1する。
3. ownerZombieCount(_from)を−１する。
4. zombieToOwner(_tokenId)に_toを代入
5. 最後にTransferイベントを起こした。

# チャプター６ ERC721: トランスファーの続き
## 要点
なし
## 今回したこと(テスト)
1. トークン/ゾンビの所有者だけがゾンビを移転できるようにtransfer関数にonlyOwnerOfをつける。
2. transfer関数の中で_transferを呼び出す。
_transfer関数ゾンビの移転の諸々の手続きやってくれる。
transfer関数はゾンビの所有者のみが_transferを呼び出せるようにするために必要？。
_transferにonlyOwnerOfをつけるとprivateとかpublicの関係で色々あってダメになるはず。
正直なんで分けるのかは筆者も明確には理解していない。

# チャプター７ ERC721: Approve
## 要点
approve / takeOwnershipを使ったゾンビの移転
1.トークン所有者がapprove関数を呼び出し、それに新たな所有者のaddressと彼に送る_tokenIdの情報を与える。

2.新たな所有者がtakeOwnership関数を_tokenIdで呼び出すと、コントラクトは彼が承認済みの新たな所有者であるかを確認してから、彼にトークンを移転する。
## 今回やったこと
1. zombieApprovals(uint=>address)マッピングの定義(誰がトークン受け取りを承認されているかをチェックするため)
2. approve関数では、トークン所有者のみが、受け手にトークンを受け取る許可を与えられるようにしておきたいので修飾子のonlyOwnerOfを追加。
3. approve関数の中でzombieApprovalsマッピングの設定
4. ERC721規格にあるApprovalイベントを発火

# まとめ
一旦ここで区切ります。仮想通貨の送金などの根幹の部分が書いてあって面白かったです。
targetSdkVersionを28にしたときにアプリがクラッシュする解決法

## 前提
- targetSdkVersionが27以上のアプリ
- OSバージョンが8.0
- Activityのテーマに`@android:style/Theme.Translucent`のようなActivityを透明にするテーマを指定している

## 何が起きるか？
起動したらこんなエラーで落ちる・・・

```
     Caused by: java.lang.IllegalStateException: Only fullscreen activities can request orientation
        at android.os.Parcel.readException(Parcel.java:1951)
        at android.os.Parcel.readException(Parcel.java:1889)
        at android.app.IActivityManager$Stub$Proxy.setRequestedOrientation(IActivityManager.java:5675)
        at android.app.Activity.setRequestedOrientation(Activity.java:5739)
```

## 原因
こいつが悪さをしているらしい

```
<style name="Theme.Translucent">
    <item name="windowBackground">@color/transparent</item>
    <item name="colorBackgroundCacheHint">@null</item>
    <item name="windowIsTranslucent">true</item>
    <!-- Note that we use the base animation style here (that is no
         animations) because we really have no idea how this kind of
         activity will be used. -->
    <item name="windowAnimationStyle">@style/Animation</item>
</style>
```

よくわからないが、透明にする系の設定がダメらしい

## 解決策
使わないようにする。(カスタムテーマでTranslucent系を使わないものに作り変える)
or
回転処理制御を書かないようにする

## 謎
OSが8.1以上になると発生しない(OSのバグなんでしょうか？)

## 最後に
もし似たような問題でお困りな方の参考になればと思います。
外部キーにnullが入ることを許容する[Rails]

# **はじめに**
時として、リレーションのために外部キーとして設けたカラムに`null`が入ることを許容してあげたい時が出てくると思います。
その場面に出くわしたので、解法をここで備忘録として共有します。

<img width="650"`="_MySQL_5_6_39__localhost_p2me_development_question_users.png" src="https://qiita-image-store.s3.amazonaws.com/0/269862/c5112926-7f45-2cc6-ed30-1014420399d3.png">

# **解法**

**アソシエーションにオプションを付けて`true`と設定するだけです。**

```user.rb
class Question < ApplicationRecord
  belongs_to :user, optional: true
end
```

これで、`Railsにおいて外部キーにnullが入ることが許容されました`。

# **終わりに**
少しでも役に立ちましたら、いいね、お願いします(^^)

# **Rails関連記事**
[正規表現まとめ（基礎）[Ruby編]](https://qiita.com/takuyanin/items/2918ffb3151dcfa88565)
[配列で利用できる主なメソッドをまとめてみた[Ruby編]](https://qiita.com/takuyanin/items/3ca4cd7067b7b9e7e9b6)
[Mysql2::Error: Duplicate entry for key.. エラーを撃退した話(validationの設定)](https://qiita.com/takuyanin/items/b28d5111447d4dedc39d)
[Rails5でJqueryを利用しようとして少しハマった件（Uncaught ReferenceError: $ is not defined）](https://qiita.com/takuyanin/items/24444ec3005098471f3b)
[change_columnでの設定はrollbackできない話(This migration uses change_column, which is not automatically reversible.)[Rails: migration]](https://qiita.com/takuyanin/items/6d51ffb4078a417fed35)
[sessionに保存されたHashを別アクションで利用しようとした際にデータ型の変更によりハマった件[Rails]](https://qiita.com/takuyanin/items/e794e8bdb46287a2a269)
[Railsでfacebookログイン認証機能を実装してみた + エラーの原因はバリデーションだった](https://qiita.com/takuyanin/items/5ebd5d9ac8a0baaa1a8e)
(Mac)Cordova開発環境構築

Cordovaの環境を作った際に何度か詰まったので、備忘録を残しました。
(AndroidStudioを構築済みであるため、同じSDKを使用）

#1.Node.jsのインストール
CordovaはNode.jsの上で動くので、https://nodejs.org/ja/ からインストーラをダウンロードしてインストール

#2.Cordovaのインストール

```
sudo npm install -g cordova
```

#3.プロジェクトの作成
```
cordova create HelloCordova

cd HelloCordova
```

#4.プラグインの追加
AndroidとiOSのプラグインを追加したかったため、以下をターミナルで入力

```
cordova platform add ios android
```

#5.Androidビルド１回目
以前にAndroidStudioを入れていたので、AndroidSDKやJDKは導入済みであったが、以下のエラーが発生

```
cordova run android

//エラー内容
JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
Requirements check failed for JDK 1.8
```
どうもJDK8を入れないとCordovaはビルドできない模様（このPCはJDK10を入れていた）

#6.JDK8の導入
JDK8はOracleのページからダウンロードしてインストール

その後インストールされていることを確認

```
/usr/libexec/java_home -V

//出力内容
Matching Java Virtual Machines (2):
    10.0.2, x86_64:	"Java SE 10.0.2"	/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
    1.8.0_191, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
```

環境設定ファイルを開く

```
open ~/.bash_profile
```

以下を追記（jdk1.8.0_191.jdkへのパスを通した）
export PATH=$PATH:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/bin
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home

確認

```
java -version

//出力内容
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
```

#7.Androidビルド２回目
```
cordova build android

//エラー内容
Could not find an installed version of Gradle either in Android Studio,
or on your system to install the gradle wrapper. Please include gradle 
in your path, or install Android Studio
```

Android Studioのgradleが発見できないようなので再度環境設定ファイルを開く


#8.Gradleのパスを設定

```
open ~/.bash_profile
```

以下を追記(このPCのgradeのバージョンは4.6）
export PATH=$PATH:"/Applications/Android Studio.app/Contents/gradle/gradle-4.6/bin"

#9.Androidビルド３回目
```
cordova build android

//エラー内容
gradle: Command failed with exit code EACCES
```

gradleの実行権限がないらしいので設定

#10.Gradleの権限設定

実行権限を設定

```
chmod +x "/Applications/Android Studio.app/Contents/gradle/gradle-4.6/bin/gradle"
```

確認

```
ls -l "/Applications/Android Studio.app/Contents/gradle/gradle-4.6/bin/gradle"

//出力内容
-rwxr-xr-x
```

#11.Androidビルド4回目
```
cordova build android

//出力内容
BUILD SUCCESSFUL in 1m 59s
```

ようやく成功しました

#12.iOSビルド

```
cordova build ios

//エラー内容
CordovaError: Promise rejected with non-error: 'xcode-select: error: tool \'xcodebuild\' requires Xcode, but active developer directory \'/Library/Developer/CommandLineTools\' is a command line tools instance\n'
    at cli.catch.err (/usr/local/lib/node_modules/cordova/bin/cordova:30:15)
    at process._tickCallback (internal/process/next_tick.js:68:7)
```

iOSのデベロッパー登録をしていないので、エラーが起こる模様
なおWindowsだとリモートでXcodeを指定するらしい

デベロッパー登録はまだ行う予定がないのでここまでで終了

#感想
Cordovaの環境作りはネイティブに比べて面倒だと聞いていたが予想以上だった。
最近の開発ツールは環境変数の設定が不要のものも多いため久しぶりに環境変数を編集したと思う。
Visual Studio Tools for Apache Cordovaも何故かVisual Studio for Macでは提供されていないなど、どの環境でクロスプラットフォーム開発をすべきかといったことを決めるのは中々骨が折れそう
SIerの若手開発エンジニア向け教育をどうすればよいか考える（その２）

[Stylez  Advent Calendar 2018](https://qiita.com/advent-calendar/2018/stylez) の 9日目です。

[株式会社スタイルズ](https://www.stylez.co.jp/)で代表をしている梶原です。

[前回](https://qiita.com/bonybeat/items/9c7a80cca9482493f07e)に引き続き、SIer（受託系）での若手社員（開発系エンジニア　新卒から20代の終わりくらいまで）の教育について考えていることを書いています。

[前回の「SIerの若手開発エンジニア向け教育をどうすればよいか考える（その２）」](https://qiita.com/bonybeat/items/9c7a80cca9482493f07e)では、自社（株式会社スタイルズ）で実際にやっている新卒から２年目が終わるまでにやっている教育コースのことを書きました。

今回は20代の残りを大きく捉えたときに、どのようなことを学んでいけばよいのかということを考えていきたいと思います。

教育ということを考えるときに「開発エンジニア」と「インフラエンジニア」の大きなスキルマップを考えないと行けないですね。だいたい５年くらい前までのそれぞれのエンジニアが取得すべきスキルマップっていうのはこんな感じだったと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/129241/bd4daf7c-214b-c146-dd6a-097edbacb217.png)

でも今はこんな感じだとおもうんですよね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/129241/5e2a2cb5-7a5d-f496-e0ba-35149709163e.png)

あんまり気にしない人に言わせると、クラウドできなくても十分にやっていけるよって言う人も今はいるかも知れないけど、つい最近、発表されたガートナーの予測だと今後、オンプレのシェアは急激に下がっていって、2022年には、クラウドに逆転されるんですよね。1-2年ずれることもあるでしょうが、これが現実になっていくことは間違いないです。ガートナーって、先進技術トレンドの予測は外れることもあるんですがこういう大きな市場動向予測ははずさないんですよね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/129241/612ed4b9-7e7f-833f-bc23-cd535593e675.png)

こうなることが前提で若い人の教育を進めていく必要があると思うんです。ですんで、スタイルズでは、全社的な教育として

- AWS教育
- コンテナ（具体的にはKubernetes)教育
- CI/CDとしてのGitの教育

を月に一回、希望者にハンズオン形式で実施しています。

##AWSに関する教育

AWSについては、UMEDYの[「手を動かしながら2週間で学ぶ AWS 基本から応用まで」](https://www.udemy.com/aws-14days/)をまず受講してもらってから、ハンズオン形式で勉強会を毎月一回実施してます。

##KubernetesとかDockerに関する教育

Kubernetesについては、[「Docker/Kubernetes 実践コンテナ開発入門」](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2-ebook/dp/B07GP1Q3VT/ref=sr_1_fkmr0_1?ie=UTF8&qid=1544341859&sr=8-1-fkmr0&keywords=2.Docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4)の目次にしたがって、ハンズオン形式で勉強会を毎月一回実施してます。

##Gitlabに関する教育

[サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)とかを随時教材にしながら勉強会をやってます。



三回目は、若い人の３年めからしばらくの間の教育をどうするかを書きたいと思います。