OmniAICreator/Qiita-1.07M huggingface dataset:
ストレージについて勉強する③

#ストレージについて勉強する③
インフラエンジニア。社会人1年目。
ちょっとわからなくなってしまって関西弁が出てくる。
##スケールアウトとスケールアップってなんやねん
###スケールアップ型：
メモリやHDを増設したりCPUをより上位スペックに交換したりして、サーバのパフォーマンスを向上させる技術。扱うデータを複数サーバに分散させづらい場合は有効。
サーバを停止して拡張するが、一部クラウドでは停止させなくていいものもある。

###スケールアウト型：
複数のサーバをスイッチでつなぎ合わせることによって束ねて1つのファイルシステムとして管理する。
拡張が無停止で可能なうえに、物理的には無限に近い拡張性を持つ。パブリッククラウドで有効な方法。

###つまり
スケールアップ：サーバのCPU やめもりをスペックアップして処理能力を高める。
スケールアウト：サーバの台数を増やして性能を高める方法。

##DAS,NAS,SANってなんやねん
いやもう
[ここ](https://www.fujitsu.com/jp/products/computing/storage/lib-f/tech/beginner/san-nas-das/)参照。

##インターフェースってなんやねん
SCSI:コンピュータ本体にストレージ装置などの周辺機器を繋いで通信するための接続規格の１つ。パラレル方式。
SAS：シリアル方式。

→パラレルは相互通信なのでメールとか重要なもの。時間がかかる。が、セキュリティOK
→シリアルは一方通行なので音声とか一気に送るもの。時間はかからない。

##参照
[用語集｜スケールアップ](https://www.idcf.jp/words/scaleup.html)
[ストレージのスケールアウトはどのようなメリットがあるのか](https://tintri.co.jp/blog/storage-scale-out/)
[React + TypeScript] Reactで特定のコンポーネントのPropsの型を取り出す方法

下記のようにReact.ComponentPropsを使用する。

```typescript
interface Props {
  name: string
  age: number
}

const Component: React.FC<Props> = props => <div />

interface CustomizedComponentProps extends React.ComponentProps<typeof Component> {
  location: string
}
/**
 * 下記のようになる
 * interface CustomizedCommponentProps {
 *   name: string;
 *   age: number;
 *   location: string
 * }
 */
```

## 参考
[Typescript React: Access component property types](https://stackoverflow.com/questions/43230765/typescript-react-access-component-property-types)
Androidプロジェクトのビルドシステムを理解するのに役立ったサイト一覧

# はじめに

Androidアプリ開発をする上で避けて通れないのがGradleを用いたビルドシステムです。最初build.gradleファイルを見たときに何が書かれているのかわからず、とりあえずdependenciesに記述して依存ライブラリをインストールしているという方も多いと思います。（私もそうでした。。）ただ、雰囲気でGradleを書いているままでは、一向にスキルが上がらないと思い、いろいろ調べていく中で、個人的にビルドシステムを理解する上で役に立ったサイトを紹介していきたいと思います。

# 役立ったサイト一覧

## Android Developers（Configure your build）

https://developer.android.com/studio/build?hl=ja

こちらは公式のドキュメントになります。
AndroidProjectを最初に作成すると生成されるbuild.gradleファイルの内容についてなどが説明されています。

## Gradleビルド言語リファレンス

http://gradle.monochromeroad.com/docs/dsl/index.html

Gradleの公式リファレンスです。Projectクラスのプロパティやメソッドが説明されてるので、各ブロックで何を設定しているのかを理解するのに役立つと思います。

## Android Plugin DSL Reference

http://google.github.io/android-gradle-dsl/current/index.html

Android Gradle Pluginの公式リファレンスです。主にbuild.gradleのandroidブロック内に書く設定を記述するときに参考になると思います。

## Groovyを知らない人のためのbuild.gradle読み書き入門

https://qiita.com/opengl-8080/items/a0bb31fb20cb6505188b

こちらは題名の通りあまりGroovyを書いたことのない人のためのGroovyの省略記法やビルドスクリプトが解釈される仕組みなどが丁寧に解説されています。
私もGroovyをあまり書いたことがなかったので、とても参考になりました。

# まとめ

まだまだ完璧に理解したというにはほど遠いですが、それぞれのブロックが何を意味しているかなど大体の概要は理解できたかなと思います。
マルチモジュール化など複雑なアプリを構築していく上で、ビルドスクリプトを書けるスキルは必要だと思うのでこれからも勉強していきたいです。
TypeScriptである型から特定のプロパティのみ除外する方法

下記のようにOmitを使う

```typescript
type Person = {
    name: string;
    age: number;
    location: string;
}

type PersonWithoutLocation = Omit<Person, 'location'>
/**
 * 中身は下記のようになる
 * type PersonWithoutLocation = {
 *   name: string;
 *   age: number;
 * }
 */
```
[Typescript Playground](https://www.typescriptlang.org/play/#code/C4TwDgpgBAChBOBnA9gOygXigbwFBQKlQEMBbCALikWHgEtUBzAbn0OMcqIFdSAjBK0JQANsgDGxYHTRUa9JqwC+uXKEiwEKVAHU6wABbJuwADISpM9FgDypfQB44SNABooAcjGTpaDwD5VIA)

## 参考
https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/#the-omit-helper-type
ストレージについて勉強する②

#ストレージについて勉強する②
駆け出しインフラエンジニア。社会人1年目。
##0.オールフラッシュストレージとは
SSDで連結されたストレージ。今までのHDDのストレージに比べて、速いし容量も多い。価格が問題になっていたことで今までは普及してこなかったが、低コスト化が進み流行中。

##1.なんでSSDのほうがいいの？
HDDは1回目と2回目のアクセスが同じHDDディスクの場所とは限らない。
→これによってアクセスごとに速さが違ったりする。
SSDは必ず同じディスクにアクセスする。
→安定した応対速度を出せる。

##2.ストレージの現状
クラウド、クラウドと騒がれている世の中でなぜ今、ストレージなのか。
ストレージは圧倒的に速い。

##3.オールフラッシュストレージを作っている会社
NetApp,DellEMC,IBMといった老舗からNimble,PureStorage,Tintriといった新興の6社が有名。

##4.他者比較の際に見るポイント
ストレージで重要なのは速さ、コスト、データのバックアップ機能、重複排除
あと、付けられている機能がビルドインなのかビルドアウトなのか。
同じ機能でもインとアウトでかなり違う。ビルドイン(最初からつけられている)されていることで障害に強く、動きにも安定性がある。

##5.感想
SSDをつなぐインターフェースとかでまたスピードが変わるので、単純にSSDにつないどけばいいでしょとかではうまくいかないらしい…
用語がいっぱいあって大変なので1つ1つまとめていきたいと思います。
Swift：macOSメニューバーの項目の選択可否を動的に変更する

```Swift:AppDelegate.swift
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    
    @IBOutlet weak var menu: NSMenu! // Storyboardのメニューバーと接続しておく
    let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)

    var isSelectable: Bool = true
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        statusItem.menu = menu

        let selectItem menu.item(withTag: 0) // 指定タグの項目と接続してみた
        selectItem?.target = self
        selectItem?.action = #selector(AppDelegate.select(_:))

        let quitItem menu.item(withTag: 1)
        quitItem?.target = self
        quitItem?.action = #selector(AppDelegate.quit(_:))
    }

    @objc func select(_ sender: NSMenuItem) {
        // do something
    }

    @objc func quit(_ sender: Any) {
        NSApp.terminate(self)
    }

}

extension AppDelegate: NSMenuItemValidation {
    
    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
        if menuItem.action == #selector(select(_:)) {
            return isSelectable // このフラグに基づき項目の選択可否が決まる
        }
    }

}
```

`NSMenuItemValidation`の`validateMenuItem`を使ってNSMenuItemの選択可否を動的に管理することができる．
Pythonで匿名クラス (無名クラス) を作る

# That's all
```python
obj = type("Hoge", (object,), {
    "var1": 2,
    "var2": "Hello",
    "func1": lambda x: x + 1,
    "func2": lambda self, x: self.var1 * x
})

print(obj.var1, obj.var2)  # 2 Hello
print(obj.func1(2), obj.func2(obj, 2))  # 3 4
```

# others

## typeについて
https://docs.python.org/ja/3/library/functions.html#type

- 引数が1つの場合、引数の型を返す (`type("hello") -> <class 'str'>`)
- 引数が3つの場合、**新しい型オブジェクトを返す**
    - 1つ目の引数でクラス名 (テキトウで良い) 、2つ目に基底クラスをタプルで渡す
    - 3つ目の引数に、dict型でプロパティ名・値をそれぞれ渡してます (変数でもメソッドでもOKです)

## 何がしたかったか？
コマンドライン引数をargparseで解析したオブジェクトを引数にしている関数を、Pythonコード内でラクに実行したかった。

- ↓のhogeのテストコードを書いていた

```python
def hoge(args):
    fuga = args.fuga
    # ...

if __name__ == "__main__":
    parser = argparse.AugmentParser()
    parser.add_argument("--fuga", type=str, required=True)
    # ...
    
    hoge(parser.parse_args())
```
Configure an Email Letterhead and Templateの和訳が原文と全然違うので原文の手順を和訳してみた

## 趣旨

メールのレターヘッドとテンプレートの設定(プロジェクト: 組織をカスタマイズして新規ビジネスユニットをサポート)
このtrailを成功させるために、原文の手順を和訳しました。

[日本語版](https://trailhead.salesforce.com/ja/content/learn/projects/customize-an-org-to-support-a-new-business-unit/configure-an-email-letterhead-and-template)

[原文(英語版)](https://trailhead.salesforce.com/en/content/learn/projects/customize-an-org-to-support-a-new-business-unit/configure-an-email-letterhead-and-template)

原文の手順どおりに進めれば成功しました。読める人は是非原文読んでください。

## 和訳

### レターヘッドの作成

1. 画像を保存(原文のリンク先(先頭にhを補ってください)...
ttps://developer.salesforce.com/files/GetCloudyConsultingLogo.png
2. アプリケーションランチャー(左上のボタン)をクリックして「ファイル」を選択(見つからなければ「アプリケーションまたは項目を検索...」に「ファイル」と入力する)
3. 右の「ファイルをアップロード」をクリック
4. 手順1で保存した画像を選択
5. タイトルが「GetCloudyConsultingLogo」になっていることを確認する。

---

1. アプリケーションランチャーをクリックして「拡張レターヘッド」を選択
2. 「新規」を選択
3. 以下の表のとおりに入力
4. ヘッダーの「画像をメッセージに挿入」ボタンをクリック(画像のアイコン)
5. 「参照またはアップロード」を選択
6. 「GetCloudyConsultingLogo」を選択して「挿入」をクリック
7. ヘッダーエリアをクリックして、``ENTER`` キーで改行する。

| 項目(Field)       | 値(Value)                                                                                                      |
| --------------- | ------------------------------------------------------------------------------------------------------------- |
| 名前(Name)        | ``General Customer Support``                                                                                      |
| 説明(Description) | ``Use this letterhead for all public facing communications if no specific Customer Support letterhead exists`` |

13. ``Dear`` と入力
14. ``SPACE`` キーを入力
15. 右下の「差し込み項目を挿入」ボタンをクリック(中括弧のアイコン)
16. 「受信者　差し込み項目を検索...」に ``名`` と入力して「名」を選択
17. 「挿入」をクリック
18. 中括弧の最後に ``,`` (コンマ)を入力し、 ``ENTER``キーを入力
19. 「保存」をクリック

### レターヘッド+メールテンプレート

20. アプリケーションランチャーをクリックして「メールテンプレート」を選択
21. 「新規メールテンプレート」をクリック
22. 以下の表のとおりに入力
23. 保存をクリック

| 項目(Field)  | 値(Value)                                                                                    |
| ---------- | ------------------------------------------------------------------------------------------- |
| メールテンプレート名 | ``Public Facing General``                                                                   |
| 説明         | ``To be used for all public facing emails if there is no more specific template available`` |
| フォルダ       | 公開メールテンプレート                       |
| 件名         | ``<<REPLACE WITH SUBJECT>>``                                                                |
| 拡張レターヘッド   | General Customer Support                                                                    |

### テストメールの送信

1. 「取引先責任者」タブをクリック
2. メニューより「すべての取引先責任者」を選択し、「Sean Forbes」を選択
3. 活動タブの「メール」をクリック(ない場合は「さらに表示」をクリックすると出てくる)
4. 「テンプレートを挿入、作成、または更新」をクリック(本文スペースのすぐしたに小さなアイコンがある)
5. 表示されたリストの中から「Public Facing General」を選択する
6. ポップアップ(警告)に対して「挿入」をクリック
7. テンプレートが正しいか確認する
8. 件名の項目で、``<<REPLACE WITH SUBJECT>>`` を削除して任意の件名に変更する
9. 破線枠(テキストボックス)をクリックして任意のテキストを入力。この部分がメールの本文となる。
10. 「送信」をクリック
11. 自分のアドレスにメールが届いていることを確認する
受けたメールをすべて捨てるSMTPブラックホールサーバの作り方③ - Dockerを使う 

[前回の記事](https://qiita.com/qualitia_cdev/items/85aaffcd5fddae5afb4c)で予告した通り、今回はSMTPブラックホールサーバをDockerで作る方法を紹介します。

*Docker自体はインストールされている状態からスタートです。

#### Docker build用のディレクトリ準備
```
# mkdir testdir
```
このtestdirの下に、以下のファイルを準備していきます。

```
Dockerfile
main.cf
master.cf
run.sh
```

#### Dockerfileの準備
```
FROM alpine:latest

RUN apk --update add postfix
    && rm -rf /var/cache/apk/*

ADD main.cf /etc/postfix/main.cf
ADD master.cf /etc/postfix/master.cf
ADD run.sh /run.sh

ENTRYPOINT ["/run.sh"]
```

#### main.cfの準備
前回のmain.cfファイルをコピーして使います。defaultから変わった項目は以下のとおり。

```
compatibility_level=2 (前回と違い、この項目を入れます)
myhostname = example.com
mynetworks = 0.0.0.0 (今回は制限なしにしますが、注意してください)
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
local_recipient_maps = 
```

#### master.cfの準備
前回のmaster.cfをコピーして使います。defaultから変わった項目は以下のとおり。

```
smtp      inet  n       -       n       -       -       smtpd
  -o content_filter=discard:
  -o smtpd_client_restrictions=permit
  -o smtpd_recipient_restrictions=permit,reject
```


#### run.shの準備
以下のようなスクリプトrun.shを書きます。

```
#!/bin/sh

postfix start
```

run.shに実行権限を与えます。Dockerfileの中に書いてもOKです。

```
# chmod 777 run.sh
```

#### Docker build
必要なファイルの準備が終わりましたので、Dockerをbuildします。タグはtestとします。

```
# docker build -t test .
```

#### Docker run
Dockerを立ち上げます。

```
# docker run --rm -i -t -p  25:25 test
```

#### 確認

docker psコマンドでこのDockerが上がったことが確認できます。

```
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
6d6d66d24db2        test                "/run.sh"           7 seconds ago       Up 7 seconds        0.0.0.0:25->25/tcp   vibrant_mccarthy

```

netstat -nlpコマンドでこのDockerが25番Portを上げていることが確認できます。

```
tcp6       0      0 :::25                   :::*                    LISTEN      31919/docker-proxy-
```

telnetコマンドで接続するとpostfixがバナーを返してくれます。

```
# telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 example.com ESMTP Postfix
```

これでDockerを使ってローカル環境にメールサーバを立ち上げることに成功しました。Dockerなので色んな環境で使えて便利です。

#### 追記: Dockerhubに公開しました (2019.8.6)
このDocker imageを[Dockerhub](https://hub.docker.com/repository/docker/qualitiaco/smtpblackhole)に公開しました。
docker pullして使ってください。

```
docker pull qualitiaco/smtpblackhole
```


*関連記事
[受けたメールをすべて捨てるSMTPブラックホールサーバの作り方①](https://qiita.com/qualitia_cdev/items/3ab284ca92939f58b9bb)
[受けたメールをすべて捨てるSMTPブラックホールサーバの作り方②]
(https://qiita.com/qualitia_cdev/items/85aaffcd5fddae5afb4c)
[受けたメールをすべて捨てるSMTPブラックホールサーバの作り方③ - Dockerを使う]
(https://qiita.com/qualitia_cdev/items/7f165e5f7e62e46ebe2b)
RubyでExcelスクリプトを書いた

動画をパラパラ漫画にしたくてツールを作った。

##ツールで自動化すること
１）パラパラ漫画にする動画を特定フレームごとに静止画に抜き出す。
２）印刷用に静止画を加工しやすいように余白をつけて並べる。
までをツールで行う。
印刷かけて裁断して閉じるまでは手でやることにした。

##前置き
印刷テンプレートはなんでも良いのでExcelとした。
Excelをいじくる方法はさまざまな方法があるがVBAはいまさらなのでパス。
いまどきっぽいのでRubyにしてみた。

##使う人用の準備編
以下の３つを実行Windows-PCにセットアップ。

####Rubyインストール
https://www.artonx.org/data/asr/
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83103/1f9e0e4a-f500-316f-e15e-18248a4980e4.png)
から「ActiveScriptRuby」をインストール。
ウィザードで入れてパスを自分で追加

#####Excel向けライブラリをダウンロード
http://www.tech-notes.org/excel_lib/
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83103/6946a5f7-b6c5-0678-cea8-04cd86a94fe1.png)
から「RubydeExcel Ver1.02」をダウンロード。
解凍して中身の「excel_lib.rb」をlib/ruby/site_rubyに置く。

#####ffmegをインストール
https://ffmpeg.zeranoe.com/builds/
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83103/f8481144-f004-80ad-ba41-1a3e1ce31750.png)
からダウンロードして解凍して適切な場所においてからパスを通す。

##自作スクリプト
2部構成
1)mp4の動画を指定した時間間隔で静止画に落とす。

```ruby
#!ruby -Ks
#必要ライブラリロード
require 'excel_lib'
require 'win32ole'

images = []

#------- ユーザで直すもの --------------
#何秒間隔で静止画に落とすか(※適宜修正ください)
frame_per_sec = 1

#どのフレームから静止画に落とすか
start_image_frame = 1

#何フレームを静止画に落とすか(※出力する動画の長さ(単位は静止画枚数)です。「動画の長さ÷静止画間隔」で修正ください)
image_frame_num = 126
#---------------------------------------

#出力先にすでにある静止画は消す。
for t in Dir.glob("./frame/*.jpg")
  File.delete(t)
  #p t
end

#動画を静止画に落とします。
for num in start_image_frame..image_frame_num do
  fname = "frame/1_%d.jpg" % num
  images.push(fname)
  command = "ffmpeg -i input_video/1.mp4 -ss %d -vframes 1 -f image2 -s 320x240 %s" % [frame_per_sec*num, fname]
  system(command)
  sleep(0.3)
end
```

2)静止画をExcelテンプレートに順に並べる。

```ruby
#!ruby -Ks
#必要ライブラリロード
require 'excel_lib'
require 'win32ole'

#ファイルの絶対パス取得サブルーチン
def getAbsolutePath(path)
  fso = WIN32OLE.new('Scripting.FileSystemObject')
  return fso.GetAbsolutePathname(path)
end

# EXCELテンプレートをコピーで開く
excel = Excel.new.copy_book("template.xlsx")
sheet1 = excel.sheets("sheet1")

# タイル状に静止画を貼り付け
xind = 0
yind = 0
sind = 0
for pic in Dir.glob("./frame/*.jpg") do
  sheet1.Shapes.AddPicture(
    getAbsolutePath(pic),
    false, true, 35+(265*xind)+(794*sind), 19+(188*yind), 218, 152);
    
  xind += 1
  if xind>2 then
    xind = 0
    yind += 1
    if yind>2 then
      xind = 0
      yind = 0
      sind += 1
    end
  end
  sleep(0.3)
end
```

以上です。
文系学生のプログラミング学習12日目ーガウスとノンガウスの処理速度ー


今回は１～Nまでの数字の和を求めるアルゴリズムを学習しました。
２種類あり、それぞれ処理速度に違いがあります。

#すべて足していく方法

タイトルの通り単純にすべて足していく方法です。

```Python
def add_all_numbers_NonGauss(num_list):
    num = 0
    for i in range(0, len(num_list)):
        num += num_list[i]
    return num
```

[1, 2]なら1+2となります。1~100なら100回繰り返します。数字が多くなるほど計算に時間がかかってしまいます。

#ガウスの方法

これは数学者ガウスが編み出した方法で、１～Nまでの和を求めるのに、n(n-1)/2を利用するものです。高校数学の数列の単元で学習したものです。

```Python
def add_all_numbers_Gauss(num_list):
    return((num_list[-1] + 1) * num_list[-1] / 2)
```


1~100までなら、N = (100+1)*(100/2) となり、どんなに数が増えても１回で計算できます。

自分は数学自体は数1A/2Bまでしか学んでいないのですが、プログラミングを勉強するにつれて数学の重要性を感じるようになってきました。数学も少し勉強しようと思います。

おわり
サクラエディタ：JavaScriptでマクロ実装（置換編）特定文字の繰り返しを置換する。

##下記サンプルコードは、選択されている部分に対して、aを3回繰り返している部分を置換します。
```replace.js
function sakuraReplace(str00) {
 var i=0;
 var lines="";
 var str01="";

 lines = str00.split(/(\r|\n|\r\n)/); // 改行コードで分割して変数に代入

 for (i in lines) // 分割したライン数をループ
 {
    str01 +=  lines[i].replace(/[a]{3}/,'【選択されていた文字を置換しました。】',6) + "\r\n";
 }
 return(str01);
}

var str00 = Editor.GetSelectedString(0); // 選択部分を変数に代入
if ( str00 !== "" ) Editor.InsText(sakuraReplace(str00));
```
##マクロ実行対象ファイルは以下になります。
```test.txt
aaa bbb ccc
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
##マクロ実行結果
```test.txt
【選択されていた文字を置換しました。】 bbb ccc
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
bxsliderでmodeをfadeにしたらIE11でちらついて怒られたときは…

jqueryのFadeInが悪さをしているようなので、
無理やりFadeInを使わないようにしてやります。

### jquery.bxslider.js:1381（修正前）

```js:jquery.bxslider.js:1381
slider.children.eq(slider.active.index)
.css('zIndex', slider.settings.slideZIndex + 1)
.fadeIn(slider.settings.speed, function() {
```
### jquery.bxslider.js:1381（修正後）

```js:jquery.bxslider.js
slider.children.eq(slider.active.index)
.css('zIndex', slider.settings.slideZIndex + 1)
.css('opacity',0).css('display','block')
.animate({opacity: 1},slider.settings.speed, function() {
```

私が発生した環境は背景にWebGLが引いてある状況下でしたので、
そういた環境下のみで発生するものかもしれませんが、誰かのためになればと思いここに記しておきます。

・bxSlider v4.2.12
・jquery v3.3.1
nodebrew で Node.js(node) のバージョンを管理する

## 概要
他の方が散々書かれてる記事だけど。

ローカルマシン上に複数の開発環境を持っていると、
nodeのバージョンが合わなくなることがある

そのため、バージョン管理を用いて
容易にnodeのバージョンを切り替えられるようにしたい

## 前提
### nodebrew がインストール済みであること

## 切り替え時に使用するコマンド
### 利用可能なnodeのバージョン一覧を取得
```
$ nodebrew ls-remote
```

### 現在、使用しているnodeのバージョンを確認
```
$ nodebrew ls
```

### nodeをインストール
install-binary じゃないと時間かかるよ

```
$ nodebrew install-binary v10.16.1
$ nodebrew install-binary stable     # <= これ動いてる？
$ nodebrew install-binary latest
```

### 使用するnodeの切り替え
```
$ nodebrew use v10.16.1
```

### その他
```
$ node -v
$ npm -v
```

## 動かしてみよう
## 最後に
バージョン管理って便利やね

## 次回はこれ！
特になし
サクラエディタ：JavaScriptでマクロ実装（置換編）aで始まりcで終わる行のみ置換する。

##下記サンプルコードは、選択されている部分に対して、aで始まりcで終わる行を置換します。
```replace.js
function sakuraReplace(str00) {
 var i=0;
 var lines="";
 var str01="";

 lines = str00.split(/(\r|\n|\r\n)/); // 改行コードで分割して変数に代入

 for (i in lines) // 分割したライン数をループ
 {
    str01 +=  lines[i].replace(/^a.*c$/,'【選択されていた文字を置換しました。】',6) + "\r\n";
 }
 return(str01);
}

var str00 = Editor.GetSelectedString(0); // 選択部分を変数に代入
if ( str00 !== "" ) Editor.InsText(sakuraReplace(str00));
```
##マクロ実行対象ファイルは以下になります。
```test.txt
aaa bbb ccc
bbb bbb ccc
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
##マクロ実行結果
```test.txt
【選択されていた文字を置換しました。】
bbbbbbccc
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
サクラエディタ：JavaScriptでマクロ実装（置換編）cで終わる行のみ置換する。

##下記サンプルコードは、選択されている部分に対して、cで終わる行を置換します。

```replace.js
function sakuraReplace(str00) {
 var i=0;
 var lines="";
 var str01="";

 lines = str00.split(/(\r|\n|\r\n)/); // 改行コードで分割して変数に代入

 for (i in lines) // 分割したライン数をループ
 {
    str01 +=  lines[i].replace(/^.*c$/,'【選択されていた文字を置換しました。】',6) + "\r\n";
 }
 return(str01);
}

var str00 = Editor.GetSelectedString(0); // 選択部分を変数に代入
if ( str00 !== "" ) Editor.InsText(sakuraReplace(str00));
```
##マクロ実行対象ファイルは以下になります。
```test.txt
aaa bbb ccc
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
##マクロ実行結果
```test.txt
【選択されていた文字を置換しました。】
ddd eee fff
ggg hhh iii
jjj kkk lll
mmm nnn ooo
ppp qqq rrr
sss ttt uuu
vvv www xxx
yyy zzz 000
111 222 333
444 555 666
777 888 999
```
覚書AWS ECS Cluter Instance 起動

AMI:amazon-ecs-optimized
userdata:
 #!/bin/bash
echo ECS_CLUSTER=<clustername> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;

これさえ覚えとけば、ECS　Instanceの起動は簡単
Rails6 のちょい足しな新機能を試す63（db:system:change 編）

# はじめに

Rails 6 に追加されそうな新機能を試す第63段。 今回は、 `db:system:change` 編です。
Rails 6 では、 `rails db:system:change` で使用するデータベースを変更できるようになりました。

`config/database.yml` と Gemfile を書き変えます。

Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は `gem install rails --prerelease` でインストールできます。

```shell
$ rails --version
Rails 6.0.0.rc1
```

今回は、 PostgreSQL から MySQL に DB を変更してみます。

# プロジェクトを作る

PostgreSQL を使うように `--database` オプションを指定します。

```shell
rails new rails6_0_0rc1 --database=postgresql
cd rails6_0_0rc1
```

# マイグレーションを作る

users テーブルを作ります。

```shell
$ bin/rails g migration CreateUser name
```

# マイグレーションを実行する

実行前に必要なら、 `config/database.yml` を編集して、データベース (PostgreSQL) にアクセスできるようにします。

```shell
$ bin/rails db:create db:migrate
```

マイグレーションが普通にできました。

# データベースを変更する

ここからが本番です。
データベースを MySQL に変更します。

```shell
$ bin/rails db:system:change --to=mysql
    conflict  config/database.yml
Overwrite /app/config/database.yml? (enter "h" for help) [Ynaqdhm]
```

確認のため、 `h` を入力してみます。


```shell
Overwrite /app/config/database.yml? (enter "h" for help) [Ynaqdhm] h
        Y - yes, overwrite
        n - no, do not overwrite
        a - all, overwrite this and all others
        q - quit, abort
        d - diff, show the differences between the old and the new
        h - help, show this help
        m - merge, run merge tool
Overwrite /app/config/database.yml? (enter "h" for help) [Ynaqdhm]
```

`rails app:update` コマンドと似ていますね。
今回は、 `Y` を入力します。

```shell
Overwrite /app/config/database.yml? (enter "h" for help) [Ynaqdhm] Y
       force  config/database.yml
       gsub  Gemfile
       gsub  Gemfile
```

Gemfile は無条件で書き変えるみたいです。

```shell
$ git diff Gemfile
...
-gem 'pg', '>= 0.18', '< 2.0'
+gem 'mysql2', '>= 0.4.4'
...
```


# bundle install を実行する

`bundle install` を実行して `mysql2` gem をインストールします。

```shell
$ bundle install
```

# マイグレーションを実行してみる

必要なら config/database.yml を編集して、接続先の情報を書き換えてください。


```shell
$ bin/rails db:create db:migrate
```

何の問題もなく終了しました。
mysql コマンドでも確認できました。

```
mysql> show create table users\G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try063_db_system_change (rails db:system:change 実行前)
https://github.com/suketa/rails6_0_0rc1/tree/try063_db_system_change_to_mysql (rails db:system:change 実行後)


# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Add rails db:system:change command](https://github.com/rails/rails/pull/34832)
ボーダーコンピューティング設備の簡単な比較

画像処理、テキスト分析、サイバーセキュリティなどを含むIoTシナリオには、強力な計算能力が必要です。 そのような場合、ニューラルネットワークが使用されており、ここでエッジコンピューティングと分析が不可欠になりました。

最近、私たちは、AIを実行できるEdge Computingデバイスを使用してシナリオを解決することを要求されたいくつかのプロジェクトに取り組みました。 エッジデバイスに利用可能なオプションを調査し、その結論に基づいて、現在の市場における5つの主要競合企業を比較しました。

しかし、まず最初に、コンテキストとして、これら2つのプロジェクトにエッジデバイスを導入することが期待されていたのは、次のとおりです。

- 1）電気めっきプラントで、プロセスモデリングおよび制御用のニューラルネットワークモデルを作成して、プラントに最適な制御設定を決定する
- 2）OEM製造工場において、品質管理のために欠陥を自動的に検査すること。 この場合は、カメラが使用されました
私が言ったように、私達は市場で利用可能な複数の選択肢の賛否両論を熟慮し、そして我々が下の表に我々の調査結果を記録すると思った。 お役に立つことを願っています！

![20190802160523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/bd37ed87-593c-6248-f07f-5e9b1e7a5dba.png)


これらのオプションは、機能だけでなく、製造資産、サポートされているOSなどとの互換性についても分析されました。

Nanoは、GeForceグラフィックカードで使用されている128コアMaxwell GPU上に構築されているため、NVIDIA Jetsonに特定の実装を追加することにしました。 他のものと比較してより高いレベルのパフォーマンスを持つMLフレームワークも多数サポートしています。

##### 私たちは他の人たちを拒絶しました:
Google CoralのTPUは、大量で精度の低い処理向けに構築されており、Tensorflowでしか動作しません。

![uploading-0]()


Intel Up2（Compute Stick 2搭載）またはCompute Stick 2（Ubuntu / Raspberry Pi搭載） - WindowsでサポートされていないComputer Vision（Open Vino）用のSDKを提供します。

Google Coralは最新の市場であり、有望に思えます。 私たちは確かにそれを見守っているでしょう、そしてもし機能が合えば私達の顧客にそれを勧めさえするかもしれません。

![uploading-0]()


あなたは現在の選択肢についてどう思いますか？ あなたは違う選択をしましたか？ そうであるかどうか私たちに知らせてください。 私たちはそれについて話をしたいのです。
Laravel5.8 文字列をキャメルケース・パスカルケース・スネークケース・ケバブケース・単数系・複数形に変換する

LaravelやPHPに標準搭載されているいい感じの関数を使って文字列を自由自在に変換します。

## Laravel5.8以降は文字列及び配列ヘルパー非推奨

- https://laravel-news.com/laravel-5-8-deprecates-string-and-array-helpers

```php
use Illuminate\Support\Str;
```

`Str` クラスを `use` して使いましょう。

## 文字列をケバブケースにする

```php
Str::kebab('fooBar'); // foo-bar
```

## 文字列をスネークケースにする

```php
Str::snake('fooBar'); // foo_bar
```

## 文字列をキャメルケースに変換する

```php
Str::camel('foo_bar'); // fooBar
```

キャメルノーテーションとも呼ぶ

## 文字列をパスカルケースに変換する

```php
Str::studly('foo_bar'); // FooBar
```

アッパーキャメルケースとも呼ぶ

## 単数系の文字列を複数形に変換する

```php
Str::plural('car'); // cars
Str::plural('child'); // children
```

## 複数形の文字列を単数系に変換する

```php
Str::singular('cars'); // car
Str::singular('children'); // child
```

## 文字列をURLで使用可能な文字列に変換する

```php
Str::slug('Laravel 5 Framework', '-'); // laravel-5-framework
```

## 補足: PHPの標準関数でできること

Laravelでも用意されてるものは合わせて紹介します。

### 文字列を小文字にする

```php
strtolower('FOO_BAR'); // foo_bar
mb_strtolower('FOO_BAR'); // foo_bar

Str::lower('FOO_BAR'); // foo_bar
```

- https://www.php.net/manual/ja/function.strtolower.php
- https://www.php.net/manual/ja/function.mb-strtolower.php
- https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/Str.php#L253

### 文字列を大文字にする

```php
strtoupper('foo_bar'); // FOO_BAR
mb_strtoupper('foo_bar'); // FOO_BAR

Str::upper('foo_bar'); // FOO_BAR
```

- https://www.php.net/manual/ja/function.strtoupper.php
- https://www.php.net/manual/ja/function.mb-strtoupper.php
- https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/Str.php#L421

### 文字列の最初の文字を大文字にする

```php
ucfirst('foo bar'); // Foo bar

Str::ucfirst('foo bar'); // Foo bar
```

https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/Str.php#L557

### 文字列の各単語の最初の文字を大文字にする

```php
ucwords('foo bar'); // Foo Bar

Str::title('foo bar'); // Foo Bar
```

## 参考

- https://readouble.com/laravel/5.8/ja/helpers.html
【N+1問題】概要と解決方法を簡単にまとめてみた

# 簡潔に、どんな問題なの？？
情報をDBから抽出する際に生じる問題で、
***全レコードの取得に一回 ＋ 各レコードの取得分にN回、 それぞれSQLを発行してしまっている状況*** を指します。


⬇️SQL文で実際に見てみると分かりやすいかもしれません。⬇️

```SQL:N+1問題が発生しているSQL文の例
SELECT 'phones'.* FROM 'phones' # Phone.allの的なコードを想定。
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 1
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 2
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 3
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 4
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 5
:                           :                           :
:                           :                           :
:                           :                           :
```

まず結論をお伝えするためにcontrollerやModelの定義を省きましたが、
**「一人のUserが一台の電話（phone）を所有している関係（一対一の関係性）における、情報の一覧取得」**を想定しています。
恥ずかしながら初学者の私は、⬆️のようなSQLを見ても「どこがN+１なんだ？？」と疑問に思いました。笑

そこで上記SQL文を少し分割して見てみると、「N+1問題」と呼ばれる訳が腹落ちするようになります。

```SQL:一行目・・・N+1の『+1』にあたる部分
SELECT ‘phones’.* FROM ‘phones’ # phone.all の実行
```
```SQL:二行目以降・・・N+1の『N』にあたる部分
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 1
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 2
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 3
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 4
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' = 5
:                           :                           :
:                           :                           :
:                           :                           :
```
**一覧に表示するデータ**を取得するために **SELECT を 1 回実行**
**各データの関連データ**を取得するために **SELECT を N 回実行**
つまり、***DBへのアクセス（SELECT）が合計 N+1 回実行されてしまう***という状況です。
SQL文の発行順通りに解釈するならば、N+1問題というよりも***「1+N問題」***と捉えた方が分かりやすそうですね。

いずれにせよ膨大なDBを利用する場合は、『N』にあたる部分の行数が何万行にも及ぶため、大きな問題となりそうです...!!

#じゃあどうやって解決するの？？
順序が逆になりましたが、
###上記N+1問題が発生しているコード（例）は以下のようなものです。

はじめに、PhoneテーブルとUserテーブルは下記によって一対一の関係性で結合しています。

```Phone.rb
has_one :user
```

次に、phone_controllerでのuserテーブルのカラムの呼び出しについて、
例えば、phone_idが1の予約者を@userに代入したいとすると、


```phones_controller.rb
@phone = phone.find_by(phone_id: 1)
@user = @phone.user.user_name
```

上記のようになります。

そして実際にphoneのviewで予約者一覧を表示したいときには、「each do」文がまず思い浮かぶのではないでしょうか。

```phone一覧.rb
@phones = phone.all
@phones.each do |@phone|
    @user = @phone.user.user_name
    @user
end
```
これにて一覧の取得は可能となるはずですが、上述の通りこれではN+1問題が発生してしまうのです。

###includesメソッドによる解決方法
includesメソッドは、関連している複数のテーブルからデータを取得してくるときのアクセス回数を大きく減らすことができるメソッドです。

```phone_controller.rb
@phones = phone.all.includes(:user)
```
上記のように記述する事で、DBへのアクセス回数が1+N行に及んだSQLが下記のようになります。

```SQL:N+1問題が解消されたSQL
SELECT ‘phone’.* FROM ‘phones’
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' IN (1,2,3,4,5)
```
includesメソッドによってSQLの発行がわずか二行に収まり、N+1問題を解決する事ができました！
PowerShellを使ってリモートでコマンドを実行する方法

# 前提
Windowsサーバーを管理するときに、毎回リモートデスクトップでログインしてから操作をするのは大変です。
特に複数のサーバーを管理している場合は尚更です。

それを解決するためにWinRM（Windows Remote Management） という、Windowsを遠隔操作をする仕組みを使ってコマンドを実行します。

## 環境

### 使用マシン

| 用途   | マシン             |
| ------------ | --------------------- |
| 操作する側   | Windows10             |
| 操作される側 | Windows Server 2012 R2 |

### 使用技術
- PowerShell
- WinRM

# 設定方法
## 操作される側
この手順は、操作される側のサーバーに実際にログインするか、リモートデスクトップでログインして行ってください。

### 1. 管理者権限でPowerShellを開く

### 2. WinRMを有効にする

下記コマンドを実行してください。

```powershell
Enable-PSRemoting
```
WinRMを使うにあたって必要な設定を一括で行ってくれます。
※ファイアウォールの例外`TCP 5985`が有効になります。`TCP 5985`はWinRMが使用するポート番号です。

以上で操作される側の設定は完了です。

## 操作する側

続いて操作する側です。

### 1. 管理者権限でPowerShellを開く

### 2. WinRMを有効にする

操作される側とは異なるコマンドを実行します

```powershell
net start WinRM
```

### 3. 操作される側のIPを信頼できるホストとして登録する

TrustedHostsに登録します。

```powershell
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "操作される側のIP"
```

以上で操作する側の設定も完了です。
一度設定をすれば次回からは不要です。

# 使い方

### 1. PowerShellを開く（管理者権限でなくてOK）

### 2. セッションを開始する

下記コマンドを実行します。

```powershell
Enter-PSSession -ComputerName 操作される側のIP -Credential ログイン名
```

パスワードの入力が求められるので入力してログインします。

これでリモートでコマンドが実行できるようになりました。

### 3. コマンドを実行する
ここでは試しに`ipconfig`を実行してみます。

```powershell
ipconfig
```

接続先のipアドレスが確認できれば、問題なく実行できています。

### 4. セッションを終了する

使い終わったら、念のためセッションを切りましょう。

```powershell
Exit-PSSession
```

または

```PowerShell
exit
```

# 参考
- [Microsoft - Windows Remote Management](https://docs.microsoft.com/ja-jp/windows/win32/winrm/portal)
WinRMに関するMicrosoftドキュメント。日本語版はありませんでした。

- [Microsoft - PowerShell - Enable-PSRemoting](https://docs.microsoft.com/ja-jp/powershell/module/Microsoft.PowerShell.Core/Enable-PSRemoting?view=powershell-5.1)
`Enable-PSRemoting`で行われる内容の詳細が確認できます。こちらも日本語版はありませんでした。

- [Masato's IT Library - PowerShellでリモートからコマンドを実行する](https://mstn.hateblo.jp/entry/2016/09/13/193124)
Pandas(1) データ構造(Series)

# データ構造
## はじめに
NumpyとPandasをインポートする。

```Python:
import pandas as pd
import numpy as np
```

## Series
Seriesは、任意のデータ型(整数、文字列、浮動小数点数、Pythonオブジェクトなど)を保持できる1次元のラベル付き配列。ラベルはまとめてindexと呼ばれる。
Seriesを作成する基本的な方法は以下のとおり。

```Python:
s = pd.Series(data, index=index)
```

### ndarray
dataがndarrayの場合、indexはdataと同じ長さの必要がある。indexが渡されない場合、値[0, 1, …,len(data) - 1]を持つindexが作成される。

```Python:インデックスを渡さない
s=pd.Series(np.random.randn(5))
```
> 0   -0.074401
> 1   -0.823889
> 2   -0.687987
> 3    1.202700
> 4    0.241094
> dtype: float64

```Python:インデックスを渡す
index = ['a', 'b', 'c', 'd', 'e']
s=pd.Series(np.random.randn(5), index=index)
```
> a    0.673887
> b    0.441498
> c   -0.782673
> d    0.765580
> e    1.412489
> dtype: float64

```Python:インデックスの確認
s.index
```
> Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

### dicts
Seriesは辞書型からインスタンス化することができる。

```Python:辞書型
dicts = {'a': 1, 'b': 2, 'c': 3}
s=pd.Series(dicts)
```

> a    1
> b    2
> c    3
> dtype: int64

### scalar value
dataがスカラ値の場合は、indexを指定する必要がある。値はindexの長さに一致するように繰り返される。
```Python:scalar value
s=pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])
```
> a    5.0
> b    5.0
> c    5.0
> d    5.0
> e    5.0
> dtype: float64

### Series acts very simiraly to a ndarray
筆者自身、ndarrayを熟知していないため、似ているかどうかは不明。

```Python:
index = ['a', 'b', 'c', 'd', 'e']
s=pd.Series(np.random.randn(5), index=index)
```

> a   -0.913132
> b   -0.351333
> c   -1.066319
> d    0.909310
> e    0.704081
> dtype: float64

```Python:
s[0]
```
> -0.9131315757113279

```Python:
s[:3]
```
> a   -0.913132
> b   -0.351333
> c   -1.066319
> dtype: float64

```Python:
s.median()
```
> -0.3513325944157782

```Python:
s[s > s.median()]
```

> d    0.909310
> e    0.704081
> dtype: float64

```Python:
s[[4, 3, 1]]
```

> e    0.704081
> d    0.909310
> b   -0.351333
> dtype: float64

```Python:
np.exp(s)
```

> a    0.401266
> b    0.703750
> c    0.344273
> d    2.482609
> e    2.021987
> dtype: float64

```Python:
s.dtype
```

> dtype('float64')

```Python:
s.array
```

> <PandasArray>
> [-0.9131315757113279, -0.3513325944157782, -1.0663194328871628,
>   0.9093099539087041,  0.7040806236764076]
> Length: 5, dtype: float64

```Python:ndarrayへの変換
s.to_numpy()
```

> array([-0.91313158, -0.35133259, -1.06631943,  0.90930995,  0.70408062])

### Series is dict-like
Seriesは、index labelで値を取得および設定できるという点で、固定サイズの辞書に類似している。

```Python:
s['a']
```
> -0.9131315757113279

```Python:
s['e'] = 3
```

> a   -0.913132
> b   -0.351333
> c   -1.066319
> d    0.909310
> e    3.000000
> dtype: float64

### Vectorized operations and label alignment with Series

```Python:
s + s
```

> a   -1.826263
> b   -0.702665
> c   -2.132639
> d    1.818620
> e    6.000000
> dtype: float64

```Python:
s * 2
```

> a   -1.826263
> b   -0.702665
> c   -2.132639
> d    1.818620
> e    6.000000
> dtype: float64
【Laravel】バルクアップデートを行う方法

Laravelで、複数のデータをアップデートしたいケースがあると思います。

通常考えられるのは、foreachでインスタンスを1つずつアップデートする方法だと思います。

他にもsave()メソッドやSQLを使う方法などがあるので、それぞれの使い道について、まとめてみます。

# update()の使い道

一番一般的な方法だと思います。

```
App\Flight::where('active', 1)
          ->update(['delayed' => 1]);
```
activeカラムが1のレコード全てのdelayedを1にするというコードです。

この方法なら、`App\Flight::all()->update(xxx)`とすることで、Flightモデルの全てのレコードに対して、更新をかけることができます。

ただ、ID:1のレコードはdelayedを2にして、ID:2のレコードのdelayedを3にする、というようなレコードによって更新したい値が違う場合は、update()コマンドでは対応できません。

# foreach + save()の使い道

```
$flights = App\Flight::all();
foreach($flights as $flight) {
    $flight->name = $request->name;
    $flight->save();
}
```
このように1レコードずつsave()メソッドで保存していく方法です。

これはレコードの数だけクエリが発生するので、かなり重くなると思われます。

save()メソッドを使用する際は、少ない件数か1件のみの時が良いと思います。

foreachで1件ずつ更新するやり方だと、件数によってはメモリリークを起こす可能性がありますので、`chunk()`や`cursor()`などを使って、分割すると良いと思います。

[Laravel(Eloquent): chunk() vs cursor()](https://qiita.com/ryo511/items/ebcd1c1b2ad5addc5c9d)

# 保存したい値が変わる場合

上記2つの方法は、1つのモデルに対して、同一データを保存するケースでした。

しかし、FlightモデルのレコードID：1にdelayed:1を保存しつつ、レコードID：2にdelayed:2を保存したい場合もあるかと思います。

この場合は、LaravelのEloquentでは対応できないと思うので、SQL文を作るしかありません。

詳しいやり方については、

[超倍速！？複数のレコードの更新を1回で実施するbulk update！](https://dream-target.jp/2018/02/17/130/)

などを参考にしてもらえばと思います。

# 【おまけ】新規作成ならinsertが使える

アップデートではなく、新規作成したい場合は、`create()`、`save()`、`insert()`を使うことができます。

insert()なら、違う値を1回で保存することができるので、新規データを挿入したい場合は`insert()`メソッドを使うと良いと思います。

ただ、セキュリティが緩くなるようなので、

[【Laravel】DBにデータを保存する方法。createとinsertの違いなど](https://qiita.com/katsunory/items/87a73297f44a65f1474f#4-insert%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)

を参考にしながら自己責任で行ってください。

SQLをがっつり書ければ、作成も更新もSQL文で書いた方がいいのかなあと思ってます。
portforwardingしたvagrantのマシンにhostからアクセスする方法

以下のようなVagrantfileがあった時、

```ruby:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.define "app" do |node|
    node.vm.box = "bento/amazonlinux-2"
    node.vm.hostname = "app"
    node.vm.synced_folder "app", "/var/www", :owner=> 'vagrant', :group=>'nginx', :mount_options => ['dmode=775', 'fmode=775']
    node.vm.network :private_network, ip: "192.168.33.10"
    node.vm.network :forwarded_port, guest:80, host:2001
    node.vm.provider "virtualbox" do |vb|
       vb.memory = "2048"
    end

  end
end
```


hostのマシンから、curlなり、ブラウザなりからアクセスする時、
2通りある。

1つは、
###「192.168.33.10:80」

としてアクセスする方法。
これは、
gestマシンに割り当てられた、192.168.33.10の80番portに「直接」アクセスする方法。
vagrantではgestへ「直接」アクセスすることが可能らしい。

詳しくは以下で解説されている
https://qiita.com/ftakao2007/items/0ec05c2ef3c14cdbea11

2つ目は、
###「localhost:2001」
としてアクセスする方法。
これは、hostマシン(localhost)の2001portにアクセスするするということ。
これは、vagrantfileに定義されているように
「2001」portにアクセスすると、gestの「192.168.33.10:80」に転送してくれるということ。

#まとめ
勘違いしていて、
localhost=192.168.33.10になっているので、
192.168.33.10:2001で接続できたり、
port forwardingせずに、
localhost:80でアクセスできると思ったが、
そうではないらしい。

あくまでアクセスするのは、

####・host(localhost)経由でgestにアクセスする方法
####・gestに直接アクセスする方法

の二つである。
Python めざせモックマスター①（Mockオブジェクトのふるまいを指定する）

ユニットテストを書くときに便利なunittest.mockライブラリをバリバリ使いこなしたい！
以下の順番で勉強していきます。今回は①をやっていきます。

①Mockオブジェクトのふるまいを指定する（return_value，side_effectを使う）、MagicMockとMockの違いを理解する

②オブジェクトをMockオブジェクトに差し替える

③　①②で登場しなかった機能を紹介


# Mockオブジェクトをつくる

実行したバージョンはPython3.7.3です。
unittest.mockはPython3.3以降は標準ライブラリとして利用可能です。それ以前のバージョンの場合はpipでインストールしてください。

Mockオブジェクトをつくってみる↓

```python
>>> from unittest.mock import Mock
>>> a = Mock()
>>> a
<Mock id='48605424'>
>>> type(a)
<class 'unittest.mock.Mock'>
```


# Mockオブジェクトのふるまいを指定する
オプションを設定することでMockオブジェクトの振る舞いは自由に指定できます。よく使う設定をまとめていきます。

###return_value
return_valueを使うことで、Mockオブジェクトが呼ばれたときの返り値を定義できます。



```python
# return_valueを設定していないときの返り値はMockオブジェクト
>>> b = Mock()
>>> b()
<Mock name='mock()' id='48614416'>

# return_valueを設定すると設定した値が返り値になる
>>> a = Mock()
>>> a.return_value = 'hoge'
>>> a()
'hoge'

# こう書いても同じ
>>> c = Mock(return_value='hoge')
>>> c()
'hoge'
```

###side_effect
Mockオブジェクトが呼ばれたときに呼ばれる関数や、発生する例外を指定することができます。
return_valueだと1つの値しか設定できませんでしたが、side_effectを使うと条件によって返り値を変えたりできます。

```python
# Mockオブジェクトが呼ばれたときにwhoメソッドが呼ばれるよう設定する
>>> m = Mock()
>>> def who(num):
...     if num == 1:
...         return 'いちろう'
...     if num == 2:
...         return 'じろう'
...
>>> m.side_effect = who
>>> m(1)
'いちろう'
>>> m(2)
'じろう'

# Mockオブジェクトが呼ばれたときに発生する例外を設定する
>>> m = Mock()
>>> m.side_effect = Exception('Out!')
>>> m()
Traceback (most recent call last):
# 中略
Exception: Out!
```
#####return_valueとside_effectを両方指定したらどうなるか？
side_effectが優先されます。side_effectにNoneを指定すると設定がクリアされ、return_valueが適用されます。

```python
>>> def who(num):
...     if num == 1:
...         return 'いちろう'
...     if num == 2:
...         return 'じろう'
>>> m = Mock()
>>> m.return_value = 'さぶろう'
>>> m(1)
'さぶろう'
>>> m.side_effect = who
# side_effectが優先される
>>> m(1)
'いちろう'
>>> m(2)
'じろう'
# side_effectをクリアするとreturn_valueが適用される
>>> m.side_effect = None
>>> m(1)
'さぶろう'
>>> m(2)
'さぶろう'

```
# Mockのサブクラス、MagicMock

MagicMockはMockのサブクラスです。Mockとの違いは特殊メソッドをデフォルトで実装している点です。

どういうことか見てみましょう。

```python
>>> from unittest.mock import Mock
>>> from unittest.mock import MagicMock
>>> mock = Mock()
>>> len(mock)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'Mock' has no len()
# mockは__len__()が定義されていないので、len()をコールできない。
>>> mock.__len__()
...省略
AttributeError: __len__
# __len__()を定義してやるとコールできるようになる。
>>> mock.__len__ = lambda x:1
>>> mock.__len__()
1
>>> len(mock)
1

# 同じことをMagicMockオブジェクトでやってみる
>>> magic = MagicMock()
# __len__()が定義されているので、len()をコールできる。
>>> magic.__len__()
0
>>> len(magic)
0
# もちろん書き換えもできる
>>> magic.__len__ = lambda x:1
>>> len(magic)
1
```
このようにMagicMockオブジェクトではほとんどの特殊メソッドをデフォルトで実装してくれています。
自分で定義しなくてもいいのでMockよりMagicMockのほうが使い勝手がよさそうですね！
ただし、デフォルト実装の内容を理解してうえで使う必要があります。上記例の`__len__()`のようにデフォルト実装だと常に結果は0になります。`__bool__()`だと常に結果は`True`になります。

※デフォルト実装している特殊メソッドとデフォルト実装の内容の詳細は公式リファレンスをご確認ください。 https://docs.python.org/ja/3/library/unittest.mock.html#unittest.mock.MagicMock
Salesforce調べ物メモ

# この文書の目的
Salesfoceについて調べたことをまとめます。
随時加筆します。

# Salesforceって何？
[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%BC%E3%83%AB%E3%82%B9%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B9%E3%83%BB%E3%83%89%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0)によると下記のように記載されています。
> セールスフォース・ドットコム（英: salesforce.com, Inc.）は、米国カリフォルニア州に本社を置く、顧客関係管理（CRM）ソリューションを中心としたクラウドコンピューティング・サービスの提供企業である。ビジネスアプリケーションおよびクラウドプラットフォームをインターネット経由で提供している。

買収企業を見ると非常に多岐にわたります。JigsawやHerokuも買収しているのね。知らなかった。

提供しているサービスはSaaS型のアプリケーションとPaaSの[Force.com](https://www.salesforce.com/jp/products/platform/products/force/)と[Heroku](https://jp.heroku.com/)がある。

# サービス
下記のサービスを提供している。これらのサービスだけでなく[AppExchange](https://appexchangejp.salesforce.com/)というアプリストア的なものもある。

## SaaS
- Sales Cloud（営業支援）
- Service Cloud（カスタマーサービス&サポート）
- Marketing Cloud(マーケティング)
- Commerce Cloud（e-コマース）
- Community Cloud

## PaaS
- Lightning Platform
- Heroku

# テクノロジ
## 言語は?
Apex(エイペックス)というJavaに似た構文の言語がある。
ブラウザ上の開発者コンソールでの開発とEclipseのプラグイン(Force.com IDE plugin for Eclipse)がある。
プラグインについては[Force.com IDE Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.eclipse.meta/eclipse/ide_getting_started.htm)を参照とのこと。残念ながら英語。

# 学習リソース
## 開発者サイト
公式の[開発者サイト](https://developer.salesforce.com/ja/)がある。

## トレイル
Salesforce公式の[学習サイト](https://trailhead.salesforce.com/ja)
多分無料で参照できるコースがある。日本語、英語。

# とりあえず出来るようにしたいこと
- [x] お試し登録(トライアル期間は30日で登録したら即営業が電話してくる)
- [ ] 既存機能のカスタマイズ(例えばプルダウンの項目を追加するとか)
- [ ] 新規機能の追加(新しい画面追加するとか)
- [ ] 開発環境を用意する(本番環境と同機能を実装した開発環境を用意するとか)

## 雑多なメモ
### 開発環境について
Sandboxを使用することで環境は作れそう。
> Sandbox とは、本番組織のデータまたは設定を破損する危険を冒さずに、変更または新しいアプリケーションをテストするために使用する特殊な編成のことです。
Sandboxにもライセンスがある模様。
画面を見ると「Developer」、「Developer Pro」、「Partial Copy」、「Full」の記載がある。

### Developer Editionについて
開発者向けのエディションもあるらしい。こちらを先に登録しておけばよかったか...
[こちら](https://developer.salesforce.com)からサインアップする。
Read RFID tag in C# UWP

A serial RFID reader can be read using <b>DataReader</b> with the help of <b>SerialPort</b> that is being used to find the connected port in the system.

```c#
private SerialDevice _serialPort;
private DataReader _dataReader;
private ObservableCollection<DeviceInformation> _deviceList;
private CancellationTokenSource _readCancellationTokenSource;
```
Then we need to configure the serial settings

```c#
try
{
   string devSel = SerialDevice.GetDeviceSelector();
   var dis = await DeviceInformation.FindAllAsync(devSel);
   if (dis.Count > 0)
   {
      DeviceInformation entry = (DeviceInformation)dis[0];
      this._serialPort = await SerialDevice.FromIdAsync(entry.Id);
      this._serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
      this._serialPort.BaudRate = 9600;
      this._serialPort.DataBits = 8;
      this._serialPort.StopBits = SerialStopBitCount.One;
      this._serialPort.Parity = SerialParity.None;
      this._serialPort.Handshake = SerialHandshake.None;
      this._readCancellationTokenSource = new CancellationTokenSource();
    }
} catch (Exception ex)
{
   Debug.WriteLine(ex.ToString());
}
```
And from that serial port InputStream, we can read the data from the serial device.

```c#
this._dataReader = new DataReader(this._serialPort.InputStream);
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
cancellationToken.ThrowIfCancellationRequested();

// create task and wait for the data on the input stream
loadAsyncTask = this._dataReader.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;

// this line will return the data from the serial RFID device
this._dataReader.ReadString(bytesRead);
```

Reference link: https://github.com/phanithken/RFIDReader
gh-pagesで"file" argument must be a non-empty stringと怒られたので対応方法メモ

# 背景
GitHub Pages使えば超簡単に静的サイトが公開できるって聞いたからやってみたんだけど、やってみたらエラーが出てきたよ。
手順は次の記事参考にしたよ→https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf

# やったこと
参考記事の通りなんだけど、

```
npm run deploy
```

ってやったら

```
"file" argument must be a non-empty string
```
って怒られた。先月(2019/07/08)普通にできたんだけど（怒）

# 対処法
つい最近の更新でバグ混入したらしい
https://stackoverflow.com/questions/57331878/gh-pages-d-build-gives-error-file-argument-must-be-a-non-empty-string

ということで、gh-pagesのバージョンを下げる

```
npm install gh-pages@2.0 --dev.
```

すると無事、gh-pagesブランチで公開できました。

8/2 17時ごろにエラーに直面して困っていたら、8/2 18時30分に同じ質問がstack overflowで投げられて、8/4に回答が出るというすごくタイミングの悪い問題でした。

まあ、そのうち治るでしょう。
【供養】amazonから商品情報等を取得することについて調べた。

###経緯
最近の趣味の一つでクラウドワークスに乗っている副業案件を眺めるってのがあるんですが、
その趣味を楽しんでいるときに似たような案件があるなぁと目についたんです。

これとか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443834/4be869f5-bac0-c664-d376-d6801df3e301.png)


これとか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443834/2c62328e-6f86-b80a-7c2d-e0b32a7b5a03.png)

後はフィルター条件に一致しない物（これよりも単価の安い物）もいくつかありました。

###最初の考え
正直最初はこれで10万だとか30万だとか貰えるのが不思議で仕方なかったです。
API叩けばすぐに終わるようにしか思わなかったからです。
私はクラウドワークスで実績がないから簡単には受けれないでしょう。
ですが非常に魅力的に目に写りました。
作業時間にして３人日程度で出来ると思ったからです。
3日で10万~30万も貰えれば本業を休んでもやる価値はありました。
愚かな私はそれ以上のことに頭が回らず、この案件が宝のように見えていました。

###APIを調べる。
まず初めにやるべきことはamazonから提供されているAPIについて調べることでした。
知の神であるgoogle様にお伺いを立てました。
そして密林の奥底にある遺跡を紹介してもらい、そこまで赴きました。
我々はそこでとある文献を発見しました。
以下がそれです。
[Product Advertising API (PA-API) の利用ガイドライン](https://affiliate.amazon.co.jp/help/topic/t32/ref=amb_link_iXr8CjIgMsKQ4US-Oe2uIA_13?pf_rd_p=81113fec-16ff-49a8-b8f5-863e145cbed1)

なるほど？取得が困難なのか？

この時点で半分気づいていました。
最初に宝に見えていたあれは宝では無いです。おそらくミミックでしょう。
ザラキの呪文で私を苦しめてくるに違いありません。

###ほかのAPIがあるかもしれない
ザラキくらいなら当たらないかもしれません。運にかければいいです。
さぁ別の手段を探しましょう。

さてamazonですが別のAPIも用意してるみたいです。
[amazon NWS](https://developer.amazonservices.jp/gp/mws/api.html?group=products&section=products&version=latest)
上記は販売者として登録が必要みたいでした。
つまりこれを使うなら月額5000円ほどかかるということですね。
すでに販売者であればこれを使える可能性がありますが、宝に見えている物がこれを取得できてるとはあまり思えません。
恐らくダメでしょう。

次にkeepa APIが候補にあがりました。
[keepa API docment](https://keepa.com/#!discuss/t/product-object/116)
これも月々のお支払いが必要です。
お支払いをお願いできるのであれば良いでしょうが、残念ながら実績のない人間にこれを進められても見向きもされないでしょう。

上記２つは月額がかかるということで深くは調べてないため、そもそも要件に合ってない可能性もあります。
ただAPIで探している限り使えそうなものはここまでで紹介した３つでした。

###APIではない方法
APIは取得するのが困難なので全く別の方法を考えました。
まぁweb scrapingですね。
ちょうどこの記事の一つ前の記事がweb scrapingで遊んでました。
良ければ見てください。→[puppeteerを使ってyoutubeの新着動画を探そう](https://qiita.com/osake_log/items/57697771e97b290f5e53)
そしてイイネしてください。

話を戻しますが、puppeteer等を用いてscrapingしてしまえば該当URLやASINさえあれば情報の取得は可能でしょう。
自身で作成するのが大変であればgithubから拝借すればいいと思います。
以下参考
[amazon-scraper-python](https://github.com/tducret/amazon-scraper-python)
[amazon-scraper](https://github.com/pmcalabrese/amazon-scraper)
パイソンの方は最近更新されているようなのでそれなりに安心できるんじゃないでしょうか。
ライセンスもMITですし商用利用自体は問題ないです。

ただ、自身で作った場合でも拝借した場合でも気を付けなければいけないことがあります。
というかweb scrapingするなら当たり前に知っててほしいことですが、常識の範囲でscrapingするということです。
で、あんまりやりすぎると当然ブロックされます。場合によってはすごく怒られます。
特にこのような技術を用いる予定がない人でも下記の事件は知っておくと良いと思います。
[岡崎市立中央図書館事件](https://ja.wikipedia.org/wiki/%E5%B2%A1%E5%B4%8E%E5%B8%82%E7%AB%8B%E4%B8%AD%E5%A4%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8%E4%BA%8B%E4%BB%B6)
こういった事情があるため、性能面で注文があった場合に上記を説明し、納得してもらう必要があります。
「それでも何とかしろ」なんて言われた日には、どの様にして黙らせるかを考えてしまいそうです。

他にも気を付ける点があります。
もし、amazonのサイトのデザインが変更された場合、それに合わせて修正しなければならないという点です。
「一度購入したがデザインが変更されたため使えなくなった！タダで直せ！」
なんて言われたらとんでもないことです。
そうならないためにも事前の契約に注意が必要になります。

すでに宝では無くミミックにしか見えなくなってきました。
少なくとも10万で受けたいかと言われると辛いなぁという感想です。

###まとめ
まとめます。
手法としてAPIとweb scrapingがある。
APIだと
・PAAPI
・NWS
・keepa API
上記のどれかを扱うことになりそう。

web scrapingだと
・完全に自作
・moduleを借り、難しいことはmoduleに任せる
どちらかになりそう。
web scraping自体正攻法ではないので気を付ける点が多そう。

以上がここ最近私自身が調べていた情報になります。
間違っていた場合は編集リクエストください。

さて、最後に一つ私から皆様に質問させてください。
ここまで読んでくれた皆様ならどのような方法でamazonから情報を取得しますか？
コメントお待ちしております。
JsonEditorOnlineが超絶便利な件

Jsonの整形には様々なツールがあります。
エディターでもデフォルトで使用できるものから、Pluginで使用できるようになるものも種々あります。
私のおすすめはChromeの拡張機能のこちら

## JSON Editor Online

DLはこちら
https://chrome.google.com/webstore/detail/json-editor/lhkmoheomjbkfloacpgllgjcamhihfaj?hl=ja

<img width="1213" alt="スクリーンショット 2019-08-05 10.41.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/a07b71ab-7220-19c2-4f6b-ad40be8e3d90.png">

### なにが便利か

- chrome上で使えるので環境・platformを選ばない
- 整形・minifyが簡単に変換できる
- 軽い
- 整形だけでなく、階層構造へ変換して表示できる（複雑なjsonになるほど便利です）

みなさんは何を使っていますか？
大規模日本語ビジネスニュースコーパスを学習したELMo（MeCab利用）モデルの紹介 

#はじめに
以前、[日本語のBERT事前学習済モデル](https://qiita.com/mkt3/items/3c1278339ff1bcc0187f)の紹介記事を投稿しましたストックマークの森長です。
前回の記事を多くの皆様に読んでいただき、大変ありがたく思っております。
そこで、今回はBERTに続いて、ELMoの日本語学習済モデルを公開いたします。

#ELMoとは

ELMoは双方向LSTMを用いて学習させた言語モデルです。
ELMoによって、文脈を考慮した単語分散表現(単語ベクトル)を獲得できます。
自然言語処理では、文脈を考慮した単語ベクトルを用いることで、[語義の曖昧性解消](https://ja.wikipedia.org/wiki/%E8%AA%9E%E7%BE%A9%E3%81%AE%E6%9B%96%E6%98%A7%E6%80%A7%E8%A7%A3%E6%B6%88)が見込めます。
例えば、以下の「人気」という単語のように、文脈によって意味が異なる単語でも、ELMoでは文脈を考慮して文脈ごとの「人気」の単語ベクトルを獲得可能です。

- あのキャラクターは人気がある。
- この道路は、夜に人気がなくて、危ない。

ELMoの単語ベクトルの具体的な利用方法としては、ELMoで獲得した単語ベクトルをfastText等の他の手法で獲得した単語ベクトルと連結した単語し、その単語ベクトルを用いてタスクを解くことで、精度の向上が見込めます。
弊社の検証用タスク(記事の分類タスク)では、「Bi-LSTM + Self-Attention」モデルの単語ベクトルにELMoの単語ベクトルを単純に連結するだけで、精度が88%→91%に向上しました。

# ELMo学習済モデルの特徴
弊社のELMo学習済モデルの特徴としては、以前公開しましたBERTの事前学習済モデルと同様に学習用データを日本語ビジネスニュース記事としていることがあげられます。そのため、本モデルは、主にビジネスに関するドメインで効果を発揮します。

ELMo学習済モデルの詳細は以下の通りです。
今回公開する学習済モデルは2パターンあり、単語単位の埋め込みのみで学習したモデル、 文字単位・単語単位の埋め込みで学習したモデルの2つになります。

| 学習用データ | トークナイザー | 埋め込み | 
|:--|:--|:--|
|日本語ビジネスニュース記事(40万記事)| MeCab +  NEologd | 単語単位埋め込み | 
|日本語ビジネスニュース記事(40万記事)| MeCab +  NEologd | 文字単位・単語単位埋め込み | 

#ダウンロード
[ダウンロードリンク](https://drive.google.com/drive/folders/1BnOeHPDiei7BAi0XhR0diTDozmXaAl1S?usp=sharing)
モデルの内訳は以下の通りです。

- 単語単位埋め込みモデル
 - char.dic、 word.dic
 - config.json
 - configs/cnn_0_100_512_4096.json
 - encoder.pkl
 - token_embedder.pkl
- 文字単位・単語単位埋め込みモデル
 - char.dic、 word.dic
 - config.json
 - configs/cnn_16_100_512_4096.json
 - encoder.pkl
 - token_embedder.pkl

#利用方法
AllenNLPというオープンソースの研究用ライブラリを継承した以下のコードを用いることで、ELMoによる単語ベクトルを生成できます。
https://github.com/HIT-SCIR/ELMoForManyLangs

以下コードのEmbedderクラスのmodel_dirにダウンロードしたモデルのディレクトリを指定することで、文脈に応じた単語ベクトルを取得できます。具体的なEmbedderクラスの利用方法は以下をご参照ください。
https://github.com/HIT-SCIR/ELMoForManyLangs#use-elmoformanylangs-programmatically

#まとめ
最後までお読みいただき、ありがとうございました。
BERTと同様に公開したELMo学習済モデルが、自然言語処理の盛り上がりに更なる貢献ができると大変嬉しいです。