OmniAICreator/Qiita-1.07M huggingface dataset:
3Dモデル配信ことはじめ

https://qiita.com/advent-calendar/2019/engineer_tail
４日目の記事です。
過去に自分のnoteで書いた内容を書き直すついでにQiitaに投稿します。

#3Dモデル配信の準備
Vtuberになれるとはいいません。画面の中で3Dモデルが動いている様子をYoutubeで配信できるようになるまでのあらすじです。

#用意するもの（１）
Vtuber知ってる人なら、すでに持ってるものか実質無料なものばかりだと思う。
##ハード
- パソコン
- Webカメラ
    - もしくはLeapMotion

##ソフト
###[OBS](https://obsproject.com/ja)
ビデオ録画と生放送用の無料でオープンソースのソフトウェア。Win,Mac,Linux対応。
###[VRoid](https://vroid.com/)
VRM規格の3Dキャラクターが作成できる
###[Ruppet](http://luppet.appspot.com/)
[ねぎぽよ](https://twitter.com/CST_negi)さん作のLeapMotionとWebカメラだけで動作するVTuberシステム。
###[VMagicMirror](https://baku-dreameater.booth.pm/items/1272298)
[ばくすたー](https://twitter.com/baku_dreameater)さん作のキーボードとマウスベースで動くVRM表示アプリ。
###ペイントソフト
illustratorなどがあると素材の使い回しやバリエーション違いの作成が楽。

#やること
ハードとソフトを揃えたら、次はサムネの用意や配信するアカウントの準備です。
##配信素材の準備
###VRoidで3Dモデルの作成
![キャプチャ0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147257/ab1a47b1-be02-39b2-f0a7-a43d411a35a4.png)
自分のフェチズムをぶつけましょう．時間をかければかけるほどいいものができるのが「作品」です．表現の自由を行使しましょう．

###ペイントソフトでサムネの作成
意外とサムネは大事です．放送のあらすじがあるなら，放送前のサムネ以外にもアイキャッチや告知用画像など用意するのがいいと思います．
###BGMの作成（作成がめんどくさいならフリー音源を探しておくと楽）
フリー音源サイト：https://pocket-se.info/rules/

##Youtubeアカウントの準備
これは少しハードル高くて、携帯の電話番号をYoutubeアカウントに登録して確認作業をしないと、配信が開始できない。登録してからだいたい１日後に配信を開始することができる。

#配信開始

####酒飲んだから今日はここまで

#終わりに
エンジニアなのにコード一行も書かなくてすみません！すみません！
MySQLで “xxx doesn’t have a default value”とエラーが表示されたときの対処法

MySQLで値を挿入する際、次のようなエラーが発生することがあります。

```
SQLSTATE[HY000]: General error: 1364 Field ‘xxxx’ doesn’t have a default value
```

これは、挿入しようとしているテーブルのあるフィールドについて、値が指定されていない場合に発生します。MySQL 5.6以前のバージョンであれば問題なかったのですが、5.6から設定が一部変更されました。対処法を紹介しましょう。

## SQLで値を指定する

このエラーメッセージは、値を指定すべきカラムに指定されていないことが問題であるため、SQL内で空の値などを指定することで回避することができます。

```
INSERT INTO xxx SET name=’abc’;
↓
INSERT INTO xxx SET name=’abc’, cnt=0;
```

※ cntカラムでエラーが発生している場合

## STRICT_TRANS_TABLESを外す

対処としては、「STRICT_TRANS_TABLES」という設定を変えることになります。MySQLの設定ファイル（my.cnf）を書き換えましょう。

```
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
↓
sql_mode=NO_ENGINE_SUBSTITUTION
```

こうして、データベースを再起動すれば設定が有効になります。

## XAMPPでの my.cnfの変更方法

XAMPPを利用している場合、my.cnfファイルはコントロールパネルから編集することができます。図のボタンをクリックし、「my.cnf」をクリックしましょう。

ただし、XAMPP 7.2に同梱されているデータベースは MariaDB（MySQLと互換性のある別製品）であるため、この問題の対象ではありません。

## MAMPでの my.cnfの変更方法

MAMPを利用している場合は、以下に設定ファイルが存在しています。

```
アプリケーション→MAMP→conf→my.cnf
```

ただし、最初はファイル自体が存在しないため、その場合は新しくファイルを作成し、以下の一文を追加しましょう。

```
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION
```

これにより、標準の設定が上書きされます。サーバーを再起動しましょう。
【Rails】フレンドリーフォワーディング【Rails Tutorial 10章まとめ】

認可機能によって、ログインしていないユーザーが編集ページにアクセスしようとすると、ログインページにリダイレクトされる。
その後ログインするとプロフィールページに移動するが、ここでもともとアクセスしようとしていた編集ページに移動してくれると親切である。
これをフレンドリーフォワーディングと呼ぶ。

##フレンドリーフォワーディングのテスト
フレンドリーフォワーディングは少し複雑なので、テスト駆動開発で進める。
編集成功時のテストを修正する。

```test/integration/users_edit_test.rb
  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_url(@user)
    name  = "Foo Bar"
    email = "foo@bar.com"
    patch user_path(@user), params: { user: { name:  name,
                                              email: email,
                                              password:              "",
                                              password_confirmation: "" } }
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name,  @user.name
    assert_equal email, @user.email
  end
```
編集ページにアクセス→ログインページにリダイレクトしてログイン→編集ページにリダイレクト、という流れになる。

##フレンドリーフォワーディングの実装
###store_locationとredirec_back_orメソッド
ユーザーを希望のページに転送するには、リクエスト時点のページを保存しておく必要がある。

```app/helpers/sessions_helper.rb
  # 記憶したURL (もしくはデフォルト値) にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  # アクセスしようとしたURLを覚えておく
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
  end
```

store_locationメソッドでは、session[:forwarding_url]に、リクエスト先を取得するrequest.original_urlを入れる。
この時、セキュリティ上の問題を解決するために、request.getを使ってGETリクエストの場合のみとする。

redirect_back_orメソッドでは、or演算子||を使って、session[:forwarding_url]がある場合はそちらにリダイレクトし、無い場合は引数のURLにリダイレクトする。
リダイレクト後はsession[:forwarding_url]を削除しておく。

store_locationメソッドを使って、非ログイン時に編集ページにアクセスしたらURLを保存する。

```app/controllers/users_controller.rb
    # beforeアクション

    # ログイン済みユーザーかどうか確認
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end
```

redirect_back_orメソッドを使って、ログイン後に保存したURLにリダイレクトする。

```app/controllers/sessions_controller.rb
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      redirect_back_or user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
```
正規表現　メソッド

#subメソッド

指定部分を別の文字列に置き換えるメソッド

####方法

操作したい文字列を/で囲う

(/ 操作したいメソッド　/)


#matchメソッド

指定した文字列が含まれているかチェックするメソッド


####方法

.match(/チェックする文字列/)

返り値が無い（見つからなかった場合）　=> nil 

一致した場合は配列に入れてあるので０から順に返り値が出ます
macOSのEmacsキーバインドを使いこなそう


## はじめに

最近の若い人は最初に触れるコンピュータがMacという人もいると思います。
そこでぜひ知っておいた方がいいのがEmacsキーバインドです。
このEmacsキーバインドについて軽く書いてみます。
あとオマケとして、ちょっとしたスクリプトも載せておきます。

## Emacsキーバインドとは

Emacsはvi(Vim)と並び、Unix系OSで広く使われているテキストエディタです。
便宜上テキストエディタと書いていますが、拡張性が非常に高く、何でもできちゃいます。
テキストエディタというよりは、今で言うIDE(統合開発環境)に近いものです。

自分はEmacsは使わなくなりましたが、そのEmacsに由来するキーバインドは今でもよく使っています。
macOS以外のEmacsキーバインドが使える有名なものとしては**bash**が挙げられます。

## macOSのEmacsキーバインドの由来

macOSではEmacsキーバインドが使えますが、
その由来はMac OS X・・・ではなく、もっと前にさかのぼります。

それは、Steve JobsがAppleを追われた際に作った会社、[NeXT][]です。
こんなコンピュータを作っていました。

![SA410004.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45169/bf598d21-bac1-c7d4-1152-7970a0fa860f.jpeg)
![SA410007.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45169/96cfe558-ce0d-af5a-1cec-eb06e783d093.jpeg)

このNeXT社の作った[NEXTSTEP][]というOSにEmacsキーバインドが組み込まれていました。

そして時は流れ、1997年にAppleがNeXT社を買収し、
NEXTSTEPはMac OS Xとして~~乗っ取り~~生まれ変わりました。

## Emacsキーバインドが使えるアプリ

macOSのネイティブアプリの基盤となっている、Cocoaを使っているアプリはまず間違いなく使えます。
逆に言えば、Cocoaを使っていないアプリ、
具体的には独自にWidgetを作っているフレームワークでは対応していないことが多いです。
例えばJavaやAdobe AIRで作られたものはダメです。
JetBrains製品は独自に対応していますが、一部標準と違うのでカスタマイズが必要です。

ちなみに、iOSでも外付けキーボードを使えばEmacsキーバインドが使えます。

## 使えるEmacsキーバインド

これだけのキーバインドがEmacs由来(のはず)です。

- カーソル移動
  - Ctrl + F: 1文字右
  - Ctrl + B: 1文字左
  - Ctrl + P: 1行上
  - Ctrl + N: 1行下
  - Ctrl + A: 行の先頭
  - Ctrl + E: 行の末尾
  - Ctrl + Option + F: 1単語後
  - Ctrl + Option + B: 1単語前
  - Ctrl + V: 1ページ前
  - Ctrl + L: カーソルを中央になるようにスクロール
- 削除
  - Ctrl + H: 前の文字を削除
  - Ctrl + D: 後の文字を削除
  - Ctrl + K: 行末まで削除(カット)
  - Ctrl + Y: 貼り付け(yank)
- その他
  - Ctrl + T: カーソル前後の文字を入れ替え
  - Ctrl + O: 改行追加

全部は覚えなくてもいいです(自分も使ってません)が、覚えておくと便利です。

## GoogleスプレッドシートでEmacsキーバインド

Emacsキーバインドではウェブブラウザでも使えます。
しかし不届きものがいました。

それは、Googleスプレッドシートです。Ctrl + Eすら使えません。
これではあまりに使いにくいということで、頑張って対応してみました。
一部動きませんが、だいたい動きます。

- [GoogleスプレッドシートでCtrl + Eを使う(TamperMonkey対応)](https://gist.github.com/ikemo3/c2279be7ba4c5f253acbf42b13280750)

## おわりに

NEXTSTEPの直系のOSが今まで残ってて、
自分がそれを使っているとは24年前には思いませんでした( ´ω`)

[NeXT]: https://ja.wikipedia.org/wiki/NeXT
[NEXTSTEP]: https://ja.wikipedia.org/wiki/NEXTSTEP
ブロックチェーンを書籍で学ぶ

# 概要
「ブロックチェーン仕組みと理論 増補改訂版」
「図解即戦力 ブロックチェーンのしくみと開発がこれ1冊でしっかりわかる教科書」
が全体を理解するのにお勧め。

「ブロックチェーン システム設計」は知っている限り設計視点は本書籍のみ。

どうしても手を動かして上で理解したい場合
「Pythonで動かして学ぶ！あたらしいブロックチェーンの教科書」
がお勧め。

後は目的別です。
「ブロックチェーンの革新技術Hyperledger Fabricによるアプリケーション開発」
「マスタリング・イーサリアム スマートコントラクトとDAppの構築」

他にも多々書籍はあります。
リックテレコム社が良い書籍出しているように思える。

# 書籍 
## 図解即戦力 ブロックチェーンのしくみと開発がこれ1冊でしっかりわかる教科書

技術評論社

- 各キーワード説明
- 課題、最新動向説明あり
- 学習手引き情報あり

## 徹底理解ブロックチェーン ゼロから着実にわかる次世代技術の原則

インプレス

- 各キーワード説明
- 章立て要因なのか読みづらい

# 書籍：プログラミングあり
## ブロックチェーン システム設計

リックテレコム

- 各キーワード説明
- ユースケース
- システム設計視点
- EthereumとHyperledger Fabricでの説明

## Pythonで動かして学ぶ！あたらしいブロックチェーンの教科書

翔泳社

- 各キーワード説明
- Pythonプログラミングでの説明
- Pythonでのプレーンブロックチェーン作成
- 章末問題あり

## 堅牢なスマートコントラクト開発 ブロックチェーン［技術］入門

技術評論社

- 各キーワード説明
- geth(Ethereumクライアントアプリ)での説明
- Etherreum公式ウォレット「Mist Wallet」での説明
- Solidity使用
- スマートコントラクト開発

## ゼロから創る暗号通貨
PEAKS

- Pythonによる「SimpleBitcoin」実装

<a href="https://peaks.cc/">PEAKS Home Page</a>

## ブロックチェーンの革新技術Hyperledger Fabricによるアプリケーション開発

リックテレコム

- 各キーワード説明
- Hyperledger Fabricのアプリケーション開発の説明
- 使用バージョン：1.0.6

## ブロックチェーン仕組みと理論 増補改訂版

リックテレコム

- 各キーワード説明
- 実践編が豊富<br />
Bitcoin Core<br />
Lightning Network<br />
Ethereum<br />
Contract<br />
Quorum<br />
Hyperledger Fabric<br />
Corda<br />

## マスタリング・イーサリアム スマートコントラクトとDAppの構築

オライリー・ジャパン

- 2019/11/30発売、未購入

# 書籍：読み物
## WHY BLOCKCHAIN なぜ、ブロックチェーンなのか？

翔泳社

- 技術説明書籍ではない
- ブロックチェーンの誕生、現状、未来の見解
[Powershell]xmlを比較して一致するものを削除

複数に散らばるxmlの共通部分を消したい。
PowerShellでdiff的なことができる`Compare-Object`は便利だけど、
xmlなんだしそのまま比較して消しゃええやんというわけで書きました


```xml
<?xml version="1.0"?>
<hogehoge>
  <fugafuga name="one">いち</message>
  <fugafuga name="two">に</message>
　<fugafuga name="three">さん</message>
</hogehoge>
```
```xml
<?xml version="1.0"?>
<hogehoge>
  <fugafuga name="ichi">いち</message>
  <!-- attributeとテキストが一致するこやつだけを消したい! -->
  <fugafuga name="two">に</message>
　<fugafuga name="three">スリー</message>
</hogehoge>
```

こちらごらんください。

```powershell
function RemoveCommonNodes($targetPath, $commonPath){
    # xmlを取得
    # ちゃんとエンコードは入れましょう、文字化けでエラーを吐きました
    $targetXml = [xml](Get-Content -Encoding UTF8 $targetPath)
    $commonXml = [xml](Get-Content -Encoding UTF8 $commonPath)

    $commonXml.hogehoge.fugafuga | ForEach-Object{
        # いろいろこねくり回しましたが、結局xpathを使うのが書きやすい気がします
        $targetNode = $targetXml.SelectSingleNode("//fugafuga[@name = '$($_.name)']")
        if($targetNode){
            if($targetNode.'#text' -eq $_.'#text')
            {
                # 自分自身を削除
                $targetNode.OwnerDocument.DocumentElement.RemoveChild($targetNode)
            }
        }
    }
    
    # 保存も忘れず
    $targetXml.Save($targetPath)
}
```

## 参考
https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmlnode?view=netframework-4.8
地図上から緯度経度を指定して経路探索してみよう！

[ヴァル研究所 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/val) 2日目の記事です。今日は緯度経度を指定して経路探索する手順を紹介しようと思います。

## 背景

お客様との打ち合わせや勉強会等で知らない場所に出かけることは多々あります。その際に困るのが、「目的地の最寄り駅には着いたけど、ここからどう移動すればよいの？」という点です。スマホでの地図を見ながら移動していても、意外と目印になる建物を見つけられず、気が付いたら迷子になっていることもあります。

知らない場所に出かけるとは言っても、目的地の場所(住所)はあらかじめ把握できているので、「ココに行きたい！」とだけ指定し、あとは経路探索サービス等で経路を把握したいものです。そこで今回は地図上で指定した緯度経度をもとに経路探索する手順を見てゆこうと思います。

## 緯度経度での経路探索

じつは[駅すぱあとWebサービス](http://docs.ekispert.com/v1/)の経路探索APIでは、出発地・目的地に駅名だけでなく、緯度経度も指定することができます。
例えば、[平均待ち時間探索](http://docs.ekispert.com/v1/api/search/course/plain.html)には出発駅と到着駅を指定する `from` と `to` があり、このパラメータには[座標情報](http://docs.ekispert.com/v1/dictionary/coordinate-information/)として緯度経度を指定することができます。サンプルとして高円寺のヴァル研究所から東京駅の八重洲口付近までの経路探索は以下のようなAPI呼び出しになります。

```
https://api.ekispert.jp/v1/json/search/course/plain?key=<アクセスキー>&from=35.70606813177083,139.651624325722,wgs84,2000&to=35.68042009453629,139.7690262983716,wgs84,2000
```

緯度経度を指定する際には、測地系に注意してください。駅すぱあとWebサービスでは[日本測地系と世界測地系](https://www.gsi.go.jp/sokuchikijun/datum-main.html#p5)のどちらかの指定が可能です。デフォルトでは日本測地系となっているため、GoogleマップやOpenStreetMapを扱うような地図ライブラリの測地系(世界測地系)と混在してしまうと、正しく緯度経度の指定が行えないことになります。
世界測地系を指定する場合は、 `<緯度>,<経度>,wgs64,<半径(m)>` のような形で指定してください。

## 地図上で緯度経度を指定して経路探索してみる

経路探索APIのパラメータに緯度経度を指定可能であることは分かりましたが、これを人間が毎回指定するのはちょっと大変です。そこで簡単なサンプルとして、地図をクリックすると、その緯度経度を取得して経路探索するアプリを作成してみました。

 * 緯度経度から経路探索するサンプル
   * https://vallaboratory.github.io/advcal_gh_pages/2019/1202/index.html

動作イメージは以下になります。緯度経度を指定して探索する便利さ(？)が見えてくるような気もします。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152217/3312faa0-fc98-826a-5ea8-06e0036da6d1.gif)

### 補足：駅すぱあとWebサービスのアクセスキーを入手する

APIを使用するためにはアクセスキーが必要ですが、個人ユーザ様においては[Amazon SaaSストア](http://www.amazon.co.jp/saas/)からアクセスキーを購入するという方法もあります。SaaSストアでのアクセスキー購入については、過去の記事で紹介していますので興味のある方はご参照ください。

 * [SaaSストアで駅すぱあとWebサービスを購入する](https://qiita.com/valsitoh/items/966ead6c0b27fad7b27a)

## まとめ

駅すぱあとWebサービスで緯度経度を指定した経路探索を行う方法を紹介しました。APIのパラメータとして緯度経度を指定する方法はちょっと大変ですが、地図ライブラリと組み合わせることでユーザにも使いやすい経路探索アプリが作成できそうです。
初心者によるプログラミング学習ログ 174日目

# 100日チャレンジの174日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

174日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>174日目<br><br>今日も今日とてwebサイトコーディングの課題<br>細かいところはおいといて、TOPの次のページを9割完成<br><br>いつもより進んだ感あるけど、たぶんみんなはもっとふつうに早いと思うｗ<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1201233769031553024?ref_src=twsrc%5Etfw">December 1, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【C++】オブジェクト指向の勉強 003

# 初めに
記事投稿にまだ慣れないので文末表現やら文章書くところで余計に時間がかかってしまう...

# 今回の内容
* コンストラクタ入門

参考ページ：[コンストラクタ(C++) - 超初心者向けプログラミング入門](https://programming.pc-note.net/cpp/constructor.html)


# コンストラクタ

まずは[【C++】オブジェクト指向の勉強 001](https://qiita.com/koralle/items/d7c6fb50b3ae09393ed9)で書いたこのクラス定義。

```cpp
class SimpleClass {
private:
    int number;
    string name;
public:
    int getNumber(void) {
        return number;
    }
    string getName(void) {
        return name;
    }

    void setNumber(int n) {
        number = n;
    }

    void setName(string s){
        name = s;
    }
};
```

実はこのサンプルコードには問題点がある。参考ページにはこうある。
> このクラス定義は、メンバ変数が初期化される前にアクセスしてしまう危険性があります。

つまり上のコードだと、生成したインスタンスの各メンバ変数に対してgetterでアクセスする前にsetterで初期化しておかないとバグの原因になる。

```cpp
int main(void){
    SimpleClass sc; // sc.nameは未定義
    std::cout << sc.getName() << endl; // ???????
}
```

だけど毎回「getterの前にsetter書かなきゃ...」なんて呪文のように唱えながら実装しているといつか忘れる日がやってくる。**どうせならインスタンスの生成の度に自動でメンバ変数を初期化してほしい。**

そこで**コンストラクタ**を使う。コンストラクタはメンバの変数の初期化を含め、**インスタンスの生成したタイミングで「確実に」実行してほしい処理**を書く。
(メンバ変数の初期化以外で何書くのかな、まだあんまりよくわかってない...)

そこでコンストラクタを実装して改良したのが次のコード。

```cpp:class003.cpp
#include <iostream>
#include <string>

using namespace std;

class SimpleClass {
private:
    int number;
    string name;
public:
    // コンストラクタ
    SimpleClass(void){
        number = 0;
        name = "koralle";
    }

    int getNumber(void) {
        return number;
    }

    void setNumber(int n) {
        number = n;
    }

    string getName(){
        return name;
    }

    void setName(string s) {
        name = s;
    }
};

int main(void) {
    // インスタンスの生成 => コンストラクタが「確実に」実行される
    // コンストラクタ内にはメンバ変数の初期化処理が含まれる
    // => setterを実行しなくてもメンバ変数にアクセスできる。
    SimpleClass sc;

    // sc.nameは"koralle"で初期化してるのでアクセスが可能。
    cout << sc.getName() << endl;
    return 0;
}
```

ちゃんと実行できる。

```
>class003
koralle
```

コンストラクタ実装時に絶対守るべき約束は以下の二つ。

```
* コンストラクタ名はクラス名と同じ
* 戻り値は「何も」書かない(voidすらNG)。
```

因みにこのプログラムを実行した後に知ったが、string型はクラス定義が存在するからコンストラクタで初期化しなくても空文字で初期化されるらしい。今回は空じゃない文字列で初期化したかったのでこのコードはok。

参考ページにはコンストラクタについて以下のような説明もあった。
> コンストラクタは通常のメンバ関数とは違い、後から呼び出して使用することはできません。
インスタンスの生成時にのみ呼び出せる特殊な関数です。
コンストラクタ内の処理は自由ですが、インスタンス生成毎に呼び出されるので、メンバ変数の初期化等に留め、あまり重い処理はしないようにしましょう。

とあるのでコンストラクタを試しにインスタンスの生成後に呼び出してみようとしたらコンパイルエラーになった。当然。

```
class003.cpp: In function 'int main()':
class003.cpp:42:8: error: invalid use of 'SimpleClass::SimpleClass'
     sc.SimpleClass();
        ^~~~~~~~~~~
```

# 終わりに

早く記事書くのに慣れたい。
ドローンを活用した避難勧告システム

# はじめに
ドローンを使ったシステムの考案をします．実用的な運用を目指したシステムの開発を目指します．ただの提案だとつまらないので実際に動かすところがゴールです．
*ドローンで救える命がある*

#背景
日本における自然災害は年々増加傾向にあり，人的被害や金銭的被害への対策が求められている．また，自宅を安全だと思い込み避難しない人は多く，よりパーソナルに危機感を煽る方法が模索されている．西日本豪雨の被災者310名に行ったNHKのアンケートでは対人的な呼びかけで避難をするきっかけになった人は全体の約3割存在している．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234751/0d5ec4ea-7208-3b87-014c-f69c5477f6a4.png" width="60%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234751/a7895de0-af25-5e34-fc3b-75adf5144883.png" width="40%"><a href="http://nav.cx/3x1Lkq0">

#考案システム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234751/3cb4fc06-e4e6-6aa6-6dd4-c85e855edc77.png" width="100%"><a href="http://nav.cx/3x1Lkq0">

上記のようなドローン巡回システムを考案する． 災害発生後または災害中にドローンは被災者や被災予備軍を捜索する．人を見つけ次第，人と対話し，自力で避難可能かを判断する．対話方法としては音声解析，画像解析，姿勢解析を用いてフィードバックを行う．自力で避難可能な人には**避難勧告**を行い，身動きがとれない人や高齢者や身体的に不自由な人(避難困難者)には**救助要請**を行う．


# 開発環境
macOS Mojave
AWS
Python2系3系
[telloドローン](https://www.apple.com/jp/shop/product/HMBE2J/A/ryze-tello-edu-drone-powered-by-dji)
Alexa(スピーカーデバイスがなくてもOK)


# 開発順序
開発にはいくつかのフェーズに分けて行うこととする．(システム要件は今後増やす可能性はあり)
記事の続きとして各リンクを参照すること
0章はおまけ

0 . [位置情報から周囲の避難場所を提示するシステムの構築](https://qiita.com/sk_nimo/items/7866ce584d7c9ef40329)
1 . [【AWS×ドローン】声でドローンを操作してみたPart1]
(https://sho-d-blog.com/tech/131/)
2 . [【AWS×ドローン】声でドローンを操作してみたPart2]
(https://sho-d-blog.com/tech/172/)
3 . [【AWS×ドローン】声でドローンを操作してみたPart3]
(https://sho-d-blog.com/tech/194/)
4 . [【AWS×ドローン】ドローン対話システム応用事例]
(https://sho-d-blog.com/tech/278/)
プルリクがどれくらい巨大になっているか知りながら仕事しよう

<img width="1142" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66421/40b19bdd-7769-8cd3-105f-158bfd756749.png">

この記事は [ギフティ Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/giftee) 2日目の記事です。

# 背景

つい夢中になって開発していたら、変更箇所が多岐にわたってしまい、レビュワーを面食らわせた・・・こんな経験、誰もが一度はあるのではないでしょうか？プルリクの粒度については色々な意見があるかと思いますが、「巨大すぎるプルリクはレビューの精度を下げるのでよくない」という認識はそれなりに一般的なものだと思います。

とはいえ、「プルリクが大きくなりすぎないように常に **気をつけましょう** 」という改善ほど意味のないものはありません。改善は常に具体的なアクションであるべきです。どうすれば同じ失敗を繰り返さずに済むでしょうか？

# 改善案 : 変更量を継続的に知ろう

先に結論を書くと、ローカルで `git commit` するたびに、作業ブランチとマージ先ブランチの差分量を表示するようにしてみました。

```
===================================================================
develop ブランチとの差分 :

 lib/foo/bar.rb    | 15 +++++++++++++++
 lib/foo/baz.rb    | 11 +++++++++++
 lib/foo/corge.rb  | 28 ++++++++++++++++++++++++++++
 lib/foo/foo.rb    |  6 ++++++
 lib/foo/fred.rb   | 11 +++++++++++
 lib/foo/garply.rb |  1 +
 lib/foo/grault.rb |  4 ++++
 lib/foo/plugh.rb  | 10 ++++++++++
 lib/foo/quux.rb   |  2 ++
 lib/foo/qux.rb    |  7 +++++++
 lib/foo/thud.rb   | 11 +++++++++++
 lib/foo/waldo.rb  |  6 ++++++
 lib/foo/xyzzy.rb  |  4 ++++
 13 files changed, 116 insertions(+)

ファイル変更数が 10 を超えました。そろそろプルリク出しませんか？
===================================================================
```

このアクションを思いついたときに考えていたのは、今の作業ブランチの変更量を知る機会が少なすぎないか？ということです。例えば、今の作業による `Files changed` の数を、プルリク作成前に見る機会はどれくらいあるでしょうか？ CLI だと、コミットしたときに「そのコミット単体の変更量」は表示されますが、「そのブランチ全体の変更量」は表示されません。これがもし `git commit` のたびに表示されれば、スコープの肥大化にいち早く気づき、キリのいいところで作業を止めて、適切な粒度でプルリクを出せそうです。

実装方法は簡単で、手元のリポジトリの .git/hooks/ 配下に、 post-commit というファイル名で、以下のスクリプトを保存するだけです（手元の Mac で確認しました）。

```sh
#!/bin/sh

TARGET="develop"
GITDIFF=`git diff --color --stat-width=800 $TARGET HEAD`
THRESHOLD=10

echo "==================================================================="
echo "$TARGET ブランチとの差分 :"
echo ""
echo "$GITDIFF"
if [ $(echo "$GITDIFF" | grep -v "changed" | wc -l) -gt $THRESHOLD ]; then
    echo ""
    echo "ファイル変更数が ${THRESHOLD} を超えました。そろそろプルリク出しませんか？"
fi
echo "==================================================================="
echo ""
```

もちろん、ファイル変更数が規模の全てではないとは思いますが、目安としては今のところ十分活用できています。導入も廃止も簡単なので、よければぜひ活用してみてください。

# ちなみに

GUI の Git アプリだと毎回表示されてたりするんでしょうか・・・。
はじめてのECS（Fargete）

#はじめに
ECSの動きがドキュメントで読んだだけではわかりにくかったので、動かしながら試して行こうと思います。
ECSってなんだかコンテナだし難しそう！って思ってたのですが、**サンプルは「次へ」押していくだけで完成します。**
動かしたほうが理解しやすいので、まだ触ったことない方はお薦めいたします。
**`htpd`コンテナが実際に動いてブラウザで画面が見えるところまで確認していきます。**
所要時間：15～20分です。

# 手順

- まずは、「今すぐ始める」を選びました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/a6dccb7b-9969-ef87-3549-c3720b72e6fb.png)

## コンテナとタスク

### コンテナの定義
- まずは「コンテナの定義」です。図の一番内側です。
- 使用する`docker image`を決めます。
- ようく見ると、`httpd:2.4`のイメージを利用し、0.5GBのメモリ予約、0.25のvCPU（1/4コア）予約されていることがわかります。
- そのまま「sample-app」を使うことにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/837ddbf0-ac05-bcf4-137c-7d57f86d70c8.png)

### タスク定義

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/a702b5b7-6e99-68aa-f0ab-6e9d20c8500a.png)

- 次は「タスク定義」です。図ではコンテナの１つ外を囲っています。
- `first-run-task-definition`という定義名はVPC内で動作し、ECSの実行ロールが付与され、`fargate`の実行タイプのが選択されています。
- タスクサイズは1つのタスクレベルの設定値で割り当てられているタスクメモリとCPUが請求対象になってきます。
- Lambdaと違い、メモリとCPUのパワーは別に設定できるようになっています。
- 今回はそのまま設定値を利用することにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/5a601e01-43e7-6b23-180a-a1e704b428bf.png)

## サービス

### サービスを定義する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/78b2440f-1018-7d27-3dc4-a5813c29b47e.png)

- タスク定義されたものにサービスを関連づけましょう
- 同時実行する必要数のインスタンスを維持できます。
- ALBとの連動ができます。APIのコンテナなんかはALBと連動させるのでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/9032da72-ba0f-8c3c-c2f5-e0624544d13d.png)

## クラスター
### クラスターを定義する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/2d5b37df-2448-0208-9d67-e84ca80bacfa.png)

- いよいよ最後に近づいてきました。
- クラスターを設定します。
- 今回は、クラスター名を設定するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/86471da3-df40-25d1-0617-8e5e6ce6b668.png)

# 作成

- 10分ほど待てば完成します。実際にはそんなに待ちません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/b8286ea0-5753-75c7-425a-760db6dc344a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/7d8c6ef4-fbd3-baec-c021-80a34d3e94d2.png)

# 動かしてみる

- クラスター`default`ができていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/f0bc21f3-c333-6cc2-5327-2ebc04bae2b2.png)

- タスクから実行中であることが確認できたでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/e148b662-735c-d783-c221-d7cc2d2a3b1c.png)


- ENIが設定されていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/38972ba7-1ff0-7a64-4527-4fc257768cc9.png)

- 割り当てられているIPアドレスを確認し、アクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/af8369c0-92a6-5a0f-60e0-d178b7ec1bd1.png)

- `httpd`イメージのコンテナにアクセスすることができました。Congratulations!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/62cfbc40-36e6-af49-28f5-52937ed593a3.png)

# さいごに
- サンプルだったため、本来考えなければならない箇所を大幅に省略しています。
- ここから、実際に作るとしたら何が足りないのか１つずつ埋めていけば理解が深まっていくと思います。
Python初心者がマイクロフレームワークFlaskを使って30秒でHello Worldしてみた


## Flaskとは
- PythonのマイクロWebフレームワーク
- 標準で提供されている機能は最小限
- フルスタックフレームワークなら[Django](https://docs.djangoproject.com/ja/2.2/)とか
- 参考
    - [PythonのWebフレームワーク4種比較](https://qiita.com/Morio/items/8db3c9b3ba7f2c71ef27)

## about me
### Python歴
3日

### やった理由
楽しそう

## やったこと
**①Flaskインストール**

```sh
pip install Flask
```

**②好きなフォルダに```hello.py```を作る**
**③以下を貼り付ける**

```py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello World!"

if __name__ == '__main__':
    app.run()
```

**④実行**

```sh
python hello.py
```

**⑤ http://127.0.0.1:5000/ にアクセス**
<img width="945" alt="スクリーンショット 2019-12-02 20.00.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191739/43d04d36-7d3f-af9d-a10b-15b5fc76096a.png">

## 参考
[Flask](https://a2c.bitbucket.io/flask/)
『すべての記事』へのリンクが消滅した

2019/12/02、Qiitaのデザインが変更になりました。

それまで申し訳なさそうにフッタの隅っこに配置されていた[すべての記事](https://qiita.com/items)へのリンクですが、ついに完全抹消されました。
もはやQiitaの公式リンクから辿り着く方法はないと思われます。

スパム汚染が深刻とは言え、どんだけ時系列順見せたくないんだよ。

時系列一覧が見れなくなると、新人がマイナージャンルに投稿した場合に全く誰にも見られなくなるんですが、それでいいんですかね。
人気タグへの集中がますます増えそうです。
emmetでrailsのコードを書くときの「.」の入力法を教えてください

エディターにatomでemmetを使用しているのですが、「<% ～ %>」のなかで「.」(ドット)を打ちたい時に打とうとすると
emmetのショートカットが作動して、勝手に「class=""」と変換されてしまって打てません
皆さんはどのようにしておられるのでしょうか？

例　<%= @post %>
　　と書いていたところを追加変更して
　　<%= @post.title %>
　としたい時に
　　<%= @postclass="" %>
　　というふうになってしまう
Mixinを使う

##Mixinって何に使うやつ？

* 内部にCSSのプロパティ群を持つことができる。
* 共通のCSSを一元管理したい時に便利。

##SCSSでかく
```scss:SCSS
//mixin設定
@mixin hoge($argmentWidth: 10px) { //引数を渡さない場合は$argmentWidthは10px(デフォルト値)
  width: $argmentWidth;
  .add {
    @content; //mixin使用先でプロパティを記述したい場合に使用
  }
}

//mixinを使う対象
.target1 {
  @include hoge(5px) {
    //@contentに代入
    display: inline-block;
  }
  height: auto;
}

.target2 {
  @include hoge {
    display: inline;
  }
  height: 0;
}
```

##CSSにすると…
```css:CSS
.target1 {
  width: 5px;
  height: auto;
}

.target1 .add {
  display: inline-block;
}

.target2 {
  width: 10px;
  height: 0;
}

.target2 .add {
  display: inline;
}
```


##こんな場所に使う

###レスポンシブのメディアクエリに

```scss:SCSS
//mixin設定
@mixin sp($breakPoint: 768px) {
  @media screen and (max-width: $breakPoint) {
    @content;
  }
}

//mixinを使う対象
.target {
  max-width: 960px;
  @include sp(560px) {
    max-width: 100%;
  }
}
```
```css:CSS
.target {
  max-width: 960px;
}

@media screen and (max-width: 560px) {
  .target {
    max-width: 100%;
  }
}
```

ブレークポイントを弄るのはあまりよくないかも…
引数のところは変数とかで共通化しよう。

##最後に


みなさんMixinをどのように使っていますか…？
MySQL 8.0.18でパスワードリセットしてもrootユーザにログインできなくなった時の解決方法

# 目的

- 何をしてもMySQLのrootユーザにログインできなくなった時の解決方法を書く

# 結論

- MySQLをアンインストール→インストールしてrootユーザのパスワードを再登録した。

# 実施概要

1. MySQLのファイル削除とアンインストールとインストール
1. パスワードの再設定とログイン確認 

# 実施詳細

1. MySQLのファイル削除とアンインストールとインストール
    1. 下記コマンドを実行してMySQLのファイルを削除する。(DB内のデータも消すことになるので注意！何もせず下記コマンドを実行するとデータベースに保存されている内容が全て吹き飛ぶ)

        ```terminal
        $ sudo rm -rf /usr/local/var/mysql
        ```
 
    1. 下記コマンドを実行してMySQLをアンインストールする。

        ```
        $ brew uninstall mysql
        ```

    1. 下記コマンドを実行してMySQLをインストールする。

        ```
        $ brew install mysql
        ```
1. パスワードの再設定とログイン確認
    1. 下記コマンドを実行してMySQLを起動する。

        ```
        $ mysql.server restart
        ```

    1. 下記コマンドを実行してMySQLに入る。

        ```
        $ mysql -u root -p 
        ```

    1. 下記コマンドを実行してパスワードを設定する。

        ```
        mysql>USE mysql;
        mysql>ALTER USER 'root'@'localhost' identified BY '任意のパスワード';
        ```

    1. 下記コマンドを実行してMySQLを抜ける。

        ```
        mysql>exit
        ```

    1. 下記コマンドを実行後、パスワードの入力を求められるため入力してログインできるか確認する。

        ```
        $ mysql -u root -p
        ```

    1. 下記のようになればOKである。

        ```
        mysql>
        ```

    1. あとはcreateしてmigrateすればテーブル構造は元どおりになる。
【2日目】RDBMS実装戦略

# まえがき
まずは、RDBMSを実装するまでの、実装戦略(?)について説明します。実装戦略としては小さいシステムから徐々に機能拡張して大きくしていこう、という話をしました。具体的には3段階に分けてステップアップしていく予定です。ホップ・ステップ・ジャンプ戦略です。
1. シンプルデータベース
2. トランザクションサポートデータベース
3. リレーショナルデータベース

## シンプルデータベース
シンプルデータベースは、データをインメモリで保持するキーバリューストアである。単発のCRUD処理ができる。少しイレギュラーな実装かもしれないが、データへのアクセスはDB側で振り出すオブジェクトIDのみでしか許されない。そのため、各カラムに対して、カラムの値からオブジェクトIDへのマップを保持する。シンプルデータベースでは、

* テーブルを作成する
* データを挿入する
* データを取得する
* データを更新する
* データを削除する
* テーブルを削除する

といった操作ができれば十分。
（初めて触るErlangと格闘するためのフェーズでもある。）

## トランザクションサポートデータベース
トランザクションサポートデータベースはその名の通り、トランザクションの機能をサポートする。具体的には、複数のSQL文をAtomicに実行できる。もし、障害が発生したら、その直前までにコミットされたデータは守られているし、コミットされていないトランザクションはロールバックする、などなど。いわゆるACID特性をサポートする。データの永続化、ログ書き込みなんかが必要になる予定。巨大システムにおいてRDBMSを使う大きな理由は、トランザクション機能をアプリではなくDBにやらせたいから、だと思うので、トランザクションサポートはRDBMSの中核機能と考えられる。ここをどう実装するかが一番面白いと思う。（2日目時点で実装方針すら考えられておらず。。助けて。。。）

## リレーショナルデータベース
最終段階はリレーショナルデータベースって言えるように、ユーザーとかスキーマとかビューとか、テーブルジョインの効率化とか、少し複雑なSQLでも実行できるとか、キーの制約とか、カラムドメインの制約とか、あとはマイRDBMSのための特別な機能を盛り込む予定。（無理予定）

# まとめ
思考段階での実装戦略について説明しました。段階踏んでいかないと迷子になると思ったので笑
果たしてこの戦略でうまくいく保証かわかりませんが、それもお楽しみです！
そのマイグレーション、戻せますか？

Railsを使うときに、マイグレーションは便利ですが、戻すときのことまで考えて実装していますでしょうか。

## `bin/rails db:rollback`
`bin/rails db:migrate`でマイグレーションを実行できますが、逆に`bin/rails db:rollback`で戻すこともできます。ただし、マイグレーションが戻ることを前提にしている必要があります。

## 考えなくて良いパターン

`create_table`や`add_column`など追加系のメソッドを`change`に書いていた場合、逆向きは「追加したものを削除する」ことが明らかですので、自分で書かなくても対応してくれます。

## 戻し方を書けば対応してくれるパターン

`drop_table`や`remove_column`を行う場合、ただ削除する内容を書くだけでは、戻し方がわかりません。そこで、これらのメソッドは`create_table`や`add_column`と同様に元の定義を書けるようになっています。ロールバック時にはそれが使われます。

* [drop_tableでテーブル削除マイグレーションする時の良い子・悪い子・普通の子](https://qiita.com/YumaInaura/items/05949d99b42516716685)
* [Railsからカラム削除するときにも型を書くと幸せになれるというお話](https://qiita.com/HiromiKai_Green/items/7cedfdabbf7db750fc8c)

## 戻さない・戻せないパターン

たとえば、`NULL`の列を`NOT NULL`に変えるとか、`utf8`だった列を`utf8mb4`に入れ替えるとか、`int`の列を`string`に変えるとか、値域を広げる方向にマイグレーションをかけた場合、元に戻そうにも広がった後のデータが入らないことがあるので、戻しようがありません。

このような場合は`up`だけ書いて、`down`は`raise ActiveRecord::IrreversibleMigration`とすることで、「戻せない」ことをコードで明示できます。

また、現実問題としてデプロイ後にマイグレーションをロールバックするような運用は通常行いませんので、ある程度以上複雑なマイグレーションを書いた場合に、戻す方まで厳密に書かずに`raise ActiveRecord::IrreversibleMigration`で済ます、という手段も、状況によってはありかもしれません。

## 戻す側が不要になる場合

時には、戻す側で何もしなくていいことがあります。たとえば、「あるカラムに空文字列と`NULL`が混在しているので、全てを一方に揃える」というようなマイグレーションを立てたとします。これの`down`側は、特に何もしなくても元のデータと整合するので、放置して構いません。このような場合、

```rb

def down
  # 戻す側で何もしなくていい理由
end
```

のように、コメントで間違いではないことを明記しておきましょう。
DynamoDB移行小話〜移行の恩恵及び注意点〜

## はじめに：
弊社で開発しているプロダクトのデータベースについて、オンプレのRDBからAWSのNoSQLDBであるDynamoDBに移行しましたので、移行を経験した上で得た恩恵と移行の注意点についてお話しさせて頂きます。


## DynamoDB移行による恩恵
今回移行対象となった記録データはユーザとともに増加傾向であり、大量のデータ保管が可能なAWSとの相性は良好でした。
本項では移行を行なったことで得られた恩恵について紹介いたします。

---

### スケールアップが容易に
DBへの負荷への対処がオンプレに比べて容易なのが最大の恩恵となりました。
テーブルサイズにも実用的な制限がないのも魅力です。

### オンプレDBと比べてカラム追加が簡易的
基本的に「入れれば入る」ようになっており、カラムについても数値や文字列などの基本的なものからJsonや配列まで使用可能です。

ただしカラム単位での削除ができないので、施策を入れる時に

- 事前の設計
- 今後の追加開発での考慮

がないと**参照しないで無駄にサイズを圧迫するデータを生むだけ**なので気軽に追加ができるとはいえ注意が必要です。

### 各種AWSサービスとの連携
データをs3に保存し、Lambdaによる定期集計を実施するなどが可能になります。
移行によって実施できた施策も多々有ります。

---
AWS初心者で時間こそかかりましたが移行によるメリットは十分あったと思います。

## DynamoDB移行における注意点
DynamoDBに移行するにあたり、考慮が必要な点について解説いたします。

### 検索機能が独特
実施可能な検索方法が

|    キー    |    実施可能な検索条件    |
|:-----------------:|:------------------:|
|    パーティションキー    |    完全一致    |
|    ソートキー    |    =、<、<=、>、>=<br>Between、BeginWith（前方一致）    |


と独特な検索条件となっており、これを踏まえた設計が必要になります。

例：

- 「2019年４月のデータのリストが欲しい」場合は日付を20190401のような数値に設定してBetween等で範囲検索して絞る
- 文字列での部分一致検索は出来ないのでリストを取ってきた後で別途絞る処理を入れる

### 一括での更新や削除ができない
NoSQLのため、まとめて更新や削除ができず、１件ずつ処理する必要があります。
更新対象リストを取得し、そのリストに対して１つずつ処理を適用していく形になると思います。

### 予約語
DynamoDBには予約語があり、これらの単語を使ってscanするとエラーになってしまいます。

予約語一覧：
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ReservedWords.html

DynamoDBにて設定可能なTTL（Time To Live）も予約語なので、使用する場合は名称に気をつけるか、下記のようにwithNameMapを経由してあげる必要があります。

```java:javaでの一例
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
                    .withPrimaryKey(
                            "id", Id,
                            "targetDate", targetDate)
                    .withUpdateExpression("set #t = :ttl")　←#tがttlだとエラーになる
                    .withValueMap(new ValueMap().withLong(":ttl", ttl))
                    .withNameMap(new NameMap().with("#t", "ttl"))　←これを追加
                    .withReturnValues(ReturnValue.UPDATED_NEW);
```

### 最大サイズの存在
移行において一番キモである「既存データのコンバート」において立ちふさがるのが最大項目サイズの存在です。
**DynamoDBの最大項目サイズは400KB**と制限されており、

- 移行後から登録されるデータ
- 移行元のデータ

の２点においてこの制限に引っかからないデータ設計が必要となります（特に**移行元のデータ量が多い場合の想定**が必須）

仮に入れるデータ量が多く、４００KBをオーバーする場合は


- **バイナリ型を使用する**
    - DynamoDBで完結するが結局最大サイズという問題がのしかかる
   
- **s3に別途データを設置してパスをDynamoDBで持つようにする**
    - 管理箇所が増えるが、シンプルでわかりやすい


といった工夫によって最大項目サイズの削減を行うことができます。

最大項目サイズを考慮して最初に十分な時間をかけて移行のための設計を行わないと制限に引っかかり、急遽データ構成を変更、なんてことも起こり得ます。

この最大項目サイズは移行が済んだ後でも当然意識する必要があるので、施策等で新しいカラムを追加する際にも注意が必要です。

## 最後に
DynamoDB移行はメリットがある分独特な特性を持ち、移行前後のデータ保証と共に今後のデータの利用方法もある程度予測しての設計が求められるので、移行の際は入念な設計とレビューが大事と感じました。

この記事が今後AWSへのデータ移行を行う方の参考になれば幸いです。
Laravelにてテーブルの既存カラムをtinyint型に変更できない問題

## 環境
- Laravel 5.7.28
- MySQL 8.0.17

## 遭遇した問題
DBの容量を節約するため、**既存**カラムのデータ型をintからtinyintに変更するマーグレーションを実行した際、下記のようなエラーが表示された。
<img width="1010" alt="スクリーンショット 2019-12-02 18.37.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/f941a469-bf48-cd44-d1a3-0a6d60265e7f.png">
「**tinyinteger**なんてカラム型はないよ」と怒られているので、「あ、マイグレーションファイルに**tinyInteger**ではなく**tinyinteger**とタイピングしちゃったかな」なんて思って確認してみるも、間違っていない。

ちなみにマイグレーションファイルの中身は以下のような感じです。

```php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class ChangeContactTypeOfUsers extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
          $table->tinyInteger('contact_type')->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('contact_type')->change();
        });
    }
}
```

## 原因
[Laravel公式ドキュメントのMigrationの項](https://laravel.com/docs/5.7/migrations)を当たってみると、以下の通り。
<img width="597" alt="スクリーンショット 2019-12-02 18.44.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299210/23f8e241-e9fa-7717-e0de-c9eee545f90d.png">

>*Only the following column types can be "changed"*

の部分を和訳すると、「以下のカラムの型のみが変更可能です」となります。
試してみたところ、tinyintから別の型に変更することはできましたが、逆にtinyintには変更できませんでした。
つまり、**Laravelではカラムの型をtinyintに変更することはできない**ということです。

また、例えばtinyintからintに変更するマイグレーションが通ったとしても、ロールバック時にはコケるので、tinyint型のカラムの型変更は行わないほうがよいでしょう。

tinyintに変更することで、格納可能サイズを超過するデータが生じる恐れがあるため、このような仕様となっているのでしょうか。
詳しい方いらっしゃいましたらコメントにてご教授いただけると幸いです。

## 対処法
一旦該当カラムをドロップし、再度tinyint型として追加することで対処しました(この時点では未使用のカラムだったので)。
結局、型変更のために2つのマイグレーションファイルの作成が必要になってしまいました。

※2019/12/4 追記
職場の方にご指摘いただき気付いたのですが、DBファサードを利用してSQLクエリを実行すれば解決する問題でした。

```php
DB::statement("alter table users modify tel_type tinyint;");
```

## 学び
テーブルを作成する際には、格納され得るデータを予め想定し、適切にデータ型を決定する必要があるということを学習しました。

## 参考文献
- [Database: Migrations - Laravel - The PHP Framework For Web Artisans](https://laravel.com/docs/5.7/migrations)
- [データベース：利用開始 5.7 Laravel](https://readouble.com/laravel/5.7/ja/database.html)
VagrantにSpring Bootの開発環境作成

## 概要
通常Spring BootにはTomcatが付いており、Java自体がJVMで動くのでローカルで作業出来るのですが、Javaから別のツールの操作を行うためVagrant上に環境を作成しました。

## 環境
OpenJDK 11
Maven 3.6.3
CentOS 7

## JDK
```
yum update -y nss curl libcurl  // 古いのでアップデート

touch /etc/yum.repos.d/adoptopenjdk.repo
echo [AdoptOpenJDK] >> /etc/yum.repos.d/adoptopenjdk.repo
echo name=AdoptOpenJDK >> /etc/yum.repos.d/adoptopenjdk.repo
echo baseurl=https://adoptopenjdk.jfrog.io/adoptopenjdk/rpm/centos/7/x86_64 >> /etc/yum.repos.d/adoptopenjdk.repo
echo enabled=1 >> /etc/yum.repos.d/adoptopenjdk.repo
echo gpgcheck=1 >> /etc/yum.repos.d/adoptopenjdk.repo
echo gpgkey=https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public >> /etc/yum.repos.d/adoptopenjdk.repo
yum -y install adoptopenjdk-11-openj9.x86_64
java -version
```

## Maven
```
wget http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
tar xf apache-maven-3.6.3-bin.tar.gz -C /opt
ln -s /opt/apache-maven-3.6.3/ /opt/maven
touch /etc/profile.d/maven.sh
echo "export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-openj9" >> /etc/profile.d/maven.sh
echo "export M2_HOME=/opt/maven" >> /etc/profile.d/maven.sh
echo "export MAVEN_HOME=/opt/maven" >> /etc/profile.d/maven.sh
echo 'export PATH=${M2_HOME}/bin:${PATH}' >> /etc/profile.d/maven.sh
rm apache-maven-3.6.3-bin.tar.gz
```

## 起動
```
$ mvn spring-boot:run
```

## 感想
VagrantにrsyncでソースをマウントしてSpring Boot Devtoolsを入れていれば、ホットリロードが出来るので、快適に動かせました。

## 参考
https://knasmueller.net/spring-boot-development-environment-virtualbox
IAM本を読んでみた

ちょっと時が過ぎましたが書評を書いてみようかと。
ちなみに自分は物理本派です。

---

IAM（Identity and Access Management）の話です。

作者の佐々木さん(@dkfj)はAWS関係で、色々な書籍を出されており、先日も執筆されたAWS試験対策本のおかげ（他2つ含む）で、
AWS Certified Solutions Architectに見事合格することができました。
その話は以下にて、
[AWS Certified Solutions Architect 受験記](https://qiita.com/keni_w/items/9f2cdda4a6dad636e239)

その佐々木さんが技術書典で本、しかもIAMに関する本を出されるとのこのことで、

IAMってAWSでは結構重要な機能ではあるものの、特化した本ってなかったなと思って、技術書典自体も初参戦でしたが、参戦して、ゲットしてみました。

---

基本的なルール、

rootは使うな、MFAは設定すべし、キー情報は公開する

などは、守っているものの、ちゃんと理解してない点があったなと読んでいて思いました。

デザインパターン（名前は佐々木さん命名？って言っていた気がする）については、

- ホワイトリストパターン
- ブラックリストパターン
- ハイブリッドパターン

について、それぞれ、メリット、デメリット書かれておりますが、
実際、関わっていた案件で、
ホワイトリストパターンで運用してるロールがあって、
ロールに設定していなかったサービスを見ようと思ったら、参照すらできず、
悲しみに打ちひしがれていた（大袈裟）のですが、
なるほど、これがホワイトリストのデメリットかと
そして、ハイブリッドパターンがいいだなと実感しました。

CloudFormationでIAMを管理するというのは、結構目から鱗でした。
そして、CloudFormationちゃんと使ったことがなかったので（Serverless Framework等で裏で動いているのは知ってる）、
勉強がてら、使ってみたいですね。

テンプレート集は、実務にも使えそうで、よかったです。
個人アカウントはお一人様アカウントですが、
普通にAdministrator権限ついたユーザーで作業してますが、
はい。すみませんって感じでした。
この辺は今後見直します。

---

IAM本を読んだという同僚に聞いたところ、

- すごい読みやすい本でした。
- やっぱそうだよね〜〜って内容が多かったので、安心感が得られてよかったです

とのことでした。

---

次の技術書典でも本を出されるということでなので、
また買いに行きたいですね。

なお、今回のIAM本は、電子版は以下で購入できますよ。
https://booth.pm/ja/items/1574937

---

他にも読んでない本がまだまだあるので読みます。。。（ダメな人）
RaspberryPiがネットワーク接続したときに、接続環境を通知させたい

Raspberry Pi 4を買いました。で、SDカードにはArchLinuxを入れました。

今回LEDとかも別に買っているわけではなく、素の状態での運用となるのですが、困ることが一つあって、

**どこに接続しているのかの確認が面倒くさい**

基本的にはDHCP利用な上にモニターもない状態なので、有線接続だろうと無線接続だろうとIPアドレスを確認しに行くのも面倒です。
そこで今回は、タイトルの通り「ネットワーク接続が確立できた時点で接続情報を自分から伝えてもらう」ことにしました。

# まとめ

## 環境情報

* 筐体: Raspberry Pi 4
* OS: ArchLinux (ARM版)
* ネットワーク管理: NetworkManager
* Python 3.8.0

## 書いたコード

```py:/etc/NetworkManager/dispatcher.d/notify-connection-information.py
#!/usr/bin/env python
import json
import os
import sys
from urllib.request import urlopen


WEBHOOK_URL = 'https://hooks.slack.com/services/THISIS/SLACK/WEBHOOK'


def main(conn_id, ip_addr):
    payload = {
        'username': 'info',
        'icon_emoji': ':strawberry:',
        'text': f'*attakei-pi* has connected to {conn_id}\n IP address is `{ip_addr}`',
        'channel': '@attakei',
    }
    urlopen(WEBHOOK_URL, json.dumps(payload).encode())


if __name__ == '__main__':
    argv = sys.argv[1:]
    # if argv[0] != 'wlan0' or argv[1] != 'up':
    if argv[1] != 'up':
        sys.exit(0)
    ip_addr = os.environ['DHCP4_IP_ADDRESS']
    conn_id = os.environ['CONNECTION_ID']
    main(conn_id, ip_addr)
```

## 出来上がった通知

<img width="360" alt="スクリーンショット 2019-12-02 18.58.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6805/f65a5ddc-b636-b408-4804-5077481bb85f.png">

# NetworkManagerの話

## NetworkManagerとは

ネットワーク接続に関するあれこれを管理するためのデーモン(+ツール)です。
SSIDの管理をしてくれたり、すでに登録済みのSSIDには自動接続を行ったりしてくれます。

`systemd-networkd` などもありますが、とりあえず自分は現在これを利用しています。

## NetworkManagerのdispatch機能

さて、NetworkManagerには「ネットワークの切り割りをイベントとしてコマンド実行する」ことを可能にする、`dispatcher`機能があります。
ArchLinuxのWikiに掲載されているサンプルなどでは、「有線接続をしたときは無線を無効化（+その逆）」「特定ネットワークに接続した場合は、続けてVPN接続する」みたいな例が書かれています。
今回はこれらのスクリプトを参考にして、上記のような「ネットワーク接続時に、指定されたSlackチャンネルに `利用したSSID`と`IPアドレス`を申告する」スクリプトを作ってみました。

## dispatcherが受け取るもの

実際に使用してわかっている範囲だと、Disptcherはコマンド実行時に以下の情報を渡すようになってます。

* コマンドの引数として
    * イベントのあったネットワークデバイス名
    * どんなイベントが発生したか（例: `up`=接続した）
* 環境変数として
    * 上記イベントに付随する情報各種
        * 接続設定名
        * IPアドレス
        * などなど

## 情報を揃えてdispatchする

トリガーにしたい条件をもとに、どこから情報を取るかや振る舞いを整理します。

* 「ネットワーク接続時に」
    * => コマンドの第２引数を参照する。`up`以外は無視
* 「指定されたSlackチャンネルに」
    * => NetworkManager-dispacherの管理領域ではないので、とりあえずスクリプト直接記載
* 「`利用したSSID`」 
    * => 環境変数の`CONNECTION_ID`を参照
* 「`IPアドレス`」
    * => とりあえずIPv４がほとんどなので、環境変数の`DHCP4_IP_ADDRESS`を参照

これで、必要な情報は揃ったので、コードが書けますね。コードは最初に記載したのでそちらを参照して下さい。

## 補足

スクリプトは直接呼び出されるので、shebangと実行権限付与を忘れずに。
※自分はこれで「あれっ」ってなり、頑張る系のIPアドレス探索をするはめになりかけました。

# URLs

- https://wiki.gnome.org/Projects/NetworkManager
- https://wiki.archlinux.org/index.php/NetworkManager
- https://wiki.archlinux.jp/index.php/NetworkManager
- https://developer.gnome.org/NetworkManager/stable/NetworkManager.html
2019年phpカンファレンス②～弁護士ドットコムを作り続ける開発組織について～

2019年phpカンファレンスでの『弁護士ドットコムを作り続ける開発組織について』の講演について、思ったことをまとめてみました。

# 講義資料
https://speakerdeck.com/bengo4com/about-bengo4com-development-organization

# 話を聞いてみて
エンジニアにとって働きやすい環境を整えるのは大事だなぁと思いました。
プログラマが最大の力を発揮するために、十分に働ける環境を提供する。またプログラマはそれにこたえる。
この関係性をしっかりと作っていくことが大切だなぁと思いました。

# エンジニアの働きやすい環境の実現に向けて
### 技術選定の方針
エンジニアには新しい技術を知ったり使ってたりすることへの欲求は一定量あります。
それの解決として、新しい技術をどこで用いるか、最大限のリスク回避をしながらどのように進めていくか、というかじ取りは必要なんだと思いました。

「コア機能の開発」で完全に新しい技術を入れようとしても、リスクが大きすぎる。コア機能では運用をメインとして、リスクが少ないことがわかってから新技術を入れていくべきだと思いました。

逆に新規案件では新しい技術を積極的に入れていく思想はとても大事になります。
ここで既存技術を使い、今まで通りの開発をやってしまうと、そのシステム自体にブレイクスルーが起こらず、無難な機能が出来上がる恐れがあります。


新規の人はどれだけチャレンジできるか（影響は小さく、衝撃は大きい）、
コア機能の運用ではどれかけ堅実なものとなるか（影響は大きく、衝撃は小さい）。


新たな技術を導入しようとしているシステムがどのような立場のシステムなのか、影響度を考えたうえで、リスクを取っていく必要があるなぁと感じました。

### マネージドサービスの活用
リソースを自社だけでなく、外に求め、外部委託をどんどん行っていく。

これにより自分たちにしかできない自社サービスの開発に注力できるようにはなります。

一方で何か起こった時への対応が遅れてしまうのも事実。


この辺りのバランス感は難しいんだろうなぁと思いました。


### Tech Focus Day
何これ、最高！
負債は常に返せるようにしておかないと！！

# エンジニアの働きやすい環境とは
エンジニアはわがままな生き物だ。
全部自由にできるようになったらなったで、不満が出るし、かといって、色々制約しても嫌だという。

やりたいこととやるべきことをちゃんと見極めて、最大パフォーマンスを出せるように環境提供していくことが重要なのかなぁと思いました。
オープンソース CMS「eZ Platform」

## eZ Platform とは
https://ezplatform.com/
eZ Platform は PHP で開発されている **オープンソース** のエンタープライズ向け **CMS** です。ノルウェー王国の [eZ Systems](https://ez.no) 社によって1999年から eZ Publish として開発されてきました。

![eZ Platform](https://ez.no/var/ezflow_site/storage/images/media/images/landing-page-animation4/683906-1-ger-DE/Landing-Page-Animation.gif)

12月1日現在の最新安定版のバージョンは [eZ Platform 2.5.6](https://github.com/ezsystems/ezplatform/releases) (LTS) 、最新開発版のバージョンは 3.0.0-beta3 です。

## eZ Platform の特徴
* 開発元企業 (eZ Systems 社) による **有償サポート**
* フレームワークに **Symfony** をフルスタック採用
* コンテンツを視覚的な階層構造で管理できる **ツリー表示**
* ユーザーを階層的に整理できるユーザー管理
* ユーザー権限の詳細な設定が可能な権限管理
* ユーザーも含めて項目を自由に編集できるコンテンツタイプ機能
* 同一コンテンツを複製せずに複数配置できるロケーション機能
* 同一コンテンツに複数の翻訳言語を登録できる **多言語対応**
* 同一コンテンツに複数のテンプレートを持たせられるサイトアクセス

## eZ Platform に適したサイト
* 部署やユーザー数が多い組織で利用するサイト
* ユーザーやコンテンツの内容に応じて細かく権限を設定する必要のあるサイト
* 同一コンテンツを複数の出力（テンプレート）で配信するサイト
* 多言語展開が必要なサイト
* コンテンツの階層構造が複雑なサイト
* コンテンツの種類や決まった入力項目が多いサイト

## システム要件
[Requirements - eZ Platform Developer Documentation](https://doc.ezplatform.com/en/latest/getting_started/requirements/)

|システム|要件|
|---|---|
|OS|Linux|
|Web サーバー|Apache 2.4<br>Nginx 1.12, 1.14|
|DB サーバー|MySQL 5.7, 8.0<br>MariaDB 10.0, 10.1, 10.2, 10.3<br>PostgreSQL 10 以上|
|PHP|7.1<br>7.2<br>7.3|
|Cluster|Redis 3.2 以上<br>Solr 6<br>NFS or S3<br>Varnish 5.1 or 6.0LTS<br>Fastly|
javascriptについて質問です。

https://blog.codecamp.jp/javascript-geolocation
上記リンクにて位置情報取得について調べていたのですが、

-----------------
getCurrentPosition()を呼び出すと、すぐに制御が返されます（次の文が実行される）。そして、位置情報の取得に成功すると、引数に渡した関数にPositionオブジェクトが渡されます。
-----------------

という一文があるのですが、いまいち理解できません。。。。
どなたか解説お願いできないでしょうか。。。。



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function test() {
    navigator.geolocation.getCurrentPosition(test2);
}

function test2(position) {

    var geo_text = "緯度:" + position.coords.latitude + "\n";
    geo_text += "経度:" + position.coords.longitude + "\n";
    geo_text += "高度:" + position.coords.altitude + "\n";
    geo_text += "位置精度:" + position.coords.accuracy + "\n";
    geo_text += "高度精度:" + position.coords.altitudeAccuracy  + "\n";
    geo_text += "移動方向:" + position.coords.heading + "\n";
    geo_text += "速度:" + position.coords.speed + "\n";

    var date = new Date(position.timestamp);

    geo_text += "取得時刻:" + date.toLocaleString() + "\n";

    alert(geo_text);

}
</script>
</head>
<body>

<button onclick="test()">test</button>

</body>
</html>
【おっちゃんがエンジニアになるまで】@1ヶ月目〜自作サイトを公開する〜(継続編)

#はじめまして
ばーんと言います。この記事は、

**30歳、独学、業界未経験、既婚者、働きながら**

のおっさんが具体的にどうやってエンジニアになれるのか？
を（ほぼ）リアルタイムで振り返り共有させてもらいます。

自身の思考整理がメインですが、これから目指す方の指標に少しでもなれれば幸いです。

2ヶ月目は[こちら](https://qiita.com/baan_nasebanaru/items/27961e8e6ea056cb1781)
3ヶ月目は[こちら](https://qiita.com/baan_nasebanaru/items/06828bab067940e7a54c)

**(2020.2.4追記、編集)**
初学者の方が参考になるように、相互リンクの設置＆当時の制作物の表示
1ヶ月目でこの程度だったらOKなんだな。という1例になれるように。

##Day0:準備
- [x] PC購入
- [x] Twitterのアカウント作成
- [x] 関連本の購入

PC購入はできればMacがいいそうです(https://kitsune.blog/programming-pc) 引用
Macは予算が…という方は24回払い無利子で新品が購入可能です（月1万円程度）
自分は実際に↑この24回払いを選択しています
#####あと、Mac操作したことない…という方でも大丈夫です！
自分も初めてでしたが1日で慣れますし、むしろ今ではWindowsが使いにくいぐらいなので

Twitterは、はじめたての人から刺激をもらえたり、有益な情報が多く流れているのでおすすめです！
転職を考えている方は、「Twitter転職」という言葉があるぐらいなので、やって損はないかと

関連本は空き時間を有効活用できるのでいいですよ〜

##Day1〜10:Progate奔走
知人のアドバイスに従い、HTML→CSSからWebサイト作成を短期目標にしました。
今更感はありますが学習サイトは主に、
・Progate(https://prog-8.com/dashboard)
・ドットインストール(https://dotinstall.com/)
を使いました。まだ未使用ですがUdemy(https://www.udemy.com/)
も勧められることが多いです。こちらはセール期間があるのでそこで買うといいですね。

Progateもドットインストールも有料版はありですが、重ねて受講しなかったので
Progateで有料を進める→詰まったらドットインストールをみて必要であれば課金
がいいかと思います。

HTML&CSSのコースを10日間でクリアしました。
自分で決めたことは**「道場編は絶対テキストを見ないこと」**でした。
Progateは初学としてはいいですが、基本テキスト通りに打ち込むだけなので、
このままだと自力がつかないと判断し、より本番に近い形に近づけました。

**躓く→Google検索　を繰り返しました。**

この判断は大きかったと思います。かなり時間はかかりましたが理解度が深まりました！

##Day11〜20:Twittwerの工夫と挫折
ここで周りのツイートをみると、自分のツイートの稚拙さが…
どうせやるなら目標を決めようと思い、
1.フォロワー数を増やしていく（フォローを多くしていく、#をつける　等）
2.後で検証できるように時間を明記する　の2点を変更しています。

そして、プログラムの方はローカル環境でのプログラミングにトライしましたが…
Git、Terminalがうまく使えず無事死亡しました。あまりにも理解が出来なさすぎたので、
できることからしようと考えProgateのJavaScriptをクリアします。

##Day21〜30:自作サイト完成編
###「いっそのこと自作サイト作った方がいいんじゃ…」
そして、友人が実際に民宿を経営しているので、そこから依頼が来たと仮定して作成し始めます。
（実はこの時実際に友人の民宿HPつくれそうだったのですが、残念ながら流れてしまいましたToT）
画像は商用可のフリー素材を使用。テキストは頭で捻出しました。

ここで学んだことは、
**・Google　Chromeの検証が神すぎる
・コードはコピって貼り付けでOK**

Google　Chromeの検証は主にCSSの確認、修正で大活躍しました！
手順を踏めば、検証での修正＆保存も可能です。
特にBootstrapは、どのスタイルが適用されているか分かりずらいと思います。
検証で一発確認できるのでめちゃくちゃオススメです。

最初はコードの意味を一語一語理解して進めるべきっ！
と思ってましたが、それを解説しているサイトも少ないので、そのやり方だと日が暮れます。
考え方を変えて、完成品を作りそれを壊すことで理解するように変更しました。
*パズルやプラモデルを思い出して欲しいのですが、バラバラで説明書がない状態から始めるのは厳しいと感じませんか？*
僕はそう感じたので、ネット上にあるコードを貼り付けて壊し、理解していきました。

**そんなこんなで、できたサイトがこちらです(https://minsyuku-example.netlify.com/index.html)**
まだまだ修正点はありますが、公開できて一安心です。

(ちなみに使用したテキストエディタはVScodeで、サイト公開はNetlifyです)

##成果物一覧
Day21~30 作業時間：20h[「自作サイト（仮定の民宿）」](https://minsyuku-example.netlify.com/index.html)制作

＋この記事を作成

初月なので基本的にはインプットがメインでした。

##さいごに

いかがでしたか？
今回は細かい技術は書かずに、考えた内容を思い出して記載していきました。
細かい技術はググればでてくるので。

今後も定期的に振り返っていく予定ですので、ご要望や意見などありましたらご連絡お待ちしています。

ばーん
手順メモ：AWS Lambdaでzipファイルをアップロードするまでに必要なこと

# やりたいこと
- lambdaでapiを叩きたい。
- python3でやるためには必要なライブラリをlambdaにzipでアップロードする

# 前提
- lambdaのランタイムはpython 3.7
- awsのlambdaの画面で関数の基本情報（関数名、ランタイム、アクセス権限）を作成しておく

#　やり方
- [ ] アップロードするzipファイルを作成する  
python3なので、仮想環境を作成する


```shell:実行コマンド

$ python3 -m venv dev
$ . dev/bin/activate
$ mkdir upload
$ cd upload/
$ pip install --upgrade pip
$ pip install requests -t ./
$ ls -la
total 8
drwxr-xr-x  14 ~ 省略 ~  .
drwxr-xr-x   6 ~ 省略 ~  ..
drwxr-xr-x   3 ~ 省略 ~  bin
drwxr-xr-x   7 ~ 省略 ~  certifi
drwxr-xr-x  10 ~ 省略 ~  certifi-2019.6.16.dist-info
drwxr-xr-x  43 ~ 省略 ~  chardet
drwxr-xr-x  10 ~ 省略 ~  chardet-3.0.4.dist-info
drwxr-xr-x  11 ~ 省略 ~  idna
drwxr-xr-x   8 ~ 省略 ~  idna-2.8.dist-info
drwxr-xr-x  21 ~ 省略 ~  requests
drwxr-xr-x   8 ~ 省略 ~  requests-2.22.0.dist-info
drwxr-xr-x  16 ~ 省略 ~  urllib3
drwxr-xr-x   8 ~ 省略 ~  urllib3-1.25.3.dist-info

*.dist-infoファイルは不要（というか、あると適切に読み込んでくれない）なので、全て削除する

$ rm -rf *.dist-info

lambda_function.pyを追加する
$ vim lambda_function.py

lambda上でapiを叩く処理を書き、ファイルを保存する。

zipにまとめる。zipファイル名は作成するlambda_function名と同じにする。
しないと、zipファイルを読み込みときに階層がずれてしまう。

$ zip -r hoge.zip ./*
```
- [ ] awsコンソール画面からzipファイルをアップロードする
- [ ] 問題なく読み込まれていたら、テストで確認する

# 注意点

- zipファイルは3MB以内に抑える必要がある 
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html

- zipにまとめるファイルのパーミッションは変更していないが、できるだけ755に合わせたほうが良さそう。
S3 Select

#◾️S3 Select とは#
**オブジェクトから必要なデータのみを抽出するよう設計された、新しい Amazon S3 機能で、パフォーマンスを大幅に改善し、S3 のデータへのアクセスに必要なアプリケーションのコストを削減することができます。** 

ほとんどのアプリケーションでは、オブジェクト全体を取得した後、詳細な分析に必要なデータのみをフィルタで除外する必要があります。

S3 Select を使用すると、アプリケーションは、Amazon S3 サービスへのオブジェクト内にあるデータのフィルタリングやデータへのアクセスといった手間のかかる作業から解放されます。

アプリケーションでロードおよび処理しなければならないデータ量を減らすことで、S3 Select は S3 のデータに頻繁にアクセスするほとんどのアプリケーションのパフォーマンスを最大で 400% 改善することができます。 


**ただし、S3 Select の料金は、入力、出力、および転送されたデータのサイズに基づいています。**
**クエリごとに、スキャンした GB あたり 0.00225 USD と、返された GB あたり 0.0008 USD の料金がかかるため、特定のデータだけを抽出したいときなどに便利かと思われる。**



#◾️やってみた#

適当なCSVファイルを準備し、S3へアップロードする。

```namae.csv
namae,type,age,city
sato,man,20,sapporo
tanaka,man,30,kanagawa
kimura,woman,20,okayama
hogawa,woman,10,miyagi
sato,woman,20,yamanashi
amuro,man,10,kanagawa
```

「アクション」から「S3 select」をクリック。
![スクリーンショット 2019-12-02 18.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2a55d2cf-9458-679c-278f-99b19cac1fb1.png)

ファイル形式：「CSV」
区切り記号：「カンマ」
「ファイルにはヘッダー行があります」にチェック。
![スクリーンショット 2019-12-02 18.56.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/d2b49fc7-899e-fa4b-f04c-39e4037becc5.png)


デフォルトのSQLを実行してみます。

```
select * from s3object s limit 5
```

最大で 5 つのデータが取得（limit 5）されたことがわかる。

![スクリーンショット 2019-12-02 19.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/1816bbb8-152b-05b9-ad3e-32dc02475095.png)


他のサンプルも確認してみましょう。age=20のものだけ抽出します。

```
select * from s3object s where s.age = '20'
```

age = 20 のものだけが抽出された。

![スクリーンショット 2019-12-02 19.12.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/becd4dd8-b2e6-a902-a8a7-e950f4588d47.png)