OmniAICreator/Qiita-1.07M huggingface dataset:
PDFからExcelに変換する3つの方法

**Portable Document Format (ポータブル・ドキュメント・フォーマット、略称：PDF)**は[**Adobe**](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%93%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%BA)が開発および提唱する、電子上の文書に関するファイルフォーマットである。1993年に発売されたAdobe Acrobatで採用された。([**ウィキペディア**](https://ja.wikipedia.org/wiki/Portable_Document_Format)) 

今、PDFが電子マニュアルや資料など他の多くの目的としてたくさんの人に使用されています。また、多くのWebサイトでは、Webページに埋め込むのではなく、データをPDFファイルとしてアップしてダウンロードしてもらうような形をとっています。これで[**Webスクレイピング**](https://www.octoparse.jp/)を効果的に避けることができます。

PDFファイルを簡単に表示、保存、印刷できます。しかし問題は、PDFがファイルの整合性を保つように設計されていることです。「電子ペーパー」のように、どんな環境のパソコンで開いても、同じように見ることができます。

しかし、PDF中の一部を削除したりし、文字や図形を書き込んだりするPDFを編集することがちょっと難しいですよね。編集したい時はどうすればいいでしょうか。これから本記事でPDFからExcelに変換する方法を紹介します。

#1.コピペ

データ量が少ない場合はコピペが手っ取り早い方法です。すべてのドキュメントを開き、抽出するテキストを選択して、Excelファイルにコピーして貼り付けます。場合によっては、テーブルをコピーする必要があるときに、まずそれをWordファイルに貼り付け、次にWordからExcelにコピーして貼り付けて構造化テーブルを作成する必要があります。

ただ、量が多い場合、この方法では無理そうですね。自動化ツールを使ったほうがおすすめです。

![ctrlcctrlv.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/ab83112b-0bab-01eb-b6d8-33a9db71c07e.jpeg)

#2.PDFエクセル変換ソフト

PDFファイルをExcelに取り込んで再編集できるソフトやウェブサービスなどがたくさんあります。操作が簡単で、瞬時でPDFファイルをExcelに変換できます。PDFファイルをドラッグして、変換ボタンをクリックしてExcelファイルをエクスポートします。変換されたファイルは、テキストと画像だけでなく、フォーマット、フォント、色もそのまま残られます。

以上の手順が完了したら、スプレッドシートを編集できます。多くのPDF変換ソフトでは、PDFファイルに保存されている画像、テキスト、ページを直接編集し、Excelスプレッドシートにエクスポートすることもできます。

もちろん、PDF形式の最初の開発者である[**Adobe** **Acrobat**](https://acrobat.adobe.com/us/en/acrobat/how-to/pdf-to-excel-xlsx-converter.html)には、変換機能が含まれています。すばやく簡単に、スマフォを含むあらゆるデバイスで行うことができます。Acrobatはファイルの変換だけでなく、共同作業中のドキュメントを作成、編集、エクスポート、署名、およびレビューできます。スキャンしたドキュメントを編集可能な検索可能なPDFに変換することもできます。
![pdfエクセル変換.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/7f209ae8-ae03-ba2c-bd46-5ce606ba689e.jpeg)
#3. PDFの表を読み取るツール

文章をPDFから抽出するのはそれほど難しくはないですが、表を表の形のまま、抽出するのはなかなか難しそうです。ファイルから特定のデータを取得できない場合があります。多くの場合、必要なデータはその中の表だけです。ファイル全体を変換した後でも、変換されたファイルから表を選択する必要があります。

[**Tabula**](https://tabula.technology/)は、PDFファイル内の表を抽出で切るツールです。クリックしてドラッグしてテーブルを選択し、表の周りにボタンをクリックするだけで抽出データを取り出せます。ファイルとして出力した結果は改行を含むセルのデータもきちんとズレずに抽出されている。

PDFからデータを抽出するための非常に多くのツールがあります。これらの自動化ツールを使用すると、PDFファイルからデータを取得する方法について頭を悩ます必要がなくなります。各ツールには長所と短所があるため、結果は異なる場合があります。最適なものを見つけてみてください！

PDFからExcelに変換するその他のツールは次のとおりです。
[**smallpdf**](https://smallpdf.com/jp/pdf-to-excel)
[**PDFelement**](https://pdf.wondershare.jp/)
[**Nitro** **Pro**](https://www.pdftoexcelonline.com/pro-a)
[**cometdocs**](https://www.cometdocs.com/)
[**iSkysoft** **PDF** **Converter** **Pro**](https://pdf.iskysoft.com/pdf-converter-pro-windows.html)
チャットとかメール、論文で見かける英語略語集

# 英語略語って多くない？
表題の通り。
社会人のチャットとかメールはもちろん、エンジニアしててSOとか公式読んでると必ずと言っていいほど出てくる英語略語達。
「これ覚えてれば大体いけるでしょ！」ってレギュラーメンバーのみを集めたら需要あるんじゃないかと思ってまとめました。
※頻度順（個人的）

##TGIF - "Thank God, It's Friday."
みんな大好き華金。（最初がこれってどうなの？笑）

##LGTM - "Looks Good To Me"
「自分的にはOKだよ」という意味。（Githubでめちゃ使う。）

##FYI - "For Your Information"
「ご参考までに」といった意味。（おっきい会社さん使ってるイメージ）

##TL;DR. - "Too Long. Didn't Read."
「長文なので、要約載せます」という時の見出しなどに使う。（ネットの記事でよく見かけるイメージ）

##IMO (IMHO) - "In My (Humble) Opinion"
「個人的な意見ですが」という意味。（使いたいけど、わざわざ使うほどでもないから使わない子）

##AFAIK - "As Far As I Know"
「自分が知っている限りでは」という意味。（なんだろ、、、githubのissue欄とか英語で会話しているときに見かけるかな）

##TBD - "To Be Determined"
「あとで決める」と言ったニュアンス。（議事録とかで使う感じ）

##TIA - "Thanks In Advance"
「先にお礼を言います」から転じて「すまないね」とか「お手数かけるけど、よろしく」といったニュアンス。（海外の人にお願いするときに使う感じ）

##WFM - "Works For Me"
「自分の手元ではうまくいく」「自分にとって都合が良い」という意味。（英語のチャットで稀に、、）

##GOTCHA - "I've Got You"
「やった！」「わかった！」といった意味。（テキストよりトークで使われてるイメージ）

##YAGNI - "You ain't gonna need it"
「それ必要なくない」「そんなのいらない」といっった意味。

# 論文とかで使われる略語（追記12/6)
## cf. - conferの略
意味 - 「参照もしくは比較してね」という意味。「シーエフ」と発音
用例 - 「50ページを参照せよ」 をcf.で表すと「cf. p. 50」
英語 - ref. 

## e.g. -　exempli gratiaの略
意味 - 「例えば」という意味。「イージー」と発音します。
用例 - 僕はプログラミング(e.g. PHP and Rails)が好きだ。
英語 - ex

## i.e. - id eatの略
意味 - 「つまり、言い換えれば」という意味。「アイイー」と発音します。
用例 - 僕は、スクラッチでアプリケーションシステムを構築する事(i.e. プログラミング)が好きだ。
英語 - this is(つかわないか。。）

# 他の方からの教えてもらった略語 (追記4/17)
##ICYMI - "In case you missed it"（@BYODKMさん情報提供）
「もし、見逃してたら」という意味。
FYIとシチュエーションで使い分けるといい感じがする。
VSCodeのデバッグではメソッドをwatchしてはいけない



###こ！れ！は！ハマるわけだ・・・・

正直タイトル落ちです。
長時間悩んだのでくやしくてつい書きます。

そして、ちょっとタイトルの一言で済ませると語弊を含んでおりますので補足。

##デバッグ実行ができていたのに突然できなくなる原因

>VSCodeのウォッチ式にメソッドを追加していませんか？

>1.ブレークポイントで止まる
2.(ウォッチ式のメソッドが実行される)
3.(メソッドが正しく実行できず)エラー

>ということだと思います。

https://teratail.com/questions/153983

まさにこれで、ウンウンうなっていたのですが。

これ、「３．(メソッドが正しく実行できず)エラー」でつまづいてるので
正しく実行できる状況なら問題ないのですね。
なので、1回目は普通にメソッドの戻り値もwatchできてたのに
再度デバッグしようとして突如動かなくなりパニックという構図に。

メソッドのwatch式を消せば問題なく、すぐデバッグできるようになります。

###メソッドは実行後は毎度消す

これがお約束。


VisualStudioでは登録しっぱなしでも問題なかったので
癖でやる人多いんじゃないかな＾＾；

そもそも設定に問題があってステップ実行できない（1回も）というパターンへの
対処法はすぐ出てくるんですが、なんどphp.ini見直しても原因見つけられなくてハマりました。

もうちょっとこの原因、ググってすぐ出てきたたらいいのにね。
WordPressでページごとにBasic認証をかける

## 概要
Webサイト全体にBasic認証かけるのは、確認用によくやることだと思います。
.htaccessとかでかけるのが常套手段。
ただ、全体ではなくページごとにかける/かけないを選択したい場合、ことWordPressにおいてはちょっと面倒っぽかったので、方法を残しておきます。

## 方法
- functions.phpに認証メソッドを作成

```php
function basic_auth($auth_list,$realm="Restricted Area",$failed_text="認証失敗時の文言"){ 
    if (isset($_SERVER['PHP_AUTH_USER']) and isset($auth_list[$_SERVER['PHP_AUTH_USER']])){
        if ($auth_list[$_SERVER['PHP_AUTH_USER']] == $_SERVER['PHP_AUTH_PW']){
            return $_SERVER['PHP_AUTH_USER'];
        }
    }
    header('WWW-Authenticate: Basic realm="'.$realm.'"');
    header('HTTP/1.0 401 Unauthorized');
    header('Content-type: text/html; charset='.mb_internal_encoding());
    die($failed_text);
}
```

- header.phpで認証をかける

※ファイルの一番上、html部分が始まるより前に！

```php
<?php
  $pageArray = array("ページIDの一覧");
  if(is_page($pageArray)):
    $userArray = array("Basic認証のID" => "Basic認証のパスワード");
    basic_auth($userArray);
  endif;
?>
```

ページIDは、WordPressの管理画面で固定ページを開いた時のURL
http://xxx.com/wp-admin/post.php?post=71
の、最後のpost=xxにある数字のことです。


## まとめ
めっちゃ簡易的なBasic認証です。
確認用のBasic認証においては、まじで「とりあえず動けばおけ」なので、htaccessとかで認証かけるときとは認証失敗時の見た目は違うけど、動く。
Raspberry Pi起動後にImpressのスライドショーを自動実行させた時のあれやこれや

#やりたかったこと
Raspberry Pi 3を起動すると下記のコマンドでImpressのスライドショーを自動実行する。

※1

```
soffice --show /home/pi/Documents/xxxxx.odp
```

#やったこと

##rc.local
/etc/rc.localのexitの前に※1を追記


##profile
/etc/profileの最終行に※1を追記


##systemctl
/etc/systemd/system/start-xxxxx.serviceを作成

```
[Unit]
Description=launch soffice

[Service]
User=pi
Environment=DISPLAY=:0
ExecStart=soffice --show /home/pi/Documents/xxxxx.odp

[Install]
WantedBy=user@.service
```

サービスの作成などは、下記を参考にした。
[Raspberry Piで、autostartが使えなくなったので、Systemdを使ってchromium-browserを自動起動した](https://qiita.com/takanemu/items/c2982bfb74c72cbf174d)
[Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説](https://qiita.com/karaage0703/items/ed18f318a1775b28eab4)

#結果
##rc.local
psでは、sofficeが存在するが、画面上ではなにも変化なし。

##profile
起動中にLibre Officeのロゴが表示されたままシステム停止。→ セーフモードで立ち上がればよかったかもしれないが、ジャンパーピンがなかったのでraspbianの再インストール。

##systemctl
再起動後、Impressが起動し、スライドショーが自動実行された！！！

#やらなかったこと
##crontab
８時に開始して２３時にリブートさせるという方法も考えたが、途中の時間に開始することができないので不採用。



#終わりに
以前は、Raspberry Piにはautostartという方法があったようだが、現在はなくなっている。
systemctlは敷居が高い感じがするが、見様見真似でもなんとかなった。
【自分用】.zsh設定

```
# 環境変数
# 環境に応じて記載
# export JAVA_HOME=`/usr/libexec/java_home -v 11`
# export PATH=$JAVA_HOME/bin:$PATH

# alias設定
alias s='source ~/.zshrc'
alias la='ls -aG'
alias ll='ls -laG'
alias tailf='tail -f'
alias findn='find . -name'
alias findg='find . -type f -print0 | xargs -0 grep -i $1'
alias javahome='/usr/libexec/java_home'

# gitのalias
alias br='git branch'
alias co='git checkout'
alias st='git status'
alias ss='git status --short --branch'
alias lg='git log -50 --date=short --pretty="format:%C(YELLOW)%h %C(GREEN)%cd %C(CYAN)%an%C(RED)%d %C(reset)%s"'
alias pull='git pull origin $(git rev-parse --abbrev-ref HEAD)'
alias push='git push origin $(git rev-parse --abbrev-ref HEAD)'
alias fetch='git fetch'
alias save='git stash save'
alias pop='git stash pop'
alias list='git stash list'
alias drop='git stash drop'

# dockerのalias
alias d='docker'
alias d:rm='docker rm $(docker ps -aq)'
alias d:rmi='docker rmi $(docker images -q)'
alias d:rmv='docker volume rm $(docker volume ls)'
alias dc='docker-compose'
alias dc:web='docker-compose run --rm web'

# ディレクトリスタックの利用(cd -で補完機能を使用することで元いたディレクトリに移動できる)
setopt AUTO_PUSHD
setopt pushd_ignore_dups
DIRSTACKSIZE=20

# 色を使用出来るようにする
autoload -Uz colors
colors
zstyle ':completion:*' menu select

# 同時に起動したzshの間でヒストリを共有する
setopt share_history

# スペースから始まるコマンド行はヒストリに残さない
setopt hist_ignore_space

# 補完機能
autoload -U compinit && compinit -u

# 時刻表示設定
# RPROMPT=%"{$fg[cyan]%}%D{%Y/%m/%d} %*%{$reset_color%}"

# バージョン管理システムから情報を自動的に取得する機能
autoload -Uz vcs_info

# ブランチ表示設定(vcs_info_msg_0_で設定したメッセージを表示させる)
zstyle ':vcs_info:*' formats "%F{green}[%b]%f"
zstyle ':vcs_info:*' actionformats '%F{magenta}[%b|%a]%f'

# コマンド入力の度に呼び出される関数
precmd() {
    vcs_info
    PROMPT="%{${fg[blue]}%}%~%{${reset_color}%} ${vcs_info_msg_0_}
> "
}

# rbenv起動
eval "$(rbenv init -)"
```

## ついでにiTerm2設定

![Default2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150463/d6096602-fce1-7073-1f35-381f5cb715f8.png)
![Default1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150463/2e5a10bc-ed93-3bbc-c6bb-481ec4a73a9b.png)
![Hotkey1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150463/c02cebbd-eb33-351a-13ca-4578d7a33eec.png)
![Hotkey2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150463/04e3f77e-c135-d132-0a0a-0657d49085b6.png)
![Hotkey3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150463/79804eef-a116-a277-4d92-948e52d3865c.png)

<!-- 18ing6tpEWgOCIqU7Yhz0y0TOglgZV1BLjD1KT4lrAZk -->
JDLA Deep Learning for GENERAL 2019 #3 合格体験記

2019/11/9にG検定を受験し、無事合格しました。
これから受験しようと考えている文系出身やAIに全く触れてこなかったけど受験してみようと考えている人向けに感想を踏まえて勉強法等をまとめてみようと思います。

#感想
　過去問や模擬試験では時間を余して8割越えをキープし、持ち込みやGoogle先生に質問しながらの受験が可だったために慢心していたがが、本番は時間もギリギリで焦った。
総受験者数：6,580名で合格者数：4,652名と合格率：約70%と結構な合格率なため、落ちなくてよかった。

#G検定概要
　一般社団法人日本ディープラーニング協会が実施している試験になります。概要は以下の通りです。　

- 概要：ディープラーニングを事業に活かすための知識を有しているかを検定する。
- 受験資格：制限なし
- 試験概要：120分、小問226問の知識問題(多肢選択式)、オンライン実施(自宅受験)
- 申込期間：2019/10/1 13:00 ～ 2019/10/31 23:59
- 試験日：2019/11/9 13:00 ～ より120分
- 申込：G検定受験サイトより申込

※上記は2019年第3回時の情報です。

#出題範囲
- 人工知能（AI）とは（人工知能の定義）
- 人工知能をめぐる動向
- 人工知能分野の問題
- 機械学習の具体的手法
- ディープラーニングの概要
- ディープラーニングの手法
- ディープラーニングの研究分野
- ディープラーニングの応用に向けて
 
大雑把にいうとAIの歴史(誰それが何を開発した、その時代の技術トレンド等)、ディープラーニングに関する知識、各国の人工知能をめぐる動向(どこ国がどんな研究してる、どんな法律がある等)を聞かれます。
※実装するための知識等はメインでないため、この検定に合格したからといって急にAIエンジニアになれるわけではありません。(別途E試験というものがあります。詳しくは<a href="https://www.jdla.org/business/certificate/" target="_blank">公式サイト</a>を参照してください。)

#自己紹介
　私の試験時の状況を簡単に紹介しときます。

- 大学では理系の学科を卒業(not 情報系)
- 現在はIT関係の仕事に従事しているがまだ2年目
- AIに関する知識はアニメや映画で登場するワードを知ってるぐらい

といった状況でした。一応理系出身なので数学に関する知識等は問題ありませんでしたが、それ以外は特に文系や非IT系の方と条件は変わらないと思います。

#勉強方法
　それでは本題に入っていこうと思います。といっても以下の書籍を購入してひたすらInputとOutputをするだけというオーソドックスな方法です。以下に書籍とその感想やそれを何時間ぐらい使ったか等説明をしていきたいと思います。 購入する際には紙でも電子書籍でもどちらでもよいと思います。

- 『<a href="https://www.amazon.co.jp/dp/4040800206" target="_blank">人工知能は人間を超えるか ディープラーニングの先にあるもの</a>』 著：松尾 豊
  - 現在に至るまでのAIに関する知識を読み物として学ぶことができます
  - ページ数も多くなくすぐ読めるので通勤通学等を利用することが可能です
  - 勉強時間：数時間

- 『<a href="https://www.amazon.co.jp/dp/B07H2ZR6M2" target="_blank">深層学習教科書 ディープラーニング G検定（ジェネラリスト） 公式テキスト</a>』
  - 試験運営団体である「日本ディープラーニング協会」が執筆している公式検定書です(通称：白本)
  - G検定の出題範囲の勉強をこれ1冊でカバーできます
  - 各章末には確認テストもあるため知識漏れも確認できます
  - 勉強時間：10時間

- 『<a href="https://www.amazon.co.jp/dp/B07NDVCN99/" target="_blank">徹底攻略 ディープラーニングG検定 ジェネラリスト 問題集 徹底攻略シリーズ</a>』
  - 白本を勉強し終えた後にこの問題集(通称：黒本)をやっても全く太刀打ちできないような内容です
  - 白本で勉強したことをベースに黒本で補強するという感じです
  - 1回分の模擬試験がついてくるので早めに受けて穴を見つけておきましょう
  - 勉強時間：10時間
- 『<a href="https://www.amazon.co.jp/dp/4049110148" target="_blank">AI白書 2019</a>』
  - 最新の技術動向や各国の取り組みがこれで学べます
  - 紙だと非常に分厚く重いので電子書籍での購入がおすすめです
  - 本番は持ち込み可なので最悪これを使っての勉強はいらない気もします
  - 勉強時間：数十分  

　また、上記の書籍に加え「<a href="http://study-ai.com/generalist/" target="_blank">Study-AI</a>」さんに無料登録して模擬試験を受けることをおすすめします。難易度も本番に近く、同じような問題が本番でも出題されたためやって損はありません。

#まとめ
　大して数学的知識やAIなり機械学習のエンジニアでもないとわからないような知識を要求されるわけではないため、ディープラーニングに興味はあるけど文系だとか非IT人材だからという理由で敬遠する必要はないと思います。むしろそういった人たちの方が呑み込みが早いかもしれません。この検定を機に昨今話題になることも多いディープラーニングに触れてみることをお勧めします。
あるFrameworksを追加したら「1 duplicate symbol for architecture arm64」エラーが出た時の対応方法

#はじめに
BLE通信対応の機器との接続処理を追加する為に、
提供されたFrameworksを追加したら「1 duplicate symbol for architecture arm64」エラーが発生した。

#ググってみた
「duplicate symbol for architecture」にヒットするサイトがいくつか出てきたが、
何となく違う感じがしたので自分で考える事に…

#エラー内容をよく見てみる
エラー内容
```duplicate symbol 'Framneworks名' in:
   /XXXXXX/○○ViewController.o
   /XXXXXX/□□ViewController.o
ld: 1 duplicate symbol for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)```
今回BLE機器と通信する為に手を入れたViewControllerで重複が発生しているので心当たりが…

#エラー原因たぶんこれ
それぞれのViewControllerで追加したFrameworksの定義や初期化をしてるのが多分ダメ

#対応方法
△△AppDelegateクラスにFrameworksの定義と初期化処理を移動して１つにまとめて、
それぞれのViewControllerで使えるようにしたら、
エラーも無く無事動作しました。

#まとめ
今回は片方のViewControllerにはじめ追加して接続や値の取得などの事前調査をしてからもう片方に処理を追加したが、その時にそのまま追加したのがそもそもの間違いだった。
ちゃんと設計してレビューする環境ならこんなことは発生しないと思われるが、
これ追加しとけって丸投げされるだけで設計もレビューもやらないからダメダメなんだな…
Rubyで連立一次方程式

Rubyで連立一次方程式を解く方法を２つ紹介する。

# Ruby標準ライブラリ `Matrix` を使う

Rubyの標準ライブラリにある`Matrix`クラスを使う方法。標準ライブラリにあるので追加でgemをインストールすることなく使える方法。
（参考: [Ruby2.2 ではアレが死ぬほど使いやすくなるの！](https://qiita.com/gogotanaka/items/912d1b74aa702588fcf7) )

```ruby
require 'matrix'
m = Matrix[ [1.0, 2.0], [1.0, 3.0] ]
# => Matrix[[1.0, 2.0], [1.0, 3.0]]
b = Vector[1.0,0.0]
# => Vector[1.0, 0.0]
m.lup.solve(b)
# => Vector[3.0, -1.0]
```

# `Nmatrix` gemを使う

https://github.com/SciRuby/nmatrix

`gem install nmatrix` でインストールする。

```ruby
require 'nmatrix'
m = N[ [1.0, 2.0], [1.0, 3.0] ]    # 初期化
# =>
# [
#  [1.0, 2.0]
#  [1.0, 3.0]
# ]
b = N[[1.0],[0.0]]
pp m.solve(b)      # => [[ 3.0],[-1.0]]
```

NMatrixの行列要素へのアクセスの方法

```
m = N[ [1.0, 2.0], [1.0, 3.0] ]
m[0,1]   # => 2.0
m[0..-1,1]   # => [ [2.0], [3.0] ]  column vector
m[0,0..-1]   # => [ [1.0, 2.0] ]    row vector
m.shape      # => [2, 2]
```

# 速度比較

一般的にnmatrixの方がより数値計算に特化しているので速い。nmatrixの方は1000x1000くらいの行列なら一瞬で解ける。

```ruby
require 'benchmark'
require 'matrix'
reuqire 'nmatrix'

m = Matrix.build(500) { rand }    # 100x100 random matrix
a = 500.times.map { rand }
b = Vector[*a]                # 100x1 random vector
m.lup.solve(b)

a2 = NMatrix.random([1000, 1000], dtype: :float64)
b2 = NMatrix.random([1000, 1], dtype: :float64)

Benchmark.benchmark(Benchmark::CAPTION) do |x|
  x.report("matrix:") { m.lup.solve(b) }
  x.report("nmatrix:") {  a2.solve(b2) }
end

#               user     system      total        real
#  matrix:  2.897694   0.002253   2.899947 (  2.901112)
# nmatrix:  0.129778   0.001833   0.131611 (  0.131675)
```
Ubuntu Linux向けVisual Studio Code (VSCode) インストール手順

Linux PC (Ubuntu 18.04で確認) へのVSCodeのインストール手順について説明します。基本的に[公式サイト](https://code.visualstudio.com/docs/setup/linux)の手順そのままです。

# aptレポジトリの追加

```
$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
$ sudo install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
$ sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
```

追加したマイクロソフトのリポジトリはhttpsアクセスのため、apt-transport-httpsパッケージが必要になります。

```
$ sudo apt install apt-transport-https
```

```
$ sudo apt update
```

# インストール

```
$ sudo apt install code
```

# 設定ファイル

GUIからも設定変更可能ですが、その設定ファイルは以下に保存されます。

```
~/.config/Code/User/settings.json
```
wordで日本語と英語のフォントを指定して自動変換するマクロ(ver.2)

https://qiita.com/NE_0813_/items/e6d9725b05b7d4e6a7b6 の改良版
コメントで教えてくれた方がいたので参考にして改良
コメントで教えてくれた方の言う通りデザイン/フォントの方が数式の誤変換も修正されるしいい感じ
でも、練習したってことでアップします！

Sub Font_Change2() 'フォントの種類別一括変換
　Dim doc_all As String
　Dim doc As Range
　Dim k As Long
　With ActiveDocument
　　doc_all = .Range(0, .Bookmarks("\EndOfDoc").End)
　End With
　For k = 1 To Len(doc_all)
　　Set doc = ActiveDocument.Range(k - 1, k)
　　With doc.Font
　　　If doc.Font.Name = "Cambria Math" Then '数式用のフォントを確認
　　　Else:
　　　　'日本語用フォント
　　　　.NameFarEast = "ＭＳ 明朝 (本文のフォント - 日本語)"
　　　　'英数字用フォント
　　　　.NameAscii = "Century (本文のフォント)"
　　　　.Name = "ＭＳ 明朝 (本文のフォント - 日本語)"
　　　　End If
　　End With
　Next
End Sub
Google Apps Script のログ管理を Google Cloud Platform で行なう

# Google Apps Script のログ管理を Google Cloud Platform で行なう

Google Apps Script と Google Cloud Platform の連携方法がわからなかったので、備忘録代わりに記録する。

## Google Cloud Platform の設定

[Google Cloud Platform](https://console.cloud.google.com/) にアクセス後にログインする。

### Google Cloud Platform のプロジェクトを新規作成する

1. 左上の現在選択中のプロジェクト名をクリックし、プロジェクトの選択ダイアログを表示させ、新しいプロジェクトをクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/0049d3ed-e238-9200-6687-93f7c48722eb.png" width="500" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/0d223788-a16e-044c-7fff-ac0bc306baa1.png" width="500" />

2. 新しく作成するプロジェクト名を指定し、作成をクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/2a826d20-5b9e-9810-4184-9b739dcb4776.png" width="500" />

3. ダッシュボード画面に戻るので、作成したプロジェクトを選択してから表示されるプロジェクト情報カードのプロジェクト番号をメモしておく。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/e66a7b6a-51fd-fd01-7db9-bcb65bac25c3.png" width="500" />

### OAuth を設定する

1. 左上のメニューから「API とサービス」->「OAuth 同意画面」をクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/d6f2c208-012b-be27-1481-f7905f3a8f1e.png" width="500" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/e75808e4-681c-a447-caf4-a2e9919bcddc.png" width="500" />

2. OAuth 同意画面が表示されるので、アプリケーション名を入力し、保存をクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/cf553779-c13d-0b6d-f9ae-a41ac62a290a.png" width="500" />

## Google Apps Script の設定

1. スクリプトエディタのメニューから「リソース」->「Gloud Platform プロジェクト...」をクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/52aa6607-bd6c-9f18-7571-1b2f2baa362f.png" width="500" />

2. Cloud Platform プロジェクトの設定画面でメモしておいたプロジェクト番号を入力し、プロジェクト設定ボタンをクリックする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/6312fd05-d660-9187-3b19-8cea9db00615.png" width="500" />

3. プロジェクトの変更の確認ダイアログが表示されるので確認をクリックする。
<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/1213ec05-9e81-979f-b31f-eee8d11652dc.png" width="500" />
<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/2e469337-c7fd-8c34-ad1c-652e278031e6.png" width="500" />

## ログ出力の確認
1. Google Apps Script のエディタからログを出力するテストスクリプトを実行してみる。

```javascript
function myFunction() {
  console.log("デバッグログ");
  console.info("情報ログ");
  console.warn("警告ログ");
  console.error("エラーログ");
}
```

2. メニューから「Stackdriver Logging」をクリックすると、Google Cloud Platform のログビューアが開くので出力されたログを確認する。
<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/baf5880e-ef4e-a061-b26b-4b511bad36fd.png" width="500" />
<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35995/50bfed90-3d2e-584e-9485-23a5a1ec0a5b.png" width="500" />
kintone REST API client for Ruby を使ってみる

kintoneのSDKを使って、コマンドラインからkintoneにアクセスしてレコードを取ってきたりする時のメモです。

# はじめに

kintoneのAPIにアクセスする Ruby用のSDK [kintone REST API client for Ruby]https://github.com/jue58/kintone を使ってみたときのメモです。

# 動作環境

* mac OS10.14.6
* Ruby 2.6.3
* Homebrew 2.1.16
* rbenv 1.1.2
* Pry version 0.12.2 on Ruby 2.6.3

# 環境設定メモ

上記環境を構築する際のメモです。

* [Homebrew]https://brew.sh/index_ja をインストール
* [rbenv]https://github.com/rbenv/rbenv#homebrew-on-macos をインストール
* rbenvでRubyをインストール


### rbenv チートシート

* `rbenv --help` 全体ヘルプ表示
* `rbenv versions` rbenvでinstall済みのRubyバージョンの一覧
* `rbenv install --help` installコマンドのヘルプ
* `rbenv install -list` rbenvでinstallできるRubyの一覧 
* `rbenv rehash` インストールしたRubyやGemの反映

# [kintone REST API client for Ruby]インストール

## Bundlerインストール

`gem install bundler`

## bundle init

Gemfileの作成

`bundle init`

## Gemfile 編集

`gem 'kintone'` 追記

## インストール

`bundle install`

### gem & bundler チートシート

* `gem --help` ヘルプ
* `gem list --local` ローカルにインストールされたGem一覧
* `gem help install` インストールコマンドのヘルプ
* `bundle init`
* `bundle install`
* `rbenv rehash`

# pry 対話シェルで実行

## pry インストール

* `gem 'pry', '~> 0.12.2'` Gemfileに追記
* `bundle install`
* `rbenv rehash`
* `pry -v`

### pryチートシート

* `pry` pry実行
* `.ls` シェルのlsコマンド実行
* `ls` 現在のスコープ内の変数とメソッドの一覧

## SDK実行

### Application information

```ruby
$ pry
[1] pry(main)> require 'kintone'
=> true
[2] pry(main)> domain = '<domain>.cybozu.com'
=> "<domain>.cybozu.com"
[3] pry(main)> uid = '<user id>'
=> "<user id>"
[4] pry(main)> pass = '<password>'
=> "<password>"
[5] pry(main)> api = Kintone::Api.new(domain, uid, pass)
=> #<Kintone::Api:0x00007fce67a24d78
 @connection=
  #<Faraday::Connection:0x00007fce67a24be8
   @builder=
    #<Faraday::RackBuilder:0x00007fce67a24738
     @handlers=
      [Faraday::Request::UrlEncoded, 
(略)
[6] pry(main)> api.app.get(1)
=> {"appId"=>"1",
 "code"=>"",
 "name"=>"顧客管理ハンズオン",
 "description"=>"<div><br /></div>",
 "createdAt"=>"2017-06-24T08:36:29.000Z",
 "creator"=>{"code"=>"<user>", "name"=>"<name>"},
 "modifiedAt"=>"2019-11-13T16:36:33.000Z",
 "modifier"=>{"code"=>"<user>", "name"=>"<name>"},
 "spaceId"=>nil,
 "threadId"=>nil}
```
---

# Basic認証を通す方法

2019-11-22現在の最新版のリリースv0.1.5
https://github.com/jue58/kintone/releases/tag/v0.1.5
では、Basic認証に対応していませんが、\#11 https://github.com/jue58/kintone/pull/11 のプルリクでマージされています。（リリースはされていない）
\#11のパッチを当てた上で、\#15 https://github.com/jue58/kintone/pull/15 のコードによりBasic認証に対応できます。

---

# 関連リンク

* [kintone REST API client for Ruby]https://github.com/jue58/kintone
* [Ruby]https://www.ruby-lang.org/ja/
* [RubyGems]https://rubygems.org/
* [Bundler]https://bundler.io/
* [pry]https://github.com/pry/pry
* [Faraday]https://lostisland.github.io/faraday/
mariadb 5.5.x をビルドするときの注意

## src.rpmの取得

* http://vault.centos.org/7.7.1908/os/Source/SPackages/mariadb-5.5.64-1.el7.src.rpm

## ビルド

* rootアカウントでビルドしようとするとエラーになるため、以下回避策

```diff:mariadb.spec
  # Regression tests take a long time, you can skip 'em with this
-  %{!?runselftest:%global runselftest 1}
+  %{!?runselftest:%global runselftest 0}
```

```sh
rpmbuild -bb mariadb.spec
```

## CentOS8 で CentOS7のmariadbをビルドする場合

依存パッケージの
`policycoreutils-python`が
`policycoreutils-python-utils`に名前変更されているため、そちらをインストール。

```diff:mariadb.spec
- BuildRequires: checkpolicy policycoreutils-python
+ BuildRequires: checkpolicy policycoreutils-python-utils
```

```sh
rpmbuild -bb mariadb.spec
```

* GCC 4.4.7 ではビルドできない。8.2.1を使う、と、cmakeのエラーが出て無理だった。
* [sys/event.h – not found – Chris on MySQL](http://www.chriscalender.com/tag/sysevent-h-not-found/)によると、 libevent-2.0.21-stable.tar.gz を使うと良い様子(試していない)
* と思ったら、`libevent-devel`か`libev-libevent-devel`を入れれば良い気もする。

![スクリーンショット_2019-11-19_07-56-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/23971cb5-4fbe-3e10-de1c-d9340a124467.png)


## CentOS8 で mariadb 5.5.66 をビルドする

* https://mariadb.com/kb/en/mariadb-server-5-5-66/
* GCC 8.2.1 でビルドする。(GCC 4.4.7ではビルドできない。)

```sh
cd /usr/local/src/
tar xzf mariadb-5.5.66.tar.gz
cd /usr/local/src/mariadb-5.5.66

yum install -y gcc gcc-c++
yum install -y cmake

cmake . -DCMAKE_INSTALL_PREFIX=/opt/mariadb-5.5
make -s 1>/dev/null
make install
```
分報で各自の作業を可視化したら、メンバー間の協力が加速された話

# はじめに
一般的に、ソフトウェア開発は、チーム内の情報を共有し、チームメンバーが相互に協力して問題を解消しながら進めることが良いとされています。
そのため、最近の書籍や記事には、上記の協力がやりやすいようにチームは物理的に同じ場所で開発することを推奨しているものもあります（最近ベストセラーになった書籍「[レガシーコードからの脱却](https://qiita.com/kojimadev/items/c2f5b4fea1992385c99a)」でも推奨されています）。
しかし、実際には様々な事情で、チームが物理的に同じ場所で働くことは難しいことがあります。そんな場合に有効なのが「分報」です。
本稿は、私のチームで分報を導入して良かった点を紹介します。

# 分報とは
分報とは、Slackなどの社内チャットツールを使い、自分専用チャンネルで「今やっていること」や「困っていること」をつぶやくプラクティスです。詳細は以下を参照ください。
[Slackで簡単に「日報」ならぬ「分報」をチームで実現する3ステップ〜Problemが10分で解決するチャットを作ろう](http://c16e.com/1511101558/)
[Slack分報についての質問と回答：僕のチームではどのように分報しているか？](http://c16e.com/1511171901/)

ポイントは以下です。

- 自分専用チャンネルなら、気軽に困っていることをつぶやける(先輩に直接質問するより敷居が低い)。
- 困っている内容を見て、解消方法を知っている人が助言することで、一人で調べて解消するよりも、早く問題が解消され、開発が加速する。
- 自発的に他メンバーが困っている内容を見て助言をすることが多くなるため、助け合う風土が自然に根付く。

例えば、下図のように、つぶやきに対して、他メンバーが助言することで開発が加速します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/cae2d028-5c73-afcc-e56c-25ae7d689ea7.png)

なお、このように、自分の作業の途中経過をアウトプットしながら開発を進める手法は、「Working Out Loud」という近年注目されているコンセプトにも合っています。これは以下の式で説明されます。
「Working Out Loud（コラボレーションによる成果の達成）= Observable Work（作業の可視化）+ Narrating Your Work（作業の共有）」
作業の途中成果や作業過程の思考プロセスが可視化されることで、早い段階でのフィードバックを得られたり、他メンバーと思考プロセスの知見を共有できたりします。
詳細は、以下参照ください。
[Working Out Loud 大声作業（しなさい）、チームメンバー同士でのトレーニング文化の醸成](https://quipper.hatenablog.com/entry/2018/11/14/working-out-loud)

# 導入効果
私のチームで導入してみたところ、以下のような良い効果がありました(チーム人数は4人です)。

### 自分で問題を整理
分報の導入前、開発経験の少ないメンバーは、ついついタスクに没頭して視野が狭くなることで、非効率な調査をしてしまうことがありました。
分報を導入後は、自分の作業経過を随時書くことで、問題が自然に整理され、自分の思考が迷子になる頻度が少なくなり、効率が上がりました。
具体例として、C#の不具合調査を行う際に、調査して分かったことを随時書きながら進めることで、問題を整理しながら無駄な調査をせずに進めることができました。

### 新人の困りごとの早期解消
チームに配属されたばかりの新人に対しても分報の効果がありました。
チーム全体のチャンネルに新人が質問を投稿するのは、気後れするようで「ちゃんとした文章を書かなきゃ」と思ったりなど、結構ハードルがあるようです。
それに対して、分報は自分専用チャンネルなので、気兼ねなく困ったことをつぶやけていました。そして、先輩社員が困ったことを拾って解消していました。

### アクションアイテムの漏れ防止
自分がちょっと後でやろうと思っているアクションアイテム(もしくはTODO項目)を忘れないように、分報でそのアクションアイテムを投稿し、ピン留めするメンバーもいました。
チームのチャンネルでなく、自分専用チャンネルのピン留めなので、気軽に使える点が良い感じでした。

## 心理的安全性の向上
あるメンバーが非効率なやり方で作業を進めようとしている場合に、他メンバーがたびたび助言をしますが、それが起きた時は__積極的に「開発が加速して良かった」というポジティブな感情をメンバ間で共有しています__。また、調査の途中経過に対しても__「論理的に妥当な方針で進められている」というポジティブフィードバックを行っています__。
そのように、自分の発言に対して前向きなフィードバックが得られる経験を何度もすることで、途中経過や考えの発信頻度が上がってきました。
これはおそらく「安心して自分の考えを発信できるようになる」という意味で、心理的安全性の向上があったと思います。
（心理的安全性とは、Googleが成功するチーム構築に最も重要なものだと発表したものです）
[心理的安全性を高める | Google re:Work](https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/steps/foster-psychological-safety/)

# まとめ
分報は、メンバー間の協力を加速させる効果的なプラクティスと思います。

<b>2020/8/26 追記</b>
上記の他、1年以上かけて様々な成長するための施策を実施しています。以下の記事にまとめていますので、ぜひ参照ください。
[1年以上かけて生産性倍増＋成長し続けるチームになった施策を全部公開](https://qiita.com/kojimadev/items/4b28f801863cf4e8f0da)

上記のプラクティスを活用して、私は [Lightning Review というレビュー支援ツール](https://www.lightning-review.com/) を開発しています。
Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)
wordで日本語と英語のフォントを指定して自動変換するマクロ

業務で使えそうなマクロを作成したのでメモ

Sub Font_Change() 'フォントの種類別一括変換
  Dim doc_all As String
  Dim doc As Range
  Dim k As Long
  With ActiveDocument
      doc_all = .Range(0, .Bookmarks("\EndOfDoc").End)
  End With
    For k = 1 To Len(doc_all)
        Set doc = ActiveDocument.Range(k - 1, k)
        If doc.Font.Name = "Cambria Math" Then '数式用のフォントを確認
        ElseIf doc.Text Like "[^ぁ-んァ-ヶ一-龠〃々〆〇｡-ﾟ]" Then '日本語識別
             doc.Font.Name = "ＭＳ 明朝 (本文のフォント - 日本語)"  '日本語フォント
         ElseIf doc.Text Like "[A-Za-zＡ-Ｚａ-ｚ]" Then  '英語識別
            doc.Font.Name = "Century (本文のフォント)"  '英語フォント
        Else: doc.Font.Name = "ＭＳ 明朝 (本文のフォント - 日本語)"  'その他のフォント
            End If
    Next
End Sub


マクロの使い方
https://kekaku.addisteria.com/wp/20180608164803
メモ: bash の set

## 参考

* [シェルスクリプト (Bash) では組み込みコマンド set を活用しましょう | ラボラジアン](https://laboradian.com/use-set-in-bash-shell-scripts/)
* [【 set 】コマンド――シェルの設定を確認、変更する：Linux基本コマンドTips（205） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1805/10/news023.html)

`man set` 

## 引数

```sh
# 現在有効になっている設定値確認
set -o

# 現在有効になっている設定値確認 himBH のように、オプション値で表示
echo $-

# ジョブコントロールの有効化
set -m
```

```sh
# 定義一覧を確認
set
```

## rpmbuild で `no job controll`となる場合

![スクリーンショット_2019-11-19_05-33-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/787ec6ea-3b0d-ae7a-653b-aa1a90366bf0.png)

```diff:perl.spec
- %global parallel_tests 1
+ %global parallel_tests 0

 (略)
  %if %{parallel_tests}
      JOBS=$(printf '%%s' "%{?_smp_mflags}" | sed 's/.*-j\([0-9][0-9]*\).*/\1/')
      LC_ALL=C TEST_JOBS=$JOBS make test_harness
  %else
      LC_ALL=C make test
  %endif

```

### 別のエラーが出たけどそれは別の話。

![スクリーンショット_2019-11-19_06-36-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/aed1b7e4-bb6e-2e06-f0af-8ea81bf75007.png)
Serverlessのwebpack.config.jsを読む

sls createすればwebpackの設定ファイルは作られちゃってデプロイ設定までしてくれて、デプロイすればCloudFormationだの作ってくれちゃったり色々やってくれるServerless Frameworkですが、理解せずともいろいろできている状態はよろしくないので設定部分について少しずつ理解を深めていきます
まずは手始めにwebpack.config.jsを読みます

## バージョン
Serverless v1.53.0
node v10.13.0

## Serverlessのテンプレート
AWS
TypeScript

`$ sls create -t aws-nodejs-typescript -n app_name -p path`

できあがるwebpack.config.jsがこちら
↓↓↓↓↓↓↓
## webpack.config.js
```JS
const path = require('path');
const slsw = require('serverless-webpack');

module.exports = {
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  entry: slsw.lib.entries,
  devtool: 'source-map',
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  target: 'node',
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      { test: /\.tsx?$/, loader: 'ts-loader' },
    ],
  },
};
```

上から見ていきます

## mode

```JS
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
```

production, development, none の３つがあり、developmentだと非圧縮の状態でビルドされる
productionは圧縮されてビルドするという違いがある
ローカルでビルドする場合は非圧縮、リモートへビルドする場合は圧縮する

## entry

```JS
entry: slsw.lib.entries,
```

webpackがビルドを始めるときの開始点となるJSファイルを指定する
通常はindex.jsみたいなメインとなるJSファイルを指定するところですが、Serverlessの場合はserverless-webpackに任せる形

## devtool

```JS
devtool: 'source-map',
```

devtoolを指定すると、圧縮してビルドしたJavaScriptのコードと元のコードを対応関係を記すファイルが生成される
コンソールに表示されるJavaScriptのエラーはコンパイルしたあとのコードを表示するが、SourceMapを作っておくと、ブラウザが対応関係を確認し元のコードを表示してくれる

## resolve

```JS
resolve: {
  extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
},
```

ビルドに含めたいファイルの拡張子を配列で指定する
TypeScript用なので.ts, .tsxなどが入っています

## output

```JS
output: {
  libraryTarget: 'commonjs',
  path: path.join(__dirname, '.webpack'),
  filename: '[name].js',
},
```

outputには出力先と出力ファイル名を指定する

### path
出力するpathを指定、この場合は`.webpack/`ディレクトリ配下に出力

### filename
出力するファイル名を指定、entryをserverless-webpackに任せているがデフォルトだとhandler.jsという名前で出力される

```JS
// 以下のように書くと handler.bundle.jsというファイル名になる
filename: '[name].bundle.js'
```

### libraryTarget
bundleの形式を指定していて、この場合はCommonJS形式となる

- CommonJS形式とはなんぞや
  - JavaScriptのモジュール管理の仕組みのこと
  - `module.exports`によるエクスポートと`require()`によるインポート
  - exportsのプロパティに追加した関数は、requireを使って呼び出せまっせってこと

CommonJS形式で提供しておけばNode.js環境とブラウザ環境どちらでも読んでもらえる

## target

```JS
target: 'node',
```

Node.jsで実行されるbundleを生成する

## module

```JS
module: {
  rules: [
    // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
    { test: /\.tsx?$/, loader: 'ts-loader' },
  ],
},
```

webpackはJavascriptしか理解できないため、TypeScript等で書かれたコードは理解できない
それを解決するためにloaderを指定して変換してwebpackに理解させる設定

### test
変換するファイルの拡張子を指定する
testというプロパティ名が意味不明すぎるw

### loader 
変換に利用するloaderを指定する
この場合、TypeScriptの`ts-loader`を使って変換する

以上、とりあえず一通り読んで調べて「なんこれ頭痛いわ」状態から抜け出せた気がします
jupyterのテーマの設定について　自分用

参考にしたサイト
[https://qiita.com/uratatsu/items/cdc83308ce85a32d0512](https://qiita.com/uratatsu/items/cdc83308ce85a32d0512)

以下が、自分のやっている設定

```
# cellwに関しては、パソコンによって変える。
jt -t monokai -N -kl -f roboto -nf roboto -tf roboto -ofs 10 -cellw 95%
```
Enigmaを使ったDappsを作ってみよう インストール編

こんにちは [なまはげ(@_namahagesan)](https://twitter.com/_namahagesan)と申します。

Enigmaというブロックチェーンを用いた秘匿計算プラットフォームのテスト用環境が提供され始めました。
まだ、ブロックチェーンのネットワークにはなっていないのですがシークレットコントラクトと呼ばれる秘匿計算を行うコントラクトを実行したり、これを用いたアプリケーションを作れるようになりました。
このシリーズではEnigmaの開発チームが公開している「くじ引き」アプリを実装していこうと思います。

# Enigmaとは
ブロックチェーンの問題点の一つとしてブロックチェーン上のトランザクションのデータが全て見ることができてしまうという問題点がありました。それに対策すべく、ゼロ知識証明を用いて送金などのデータを秘匿化したMoneroなどの通貨が生まれています。しかし、これらのゼロ知識証明では送金などの決められた処理しか秘匿化できず、Ethereumのスマートコントラクトのような柔軟な処理は不可能です。
そこでEnigmaではTEEと呼ばれる耐タンパ性のあるハードウェア内でコントラクトを実行し、入出力を暗号化することでコントラクトを実行したアカウントなど一部のアカウントのみがコントラクトの入力と出力を知ることができるようになります。これによって送金に限らない様々な処理を秘匿化して行うことが可能になります。

今回はこのEnigmaの環境設定を行っていきます。
まだテストネットもパブリックなものは存在していないので今回はローカル環境で行っていきます。

# Enigmaの環境設定
事前にdockerを使えるようにインストールしておきましょう。
## NodeJSの設定
NodeJSのバージョンは10.17.0で固定しましょう。
もしかしたらそれ以外のバージョンでも動くかもしれませんが、現状最新版と安定版では動きません。（エラーが出てきます）
今後、最新版でも動くようになったり、他にNodeJSを使う場面もあると思うので未インストールの人でもNodeJSのバージョン管理ツール、Nodebrewなどを使ってNodeJSのバージョンの切り替えをできるようにしておくといいと思います。

NodebrewはHomebrewインストール済みのMacなら

```
$ brew install nodebrew
$ nodebrew install v10.17.0
$ nodebrew use v10.17.0
```

ここまでできたらnodeのバージョンを確認します。

```
$ node -v
v10.17.0
```

となれば成功です。

### Discovery CLIのインストール
続いてDiscovery CLIをインストールします。Discoveryというのは現在開発中のEnigmaのバージョン名のようなものです。
インストール自体は

```
$ npm i -g @enigmampc/discovery-cli 
```

で完了です。
次に開発用のディレクトリを用意して、そこに先ほどインストールしたDiscoveryを適用します。
これによってEnigmaアプリケーションを作る準備が整います

```
$ mkdir enigma-test-dapp
$ cd enigma-test-dapp
$ discovery init
```
途中で15GBくらいのdocker imageをダウンロードしてくるので注意しましょう。
途中で何か聞かれたら基本的にはyesを回答しましょう。
また、途中で```HW/SW？```と聞かれます。これはSGXを利用したハードウェアモードかSGXを利用せず、SGXが動いているようにシミュレーションするソフトウェアモードを利用するか聞いています。今回はソフトウェアモードを選択し、```sw```と答えておきます。


### Enigmaアプリケーションのファイル構成

さて、これでEnigmaアプリケーションを作る準備が整いました。
ここでファイル構成を見ておきましょう。

```
$ tree -L 1

├── build
├── client
├── config
├── docker-compose.cli-hw.yml
├── docker-compose.cli-sw.yml
├── docker-compose.yml -> docker-compose.cli-sw.yml
├── migrations
├── node_modules
├── package-lock.json
├── package.json
├── secret_contracts
├── smart_contracts
├── test
└── truffle.js
```


```smart_contracts``` フォルダにはSolidityで書いた***Ethereum用の***スマートコントラクトを格納します。
これはEnigmaアプリケーションではシークレットコントラクトによるEnigma上での処理の他にEthereum上でも処理を行う場合があるからです。（ETHの受け渡しなど）
また、シークレットコントラクトからスマートコントラクトを呼び出すことができます。

```secret_contracts``` フォルダでシークレットコントラクトを編集します。
コンパイルされたコントラクトたちはabiやwasmファイルになって ```build``` フォルダに移動します。

Reactによって書かれたフロントエンドは```client``` フォルダで編集します。
また、テストは```test``` フォルダで編集します。

なので主に```smart_contracts``` フォルダ、```secret_contracts``` フォルダ、```client``` フォルダ、```test``` フォルダの4つを編集します。

と、ここまででとりあえず終了です。
次回はいよいよシークレットコントラクトを書いていきます。

## Enigma Developer Guildの宣伝
弊社turingumではEnigma開発を行う開発者のコミュニティであるEnigma Developer Guildを作っています。
まだEnigmaが正式ローンチ前なのでほとんど活動していませんが、今後Enigma開発に関する議論や質問、イベントなどを行っていくつもりです。
参加はもちろん無料で入退会自由なコミュニティです。

このリンクからslackチャンネルに登録できます。（準備中）
【初心者】jQuery　イベント処理／CSS・text・htmlメソッド／this／変数／メソッドチェーン／find・children【備忘録１７】

##11/17～11/18に勉強したこと
###イベント処理
WEB上でクリックした際に、イベント内で指定した処理を実行させること。

```js

$('セレクタ').イベント名(function(){
　　　  //イベント発生時に実行したい処理
});
```

基本的に上記のように書く。

【例】ボタンをクリックした時⇒文章を隠す

```js
//html
<div id="hide-text">説明を隠す</div>
<p id="text">ボタンをクリックすると文章が隠れる</p>

//js
$('#hide-text').click(function(){
  $('#text').hide();
});
```
【気を付けること】
- [function()]を忘れやすいので気を付ける。
- idの際の#を付け忘れないようにする。


###CSSメソッド
CSSを変更することができるメソッド

```js
$('セレクタ').css('プロパティ','値');
```
基本的に上記のように書く。

【例】

```js

//css
p{
color:blue;
}

//js
$('p').css('color','red');

```
【出力】
青色だった値が赤色に変更された。

###textメソッド
CSSだけでなく、HTMLの文字や値を変えることができる。

```js
//html
<p>こんにちは</p>

//js
$('p').text('こんばんは');
```
【出力】
「こんにちは」の表示が「こんばんは」になる。

###htmlメソッド
上記のように文章などではなく、HTMLそのものを変えることができる。

```js

//html
<p>こんにちは</p>

//js
$('p').html('<span>こんばんは</span>');

```

###this
【例】

```js

//html
<ul>
  <li>リスト１</li>
  <li>リスト２</li>
</ul>

//js
$('li').click(function(){
  $(this).css('color','red');
});

```

【出力】
リスト１
リスト２

と普通に表示されていたものが、クリックした文字だけ赤文字に変わる。

【気を付けること】
(this)には「"」や「'」は付けないこと！


###変数(var)
同じオブジェクトを使用する際に変数にすることによって
★見やすくなる　★処理が速くなる　ので覚えておく。

【例-使用していないバージョン-】

```js
$('div').css('color','red');
$('div').html('jQuery');
```
【例-使用したバージョン-】

```js
var $div =$('div');

$div.css('color','red');
$div.html('jQuery');
```

###メソッドチェーン
メソッドをつなげて書くことができる。こちらも見やすくなるので覚えておく。

【例】

```js

$('div').css('color','red').html('jQuery');

//varで変数宣言した後に$div.css...で書いても反応する。
```

###find/children
#####find
親要素より下のすべての要素を取得する。
[HTML↓] 

```html
<div id="wrapper">
 <a href="#">リンク１</a>
 <p>
  <a href="#">リンク２</a>
 </p>
</div>
```

[js↓]

```js
$('#wrapper').find('a').css('color','red');
```
【出力】
リンク１もリンク２も赤色になる。

#####children
一階層下の子要素のみを取得できる。
[HTML↓] 

```html
<div id="wrapper">
 <a href="#">リンク１</a>
 <p>
  <a href="#">リンク２</a>
 </p>
</div>
```

[js↓]

```js
$('#wrapper').children('a').css('color','red');
```
【出力】
リンク１のみ赤色になる。

###hoverイベント
マウスを乗せたとき／外した時に指定した処理を行う。

【気を付けること】
引数が２つ必要！間は「,コンマ」で区切る！

【例】

```js
$('div').hover(
 function(){
  $('#wrapper').fadeIn();
 },
 function(){
  $('wrapper').fadeOut();
 }
);
```

【出力】
カーソルを乗せたとき徐々に表示。外した時徐々に消える。

##今後
初級編が一息ついたので、リセットして復習⇒そのあと中級編に移る！
超簡単な触りを見て、FlutterのColumnとRowのウィジェットイメージを理解する

# 対象読者
初心者で、RowやColumnのイメージだけを知りたいレベル
簡単なRowやColumnを書く時の参考にしていただけるといいかもしれません。
僕は文章だけだと全く理解できないので、図にしてみました。

# どのような時に使うのか？
## 子が複数の時
ColumnやRowを用いる

### Column
子（child）を垂直配列で表示するウィジェット。

https://api.flutter.dev/flutter/widgets/Column-class.html

### Row
子（child）を水平配列で表示するウィジェット。

https://api.flutter.dev/flutter/widgets/Row-class.html

### 仮に以下の画像を無理やりウィジェットで表現してみると
https://icooon-mono.com/16213-%e6%8e%88%e6%a5%ad%e3%81%ae%e3%83%95%e3%83%aa%e3%83%bc%e7%b4%a0%e6%9d%90/

![授業のフリー素材.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451035/2d5e66d3-0864-73e1-2954-1ecf7c72b510.png)


- Container
    - Column
        - Row・・・A
            - Icon・・・C
            - Icon・・・D
        - Row・・・B
            - Icon・・・a
            - Icon・・・b
            - Icon・・・c

このような形で表せる。

#### Container
paddingやborderやmarginなどの設定をする。
今回は、全体を覆っている。

![授業のフリー素材.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451035/87f7c48e-7874-1ad8-5f06-32ef40ce9331.png)

#### Column
Containerの子。
先の例のAとBを垂直方向に表示している。

![授業のフリー素材.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451035/a382fc61-ee2e-2c9e-7d13-2e3948d6c1ae.png)

#### Row
Columnの子。
先の例のCとD、かつaとbとcを水平方向に表示している。

![授業のフリー素材.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451035/49aecefd-636c-88f9-14d5-103ea5b0233d.png)

#### サンプルコード
全く同じものを作ることは大変だったので、似たようなアイコンをあててみる。そんなに丁寧に書いてません。とりあえず表示させる所だけ。

```dart
// lib/main.dart
import 'package:flutter/material.dart';

void main() => runApp(JinDesignContainer());

class JinDesignContainer extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
    home: _buildImageSample(),
  );
  Widget _buildImageSample() {
    return Container(
      color: Colors.white,
      child: Column(
        children: <Widget>[
          _buildUpperSide(), // A
          _buildLowerSide(), // B
        ],
      ),
    );
  }
  // A
  Widget _buildUpperSide() {
    return Row(
      children: <Widget>[ // Iconのデフォ値が24なので24*3を２つに区切っている
        Icon(Icons.person, size: 34,), // C
        Icon(Icons.sms, size: 38,), // D
      ],
    );
  }
  // B
  Widget _buildLowerSide() {
    return Row(
      children: new List.generate(3, (i)=>Icon(Icons.person),), // a, b, c
    );
  }
}
```

<img width="403" alt="スクリーンショット 2019-11-19 2.51.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451035/87303266-3d7e-11fa-9127-13d275381142.png">


### ウィジェット
この単純なウィジェットを組合せて複雑なレイアウトを作っていく。
一見すると難しいが、簡単な図で試してみるとレイアウトに関しては何となくイメージしやすいんじゃないかと思います。

### なお、子が単数の時は
当然、ColumnやRowは用いない。

CenterやAlignなどを用いる。

## Align
https://api.flutter.dev/flutter/widgets/Align-class.html

## Center
https://api.flutter.dev/flutter/widgets/Center-class.html
【Javascript】PHPのlist関数のようにJSで配列の要素を一気に変数群に展開する【TL;DR】

メモとして残します。


# ■やり方
## on PHP
```PHP
list($id, $name, $remark) = [1, 't.yamada', 'bikou'];
```
## on Javascript
```javascript
let [id, name, remark] = [1, 't.yamada', 'bikou'];
```

phpはバージョンによりますが、PHP、JSともに不要な展開は変数定義しないで飛ばせます（（$a,,$c）みたいに。）。
VBScriptでのReDimの罠

VBScriptで動的配列の要素数を変えるためには、ReDimを使います。
しかし、ReDimを使うときに意図せずに配列の中身をすべて消すことになることもあるので、注意が必要です。
例えば、以下のコードではReDimのタイミングで要素数6の空配列になってしまいます。

```vb
Dim arr()
ReDim arr(2)
arr(0) = "hoge"
arr(1) = "fuga"
arr(2) = "piyo"

ReDim arr(5)
```

ReDim以前に配列に保存した値を保持したい時にはPreserveを付与する必要があります。

```vb
Dim arr()
ReDim arr(2)
arr(0) = "hoge"
arr(1) = "fuga"
arr(2) = "piyo"

ReDim Preserve arr(5)
```
さくらのサーバーによるpython3の動作

さくらのサーバーで公式に対応しているのはpython 2.7
python 3系列も手動でインストールすれば一応は使える。
python 3.6はpipが古いためエラーを起こして更新できない。
python 3.7.5はpipが動作する。
[UE4] CSVToSVGToolを用いたパフォーマンスグラフ作成

#1. はじめに
**[検証バージョン：4.24.0]**
　4.23から追加された**[CSVToSVGTool](https://docs.unrealengine.com/en-US/Engine/Performance/CSVToSVG/index.html)**はCSVProfilerで取得したデータをグラフ化するためのコマンドラインツールです。このツールを利用することでCSVProfilerで出力した.csvファイルを.svgファイルに変換し、パフォーマンス推移グラフとして可視化することができます。
　ざっくり言えば**「カッコいいグラフを作るツール」**です。

**[基礎知識]**
[公式ドキュメント：CSV Profiler](https://docs.unrealengine.com/en-US/Engine/Performance/CSVProfiler/index.html)
[Qiita：[UE4] CSV Profileを用いたパフォーマンス計測](https://qiita.com/EGJ-Ken_Kuwano/items/a6c97a7eda8d69cae6d5)

これらのツールを用いることで以下のようなグラフを作成することができます。上の.csvファイルはCSVProfilerから取得されたもので、下のグラフは.csvから.svg変換したものとなります。

![2019-11-20_17h59_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/546de6ad-682e-328c-db05-6eade5969aad.png)

#2. 使い方
　CSVToSVGToolを利用してパフォーマンスグラフを作成する手順は以下の２つです。

**【CSVToSVGToolでパフォーマンスグラフを作成する手順】**
**① CSVProfilerでアプリケーションのプロファイルデータ(.csv)を取得**
　CSVProfilerの使い方を参考に、csvprofile start/csvprofile stopコマンドを利用して取得できます。

**② CSVToSVGToolでプロファイルデータ(.csv)を.svg形式に変換**
　CSVToSVGToolはコマンドラインツールのため、必要な引数とプロファイルデータを渡すことで変換します。

以下は②のバッチファイル例で、プロジェクト構成に沿って編集することで直ぐに活用できます。

```bat:CSVToSVGTool.bat
@echo off
rem ---------- Common ----------
rem Engine Root
set ENGINE_PATH=G:\GitHub\UnrealEngine-4.24
rem Tool Path
set TOOL_PATH=\Engine\Binaries\DotNET\CsvTools\CSVToSVG.exe

rem ---------- Option ----------
rem 入力先csv指定: -csv [csvFileName] OR -csvs [list] OR -csvDir [path]
set CMD_CSV=-csv G:\Report\Profile(20191204_232056).csv
rem 出力先svg指定: -o [svgFilename]
set CMD_O=-o G:\Report\Profile(20191204_232056).svg
rem stats指定: -stats [stat names]
set CMD_STATS=-stats Exclusive/GameThread/*
rem オプション
set OPTION=%CMD_CSV% %CMD_O% %CMD_STATS%

@echo on
%ENGINE_PATH%%TOOL_PATH% %OPTION%
```

このバッチファイルを利用すると、-statsで「Exclusive/GameThread/*」と指定しているためGameThreadに関する情報のグラフを作成します。このパラメータを変更したい場合は、[4.2. 出力されるプロファイル情報](https://qiita.com/EGJ-Ken_Kuwano/items/a6c97a7eda8d69cae6d5#42-%E5%87%BA%E5%8A%9B%E3%81%95%E3%82%8C%E3%82%8B%E3%83%97%E3%83%AD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%83%85%E5%A0%B1)の「Profile項目一覧」から抽出する文字を指定してください。完成後に以下のように出力されます。

![2019-12-04_23h38_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/71b2bed8-d585-0e14-0cbd-3a33405cc7f9.png)

#3. 引数一覧
　CSVToSVGToolに対して指定する引数については[「公式ドキュメント：CSVToSVGTool」](https://docs.unrealengine.com/en-US/Engine/Performance/CSVToSVG/index.html)に記載されているためご参考ください。

#4. まとめ
　CSVToSVGToolを利用することで、CSVProfilerで取得したパフォーマンスキャプチャデータを自動で手軽にグラフ化することができます。この作業は地味に面倒で手間がかかるため、日々のパフォーマンスを監視することに役に立つと思いますので是非ご活用ください。
VBScriptでの変数宣言の巻き上げの罠

以下のスクリプトは変数sを宣言せずに代入しているために、エラーになります。

```vb
Option Explicit
s = "hoge"
```

しかし、以下のスクリプトはエラーになりそうですが、エラーになりません。
2行目の時点ではsの宣言が行われていないにも関わらず、エラーなく処理を行うことができます。

```vb
Option Explicit
s = "hoge"
Dim s
```

実は、VBScriptにはJavaScriptと同様に変数の巻き上げを行う仕様があります。

そのため、以下のスクリプトと等価になります。

```vb
Option Explicit
Dim s
s = "hoge"
```

JavaScriptと同様に意図しない挙動につながることが多いため、変数の巻き上げは起こさないようにコーディングをするように心がける必要があります。
具体的には、変数宣言はスコープの先頭部分で行うようにするのが無難です。
【WordPress】プライバシーポリシーページのパーマリンクの取得方法

ものごっつ今更感があるのですが、Googleで『WordPress プライバシーポリシー パーマリンク』とかで調べても1ページ目に出てこなかったため。

## 方法

と言っても、WordPressにこなれた人ならすぐ思い当たる関数名でした。

```php:example.php
the_privacy_policy_link( $before, $after );
```
これだけ。見りゃ分かるかと思いますが、一応引数の説明を。

|パラメータ|データ型|説明|初期値|
|:---:|:---:|:---:|:---:|
|`$before`|文字列|オプション：リンクの前に連結するテキスト。|（無し）|
|`$after`|文字列|オプション：リンクの後に連結するテキスト。|（無し）|

もちろん、getバージョンもあります。引数も同じ。

```php:example.php
get_the_privacy_policy_link( $before, $after );
```

ただしこの`get_the_privacy_policy_link`、`<a>`タグ付きのリンクとして取得するので、`get_permalink`と同じノリで使おうとするとちょっとだけハマる。（筆者が最初ハマった）

```php:example.php
get_privacy_policy_url();
```

パーマリンクのみ取得するための関数も用意されてるので、URLだけ欲しければそっちを使おう。


<br>
## 応用

編集画面（`wp-edit.php`）上でも使う関数だと思うので（問い合わせフォームとか）、ショートコードにしちゃってもいいでしょう。

```php:functions.php
function privacy_link() {
	if ( function_exists( 'the_privacy_policy_link' ) ) {
		return get_the_privacy_policy_link( '', '' );
	}
}
add_shortcode('privacy', 'privacy_link');
```

```html:編集画面
[privacy]
↓
<a class="privacy-policy-link" href="https://www.example.com/privacy-policy/">プライバシーポリシー</a>
```

<br>
Codex見りゃ分かる話…かと思いきや日本語のCodexにページが無い（2019年11月現在）上に、上記キーワードで調べると**リンクを生書き**させている初心者指南サイトがほとんどだったので、一応共有しとこうかなあ…と思った次第です。

WordPressに慣れてれば1～2回試行すりゃ当たりを引けそうな（というか筆者がそう）そのまんまな関数名ですが…
関数を使える場面では使った方が取り回しがきくというか、WordPressを使う意味が無いですし。慣れない人、初心者の方ほどこういう情報が必要かな、と。
いずれにせよ、『テンプレートを編集しよう！→リンク生書き』は**さすがに無い**ので、この情報を求めてググった人の検索上位に表示されますように。
vue-cli+firebaseをnetlifyでデプロイしたら認証機能が使えなかった

# netlifyに至る過程
今まではfirebase hostingでデプロイしていたので、自動デプロイという言葉に惹かれ、下記の人達を参考にして、netlifyを使ってみました。↓
https://qiita.com/shozzy/items/dadea4181d6219d2d326
https://qiita.com/tiwu_official/items/5d1e883b3190cd8de56f
　
# はまったところ
そしてfirebaseのログイン機能が付いたチュートリアルの写経を試しにnetlifyで自動デプロイしたところなぜかログインできませんでした。ローカルなら普通にログインできるのに・・・。
下記がエラー文です。
![スクリーンショット (55).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/bdc693f8-4c28-2582-04fd-f514f92d0077.png)

# 解決方法
firebaseAuthenticationで承認付きドメインに登録すると認証が有効になりました！
まぁ、よく考えたら当たり前の話でしたね..
<img width="960" alt="スクリーンショット (56).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/2b24e9de-f1b7-16e1-5806-faf6847506df.png">


# 使わせていただいているチュートリアル↓
https://www.udemy.com/course/vuejs-firebase/learn/lecture/14204318#overview
git pushしたらPermission to hoge.git denied to hugaとなったときの解決方法【Windows】

**この方法はWindowsだけです**
(同じような感じでMacとかもいけるかも)

# 解決方法
1. コントロールパネル -> ユーザーアカウント -> 資格情報マネージャーにいきます
2. Windows資格情報をクリック
3. 汎用資格情報の git:https://github.com を削除

異常が終わってからもう一度git pushするとgithubのアカウント確認が出るので、打ち込む

以上

# 参考文献
https://www.freecodecamp.org/forum/t/need-your-help-with-github-permission-denied-to-my-own-repo/17421

半年くらいできなかったのが解決してよかった。よくわからないまま使うのはだめだね
DynamoDBって結構使われてるけど触る機会がないと触らないよね。触ってみた。

DynamoDB もしばしば使われますが、KVS よりちょっと複雑な印象で敬遠してました。
無理やり機会を作って触ってみました。

## 環境構築、テストデータ

[開発やテスト用の DynamoDB Local の Docker Image](https://hub.docker.com/r/amazon/dynamodb-local/)がありますが、AWS のマネジメントコンソールからクエリを発行できたりするので AWS を使います。

今回はランチの評価データを管理してみます。

- ユーザID
- 店名(本当は店IDが良いかもしれませんがわかりやすいので…)
- コメント

ユーザIDと店名をキーにしてみます。
今回は Ruby と AWS SDK でやってみます。

## テーブルを作成する

```ruby
require "json"
require "aws-sdk"

TABLE = "meals"

dynamo = Aws::DynamoDB::Client.new(
    region: "ap-northeast-1",
    access_key_id:  ENV["AWS_ACCESS_KEY_ID"],
    secret_access_key:  ENV["AWS_SECRET_ACCESS_KEY"],
)

options = {
    table_name: TABLE,
    key_schema: [
        {
            attribute_name: "user_id",
            key_type: "HASH"
        },
        {
            attribute_name: "shop_name",
            key_type: "RANGE"
        }
    ],
    attribute_definitions: [
        {
            attribute_name: "user_id",
            attribute_type: "N"
        },
        {
            attribute_name: "shop_name",
            attribute_type: "S"
        }
    ],
    provisioned_throughput: {
        read_capacity_units:  1,
        write_capacity_units:  1
    }
}

# NOTE: テーブル作成は非同期。この直後にデータ挿入を行うとテーブルがなくてエラーになります。
dynamo.create_table(options)
```

## データを挿入する

```ruby
100.times do |n|
    # NOTE:一括はbatch_write_itemのほうが速いです
    dynamo.put_item(
        table_name: TABLE,
        item:  {
            user_id: [1, 2, 3].shuffle[0],
            shop_name: %w(海 馬 山 川 山本 鈴木 ゴン キン ベジ).shuffle[0] + %w(寿司 ラーメン カレー 中華 アジアン 食堂).shuffle[0],
            text: 
              %w(ぎとぎとしてて さっぱりしてて ぬるぬるしてて まったりしてて ぱさぱさで).shuffle[0] + %w(美味しかった うんま! まずかった まずまずだった くっせ!).shuffle[0]
        }
    )
end
```

雑ですが適当に、ユーザ1〜3がいろんな店のコメントを書いている、というデータを挿入しました。

## データを読み出してみる

Rubyでやってもよいですが、AWSのコンソールに触れてみたかったのもあり、触ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21799/8d9b7faf-bc09-d839-d5bc-00c641aed73e.png)

おー、入ってる。キーがユーザIDと店名なので2回目の来店で上書きされてますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21799/27e3cdd3-05f5-4fb1-b328-aaa7f7cf3de5.png)

誰が、どの店を、の条件で検索もできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21799/826238a1-37aa-0b97-bbc9-46784bba0a35.png)
キン寿司の評価を探してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21799/fb2b58b7-f5e2-b341-4faa-392990b21f9d.png)
key に指定していない text で探すこともできた。
本当か!? indexとは?

## 向いていること

- KVS。シンプルでメンテのいらない高速なKVSとして使用できます
- 副業主キーが表現できる
- データを挿入さえしてしまえばkeyではない項目でも検索できる(まじか? コンソールだけの機能かも) 

## 向いていないこと

- RDBにあるような参照や制約

## まとめ

スキーマレスでキーを複数指定できるKVSです。
スキーマレスではありますが、キーの定義は必要で、テーブル定義がとっつきにくく感じました。
躓いた感があり、十分に評価できていません。
memcachedより複雑なデータ構造を扱うことができ、運用のことを考えなくて良いのが良いところですね。